diff options
author | jhawkins@chromium.org <jhawkins@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-06 22:21:17 +0000 |
---|---|---|
committer | jhawkins@chromium.org <jhawkins@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-06 22:21:17 +0000 |
commit | 51e8d9357bb1738b462baa48da9f86e016f936ce (patch) | |
tree | 463241b65d5c3993992f62e313d49aebce220bfc /printing | |
parent | c27a5ed3f25971f028dd1baedd73efb59497ceeb (diff) | |
download | chromium_src-51e8d9357bb1738b462baa48da9f86e016f936ce.zip chromium_src-51e8d9357bb1738b462baa48da9f86e016f936ce.tar.gz chromium_src-51e8d9357bb1738b462baa48da9f86e016f936ce.tar.bz2 |
Printing: Convert PrintingContext into an interface implemented by the separate
platforms.
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/3610013
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@61714 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'printing')
-rw-r--r-- | printing/emf_win_unittest.cc | 16 | ||||
-rw-r--r-- | printing/printing.gyp | 4 | ||||
-rw-r--r-- | printing/printing_context.cc | 31 | ||||
-rw-r--r-- | printing/printing_context.h | 154 | ||||
-rw-r--r-- | printing/printing_context_cairo.cc | 50 | ||||
-rw-r--r-- | printing/printing_context_cairo.h | 39 | ||||
-rw-r--r-- | printing/printing_context_mac.h | 55 | ||||
-rw-r--r-- | printing/printing_context_mac.mm | 70 | ||||
-rw-r--r-- | printing/printing_context_win.cc | 103 | ||||
-rw-r--r-- | printing/printing_context_win.h | 97 | ||||
-rw-r--r-- | printing/printing_context_win_unittest.cc | 23 | ||||
-rw-r--r-- | printing/printing_test.h | 4 |
12 files changed, 400 insertions, 246 deletions
diff --git a/printing/emf_win_unittest.cc b/printing/emf_win_unittest.cc index 4c1247b..bfd56b8 100644 --- a/printing/emf_win_unittest.cc +++ b/printing/emf_win_unittest.cc @@ -13,6 +13,7 @@ #include "base/file_util.h" #include "base/path_service.h" #include "base/scoped_handle_win.h" +#include "base/scoped_ptr.h" #include "printing/printing_context.h" #include "testing/gtest/include/gtest/gtest.h" @@ -75,8 +76,9 @@ TEST_F(EmfPrintingTest, Enumerate) { settings.set_device_name(L"UnitTest Printer"); // Initialize it. - printing::PrintingContext context; - EXPECT_EQ(context.InitWithSettings(settings), printing::PrintingContext::OK); + scoped_ptr<printing::PrintingContext> context( + printing::PrintingContext::Create()); + EXPECT_EQ(context->InitWithSettings(settings), printing::PrintingContext::OK); FilePath emf_file; EXPECT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &emf_file)); @@ -95,10 +97,10 @@ TEST_F(EmfPrintingTest, Enumerate) { // unit_test, printing::PrintingContext automatically dumps its files to the // current directory. // TODO(maruel): Clean the .PRN file generated in current directory. - context.NewDocument(L"EmfTest.Enumerate"); - context.NewPage(); + context->NewDocument(L"EmfTest.Enumerate"); + context->NewPage(); // Process one at a time. - printing::Emf::Enumerator emf_enum(emf, context.context(), + printing::Emf::Enumerator emf_enum(emf, context->context(), &emf.GetBounds().ToRECT()); for (printing::Emf::Enumerator::const_iterator itr = emf_enum.begin(); itr != emf_enum.end(); @@ -111,8 +113,8 @@ TEST_F(EmfPrintingTest, Enumerate) { EXPECT_TRUE(itr->SafePlayback(NULL)) << " index: " << index << " type: " << itr->record()->iType; } - context.PageDone(); - context.DocumentDone(); + context->PageDone(); + context->DocumentDone(); } // Disabled if no "UnitTest printer" exists. diff --git a/printing/printing.gyp b/printing/printing.gyp index 050f830..be84caf 100644 --- a/printing/printing.gyp +++ b/printing/printing.gyp @@ -52,8 +52,12 @@ 'printed_page.h', 'printed_pages_source.h', 'printing_context.h', + 'printing_context.cc', + 'printing_context_cairo.h', 'printing_context_cairo.cc', + 'printing_context_mac.h', 'printing_context_mac.mm', + 'printing_context_win.h', 'printing_context_win.cc', 'units.cc', 'units.h', diff --git a/printing/printing_context.cc b/printing/printing_context.cc new file mode 100644 index 0000000..933906d --- /dev/null +++ b/printing/printing_context.cc @@ -0,0 +1,31 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "printing/printing_context.h" + +namespace printing { + +PrintingContext::PrintingContext() + : dialog_box_dismissed_(false), + in_print_job_(false), + abort_printing_(false) { +} + +PrintingContext::~PrintingContext() { +} + +void PrintingContext::ResetSettings() { + ReleaseContext(); + settings_.Clear(); + in_print_job_ = false; + dialog_box_dismissed_ = false; + abort_printing_ = false; +} + +PrintingContext::Result PrintingContext::OnError() { + ResetSettings(); + return abort_printing_ ? CANCEL : FAILED; +} + +} // namespace printing diff --git a/printing/printing_context.h b/printing/printing_context.h index 39e118c..6c9daaa 100644 --- a/printing/printing_context.h +++ b/printing/printing_context.h @@ -5,40 +5,21 @@ #ifndef PRINTING_PRINTING_CONTEXT_H_ #define PRINTING_PRINTING_CONTEXT_H_ -#include "build/build_config.h" - -#if defined(OS_WIN) -#include <ocidl.h> -#include <commdlg.h> -#endif - #include <string> #include "base/basictypes.h" #include "base/callback.h" -#if !(defined(OS_WIN) || defined(OS_MACOSX)) -// TODO(port) Remove after implementing PrintingContext::context() -#include "base/logging.h" -#endif #include "base/scoped_ptr.h" #include "base/string16.h" #include "gfx/native_widget_types.h" #include "printing/print_settings.h" -#if defined(OS_MACOSX) -#include "base/scoped_cftyperef.h" -#ifdef __OBJC__ -@class NSPrintInfo; -#else -class NSPrintInfo; -#endif // __OBJC__ -#endif // OS_MACOSX - namespace printing { -// Describe the user selected printing context for Windows. This includes the -// OS-dependent UI to ask the user about the print settings. This class directly -// talk to the printer and manages the document and pages breaks. +// An abstraction of a printer context, implemented by objects that describe the +// user selected printing context. This includes the OS-dependent UI to ask the +// user about the print settings. Concrete implementations directly talk to the +// printer and manage the document and page breaks. class PrintingContext { public: // Tri-state result for user behavior-dependent functions. @@ -48,8 +29,7 @@ class PrintingContext { FAILED, }; - PrintingContext(); - ~PrintingContext(); + virtual ~PrintingContext(); // Callback of AskUserForSettings, used to notify the PrintJobWorker when // print settings are available. @@ -59,42 +39,17 @@ class PrintingContext { // context with the select device settings. The result of the call is returned // in the callback. This is necessary for Linux, which only has an // asynchronous printing API. - void AskUserForSettings(gfx::NativeView parent_view, - int max_pages, - bool has_selection, - PrintSettingsCallback* callback); - -#if defined(OS_WIN) && defined(UNIT_TEST) - // Sets a fake PrintDlgEx function pointer in tests. - void SetPrintDialog(HRESULT (__stdcall *print_dialog_func)(LPPRINTDLGEX)) { - print_dialog_func_ = print_dialog_func; - } -#endif - -#if defined(OS_WIN) - // Allocates the HDC for a specific DEVMODE. - static bool AllocateContext(const std::wstring& printer_name, - const DEVMODE* dev_mode, - gfx::NativeDrawingContext* context); - - // Retrieves the content of a GetPrinter call. - static void GetPrinterHelper(HANDLE printer, int level, - scoped_array<uint8>* buffer); -#endif + virtual void AskUserForSettings(gfx::NativeView parent_view, + int max_pages, + bool has_selection, + PrintSettingsCallback* callback) = 0; // Selects the user's default printer and format. Updates the context with the // default device settings. - Result UseDefaultSettings(); - - void SetUseOverlays(bool use_overlays) { - settings_.use_overlays = use_overlays; - } + virtual Result UseDefaultSettings() = 0; // Initializes with predefined settings. - Result InitWithSettings(const PrintSettings& settings); - - // Reinitializes the settings to uninitialized for object reuse. - void ResetSettings(); + virtual Result InitWithSettings(const PrintSettings& settings) = 0; // Does platform specific setup of the printer before the printing. Signal the // printer that a document is about to be spooled. @@ -102,93 +57,56 @@ class PrintingContext { // like IPC message processing! Some printers have side-effects on this call // like virtual printers that ask the user for the path of the saved document; // for example a PDF printer. - Result NewDocument(const string16& document_name); + virtual Result NewDocument(const string16& document_name) = 0; // Starts a new page. - Result NewPage(); + virtual Result NewPage() = 0; // Closes the printed page. - Result PageDone(); + virtual Result PageDone() = 0; // Closes the printing job. After this call the object is ready to start a new // document. - Result DocumentDone(); + virtual Result DocumentDone() = 0; // Cancels printing. Can be used in a multi-threaded context. Takes effect // immediately. - void Cancel(); + virtual void Cancel() = 0; // Dismiss the Print... dialog box if shown. - void DismissDialog(); - - gfx::NativeDrawingContext context() { -#if defined(OS_WIN) || defined(OS_MACOSX) - return context_; -#else - NOTIMPLEMENTED(); - return NULL; -#endif + virtual void DismissDialog() = 0; + + // Releases the native printing context. + virtual void ReleaseContext() = 0; + + // Returns the native context used to print. + virtual gfx::NativeDrawingContext context() const = 0; + + // Creates an instance of this object. Implementers of this interface should + // implement this method to create an object of their implementation. The + // caller owns the returned object. + static PrintingContext* Create(); + + void set_use_overlays(bool use_overlays) { + settings_.use_overlays = use_overlays; } const PrintSettings& settings() const { return settings_; } - private: - // Class that manages the PrintDlgEx() callbacks. This is meant to be a - // temporary object used during the Print... dialog display. - class CallbackHandler; + protected: + PrintingContext(); + + // Reinitializes the settings for object reuse. + void ResetSettings(); // Does bookkeeping when an error occurs. PrintingContext::Result OnError(); -#if defined(OS_WIN) - // Used in response to the user canceling the printing. - static BOOL CALLBACK AbortProc(HDC hdc, int nCode); - - // Reads the settings from the selected device context. Updates settings_ and - // its margins. - bool InitializeSettings(const DEVMODE& dev_mode, - const std::wstring& new_device_name, - const PRINTPAGERANGE* ranges, - int number_ranges, - bool selection_only); - - // Retrieves the printer's default low-level settings. On Windows, context_ is - // allocated with this call. - bool GetPrinterSettings(HANDLE printer, - const std::wstring& device_name); - - // Parses the result of a PRINTDLGEX result. - Result ParseDialogResultEx(const PRINTDLGEX& dialog_options); - Result ParseDialogResult(const PRINTDLG& dialog_options); -#elif defined(OS_MACOSX) - // Read the settings from the given NSPrintInfo (and cache it for later use). - void ParsePrintInfo(NSPrintInfo* print_info); -#endif - - // On Windows, the selected printer context. - // On Mac, the current page's context; only valid between NewPage and PageDone - // call pairs. - gfx::NativeDrawingContext context_; - -#if defined(OS_MACOSX) - // The native print info object. - NSPrintInfo* print_info_; -#endif - // Complete print context settings. PrintSettings settings_; -#if defined(OS_WIN) - // The dialog box for the time it is shown. - volatile HWND dialog_box_; - - // Function pointer that defaults to PrintDlgEx. It can be changed using - // SetPrintDialog() in tests. - HRESULT (__stdcall *print_dialog_func_)(LPPRINTDLGEX); -#endif - // The dialog box has been dismissed. volatile bool dialog_box_dismissed_; diff --git a/printing/printing_context_cairo.cc b/printing/printing_context_cairo.cc index 86de49c..0f5a500 100644 --- a/printing/printing_context_cairo.cc +++ b/printing/printing_context_cairo.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "printing/printing_context.h" +#include "printing/printing_context_cairo.h" #include <gtk/gtk.h> #include <gtk/gtkprintunixdialog.h> @@ -11,18 +11,19 @@ namespace printing { -PrintingContext::PrintingContext() - : - dialog_box_dismissed_(false), - in_print_job_(false), - abort_printing_(false) { +// static +PrintingContext* PrintingContext::Create() { + return static_cast<PrintingContext*>(new PrintingContextCairo); } -PrintingContext::~PrintingContext() { - ResetSettings(); +PrintingContextCairo::PrintingContextCairo() : PrintingContext() { +} + +PrintingContextCairo::~PrintingContextCairo() { + ReleaseContext(); } -void PrintingContext::AskUserForSettings( +void PrintingContextCairo::AskUserForSettings( gfx::NativeView parent_view, int max_pages, bool has_selection, @@ -31,7 +32,7 @@ void PrintingContext::AskUserForSettings( callback->Run(OK); } -PrintingContext::Result PrintingContext::UseDefaultSettings() { +PrintingContext::Result PrintingContextCairo::UseDefaultSettings() { DCHECK(!in_print_job_); ResetSettings(); @@ -52,7 +53,7 @@ PrintingContext::Result PrintingContext::UseDefaultSettings() { return OK; } -PrintingContext::Result PrintingContext::InitWithSettings( +PrintingContext::Result PrintingContextCairo::InitWithSettings( const PrintSettings& settings) { DCHECK(!in_print_job_); settings_ = settings; @@ -62,13 +63,7 @@ PrintingContext::Result PrintingContext::InitWithSettings( return FAILED; } -void PrintingContext::ResetSettings() { - dialog_box_dismissed_ = false; - abort_printing_ = false; - in_print_job_ = false; -} - -PrintingContext::Result PrintingContext::NewDocument( +PrintingContext::Result PrintingContextCairo::NewDocument( const string16& document_name) { DCHECK(!in_print_job_); @@ -77,7 +72,7 @@ PrintingContext::Result PrintingContext::NewDocument( return FAILED; } -PrintingContext::Result PrintingContext::NewPage() { +PrintingContext::Result PrintingContextCairo::NewPage() { if (abort_printing_) return CANCEL; DCHECK(in_print_job_); @@ -87,7 +82,7 @@ PrintingContext::Result PrintingContext::NewPage() { return FAILED; } -PrintingContext::Result PrintingContext::PageDone() { +PrintingContext::Result PrintingContextCairo::PageDone() { if (abort_printing_) return CANCEL; DCHECK(in_print_job_); @@ -97,7 +92,7 @@ PrintingContext::Result PrintingContext::PageDone() { return FAILED; } -PrintingContext::Result PrintingContext::DocumentDone() { +PrintingContext::Result PrintingContextCairo::DocumentDone() { if (abort_printing_) return CANCEL; DCHECK(in_print_job_); @@ -108,20 +103,23 @@ PrintingContext::Result PrintingContext::DocumentDone() { return FAILED; } -void PrintingContext::Cancel() { +void PrintingContextCairo::Cancel() { abort_printing_ = true; in_print_job_ = false; NOTIMPLEMENTED(); } -void PrintingContext::DismissDialog() { +void PrintingContextCairo::DismissDialog() { NOTIMPLEMENTED(); } -PrintingContext::Result PrintingContext::OnError() { - ResetSettings(); - return abort_printing_ ? CANCEL : FAILED; +void PrintingContextCairo::ReleaseContext() { + // Nothing to do yet. +} + +gfx::NativeDrawingContext PrintingContextCairo::context() const { + return NULL; } } // namespace printing diff --git a/printing/printing_context_cairo.h b/printing/printing_context_cairo.h new file mode 100644 index 0000000..d4c98ca --- /dev/null +++ b/printing/printing_context_cairo.h @@ -0,0 +1,39 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PRINTING_PRINTING_CONTEXT_CAIRO_H_ +#define PRINTING_PRINTING_CONTEXT_CAIRO_H_ + +#include "printing/printing_context.h" + +namespace printing { + +class PrintingContextCairo : public PrintingContext { + public: + PrintingContextCairo(); + ~PrintingContextCairo(); + + // PrintingContext implementation. + virtual void AskUserForSettings(gfx::NativeView parent_view, + int max_pages, + bool has_selection, + PrintSettingsCallback* callback); + virtual Result UseDefaultSettings(); + virtual Result InitWithSettings(const PrintSettings& settings); + virtual Result NewDocument(const string16& document_name); + virtual Result NewPage(); + virtual Result PageDone(); + virtual Result DocumentDone(); + virtual void Cancel(); + virtual void DismissDialog(); + virtual void ReleaseContext(); + virtual gfx::NativeDrawingContext context() const; + + private: + DISALLOW_COPY_AND_ASSIGN(PrintingContextCairo); +}; + +} // namespace printing + +#endif // PRINTING_PRINTING_CONTEXT_CAIRO_H_ diff --git a/printing/printing_context_mac.h b/printing/printing_context_mac.h new file mode 100644 index 0000000..f94fae2 --- /dev/null +++ b/printing/printing_context_mac.h @@ -0,0 +1,55 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PRINTING_PRINTING_CONTEXT_MAC_H_ +#define PRINTING_PRINTING_CONTEXT_MAC_H_ + +#include "printing/printing_context.h" + +#ifdef __OBJC__ +@class NSPrintInfo; +#else +class NSPrintInfo; +#endif // __OBJC__ + +namespace printing { + +class PrintingContextMac : public PrintingContext { + public: + PrintingContextMac(); + ~PrintingContextMac(); + + // PrintingContext implementation. + virtual void AskUserForSettings(gfx::NativeView parent_view, + int max_pages, + bool has_selection, + PrintSettingsCallback* callback); + virtual Result UseDefaultSettings(); + virtual Result InitWithSettings(const PrintSettings& settings); + virtual Result NewDocument(const string16& document_name); + virtual Result NewPage(); + virtual Result PageDone(); + virtual Result DocumentDone(); + virtual void Cancel(); + virtual void DismissDialog(); + virtual void ReleaseContext(); + virtual gfx::NativeDrawingContext context() const; + + private: + // Read the settings from the given NSPrintInfo (and cache it for later use). + void ParsePrintInfo(NSPrintInfo* print_info); + + // The native print info object. + NSPrintInfo* print_info_; + + // The current page's context; only valid between NewPage and PageDone call + // pairs. + CGContext* context_; + + DISALLOW_COPY_AND_ASSIGN(PrintingContextMac); +}; + +} // namespace printing + +#endif // PRINTING_PRINTING_CONTEXT_MAC_H_ diff --git a/printing/printing_context_mac.mm b/printing/printing_context_mac.mm index 828a7f4..50431ae6 100644 --- a/printing/printing_context_mac.mm +++ b/printing/printing_context_mac.mm @@ -2,33 +2,36 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "printing/printing_context.h" +#include "printing/printing_context_mac.h" #import <ApplicationServices/ApplicationServices.h> #import <AppKit/AppKit.h> #include "base/logging.h" +#include "base/scoped_cftyperef.h" #include "base/sys_string_conversions.h" namespace printing { -PrintingContext::PrintingContext() - : context_(NULL), - print_info_(nil), - dialog_box_dismissed_(false), - in_print_job_(false), - abort_printing_(false) { +// static +PrintingContext* PrintingContext::Create() { + return static_cast<PrintingContext*>(new PrintingContextMac); } -PrintingContext::~PrintingContext() { - ResetSettings(); +PrintingContextMac::PrintingContextMac() + : PrintingContext(), + print_info_(NULL), + context_(NULL) { } +PrintingContextMac::~PrintingContextMac() { + ReleaseContext(); +} -void PrintingContext::AskUserForSettings(gfx::NativeView parent_view, - int max_pages, - bool has_selection, - PrintSettingsCallback* callback) { +void PrintingContextMac::AskUserForSettings(gfx::NativeView parent_view, + int max_pages, + bool has_selection, + PrintSettingsCallback* callback) { DCHECK([NSThread isMainThread]); // We deliberately don't feed max_pages into the dialog, because setting @@ -68,7 +71,7 @@ void PrintingContext::AskUserForSettings(gfx::NativeView parent_view, } } -PrintingContext::Result PrintingContext::UseDefaultSettings() { +PrintingContext::Result PrintingContextMac::UseDefaultSettings() { DCHECK(!in_print_job_); ParsePrintInfo([NSPrintInfo sharedPrintInfo]); @@ -76,7 +79,7 @@ PrintingContext::Result PrintingContext::UseDefaultSettings() { return OK; } -void PrintingContext::ParsePrintInfo(NSPrintInfo* print_info) { +void PrintingContextMac::ParsePrintInfo(NSPrintInfo* print_info) { ResetSettings(); print_info_ = [print_info retain]; PageRanges page_ranges; @@ -97,7 +100,7 @@ void PrintingContext::ParsePrintInfo(NSPrintInfo* print_info) { settings_.Init(printer, page_format, page_ranges, false); } -PrintingContext::Result PrintingContext::InitWithSettings( +PrintingContext::Result PrintingContextMac::InitWithSettings( const PrintSettings& settings) { DCHECK(!in_print_job_); settings_ = settings; @@ -107,17 +110,7 @@ PrintingContext::Result PrintingContext::InitWithSettings( return FAILED; } -void PrintingContext::ResetSettings() { - [print_info_ autorelease]; - print_info_ = nil; - settings_.Clear(); - dialog_box_dismissed_ = false; - abort_printing_ = false; - in_print_job_ = false; - context_ = NULL; -} - -PrintingContext::Result PrintingContext::NewDocument( +PrintingContext::Result PrintingContextMac::NewDocument( const string16& document_name) { DCHECK(!in_print_job_); @@ -143,7 +136,7 @@ PrintingContext::Result PrintingContext::NewDocument( return OK; } -PrintingContext::Result PrintingContext::NewPage() { +PrintingContext::Result PrintingContextMac::NewPage() { if (abort_printing_) return CANCEL; DCHECK(in_print_job_); @@ -164,7 +157,7 @@ PrintingContext::Result PrintingContext::NewPage() { return OK; } -PrintingContext::Result PrintingContext::PageDone() { +PrintingContext::Result PrintingContextMac::PageDone() { if (abort_printing_) return CANCEL; DCHECK(in_print_job_); @@ -180,7 +173,7 @@ PrintingContext::Result PrintingContext::PageDone() { return OK; } -PrintingContext::Result PrintingContext::DocumentDone() { +PrintingContext::Result PrintingContextMac::DocumentDone() { if (abort_printing_) return CANCEL; DCHECK(in_print_job_); @@ -195,7 +188,7 @@ PrintingContext::Result PrintingContext::DocumentDone() { return OK; } -void PrintingContext::Cancel() { +void PrintingContextMac::Cancel() { abort_printing_ = true; in_print_job_ = false; context_ = NULL; @@ -205,13 +198,20 @@ void PrintingContext::Cancel() { PMSessionEndPageNoDialog(print_session); } -void PrintingContext::DismissDialog() { +void PrintingContextMac::DismissDialog() { NOTIMPLEMENTED(); } -PrintingContext::Result PrintingContext::OnError() { - ResetSettings(); - return abort_printing_ ? CANCEL : FAILED; +void PrintingContextMac::ReleaseContext() { + if (print_info_) { + [print_info_ autorelease]; + print_info_ = nil; + context_ = NULL; + } +} + +gfx::NativeDrawingContext PrintingContextMac::context() const { + return context_; } } // namespace printing diff --git a/printing/printing_context_win.cc b/printing/printing_context_win.cc index 038f5d3..9d855cd 100644 --- a/printing/printing_context_win.cc +++ b/printing/printing_context_win.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "printing/printing_context.h" +#include "printing/printing_context_win.h" #include <winspool.h> @@ -19,10 +19,10 @@ using base::Time; namespace printing { -class PrintingContext::CallbackHandler : public IPrintDialogCallback, - public IObjectWithSite { +class PrintingContextWin::CallbackHandler : public IPrintDialogCallback, + public IObjectWithSite { public: - CallbackHandler(PrintingContext& owner, HWND owner_hwnd) + CallbackHandler(PrintingContextWin& owner, HWND owner_hwnd) : owner_(owner), owner_hwnd_(owner_hwnd), services_(NULL) { @@ -113,30 +113,33 @@ class PrintingContext::CallbackHandler : public IPrintDialogCallback, } private: - PrintingContext& owner_; + PrintingContextWin& owner_; HWND owner_hwnd_; IPrintDialogServices* services_; DISALLOW_COPY_AND_ASSIGN(CallbackHandler); }; -PrintingContext::PrintingContext() - : context_(NULL), +// static +PrintingContext* PrintingContext::Create() { + return static_cast<PrintingContext*>(new PrintingContextWin); +} + +PrintingContextWin::PrintingContextWin() + : PrintingContext(), + context_(NULL), dialog_box_(NULL), - dialog_box_dismissed_(false), - in_print_job_(false), - abort_printing_(false), print_dialog_func_(&PrintDlgEx) { } -PrintingContext::~PrintingContext() { - ResetSettings(); +PrintingContextWin::~PrintingContextWin() { + ReleaseContext(); } -void PrintingContext::AskUserForSettings(HWND view, - int max_pages, - bool has_selection, - PrintSettingsCallback* callback) { +void PrintingContextWin::AskUserForSettings(HWND view, + int max_pages, + bool has_selection, + PrintSettingsCallback* callback) { DCHECK(!in_print_job_); dialog_box_dismissed_ = false; @@ -194,7 +197,7 @@ void PrintingContext::AskUserForSettings(HWND view, callback->Run(ParseDialogResultEx(dialog_options)); } -PrintingContext::Result PrintingContext::UseDefaultSettings() { +PrintingContext::Result PrintingContextWin::UseDefaultSettings() { DCHECK(!in_print_job_); PRINTDLG dialog_options = { sizeof(PRINTDLG) }; @@ -206,7 +209,7 @@ PrintingContext::Result PrintingContext::UseDefaultSettings() { return ParseDialogResult(dialog_options); } -PrintingContext::Result PrintingContext::InitWithSettings( +PrintingContext::Result PrintingContextWin::InitWithSettings( const PrintSettings& settings) { DCHECK(!in_print_job_); settings_ = settings; @@ -230,16 +233,7 @@ PrintingContext::Result PrintingContext::InitWithSettings( return status; } -void PrintingContext::ResetSettings() { - if (context_ != NULL) { - DeleteDC(context_); - context_ = NULL; - } - settings_.Clear(); - in_print_job_ = false; -} - -PrintingContext::Result PrintingContext::NewDocument( +PrintingContext::Result PrintingContextWin::NewDocument( const string16& document_name) { DCHECK(!in_print_job_); if (!context_) @@ -289,7 +283,7 @@ PrintingContext::Result PrintingContext::NewDocument( return OK; } -PrintingContext::Result PrintingContext::NewPage() { +PrintingContext::Result PrintingContextWin::NewPage() { if (abort_printing_) return CANCEL; @@ -303,7 +297,7 @@ PrintingContext::Result PrintingContext::NewPage() { return OK; } -PrintingContext::Result PrintingContext::PageDone() { +PrintingContext::Result PrintingContextWin::PageDone() { if (abort_printing_) return CANCEL; DCHECK(in_print_job_); @@ -313,7 +307,7 @@ PrintingContext::Result PrintingContext::PageDone() { return OK; } -PrintingContext::Result PrintingContext::DocumentDone() { +PrintingContext::Result PrintingContextWin::DocumentDone() { if (abort_printing_) return CANCEL; DCHECK(in_print_job_); @@ -327,7 +321,7 @@ PrintingContext::Result PrintingContext::DocumentDone() { return OK; } -void PrintingContext::Cancel() { +void PrintingContextWin::Cancel() { abort_printing_ = true; in_print_job_ = false; if (context_) @@ -335,21 +329,26 @@ void PrintingContext::Cancel() { DismissDialog(); } -void PrintingContext::DismissDialog() { +void PrintingContextWin::DismissDialog() { if (dialog_box_) { DestroyWindow(dialog_box_); dialog_box_dismissed_ = true; } } -PrintingContext::Result PrintingContext::OnError() { - // This will close context_ and clear settings_. - ResetSettings(); - return abort_printing_ ? CANCEL : FAILED; +void PrintingContextWin::ReleaseContext() { + if (context_) { + DeleteDC(context_); + context_ = NULL; + } +} + +gfx::NativeDrawingContext PrintingContextWin::context() const { + return context_; } // static -BOOL PrintingContext::AbortProc(HDC hdc, int nCode) { +BOOL PrintingContextWin::AbortProc(HDC hdc, int nCode) { if (nCode) { // TODO(maruel): Need a way to find the right instance to set. Should // leverage PrintJobManager here? @@ -358,11 +357,11 @@ BOOL PrintingContext::AbortProc(HDC hdc, int nCode) { return true; } -bool PrintingContext::InitializeSettings(const DEVMODE& dev_mode, - const std::wstring& new_device_name, - const PRINTPAGERANGE* ranges, - int number_ranges, - bool selection_only) { +bool PrintingContextWin::InitializeSettings(const DEVMODE& dev_mode, + const std::wstring& new_device_name, + const PRINTPAGERANGE* ranges, + int number_ranges, + bool selection_only) { skia::PlatformDevice::InitializeDC(context_); DCHECK(GetDeviceCaps(context_, CLIPCAPS)); DCHECK(GetDeviceCaps(context_, RASTERCAPS) & RC_STRETCHDIB); @@ -402,8 +401,8 @@ bool PrintingContext::InitializeSettings(const DEVMODE& dev_mode, return true; } -bool PrintingContext::GetPrinterSettings(HANDLE printer, - const std::wstring& device_name) { +bool PrintingContextWin::GetPrinterSettings(HANDLE printer, + const std::wstring& device_name) { DCHECK(!in_print_job_); scoped_array<uint8> buffer; @@ -456,15 +455,15 @@ bool PrintingContext::GetPrinterSettings(HANDLE printer, } // static -bool PrintingContext::AllocateContext(const std::wstring& printer_name, - const DEVMODE* dev_mode, - gfx::NativeDrawingContext* context) { +bool PrintingContextWin::AllocateContext(const std::wstring& printer_name, + const DEVMODE* dev_mode, + gfx::NativeDrawingContext* context) { *context = CreateDC(L"WINSPOOL", printer_name.c_str(), NULL, dev_mode); DCHECK(*context); return *context != NULL; } -PrintingContext::Result PrintingContext::ParseDialogResultEx( +PrintingContext::Result PrintingContextWin::ParseDialogResultEx( const PRINTDLGEX& dialog_options) { // If the user clicked OK or Apply then Cancel, but not only Cancel. if (dialog_options.dwResultAction != PD_RESULT_CANCEL) { @@ -543,7 +542,7 @@ PrintingContext::Result PrintingContext::ParseDialogResultEx( } } -PrintingContext::Result PrintingContext::ParseDialogResult( +PrintingContext::Result PrintingContextWin::ParseDialogResult( const PRINTDLG& dialog_options) { // If the user clicked OK or Apply then Cancel, but not only Cancel. // Start fresh. @@ -594,8 +593,8 @@ PrintingContext::Result PrintingContext::ParseDialogResult( } // static -void PrintingContext::GetPrinterHelper(HANDLE printer, int level, - scoped_array<uint8>* buffer) { +void PrintingContextWin::GetPrinterHelper(HANDLE printer, int level, + scoped_array<uint8>* buffer) { DWORD buf_size = 0; GetPrinter(printer, level, NULL, 0, &buf_size); if (buf_size) { diff --git a/printing/printing_context_win.h b/printing/printing_context_win.h new file mode 100644 index 0000000..90fc738 --- /dev/null +++ b/printing/printing_context_win.h @@ -0,0 +1,97 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PRINTING_PRINTING_CONTEXT_WIN_H_ +#define PRINTING_PRINTING_CONTEXT_WIN_H_ + +#include <ocidl.h> +#include <commdlg.h> + +#include <string> + +#include "base/scoped_ptr.h" +#include "build/build_config.h" +#include "gfx/native_widget_types.h" +#include "printing/printing_context.h" + +namespace printing { + +class PrintingContextWin : public PrintingContext { + public: + PrintingContextWin(); + ~PrintingContextWin(); + + // PrintingContext implementation. + virtual void AskUserForSettings(gfx::NativeView parent_view, + int max_pages, + bool has_selection, + PrintSettingsCallback* callback); + virtual Result UseDefaultSettings(); + virtual Result InitWithSettings(const PrintSettings& settings); + virtual Result NewDocument(const string16& document_name); + virtual Result NewPage(); + virtual Result PageDone(); + virtual Result DocumentDone(); + virtual void Cancel(); + virtual void DismissDialog(); + virtual void ReleaseContext(); + virtual gfx::NativeDrawingContext context() const; + +#if defined(UNIT_TEST) + // Sets a fake PrintDlgEx function pointer in tests. + void SetPrintDialog(HRESULT (__stdcall *print_dialog_func)(LPPRINTDLGEX)) { + print_dialog_func_ = print_dialog_func; + } +#endif // defined(UNIT_TEST) + + // Allocates the HDC for a specific DEVMODE. + static bool AllocateContext(const std::wstring& printer_name, + const DEVMODE* dev_mode, + gfx::NativeDrawingContext* context); + + // Retrieves the content of a GetPrinter call. + static void GetPrinterHelper(HANDLE printer, int level, + scoped_array<uint8>* buffer); + + private: + // Class that manages the PrintDlgEx() callbacks. This is meant to be a + // temporary object used during the Print... dialog display. + class CallbackHandler; + + // Used in response to the user canceling the printing. + static BOOL CALLBACK AbortProc(HDC hdc, int nCode); + + // Reads the settings from the selected device context. Updates settings_ and + // its margins. + bool InitializeSettings(const DEVMODE& dev_mode, + const std::wstring& new_device_name, + const PRINTPAGERANGE* ranges, + int number_ranges, + bool selection_only); + + // Retrieves the printer's default low-level settings. On Windows, context_ is + // allocated with this call. + bool GetPrinterSettings(HANDLE printer, + const std::wstring& device_name); + + // Parses the result of a PRINTDLGEX result. + Result ParseDialogResultEx(const PRINTDLGEX& dialog_options); + Result ParseDialogResult(const PRINTDLG& dialog_options); + + // The selected printer context. + HDC context_; + + // The dialog box for the time it is shown. + volatile HWND dialog_box_; + + // Function pointer that defaults to PrintDlgEx. It can be changed using + // SetPrintDialog() in tests. + HRESULT (__stdcall *print_dialog_func_)(LPPRINTDLGEX); + + DISALLOW_COPY_AND_ASSIGN(PrintingContextWin); +}; + +} // namespace printing + +#endif // PRINTING_PRINTING_CONTEXT_WIN_H_ diff --git a/printing/printing_context_win_unittest.cc b/printing/printing_context_win_unittest.cc index 625af54..6e194d1 100644 --- a/printing/printing_context_win_unittest.cc +++ b/printing/printing_context_win_unittest.cc @@ -2,9 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "printing/printing_context.h" +#include <ocidl.h> +#include <commdlg.h> + +#include <string> +#include "base/scoped_ptr.h" #include "printing/printing_test.h" +#include "printing/printing_context.h" +#include "printing/printing_context_win.h" #include "printing/print_settings.h" #include "testing/gtest/include/gtest/gtest.h" @@ -46,7 +52,7 @@ HRESULT WINAPI PrintDlgExMock(LPPRINTDLGEX lppd) { DEVMODE* dev_mode = NULL; PRINTER_INFO_2* info_2 = NULL; - printing::PrintingContext::GetPrinterHelper(printer, 2, &buffer); + printing::PrintingContextWin::GetPrinterHelper(printer, 2, &buffer); if (buffer.get()) { info_2 = reinterpret_cast<PRINTER_INFO_2*>(buffer.get()); if (info_2->pDevMode != NULL) @@ -55,7 +61,7 @@ HRESULT WINAPI PrintDlgExMock(LPPRINTDLGEX lppd) { if (!dev_mode) return E_FAIL; - if (!printing::PrintingContext::AllocateContext(printer_name, dev_mode, + if (!printing::PrintingContextWin::AllocateContext(printer_name, dev_mode, &lppd->hDC)) { return E_FAIL; } @@ -102,18 +108,19 @@ TEST_F(PrintingContextTest, Base) { settings.set_device_name(GetDefaultPrinter()); // Initialize it. - printing::PrintingContext context; - EXPECT_EQ(printing::PrintingContext::OK, context.InitWithSettings(settings)); + scoped_ptr<printing::PrintingContext> context( + printing::PrintingContext::Create()); + EXPECT_EQ(printing::PrintingContext::OK, context->InitWithSettings(settings)); // The print may lie to use and may not support world transformation. // Verify right now. XFORM random_matrix = { 1, 0.1f, 0, 1.5f, 0, 1 }; - EXPECT_TRUE(SetWorldTransform(context.context(), &random_matrix)); - EXPECT_TRUE(ModifyWorldTransform(context.context(), NULL, MWT_IDENTITY)); + EXPECT_TRUE(SetWorldTransform(context->context(), &random_matrix)); + EXPECT_TRUE(ModifyWorldTransform(context->context(), NULL, MWT_IDENTITY)); } TEST_F(PrintingContextTest, PrintAll) { - printing::PrintingContext context; + printing::PrintingContextWin context; context.SetPrintDialog(&PrintDlgExMock); context.AskUserForSettings( NULL, diff --git a/printing/printing_test.h b/printing/printing_test.h index 3237813..da5d86d 100644 --- a/printing/printing_test.h +++ b/printing/printing_test.h @@ -8,6 +8,10 @@ #include <windows.h> #include <winspool.h> +#include <string> + +#include "base/basictypes.h" + // Disable the whole test case when executing on a computer that has no printer // installed. // Note: Parent should be testing::Test or UITest. |