Bug 1807268 - Fix verifyOpenAllInNewTabsOptionTest UI test r=ohorvath
[gecko.git] / widget / gtk / nsPrintSettingsGTK.cpp
bloba101f44fcb78c5c865b59268d9835580eb6ef932
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);
100 if (rhs.mGTKPrinter) {
101 g_object_ref(rhs.mGTKPrinter);
103 mGTKPrinter = rhs.mGTKPrinter;
105 return *this;
108 /** -------------------------------------------
110 nsresult nsPrintSettingsGTK::_Clone(nsIPrintSettings** _retval) {
111 NS_ENSURE_ARG_POINTER(_retval);
112 *_retval = nullptr;
114 nsPrintSettingsGTK* newSettings = new nsPrintSettingsGTK(*this);
115 if (!newSettings) return NS_ERROR_FAILURE;
116 *_retval = newSettings;
117 NS_ADDREF(*_retval);
118 return NS_OK;
121 /** -------------------------------------------
123 NS_IMETHODIMP
124 nsPrintSettingsGTK::_Assign(nsIPrintSettings* aPS) {
125 nsPrintSettingsGTK* printSettingsGTK = static_cast<nsPrintSettingsGTK*>(aPS);
126 if (!printSettingsGTK) return NS_ERROR_UNEXPECTED;
127 *this = *printSettingsGTK;
128 return NS_OK;
131 /** ---------------------------------------------------
133 void nsPrintSettingsGTK::SetGtkPageSetup(GtkPageSetup* aPageSetup) {
134 if (mPageSetup) g_object_unref(mPageSetup);
136 mPageSetup = (GtkPageSetup*)g_object_ref(aPageSetup);
137 InitUnwriteableMargin();
139 // If the paper size is not custom, then we make a custom copy of the
140 // GtkPaperSize, so it can be mutable. If a GtkPaperSize wasn't made as
141 // custom, its properties are immutable.
142 GtkPaperSize* paperSize = gtk_page_setup_get_paper_size(aPageSetup);
143 if (!gtk_paper_size_is_custom(paperSize)) {
144 GtkPaperSize* customPaperSize =
145 moz_gtk_paper_size_copy_to_new_custom(paperSize);
146 gtk_page_setup_set_paper_size(mPageSetup, customPaperSize);
147 gtk_paper_size_free(customPaperSize);
149 SaveNewPageSize();
152 /** ---------------------------------------------------
154 void nsPrintSettingsGTK::SetGtkPrintSettings(GtkPrintSettings* aPrintSettings) {
155 if (mPrintSettings) g_object_unref(mPrintSettings);
157 mPrintSettings = (GtkPrintSettings*)g_object_ref(aPrintSettings);
159 GtkPaperSize* paperSize = gtk_print_settings_get_paper_size(aPrintSettings);
160 if (paperSize) {
161 GtkPaperSize* customPaperSize =
162 moz_gtk_paper_size_copy_to_new_custom(paperSize);
163 gtk_paper_size_free(paperSize);
164 gtk_page_setup_set_paper_size(mPageSetup, customPaperSize);
165 gtk_paper_size_free(customPaperSize);
166 } else {
167 // paperSize was null, and so we add the paper size in the GtkPageSetup to
168 // the settings.
169 SaveNewPageSize();
173 /** ---------------------------------------------------
175 void nsPrintSettingsGTK::SetGtkPrinter(GtkPrinter* aPrinter) {
176 if (mGTKPrinter) g_object_unref(mGTKPrinter);
178 mGTKPrinter = (GtkPrinter*)g_object_ref(aPrinter);
181 NS_IMETHODIMP nsPrintSettingsGTK::GetOutputFormat(int16_t* aOutputFormat) {
182 NS_ENSURE_ARG_POINTER(aOutputFormat);
184 int16_t format;
185 nsresult rv = nsPrintSettings::GetOutputFormat(&format);
186 if (NS_FAILED(rv)) {
187 return rv;
190 if (format == nsIPrintSettings::kOutputFormatNative &&
191 GTK_IS_PRINTER(mGTKPrinter)) {
192 format = nsIPrintSettings::kOutputFormatPDF;
195 *aOutputFormat = format;
196 return NS_OK;
200 * Reimplementation of nsPrintSettings functions so that we get the values
201 * from the GTK objects rather than our own variables.
204 NS_IMETHODIMP
205 nsPrintSettingsGTK::SetPageRanges(const nsTArray<int32_t>& aRanges) {
206 if (aRanges.Length() % 2 != 0) {
207 return NS_ERROR_FAILURE;
210 gtk_print_settings_set_print_pages(
211 mPrintSettings,
212 aRanges.IsEmpty() ? GTK_PRINT_PAGES_ALL : GTK_PRINT_PAGES_RANGES);
214 nsTArray<GtkPageRange> ranges;
215 ranges.SetCapacity(aRanges.Length() / 2);
216 for (size_t i = 0; i < aRanges.Length(); i += 2) {
217 GtkPageRange* gtkRange = ranges.AppendElement();
218 gtkRange->start = aRanges[i] - 1;
219 gtkRange->end = aRanges[i + 1] - 1;
222 gtk_print_settings_set_page_ranges(mPrintSettings, ranges.Elements(),
223 ranges.Length());
224 return NS_OK;
227 NS_IMETHODIMP
228 nsPrintSettingsGTK::GetPrintReversed(bool* aPrintReversed) {
229 *aPrintReversed = gtk_print_settings_get_reverse(mPrintSettings);
230 return NS_OK;
232 NS_IMETHODIMP
233 nsPrintSettingsGTK::SetPrintReversed(bool aPrintReversed) {
234 gtk_print_settings_set_reverse(mPrintSettings, aPrintReversed);
235 return NS_OK;
238 NS_IMETHODIMP
239 nsPrintSettingsGTK::GetPrintInColor(bool* aPrintInColor) {
240 *aPrintInColor = gtk_print_settings_get_use_color(mPrintSettings);
241 return NS_OK;
243 NS_IMETHODIMP
244 nsPrintSettingsGTK::SetPrintInColor(bool aPrintInColor) {
245 gtk_print_settings_set_use_color(mPrintSettings, aPrintInColor);
246 return NS_OK;
249 NS_IMETHODIMP
250 nsPrintSettingsGTK::GetOrientation(int32_t* aOrientation) {
251 NS_ENSURE_ARG_POINTER(aOrientation);
253 GtkPageOrientation gtkOrient = gtk_page_setup_get_orientation(mPageSetup);
254 switch (gtkOrient) {
255 case GTK_PAGE_ORIENTATION_LANDSCAPE:
256 case GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE:
257 *aOrientation = kLandscapeOrientation;
258 break;
260 case GTK_PAGE_ORIENTATION_PORTRAIT:
261 case GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT:
262 default:
263 *aOrientation = kPortraitOrientation;
265 return NS_OK;
267 NS_IMETHODIMP
268 nsPrintSettingsGTK::SetOrientation(int32_t aOrientation) {
269 GtkPageOrientation gtkOrient;
270 if (aOrientation == kLandscapeOrientation)
271 gtkOrient = GTK_PAGE_ORIENTATION_LANDSCAPE;
272 else
273 gtkOrient = GTK_PAGE_ORIENTATION_PORTRAIT;
275 gtk_print_settings_set_orientation(mPrintSettings, gtkOrient);
276 gtk_page_setup_set_orientation(mPageSetup, gtkOrient);
277 return NS_OK;
280 NS_IMETHODIMP
281 nsPrintSettingsGTK::GetToFileName(nsAString& aToFileName) {
282 // Get the gtk output filename
283 const char* gtk_output_uri =
284 gtk_print_settings_get(mPrintSettings, GTK_PRINT_SETTINGS_OUTPUT_URI);
285 if (!gtk_output_uri) {
286 aToFileName = mToFileName;
287 return NS_OK;
290 // Convert to an nsIFile
291 nsCOMPtr<nsIFile> file;
292 nsresult rv = NS_GetFileFromURLSpec(nsDependentCString(gtk_output_uri),
293 getter_AddRefs(file));
294 if (NS_FAILED(rv)) return rv;
296 // Extract the path
297 return file->GetPath(aToFileName);
300 NS_IMETHODIMP
301 nsPrintSettingsGTK::SetToFileName(const nsAString& aToFileName) {
302 if (aToFileName.IsEmpty()) {
303 mToFileName.SetLength(0);
304 gtk_print_settings_set(mPrintSettings, GTK_PRINT_SETTINGS_OUTPUT_URI,
305 nullptr);
306 return NS_OK;
309 gtk_print_settings_set(mPrintSettings, GTK_PRINT_SETTINGS_OUTPUT_FILE_FORMAT,
310 "pdf");
312 nsCOMPtr<nsIFile> file;
313 nsresult rv = NS_NewLocalFile(aToFileName, true, getter_AddRefs(file));
314 NS_ENSURE_SUCCESS(rv, rv);
316 // Convert the nsIFile to a URL
317 nsAutoCString url;
318 rv = NS_GetURLSpecFromFile(file, url);
319 NS_ENSURE_SUCCESS(rv, rv);
321 gtk_print_settings_set(mPrintSettings, GTK_PRINT_SETTINGS_OUTPUT_URI,
322 url.get());
323 mToFileName = aToFileName;
325 return NS_OK;
328 NS_IMETHODIMP
329 nsPrintSettingsGTK::GetPrinterName(nsAString& aPrinter) {
330 const char* gtkPrintName = gtk_print_settings_get_printer(mPrintSettings);
331 if (!gtkPrintName) {
332 if (GTK_IS_PRINTER(mGTKPrinter)) {
333 gtkPrintName = gtk_printer_get_name(mGTKPrinter);
334 } else {
335 // This mimics what nsPrintSettingsImpl does when we try to Get before we
336 // Set
337 aPrinter.Truncate();
338 return NS_OK;
341 CopyUTF8toUTF16(mozilla::MakeStringSpan(gtkPrintName), aPrinter);
342 return NS_OK;
345 NS_IMETHODIMP
346 nsPrintSettingsGTK::SetPrinterName(const nsAString& aPrinter) {
347 NS_ConvertUTF16toUTF8 gtkPrinter(aPrinter);
349 if (StringBeginsWith(gtkPrinter, "CUPS/"_ns)) {
350 // Strip off "CUPS/"; GTK might recognize the rest
351 gtkPrinter.Cut(0, strlen("CUPS/"));
354 // Give mPrintSettings the passed-in printer name if either...
355 // - it has no printer name stored yet
356 // - it has an existing printer name that's different from
357 // the name passed to this function.
358 const char* oldPrinterName = gtk_print_settings_get_printer(mPrintSettings);
359 if (!oldPrinterName || !gtkPrinter.Equals(oldPrinterName)) {
360 mIsInitedFromPrinter = false;
361 mIsInitedFromPrefs = false;
362 gtk_print_settings_set_printer(mPrintSettings, gtkPrinter.get());
365 return NS_OK;
368 NS_IMETHODIMP
369 nsPrintSettingsGTK::GetNumCopies(int32_t* aNumCopies) {
370 NS_ENSURE_ARG_POINTER(aNumCopies);
371 *aNumCopies = gtk_print_settings_get_n_copies(mPrintSettings);
372 return NS_OK;
374 NS_IMETHODIMP
375 nsPrintSettingsGTK::SetNumCopies(int32_t aNumCopies) {
376 gtk_print_settings_set_n_copies(mPrintSettings, aNumCopies);
377 return NS_OK;
380 NS_IMETHODIMP
381 nsPrintSettingsGTK::GetScaling(double* aScaling) {
382 *aScaling = gtk_print_settings_get_scale(mPrintSettings) / 100.0;
383 return NS_OK;
386 NS_IMETHODIMP
387 nsPrintSettingsGTK::SetScaling(double aScaling) {
388 gtk_print_settings_set_scale(mPrintSettings, aScaling * 100.0);
389 return NS_OK;
392 NS_IMETHODIMP
393 nsPrintSettingsGTK::GetPaperId(nsAString& aPaperId) {
394 const gchar* name =
395 gtk_paper_size_get_name(gtk_page_setup_get_paper_size(mPageSetup));
396 CopyUTF8toUTF16(mozilla::MakeStringSpan(name), aPaperId);
397 return NS_OK;
399 NS_IMETHODIMP
400 nsPrintSettingsGTK::SetPaperId(const nsAString& aPaperId) {
401 NS_ConvertUTF16toUTF8 gtkPaperName(aPaperId);
403 // Convert these Gecko names to GTK names
404 // XXX (jfkthame): is this still relevant?
405 if (gtkPaperName.EqualsIgnoreCase("letter"))
406 gtkPaperName.AssignLiteral(GTK_PAPER_NAME_LETTER);
407 else if (gtkPaperName.EqualsIgnoreCase("legal"))
408 gtkPaperName.AssignLiteral(GTK_PAPER_NAME_LEGAL);
410 GtkPaperSize* oldPaperSize = gtk_page_setup_get_paper_size(mPageSetup);
411 gdouble width = gtk_paper_size_get_width(oldPaperSize, GTK_UNIT_INCH);
412 gdouble height = gtk_paper_size_get_height(oldPaperSize, GTK_UNIT_INCH);
414 // Try to get the display name from the name so our paper size fits in the
415 // Page Setup dialog.
416 GtkPaperSize* paperSize = gtk_paper_size_new(gtkPaperName.get());
417 GtkPaperSize* customPaperSize = gtk_paper_size_new_custom(
418 gtkPaperName.get(), gtk_paper_size_get_display_name(paperSize), width,
419 height, GTK_UNIT_INCH);
420 gtk_paper_size_free(paperSize);
422 gtk_page_setup_set_paper_size(mPageSetup, customPaperSize);
423 gtk_paper_size_free(customPaperSize);
424 SaveNewPageSize();
425 return NS_OK;
428 GtkUnit nsPrintSettingsGTK::GetGTKUnit(int16_t aGeckoUnit) {
429 if (aGeckoUnit == kPaperSizeMillimeters)
430 return GTK_UNIT_MM;
431 else
432 return GTK_UNIT_INCH;
435 void nsPrintSettingsGTK::SaveNewPageSize() {
436 gtk_print_settings_set_paper_size(mPrintSettings,
437 gtk_page_setup_get_paper_size(mPageSetup));
440 void nsPrintSettingsGTK::InitUnwriteableMargin() {
441 mUnwriteableMargin.SizeTo(
442 NS_INCHES_TO_INT_TWIPS(
443 gtk_page_setup_get_top_margin(mPageSetup, GTK_UNIT_INCH)),
444 NS_INCHES_TO_INT_TWIPS(
445 gtk_page_setup_get_right_margin(mPageSetup, GTK_UNIT_INCH)),
446 NS_INCHES_TO_INT_TWIPS(
447 gtk_page_setup_get_bottom_margin(mPageSetup, GTK_UNIT_INCH)),
448 NS_INCHES_TO_INT_TWIPS(
449 gtk_page_setup_get_left_margin(mPageSetup, GTK_UNIT_INCH)));
453 * NOTE: Need a custom set of SetUnwriteableMargin functions, because
454 * whenever we change mUnwriteableMargin, we must pass the change
455 * down to our GTKPageSetup object. (This is needed in order for us
456 * to give the correct default values in nsPrintDialogGTK.)
458 * It's important that the following functions pass
459 * mUnwriteableMargin values rather than aUnwriteableMargin values
460 * to gtk_page_setup_set_[blank]_margin, because the two may not be
461 * the same. (Specifically, negative values of aUnwriteableMargin
462 * are ignored by the nsPrintSettings::SetUnwriteableMargin functions.)
464 NS_IMETHODIMP
465 nsPrintSettingsGTK::SetUnwriteableMarginInTwips(
466 nsIntMargin& aUnwriteableMargin) {
467 nsPrintSettings::SetUnwriteableMarginInTwips(aUnwriteableMargin);
468 gtk_page_setup_set_top_margin(
469 mPageSetup, NS_TWIPS_TO_INCHES(mUnwriteableMargin.top), GTK_UNIT_INCH);
470 gtk_page_setup_set_left_margin(
471 mPageSetup, NS_TWIPS_TO_INCHES(mUnwriteableMargin.left), GTK_UNIT_INCH);
472 gtk_page_setup_set_bottom_margin(
473 mPageSetup, NS_TWIPS_TO_INCHES(mUnwriteableMargin.bottom), GTK_UNIT_INCH);
474 gtk_page_setup_set_right_margin(
475 mPageSetup, NS_TWIPS_TO_INCHES(mUnwriteableMargin.right), GTK_UNIT_INCH);
476 return NS_OK;
479 NS_IMETHODIMP
480 nsPrintSettingsGTK::SetUnwriteableMarginTop(double aUnwriteableMarginTop) {
481 nsPrintSettings::SetUnwriteableMarginTop(aUnwriteableMarginTop);
482 gtk_page_setup_set_top_margin(
483 mPageSetup, NS_TWIPS_TO_INCHES(mUnwriteableMargin.top), GTK_UNIT_INCH);
484 return NS_OK;
487 NS_IMETHODIMP
488 nsPrintSettingsGTK::SetUnwriteableMarginLeft(double aUnwriteableMarginLeft) {
489 nsPrintSettings::SetUnwriteableMarginLeft(aUnwriteableMarginLeft);
490 gtk_page_setup_set_left_margin(
491 mPageSetup, NS_TWIPS_TO_INCHES(mUnwriteableMargin.left), GTK_UNIT_INCH);
492 return NS_OK;
495 NS_IMETHODIMP
496 nsPrintSettingsGTK::SetUnwriteableMarginBottom(
497 double aUnwriteableMarginBottom) {
498 nsPrintSettings::SetUnwriteableMarginBottom(aUnwriteableMarginBottom);
499 gtk_page_setup_set_bottom_margin(
500 mPageSetup, NS_TWIPS_TO_INCHES(mUnwriteableMargin.bottom), GTK_UNIT_INCH);
501 return NS_OK;
504 NS_IMETHODIMP
505 nsPrintSettingsGTK::SetUnwriteableMarginRight(double aUnwriteableMarginRight) {
506 nsPrintSettings::SetUnwriteableMarginRight(aUnwriteableMarginRight);
507 gtk_page_setup_set_right_margin(
508 mPageSetup, NS_TWIPS_TO_INCHES(mUnwriteableMargin.right), GTK_UNIT_INCH);
509 return NS_OK;
512 NS_IMETHODIMP
513 nsPrintSettingsGTK::GetPaperWidth(double* aPaperWidth) {
514 NS_ENSURE_ARG_POINTER(aPaperWidth);
515 GtkPaperSize* paperSize = gtk_page_setup_get_paper_size(mPageSetup);
516 *aPaperWidth =
517 gtk_paper_size_get_width(paperSize, GetGTKUnit(mPaperSizeUnit));
518 return NS_OK;
520 NS_IMETHODIMP
521 nsPrintSettingsGTK::SetPaperWidth(double aPaperWidth) {
522 GtkPaperSize* paperSize = gtk_page_setup_get_paper_size(mPageSetup);
523 gtk_paper_size_set_size(
524 paperSize, aPaperWidth,
525 gtk_paper_size_get_height(paperSize, GetGTKUnit(mPaperSizeUnit)),
526 GetGTKUnit(mPaperSizeUnit));
527 SaveNewPageSize();
528 return NS_OK;
531 NS_IMETHODIMP
532 nsPrintSettingsGTK::GetPaperHeight(double* aPaperHeight) {
533 NS_ENSURE_ARG_POINTER(aPaperHeight);
534 GtkPaperSize* paperSize = gtk_page_setup_get_paper_size(mPageSetup);
535 *aPaperHeight =
536 gtk_paper_size_get_height(paperSize, GetGTKUnit(mPaperSizeUnit));
537 return NS_OK;
539 NS_IMETHODIMP
540 nsPrintSettingsGTK::SetPaperHeight(double aPaperHeight) {
541 GtkPaperSize* paperSize = gtk_page_setup_get_paper_size(mPageSetup);
542 gtk_paper_size_set_size(
543 paperSize,
544 gtk_paper_size_get_width(paperSize, GetGTKUnit(mPaperSizeUnit)),
545 aPaperHeight, GetGTKUnit(mPaperSizeUnit));
546 SaveNewPageSize();
547 return NS_OK;
550 NS_IMETHODIMP
551 nsPrintSettingsGTK::SetPaperSizeUnit(int16_t aPaperSizeUnit) {
552 // Convert units internally. e.g. they might have set the values while we're
553 // still in mm but they change to inch just afterwards, expecting that their
554 // sizes are in inches.
555 GtkPaperSize* paperSize = gtk_page_setup_get_paper_size(mPageSetup);
556 gtk_paper_size_set_size(
557 paperSize,
558 gtk_paper_size_get_width(paperSize, GetGTKUnit(mPaperSizeUnit)),
559 gtk_paper_size_get_height(paperSize, GetGTKUnit(mPaperSizeUnit)),
560 GetGTKUnit(aPaperSizeUnit));
561 SaveNewPageSize();
563 mPaperSizeUnit = aPaperSizeUnit;
564 return NS_OK;
567 NS_IMETHODIMP
568 nsPrintSettingsGTK::GetEffectivePageSize(double* aWidth, double* aHeight) {
569 GtkPaperSize* paperSize = gtk_page_setup_get_paper_size(mPageSetup);
570 if (mPaperSizeUnit == kPaperSizeInches) {
571 *aWidth =
572 NS_INCHES_TO_TWIPS(gtk_paper_size_get_width(paperSize, GTK_UNIT_INCH));
573 *aHeight =
574 NS_INCHES_TO_TWIPS(gtk_paper_size_get_height(paperSize, GTK_UNIT_INCH));
575 } else {
576 MOZ_ASSERT(mPaperSizeUnit == kPaperSizeMillimeters,
577 "unexpected paper size unit");
578 *aWidth = NS_MILLIMETERS_TO_TWIPS(
579 gtk_paper_size_get_width(paperSize, GTK_UNIT_MM));
580 *aHeight = NS_MILLIMETERS_TO_TWIPS(
581 gtk_paper_size_get_height(paperSize, GTK_UNIT_MM));
583 GtkPageOrientation gtkOrient = gtk_page_setup_get_orientation(mPageSetup);
585 if (gtkOrient == GTK_PAGE_ORIENTATION_LANDSCAPE ||
586 gtkOrient == GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE) {
587 double temp = *aWidth;
588 *aWidth = *aHeight;
589 *aHeight = temp;
591 return NS_OK;
594 NS_IMETHODIMP
595 nsPrintSettingsGTK::GetPageRanges(nsTArray<int32_t>& aPages) {
596 GtkPrintPages gtkRange = gtk_print_settings_get_print_pages(mPrintSettings);
597 if (gtkRange != GTK_PRINT_PAGES_RANGES) {
598 aPages.Clear();
599 return NS_OK;
602 gint ctRanges;
603 GtkPageRange* lstRanges =
604 gtk_print_settings_get_page_ranges(mPrintSettings, &ctRanges);
606 aPages.Clear();
608 for (gint i = 0; i < ctRanges; i++) {
609 aPages.AppendElement(lstRanges[i].start + 1);
610 aPages.AppendElement(lstRanges[i].end + 1);
613 g_free(lstRanges);
614 return NS_OK;
617 NS_IMETHODIMP
618 nsPrintSettingsGTK::GetResolution(int32_t* aResolution) {
619 *aResolution = gtk_print_settings_get_resolution(mPrintSettings);
620 return NS_OK;
623 NS_IMETHODIMP
624 nsPrintSettingsGTK::SetResolution(int32_t aResolution) {
625 gtk_print_settings_set_resolution(mPrintSettings, aResolution);
626 return NS_OK;
629 NS_IMETHODIMP
630 nsPrintSettingsGTK::GetDuplex(int32_t* aDuplex) {
631 NS_ENSURE_ARG_POINTER(aDuplex);
633 // Default to DuplexNone.
634 *aDuplex = kDuplexNone;
636 if (!gtk_print_settings_has_key(mPrintSettings, GTK_PRINT_SETTINGS_DUPLEX)) {
637 return NS_OK;
640 switch (gtk_print_settings_get_duplex(mPrintSettings)) {
641 case GTK_PRINT_DUPLEX_SIMPLEX:
642 *aDuplex = kDuplexNone;
643 break;
644 case GTK_PRINT_DUPLEX_HORIZONTAL:
645 *aDuplex = kDuplexFlipOnLongEdge;
646 break;
647 case GTK_PRINT_DUPLEX_VERTICAL:
648 *aDuplex = kDuplexFlipOnShortEdge;
649 break;
652 return NS_OK;
655 NS_IMETHODIMP
656 nsPrintSettingsGTK::SetDuplex(int32_t aDuplex) {
657 uint32_t duplex = static_cast<uint32_t>(aDuplex);
658 MOZ_ASSERT(duplex <= kDuplexFlipOnShortEdge,
659 "value is out of bounds for duplex enum");
661 // We want to set the GTK CUPS Duplex setting in addition to calling
662 // gtk_print_settings_set_duplex(). Some systems may look for one, or the
663 // other, so it is best to set them both consistently.
664 switch (duplex) {
665 case kDuplexNone:
666 gtk_print_settings_set(mPrintSettings, kCupsDuplex, kCupsDuplexNone);
667 gtk_print_settings_set_duplex(mPrintSettings, GTK_PRINT_DUPLEX_SIMPLEX);
668 break;
669 case kDuplexFlipOnLongEdge:
670 gtk_print_settings_set(mPrintSettings, kCupsDuplex, kCupsDuplexNoTumble);
671 gtk_print_settings_set_duplex(mPrintSettings,
672 GTK_PRINT_DUPLEX_HORIZONTAL);
673 break;
674 case kDuplexFlipOnShortEdge:
675 gtk_print_settings_set(mPrintSettings, kCupsDuplex, kCupsDuplexTumble);
676 gtk_print_settings_set_duplex(mPrintSettings, GTK_PRINT_DUPLEX_VERTICAL);
677 break;
680 return NS_OK;