1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/widget/qt/nsDeviceContextSpecQt.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,273 @@ 1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 + 1.10 +#include <QTemporaryFile> 1.11 +#include <QPrinterInfo> 1.12 + 1.13 +#define SET_PRINTER_FEATURES_VIA_PREFS 1 1.14 +#define PRINTERFEATURES_PREF "print.tmp.printerfeatures" 1.15 + 1.16 +#ifdef MOZ_LOGGING 1.17 +#define FORCE_PR_LOG 1 /* Allow logging in the release build */ 1.18 +#endif /* MOZ_LOGGING */ 1.19 +#include "prlog.h" 1.20 + 1.21 +#include "plstr.h" 1.22 + 1.23 +#include "nsDeviceContextSpecQt.h" 1.24 + 1.25 +#include "prenv.h" /* for PR_GetEnv */ 1.26 + 1.27 +#include "nsReadableUtils.h" 1.28 +#include "nsStringEnumerator.h" 1.29 +#include "nsIServiceManager.h" 1.30 +#include "nsPrintSettingsQt.h" 1.31 +#include "nsIFileStreams.h" 1.32 +#include "nsIFile.h" 1.33 +#include "nsTArray.h" 1.34 + 1.35 +#include <unistd.h> 1.36 +#include <sys/types.h> 1.37 +#include <sys/stat.h> 1.38 + 1.39 +#include "gfxPDFSurface.h" 1.40 + 1.41 +#ifdef PR_LOGGING 1.42 +static PRLogModuleInfo* DeviceContextSpecQtLM = 1.43 + PR_NewLogModule("DeviceContextSpecQt"); 1.44 +#endif /* PR_LOGGING */ 1.45 +/* Macro to make lines shorter */ 1.46 +#define DO_PR_DEBUG_LOG(x) PR_LOG(DeviceContextSpecQtLM, PR_LOG_DEBUG, x) 1.47 + 1.48 +nsDeviceContextSpecQt::nsDeviceContextSpecQt() 1.49 +{ 1.50 + DO_PR_DEBUG_LOG(("nsDeviceContextSpecQt::nsDeviceContextSpecQt()\n")); 1.51 +} 1.52 + 1.53 +nsDeviceContextSpecQt::~nsDeviceContextSpecQt() 1.54 +{ 1.55 + DO_PR_DEBUG_LOG(("nsDeviceContextSpecQt::~nsDeviceContextSpecQt()\n")); 1.56 +} 1.57 + 1.58 +NS_IMPL_ISUPPORTS(nsDeviceContextSpecQt, 1.59 + nsIDeviceContextSpec) 1.60 + 1.61 +NS_IMETHODIMP nsDeviceContextSpecQt::GetSurfaceForPrinter( 1.62 + gfxASurface** aSurface) 1.63 +{ 1.64 + NS_ENSURE_ARG_POINTER(aSurface); 1.65 + *aSurface = nullptr; 1.66 + 1.67 + double width, height; 1.68 + mPrintSettings->GetEffectivePageSize(&width, &height); 1.69 + 1.70 + // If we're in landscape mode, we'll be rotating the output -- 1.71 + // need to swap width & height. 1.72 + int32_t orientation; 1.73 + mPrintSettings->GetOrientation(&orientation); 1.74 + if (nsIPrintSettings::kLandscapeOrientation == orientation) { 1.75 + double tmp = width; 1.76 + width = height; 1.77 + height = tmp; 1.78 + } 1.79 + 1.80 + // convert twips to points 1.81 + width /= TWIPS_PER_POINT_FLOAT; 1.82 + height /= TWIPS_PER_POINT_FLOAT; 1.83 + 1.84 + DO_PR_DEBUG_LOG(("\"%s\", %f, %f\n", mPath, width, height)); 1.85 + 1.86 + QTemporaryFile file; 1.87 + if(!file.open()) { 1.88 + return NS_ERROR_GFX_PRINTER_COULD_NOT_OPEN_FILE; 1.89 + } 1.90 + file.setAutoRemove(false); 1.91 + 1.92 + nsresult rv = NS_NewNativeLocalFile( 1.93 + nsDependentCString(file.fileName().toUtf8().constData()), 1.94 + false, 1.95 + getter_AddRefs(mSpoolFile)); 1.96 + if (NS_FAILED(rv)) { 1.97 + file.remove(); 1.98 + return NS_ERROR_GFX_PRINTER_COULD_NOT_OPEN_FILE; 1.99 + } 1.100 + 1.101 + mSpoolName = file.fileName().toUtf8().constData(); 1.102 + 1.103 + mSpoolFile->SetPermissions(0600); 1.104 + 1.105 + nsCOMPtr<nsIFileOutputStream> stream = 1.106 + do_CreateInstance("@mozilla.org/network/file-output-stream;1"); 1.107 + 1.108 + rv = stream->Init(mSpoolFile, -1, -1, 0); 1.109 + if (NS_FAILED(rv)) 1.110 + return rv; 1.111 + 1.112 + int16_t format; 1.113 + mPrintSettings->GetOutputFormat(&format); 1.114 + 1.115 + nsRefPtr<gfxASurface> surface; 1.116 + gfxSize surfaceSize(width, height); 1.117 + 1.118 + if (format == nsIPrintSettings::kOutputFormatNative) { 1.119 + if (mIsPPreview) { 1.120 + // There is nothing to detect on Print Preview, use PS. 1.121 + // TODO: implement for Qt? 1.122 + //format = nsIPrintSettings::kOutputFormatPS; 1.123 + return NS_ERROR_NOT_IMPLEMENTED; 1.124 + } 1.125 + format = nsIPrintSettings::kOutputFormatPDF; 1.126 + } 1.127 + if (format == nsIPrintSettings::kOutputFormatPDF) { 1.128 + surface = new gfxPDFSurface(stream, surfaceSize); 1.129 + } else { 1.130 + return NS_ERROR_NOT_IMPLEMENTED; 1.131 + } 1.132 + 1.133 + NS_ABORT_IF_FALSE(surface, "valid address expected"); 1.134 + 1.135 + surface.swap(*aSurface); 1.136 + return NS_OK; 1.137 +} 1.138 + 1.139 +NS_IMETHODIMP nsDeviceContextSpecQt::Init(nsIWidget* aWidget, 1.140 + nsIPrintSettings* aPS, 1.141 + bool aIsPrintPreview) 1.142 +{ 1.143 + DO_PR_DEBUG_LOG(("nsDeviceContextSpecQt::Init(aPS=%p)\n", aPS)); 1.144 + 1.145 + mPrintSettings = aPS; 1.146 + mIsPPreview = aIsPrintPreview; 1.147 + 1.148 + // This is only set by embedders 1.149 + bool toFile; 1.150 + aPS->GetPrintToFile(&toFile); 1.151 + 1.152 + mToPrinter = !toFile && !aIsPrintPreview; 1.153 + 1.154 + nsCOMPtr<nsPrintSettingsQt> printSettingsQt(do_QueryInterface(aPS)); 1.155 + if (!printSettingsQt) 1.156 + return NS_ERROR_NO_INTERFACE; 1.157 + return NS_OK; 1.158 +} 1.159 + 1.160 +NS_IMETHODIMP nsDeviceContextSpecQt::GetPath(const char** aPath) 1.161 +{ 1.162 + *aPath = mPath; 1.163 + return NS_OK; 1.164 +} 1.165 + 1.166 +NS_IMETHODIMP nsDeviceContextSpecQt::BeginDocument( 1.167 + const nsAString& aTitle, 1.168 + char16_t* aPrintToFileName, 1.169 + int32_t aStartPage, 1.170 + int32_t aEndPage) 1.171 +{ 1.172 + if (mToPrinter) { 1.173 + return NS_ERROR_NOT_IMPLEMENTED; 1.174 + } 1.175 + return NS_OK; 1.176 +} 1.177 + 1.178 +NS_IMETHODIMP nsDeviceContextSpecQt::EndDocument() 1.179 +{ 1.180 + if (mToPrinter) { 1.181 + return NS_ERROR_NOT_IMPLEMENTED; 1.182 + } 1.183 + // Handle print-to-file ourselves for the benefit of embedders 1.184 + nsXPIDLString targetPath; 1.185 + nsCOMPtr<nsIFile> destFile; 1.186 + mPrintSettings->GetToFileName(getter_Copies(targetPath)); 1.187 + 1.188 + nsresult rv = NS_NewNativeLocalFile(NS_ConvertUTF16toUTF8(targetPath), 1.189 + false, getter_AddRefs(destFile)); 1.190 + NS_ENSURE_SUCCESS(rv, rv); 1.191 + 1.192 + nsAutoString destLeafName; 1.193 + rv = destFile->GetLeafName(destLeafName); 1.194 + NS_ENSURE_SUCCESS(rv, rv); 1.195 + 1.196 + nsCOMPtr<nsIFile> destDir; 1.197 + rv = destFile->GetParent(getter_AddRefs(destDir)); 1.198 + NS_ENSURE_SUCCESS(rv, rv); 1.199 + 1.200 + rv = mSpoolFile->MoveTo(destDir, destLeafName); 1.201 + NS_ENSURE_SUCCESS(rv, rv); 1.202 + 1.203 + // This is the standard way to get the UNIX umask. Ugh. 1.204 + mode_t mask = umask(0); 1.205 + umask(mask); 1.206 + // If you're not familiar with umasks, they contain the bits of what NOT 1.207 + // to set in the permissions 1.208 + // (thats because files and directories have different numbers of bits 1.209 + // for their permissions) 1.210 + destFile->SetPermissions(0666 & ~(mask)); 1.211 + 1.212 + return NS_OK; 1.213 +} 1.214 + 1.215 +// Printer Enumerator 1.216 +nsPrinterEnumeratorQt::nsPrinterEnumeratorQt() 1.217 +{ 1.218 +} 1.219 + 1.220 +NS_IMPL_ISUPPORTS(nsPrinterEnumeratorQt, nsIPrinterEnumerator) 1.221 + 1.222 +NS_IMETHODIMP nsPrinterEnumeratorQt::GetPrinterNameList( 1.223 + nsIStringEnumerator** aPrinterNameList) 1.224 +{ 1.225 + NS_ENSURE_ARG_POINTER(aPrinterNameList); 1.226 + *aPrinterNameList = nullptr; 1.227 + 1.228 + QList<QPrinterInfo> qprinters = QPrinterInfo::availablePrinters(); 1.229 + if (qprinters.size() == 0) 1.230 + return NS_ERROR_NOT_AVAILABLE; 1.231 + 1.232 + nsTArray<nsString>* printers = 1.233 + new nsTArray<nsString>(qprinters.size()); 1.234 + 1.235 + for (int32_t i = 0; i < qprinters.size(); ++i) { 1.236 + printers->AppendElement( 1.237 + nsDependentString( 1.238 + (const char16_t*)qprinters[i].printerName().constData())); 1.239 + } 1.240 + 1.241 + return NS_NewAdoptingStringEnumerator(aPrinterNameList, printers); 1.242 +} 1.243 + 1.244 +NS_IMETHODIMP nsPrinterEnumeratorQt::GetDefaultPrinterName( 1.245 + char16_t** aDefaultPrinterName) 1.246 +{ 1.247 + DO_PR_DEBUG_LOG(("nsPrinterEnumeratorQt::GetDefaultPrinterName()\n")); 1.248 + NS_ENSURE_ARG_POINTER(aDefaultPrinterName); 1.249 + 1.250 + QString defprinter = QPrinterInfo::defaultPrinter().printerName(); 1.251 + *aDefaultPrinterName = ToNewUnicode(nsDependentString( 1.252 + (const char16_t*)defprinter.constData())); 1.253 + 1.254 + DO_PR_DEBUG_LOG(("GetDefaultPrinterName(): default printer='%s'.\n", 1.255 + NS_ConvertUTF16toUTF8(*aDefaultPrinterName).get())); 1.256 + 1.257 + return NS_OK; 1.258 +} 1.259 + 1.260 +NS_IMETHODIMP nsPrinterEnumeratorQt::InitPrintSettingsFromPrinter( 1.261 + const char16_t* aPrinterName, 1.262 + nsIPrintSettings* aPrintSettings) 1.263 +{ 1.264 + DO_PR_DEBUG_LOG(("nsPrinterEnumeratorQt::InitPrintSettingsFromPrinter()")); 1.265 + // XXX Leave NS_OK for now 1.266 + // Probably should use NS_ERROR_NOT_IMPLEMENTED 1.267 + return NS_OK; 1.268 +} 1.269 + 1.270 +NS_IMETHODIMP nsPrinterEnumeratorQt::DisplayPropertiesDlg( 1.271 + const char16_t* aPrinter, 1.272 + nsIPrintSettings* aPrintSettings) 1.273 +{ 1.274 + return NS_ERROR_NOT_IMPLEMENTED; 1.275 +} 1.276 +