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.

     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()
    46 {
    47     DO_PR_DEBUG_LOG(("nsDeviceContextSpecQt::nsDeviceContextSpecQt()\n"));
    48 }
    50 nsDeviceContextSpecQt::~nsDeviceContextSpecQt()
    51 {
    52     DO_PR_DEBUG_LOG(("nsDeviceContextSpecQt::~nsDeviceContextSpecQt()\n"));
    53 }
    55 NS_IMPL_ISUPPORTS(nsDeviceContextSpecQt,
    56         nsIDeviceContextSpec)
    58 NS_IMETHODIMP nsDeviceContextSpecQt::GetSurfaceForPrinter(
    59         gfxASurface** aSurface)
    60 {
    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;
    75     }
    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;
    86     }
    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;
    96     }
    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;
   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     }
   130     NS_ABORT_IF_FALSE(surface, "valid address expected");
   132     surface.swap(*aSurface);
   133     return NS_OK;
   134 }
   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));
   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;
   155 }
   157 NS_IMETHODIMP nsDeviceContextSpecQt::GetPath(const char** aPath)
   158 {
   159     *aPath = mPath;
   160     return NS_OK;
   161 }
   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 }
   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));
   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;
   210 }
   212 //  Printer Enumerator
   213 nsPrinterEnumeratorQt::nsPrinterEnumeratorQt()
   214 {
   215 }
   217 NS_IMPL_ISUPPORTS(nsPrinterEnumeratorQt, nsIPrinterEnumerator)
   219 NS_IMETHODIMP nsPrinterEnumeratorQt::GetPrinterNameList(
   220         nsIStringEnumerator** aPrinterNameList)
   221 {
   222     NS_ENSURE_ARG_POINTER(aPrinterNameList);
   223     *aPrinterNameList = nullptr;
   225     QList<QPrinterInfo> qprinters = QPrinterInfo::availablePrinters();
   226     if (qprinters.size() == 0)
   227         return NS_ERROR_NOT_AVAILABLE;
   229     nsTArray<nsString>* printers =
   230         new nsTArray<nsString>(qprinters.size()); 
   232     for (int32_t i = 0; i < qprinters.size(); ++i) {
   233         printers->AppendElement(
   234                 nsDependentString(
   235                     (const char16_t*)qprinters[i].printerName().constData()));
   236     }
   238     return NS_NewAdoptingStringEnumerator(aPrinterNameList, printers);
   239 }
   241 NS_IMETHODIMP nsPrinterEnumeratorQt::GetDefaultPrinterName(
   242         char16_t** aDefaultPrinterName)
   243 {
   244     DO_PR_DEBUG_LOG(("nsPrinterEnumeratorQt::GetDefaultPrinterName()\n"));
   245     NS_ENSURE_ARG_POINTER(aDefaultPrinterName);
   247     QString defprinter = QPrinterInfo::defaultPrinter().printerName();
   248     *aDefaultPrinterName = ToNewUnicode(nsDependentString(
   249         (const char16_t*)defprinter.constData()));
   251     DO_PR_DEBUG_LOG(("GetDefaultPrinterName(): default printer='%s'.\n",
   252         NS_ConvertUTF16toUTF8(*aDefaultPrinterName).get()));
   254     return NS_OK;
   255 }
   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 }
   267 NS_IMETHODIMP nsPrinterEnumeratorQt::DisplayPropertiesDlg(
   268         const char16_t* aPrinter,
   269         nsIPrintSettings* aPrintSettings)
   270 {
   271     return NS_ERROR_NOT_IMPLEMENTED;
   272 }

mercurial