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