|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 /* ------------------------------------------------------------------- |
|
7 To Build This: |
|
8 |
|
9 You need to add this to the the makefile.win in mozilla/content/base/src: |
|
10 |
|
11 .\$(OBJDIR)\nsFlyOwnPrintDialog.obj \ |
|
12 |
|
13 |
|
14 And this to the makefile.win in mozilla/content/build: |
|
15 |
|
16 WIN_LIBS= \ |
|
17 winspool.lib \ |
|
18 comctl32.lib \ |
|
19 comdlg32.lib |
|
20 |
|
21 ---------------------------------------------------------------------- */ |
|
22 |
|
23 #define NOMINMAX 1 |
|
24 |
|
25 #include "plstr.h" |
|
26 #include <windows.h> |
|
27 #include <tchar.h> |
|
28 |
|
29 #include <unknwn.h> |
|
30 #include <commdlg.h> |
|
31 |
|
32 #include "nsIWebBrowserPrint.h" |
|
33 #include "nsString.h" |
|
34 #include "nsIServiceManager.h" |
|
35 #include "nsReadableUtils.h" |
|
36 #include "nsIPrintSettings.h" |
|
37 #include "nsIPrintSettingsWin.h" |
|
38 #include "nsIPrintOptions.h" |
|
39 |
|
40 #include "nsRect.h" |
|
41 |
|
42 #include "nsIPrefService.h" |
|
43 #include "nsIPrefBranch.h" |
|
44 |
|
45 #include "nsCRT.h" |
|
46 #include "prenv.h" /* for PR_GetEnv */ |
|
47 |
|
48 #include <windows.h> |
|
49 #include <winspool.h> |
|
50 |
|
51 // For Localization |
|
52 #include "nsIStringBundle.h" |
|
53 |
|
54 // For NS_CopyUnicodeToNative |
|
55 #include "nsNativeCharsetUtils.h" |
|
56 |
|
57 // This is for extending the dialog |
|
58 #include <dlgs.h> |
|
59 |
|
60 // Default labels for the radio buttons |
|
61 static const char* kAsLaidOutOnScreenStr = "As &laid out on the screen"; |
|
62 static const char* kTheSelectedFrameStr = "The selected &frame"; |
|
63 static const char* kEachFrameSeparately = "&Each frame separately"; |
|
64 |
|
65 |
|
66 //----------------------------------------------- |
|
67 // Global Data |
|
68 //----------------------------------------------- |
|
69 // Identifies which new radio btn was cliked on |
|
70 static UINT gFrameSelectedRadioBtn = 0; |
|
71 |
|
72 // Indicates whether the native print dialog was successfully extended |
|
73 static bool gDialogWasExtended = false; |
|
74 |
|
75 #define PRINTDLG_PROPERTIES "chrome://global/locale/printdialog.properties" |
|
76 |
|
77 static HWND gParentWnd = nullptr; |
|
78 |
|
79 //****************************************************** |
|
80 // Define native paper sizes |
|
81 //****************************************************** |
|
82 typedef struct { |
|
83 short mPaperSize; // native enum |
|
84 double mWidth; |
|
85 double mHeight; |
|
86 bool mIsInches; |
|
87 } NativePaperSizes; |
|
88 |
|
89 // There are around 40 default print sizes defined by Windows |
|
90 const NativePaperSizes kPaperSizes[] = { |
|
91 {DMPAPER_LETTER, 8.5, 11.0, true}, |
|
92 {DMPAPER_LEGAL, 8.5, 14.0, true}, |
|
93 {DMPAPER_A4, 210.0, 297.0, false}, |
|
94 {DMPAPER_TABLOID, 11.0, 17.0, true}, |
|
95 {DMPAPER_LEDGER, 17.0, 11.0, true}, |
|
96 {DMPAPER_STATEMENT, 5.5, 8.5, true}, |
|
97 {DMPAPER_EXECUTIVE, 7.25, 10.5, true}, |
|
98 {DMPAPER_A3, 297.0, 420.0, false}, |
|
99 {DMPAPER_A5, 148.0, 210.0, false}, |
|
100 {DMPAPER_CSHEET, 17.0, 22.0, true}, |
|
101 {DMPAPER_DSHEET, 22.0, 34.0, true}, |
|
102 {DMPAPER_ESHEET, 34.0, 44.0, true}, |
|
103 {DMPAPER_LETTERSMALL, 8.5, 11.0, true}, |
|
104 {DMPAPER_A4SMALL, 210.0, 297.0, false}, |
|
105 {DMPAPER_B4, 250.0, 354.0, false}, |
|
106 {DMPAPER_B5, 182.0, 257.0, false}, |
|
107 {DMPAPER_FOLIO, 8.5, 13.0, true}, |
|
108 {DMPAPER_QUARTO, 215.0, 275.0, false}, |
|
109 {DMPAPER_10X14, 10.0, 14.0, true}, |
|
110 {DMPAPER_11X17, 11.0, 17.0, true}, |
|
111 {DMPAPER_NOTE, 8.5, 11.0, true}, |
|
112 {DMPAPER_ENV_9, 3.875, 8.875, true}, |
|
113 {DMPAPER_ENV_10, 40.125, 9.5, true}, |
|
114 {DMPAPER_ENV_11, 4.5, 10.375, true}, |
|
115 {DMPAPER_ENV_12, 4.75, 11.0, true}, |
|
116 {DMPAPER_ENV_14, 5.0, 11.5, true}, |
|
117 {DMPAPER_ENV_DL, 110.0, 220.0, false}, |
|
118 {DMPAPER_ENV_C5, 162.0, 229.0, false}, |
|
119 {DMPAPER_ENV_C3, 324.0, 458.0, false}, |
|
120 {DMPAPER_ENV_C4, 229.0, 324.0, false}, |
|
121 {DMPAPER_ENV_C6, 114.0, 162.0, false}, |
|
122 {DMPAPER_ENV_C65, 114.0, 229.0, false}, |
|
123 {DMPAPER_ENV_B4, 250.0, 353.0, false}, |
|
124 {DMPAPER_ENV_B5, 176.0, 250.0, false}, |
|
125 {DMPAPER_ENV_B6, 176.0, 125.0, false}, |
|
126 {DMPAPER_ENV_ITALY, 110.0, 230.0, false}, |
|
127 {DMPAPER_ENV_MONARCH, 3.875, 7.5, true}, |
|
128 {DMPAPER_ENV_PERSONAL, 3.625, 6.5, true}, |
|
129 {DMPAPER_FANFOLD_US, 14.875, 11.0, true}, |
|
130 {DMPAPER_FANFOLD_STD_GERMAN, 8.5, 12.0, true}, |
|
131 {DMPAPER_FANFOLD_LGL_GERMAN, 8.5, 13.0, true}, |
|
132 }; |
|
133 const int32_t kNumPaperSizes = 41; |
|
134 |
|
135 //---------------------------------------------------------------------------------- |
|
136 // Map an incoming size to a Windows Native enum in the DevMode |
|
137 static void |
|
138 MapPaperSizeToNativeEnum(LPDEVMODEW aDevMode, |
|
139 int16_t aType, |
|
140 double aW, |
|
141 double aH) |
|
142 { |
|
143 |
|
144 #ifdef DEBUG_rods |
|
145 BOOL doingOrientation = aDevMode->dmFields & DM_ORIENTATION; |
|
146 BOOL doingPaperSize = aDevMode->dmFields & DM_PAPERSIZE; |
|
147 BOOL doingPaperLength = aDevMode->dmFields & DM_PAPERLENGTH; |
|
148 BOOL doingPaperWidth = aDevMode->dmFields & DM_PAPERWIDTH; |
|
149 #endif |
|
150 |
|
151 const double kThreshold = 0.05; |
|
152 for (int32_t i=0;i<kNumPaperSizes;i++) { |
|
153 double width = kPaperSizes[i].mWidth; |
|
154 double height = kPaperSizes[i].mHeight; |
|
155 if (aW < width+kThreshold && aW > width-kThreshold && |
|
156 aH < height+kThreshold && aH > height-kThreshold) { |
|
157 aDevMode->dmPaperSize = kPaperSizes[i].mPaperSize; |
|
158 aDevMode->dmFields &= ~DM_PAPERLENGTH; |
|
159 aDevMode->dmFields &= ~DM_PAPERWIDTH; |
|
160 aDevMode->dmFields |= DM_PAPERSIZE; |
|
161 return; |
|
162 } |
|
163 } |
|
164 |
|
165 short width = 0; |
|
166 short height = 0; |
|
167 if (aType == nsIPrintSettings::kPaperSizeInches) { |
|
168 width = short(NS_TWIPS_TO_MILLIMETERS(NS_INCHES_TO_TWIPS(float(aW))) / 10); |
|
169 height = short(NS_TWIPS_TO_MILLIMETERS(NS_INCHES_TO_TWIPS(float(aH))) / 10); |
|
170 |
|
171 } else if (aType == nsIPrintSettings::kPaperSizeMillimeters) { |
|
172 width = short(aW / 10.0); |
|
173 height = short(aH / 10.0); |
|
174 } else { |
|
175 return; // don't set anything |
|
176 } |
|
177 |
|
178 // width and height is in |
|
179 aDevMode->dmPaperSize = 0; |
|
180 aDevMode->dmPaperWidth = width; |
|
181 aDevMode->dmPaperLength = height; |
|
182 |
|
183 aDevMode->dmFields |= DM_PAPERSIZE; |
|
184 aDevMode->dmFields |= DM_PAPERLENGTH; |
|
185 aDevMode->dmFields |= DM_PAPERWIDTH; |
|
186 } |
|
187 |
|
188 //---------------------------------------------------------------------------------- |
|
189 // Setup Paper Size & Orientation options into the DevMode |
|
190 // |
|
191 static void |
|
192 SetupDevModeFromSettings(LPDEVMODEW aDevMode, nsIPrintSettings* aPrintSettings) |
|
193 { |
|
194 // Setup paper size |
|
195 if (aPrintSettings) { |
|
196 int16_t type; |
|
197 aPrintSettings->GetPaperSizeType(&type); |
|
198 if (type == nsIPrintSettings::kPaperSizeNativeData) { |
|
199 int16_t paperEnum; |
|
200 aPrintSettings->GetPaperData(&paperEnum); |
|
201 aDevMode->dmPaperSize = paperEnum; |
|
202 aDevMode->dmFields &= ~DM_PAPERLENGTH; |
|
203 aDevMode->dmFields &= ~DM_PAPERWIDTH; |
|
204 aDevMode->dmFields |= DM_PAPERSIZE; |
|
205 } else { |
|
206 int16_t unit; |
|
207 double width, height; |
|
208 aPrintSettings->GetPaperSizeUnit(&unit); |
|
209 aPrintSettings->GetPaperWidth(&width); |
|
210 aPrintSettings->GetPaperHeight(&height); |
|
211 MapPaperSizeToNativeEnum(aDevMode, unit, width, height); |
|
212 } |
|
213 |
|
214 // Setup Orientation |
|
215 int32_t orientation; |
|
216 aPrintSettings->GetOrientation(&orientation); |
|
217 aDevMode->dmOrientation = orientation == nsIPrintSettings::kPortraitOrientation?DMORIENT_PORTRAIT:DMORIENT_LANDSCAPE; |
|
218 aDevMode->dmFields |= DM_ORIENTATION; |
|
219 |
|
220 // Setup Number of Copies |
|
221 int32_t copies; |
|
222 aPrintSettings->GetNumCopies(&copies); |
|
223 aDevMode->dmCopies = copies; |
|
224 aDevMode->dmFields |= DM_COPIES; |
|
225 |
|
226 } |
|
227 |
|
228 } |
|
229 |
|
230 //---------------------------------------------------------------------------------- |
|
231 // Helper Function - Free and reallocate the string |
|
232 static nsresult |
|
233 SetPrintSettingsFromDevMode(nsIPrintSettings* aPrintSettings, |
|
234 LPDEVMODEW aDevMode) |
|
235 { |
|
236 if (aPrintSettings == nullptr) { |
|
237 return NS_ERROR_FAILURE; |
|
238 } |
|
239 |
|
240 aPrintSettings->SetIsInitializedFromPrinter(true); |
|
241 if (aDevMode->dmFields & DM_ORIENTATION) { |
|
242 int32_t orientation = aDevMode->dmOrientation == DMORIENT_PORTRAIT? |
|
243 nsIPrintSettings::kPortraitOrientation:nsIPrintSettings::kLandscapeOrientation; |
|
244 aPrintSettings->SetOrientation(orientation); |
|
245 } |
|
246 |
|
247 // Setup Number of Copies |
|
248 if (aDevMode->dmFields & DM_COPIES) { |
|
249 aPrintSettings->SetNumCopies(int32_t(aDevMode->dmCopies)); |
|
250 } |
|
251 |
|
252 // Scaling |
|
253 // Since we do the scaling, grab their value and reset back to 100 |
|
254 if (aDevMode->dmFields & DM_SCALE) { |
|
255 double origScale = 1.0; |
|
256 aPrintSettings->GetScaling(&origScale); |
|
257 double scale = double(aDevMode->dmScale) / 100.0f; |
|
258 if (origScale == 1.0 || scale != 1.0) { |
|
259 aPrintSettings->SetScaling(scale); |
|
260 } |
|
261 aDevMode->dmScale = 100; |
|
262 // To turn this on you must change where the mPrt->mShrinkToFit is being set in the DocumentViewer |
|
263 //aPrintSettings->SetShrinkToFit(false); |
|
264 } |
|
265 |
|
266 if (aDevMode->dmFields & DM_PAPERSIZE) { |
|
267 aPrintSettings->SetPaperSizeType(nsIPrintSettings::kPaperSizeNativeData); |
|
268 aPrintSettings->SetPaperData(aDevMode->dmPaperSize); |
|
269 for (int32_t i=0;i<kNumPaperSizes;i++) { |
|
270 if (kPaperSizes[i].mPaperSize == aDevMode->dmPaperSize) { |
|
271 aPrintSettings->SetPaperSizeUnit(kPaperSizes[i].mIsInches?nsIPrintSettings::kPaperSizeInches:nsIPrintSettings::kPaperSizeMillimeters); |
|
272 break; |
|
273 } |
|
274 } |
|
275 |
|
276 } else if (aDevMode->dmFields & DM_PAPERLENGTH && aDevMode->dmFields & DM_PAPERWIDTH) { |
|
277 bool found = false; |
|
278 for (int32_t i=0;i<kNumPaperSizes;i++) { |
|
279 if (kPaperSizes[i].mPaperSize == aDevMode->dmPaperSize) { |
|
280 aPrintSettings->SetPaperSizeType(nsIPrintSettings::kPaperSizeDefined); |
|
281 aPrintSettings->SetPaperWidth(kPaperSizes[i].mWidth); |
|
282 aPrintSettings->SetPaperHeight(kPaperSizes[i].mHeight); |
|
283 aPrintSettings->SetPaperSizeUnit(kPaperSizes[i].mIsInches?nsIPrintSettings::kPaperSizeInches:nsIPrintSettings::kPaperSizeMillimeters); |
|
284 found = true; |
|
285 break; |
|
286 } |
|
287 } |
|
288 if (!found) { |
|
289 return NS_ERROR_FAILURE; |
|
290 } |
|
291 } else { |
|
292 return NS_ERROR_FAILURE; |
|
293 } |
|
294 return NS_OK; |
|
295 } |
|
296 |
|
297 //---------------------------------------------------------------------------------- |
|
298 // Return localized bundle for resource strings |
|
299 static nsresult |
|
300 GetLocalizedBundle(const char * aPropFileName, nsIStringBundle** aStrBundle) |
|
301 { |
|
302 NS_ENSURE_ARG_POINTER(aPropFileName); |
|
303 NS_ENSURE_ARG_POINTER(aStrBundle); |
|
304 |
|
305 nsresult rv; |
|
306 nsCOMPtr<nsIStringBundle> bundle; |
|
307 |
|
308 |
|
309 // Create bundle |
|
310 nsCOMPtr<nsIStringBundleService> stringService = |
|
311 do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv); |
|
312 if (NS_SUCCEEDED(rv) && stringService) { |
|
313 rv = stringService->CreateBundle(aPropFileName, aStrBundle); |
|
314 } |
|
315 |
|
316 return rv; |
|
317 } |
|
318 |
|
319 //-------------------------------------------------------- |
|
320 // Return localized string |
|
321 static nsresult |
|
322 GetLocalizedString(nsIStringBundle* aStrBundle, const char* aKey, nsString& oVal) |
|
323 { |
|
324 NS_ENSURE_ARG_POINTER(aStrBundle); |
|
325 NS_ENSURE_ARG_POINTER(aKey); |
|
326 |
|
327 // Determine default label from string bundle |
|
328 nsXPIDLString valUni; |
|
329 nsAutoString key; |
|
330 key.AssignWithConversion(aKey); |
|
331 nsresult rv = aStrBundle->GetStringFromName(key.get(), getter_Copies(valUni)); |
|
332 if (NS_SUCCEEDED(rv) && valUni) { |
|
333 oVal.Assign(valUni); |
|
334 } else { |
|
335 oVal.Truncate(); |
|
336 } |
|
337 return rv; |
|
338 } |
|
339 |
|
340 //-------------------------------------------------------- |
|
341 // Set a multi-byte string in the control |
|
342 static void SetTextOnWnd(HWND aControl, const nsString& aStr) |
|
343 { |
|
344 nsAutoCString text; |
|
345 if (NS_SUCCEEDED(NS_CopyUnicodeToNative(aStr, text))) { |
|
346 ::SetWindowText(aControl, text.get()); |
|
347 } |
|
348 } |
|
349 |
|
350 //-------------------------------------------------------- |
|
351 // Will get the control and localized string by "key" |
|
352 static void SetText(HWND aParent, |
|
353 UINT aId, |
|
354 nsIStringBundle* aStrBundle, |
|
355 const char* aKey) |
|
356 { |
|
357 HWND wnd = GetDlgItem (aParent, aId); |
|
358 if (!wnd) { |
|
359 return; |
|
360 } |
|
361 nsAutoString str; |
|
362 nsresult rv = GetLocalizedString(aStrBundle, aKey, str); |
|
363 if (NS_SUCCEEDED(rv)) { |
|
364 SetTextOnWnd(wnd, str); |
|
365 } |
|
366 } |
|
367 |
|
368 //-------------------------------------------------------- |
|
369 static void SetRadio(HWND aParent, |
|
370 UINT aId, |
|
371 bool aIsSet, |
|
372 bool isEnabled = true) |
|
373 { |
|
374 HWND wnd = ::GetDlgItem (aParent, aId); |
|
375 if (!wnd) { |
|
376 return; |
|
377 } |
|
378 if (!isEnabled) { |
|
379 ::EnableWindow(wnd, FALSE); |
|
380 return; |
|
381 } |
|
382 ::EnableWindow(wnd, TRUE); |
|
383 ::SendMessage(wnd, BM_SETCHECK, (WPARAM)aIsSet, (LPARAM)0); |
|
384 } |
|
385 |
|
386 //-------------------------------------------------------- |
|
387 static void SetRadioOfGroup(HWND aDlg, int aRadId) |
|
388 { |
|
389 int radioIds[] = {rad4, rad5, rad6}; |
|
390 int numRads = 3; |
|
391 |
|
392 for (int i=0;i<numRads;i++) { |
|
393 HWND radWnd = ::GetDlgItem(aDlg, radioIds[i]); |
|
394 if (radWnd != nullptr) { |
|
395 ::SendMessage(radWnd, BM_SETCHECK, (WPARAM)(radioIds[i] == aRadId), (LPARAM)0); |
|
396 } |
|
397 } |
|
398 } |
|
399 |
|
400 //-------------------------------------------------------- |
|
401 typedef struct { |
|
402 const char * mKeyStr; |
|
403 long mKeyId; |
|
404 } PropKeyInfo; |
|
405 |
|
406 // These are the control ids used in the dialog and |
|
407 // defined by MS-Windows in commdlg.h |
|
408 static PropKeyInfo gAllPropKeys[] = { |
|
409 {"printFramesTitleWindows", grp3}, |
|
410 {"asLaidOutWindows", rad4}, |
|
411 {"selectedFrameWindows", rad5}, |
|
412 {"separateFramesWindows", rad6}, |
|
413 {nullptr, 0}}; |
|
414 |
|
415 //-------------------------------------------------------- |
|
416 //-------------------------------------------------------- |
|
417 //-------------------------------------------------------- |
|
418 //-------------------------------------------------------- |
|
419 // Get the absolute coords of the child windows relative |
|
420 // to its parent window |
|
421 static void GetLocalRect(HWND aWnd, RECT& aRect, HWND aParent) |
|
422 { |
|
423 ::GetWindowRect(aWnd, &aRect); |
|
424 |
|
425 // MapWindowPoints converts screen coordinates to client coordinates. |
|
426 // It works correctly in both left-to-right and right-to-left windows. |
|
427 ::MapWindowPoints(nullptr, aParent, (LPPOINT)&aRect, 2); |
|
428 } |
|
429 |
|
430 //-------------------------------------------------------- |
|
431 // Show or Hide the control |
|
432 static void Show(HWND aWnd, bool bState) |
|
433 { |
|
434 if (aWnd) { |
|
435 ::ShowWindow(aWnd, bState?SW_SHOW:SW_HIDE); |
|
436 } |
|
437 } |
|
438 |
|
439 //-------------------------------------------------------- |
|
440 // Create a child window "control" |
|
441 static HWND CreateControl(LPCTSTR aType, |
|
442 DWORD aStyle, |
|
443 HINSTANCE aHInst, |
|
444 HWND aHdlg, |
|
445 int aId, |
|
446 const nsAString& aStr, |
|
447 const nsIntRect& aRect) |
|
448 { |
|
449 nsAutoCString str; |
|
450 if (NS_FAILED(NS_CopyUnicodeToNative(aStr, str))) |
|
451 return nullptr; |
|
452 |
|
453 HWND hWnd = ::CreateWindow (aType, str.get(), |
|
454 WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | aStyle, |
|
455 aRect.x, aRect.y, aRect.width, aRect.height, |
|
456 (HWND)aHdlg, (HMENU)(intptr_t)aId, |
|
457 aHInst, nullptr); |
|
458 if (hWnd == nullptr) return nullptr; |
|
459 |
|
460 // get the native font for the dialog and |
|
461 // set it into the new control |
|
462 HFONT hFont = (HFONT)::SendMessage(aHdlg, WM_GETFONT, (WPARAM)0, (LPARAM)0); |
|
463 if (hFont != nullptr) { |
|
464 ::SendMessage(hWnd, WM_SETFONT, (WPARAM) hFont, (LPARAM)0); |
|
465 } |
|
466 return hWnd; |
|
467 } |
|
468 |
|
469 //-------------------------------------------------------- |
|
470 // Create a Radio Button |
|
471 static HWND CreateRadioBtn(HINSTANCE aHInst, |
|
472 HWND aHdlg, |
|
473 int aId, |
|
474 const char* aStr, |
|
475 const nsIntRect& aRect) |
|
476 { |
|
477 nsString cStr; |
|
478 cStr.AssignWithConversion(aStr); |
|
479 return CreateControl("BUTTON", BS_RADIOBUTTON, aHInst, aHdlg, aId, cStr, aRect); |
|
480 } |
|
481 |
|
482 //-------------------------------------------------------- |
|
483 // Create a Group Box |
|
484 static HWND CreateGroupBox(HINSTANCE aHInst, |
|
485 HWND aHdlg, |
|
486 int aId, |
|
487 const nsAString& aStr, |
|
488 const nsIntRect& aRect) |
|
489 { |
|
490 return CreateControl("BUTTON", BS_GROUPBOX, aHInst, aHdlg, aId, aStr, aRect); |
|
491 } |
|
492 |
|
493 //-------------------------------------------------------- |
|
494 // Localizes and initializes the radio buttons and group |
|
495 static void InitializeExtendedDialog(HWND hdlg, int16_t aHowToEnableFrameUI) |
|
496 { |
|
497 NS_ABORT_IF_FALSE(aHowToEnableFrameUI != nsIPrintSettings::kFrameEnableNone, |
|
498 "should not be called"); |
|
499 |
|
500 // Localize the new controls in the print dialog |
|
501 nsCOMPtr<nsIStringBundle> strBundle; |
|
502 if (NS_SUCCEEDED(GetLocalizedBundle(PRINTDLG_PROPERTIES, getter_AddRefs(strBundle)))) { |
|
503 int32_t i = 0; |
|
504 while (gAllPropKeys[i].mKeyStr != nullptr) { |
|
505 SetText(hdlg, gAllPropKeys[i].mKeyId, strBundle, gAllPropKeys[i].mKeyStr); |
|
506 i++; |
|
507 } |
|
508 } |
|
509 |
|
510 // Set up radio buttons |
|
511 if (aHowToEnableFrameUI == nsIPrintSettings::kFrameEnableAll) { |
|
512 SetRadio(hdlg, rad4, false); |
|
513 SetRadio(hdlg, rad5, true); |
|
514 SetRadio(hdlg, rad6, false); |
|
515 // set default so user doesn't have to actually press on it |
|
516 gFrameSelectedRadioBtn = rad5; |
|
517 |
|
518 } else { // nsIPrintSettings::kFrameEnableAsIsAndEach |
|
519 SetRadio(hdlg, rad4, false); |
|
520 SetRadio(hdlg, rad5, false, false); |
|
521 SetRadio(hdlg, rad6, true); |
|
522 // set default so user doesn't have to actually press on it |
|
523 gFrameSelectedRadioBtn = rad6; |
|
524 } |
|
525 } |
|
526 |
|
527 |
|
528 //-------------------------------------------------------- |
|
529 // Special Hook Procedure for handling the print dialog messages |
|
530 static UINT CALLBACK PrintHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam) |
|
531 { |
|
532 |
|
533 if (uiMsg == WM_COMMAND) { |
|
534 UINT id = LOWORD(wParam); |
|
535 if (id == rad4 || id == rad5 || id == rad6) { |
|
536 gFrameSelectedRadioBtn = id; |
|
537 SetRadioOfGroup(hdlg, id); |
|
538 } |
|
539 |
|
540 } else if (uiMsg == WM_INITDIALOG) { |
|
541 PRINTDLG * printDlg = (PRINTDLG *)lParam; |
|
542 if (printDlg == nullptr) return 0L; |
|
543 |
|
544 int16_t howToEnableFrameUI = (int16_t)printDlg->lCustData; |
|
545 // don't add frame options if they would be disabled anyway |
|
546 // because there are no frames |
|
547 if (howToEnableFrameUI == nsIPrintSettings::kFrameEnableNone) |
|
548 return TRUE; |
|
549 |
|
550 HINSTANCE hInst = (HINSTANCE)::GetWindowLongPtr(hdlg, GWLP_HINSTANCE); |
|
551 if (hInst == nullptr) return 0L; |
|
552 |
|
553 // Start by getting the local rects of several of the controls |
|
554 // so we can calculate where the new controls are |
|
555 HWND wnd = ::GetDlgItem(hdlg, grp1); |
|
556 if (wnd == nullptr) return 0L; |
|
557 RECT dlgRect; |
|
558 GetLocalRect(wnd, dlgRect, hdlg); |
|
559 |
|
560 wnd = ::GetDlgItem(hdlg, rad1); // this is the top control "All" |
|
561 if (wnd == nullptr) return 0L; |
|
562 RECT rad1Rect; |
|
563 GetLocalRect(wnd, rad1Rect, hdlg); |
|
564 |
|
565 wnd = ::GetDlgItem(hdlg, rad2); // this is the bottom control "Selection" |
|
566 if (wnd == nullptr) return 0L; |
|
567 RECT rad2Rect; |
|
568 GetLocalRect(wnd, rad2Rect, hdlg); |
|
569 |
|
570 wnd = ::GetDlgItem(hdlg, rad3); // this is the middle control "Pages" |
|
571 if (wnd == nullptr) return 0L; |
|
572 RECT rad3Rect; |
|
573 GetLocalRect(wnd, rad3Rect, hdlg); |
|
574 |
|
575 HWND okWnd = ::GetDlgItem(hdlg, IDOK); |
|
576 if (okWnd == nullptr) return 0L; |
|
577 RECT okRect; |
|
578 GetLocalRect(okWnd, okRect, hdlg); |
|
579 |
|
580 wnd = ::GetDlgItem(hdlg, grp4); // this is the "Print range" groupbox |
|
581 if (wnd == nullptr) return 0L; |
|
582 RECT prtRect; |
|
583 GetLocalRect(wnd, prtRect, hdlg); |
|
584 |
|
585 |
|
586 // calculate various different "gaps" for layout purposes |
|
587 |
|
588 int rbGap = rad3Rect.top - rad1Rect.bottom; // gap between radiobtns |
|
589 int grpBotGap = dlgRect.bottom - rad2Rect.bottom; // gap from bottom rb to bottom of grpbox |
|
590 int grpGap = dlgRect.top - prtRect.bottom ; // gap between group boxes |
|
591 int top = dlgRect.bottom + grpGap; |
|
592 int radHgt = rad1Rect.bottom - rad1Rect.top + 1; // top of new group box |
|
593 int y = top+(rad1Rect.top-dlgRect.top); // starting pos of first radio |
|
594 int rbWidth = dlgRect.right - rad1Rect.left - 5; // measure from rb left to the edge of the groupbox |
|
595 // (5 is arbitrary) |
|
596 nsIntRect rect; |
|
597 |
|
598 // Create and position the radio buttons |
|
599 // |
|
600 // If any one control cannot be created then |
|
601 // hide the others and bail out |
|
602 // |
|
603 rect.SetRect(rad1Rect.left, y, rbWidth,radHgt); |
|
604 HWND rad4Wnd = CreateRadioBtn(hInst, hdlg, rad4, kAsLaidOutOnScreenStr, rect); |
|
605 if (rad4Wnd == nullptr) return 0L; |
|
606 y += radHgt + rbGap; |
|
607 |
|
608 rect.SetRect(rad1Rect.left, y, rbWidth, radHgt); |
|
609 HWND rad5Wnd = CreateRadioBtn(hInst, hdlg, rad5, kTheSelectedFrameStr, rect); |
|
610 if (rad5Wnd == nullptr) { |
|
611 Show(rad4Wnd, FALSE); // hide |
|
612 return 0L; |
|
613 } |
|
614 y += radHgt + rbGap; |
|
615 |
|
616 rect.SetRect(rad1Rect.left, y, rbWidth, radHgt); |
|
617 HWND rad6Wnd = CreateRadioBtn(hInst, hdlg, rad6, kEachFrameSeparately, rect); |
|
618 if (rad6Wnd == nullptr) { |
|
619 Show(rad4Wnd, FALSE); // hide |
|
620 Show(rad5Wnd, FALSE); // hide |
|
621 return 0L; |
|
622 } |
|
623 y += radHgt + grpBotGap; |
|
624 |
|
625 // Create and position the group box |
|
626 rect.SetRect (dlgRect.left, top, dlgRect.right-dlgRect.left+1, y-top+1); |
|
627 HWND grpBoxWnd = CreateGroupBox(hInst, hdlg, grp3, NS_LITERAL_STRING("Print Frame"), rect); |
|
628 if (grpBoxWnd == nullptr) { |
|
629 Show(rad4Wnd, FALSE); // hide |
|
630 Show(rad5Wnd, FALSE); // hide |
|
631 Show(rad6Wnd, FALSE); // hide |
|
632 return 0L; |
|
633 } |
|
634 |
|
635 // Here we figure out the old height of the dlg |
|
636 // then figure its gap from the old grpbx to the bottom |
|
637 // then size the dlg |
|
638 RECT pr, cr; |
|
639 ::GetWindowRect(hdlg, &pr); |
|
640 ::GetClientRect(hdlg, &cr); |
|
641 |
|
642 int dlgHgt = (cr.bottom - cr.top) + 1; |
|
643 int bottomGap = dlgHgt - okRect.bottom; |
|
644 pr.bottom += (dlgRect.bottom-dlgRect.top) + grpGap + 1 - (dlgHgt-dlgRect.bottom) + bottomGap; |
|
645 |
|
646 ::SetWindowPos(hdlg, nullptr, pr.left, pr.top, pr.right-pr.left+1, pr.bottom-pr.top+1, |
|
647 SWP_NOMOVE|SWP_NOREDRAW|SWP_NOZORDER); |
|
648 |
|
649 // figure out the new height of the dialog |
|
650 ::GetClientRect(hdlg, &cr); |
|
651 dlgHgt = (cr.bottom - cr.top) + 1; |
|
652 |
|
653 // Reposition the OK and Cancel btns |
|
654 int okHgt = okRect.bottom - okRect.top + 1; |
|
655 ::SetWindowPos(okWnd, nullptr, okRect.left, dlgHgt-bottomGap-okHgt, 0, 0, |
|
656 SWP_NOSIZE|SWP_NOREDRAW|SWP_NOZORDER); |
|
657 |
|
658 HWND cancelWnd = ::GetDlgItem(hdlg, IDCANCEL); |
|
659 if (cancelWnd == nullptr) return 0L; |
|
660 |
|
661 RECT cancelRect; |
|
662 GetLocalRect(cancelWnd, cancelRect, hdlg); |
|
663 int cancelHgt = cancelRect.bottom - cancelRect.top + 1; |
|
664 ::SetWindowPos(cancelWnd, nullptr, cancelRect.left, dlgHgt-bottomGap-cancelHgt, 0, 0, |
|
665 SWP_NOSIZE|SWP_NOREDRAW|SWP_NOZORDER); |
|
666 |
|
667 // localize and initialize the groupbox and radiobuttons |
|
668 InitializeExtendedDialog(hdlg, howToEnableFrameUI); |
|
669 |
|
670 // Looks like we were able to extend the dialog |
|
671 gDialogWasExtended = true; |
|
672 return TRUE; |
|
673 } |
|
674 return 0L; |
|
675 } |
|
676 |
|
677 //---------------------------------------------------------------------------------- |
|
678 // Returns a Global Moveable Memory Handle to a DevMode |
|
679 // from the Printer by the name of aPrintName |
|
680 // |
|
681 // NOTE: |
|
682 // This function assumes that aPrintName has already been converted from |
|
683 // unicode |
|
684 // |
|
685 static HGLOBAL CreateGlobalDevModeAndInit(const nsXPIDLString& aPrintName, nsIPrintSettings* aPS) |
|
686 { |
|
687 HGLOBAL hGlobalDevMode = nullptr; |
|
688 |
|
689 HANDLE hPrinter = nullptr; |
|
690 // const cast kludge for silly Win32 api's |
|
691 LPWSTR printName = const_cast<wchar_t*>(static_cast<const wchar_t*>(aPrintName.get())); |
|
692 BOOL status = ::OpenPrinterW(printName, &hPrinter, nullptr); |
|
693 if (status) { |
|
694 |
|
695 LPDEVMODEW pNewDevMode; |
|
696 DWORD dwNeeded, dwRet; |
|
697 |
|
698 // Get the buffer size |
|
699 dwNeeded = ::DocumentPropertiesW(gParentWnd, hPrinter, printName, nullptr, nullptr, 0); |
|
700 if (dwNeeded == 0) { |
|
701 return nullptr; |
|
702 } |
|
703 |
|
704 // Allocate a buffer of the correct size. |
|
705 pNewDevMode = (LPDEVMODEW)::HeapAlloc (::GetProcessHeap(), HEAP_ZERO_MEMORY, dwNeeded); |
|
706 if (!pNewDevMode) return nullptr; |
|
707 |
|
708 hGlobalDevMode = (HGLOBAL)::GlobalAlloc(GHND, dwNeeded); |
|
709 if (!hGlobalDevMode) { |
|
710 ::HeapFree(::GetProcessHeap(), 0, pNewDevMode); |
|
711 return nullptr; |
|
712 } |
|
713 |
|
714 dwRet = ::DocumentPropertiesW(gParentWnd, hPrinter, printName, pNewDevMode, nullptr, DM_OUT_BUFFER); |
|
715 |
|
716 if (dwRet != IDOK) { |
|
717 ::HeapFree(::GetProcessHeap(), 0, pNewDevMode); |
|
718 ::GlobalFree(hGlobalDevMode); |
|
719 ::ClosePrinter(hPrinter); |
|
720 return nullptr; |
|
721 } |
|
722 |
|
723 // Lock memory and copy contents from DEVMODE (current printer) |
|
724 // to Global Memory DEVMODE |
|
725 LPDEVMODEW devMode = (DEVMODEW *)::GlobalLock(hGlobalDevMode); |
|
726 if (devMode) { |
|
727 memcpy(devMode, pNewDevMode, dwNeeded); |
|
728 // Initialize values from the PrintSettings |
|
729 SetupDevModeFromSettings(devMode, aPS); |
|
730 |
|
731 // Sets back the changes we made to the DevMode into the Printer Driver |
|
732 dwRet = ::DocumentPropertiesW(gParentWnd, hPrinter, printName, devMode, devMode, DM_IN_BUFFER | DM_OUT_BUFFER); |
|
733 if (dwRet != IDOK) { |
|
734 ::GlobalUnlock(hGlobalDevMode); |
|
735 ::GlobalFree(hGlobalDevMode); |
|
736 ::HeapFree(::GetProcessHeap(), 0, pNewDevMode); |
|
737 ::ClosePrinter(hPrinter); |
|
738 return nullptr; |
|
739 } |
|
740 |
|
741 ::GlobalUnlock(hGlobalDevMode); |
|
742 } else { |
|
743 ::GlobalFree(hGlobalDevMode); |
|
744 hGlobalDevMode = nullptr; |
|
745 } |
|
746 |
|
747 ::HeapFree(::GetProcessHeap(), 0, pNewDevMode); |
|
748 |
|
749 ::ClosePrinter(hPrinter); |
|
750 |
|
751 } else { |
|
752 return nullptr; |
|
753 } |
|
754 |
|
755 return hGlobalDevMode; |
|
756 } |
|
757 |
|
758 //------------------------------------------------------------------ |
|
759 // helper |
|
760 static void GetDefaultPrinterNameFromGlobalPrinters(nsXPIDLString &printerName) |
|
761 { |
|
762 nsCOMPtr<nsIPrinterEnumerator> prtEnum = do_GetService("@mozilla.org/gfx/printerenumerator;1"); |
|
763 if (prtEnum) { |
|
764 prtEnum->GetDefaultPrinterName(getter_Copies(printerName)); |
|
765 } |
|
766 } |
|
767 |
|
768 // Determine whether we have a completely native dialog |
|
769 // or whether we cshould extend it |
|
770 static bool ShouldExtendPrintDialog() |
|
771 { |
|
772 nsresult rv; |
|
773 nsCOMPtr<nsIPrefService> prefs = |
|
774 do_GetService(NS_PREFSERVICE_CONTRACTID, &rv); |
|
775 NS_ENSURE_SUCCESS(rv, true); |
|
776 nsCOMPtr<nsIPrefBranch> prefBranch; |
|
777 rv = prefs->GetBranch(nullptr, getter_AddRefs(prefBranch)); |
|
778 NS_ENSURE_SUCCESS(rv, true); |
|
779 |
|
780 bool result; |
|
781 rv = prefBranch->GetBoolPref("print.extend_native_print_dialog", &result); |
|
782 NS_ENSURE_SUCCESS(rv, true); |
|
783 return result; |
|
784 } |
|
785 |
|
786 //------------------------------------------------------------------ |
|
787 // Displays the native Print Dialog |
|
788 static nsresult |
|
789 ShowNativePrintDialog(HWND aHWnd, |
|
790 nsIPrintSettings* aPrintSettings) |
|
791 { |
|
792 //NS_ENSURE_ARG_POINTER(aHWnd); |
|
793 NS_ENSURE_ARG_POINTER(aPrintSettings); |
|
794 |
|
795 gDialogWasExtended = false; |
|
796 |
|
797 HGLOBAL hGlobalDevMode = nullptr; |
|
798 HGLOBAL hDevNames = nullptr; |
|
799 |
|
800 // Get the Print Name to be used |
|
801 nsXPIDLString printerName; |
|
802 aPrintSettings->GetPrinterName(getter_Copies(printerName)); |
|
803 |
|
804 // If there is no name then use the default printer |
|
805 if (printerName.IsEmpty()) { |
|
806 GetDefaultPrinterNameFromGlobalPrinters(printerName); |
|
807 } else { |
|
808 HANDLE hPrinter = nullptr; |
|
809 if(!::OpenPrinterW(const_cast<wchar_t*>(static_cast<const wchar_t*>(printerName.get())), &hPrinter, nullptr)) { |
|
810 // If the last used printer is not found, we should use default printer. |
|
811 GetDefaultPrinterNameFromGlobalPrinters(printerName); |
|
812 } else { |
|
813 ::ClosePrinter(hPrinter); |
|
814 } |
|
815 } |
|
816 |
|
817 // Now create a DEVNAMES struct so the the dialog is initialized correctly. |
|
818 |
|
819 uint32_t len = printerName.Length(); |
|
820 hDevNames = (HGLOBAL)::GlobalAlloc(GHND, sizeof(wchar_t) * (len + 1) + |
|
821 sizeof(DEVNAMES)); |
|
822 if (!hDevNames) { |
|
823 return NS_ERROR_OUT_OF_MEMORY; |
|
824 } |
|
825 |
|
826 DEVNAMES* pDevNames = (DEVNAMES*)::GlobalLock(hDevNames); |
|
827 if (!pDevNames) { |
|
828 ::GlobalFree(hDevNames); |
|
829 return NS_ERROR_FAILURE; |
|
830 } |
|
831 pDevNames->wDriverOffset = sizeof(DEVNAMES)/sizeof(wchar_t); |
|
832 pDevNames->wDeviceOffset = sizeof(DEVNAMES)/sizeof(wchar_t); |
|
833 pDevNames->wOutputOffset = sizeof(DEVNAMES)/sizeof(wchar_t)+len; |
|
834 pDevNames->wDefault = 0; |
|
835 |
|
836 memcpy(pDevNames+1, printerName, (len + 1) * sizeof(wchar_t)); |
|
837 ::GlobalUnlock(hDevNames); |
|
838 |
|
839 // Create a Moveable Memory Object that holds a new DevMode |
|
840 // from the Printer Name |
|
841 // The PRINTDLG.hDevMode requires that it be a moveable memory object |
|
842 // NOTE: We only need to free hGlobalDevMode when the dialog is cancelled |
|
843 // When the user prints, it comes back in the printdlg struct and |
|
844 // is used and cleaned up later |
|
845 hGlobalDevMode = CreateGlobalDevModeAndInit(printerName, aPrintSettings); |
|
846 |
|
847 // Prepare to Display the Print Dialog |
|
848 PRINTDLGW prntdlg; |
|
849 memset(&prntdlg, 0, sizeof(PRINTDLGW)); |
|
850 |
|
851 prntdlg.lStructSize = sizeof(prntdlg); |
|
852 prntdlg.hwndOwner = aHWnd; |
|
853 prntdlg.hDevMode = hGlobalDevMode; |
|
854 prntdlg.hDevNames = hDevNames; |
|
855 prntdlg.hDC = nullptr; |
|
856 prntdlg.Flags = PD_ALLPAGES | PD_RETURNIC | |
|
857 PD_USEDEVMODECOPIESANDCOLLATE | PD_COLLATE; |
|
858 |
|
859 // if there is a current selection then enable the "Selection" radio button |
|
860 int16_t howToEnableFrameUI = nsIPrintSettings::kFrameEnableNone; |
|
861 bool isOn; |
|
862 aPrintSettings->GetPrintOptions(nsIPrintSettings::kEnableSelectionRB, &isOn); |
|
863 if (!isOn) { |
|
864 prntdlg.Flags |= PD_NOSELECTION; |
|
865 } |
|
866 aPrintSettings->GetHowToEnableFrameUI(&howToEnableFrameUI); |
|
867 |
|
868 int32_t pg = 1; |
|
869 aPrintSettings->GetStartPageRange(&pg); |
|
870 prntdlg.nFromPage = pg; |
|
871 |
|
872 aPrintSettings->GetEndPageRange(&pg); |
|
873 prntdlg.nToPage = pg; |
|
874 |
|
875 prntdlg.nMinPage = 1; |
|
876 prntdlg.nMaxPage = 0xFFFF; |
|
877 prntdlg.nCopies = 1; |
|
878 prntdlg.lpfnSetupHook = nullptr; |
|
879 prntdlg.lpSetupTemplateName = nullptr; |
|
880 prntdlg.hPrintTemplate = nullptr; |
|
881 prntdlg.hSetupTemplate = nullptr; |
|
882 |
|
883 prntdlg.hInstance = nullptr; |
|
884 prntdlg.lpPrintTemplateName = nullptr; |
|
885 |
|
886 if (!ShouldExtendPrintDialog()) { |
|
887 prntdlg.lCustData = 0; |
|
888 prntdlg.lpfnPrintHook = nullptr; |
|
889 } else { |
|
890 // Set up print dialog "hook" procedure for extending the dialog |
|
891 prntdlg.lCustData = (DWORD)howToEnableFrameUI; |
|
892 prntdlg.lpfnPrintHook = (LPPRINTHOOKPROC)PrintHookProc; |
|
893 prntdlg.Flags |= PD_ENABLEPRINTHOOK; |
|
894 } |
|
895 |
|
896 BOOL result = ::PrintDlgW(&prntdlg); |
|
897 |
|
898 if (TRUE == result) { |
|
899 // check to make sure we don't have any nullptr pointers |
|
900 NS_ENSURE_TRUE(aPrintSettings && prntdlg.hDevMode, NS_ERROR_FAILURE); |
|
901 |
|
902 if (prntdlg.hDevNames == nullptr) { |
|
903 ::GlobalFree(hGlobalDevMode); |
|
904 return NS_ERROR_FAILURE; |
|
905 } |
|
906 // Lock the deviceNames and check for nullptr |
|
907 DEVNAMES *devnames = (DEVNAMES *)::GlobalLock(prntdlg.hDevNames); |
|
908 if (devnames == nullptr) { |
|
909 ::GlobalFree(hGlobalDevMode); |
|
910 return NS_ERROR_FAILURE; |
|
911 } |
|
912 |
|
913 char16_t* device = &(((char16_t *)devnames)[devnames->wDeviceOffset]); |
|
914 char16_t* driver = &(((char16_t *)devnames)[devnames->wDriverOffset]); |
|
915 |
|
916 // Check to see if the "Print To File" control is checked |
|
917 // then take the name from devNames and set it in the PrintSettings |
|
918 // |
|
919 // NOTE: |
|
920 // As per Microsoft SDK documentation the returned value offset from |
|
921 // devnames->wOutputOffset is either "FILE:" or nullptr |
|
922 // if the "Print To File" checkbox is checked it MUST be "FILE:" |
|
923 // We assert as an extra safety check. |
|
924 if (prntdlg.Flags & PD_PRINTTOFILE) { |
|
925 char16ptr_t fileName = &(((wchar_t *)devnames)[devnames->wOutputOffset]); |
|
926 NS_ASSERTION(wcscmp(fileName, L"FILE:") == 0, "FileName must be `FILE:`"); |
|
927 aPrintSettings->SetToFileName(fileName); |
|
928 aPrintSettings->SetPrintToFile(true); |
|
929 } else { |
|
930 // clear "print to file" info |
|
931 aPrintSettings->SetPrintToFile(false); |
|
932 aPrintSettings->SetToFileName(nullptr); |
|
933 } |
|
934 |
|
935 nsCOMPtr<nsIPrintSettingsWin> psWin(do_QueryInterface(aPrintSettings)); |
|
936 if (!psWin) { |
|
937 ::GlobalFree(hGlobalDevMode); |
|
938 return NS_ERROR_FAILURE; |
|
939 } |
|
940 |
|
941 // Setup local Data members |
|
942 psWin->SetDeviceName(device); |
|
943 psWin->SetDriverName(driver); |
|
944 |
|
945 #if defined(DEBUG_rods) || defined(DEBUG_dcone) |
|
946 wprintf(L"printer: driver %s, device %s flags: %d\n", driver, device, prntdlg.Flags); |
|
947 #endif |
|
948 // fill the print options with the info from the dialog |
|
949 |
|
950 aPrintSettings->SetPrinterName(device); |
|
951 |
|
952 if (prntdlg.Flags & PD_SELECTION) { |
|
953 aPrintSettings->SetPrintRange(nsIPrintSettings::kRangeSelection); |
|
954 |
|
955 } else if (prntdlg.Flags & PD_PAGENUMS) { |
|
956 aPrintSettings->SetPrintRange(nsIPrintSettings::kRangeSpecifiedPageRange); |
|
957 aPrintSettings->SetStartPageRange(prntdlg.nFromPage); |
|
958 aPrintSettings->SetEndPageRange(prntdlg.nToPage); |
|
959 |
|
960 } else { // (prntdlg.Flags & PD_ALLPAGES) |
|
961 aPrintSettings->SetPrintRange(nsIPrintSettings::kRangeAllPages); |
|
962 } |
|
963 |
|
964 if (howToEnableFrameUI != nsIPrintSettings::kFrameEnableNone) { |
|
965 // make sure the dialog got extended |
|
966 if (gDialogWasExtended) { |
|
967 // check to see about the frame radio buttons |
|
968 switch (gFrameSelectedRadioBtn) { |
|
969 case rad4: |
|
970 aPrintSettings->SetPrintFrameType(nsIPrintSettings::kFramesAsIs); |
|
971 break; |
|
972 case rad5: |
|
973 aPrintSettings->SetPrintFrameType(nsIPrintSettings::kSelectedFrame); |
|
974 break; |
|
975 case rad6: |
|
976 aPrintSettings->SetPrintFrameType(nsIPrintSettings::kEachFrameSep); |
|
977 break; |
|
978 } // switch |
|
979 } else { |
|
980 // if it didn't get extended then have it default to printing |
|
981 // each frame separately |
|
982 aPrintSettings->SetPrintFrameType(nsIPrintSettings::kEachFrameSep); |
|
983 } |
|
984 } else { |
|
985 aPrintSettings->SetPrintFrameType(nsIPrintSettings::kNoFrames); |
|
986 } |
|
987 // Unlock DeviceNames |
|
988 ::GlobalUnlock(prntdlg.hDevNames); |
|
989 |
|
990 // Transfer the settings from the native data to the PrintSettings |
|
991 LPDEVMODEW devMode = (LPDEVMODEW)::GlobalLock(prntdlg.hDevMode); |
|
992 if (devMode == nullptr) { |
|
993 ::GlobalFree(hGlobalDevMode); |
|
994 return NS_ERROR_FAILURE; |
|
995 } |
|
996 psWin->SetDevMode(devMode); // copies DevMode |
|
997 SetPrintSettingsFromDevMode(aPrintSettings, devMode); |
|
998 ::GlobalUnlock(prntdlg.hDevMode); |
|
999 |
|
1000 #if defined(DEBUG_rods) || defined(DEBUG_dcone) |
|
1001 bool printSelection = prntdlg.Flags & PD_SELECTION; |
|
1002 bool printAllPages = prntdlg.Flags & PD_ALLPAGES; |
|
1003 bool printNumPages = prntdlg.Flags & PD_PAGENUMS; |
|
1004 int32_t fromPageNum = 0; |
|
1005 int32_t toPageNum = 0; |
|
1006 |
|
1007 if (printNumPages) { |
|
1008 fromPageNum = prntdlg.nFromPage; |
|
1009 toPageNum = prntdlg.nToPage; |
|
1010 } |
|
1011 if (printSelection) { |
|
1012 printf("Printing the selection\n"); |
|
1013 |
|
1014 } else if (printAllPages) { |
|
1015 printf("Printing all the pages\n"); |
|
1016 |
|
1017 } else { |
|
1018 printf("Printing from page no. %d to %d\n", fromPageNum, toPageNum); |
|
1019 } |
|
1020 #endif |
|
1021 |
|
1022 } else { |
|
1023 ::SetFocus(aHWnd); |
|
1024 aPrintSettings->SetIsCancelled(true); |
|
1025 if (hGlobalDevMode) ::GlobalFree(hGlobalDevMode); |
|
1026 return NS_ERROR_ABORT; |
|
1027 } |
|
1028 |
|
1029 return NS_OK; |
|
1030 } |
|
1031 |
|
1032 //------------------------------------------------------------------ |
|
1033 static void |
|
1034 PrepareForPrintDialog(nsIWebBrowserPrint* aWebBrowserPrint, nsIPrintSettings* aPS) |
|
1035 { |
|
1036 NS_ASSERTION(aWebBrowserPrint, "Can't be null"); |
|
1037 NS_ASSERTION(aPS, "Can't be null"); |
|
1038 |
|
1039 bool isFramesetDocument; |
|
1040 bool isFramesetFrameSelected; |
|
1041 bool isIFrameSelected; |
|
1042 bool isRangeSelection; |
|
1043 |
|
1044 aWebBrowserPrint->GetIsFramesetDocument(&isFramesetDocument); |
|
1045 aWebBrowserPrint->GetIsFramesetFrameSelected(&isFramesetFrameSelected); |
|
1046 aWebBrowserPrint->GetIsIFrameSelected(&isIFrameSelected); |
|
1047 aWebBrowserPrint->GetIsRangeSelection(&isRangeSelection); |
|
1048 |
|
1049 // Setup print options for UI |
|
1050 if (isFramesetDocument) { |
|
1051 if (isFramesetFrameSelected) { |
|
1052 aPS->SetHowToEnableFrameUI(nsIPrintSettings::kFrameEnableAll); |
|
1053 } else { |
|
1054 aPS->SetHowToEnableFrameUI(nsIPrintSettings::kFrameEnableAsIsAndEach); |
|
1055 } |
|
1056 } else { |
|
1057 aPS->SetHowToEnableFrameUI(nsIPrintSettings::kFrameEnableNone); |
|
1058 } |
|
1059 |
|
1060 // Now determine how to set up the Frame print UI |
|
1061 aPS->SetPrintOptions(nsIPrintSettings::kEnableSelectionRB, isRangeSelection || isIFrameSelected); |
|
1062 |
|
1063 } |
|
1064 |
|
1065 //---------------------------------------------------------------------------------- |
|
1066 //-- Show Print Dialog |
|
1067 //---------------------------------------------------------------------------------- |
|
1068 nsresult NativeShowPrintDialog(HWND aHWnd, |
|
1069 nsIWebBrowserPrint* aWebBrowserPrint, |
|
1070 nsIPrintSettings* aPrintSettings) |
|
1071 { |
|
1072 PrepareForPrintDialog(aWebBrowserPrint, aPrintSettings); |
|
1073 |
|
1074 nsresult rv = ShowNativePrintDialog(aHWnd, aPrintSettings); |
|
1075 if (aHWnd) { |
|
1076 ::DestroyWindow(aHWnd); |
|
1077 } |
|
1078 |
|
1079 return rv; |
|
1080 } |
|
1081 |