summaryrefslogtreecommitdiffstats
path: root/widget/gtk/nsPrintSettingsGTK.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'widget/gtk/nsPrintSettingsGTK.cpp')
-rw-r--r--widget/gtk/nsPrintSettingsGTK.cpp813
1 files changed, 813 insertions, 0 deletions
diff --git a/widget/gtk/nsPrintSettingsGTK.cpp b/widget/gtk/nsPrintSettingsGTK.cpp
new file mode 100644
index 000000000..a8fd60bd1
--- /dev/null
+++ b/widget/gtk/nsPrintSettingsGTK.cpp
@@ -0,0 +1,813 @@
+/* -*- 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>
+
+static
+gboolean ref_printer(GtkPrinter *aPrinter, gpointer aData)
+{
+ ((nsPrintSettingsGTK*) aData)->SetGtkPrinter(aPrinter);
+ return TRUE;
+}
+
+static
+gboolean printer_enumerator(GtkPrinter *aPrinter, gpointer aData)
+{
+ if (gtk_printer_is_default(aPrinter))
+ return ref_printer(aPrinter, aData);
+
+ return FALSE; // Keep 'em coming...
+}
+
+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),
+ mPrintSelectionOnly(false)
+{
+ // 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);
+}
+
+/** ---------------------------------------------------
+ */
+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),
+ mPrintSelectionOnly(false)
+{
+ *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);
+ mGTKPrinter = (GtkPrinter*) g_object_ref(rhs.mGTKPrinter);
+
+ mPrintSelectionOnly = rhs.mPrintSelectionOnly;
+
+ 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) {
+ const gchar* fmtGTK =
+ gtk_print_settings_get(mPrintSettings,
+ GTK_PRINT_SETTINGS_OUTPUT_FILE_FORMAT);
+ if (fmtGTK) {
+ if (nsDependentCString(fmtGTK).EqualsIgnoreCase("pdf")) {
+ format = nsIPrintSettings::kOutputFormatPDF;
+ } else {
+ format = nsIPrintSettings::kOutputFormatPS;
+ }
+ } else if (GTK_IS_PRINTER(mGTKPrinter)) {
+ // Prior to gtk 2.24, gtk_printer_accepts_pdf() and
+ // gtk_printer_accepts_ps() always returned true regardless of the
+ // printer's capability.
+ bool shouldTrustGTK =
+ (gtk_major_version > 2 ||
+ (gtk_major_version == 2 && gtk_minor_version >= 24));
+ bool acceptsPDF = shouldTrustGTK && gtk_printer_accepts_pdf(mGTKPrinter);
+
+ format = acceptsPDF ? nsIPrintSettings::kOutputFormatPDF
+ : nsIPrintSettings::kOutputFormatPS;
+ }
+ }
+
+ *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::GetPrintRange(int16_t *aPrintRange)
+{
+ NS_ENSURE_ARG_POINTER(aPrintRange);
+ if (mPrintSelectionOnly) {
+ *aPrintRange = kRangeSelection;
+ return NS_OK;
+ }
+
+ GtkPrintPages gtkRange = gtk_print_settings_get_print_pages(mPrintSettings);
+ if (gtkRange == GTK_PRINT_PAGES_RANGES)
+ *aPrintRange = kRangeSpecifiedPageRange;
+ else
+ *aPrintRange = kRangeAllPages;
+
+ return NS_OK;
+}
+NS_IMETHODIMP nsPrintSettingsGTK::SetPrintRange(int16_t aPrintRange)
+{
+ if (aPrintRange == kRangeSelection) {
+ mPrintSelectionOnly = true;
+ return NS_OK;
+ }
+
+ mPrintSelectionOnly = false;
+ if (aPrintRange == kRangeSpecifiedPageRange)
+ gtk_print_settings_set_print_pages(mPrintSettings, GTK_PRINT_PAGES_RANGES);
+ else
+ gtk_print_settings_set_print_pages(mPrintSettings, GTK_PRINT_PAGES_ALL);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPrintSettingsGTK::GetStartPageRange(int32_t *aStartPageRange)
+{
+ gint ctRanges;
+ GtkPageRange* lstRanges = gtk_print_settings_get_page_ranges(mPrintSettings, &ctRanges);
+
+ // Make sure we got a range.
+ if (ctRanges < 1) {
+ *aStartPageRange = 1;
+ } else {
+ // GTK supports multiple page ranges; gecko only supports 1. So find
+ // the lowest start page.
+ int32_t start(lstRanges[0].start);
+ for (gint ii = 1; ii < ctRanges; ii++) {
+ start = std::min(lstRanges[ii].start, start);
+ }
+ *aStartPageRange = start + 1;
+ }
+
+ g_free(lstRanges);
+ return NS_OK;
+}
+NS_IMETHODIMP
+nsPrintSettingsGTK::SetStartPageRange(int32_t aStartPageRange)
+{
+ int32_t endRange;
+ GetEndPageRange(&endRange);
+
+ GtkPageRange gtkRange;
+ gtkRange.start = aStartPageRange - 1;
+ gtkRange.end = endRange - 1;
+
+ gtk_print_settings_set_page_ranges(mPrintSettings, &gtkRange, 1);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPrintSettingsGTK::GetEndPageRange(int32_t *aEndPageRange)
+{
+ gint ctRanges;
+ GtkPageRange* lstRanges = gtk_print_settings_get_page_ranges(mPrintSettings, &ctRanges);
+
+ if (ctRanges < 1) {
+ *aEndPageRange = 1;
+ } else {
+ int32_t end(lstRanges[0].end);
+ for (gint ii = 1; ii < ctRanges; ii++) {
+ end = std::max(lstRanges[ii].end, end);
+ }
+ *aEndPageRange = end + 1;
+ }
+
+ g_free(lstRanges);
+ return NS_OK;
+}
+NS_IMETHODIMP
+nsPrintSettingsGTK::SetEndPageRange(int32_t aEndPageRange)
+{
+ int32_t startRange;
+ GetStartPageRange(&startRange);
+
+ GtkPageRange gtkRange;
+ gtkRange.start = startRange - 1;
+ gtkRange.end = aEndPageRange - 1;
+
+ gtk_print_settings_set_page_ranges(mPrintSettings, &gtkRange, 1);
+
+ 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(char16_t * *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 = ToNewUnicode(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
+ nsAutoString path;
+ rv = file->GetPath(path);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ *aToFileName = ToNewUnicode(path);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPrintSettingsGTK::SetToFileName(const char16_t * aToFileName)
+{
+ if (aToFileName[0] == 0) {
+ mToFileName.SetLength(0);
+ gtk_print_settings_set(mPrintSettings, GTK_PRINT_SETTINGS_OUTPUT_URI,
+ nullptr);
+ return NS_OK;
+ }
+
+ if (StringEndsWith(nsDependentString(aToFileName), NS_LITERAL_STRING(".ps"))) {
+ gtk_print_settings_set(mPrintSettings, GTK_PRINT_SETTINGS_OUTPUT_FILE_FORMAT, "ps");
+ } else {
+ gtk_print_settings_set(mPrintSettings, GTK_PRINT_SETTINGS_OUTPUT_FILE_FORMAT, "pdf");
+ }
+
+ nsCOMPtr<nsIFile> file;
+ nsresult rv = NS_NewLocalFile(nsDependentString(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(char16_t * *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
+ nsXPIDLString nullPrintName;
+ *aPrinter = ToNewUnicode(nullPrintName);
+ return NS_OK;
+ }
+ }
+ *aPrinter = UTF8ToNewUnicode(nsDependentCString(gtkPrintName));
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPrintSettingsGTK::SetPrinterName(const char16_t * aPrinter)
+{
+ NS_ConvertUTF16toUTF8 gtkPrinter(aPrinter);
+
+ if (StringBeginsWith(gtkPrinter, NS_LITERAL_CSTRING("CUPS/"))) {
+ // 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::GetPaperName(char16_t * *aPaperName)
+{
+ NS_ENSURE_ARG_POINTER(aPaperName);
+ const gchar* name =
+ gtk_paper_size_get_name(gtk_page_setup_get_paper_size(mPageSetup));
+ *aPaperName = ToNewUnicode(NS_ConvertUTF8toUTF16(name));
+ return NS_OK;
+}
+NS_IMETHODIMP
+nsPrintSettingsGTK::SetPaperName(const char16_t * aPaperName)
+{
+ NS_ConvertUTF16toUTF8 gtkPaperName(aPaperName);
+
+ // Convert these Gecko names to GTK names
+ 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);
+ *aWidth = NS_INCHES_TO_INT_TWIPS(gtk_paper_size_get_width(paperSize, GTK_UNIT_INCH));
+ *aHeight = NS_INCHES_TO_INT_TWIPS(gtk_paper_size_get_height(paperSize, GTK_UNIT_INCH));
+
+ 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::SetupSilentPrinting()
+{
+ // We have to get a printer here, rather than when the print settings are constructed.
+ // This is because when we request sync, GTK makes us wait in the *event loop* while waiting
+ // for the enumeration to finish. We must do this when event loop runs are expected.
+ gtk_enumerate_printers(printer_enumerator, this, nullptr, TRUE);
+
+ // XXX If no default printer set, get the first one.
+ if (!GTK_IS_PRINTER(mGTKPrinter))
+ gtk_enumerate_printers(ref_printer, this, nullptr, TRUE);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPrintSettingsGTK::GetPageRanges(nsTArray<int32_t> &aPages)
+{
+ gint ctRanges;
+ GtkPageRange* lstRanges = gtk_print_settings_get_page_ranges(mPrintSettings, &ctRanges);
+
+ aPages.Clear();
+
+ if (ctRanges > 1) {
+ 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)
+{
+ if (!gtk_print_settings_has_key(mPrintSettings, GTK_PRINT_SETTINGS_RESOLUTION))
+ return NS_ERROR_FAILURE;
+ *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)
+{
+ if (!gtk_print_settings_has_key(mPrintSettings, GTK_PRINT_SETTINGS_DUPLEX)) {
+ *aDuplex = GTK_PRINT_DUPLEX_SIMPLEX;
+ } else {
+ *aDuplex = gtk_print_settings_get_duplex(mPrintSettings);
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPrintSettingsGTK::SetDuplex(int32_t aDuplex)
+{
+ MOZ_ASSERT(aDuplex >= GTK_PRINT_DUPLEX_SIMPLEX &&
+ aDuplex <= GTK_PRINT_DUPLEX_VERTICAL,
+ "value is out of bounds for GtkPrintDuplex enum");
+ gtk_print_settings_set_duplex(mPrintSettings, static_cast<GtkPrintDuplex>(aDuplex));
+ return NS_OK;
+}
+