15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/printing/print_job_worker.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
119ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_process.h"
147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/printing/print_job.h"
1603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/grit/generated_resources.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h"
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/public/browser/render_view_host.h"
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/public/browser/web_contents.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "printing/print_job_constants.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "printing/printed_document.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "printing/printed_page.h"
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "printing/printing_utils.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)namespace printing {
3003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper function to ensure |owner| is valid until at least |callback| returns.
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HoldRefCallback(const scoped_refptr<printing::PrintJobWorkerOwner>& owner,
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const base::Closure& callback) {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  callback.Run();
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass PrintingContextDelegate : public PrintingContext::Delegate {
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci public:
411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  PrintingContextDelegate(int render_process_id, int render_view_id);
421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual ~PrintingContextDelegate();
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual gfx::NativeView GetParentView() OVERRIDE;
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual std::string GetAppLocale() OVERRIDE;
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci private:
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int render_process_id_;
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int render_view_id_;
501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci};
511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciPrintingContextDelegate::PrintingContextDelegate(int render_process_id,
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                 int render_view_id)
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    : render_process_id_(render_process_id),
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      render_view_id_(render_view_id) {
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciPrintingContextDelegate::~PrintingContextDelegate() {
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccigfx::NativeView PrintingContextDelegate::GetParentView() {
621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK_CURRENTLY_ON(BrowserThread::UI);
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  content::RenderViewHost* view =
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      content::RenderViewHost::FromID(render_process_id_, render_view_id_);
651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!view)
661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return NULL;
671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  content::WebContents* wc = content::WebContents::FromRenderViewHost(view);
681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return wc ? wc->GetNativeView() : NULL;
691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccistd::string PrintingContextDelegate::GetAppLocale() {
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return g_browser_process->GetApplicationLocale();
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NotificationCallback(PrintJobWorkerOwner* print_job,
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          JobEventDetails::Type detail_type,
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          PrintedDocument* document,
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          PrintedPage* page) {
79a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  JobEventDetails* details = new JobEventDetails(detail_type, document, page);
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NotificationService::current()->Notify(
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome::NOTIFICATION_PRINT_JOB_EVENT,
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // We know that is is a PrintJob object in this circumstance.
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::Source<PrintJob>(static_cast<PrintJob*>(print_job)),
84a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      content::Details<JobEventDetails>(details));
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}  // namespace
881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciPrintJobWorker::PrintJobWorker(int render_process_id,
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               int render_view_id,
911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               PrintJobWorkerOwner* owner)
9203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    : owner_(owner), thread_("Printing_Worker"), weak_factory_(this) {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The object is created in the IO thread.
9403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DCHECK(owner_->RunsTasksOnCurrentThread());
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  printing_context_delegate_.reset(
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new PrintingContextDelegate(render_process_id, render_view_id));
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  printing_context_ = PrintingContext::Create(printing_context_delegate_.get());
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PrintJobWorker::~PrintJobWorker() {
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The object is normally deleted in the UI thread, but when the user
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // cancels printing or in the case of print preview, the worker is destroyed
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // on the I/O thread.
10503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DCHECK(owner_->RunsTasksOnCurrentThread());
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Stop();
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintJobWorker::SetNewOwner(PrintJobWorkerOwner* new_owner) {
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(page_number_ == PageNumber::npos());
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  owner_ = new_owner;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void PrintJobWorker::GetSettings(
1158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    bool ask_user_for_settings,
1168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    int document_page_count,
1178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    bool has_selection,
1188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    MarginType margin_type) {
11903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(page_number_, PageNumber::npos());
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Recursive task processing is needed for the dialog in case it needs to be
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // destroyed by a task.
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(thestig): This code is wrong. SetNestableTasksAllowed(true) is needed
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // on the thread where the PrintDlgEx is called, and definitely both calls
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // should happen on the same thread. See http://crbug.com/73466
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // MessageLoop::current()->SetNestableTasksAllowed(true);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printing_context_->set_margin_type(margin_type);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When we delegate to a destination, we don't ask the user for settings.
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(mad): Ask the destination for settings.
1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (ask_user_for_settings) {
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserThread::PostTask(
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        BrowserThread::UI, FROM_HERE,
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&HoldRefCallback, make_scoped_refptr(owner_),
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   base::Bind(&PrintJobWorker::GetSettingsWithUI,
1378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                              base::Unretained(this),
1388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                              document_page_count,
1398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                              has_selection)));
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserThread::PostTask(
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        BrowserThread::UI, FROM_HERE,
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&HoldRefCallback, make_scoped_refptr(owner_),
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   base::Bind(&PrintJobWorker::UseDefaultSettings,
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              base::Unretained(this))));
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PrintJobWorker::SetSettings(
15003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    scoped_ptr<base::DictionaryValue> new_settings) {
15103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
154f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      BrowserThread::UI,
155f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      FROM_HERE,
156f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      base::Bind(&HoldRefCallback,
157f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                 make_scoped_refptr(owner_),
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Bind(&PrintJobWorker::UpdatePrintSettings,
159f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                            base::Unretained(this),
16003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                            base::Passed(&new_settings))));
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintJobWorker::UpdatePrintSettings(
16403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    scoped_ptr<base::DictionaryValue> new_settings) {
1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK_CURRENTLY_ON(BrowserThread::UI);
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PrintingContext::Result result =
167f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      printing_context_->UpdatePrintSettings(*new_settings);
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetSettingsDone(result);
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintJobWorker::GetSettingsDone(PrintingContext::Result result) {
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Most PrintingContext functions may start a message loop and process
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // message recursively, so disable recursive task processing.
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(thestig): See above comment. SetNestableTasksAllowed(false) needs to
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be called on the same thread as the previous call.  See
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // http://crbug.com/73466
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // MessageLoop::current()->SetNestableTasksAllowed(false);
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We can't use OnFailure() here since owner_ may not support notifications.
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // PrintJob will create the new PrintedDocument.
18203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  owner_->PostTask(FROM_HERE,
18303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                   base::Bind(&PrintJobWorkerOwner::GetSettingsDone,
18403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                              make_scoped_refptr(owner_),
18503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                              printing_context_->settings(),
18603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                              result));
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void PrintJobWorker::GetSettingsWithUI(
1908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    int document_page_count,
1918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    bool has_selection) {
1920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::UI);
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printing_context_->AskUserForSettings(
1941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      document_page_count,
1951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      has_selection,
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&PrintJobWorker::GetSettingsWithUIDone,
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(this)));
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintJobWorker::GetSettingsWithUIDone(PrintingContext::Result result) {
20103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  PostTask(FROM_HERE,
20203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)           base::Bind(&HoldRefCallback,
20303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                      make_scoped_refptr(owner_),
20403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                      base::Bind(&PrintJobWorker::GetSettingsDone,
20503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                 base::Unretained(this),
20603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                 result)));
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintJobWorker::UseDefaultSettings() {
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PrintingContext::Result result = printing_context_->UseDefaultSettings();
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetSettingsDone(result);
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintJobWorker::StartPrinting(PrintedDocument* new_document) {
21503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(page_number_, PageNumber::npos());
2171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK_EQ(document_.get(), new_document);
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(document_.get());
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!document_.get() || page_number_ != PageNumber::npos() ||
221868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      document_.get() != new_document) {
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 document_name =
226f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      printing::SimplifyDocumentTitle(document_->name());
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (document_name.empty()) {
228f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    document_name = printing::SimplifyDocumentTitle(
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        l10n_util::GetStringUTF16(IDS_DEFAULT_PRINT_DOCUMENT_TITLE));
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PrintingContext::Result result =
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printing_context_->NewDocument(document_name);
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result != PrintingContext::OK) {
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OnFailure();
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Try to print already cached data. It may already have been generated for
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the print preview.
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OnNewPage();
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Don't touch this anymore since the instance could be destroyed. It happens
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // if all the pages are printed a one sweep and the client doesn't have a
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // handle to us anymore. There's a timing issue involved between the worker
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // thread and the UI thread. Take no chance.
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintJobWorker::OnDocumentChanged(PrintedDocument* new_document) {
24803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(page_number_, PageNumber::npos());
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (page_number_ != PageNumber::npos())
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  document_ = new_document;
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintJobWorker::OnNewPage() {
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!document_.get())  // Spurious message.
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // message_loop() could return NULL when the print job is cancelled.
26203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (page_number_ == PageNumber::npos()) {
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Find first page to print.
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int page_count = document_->page_count();
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!page_count) {
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // We still don't know how many pages the document contains. We can't
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // start to print the document yet since the header/footer may refer to
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // the document's page count.
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We have enough information to initialize page_number_.
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    page_number_.Init(document_->settings(), page_count);
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_NE(page_number_, PageNumber::npos());
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (true) {
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Is the page available?
280f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    scoped_refptr<PrintedPage> page = document_->GetPage(page_number_.ToInt());
2811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (!page.get()) {
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // We need to wait for the page to be available.
28390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::MessageLoop::current()->PostDelayedTask(
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          FROM_HERE,
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::Bind(&PrintJobWorker::OnNewPage, weak_factory_.GetWeakPtr()),
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::TimeDelta::FromMilliseconds(500));
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The page is there, print it.
290868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    SpoolPage(page.get());
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ++page_number_;
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (page_number_ == PageNumber::npos()) {
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      OnDocumentDone();
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Don't touch this anymore since the instance could be destroyed.
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintJobWorker::Cancel() {
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This is the only function that can be called from any thread.
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printing_context_->Cancel();
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Cannot touch any member variable since we don't know in which thread
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // context we run.
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool PrintJobWorker::IsRunning() const {
30803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return thread_.IsRunning();
30903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
31003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
31103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool PrintJobWorker::PostTask(const tracked_objects::Location& from_here,
31203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                              const base::Closure& task) {
3131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (task_runner_.get())
31403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return task_runner_->PostTask(from_here, task);
31503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return false;
31603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
31703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
31803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void PrintJobWorker::StopSoon() {
31903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  thread_.StopSoon();
32003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
32103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
32203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void PrintJobWorker::Stop() {
32303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  thread_.Stop();
32403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
32503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
32603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool PrintJobWorker::Start() {
32703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  bool result = thread_.Start();
32803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  task_runner_ = thread_.task_runner();
32903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return result;
33003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
33103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintJobWorker::OnDocumentDone() {
33303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(page_number_, PageNumber::npos());
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(document_.get());
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (printing_context_->DocumentDone() != PrintingContext::OK) {
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OnFailure();
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  owner_->PostTask(FROM_HERE,
3431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                   base::Bind(&NotificationCallback,
34403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                              make_scoped_refptr(owner_),
34503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                              JobEventDetails::DOC_DONE,
34603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                              document_,
34703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                              scoped_refptr<PrintedPage>()));
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Makes sure the variables are reinitialized.
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  document_ = NULL;
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintJobWorker::SpoolPage(PrintedPage* page) {
35403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_NE(page_number_, PageNumber::npos());
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Signal everyone that the page is about to be printed.
35803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  owner_->PostTask(FROM_HERE,
3591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                   base::Bind(&NotificationCallback,
36003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                              make_scoped_refptr(owner_),
36103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                              JobEventDetails::NEW_PAGE,
36203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                              document_,
36303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                              make_scoped_refptr(page)));
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Preprocess.
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (printing_context_->NewPage() != PrintingContext::OK) {
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OnFailure();
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Actual printing.
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) || defined(OS_MACOSX)
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  document_->RenderPrintedPage(*page, printing_context_->context());
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX)
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  document_->RenderPrintedPage(*page, printing_context_.get());
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Postprocess.
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (printing_context_->PageDone() != PrintingContext::OK) {
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OnFailure();
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Signal everyone that the page is printed.
38503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  owner_->PostTask(FROM_HERE,
3861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                   base::Bind(&NotificationCallback,
38703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                              make_scoped_refptr(owner_),
38803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                              JobEventDetails::PAGE_DONE,
38903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                              document_,
39003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                              make_scoped_refptr(page)));
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintJobWorker::OnFailure() {
39403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DCHECK(task_runner_->RunsTasksOnCurrentThread());
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We may loose our last reference by broadcasting the FAILED event.
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<PrintJobWorkerOwner> handle(owner_);
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  owner_->PostTask(FROM_HERE,
4001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                   base::Bind(&NotificationCallback,
40103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                              make_scoped_refptr(owner_),
40203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                              JobEventDetails::FAILED,
40303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                              document_,
40403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                              scoped_refptr<PrintedPage>()));
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Cancel();
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Makes sure the variables are reinitialized.
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  document_ = NULL;
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  page_number_ = PageNumber::npos();
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace printing
413