From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Shelley Vohr Date: Thu, 20 Aug 2020 10:55:48 -0700 Subject: fix: properly honor printing page ranges The print ranges in Chromium's print job settings were not being properly plumbed through to PMPrintSettings on mcOS. This fixes that by setting them should they exist. This will be upstreamed. diff --git a/printing/printing_context_mac.h b/printing/printing_context_mac.h index c9a13aee1e64f359cd1d5c2e440b4df204420997..7790c311400fc84bfda6c99e1ebd8da728031a77 100644 --- a/printing/printing_context_mac.h +++ b/printing/printing_context_mac.h @@ -84,6 +84,10 @@ class COMPONENT_EXPORT(PRINTING) PrintingContextMac : public PrintingContext { // Returns true if the orientation was set. bool SetOrientationIsLandscape(bool landscape); + // Set the page range in native print info object. + // Returns true if the range was set. + bool SetPrintRangeInPrintSettings(const PageRanges& ranges); + // Sets duplex mode in PMPrintSettings. // Returns true if duplex mode is set. bool SetDuplexModeInPrintSettings(mojom::DuplexMode mode); diff --git a/printing/printing_context_mac.mm b/printing/printing_context_mac.mm index 010c7ed3025172e1e5a60fb7c89c3ea7a38c3ba5..ce13929c3b9205b71eeae32aad89c92f00d6c8c0 100644 --- a/printing/printing_context_mac.mm +++ b/printing/printing_context_mac.mm @@ -209,7 +209,8 @@ bool IsIppColorModelColorful(mojom::ColorModel color_model) { !SetCollateInPrintSettings(settings_->collate()) || !SetDuplexModeInPrintSettings(settings_->duplex_mode()) || !SetOutputColor(static_cast(settings_->color())) || - !SetResolution(settings_->dpi_size())) { + !SetResolution(settings_->dpi_size()) || + !SetPrintRangeInPrintSettings(settings_->ranges()) ) { return OnError(); } } @@ -362,6 +363,22 @@ bool IsIppColorModelColorful(mojom::ColorModel color_model) { return PMSetCopies(print_settings, copies, false) == noErr; } +bool PrintingContextMac::SetPrintRangeInPrintSettings(const PageRanges& ranges) { + // Default is already NSPrintAllPages - we can safely bail. + if (ranges.empty()) + return true; + + PMPrintSettings print_settings = + static_cast([print_info_ PMPrintSettings]); + + // macOS does not allow multiple ranges, so pluck the first. + auto range = ranges.front(); + bool set_first_page = PMSetFirstPage(print_settings, range.from + 1, false) == noErr; + bool set_last_page = PMSetLastPage(print_settings, range.to + 1, false) == noErr; + + return set_first_page && set_last_page; +} + bool PrintingContextMac::SetCollateInPrintSettings(bool collate) { PMPrintSettings print_settings = static_cast([print_info_ PMPrintSettings]); diff --git a/printing/printing_context_system_dialog_win.cc b/printing/printing_context_system_dialog_win.cc index 07847521e7217c78480205812a73cc89503c00d2..586e866ca7ec0eb0b573d23e3bd95792c22bff20 100644 --- a/printing/printing_context_system_dialog_win.cc +++ b/printing/printing_context_system_dialog_win.cc @@ -75,14 +75,28 @@ void PrintingContextSystemDialogWin::AskUserForSettings( PRINTPAGERANGE ranges[32]; dialog_options.nStartPage = START_PAGE_GENERAL; if (max_pages) { - // Default initialize to print all the pages. memset(ranges, 0, sizeof(ranges)); - ranges[0].nFromPage = 1; - ranges[0].nToPage = max_pages; - dialog_options.nPageRanges = 1; - dialog_options.nMaxPageRanges = std::size(ranges); + + auto page_ranges = settings_->ranges(); + if (!page_ranges.empty()) { + for (size_t i = 0; i < page_ranges.size(); i++) { + auto range = page_ranges[i]; + ranges[i].nFromPage = range.from + 1; + ranges[i].nToPage = range.to + 1; + } + dialog_options.nPageRanges = page_ranges.size(); + + // Ensure the Pages radio button is selected. + dialog_options.Flags |= PD_PAGENUMS; + } else { + ranges[0].nFromPage = 1; + ranges[0].nToPage = max_pages; + dialog_options.nPageRanges = 1; + } + dialog_options.nMinPage = 1; dialog_options.nMaxPage = max_pages; + dialog_options.nMaxPageRanges = std::size(ranges); dialog_options.lpPageRanges = ranges; } else { // No need to bother, we don't know how many pages are available. diff --git a/ui/gtk/printing/print_dialog_gtk.cc b/ui/gtk/printing/print_dialog_gtk.cc index afa936ce95602d5e66189303a73d7824611187b3..89371a4f0d3216f21761adc51bdd2accec0c74a1 100644 --- a/ui/gtk/printing/print_dialog_gtk.cc +++ b/ui/gtk/printing/print_dialog_gtk.cc @@ -247,6 +247,24 @@ void PrintDialogGtk::UpdateSettings( gtk_print_settings_set_n_copies(gtk_settings_, settings->copies()); gtk_print_settings_set_collate(gtk_settings_, settings->collate()); + + auto print_ranges = settings->ranges(); + if (!print_ranges.empty()) { + // Tell the system that we only intend to print a subset of pages. + gtk_print_settings_set_print_pages(gtk_settings_, GTK_PRINT_PAGES_RANGES); + + GtkPageRange* ranges; + ranges = g_new(GtkPageRange, print_ranges.size()); + for (size_t i = 0; i < print_ranges.size(); i++) { + auto range = print_ranges[i]; + ranges[i].start = range.from; + ranges[i].end = range.to; + } + + gtk_print_settings_set_page_ranges(gtk_settings_, ranges, 1); + g_free(ranges); + } + if (settings->dpi_horizontal() > 0 && settings->dpi_vertical() > 0) { gtk_print_settings_set_resolution_xy( gtk_settings_, settings->dpi_horizontal(), settings->dpi_vertical());