1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6 #include "nsPrintDialogWin.h"
7
8 #include "nsArray.h"
9 #include "nsCOMPtr.h"
10 #include "nsIBaseWindow.h"
11 #include "nsIDialogParamBlock.h"
12 #include "nsIDocShellTreeOwner.h"
13 #include "nsIDocShellTreeItem.h"
14 #include "nsIDocShell.h"
15 #include "nsIEmbeddingSiteWindow.h"
16 #include "nsIInterfaceRequestorUtils.h"
17 #include "nsIPrintSettings.h"
18 #include "nsIWebBrowserChrome.h"
19 #include "nsIWidget.h"
20 #include "nsPrintDialogUtil.h"
21 #include "nsIPrintSettings.h"
22 #include "nsIWebBrowserChrome.h"
23 #include "nsQueryObject.h"
24
25 static const char* kPageSetupDialogURL =
26 "chrome://global/content/printPageSetup.xul";
27
28 using namespace mozilla;
29 using namespace mozilla::widget;
30
31 /**
32 * ParamBlock
33 */
34
35 class ParamBlock {
36 public:
ParamBlock()37 ParamBlock() { mBlock = 0; }
~ParamBlock()38 ~ParamBlock() { NS_IF_RELEASE(mBlock); }
Init()39 nsresult Init() {
40 return CallCreateInstance(NS_DIALOGPARAMBLOCK_CONTRACTID, &mBlock);
41 }
operator ->() const42 nsIDialogParamBlock* operator->() const MOZ_NO_ADDREF_RELEASE_ON_RETURN {
43 return mBlock;
44 }
operator nsIDialogParamBlock*const()45 operator nsIDialogParamBlock* const() { return mBlock; }
46
47 private:
48 nsIDialogParamBlock* mBlock;
49 };
50
NS_IMPL_ISUPPORTS(nsPrintDialogServiceWin,nsIPrintDialogService)51 NS_IMPL_ISUPPORTS(nsPrintDialogServiceWin, nsIPrintDialogService)
52
53 nsPrintDialogServiceWin::nsPrintDialogServiceWin() {}
54
~nsPrintDialogServiceWin()55 nsPrintDialogServiceWin::~nsPrintDialogServiceWin() {}
56
57 NS_IMETHODIMP
Init()58 nsPrintDialogServiceWin::Init() {
59 nsresult rv;
60 mWatcher = do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv);
61 return rv;
62 }
63
64 NS_IMETHODIMP
Show(nsPIDOMWindowOuter * aParent,nsIPrintSettings * aSettings,nsIWebBrowserPrint * aWebBrowserPrint)65 nsPrintDialogServiceWin::Show(nsPIDOMWindowOuter* aParent,
66 nsIPrintSettings* aSettings,
67 nsIWebBrowserPrint* aWebBrowserPrint) {
68 NS_ENSURE_ARG(aParent);
69 HWND hWnd = GetHWNDForDOMWindow(aParent);
70 NS_ASSERTION(hWnd, "Couldn't get native window for PRint Dialog!");
71
72 return NativeShowPrintDialog(hWnd, aWebBrowserPrint, aSettings);
73 }
74
75 NS_IMETHODIMP
ShowPageSetup(nsPIDOMWindowOuter * aParent,nsIPrintSettings * aNSSettings)76 nsPrintDialogServiceWin::ShowPageSetup(nsPIDOMWindowOuter* aParent,
77 nsIPrintSettings* aNSSettings) {
78 NS_ENSURE_ARG(aParent);
79 NS_ENSURE_ARG(aNSSettings);
80
81 ParamBlock block;
82 nsresult rv = block.Init();
83 if (NS_FAILED(rv)) return rv;
84
85 block->SetInt(0, 0);
86 rv = DoDialog(aParent, block, aNSSettings, kPageSetupDialogURL);
87
88 // if aWebBrowserPrint is not null then we are printing
89 // so we want to pass back NS_ERROR_ABORT on cancel
90 if (NS_SUCCEEDED(rv)) {
91 int32_t status;
92 block->GetInt(0, &status);
93 return status == 0 ? NS_ERROR_ABORT : NS_OK;
94 }
95
96 return rv;
97 }
98
DoDialog(mozIDOMWindowProxy * aParent,nsIDialogParamBlock * aParamBlock,nsIPrintSettings * aPS,const char * aChromeURL)99 nsresult nsPrintDialogServiceWin::DoDialog(mozIDOMWindowProxy* aParent,
100 nsIDialogParamBlock* aParamBlock,
101 nsIPrintSettings* aPS,
102 const char* aChromeURL) {
103 NS_ENSURE_ARG(aParamBlock);
104 NS_ENSURE_ARG(aPS);
105 NS_ENSURE_ARG(aChromeURL);
106
107 if (!mWatcher) return NS_ERROR_FAILURE;
108
109 // get a parent, if at all possible
110 // (though we'd rather this didn't fail, it's OK if it does. so there's
111 // no failure or null check.)
112 // retain ownership for method lifetime
113 nsCOMPtr<mozIDOMWindowProxy> activeParent;
114 if (!aParent) {
115 mWatcher->GetActiveWindow(getter_AddRefs(activeParent));
116 aParent = activeParent;
117 }
118
119 // create a nsIMutableArray of the parameters
120 // being passed to the window
121 nsCOMPtr<nsIMutableArray> array = nsArray::Create();
122
123 nsCOMPtr<nsISupports> psSupports(do_QueryInterface(aPS));
124 NS_ASSERTION(psSupports, "PrintSettings must be a supports");
125 array->AppendElement(psSupports);
126
127 nsCOMPtr<nsISupports> blkSupps(do_QueryInterface(aParamBlock));
128 NS_ASSERTION(blkSupps, "IOBlk must be a supports");
129 array->AppendElement(blkSupps);
130
131 nsCOMPtr<mozIDOMWindowProxy> dialog;
132 nsresult rv = mWatcher->OpenWindow(aParent, aChromeURL, "_blank",
133 "centerscreen,chrome,modal,titlebar",
134 array, getter_AddRefs(dialog));
135
136 return rv;
137 }
138
GetHWNDForDOMWindow(mozIDOMWindowProxy * aWindow)139 HWND nsPrintDialogServiceWin::GetHWNDForDOMWindow(mozIDOMWindowProxy* aWindow) {
140 nsCOMPtr<nsIWebBrowserChrome> chrome;
141
142 // We might be embedded so check this path first
143 if (mWatcher) {
144 nsCOMPtr<mozIDOMWindowProxy> fosterParent;
145 // it will be a dependent window. try to find a foster parent.
146 if (!aWindow) {
147 mWatcher->GetActiveWindow(getter_AddRefs(fosterParent));
148 aWindow = fosterParent;
149 }
150 mWatcher->GetChromeForWindow(aWindow, getter_AddRefs(chrome));
151 }
152
153 if (chrome) {
154 nsCOMPtr<nsIEmbeddingSiteWindow> site(do_QueryInterface(chrome));
155 if (site) {
156 HWND w;
157 site->GetSiteWindow(reinterpret_cast<void**>(&w));
158 return w;
159 }
160 }
161
162 // Now we might be the Browser so check this path
163 nsCOMPtr<nsPIDOMWindowOuter> window = nsPIDOMWindowOuter::From(aWindow);
164
165 nsCOMPtr<nsIDocShellTreeItem> treeItem =
166 do_QueryInterface(window->GetDocShell());
167 if (!treeItem) return nullptr;
168
169 nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
170 treeItem->GetTreeOwner(getter_AddRefs(treeOwner));
171 if (!treeOwner) return nullptr;
172
173 nsCOMPtr<nsIWebBrowserChrome> webBrowserChrome(do_GetInterface(treeOwner));
174 if (!webBrowserChrome) return nullptr;
175
176 nsCOMPtr<nsIBaseWindow> baseWin(do_QueryInterface(webBrowserChrome));
177 if (!baseWin) return nullptr;
178
179 nsCOMPtr<nsIWidget> widget;
180 baseWin->GetMainWidget(getter_AddRefs(widget));
181 if (!widget) return nullptr;
182
183 return (HWND)widget->GetNativeData(NS_NATIVE_TMP_WINDOW);
184 }
185