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/. */
5
6 #include "nsPrintSettingsGTK.h"
7 #include "nsIFile.h"
8 #include "nsNetUtil.h"
9 #include <stdlib.h>
10 #include <algorithm>
11
12 static
ref_printer(GtkPrinter * aPrinter,gpointer aData)13 gboolean ref_printer(GtkPrinter *aPrinter, gpointer aData)
14 {
15 ((nsPrintSettingsGTK*) aData)->SetGtkPrinter(aPrinter);
16 return TRUE;
17 }
18
19 static
printer_enumerator(GtkPrinter * aPrinter,gpointer aData)20 gboolean printer_enumerator(GtkPrinter *aPrinter, gpointer aData)
21 {
22 if (gtk_printer_is_default(aPrinter))
23 return ref_printer(aPrinter, aData);
24
25 return FALSE; // Keep 'em coming...
26 }
27
28 static
moz_gtk_paper_size_copy_to_new_custom(GtkPaperSize * oldPaperSize)29 GtkPaperSize* moz_gtk_paper_size_copy_to_new_custom(GtkPaperSize* oldPaperSize)
30 {
31 // We make a "custom-ified" copy of the paper size so it can be changed later.
32 return gtk_paper_size_new_custom(gtk_paper_size_get_name(oldPaperSize),
33 gtk_paper_size_get_display_name(oldPaperSize),
34 gtk_paper_size_get_width(oldPaperSize, GTK_UNIT_INCH),
35 gtk_paper_size_get_height(oldPaperSize, GTK_UNIT_INCH),
36 GTK_UNIT_INCH);
37 }
38
NS_IMPL_ISUPPORTS_INHERITED(nsPrintSettingsGTK,nsPrintSettings,nsPrintSettingsGTK)39 NS_IMPL_ISUPPORTS_INHERITED(nsPrintSettingsGTK,
40 nsPrintSettings,
41 nsPrintSettingsGTK)
42
43 /** ---------------------------------------------------
44 */
45 nsPrintSettingsGTK::nsPrintSettingsGTK() :
46 mPageSetup(nullptr),
47 mPrintSettings(nullptr),
48 mGTKPrinter(nullptr),
49 mPrintSelectionOnly(false)
50 {
51 // The aim here is to set up the objects enough that silent printing works well.
52 // These will be replaced anyway if the print dialog is used.
53 mPrintSettings = gtk_print_settings_new();
54 GtkPageSetup* pageSetup = gtk_page_setup_new();
55 SetGtkPageSetup(pageSetup);
56 g_object_unref(pageSetup);
57
58 SetOutputFormat(nsIPrintSettings::kOutputFormatNative);
59 }
60
61 /** ---------------------------------------------------
62 */
~nsPrintSettingsGTK()63 nsPrintSettingsGTK::~nsPrintSettingsGTK()
64 {
65 if (mPageSetup) {
66 g_object_unref(mPageSetup);
67 mPageSetup = nullptr;
68 }
69 if (mPrintSettings) {
70 g_object_unref(mPrintSettings);
71 mPrintSettings = nullptr;
72 }
73 if (mGTKPrinter) {
74 g_object_unref(mGTKPrinter);
75 mGTKPrinter = nullptr;
76 }
77 }
78
79 /** ---------------------------------------------------
80 */
nsPrintSettingsGTK(const nsPrintSettingsGTK & aPS)81 nsPrintSettingsGTK::nsPrintSettingsGTK(const nsPrintSettingsGTK& aPS) :
82 mPageSetup(nullptr),
83 mPrintSettings(nullptr),
84 mGTKPrinter(nullptr),
85 mPrintSelectionOnly(false)
86 {
87 *this = aPS;
88 }
89
90 /** ---------------------------------------------------
91 */
operator =(const nsPrintSettingsGTK & rhs)92 nsPrintSettingsGTK& nsPrintSettingsGTK::operator=(const nsPrintSettingsGTK& rhs)
93 {
94 if (this == &rhs) {
95 return *this;
96 }
97
98 nsPrintSettings::operator=(rhs);
99
100 if (mPageSetup)
101 g_object_unref(mPageSetup);
102 mPageSetup = gtk_page_setup_copy(rhs.mPageSetup);
103 // NOTE: No need to re-initialize mUnwriteableMargin here (even
104 // though mPageSetup is changing). It'll be copied correctly by
105 // nsPrintSettings::operator=.
106
107 if (mPrintSettings)
108 g_object_unref(mPrintSettings);
109 mPrintSettings = gtk_print_settings_copy(rhs.mPrintSettings);
110
111 if (mGTKPrinter)
112 g_object_unref(mGTKPrinter);
113 mGTKPrinter = (GtkPrinter*) g_object_ref(rhs.mGTKPrinter);
114
115 mPrintSelectionOnly = rhs.mPrintSelectionOnly;
116
117 return *this;
118 }
119
120 /** -------------------------------------------
121 */
_Clone(nsIPrintSettings ** _retval)122 nsresult nsPrintSettingsGTK::_Clone(nsIPrintSettings **_retval)
123 {
124 NS_ENSURE_ARG_POINTER(_retval);
125 *_retval = nullptr;
126
127 nsPrintSettingsGTK *newSettings = new nsPrintSettingsGTK(*this);
128 if (!newSettings)
129 return NS_ERROR_FAILURE;
130 *_retval = newSettings;
131 NS_ADDREF(*_retval);
132 return NS_OK;
133 }
134
135
136 /** -------------------------------------------
137 */
138 NS_IMETHODIMP
_Assign(nsIPrintSettings * aPS)139 nsPrintSettingsGTK::_Assign(nsIPrintSettings *aPS)
140 {
141 nsPrintSettingsGTK *printSettingsGTK = static_cast<nsPrintSettingsGTK*>(aPS);
142 if (!printSettingsGTK)
143 return NS_ERROR_UNEXPECTED;
144 *this = *printSettingsGTK;
145 return NS_OK;
146 }
147
148 /** ---------------------------------------------------
149 */
150 void
SetGtkPageSetup(GtkPageSetup * aPageSetup)151 nsPrintSettingsGTK::SetGtkPageSetup(GtkPageSetup *aPageSetup)
152 {
153 if (mPageSetup)
154 g_object_unref(mPageSetup);
155
156 mPageSetup = (GtkPageSetup*) g_object_ref(aPageSetup);
157 InitUnwriteableMargin();
158
159 // If the paper size is not custom, then we make a custom copy of the
160 // GtkPaperSize, so it can be mutable. If a GtkPaperSize wasn't made as
161 // custom, its properties are immutable.
162 GtkPaperSize* paperSize = gtk_page_setup_get_paper_size(aPageSetup);
163 if (!gtk_paper_size_is_custom(paperSize)) {
164 GtkPaperSize* customPaperSize =
165 moz_gtk_paper_size_copy_to_new_custom(paperSize);
166 gtk_page_setup_set_paper_size(mPageSetup, customPaperSize);
167 gtk_paper_size_free(customPaperSize);
168 }
169 SaveNewPageSize();
170 }
171
172 /** ---------------------------------------------------
173 */
174 void
SetGtkPrintSettings(GtkPrintSettings * aPrintSettings)175 nsPrintSettingsGTK::SetGtkPrintSettings(GtkPrintSettings *aPrintSettings)
176 {
177 if (mPrintSettings)
178 g_object_unref(mPrintSettings);
179
180 mPrintSettings = (GtkPrintSettings*) g_object_ref(aPrintSettings);
181
182 GtkPaperSize* paperSize = gtk_print_settings_get_paper_size(aPrintSettings);
183 if (paperSize) {
184 GtkPaperSize* customPaperSize =
185 moz_gtk_paper_size_copy_to_new_custom(paperSize);
186 gtk_paper_size_free(paperSize);
187 gtk_page_setup_set_paper_size(mPageSetup, customPaperSize);
188 gtk_paper_size_free(customPaperSize);
189 } else {
190 // paperSize was null, and so we add the paper size in the GtkPageSetup to
191 // the settings.
192 SaveNewPageSize();
193 }
194 }
195
196 /** ---------------------------------------------------
197 */
198 void
SetGtkPrinter(GtkPrinter * aPrinter)199 nsPrintSettingsGTK::SetGtkPrinter(GtkPrinter *aPrinter)
200 {
201 if (mGTKPrinter)
202 g_object_unref(mGTKPrinter);
203
204 mGTKPrinter = (GtkPrinter*) g_object_ref(aPrinter);
205 }
206
GetOutputFormat(int16_t * aOutputFormat)207 NS_IMETHODIMP nsPrintSettingsGTK::GetOutputFormat(int16_t *aOutputFormat)
208 {
209 NS_ENSURE_ARG_POINTER(aOutputFormat);
210
211 int16_t format;
212 nsresult rv = nsPrintSettings::GetOutputFormat(&format);
213 if (NS_FAILED(rv)) {
214 return rv;
215 }
216
217 if (format == nsIPrintSettings::kOutputFormatNative) {
218 const gchar* fmtGTK =
219 gtk_print_settings_get(mPrintSettings,
220 GTK_PRINT_SETTINGS_OUTPUT_FILE_FORMAT);
221 if (fmtGTK) {
222 if (nsDependentCString(fmtGTK).EqualsIgnoreCase("pdf")) {
223 format = nsIPrintSettings::kOutputFormatPDF;
224 } else {
225 format = nsIPrintSettings::kOutputFormatPS;
226 }
227 } else if (GTK_IS_PRINTER(mGTKPrinter)) {
228 // Prior to gtk 2.24, gtk_printer_accepts_pdf() and
229 // gtk_printer_accepts_ps() always returned true regardless of the
230 // printer's capability.
231 bool shouldTrustGTK =
232 (gtk_major_version > 2 ||
233 (gtk_major_version == 2 && gtk_minor_version >= 24));
234 bool acceptsPDF = shouldTrustGTK && gtk_printer_accepts_pdf(mGTKPrinter);
235
236 format = acceptsPDF ? nsIPrintSettings::kOutputFormatPDF
237 : nsIPrintSettings::kOutputFormatPS;
238 }
239 }
240
241 *aOutputFormat = format;
242 return NS_OK;
243 }
244
245 /**
246 * Reimplementation of nsPrintSettings functions so that we get the values
247 * from the GTK objects rather than our own variables.
248 */
249
GetPrintRange(int16_t * aPrintRange)250 NS_IMETHODIMP nsPrintSettingsGTK::GetPrintRange(int16_t *aPrintRange)
251 {
252 NS_ENSURE_ARG_POINTER(aPrintRange);
253 if (mPrintSelectionOnly) {
254 *aPrintRange = kRangeSelection;
255 return NS_OK;
256 }
257
258 GtkPrintPages gtkRange = gtk_print_settings_get_print_pages(mPrintSettings);
259 if (gtkRange == GTK_PRINT_PAGES_RANGES)
260 *aPrintRange = kRangeSpecifiedPageRange;
261 else
262 *aPrintRange = kRangeAllPages;
263
264 return NS_OK;
265 }
SetPrintRange(int16_t aPrintRange)266 NS_IMETHODIMP nsPrintSettingsGTK::SetPrintRange(int16_t aPrintRange)
267 {
268 if (aPrintRange == kRangeSelection) {
269 mPrintSelectionOnly = true;
270 return NS_OK;
271 }
272
273 mPrintSelectionOnly = false;
274 if (aPrintRange == kRangeSpecifiedPageRange)
275 gtk_print_settings_set_print_pages(mPrintSettings, GTK_PRINT_PAGES_RANGES);
276 else
277 gtk_print_settings_set_print_pages(mPrintSettings, GTK_PRINT_PAGES_ALL);
278 return NS_OK;
279 }
280
281 NS_IMETHODIMP
GetStartPageRange(int32_t * aStartPageRange)282 nsPrintSettingsGTK::GetStartPageRange(int32_t *aStartPageRange)
283 {
284 gint ctRanges;
285 GtkPageRange* lstRanges = gtk_print_settings_get_page_ranges(mPrintSettings, &ctRanges);
286
287 // Make sure we got a range.
288 if (ctRanges < 1) {
289 *aStartPageRange = 1;
290 } else {
291 // GTK supports multiple page ranges; gecko only supports 1. So find
292 // the lowest start page.
293 int32_t start(lstRanges[0].start);
294 for (gint ii = 1; ii < ctRanges; ii++) {
295 start = std::min(lstRanges[ii].start, start);
296 }
297 *aStartPageRange = start + 1;
298 }
299
300 g_free(lstRanges);
301 return NS_OK;
302 }
303 NS_IMETHODIMP
SetStartPageRange(int32_t aStartPageRange)304 nsPrintSettingsGTK::SetStartPageRange(int32_t aStartPageRange)
305 {
306 int32_t endRange;
307 GetEndPageRange(&endRange);
308
309 GtkPageRange gtkRange;
310 gtkRange.start = aStartPageRange - 1;
311 gtkRange.end = endRange - 1;
312
313 gtk_print_settings_set_page_ranges(mPrintSettings, >kRange, 1);
314
315 return NS_OK;
316 }
317
318 NS_IMETHODIMP
GetEndPageRange(int32_t * aEndPageRange)319 nsPrintSettingsGTK::GetEndPageRange(int32_t *aEndPageRange)
320 {
321 gint ctRanges;
322 GtkPageRange* lstRanges = gtk_print_settings_get_page_ranges(mPrintSettings, &ctRanges);
323
324 if (ctRanges < 1) {
325 *aEndPageRange = 1;
326 } else {
327 int32_t end(lstRanges[0].end);
328 for (gint ii = 1; ii < ctRanges; ii++) {
329 end = std::max(lstRanges[ii].end, end);
330 }
331 *aEndPageRange = end + 1;
332 }
333
334 g_free(lstRanges);
335 return NS_OK;
336 }
337 NS_IMETHODIMP
SetEndPageRange(int32_t aEndPageRange)338 nsPrintSettingsGTK::SetEndPageRange(int32_t aEndPageRange)
339 {
340 int32_t startRange;
341 GetStartPageRange(&startRange);
342
343 GtkPageRange gtkRange;
344 gtkRange.start = startRange - 1;
345 gtkRange.end = aEndPageRange - 1;
346
347 gtk_print_settings_set_page_ranges(mPrintSettings, >kRange, 1);
348
349 return NS_OK;
350 }
351
352 NS_IMETHODIMP
GetPrintReversed(bool * aPrintReversed)353 nsPrintSettingsGTK::GetPrintReversed(bool *aPrintReversed)
354 {
355 *aPrintReversed = gtk_print_settings_get_reverse(mPrintSettings);
356 return NS_OK;
357 }
358 NS_IMETHODIMP
SetPrintReversed(bool aPrintReversed)359 nsPrintSettingsGTK::SetPrintReversed(bool aPrintReversed)
360 {
361 gtk_print_settings_set_reverse(mPrintSettings, aPrintReversed);
362 return NS_OK;
363 }
364
365 NS_IMETHODIMP
GetPrintInColor(bool * aPrintInColor)366 nsPrintSettingsGTK::GetPrintInColor(bool *aPrintInColor)
367 {
368 *aPrintInColor = gtk_print_settings_get_use_color(mPrintSettings);
369 return NS_OK;
370 }
371 NS_IMETHODIMP
SetPrintInColor(bool aPrintInColor)372 nsPrintSettingsGTK::SetPrintInColor(bool aPrintInColor)
373 {
374 gtk_print_settings_set_use_color(mPrintSettings, aPrintInColor);
375 return NS_OK;
376 }
377
378 NS_IMETHODIMP
GetOrientation(int32_t * aOrientation)379 nsPrintSettingsGTK::GetOrientation(int32_t *aOrientation)
380 {
381 NS_ENSURE_ARG_POINTER(aOrientation);
382
383 GtkPageOrientation gtkOrient = gtk_page_setup_get_orientation(mPageSetup);
384 switch (gtkOrient) {
385 case GTK_PAGE_ORIENTATION_LANDSCAPE:
386 case GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE:
387 *aOrientation = kLandscapeOrientation;
388 break;
389
390 case GTK_PAGE_ORIENTATION_PORTRAIT:
391 case GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT:
392 default:
393 *aOrientation = kPortraitOrientation;
394 }
395 return NS_OK;
396 }
397 NS_IMETHODIMP
SetOrientation(int32_t aOrientation)398 nsPrintSettingsGTK::SetOrientation(int32_t aOrientation)
399 {
400 GtkPageOrientation gtkOrient;
401 if (aOrientation == kLandscapeOrientation)
402 gtkOrient = GTK_PAGE_ORIENTATION_LANDSCAPE;
403 else
404 gtkOrient = GTK_PAGE_ORIENTATION_PORTRAIT;
405
406 gtk_print_settings_set_orientation(mPrintSettings, gtkOrient);
407 gtk_page_setup_set_orientation(mPageSetup, gtkOrient);
408 return NS_OK;
409 }
410
411 NS_IMETHODIMP
GetToFileName(char16_t ** aToFileName)412 nsPrintSettingsGTK::GetToFileName(char16_t * *aToFileName)
413 {
414 // Get the gtk output filename
415 const char* gtk_output_uri = gtk_print_settings_get(mPrintSettings, GTK_PRINT_SETTINGS_OUTPUT_URI);
416 if (!gtk_output_uri) {
417 *aToFileName = ToNewUnicode(mToFileName);
418 return NS_OK;
419 }
420
421 // Convert to an nsIFile
422 nsCOMPtr<nsIFile> file;
423 nsresult rv = NS_GetFileFromURLSpec(nsDependentCString(gtk_output_uri),
424 getter_AddRefs(file));
425 if (NS_FAILED(rv))
426 return rv;
427
428 // Extract the path
429 nsAutoString path;
430 rv = file->GetPath(path);
431 NS_ENSURE_SUCCESS(rv, rv);
432
433 *aToFileName = ToNewUnicode(path);
434 return NS_OK;
435 }
436
437 NS_IMETHODIMP
SetToFileName(const char16_t * aToFileName)438 nsPrintSettingsGTK::SetToFileName(const char16_t * aToFileName)
439 {
440 if (aToFileName[0] == 0) {
441 mToFileName.SetLength(0);
442 gtk_print_settings_set(mPrintSettings, GTK_PRINT_SETTINGS_OUTPUT_URI,
443 nullptr);
444 return NS_OK;
445 }
446
447 if (StringEndsWith(nsDependentString(aToFileName), NS_LITERAL_STRING(".ps"))) {
448 gtk_print_settings_set(mPrintSettings, GTK_PRINT_SETTINGS_OUTPUT_FILE_FORMAT, "ps");
449 } else {
450 gtk_print_settings_set(mPrintSettings, GTK_PRINT_SETTINGS_OUTPUT_FILE_FORMAT, "pdf");
451 }
452
453 nsCOMPtr<nsIFile> file;
454 nsresult rv = NS_NewLocalFile(nsDependentString(aToFileName), true,
455 getter_AddRefs(file));
456 NS_ENSURE_SUCCESS(rv, rv);
457
458 // Convert the nsIFile to a URL
459 nsAutoCString url;
460 rv = NS_GetURLSpecFromFile(file, url);
461 NS_ENSURE_SUCCESS(rv, rv);
462
463 gtk_print_settings_set(mPrintSettings, GTK_PRINT_SETTINGS_OUTPUT_URI, url.get());
464 mToFileName = aToFileName;
465
466 return NS_OK;
467 }
468
469 NS_IMETHODIMP
GetPrinterName(char16_t ** aPrinter)470 nsPrintSettingsGTK::GetPrinterName(char16_t * *aPrinter)
471 {
472 const char* gtkPrintName = gtk_print_settings_get_printer(mPrintSettings);
473 if (!gtkPrintName) {
474 if (GTK_IS_PRINTER(mGTKPrinter)) {
475 gtkPrintName = gtk_printer_get_name(mGTKPrinter);
476 } else {
477 // This mimics what nsPrintSettingsImpl does when we try to Get before we Set
478 nsXPIDLString nullPrintName;
479 *aPrinter = ToNewUnicode(nullPrintName);
480 return NS_OK;
481 }
482 }
483 *aPrinter = UTF8ToNewUnicode(nsDependentCString(gtkPrintName));
484 return NS_OK;
485 }
486
487 NS_IMETHODIMP
SetPrinterName(const char16_t * aPrinter)488 nsPrintSettingsGTK::SetPrinterName(const char16_t * aPrinter)
489 {
490 NS_ConvertUTF16toUTF8 gtkPrinter(aPrinter);
491
492 if (StringBeginsWith(gtkPrinter, NS_LITERAL_CSTRING("CUPS/"))) {
493 // Strip off "CUPS/"; GTK might recognize the rest
494 gtkPrinter.Cut(0, strlen("CUPS/"));
495 }
496
497 // Give mPrintSettings the passed-in printer name if either...
498 // - it has no printer name stored yet
499 // - it has an existing printer name that's different from
500 // the name passed to this function.
501 const char* oldPrinterName = gtk_print_settings_get_printer(mPrintSettings);
502 if (!oldPrinterName || !gtkPrinter.Equals(oldPrinterName)) {
503 mIsInitedFromPrinter = false;
504 mIsInitedFromPrefs = false;
505 gtk_print_settings_set_printer(mPrintSettings, gtkPrinter.get());
506 }
507
508 return NS_OK;
509 }
510
511 NS_IMETHODIMP
GetNumCopies(int32_t * aNumCopies)512 nsPrintSettingsGTK::GetNumCopies(int32_t *aNumCopies)
513 {
514 NS_ENSURE_ARG_POINTER(aNumCopies);
515 *aNumCopies = gtk_print_settings_get_n_copies(mPrintSettings);
516 return NS_OK;
517 }
518 NS_IMETHODIMP
SetNumCopies(int32_t aNumCopies)519 nsPrintSettingsGTK::SetNumCopies(int32_t aNumCopies)
520 {
521 gtk_print_settings_set_n_copies(mPrintSettings, aNumCopies);
522 return NS_OK;
523 }
524
525 NS_IMETHODIMP
GetScaling(double * aScaling)526 nsPrintSettingsGTK::GetScaling(double *aScaling)
527 {
528 *aScaling = gtk_print_settings_get_scale(mPrintSettings) / 100.0;
529 return NS_OK;
530 }
531
532 NS_IMETHODIMP
SetScaling(double aScaling)533 nsPrintSettingsGTK::SetScaling(double aScaling)
534 {
535 gtk_print_settings_set_scale(mPrintSettings, aScaling * 100.0);
536 return NS_OK;
537 }
538
539 NS_IMETHODIMP
GetPaperName(char16_t ** aPaperName)540 nsPrintSettingsGTK::GetPaperName(char16_t * *aPaperName)
541 {
542 NS_ENSURE_ARG_POINTER(aPaperName);
543 const gchar* name =
544 gtk_paper_size_get_name(gtk_page_setup_get_paper_size(mPageSetup));
545 *aPaperName = ToNewUnicode(NS_ConvertUTF8toUTF16(name));
546 return NS_OK;
547 }
548 NS_IMETHODIMP
SetPaperName(const char16_t * aPaperName)549 nsPrintSettingsGTK::SetPaperName(const char16_t * aPaperName)
550 {
551 NS_ConvertUTF16toUTF8 gtkPaperName(aPaperName);
552
553 // Convert these Gecko names to GTK names
554 if (gtkPaperName.EqualsIgnoreCase("letter"))
555 gtkPaperName.AssignLiteral(GTK_PAPER_NAME_LETTER);
556 else if (gtkPaperName.EqualsIgnoreCase("legal"))
557 gtkPaperName.AssignLiteral(GTK_PAPER_NAME_LEGAL);
558
559 GtkPaperSize* oldPaperSize = gtk_page_setup_get_paper_size(mPageSetup);
560 gdouble width = gtk_paper_size_get_width(oldPaperSize, GTK_UNIT_INCH);
561 gdouble height = gtk_paper_size_get_height(oldPaperSize, GTK_UNIT_INCH);
562
563 // Try to get the display name from the name so our paper size fits in the Page Setup dialog.
564 GtkPaperSize* paperSize = gtk_paper_size_new(gtkPaperName.get());
565 GtkPaperSize* customPaperSize =
566 gtk_paper_size_new_custom(gtkPaperName.get(),
567 gtk_paper_size_get_display_name(paperSize),
568 width, height, GTK_UNIT_INCH);
569 gtk_paper_size_free(paperSize);
570
571 gtk_page_setup_set_paper_size(mPageSetup, customPaperSize);
572 gtk_paper_size_free(customPaperSize);
573 SaveNewPageSize();
574 return NS_OK;
575 }
576
577 GtkUnit
GetGTKUnit(int16_t aGeckoUnit)578 nsPrintSettingsGTK::GetGTKUnit(int16_t aGeckoUnit)
579 {
580 if (aGeckoUnit == kPaperSizeMillimeters)
581 return GTK_UNIT_MM;
582 else
583 return GTK_UNIT_INCH;
584 }
585
586 void
SaveNewPageSize()587 nsPrintSettingsGTK::SaveNewPageSize()
588 {
589 gtk_print_settings_set_paper_size(mPrintSettings,
590 gtk_page_setup_get_paper_size(mPageSetup));
591 }
592
593 void
InitUnwriteableMargin()594 nsPrintSettingsGTK::InitUnwriteableMargin()
595 {
596 mUnwriteableMargin.SizeTo(
597 NS_INCHES_TO_INT_TWIPS(gtk_page_setup_get_top_margin(mPageSetup, GTK_UNIT_INCH)),
598 NS_INCHES_TO_INT_TWIPS(gtk_page_setup_get_right_margin(mPageSetup, GTK_UNIT_INCH)),
599 NS_INCHES_TO_INT_TWIPS(gtk_page_setup_get_bottom_margin(mPageSetup, GTK_UNIT_INCH)),
600 NS_INCHES_TO_INT_TWIPS(gtk_page_setup_get_left_margin(mPageSetup, GTK_UNIT_INCH))
601 );
602 }
603
604 /**
605 * NOTE: Need a custom set of SetUnwriteableMargin functions, because
606 * whenever we change mUnwriteableMargin, we must pass the change
607 * down to our GTKPageSetup object. (This is needed in order for us
608 * to give the correct default values in nsPrintDialogGTK.)
609 *
610 * It's important that the following functions pass
611 * mUnwriteableMargin values rather than aUnwriteableMargin values
612 * to gtk_page_setup_set_[blank]_margin, because the two may not be
613 * the same. (Specifically, negative values of aUnwriteableMargin
614 * are ignored by the nsPrintSettings::SetUnwriteableMargin functions.)
615 */
616 NS_IMETHODIMP
SetUnwriteableMarginInTwips(nsIntMargin & aUnwriteableMargin)617 nsPrintSettingsGTK::SetUnwriteableMarginInTwips(nsIntMargin& aUnwriteableMargin)
618 {
619 nsPrintSettings::SetUnwriteableMarginInTwips(aUnwriteableMargin);
620 gtk_page_setup_set_top_margin(mPageSetup,
621 NS_TWIPS_TO_INCHES(mUnwriteableMargin.top), GTK_UNIT_INCH);
622 gtk_page_setup_set_left_margin(mPageSetup,
623 NS_TWIPS_TO_INCHES(mUnwriteableMargin.left), GTK_UNIT_INCH);
624 gtk_page_setup_set_bottom_margin(mPageSetup,
625 NS_TWIPS_TO_INCHES(mUnwriteableMargin.bottom), GTK_UNIT_INCH);
626 gtk_page_setup_set_right_margin(mPageSetup,
627 NS_TWIPS_TO_INCHES(mUnwriteableMargin.right), GTK_UNIT_INCH);
628 return NS_OK;
629 }
630
631 NS_IMETHODIMP
SetUnwriteableMarginTop(double aUnwriteableMarginTop)632 nsPrintSettingsGTK::SetUnwriteableMarginTop(double aUnwriteableMarginTop)
633 {
634 nsPrintSettings::SetUnwriteableMarginTop(aUnwriteableMarginTop);
635 gtk_page_setup_set_top_margin(mPageSetup,
636 NS_TWIPS_TO_INCHES(mUnwriteableMargin.top), GTK_UNIT_INCH);
637 return NS_OK;
638 }
639
640 NS_IMETHODIMP
SetUnwriteableMarginLeft(double aUnwriteableMarginLeft)641 nsPrintSettingsGTK::SetUnwriteableMarginLeft(double aUnwriteableMarginLeft)
642 {
643 nsPrintSettings::SetUnwriteableMarginLeft(aUnwriteableMarginLeft);
644 gtk_page_setup_set_left_margin(mPageSetup,
645 NS_TWIPS_TO_INCHES(mUnwriteableMargin.left), GTK_UNIT_INCH);
646 return NS_OK;
647 }
648
649 NS_IMETHODIMP
SetUnwriteableMarginBottom(double aUnwriteableMarginBottom)650 nsPrintSettingsGTK::SetUnwriteableMarginBottom(double aUnwriteableMarginBottom)
651 {
652 nsPrintSettings::SetUnwriteableMarginBottom(aUnwriteableMarginBottom);
653 gtk_page_setup_set_bottom_margin(mPageSetup,
654 NS_TWIPS_TO_INCHES(mUnwriteableMargin.bottom), GTK_UNIT_INCH);
655 return NS_OK;
656 }
657
658 NS_IMETHODIMP
SetUnwriteableMarginRight(double aUnwriteableMarginRight)659 nsPrintSettingsGTK::SetUnwriteableMarginRight(double aUnwriteableMarginRight)
660 {
661 nsPrintSettings::SetUnwriteableMarginRight(aUnwriteableMarginRight);
662 gtk_page_setup_set_right_margin(mPageSetup,
663 NS_TWIPS_TO_INCHES(mUnwriteableMargin.right), GTK_UNIT_INCH);
664 return NS_OK;
665 }
666
667 NS_IMETHODIMP
GetPaperWidth(double * aPaperWidth)668 nsPrintSettingsGTK::GetPaperWidth(double *aPaperWidth)
669 {
670 NS_ENSURE_ARG_POINTER(aPaperWidth);
671 GtkPaperSize* paperSize = gtk_page_setup_get_paper_size(mPageSetup);
672 *aPaperWidth =
673 gtk_paper_size_get_width(paperSize, GetGTKUnit(mPaperSizeUnit));
674 return NS_OK;
675 }
676 NS_IMETHODIMP
SetPaperWidth(double aPaperWidth)677 nsPrintSettingsGTK::SetPaperWidth(double aPaperWidth)
678 {
679 GtkPaperSize* paperSize = gtk_page_setup_get_paper_size(mPageSetup);
680 gtk_paper_size_set_size(paperSize,
681 aPaperWidth,
682 gtk_paper_size_get_height(paperSize, GetGTKUnit(mPaperSizeUnit)),
683 GetGTKUnit(mPaperSizeUnit));
684 SaveNewPageSize();
685 return NS_OK;
686 }
687
688 NS_IMETHODIMP
GetPaperHeight(double * aPaperHeight)689 nsPrintSettingsGTK::GetPaperHeight(double *aPaperHeight)
690 {
691 NS_ENSURE_ARG_POINTER(aPaperHeight);
692 GtkPaperSize* paperSize = gtk_page_setup_get_paper_size(mPageSetup);
693 *aPaperHeight =
694 gtk_paper_size_get_height(paperSize, GetGTKUnit(mPaperSizeUnit));
695 return NS_OK;
696 }
697 NS_IMETHODIMP
SetPaperHeight(double aPaperHeight)698 nsPrintSettingsGTK::SetPaperHeight(double aPaperHeight)
699 {
700 GtkPaperSize* paperSize = gtk_page_setup_get_paper_size(mPageSetup);
701 gtk_paper_size_set_size(paperSize,
702 gtk_paper_size_get_width(paperSize, GetGTKUnit(mPaperSizeUnit)),
703 aPaperHeight,
704 GetGTKUnit(mPaperSizeUnit));
705 SaveNewPageSize();
706 return NS_OK;
707 }
708
709 NS_IMETHODIMP
SetPaperSizeUnit(int16_t aPaperSizeUnit)710 nsPrintSettingsGTK::SetPaperSizeUnit(int16_t aPaperSizeUnit)
711 {
712 // Convert units internally. e.g. they might have set the values while we're still in mm but
713 // they change to inch just afterwards, expecting that their sizes are in inches.
714 GtkPaperSize* paperSize = gtk_page_setup_get_paper_size(mPageSetup);
715 gtk_paper_size_set_size(paperSize,
716 gtk_paper_size_get_width(paperSize, GetGTKUnit(mPaperSizeUnit)),
717 gtk_paper_size_get_height(paperSize, GetGTKUnit(mPaperSizeUnit)),
718 GetGTKUnit(aPaperSizeUnit));
719 SaveNewPageSize();
720
721 mPaperSizeUnit = aPaperSizeUnit;
722 return NS_OK;
723 }
724
725 NS_IMETHODIMP
GetEffectivePageSize(double * aWidth,double * aHeight)726 nsPrintSettingsGTK::GetEffectivePageSize(double *aWidth, double *aHeight)
727 {
728 GtkPaperSize* paperSize = gtk_page_setup_get_paper_size(mPageSetup);
729 *aWidth = NS_INCHES_TO_INT_TWIPS(gtk_paper_size_get_width(paperSize, GTK_UNIT_INCH));
730 *aHeight = NS_INCHES_TO_INT_TWIPS(gtk_paper_size_get_height(paperSize, GTK_UNIT_INCH));
731
732 GtkPageOrientation gtkOrient = gtk_page_setup_get_orientation(mPageSetup);
733
734 if (gtkOrient == GTK_PAGE_ORIENTATION_LANDSCAPE ||
735 gtkOrient == GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE) {
736 double temp = *aWidth;
737 *aWidth = *aHeight;
738 *aHeight = temp;
739 }
740 return NS_OK;
741 }
742
743 NS_IMETHODIMP
SetupSilentPrinting()744 nsPrintSettingsGTK::SetupSilentPrinting()
745 {
746 // We have to get a printer here, rather than when the print settings are constructed.
747 // This is because when we request sync, GTK makes us wait in the *event loop* while waiting
748 // for the enumeration to finish. We must do this when event loop runs are expected.
749 gtk_enumerate_printers(printer_enumerator, this, nullptr, TRUE);
750
751 // XXX If no default printer set, get the first one.
752 if (!GTK_IS_PRINTER(mGTKPrinter))
753 gtk_enumerate_printers(ref_printer, this, nullptr, TRUE);
754
755 return NS_OK;
756 }
757
758 NS_IMETHODIMP
GetPageRanges(nsTArray<int32_t> & aPages)759 nsPrintSettingsGTK::GetPageRanges(nsTArray<int32_t> &aPages)
760 {
761 gint ctRanges;
762 GtkPageRange* lstRanges = gtk_print_settings_get_page_ranges(mPrintSettings, &ctRanges);
763
764 aPages.Clear();
765
766 if (ctRanges > 1) {
767 for (gint i = 0; i < ctRanges; i++) {
768 aPages.AppendElement(lstRanges[i].start+1);
769 aPages.AppendElement(lstRanges[i].end+1);
770 }
771 }
772
773 g_free(lstRanges);
774 return NS_OK;
775 }
776
777 NS_IMETHODIMP
GetResolution(int32_t * aResolution)778 nsPrintSettingsGTK::GetResolution(int32_t *aResolution)
779 {
780 if (!gtk_print_settings_has_key(mPrintSettings, GTK_PRINT_SETTINGS_RESOLUTION))
781 return NS_ERROR_FAILURE;
782 *aResolution = gtk_print_settings_get_resolution(mPrintSettings);
783 return NS_OK;
784 }
785
786 NS_IMETHODIMP
SetResolution(int32_t aResolution)787 nsPrintSettingsGTK::SetResolution(int32_t aResolution)
788 {
789 gtk_print_settings_set_resolution(mPrintSettings, aResolution);
790 return NS_OK;
791 }
792
793 NS_IMETHODIMP
GetDuplex(int32_t * aDuplex)794 nsPrintSettingsGTK::GetDuplex(int32_t *aDuplex)
795 {
796 if (!gtk_print_settings_has_key(mPrintSettings, GTK_PRINT_SETTINGS_DUPLEX)) {
797 *aDuplex = GTK_PRINT_DUPLEX_SIMPLEX;
798 } else {
799 *aDuplex = gtk_print_settings_get_duplex(mPrintSettings);
800 }
801 return NS_OK;
802 }
803
804 NS_IMETHODIMP
SetDuplex(int32_t aDuplex)805 nsPrintSettingsGTK::SetDuplex(int32_t aDuplex)
806 {
807 MOZ_ASSERT(aDuplex >= GTK_PRINT_DUPLEX_SIMPLEX &&
808 aDuplex <= GTK_PRINT_DUPLEX_VERTICAL,
809 "value is out of bounds for GtkPrintDuplex enum");
810 gtk_print_settings_set_duplex(mPrintSettings, static_cast<GtkPrintDuplex>(aDuplex));
811 return NS_OK;
812 }
813
814