Bug 1943650 - Command-line --help output misformatted after --dbus-service. r=emilio
[gecko.git] / toolkit / components / printing / content / printPageSetup.js
blob91f5786243da28d72da914a1d3010a4ba6a68227
1 // -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 var gDialog;
8 var paramBlock;
9 var gPrintService = null;
10 var gPrintSettings = null;
11 var gStringBundle = null;
12 var gDoingMetric = false;
14 var gPrintSettingsInterface = Ci.nsIPrintSettings;
15 var gDoDebug = false;
17 // ---------------------------------------------------
18 function initDialog() {
19 gDialog = {};
21 gDialog.orientation = document.getElementById("orientation");
22 gDialog.portrait = document.getElementById("portrait");
23 gDialog.landscape = document.getElementById("landscape");
25 gDialog.printBG = document.getElementById("printBG");
27 gDialog.shrinkToFit = document.getElementById("shrinkToFit");
29 gDialog.marginGroup = document.getElementById("marginGroup");
31 gDialog.marginPage = document.getElementById("marginPage");
32 gDialog.marginTop = document.getElementById("marginTop");
33 gDialog.marginBottom = document.getElementById("marginBottom");
34 gDialog.marginLeft = document.getElementById("marginLeft");
35 gDialog.marginRight = document.getElementById("marginRight");
37 gDialog.topInput = document.getElementById("topInput");
38 gDialog.bottomInput = document.getElementById("bottomInput");
39 gDialog.leftInput = document.getElementById("leftInput");
40 gDialog.rightInput = document.getElementById("rightInput");
42 gDialog.hLeftOption = document.getElementById("hLeftOption");
43 gDialog.hCenterOption = document.getElementById("hCenterOption");
44 gDialog.hRightOption = document.getElementById("hRightOption");
46 gDialog.fLeftOption = document.getElementById("fLeftOption");
47 gDialog.fCenterOption = document.getElementById("fCenterOption");
48 gDialog.fRightOption = document.getElementById("fRightOption");
50 gDialog.scalingLabel = document.getElementById("scalingInput");
51 gDialog.scalingInput = document.getElementById("scalingInput");
53 gDialog.enabled = false;
55 document.addEventListener("dialogaccept", onAccept);
58 // ---------------------------------------------------
59 function isListOfPrinterFeaturesAvailable() {
60 return Services.prefs.getBoolPref(
61 "print.tmp.printerfeatures." +
62 gPrintSettings.printerName +
63 ".has_special_printerfeatures",
64 false
68 // ---------------------------------------------------
69 function checkDouble(element) {
70 element.value = element.value.replace(/[^.0-9]/g, "");
73 // Theoretical paper width/height.
74 var gPageWidth = 8.5;
75 var gPageHeight = 11.0;
77 // ---------------------------------------------------
78 function setOrientation() {
79 var selection = gDialog.orientation.selectedItem;
81 var style = "background-color:white;";
82 if (
83 (selection == gDialog.portrait && gPageWidth > gPageHeight) ||
84 (selection == gDialog.landscape && gPageWidth < gPageHeight)
85 ) {
86 // Swap width/height.
87 var temp = gPageHeight;
88 gPageHeight = gPageWidth;
89 gPageWidth = temp;
91 var div = gDoingMetric ? 100 : 10;
92 style +=
93 "width:" +
94 gPageWidth / div +
95 unitString() +
96 ";height:" +
97 gPageHeight / div +
98 unitString() +
99 ";";
100 gDialog.marginPage.setAttribute("style", style);
103 // ---------------------------------------------------
104 function unitString() {
105 return gPrintSettings.paperSizeUnit ==
106 gPrintSettingsInterface.kPaperSizeInches
107 ? "in"
108 : "mm";
111 // ---------------------------------------------------
112 function checkMargin(value, max, other) {
113 // Don't draw this margin bigger than permitted.
114 return Math.min(value, max - other.value);
117 // ---------------------------------------------------
118 function changeMargin(node) {
119 // Correct invalid input.
120 checkDouble(node);
122 // Reset the margin height/width for this node.
123 var val = node.value;
124 var nodeToStyle;
125 var attr = "width";
126 if (node == gDialog.topInput) {
127 nodeToStyle = gDialog.marginTop;
128 val = checkMargin(val, gPageHeight, gDialog.bottomInput);
129 attr = "height";
130 } else if (node == gDialog.bottomInput) {
131 nodeToStyle = gDialog.marginBottom;
132 val = checkMargin(val, gPageHeight, gDialog.topInput);
133 attr = "height";
134 } else if (node == gDialog.leftInput) {
135 nodeToStyle = gDialog.marginLeft;
136 val = checkMargin(val, gPageWidth, gDialog.rightInput);
137 } else {
138 nodeToStyle = gDialog.marginRight;
139 val = checkMargin(val, gPageWidth, gDialog.leftInput);
141 var style = attr + ":" + val / 10 + unitString() + ";";
142 nodeToStyle.setAttribute("style", style);
145 // ---------------------------------------------------
146 function changeMargins() {
147 changeMargin(gDialog.topInput);
148 changeMargin(gDialog.bottomInput);
149 changeMargin(gDialog.leftInput);
150 changeMargin(gDialog.rightInput);
153 // ---------------------------------------------------
154 async function customize(node) {
155 // If selection is now "Custom..." then prompt user for custom setting.
156 if (node.value == 6) {
157 let [title, promptText] = await document.l10n.formatValues([
158 { id: "custom-prompt-title" },
159 { id: "custom-prompt-prompt" },
161 var result = { value: node.custom };
162 var ok = Services.prompt.prompt(window, title, promptText, result, null, {
163 value: false,
165 if (ok) {
166 node.custom = result.value;
171 // ---------------------------------------------------
172 function setHeaderFooter(node, value) {
173 node.value = hfValueToId(value);
174 if (node.value == 6) {
175 // Remember current Custom... value.
176 node.custom = value;
177 } else {
178 // Start with empty Custom... value.
179 node.custom = "";
183 var gHFValues = [];
184 gHFValues["&T"] = 1;
185 gHFValues["&U"] = 2;
186 gHFValues["&D"] = 3;
187 gHFValues["&P"] = 4;
188 gHFValues["&PT"] = 5;
190 function hfValueToId(val) {
191 if (val in gHFValues) {
192 return gHFValues[val];
194 if (val.length) {
195 return 6; // Custom...
197 return 0; // --blank--
200 function hfIdToValue(node) {
201 var result = "";
202 switch (parseInt(node.value)) {
203 case 0:
204 break;
205 case 1:
206 result = "&T";
207 break;
208 case 2:
209 result = "&U";
210 break;
211 case 3:
212 result = "&D";
213 break;
214 case 4:
215 result = "&P";
216 break;
217 case 5:
218 result = "&PT";
219 break;
220 case 6:
221 result = node.custom;
222 break;
224 return result;
227 async function lastUsedPrinterNameOrDefault() {
228 let printerList = Cc["@mozilla.org/gfx/printerlist;1"].getService(
229 Ci.nsIPrinterList
231 let lastUsedName = gPrintService.lastUsedPrinterName;
232 let printers = await printerList.printers;
233 for (let printer of printers) {
234 printer.QueryInterface(Ci.nsIPrinter);
235 if (printer.name == lastUsedName) {
236 return lastUsedName;
239 return printerList.systemDefaultPrinterName;
242 async function setPrinterDefaultsForSelectedPrinter() {
243 if (gPrintSettings.printerName == "") {
244 gPrintSettings.printerName = await lastUsedPrinterNameOrDefault();
247 // First get any defaults from the printer
248 gPrintService.initPrintSettingsFromPrinter(
249 gPrintSettings.printerName,
250 gPrintSettings
253 // now augment them with any values from last time
254 gPrintService.initPrintSettingsFromPrefs(
255 gPrintSettings,
256 true,
257 gPrintSettingsInterface.kInitSaveAll
260 if (gDoDebug) {
261 dump(
262 "pagesetup/setPrinterDefaultsForSelectedPrinter: printerName='" +
263 gPrintSettings.printerName +
264 "', orientation='" +
265 gPrintSettings.orientation +
266 "'\n"
271 // ---------------------------------------------------
272 async function loadDialog() {
273 var print_orientation = 0;
274 var print_margin_top = 0.5;
275 var print_margin_left = 0.5;
276 var print_margin_bottom = 0.5;
277 var print_margin_right = 0.5;
279 try {
280 gPrintService = Cc["@mozilla.org/gfx/printsettings-service;1"];
281 if (gPrintService) {
282 gPrintService = gPrintService.getService();
283 if (gPrintService) {
284 gPrintService = gPrintService.QueryInterface(
285 Ci.nsIPrintSettingsService
289 } catch (ex) {
290 dump("loadDialog: ex=" + ex + "\n");
293 await setPrinterDefaultsForSelectedPrinter();
295 gDialog.printBG.checked =
296 gPrintSettings.printBGColors || gPrintSettings.printBGImages;
298 gDialog.shrinkToFit.checked = gPrintSettings.shrinkToFit;
300 gDialog.scalingLabel.disabled = gDialog.scalingInput.disabled =
301 gDialog.shrinkToFit.checked;
303 if (
304 gPrintSettings.paperSizeUnit == gPrintSettingsInterface.kPaperSizeInches
306 document.l10n.setAttributes(
307 gDialog.marginGroup,
308 "margin-group-label-inches"
310 gDoingMetric = false;
311 } else {
312 document.l10n.setAttributes(
313 gDialog.marginGroup,
314 "margin-group-label-metric"
316 // Also, set global page dimensions for A4 paper, in millimeters (assumes portrait at this point).
317 gPageWidth = 2100;
318 gPageHeight = 2970;
319 gDoingMetric = true;
322 print_orientation = gPrintSettings.orientation;
323 print_margin_top = convertMarginInchesToUnits(
324 gPrintSettings.marginTop,
325 gDoingMetric
327 print_margin_left = convertMarginInchesToUnits(
328 gPrintSettings.marginLeft,
329 gDoingMetric
331 print_margin_right = convertMarginInchesToUnits(
332 gPrintSettings.marginRight,
333 gDoingMetric
335 print_margin_bottom = convertMarginInchesToUnits(
336 gPrintSettings.marginBottom,
337 gDoingMetric
340 if (gDoDebug) {
341 dump("print_orientation " + print_orientation + "\n");
343 dump("print_margin_top " + print_margin_top + "\n");
344 dump("print_margin_left " + print_margin_left + "\n");
345 dump("print_margin_right " + print_margin_right + "\n");
346 dump("print_margin_bottom " + print_margin_bottom + "\n");
349 if (print_orientation == gPrintSettingsInterface.kPortraitOrientation) {
350 gDialog.orientation.selectedItem = gDialog.portrait;
351 } else if (
352 print_orientation == gPrintSettingsInterface.kLandscapeOrientation
354 gDialog.orientation.selectedItem = gDialog.landscape;
357 // Set orientation the first time on a timeout so the dialog sizes to the
358 // maximum height specified in the .xul file. Otherwise, if the user switches
359 // from landscape to portrait, the content grows and the buttons are clipped.
360 setTimeout(setOrientation, 0);
362 gDialog.topInput.value = print_margin_top.toFixed(1);
363 gDialog.bottomInput.value = print_margin_bottom.toFixed(1);
364 gDialog.leftInput.value = print_margin_left.toFixed(1);
365 gDialog.rightInput.value = print_margin_right.toFixed(1);
366 changeMargins();
368 setHeaderFooter(gDialog.hLeftOption, gPrintSettings.headerStrLeft);
369 setHeaderFooter(gDialog.hCenterOption, gPrintSettings.headerStrCenter);
370 setHeaderFooter(gDialog.hRightOption, gPrintSettings.headerStrRight);
372 setHeaderFooter(gDialog.fLeftOption, gPrintSettings.footerStrLeft);
373 setHeaderFooter(gDialog.fCenterOption, gPrintSettings.footerStrCenter);
374 setHeaderFooter(gDialog.fRightOption, gPrintSettings.footerStrRight);
376 gDialog.scalingInput.value = (gPrintSettings.scaling * 100).toFixed(0);
378 // Enable/disable widgets based in the information whether the selected
379 // printer supports the matching feature or not
380 if (isListOfPrinterFeaturesAvailable()) {
381 if (
382 Services.prefs.getBoolPref(
383 "print.tmp.printerfeatures." +
384 gPrintSettings.printerName +
385 ".can_change_orientation"
388 gDialog.orientation.removeAttribute("disabled");
389 } else {
390 gDialog.orientation.setAttribute("disabled", "true");
394 // Give initial focus to the orientation radio group.
395 // Done on a timeout due to to bug 103197.
396 setTimeout(function () {
397 gDialog.orientation.focus();
398 }, 0);
401 // ---------------------------------------------------
402 function onLoad() {
403 // Init gDialog.
404 initDialog();
406 if (window.arguments[0] != null) {
407 gPrintSettings = window.arguments[0].QueryInterface(Ci.nsIPrintSettings);
408 paramBlock = window.arguments[1].QueryInterface(Ci.nsIDialogParamBlock);
409 } else if (gDoDebug) {
410 alert("window.arguments[0] == null!");
413 // default return value is "cancel"
414 paramBlock.SetInt(0, 0);
416 if (gPrintSettings) {
417 loadDialog();
418 } else if (gDoDebug) {
419 alert("Could initialize gDialog, PrintSettings is null!");
423 function convertUnitsMarginToInches(aVal, aIsMetric) {
424 if (aIsMetric) {
425 return aVal / 25.4;
427 return aVal;
430 function convertMarginInchesToUnits(aVal, aIsMetric) {
431 if (aIsMetric) {
432 return aVal * 25.4;
434 return aVal;
437 // ---------------------------------------------------
438 function onAccept() {
439 if (gPrintSettings) {
440 if (gDialog.orientation.selectedItem == gDialog.portrait) {
441 gPrintSettings.orientation = gPrintSettingsInterface.kPortraitOrientation;
442 } else {
443 gPrintSettings.orientation =
444 gPrintSettingsInterface.kLandscapeOrientation;
447 // save these out so they can be picked up by the device spec
448 gPrintSettings.marginTop = convertUnitsMarginToInches(
449 gDialog.topInput.value,
450 gDoingMetric
452 gPrintSettings.marginLeft = convertUnitsMarginToInches(
453 gDialog.leftInput.value,
454 gDoingMetric
456 gPrintSettings.marginBottom = convertUnitsMarginToInches(
457 gDialog.bottomInput.value,
458 gDoingMetric
460 gPrintSettings.marginRight = convertUnitsMarginToInches(
461 gDialog.rightInput.value,
462 gDoingMetric
465 gPrintSettings.headerStrLeft = hfIdToValue(gDialog.hLeftOption);
466 gPrintSettings.headerStrCenter = hfIdToValue(gDialog.hCenterOption);
467 gPrintSettings.headerStrRight = hfIdToValue(gDialog.hRightOption);
469 gPrintSettings.footerStrLeft = hfIdToValue(gDialog.fLeftOption);
470 gPrintSettings.footerStrCenter = hfIdToValue(gDialog.fCenterOption);
471 gPrintSettings.footerStrRight = hfIdToValue(gDialog.fRightOption);
473 gPrintSettings.printBGColors = gDialog.printBG.checked;
474 gPrintSettings.printBGImages = gDialog.printBG.checked;
476 gPrintSettings.shrinkToFit = gDialog.shrinkToFit.checked;
478 var scaling = document.getElementById("scalingInput").value;
479 if (scaling < 10.0) {
480 scaling = 10.0;
482 if (scaling > 500.0) {
483 scaling = 500.0;
485 scaling /= 100.0;
486 gPrintSettings.scaling = scaling;
488 if (gDoDebug) {
489 dump("******* Page Setup Accepting ******\n");
490 dump("print_margin_top " + gDialog.topInput.value + "\n");
491 dump("print_margin_left " + gDialog.leftInput.value + "\n");
492 dump("print_margin_right " + gDialog.bottomInput.value + "\n");
493 dump("print_margin_bottom " + gDialog.rightInput.value + "\n");
497 // set return value to "ok"
498 if (paramBlock) {
499 paramBlock.SetInt(0, 1);
500 } else {
501 dump("*** FATAL ERROR: No paramBlock\n");
504 var flags =
505 gPrintSettingsInterface.kInitSaveMargins |
506 gPrintSettingsInterface.kInitSaveHeaderLeft |
507 gPrintSettingsInterface.kInitSaveHeaderCenter |
508 gPrintSettingsInterface.kInitSaveHeaderRight |
509 gPrintSettingsInterface.kInitSaveFooterLeft |
510 gPrintSettingsInterface.kInitSaveFooterCenter |
511 gPrintSettingsInterface.kInitSaveFooterRight |
512 gPrintSettingsInterface.kInitSaveBGColors |
513 gPrintSettingsInterface.kInitSaveBGImages |
514 gPrintSettingsInterface.kInitSaveInColor |
515 gPrintSettingsInterface.kInitSaveReversed |
516 gPrintSettingsInterface.kInitSaveOrientation |
517 gPrintSettingsInterface.kInitSaveShrinkToFit |
518 gPrintSettingsInterface.kInitSaveScaling;
520 // Note that this file is Windows only code, so this doesn't handle saving
521 // for other platforms.
522 // XXX Should we do this in nsPrintDialogServiceWin::ShowPageSetup (the code
523 // that invokes us), since ShowPageSetup is where we do the saving for the
524 // other platforms?
525 gPrintService.maybeSavePrintSettingsToPrefs(gPrintSettings, flags);
528 // ---------------------------------------------------
529 function onCancel() {
530 // set return value to "cancel"
531 if (paramBlock) {
532 paramBlock.SetInt(0, 0);
533 } else {
534 dump("*** FATAL ERROR: No paramBlock\n");
537 return true;