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 |