Bug 1869647 - Mark hasStorageAccess.sub.https.window.html as intermittent after wpt...
[gecko.git] / widget / gtk / nsPrintSettingsGTK.cpp
blob6ca66a0fcfd0defadf0e1463b86029c887c997a5
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "nsPrintSettingsGTK.h"
7 #include "nsIFile.h"
8 #include "nsNetUtil.h"
9 #include <stdlib.h>
10 #include <algorithm>
12 // These constants are the the strings that GTK expects as key-value pairs for
13 // setting CUPS duplex modes. These are not universal to all CUPS systems, which
14 // is why they are local to this file.
15 static constexpr gchar kCupsDuplex[] = "cups-Duplex";
16 static constexpr gchar kCupsDuplexNone[] = "None";
17 static constexpr gchar kCupsDuplexNoTumble[] = "DuplexNoTumble";
18 static constexpr gchar kCupsDuplexTumble[] = "DuplexTumble";
20 static GtkPaperSize* moz_gtk_paper_size_copy_to_new_custom(
21 GtkPaperSize* oldPaperSize) {
22 // We make a "custom-ified" copy of the paper size so it can be changed later.
23 return gtk_paper_size_new_custom(
24 gtk_paper_size_get_name(oldPaperSize),
25 gtk_paper_size_get_display_name(oldPaperSize),
26 gtk_paper_size_get_width(oldPaperSize, GTK_UNIT_INCH),
27 gtk_paper_size_get_height(oldPaperSize, GTK_UNIT_INCH), GTK_UNIT_INCH);
30 NS_IMPL_ISUPPORTS_INHERITED(nsPrintSettingsGTK, nsPrintSettings,
31 nsPrintSettingsGTK)
33 /** ---------------------------------------------------
35 nsPrintSettingsGTK::nsPrintSettingsGTK()
36 : mPageSetup(nullptr), mPrintSettings(nullptr), mGTKPrinter(nullptr) {
37 // The aim here is to set up the objects enough that silent printing works
38 // well. These will be replaced anyway if the print dialog is used.
39 mPrintSettings = gtk_print_settings_new();
40 GtkPageSetup* pageSetup = gtk_page_setup_new();
41 SetGtkPageSetup(pageSetup);
42 g_object_unref(pageSetup);
44 SetOutputFormat(nsIPrintSettings::kOutputFormatNative);
47 already_AddRefed<nsIPrintSettings> CreatePlatformPrintSettings(
48 const mozilla::PrintSettingsInitializer& aSettings) {
49 RefPtr<nsPrintSettings> settings = new nsPrintSettingsGTK();
50 settings->InitWithInitializer(aSettings);
51 settings->SetDefaultFileName();
52 return settings.forget();
55 /** ---------------------------------------------------
57 nsPrintSettingsGTK::~nsPrintSettingsGTK() {
58 if (mPageSetup) {
59 g_object_unref(mPageSetup);
60 mPageSetup = nullptr;
62 if (mPrintSettings) {
63 g_object_unref(mPrintSettings);
64 mPrintSettings = nullptr;
66 if (mGTKPrinter) {
67 g_object_unref(mGTKPrinter);
68 mGTKPrinter = nullptr;
72 /** ---------------------------------------------------
74 nsPrintSettingsGTK::nsPrintSettingsGTK(const nsPrintSettingsGTK& aPS)
75 : mPageSetup(nullptr), mPrintSettings(nullptr), mGTKPrinter(nullptr) {
76 *this = aPS;
79 /** ---------------------------------------------------
81 nsPrintSettingsGTK& nsPrintSettingsGTK::operator=(
82 const nsPrintSettingsGTK& rhs) {
83 if (this == &rhs) {
84 return *this;
87 nsPrintSettings::operator=(rhs);
89 if (mPageSetup) g_object_unref(mPageSetup);
90 mPageSetup = gtk_page_setup_copy(rhs.mPageSetup);
91 // NOTE: No need to re-initialize mUnwriteableMargin here (even
92 // though mPageSetup is changing). It'll be copied correctly by
93 // nsPrintSettings::operator=.
95 if (mPrintSettings) g_object_unref(mPrintSettings);
96 mPrintSettings = gtk_print_settings_copy(rhs.mPrintSettings);
98 if (mGTKPrinter) g_object_unref(mGTKPrinter);
99 mGTKPrinter = (GtkPrinter*)g_object_ref(rhs.mGTKPrinter);
101 return *this;
104 /** -------------------------------------------
106 nsresult nsPrintSettingsGTK::_Clone(nsIPrintSettings** _retval) {
107 NS_ENSURE_ARG_POINTER(_retval);
108 *_retval = nullptr;
110 nsPrintSettingsGTK* newSettings = new nsPrintSettingsGTK(*this);
111 if (!newSettings) return NS_ERROR_FAILURE;
112 *_retval = newSettings;
113 NS_ADDREF(*_retval);
114 return NS_OK;
117 /** -------------------------------------------
119 NS_IMETHODIMP
120 nsPrintSettingsGTK::_Assign(nsIPrintSettings* aPS) {
121 nsPrintSettingsGTK* printSettingsGTK = static_cast<nsPrintSettingsGTK*>(aPS);
122 if (!printSettingsGTK) return NS_ERROR_UNEXPECTED;
123 *this = *printSettingsGTK;
124 return NS_OK;
127 /** ---------------------------------------------------
129 void nsPrintSettingsGTK::SetGtkPageSetup(GtkPageSetup* aPageSetup) {
130 if (mPageSetup) g_object_unref(mPageSetup);
132 mPageSetup = (GtkPageSetup*)g_object_ref(aPageSetup);
133 InitUnwriteableMargin();
135 // If the paper size is not custom, then we make a custom copy of the
136 // GtkPaperSize, so it can be mutable. If a GtkPaperSize wasn't made as
137 // custom, its properties are immutable.
138 GtkPaperSize* paperSize = gtk_page_setup_get_paper_size(aPageSetup);
139 if (!gtk_paper_size_is_custom(paperSize)) {
140 GtkPaperSize* customPaperSize =
141 moz_gtk_paper_size_copy_to_new_custom(paperSize);
142 gtk_page_setup_set_paper_size(mPageSetup, customPaperSize);
143 gtk_paper_size_free(customPaperSize);
145 SaveNewPageSize();
148 /** ---------------------------------------------------
150 void nsPrintSettingsGTK::SetGtkPrintSettings(GtkPrintSettings* aPrintSettings) {
151 if (mPrintSettings) g_object_unref(mPrintSettings);
153 mPrintSettings = (GtkPrintSettings*)g_object_ref(aPrintSettings);
155 GtkPaperSize* paperSize = gtk_print_settings_get_paper_size(aPrintSettings);
156 if (paperSize) {
157 GtkPaperSize* customPaperSize =
158 moz_gtk_paper_size_copy_to_new_custom(paperSize);
159 gtk_paper_size_free(paperSize);
160 gtk_page_setup_set_paper_size(mPageSetup, customPaperSize);
161 gtk_paper_size_free(customPaperSize);
162 } else {
163 // paperSize was null, and so we add the paper size in the GtkPageSetup to
164 // the settings.
165 SaveNewPageSize();
169 /** ---------------------------------------------------
171 void nsPrintSettingsGTK::SetGtkPrinter(GtkPrinter* aPrinter) {
172 if (mGTKPrinter) g_object_unref(mGTKPrinter);
174 mGTKPrinter = (GtkPrinter*)g_object_ref(aPrinter);
177 NS_IMETHODIMP nsPrintSettingsGTK::GetOutputFormat(int16_t* aOutputFormat) {
178 NS_ENSURE_ARG_POINTER(aOutputFormat);
180 int16_t format;
181 nsresult rv = nsPrintSettings::GetOutputFormat(&format);
182 if (NS_FAILED(rv)) {
183 return rv;
186 if (format == nsIPrintSettings::kOutputFormatNative &&
187 GTK_IS_PRINTER(mGTKPrinter)) {
188 format = nsIPrintSettings::kOutputFormatPDF;
191 *aOutputFormat = format;
192 return NS_OK;
196 * Reimplementation of nsPrintSettings functions so that we get the values
197 * from the GTK objects rather than our own variables.
200 NS_IMETHODIMP
201 nsPrintSettingsGTK::SetPageRanges(const nsTArray<int32_t>& aRanges) {
202 if (aRanges.Length() % 2 != 0) {
203 return NS_ERROR_FAILURE;
206 gtk_print_settings_set_print_pages(
207 mPrintSettings,
208 aRanges.IsEmpty() ? GTK_PRINT_PAGES_ALL : GTK_PRINT_PAGES_RANGES);
210 nsTArray<GtkPageRange> ranges;
211 ranges.SetCapacity(aRanges.Length() / 2);
212 for (size_t i = 0; i < aRanges.Length(); i += 2) {
213 GtkPageRange* gtkRange = ranges.AppendElement();
214 gtkRange->start = aRanges[i] - 1;
215 gtkRange->end = aRanges[i + 1] - 1;
218 gtk_print_settings_set_page_ranges(mPrintSettings, ranges.Elements(),
219 ranges.Length());
220 return NS_OK;
223 NS_IMETHODIMP
224 nsPrintSettingsGTK::GetPrintReversed(bool* aPrintReversed) {
225 *aPrintReversed = gtk_print_settings_get_reverse(mPrintSettings);
226 return NS_OK;
228 NS_IMETHODIMP
229 nsPrintSettingsGTK::SetPrintReversed(bool aPrintReversed) {
230 gtk_print_settings_set_reverse(mPrintSettings, aPrintReversed);
231 return NS_OK;
234 NS_IMETHODIMP
235 nsPrintSettingsGTK::GetPrintInColor(bool* aPrintInColor) {
236 *aPrintInColor = gtk_print_settings_get_use_color(mPrintSettings);
237 return NS_OK;
239 NS_IMETHODIMP
240 nsPrintSettingsGTK::SetPrintInColor(bool aPrintInColor) {
241 gtk_print_settings_set_use_color(mPrintSettings, aPrintInColor);
242 return NS_OK;
245 NS_IMETHODIMP
246 nsPrintSettingsGTK::GetOrientation(int32_t* aOrientation) {
247 NS_ENSURE_ARG_POINTER(aOrientation);
249 GtkPageOrientation gtkOrient = gtk_page_setup_get_orientation(mPageSetup);
250 switch (gtkOrient) {
251 case GTK_PAGE_ORIENTATION_LANDSCAPE:
252 case GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE:
253 *aOrientation = kLandscapeOrientation;
254 break;
256 case GTK_PAGE_ORIENTATION_PORTRAIT:
257 case GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT:
258 default:
259 *aOrientation = kPortraitOrientation;
261 return NS_OK;
263 NS_IMETHODIMP
264 nsPrintSettingsGTK::SetOrientation(int32_t aOrientation) {
265 GtkPageOrientation gtkOrient;
266 if (aOrientation == kLandscapeOrientation)
267 gtkOrient = GTK_PAGE_ORIENTATION_LANDSCAPE;
268 else
269 gtkOrient = GTK_PAGE_ORIENTATION_PORTRAIT;
271 gtk_print_settings_set_orientation(mPrintSettings, gtkOrient);
272 gtk_page_setup_set_orientation(mPageSetup, gtkOrient);
273 return NS_OK;
276 NS_IMETHODIMP
277 nsPrintSettingsGTK::GetToFileName(nsAString& aToFileName) {
278 // Get the gtk output filename
279 const char* gtk_output_uri =
280 gtk_print_settings_get(mPrintSettings, GTK_PRINT_SETTINGS_OUTPUT_URI);
281 if (!gtk_output_uri) {
282 aToFileName = mToFileName;
283 return NS_OK;
286 // Convert to an nsIFile
287 nsCOMPtr<nsIFile> file;
288 nsresult rv = NS_GetFileFromURLSpec(nsDependentCString(gtk_output_uri),
289 getter_AddRefs(file));
290 if (NS_FAILED(rv)) return rv;
292 // Extract the path
293 return file->GetPath(aToFileName);
296 NS_IMETHODIMP
297 nsPrintSettingsGTK::SetToFileName(const nsAString& aToFileName) {
298 if (aToFileName.IsEmpty()) {
299 mToFileName.SetLength(0);
300 gtk_print_settings_set(mPrintSettings, GTK_PRINT_SETTINGS_OUTPUT_URI,
301 nullptr);
302 return NS_OK;
305 gtk_print_settings_set(mPrintSettings, GTK_PRINT_SETTINGS_OUTPUT_FILE_FORMAT,
306 "pdf");
308 nsCOMPtr<nsIFile> file;
309 nsresult rv = NS_NewLocalFile(aToFileName, true, getter_AddRefs(file));
310 NS_ENSURE_SUCCESS(rv, rv);
312 // Convert the nsIFile to a URL
313 nsAutoCString url;
314 rv = NS_GetURLSpecFromFile(file, url);
315 NS_ENSURE_SUCCESS(rv, rv);
317 gtk_print_settings_set(mPrintSettings, GTK_PRINT_SETTINGS_OUTPUT_URI,
318 url.get());
319 mToFileName = aToFileName;
321 return NS_OK;
324 NS_IMETHODIMP
325 nsPrintSettingsGTK::GetPrinterName(nsAString& aPrinter) {
326 const char* gtkPrintName = gtk_print_settings_get_printer(mPrintSettings);
327 if (!gtkPrintName) {
328 if (GTK_IS_PRINTER(mGTKPrinter)) {
329 gtkPrintName = gtk_printer_get_name(mGTKPrinter);
330 } else {
331 // This mimics what nsPrintSettingsImpl does when we try to Get before we
332 // Set
333 aPrinter.Truncate();
334 return NS_OK;
337 CopyUTF8toUTF16(mozilla::MakeStringSpan(gtkPrintName), aPrinter);
338 return NS_OK;
341 NS_IMETHODIMP
342 nsPrintSettingsGTK::SetPrinterName(const nsAString& aPrinter) {
343 NS_ConvertUTF16toUTF8 gtkPrinter(aPrinter);
345 if (StringBeginsWith(gtkPrinter, "CUPS/"_ns)) {
346 // Strip off "CUPS/"; GTK might recognize the rest
347 gtkPrinter.Cut(0, strlen("CUPS/"));
350 // Give mPrintSettings the passed-in printer name if either...
351 // - it has no printer name stored yet
352 // - it has an existing printer name that's different from
353 // the name passed to this function.
354 const char* oldPrinterName = gtk_print_settings_get_printer(mPrintSettings);
355 if (!oldPrinterName || !gtkPrinter.Equals(oldPrinterName)) {
356 mIsInitedFromPrinter = false;
357 mIsInitedFromPrefs = false;
358 gtk_print_settings_set_printer(mPrintSettings, gtkPrinter.get());
361 return NS_OK;
364 NS_IMETHODIMP
365 nsPrintSettingsGTK::GetNumCopies(int32_t* aNumCopies) {
366 NS_ENSURE_ARG_POINTER(aNumCopies);
367 *aNumCopies = gtk_print_settings_get_n_copies(mPrintSettings);
368 return NS_OK;
370 NS_IMETHODIMP
371 nsPrintSettingsGTK::SetNumCopies(int32_t aNumCopies) {
372 gtk_print_settings_set_n_copies(mPrintSettings, aNumCopies);
373 return NS_OK;
376 NS_IMETHODIMP
377 nsPrintSettingsGTK::GetScaling(double* aScaling) {
378 *aScaling = gtk_print_settings_get_scale(mPrintSettings) / 100.0;
379 return NS_OK;
382 NS_IMETHODIMP
383 nsPrintSettingsGTK::SetScaling(double aScaling) {
384 gtk_print_settings_set_scale(mPrintSettings, aScaling * 100.0);
385 return NS_OK;
388 NS_IMETHODIMP
389 nsPrintSettingsGTK::GetPaperId(nsAString& aPaperId) {
390 const gchar* name =
391 gtk_paper_size_get_name(gtk_page_setup_get_paper_size(mPageSetup));
392 CopyUTF8toUTF16(mozilla::MakeStringSpan(name), aPaperId);
393 return NS_OK;
395 NS_IMETHODIMP
396 nsPrintSettingsGTK::SetPaperId(const nsAString& aPaperId) {
397 NS_ConvertUTF16toUTF8 gtkPaperName(aPaperId);
399 // Convert these Gecko names to GTK names
400 // XXX (jfkthame): is this still relevant?
401 if (gtkPaperName.EqualsIgnoreCase("letter"))
402 gtkPaperName.AssignLiteral(GTK_PAPER_NAME_LETTER);
403 else if (gtkPaperName.EqualsIgnoreCase("legal"))
404 gtkPaperName.AssignLiteral(GTK_PAPER_NAME_LEGAL);
406 GtkPaperSize* oldPaperSize = gtk_page_setup_get_paper_size(mPageSetup);
407 gdouble width = gtk_paper_size_get_width(oldPaperSize, GTK_UNIT_INCH);
408 gdouble height = gtk_paper_size_get_height(oldPaperSize, GTK_UNIT_INCH);
410 // Try to get the display name from the name so our paper size fits in the
411 // Page Setup dialog.
412 GtkPaperSize* paperSize = gtk_paper_size_new(gtkPaperName.get());
413 GtkPaperSize* customPaperSize = gtk_paper_size_new_custom(
414 gtkPaperName.get(), gtk_paper_size_get_display_name(paperSize), width,
415 height, GTK_UNIT_INCH);
416 gtk_paper_size_free(paperSize);
418 gtk_page_setup_set_paper_size(mPageSetup, customPaperSize);
419 gtk_paper_size_free(customPaperSize);
420 SaveNewPageSize();
421 return NS_OK;
424 GtkUnit nsPrintSettingsGTK::GetGTKUnit(int16_t aGeckoUnit) {
425 if (aGeckoUnit == kPaperSizeMillimeters)
426 return GTK_UNIT_MM;
427 else
428 return GTK_UNIT_INCH;
431 void nsPrintSettingsGTK::SaveNewPageSize() {
432 gtk_print_settings_set_paper_size(mPrintSettings,
433 gtk_page_setup_get_paper_size(mPageSetup));
436 void nsPrintSettingsGTK::InitUnwriteableMargin() {
437 mUnwriteableMargin.SizeTo(
438 NS_INCHES_TO_INT_TWIPS(
439 gtk_page_setup_get_top_margin(mPageSetup, GTK_UNIT_INCH)),
440 NS_INCHES_TO_INT_TWIPS(
441 gtk_page_setup_get_right_margin(mPageSetup, GTK_UNIT_INCH)),
442 NS_INCHES_TO_INT_TWIPS(
443 gtk_page_setup_get_bottom_margin(mPageSetup, GTK_UNIT_INCH)),
444 NS_INCHES_TO_INT_TWIPS(
445 gtk_page_setup_get_left_margin(mPageSetup, GTK_UNIT_INCH)));
449 * NOTE: Need a custom set of SetUnwriteableMargin functions, because
450 * whenever we change mUnwriteableMargin, we must pass the change
451 * down to our GTKPageSetup object. (This is needed in order for us
452 * to give the correct default values in nsPrintDialogGTK.)
454 * It's important that the following functions pass
455 * mUnwriteableMargin values rather than aUnwriteableMargin values
456 * to gtk_page_setup_set_[blank]_margin, because the two may not be
457 * the same. (Specifically, negative values of aUnwriteableMargin
458 * are ignored by the nsPrintSettings::SetUnwriteableMargin functions.)
460 NS_IMETHODIMP
461 nsPrintSettingsGTK::SetUnwriteableMarginInTwips(
462 nsIntMargin& aUnwriteableMargin) {
463 nsPrintSettings::SetUnwriteableMarginInTwips(aUnwriteableMargin);
464 gtk_page_setup_set_top_margin(
465 mPageSetup, NS_TWIPS_TO_INCHES(mUnwriteableMargin.top), GTK_UNIT_INCH);
466 gtk_page_setup_set_left_margin(
467 mPageSetup, NS_TWIPS_TO_INCHES(mUnwriteableMargin.left), GTK_UNIT_INCH);
468 gtk_page_setup_set_bottom_margin(
469 mPageSetup, NS_TWIPS_TO_INCHES(mUnwriteableMargin.bottom), GTK_UNIT_INCH);
470 gtk_page_setup_set_right_margin(
471 mPageSetup, NS_TWIPS_TO_INCHES(mUnwriteableMargin.right), GTK_UNIT_INCH);
472 return NS_OK;
475 NS_IMETHODIMP
476 nsPrintSettingsGTK::SetUnwriteableMarginTop(double aUnwriteableMarginTop) {
477 nsPrintSettings::SetUnwriteableMarginTop(aUnwriteableMarginTop);
478 gtk_page_setup_set_top_margin(
479 mPageSetup, NS_TWIPS_TO_INCHES(mUnwriteableMargin.top), GTK_UNIT_INCH);
480 return NS_OK;
483 NS_IMETHODIMP
484 nsPrintSettingsGTK::SetUnwriteableMarginLeft(double aUnwriteableMarginLeft) {
485 nsPrintSettings::SetUnwriteableMarginLeft(aUnwriteableMarginLeft);
486 gtk_page_setup_set_left_margin(
487 mPageSetup, NS_TWIPS_TO_INCHES(mUnwriteableMargin.left), GTK_UNIT_INCH);
488 return NS_OK;
491 NS_IMETHODIMP
492 nsPrintSettingsGTK::SetUnwriteableMarginBottom(
493 double aUnwriteableMarginBottom) {
494 nsPrintSettings::SetUnwriteableMarginBottom(aUnwriteableMarginBottom);
495 gtk_page_setup_set_bottom_margin(
496 mPageSetup, NS_TWIPS_TO_INCHES(mUnwriteableMargin.bottom), GTK_UNIT_INCH);
497 return NS_OK;
500 NS_IMETHODIMP
501 nsPrintSettingsGTK::SetUnwriteableMarginRight(double aUnwriteableMarginRight) {
502 nsPrintSettings::SetUnwriteableMarginRight(aUnwriteableMarginRight);
503 gtk_page_setup_set_right_margin(
504 mPageSetup, NS_TWIPS_TO_INCHES(mUnwriteableMargin.right), GTK_UNIT_INCH);
505 return NS_OK;
508 NS_IMETHODIMP
509 nsPrintSettingsGTK::GetPaperWidth(double* aPaperWidth) {
510 NS_ENSURE_ARG_POINTER(aPaperWidth);
511 GtkPaperSize* paperSize = gtk_page_setup_get_paper_size(mPageSetup);
512 *aPaperWidth =
513 gtk_paper_size_get_width(paperSize, GetGTKUnit(mPaperSizeUnit));
514 return NS_OK;
516 NS_IMETHODIMP
517 nsPrintSettingsGTK::SetPaperWidth(double aPaperWidth) {
518 GtkPaperSize* paperSize = gtk_page_setup_get_paper_size(mPageSetup);
519 gtk_paper_size_set_size(
520 paperSize, aPaperWidth,
521 gtk_paper_size_get_height(paperSize, GetGTKUnit(mPaperSizeUnit)),
522 GetGTKUnit(mPaperSizeUnit));
523 SaveNewPageSize();
524 return NS_OK;
527 NS_IMETHODIMP
528 nsPrintSettingsGTK::GetPaperHeight(double* aPaperHeight) {
529 NS_ENSURE_ARG_POINTER(aPaperHeight);
530 GtkPaperSize* paperSize = gtk_page_setup_get_paper_size(mPageSetup);
531 *aPaperHeight =
532 gtk_paper_size_get_height(paperSize, GetGTKUnit(mPaperSizeUnit));
533 return NS_OK;
535 NS_IMETHODIMP
536 nsPrintSettingsGTK::SetPaperHeight(double aPaperHeight) {
537 GtkPaperSize* paperSize = gtk_page_setup_get_paper_size(mPageSetup);
538 gtk_paper_size_set_size(
539 paperSize,
540 gtk_paper_size_get_width(paperSize, GetGTKUnit(mPaperSizeUnit)),
541 aPaperHeight, GetGTKUnit(mPaperSizeUnit));
542 SaveNewPageSize();
543 return NS_OK;
546 NS_IMETHODIMP
547 nsPrintSettingsGTK::SetPaperSizeUnit(int16_t aPaperSizeUnit) {
548 // Convert units internally. e.g. they might have set the values while we're
549 // still in mm but they change to inch just afterwards, expecting that their
550 // sizes are in inches.
551 GtkPaperSize* paperSize = gtk_page_setup_get_paper_size(mPageSetup);
552 gtk_paper_size_set_size(
553 paperSize,
554 gtk_paper_size_get_width(paperSize, GetGTKUnit(mPaperSizeUnit)),
555 gtk_paper_size_get_height(paperSize, GetGTKUnit(mPaperSizeUnit)),
556 GetGTKUnit(aPaperSizeUnit));
557 SaveNewPageSize();
559 mPaperSizeUnit = aPaperSizeUnit;
560 return NS_OK;
563 NS_IMETHODIMP
564 nsPrintSettingsGTK::GetEffectivePageSize(double* aWidth, double* aHeight) {
565 GtkPaperSize* paperSize = gtk_page_setup_get_paper_size(mPageSetup);
566 if (mPaperSizeUnit == kPaperSizeInches) {
567 *aWidth =
568 NS_INCHES_TO_TWIPS(gtk_paper_size_get_width(paperSize, GTK_UNIT_INCH));
569 *aHeight =
570 NS_INCHES_TO_TWIPS(gtk_paper_size_get_height(paperSize, GTK_UNIT_INCH));
571 } else {
572 MOZ_ASSERT(mPaperSizeUnit == kPaperSizeMillimeters,
573 "unexpected paper size unit");
574 *aWidth = NS_MILLIMETERS_TO_TWIPS(
575 gtk_paper_size_get_width(paperSize, GTK_UNIT_MM));
576 *aHeight = NS_MILLIMETERS_TO_TWIPS(
577 gtk_paper_size_get_height(paperSize, GTK_UNIT_MM));
579 GtkPageOrientation gtkOrient = gtk_page_setup_get_orientation(mPageSetup);
581 if (gtkOrient == GTK_PAGE_ORIENTATION_LANDSCAPE ||
582 gtkOrient == GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE) {
583 double temp = *aWidth;
584 *aWidth = *aHeight;
585 *aHeight = temp;
587 return NS_OK;
590 NS_IMETHODIMP
591 nsPrintSettingsGTK::GetPageRanges(nsTArray<int32_t>& aPages) {
592 GtkPrintPages gtkRange = gtk_print_settings_get_print_pages(mPrintSettings);
593 if (gtkRange != GTK_PRINT_PAGES_RANGES) {
594 aPages.Clear();
595 return NS_OK;
598 gint ctRanges;
599 GtkPageRange* lstRanges =
600 gtk_print_settings_get_page_ranges(mPrintSettings, &ctRanges);
602 aPages.Clear();
604 for (gint i = 0; i < ctRanges; i++) {
605 aPages.AppendElement(lstRanges[i].start + 1);
606 aPages.AppendElement(lstRanges[i].end + 1);
609 g_free(lstRanges);
610 return NS_OK;
613 NS_IMETHODIMP
614 nsPrintSettingsGTK::GetResolution(int32_t* aResolution) {
615 *aResolution = gtk_print_settings_get_resolution(mPrintSettings);
616 return NS_OK;
619 NS_IMETHODIMP
620 nsPrintSettingsGTK::SetResolution(int32_t aResolution) {
621 gtk_print_settings_set_resolution(mPrintSettings, aResolution);
622 return NS_OK;
625 NS_IMETHODIMP
626 nsPrintSettingsGTK::GetDuplex(int32_t* aDuplex) {
627 NS_ENSURE_ARG_POINTER(aDuplex);
629 // Default to DuplexNone.
630 *aDuplex = kDuplexNone;
632 if (!gtk_print_settings_has_key(mPrintSettings, GTK_PRINT_SETTINGS_DUPLEX)) {
633 return NS_OK;
636 switch (gtk_print_settings_get_duplex(mPrintSettings)) {
637 case GTK_PRINT_DUPLEX_SIMPLEX:
638 *aDuplex = kDuplexNone;
639 break;
640 case GTK_PRINT_DUPLEX_HORIZONTAL:
641 *aDuplex = kDuplexFlipOnLongEdge;
642 break;
643 case GTK_PRINT_DUPLEX_VERTICAL:
644 *aDuplex = kDuplexFlipOnShortEdge;
645 break;
648 return NS_OK;
651 NS_IMETHODIMP
652 nsPrintSettingsGTK::SetDuplex(int32_t aDuplex) {
653 uint32_t duplex = static_cast<uint32_t>(aDuplex);
654 MOZ_ASSERT(duplex <= kDuplexFlipOnShortEdge,
655 "value is out of bounds for duplex enum");
657 // We want to set the GTK CUPS Duplex setting in addition to calling
658 // gtk_print_settings_set_duplex(). Some systems may look for one, or the
659 // other, so it is best to set them both consistently.
660 switch (duplex) {
661 case kDuplexNone:
662 gtk_print_settings_set(mPrintSettings, kCupsDuplex, kCupsDuplexNone);
663 gtk_print_settings_set_duplex(mPrintSettings, GTK_PRINT_DUPLEX_SIMPLEX);
664 break;
665 case kDuplexFlipOnLongEdge:
666 gtk_print_settings_set(mPrintSettings, kCupsDuplex, kCupsDuplexNoTumble);
667 gtk_print_settings_set_duplex(mPrintSettings,
668 GTK_PRINT_DUPLEX_HORIZONTAL);
669 break;
670 case kDuplexFlipOnShortEdge:
671 gtk_print_settings_set(mPrintSettings, kCupsDuplex, kCupsDuplexTumble);
672 gtk_print_settings_set_duplex(mPrintSettings, GTK_PRINT_DUPLEX_VERTICAL);
673 break;
676 return NS_OK;