widget/qt/nsDeviceContextSpecQt.cpp

Thu, 15 Jan 2015 15:59:08 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 15:59:08 +0100
branch
TOR_BUG_9701
changeset 10
ac0c01689b40
permissions
-rw-r--r--

Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

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

mercurial