|
1 // -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- |
|
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/. */ |
|
6 |
|
7 var gPrintSettingsAreGlobal = false; |
|
8 var gSavePrintSettings = false; |
|
9 var gFocusedElement = null; |
|
10 |
|
11 var PrintUtils = { |
|
12 |
|
13 showPageSetup: function () |
|
14 { |
|
15 try { |
|
16 var printSettings = this.getPrintSettings(); |
|
17 var PRINTPROMPTSVC = Components.classes["@mozilla.org/embedcomp/printingprompt-service;1"] |
|
18 .getService(Components.interfaces.nsIPrintingPromptService); |
|
19 PRINTPROMPTSVC.showPageSetup(window, printSettings, null); |
|
20 if (gSavePrintSettings) { |
|
21 // Page Setup data is a "native" setting on the Mac |
|
22 var PSSVC = Components.classes["@mozilla.org/gfx/printsettings-service;1"] |
|
23 .getService(Components.interfaces.nsIPrintSettingsService); |
|
24 PSSVC.savePrintSettingsToPrefs(printSettings, true, printSettings.kInitSaveNativeData); |
|
25 } |
|
26 } catch (e) { |
|
27 dump("showPageSetup "+e+"\n"); |
|
28 return false; |
|
29 } |
|
30 return true; |
|
31 }, |
|
32 |
|
33 print: function (aWindow) |
|
34 { |
|
35 var webBrowserPrint = this.getWebBrowserPrint(aWindow); |
|
36 var printSettings = this.getPrintSettings(); |
|
37 try { |
|
38 webBrowserPrint.print(printSettings, null); |
|
39 if (gPrintSettingsAreGlobal && gSavePrintSettings) { |
|
40 var PSSVC = Components.classes["@mozilla.org/gfx/printsettings-service;1"] |
|
41 .getService(Components.interfaces.nsIPrintSettingsService); |
|
42 PSSVC.savePrintSettingsToPrefs(printSettings, true, |
|
43 printSettings.kInitSaveAll); |
|
44 PSSVC.savePrintSettingsToPrefs(printSettings, false, |
|
45 printSettings.kInitSavePrinterName); |
|
46 } |
|
47 } catch (e) { |
|
48 // Pressing cancel is expressed as an NS_ERROR_ABORT return value, |
|
49 // causing an exception to be thrown which we catch here. |
|
50 // Unfortunately this will also consume helpful failures, so add a |
|
51 // dump("print: "+e+"\n"); // if you need to debug |
|
52 } |
|
53 }, |
|
54 |
|
55 // If aCallback is not null, it must be an object which has the following methods: |
|
56 // getPrintPreviewBrowser(), getSourceBrowser(), |
|
57 // getNavToolbox(), onEnter() and onExit(). |
|
58 // If aCallback is null, then printPreview must previously have been called with |
|
59 // non-null aCallback and that object will be reused. |
|
60 printPreview: function (aCallback) |
|
61 { |
|
62 // if we're already in PP mode, don't set the callback; chances |
|
63 // are it is null because someone is calling printPreview() to |
|
64 // get us to refresh the display. |
|
65 if (!document.getElementById("print-preview-toolbar")) { |
|
66 this._callback = aCallback; |
|
67 this._sourceBrowser = aCallback.getSourceBrowser(); |
|
68 this._originalTitle = this._sourceBrowser.contentDocument.title; |
|
69 this._originalURL = this._sourceBrowser.currentURI.spec; |
|
70 } else { |
|
71 // collapse the browser here -- it will be shown in |
|
72 // enterPrintPreview; this forces a reflow which fixes display |
|
73 // issues in bug 267422. |
|
74 this._sourceBrowser = this._callback.getPrintPreviewBrowser(); |
|
75 this._sourceBrowser.collapsed = true; |
|
76 } |
|
77 |
|
78 this._webProgressPP = {}; |
|
79 var ppParams = {}; |
|
80 var notifyOnOpen = {}; |
|
81 var webBrowserPrint = this.getWebBrowserPrint(); |
|
82 var printSettings = this.getPrintSettings(); |
|
83 // Here we get the PrintingPromptService so we can display the PP Progress from script |
|
84 // For the browser implemented via XUL with the PP toolbar we cannot let it be |
|
85 // automatically opened from the print engine because the XUL scrollbars in the PP window |
|
86 // will layout before the content window and a crash will occur. |
|
87 // Doing it all from script, means it lays out before hand and we can let printing do its own thing |
|
88 var PPROMPTSVC = Components.classes["@mozilla.org/embedcomp/printingprompt-service;1"] |
|
89 .getService(Components.interfaces.nsIPrintingPromptService); |
|
90 // just in case we are already printing, |
|
91 // an error code could be returned if the Prgress Dialog is already displayed |
|
92 try { |
|
93 PPROMPTSVC.showProgress(window, webBrowserPrint, printSettings, this._obsPP, false, |
|
94 this._webProgressPP, ppParams, notifyOnOpen); |
|
95 if (ppParams.value) { |
|
96 ppParams.value.docTitle = this._originalTitle; |
|
97 ppParams.value.docURL = this._originalURL; |
|
98 } |
|
99 |
|
100 // this tells us whether we should continue on with PP or |
|
101 // wait for the callback via the observer |
|
102 if (!notifyOnOpen.value.valueOf() || this._webProgressPP.value == null) |
|
103 this.enterPrintPreview(); |
|
104 } catch (e) { |
|
105 this.enterPrintPreview(); |
|
106 } |
|
107 }, |
|
108 |
|
109 getWebBrowserPrint: function (aWindow) |
|
110 { |
|
111 var contentWindow = aWindow || window.content; |
|
112 return contentWindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor) |
|
113 .getInterface(Components.interfaces.nsIWebBrowserPrint); |
|
114 }, |
|
115 |
|
116 getPrintPreview: function() { |
|
117 return this._callback.getPrintPreviewBrowser().docShell.printPreview; |
|
118 }, |
|
119 |
|
120 //////////////////////////////////////// |
|
121 // "private" methods. Don't use them. // |
|
122 //////////////////////////////////////// |
|
123 |
|
124 setPrinterDefaultsForSelectedPrinter: function (aPSSVC, aPrintSettings) |
|
125 { |
|
126 if (!aPrintSettings.printerName) |
|
127 aPrintSettings.printerName = aPSSVC.defaultPrinterName; |
|
128 |
|
129 // First get any defaults from the printer |
|
130 aPSSVC.initPrintSettingsFromPrinter(aPrintSettings.printerName, aPrintSettings); |
|
131 // now augment them with any values from last time |
|
132 aPSSVC.initPrintSettingsFromPrefs(aPrintSettings, true, aPrintSettings.kInitSaveAll); |
|
133 }, |
|
134 |
|
135 getPrintSettings: function () |
|
136 { |
|
137 var pref = Components.classes["@mozilla.org/preferences-service;1"] |
|
138 .getService(Components.interfaces.nsIPrefBranch); |
|
139 if (pref) { |
|
140 gPrintSettingsAreGlobal = pref.getBoolPref("print.use_global_printsettings", false); |
|
141 gSavePrintSettings = pref.getBoolPref("print.save_print_settings", false); |
|
142 } |
|
143 |
|
144 var printSettings; |
|
145 try { |
|
146 var PSSVC = Components.classes["@mozilla.org/gfx/printsettings-service;1"] |
|
147 .getService(Components.interfaces.nsIPrintSettingsService); |
|
148 if (gPrintSettingsAreGlobal) { |
|
149 printSettings = PSSVC.globalPrintSettings; |
|
150 this.setPrinterDefaultsForSelectedPrinter(PSSVC, printSettings); |
|
151 } else { |
|
152 printSettings = PSSVC.newPrintSettings; |
|
153 } |
|
154 } catch (e) { |
|
155 dump("getPrintSettings: "+e+"\n"); |
|
156 } |
|
157 return printSettings; |
|
158 }, |
|
159 |
|
160 _closeHandlerPP: null, |
|
161 _webProgressPP: null, |
|
162 _callback: null, |
|
163 _sourceBrowser: null, |
|
164 _originalTitle: "", |
|
165 _originalURL: "", |
|
166 |
|
167 // This observer is called once the progress dialog has been "opened" |
|
168 _obsPP: |
|
169 { |
|
170 observe: function(aSubject, aTopic, aData) |
|
171 { |
|
172 // delay the print preview to show the content of the progress dialog |
|
173 setTimeout(function () { PrintUtils.enterPrintPreview(); }, 0); |
|
174 }, |
|
175 |
|
176 QueryInterface : function(iid) |
|
177 { |
|
178 if (iid.equals(Components.interfaces.nsIObserver) || |
|
179 iid.equals(Components.interfaces.nsISupportsWeakReference) || |
|
180 iid.equals(Components.interfaces.nsISupports)) |
|
181 return this; |
|
182 throw Components.results.NS_NOINTERFACE; |
|
183 } |
|
184 }, |
|
185 |
|
186 enterPrintPreview: function () |
|
187 { |
|
188 gFocusedElement = document.commandDispatcher.focusedElement; |
|
189 |
|
190 var webBrowserPrint; |
|
191 var printSettings = this.getPrintSettings(); |
|
192 var originalWindow = this._sourceBrowser.contentWindow; |
|
193 |
|
194 try { |
|
195 webBrowserPrint = this.getPrintPreview(); |
|
196 webBrowserPrint.printPreview(printSettings, originalWindow, |
|
197 this._webProgressPP.value); |
|
198 } catch (e) { |
|
199 // Pressing cancel is expressed as an NS_ERROR_ABORT return value, |
|
200 // causing an exception to be thrown which we catch here. |
|
201 // Unfortunately this will also consume helpful failures, so add a |
|
202 // dump(e); // if you need to debug |
|
203 |
|
204 // Need to call enter and exit so that UI gets back to normal. |
|
205 this._callback.onEnter(); |
|
206 this._callback.onExit(); |
|
207 return; |
|
208 } |
|
209 |
|
210 var printPreviewTB = document.getElementById("print-preview-toolbar"); |
|
211 if (printPreviewTB) { |
|
212 printPreviewTB.updateToolbar(); |
|
213 var browser = this._callback.getPrintPreviewBrowser(); |
|
214 browser.collapsed = false; |
|
215 browser.contentWindow.focus(); |
|
216 return; |
|
217 } |
|
218 |
|
219 // Set the original window as an active window so any mozPrintCallbacks can |
|
220 // run without delayed setTimeouts. |
|
221 var docShell = originalWindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor) |
|
222 .getInterface(Components.interfaces.nsIWebNavigation) |
|
223 .QueryInterface(Components.interfaces.nsIDocShell); |
|
224 docShell.isActive = true; |
|
225 |
|
226 // show the toolbar after we go into print preview mode so |
|
227 // that we can initialize the toolbar with total num pages |
|
228 var XUL_NS = |
|
229 "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; |
|
230 printPreviewTB = document.createElementNS(XUL_NS, "toolbar"); |
|
231 printPreviewTB.setAttribute("printpreview", true); |
|
232 printPreviewTB.id = "print-preview-toolbar"; |
|
233 printPreviewTB.className = "toolbar-primary"; |
|
234 |
|
235 var navToolbox = this._callback.getNavToolbox(); |
|
236 navToolbox.parentNode.insertBefore(printPreviewTB, navToolbox); |
|
237 |
|
238 // copy the window close handler |
|
239 if (document.documentElement.hasAttribute("onclose")) |
|
240 this._closeHandlerPP = document.documentElement.getAttribute("onclose"); |
|
241 else |
|
242 this._closeHandlerPP = null; |
|
243 document.documentElement.setAttribute("onclose", "PrintUtils.exitPrintPreview(); return false;"); |
|
244 |
|
245 // disable chrome shortcuts... |
|
246 window.addEventListener("keydown", this.onKeyDownPP, true); |
|
247 window.addEventListener("keypress", this.onKeyPressPP, true); |
|
248 |
|
249 var browser = this._callback.getPrintPreviewBrowser(); |
|
250 browser.collapsed = false; |
|
251 browser.contentWindow.focus(); |
|
252 |
|
253 // on Enter PP Call back |
|
254 this._callback.onEnter(); |
|
255 }, |
|
256 |
|
257 exitPrintPreview: function () |
|
258 { |
|
259 window.removeEventListener("keydown", this.onKeyDownPP, true); |
|
260 window.removeEventListener("keypress", this.onKeyPressPP, true); |
|
261 |
|
262 // restore the old close handler |
|
263 document.documentElement.setAttribute("onclose", this._closeHandlerPP); |
|
264 this._closeHandlerPP = null; |
|
265 |
|
266 var webBrowserPrint = this.getPrintPreview(); |
|
267 webBrowserPrint.exitPrintPreview(); |
|
268 |
|
269 // remove the print preview toolbar |
|
270 var printPreviewTB = document.getElementById("print-preview-toolbar"); |
|
271 this._callback.getNavToolbox().parentNode.removeChild(printPreviewTB); |
|
272 |
|
273 var fm = Components.classes["@mozilla.org/focus-manager;1"] |
|
274 .getService(Components.interfaces.nsIFocusManager); |
|
275 if (gFocusedElement) |
|
276 fm.setFocus(gFocusedElement, fm.FLAG_NOSCROLL); |
|
277 else |
|
278 window.content.focus(); |
|
279 gFocusedElement = null; |
|
280 |
|
281 this._callback.onExit(); |
|
282 }, |
|
283 |
|
284 onKeyDownPP: function (aEvent) |
|
285 { |
|
286 // Esc exits the PP |
|
287 if (aEvent.keyCode == aEvent.DOM_VK_ESCAPE) { |
|
288 PrintUtils.exitPrintPreview(); |
|
289 } |
|
290 }, |
|
291 |
|
292 onKeyPressPP: function (aEvent) |
|
293 { |
|
294 var closeKey; |
|
295 try { |
|
296 closeKey = document.getElementById("key_close") |
|
297 .getAttribute("key"); |
|
298 closeKey = aEvent["DOM_VK_"+closeKey]; |
|
299 } catch (e) {} |
|
300 var isModif = aEvent.ctrlKey || aEvent.metaKey; |
|
301 // Ctrl-W exits the PP |
|
302 if (isModif && |
|
303 (aEvent.charCode == closeKey || aEvent.charCode == closeKey + 32)) { |
|
304 PrintUtils.exitPrintPreview(); |
|
305 } |
|
306 else if (isModif) { |
|
307 var printPreviewTB = document.getElementById("print-preview-toolbar"); |
|
308 var printKey = document.getElementById("printKb").getAttribute("key").toUpperCase(); |
|
309 var pressedKey = String.fromCharCode(aEvent.charCode).toUpperCase(); |
|
310 if (printKey == pressedKey) { |
|
311 PrintUtils.print(); |
|
312 } |
|
313 } |
|
314 // cancel shortkeys |
|
315 if (isModif) { |
|
316 aEvent.preventDefault(); |
|
317 aEvent.stopPropagation(); |
|
318 } |
|
319 } |
|
320 } |