Bumping manifests a=b2g-bump
[gecko.git] / widget / qt / nsDeviceContextSpecQt.cpp
blob12c93db11677925e5d36c7ddbce4976f4ad59d4f
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/. */
7 #include <QTemporaryFile>
8 #include <QPrinterInfo>
10 #define SET_PRINTER_FEATURES_VIA_PREFS 1
11 #define PRINTERFEATURES_PREF "print.tmp.printerfeatures"
13 #ifdef MOZ_LOGGING
14 #define FORCE_PR_LOG 1 /* Allow logging in the release build */
15 #endif /* MOZ_LOGGING */
16 #include "prlog.h"
18 #include "plstr.h"
20 #include "nsDeviceContextSpecQt.h"
22 #include "prenv.h" /* for PR_GetEnv */
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"
32 #include <unistd.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
36 #include "gfxPDFSurface.h"
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)
45 nsDeviceContextSpecQt::nsDeviceContextSpecQt()
47 DO_PR_DEBUG_LOG(("nsDeviceContextSpecQt::nsDeviceContextSpecQt()\n"));
50 nsDeviceContextSpecQt::~nsDeviceContextSpecQt()
52 DO_PR_DEBUG_LOG(("nsDeviceContextSpecQt::~nsDeviceContextSpecQt()\n"));
55 NS_IMPL_ISUPPORTS(nsDeviceContextSpecQt,
56 nsIDeviceContextSpec)
58 NS_IMETHODIMP nsDeviceContextSpecQt::GetSurfaceForPrinter(
59 gfxASurface** aSurface)
61 NS_ENSURE_ARG_POINTER(aSurface);
62 *aSurface = nullptr;
64 double width, height;
65 mPrintSettings->GetEffectivePageSize(&width, &height);
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;
77 // convert twips to points
78 width /= TWIPS_PER_POINT_FLOAT;
79 height /= TWIPS_PER_POINT_FLOAT;
81 DO_PR_DEBUG_LOG(("\"%s\", %f, %f\n", mPath, width, height));
83 QTemporaryFile file;
84 if(!file.open()) {
85 return NS_ERROR_GFX_PRINTER_COULD_NOT_OPEN_FILE;
87 file.setAutoRemove(false);
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;
98 mSpoolName = file.fileName().toUtf8().constData();
100 mSpoolFile->SetPermissions(0600);
102 nsCOMPtr<nsIFileOutputStream> stream =
103 do_CreateInstance("@mozilla.org/network/file-output-stream;1");
105 rv = stream->Init(mSpoolFile, -1, -1, 0);
106 if (NS_FAILED(rv))
107 return rv;
109 int16_t format;
110 mPrintSettings->GetOutputFormat(&format);
112 nsRefPtr<gfxASurface> surface;
113 gfxSize surfaceSize(width, height);
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;
122 format = nsIPrintSettings::kOutputFormatPDF;
124 if (format == nsIPrintSettings::kOutputFormatPDF) {
125 surface = new gfxPDFSurface(stream, surfaceSize);
126 } else {
127 return NS_ERROR_NOT_IMPLEMENTED;
130 NS_ABORT_IF_FALSE(surface, "valid address expected");
132 surface.swap(*aSurface);
133 return NS_OK;
136 NS_IMETHODIMP nsDeviceContextSpecQt::Init(nsIWidget* aWidget,
137 nsIPrintSettings* aPS,
138 bool aIsPrintPreview)
140 DO_PR_DEBUG_LOG(("nsDeviceContextSpecQt::Init(aPS=%p)\n", aPS));
142 mPrintSettings = aPS;
143 mIsPPreview = aIsPrintPreview;
145 // This is only set by embedders
146 bool toFile;
147 aPS->GetPrintToFile(&toFile);
149 mToPrinter = !toFile && !aIsPrintPreview;
151 nsCOMPtr<nsPrintSettingsQt> printSettingsQt(do_QueryInterface(aPS));
152 if (!printSettingsQt)
153 return NS_ERROR_NO_INTERFACE;
154 return NS_OK;
157 NS_IMETHODIMP nsDeviceContextSpecQt::GetPath(const char** aPath)
159 *aPath = mPath;
160 return NS_OK;
163 NS_IMETHODIMP nsDeviceContextSpecQt::BeginDocument(
164 const nsAString& aTitle,
165 char16_t* aPrintToFileName,
166 int32_t aStartPage,
167 int32_t aEndPage)
169 if (mToPrinter) {
170 return NS_ERROR_NOT_IMPLEMENTED;
172 return NS_OK;
175 NS_IMETHODIMP nsDeviceContextSpecQt::EndDocument()
177 if (mToPrinter) {
178 return NS_ERROR_NOT_IMPLEMENTED;
180 // Handle print-to-file ourselves for the benefit of embedders
181 nsXPIDLString targetPath;
182 nsCOMPtr<nsIFile> destFile;
183 mPrintSettings->GetToFileName(getter_Copies(targetPath));
185 nsresult rv = NS_NewNativeLocalFile(NS_ConvertUTF16toUTF8(targetPath),
186 false, getter_AddRefs(destFile));
187 NS_ENSURE_SUCCESS(rv, rv);
189 nsAutoString destLeafName;
190 rv = destFile->GetLeafName(destLeafName);
191 NS_ENSURE_SUCCESS(rv, rv);
193 nsCOMPtr<nsIFile> destDir;
194 rv = destFile->GetParent(getter_AddRefs(destDir));
195 NS_ENSURE_SUCCESS(rv, rv);
197 rv = mSpoolFile->MoveTo(destDir, destLeafName);
198 NS_ENSURE_SUCCESS(rv, rv);
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));
209 return NS_OK;
212 // Printer Enumerator
213 nsPrinterEnumeratorQt::nsPrinterEnumeratorQt()
217 nsPrinterEnumeratorQt::~nsPrinterEnumeratorQt()
221 NS_IMPL_ISUPPORTS(nsPrinterEnumeratorQt, nsIPrinterEnumerator)
223 NS_IMETHODIMP nsPrinterEnumeratorQt::GetPrinterNameList(
224 nsIStringEnumerator** aPrinterNameList)
226 NS_ENSURE_ARG_POINTER(aPrinterNameList);
227 *aPrinterNameList = nullptr;
229 QList<QPrinterInfo> qprinters = QPrinterInfo::availablePrinters();
230 if (qprinters.size() == 0)
231 return NS_ERROR_NOT_AVAILABLE;
233 nsTArray<nsString>* printers =
234 new nsTArray<nsString>(qprinters.size());
236 for (int32_t i = 0; i < qprinters.size(); ++i) {
237 printers->AppendElement(
238 nsDependentString(
239 (const char16_t*)qprinters[i].printerName().constData()));
242 return NS_NewAdoptingStringEnumerator(aPrinterNameList, printers);
245 NS_IMETHODIMP nsPrinterEnumeratorQt::GetDefaultPrinterName(
246 char16_t** aDefaultPrinterName)
248 DO_PR_DEBUG_LOG(("nsPrinterEnumeratorQt::GetDefaultPrinterName()\n"));
249 NS_ENSURE_ARG_POINTER(aDefaultPrinterName);
251 QString defprinter = QPrinterInfo::defaultPrinter().printerName();
252 *aDefaultPrinterName = ToNewUnicode(nsDependentString(
253 (const char16_t*)defprinter.constData()));
255 DO_PR_DEBUG_LOG(("GetDefaultPrinterName(): default printer='%s'.\n",
256 NS_ConvertUTF16toUTF8(*aDefaultPrinterName).get()));
258 return NS_OK;
261 NS_IMETHODIMP nsPrinterEnumeratorQt::InitPrintSettingsFromPrinter(
262 const char16_t* aPrinterName,
263 nsIPrintSettings* aPrintSettings)
265 DO_PR_DEBUG_LOG(("nsPrinterEnumeratorQt::InitPrintSettingsFromPrinter()"));
266 // XXX Leave NS_OK for now
267 // Probably should use NS_ERROR_NOT_IMPLEMENTED
268 return NS_OK;
271 NS_IMETHODIMP nsPrinterEnumeratorQt::DisplayPropertiesDlg(
272 const char16_t* aPrinter,
273 nsIPrintSettings* aPrintSettings)
275 return NS_ERROR_NOT_IMPLEMENTED;