gecko-dev/widget/gtk/nsPrintSettingsGTK.cpp

711 строки
23 KiB
C++

/* -*- 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 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) {
// 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);
mGTKPrinter = (GtkPrinter*)g_object_ref(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)) {
if (gtk_printer_accepts_pdf(mGTKPrinter)) {
format = nsIPrintSettings::kOutputFormatPDF;
} else {
format = 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::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::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) {
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) {
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) {
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;
}