Chromium Code Reviews| 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_worker.h" | 5 #include "chrome/browser/printing/print_job_worker.h" |
| 6 | 6 |
| 7 #include "base/message_loop.h" | 7 #include "base/message_loop.h" |
| 8 #include "chrome/browser/chrome_thread.h" | |
| 8 #include "chrome/browser/printing/print_job.h" | 9 #include "chrome/browser/printing/print_job.h" |
| 9 #include "chrome/common/notification_service.h" | 10 #include "chrome/common/notification_service.h" |
| 10 #include "printing/printed_document.h" | 11 #include "printing/printed_document.h" |
| 11 #include "printing/printed_page.h" | 12 #include "printing/printed_page.h" |
| 12 | 13 |
| 13 namespace printing { | 14 namespace printing { |
| 14 | 15 |
| 15 class PrintJobWorker::NotificationTask : public Task { | 16 class PrintJobWorker::NotificationTask : public Task { |
| 16 public: | 17 public: |
| 17 NotificationTask() : print_job_(NULL), details_(NULL) { | 18 NotificationTask() : print_job_(NULL), details_(NULL) { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 57 // The object is deleted in the UI thread. | 58 // The object is deleted in the UI thread. |
| 58 DCHECK_EQ(owner_->message_loop(), MessageLoop::current()); | 59 DCHECK_EQ(owner_->message_loop(), MessageLoop::current()); |
| 59 } | 60 } |
| 60 | 61 |
| 61 void PrintJobWorker::SetNewOwner(PrintJobWorkerOwner* new_owner) { | 62 void PrintJobWorker::SetNewOwner(PrintJobWorkerOwner* new_owner) { |
| 62 DCHECK(page_number_ == PageNumber::npos()); | 63 DCHECK(page_number_ == PageNumber::npos()); |
| 63 owner_ = new_owner; | 64 owner_ = new_owner; |
| 64 } | 65 } |
| 65 | 66 |
| 66 void PrintJobWorker::GetSettings(bool ask_user_for_settings, | 67 void PrintJobWorker::GetSettings(bool ask_user_for_settings, |
| 67 HWND parent_window, | 68 gfx::NativeWindow parent_window, |
| 68 int document_page_count, | 69 int document_page_count, |
| 69 bool has_selection) { | 70 bool has_selection) { |
| 70 DCHECK_EQ(message_loop(), MessageLoop::current()); | 71 DCHECK_EQ(message_loop(), MessageLoop::current()); |
| 71 DCHECK_EQ(page_number_, PageNumber::npos()); | 72 DCHECK_EQ(page_number_, PageNumber::npos()); |
| 72 | 73 |
| 73 // Recursive task processing is needed for the dialog in case it needs to be | 74 // Recursive task processing is needed for the dialog in case it needs to be |
| 74 // destroyed by a task. | 75 // destroyed by a task. |
| 75 MessageLoop::current()->SetNestableTasksAllowed(true); | 76 MessageLoop::current()->SetNestableTasksAllowed(true); |
| 76 | 77 |
| 77 PrintingContext::Result result; | |
| 78 if (ask_user_for_settings) { | 78 if (ask_user_for_settings) { |
| 79 result = printing_context_.AskUserForSettings(parent_window, | 79 #if defined(OS_MACOSX) |
| 80 document_page_count, | 80 ChromeThread::GetMessageLoop(ChromeThread::UI)->PostTask( |
| 81 has_selection); | 81 FROM_HERE, NewRunnableMethod(this, &PrintJobWorker::GetSettingsWithUI, |
| 82 parent_window, document_page_count, | |
| 83 has_selection)); | |
| 84 #else | |
| 85 PrintingContext::Result result = printing_context_.AskUserForSettings( | |
| 86 parent_window, document_page_count, has_selection); | |
| 87 GetSettingsDone(result); | |
| 88 #endif | |
| 82 } else { | 89 } else { |
| 83 result = printing_context_.UseDefaultSettings(); | 90 PrintingContext::Result result = printing_context_.UseDefaultSettings(); |
| 91 GetSettingsDone(result); | |
| 84 } | 92 } |
| 93 } | |
| 85 | 94 |
| 95 void PrintJobWorker::GetSettingsDone(PrintingContext::Result result) { | |
| 86 // Most PrintingContext functions may start a message loop and process | 96 // Most PrintingContext functions may start a message loop and process |
| 87 // message recursively, so disable recursive task processing. | 97 // message recursively, so disable recursive task processing. |
| 88 MessageLoop::current()->SetNestableTasksAllowed(false); | 98 MessageLoop::current()->SetNestableTasksAllowed(false); |
| 89 | 99 |
| 90 // We can't use OnFailure() here since owner_ may not support notifications. | 100 // We can't use OnFailure() here since owner_ may not support notifications. |
| 91 | 101 |
| 92 // PrintJob will create the new PrintedDocument. | 102 // PrintJob will create the new PrintedDocument. |
| 93 owner_->message_loop()->PostTask(FROM_HERE, NewRunnableMethod( | 103 owner_->message_loop()->PostTask(FROM_HERE, NewRunnableMethod( |
| 94 owner_, | 104 owner_, |
| 95 &PrintJobWorkerOwner::GetSettingsDone, | 105 &PrintJobWorkerOwner::GetSettingsDone, |
| 96 printing_context_.settings(), | 106 printing_context_.settings(), |
| 97 result)); | 107 result)); |
| 98 } | 108 } |
| 99 | 109 |
| 110 #if defined(OS_MACOSX) | |
| 111 void PrintJobWorker::GetSettingsWithUI(gfx::NativeWindow parent_window, | |
| 112 int document_page_count, | |
| 113 bool has_selection) { | |
| 114 DCHECK_EQ(ChromeThread::GetMessageLoop(ChromeThread::UI), | |
| 115 MessageLoop::current()); | |
| 116 | |
| 117 PrintingContext::Result result = printing_context_.AskUserForSettings( | |
| 118 parent_window, document_page_count, has_selection); | |
| 119 message_loop()->PostTask(FROM_HERE, NewRunnableMethod( | |
|
pink (ping after 24hrs)
2009/10/13 21:04:51
so this will now run GetSettingsDone on the UI thr
Amanda Walker
2009/10/13 21:20:55
No, it'll run it on the PrintJobWorker thread. me
stuartmorgan
2009/10/13 22:07:43
Right; this is a PostTask rather than a straight c
| |
| 120 this, &PrintJobWorker::GetSettingsDone, result)); | |
| 121 } | |
| 122 #endif | |
| 123 | |
| 100 void PrintJobWorker::StartPrinting(PrintedDocument* new_document) { | 124 void PrintJobWorker::StartPrinting(PrintedDocument* new_document) { |
| 101 DCHECK_EQ(message_loop(), MessageLoop::current()); | 125 DCHECK_EQ(message_loop(), MessageLoop::current()); |
| 102 DCHECK_EQ(page_number_, PageNumber::npos()); | 126 DCHECK_EQ(page_number_, PageNumber::npos()); |
| 103 DCHECK_EQ(document_, new_document); | 127 DCHECK_EQ(document_, new_document); |
| 104 DCHECK(document_.get()); | 128 DCHECK(document_.get()); |
| 105 DCHECK(new_document->settings().Equals(printing_context_.settings())); | 129 DCHECK(new_document->settings().Equals(printing_context_.settings())); |
| 130 #if !defined(OS_MACOSX) | |
|
pink (ping after 24hrs)
2009/10/13 21:04:51
I see below why this the case, but it's 150 lines
stuartmorgan
2009/10/13 22:07:43
I have a header comment on context() explaining wh
| |
| 106 DCHECK(printing_context_.context()); | 131 DCHECK(printing_context_.context()); |
| 132 #endif | |
| 107 if (!document_.get() || page_number_ != PageNumber::npos() || | 133 if (!document_.get() || page_number_ != PageNumber::npos() || |
| 108 document_ != new_document) { | 134 document_ != new_document) { |
| 109 return; | 135 return; |
| 110 } | 136 } |
| 111 | 137 |
| 112 PrintingContext::Result result = | 138 PrintingContext::Result result = |
| 113 printing_context_.NewDocument(document_->name()); | 139 printing_context_.NewDocument(document_->name()); |
| 114 if (result != PrintingContext::OK) { | 140 if (result != PrintingContext::OK) { |
| 115 OnFailure(); | 141 OnFailure(); |
| 116 return; | 142 return; |
| 117 } | 143 } |
| 118 | 144 |
| 119 // Try to print already cached data. It may already have been generated for | 145 // Try to print already cached data. It may already have been generated for |
| 120 // the print preview. | 146 // the print preview. |
| 121 OnNewPage(); | 147 OnNewPage(); |
| 122 // Don't touch this anymore since the instance could be destroyed. It happens | 148 // Don't touch this anymore since the instance could be destroyed. It happens |
| 123 // if all the pages are printed a one sweep and the client doesn't have a | 149 // if all the pages are printed a one sweep and the client doesn't have a |
| 124 // handle to us anymore. There's a timing issue involved between the worker | 150 // handle to us anymore. There's a timing issue involved between the worker |
| 125 // thread and the UI thread. Take no chance. | 151 // thread and the UI thread. Take no chance. |
| 126 } | 152 } |
| 127 | 153 |
| 128 void PrintJobWorker::OnDocumentChanged(PrintedDocument* new_document) { | 154 void PrintJobWorker::OnDocumentChanged(PrintedDocument* new_document) { |
| 129 DCHECK_EQ(message_loop(), MessageLoop::current()); | 155 DCHECK_EQ(message_loop(), MessageLoop::current()); |
| 130 DCHECK_EQ(page_number_, PageNumber::npos()); | 156 DCHECK_EQ(page_number_, PageNumber::npos()); |
| 131 DCHECK(!new_document || | 157 DCHECK(!new_document || |
| 132 new_document->settings().Equals(printing_context_.settings())); | 158 new_document->settings().Equals(printing_context_.settings())); |
| 159 #if !defined(OS_MACOSX) | |
| 133 DCHECK(printing_context_.context()); | 160 DCHECK(printing_context_.context()); |
| 161 #endif | |
| 134 if (page_number_ != PageNumber::npos()) | 162 if (page_number_ != PageNumber::npos()) |
| 135 return; | 163 return; |
| 136 | 164 |
| 137 document_ = new_document; | 165 document_ = new_document; |
| 138 } | 166 } |
| 139 | 167 |
| 140 void PrintJobWorker::OnNewPage() { | 168 void PrintJobWorker::OnNewPage() { |
| 141 if (!document_.get()) { | 169 if (!document_.get()) { |
| 142 // Spurious message. | 170 // Spurious message. |
| 143 return; | 171 return; |
| 144 } | 172 } |
| 145 // message_loop() could return NULL when the print job is cancelled. | 173 // message_loop() could return NULL when the print job is cancelled. |
| 146 DCHECK_EQ(message_loop(), MessageLoop::current()); | 174 DCHECK_EQ(message_loop(), MessageLoop::current()); |
| 175 #if !defined(OS_MACOSX) | |
| 147 DCHECK(printing_context_.context()); | 176 DCHECK(printing_context_.context()); |
| 148 if (!printing_context_.context()) | 177 if (!printing_context_.context()) |
| 149 return; | 178 return; |
| 179 #endif | |
| 150 | 180 |
| 151 if (page_number_ == PageNumber::npos()) { | 181 if (page_number_ == PageNumber::npos()) { |
| 152 // Find first page to print. | 182 // Find first page to print. |
| 153 int page_count = document_->page_count(); | 183 int page_count = document_->page_count(); |
| 154 if (!page_count) { | 184 if (!page_count) { |
| 155 // We still don't know how many pages the document contains. We can't | 185 // We still don't know how many pages the document contains. We can't |
| 156 // start to print the document yet since the header/footer may refer to | 186 // start to print the document yet since the header/footer may refer to |
| 157 // the document's page count. | 187 // the document's page count. |
| 158 return; | 188 return; |
| 159 } | 189 } |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 192 } | 222 } |
| 193 | 223 |
| 194 void PrintJobWorker::DismissDialog() { | 224 void PrintJobWorker::DismissDialog() { |
| 195 printing_context_.DismissDialog(); | 225 printing_context_.DismissDialog(); |
| 196 } | 226 } |
| 197 | 227 |
| 198 void PrintJobWorker::OnDocumentDone() { | 228 void PrintJobWorker::OnDocumentDone() { |
| 199 DCHECK_EQ(message_loop(), MessageLoop::current()); | 229 DCHECK_EQ(message_loop(), MessageLoop::current()); |
| 200 DCHECK_EQ(page_number_, PageNumber::npos()); | 230 DCHECK_EQ(page_number_, PageNumber::npos()); |
| 201 DCHECK(document_.get()); | 231 DCHECK(document_.get()); |
| 232 #if !defined(OS_MACOSX) | |
| 202 DCHECK(printing_context_.context()); | 233 DCHECK(printing_context_.context()); |
| 234 #endif | |
| 203 | 235 |
| 204 if (printing_context_.DocumentDone() != PrintingContext::OK) { | 236 if (printing_context_.DocumentDone() != PrintingContext::OK) { |
| 205 OnFailure(); | 237 OnFailure(); |
| 206 return; | 238 return; |
| 207 } | 239 } |
| 208 | 240 |
| 209 // Tell everyone! | 241 // Tell everyone! |
| 210 NotificationTask* task = new NotificationTask(); | 242 NotificationTask* task = new NotificationTask(); |
| 211 task->Init(owner_, | 243 task->Init(owner_, |
| 212 JobEventDetails::DOC_DONE, | 244 JobEventDetails::DOC_DONE, |
| 213 document_.get(), | 245 document_.get(), |
| 214 NULL); | 246 NULL); |
| 215 owner_->message_loop()->PostTask(FROM_HERE, task); | 247 owner_->message_loop()->PostTask(FROM_HERE, task); |
| 216 | 248 |
| 217 // Makes sure the variables are reinitialized. | 249 // Makes sure the variables are reinitialized. |
| 218 document_ = NULL; | 250 document_ = NULL; |
| 219 } | 251 } |
| 220 | 252 |
| 221 void PrintJobWorker::SpoolPage(PrintedPage& page) { | 253 void PrintJobWorker::SpoolPage(PrintedPage& page) { |
| 222 DCHECK_EQ(message_loop(), MessageLoop::current()); | 254 DCHECK_EQ(message_loop(), MessageLoop::current()); |
| 223 DCHECK_NE(page_number_, PageNumber::npos()); | 255 DCHECK_NE(page_number_, PageNumber::npos()); |
| 256 #if !defined(OS_MACOSX) | |
| 224 DCHECK(printing_context_.context()); | 257 DCHECK(printing_context_.context()); |
| 258 #endif | |
| 225 // Signal everyone that the page is about to be printed. | 259 // Signal everyone that the page is about to be printed. |
| 226 NotificationTask* task = new NotificationTask(); | 260 NotificationTask* task = new NotificationTask(); |
| 227 task->Init(owner_, | 261 task->Init(owner_, |
| 228 JobEventDetails::NEW_PAGE, | 262 JobEventDetails::NEW_PAGE, |
| 229 document_.get(), | 263 document_.get(), |
| 230 &page); | 264 &page); |
| 231 owner_->message_loop()->PostTask(FROM_HERE, task); | 265 owner_->message_loop()->PostTask(FROM_HERE, task); |
| 232 | 266 |
| 233 // Preprocess. | 267 // Preprocess. |
| 234 if (printing_context_.NewPage() != PrintingContext::OK) { | 268 if (printing_context_.NewPage() != PrintingContext::OK) { |
| 235 OnFailure(); | 269 OnFailure(); |
| 236 return; | 270 return; |
| 237 } | 271 } |
| 238 | 272 |
| 273 #if defined(OS_MACOSX) | |
| 274 // Context is only valid between NewPage and PageDone, so we only check here. | |
| 275 DCHECK(printing_context_.context()); | |
| 276 #endif | |
| 239 // Actual printing. | 277 // Actual printing. |
| 240 document_->RenderPrintedPage(page, printing_context_.context()); | 278 document_->RenderPrintedPage(page, printing_context_.context()); |
| 241 | 279 |
| 242 // Postprocess. | 280 // Postprocess. |
| 243 if (printing_context_.PageDone() != PrintingContext::OK) { | 281 if (printing_context_.PageDone() != PrintingContext::OK) { |
| 244 OnFailure(); | 282 OnFailure(); |
| 245 return; | 283 return; |
| 246 } | 284 } |
| 247 | 285 |
| 248 // Signal everyone that the page is printed. | 286 // Signal everyone that the page is printed. |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 279 printing::PrintJobWorker* obj) { | 317 printing::PrintJobWorker* obj) { |
| 280 DCHECK(!owner_.get()); | 318 DCHECK(!owner_.get()); |
| 281 owner_ = obj->owner_; | 319 owner_ = obj->owner_; |
| 282 } | 320 } |
| 283 | 321 |
| 284 void RunnableMethodTraits<printing::PrintJobWorker>::ReleaseCallee( | 322 void RunnableMethodTraits<printing::PrintJobWorker>::ReleaseCallee( |
| 285 printing::PrintJobWorker* obj) { | 323 printing::PrintJobWorker* obj) { |
| 286 DCHECK_EQ(owner_, obj->owner_); | 324 DCHECK_EQ(owner_, obj->owner_); |
| 287 owner_ = NULL; | 325 owner_ = NULL; |
| 288 } | 326 } |
| OLD | NEW |