diff options
Diffstat (limited to 'widget/cocoa/nsPrintOptionsX.mm')
-rw-r--r-- | widget/cocoa/nsPrintOptionsX.mm | 349 |
1 files changed, 349 insertions, 0 deletions
diff --git a/widget/cocoa/nsPrintOptionsX.mm b/widget/cocoa/nsPrintOptionsX.mm new file mode 100644 index 000000000..d9aa17b42 --- /dev/null +++ b/widget/cocoa/nsPrintOptionsX.mm @@ -0,0 +1,349 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsCOMPtr.h" +#include "nsQueryObject.h" +#include "nsIServiceManager.h" +#include "nsPrintOptionsX.h" +#include "nsPrintSettingsX.h" + +// The constants for paper orientation were renamed in 10.9. __MAC_10_9 is +// defined on OS X 10.9 and later. Although 10.8 and earlier are not supported +// at this time, this allows for building on those older OS versions. The +// values are consistent across OS versions so the rename does not affect +// runtime, just compilation. +#ifdef __MAC_10_9 +#define NS_PAPER_ORIENTATION_PORTRAIT (NSPaperOrientationPortrait) +#define NS_PAPER_ORIENTATION_LANDSCAPE (NSPaperOrientationLandscape) +#else +#define NS_PAPER_ORIENTATION_PORTRAIT (NSPortraitOrientation) +#define NS_PAPER_ORIENTATION_LANDSCAPE (NSLandscapeOrientation) +#endif + +using namespace mozilla::embedding; + +nsPrintOptionsX::nsPrintOptionsX() +{ +} + +nsPrintOptionsX::~nsPrintOptionsX() +{ +} + +NS_IMETHODIMP +nsPrintOptionsX::SerializeToPrintData(nsIPrintSettings* aSettings, + nsIWebBrowserPrint* aWBP, + PrintData* data) +{ + nsresult rv = nsPrintOptions::SerializeToPrintData(aSettings, aWBP, data); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + if (aWBP) { + // When serializing an nsIWebBrowserPrint, we need to pass up the first + // document name. We could pass up the entire collection of document + // names, but the OS X printing prompt code only really cares about + // the first one, so we just send the first to save IPC traffic. + char16_t** docTitles; + uint32_t titleCount; + rv = aWBP->EnumerateDocumentNames(&titleCount, &docTitles); + if (NS_SUCCEEDED(rv) && titleCount > 0) { + data->printJobName().Assign(docTitles[0]); + } + + for (int32_t i = titleCount - 1; i >= 0; i--) { + free(docTitles[i]); + } + free(docTitles); + docTitles = nullptr; + } + + RefPtr<nsPrintSettingsX> settingsX(do_QueryObject(aSettings)); + if (NS_WARN_IF(!settingsX)) { + return NS_ERROR_FAILURE; + } + + NSPrintInfo* printInfo = settingsX->GetCocoaPrintInfo(); + if (NS_WARN_IF(!printInfo)) { + return NS_ERROR_FAILURE; + } + + double adjustedWidth, adjustedHeight; + settingsX->GetAdjustedPaperSize(&adjustedWidth, &adjustedHeight); + data->adjustedPaperWidth() = adjustedWidth; + data->adjustedPaperHeight() = adjustedHeight; + + NSDictionary* dict = [printInfo dictionary]; + if (NS_WARN_IF(!dict)) { + return NS_ERROR_FAILURE; + } + + NSString* printerName = [dict objectForKey: NSPrintPrinterName]; + if (printerName) { + nsCocoaUtils::GetStringForNSString(printerName, data->printerName()); + } + + NSString* faxNumber = [dict objectForKey: NSPrintFaxNumber]; + if (faxNumber) { + nsCocoaUtils::GetStringForNSString(faxNumber, data->faxNumber()); + } + + NSURL* printToFileURL = [dict objectForKey: NSPrintJobSavingURL]; + if (printToFileURL) { + nsCocoaUtils::GetStringForNSString([printToFileURL absoluteString], + data->toFileName()); + } + + NSDate* printTime = [dict objectForKey: NSPrintTime]; + if (printTime) { + NSTimeInterval timestamp = [printTime timeIntervalSinceReferenceDate]; + data->printTime() = timestamp; + } + + NSString* disposition = [dict objectForKey: NSPrintJobDisposition]; + if (disposition) { + nsCocoaUtils::GetStringForNSString(disposition, data->disposition()); + } + + NSString* paperName = [dict objectForKey: NSPrintPaperName]; + if (paperName) { + nsCocoaUtils::GetStringForNSString(paperName, data->paperName()); + } + + float scalingFactor = [[dict objectForKey: NSPrintScalingFactor] floatValue]; + data->scalingFactor() = scalingFactor; + + int32_t orientation; + if ([printInfo orientation] == NS_PAPER_ORIENTATION_PORTRAIT) { + orientation = nsIPrintSettings::kPortraitOrientation; + } else { + orientation = nsIPrintSettings::kLandscapeOrientation; + } + data->orientation() = orientation; + + NSSize paperSize = [printInfo paperSize]; + float widthScale, heightScale; + settingsX->GetInchesScale(&widthScale, &heightScale); + if (orientation == nsIPrintSettings::kLandscapeOrientation) { + // switch widths and heights + data->widthScale() = heightScale; + data->heightScale() = widthScale; + data->paperWidth() = paperSize.height / heightScale; + data->paperHeight() = paperSize.width / widthScale; + } else { + data->widthScale() = widthScale; + data->heightScale() = heightScale; + data->paperWidth() = paperSize.width / widthScale; + data->paperHeight() = paperSize.height / heightScale; + } + + data->numCopies() = [[dict objectForKey: NSPrintCopies] intValue]; + data->printAllPages() = [[dict objectForKey: NSPrintAllPages] boolValue]; + data->startPageRange() = [[dict objectForKey: NSPrintFirstPage] intValue]; + data->endPageRange() = [[dict objectForKey: NSPrintLastPage] intValue]; + data->mustCollate() = [[dict objectForKey: NSPrintMustCollate] boolValue]; + data->printReversed() = [[dict objectForKey: NSPrintReversePageOrder] boolValue]; + data->pagesAcross() = [[dict objectForKey: NSPrintPagesAcross] unsignedShortValue]; + data->pagesDown() = [[dict objectForKey: NSPrintPagesDown] unsignedShortValue]; + data->detailedErrorReporting() = [[dict objectForKey: NSPrintDetailedErrorReporting] boolValue]; + data->addHeaderAndFooter() = [[dict objectForKey: NSPrintHeaderAndFooter] boolValue]; + data->fileNameExtensionHidden() = + [[dict objectForKey: NSPrintJobSavingFileNameExtensionHidden] boolValue]; + + bool printSelectionOnly = [[dict objectForKey: NSPrintSelectionOnly] boolValue]; + aSettings->SetPrintOptions(nsIPrintSettings::kEnableSelectionRB, + printSelectionOnly); + aSettings->GetPrintOptionsBits(&data->optionFlags()); + + return NS_OK; +} + +NS_IMETHODIMP +nsPrintOptionsX::DeserializeToPrintSettings(const PrintData& data, + nsIPrintSettings* settings) +{ + nsresult rv = nsPrintOptions::DeserializeToPrintSettings(data, settings); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + RefPtr<nsPrintSettingsX> settingsX(do_QueryObject(settings)); + if (NS_WARN_IF(!settingsX)) { + return NS_ERROR_FAILURE; + } + + NSPrintInfo* sharedPrintInfo = [NSPrintInfo sharedPrintInfo]; + if (NS_WARN_IF(!sharedPrintInfo)) { + return NS_ERROR_FAILURE; + } + + NSDictionary* sharedDict = [sharedPrintInfo dictionary]; + if (NS_WARN_IF(!sharedDict)) { + return NS_ERROR_FAILURE; + } + + // We need to create a new NSMutableDictionary to pass to NSPrintInfo with + // the values that we got from the other process. + NSMutableDictionary* newPrintInfoDict = + [NSMutableDictionary dictionaryWithDictionary:sharedDict]; + if (NS_WARN_IF(!newPrintInfoDict)) { + return NS_ERROR_OUT_OF_MEMORY; + } + + NSString* printerName = nsCocoaUtils::ToNSString(data.printerName()); + if (printerName) { + NSPrinter* printer = [NSPrinter printerWithName: printerName]; + if (printer) { + [newPrintInfoDict setObject: printer forKey: NSPrintPrinter]; + [newPrintInfoDict setObject: printerName forKey: NSPrintPrinterName]; + } + } + + [newPrintInfoDict setObject: [NSNumber numberWithInt: data.numCopies()] + forKey: NSPrintCopies]; + [newPrintInfoDict setObject: [NSNumber numberWithBool: data.printAllPages()] + forKey: NSPrintAllPages]; + [newPrintInfoDict setObject: [NSNumber numberWithInt: data.startPageRange()] + forKey: NSPrintFirstPage]; + [newPrintInfoDict setObject: [NSNumber numberWithInt: data.endPageRange()] + forKey: NSPrintLastPage]; + [newPrintInfoDict setObject: [NSNumber numberWithBool: data.mustCollate()] + forKey: NSPrintMustCollate]; + [newPrintInfoDict setObject: [NSNumber numberWithBool: data.printReversed()] + forKey: NSPrintReversePageOrder]; + + [newPrintInfoDict setObject: nsCocoaUtils::ToNSString(data.disposition()) + forKey: NSPrintJobDisposition]; + + [newPrintInfoDict setObject: nsCocoaUtils::ToNSString(data.paperName()) + forKey: NSPrintPaperName]; + + [newPrintInfoDict setObject: [NSNumber numberWithFloat: data.scalingFactor()] + forKey: NSPrintScalingFactor]; + + CGFloat width = data.paperWidth() * data.widthScale(); + CGFloat height = data.paperHeight() * data.heightScale(); + [newPrintInfoDict setObject: [NSValue valueWithSize:NSMakeSize(width,height)] + forKey: NSPrintPaperSize]; + + int paperOrientation; + if (data.orientation() == nsIPrintSettings::kPortraitOrientation) { + paperOrientation = NS_PAPER_ORIENTATION_PORTRAIT; + settings->SetOrientation(nsIPrintSettings::kPortraitOrientation); + } else { + paperOrientation = NS_PAPER_ORIENTATION_LANDSCAPE; + settings->SetOrientation(nsIPrintSettings::kLandscapeOrientation); + } + [newPrintInfoDict setObject: [NSNumber numberWithInt:paperOrientation] + forKey: NSPrintOrientation]; + + [newPrintInfoDict setObject: [NSNumber numberWithShort: data.pagesAcross()] + forKey: NSPrintPagesAcross]; + [newPrintInfoDict setObject: [NSNumber numberWithShort: data.pagesDown()] + forKey: NSPrintPagesDown]; + [newPrintInfoDict setObject: [NSNumber numberWithBool: data.detailedErrorReporting()] + forKey: NSPrintDetailedErrorReporting]; + [newPrintInfoDict setObject: nsCocoaUtils::ToNSString(data.faxNumber()) + forKey: NSPrintFaxNumber]; + [newPrintInfoDict setObject: [NSNumber numberWithBool: data.addHeaderAndFooter()] + forKey: NSPrintHeaderAndFooter]; + [newPrintInfoDict setObject: [NSNumber numberWithBool: data.fileNameExtensionHidden()] + forKey: NSPrintJobSavingFileNameExtensionHidden]; + + // At this point, the base class should have properly deserialized the print + // options bitfield for nsIPrintSettings, so that it holds the correct value + // for kEnableSelectionRB, which we use to set NSPrintSelectionOnly. + + bool printSelectionOnly = false; + rv = settings->GetPrintOptions(nsIPrintSettings::kEnableSelectionRB, &printSelectionOnly); + if (NS_SUCCEEDED(rv)) { + [newPrintInfoDict setObject: [NSNumber numberWithBool: printSelectionOnly] + forKey: NSPrintSelectionOnly]; + } else { + [newPrintInfoDict setObject: [NSNumber numberWithBool: NO] + forKey: NSPrintSelectionOnly]; + } + + NSURL* jobSavingURL = + [NSURL URLWithString: nsCocoaUtils::ToNSString(data.toFileName())]; + if (jobSavingURL) { + [newPrintInfoDict setObject: jobSavingURL forKey: NSPrintJobSavingURL]; + } + + NSTimeInterval timestamp = data.printTime(); + NSDate* printTime = [NSDate dateWithTimeIntervalSinceReferenceDate: timestamp]; + if (printTime) { + [newPrintInfoDict setObject: printTime forKey: NSPrintTime]; + } + + // Next, we create a new NSPrintInfo with the values in our dictionary. + NSPrintInfo* newPrintInfo = + [[NSPrintInfo alloc] initWithDictionary: newPrintInfoDict]; + if (NS_WARN_IF(!newPrintInfo)) { + return NS_ERROR_OUT_OF_MEMORY; + } + + // And now swap in the new NSPrintInfo we've just populated. + settingsX->SetCocoaPrintInfo(newPrintInfo); + [newPrintInfo release]; + + settingsX->SetAdjustedPaperSize(data.adjustedPaperWidth(), + data.adjustedPaperHeight()); + + return NS_OK; +} + +nsresult +nsPrintOptionsX::ReadPrefs(nsIPrintSettings* aPS, const nsAString& aPrinterName, uint32_t aFlags) +{ + nsresult rv; + + rv = nsPrintOptions::ReadPrefs(aPS, aPrinterName, aFlags); + NS_ASSERTION(NS_SUCCEEDED(rv), "nsPrintOptions::ReadPrefs() failed"); + + RefPtr<nsPrintSettingsX> printSettingsX(do_QueryObject(aPS)); + if (!printSettingsX) + return NS_ERROR_NO_INTERFACE; + rv = printSettingsX->ReadPageFormatFromPrefs(); + + return NS_OK; +} + +nsresult nsPrintOptionsX::_CreatePrintSettings(nsIPrintSettings **_retval) +{ + nsresult rv; + *_retval = nullptr; + + nsPrintSettingsX* printSettings = new nsPrintSettingsX; // does not initially ref count + NS_ENSURE_TRUE(printSettings, NS_ERROR_OUT_OF_MEMORY); + NS_ADDREF(*_retval = printSettings); + + rv = printSettings->Init(); + if (NS_FAILED(rv)) { + NS_RELEASE(*_retval); + return rv; + } + + InitPrintSettingsFromPrefs(*_retval, false, nsIPrintSettings::kInitSaveAll); + return rv; +} + +nsresult +nsPrintOptionsX::WritePrefs(nsIPrintSettings* aPS, const nsAString& aPrinterName, uint32_t aFlags) +{ + nsresult rv; + + rv = nsPrintOptions::WritePrefs(aPS, aPrinterName, aFlags); + NS_ASSERTION(NS_SUCCEEDED(rv), "nsPrintOptions::WritePrefs() failed"); + + RefPtr<nsPrintSettingsX> printSettingsX(do_QueryObject(aPS)); + if (!printSettingsX) + return NS_ERROR_NO_INTERFACE; + rv = printSettingsX->WritePageFormatToPrefs(); + NS_ASSERTION(NS_SUCCEEDED(rv), "nsPrintSettingsX::WritePageFormatToPrefs() failed"); + + return NS_OK; +} |