|
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- |
|
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 #include "nsCOMPtr.h" |
|
8 |
|
9 #include "nsPrintingPromptService.h" |
|
10 #include "nsIPrintingPromptService.h" |
|
11 #include "nsIFactory.h" |
|
12 #include "nsPIDOMWindow.h" |
|
13 #include "nsReadableUtils.h" |
|
14 #include "nsIEmbeddingSiteWindow.h" |
|
15 #include "nsIServiceManager.h" |
|
16 #include "nsIWebBrowserChrome.h" |
|
17 #include "nsIWindowWatcher.h" |
|
18 #include "nsPrintDialogUtil.h" |
|
19 |
|
20 // Printing Progress Includes |
|
21 #include "nsPrintProgress.h" |
|
22 #include "nsPrintProgressParams.h" |
|
23 #include "nsIWebProgressListener.h" |
|
24 |
|
25 // XP Dialog includes |
|
26 #include "nsIDialogParamBlock.h" |
|
27 #include "nsISupportsUtils.h" |
|
28 #include "nsISupportsArray.h" |
|
29 |
|
30 // Includes need to locate the native Window |
|
31 #include "nsIWidget.h" |
|
32 #include "nsIBaseWindow.h" |
|
33 #include "nsIWebBrowserChrome.h" |
|
34 #include "nsIDocShellTreeOwner.h" |
|
35 #include "nsIDocShellTreeItem.h" |
|
36 #include "nsIDocShell.h" |
|
37 #include "nsIInterfaceRequestorUtils.h" |
|
38 |
|
39 |
|
40 static const char *kPrintProgressDialogURL = "chrome://global/content/printProgress.xul"; |
|
41 static const char *kPrtPrvProgressDialogURL = "chrome://global/content/printPreviewProgress.xul"; |
|
42 static const char *kPageSetupDialogURL = "chrome://global/content/printPageSetup.xul"; |
|
43 |
|
44 /**************************************************************** |
|
45 ************************* ParamBlock *************************** |
|
46 ****************************************************************/ |
|
47 |
|
48 class ParamBlock { |
|
49 |
|
50 public: |
|
51 ParamBlock() |
|
52 { |
|
53 mBlock = 0; |
|
54 } |
|
55 ~ParamBlock() |
|
56 { |
|
57 NS_IF_RELEASE(mBlock); |
|
58 } |
|
59 nsresult Init() { |
|
60 return CallCreateInstance(NS_DIALOGPARAMBLOCK_CONTRACTID, &mBlock); |
|
61 } |
|
62 nsIDialogParamBlock * operator->() const { return mBlock; } |
|
63 operator nsIDialogParamBlock * const () { return mBlock; } |
|
64 |
|
65 private: |
|
66 nsIDialogParamBlock *mBlock; |
|
67 }; |
|
68 |
|
69 //***************************************************************************** |
|
70 |
|
71 NS_IMPL_ISUPPORTS(nsPrintingPromptService, nsIPrintingPromptService, nsIWebProgressListener) |
|
72 |
|
73 nsPrintingPromptService::nsPrintingPromptService() |
|
74 { |
|
75 } |
|
76 |
|
77 //----------------------------------------------------------- |
|
78 nsPrintingPromptService::~nsPrintingPromptService() |
|
79 { |
|
80 } |
|
81 |
|
82 //----------------------------------------------------------- |
|
83 nsresult |
|
84 nsPrintingPromptService::Init() |
|
85 { |
|
86 nsresult rv; |
|
87 mWatcher = do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv); |
|
88 return rv; |
|
89 } |
|
90 |
|
91 //----------------------------------------------------------- |
|
92 HWND |
|
93 nsPrintingPromptService::GetHWNDForDOMWindow(nsIDOMWindow *aWindow) |
|
94 { |
|
95 nsCOMPtr<nsIWebBrowserChrome> chrome; |
|
96 |
|
97 // We might be embedded so check this path first |
|
98 if (mWatcher) { |
|
99 nsCOMPtr<nsIDOMWindow> fosterParent; |
|
100 if (!aWindow) |
|
101 { // it will be a dependent window. try to find a foster parent. |
|
102 mWatcher->GetActiveWindow(getter_AddRefs(fosterParent)); |
|
103 aWindow = fosterParent; |
|
104 } |
|
105 mWatcher->GetChromeForWindow(aWindow, getter_AddRefs(chrome)); |
|
106 } |
|
107 |
|
108 if (chrome) { |
|
109 nsCOMPtr<nsIEmbeddingSiteWindow> site(do_QueryInterface(chrome)); |
|
110 if (site) |
|
111 { |
|
112 HWND w; |
|
113 site->GetSiteWindow(reinterpret_cast<void **>(&w)); |
|
114 return w; |
|
115 } |
|
116 } |
|
117 |
|
118 // Now we might be the Browser so check this path |
|
119 nsCOMPtr<nsPIDOMWindow> window(do_QueryInterface(aWindow)); |
|
120 |
|
121 nsCOMPtr<nsIDocShellTreeItem> treeItem = |
|
122 do_QueryInterface(window->GetDocShell()); |
|
123 if (!treeItem) return nullptr; |
|
124 |
|
125 nsCOMPtr<nsIDocShellTreeOwner> treeOwner; |
|
126 treeItem->GetTreeOwner(getter_AddRefs(treeOwner)); |
|
127 if (!treeOwner) return nullptr; |
|
128 |
|
129 nsCOMPtr<nsIWebBrowserChrome> webBrowserChrome(do_GetInterface(treeOwner)); |
|
130 if (!webBrowserChrome) return nullptr; |
|
131 |
|
132 nsCOMPtr<nsIBaseWindow> baseWin(do_QueryInterface(webBrowserChrome)); |
|
133 if (!baseWin) return nullptr; |
|
134 |
|
135 nsCOMPtr<nsIWidget> widget; |
|
136 baseWin->GetMainWidget(getter_AddRefs(widget)); |
|
137 if (!widget) return nullptr; |
|
138 |
|
139 return (HWND)widget->GetNativeData(NS_NATIVE_TMP_WINDOW); |
|
140 |
|
141 } |
|
142 |
|
143 |
|
144 /////////////////////////////////////////////////////////////////////////////// |
|
145 // nsIPrintingPrompt |
|
146 |
|
147 //----------------------------------------------------------- |
|
148 NS_IMETHODIMP |
|
149 nsPrintingPromptService::ShowPrintDialog(nsIDOMWindow *parent, nsIWebBrowserPrint *webBrowserPrint, nsIPrintSettings *printSettings) |
|
150 { |
|
151 NS_ENSURE_ARG(parent); |
|
152 |
|
153 HWND hWnd = GetHWNDForDOMWindow(parent); |
|
154 NS_ASSERTION(hWnd, "Couldn't get native window for PRint Dialog!"); |
|
155 |
|
156 return NativeShowPrintDialog(hWnd, webBrowserPrint, printSettings); |
|
157 } |
|
158 |
|
159 |
|
160 /* void showProgress (in nsIDOMWindow parent, in nsIWebBrowserPrint webBrowserPrint, in nsIPrintSettings printSettings, in nsIObserver openDialogObserver, in boolean isForPrinting, out nsIWebProgressListener webProgressListener, out nsIPrintProgressParams printProgressParams, out boolean notifyOnOpen); */ |
|
161 NS_IMETHODIMP |
|
162 nsPrintingPromptService::ShowProgress(nsIDOMWindow* parent, |
|
163 nsIWebBrowserPrint* webBrowserPrint, // ok to be null |
|
164 nsIPrintSettings* printSettings, // ok to be null |
|
165 nsIObserver* openDialogObserver, // ok to be null |
|
166 bool isForPrinting, |
|
167 nsIWebProgressListener** webProgressListener, |
|
168 nsIPrintProgressParams** printProgressParams, |
|
169 bool* notifyOnOpen) |
|
170 { |
|
171 NS_ENSURE_ARG(webProgressListener); |
|
172 NS_ENSURE_ARG(printProgressParams); |
|
173 NS_ENSURE_ARG(notifyOnOpen); |
|
174 |
|
175 *notifyOnOpen = false; |
|
176 if (mPrintProgress) { |
|
177 *webProgressListener = nullptr; |
|
178 *printProgressParams = nullptr; |
|
179 return NS_ERROR_FAILURE; |
|
180 } |
|
181 |
|
182 nsPrintProgress* prtProgress = new nsPrintProgress(); |
|
183 mPrintProgress = prtProgress; |
|
184 mWebProgressListener = prtProgress; |
|
185 |
|
186 nsCOMPtr<nsIPrintProgressParams> prtProgressParams = new nsPrintProgressParams(); |
|
187 |
|
188 nsCOMPtr<nsIDOMWindow> parentWindow = parent; |
|
189 |
|
190 if (mWatcher && !parentWindow) { |
|
191 mWatcher->GetActiveWindow(getter_AddRefs(parentWindow)); |
|
192 } |
|
193 |
|
194 if (parentWindow) { |
|
195 mPrintProgress->OpenProgressDialog(parentWindow, |
|
196 isForPrinting ? kPrintProgressDialogURL : kPrtPrvProgressDialogURL, |
|
197 prtProgressParams, openDialogObserver, notifyOnOpen); |
|
198 } |
|
199 |
|
200 prtProgressParams.forget(printProgressParams); |
|
201 NS_ADDREF(*webProgressListener = this); |
|
202 |
|
203 return NS_OK; |
|
204 } |
|
205 |
|
206 /* void showPageSetup (in nsIDOMWindow parent, in nsIPrintSettings printSettings); */ |
|
207 NS_IMETHODIMP |
|
208 nsPrintingPromptService::ShowPageSetup(nsIDOMWindow *parent, nsIPrintSettings *printSettings, nsIObserver *aObs) |
|
209 { |
|
210 NS_ENSURE_ARG(printSettings); |
|
211 |
|
212 ParamBlock block; |
|
213 nsresult rv = block.Init(); |
|
214 if (NS_FAILED(rv)) |
|
215 return rv; |
|
216 |
|
217 block->SetInt(0, 0); |
|
218 rv = DoDialog(parent, block, printSettings, kPageSetupDialogURL); |
|
219 |
|
220 // if aWebBrowserPrint is not null then we are printing |
|
221 // so we want to pass back NS_ERROR_ABORT on cancel |
|
222 if (NS_SUCCEEDED(rv)) |
|
223 { |
|
224 int32_t status; |
|
225 block->GetInt(0, &status); |
|
226 return status == 0?NS_ERROR_ABORT:NS_OK; |
|
227 } |
|
228 |
|
229 return rv; |
|
230 } |
|
231 |
|
232 /* void showPrinterProperties (in nsIDOMWindow parent, in wstring printerName, in nsIPrintSettings printSettings); */ |
|
233 NS_IMETHODIMP |
|
234 nsPrintingPromptService::ShowPrinterProperties(nsIDOMWindow *parent, const char16_t *printerName, nsIPrintSettings *printSettings) |
|
235 { |
|
236 return NS_ERROR_NOT_IMPLEMENTED; |
|
237 } |
|
238 |
|
239 //----------------------------------------------------------- |
|
240 // Helper to Fly XP Dialog |
|
241 nsresult |
|
242 nsPrintingPromptService::DoDialog(nsIDOMWindow *aParent, |
|
243 nsIDialogParamBlock *aParamBlock, |
|
244 nsIPrintSettings* aPS, |
|
245 const char *aChromeURL) |
|
246 { |
|
247 NS_ENSURE_ARG(aParamBlock); |
|
248 NS_ENSURE_ARG(aPS); |
|
249 NS_ENSURE_ARG(aChromeURL); |
|
250 |
|
251 if (!mWatcher) |
|
252 return NS_ERROR_FAILURE; |
|
253 |
|
254 nsresult rv = NS_OK; |
|
255 |
|
256 // get a parent, if at all possible |
|
257 // (though we'd rather this didn't fail, it's OK if it does. so there's |
|
258 // no failure or null check.) |
|
259 nsCOMPtr<nsIDOMWindow> activeParent; // retain ownership for method lifetime |
|
260 if (!aParent) |
|
261 { |
|
262 mWatcher->GetActiveWindow(getter_AddRefs(activeParent)); |
|
263 aParent = activeParent; |
|
264 } |
|
265 |
|
266 // create a nsISupportsArray of the parameters |
|
267 // being passed to the window |
|
268 nsCOMPtr<nsISupportsArray> array; |
|
269 NS_NewISupportsArray(getter_AddRefs(array)); |
|
270 if (!array) return NS_ERROR_FAILURE; |
|
271 |
|
272 nsCOMPtr<nsISupports> psSupports(do_QueryInterface(aPS)); |
|
273 NS_ASSERTION(psSupports, "PrintSettings must be a supports"); |
|
274 array->AppendElement(psSupports); |
|
275 |
|
276 nsCOMPtr<nsISupports> blkSupps(do_QueryInterface(aParamBlock)); |
|
277 NS_ASSERTION(blkSupps, "IOBlk must be a supports"); |
|
278 array->AppendElement(blkSupps); |
|
279 |
|
280 nsCOMPtr<nsISupports> arguments(do_QueryInterface(array)); |
|
281 NS_ASSERTION(array, "array must be a supports"); |
|
282 |
|
283 |
|
284 nsCOMPtr<nsIDOMWindow> dialog; |
|
285 rv = mWatcher->OpenWindow(aParent, aChromeURL, "_blank", |
|
286 "centerscreen,chrome,modal,titlebar", arguments, |
|
287 getter_AddRefs(dialog)); |
|
288 |
|
289 return rv; |
|
290 } |
|
291 |
|
292 ////////////////////////////////////////////////////////////////////// |
|
293 // nsIWebProgressListener |
|
294 ////////////////////////////////////////////////////////////////////// |
|
295 |
|
296 /* void onStateChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aStateFlags, in nsresult aStatus); */ |
|
297 NS_IMETHODIMP |
|
298 nsPrintingPromptService::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, uint32_t aStateFlags, nsresult aStatus) |
|
299 { |
|
300 if ((aStateFlags & STATE_STOP) && mWebProgressListener) |
|
301 { |
|
302 mWebProgressListener->OnStateChange(aWebProgress, aRequest, aStateFlags, aStatus); |
|
303 if (mPrintProgress) |
|
304 { |
|
305 mPrintProgress->CloseProgressDialog(true); |
|
306 } |
|
307 mPrintProgress = nullptr; |
|
308 mWebProgressListener = nullptr; |
|
309 } |
|
310 return NS_OK; |
|
311 } |
|
312 |
|
313 /* void onProgressChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aCurSelfProgress, in long aMaxSelfProgress, in long aCurTotalProgress, in long aMaxTotalProgress); */ |
|
314 NS_IMETHODIMP |
|
315 nsPrintingPromptService::OnProgressChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, int32_t aCurSelfProgress, int32_t aMaxSelfProgress, int32_t aCurTotalProgress, int32_t aMaxTotalProgress) |
|
316 { |
|
317 if (mWebProgressListener) |
|
318 { |
|
319 return mWebProgressListener->OnProgressChange(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress); |
|
320 } |
|
321 return NS_ERROR_FAILURE; |
|
322 } |
|
323 |
|
324 /* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location, in unsigned long aFlags); */ |
|
325 NS_IMETHODIMP |
|
326 nsPrintingPromptService::OnLocationChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsIURI *location, uint32_t aFlags) |
|
327 { |
|
328 if (mWebProgressListener) |
|
329 { |
|
330 return mWebProgressListener->OnLocationChange(aWebProgress, aRequest, location, aFlags); |
|
331 } |
|
332 return NS_ERROR_FAILURE; |
|
333 } |
|
334 |
|
335 /* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */ |
|
336 NS_IMETHODIMP |
|
337 nsPrintingPromptService::OnStatusChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsresult aStatus, const char16_t *aMessage) |
|
338 { |
|
339 if (mWebProgressListener) |
|
340 { |
|
341 return mWebProgressListener->OnStatusChange(aWebProgress, aRequest, aStatus, aMessage); |
|
342 } |
|
343 return NS_ERROR_FAILURE; |
|
344 } |
|
345 |
|
346 /* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long state); */ |
|
347 NS_IMETHODIMP |
|
348 nsPrintingPromptService::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, uint32_t state) |
|
349 { |
|
350 if (mWebProgressListener) |
|
351 { |
|
352 return mWebProgressListener->OnSecurityChange(aWebProgress, aRequest, state); |
|
353 } |
|
354 return NS_ERROR_FAILURE; |
|
355 } |
|
356 |
|
357 |