diff options
Diffstat (limited to 'widget/gtk/nsPrintSettingsGTK.cpp')
-rw-r--r-- | widget/gtk/nsPrintSettingsGTK.cpp | 813 |
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, >kRange, 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, >kRange, 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; +} + |