Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
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 "RemotePrintJobParent.h"
8 :
9 : #include <fstream>
10 :
11 : #include "gfxContext.h"
12 : #include "mozilla/Attributes.h"
13 : #include "mozilla/Unused.h"
14 : #include "nsAppDirectoryServiceDefs.h"
15 : #include "nsComponentManagerUtils.h"
16 : #include "nsDirectoryServiceUtils.h"
17 : #include "nsDeviceContext.h"
18 : #include "nsIDeviceContextSpec.h"
19 : #include "nsIPrintSettings.h"
20 : #include "nsIWebProgressListener.h"
21 : #include "PrintTranslator.h"
22 :
23 : namespace mozilla {
24 : namespace layout {
25 :
26 0 : RemotePrintJobParent::RemotePrintJobParent(nsIPrintSettings* aPrintSettings)
27 0 : : mPrintSettings(aPrintSettings)
28 : {
29 0 : MOZ_COUNT_CTOR(RemotePrintJobParent);
30 0 : }
31 :
32 : mozilla::ipc::IPCResult
33 0 : RemotePrintJobParent::RecvInitializePrint(const nsString& aDocumentTitle,
34 : const nsString& aPrintToFile,
35 : const int32_t& aStartPage,
36 : const int32_t& aEndPage)
37 : {
38 0 : nsresult rv = InitializePrintDevice(aDocumentTitle, aPrintToFile, aStartPage,
39 0 : aEndPage);
40 0 : if (NS_FAILED(rv)) {
41 0 : Unused << SendPrintInitializationResult(rv);
42 0 : Unused << Send__delete__(this);
43 0 : return IPC_OK();
44 : }
45 :
46 0 : mPrintTranslator.reset(new PrintTranslator(mPrintDeviceContext));
47 0 : Unused << SendPrintInitializationResult(NS_OK);
48 :
49 0 : return IPC_OK();
50 : }
51 :
52 : nsresult
53 0 : RemotePrintJobParent::InitializePrintDevice(const nsString& aDocumentTitle,
54 : const nsString& aPrintToFile,
55 : const int32_t& aStartPage,
56 : const int32_t& aEndPage)
57 : {
58 : nsresult rv;
59 : nsCOMPtr<nsIDeviceContextSpec> deviceContextSpec =
60 0 : do_CreateInstance("@mozilla.org/gfx/devicecontextspec;1", &rv);
61 0 : if (NS_WARN_IF(NS_FAILED(rv))) {
62 0 : return rv;
63 : }
64 :
65 0 : rv = deviceContextSpec->Init(nullptr, mPrintSettings, false);
66 0 : if (NS_WARN_IF(NS_FAILED(rv))) {
67 0 : return rv;
68 : }
69 :
70 0 : mPrintDeviceContext = new nsDeviceContext();
71 0 : rv = mPrintDeviceContext->InitForPrinting(deviceContextSpec);
72 0 : if (NS_WARN_IF(NS_FAILED(rv))) {
73 0 : return rv;
74 : }
75 :
76 0 : rv = mPrintDeviceContext->BeginDocument(aDocumentTitle, aPrintToFile,
77 : aStartPage, aEndPage);
78 0 : if (NS_WARN_IF(NS_FAILED(rv))) {
79 0 : return rv;
80 : }
81 :
82 0 : return NS_OK;
83 : }
84 :
85 : mozilla::ipc::IPCResult
86 0 : RemotePrintJobParent::RecvProcessPage(const nsCString& aPageFileName)
87 : {
88 0 : nsresult rv = PrintPage(aPageFileName);
89 :
90 0 : if (NS_FAILED(rv)) {
91 0 : Unused << SendAbortPrint(rv);
92 : } else {
93 0 : Unused << SendPageProcessed();
94 : }
95 :
96 0 : return IPC_OK();
97 : }
98 :
99 : nsresult
100 0 : RemotePrintJobParent::PrintPage(const nsCString& aPageFileName)
101 : {
102 0 : MOZ_ASSERT(mPrintDeviceContext);
103 :
104 0 : nsresult rv = mPrintDeviceContext->BeginPage();
105 0 : if (NS_WARN_IF(NS_FAILED(rv))) {
106 0 : return rv;
107 : }
108 :
109 0 : nsCOMPtr<nsIFile> recordingFile;
110 0 : rv = NS_GetSpecialDirectory(NS_APP_CONTENT_PROCESS_TEMP_DIR,
111 0 : getter_AddRefs(recordingFile));
112 0 : if (NS_WARN_IF(NS_FAILED(rv))) {
113 0 : return rv;
114 : }
115 :
116 0 : rv = recordingFile->AppendNative(aPageFileName);
117 0 : if (NS_WARN_IF(NS_FAILED(rv))) {
118 0 : return rv;
119 : }
120 :
121 0 : nsAutoCString recordingPath;
122 0 : rv = recordingFile->GetNativePath(recordingPath);
123 0 : if (NS_WARN_IF(NS_FAILED(rv))) {
124 0 : return rv;
125 : }
126 :
127 0 : std::ifstream recording(recordingPath.get(), std::ifstream::binary);
128 0 : if (!mPrintTranslator->TranslateRecording(recording)) {
129 0 : return NS_ERROR_FAILURE;
130 : }
131 :
132 0 : rv = mPrintDeviceContext->EndPage();
133 0 : if (NS_WARN_IF(NS_FAILED(rv))) {
134 0 : return rv;
135 : }
136 :
137 0 : recording.close();
138 0 : rv = recordingFile->Remove(/* recursive= */ false);
139 0 : if (NS_WARN_IF(NS_FAILED(rv))) {
140 0 : return rv;
141 : }
142 :
143 0 : return NS_OK;
144 : }
145 :
146 : mozilla::ipc::IPCResult
147 0 : RemotePrintJobParent::RecvFinalizePrint()
148 : {
149 : // EndDocument is sometimes called in the child even when BeginDocument has
150 : // not been called. See bug 1223332.
151 0 : if (mPrintDeviceContext) {
152 0 : DebugOnly<nsresult> rv = mPrintDeviceContext->EndDocument();
153 :
154 : // Too late to abort the child just log.
155 0 : NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "EndDocument failed");
156 : }
157 :
158 :
159 0 : Unused << Send__delete__(this);
160 0 : return IPC_OK();
161 : }
162 :
163 : mozilla::ipc::IPCResult
164 0 : RemotePrintJobParent::RecvAbortPrint(const nsresult& aRv)
165 : {
166 0 : if (mPrintDeviceContext) {
167 0 : Unused << mPrintDeviceContext->AbortDocument();
168 : }
169 :
170 0 : Unused << Send__delete__(this);
171 0 : return IPC_OK();
172 : }
173 :
174 : mozilla::ipc::IPCResult
175 0 : RemotePrintJobParent::RecvStateChange(const long& aStateFlags,
176 : const nsresult& aStatus)
177 : {
178 0 : uint32_t numberOfListeners = mPrintProgressListeners.Length();
179 0 : for (uint32_t i = 0; i < numberOfListeners; ++i) {
180 0 : nsIWebProgressListener* listener = mPrintProgressListeners.SafeElementAt(i);
181 0 : listener->OnStateChange(nullptr, nullptr, aStateFlags, aStatus);
182 : }
183 :
184 0 : return IPC_OK();
185 : }
186 :
187 : mozilla::ipc::IPCResult
188 0 : RemotePrintJobParent::RecvProgressChange(const long& aCurSelfProgress,
189 : const long& aMaxSelfProgress,
190 : const long& aCurTotalProgress,
191 : const long& aMaxTotalProgress)
192 : {
193 0 : uint32_t numberOfListeners = mPrintProgressListeners.Length();
194 0 : for (uint32_t i = 0; i < numberOfListeners; ++i) {
195 0 : nsIWebProgressListener* listener = mPrintProgressListeners.SafeElementAt(i);
196 0 : listener->OnProgressChange(nullptr, nullptr,
197 0 : aCurSelfProgress, aMaxSelfProgress,
198 0 : aCurTotalProgress, aMaxTotalProgress);
199 : }
200 :
201 0 : return IPC_OK();
202 : }
203 :
204 : mozilla::ipc::IPCResult
205 0 : RemotePrintJobParent::RecvStatusChange(const nsresult& aStatus)
206 : {
207 0 : uint32_t numberOfListeners = mPrintProgressListeners.Length();
208 0 : for (uint32_t i = 0; i < numberOfListeners; ++i) {
209 0 : nsIWebProgressListener* listener = mPrintProgressListeners.SafeElementAt(i);
210 0 : listener->OnStatusChange(nullptr, nullptr, aStatus, nullptr);
211 : }
212 :
213 0 : return IPC_OK();
214 : }
215 :
216 : void
217 0 : RemotePrintJobParent::RegisterListener(nsIWebProgressListener* aListener)
218 : {
219 0 : MOZ_ASSERT(aListener);
220 :
221 0 : mPrintProgressListeners.AppendElement(aListener);
222 0 : }
223 :
224 : already_AddRefed<nsIPrintSettings>
225 0 : RemotePrintJobParent::GetPrintSettings()
226 : {
227 0 : nsCOMPtr<nsIPrintSettings> printSettings = mPrintSettings;
228 0 : return printSettings.forget();
229 : }
230 :
231 0 : RemotePrintJobParent::~RemotePrintJobParent()
232 : {
233 0 : MOZ_COUNT_DTOR(RemotePrintJobParent);
234 0 : }
235 :
236 : void
237 0 : RemotePrintJobParent::ActorDestroy(ActorDestroyReason aWhy)
238 : {
239 0 : }
240 :
241 : } // namespace layout
242 : } // namespace mozilla
243 :
244 :
|