print_job.h revision 3345a6884c488ff3a535c2c9acdd33d74b37e311
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 3// found in the LICENSE file. 4 5#ifndef CHROME_BROWSER_PRINTING_PRINT_JOB_H_ 6#define CHROME_BROWSER_PRINTING_PRINT_JOB_H_ 7#pragma once 8 9#include "base/basictypes.h" 10#include "base/message_loop.h" 11#include "base/scoped_ptr.h" 12#include "chrome/browser/printing/print_job_worker_owner.h" 13#include "chrome/common/notification_observer.h" 14#include "chrome/common/notification_registrar.h" 15#include "gfx/native_widget_types.h" 16 17class GURL; 18class Thread; 19 20namespace printing { 21 22// See definition below. 23class JobEventDetails; 24 25class PrintedDocument; 26class PrintedPage; 27class PrintedPagesSource; 28class PrintJobWorker; 29class PrinterQuery; 30 31// Manages the print work for a specific document. Talks to the printer through 32// PrintingContext though PrintJob::Worker. Hides access to PrintingContext in a 33// worker thread so the caller never blocks. PrintJob will send notifications on 34// any state change. While printing, the PrintJobManager instance keeps a 35// reference to the job to be sure it is kept alive. All the code in this class 36// runs in the UI thread. 37class PrintJob : public PrintJobWorkerOwner, 38 public NotificationObserver, 39 public MessageLoop::DestructionObserver { 40 public: 41 // Create a empty PrintJob. When initializing with this constructor, 42 // post-constructor initialization must be done with Initialize(). 43 PrintJob(); 44 45 // Grabs the ownership of the PrintJobWorker from another job, which is 46 // usually a PrinterQuery. 47 void Initialize(PrintJobWorkerOwner* job, PrintedPagesSource* source); 48 49 // NotificationObserver 50 virtual void Observe(NotificationType type, 51 const NotificationSource& source, 52 const NotificationDetails& details); 53 54 // PrintJobWorkerOwner 55 virtual void GetSettingsDone(const PrintSettings& new_settings, 56 PrintingContext::Result result); 57 virtual PrintJobWorker* DetachWorker(PrintJobWorkerOwner* new_owner); 58 virtual MessageLoop* message_loop() { return ui_message_loop_; } 59 virtual const PrintSettings& settings() const { return settings_; } 60 virtual int cookie() const; 61 62 // DestructionObserver 63 virtual void WillDestroyCurrentMessageLoop(); 64 65 // Starts the actual printing. Signals the worker that it should begin to 66 // spool as soon as data is available. 67 void StartPrinting(); 68 69 // Waits for the worker thread to finish its queued tasks and disconnects the 70 // delegate object. The PrintJobManager will remove it reference. This may 71 // have the side-effect of destroying the object if the caller doesn't have a 72 // handle to the object. 73 void Stop(); 74 75 // Cancels printing job and stops the worker thread. Takes effect immediately. 76 void Cancel(); 77 78 // Synchronously wait for the job to finish. It is mainly useful when the 79 // process is about to be shut down and we're waiting for the spooler to eat 80 // our data. 81 bool FlushJob(int timeout_ms); 82 83 // Disconnects the PrintedPage source (PrintedPagesSource). It is done when 84 // the source is being destroyed. 85 void DisconnectSource(); 86 87 // Returns true if the print job is pending, i.e. between a StartPrinting() 88 // and the end of the spooling. 89 bool is_job_pending() const; 90 91 // Returns true if the Print... dialog box is currently displayed. 92 bool is_print_dialog_box_shown() const; 93 94 // Access the current printed document. Warning: may be NULL. 95 PrintedDocument* document() const; 96 97 protected: 98 virtual ~PrintJob(); 99 100 private: 101 // Updates document_ to a new instance. 102 void UpdatePrintedDocument(PrintedDocument* new_document); 103 104 // Processes a NOTIFY_PRINT_JOB_EVENT notification. 105 void OnNotifyPrintJobEvent(const JobEventDetails& event_details); 106 107 // Releases the worker thread by calling Stop(), then broadcasts a JOB_DONE 108 // notification. 109 void OnDocumentDone(); 110 111 // Terminates the worker thread in a very controlled way, to work around any 112 // eventual deadlock. 113 void ControlledWorkerShutdown(); 114 115 NotificationRegistrar registrar_; 116 117 // Main message loop reference. Used to send notifications in the right 118 // thread. 119 MessageLoop* const ui_message_loop_; 120 121 // Source that generates the PrintedPage's (i.e. a TabContents). It will be 122 // set back to NULL if the source is deleted before this object. 123 PrintedPagesSource* source_; 124 125 // All the UI is done in a worker thread because many Win32 print functions 126 // are blocking and enters a message loop without your consent. There is one 127 // worker thread per print job. 128 scoped_ptr<PrintJobWorker> worker_; 129 130 // Cache of the print context settings for access in the UI thread. 131 PrintSettings settings_; 132 133 // The printed document. 134 scoped_refptr<PrintedDocument> document_; 135 136 // Is the worker thread printing. 137 bool is_job_pending_; 138 139 // Is the Print... dialog box currently shown. 140 bool is_print_dialog_box_shown_; 141 142 // Is Canceling? If so, try to not cause recursion if on FAILED notification, 143 // the notified calls Cancel() again. 144 bool is_canceling_; 145 146 DISALLOW_COPY_AND_ASSIGN(PrintJob); 147}; 148 149// Details for a NOTIFY_PRINT_JOB_EVENT notification. The members may be NULL. 150class JobEventDetails : public base::RefCountedThreadSafe<JobEventDetails> { 151 public: 152 // Event type. 153 enum Type { 154 // Print... dialog box has been closed with OK button. 155 USER_INIT_DONE, 156 157 // Print... dialog box has been closed with CANCEL button. 158 USER_INIT_CANCELED, 159 160 // An automated initialization has been done, e.g. Init(false, NULL). 161 DEFAULT_INIT_DONE, 162 163 // A new document started printing. 164 NEW_DOC, 165 166 // A new page started printing. 167 NEW_PAGE, 168 169 // A page is done printing. 170 PAGE_DONE, 171 172 // A document is done printing. The worker thread is still alive. Warning: 173 // not a good moment to release the handle to PrintJob. 174 DOC_DONE, 175 176 // The worker thread is finished. A good moment to release the handle to 177 // PrintJob. 178 JOB_DONE, 179 180 // All missing pages have been requested. 181 ALL_PAGES_REQUESTED, 182 183 // An error occured. Printing is canceled. 184 FAILED, 185 }; 186 187 JobEventDetails(Type type, PrintedDocument* document, PrintedPage* page); 188 189 // Getters. 190 PrintedDocument* document() const; 191 PrintedPage* page() const; 192 Type type() const { 193 return type_; 194 } 195 196 private: 197 friend class base::RefCountedThreadSafe<JobEventDetails>; 198 199 ~JobEventDetails(); 200 201 scoped_refptr<PrintedDocument> document_; 202 scoped_refptr<PrintedPage> page_; 203 const Type type_; 204 205 DISALLOW_COPY_AND_ASSIGN(JobEventDetails); 206}; 207 208} // namespace printing 209 210#endif // CHROME_BROWSER_PRINTING_PRINT_JOB_H_ 211