1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/components/printing/content/printUtils.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,320 @@ 1.4 +// -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- 1.5 + 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +var gPrintSettingsAreGlobal = false; 1.11 +var gSavePrintSettings = false; 1.12 +var gFocusedElement = null; 1.13 + 1.14 +var PrintUtils = { 1.15 + 1.16 + showPageSetup: function () 1.17 + { 1.18 + try { 1.19 + var printSettings = this.getPrintSettings(); 1.20 + var PRINTPROMPTSVC = Components.classes["@mozilla.org/embedcomp/printingprompt-service;1"] 1.21 + .getService(Components.interfaces.nsIPrintingPromptService); 1.22 + PRINTPROMPTSVC.showPageSetup(window, printSettings, null); 1.23 + if (gSavePrintSettings) { 1.24 + // Page Setup data is a "native" setting on the Mac 1.25 + var PSSVC = Components.classes["@mozilla.org/gfx/printsettings-service;1"] 1.26 + .getService(Components.interfaces.nsIPrintSettingsService); 1.27 + PSSVC.savePrintSettingsToPrefs(printSettings, true, printSettings.kInitSaveNativeData); 1.28 + } 1.29 + } catch (e) { 1.30 + dump("showPageSetup "+e+"\n"); 1.31 + return false; 1.32 + } 1.33 + return true; 1.34 + }, 1.35 + 1.36 + print: function (aWindow) 1.37 + { 1.38 + var webBrowserPrint = this.getWebBrowserPrint(aWindow); 1.39 + var printSettings = this.getPrintSettings(); 1.40 + try { 1.41 + webBrowserPrint.print(printSettings, null); 1.42 + if (gPrintSettingsAreGlobal && gSavePrintSettings) { 1.43 + var PSSVC = Components.classes["@mozilla.org/gfx/printsettings-service;1"] 1.44 + .getService(Components.interfaces.nsIPrintSettingsService); 1.45 + PSSVC.savePrintSettingsToPrefs(printSettings, true, 1.46 + printSettings.kInitSaveAll); 1.47 + PSSVC.savePrintSettingsToPrefs(printSettings, false, 1.48 + printSettings.kInitSavePrinterName); 1.49 + } 1.50 + } catch (e) { 1.51 + // Pressing cancel is expressed as an NS_ERROR_ABORT return value, 1.52 + // causing an exception to be thrown which we catch here. 1.53 + // Unfortunately this will also consume helpful failures, so add a 1.54 + // dump("print: "+e+"\n"); // if you need to debug 1.55 + } 1.56 + }, 1.57 + 1.58 + // If aCallback is not null, it must be an object which has the following methods: 1.59 + // getPrintPreviewBrowser(), getSourceBrowser(), 1.60 + // getNavToolbox(), onEnter() and onExit(). 1.61 + // If aCallback is null, then printPreview must previously have been called with 1.62 + // non-null aCallback and that object will be reused. 1.63 + printPreview: function (aCallback) 1.64 + { 1.65 + // if we're already in PP mode, don't set the callback; chances 1.66 + // are it is null because someone is calling printPreview() to 1.67 + // get us to refresh the display. 1.68 + if (!document.getElementById("print-preview-toolbar")) { 1.69 + this._callback = aCallback; 1.70 + this._sourceBrowser = aCallback.getSourceBrowser(); 1.71 + this._originalTitle = this._sourceBrowser.contentDocument.title; 1.72 + this._originalURL = this._sourceBrowser.currentURI.spec; 1.73 + } else { 1.74 + // collapse the browser here -- it will be shown in 1.75 + // enterPrintPreview; this forces a reflow which fixes display 1.76 + // issues in bug 267422. 1.77 + this._sourceBrowser = this._callback.getPrintPreviewBrowser(); 1.78 + this._sourceBrowser.collapsed = true; 1.79 + } 1.80 + 1.81 + this._webProgressPP = {}; 1.82 + var ppParams = {}; 1.83 + var notifyOnOpen = {}; 1.84 + var webBrowserPrint = this.getWebBrowserPrint(); 1.85 + var printSettings = this.getPrintSettings(); 1.86 + // Here we get the PrintingPromptService so we can display the PP Progress from script 1.87 + // For the browser implemented via XUL with the PP toolbar we cannot let it be 1.88 + // automatically opened from the print engine because the XUL scrollbars in the PP window 1.89 + // will layout before the content window and a crash will occur. 1.90 + // Doing it all from script, means it lays out before hand and we can let printing do its own thing 1.91 + var PPROMPTSVC = Components.classes["@mozilla.org/embedcomp/printingprompt-service;1"] 1.92 + .getService(Components.interfaces.nsIPrintingPromptService); 1.93 + // just in case we are already printing, 1.94 + // an error code could be returned if the Prgress Dialog is already displayed 1.95 + try { 1.96 + PPROMPTSVC.showProgress(window, webBrowserPrint, printSettings, this._obsPP, false, 1.97 + this._webProgressPP, ppParams, notifyOnOpen); 1.98 + if (ppParams.value) { 1.99 + ppParams.value.docTitle = this._originalTitle; 1.100 + ppParams.value.docURL = this._originalURL; 1.101 + } 1.102 + 1.103 + // this tells us whether we should continue on with PP or 1.104 + // wait for the callback via the observer 1.105 + if (!notifyOnOpen.value.valueOf() || this._webProgressPP.value == null) 1.106 + this.enterPrintPreview(); 1.107 + } catch (e) { 1.108 + this.enterPrintPreview(); 1.109 + } 1.110 + }, 1.111 + 1.112 + getWebBrowserPrint: function (aWindow) 1.113 + { 1.114 + var contentWindow = aWindow || window.content; 1.115 + return contentWindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor) 1.116 + .getInterface(Components.interfaces.nsIWebBrowserPrint); 1.117 + }, 1.118 + 1.119 + getPrintPreview: function() { 1.120 + return this._callback.getPrintPreviewBrowser().docShell.printPreview; 1.121 + }, 1.122 + 1.123 + //////////////////////////////////////// 1.124 + // "private" methods. Don't use them. // 1.125 + //////////////////////////////////////// 1.126 + 1.127 + setPrinterDefaultsForSelectedPrinter: function (aPSSVC, aPrintSettings) 1.128 + { 1.129 + if (!aPrintSettings.printerName) 1.130 + aPrintSettings.printerName = aPSSVC.defaultPrinterName; 1.131 + 1.132 + // First get any defaults from the printer 1.133 + aPSSVC.initPrintSettingsFromPrinter(aPrintSettings.printerName, aPrintSettings); 1.134 + // now augment them with any values from last time 1.135 + aPSSVC.initPrintSettingsFromPrefs(aPrintSettings, true, aPrintSettings.kInitSaveAll); 1.136 + }, 1.137 + 1.138 + getPrintSettings: function () 1.139 + { 1.140 + var pref = Components.classes["@mozilla.org/preferences-service;1"] 1.141 + .getService(Components.interfaces.nsIPrefBranch); 1.142 + if (pref) { 1.143 + gPrintSettingsAreGlobal = pref.getBoolPref("print.use_global_printsettings", false); 1.144 + gSavePrintSettings = pref.getBoolPref("print.save_print_settings", false); 1.145 + } 1.146 + 1.147 + var printSettings; 1.148 + try { 1.149 + var PSSVC = Components.classes["@mozilla.org/gfx/printsettings-service;1"] 1.150 + .getService(Components.interfaces.nsIPrintSettingsService); 1.151 + if (gPrintSettingsAreGlobal) { 1.152 + printSettings = PSSVC.globalPrintSettings; 1.153 + this.setPrinterDefaultsForSelectedPrinter(PSSVC, printSettings); 1.154 + } else { 1.155 + printSettings = PSSVC.newPrintSettings; 1.156 + } 1.157 + } catch (e) { 1.158 + dump("getPrintSettings: "+e+"\n"); 1.159 + } 1.160 + return printSettings; 1.161 + }, 1.162 + 1.163 + _closeHandlerPP: null, 1.164 + _webProgressPP: null, 1.165 + _callback: null, 1.166 + _sourceBrowser: null, 1.167 + _originalTitle: "", 1.168 + _originalURL: "", 1.169 + 1.170 + // This observer is called once the progress dialog has been "opened" 1.171 + _obsPP: 1.172 + { 1.173 + observe: function(aSubject, aTopic, aData) 1.174 + { 1.175 + // delay the print preview to show the content of the progress dialog 1.176 + setTimeout(function () { PrintUtils.enterPrintPreview(); }, 0); 1.177 + }, 1.178 + 1.179 + QueryInterface : function(iid) 1.180 + { 1.181 + if (iid.equals(Components.interfaces.nsIObserver) || 1.182 + iid.equals(Components.interfaces.nsISupportsWeakReference) || 1.183 + iid.equals(Components.interfaces.nsISupports)) 1.184 + return this; 1.185 + throw Components.results.NS_NOINTERFACE; 1.186 + } 1.187 + }, 1.188 + 1.189 + enterPrintPreview: function () 1.190 + { 1.191 + gFocusedElement = document.commandDispatcher.focusedElement; 1.192 + 1.193 + var webBrowserPrint; 1.194 + var printSettings = this.getPrintSettings(); 1.195 + var originalWindow = this._sourceBrowser.contentWindow; 1.196 + 1.197 + try { 1.198 + webBrowserPrint = this.getPrintPreview(); 1.199 + webBrowserPrint.printPreview(printSettings, originalWindow, 1.200 + this._webProgressPP.value); 1.201 + } catch (e) { 1.202 + // Pressing cancel is expressed as an NS_ERROR_ABORT return value, 1.203 + // causing an exception to be thrown which we catch here. 1.204 + // Unfortunately this will also consume helpful failures, so add a 1.205 + // dump(e); // if you need to debug 1.206 + 1.207 + // Need to call enter and exit so that UI gets back to normal. 1.208 + this._callback.onEnter(); 1.209 + this._callback.onExit(); 1.210 + return; 1.211 + } 1.212 + 1.213 + var printPreviewTB = document.getElementById("print-preview-toolbar"); 1.214 + if (printPreviewTB) { 1.215 + printPreviewTB.updateToolbar(); 1.216 + var browser = this._callback.getPrintPreviewBrowser(); 1.217 + browser.collapsed = false; 1.218 + browser.contentWindow.focus(); 1.219 + return; 1.220 + } 1.221 + 1.222 + // Set the original window as an active window so any mozPrintCallbacks can 1.223 + // run without delayed setTimeouts. 1.224 + var docShell = originalWindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor) 1.225 + .getInterface(Components.interfaces.nsIWebNavigation) 1.226 + .QueryInterface(Components.interfaces.nsIDocShell); 1.227 + docShell.isActive = true; 1.228 + 1.229 + // show the toolbar after we go into print preview mode so 1.230 + // that we can initialize the toolbar with total num pages 1.231 + var XUL_NS = 1.232 + "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; 1.233 + printPreviewTB = document.createElementNS(XUL_NS, "toolbar"); 1.234 + printPreviewTB.setAttribute("printpreview", true); 1.235 + printPreviewTB.id = "print-preview-toolbar"; 1.236 + printPreviewTB.className = "toolbar-primary"; 1.237 + 1.238 + var navToolbox = this._callback.getNavToolbox(); 1.239 + navToolbox.parentNode.insertBefore(printPreviewTB, navToolbox); 1.240 + 1.241 + // copy the window close handler 1.242 + if (document.documentElement.hasAttribute("onclose")) 1.243 + this._closeHandlerPP = document.documentElement.getAttribute("onclose"); 1.244 + else 1.245 + this._closeHandlerPP = null; 1.246 + document.documentElement.setAttribute("onclose", "PrintUtils.exitPrintPreview(); return false;"); 1.247 + 1.248 + // disable chrome shortcuts... 1.249 + window.addEventListener("keydown", this.onKeyDownPP, true); 1.250 + window.addEventListener("keypress", this.onKeyPressPP, true); 1.251 + 1.252 + var browser = this._callback.getPrintPreviewBrowser(); 1.253 + browser.collapsed = false; 1.254 + browser.contentWindow.focus(); 1.255 + 1.256 + // on Enter PP Call back 1.257 + this._callback.onEnter(); 1.258 + }, 1.259 + 1.260 + exitPrintPreview: function () 1.261 + { 1.262 + window.removeEventListener("keydown", this.onKeyDownPP, true); 1.263 + window.removeEventListener("keypress", this.onKeyPressPP, true); 1.264 + 1.265 + // restore the old close handler 1.266 + document.documentElement.setAttribute("onclose", this._closeHandlerPP); 1.267 + this._closeHandlerPP = null; 1.268 + 1.269 + var webBrowserPrint = this.getPrintPreview(); 1.270 + webBrowserPrint.exitPrintPreview(); 1.271 + 1.272 + // remove the print preview toolbar 1.273 + var printPreviewTB = document.getElementById("print-preview-toolbar"); 1.274 + this._callback.getNavToolbox().parentNode.removeChild(printPreviewTB); 1.275 + 1.276 + var fm = Components.classes["@mozilla.org/focus-manager;1"] 1.277 + .getService(Components.interfaces.nsIFocusManager); 1.278 + if (gFocusedElement) 1.279 + fm.setFocus(gFocusedElement, fm.FLAG_NOSCROLL); 1.280 + else 1.281 + window.content.focus(); 1.282 + gFocusedElement = null; 1.283 + 1.284 + this._callback.onExit(); 1.285 + }, 1.286 + 1.287 + onKeyDownPP: function (aEvent) 1.288 + { 1.289 + // Esc exits the PP 1.290 + if (aEvent.keyCode == aEvent.DOM_VK_ESCAPE) { 1.291 + PrintUtils.exitPrintPreview(); 1.292 + } 1.293 + }, 1.294 + 1.295 + onKeyPressPP: function (aEvent) 1.296 + { 1.297 + var closeKey; 1.298 + try { 1.299 + closeKey = document.getElementById("key_close") 1.300 + .getAttribute("key"); 1.301 + closeKey = aEvent["DOM_VK_"+closeKey]; 1.302 + } catch (e) {} 1.303 + var isModif = aEvent.ctrlKey || aEvent.metaKey; 1.304 + // Ctrl-W exits the PP 1.305 + if (isModif && 1.306 + (aEvent.charCode == closeKey || aEvent.charCode == closeKey + 32)) { 1.307 + PrintUtils.exitPrintPreview(); 1.308 + } 1.309 + else if (isModif) { 1.310 + var printPreviewTB = document.getElementById("print-preview-toolbar"); 1.311 + var printKey = document.getElementById("printKb").getAttribute("key").toUpperCase(); 1.312 + var pressedKey = String.fromCharCode(aEvent.charCode).toUpperCase(); 1.313 + if (printKey == pressedKey) { 1.314 + PrintUtils.print(); 1.315 + } 1.316 + } 1.317 + // cancel shortkeys 1.318 + if (isModif) { 1.319 + aEvent.preventDefault(); 1.320 + aEvent.stopPropagation(); 1.321 + } 1.322 + } 1.323 +}