Bug 1091112 - Proxy opening the print dialog on OS X to the parent. r=mstange

This commit is contained in:
Mike Conley 2015-05-06 14:10:21 -04:00
parent 595ae59517
commit 3e6536b62e
8 changed files with 252 additions and 6 deletions

View File

@ -26,6 +26,7 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
'../printingui/win',
]
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
DEFINES['PROXY_PRINTING'] = 1
LOCAL_INCLUDES += [
'../printingui/mac',
]

View File

@ -101,7 +101,7 @@ struct PrintData {
/** TODO: Is there an "unsigned short" primitive? **/
short pagesAcross;
short pagesDown;
nsString printTime;
double printTime;
bool detailedErrorReporting;
nsString faxNumber;
bool addHeaderAndFooter;

View File

@ -129,7 +129,23 @@ NS_IMETHODIMP
MockWebBrowserPrint::EnumerateDocumentNames(uint32_t* aCount,
char16_t*** aResult)
{
return NS_ERROR_NOT_IMPLEMENTED;
*aCount = 0;
*aResult = nullptr;
if (mData.printJobName().IsEmpty()) {
return NS_OK;
}
// The only consumer that cares about this is the OS X printing
// dialog, and even then, it only cares about the first document
// name. That's why we only send a single document name through
// PrintData.
char16_t** array = (char16_t**) moz_xmalloc(sizeof(char16_t*));
array[0] = ToNewUnicode(mData.printJobName());
*aCount = 1;
*aResult = array;
return NS_OK;
}
NS_IMETHODIMP

View File

@ -88,9 +88,14 @@ nsPrintDialogServiceX::Show(nsIDOMWindow *aParent, nsIPrintSettings *aSettings,
int button = [panel runModal];
nsCocoaUtils::CleanUpAfterNativeAppModalDialog();
settingsX->SetCocoaPrintInfo([[[NSPrintOperation currentOperation] printInfo] copy]);
NSPrintInfo* copy = [[[NSPrintOperation currentOperation] printInfo] copy];
if (!copy) {
return NS_ERROR_OUT_OF_MEMORY;
}
settingsX->SetCocoaPrintInfo(copy);
[copy release];
[NSPrintOperation setCurrentOperation:nil];
[printInfo release];
[tmpView release];
if (button != NSOKButton)

View File

@ -8,11 +8,26 @@
#include "nsPrintOptionsImpl.h"
namespace mozilla
{
namespace embedding
{
class PrintData;
} // namespace embedding
} // namespace mozilla
class nsPrintOptionsX : public nsPrintOptions
{
public:
nsPrintOptionsX();
virtual ~nsPrintOptionsX();
NS_IMETHODIMP SerializeToPrintData(nsIPrintSettings* aSettings,
nsIWebBrowserPrint* aWBP,
mozilla::embedding::PrintData* data);
NS_IMETHODIMP DeserializeToPrintSettings(const mozilla::embedding::PrintData& data,
nsIPrintSettings* settings);
protected:
nsresult _CreatePrintSettings(nsIPrintSettings **_retval);
nsresult ReadPrefs(nsIPrintSettings* aPS, const nsAString& aPrinterName, uint32_t aFlags);

View File

@ -9,6 +9,8 @@
#include "nsPrintOptionsX.h"
#include "nsPrintSettingsX.h"
using namespace mozilla::embedding;
nsPrintOptionsX::nsPrintOptionsX()
{
}
@ -17,6 +19,210 @@ 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;
nsresult 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;
}
nsRefPtr<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;
}
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());
}
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;
}
nsRefPtr<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 (NS_WARN_IF(!printer)) {
return NS_ERROR_FAILURE;
}
[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: [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())
stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]];
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];
return NS_OK;
}
nsresult
nsPrintOptionsX::ReadPrefs(nsIPrintSettings* aPS, const nsAString& aPrinterName, uint32_t aFlags)
{

View File

@ -94,7 +94,10 @@ NS_IMETHODIMP nsPrintSettingsX::InitUnwriteableMargin()
void
nsPrintSettingsX::SetCocoaPrintInfo(NSPrintInfo* aPrintInfo)
{
mPrintInfo = aPrintInfo;
if (mPrintInfo != aPrintInfo) {
[mPrintInfo release];
mPrintInfo = [aPrintInfo retain];
}
}
NS_IMETHODIMP nsPrintSettingsX::ReadPageFormatFromPrefs()

View File

@ -242,7 +242,7 @@ nsPrintOptions::SerializeToPrintData(nsIPrintSettings* aSettings,
// data->disposition() default-initializes
data->pagesAcross() = 1;
data->pagesDown() = 1;
// data->printTime() default-initializes
data->printTime() = 0;
data->detailedErrorReporting() = true;
// data->faxNumber() default-initializes
data->addHeaderAndFooter() = false;