michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "nsPrintSettingsGTK.h" michael@0: #include "nsIFile.h" michael@0: #include "nsNetUtil.h" michael@0: #include michael@0: #include michael@0: michael@0: static michael@0: gboolean ref_printer(GtkPrinter *aPrinter, gpointer aData) michael@0: { michael@0: ((nsPrintSettingsGTK*) aData)->SetGtkPrinter(aPrinter); michael@0: return TRUE; michael@0: } michael@0: michael@0: static michael@0: gboolean printer_enumerator(GtkPrinter *aPrinter, gpointer aData) michael@0: { michael@0: if (gtk_printer_is_default(aPrinter)) michael@0: return ref_printer(aPrinter, aData); michael@0: michael@0: return FALSE; // Keep 'em coming... michael@0: } michael@0: michael@0: static michael@0: GtkPaperSize* moz_gtk_paper_size_copy_to_new_custom(GtkPaperSize* oldPaperSize) michael@0: { michael@0: // We make a "custom-ified" copy of the paper size so it can be changed later. michael@0: return gtk_paper_size_new_custom(gtk_paper_size_get_name(oldPaperSize), michael@0: gtk_paper_size_get_display_name(oldPaperSize), michael@0: gtk_paper_size_get_width(oldPaperSize, GTK_UNIT_INCH), michael@0: gtk_paper_size_get_height(oldPaperSize, GTK_UNIT_INCH), michael@0: GTK_UNIT_INCH); michael@0: } michael@0: michael@0: NS_IMPL_ISUPPORTS_INHERITED(nsPrintSettingsGTK, michael@0: nsPrintSettings, michael@0: nsPrintSettingsGTK) michael@0: michael@0: /** --------------------------------------------------- michael@0: */ michael@0: nsPrintSettingsGTK::nsPrintSettingsGTK() : michael@0: mPageSetup(nullptr), michael@0: mPrintSettings(nullptr), michael@0: mGTKPrinter(nullptr), michael@0: mPrintSelectionOnly(false) michael@0: { michael@0: // The aim here is to set up the objects enough that silent printing works well. michael@0: // These will be replaced anyway if the print dialog is used. michael@0: mPrintSettings = gtk_print_settings_new(); michael@0: mPageSetup = gtk_page_setup_new(); michael@0: InitUnwriteableMargin(); michael@0: michael@0: SetOutputFormat(nsIPrintSettings::kOutputFormatNative); michael@0: michael@0: GtkPaperSize* defaultPaperSize = gtk_paper_size_new(nullptr); michael@0: mPaperSize = moz_gtk_paper_size_copy_to_new_custom(defaultPaperSize); michael@0: gtk_paper_size_free(defaultPaperSize); michael@0: SaveNewPageSize(); michael@0: } michael@0: michael@0: /** --------------------------------------------------- michael@0: */ michael@0: nsPrintSettingsGTK::~nsPrintSettingsGTK() michael@0: { michael@0: if (mPageSetup) { michael@0: g_object_unref(mPageSetup); michael@0: mPageSetup = nullptr; michael@0: } michael@0: if (mPrintSettings) { michael@0: g_object_unref(mPrintSettings); michael@0: mPrintSettings = nullptr; michael@0: } michael@0: if (mGTKPrinter) { michael@0: g_object_unref(mGTKPrinter); michael@0: mGTKPrinter = nullptr; michael@0: } michael@0: gtk_paper_size_free(mPaperSize); michael@0: } michael@0: michael@0: /** --------------------------------------------------- michael@0: */ michael@0: nsPrintSettingsGTK::nsPrintSettingsGTK(const nsPrintSettingsGTK& aPS) : michael@0: mPageSetup(nullptr), michael@0: mPrintSettings(nullptr), michael@0: mGTKPrinter(nullptr), michael@0: mPrintSelectionOnly(false) michael@0: { michael@0: *this = aPS; michael@0: } michael@0: michael@0: /** --------------------------------------------------- michael@0: */ michael@0: nsPrintSettingsGTK& nsPrintSettingsGTK::operator=(const nsPrintSettingsGTK& rhs) michael@0: { michael@0: if (this == &rhs) { michael@0: return *this; michael@0: } michael@0: michael@0: nsPrintSettings::operator=(rhs); michael@0: michael@0: if (mPageSetup) michael@0: g_object_unref(mPageSetup); michael@0: mPageSetup = gtk_page_setup_copy(rhs.mPageSetup); michael@0: // NOTE: No need to re-initialize mUnwriteableMargin here (even michael@0: // though mPageSetup is changing). It'll be copied correctly by michael@0: // nsPrintSettings::operator=. michael@0: michael@0: if (mPrintSettings) michael@0: g_object_unref(mPrintSettings); michael@0: mPrintSettings = gtk_print_settings_copy(rhs.mPrintSettings); michael@0: michael@0: if (mGTKPrinter) michael@0: g_object_unref(mGTKPrinter); michael@0: mGTKPrinter = (GtkPrinter*) g_object_ref(rhs.mGTKPrinter); michael@0: michael@0: mPrintSelectionOnly = rhs.mPrintSelectionOnly; michael@0: michael@0: return *this; michael@0: } michael@0: michael@0: /** ------------------------------------------- michael@0: */ michael@0: nsresult nsPrintSettingsGTK::_Clone(nsIPrintSettings **_retval) michael@0: { michael@0: NS_ENSURE_ARG_POINTER(_retval); michael@0: *_retval = nullptr; michael@0: michael@0: nsPrintSettingsGTK *newSettings = new nsPrintSettingsGTK(*this); michael@0: if (!newSettings) michael@0: return NS_ERROR_FAILURE; michael@0: *_retval = newSettings; michael@0: NS_ADDREF(*_retval); michael@0: return NS_OK; michael@0: } michael@0: michael@0: michael@0: /** ------------------------------------------- michael@0: */ michael@0: NS_IMETHODIMP michael@0: nsPrintSettingsGTK::_Assign(nsIPrintSettings *aPS) michael@0: { michael@0: nsPrintSettingsGTK *printSettingsGTK = static_cast(aPS); michael@0: if (!printSettingsGTK) michael@0: return NS_ERROR_UNEXPECTED; michael@0: *this = *printSettingsGTK; michael@0: return NS_OK; michael@0: } michael@0: michael@0: /** --------------------------------------------------- michael@0: */ michael@0: void michael@0: nsPrintSettingsGTK::SetGtkPageSetup(GtkPageSetup *aPageSetup) michael@0: { michael@0: if (mPageSetup) michael@0: g_object_unref(mPageSetup); michael@0: michael@0: mPageSetup = (GtkPageSetup*) g_object_ref(aPageSetup); michael@0: InitUnwriteableMargin(); michael@0: michael@0: // We make a custom copy of the GtkPaperSize so it can be mutable. If a michael@0: // GtkPaperSize wasn't made as custom, its properties are immutable. michael@0: GtkPaperSize* newPaperSize = gtk_page_setup_get_paper_size(aPageSetup); michael@0: if (newPaperSize) { // Yes, this can be null michael@0: gtk_paper_size_free(mPaperSize); michael@0: mPaperSize = moz_gtk_paper_size_copy_to_new_custom(newPaperSize); michael@0: } michael@0: // If newPaperSize was not null, we must update our twin too (GtkPrintSettings). michael@0: // If newPaperSize was null, we must set this object to use mPaperSize. michael@0: SaveNewPageSize(); michael@0: } michael@0: michael@0: /** --------------------------------------------------- michael@0: */ michael@0: void michael@0: nsPrintSettingsGTK::SetGtkPrintSettings(GtkPrintSettings *aPrintSettings) michael@0: { michael@0: if (mPrintSettings) michael@0: g_object_unref(mPrintSettings); michael@0: michael@0: mPrintSettings = (GtkPrintSettings*) g_object_ref(aPrintSettings); michael@0: michael@0: GtkPaperSize* newPaperSize = gtk_print_settings_get_paper_size(aPrintSettings); michael@0: if (newPaperSize) { michael@0: gtk_paper_size_free(mPaperSize); michael@0: mPaperSize = moz_gtk_paper_size_copy_to_new_custom(newPaperSize); michael@0: } michael@0: SaveNewPageSize(); michael@0: } michael@0: michael@0: /** --------------------------------------------------- michael@0: */ michael@0: void michael@0: nsPrintSettingsGTK::SetGtkPrinter(GtkPrinter *aPrinter) michael@0: { michael@0: if (mGTKPrinter) michael@0: g_object_unref(mGTKPrinter); michael@0: michael@0: mGTKPrinter = (GtkPrinter*) g_object_ref(aPrinter); michael@0: } michael@0: michael@0: /** michael@0: * Reimplementation of nsPrintSettings functions so that we get the values michael@0: * from the GTK objects rather than our own variables. michael@0: */ michael@0: michael@0: /* attribute long printRange; */ michael@0: NS_IMETHODIMP nsPrintSettingsGTK::GetPrintRange(int16_t *aPrintRange) michael@0: { michael@0: NS_ENSURE_ARG_POINTER(aPrintRange); michael@0: if (mPrintSelectionOnly) { michael@0: *aPrintRange = kRangeSelection; michael@0: return NS_OK; michael@0: } michael@0: michael@0: GtkPrintPages gtkRange = gtk_print_settings_get_print_pages(mPrintSettings); michael@0: if (gtkRange == GTK_PRINT_PAGES_RANGES) michael@0: *aPrintRange = kRangeSpecifiedPageRange; michael@0: else michael@0: *aPrintRange = kRangeAllPages; michael@0: michael@0: return NS_OK; michael@0: } michael@0: NS_IMETHODIMP nsPrintSettingsGTK::SetPrintRange(int16_t aPrintRange) michael@0: { michael@0: if (aPrintRange == kRangeSelection) { michael@0: mPrintSelectionOnly = true; michael@0: return NS_OK; michael@0: } michael@0: michael@0: mPrintSelectionOnly = false; michael@0: if (aPrintRange == kRangeSpecifiedPageRange) michael@0: gtk_print_settings_set_print_pages(mPrintSettings, GTK_PRINT_PAGES_RANGES); michael@0: else michael@0: gtk_print_settings_set_print_pages(mPrintSettings, GTK_PRINT_PAGES_ALL); michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* attribute long startPageRange; */ michael@0: NS_IMETHODIMP michael@0: nsPrintSettingsGTK::GetStartPageRange(int32_t *aStartPageRange) michael@0: { michael@0: gint ctRanges; michael@0: GtkPageRange* lstRanges = gtk_print_settings_get_page_ranges(mPrintSettings, &ctRanges); michael@0: michael@0: // Make sure we got a range. michael@0: if (ctRanges < 1) { michael@0: *aStartPageRange = 1; michael@0: } else { michael@0: // GTK supports multiple page ranges; gecko only supports 1. So find michael@0: // the lowest start page. michael@0: int32_t start(lstRanges[0].start); michael@0: for (gint ii = 1; ii < ctRanges; ii++) { michael@0: start = std::min(lstRanges[ii].start, start); michael@0: } michael@0: *aStartPageRange = start + 1; michael@0: } michael@0: michael@0: g_free(lstRanges); michael@0: return NS_OK; michael@0: } michael@0: NS_IMETHODIMP michael@0: nsPrintSettingsGTK::SetStartPageRange(int32_t aStartPageRange) michael@0: { michael@0: int32_t endRange; michael@0: GetEndPageRange(&endRange); michael@0: michael@0: GtkPageRange gtkRange; michael@0: gtkRange.start = aStartPageRange - 1; michael@0: gtkRange.end = endRange - 1; michael@0: michael@0: gtk_print_settings_set_page_ranges(mPrintSettings, >kRange, 1); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* attribute long endPageRange; */ michael@0: NS_IMETHODIMP michael@0: nsPrintSettingsGTK::GetEndPageRange(int32_t *aEndPageRange) michael@0: { michael@0: gint ctRanges; michael@0: GtkPageRange* lstRanges = gtk_print_settings_get_page_ranges(mPrintSettings, &ctRanges); michael@0: michael@0: if (ctRanges < 1) { michael@0: *aEndPageRange = 1; michael@0: } else { michael@0: int32_t end(lstRanges[0].end); michael@0: for (gint ii = 1; ii < ctRanges; ii++) { michael@0: end = std::max(lstRanges[ii].end, end); michael@0: } michael@0: *aEndPageRange = end + 1; michael@0: } michael@0: michael@0: g_free(lstRanges); michael@0: return NS_OK; michael@0: } michael@0: NS_IMETHODIMP michael@0: nsPrintSettingsGTK::SetEndPageRange(int32_t aEndPageRange) michael@0: { michael@0: int32_t startRange; michael@0: GetStartPageRange(&startRange); michael@0: michael@0: GtkPageRange gtkRange; michael@0: gtkRange.start = startRange - 1; michael@0: gtkRange.end = aEndPageRange - 1; michael@0: michael@0: gtk_print_settings_set_page_ranges(mPrintSettings, >kRange, 1); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* attribute boolean printReversed; */ michael@0: NS_IMETHODIMP michael@0: nsPrintSettingsGTK::GetPrintReversed(bool *aPrintReversed) michael@0: { michael@0: *aPrintReversed = gtk_print_settings_get_reverse(mPrintSettings); michael@0: return NS_OK; michael@0: } michael@0: NS_IMETHODIMP michael@0: nsPrintSettingsGTK::SetPrintReversed(bool aPrintReversed) michael@0: { michael@0: gtk_print_settings_set_reverse(mPrintSettings, aPrintReversed); michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* attribute boolean printInColor; */ michael@0: NS_IMETHODIMP michael@0: nsPrintSettingsGTK::GetPrintInColor(bool *aPrintInColor) michael@0: { michael@0: *aPrintInColor = gtk_print_settings_get_use_color(mPrintSettings); michael@0: return NS_OK; michael@0: } michael@0: NS_IMETHODIMP michael@0: nsPrintSettingsGTK::SetPrintInColor(bool aPrintInColor) michael@0: { michael@0: gtk_print_settings_set_use_color(mPrintSettings, aPrintInColor); michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* attribute short orientation; */ michael@0: NS_IMETHODIMP michael@0: nsPrintSettingsGTK::GetOrientation(int32_t *aOrientation) michael@0: { michael@0: NS_ENSURE_ARG_POINTER(aOrientation); michael@0: michael@0: GtkPageOrientation gtkOrient = gtk_page_setup_get_orientation(mPageSetup); michael@0: switch (gtkOrient) { michael@0: case GTK_PAGE_ORIENTATION_LANDSCAPE: michael@0: case GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE: michael@0: *aOrientation = kLandscapeOrientation; michael@0: break; michael@0: michael@0: case GTK_PAGE_ORIENTATION_PORTRAIT: michael@0: case GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT: michael@0: default: michael@0: *aOrientation = kPortraitOrientation; michael@0: } michael@0: return NS_OK; michael@0: } michael@0: NS_IMETHODIMP michael@0: nsPrintSettingsGTK::SetOrientation(int32_t aOrientation) michael@0: { michael@0: GtkPageOrientation gtkOrient; michael@0: if (aOrientation == kLandscapeOrientation) michael@0: gtkOrient = GTK_PAGE_ORIENTATION_LANDSCAPE; michael@0: else michael@0: gtkOrient = GTK_PAGE_ORIENTATION_PORTRAIT; michael@0: michael@0: gtk_print_settings_set_orientation(mPrintSettings, gtkOrient); michael@0: gtk_page_setup_set_orientation(mPageSetup, gtkOrient); michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* attribute wstring toFileName; */ michael@0: NS_IMETHODIMP michael@0: nsPrintSettingsGTK::GetToFileName(char16_t * *aToFileName) michael@0: { michael@0: // Get the gtk output filename michael@0: const char* gtk_output_uri = gtk_print_settings_get(mPrintSettings, GTK_PRINT_SETTINGS_OUTPUT_URI); michael@0: if (!gtk_output_uri) { michael@0: *aToFileName = ToNewUnicode(mToFileName); michael@0: return NS_OK; michael@0: } michael@0: michael@0: // Convert to an nsIFile michael@0: nsCOMPtr file; michael@0: nsresult rv = NS_GetFileFromURLSpec(nsDependentCString(gtk_output_uri), michael@0: getter_AddRefs(file)); michael@0: if (NS_FAILED(rv)) michael@0: return rv; michael@0: michael@0: // Extract the path michael@0: nsAutoString path; michael@0: rv = file->GetPath(path); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: *aToFileName = ToNewUnicode(path); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsPrintSettingsGTK::SetToFileName(const char16_t * aToFileName) michael@0: { michael@0: if (aToFileName[0] == 0) { michael@0: mToFileName.SetLength(0); michael@0: gtk_print_settings_set(mPrintSettings, GTK_PRINT_SETTINGS_OUTPUT_URI, michael@0: nullptr); michael@0: return NS_OK; michael@0: } michael@0: michael@0: if (StringEndsWith(nsDependentString(aToFileName), NS_LITERAL_STRING(".ps"))) { michael@0: gtk_print_settings_set(mPrintSettings, GTK_PRINT_SETTINGS_OUTPUT_FILE_FORMAT, "ps"); michael@0: } else { michael@0: gtk_print_settings_set(mPrintSettings, GTK_PRINT_SETTINGS_OUTPUT_FILE_FORMAT, "pdf"); michael@0: } michael@0: michael@0: nsCOMPtr file; michael@0: nsresult rv = NS_NewLocalFile(nsDependentString(aToFileName), true, michael@0: getter_AddRefs(file)); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: // Convert the nsIFile to a URL michael@0: nsAutoCString url; michael@0: rv = NS_GetURLSpecFromFile(file, url); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: gtk_print_settings_set(mPrintSettings, GTK_PRINT_SETTINGS_OUTPUT_URI, url.get()); michael@0: mToFileName = aToFileName; michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsPrintSettingsGTK::GetPrinterName(char16_t * *aPrinter) michael@0: { michael@0: const char* gtkPrintName = gtk_print_settings_get_printer(mPrintSettings); michael@0: if (!gtkPrintName) { michael@0: if (GTK_IS_PRINTER(mGTKPrinter)) { michael@0: gtkPrintName = gtk_printer_get_name(mGTKPrinter); michael@0: } else { michael@0: // This mimics what nsPrintSettingsImpl does when we try to Get before we Set michael@0: nsXPIDLString nullPrintName; michael@0: *aPrinter = ToNewUnicode(nullPrintName); michael@0: return NS_OK; michael@0: } michael@0: } michael@0: *aPrinter = ToNewUnicode(nsDependentCString(gtkPrintName)); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsPrintSettingsGTK::SetPrinterName(const char16_t * aPrinter) michael@0: { michael@0: NS_ConvertUTF16toUTF8 gtkPrinter(aPrinter); michael@0: michael@0: if (StringBeginsWith(gtkPrinter, NS_LITERAL_CSTRING("CUPS/"))) { michael@0: // Strip off "CUPS/"; GTK might recognize the rest michael@0: gtkPrinter.Cut(0, strlen("CUPS/")); michael@0: } michael@0: michael@0: // Give mPrintSettings the passed-in printer name if either... michael@0: // - it has no printer name stored yet michael@0: // - it has an existing printer name that's different from michael@0: // the name passed to this function. michael@0: const char* oldPrinterName = gtk_print_settings_get_printer(mPrintSettings); michael@0: if (!oldPrinterName || !gtkPrinter.Equals(oldPrinterName)) { michael@0: mIsInitedFromPrinter = false; michael@0: mIsInitedFromPrefs = false; michael@0: gtk_print_settings_set_printer(mPrintSettings, gtkPrinter.get()); michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* attribute long numCopies; */ michael@0: NS_IMETHODIMP michael@0: nsPrintSettingsGTK::GetNumCopies(int32_t *aNumCopies) michael@0: { michael@0: NS_ENSURE_ARG_POINTER(aNumCopies); michael@0: *aNumCopies = gtk_print_settings_get_n_copies(mPrintSettings); michael@0: return NS_OK; michael@0: } michael@0: NS_IMETHODIMP michael@0: nsPrintSettingsGTK::SetNumCopies(int32_t aNumCopies) michael@0: { michael@0: gtk_print_settings_set_n_copies(mPrintSettings, aNumCopies); michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* attribute double scaling; */ michael@0: NS_IMETHODIMP michael@0: nsPrintSettingsGTK::GetScaling(double *aScaling) michael@0: { michael@0: *aScaling = gtk_print_settings_get_scale(mPrintSettings) / 100.0; michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsPrintSettingsGTK::SetScaling(double aScaling) michael@0: { michael@0: gtk_print_settings_set_scale(mPrintSettings, aScaling * 100.0); michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* attribute wstring paperName; */ michael@0: NS_IMETHODIMP michael@0: nsPrintSettingsGTK::GetPaperName(char16_t * *aPaperName) michael@0: { michael@0: NS_ENSURE_ARG_POINTER(aPaperName); michael@0: *aPaperName = ToNewUnicode(NS_ConvertUTF8toUTF16(gtk_paper_size_get_name(mPaperSize))); michael@0: return NS_OK; michael@0: } michael@0: NS_IMETHODIMP michael@0: nsPrintSettingsGTK::SetPaperName(const char16_t * aPaperName) michael@0: { michael@0: NS_ConvertUTF16toUTF8 gtkPaperName(aPaperName); michael@0: michael@0: // Convert these Gecko names to GTK names michael@0: if (gtkPaperName.EqualsIgnoreCase("letter")) michael@0: gtkPaperName.AssignLiteral(GTK_PAPER_NAME_LETTER); michael@0: else if (gtkPaperName.EqualsIgnoreCase("legal")) michael@0: gtkPaperName.AssignLiteral(GTK_PAPER_NAME_LEGAL); michael@0: michael@0: // Try to get the display name from the name so our paper size fits in the Page Setup dialog. michael@0: GtkPaperSize* paperSize = gtk_paper_size_new(gtkPaperName.get()); michael@0: char* displayName = strdup(gtk_paper_size_get_display_name(paperSize)); michael@0: gtk_paper_size_free(paperSize); michael@0: michael@0: paperSize = gtk_paper_size_new_custom(gtkPaperName.get(), displayName, michael@0: gtk_paper_size_get_width(mPaperSize, GTK_UNIT_INCH), michael@0: gtk_paper_size_get_height(mPaperSize, GTK_UNIT_INCH), michael@0: GTK_UNIT_INCH); michael@0: michael@0: free(displayName); michael@0: gtk_paper_size_free(mPaperSize); michael@0: mPaperSize = paperSize; michael@0: SaveNewPageSize(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: GtkUnit michael@0: nsPrintSettingsGTK::GetGTKUnit(int16_t aGeckoUnit) michael@0: { michael@0: if (aGeckoUnit == kPaperSizeMillimeters) michael@0: return GTK_UNIT_MM; michael@0: else michael@0: return GTK_UNIT_INCH; michael@0: } michael@0: michael@0: void michael@0: nsPrintSettingsGTK::SaveNewPageSize() michael@0: { michael@0: gtk_print_settings_set_paper_size(mPrintSettings, mPaperSize); michael@0: gtk_page_setup_set_paper_size(mPageSetup, mPaperSize); michael@0: } michael@0: michael@0: void michael@0: nsPrintSettingsGTK::InitUnwriteableMargin() michael@0: { michael@0: mUnwriteableMargin.SizeTo( michael@0: NS_INCHES_TO_INT_TWIPS(gtk_page_setup_get_top_margin(mPageSetup, GTK_UNIT_INCH)), michael@0: NS_INCHES_TO_INT_TWIPS(gtk_page_setup_get_right_margin(mPageSetup, GTK_UNIT_INCH)), michael@0: NS_INCHES_TO_INT_TWIPS(gtk_page_setup_get_bottom_margin(mPageSetup, GTK_UNIT_INCH)), michael@0: NS_INCHES_TO_INT_TWIPS(gtk_page_setup_get_left_margin(mPageSetup, GTK_UNIT_INCH)) michael@0: ); michael@0: } michael@0: michael@0: /** michael@0: * NOTE: Need a custom set of SetUnwriteableMargin functions, because michael@0: * whenever we change mUnwriteableMargin, we must pass the change michael@0: * down to our GTKPageSetup object. (This is needed in order for us michael@0: * to give the correct default values in nsPrintDialogGTK.) michael@0: * michael@0: * It's important that the following functions pass michael@0: * mUnwriteableMargin values rather than aUnwriteableMargin values michael@0: * to gtk_page_setup_set_[blank]_margin, because the two may not be michael@0: * the same. (Specifically, negative values of aUnwriteableMargin michael@0: * are ignored by the nsPrintSettings::SetUnwriteableMargin functions.) michael@0: */ michael@0: NS_IMETHODIMP michael@0: nsPrintSettingsGTK::SetUnwriteableMarginInTwips(nsIntMargin& aUnwriteableMargin) michael@0: { michael@0: nsPrintSettings::SetUnwriteableMarginInTwips(aUnwriteableMargin); michael@0: gtk_page_setup_set_top_margin(mPageSetup, michael@0: NS_TWIPS_TO_INCHES(mUnwriteableMargin.top), GTK_UNIT_INCH); michael@0: gtk_page_setup_set_left_margin(mPageSetup, michael@0: NS_TWIPS_TO_INCHES(mUnwriteableMargin.left), GTK_UNIT_INCH); michael@0: gtk_page_setup_set_bottom_margin(mPageSetup, michael@0: NS_TWIPS_TO_INCHES(mUnwriteableMargin.bottom), GTK_UNIT_INCH); michael@0: gtk_page_setup_set_right_margin(mPageSetup, michael@0: NS_TWIPS_TO_INCHES(mUnwriteableMargin.right), GTK_UNIT_INCH); michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* attribute double unwriteableMarginTop; */ michael@0: NS_IMETHODIMP michael@0: nsPrintSettingsGTK::SetUnwriteableMarginTop(double aUnwriteableMarginTop) michael@0: { michael@0: nsPrintSettings::SetUnwriteableMarginTop(aUnwriteableMarginTop); michael@0: gtk_page_setup_set_top_margin(mPageSetup, michael@0: NS_TWIPS_TO_INCHES(mUnwriteableMargin.top), GTK_UNIT_INCH); michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* attribute double unwriteableMarginLeft; */ michael@0: NS_IMETHODIMP michael@0: nsPrintSettingsGTK::SetUnwriteableMarginLeft(double aUnwriteableMarginLeft) michael@0: { michael@0: nsPrintSettings::SetUnwriteableMarginLeft(aUnwriteableMarginLeft); michael@0: gtk_page_setup_set_left_margin(mPageSetup, michael@0: NS_TWIPS_TO_INCHES(mUnwriteableMargin.left), GTK_UNIT_INCH); michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* attribute double unwriteableMarginBottom; */ michael@0: NS_IMETHODIMP michael@0: nsPrintSettingsGTK::SetUnwriteableMarginBottom(double aUnwriteableMarginBottom) michael@0: { michael@0: nsPrintSettings::SetUnwriteableMarginBottom(aUnwriteableMarginBottom); michael@0: gtk_page_setup_set_bottom_margin(mPageSetup, michael@0: NS_TWIPS_TO_INCHES(mUnwriteableMargin.bottom), GTK_UNIT_INCH); michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* attribute double unwriteableMarginRight; */ michael@0: NS_IMETHODIMP michael@0: nsPrintSettingsGTK::SetUnwriteableMarginRight(double aUnwriteableMarginRight) michael@0: { michael@0: nsPrintSettings::SetUnwriteableMarginRight(aUnwriteableMarginRight); michael@0: gtk_page_setup_set_right_margin(mPageSetup, michael@0: NS_TWIPS_TO_INCHES(mUnwriteableMargin.right), GTK_UNIT_INCH); michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* attribute double paperWidth; */ michael@0: NS_IMETHODIMP michael@0: nsPrintSettingsGTK::GetPaperWidth(double *aPaperWidth) michael@0: { michael@0: NS_ENSURE_ARG_POINTER(aPaperWidth); michael@0: *aPaperWidth = gtk_paper_size_get_width(mPaperSize, GetGTKUnit(mPaperSizeUnit)); michael@0: return NS_OK; michael@0: } michael@0: NS_IMETHODIMP michael@0: nsPrintSettingsGTK::SetPaperWidth(double aPaperWidth) michael@0: { michael@0: gtk_paper_size_set_size(mPaperSize, michael@0: aPaperWidth, michael@0: gtk_paper_size_get_height(mPaperSize, GetGTKUnit(mPaperSizeUnit)), michael@0: GetGTKUnit(mPaperSizeUnit)); michael@0: SaveNewPageSize(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* attribute double paperHeight; */ michael@0: NS_IMETHODIMP michael@0: nsPrintSettingsGTK::GetPaperHeight(double *aPaperHeight) michael@0: { michael@0: NS_ENSURE_ARG_POINTER(aPaperHeight); michael@0: *aPaperHeight = gtk_paper_size_get_height(mPaperSize, GetGTKUnit(mPaperSizeUnit)); michael@0: return NS_OK; michael@0: } michael@0: NS_IMETHODIMP michael@0: nsPrintSettingsGTK::SetPaperHeight(double aPaperHeight) michael@0: { michael@0: gtk_paper_size_set_size(mPaperSize, michael@0: gtk_paper_size_get_width(mPaperSize, GetGTKUnit(mPaperSizeUnit)), michael@0: aPaperHeight, michael@0: GetGTKUnit(mPaperSizeUnit)); michael@0: SaveNewPageSize(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsPrintSettingsGTK::SetPaperSizeUnit(int16_t aPaperSizeUnit) michael@0: { michael@0: // Convert units internally. e.g. they might have set the values while we're still in mm but michael@0: // they change to inch just afterwards, expecting that their sizes are in inches. michael@0: gtk_paper_size_set_size(mPaperSize, michael@0: gtk_paper_size_get_width(mPaperSize, GetGTKUnit(mPaperSizeUnit)), michael@0: gtk_paper_size_get_height(mPaperSize, GetGTKUnit(mPaperSizeUnit)), michael@0: GetGTKUnit(aPaperSizeUnit)); michael@0: SaveNewPageSize(); michael@0: michael@0: mPaperSizeUnit = aPaperSizeUnit; michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsPrintSettingsGTK::GetEffectivePageSize(double *aWidth, double *aHeight) michael@0: { michael@0: *aWidth = NS_INCHES_TO_INT_TWIPS(gtk_paper_size_get_width(mPaperSize, GTK_UNIT_INCH)); michael@0: *aHeight = NS_INCHES_TO_INT_TWIPS(gtk_paper_size_get_height(mPaperSize, GTK_UNIT_INCH)); michael@0: michael@0: GtkPageOrientation gtkOrient = gtk_page_setup_get_orientation(mPageSetup); michael@0: michael@0: if (gtkOrient == GTK_PAGE_ORIENTATION_LANDSCAPE || michael@0: gtkOrient == GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE) { michael@0: double temp = *aWidth; michael@0: *aWidth = *aHeight; michael@0: *aHeight = temp; michael@0: } michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsPrintSettingsGTK::SetupSilentPrinting() michael@0: { michael@0: // We have to get a printer here, rather than when the print settings are constructed. michael@0: // This is because when we request sync, GTK makes us wait in the *event loop* while waiting michael@0: // for the enumeration to finish. We must do this when event loop runs are expected. michael@0: gtk_enumerate_printers(printer_enumerator, this, nullptr, TRUE); michael@0: michael@0: // XXX If no default printer set, get the first one. michael@0: if (!GTK_IS_PRINTER(mGTKPrinter)) michael@0: gtk_enumerate_printers(ref_printer, this, nullptr, TRUE); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsPrintSettingsGTK::GetPageRanges(nsTArray &aPages) michael@0: { michael@0: gint ctRanges; michael@0: GtkPageRange* lstRanges = gtk_print_settings_get_page_ranges(mPrintSettings, &ctRanges); michael@0: michael@0: aPages.Clear(); michael@0: michael@0: if (ctRanges > 1) { michael@0: for (gint i = 0; i < ctRanges; i++) { michael@0: aPages.AppendElement(lstRanges[i].start+1); michael@0: aPages.AppendElement(lstRanges[i].end+1); michael@0: } michael@0: } michael@0: michael@0: g_free(lstRanges); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsPrintSettingsGTK::GetResolution(int32_t *aResolution) michael@0: { michael@0: if (!gtk_print_settings_has_key(mPrintSettings, GTK_PRINT_SETTINGS_RESOLUTION)) michael@0: return NS_ERROR_FAILURE; michael@0: *aResolution = gtk_print_settings_get_resolution(mPrintSettings); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsPrintSettingsGTK::SetResolution(int32_t aResolution) michael@0: { michael@0: gtk_print_settings_set_resolution(mPrintSettings, aResolution); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsPrintSettingsGTK::GetDuplex(int32_t *aDuplex) michael@0: { michael@0: if (!gtk_print_settings_has_key(mPrintSettings, GTK_PRINT_SETTINGS_DUPLEX)) michael@0: return NS_ERROR_FAILURE; michael@0: *aDuplex = gtk_print_settings_get_duplex(mPrintSettings); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsPrintSettingsGTK::SetDuplex(int32_t aDuplex) michael@0: { michael@0: MOZ_ASSERT(aDuplex >= GTK_PRINT_DUPLEX_SIMPLEX && michael@0: aDuplex <= GTK_PRINT_DUPLEX_VERTICAL, michael@0: "value is out of bounds for GtkPrintDuplex enum"); michael@0: gtk_print_settings_set_duplex(mPrintSettings, static_cast(aDuplex)); michael@0: return NS_OK; michael@0: } michael@0: