OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/printing/print_job.h" | 5 #include "chrome/browser/printing/print_job.h" |
6 | 6 |
7 #include "base/message_loop.h" | 7 #include "base/message_loop.h" |
8 #include "chrome/browser/printing/print_job_worker.h" | 8 #include "chrome/browser/printing/print_job_worker.h" |
9 #include "chrome/browser/printing/printed_document.h" | 9 #include "chrome/browser/printing/printed_document.h" |
10 #include "chrome/browser/printing/printed_page.h" | 10 #include "chrome/browser/printing/printed_page.h" |
11 #include "chrome/common/notification_service.h" | 11 #include "chrome/common/notification_service.h" |
12 | 12 |
13 #ifdef _MSC_VER | 13 #ifdef _MSC_VER |
14 #pragma warning(disable:4355) // 'this' : used in base member initializer list | 14 #pragma warning(disable:4355) // 'this' : used in base member initializer list |
15 #endif | 15 #endif |
16 | 16 |
17 using base::TimeDelta; | 17 using base::TimeDelta; |
18 | 18 |
19 namespace printing { | 19 namespace printing { |
20 | 20 |
21 PrintJob::PrintJob(PrintedPagesSource* source) | |
22 : ui_message_loop_(MessageLoop::current()), | |
23 worker_(new PrintJobWorker(this)), | |
24 source_(source), | |
25 is_job_pending_(false), | |
26 is_print_dialog_box_shown_(false), | |
27 is_canceling_(false) { | |
28 DCHECK(ui_message_loop_); | |
29 ui_message_loop_->AddDestructionObserver(this); | |
30 } | |
31 | |
32 PrintJob::PrintJob() | 21 PrintJob::PrintJob() |
33 : ui_message_loop_(MessageLoop::current()), | 22 : ui_message_loop_(MessageLoop::current()), |
34 worker_(), | 23 worker_(), |
35 source_(NULL), | 24 source_(NULL), |
36 settings_(), | 25 settings_(), |
37 is_job_pending_(false), | 26 is_job_pending_(false), |
38 is_print_dialog_box_shown_(false), | 27 is_print_dialog_box_shown_(false), |
39 is_canceling_(false) { | 28 is_canceling_(false) { |
40 DCHECK(ui_message_loop_); | 29 DCHECK(ui_message_loop_); |
41 ui_message_loop_->AddDestructionObserver(this); | 30 ui_message_loop_->AddDestructionObserver(this); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
96 break; | 85 break; |
97 } | 86 } |
98 default: { | 87 default: { |
99 break; | 88 break; |
100 } | 89 } |
101 } | 90 } |
102 } | 91 } |
103 | 92 |
104 void PrintJob::GetSettingsDone(const PrintSettings& new_settings, | 93 void PrintJob::GetSettingsDone(const PrintSettings& new_settings, |
105 PrintingContext::Result result) { | 94 PrintingContext::Result result) { |
106 DCHECK(!is_job_pending_); | 95 NOTREACHED(); |
107 | |
108 if (!source_ || result == PrintingContext::FAILED) { | |
109 // The source is gone, there's nothing to do. | |
110 Cancel(); | |
111 return; | |
112 } | |
113 | |
114 // Only create a new PrintedDocument if the settings have changed or if | |
115 // there was no printed document. | |
116 if (!document_.get() || !new_settings.Equals(settings_)) { | |
117 UpdatePrintedDocument(new PrintedDocument(new_settings, source_, | |
118 PrintSettings::NewCookie())); | |
119 } | |
120 | |
121 JobEventDetails::Type type; | |
122 if (is_print_dialog_box_shown_) { | |
123 type = (result == PrintingContext::OK) ? | |
124 JobEventDetails::USER_INIT_DONE : | |
125 JobEventDetails::USER_INIT_CANCELED; | |
126 // Dialog box is not shown anymore. | |
127 is_print_dialog_box_shown_ = false; | |
128 } else { | |
129 DCHECK_EQ(result, PrintingContext::OK); | |
130 type = JobEventDetails::DEFAULT_INIT_DONE; | |
131 } | |
132 scoped_refptr<JobEventDetails> details( | |
133 new JobEventDetails(type, document_.get(), NULL)); | |
134 NotificationService::current()->Notify( | |
135 NotificationType::PRINT_JOB_EVENT, | |
136 Source<PrintJob>(this), | |
137 Details<JobEventDetails>(details.get())); | |
138 } | 96 } |
139 | 97 |
140 PrintJobWorker* PrintJob::DetachWorker(PrintJobWorkerOwner* new_owner) { | 98 PrintJobWorker* PrintJob::DetachWorker(PrintJobWorkerOwner* new_owner) { |
141 NOTREACHED(); | 99 NOTREACHED(); |
142 return NULL; | 100 return NULL; |
143 } | 101 } |
144 | 102 |
145 int PrintJob::cookie() const { | 103 int PrintJob::cookie() const { |
146 if (!document_.get()) | 104 if (!document_.get()) |
147 // Always use an invalid cookie in this case. | 105 // Always use an invalid cookie in this case. |
148 return 0; | 106 return 0; |
149 return document_->cookie(); | 107 return document_->cookie(); |
150 } | 108 } |
151 | 109 |
152 void PrintJob::WillDestroyCurrentMessageLoop() { | 110 void PrintJob::WillDestroyCurrentMessageLoop() { |
153 NOTREACHED(); | 111 NOTREACHED(); |
154 } | 112 } |
155 | 113 |
156 void PrintJob::GetSettings(GetSettingsAskParam ask_user_for_settings, | |
157 HWND parent_window) { | |
158 DCHECK_EQ(ui_message_loop_, MessageLoop::current()); | |
159 DCHECK(!is_job_pending_); | |
160 DCHECK(!is_print_dialog_box_shown_); | |
161 // Is not reentrant. | |
162 if (is_job_pending_) | |
163 return; | |
164 | |
165 // Lazy create the worker thread. There is one worker thread per print job. | |
166 if (!worker_->message_loop()) { | |
167 if (!worker_->Start()) | |
168 return; | |
169 | |
170 // Don't re-register if we were already registered. | |
171 NotificationService::current()->AddObserver( | |
172 this, NotificationType::PRINT_JOB_EVENT, Source<PrintJob>(this)); | |
173 } | |
174 | |
175 int page_count = 0; | |
176 if (document_.get()) { | |
177 page_count = document_->page_count(); | |
178 } | |
179 | |
180 // Real work is done in PrintJobWorker::Init(). | |
181 is_print_dialog_box_shown_ = ask_user_for_settings == ASK_USER; | |
182 worker_->message_loop()->PostTask(FROM_HERE, NewRunnableMethod( | |
183 worker_.get(), &PrintJobWorker::GetSettings, is_print_dialog_box_shown_, | |
184 parent_window, page_count)); | |
185 } | |
186 | |
187 void PrintJob::StartPrinting() { | 114 void PrintJob::StartPrinting() { |
188 DCHECK_EQ(ui_message_loop_, MessageLoop::current()); | 115 DCHECK_EQ(ui_message_loop_, MessageLoop::current()); |
189 DCHECK(worker_->message_loop()); | 116 DCHECK(worker_->message_loop()); |
190 DCHECK(!is_job_pending_); | 117 DCHECK(!is_job_pending_); |
191 DCHECK(!is_print_dialog_box_shown_); | 118 DCHECK(!is_print_dialog_box_shown_); |
192 if (!worker_->message_loop() || is_job_pending_) | 119 if (!worker_->message_loop() || is_job_pending_) |
193 return; | 120 return; |
194 | 121 |
195 // Real work is done in PrintJobWorker::StartPrinting(). | 122 // Real work is done in PrintJobWorker::StartPrinting(). |
196 worker_->message_loop()->PostTask(FROM_HERE, NewRunnableMethod( | 123 worker_->message_loop()->PostTask(FROM_HERE, NewRunnableMethod( |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
251 scoped_refptr<JobEventDetails> details( | 178 scoped_refptr<JobEventDetails> details( |
252 new JobEventDetails(JobEventDetails::FAILED, NULL, NULL)); | 179 new JobEventDetails(JobEventDetails::FAILED, NULL, NULL)); |
253 NotificationService::current()->Notify( | 180 NotificationService::current()->Notify( |
254 NotificationType::PRINT_JOB_EVENT, | 181 NotificationType::PRINT_JOB_EVENT, |
255 Source<PrintJob>(this), | 182 Source<PrintJob>(this), |
256 Details<JobEventDetails>(details.get())); | 183 Details<JobEventDetails>(details.get())); |
257 Stop(); | 184 Stop(); |
258 is_canceling_ = false; | 185 is_canceling_ = false; |
259 } | 186 } |
260 | 187 |
261 bool PrintJob::RequestMissingPages() { | |
262 DCHECK_EQ(ui_message_loop_, MessageLoop::current()); | |
263 DCHECK(!is_print_dialog_box_shown_); | |
264 if (!is_job_pending_ || is_print_dialog_box_shown_) | |
265 return false; | |
266 | |
267 MessageLoop* worker_loop = worker_.get() ? worker_->message_loop() : NULL; | |
268 if (!worker_loop) | |
269 return false; | |
270 | |
271 worker_loop->PostTask(FROM_HERE, NewRunnableMethod( | |
272 worker_.get(), &PrintJobWorker::RequestMissingPages)); | |
273 return true; | |
274 } | |
275 | |
276 bool PrintJob::FlushJob(int timeout_ms) { | 188 bool PrintJob::FlushJob(int timeout_ms) { |
277 if (!RequestMissingPages()) | |
278 return false; | |
279 | |
280 // Make sure the object outlive this message loop. | 189 // Make sure the object outlive this message loop. |
281 scoped_refptr<PrintJob> handle(this); | 190 scoped_refptr<PrintJob> handle(this); |
282 | 191 |
283 // Stop() will eventually be called, which will get out of the inner message | 192 // Stop() will eventually be called, which will get out of the inner message |
284 // loop. But, don't take it for granted and set a timer in case something goes | 193 // loop. But, don't take it for granted and set a timer in case something goes |
285 // wrong. | 194 // wrong. |
286 base::OneShotTimer<MessageLoop> quit_task; | 195 base::OneShotTimer<MessageLoop> quit_task; |
287 if (timeout_ms) { | 196 if (timeout_ms) { |
288 quit_task.Start(TimeDelta::FromMilliseconds(timeout_ms), | 197 quit_task.Start(TimeDelta::FromMilliseconds(timeout_ms), |
289 MessageLoop::current(), &MessageLoop::Quit); | 198 MessageLoop::current(), &MessageLoop::Quit); |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
459 PrintedDocument* JobEventDetails::document() const { | 368 PrintedDocument* JobEventDetails::document() const { |
460 return document_; | 369 return document_; |
461 } | 370 } |
462 | 371 |
463 PrintedPage* JobEventDetails::page() const { | 372 PrintedPage* JobEventDetails::page() const { |
464 return page_; | 373 return page_; |
465 } | 374 } |
466 | 375 |
467 } // namespace printing | 376 } // namespace printing |
468 | 377 |
OLD | NEW |