widget/qt/nsDeviceContextSpecQt.cpp

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:44cd71fe2160
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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
7 #include <QTemporaryFile>
8 #include <QPrinterInfo>
9
10 #define SET_PRINTER_FEATURES_VIA_PREFS 1
11 #define PRINTERFEATURES_PREF "print.tmp.printerfeatures"
12
13 #ifdef MOZ_LOGGING
14 #define FORCE_PR_LOG 1 /* Allow logging in the release build */
15 #endif /* MOZ_LOGGING */
16 #include "prlog.h"
17
18 #include "plstr.h"
19
20 #include "nsDeviceContextSpecQt.h"
21
22 #include "prenv.h" /* for PR_GetEnv */
23
24 #include "nsReadableUtils.h"
25 #include "nsStringEnumerator.h"
26 #include "nsIServiceManager.h"
27 #include "nsPrintSettingsQt.h"
28 #include "nsIFileStreams.h"
29 #include "nsIFile.h"
30 #include "nsTArray.h"
31
32 #include <unistd.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35
36 #include "gfxPDFSurface.h"
37
38 #ifdef PR_LOGGING
39 static PRLogModuleInfo* DeviceContextSpecQtLM =
40 PR_NewLogModule("DeviceContextSpecQt");
41 #endif /* PR_LOGGING */
42 /* Macro to make lines shorter */
43 #define DO_PR_DEBUG_LOG(x) PR_LOG(DeviceContextSpecQtLM, PR_LOG_DEBUG, x)
44
45 nsDeviceContextSpecQt::nsDeviceContextSpecQt()
46 {
47 DO_PR_DEBUG_LOG(("nsDeviceContextSpecQt::nsDeviceContextSpecQt()\n"));
48 }
49
50 nsDeviceContextSpecQt::~nsDeviceContextSpecQt()
51 {
52 DO_PR_DEBUG_LOG(("nsDeviceContextSpecQt::~nsDeviceContextSpecQt()\n"));
53 }
54
55 NS_IMPL_ISUPPORTS(nsDeviceContextSpecQt,
56 nsIDeviceContextSpec)
57
58 NS_IMETHODIMP nsDeviceContextSpecQt::GetSurfaceForPrinter(
59 gfxASurface** aSurface)
60 {
61 NS_ENSURE_ARG_POINTER(aSurface);
62 *aSurface = nullptr;
63
64 double width, height;
65 mPrintSettings->GetEffectivePageSize(&width, &height);
66
67 // If we're in landscape mode, we'll be rotating the output --
68 // need to swap width & height.
69 int32_t orientation;
70 mPrintSettings->GetOrientation(&orientation);
71 if (nsIPrintSettings::kLandscapeOrientation == orientation) {
72 double tmp = width;
73 width = height;
74 height = tmp;
75 }
76
77 // convert twips to points
78 width /= TWIPS_PER_POINT_FLOAT;
79 height /= TWIPS_PER_POINT_FLOAT;
80
81 DO_PR_DEBUG_LOG(("\"%s\", %f, %f\n", mPath, width, height));
82
83 QTemporaryFile file;
84 if(!file.open()) {
85 return NS_ERROR_GFX_PRINTER_COULD_NOT_OPEN_FILE;
86 }
87 file.setAutoRemove(false);
88
89 nsresult rv = NS_NewNativeLocalFile(
90 nsDependentCString(file.fileName().toUtf8().constData()),
91 false,
92 getter_AddRefs(mSpoolFile));
93 if (NS_FAILED(rv)) {
94 file.remove();
95 return NS_ERROR_GFX_PRINTER_COULD_NOT_OPEN_FILE;
96 }
97
98 mSpoolName = file.fileName().toUtf8().constData();
99
100 mSpoolFile->SetPermissions(0600);
101
102 nsCOMPtr<nsIFileOutputStream> stream =
103 do_CreateInstance("@mozilla.org/network/file-output-stream;1");
104
105 rv = stream->Init(mSpoolFile, -1, -1, 0);
106 if (NS_FAILED(rv))
107 return rv;
108
109 int16_t format;
110 mPrintSettings->GetOutputFormat(&format);
111
112 nsRefPtr<gfxASurface> surface;
113 gfxSize surfaceSize(width, height);
114
115 if (format == nsIPrintSettings::kOutputFormatNative) {
116 if (mIsPPreview) {
117 // There is nothing to detect on Print Preview, use PS.
118 // TODO: implement for Qt?
119 //format = nsIPrintSettings::kOutputFormatPS;
120 return NS_ERROR_NOT_IMPLEMENTED;
121 }
122 format = nsIPrintSettings::kOutputFormatPDF;
123 }
124 if (format == nsIPrintSettings::kOutputFormatPDF) {
125 surface = new gfxPDFSurface(stream, surfaceSize);
126 } else {
127 return NS_ERROR_NOT_IMPLEMENTED;
128 }
129
130 NS_ABORT_IF_FALSE(surface, "valid address expected");
131
132 surface.swap(*aSurface);
133 return NS_OK;
134 }
135
136 NS_IMETHODIMP nsDeviceContextSpecQt::Init(nsIWidget* aWidget,
137 nsIPrintSettings* aPS,
138 bool aIsPrintPreview)
139 {
140 DO_PR_DEBUG_LOG(("nsDeviceContextSpecQt::Init(aPS=%p)\n", aPS));
141
142 mPrintSettings = aPS;
143 mIsPPreview = aIsPrintPreview;
144
145 // This is only set by embedders
146 bool toFile;
147 aPS->GetPrintToFile(&toFile);
148
149 mToPrinter = !toFile && !aIsPrintPreview;
150
151 nsCOMPtr<nsPrintSettingsQt> printSettingsQt(do_QueryInterface(aPS));
152 if (!printSettingsQt)
153 return NS_ERROR_NO_INTERFACE;
154 return NS_OK;
155 }
156
157 NS_IMETHODIMP nsDeviceContextSpecQt::GetPath(const char** aPath)
158 {
159 *aPath = mPath;
160 return NS_OK;
161 }
162
163 NS_IMETHODIMP nsDeviceContextSpecQt::BeginDocument(
164 const nsAString& aTitle,
165 char16_t* aPrintToFileName,
166 int32_t aStartPage,
167 int32_t aEndPage)
168 {
169 if (mToPrinter) {
170 return NS_ERROR_NOT_IMPLEMENTED;
171 }
172 return NS_OK;
173 }
174
175 NS_IMETHODIMP nsDeviceContextSpecQt::EndDocument()
176 {
177 if (mToPrinter) {
178 return NS_ERROR_NOT_IMPLEMENTED;
179 }
180 // Handle print-to-file ourselves for the benefit of embedders
181 nsXPIDLString targetPath;
182 nsCOMPtr<nsIFile> destFile;
183 mPrintSettings->GetToFileName(getter_Copies(targetPath));
184
185 nsresult rv = NS_NewNativeLocalFile(NS_ConvertUTF16toUTF8(targetPath),
186 false, getter_AddRefs(destFile));
187 NS_ENSURE_SUCCESS(rv, rv);
188
189 nsAutoString destLeafName;
190 rv = destFile->GetLeafName(destLeafName);
191 NS_ENSURE_SUCCESS(rv, rv);
192
193 nsCOMPtr<nsIFile> destDir;
194 rv = destFile->GetParent(getter_AddRefs(destDir));
195 NS_ENSURE_SUCCESS(rv, rv);
196
197 rv = mSpoolFile->MoveTo(destDir, destLeafName);
198 NS_ENSURE_SUCCESS(rv, rv);
199
200 // This is the standard way to get the UNIX umask. Ugh.
201 mode_t mask = umask(0);
202 umask(mask);
203 // If you're not familiar with umasks, they contain the bits of what NOT
204 // to set in the permissions
205 // (thats because files and directories have different numbers of bits
206 // for their permissions)
207 destFile->SetPermissions(0666 & ~(mask));
208
209 return NS_OK;
210 }
211
212 // Printer Enumerator
213 nsPrinterEnumeratorQt::nsPrinterEnumeratorQt()
214 {
215 }
216
217 NS_IMPL_ISUPPORTS(nsPrinterEnumeratorQt, nsIPrinterEnumerator)
218
219 NS_IMETHODIMP nsPrinterEnumeratorQt::GetPrinterNameList(
220 nsIStringEnumerator** aPrinterNameList)
221 {
222 NS_ENSURE_ARG_POINTER(aPrinterNameList);
223 *aPrinterNameList = nullptr;
224
225 QList<QPrinterInfo> qprinters = QPrinterInfo::availablePrinters();
226 if (qprinters.size() == 0)
227 return NS_ERROR_NOT_AVAILABLE;
228
229 nsTArray<nsString>* printers =
230 new nsTArray<nsString>(qprinters.size());
231
232 for (int32_t i = 0; i < qprinters.size(); ++i) {
233 printers->AppendElement(
234 nsDependentString(
235 (const char16_t*)qprinters[i].printerName().constData()));
236 }
237
238 return NS_NewAdoptingStringEnumerator(aPrinterNameList, printers);
239 }
240
241 NS_IMETHODIMP nsPrinterEnumeratorQt::GetDefaultPrinterName(
242 char16_t** aDefaultPrinterName)
243 {
244 DO_PR_DEBUG_LOG(("nsPrinterEnumeratorQt::GetDefaultPrinterName()\n"));
245 NS_ENSURE_ARG_POINTER(aDefaultPrinterName);
246
247 QString defprinter = QPrinterInfo::defaultPrinter().printerName();
248 *aDefaultPrinterName = ToNewUnicode(nsDependentString(
249 (const char16_t*)defprinter.constData()));
250
251 DO_PR_DEBUG_LOG(("GetDefaultPrinterName(): default printer='%s'.\n",
252 NS_ConvertUTF16toUTF8(*aDefaultPrinterName).get()));
253
254 return NS_OK;
255 }
256
257 NS_IMETHODIMP nsPrinterEnumeratorQt::InitPrintSettingsFromPrinter(
258 const char16_t* aPrinterName,
259 nsIPrintSettings* aPrintSettings)
260 {
261 DO_PR_DEBUG_LOG(("nsPrinterEnumeratorQt::InitPrintSettingsFromPrinter()"));
262 // XXX Leave NS_OK for now
263 // Probably should use NS_ERROR_NOT_IMPLEMENTED
264 return NS_OK;
265 }
266
267 NS_IMETHODIMP nsPrinterEnumeratorQt::DisplayPropertiesDlg(
268 const char16_t* aPrinter,
269 nsIPrintSettings* aPrintSettings)
270 {
271 return NS_ERROR_NOT_IMPLEMENTED;
272 }
273

mercurial