| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "printing/printing_context_system_dialog_win.h" | 5 #include "printing/printing_context_system_dialog_win.h" |
| 6 | 6 |
| 7 #include "base/auto_reset.h" | 7 #include "base/auto_reset.h" |
| 8 #include "base/macros.h" | 8 #include "base/macros.h" |
| 9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
| 10 #include "printing/backend/win_helper.h" | 10 #include "printing/backend/win_helper.h" |
| 11 #include "printing/print_settings_initializer_win.h" | 11 #include "printing/print_settings_initializer_win.h" |
| 12 #include "skia/ext/skia_utils_win.h" | 12 #include "skia/ext/skia_utils_win.h" |
| 13 | 13 |
| 14 namespace printing { | 14 namespace printing { |
| 15 | 15 |
| 16 PrintingContextSytemDialogWin::PrintingContextSytemDialogWin(Delegate* delegate) | 16 PrintingContextSystemDialogWin::PrintingContextSystemDialogWin( |
| 17 : PrintingContextWin(delegate) { | 17 Delegate* delegate) |
| 18 } | 18 : PrintingContextWin(delegate) {} |
| 19 | 19 |
| 20 PrintingContextSytemDialogWin::~PrintingContextSytemDialogWin() { | 20 PrintingContextSystemDialogWin::~PrintingContextSystemDialogWin() {} |
| 21 } | |
| 22 | 21 |
| 23 void PrintingContextSytemDialogWin::AskUserForSettings( | 22 void PrintingContextSystemDialogWin::AskUserForSettings( |
| 24 int max_pages, | 23 int max_pages, |
| 25 bool has_selection, | 24 bool has_selection, |
| 26 bool is_scripted, | 25 bool is_scripted, |
| 27 const PrintSettingsCallback& callback) { | 26 const PrintSettingsCallback& callback) { |
| 28 DCHECK(!in_print_job_); | 27 DCHECK(!in_print_job_); |
| 29 | 28 |
| 30 HWND window = GetRootWindow(delegate_->GetParentView()); | 29 HWND window = GetRootWindow(delegate_->GetParentView()); |
| 31 DCHECK(window); | 30 DCHECK(window); |
| 32 | 31 |
| 33 // Show the OS-dependent dialog box. | 32 // Show the OS-dependent dialog box. |
| 34 // If the user press | 33 // If the user press |
| 35 // - OK, the settings are reset and reinitialized with the new settings. OK | 34 // - OK, the settings are reset and reinitialized with the new settings. OK is |
| 36 // is | |
| 37 // returned. | 35 // returned. |
| 38 // - Apply then Cancel, the settings are reset and reinitialized with the | 36 // - Apply then Cancel, the settings are reset and reinitialized with the new |
| 39 // new | |
| 40 // settings. CANCEL is returned. | 37 // settings. CANCEL is returned. |
| 41 // - Cancel, the settings are not changed, the previous setting, if it was | 38 // - Cancel, the settings are not changed, the previous setting, if it was |
| 42 // initialized before, are kept. CANCEL is returned. | 39 // initialized before, are kept. CANCEL is returned. |
| 43 // On failure, the settings are reset and FAILED is returned. | 40 // On failure, the settings are reset and FAILED is returned. |
| 44 PRINTDLGEX dialog_options = {sizeof(PRINTDLGEX)}; | 41 PRINTDLGEX dialog_options = {sizeof(PRINTDLGEX)}; |
| 45 dialog_options.hwndOwner = window; | 42 dialog_options.hwndOwner = window; |
| 46 // Disable options we don't support currently. | 43 // Disable options we don't support currently. |
| 47 // TODO(maruel): Reuse the previously loaded settings! | 44 // TODO(maruel): Reuse the previously loaded settings! |
| 48 dialog_options.Flags = PD_RETURNDC | PD_USEDEVMODECOPIESANDCOLLATE | | 45 dialog_options.Flags = PD_RETURNDC | PD_USEDEVMODECOPIESANDCOLLATE | |
| 49 PD_NOCURRENTPAGE | PD_HIDEPRINTTOFILE; | 46 PD_NOCURRENTPAGE | PD_HIDEPRINTTOFILE; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 70 if (ShowPrintDialog(&dialog_options) != S_OK) { | 67 if (ShowPrintDialog(&dialog_options) != S_OK) { |
| 71 ResetSettings(); | 68 ResetSettings(); |
| 72 callback.Run(FAILED); | 69 callback.Run(FAILED); |
| 73 return; | 70 return; |
| 74 } | 71 } |
| 75 | 72 |
| 76 // TODO(maruel): Support PD_PRINTTOFILE. | 73 // TODO(maruel): Support PD_PRINTTOFILE. |
| 77 callback.Run(ParseDialogResultEx(dialog_options)); | 74 callback.Run(ParseDialogResultEx(dialog_options)); |
| 78 } | 75 } |
| 79 | 76 |
| 80 HRESULT PrintingContextSytemDialogWin::ShowPrintDialog(PRINTDLGEX* options) { | 77 HRESULT PrintingContextSystemDialogWin::ShowPrintDialog(PRINTDLGEX* options) { |
| 81 // Runs always on the UI thread. | 78 // Runs always on the UI thread. |
| 82 static bool is_dialog_shown = false; | 79 static bool is_dialog_shown = false; |
| 83 if (is_dialog_shown) | 80 if (is_dialog_shown) |
| 84 return E_FAIL; | 81 return E_FAIL; |
| 85 // Block opening dialog from nested task. It crashes PrintDlgEx. | 82 // Block opening dialog from nested task. It crashes PrintDlgEx. |
| 86 base::AutoReset<bool> auto_reset(&is_dialog_shown, true); | 83 base::AutoReset<bool> auto_reset(&is_dialog_shown, true); |
| 87 | 84 |
| 88 // Note that this cannot use ui::BaseShellDialog as the print dialog is | 85 // Note that this cannot use ui::BaseShellDialog as the print dialog is |
| 89 // system modal: opening it from a background thread can cause Windows to | 86 // system modal: opening it from a background thread can cause Windows to |
| 90 // get the wrong Z-order which will make the print dialog appear behind the | 87 // get the wrong Z-order which will make the print dialog appear behind the |
| 91 // browser frame (but still being modal) so neither the browser frame nor | 88 // browser frame (but still being modal) so neither the browser frame nor |
| 92 // the print dialog will get any input. See http://crbug.com/342697 | 89 // the print dialog will get any input. See http://crbug.com/342697 |
| 93 // http://crbug.com/180997 for details. | 90 // http://crbug.com/180997 for details. |
| 94 base::MessageLoop::ScopedNestableTaskAllower allow( | 91 base::MessageLoop::ScopedNestableTaskAllower allow( |
| 95 base::MessageLoop::current()); | 92 base::MessageLoop::current()); |
| 96 | 93 |
| 97 return PrintDlgEx(options); | 94 return PrintDlgEx(options); |
| 98 } | 95 } |
| 99 | 96 |
| 100 bool PrintingContextSytemDialogWin::InitializeSettingsWithRanges( | 97 bool PrintingContextSystemDialogWin::InitializeSettingsWithRanges( |
| 101 const DEVMODE& dev_mode, | 98 const DEVMODE& dev_mode, |
| 102 const std::wstring& new_device_name, | 99 const std::wstring& new_device_name, |
| 103 const PRINTPAGERANGE* ranges, | 100 const PRINTPAGERANGE* ranges, |
| 104 int number_ranges, | 101 int number_ranges, |
| 105 bool selection_only) { | 102 bool selection_only) { |
| 106 DCHECK(GetDeviceCaps(context(), CLIPCAPS)); | 103 DCHECK(GetDeviceCaps(context(), CLIPCAPS)); |
| 107 DCHECK(GetDeviceCaps(context(), RASTERCAPS) & RC_STRETCHDIB); | 104 DCHECK(GetDeviceCaps(context(), RASTERCAPS) & RC_STRETCHDIB); |
| 108 DCHECK(GetDeviceCaps(context(), RASTERCAPS) & RC_BITMAP64); | 105 DCHECK(GetDeviceCaps(context(), RASTERCAPS) & RC_BITMAP64); |
| 109 // Some printers don't advertise these. | 106 // Some printers don't advertise these. |
| 110 // DCHECK(GetDeviceCaps(context(), RASTERCAPS) & RC_SCALING); | 107 // DCHECK(GetDeviceCaps(context(), RASTERCAPS) & RC_SCALING); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 136 | 133 |
| 137 settings_.set_ranges(ranges_vector); | 134 settings_.set_ranges(ranges_vector); |
| 138 settings_.set_device_name(new_device_name); | 135 settings_.set_device_name(new_device_name); |
| 139 settings_.set_selection_only(selection_only); | 136 settings_.set_selection_only(selection_only); |
| 140 PrintSettingsInitializerWin::InitPrintSettings( | 137 PrintSettingsInitializerWin::InitPrintSettings( |
| 141 context(), dev_mode, &settings_); | 138 context(), dev_mode, &settings_); |
| 142 | 139 |
| 143 return true; | 140 return true; |
| 144 } | 141 } |
| 145 | 142 |
| 146 PrintingContext::Result PrintingContextSytemDialogWin::ParseDialogResultEx( | 143 PrintingContext::Result PrintingContextSystemDialogWin::ParseDialogResultEx( |
| 147 const PRINTDLGEX& dialog_options) { | 144 const PRINTDLGEX& dialog_options) { |
| 148 // If the user clicked OK or Apply then Cancel, but not only Cancel. | 145 // If the user clicked OK or Apply then Cancel, but not only Cancel. |
| 149 if (dialog_options.dwResultAction != PD_RESULT_CANCEL) { | 146 if (dialog_options.dwResultAction != PD_RESULT_CANCEL) { |
| 150 // Start fresh. | 147 // Start fresh, but preserve GDI print setting. |
| 148 bool print_text_with_gdi = settings_.print_text_with_gdi(); |
| 151 ResetSettings(); | 149 ResetSettings(); |
| 150 settings_.set_print_text_with_gdi(print_text_with_gdi); |
| 152 | 151 |
| 153 DEVMODE* dev_mode = NULL; | 152 DEVMODE* dev_mode = NULL; |
| 154 if (dialog_options.hDevMode) { | 153 if (dialog_options.hDevMode) { |
| 155 dev_mode = | 154 dev_mode = |
| 156 reinterpret_cast<DEVMODE*>(GlobalLock(dialog_options.hDevMode)); | 155 reinterpret_cast<DEVMODE*>(GlobalLock(dialog_options.hDevMode)); |
| 157 DCHECK(dev_mode); | 156 DCHECK(dev_mode); |
| 158 } | 157 } |
| 159 | 158 |
| 160 std::wstring device_name; | 159 std::wstring device_name; |
| 161 if (dialog_options.hDevNames) { | 160 if (dialog_options.hDevNames) { |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 211 return context() ? OK : FAILED; | 210 return context() ? OK : FAILED; |
| 212 case PD_RESULT_APPLY: | 211 case PD_RESULT_APPLY: |
| 213 return context() ? CANCEL : FAILED; | 212 return context() ? CANCEL : FAILED; |
| 214 case PD_RESULT_CANCEL: | 213 case PD_RESULT_CANCEL: |
| 215 return CANCEL; | 214 return CANCEL; |
| 216 default: | 215 default: |
| 217 return FAILED; | 216 return FAILED; |
| 218 } | 217 } |
| 219 } | 218 } |
| 220 | 219 |
| 221 PrintingContext::Result PrintingContextSytemDialogWin::ParseDialogResult( | |
| 222 const PRINTDLG& dialog_options) { | |
| 223 // If the user clicked OK or Apply then Cancel, but not only Cancel. | |
| 224 // Start fresh. | |
| 225 ResetSettings(); | |
| 226 | |
| 227 DEVMODE* dev_mode = NULL; | |
| 228 if (dialog_options.hDevMode) { | |
| 229 dev_mode = reinterpret_cast<DEVMODE*>(GlobalLock(dialog_options.hDevMode)); | |
| 230 DCHECK(dev_mode); | |
| 231 } | |
| 232 | |
| 233 std::wstring device_name; | |
| 234 if (dialog_options.hDevNames) { | |
| 235 DEVNAMES* dev_names = | |
| 236 reinterpret_cast<DEVNAMES*>(GlobalLock(dialog_options.hDevNames)); | |
| 237 DCHECK(dev_names); | |
| 238 if (dev_names) { | |
| 239 device_name = reinterpret_cast<const wchar_t*>( | |
| 240 reinterpret_cast<const wchar_t*>(dev_names) + | |
| 241 dev_names->wDeviceOffset); | |
| 242 GlobalUnlock(dialog_options.hDevNames); | |
| 243 } | |
| 244 } | |
| 245 | |
| 246 bool success = false; | |
| 247 if (dev_mode && !device_name.empty()) { | |
| 248 set_context(dialog_options.hDC); | |
| 249 success = | |
| 250 InitializeSettingsWithRanges(*dev_mode, device_name, NULL, 0, false); | |
| 251 } | |
| 252 | |
| 253 if (!success && dialog_options.hDC) { | |
| 254 DeleteDC(dialog_options.hDC); | |
| 255 set_context(NULL); | |
| 256 } | |
| 257 | |
| 258 if (dev_mode) { | |
| 259 GlobalUnlock(dialog_options.hDevMode); | |
| 260 } | |
| 261 | |
| 262 if (dialog_options.hDevMode != NULL) | |
| 263 GlobalFree(dialog_options.hDevMode); | |
| 264 if (dialog_options.hDevNames != NULL) | |
| 265 GlobalFree(dialog_options.hDevNames); | |
| 266 | |
| 267 return context() ? OK : FAILED; | |
| 268 } | |
| 269 | |
| 270 } // namespace printing | 220 } // namespace printing |
| OLD | NEW |