From 3a7fc409b73f03a504d828675dcee237d9134ca1 Mon Sep 17 00:00:00 2001 From: Erik Nordin Date: Thu, 28 May 2020 15:36:44 +0000 Subject: [PATCH] Bug 117233 - Implement nsIPrinterEnumeratorX r=jwatt - Implement the nsPrinterEnumeratorX - Enable the contract @mozilla.org/gfx/printerenumerator;1 for macOS - Add test for default printer name. - Remove restrictions preventing some tests from running on macOS Differential Revision: https://phabricator.services.mozilla.com/D76356 --- layout/base/tests/chrome/chrome.ini | 1 + .../printpreview_bug396024_helper.xhtml | 9 -- .../printpreview_bug482976_helper.xhtml | 11 +- .../tests/chrome/printpreview_helper.xhtml | 9 -- .../chrome/test_default_printer_name.html | 32 ++++++ widget/cocoa/nsDeviceContextSpecX.h | 14 +++ widget/cocoa/nsDeviceContextSpecX.mm | 106 +++++++++++++++++- widget/cocoa/nsWidgetFactory.mm | 4 + 8 files changed, 154 insertions(+), 32 deletions(-) create mode 100644 layout/base/tests/chrome/test_default_printer_name.html diff --git a/layout/base/tests/chrome/chrome.ini b/layout/base/tests/chrome/chrome.ini index 1ace6c076986..cf6a00f4314e 100644 --- a/layout/base/tests/chrome/chrome.ini +++ b/layout/base/tests/chrome/chrome.ini @@ -56,6 +56,7 @@ support-files = chrome_over_plugin_window.xhtml chrome_over_plugin_window_frame.html [test_default_background.xhtml] +[test_default_printer_name.html] [test_dialog_with_positioning.html] tags = openwindow [test_fixed_bg_scrolling_repaints.html] diff --git a/layout/base/tests/chrome/printpreview_bug396024_helper.xhtml b/layout/base/tests/chrome/printpreview_bug396024_helper.xhtml index f018a8001bac..fadaed1034e7 100644 --- a/layout/base/tests/chrome/printpreview_bug396024_helper.xhtml +++ b/layout/base/tests/chrome/printpreview_bug396024_helper.xhtml @@ -62,15 +62,6 @@ function run() var printService = Cc["@mozilla.org/gfx/printsettings-service;1"] .getService(Ci.nsIPrintSettingsService); - try { - Cc["@mozilla.org/gfx/printerenumerator;1"] - .getService(Ci.nsIPrinterEnumerator); - } catch(e) { - todo(false, "Test skipped on MacOSX, as the print preview code doesn't work there"); - finish(); - return; - } - if (printService.defaultPrinterName != '') { printpreview(); ok(gWbp.doingPrintPreview, "Should be doing print preview"); diff --git a/layout/base/tests/chrome/printpreview_bug482976_helper.xhtml b/layout/base/tests/chrome/printpreview_bug482976_helper.xhtml index 1f6bd1cc540c..23c3f13d4839 100644 --- a/layout/base/tests/chrome/printpreview_bug482976_helper.xhtml +++ b/layout/base/tests/chrome/printpreview_bug482976_helper.xhtml @@ -24,7 +24,7 @@ function printpreview() { gWbp = frameElts[1].contentWindow.docShell.initOrReusePrintPreviewViewer(); var listener = { onLocationChange: function(webProgress, request, location, flags) { }, - onProgressChange: function(webProgress, request, curSelfProgress, + onProgressChange: function(webProgress, request, curSelfProgress, maxSelfProgress, curTotalProgress, maxTotalProgress) { }, onSecurityChange: function(webProgress, request, state) { }, @@ -62,15 +62,6 @@ function run1() var printService = Cc["@mozilla.org/gfx/printsettings-service;1"] .getService(Ci.nsIPrintSettingsService); - try { - Cc["@mozilla.org/gfx/printerenumerator;1"] - .getService(Ci.nsIPrinterEnumerator); - } catch(e) { - todo(false, "Test skipped on MacOSX, as the print preview code doesn't work there"); - finish(); - return; - } - if (printService.defaultPrinterName != '') { printpreview(); ok(gWbp.doingPrintPreview, "Should be doing print preview"); diff --git a/layout/base/tests/chrome/printpreview_helper.xhtml b/layout/base/tests/chrome/printpreview_helper.xhtml index 506340fbb700..08969421f997 100644 --- a/layout/base/tests/chrome/printpreview_helper.xhtml +++ b/layout/base/tests/chrome/printpreview_helper.xhtml @@ -82,15 +82,6 @@ function runTests() var printService = Cc["@mozilla.org/gfx/printsettings-service;1"] .getService(Ci.nsIPrintSettingsService); - try { - Cc["@mozilla.org/gfx/printerenumerator;1"] - .getService(Ci.nsIPrinterEnumerator); - } catch(e) { - todo(false, "Test skipped on MacOSX, as the print preview code doesn't work there"); - finish(); - return; - } - if (printService.defaultPrinterName != '') { startTest1(); } else { diff --git a/layout/base/tests/chrome/test_default_printer_name.html b/layout/base/tests/chrome/test_default_printer_name.html new file mode 100644 index 000000000000..58bd992b146c --- /dev/null +++ b/layout/base/tests/chrome/test_default_printer_name.html @@ -0,0 +1,32 @@ + + + + + + + + + diff --git a/widget/cocoa/nsDeviceContextSpecX.h b/widget/cocoa/nsDeviceContextSpecX.h index d082c35bd652..85ee81b940c8 100644 --- a/widget/cocoa/nsDeviceContextSpecX.h +++ b/widget/cocoa/nsDeviceContextSpecX.h @@ -7,6 +7,7 @@ #define nsDeviceContextSpecX_h_ #include "nsIDeviceContextSpec.h" +#include "nsIPrinterEnumerator.h" #include "nsCOMPtr.h" @@ -45,4 +46,17 @@ class nsDeviceContextSpecX : public nsIDeviceContextSpec { #endif }; +//---------------------------------------------------------------------- +// nsPrinterErnumeratorX + +class nsPrinterEnumeratorX final : public nsIPrinterEnumerator { + public: + NS_DECL_ISUPPORTS + NS_DECL_NSIPRINTERENUMERATOR + nsPrinterEnumeratorX() = default; + + private: + ~nsPrinterEnumeratorX() = default; +}; + #endif // nsDeviceContextSpecX_h_ diff --git a/widget/cocoa/nsDeviceContextSpecX.mm b/widget/cocoa/nsDeviceContextSpecX.mm index c82de5bcc291..118199d27768 100644 --- a/widget/cocoa/nsDeviceContextSpecX.mm +++ b/widget/cocoa/nsDeviceContextSpecX.mm @@ -5,19 +5,26 @@ #include "nsDeviceContextSpecX.h" -#include "mozilla/gfx/PrintTargetCG.h" +#import +#include +#include + #ifdef MOZ_ENABLE_SKIA_PDF # include "mozilla/gfx/PrintTargetSkPDF.h" #endif +#include "mozilla/gfx/PrintTargetCG.h" +#include "mozilla/Logging.h" #include "mozilla/Preferences.h" #include "mozilla/RefPtr.h" + +#include "nsCocoaUtils.h" #include "nsCRT.h" #include "nsDirectoryServiceDefs.h" #include "nsILocalFileMac.h" -#include - -#include "nsQueryObject.h" #include "nsPrintSettingsX.h" +#include "nsQueryObject.h" +#include "nsStringEnumerator.h" +#include "prenv.h" // This must be the last include: #include "nsObjCExceptions.h" @@ -31,6 +38,97 @@ using mozilla::gfx::PrintTargetSkPDF; #endif using mozilla::gfx::SurfaceFormat; +static LazyLogModule sDeviceContextSpecXLog("DeviceContextSpecX"); +// Macro to make lines shorter +#define DO_PR_DEBUG_LOG(x) MOZ_LOG(sDeviceContextSpecXLog, mozilla::LogLevel::Debug, x) + +//---------------------------------------------------------------------- +// nsPrinterErnumeratorX + +NS_IMPL_ISUPPORTS(nsPrinterEnumeratorX, nsIPrinterEnumerator); + +NS_IMETHODIMP nsPrinterEnumeratorX::GetPrinterNameList(nsIStringEnumerator** aPrinterNameList) { + NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; + + NS_ENSURE_ARG_POINTER(aPrinterNameList); + *aPrinterNameList = nullptr; + + NSArray* printerNames = [NSPrinter printerNames]; + size_t nameCount = [printerNames count]; + nsTArray* printerNameList = new nsTArray(nameCount); + + for (size_t i = 0; i < nameCount; ++i) { + NSString* name = [printerNames objectAtIndex:i]; + nsAutoString nsName; + nsCocoaUtils::GetStringForNSString(name, nsName); + printerNameList->AppendElement(nsName); + } + + // If there are no printers available after all checks, return an error + if (printerNameList->IsEmpty()) { + delete printerNameList; + return NS_ERROR_GFX_PRINTER_NO_PRINTER_AVAILABLE; + } + + return NS_NewAdoptingStringEnumerator(aPrinterNameList, printerNameList); + + NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT; +} + +NS_IMETHODIMP nsPrinterEnumeratorX::GetDefaultPrinterName(nsAString& aDefaultPrinterName) { + NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; + + DO_PR_DEBUG_LOG(("nsPrinterEnumeratorX::GetDefaultPrinterName()\n")); + + aDefaultPrinterName.Truncate(); + NSArray* printerNames = [NSPrinter printerNames]; + if ([printerNames count] > 0) { + NSString* name = [printerNames objectAtIndex:0]; + nsCocoaUtils::GetStringForNSString(name, aDefaultPrinterName); + } + + DO_PR_DEBUG_LOG(("GetDefaultPrinterName(): default printer='%s'.\n", + NS_ConvertUTF16toUTF8(aDefaultPrinterName).get())); + return NS_OK; + + NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT; +} + +NS_IMETHODIMP +nsPrinterEnumeratorX::InitPrintSettingsFromPrinter(const nsAString& aPrinterName, + nsIPrintSettings* aPrintSettings) { + DO_PR_DEBUG_LOG(("nsPrinterEnumeratorX::InitPrintSettingsFromPrinter()")); + + NS_ENSURE_ARG_POINTER(aPrintSettings); + + // Set a default file name. + nsAutoString filename; + nsresult rv = aPrintSettings->GetToFileName(filename); + if (NS_FAILED(rv) || filename.IsEmpty()) { + const char* path = PR_GetEnv("PWD"); + if (!path) { + path = PR_GetEnv("HOME"); + } + + if (path) { + CopyUTF8toUTF16(MakeStringSpan(path), filename); + filename.AppendLiteral("/mozilla.pdf"); + } else { + filename.AssignLiteral("mozilla.pdf"); + } + + DO_PR_DEBUG_LOG(("Setting default filename to '%s'\n", NS_ConvertUTF16toUTF8(filename).get())); + aPrintSettings->SetToFileName(filename); + } + + aPrintSettings->SetIsInitializedFromPrinter(true); + + return NS_OK; +} + +//---------------------------------------------------------------------- +// nsDeviceContentSpecX + nsDeviceContextSpecX::nsDeviceContextSpecX() : mPrintSession(NULL), mPageFormat(kPMNoPageFormat), diff --git a/widget/cocoa/nsWidgetFactory.mm b/widget/cocoa/nsWidgetFactory.mm index 7d545832fb3a..57b8c1abd8db 100644 --- a/widget/cocoa/nsWidgetFactory.mm +++ b/widget/cocoa/nsWidgetFactory.mm @@ -67,6 +67,7 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsHTMLFormatConverter) NS_GENERIC_FACTORY_CONSTRUCTOR(nsClipboardHelper) NS_GENERIC_FACTORY_CONSTRUCTOR(nsDragService) NS_GENERIC_FACTORY_CONSTRUCTOR(nsDeviceContextSpecX) +NS_GENERIC_FACTORY_CONSTRUCTOR(nsPrinterEnumeratorX) NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrintSettingsServiceX, Init) NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrintDialogServiceX, Init) NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrintSession, Init) @@ -117,6 +118,7 @@ NS_DEFINE_NAMED_CID(NS_CLIPBOARDHELPER_CID); NS_DEFINE_NAMED_CID(NS_DRAGSERVICE_CID); NS_DEFINE_NAMED_CID(NS_SCREENMANAGER_CID); NS_DEFINE_NAMED_CID(NS_DEVICE_CONTEXT_SPEC_CID); +NS_DEFINE_NAMED_CID(NS_PRINTER_ENUMERATOR_CID); NS_DEFINE_NAMED_CID(NS_PRINTSESSION_CID); NS_DEFINE_NAMED_CID(NS_PRINTSETTINGSSERVICE_CID); NS_DEFINE_NAMED_CID(NS_PRINTDIALOGSERVICE_CID); @@ -148,6 +150,7 @@ static const mozilla::Module::CIDEntry kWidgetCIDs[] = { {&kNS_SCREENMANAGER_CID, false, NULL, ScreenManagerConstructor, mozilla::Module::MAIN_PROCESS_ONLY}, {&kNS_DEVICE_CONTEXT_SPEC_CID, false, NULL, nsDeviceContextSpecXConstructor}, + {&kNS_PRINTER_ENUMERATOR_CID, false, NULL, nsPrinterEnumeratorXConstructor}, {&kNS_PRINTSESSION_CID, false, NULL, nsPrintSessionConstructor}, {&kNS_PRINTSETTINGSSERVICE_CID, false, NULL, nsPrintSettingsServiceXConstructor}, {&kNS_PRINTDIALOGSERVICE_CID, false, NULL, nsPrintDialogServiceXConstructor}, @@ -178,6 +181,7 @@ static const mozilla::Module::ContractIDEntry kWidgetContracts[] = { {"@mozilla.org/gfx/screenmanager;1", &kNS_SCREENMANAGER_CID, mozilla::Module::MAIN_PROCESS_ONLY}, {"@mozilla.org/gfx/devicecontextspec;1", &kNS_DEVICE_CONTEXT_SPEC_CID}, + {"@mozilla.org/gfx/printerenumerator;1", &kNS_PRINTER_ENUMERATOR_CID}, {"@mozilla.org/gfx/printsession;1", &kNS_PRINTSESSION_CID}, {"@mozilla.org/gfx/printsettings-service;1", &kNS_PRINTSETTINGSSERVICE_CID}, {NS_PRINTDIALOGSERVICE_CONTRACTID, &kNS_PRINTDIALOGSERVICE_CID},