widget/gtk/nsPrintSettingsGTK.cpp

Thu, 15 Jan 2015 15:59:08 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 15:59:08 +0100
branch
TOR_BUG_9701
changeset 10
ac0c01689b40
permissions
-rw-r--r--

Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

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

mercurial