diff options
author | vitalybuka <vitalybuka@chromium.org> | 2014-08-26 16:41:45 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-08-26 23:45:57 +0000 |
commit | 92ab8ce04d850a59aa3d1b49ba2986845102baf3 (patch) | |
tree | de095372d9f4ae672eb11adef98681ae1d2acb04 /printing | |
parent | fa29c3e30198fcdb462ec65f0627a5e5f524effb (diff) | |
download | chromium_src-92ab8ce04d850a59aa3d1b49ba2986845102baf3.zip chromium_src-92ab8ce04d850a59aa3d1b49ba2986845102baf3.tar.gz chromium_src-92ab8ce04d850a59aa3d1b49ba2986845102baf3.tar.bz2 |
Use document from preview for System Dialog printing on Windows.
System dialog shows only properties of selected printers, no system dialog with printers.
Removed global Ctrl+Shift+P shortcut on windows.
BUG=374321
Review URL: https://codereview.chromium.org/480303002
Cr-Commit-Position: refs/heads/master@{#292032}
Diffstat (limited to 'printing')
-rw-r--r-- | printing/backend/win_helper.cc | 32 | ||||
-rw-r--r-- | printing/backend/win_helper.h | 8 | ||||
-rw-r--r-- | printing/print_job_constants.cc | 3 | ||||
-rw-r--r-- | printing/print_job_constants.h | 1 | ||||
-rw-r--r-- | printing/printing_context.cc | 6 | ||||
-rw-r--r-- | printing/printing_context.h | 3 | ||||
-rw-r--r-- | printing/printing_context_android.cc | 4 | ||||
-rw-r--r-- | printing/printing_context_android.h | 3 | ||||
-rw-r--r-- | printing/printing_context_linux.cc | 4 | ||||
-rw-r--r-- | printing/printing_context_linux.h | 3 | ||||
-rw-r--r-- | printing/printing_context_mac.h | 3 | ||||
-rw-r--r-- | printing/printing_context_mac.mm | 4 | ||||
-rw-r--r-- | printing/printing_context_no_system_dialog.cc | 4 | ||||
-rw-r--r-- | printing/printing_context_no_system_dialog.h | 3 | ||||
-rw-r--r-- | printing/printing_context_win.cc | 340 | ||||
-rw-r--r-- | printing/printing_context_win.h | 36 | ||||
-rw-r--r-- | printing/printing_context_win_unittest.cc | 146 |
17 files changed, 141 insertions, 462 deletions
diff --git a/printing/backend/win_helper.cc b/printing/backend/win_helper.cc index 6aba7c6..db8d735 100644 --- a/printing/backend/win_helper.cc +++ b/printing/backend/win_helper.cc @@ -488,4 +488,36 @@ scoped_ptr<DEVMODE, base::FreeDeleter> CreateDevMode(HANDLE printer, return out.Pass(); } +scoped_ptr<DEVMODE, base::FreeDeleter> PromptDevMode( + HANDLE printer, + const base::string16& printer_name, + DEVMODE* in, + HWND window, + bool* canceled) { + LONG buffer_size = + DocumentProperties(window, + printer, + const_cast<wchar_t*>(printer_name.c_str()), + NULL, + NULL, + 0); + if (buffer_size < static_cast<int>(sizeof(DEVMODE))) + return scoped_ptr<DEVMODE, base::FreeDeleter>(); + scoped_ptr<DEVMODE, base::FreeDeleter> out( + reinterpret_cast<DEVMODE*>(malloc(buffer_size))); + DWORD flags = (in ? (DM_IN_BUFFER) : 0) | DM_OUT_BUFFER | DM_IN_PROMPT; + LONG result = DocumentProperties(window, + printer, + const_cast<wchar_t*>(printer_name.c_str()), + out.get(), + in, + flags); + if (canceled) + *canceled = (result == IDCANCEL); + if (result != IDOK) + return scoped_ptr<DEVMODE, base::FreeDeleter>(); + CHECK_GE(buffer_size, out.get()->dmSize + out.get()->dmDriverExtra); + return out.Pass(); +} + } // namespace printing diff --git a/printing/backend/win_helper.h b/printing/backend/win_helper.h index 18d0355..c6665f4 100644 --- a/printing/backend/win_helper.h +++ b/printing/backend/win_helper.h @@ -186,6 +186,14 @@ PRINTING_EXPORT scoped_ptr<DEVMODE, base::FreeDeleter> CreateDevMode( HANDLE printer, DEVMODE* in); +// Prompts for new DEVMODE. If |in| is not NULL copy settings from there. +PRINTING_EXPORT scoped_ptr<DEVMODE, base::FreeDeleter> PromptDevMode( + HANDLE printer, + const base::string16& printer_name, + DEVMODE* in, + HWND window, + bool* canceled); + } // namespace printing #endif // PRINTING_BACKEND_WIN_HELPER_H_ diff --git a/printing/print_job_constants.cc b/printing/print_job_constants.cc index 6ac461c..ed4d1e2 100644 --- a/printing/print_job_constants.cc +++ b/printing/print_job_constants.cc @@ -163,6 +163,9 @@ const char kSettingShouldPrintBackgrounds[] = "shouldPrintBackgrounds"; // Whether to print selection only. const char kSettingShouldPrintSelectionOnly[] = "shouldPrintSelectionOnly"; +// Whether to print selection only. +const char kSettingShowSystemDialog[] = "showSystemDialog"; + // Indices used to represent first preview page and complete preview document. const int FIRST_PAGE_INDEX = 0; const int COMPLETE_PREVIEW_DOCUMENT_INDEX = -1; diff --git a/printing/print_job_constants.h b/printing/print_job_constants.h index 646191b..35f036d 100644 --- a/printing/print_job_constants.h +++ b/printing/print_job_constants.h @@ -63,6 +63,7 @@ PRINTING_EXPORT extern const char kSettingPrinterOptions[]; PRINTING_EXPORT extern const char kSettingTicket[]; PRINTING_EXPORT extern const char kSettingShouldPrintBackgrounds[]; PRINTING_EXPORT extern const char kSettingShouldPrintSelectionOnly[]; +PRINTING_EXPORT extern const char kSettingShowSystemDialog[]; PRINTING_EXPORT extern const int FIRST_PAGE_INDEX; PRINTING_EXPORT extern const int COMPLETE_PREVIEW_DOCUMENT_INDEX; diff --git a/printing/printing_context.cc b/printing/printing_context.cc index d2b1e68..3528828 100644 --- a/printing/printing_context.cc +++ b/printing/printing_context.cc @@ -114,7 +114,11 @@ PrintingContext::Result PrintingContext::UpdatePrintSettings( return OK; } - return UpdatePrinterSettings(open_in_external_preview); + bool show_system_dialog = false; + job_settings.GetBoolean(printing::kSettingShowSystemDialog, + &show_system_dialog); + + return UpdatePrinterSettings(open_in_external_preview, show_system_dialog); } } // namespace printing diff --git a/printing/printing_context.h b/printing/printing_context.h index 875c070..0cc4731 100644 --- a/printing/printing_context.h +++ b/printing/printing_context.h @@ -72,7 +72,8 @@ class PRINTING_EXPORT PrintingContext { // Updates printer settings. // |external_preview| is true if pdf is going to be opened in external // preview. Used by MacOS only now to open Preview.app. - virtual Result UpdatePrinterSettings(bool external_preview) = 0; + virtual Result UpdatePrinterSettings(bool external_preview, + bool show_system_dialog) = 0; // Updates Print Settings. |job_settings| contains all print job // settings information. |ranges| has the new page range settings. diff --git a/printing/printing_context_android.cc b/printing/printing_context_android.cc index 39f1c6d..64139c8 100644 --- a/printing/printing_context_android.cc +++ b/printing/printing_context_android.cc @@ -170,7 +170,9 @@ gfx::Size PrintingContextAndroid::GetPdfPaperSizeDeviceUnits() { } PrintingContext::Result PrintingContextAndroid::UpdatePrinterSettings( - bool external_preview) { + bool external_preview, + bool show_system_dialog) { + DCHECK(!show_system_dialog); DCHECK(!in_print_job_); // Intentional No-op. diff --git a/printing/printing_context_android.h b/printing/printing_context_android.h index 56068a1..fee2259 100644 --- a/printing/printing_context_android.h +++ b/printing/printing_context_android.h @@ -37,7 +37,8 @@ class PRINTING_EXPORT PrintingContextAndroid : public PrintingContext { const PrintSettingsCallback& callback) OVERRIDE; virtual Result UseDefaultSettings() OVERRIDE; virtual gfx::Size GetPdfPaperSizeDeviceUnits() OVERRIDE; - virtual Result UpdatePrinterSettings(bool external_preview) OVERRIDE; + virtual Result UpdatePrinterSettings(bool external_preview, + bool show_system_dialog) OVERRIDE; virtual Result InitWithSettings(const PrintSettings& settings) OVERRIDE; virtual Result NewDocument(const base::string16& document_name) OVERRIDE; virtual Result NewPage() OVERRIDE; diff --git a/printing/printing_context_linux.cc b/printing/printing_context_linux.cc index c267478..926d4e2 100644 --- a/printing/printing_context_linux.cc +++ b/printing/printing_context_linux.cc @@ -106,7 +106,9 @@ gfx::Size PrintingContextLinux::GetPdfPaperSizeDeviceUnits() { } PrintingContext::Result PrintingContextLinux::UpdatePrinterSettings( - bool external_preview) { + bool external_preview, + bool show_system_dialog) { + DCHECK(!show_system_dialog); DCHECK(!in_print_job_); DCHECK(!external_preview) << "Not implemented"; diff --git a/printing/printing_context_linux.h b/printing/printing_context_linux.h index 984d7dc..af59806 100644 --- a/printing/printing_context_linux.h +++ b/printing/printing_context_linux.h @@ -43,7 +43,8 @@ class PRINTING_EXPORT PrintingContextLinux : public PrintingContext { const PrintSettingsCallback& callback) OVERRIDE; virtual gfx::Size GetPdfPaperSizeDeviceUnits() OVERRIDE; virtual Result UseDefaultSettings() OVERRIDE; - virtual Result UpdatePrinterSettings(bool external_preview) OVERRIDE; + virtual Result UpdatePrinterSettings(bool external_preview, + bool show_system_dialog) OVERRIDE; virtual Result InitWithSettings(const PrintSettings& settings) OVERRIDE; virtual Result NewDocument(const base::string16& document_name) OVERRIDE; virtual Result NewPage() OVERRIDE; diff --git a/printing/printing_context_mac.h b/printing/printing_context_mac.h index 9eb924a..609080e 100644 --- a/printing/printing_context_mac.h +++ b/printing/printing_context_mac.h @@ -31,7 +31,8 @@ class PRINTING_EXPORT PrintingContextMac : public PrintingContext { const PrintSettingsCallback& callback) OVERRIDE; virtual Result UseDefaultSettings() OVERRIDE; virtual gfx::Size GetPdfPaperSizeDeviceUnits() OVERRIDE; - virtual Result UpdatePrinterSettings(bool external_preview) OVERRIDE; + virtual Result UpdatePrinterSettings(bool external_preview, + bool show_system_dialog) OVERRIDE; virtual Result InitWithSettings(const PrintSettings& settings) OVERRIDE; virtual Result NewDocument(const base::string16& document_name) OVERRIDE; virtual Result NewPage() OVERRIDE; diff --git a/printing/printing_context_mac.mm b/printing/printing_context_mac.mm index fa907b5..23d2d84 100644 --- a/printing/printing_context_mac.mm +++ b/printing/printing_context_mac.mm @@ -168,7 +168,9 @@ PrintingContext::Result PrintingContextMac::UseDefaultSettings() { } PrintingContext::Result PrintingContextMac::UpdatePrinterSettings( - bool external_preview) { + bool external_preview, + bool show_system_dialog) { + DCHECK(!show_system_dialog); DCHECK(!in_print_job_); // NOTE: Reset |print_info_| with a copy of |sharedPrintInfo| so as to start diff --git a/printing/printing_context_no_system_dialog.cc b/printing/printing_context_no_system_dialog.cc index fd6e166..7ae10dd 100644 --- a/printing/printing_context_no_system_dialog.cc +++ b/printing/printing_context_no_system_dialog.cc @@ -75,7 +75,9 @@ gfx::Size PrintingContextNoSystemDialog::GetPdfPaperSizeDeviceUnits() { } PrintingContext::Result PrintingContextNoSystemDialog::UpdatePrinterSettings( - bool external_preview) { + bool external_preview, + bool show_system_dialog) { + DCHECK(!show_system_dialog); if (settings_.dpi() == 0) UseDefaultSettings(); diff --git a/printing/printing_context_no_system_dialog.h b/printing/printing_context_no_system_dialog.h index fbc69aa..0c5e0b5 100644 --- a/printing/printing_context_no_system_dialog.h +++ b/printing/printing_context_no_system_dialog.h @@ -27,7 +27,8 @@ class PRINTING_EXPORT PrintingContextNoSystemDialog : public PrintingContext { const PrintSettingsCallback& callback) OVERRIDE; virtual Result UseDefaultSettings() OVERRIDE; virtual gfx::Size GetPdfPaperSizeDeviceUnits() OVERRIDE; - virtual Result UpdatePrinterSettings(bool external_preview) OVERRIDE; + virtual Result UpdatePrinterSettings(bool external_preview, + bool show_system_dialog) OVERRIDE; virtual Result InitWithSettings(const PrintSettings& settings) OVERRIDE; virtual Result NewDocument(const base::string16& document_name) OVERRIDE; virtual Result NewPage() OVERRIDE; diff --git a/printing/printing_context_win.cc b/printing/printing_context_win.cc index dd0e2c4..4d7ea92 100644 --- a/printing/printing_context_win.cc +++ b/printing/printing_context_win.cc @@ -50,7 +50,7 @@ scoped_ptr<PrintingContext> PrintingContext::Create(Delegate* delegate) { } PrintingContextWin::PrintingContextWin(Delegate* delegate) - : PrintingContext(delegate), context_(NULL), dialog_box_(NULL) { + : PrintingContext(delegate), context_(NULL) { } PrintingContextWin::~PrintingContextWin() { @@ -61,63 +61,26 @@ void PrintingContextWin::AskUserForSettings( int max_pages, bool has_selection, const PrintSettingsCallback& callback) { - DCHECK(!in_print_job_); - dialog_box_dismissed_ = false; - - HWND window = GetRootWindow(delegate_->GetParentView()); - DCHECK(window); - - // Show the OS-dependent dialog box. - // If the user press - // - OK, the settings are reset and reinitialized with the new settings. OK is - // returned. - // - Apply then Cancel, the settings are reset and reinitialized with the new - // settings. CANCEL is returned. - // - Cancel, the settings are not changed, the previous setting, if it was - // initialized before, are kept. CANCEL is returned. - // On failure, the settings are reset and FAILED is returned. - PRINTDLGEX dialog_options = { sizeof(PRINTDLGEX) }; - dialog_options.hwndOwner = window; - // Disable options we don't support currently. - // TODO(maruel): Reuse the previously loaded settings! - dialog_options.Flags = PD_RETURNDC | PD_USEDEVMODECOPIESANDCOLLATE | - PD_NOCURRENTPAGE | PD_HIDEPRINTTOFILE; - if (!has_selection) - dialog_options.Flags |= PD_NOSELECTION; - - PRINTPAGERANGE ranges[32]; - dialog_options.nStartPage = START_PAGE_GENERAL; - if (max_pages) { - // Default initialize to print all the pages. - memset(ranges, 0, sizeof(ranges)); - ranges[0].nFromPage = 1; - ranges[0].nToPage = max_pages; - dialog_options.nPageRanges = 1; - dialog_options.nMaxPageRanges = arraysize(ranges); - dialog_options.nMinPage = 1; - dialog_options.nMaxPage = max_pages; - dialog_options.lpPageRanges = ranges; - } else { - // No need to bother, we don't know how many pages are available. - dialog_options.Flags |= PD_NOPAGENUMS; - } - - if (ShowPrintDialog(&dialog_options) != S_OK) { - ResetSettings(); - callback.Run(FAILED); - } - - // TODO(maruel): Support PD_PRINTTOFILE. - callback.Run(ParseDialogResultEx(dialog_options)); + NOTIMPLEMENTED(); } PrintingContext::Result PrintingContextWin::UseDefaultSettings() { DCHECK(!in_print_job_); - PRINTDLG dialog_options = { sizeof(PRINTDLG) }; - dialog_options.Flags = PD_RETURNDC | PD_RETURNDEFAULT; - if (PrintDlg(&dialog_options)) - return ParseDialogResult(dialog_options); + scoped_refptr<PrintBackend> backend = PrintBackend::CreateInstance(NULL); + base::string16 default_printer = + base::UTF8ToWide(backend->GetDefaultPrinterName()); + if (!default_printer.empty()) { + ScopedPrinterHandle printer; + if (printer.OpenPrinter(default_printer.c_str())) { + scoped_ptr<DEVMODE, base::FreeDeleter> dev_mode = + CreateDevMode(printer, NULL); + if (InitializeSettings(default_printer, dev_mode.get()) == OK) + return OK; + } + } + + ReleaseContext(); // No default printer configured, do we have any printers at all? DWORD bytes_needed = 0; @@ -142,23 +105,15 @@ PrintingContext::Result PrintingContextWin::UseDefaultSettings() { continue; scoped_ptr<DEVMODE, base::FreeDeleter> dev_mode = CreateDevMode(printer, NULL); - if (!dev_mode || !AllocateContext(info_2->pPrinterName, dev_mode.get(), - &context_)) { - continue; - } - if (InitializeSettings(*dev_mode.get(), info_2->pPrinterName, NULL, 0, - false)) { + if (InitializeSettings(info_2->pPrinterName, dev_mode.get()) == OK) return OK; - } - ReleaseContext(); } if (context_) return OK; } } - ResetSettings(); - return FAILED; + return OnError(); } gfx::Size PrintingContextWin::GetPdfPaperSizeDeviceUnits() { @@ -192,7 +147,8 @@ gfx::Size PrintingContextWin::GetPdfPaperSizeDeviceUnits() { } PrintingContext::Result PrintingContextWin::UpdatePrinterSettings( - bool external_preview) { + bool external_preview, + bool show_system_dialog) { DCHECK(!in_print_job_); DCHECK(!external_preview) << "Not implemented"; @@ -256,19 +212,14 @@ PrintingContext::Result PrintingContextWin::UpdatePrinterSettings( } // Update data using DocumentProperties. - scoped_dev_mode = CreateDevMode(printer, scoped_dev_mode.get()); - if (!scoped_dev_mode) - return OnError(); - - // Set printer then refresh printer settings. - if (!AllocateContext(settings_.device_name(), scoped_dev_mode.get(), - &context_)) { - return OnError(); + if (show_system_dialog) { + scoped_dev_mode = ShowPrintDialog( + printer, delegate_->GetParentView(), scoped_dev_mode.get()); + } else { + scoped_dev_mode = CreateDevMode(printer, scoped_dev_mode.get()); } - PrintSettingsInitializerWin::InitPrintSettings(context_, - *scoped_dev_mode.get(), - &settings_); - return OK; + // Set printer then refresh printer settings. + return InitializeSettings(settings_.device_name(), scoped_dev_mode.get()); } PrintingContext::Result PrintingContextWin::InitWithSettings( @@ -279,18 +230,13 @@ PrintingContext::Result PrintingContextWin::InitWithSettings( // TODO(maruel): settings_.ToDEVMODE() ScopedPrinterHandle printer; - if (!printer.OpenPrinter(settings_.device_name().c_str())) { + if (!printer.OpenPrinter(settings_.device_name().c_str())) return FAILED; - } - - Result status = OK; - if (!GetPrinterSettings(printer, settings_.device_name())) - status = FAILED; + scoped_ptr<DEVMODE, base::FreeDeleter> dev_mode = + CreateDevMode(printer, NULL); - if (status != OK) - ResetSettings(); - return status; + return InitializeSettings(settings_.device_name(), dev_mode.get()); } PrintingContext::Result PrintingContextWin::NewDocument( @@ -374,10 +320,6 @@ void PrintingContextWin::Cancel() { in_print_job_ = false; if (context_) CancelDC(context_); - if (dialog_box_) { - DestroyWindow(dialog_box_); - dialog_box_dismissed_ = true; - } } void PrintingContextWin::ReleaseContext() { @@ -401,154 +343,31 @@ BOOL PrintingContextWin::AbortProc(HDC hdc, int nCode) { return true; } -bool PrintingContextWin::InitializeSettings(const DEVMODE& dev_mode, - const std::wstring& new_device_name, - const PRINTPAGERANGE* ranges, - int number_ranges, - bool selection_only) { - skia::InitializeDC(context_); - DCHECK(GetDeviceCaps(context_, CLIPCAPS)); - DCHECK(GetDeviceCaps(context_, RASTERCAPS) & RC_STRETCHDIB); - DCHECK(GetDeviceCaps(context_, RASTERCAPS) & RC_BITMAP64); - // Some printers don't advertise these. - // DCHECK(GetDeviceCaps(context_, RASTERCAPS) & RC_SCALING); - // DCHECK(GetDeviceCaps(context_, SHADEBLENDCAPS) & SB_CONST_ALPHA); - // DCHECK(GetDeviceCaps(context_, SHADEBLENDCAPS) & SB_PIXEL_ALPHA); - - // StretchDIBits() support is needed for printing. - if (!(GetDeviceCaps(context_, RASTERCAPS) & RC_STRETCHDIB) || - !(GetDeviceCaps(context_, RASTERCAPS) & RC_BITMAP64)) { - NOTREACHED(); - ResetSettings(); - return false; - } - - DCHECK(!in_print_job_); - DCHECK(context_); - PageRanges ranges_vector; - if (!selection_only) { - // Convert the PRINTPAGERANGE array to a PrintSettings::PageRanges vector. - ranges_vector.reserve(number_ranges); - for (int i = 0; i < number_ranges; ++i) { - PageRange range; - // Transfer from 1-based to 0-based. - range.from = ranges[i].nFromPage - 1; - range.to = ranges[i].nToPage - 1; - ranges_vector.push_back(range); - } - } +PrintingContext::Result PrintingContextWin::InitializeSettings( + const std::wstring& device_name, + DEVMODE* dev_mode) { + if (!dev_mode) + return OnError(); - settings_.set_ranges(ranges_vector); - settings_.set_device_name(new_device_name); - settings_.set_selection_only(selection_only); - PrintSettingsInitializerWin::InitPrintSettings(context_, dev_mode, - &settings_); + ReleaseContext(); + context_ = CreateDC(L"WINSPOOL", device_name.c_str(), NULL, dev_mode); + if (!context_) + return OnError(); - return true; -} + skia::InitializeDC(context_); -bool PrintingContextWin::GetPrinterSettings(HANDLE printer, - const std::wstring& device_name) { DCHECK(!in_print_job_); + settings_.set_device_name(device_name); + PrintSettingsInitializerWin::InitPrintSettings( + context_, *dev_mode, &settings_); - scoped_ptr<DEVMODE, base::FreeDeleter> dev_mode = - CreateDevMode(printer, NULL); - - if (!dev_mode || !AllocateContext(device_name, dev_mode.get(), &context_)) { - ResetSettings(); - return false; - } - - return InitializeSettings(*dev_mode.get(), device_name, NULL, 0, false); -} - -// static -bool PrintingContextWin::AllocateContext(const std::wstring& device_name, - const DEVMODE* dev_mode, - gfx::NativeDrawingContext* context) { - *context = CreateDC(L"WINSPOOL", device_name.c_str(), NULL, dev_mode); - DCHECK(*context); - return *context != NULL; -} - -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) { - // Start fresh. - ResetSettings(); - - DEVMODE* dev_mode = NULL; - if (dialog_options.hDevMode) { - dev_mode = - reinterpret_cast<DEVMODE*>(GlobalLock(dialog_options.hDevMode)); - DCHECK(dev_mode); - } - - std::wstring device_name; - if (dialog_options.hDevNames) { - DEVNAMES* dev_names = - reinterpret_cast<DEVNAMES*>(GlobalLock(dialog_options.hDevNames)); - DCHECK(dev_names); - if (dev_names) { - device_name = reinterpret_cast<const wchar_t*>(dev_names) + - dev_names->wDeviceOffset; - GlobalUnlock(dialog_options.hDevNames); - } - } - - bool success = false; - if (dev_mode && !device_name.empty()) { - context_ = dialog_options.hDC; - PRINTPAGERANGE* page_ranges = NULL; - DWORD num_page_ranges = 0; - bool print_selection_only = false; - if (dialog_options.Flags & PD_PAGENUMS) { - page_ranges = dialog_options.lpPageRanges; - num_page_ranges = dialog_options.nPageRanges; - } - if (dialog_options.Flags & PD_SELECTION) { - print_selection_only = true; - } - success = InitializeSettings(*dev_mode, - device_name, - page_ranges, - num_page_ranges, - print_selection_only); - } - - if (!success && dialog_options.hDC) { - DeleteDC(dialog_options.hDC); - context_ = NULL; - } - - if (dev_mode) { - GlobalUnlock(dialog_options.hDevMode); - } - } else { - if (dialog_options.hDC) { - DeleteDC(dialog_options.hDC); - } - } - - if (dialog_options.hDevMode != NULL) - GlobalFree(dialog_options.hDevMode); - if (dialog_options.hDevNames != NULL) - GlobalFree(dialog_options.hDevNames); - - switch (dialog_options.dwResultAction) { - case PD_RESULT_PRINT: - return context_ ? OK : FAILED; - case PD_RESULT_APPLY: - return context_ ? CANCEL : FAILED; - case PD_RESULT_CANCEL: - return CANCEL; - default: - return FAILED; - } + return OK; } -HRESULT PrintingContextWin::ShowPrintDialog(PRINTDLGEX* options) { +scoped_ptr<DEVMODE, base::FreeDeleter> PrintingContextWin::ShowPrintDialog( + HANDLE printer, + gfx::NativeView parent_view, + DEVMODE* dev_mode) { // Note that this cannot use ui::BaseShellDialog as the print dialog is // system modal: opening it from a background thread can cause Windows to // get the wrong Z-order which will make the print dialog appear behind the @@ -558,57 +377,20 @@ HRESULT PrintingContextWin::ShowPrintDialog(PRINTDLGEX* options) { base::MessageLoop::ScopedNestableTaskAllower allow( base::MessageLoop::current()); - return PrintDlgEx(options); -} - -PrintingContext::Result PrintingContextWin::ParseDialogResult( - const PRINTDLG& dialog_options) { - // If the user clicked OK or Apply then Cancel, but not only Cancel. - // Start fresh. - ResetSettings(); - - DEVMODE* dev_mode = NULL; - if (dialog_options.hDevMode) { - dev_mode = - reinterpret_cast<DEVMODE*>(GlobalLock(dialog_options.hDevMode)); - DCHECK(dev_mode); + bool canceled = false; + scoped_ptr<DEVMODE, base::FreeDeleter> result = + PromptDevMode(printer, + settings_.device_name(), + dev_mode, + GetRootWindow(parent_view), + &canceled); + + if (canceled) { + result.reset(); + abort_printing_ = true; } - std::wstring device_name; - if (dialog_options.hDevNames) { - DEVNAMES* dev_names = - reinterpret_cast<DEVNAMES*>(GlobalLock(dialog_options.hDevNames)); - DCHECK(dev_names); - if (dev_names) { - device_name = - reinterpret_cast<const wchar_t*>( - reinterpret_cast<const wchar_t*>(dev_names) + - dev_names->wDeviceOffset); - GlobalUnlock(dialog_options.hDevNames); - } - } - - bool success = false; - if (dev_mode && !device_name.empty()) { - context_ = dialog_options.hDC; - success = InitializeSettings(*dev_mode, device_name, NULL, 0, false); - } - - if (!success && dialog_options.hDC) { - DeleteDC(dialog_options.hDC); - context_ = NULL; - } - - if (dev_mode) { - GlobalUnlock(dialog_options.hDevMode); - } - - if (dialog_options.hDevMode != NULL) - GlobalFree(dialog_options.hDevMode); - if (dialog_options.hDevNames != NULL) - GlobalFree(dialog_options.hDevNames); - - return context_ ? OK : FAILED; + return result.Pass(); } } // namespace printing diff --git a/printing/printing_context_win.h b/printing/printing_context_win.h index 94fd041..99a7e3e 100644 --- a/printing/printing_context_win.h +++ b/printing/printing_context_win.h @@ -29,7 +29,8 @@ class PRINTING_EXPORT PrintingContextWin : public PrintingContext { const PrintSettingsCallback& callback) OVERRIDE; virtual Result UseDefaultSettings() OVERRIDE; virtual gfx::Size GetPdfPaperSizeDeviceUnits() OVERRIDE; - virtual Result UpdatePrinterSettings(bool external_preview) OVERRIDE; + virtual Result UpdatePrinterSettings(bool external_preview, + bool show_system_dialog) OVERRIDE; virtual Result InitWithSettings(const PrintSettings& settings) OVERRIDE; virtual Result NewDocument(const base::string16& document_name) OVERRIDE; virtual Result NewPage() OVERRIDE; @@ -39,45 +40,24 @@ class PRINTING_EXPORT PrintingContextWin : public PrintingContext { virtual void ReleaseContext() OVERRIDE; virtual gfx::NativeDrawingContext context() const OVERRIDE; - // Allocates the HDC for a specific DEVMODE. - static bool AllocateContext(const std::wstring& printer_name, - const DEVMODE* dev_mode, - gfx::NativeDrawingContext* context); - protected: - virtual HRESULT ShowPrintDialog(PRINTDLGEX* options); + virtual scoped_ptr<DEVMODE, base::FreeDeleter> ShowPrintDialog( + HANDLE printer, + gfx::NativeView parent_view, + DEVMODE* dev_mode); 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); + virtual Result InitializeSettings(const base::string16& device_name, + DEVMODE* dev_mode); // The selected printer context. HDC context_; - // The dialog box for the time it is shown. - volatile HWND dialog_box_; - DISALLOW_COPY_AND_ASSIGN(PrintingContextWin); }; diff --git a/printing/printing_context_win_unittest.cc b/printing/printing_context_win_unittest.cc index 1d27935..5147249 100644 --- a/printing/printing_context_win_unittest.cc +++ b/printing/printing_context_win_unittest.cc @@ -2,20 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include <ocidl.h> -#include <commdlg.h> - -#include <string> +#include "printing/printing_context_win.h" -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/memory/scoped_ptr.h" -#include "base/message_loop/message_loop.h" -#include "printing/backend/printing_info_win.h" -#include "printing/backend/win_helper.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" @@ -40,123 +29,6 @@ class PrintingContextTest : public PrintingTest<testing::Test>, PrintingContext::Result result_; }; -class MockPrintingContextWin : public PrintingContextWin { - public: - MockPrintingContextWin(Delegate* delegate) : PrintingContextWin(delegate) {} - - protected: - // This is a fake PrintDlgEx implementation that sets the right fields in - // |lppd| to trigger a bug in older revisions of PrintingContext. - HRESULT ShowPrintDialog(PRINTDLGEX* lppd) OVERRIDE { - // The interesting bits: - // Pretend the user hit print - lppd->dwResultAction = PD_RESULT_PRINT; - - // Pretend the page range is 1-5, but since lppd->Flags does not have - // PD_SELECTION set, this really shouldn't matter. - lppd->nPageRanges = 1; - lppd->lpPageRanges[0].nFromPage = 1; - lppd->lpPageRanges[0].nToPage = 5; - - base::string16 printer_name = PrintingContextTest::GetDefaultPrinter(); - ScopedPrinterHandle printer; - if (!printer.OpenPrinter(printer_name.c_str())) - return E_FAIL; - - scoped_ptr<uint8[]> buffer; - const DEVMODE* dev_mode = NULL; - HRESULT result = S_OK; - lppd->hDC = NULL; - lppd->hDevMode = NULL; - lppd->hDevNames = NULL; - - PrinterInfo2 info_2; - if (info_2.Init(printer)) { - dev_mode = info_2.get()->pDevMode; - } - if (!dev_mode) { - result = E_FAIL; - goto Cleanup; - } - - if (!PrintingContextWin::AllocateContext( - printer_name, dev_mode, &lppd->hDC)) { - result = E_FAIL; - goto Cleanup; - } - - size_t dev_mode_size = dev_mode->dmSize + dev_mode->dmDriverExtra; - lppd->hDevMode = GlobalAlloc(GMEM_MOVEABLE, dev_mode_size); - if (!lppd->hDevMode) { - result = E_FAIL; - goto Cleanup; - } - void* dev_mode_ptr = GlobalLock(lppd->hDevMode); - if (!dev_mode_ptr) { - result = E_FAIL; - goto Cleanup; - } - memcpy(dev_mode_ptr, dev_mode, dev_mode_size); - GlobalUnlock(lppd->hDevMode); - dev_mode_ptr = NULL; - - size_t driver_size = - 2 + sizeof(wchar_t) * lstrlen(info_2.get()->pDriverName); - size_t printer_size = - 2 + sizeof(wchar_t) * lstrlen(info_2.get()->pPrinterName); - size_t port_size = 2 + sizeof(wchar_t) * lstrlen(info_2.get()->pPortName); - size_t dev_names_size = - sizeof(DEVNAMES) + driver_size + printer_size + port_size; - lppd->hDevNames = GlobalAlloc(GHND, dev_names_size); - if (!lppd->hDevNames) { - result = E_FAIL; - goto Cleanup; - } - void* dev_names_ptr = GlobalLock(lppd->hDevNames); - if (!dev_names_ptr) { - result = E_FAIL; - goto Cleanup; - } - DEVNAMES* dev_names = reinterpret_cast<DEVNAMES*>(dev_names_ptr); - dev_names->wDefault = 1; - dev_names->wDriverOffset = sizeof(DEVNAMES) / sizeof(wchar_t); - memcpy(reinterpret_cast<uint8*>(dev_names_ptr) + dev_names->wDriverOffset, - info_2.get()->pDriverName, - driver_size); - dev_names->wDeviceOffset = - dev_names->wDriverOffset + driver_size / sizeof(wchar_t); - memcpy(reinterpret_cast<uint8*>(dev_names_ptr) + dev_names->wDeviceOffset, - info_2.get()->pPrinterName, - printer_size); - dev_names->wOutputOffset = - dev_names->wDeviceOffset + printer_size / sizeof(wchar_t); - memcpy(reinterpret_cast<uint8*>(dev_names_ptr) + dev_names->wOutputOffset, - info_2.get()->pPortName, - port_size); - GlobalUnlock(lppd->hDevNames); - dev_names_ptr = NULL; - - Cleanup: - // Note: This section does proper deallocation/free of DC/global handles. We - // did not use ScopedHGlobal or ScopedHandle because they did not - // perform what we need. Goto's are used based on Windows programming - // idiom, to avoid deeply nested if's, and try-catch-finally is not - // allowed in Chromium. - if (FAILED(result)) { - if (lppd->hDC) { - DeleteDC(lppd->hDC); - } - if (lppd->hDevMode) { - GlobalFree(lppd->hDevMode); - } - if (lppd->hDevNames) { - GlobalFree(lppd->hDevNames); - } - } - return result; - } -}; - TEST_F(PrintingContextTest, Base) { if (IsTestCaseDisabled()) return; @@ -174,20 +46,4 @@ TEST_F(PrintingContextTest, Base) { EXPECT_TRUE(ModifyWorldTransform(context->context(), NULL, MWT_IDENTITY)); } -TEST_F(PrintingContextTest, PrintAll) { - base::MessageLoop message_loop; - if (IsTestCaseDisabled()) - return; - - MockPrintingContextWin context(this); - context.AskUserForSettings( - 123, - false, - base::Bind(&PrintingContextTest::PrintSettingsCallback, - base::Unretained(this))); - EXPECT_EQ(PrintingContext::OK, result()); - PrintSettings settings = context.settings(); - EXPECT_EQ(settings.ranges().size(), 0); -} - } // namespace printing |