| 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_view_manager.h" | 5 #include "chrome/browser/printing/print_view_manager.h" |
| 6 | 6 |
| 7 #include "app/l10n_util.h" | 7 #include "app/l10n_util.h" |
| 8 #include "chrome/browser/browser_process.h" | 8 #include "chrome/browser/browser_process.h" |
| 9 #include "chrome/browser/printing/print_job.h" | 9 #include "chrome/browser/printing/print_job.h" |
| 10 #include "chrome/browser/printing/print_job_manager.h" | 10 #include "chrome/browser/printing/print_job_manager.h" |
| 11 #include "chrome/browser/printing/printed_document.h" | 11 #include "chrome/browser/printing/printed_document.h" |
| 12 #include "chrome/browser/printing/printer_query.h" | 12 #include "chrome/browser/printing/printer_query.h" |
| 13 #include "chrome/browser/renderer_host/render_view_host.h" | 13 #include "chrome/browser/renderer_host/render_view_host.h" |
| 14 #include "chrome/browser/tab_contents/navigation_entry.h" | 14 #include "chrome/browser/tab_contents/navigation_entry.h" |
| 15 #include "chrome/browser/tab_contents/tab_contents.h" | 15 #include "chrome/browser/tab_contents/tab_contents.h" |
| 16 #include "chrome/common/gfx/emf.h" | 16 #include "chrome/common/gfx/emf.h" |
| 17 #include "chrome/common/notification_service.h" | 17 #include "chrome/common/notification_service.h" |
| 18 #include "chrome/common/render_messages.h" | 18 #include "chrome/common/render_messages.h" |
| 19 #include "grit/generated_resources.h" | 19 #include "grit/generated_resources.h" |
| 20 | 20 |
| 21 using base::TimeDelta; | 21 using base::TimeDelta; |
| 22 | 22 |
| 23 namespace printing { | 23 namespace printing { |
| 24 | 24 |
| 25 PrintViewManager::PrintViewManager(TabContents& owner) | 25 PrintViewManager::PrintViewManager(TabContents& owner) |
| 26 : owner_(owner), | 26 : owner_(owner), |
| 27 waiting_to_print_(false), | 27 waiting_to_print_(false), |
| 28 printing_succeeded_(false), |
| 28 inside_inner_message_loop_(false) { | 29 inside_inner_message_loop_(false) { |
| 29 } | 30 } |
| 30 | 31 |
| 31 PrintViewManager::~PrintViewManager() { | 32 PrintViewManager::~PrintViewManager() { |
| 32 DisconnectFromCurrentPrintJob(); | 33 DisconnectFromCurrentPrintJob(); |
| 33 } | 34 } |
| 34 | 35 |
| 35 void PrintViewManager::Stop() { | 36 void PrintViewManager::Stop() { |
| 36 // Cancel the current job, wait for the worker to finish. | 37 // Cancel the current job, wait for the worker to finish. |
| 37 TerminatePrintJob(true); | 38 TerminatePrintJob(true); |
| 38 } | 39 } |
| 39 | 40 |
| 40 bool PrintViewManager::OnRenderViewGone(RenderViewHost* render_view_host) { | 41 bool PrintViewManager::OnRenderViewGone(RenderViewHost* render_view_host) { |
| 41 if (!print_job_.get()) | 42 if (!print_job_.get()) |
| 42 return true; | 43 return true; |
| 43 | 44 |
| 44 if (render_view_host != owner_.render_view_host()) | 45 if (render_view_host != owner_.render_view_host()) |
| 45 return false; | 46 return false; |
| 46 | 47 |
| 47 scoped_refptr<PrintedDocument> document(print_job_->document()); | 48 scoped_refptr<PrintedDocument> document(print_job_->document()); |
| 48 if (document) { | 49 if (document) { |
| 49 // If IsComplete() returns false, the document isn't completely renderered. | 50 // If IsComplete() returns false, the document isn't completely rendered. |
| 50 // Since our renderer is gone, there's nothing to do, cancel it. Otherwise, | 51 // Since our renderer is gone, there's nothing to do, cancel it. Otherwise, |
| 51 // the print job may finish without problem. | 52 // the print job may finish without problem. |
| 52 TerminatePrintJob(!document->IsComplete()); | 53 TerminatePrintJob(!document->IsComplete()); |
| 53 } | 54 } |
| 54 return true; | 55 return true; |
| 55 } | 56 } |
| 56 | 57 |
| 57 void PrintViewManager::DidGetPrintedPagesCount(int cookie, int number_pages) { | 58 void PrintViewManager::DidGetPrintedPagesCount(int cookie, int number_pages) { |
| 58 DCHECK_GT(cookie, 0); | 59 DCHECK_GT(cookie, 0); |
| 59 if (!OpportunisticallyCreatePrintJob(cookie)) | 60 if (!OpportunisticallyCreatePrintJob(cookie)) |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 141 NOTREACHED(); | 142 NOTREACHED(); |
| 142 break; | 143 break; |
| 143 } | 144 } |
| 144 } | 145 } |
| 145 } | 146 } |
| 146 | 147 |
| 147 void PrintViewManager::OnNotifyPrintJobEvent( | 148 void PrintViewManager::OnNotifyPrintJobEvent( |
| 148 const JobEventDetails& event_details) { | 149 const JobEventDetails& event_details) { |
| 149 switch (event_details.type()) { | 150 switch (event_details.type()) { |
| 150 case JobEventDetails::FAILED: { | 151 case JobEventDetails::FAILED: { |
| 151 // TODO(maruel): bug 1123882 Show some kind of notification. | |
| 152 TerminatePrintJob(true); | 152 TerminatePrintJob(true); |
| 153 break; | 153 break; |
| 154 } | 154 } |
| 155 case JobEventDetails::USER_INIT_DONE: | 155 case JobEventDetails::USER_INIT_DONE: |
| 156 case JobEventDetails::DEFAULT_INIT_DONE: | 156 case JobEventDetails::DEFAULT_INIT_DONE: |
| 157 case JobEventDetails::USER_INIT_CANCELED: { | 157 case JobEventDetails::USER_INIT_CANCELED: { |
| 158 NOTREACHED(); | 158 NOTREACHED(); |
| 159 break; | 159 break; |
| 160 } | 160 } |
| 161 case JobEventDetails::ALL_PAGES_REQUESTED: { | 161 case JobEventDetails::ALL_PAGES_REQUESTED: { |
| 162 ShouldQuitFromInnerMessageLoop(); | 162 ShouldQuitFromInnerMessageLoop(); |
| 163 break; | 163 break; |
| 164 } | 164 } |
| 165 case JobEventDetails::NEW_DOC: | 165 case JobEventDetails::NEW_DOC: |
| 166 case JobEventDetails::NEW_PAGE: | 166 case JobEventDetails::NEW_PAGE: |
| 167 case JobEventDetails::PAGE_DONE: { | 167 case JobEventDetails::PAGE_DONE: { |
| 168 // Don't care about the actual printing process. | 168 // Don't care about the actual printing process. |
| 169 break; | 169 break; |
| 170 } | 170 } |
| 171 case JobEventDetails::DOC_DONE: { | 171 case JobEventDetails::DOC_DONE: { |
| 172 waiting_to_print_ = false; | 172 waiting_to_print_ = false; |
| 173 break; | 173 break; |
| 174 } | 174 } |
| 175 case JobEventDetails::JOB_DONE: { | 175 case JobEventDetails::JOB_DONE: { |
| 176 // Printing is done, we don't need it anymore. | 176 // Printing is done, we don't need it anymore. |
| 177 // print_job_->is_job_pending() may still be true, depending on the order | 177 // print_job_->is_job_pending() may still be true, depending on the order |
| 178 // of object registration. | 178 // of object registration. |
| 179 printing_succeeded_ = true; |
| 179 ReleasePrintJob(); | 180 ReleasePrintJob(); |
| 180 break; | 181 break; |
| 181 } | 182 } |
| 182 default: { | 183 default: { |
| 183 NOTREACHED(); | 184 NOTREACHED(); |
| 184 break; | 185 break; |
| 185 } | 186 } |
| 186 } | 187 } |
| 187 } | 188 } |
| 188 | 189 |
| 189 bool PrintViewManager::RenderAllMissingPagesNow() { | 190 bool PrintViewManager::RenderAllMissingPagesNow() { |
| 190 if (!print_job_.get() || !print_job_->is_job_pending()) { | 191 if (!print_job_.get() || !print_job_->is_job_pending()) { |
| 191 DCHECK_EQ(waiting_to_print_, false); | 192 DCHECK_EQ(waiting_to_print_, false); |
| 192 return false; | 193 return false; |
| 193 } | 194 } |
| 194 | 195 |
| 195 // We can't print if there is no renderer. | 196 // We can't print if there is no renderer. |
| 196 if (!owner_.render_view_host() || | 197 if (!owner_.render_view_host() || |
| 197 !owner_.render_view_host()->IsRenderViewLive()) { | 198 !owner_.render_view_host()->IsRenderViewLive()) { |
| 198 waiting_to_print_ = false; | 199 waiting_to_print_ = false; |
| 199 return false; | 200 return false; |
| 200 } | 201 } |
| 201 | 202 |
| 202 // Is the document already complete? | 203 // Is the document already complete? |
| 203 if (print_job_->document() && print_job_->document()->IsComplete()) { | 204 if (print_job_->document() && print_job_->document()->IsComplete()) { |
| 204 waiting_to_print_ = false; | 205 waiting_to_print_ = false; |
| 206 printing_succeeded_ = true; |
| 205 return true; | 207 return true; |
| 206 } | 208 } |
| 207 | 209 |
| 208 // TabContents is either dying or a second consecutive request to print | 210 // TabContents is either dying or a second consecutive request to print |
| 209 // happened before the first had time to finish. We need to render all the | 211 // happened before the first had time to finish. We need to render all the |
| 210 // pages in an hurry if a print_job_ is still pending. No need to wait for it | 212 // pages in an hurry if a print_job_ is still pending. No need to wait for it |
| 211 // to actually spool the pages, only to have the renderer generate them. Run | 213 // to actually spool the pages, only to have the renderer generate them. Run |
| 212 // a message loop until we get our signal that the print job is satisfied. | 214 // a message loop until we get our signal that the print job is satisfied. |
| 213 // PrintJob will send a ALL_PAGES_REQUESTED after having received all the | 215 // PrintJob will send a ALL_PAGES_REQUESTED after having received all the |
| 214 // pages it needs. MessageLoop::current()->Quit() will be called as soon as | 216 // pages it needs. MessageLoop::current()->Quit() will be called as soon as |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 259 // view and switch to it, initialize the printer and show the print dialog. | 261 // view and switch to it, initialize the printer and show the print dialog. |
| 260 DCHECK(!print_job_.get()); | 262 DCHECK(!print_job_.get()); |
| 261 DCHECK(job); | 263 DCHECK(job); |
| 262 if (!job) | 264 if (!job) |
| 263 return false; | 265 return false; |
| 264 | 266 |
| 265 print_job_ = new PrintJob(); | 267 print_job_ = new PrintJob(); |
| 266 print_job_->Initialize(job, this); | 268 print_job_->Initialize(job, this); |
| 267 registrar_.Add(this, NotificationType::PRINT_JOB_EVENT, | 269 registrar_.Add(this, NotificationType::PRINT_JOB_EVENT, |
| 268 Source<PrintJob>(print_job_.get())); | 270 Source<PrintJob>(print_job_.get())); |
| 271 printing_succeeded_ = false; |
| 269 return true; | 272 return true; |
| 270 } | 273 } |
| 271 | 274 |
| 272 void PrintViewManager::DisconnectFromCurrentPrintJob() { | 275 void PrintViewManager::DisconnectFromCurrentPrintJob() { |
| 273 // Make sure all the necessary rendered page are done. Don't bother with the | 276 // Make sure all the necessary rendered page are done. Don't bother with the |
| 274 // return value. | 277 // return value. |
| 275 bool result = RenderAllMissingPagesNow(); | 278 bool result = RenderAllMissingPagesNow(); |
| 276 | 279 |
| 277 // Verify that assertion. | 280 // Verify that assertion. |
| 278 if (print_job_.get() && | 281 if (print_job_.get() && |
| 279 print_job_->document() && | 282 print_job_->document() && |
| 280 !print_job_->document()->IsComplete()) { | 283 !print_job_->document()->IsComplete()) { |
| 281 DCHECK(!result); | 284 DCHECK(!result); |
| 282 // That failed. | 285 // That failed. |
| 283 TerminatePrintJob(true); | 286 TerminatePrintJob(true); |
| 284 } else { | 287 } else { |
| 285 // DO NOT wait for the job to finish. | 288 // DO NOT wait for the job to finish. |
| 286 ReleasePrintJob(); | 289 ReleasePrintJob(); |
| 287 } | 290 } |
| 288 } | 291 } |
| 289 | 292 |
| 293 void PrintViewManager::PrintingDone(bool success) { |
| 294 if (print_job_.get()) { |
| 295 owner_.PrintingDone(print_job_->cookie(), success); |
| 296 } |
| 297 } |
| 298 |
| 290 void PrintViewManager::TerminatePrintJob(bool cancel) { | 299 void PrintViewManager::TerminatePrintJob(bool cancel) { |
| 291 if (!print_job_.get()) | 300 if (!print_job_.get()) |
| 292 return; | 301 return; |
| 293 | 302 |
| 294 if (cancel) { | 303 if (cancel) { |
| 295 // We don't need the EMF data anymore because the printing is canceled. | 304 // We don't need the EMF data anymore because the printing is canceled. |
| 296 print_job_->Cancel(); | 305 print_job_->Cancel(); |
| 297 waiting_to_print_ = false; | 306 waiting_to_print_ = false; |
| 298 inside_inner_message_loop_ = false; | 307 inside_inner_message_loop_ = false; |
| 299 } else { | 308 } else { |
| 300 DCHECK(!inside_inner_message_loop_); | 309 DCHECK(!inside_inner_message_loop_); |
| 301 DCHECK(!print_job_->document() || print_job_->document()->IsComplete() || | 310 DCHECK(!print_job_->document() || print_job_->document()->IsComplete() || |
| 302 !waiting_to_print_); | 311 !waiting_to_print_); |
| 303 | 312 |
| 304 // TabContents is either dying or navigating elsewhere. We need to render | 313 // TabContents is either dying or navigating elsewhere. We need to render |
| 305 // all the pages in an hurry if a print job is still pending. This does the | 314 // all the pages in an hurry if a print job is still pending. This does the |
| 306 // trick since it runs a blocking message loop: | 315 // trick since it runs a blocking message loop: |
| 307 print_job_->Stop(); | 316 print_job_->Stop(); |
| 308 } | 317 } |
| 309 ReleasePrintJob(); | 318 ReleasePrintJob(); |
| 310 } | 319 } |
| 311 | 320 |
| 312 void PrintViewManager::ReleasePrintJob() { | 321 void PrintViewManager::ReleasePrintJob() { |
| 313 DCHECK_EQ(waiting_to_print_, false); | 322 DCHECK_EQ(waiting_to_print_, false); |
| 314 if (!print_job_.get()) | 323 if (!print_job_.get()) |
| 315 return; | 324 return; |
| 316 | 325 |
| 326 PrintingDone(printing_succeeded_); |
| 327 |
| 317 registrar_.Remove(this, NotificationType::PRINT_JOB_EVENT, | 328 registrar_.Remove(this, NotificationType::PRINT_JOB_EVENT, |
| 318 Source<PrintJob>(print_job_.get())); | 329 Source<PrintJob>(print_job_.get())); |
| 319 print_job_->DisconnectSource(); | 330 print_job_->DisconnectSource(); |
| 320 // Don't close the worker thread. | 331 // Don't close the worker thread. |
| 321 print_job_ = NULL; | 332 print_job_ = NULL; |
| 322 } | 333 } |
| 323 | 334 |
| 324 void PrintViewManager::PrintNowInternal() { | 335 void PrintViewManager::PrintNowInternal() { |
| 325 DCHECK(waiting_to_print_); | 336 DCHECK(waiting_to_print_); |
| 326 | 337 |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 392 return false; | 403 return false; |
| 393 } | 404 } |
| 394 | 405 |
| 395 // Settings are already loaded. Go ahead. This will set | 406 // Settings are already loaded. Go ahead. This will set |
| 396 // print_job_->is_job_pending() to true. | 407 // print_job_->is_job_pending() to true. |
| 397 print_job_->StartPrinting(); | 408 print_job_->StartPrinting(); |
| 398 return true; | 409 return true; |
| 399 } | 410 } |
| 400 | 411 |
| 401 } // namespace printing | 412 } // namespace printing |
| OLD | NEW |