michael@0: // -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- michael@0: michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: var gPrintSettingsAreGlobal = false; michael@0: var gSavePrintSettings = false; michael@0: var gFocusedElement = null; michael@0: michael@0: var PrintUtils = { michael@0: michael@0: showPageSetup: function () michael@0: { michael@0: try { michael@0: var printSettings = this.getPrintSettings(); michael@0: var PRINTPROMPTSVC = Components.classes["@mozilla.org/embedcomp/printingprompt-service;1"] michael@0: .getService(Components.interfaces.nsIPrintingPromptService); michael@0: PRINTPROMPTSVC.showPageSetup(window, printSettings, null); michael@0: if (gSavePrintSettings) { michael@0: // Page Setup data is a "native" setting on the Mac michael@0: var PSSVC = Components.classes["@mozilla.org/gfx/printsettings-service;1"] michael@0: .getService(Components.interfaces.nsIPrintSettingsService); michael@0: PSSVC.savePrintSettingsToPrefs(printSettings, true, printSettings.kInitSaveNativeData); michael@0: } michael@0: } catch (e) { michael@0: dump("showPageSetup "+e+"\n"); michael@0: return false; michael@0: } michael@0: return true; michael@0: }, michael@0: michael@0: print: function (aWindow) michael@0: { michael@0: var webBrowserPrint = this.getWebBrowserPrint(aWindow); michael@0: var printSettings = this.getPrintSettings(); michael@0: try { michael@0: webBrowserPrint.print(printSettings, null); michael@0: if (gPrintSettingsAreGlobal && gSavePrintSettings) { michael@0: var PSSVC = Components.classes["@mozilla.org/gfx/printsettings-service;1"] michael@0: .getService(Components.interfaces.nsIPrintSettingsService); michael@0: PSSVC.savePrintSettingsToPrefs(printSettings, true, michael@0: printSettings.kInitSaveAll); michael@0: PSSVC.savePrintSettingsToPrefs(printSettings, false, michael@0: printSettings.kInitSavePrinterName); michael@0: } michael@0: } catch (e) { michael@0: // Pressing cancel is expressed as an NS_ERROR_ABORT return value, michael@0: // causing an exception to be thrown which we catch here. michael@0: // Unfortunately this will also consume helpful failures, so add a michael@0: // dump("print: "+e+"\n"); // if you need to debug michael@0: } michael@0: }, michael@0: michael@0: // If aCallback is not null, it must be an object which has the following methods: michael@0: // getPrintPreviewBrowser(), getSourceBrowser(), michael@0: // getNavToolbox(), onEnter() and onExit(). michael@0: // If aCallback is null, then printPreview must previously have been called with michael@0: // non-null aCallback and that object will be reused. michael@0: printPreview: function (aCallback) michael@0: { michael@0: // if we're already in PP mode, don't set the callback; chances michael@0: // are it is null because someone is calling printPreview() to michael@0: // get us to refresh the display. michael@0: if (!document.getElementById("print-preview-toolbar")) { michael@0: this._callback = aCallback; michael@0: this._sourceBrowser = aCallback.getSourceBrowser(); michael@0: this._originalTitle = this._sourceBrowser.contentDocument.title; michael@0: this._originalURL = this._sourceBrowser.currentURI.spec; michael@0: } else { michael@0: // collapse the browser here -- it will be shown in michael@0: // enterPrintPreview; this forces a reflow which fixes display michael@0: // issues in bug 267422. michael@0: this._sourceBrowser = this._callback.getPrintPreviewBrowser(); michael@0: this._sourceBrowser.collapsed = true; michael@0: } michael@0: michael@0: this._webProgressPP = {}; michael@0: var ppParams = {}; michael@0: var notifyOnOpen = {}; michael@0: var webBrowserPrint = this.getWebBrowserPrint(); michael@0: var printSettings = this.getPrintSettings(); michael@0: // Here we get the PrintingPromptService so we can display the PP Progress from script michael@0: // For the browser implemented via XUL with the PP toolbar we cannot let it be michael@0: // automatically opened from the print engine because the XUL scrollbars in the PP window michael@0: // will layout before the content window and a crash will occur. michael@0: // Doing it all from script, means it lays out before hand and we can let printing do its own thing michael@0: var PPROMPTSVC = Components.classes["@mozilla.org/embedcomp/printingprompt-service;1"] michael@0: .getService(Components.interfaces.nsIPrintingPromptService); michael@0: // just in case we are already printing, michael@0: // an error code could be returned if the Prgress Dialog is already displayed michael@0: try { michael@0: PPROMPTSVC.showProgress(window, webBrowserPrint, printSettings, this._obsPP, false, michael@0: this._webProgressPP, ppParams, notifyOnOpen); michael@0: if (ppParams.value) { michael@0: ppParams.value.docTitle = this._originalTitle; michael@0: ppParams.value.docURL = this._originalURL; michael@0: } michael@0: michael@0: // this tells us whether we should continue on with PP or michael@0: // wait for the callback via the observer michael@0: if (!notifyOnOpen.value.valueOf() || this._webProgressPP.value == null) michael@0: this.enterPrintPreview(); michael@0: } catch (e) { michael@0: this.enterPrintPreview(); michael@0: } michael@0: }, michael@0: michael@0: getWebBrowserPrint: function (aWindow) michael@0: { michael@0: var contentWindow = aWindow || window.content; michael@0: return contentWindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor) michael@0: .getInterface(Components.interfaces.nsIWebBrowserPrint); michael@0: }, michael@0: michael@0: getPrintPreview: function() { michael@0: return this._callback.getPrintPreviewBrowser().docShell.printPreview; michael@0: }, michael@0: michael@0: //////////////////////////////////////// michael@0: // "private" methods. Don't use them. // michael@0: //////////////////////////////////////// michael@0: michael@0: setPrinterDefaultsForSelectedPrinter: function (aPSSVC, aPrintSettings) michael@0: { michael@0: if (!aPrintSettings.printerName) michael@0: aPrintSettings.printerName = aPSSVC.defaultPrinterName; michael@0: michael@0: // First get any defaults from the printer michael@0: aPSSVC.initPrintSettingsFromPrinter(aPrintSettings.printerName, aPrintSettings); michael@0: // now augment them with any values from last time michael@0: aPSSVC.initPrintSettingsFromPrefs(aPrintSettings, true, aPrintSettings.kInitSaveAll); michael@0: }, michael@0: michael@0: getPrintSettings: function () michael@0: { michael@0: var pref = Components.classes["@mozilla.org/preferences-service;1"] michael@0: .getService(Components.interfaces.nsIPrefBranch); michael@0: if (pref) { michael@0: gPrintSettingsAreGlobal = pref.getBoolPref("print.use_global_printsettings", false); michael@0: gSavePrintSettings = pref.getBoolPref("print.save_print_settings", false); michael@0: } michael@0: michael@0: var printSettings; michael@0: try { michael@0: var PSSVC = Components.classes["@mozilla.org/gfx/printsettings-service;1"] michael@0: .getService(Components.interfaces.nsIPrintSettingsService); michael@0: if (gPrintSettingsAreGlobal) { michael@0: printSettings = PSSVC.globalPrintSettings; michael@0: this.setPrinterDefaultsForSelectedPrinter(PSSVC, printSettings); michael@0: } else { michael@0: printSettings = PSSVC.newPrintSettings; michael@0: } michael@0: } catch (e) { michael@0: dump("getPrintSettings: "+e+"\n"); michael@0: } michael@0: return printSettings; michael@0: }, michael@0: michael@0: _closeHandlerPP: null, michael@0: _webProgressPP: null, michael@0: _callback: null, michael@0: _sourceBrowser: null, michael@0: _originalTitle: "", michael@0: _originalURL: "", michael@0: michael@0: // This observer is called once the progress dialog has been "opened" michael@0: _obsPP: michael@0: { michael@0: observe: function(aSubject, aTopic, aData) michael@0: { michael@0: // delay the print preview to show the content of the progress dialog michael@0: setTimeout(function () { PrintUtils.enterPrintPreview(); }, 0); michael@0: }, michael@0: michael@0: QueryInterface : function(iid) michael@0: { michael@0: if (iid.equals(Components.interfaces.nsIObserver) || michael@0: iid.equals(Components.interfaces.nsISupportsWeakReference) || michael@0: iid.equals(Components.interfaces.nsISupports)) michael@0: return this; michael@0: throw Components.results.NS_NOINTERFACE; michael@0: } michael@0: }, michael@0: michael@0: enterPrintPreview: function () michael@0: { michael@0: gFocusedElement = document.commandDispatcher.focusedElement; michael@0: michael@0: var webBrowserPrint; michael@0: var printSettings = this.getPrintSettings(); michael@0: var originalWindow = this._sourceBrowser.contentWindow; michael@0: michael@0: try { michael@0: webBrowserPrint = this.getPrintPreview(); michael@0: webBrowserPrint.printPreview(printSettings, originalWindow, michael@0: this._webProgressPP.value); michael@0: } catch (e) { michael@0: // Pressing cancel is expressed as an NS_ERROR_ABORT return value, michael@0: // causing an exception to be thrown which we catch here. michael@0: // Unfortunately this will also consume helpful failures, so add a michael@0: // dump(e); // if you need to debug michael@0: michael@0: // Need to call enter and exit so that UI gets back to normal. michael@0: this._callback.onEnter(); michael@0: this._callback.onExit(); michael@0: return; michael@0: } michael@0: michael@0: var printPreviewTB = document.getElementById("print-preview-toolbar"); michael@0: if (printPreviewTB) { michael@0: printPreviewTB.updateToolbar(); michael@0: var browser = this._callback.getPrintPreviewBrowser(); michael@0: browser.collapsed = false; michael@0: browser.contentWindow.focus(); michael@0: return; michael@0: } michael@0: michael@0: // Set the original window as an active window so any mozPrintCallbacks can michael@0: // run without delayed setTimeouts. michael@0: var docShell = originalWindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor) michael@0: .getInterface(Components.interfaces.nsIWebNavigation) michael@0: .QueryInterface(Components.interfaces.nsIDocShell); michael@0: docShell.isActive = true; michael@0: michael@0: // show the toolbar after we go into print preview mode so michael@0: // that we can initialize the toolbar with total num pages michael@0: var XUL_NS = michael@0: "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; michael@0: printPreviewTB = document.createElementNS(XUL_NS, "toolbar"); michael@0: printPreviewTB.setAttribute("printpreview", true); michael@0: printPreviewTB.id = "print-preview-toolbar"; michael@0: printPreviewTB.className = "toolbar-primary"; michael@0: michael@0: var navToolbox = this._callback.getNavToolbox(); michael@0: navToolbox.parentNode.insertBefore(printPreviewTB, navToolbox); michael@0: michael@0: // copy the window close handler michael@0: if (document.documentElement.hasAttribute("onclose")) michael@0: this._closeHandlerPP = document.documentElement.getAttribute("onclose"); michael@0: else michael@0: this._closeHandlerPP = null; michael@0: document.documentElement.setAttribute("onclose", "PrintUtils.exitPrintPreview(); return false;"); michael@0: michael@0: // disable chrome shortcuts... michael@0: window.addEventListener("keydown", this.onKeyDownPP, true); michael@0: window.addEventListener("keypress", this.onKeyPressPP, true); michael@0: michael@0: var browser = this._callback.getPrintPreviewBrowser(); michael@0: browser.collapsed = false; michael@0: browser.contentWindow.focus(); michael@0: michael@0: // on Enter PP Call back michael@0: this._callback.onEnter(); michael@0: }, michael@0: michael@0: exitPrintPreview: function () michael@0: { michael@0: window.removeEventListener("keydown", this.onKeyDownPP, true); michael@0: window.removeEventListener("keypress", this.onKeyPressPP, true); michael@0: michael@0: // restore the old close handler michael@0: document.documentElement.setAttribute("onclose", this._closeHandlerPP); michael@0: this._closeHandlerPP = null; michael@0: michael@0: var webBrowserPrint = this.getPrintPreview(); michael@0: webBrowserPrint.exitPrintPreview(); michael@0: michael@0: // remove the print preview toolbar michael@0: var printPreviewTB = document.getElementById("print-preview-toolbar"); michael@0: this._callback.getNavToolbox().parentNode.removeChild(printPreviewTB); michael@0: michael@0: var fm = Components.classes["@mozilla.org/focus-manager;1"] michael@0: .getService(Components.interfaces.nsIFocusManager); michael@0: if (gFocusedElement) michael@0: fm.setFocus(gFocusedElement, fm.FLAG_NOSCROLL); michael@0: else michael@0: window.content.focus(); michael@0: gFocusedElement = null; michael@0: michael@0: this._callback.onExit(); michael@0: }, michael@0: michael@0: onKeyDownPP: function (aEvent) michael@0: { michael@0: // Esc exits the PP michael@0: if (aEvent.keyCode == aEvent.DOM_VK_ESCAPE) { michael@0: PrintUtils.exitPrintPreview(); michael@0: } michael@0: }, michael@0: michael@0: onKeyPressPP: function (aEvent) michael@0: { michael@0: var closeKey; michael@0: try { michael@0: closeKey = document.getElementById("key_close") michael@0: .getAttribute("key"); michael@0: closeKey = aEvent["DOM_VK_"+closeKey]; michael@0: } catch (e) {} michael@0: var isModif = aEvent.ctrlKey || aEvent.metaKey; michael@0: // Ctrl-W exits the PP michael@0: if (isModif && michael@0: (aEvent.charCode == closeKey || aEvent.charCode == closeKey + 32)) { michael@0: PrintUtils.exitPrintPreview(); michael@0: } michael@0: else if (isModif) { michael@0: var printPreviewTB = document.getElementById("print-preview-toolbar"); michael@0: var printKey = document.getElementById("printKb").getAttribute("key").toUpperCase(); michael@0: var pressedKey = String.fromCharCode(aEvent.charCode).toUpperCase(); michael@0: if (printKey == pressedKey) { michael@0: PrintUtils.print(); michael@0: } michael@0: } michael@0: // cancel shortkeys michael@0: if (isModif) { michael@0: aEvent.preventDefault(); michael@0: aEvent.stopPropagation(); michael@0: } michael@0: } michael@0: }