diff options
Diffstat (limited to 'widget/gtk/nsPrintSettingsGTK.cpp')
-rw-r--r-- | widget/gtk/nsPrintSettingsGTK.cpp | 681 |
1 files changed, 681 insertions, 0 deletions
diff --git a/widget/gtk/nsPrintSettingsGTK.cpp b/widget/gtk/nsPrintSettingsGTK.cpp new file mode 100644 index 0000000000..a101f44fcb --- /dev/null +++ b/widget/gtk/nsPrintSettingsGTK.cpp @@ -0,0 +1,681 @@ +/* -*- 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 "nsPrintSettingsGTK.h" +#include "nsIFile.h" +#include "nsNetUtil.h" +#include <stdlib.h> +#include <algorithm> + +// These constants are the the strings that GTK expects as key-value pairs for +// setting CUPS duplex modes. These are not universal to all CUPS systems, which +// is why they are local to this file. +static constexpr gchar kCupsDuplex[] = "cups-Duplex"; +static constexpr gchar kCupsDuplexNone[] = "None"; +static constexpr gchar kCupsDuplexNoTumble[] = "DuplexNoTumble"; +static constexpr gchar kCupsDuplexTumble[] = "DuplexTumble"; + +static GtkPaperSize* moz_gtk_paper_size_copy_to_new_custom( + GtkPaperSize* oldPaperSize) { + // We make a "custom-ified" copy of the paper size so it can be changed later. + return gtk_paper_size_new_custom( + gtk_paper_size_get_name(oldPaperSize), + gtk_paper_size_get_display_name(oldPaperSize), + gtk_paper_size_get_width(oldPaperSize, GTK_UNIT_INCH), + gtk_paper_size_get_height(oldPaperSize, GTK_UNIT_INCH), GTK_UNIT_INCH); +} + +NS_IMPL_ISUPPORTS_INHERITED(nsPrintSettingsGTK, nsPrintSettings, + nsPrintSettingsGTK) + +/** --------------------------------------------------- + */ +nsPrintSettingsGTK::nsPrintSettingsGTK() + : mPageSetup(nullptr), mPrintSettings(nullptr), mGTKPrinter(nullptr) { + // The aim here is to set up the objects enough that silent printing works + // well. These will be replaced anyway if the print dialog is used. + mPrintSettings = gtk_print_settings_new(); + GtkPageSetup* pageSetup = gtk_page_setup_new(); + SetGtkPageSetup(pageSetup); + g_object_unref(pageSetup); + + SetOutputFormat(nsIPrintSettings::kOutputFormatNative); +} + +already_AddRefed<nsIPrintSettings> CreatePlatformPrintSettings( + const mozilla::PrintSettingsInitializer& aSettings) { + RefPtr<nsPrintSettings> settings = new nsPrintSettingsGTK(); + settings->InitWithInitializer(aSettings); + settings->SetDefaultFileName(); + return settings.forget(); +} + +/** --------------------------------------------------- + */ +nsPrintSettingsGTK::~nsPrintSettingsGTK() { + if (mPageSetup) { + g_object_unref(mPageSetup); + mPageSetup = nullptr; + } + if (mPrintSettings) { + g_object_unref(mPrintSettings); + mPrintSettings = nullptr; + } + if (mGTKPrinter) { + g_object_unref(mGTKPrinter); + mGTKPrinter = nullptr; + } +} + +/** --------------------------------------------------- + */ +nsPrintSettingsGTK::nsPrintSettingsGTK(const nsPrintSettingsGTK& aPS) + : mPageSetup(nullptr), mPrintSettings(nullptr), mGTKPrinter(nullptr) { + *this = aPS; +} + +/** --------------------------------------------------- + */ +nsPrintSettingsGTK& nsPrintSettingsGTK::operator=( + const nsPrintSettingsGTK& rhs) { + if (this == &rhs) { + return *this; + } + + nsPrintSettings::operator=(rhs); + + if (mPageSetup) g_object_unref(mPageSetup); + mPageSetup = gtk_page_setup_copy(rhs.mPageSetup); + // NOTE: No need to re-initialize mUnwriteableMargin here (even + // though mPageSetup is changing). It'll be copied correctly by + // nsPrintSettings::operator=. + + if (mPrintSettings) g_object_unref(mPrintSettings); + mPrintSettings = gtk_print_settings_copy(rhs.mPrintSettings); + + if (mGTKPrinter) g_object_unref(mGTKPrinter); + + if (rhs.mGTKPrinter) { + g_object_ref(rhs.mGTKPrinter); + } + mGTKPrinter = rhs.mGTKPrinter; + + return *this; +} + +/** ------------------------------------------- + */ +nsresult nsPrintSettingsGTK::_Clone(nsIPrintSettings** _retval) { + NS_ENSURE_ARG_POINTER(_retval); + *_retval = nullptr; + + nsPrintSettingsGTK* newSettings = new nsPrintSettingsGTK(*this); + if (!newSettings) return NS_ERROR_FAILURE; + *_retval = newSettings; + NS_ADDREF(*_retval); + return NS_OK; +} + +/** ------------------------------------------- + */ +NS_IMETHODIMP +nsPrintSettingsGTK::_Assign(nsIPrintSettings* aPS) { + nsPrintSettingsGTK* printSettingsGTK = static_cast<nsPrintSettingsGTK*>(aPS); + if (!printSettingsGTK) return NS_ERROR_UNEXPECTED; + *this = *printSettingsGTK; + return NS_OK; +} + +/** --------------------------------------------------- + */ +void nsPrintSettingsGTK::SetGtkPageSetup(GtkPageSetup* aPageSetup) { + if (mPageSetup) g_object_unref(mPageSetup); + + mPageSetup = (GtkPageSetup*)g_object_ref(aPageSetup); + InitUnwriteableMargin(); + + // If the paper size is not custom, then we make a custom copy of the + // GtkPaperSize, so it can be mutable. If a GtkPaperSize wasn't made as + // custom, its properties are immutable. + GtkPaperSize* paperSize = gtk_page_setup_get_paper_size(aPageSetup); + if (!gtk_paper_size_is_custom(paperSize)) { + GtkPaperSize* customPaperSize = + moz_gtk_paper_size_copy_to_new_custom(paperSize); + gtk_page_setup_set_paper_size(mPageSetup, customPaperSize); + gtk_paper_size_free(customPaperSize); + } + SaveNewPageSize(); +} + +/** --------------------------------------------------- + */ +void nsPrintSettingsGTK::SetGtkPrintSettings(GtkPrintSettings* aPrintSettings) { + if (mPrintSettings) g_object_unref(mPrintSettings); + + mPrintSettings = (GtkPrintSettings*)g_object_ref(aPrintSettings); + + GtkPaperSize* paperSize = gtk_print_settings_get_paper_size(aPrintSettings); + if (paperSize) { + GtkPaperSize* customPaperSize = + moz_gtk_paper_size_copy_to_new_custom(paperSize); + gtk_paper_size_free(paperSize); + gtk_page_setup_set_paper_size(mPageSetup, customPaperSize); + gtk_paper_size_free(customPaperSize); + } else { + // paperSize was null, and so we add the paper size in the GtkPageSetup to + // the settings. + SaveNewPageSize(); + } +} + +/** --------------------------------------------------- + */ +void nsPrintSettingsGTK::SetGtkPrinter(GtkPrinter* aPrinter) { + if (mGTKPrinter) g_object_unref(mGTKPrinter); + + mGTKPrinter = (GtkPrinter*)g_object_ref(aPrinter); +} + +NS_IMETHODIMP nsPrintSettingsGTK::GetOutputFormat(int16_t* aOutputFormat) { + NS_ENSURE_ARG_POINTER(aOutputFormat); + + int16_t format; + nsresult rv = nsPrintSettings::GetOutputFormat(&format); + if (NS_FAILED(rv)) { + return rv; + } + + if (format == nsIPrintSettings::kOutputFormatNative && + GTK_IS_PRINTER(mGTKPrinter)) { + format = nsIPrintSettings::kOutputFormatPDF; + } + + *aOutputFormat = format; + return NS_OK; +} + +/** + * Reimplementation of nsPrintSettings functions so that we get the values + * from the GTK objects rather than our own variables. + */ + +NS_IMETHODIMP +nsPrintSettingsGTK::SetPageRanges(const nsTArray<int32_t>& aRanges) { + if (aRanges.Length() % 2 != 0) { + return NS_ERROR_FAILURE; + } + + gtk_print_settings_set_print_pages( + mPrintSettings, + aRanges.IsEmpty() ? GTK_PRINT_PAGES_ALL : GTK_PRINT_PAGES_RANGES); + + nsTArray<GtkPageRange> ranges; + ranges.SetCapacity(aRanges.Length() / 2); + for (size_t i = 0; i < aRanges.Length(); i += 2) { + GtkPageRange* gtkRange = ranges.AppendElement(); + gtkRange->start = aRanges[i] - 1; + gtkRange->end = aRanges[i + 1] - 1; + } + + gtk_print_settings_set_page_ranges(mPrintSettings, ranges.Elements(), + ranges.Length()); + return NS_OK; +} + +NS_IMETHODIMP +nsPrintSettingsGTK::GetPrintReversed(bool* aPrintReversed) { + *aPrintReversed = gtk_print_settings_get_reverse(mPrintSettings); + return NS_OK; +} +NS_IMETHODIMP +nsPrintSettingsGTK::SetPrintReversed(bool aPrintReversed) { + gtk_print_settings_set_reverse(mPrintSettings, aPrintReversed); + return NS_OK; +} + +NS_IMETHODIMP +nsPrintSettingsGTK::GetPrintInColor(bool* aPrintInColor) { + *aPrintInColor = gtk_print_settings_get_use_color(mPrintSettings); + return NS_OK; +} +NS_IMETHODIMP +nsPrintSettingsGTK::SetPrintInColor(bool aPrintInColor) { + gtk_print_settings_set_use_color(mPrintSettings, aPrintInColor); + return NS_OK; +} + +NS_IMETHODIMP +nsPrintSettingsGTK::GetOrientation(int32_t* aOrientation) { + NS_ENSURE_ARG_POINTER(aOrientation); + + GtkPageOrientation gtkOrient = gtk_page_setup_get_orientation(mPageSetup); + switch (gtkOrient) { + case GTK_PAGE_ORIENTATION_LANDSCAPE: + case GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE: + *aOrientation = kLandscapeOrientation; + break; + + case GTK_PAGE_ORIENTATION_PORTRAIT: + case GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT: + default: + *aOrientation = kPortraitOrientation; + } + return NS_OK; +} +NS_IMETHODIMP +nsPrintSettingsGTK::SetOrientation(int32_t aOrientation) { + GtkPageOrientation gtkOrient; + if (aOrientation == kLandscapeOrientation) + gtkOrient = GTK_PAGE_ORIENTATION_LANDSCAPE; + else + gtkOrient = GTK_PAGE_ORIENTATION_PORTRAIT; + + gtk_print_settings_set_orientation(mPrintSettings, gtkOrient); + gtk_page_setup_set_orientation(mPageSetup, gtkOrient); + return NS_OK; +} + +NS_IMETHODIMP +nsPrintSettingsGTK::GetToFileName(nsAString& aToFileName) { + // Get the gtk output filename + const char* gtk_output_uri = + gtk_print_settings_get(mPrintSettings, GTK_PRINT_SETTINGS_OUTPUT_URI); + if (!gtk_output_uri) { + aToFileName = mToFileName; + return NS_OK; + } + + // Convert to an nsIFile + nsCOMPtr<nsIFile> file; + nsresult rv = NS_GetFileFromURLSpec(nsDependentCString(gtk_output_uri), + getter_AddRefs(file)); + if (NS_FAILED(rv)) return rv; + + // Extract the path + return file->GetPath(aToFileName); +} + +NS_IMETHODIMP +nsPrintSettingsGTK::SetToFileName(const nsAString& aToFileName) { + if (aToFileName.IsEmpty()) { + mToFileName.SetLength(0); + gtk_print_settings_set(mPrintSettings, GTK_PRINT_SETTINGS_OUTPUT_URI, + nullptr); + return NS_OK; + } + + gtk_print_settings_set(mPrintSettings, GTK_PRINT_SETTINGS_OUTPUT_FILE_FORMAT, + "pdf"); + + nsCOMPtr<nsIFile> file; + nsresult rv = NS_NewLocalFile(aToFileName, true, getter_AddRefs(file)); + NS_ENSURE_SUCCESS(rv, rv); + + // Convert the nsIFile to a URL + nsAutoCString url; + rv = NS_GetURLSpecFromFile(file, url); + NS_ENSURE_SUCCESS(rv, rv); + + gtk_print_settings_set(mPrintSettings, GTK_PRINT_SETTINGS_OUTPUT_URI, + url.get()); + mToFileName = aToFileName; + + return NS_OK; +} + +NS_IMETHODIMP +nsPrintSettingsGTK::GetPrinterName(nsAString& aPrinter) { + const char* gtkPrintName = gtk_print_settings_get_printer(mPrintSettings); + if (!gtkPrintName) { + if (GTK_IS_PRINTER(mGTKPrinter)) { + gtkPrintName = gtk_printer_get_name(mGTKPrinter); + } else { + // This mimics what nsPrintSettingsImpl does when we try to Get before we + // Set + aPrinter.Truncate(); + return NS_OK; + } + } + CopyUTF8toUTF16(mozilla::MakeStringSpan(gtkPrintName), aPrinter); + return NS_OK; +} + +NS_IMETHODIMP +nsPrintSettingsGTK::SetPrinterName(const nsAString& aPrinter) { + NS_ConvertUTF16toUTF8 gtkPrinter(aPrinter); + + if (StringBeginsWith(gtkPrinter, "CUPS/"_ns)) { + // Strip off "CUPS/"; GTK might recognize the rest + gtkPrinter.Cut(0, strlen("CUPS/")); + } + + // Give mPrintSettings the passed-in printer name if either... + // - it has no printer name stored yet + // - it has an existing printer name that's different from + // the name passed to this function. + const char* oldPrinterName = gtk_print_settings_get_printer(mPrintSettings); + if (!oldPrinterName || !gtkPrinter.Equals(oldPrinterName)) { + mIsInitedFromPrinter = false; + mIsInitedFromPrefs = false; + gtk_print_settings_set_printer(mPrintSettings, gtkPrinter.get()); + } + + return NS_OK; +} + +NS_IMETHODIMP +nsPrintSettingsGTK::GetNumCopies(int32_t* aNumCopies) { + NS_ENSURE_ARG_POINTER(aNumCopies); + *aNumCopies = gtk_print_settings_get_n_copies(mPrintSettings); + return NS_OK; +} +NS_IMETHODIMP +nsPrintSettingsGTK::SetNumCopies(int32_t aNumCopies) { + gtk_print_settings_set_n_copies(mPrintSettings, aNumCopies); + return NS_OK; +} + +NS_IMETHODIMP +nsPrintSettingsGTK::GetScaling(double* aScaling) { + *aScaling = gtk_print_settings_get_scale(mPrintSettings) / 100.0; + return NS_OK; +} + +NS_IMETHODIMP +nsPrintSettingsGTK::SetScaling(double aScaling) { + gtk_print_settings_set_scale(mPrintSettings, aScaling * 100.0); + return NS_OK; +} + +NS_IMETHODIMP +nsPrintSettingsGTK::GetPaperId(nsAString& aPaperId) { + const gchar* name = + gtk_paper_size_get_name(gtk_page_setup_get_paper_size(mPageSetup)); + CopyUTF8toUTF16(mozilla::MakeStringSpan(name), aPaperId); + return NS_OK; +} +NS_IMETHODIMP +nsPrintSettingsGTK::SetPaperId(const nsAString& aPaperId) { + NS_ConvertUTF16toUTF8 gtkPaperName(aPaperId); + + // Convert these Gecko names to GTK names + // XXX (jfkthame): is this still relevant? + if (gtkPaperName.EqualsIgnoreCase("letter")) + gtkPaperName.AssignLiteral(GTK_PAPER_NAME_LETTER); + else if (gtkPaperName.EqualsIgnoreCase("legal")) + gtkPaperName.AssignLiteral(GTK_PAPER_NAME_LEGAL); + + GtkPaperSize* oldPaperSize = gtk_page_setup_get_paper_size(mPageSetup); + gdouble width = gtk_paper_size_get_width(oldPaperSize, GTK_UNIT_INCH); + gdouble height = gtk_paper_size_get_height(oldPaperSize, GTK_UNIT_INCH); + + // Try to get the display name from the name so our paper size fits in the + // Page Setup dialog. + GtkPaperSize* paperSize = gtk_paper_size_new(gtkPaperName.get()); + GtkPaperSize* customPaperSize = gtk_paper_size_new_custom( + gtkPaperName.get(), gtk_paper_size_get_display_name(paperSize), width, + height, GTK_UNIT_INCH); + gtk_paper_size_free(paperSize); + + gtk_page_setup_set_paper_size(mPageSetup, customPaperSize); + gtk_paper_size_free(customPaperSize); + SaveNewPageSize(); + return NS_OK; +} + +GtkUnit nsPrintSettingsGTK::GetGTKUnit(int16_t aGeckoUnit) { + if (aGeckoUnit == kPaperSizeMillimeters) + return GTK_UNIT_MM; + else + return GTK_UNIT_INCH; +} + +void nsPrintSettingsGTK::SaveNewPageSize() { + gtk_print_settings_set_paper_size(mPrintSettings, + gtk_page_setup_get_paper_size(mPageSetup)); +} + +void nsPrintSettingsGTK::InitUnwriteableMargin() { + mUnwriteableMargin.SizeTo( + NS_INCHES_TO_INT_TWIPS( + gtk_page_setup_get_top_margin(mPageSetup, GTK_UNIT_INCH)), + NS_INCHES_TO_INT_TWIPS( + gtk_page_setup_get_right_margin(mPageSetup, GTK_UNIT_INCH)), + NS_INCHES_TO_INT_TWIPS( + gtk_page_setup_get_bottom_margin(mPageSetup, GTK_UNIT_INCH)), + NS_INCHES_TO_INT_TWIPS( + gtk_page_setup_get_left_margin(mPageSetup, GTK_UNIT_INCH))); +} + +/** + * NOTE: Need a custom set of SetUnwriteableMargin functions, because + * whenever we change mUnwriteableMargin, we must pass the change + * down to our GTKPageSetup object. (This is needed in order for us + * to give the correct default values in nsPrintDialogGTK.) + * + * It's important that the following functions pass + * mUnwriteableMargin values rather than aUnwriteableMargin values + * to gtk_page_setup_set_[blank]_margin, because the two may not be + * the same. (Specifically, negative values of aUnwriteableMargin + * are ignored by the nsPrintSettings::SetUnwriteableMargin functions.) + */ +NS_IMETHODIMP +nsPrintSettingsGTK::SetUnwriteableMarginInTwips( + nsIntMargin& aUnwriteableMargin) { + nsPrintSettings::SetUnwriteableMarginInTwips(aUnwriteableMargin); + gtk_page_setup_set_top_margin( + mPageSetup, NS_TWIPS_TO_INCHES(mUnwriteableMargin.top), GTK_UNIT_INCH); + gtk_page_setup_set_left_margin( + mPageSetup, NS_TWIPS_TO_INCHES(mUnwriteableMargin.left), GTK_UNIT_INCH); + gtk_page_setup_set_bottom_margin( + mPageSetup, NS_TWIPS_TO_INCHES(mUnwriteableMargin.bottom), GTK_UNIT_INCH); + gtk_page_setup_set_right_margin( + mPageSetup, NS_TWIPS_TO_INCHES(mUnwriteableMargin.right), GTK_UNIT_INCH); + return NS_OK; +} + +NS_IMETHODIMP +nsPrintSettingsGTK::SetUnwriteableMarginTop(double aUnwriteableMarginTop) { + nsPrintSettings::SetUnwriteableMarginTop(aUnwriteableMarginTop); + gtk_page_setup_set_top_margin( + mPageSetup, NS_TWIPS_TO_INCHES(mUnwriteableMargin.top), GTK_UNIT_INCH); + return NS_OK; +} + +NS_IMETHODIMP +nsPrintSettingsGTK::SetUnwriteableMarginLeft(double aUnwriteableMarginLeft) { + nsPrintSettings::SetUnwriteableMarginLeft(aUnwriteableMarginLeft); + gtk_page_setup_set_left_margin( + mPageSetup, NS_TWIPS_TO_INCHES(mUnwriteableMargin.left), GTK_UNIT_INCH); + return NS_OK; +} + +NS_IMETHODIMP +nsPrintSettingsGTK::SetUnwriteableMarginBottom( + double aUnwriteableMarginBottom) { + nsPrintSettings::SetUnwriteableMarginBottom(aUnwriteableMarginBottom); + gtk_page_setup_set_bottom_margin( + mPageSetup, NS_TWIPS_TO_INCHES(mUnwriteableMargin.bottom), GTK_UNIT_INCH); + return NS_OK; +} + +NS_IMETHODIMP +nsPrintSettingsGTK::SetUnwriteableMarginRight(double aUnwriteableMarginRight) { + nsPrintSettings::SetUnwriteableMarginRight(aUnwriteableMarginRight); + gtk_page_setup_set_right_margin( + mPageSetup, NS_TWIPS_TO_INCHES(mUnwriteableMargin.right), GTK_UNIT_INCH); + return NS_OK; +} + +NS_IMETHODIMP +nsPrintSettingsGTK::GetPaperWidth(double* aPaperWidth) { + NS_ENSURE_ARG_POINTER(aPaperWidth); + GtkPaperSize* paperSize = gtk_page_setup_get_paper_size(mPageSetup); + *aPaperWidth = + gtk_paper_size_get_width(paperSize, GetGTKUnit(mPaperSizeUnit)); + return NS_OK; +} +NS_IMETHODIMP +nsPrintSettingsGTK::SetPaperWidth(double aPaperWidth) { + GtkPaperSize* paperSize = gtk_page_setup_get_paper_size(mPageSetup); + gtk_paper_size_set_size( + paperSize, aPaperWidth, + gtk_paper_size_get_height(paperSize, GetGTKUnit(mPaperSizeUnit)), + GetGTKUnit(mPaperSizeUnit)); + SaveNewPageSize(); + return NS_OK; +} + +NS_IMETHODIMP +nsPrintSettingsGTK::GetPaperHeight(double* aPaperHeight) { + NS_ENSURE_ARG_POINTER(aPaperHeight); + GtkPaperSize* paperSize = gtk_page_setup_get_paper_size(mPageSetup); + *aPaperHeight = + gtk_paper_size_get_height(paperSize, GetGTKUnit(mPaperSizeUnit)); + return NS_OK; +} +NS_IMETHODIMP +nsPrintSettingsGTK::SetPaperHeight(double aPaperHeight) { + GtkPaperSize* paperSize = gtk_page_setup_get_paper_size(mPageSetup); + gtk_paper_size_set_size( + paperSize, + gtk_paper_size_get_width(paperSize, GetGTKUnit(mPaperSizeUnit)), + aPaperHeight, GetGTKUnit(mPaperSizeUnit)); + SaveNewPageSize(); + return NS_OK; +} + +NS_IMETHODIMP +nsPrintSettingsGTK::SetPaperSizeUnit(int16_t aPaperSizeUnit) { + // Convert units internally. e.g. they might have set the values while we're + // still in mm but they change to inch just afterwards, expecting that their + // sizes are in inches. + GtkPaperSize* paperSize = gtk_page_setup_get_paper_size(mPageSetup); + gtk_paper_size_set_size( + paperSize, + gtk_paper_size_get_width(paperSize, GetGTKUnit(mPaperSizeUnit)), + gtk_paper_size_get_height(paperSize, GetGTKUnit(mPaperSizeUnit)), + GetGTKUnit(aPaperSizeUnit)); + SaveNewPageSize(); + + mPaperSizeUnit = aPaperSizeUnit; + return NS_OK; +} + +NS_IMETHODIMP +nsPrintSettingsGTK::GetEffectivePageSize(double* aWidth, double* aHeight) { + GtkPaperSize* paperSize = gtk_page_setup_get_paper_size(mPageSetup); + if (mPaperSizeUnit == kPaperSizeInches) { + *aWidth = + NS_INCHES_TO_TWIPS(gtk_paper_size_get_width(paperSize, GTK_UNIT_INCH)); + *aHeight = + NS_INCHES_TO_TWIPS(gtk_paper_size_get_height(paperSize, GTK_UNIT_INCH)); + } else { + MOZ_ASSERT(mPaperSizeUnit == kPaperSizeMillimeters, + "unexpected paper size unit"); + *aWidth = NS_MILLIMETERS_TO_TWIPS( + gtk_paper_size_get_width(paperSize, GTK_UNIT_MM)); + *aHeight = NS_MILLIMETERS_TO_TWIPS( + gtk_paper_size_get_height(paperSize, GTK_UNIT_MM)); + } + GtkPageOrientation gtkOrient = gtk_page_setup_get_orientation(mPageSetup); + + if (gtkOrient == GTK_PAGE_ORIENTATION_LANDSCAPE || + gtkOrient == GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE) { + double temp = *aWidth; + *aWidth = *aHeight; + *aHeight = temp; + } + return NS_OK; +} + +NS_IMETHODIMP +nsPrintSettingsGTK::GetPageRanges(nsTArray<int32_t>& aPages) { + GtkPrintPages gtkRange = gtk_print_settings_get_print_pages(mPrintSettings); + if (gtkRange != GTK_PRINT_PAGES_RANGES) { + aPages.Clear(); + return NS_OK; + } + + gint ctRanges; + GtkPageRange* lstRanges = + gtk_print_settings_get_page_ranges(mPrintSettings, &ctRanges); + + aPages.Clear(); + + for (gint i = 0; i < ctRanges; i++) { + aPages.AppendElement(lstRanges[i].start + 1); + aPages.AppendElement(lstRanges[i].end + 1); + } + + g_free(lstRanges); + return NS_OK; +} + +NS_IMETHODIMP +nsPrintSettingsGTK::GetResolution(int32_t* aResolution) { + *aResolution = gtk_print_settings_get_resolution(mPrintSettings); + return NS_OK; +} + +NS_IMETHODIMP +nsPrintSettingsGTK::SetResolution(int32_t aResolution) { + gtk_print_settings_set_resolution(mPrintSettings, aResolution); + return NS_OK; +} + +NS_IMETHODIMP +nsPrintSettingsGTK::GetDuplex(int32_t* aDuplex) { + NS_ENSURE_ARG_POINTER(aDuplex); + + // Default to DuplexNone. + *aDuplex = kDuplexNone; + + if (!gtk_print_settings_has_key(mPrintSettings, GTK_PRINT_SETTINGS_DUPLEX)) { + return NS_OK; + } + + switch (gtk_print_settings_get_duplex(mPrintSettings)) { + case GTK_PRINT_DUPLEX_SIMPLEX: + *aDuplex = kDuplexNone; + break; + case GTK_PRINT_DUPLEX_HORIZONTAL: + *aDuplex = kDuplexFlipOnLongEdge; + break; + case GTK_PRINT_DUPLEX_VERTICAL: + *aDuplex = kDuplexFlipOnShortEdge; + break; + } + + return NS_OK; +} + +NS_IMETHODIMP +nsPrintSettingsGTK::SetDuplex(int32_t aDuplex) { + uint32_t duplex = static_cast<uint32_t>(aDuplex); + MOZ_ASSERT(duplex <= kDuplexFlipOnShortEdge, + "value is out of bounds for duplex enum"); + + // We want to set the GTK CUPS Duplex setting in addition to calling + // gtk_print_settings_set_duplex(). Some systems may look for one, or the + // other, so it is best to set them both consistently. + switch (duplex) { + case kDuplexNone: + gtk_print_settings_set(mPrintSettings, kCupsDuplex, kCupsDuplexNone); + gtk_print_settings_set_duplex(mPrintSettings, GTK_PRINT_DUPLEX_SIMPLEX); + break; + case kDuplexFlipOnLongEdge: + gtk_print_settings_set(mPrintSettings, kCupsDuplex, kCupsDuplexNoTumble); + gtk_print_settings_set_duplex(mPrintSettings, + GTK_PRINT_DUPLEX_HORIZONTAL); + break; + case kDuplexFlipOnShortEdge: + gtk_print_settings_set(mPrintSettings, kCupsDuplex, kCupsDuplexTumble); + gtk_print_settings_set_duplex(mPrintSettings, GTK_PRINT_DUPLEX_VERTICAL); + break; + } + + return NS_OK; +} |