Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(164)

Side by Side Diff: chrome/browser/chromeos/printing/cups_print_job_notification.cc

Issue 2435303003: [CUPS] Implement the Print Job notification. (Closed)
Patch Set: Address stevenjb@'s comments. Rebase. Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/chromeos/printing/cups_print_job_notification.h"
6
7 #include "base/strings/string_number_conversions.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/browser/browser_process.h"
10 #include "chrome/browser/chromeos/printing/cups_print_job.h"
11 #include "chrome/browser/chromeos/printing/cups_print_job_manager.h"
12 #include "chrome/browser/chromeos/printing/cups_print_job_manager_factory.h"
13 #include "chrome/browser/notifications/notification_ui_manager.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/grit/generated_resources.h"
16 #include "ui/base/l10n/l10n_util.h"
17 #include "ui/base/resource/resource_bundle.h"
18 #include "ui/chromeos/resources/grit/ui_chromeos_resources.h"
19 #include "ui/message_center/message_center.h"
20 #include "ui/message_center/notification_types.h"
21
22 namespace chromeos {
23
24 namespace {
25
26 const char kCupsPrintJobNotificationId[] =
27 "chrome://settings/printing/cups-print-job-notification";
28
29 class CupsPrintJobNotificationDelegate : public NotificationDelegate {
30 public:
31 explicit CupsPrintJobNotificationDelegate(CupsPrintJobNotification* item)
32 : item_(item) {}
33
34 // NotificationDelegate overrides:
35 void Close(bool by_user) override {
36 if (by_user)
37 item_->CloseNotificationByUser();
38 }
39
40 bool HasClickedListener() override { return true; }
41
42 void ButtonClick(int button_index) override {
43 item_->ClickOnNotificationButton(button_index);
44 }
45
46 std::string id() const override { return item_->GetNotificationId(); }
47
48 private:
49 ~CupsPrintJobNotificationDelegate() override {}
50
51 CupsPrintJobNotification* item_;
52
53 DISALLOW_COPY_AND_ASSIGN(CupsPrintJobNotificationDelegate);
54 };
55
56 } // namespace
57
58 CupsPrintJobNotification::CupsPrintJobNotification(CupsPrintJob* print_job,
59 Profile* profile)
60 : notification_id_(print_job->GetUniqueId()),
61 print_job_(print_job),
62 delegate_(new CupsPrintJobNotificationDelegate(this)),
63 profile_(profile) {
64 // Create a notification for the print job. The title, body, icon and buttons
65 // of the notification will be updated in UpdateNotification().
66 notification_.reset(new Notification(
67 message_center::NOTIFICATION_TYPE_SIMPLE,
68 base::string16(), // title
69 base::string16(), // body
70 gfx::Image(), // icon
71 message_center::NotifierId(message_center::NotifierId::SYSTEM_COMPONENT,
72 kCupsPrintJobNotificationId),
73 base::string16(), // display_source
74 GURL(kCupsPrintJobNotificationId),
75 notification_id_, // tag
76 message_center::RichNotificationData(), delegate_.get()));
77 UpdateNotification();
78 }
79
80 CupsPrintJobNotification::~CupsPrintJobNotification() {}
81
82 void CupsPrintJobNotification::OnPrintJobStatusUpdated() {
83 UpdateNotification();
84 }
85
86 void CupsPrintJobNotification::CloseNotificationByUser() {
87 closed_in_middle_ = true;
88 g_browser_process->message_center()->RemoveNotification(GetNotificationId(),
89 true /* by_user */);
90 }
91
92 void CupsPrintJobNotification::ClickOnNotificationButton(int button_index) {
93 DCHECK(button_index >= 0 &&
94 static_cast<size_t>(button_index) < button_commands_->size());
95
96 CupsPrintJobNotification::ButtonCommand button_command =
97 button_commands_->at(button_index);
98 CupsPrintJobManager* print_job_manager =
99 CupsPrintJobManagerFactory::GetForBrowserContext(profile_);
100 const ProfileID profile_id = NotificationUIManager::GetProfileID(profile_);
101
102 switch (button_command) {
103 case ButtonCommand::CANCEL_PRINTING:
104 print_job_manager->CancelPrintJob(print_job_);
105 g_browser_process->notification_ui_manager()->CancelById(
106 GetNotificationId(), profile_id);
107 // |print_job_| is deleted by CupsPrintManager when the print job is
108 // cancelled, thus set it to nullptr.
109 print_job_ = nullptr;
110 break;
111 case ButtonCommand::PAUSE_PRINTING:
112 print_job_manager->SuspendPrintJob(print_job_);
113 break;
114 case ButtonCommand::RESUME_PRINTING:
115 print_job_manager->ResumePrintJob(print_job_);
116 break;
117 case ButtonCommand::GET_HELP:
118 break;
119 }
120 }
121
122 const std::string& CupsPrintJobNotification::GetNotificationId() {
123 return notification_id_;
124 }
125
126 void CupsPrintJobNotification::UpdateNotification() {
127 DCHECK(print_job_->state() != CupsPrintJob::State::STATE_CANCELLED);
skau 2016/10/27 01:43:01 Is this because jobs are canceled by closing the n
xdai1 2016/10/28 23:59:54 Yes, the notification is gone after the job is can
128
129 UpdateNotificationTitle();
130 UpdateNotificationIcon();
131 UpdateNotificationBodyMessage();
132 UpdateNotificationType();
133 UpdateNotificationButtons();
134
135 if (closed_in_middle_ &&
136 print_job_->state() == CupsPrintJob::State::STATE_PAGE_DONE) {
137 // If the notification was closed during the printing, prevent showing the
138 // following printing progress.
139 g_browser_process->notification_ui_manager()->Update(*notification_,
140 profile_);
141 } else if (print_job_->state() == CupsPrintJob::State::STATE_PAGE_DONE) {
142 // If it was not closed, update the notification message directly.
143 g_browser_process->notification_ui_manager()->Add(*notification_, profile_);
skau 2016/10/27 01:43:00 Did you mean to update here? The comment doesn't
xdai1 2016/10/28 23:59:53 Yes, that's the way to implement it. Add an existi
144 } else {
145 closed_in_middle_ = false;
146 // In order to make sure it pop up, we should delete it before readding it.
147 const ProfileID profile_id = NotificationUIManager::GetProfileID(profile_);
148 g_browser_process->notification_ui_manager()->CancelById(
149 GetNotificationId(), profile_id);
150 g_browser_process->notification_ui_manager()->Add(*notification_, profile_);
151 }
152 }
153
154 void CupsPrintJobNotification::UpdateNotificationTitle() {
155 notification_->set_title(base::UTF8ToUTF16(print_job_->document_title()));
156 }
157
158 void CupsPrintJobNotification::UpdateNotificationIcon() {
159 ResourceBundle& bundle = ResourceBundle::GetSharedInstance();
160 switch (print_job_->state()) {
161 case CupsPrintJob::State::STATE_WAITING:
162 notification_->set_icon(
163 bundle.GetImageNamed(IDR_PRINT_NOTIFICATION_WAITING));
164 break;
165 case CupsPrintJob::State::STATE_STARTED:
166 case CupsPrintJob::State::STATE_PAGE_DONE:
167 case CupsPrintJob::State::STATE_SUSPENDED:
168 case CupsPrintJob::State::STATE_RESUMED:
169 notification_->set_icon(
170 bundle.GetImageNamed(IDR_PRINT_NOTIFICATION_PRINTING));
171 break;
172 case CupsPrintJob::State::STATE_DOCUMENT_DONE:
173 notification_->set_icon(
174 bundle.GetImageNamed(IDR_PRINT_NOTIFICATION_DONE));
175 break;
176 case CupsPrintJob::State::STATE_ERROR:
177 notification_->set_icon(
178 bundle.GetImageNamed(IDR_PRINT_NOTIFICATION_ERROR));
179 break;
180 default:
181 break;
182 }
183 }
184
185 void CupsPrintJobNotification::UpdateNotificationBodyMessage() {
186 base::string16 message;
187 switch (print_job_->state()) {
188 case CupsPrintJob::State::STATE_NONE:
189 break;
190 case CupsPrintJob::State::STATE_WAITING:
191 message = l10n_util::GetStringFUTF16(
192 IDS_PRINT_JOB_WAITING_NOTIFICATION_MESSAGE,
193 base::IntToString16(print_job_->total_page_number()),
194 base::UTF8ToUTF16(print_job_->printer().display_name()));
195 break;
196 case CupsPrintJob::State::STATE_STARTED:
197 case CupsPrintJob::State::STATE_PAGE_DONE:
198 case CupsPrintJob::State::STATE_SUSPENDED:
skau 2016/10/27 01:43:00 Does SUSPENDED belong here? Do we have no messagi
xdai1 2016/10/28 23:59:54 Right. We don't have special message for the pause
199 case CupsPrintJob::State::STATE_RESUMED:
200 message = l10n_util::GetStringFUTF16(
201 IDS_PRINT_JOB_PRINTING_NOTIFICATION_MESSAGE,
202 base::IntToString16(print_job_->total_page_number()),
203 base::UTF8ToUTF16(print_job_->printer().display_name()));
204
205 break;
206 case CupsPrintJob::State::STATE_DOCUMENT_DONE:
207 message = l10n_util::GetStringFUTF16(
208 IDS_PRINT_JOB_DONE_NOTIFICATION_MESSAGE,
209 base::IntToString16(print_job_->total_page_number()),
210 base::UTF8ToUTF16(print_job_->printer().display_name()));
211 break;
212 case CupsPrintJob::State::STATE_ERROR:
213 message = l10n_util::GetStringFUTF16(
214 IDS_PRINT_JOB_ERROR_NOTIFICATION_MESSAGE,
215 base::IntToString16(print_job_->total_page_number()),
216 base::UTF8ToUTF16(print_job_->printer().display_name()));
217 break;
218 default:
219 break;
220 }
221 notification_->set_message(message);
222 }
223
224 void CupsPrintJobNotification::UpdateNotificationType() {
225 switch (print_job_->state()) {
226 case CupsPrintJob::State::STATE_STARTED:
227 case CupsPrintJob::State::STATE_PAGE_DONE:
228 case CupsPrintJob::State::STATE_SUSPENDED:
229 case CupsPrintJob::State::STATE_RESUMED:
230 notification_->set_type(message_center::NOTIFICATION_TYPE_PROGRESS);
231 notification_->set_progress(print_job_->printed_page_number() * 100 /
232 print_job_->total_page_number());
233 break;
234 case CupsPrintJob::State::STATE_NONE:
235 case CupsPrintJob::State::STATE_WAITING:
236 case CupsPrintJob::State::STATE_DOCUMENT_DONE:
237 case CupsPrintJob::State::STATE_ERROR:
238 default:
239 notification_->set_type(message_center::NOTIFICATION_TYPE_SIMPLE);
240 break;
241 }
242 }
243
244 void CupsPrintJobNotification::UpdateNotificationButtons() {
245 std::vector<message_center::ButtonInfo> buttons;
246 button_commands_ = GetButtonCommands();
247 for (auto& iter : *button_commands_.get()) {
skau 2016/10/27 01:43:01 iter isn't an iterator, it's a ButtonCommand.
skau 2016/10/27 01:43:01 You shouldn't need get() here
xdai1 2016/10/28 23:59:54 Done.
xdai1 2016/10/28 23:59:54 Done.
248 message_center::ButtonInfo button_info =
249 message_center::ButtonInfo(GetButtonLabel(iter));
250 button_info.icon = GetButtonIcon(iter);
251 buttons.push_back(button_info);
252 }
253 notification_->set_buttons(buttons);
254 }
255
256 std::unique_ptr<std::vector<CupsPrintJobNotification::ButtonCommand>>
257 CupsPrintJobNotification::GetButtonCommands() const {
258 std::unique_ptr<std::vector<CupsPrintJobNotification::ButtonCommand>>
259 commands(new std::vector<CupsPrintJobNotification::ButtonCommand>());
skau 2016/10/27 01:43:01 MakeUnique is preferred
260 switch (print_job_->state()) {
261 case CupsPrintJob::State::STATE_WAITING:
262 commands->push_back(ButtonCommand::CANCEL_PRINTING);
263 break;
264 case CupsPrintJob::State::STATE_STARTED:
265 case CupsPrintJob::State::STATE_PAGE_DONE:
266 case CupsPrintJob::State::STATE_RESUMED:
267 commands->push_back(ButtonCommand::PAUSE_PRINTING);
268 commands->push_back(ButtonCommand::CANCEL_PRINTING);
269 break;
270 case CupsPrintJob::State::STATE_SUSPENDED:
271 commands->push_back(ButtonCommand::RESUME_PRINTING);
272 commands->push_back(ButtonCommand::CANCEL_PRINTING);
273 break;
274 case CupsPrintJob::State::STATE_ERROR:
275 commands->push_back(ButtonCommand::GET_HELP);
276 break;
277 default:
278 break;
279 }
280 return commands;
281 }
282
283 base::string16 CupsPrintJobNotification::GetButtonLabel(
284 ButtonCommand button) const {
285 switch (button) {
286 case ButtonCommand::CANCEL_PRINTING:
287 return l10n_util::GetStringUTF16(
288 IDS_PRINT_JOB_NOTIFICATION_CANCEL_BUTTON);
289 case ButtonCommand::PAUSE_PRINTING:
290 return l10n_util::GetStringUTF16(IDS_PRINT_JOB_NOTIFICATION_PAUSE_BUTTON);
291 case ButtonCommand::RESUME_PRINTING:
292 return l10n_util::GetStringUTF16(
293 IDS_PRINT_JOB_NOTIFICATION_RESUME_BUTTON);
294 case ButtonCommand::GET_HELP:
295 return l10n_util::GetStringUTF16(
296 IDS_PRINT_JOB_NOTIFICATION_GET_HELP_BUTTON);
297 }
298 }
299
300 gfx::Image CupsPrintJobNotification::GetButtonIcon(ButtonCommand button) const {
301 ResourceBundle& bundle = ResourceBundle::GetSharedInstance();
302 gfx::Image icon;
303 switch (button) {
304 case ButtonCommand::CANCEL_PRINTING:
305 icon = bundle.GetImageNamed(IDR_PRINT_NOTIFICATION_CANCEL);
306 break;
307 case ButtonCommand::PAUSE_PRINTING:
308 icon = bundle.GetImageNamed(IDR_PRINT_NOTIFICATION_PAUSE);
309 break;
310 case ButtonCommand::RESUME_PRINTING:
311 // TODO(xdai): Add "Resume" icon once it's available.
312 break;
313 case ButtonCommand::GET_HELP:
314 // TODO(xdai): Add "Get help" icon once it's available.
315 break;
316 }
317 return icon;
318 }
319
320 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698