LCOV - code coverage report
Current view: top level - widget/gtk - nsPrintDialogGTK.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 304 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 21 0.0 %
Legend: Lines: hit not hit

          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 <gtk/gtk.h>
       7             : #include <gtk/gtkunixprint.h>
       8             : #include <stdlib.h>
       9             : 
      10             : #include "mozilla/ArrayUtils.h"
      11             : 
      12             : #include "mozcontainer.h"
      13             : #include "nsIPrintSettings.h"
      14             : #include "nsIWidget.h"
      15             : #include "nsPrintDialogGTK.h"
      16             : #include "nsPrintSettingsGTK.h"
      17             : #include "nsString.h"
      18             : #include "nsReadableUtils.h"
      19             : #include "nsIFile.h"
      20             : #include "nsIStringBundle.h"
      21             : #include "nsIPrintSettingsService.h"
      22             : #include "nsIDOMWindow.h"
      23             : #include "nsPIDOMWindow.h"
      24             : #include "nsIBaseWindow.h"
      25             : #include "nsIDocShellTreeItem.h"
      26             : #include "nsIDocShell.h"
      27             : #include "WidgetUtils.h"
      28             : 
      29             : using namespace mozilla;
      30             : using namespace mozilla::widget;
      31             : 
      32             : static const char header_footer_tags[][4] =  {"", "&T", "&U", "&D", "&P", "&PT"};
      33             : 
      34             : #define CUSTOM_VALUE_INDEX gint(ArrayLength(header_footer_tags))
      35             : 
      36             : static GtkWindow *
      37           0 : get_gtk_window_for_nsiwidget(nsIWidget *widget)
      38             : {
      39           0 :   return GTK_WINDOW(widget->GetNativeData(NS_NATIVE_SHELLWIDGET));
      40             : }
      41             : 
      42             : static void
      43           0 : ShowCustomDialog(GtkComboBox *changed_box, gpointer user_data)
      44             : {
      45           0 :   if (gtk_combo_box_get_active(changed_box) != CUSTOM_VALUE_INDEX) {
      46           0 :     g_object_set_data(G_OBJECT(changed_box), "previous-active", GINT_TO_POINTER(gtk_combo_box_get_active(changed_box)));
      47           0 :     return;
      48             :   }
      49             : 
      50           0 :   GtkWindow* printDialog = GTK_WINDOW(user_data);
      51             :   nsCOMPtr<nsIStringBundleService> bundleSvc =
      52           0 :        do_GetService(NS_STRINGBUNDLE_CONTRACTID);
      53             : 
      54           0 :   nsCOMPtr<nsIStringBundle> printBundle;
      55           0 :   bundleSvc->CreateBundle("chrome://global/locale/printdialog.properties", getter_AddRefs(printBundle));
      56           0 :   nsXPIDLString intlString;
      57             : 
      58           0 :   printBundle->GetStringFromName(u"headerFooterCustom", getter_Copies(intlString));
      59           0 :   GtkWidget* prompt_dialog = gtk_dialog_new_with_buttons(NS_ConvertUTF16toUTF8(intlString).get(), printDialog,
      60             : #if (MOZ_WIDGET_GTK == 2)
      61             :                                                          (GtkDialogFlags)(GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR),
      62             : #else
      63             :                                                          (GtkDialogFlags)(GTK_DIALOG_MODAL),
      64             : #endif
      65             :                                                          GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
      66             :                                                          GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
      67           0 :                                                          nullptr);
      68           0 :   gtk_dialog_set_default_response(GTK_DIALOG(prompt_dialog), GTK_RESPONSE_ACCEPT);
      69           0 :   gtk_dialog_set_alternative_button_order(GTK_DIALOG(prompt_dialog),
      70             :                                           GTK_RESPONSE_ACCEPT,
      71             :                                           GTK_RESPONSE_REJECT,
      72           0 :                                           -1);
      73             : 
      74           0 :   printBundle->GetStringFromName(u"customHeaderFooterPrompt", getter_Copies(intlString));
      75           0 :   GtkWidget* custom_label = gtk_label_new(NS_ConvertUTF16toUTF8(intlString).get());
      76           0 :   GtkWidget* custom_entry = gtk_entry_new();
      77           0 :   GtkWidget* question_icon = gtk_image_new_from_stock(GTK_STOCK_DIALOG_QUESTION, GTK_ICON_SIZE_DIALOG);
      78             : 
      79             :   // To be convenient, prefill the textbox with the existing value, if any, and select it all so they can easily
      80             :   // both edit it and type in a new one.
      81           0 :   const char* current_text = (const char*) g_object_get_data(G_OBJECT(changed_box), "custom-text");
      82           0 :   if (current_text) {
      83           0 :     gtk_entry_set_text(GTK_ENTRY(custom_entry), current_text);
      84           0 :     gtk_editable_select_region(GTK_EDITABLE(custom_entry), 0, -1);
      85             :   }
      86           0 :   gtk_entry_set_activates_default(GTK_ENTRY(custom_entry), TRUE);
      87             : 
      88           0 :   GtkWidget* custom_vbox = gtk_vbox_new(TRUE, 2);
      89           0 :   gtk_box_pack_start(GTK_BOX(custom_vbox), custom_label, FALSE, FALSE, 0);
      90           0 :   gtk_box_pack_start(GTK_BOX(custom_vbox), custom_entry, FALSE, FALSE, 5); // Make entry 5px underneath label
      91           0 :   GtkWidget* custom_hbox = gtk_hbox_new(FALSE, 2);
      92           0 :   gtk_box_pack_start(GTK_BOX(custom_hbox), question_icon, FALSE, FALSE, 0);
      93           0 :   gtk_box_pack_start(GTK_BOX(custom_hbox), custom_vbox, FALSE, FALSE, 10); // Make question icon 10px away from content
      94           0 :   gtk_container_set_border_width(GTK_CONTAINER(custom_hbox), 2);
      95           0 :   gtk_widget_show_all(custom_hbox);
      96             : 
      97           0 :   gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(prompt_dialog))), 
      98           0 :                      custom_hbox, FALSE, FALSE, 0);
      99           0 :   gint diag_response = gtk_dialog_run(GTK_DIALOG(prompt_dialog));
     100             : 
     101           0 :   if (diag_response == GTK_RESPONSE_ACCEPT) {
     102           0 :     const gchar* response_text = gtk_entry_get_text(GTK_ENTRY(custom_entry));
     103           0 :     g_object_set_data_full(G_OBJECT(changed_box), "custom-text", strdup(response_text), (GDestroyNotify) free);
     104           0 :     g_object_set_data(G_OBJECT(changed_box), "previous-active", GINT_TO_POINTER(CUSTOM_VALUE_INDEX));
     105             :   } else {
     106             :     // Go back to the previous index
     107           0 :     gint previous_active = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(changed_box), "previous-active"));
     108           0 :     gtk_combo_box_set_active(changed_box, previous_active);
     109             :   }
     110             : 
     111           0 :   gtk_widget_destroy(prompt_dialog);
     112             : }
     113             : 
     114             : class nsPrintDialogWidgetGTK {
     115             :   public:
     116             :     nsPrintDialogWidgetGTK(nsPIDOMWindowOuter *aParent,
     117             :                            nsIPrintSettings *aPrintSettings);
     118           0 :     ~nsPrintDialogWidgetGTK() { gtk_widget_destroy(dialog); }
     119             :     NS_ConvertUTF16toUTF8 GetUTF8FromBundle(const char* aKey);
     120             :     gint Run();
     121             : 
     122             :     nsresult ImportSettings(nsIPrintSettings *aNSSettings);
     123             :     nsresult ExportSettings(nsIPrintSettings *aNSSettings);
     124             : 
     125             :   private:
     126             :     GtkWidget* dialog;
     127             :     GtkWidget* radio_as_laid_out;
     128             :     GtkWidget* radio_selected_frame;
     129             :     GtkWidget* radio_separate_frames;
     130             :     GtkWidget* shrink_to_fit_toggle;
     131             :     GtkWidget* print_bg_colors_toggle;
     132             :     GtkWidget* print_bg_images_toggle;
     133             :     GtkWidget* selection_only_toggle;
     134             :     GtkWidget* header_dropdown[3];  // {left, center, right}
     135             :     GtkWidget* footer_dropdown[3];
     136             : 
     137             :     nsCOMPtr<nsIStringBundle> printBundle;
     138             : 
     139             :     bool useNativeSelection;
     140             : 
     141             :     GtkWidget* ConstructHeaderFooterDropdown(const char16_t *currentString);
     142             :     const char* OptionWidgetToString(GtkWidget *dropdown);
     143             : 
     144             :     /* Code to copy between GTK and NS print settings structures.
     145             :      * In the following, 
     146             :      *   "Import" means to copy from NS to GTK
     147             :      *   "Export" means to copy from GTK to NS
     148             :      */
     149             :     void ExportFramePrinting(nsIPrintSettings *aNS, GtkPrintSettings *aSettings);
     150             :     void ExportHeaderFooter(nsIPrintSettings *aNS);
     151             : };
     152             : 
     153           0 : nsPrintDialogWidgetGTK::nsPrintDialogWidgetGTK(nsPIDOMWindowOuter *aParent,
     154           0 :                                                nsIPrintSettings *aSettings)
     155             : {
     156           0 :   nsCOMPtr<nsIWidget> widget = WidgetUtils::DOMWindowToWidget(aParent);
     157           0 :   NS_ASSERTION(widget, "Need a widget for dialog to be modal.");
     158           0 :   GtkWindow* gtkParent = get_gtk_window_for_nsiwidget(widget);
     159           0 :   NS_ASSERTION(gtkParent, "Need a GTK window for dialog to be modal.");
     160             : 
     161           0 :   nsCOMPtr<nsIStringBundleService> bundleSvc = do_GetService(NS_STRINGBUNDLE_CONTRACTID);
     162           0 :   bundleSvc->CreateBundle("chrome://global/locale/printdialog.properties", getter_AddRefs(printBundle));
     163             : 
     164           0 :   dialog = gtk_print_unix_dialog_new(GetUTF8FromBundle("printTitleGTK").get(), gtkParent);
     165             : 
     166           0 :   gtk_print_unix_dialog_set_manual_capabilities(GTK_PRINT_UNIX_DIALOG(dialog),
     167             :                     GtkPrintCapabilities(
     168             :                         GTK_PRINT_CAPABILITY_PAGE_SET
     169             :                       | GTK_PRINT_CAPABILITY_COPIES
     170             :                       | GTK_PRINT_CAPABILITY_COLLATE
     171             :                       | GTK_PRINT_CAPABILITY_REVERSE
     172             :                       | GTK_PRINT_CAPABILITY_SCALE
     173             :                       | GTK_PRINT_CAPABILITY_GENERATE_PDF
     174             :                       | GTK_PRINT_CAPABILITY_GENERATE_PS
     175             :                     )
     176           0 :                   );
     177             : 
     178             :   // The vast majority of magic numbers in this widget construction are padding. e.g. for
     179             :   // the set_border_width below, 12px matches that of just about every other window.
     180           0 :   GtkWidget* custom_options_tab = gtk_vbox_new(FALSE, 0);
     181           0 :   gtk_container_set_border_width(GTK_CONTAINER(custom_options_tab), 12);
     182           0 :   GtkWidget* tab_label = gtk_label_new(GetUTF8FromBundle("optionsTabLabelGTK").get());
     183             : 
     184             :   int16_t frameUIFlag;
     185           0 :   aSettings->GetHowToEnableFrameUI(&frameUIFlag);
     186           0 :   radio_as_laid_out = gtk_radio_button_new_with_mnemonic(nullptr, GetUTF8FromBundle("asLaidOut").get());
     187           0 :   if (frameUIFlag == nsIPrintSettings::kFrameEnableNone)
     188           0 :     gtk_widget_set_sensitive(radio_as_laid_out, FALSE);
     189             : 
     190           0 :   radio_selected_frame = gtk_radio_button_new_with_mnemonic_from_widget(GTK_RADIO_BUTTON(radio_as_laid_out),
     191           0 :                                                                         GetUTF8FromBundle("selectedFrame").get());
     192           0 :   if (frameUIFlag == nsIPrintSettings::kFrameEnableNone ||
     193           0 :       frameUIFlag == nsIPrintSettings::kFrameEnableAsIsAndEach)
     194           0 :     gtk_widget_set_sensitive(radio_selected_frame, FALSE);
     195             : 
     196           0 :   radio_separate_frames = gtk_radio_button_new_with_mnemonic_from_widget(GTK_RADIO_BUTTON(radio_as_laid_out),
     197           0 :                                                                          GetUTF8FromBundle("separateFrames").get());
     198           0 :   if (frameUIFlag == nsIPrintSettings::kFrameEnableNone)
     199           0 :     gtk_widget_set_sensitive(radio_separate_frames, FALSE);
     200             : 
     201             :   // "Print Frames" options label, bold and center-aligned
     202           0 :   GtkWidget* print_frames_label = gtk_label_new(nullptr);
     203           0 :   char* pangoMarkup = g_markup_printf_escaped("<b>%s</b>", GetUTF8FromBundle("printFramesTitleGTK").get());
     204           0 :   gtk_label_set_markup(GTK_LABEL(print_frames_label), pangoMarkup);
     205           0 :   g_free(pangoMarkup);
     206           0 :   gtk_misc_set_alignment(GTK_MISC(print_frames_label), 0, 0);
     207             : 
     208             :   // Align the radio buttons slightly so they appear to fall under the aforementioned label as per the GNOME HIG
     209           0 :   GtkWidget* frames_radio_container = gtk_alignment_new(0, 0, 0, 0);
     210           0 :   gtk_alignment_set_padding(GTK_ALIGNMENT(frames_radio_container), 8, 0, 12, 0);
     211             : 
     212             :   // Radio buttons for the print frames options
     213           0 :   GtkWidget* frames_radio_list = gtk_vbox_new(TRUE, 2);
     214           0 :   gtk_box_pack_start(GTK_BOX(frames_radio_list), radio_as_laid_out, FALSE, FALSE, 0);
     215           0 :   gtk_box_pack_start(GTK_BOX(frames_radio_list), radio_selected_frame, FALSE, FALSE, 0);
     216           0 :   gtk_box_pack_start(GTK_BOX(frames_radio_list), radio_separate_frames, FALSE, FALSE, 0);
     217           0 :   gtk_container_add(GTK_CONTAINER(frames_radio_container), frames_radio_list);
     218             : 
     219             :   // Check buttons for shrink-to-fit and print selection
     220           0 :   GtkWidget* check_buttons_container = gtk_vbox_new(TRUE, 2);
     221           0 :   shrink_to_fit_toggle = gtk_check_button_new_with_mnemonic(GetUTF8FromBundle("shrinkToFit").get());
     222           0 :   gtk_box_pack_start(GTK_BOX(check_buttons_container), shrink_to_fit_toggle, FALSE, FALSE, 0);
     223             : 
     224             :   // GTK+2.18 and above allow us to add a "Selection" option to the main settings screen,
     225             :   // rather than adding an option on a custom tab like we must do on older versions.
     226             :   bool canSelectText;
     227           0 :   aSettings->GetPrintOptions(nsIPrintSettings::kEnableSelectionRB, &canSelectText);
     228           0 :   if (gtk_major_version > 2 ||
     229           0 :       (gtk_major_version == 2 && gtk_minor_version >= 18)) {
     230           0 :     useNativeSelection = true;
     231           0 :     g_object_set(dialog,
     232             :                  "support-selection", TRUE,
     233             :                  "has-selection", canSelectText,
     234             :                  "embed-page-setup", TRUE,
     235           0 :                  nullptr);
     236             :   } else {
     237           0 :     useNativeSelection = false;
     238           0 :     selection_only_toggle = gtk_check_button_new_with_mnemonic(GetUTF8FromBundle("selectionOnly").get());
     239           0 :     gtk_widget_set_sensitive(selection_only_toggle, canSelectText);
     240           0 :     gtk_box_pack_start(GTK_BOX(check_buttons_container), selection_only_toggle, FALSE, FALSE, 0);
     241             :   }
     242             : 
     243             :   // Check buttons for printing background
     244           0 :   GtkWidget* appearance_buttons_container = gtk_vbox_new(TRUE, 2);
     245           0 :   print_bg_colors_toggle = gtk_check_button_new_with_mnemonic(GetUTF8FromBundle("printBGColors").get());
     246           0 :   print_bg_images_toggle = gtk_check_button_new_with_mnemonic(GetUTF8FromBundle("printBGImages").get());
     247           0 :   gtk_box_pack_start(GTK_BOX(appearance_buttons_container), print_bg_colors_toggle, FALSE, FALSE, 0);
     248           0 :   gtk_box_pack_start(GTK_BOX(appearance_buttons_container), print_bg_images_toggle, FALSE, FALSE, 0);
     249             : 
     250             :   // "Appearance" options label, bold and center-aligned
     251           0 :   GtkWidget* appearance_label = gtk_label_new(nullptr);
     252           0 :   pangoMarkup = g_markup_printf_escaped("<b>%s</b>", GetUTF8FromBundle("printBGOptions").get());
     253           0 :   gtk_label_set_markup(GTK_LABEL(appearance_label), pangoMarkup);
     254           0 :   g_free(pangoMarkup);
     255           0 :   gtk_misc_set_alignment(GTK_MISC(appearance_label), 0, 0);
     256             : 
     257           0 :   GtkWidget* appearance_container = gtk_alignment_new(0, 0, 0, 0);
     258           0 :   gtk_alignment_set_padding(GTK_ALIGNMENT(appearance_container), 8, 0, 12, 0);
     259           0 :   gtk_container_add(GTK_CONTAINER(appearance_container), appearance_buttons_container);
     260             : 
     261           0 :   GtkWidget* appearance_vertical_squasher = gtk_vbox_new(FALSE, 0);
     262           0 :   gtk_box_pack_start(GTK_BOX(appearance_vertical_squasher), appearance_label, FALSE, FALSE, 0);
     263           0 :   gtk_box_pack_start(GTK_BOX(appearance_vertical_squasher), appearance_container, FALSE, FALSE, 0);
     264             : 
     265             :   // "Header & Footer" options label, bold and center-aligned
     266           0 :   GtkWidget* header_footer_label = gtk_label_new(nullptr);
     267           0 :   pangoMarkup = g_markup_printf_escaped("<b>%s</b>", GetUTF8FromBundle("headerFooter").get());
     268           0 :   gtk_label_set_markup(GTK_LABEL(header_footer_label), pangoMarkup);
     269           0 :   g_free(pangoMarkup);
     270           0 :   gtk_misc_set_alignment(GTK_MISC(header_footer_label), 0, 0);
     271             : 
     272           0 :   GtkWidget* header_footer_container = gtk_alignment_new(0, 0, 0, 0);
     273           0 :   gtk_alignment_set_padding(GTK_ALIGNMENT(header_footer_container), 8, 0, 12, 0);
     274             : 
     275             : 
     276             :   // --- Table for making the header and footer options ---
     277           0 :   GtkWidget* header_footer_table = gtk_table_new(3, 3, FALSE); // 3x3 table
     278           0 :   nsXPIDLString header_footer_str[3];
     279             : 
     280           0 :   aSettings->GetHeaderStrLeft(getter_Copies(header_footer_str[0]));
     281           0 :   aSettings->GetHeaderStrCenter(getter_Copies(header_footer_str[1]));
     282           0 :   aSettings->GetHeaderStrRight(getter_Copies(header_footer_str[2]));
     283             : 
     284           0 :   for (unsigned int i = 0; i < ArrayLength(header_dropdown); i++) {
     285           0 :     header_dropdown[i] = ConstructHeaderFooterDropdown(header_footer_str[i].get());
     286             :     // Those 4 magic numbers in the middle provide the position in the table.
     287             :     // The last two numbers mean 2 px padding on every side.
     288           0 :     gtk_table_attach(GTK_TABLE(header_footer_table), header_dropdown[i], i, (i + 1),
     289           0 :                      0, 1, (GtkAttachOptions) 0, (GtkAttachOptions) 0, 2, 2);
     290             :   }
     291             : 
     292           0 :   const char labelKeys[][7] = {"left", "center", "right"};
     293           0 :   for (unsigned int i = 0; i < ArrayLength(labelKeys); i++) {
     294           0 :     gtk_table_attach(GTK_TABLE(header_footer_table),
     295           0 :                      gtk_label_new(GetUTF8FromBundle(labelKeys[i]).get()),
     296           0 :                      i, (i + 1), 1, 2, (GtkAttachOptions) 0, (GtkAttachOptions) 0, 2, 2);
     297             :   }
     298             : 
     299           0 :   aSettings->GetFooterStrLeft(getter_Copies(header_footer_str[0]));
     300           0 :   aSettings->GetFooterStrCenter(getter_Copies(header_footer_str[1]));
     301           0 :   aSettings->GetFooterStrRight(getter_Copies(header_footer_str[2]));
     302             : 
     303           0 :   for (unsigned int i = 0; i < ArrayLength(footer_dropdown); i++) {
     304           0 :     footer_dropdown[i] = ConstructHeaderFooterDropdown(header_footer_str[i].get());
     305           0 :     gtk_table_attach(GTK_TABLE(header_footer_table), footer_dropdown[i], i, (i + 1),
     306           0 :                      2, 3, (GtkAttachOptions) 0, (GtkAttachOptions) 0, 2, 2);
     307             :   }
     308             :   // ---
     309             : 
     310           0 :   gtk_container_add(GTK_CONTAINER(header_footer_container), header_footer_table);
     311             : 
     312           0 :   GtkWidget* header_footer_vertical_squasher = gtk_vbox_new(FALSE, 0);
     313           0 :   gtk_box_pack_start(GTK_BOX(header_footer_vertical_squasher), header_footer_label, FALSE, FALSE, 0);
     314           0 :   gtk_box_pack_start(GTK_BOX(header_footer_vertical_squasher), header_footer_container, FALSE, FALSE, 0);
     315             : 
     316             :   // Construction of everything
     317           0 :   gtk_box_pack_start(GTK_BOX(custom_options_tab), print_frames_label, FALSE, FALSE, 0);
     318           0 :   gtk_box_pack_start(GTK_BOX(custom_options_tab), frames_radio_container, FALSE, FALSE, 0);
     319           0 :   gtk_box_pack_start(GTK_BOX(custom_options_tab), check_buttons_container, FALSE, FALSE, 10); // 10px padding
     320           0 :   gtk_box_pack_start(GTK_BOX(custom_options_tab), appearance_vertical_squasher, FALSE, FALSE, 10);
     321           0 :   gtk_box_pack_start(GTK_BOX(custom_options_tab), header_footer_vertical_squasher, FALSE, FALSE, 0);
     322             : 
     323           0 :   gtk_print_unix_dialog_add_custom_tab(GTK_PRINT_UNIX_DIALOG(dialog), custom_options_tab, tab_label);
     324           0 :   gtk_widget_show_all(custom_options_tab);
     325           0 : }
     326             : 
     327             : NS_ConvertUTF16toUTF8
     328           0 : nsPrintDialogWidgetGTK::GetUTF8FromBundle(const char *aKey)
     329             : {
     330           0 :   nsXPIDLString intlString;
     331           0 :   printBundle->GetStringFromName(NS_ConvertUTF8toUTF16(aKey).get(), getter_Copies(intlString));
     332           0 :   return NS_ConvertUTF16toUTF8(intlString);  // Return the actual object so we don't lose reference
     333             : }
     334             : 
     335             : const char*
     336           0 : nsPrintDialogWidgetGTK::OptionWidgetToString(GtkWidget *dropdown)
     337             : {
     338           0 :   gint index = gtk_combo_box_get_active(GTK_COMBO_BOX(dropdown));
     339             : 
     340           0 :   NS_ASSERTION(index <= CUSTOM_VALUE_INDEX, "Index of dropdown is higher than expected!");
     341             : 
     342           0 :   if (index == CUSTOM_VALUE_INDEX)
     343           0 :     return (const char*) g_object_get_data(G_OBJECT(dropdown), "custom-text");
     344             :   else
     345           0 :     return header_footer_tags[index];
     346             : }
     347             : 
     348             : gint
     349           0 : nsPrintDialogWidgetGTK::Run()
     350             : {
     351           0 :   const gint response = gtk_dialog_run(GTK_DIALOG(dialog));
     352           0 :   gtk_widget_hide(dialog);
     353           0 :   return response;
     354             : }
     355             : 
     356             : void
     357           0 : nsPrintDialogWidgetGTK::ExportFramePrinting(nsIPrintSettings *aNS, GtkPrintSettings *aSettings)
     358             : {
     359           0 :   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radio_as_laid_out)))
     360           0 :     aNS->SetPrintFrameType(nsIPrintSettings::kFramesAsIs);
     361           0 :   else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radio_selected_frame)))
     362           0 :     aNS->SetPrintFrameType(nsIPrintSettings::kSelectedFrame);
     363           0 :   else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radio_separate_frames)))
     364           0 :     aNS->SetPrintFrameType(nsIPrintSettings::kEachFrameSep);
     365             :   else
     366           0 :     aNS->SetPrintFrameType(nsIPrintSettings::kNoFrames);
     367           0 : }
     368             : 
     369             : void
     370           0 : nsPrintDialogWidgetGTK::ExportHeaderFooter(nsIPrintSettings *aNS)
     371             : {
     372             :   const char* header_footer_str;
     373           0 :   header_footer_str = OptionWidgetToString(header_dropdown[0]);
     374           0 :   aNS->SetHeaderStrLeft(NS_ConvertUTF8toUTF16(header_footer_str).get());
     375             : 
     376           0 :   header_footer_str = OptionWidgetToString(header_dropdown[1]);
     377           0 :   aNS->SetHeaderStrCenter(NS_ConvertUTF8toUTF16(header_footer_str).get());
     378             : 
     379           0 :   header_footer_str = OptionWidgetToString(header_dropdown[2]);
     380           0 :   aNS->SetHeaderStrRight(NS_ConvertUTF8toUTF16(header_footer_str).get());
     381             : 
     382           0 :   header_footer_str = OptionWidgetToString(footer_dropdown[0]);
     383           0 :   aNS->SetFooterStrLeft(NS_ConvertUTF8toUTF16(header_footer_str).get());
     384             : 
     385           0 :   header_footer_str = OptionWidgetToString(footer_dropdown[1]);
     386           0 :   aNS->SetFooterStrCenter(NS_ConvertUTF8toUTF16(header_footer_str).get());
     387             : 
     388           0 :   header_footer_str = OptionWidgetToString(footer_dropdown[2]);
     389           0 :   aNS->SetFooterStrRight(NS_ConvertUTF8toUTF16(header_footer_str).get());
     390           0 : }
     391             : 
     392             : nsresult
     393           0 : nsPrintDialogWidgetGTK::ImportSettings(nsIPrintSettings *aNSSettings)
     394             : {
     395           0 :   NS_PRECONDITION(aNSSettings, "aSettings must not be null");
     396           0 :   NS_ENSURE_TRUE(aNSSettings, NS_ERROR_FAILURE);
     397             : 
     398           0 :   nsCOMPtr<nsPrintSettingsGTK> aNSSettingsGTK(do_QueryInterface(aNSSettings));
     399           0 :   if (!aNSSettingsGTK)
     400           0 :     return NS_ERROR_FAILURE;
     401             : 
     402           0 :   GtkPrintSettings* settings = aNSSettingsGTK->GetGtkPrintSettings();
     403           0 :   GtkPageSetup* setup = aNSSettingsGTK->GetGtkPageSetup();
     404             : 
     405             :   bool geckoBool;
     406           0 :   aNSSettings->GetShrinkToFit(&geckoBool);
     407           0 :   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(shrink_to_fit_toggle), geckoBool);
     408             : 
     409           0 :   aNSSettings->GetPrintBGColors(&geckoBool);
     410           0 :   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(print_bg_colors_toggle), geckoBool);
     411             : 
     412           0 :   aNSSettings->GetPrintBGImages(&geckoBool);
     413           0 :   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(print_bg_images_toggle), geckoBool);
     414             : 
     415           0 :   gtk_print_unix_dialog_set_settings(GTK_PRINT_UNIX_DIALOG(dialog), settings);
     416           0 :   gtk_print_unix_dialog_set_page_setup(GTK_PRINT_UNIX_DIALOG(dialog), setup);
     417             :   
     418           0 :   return NS_OK;
     419             : }
     420             : 
     421             : nsresult
     422           0 : nsPrintDialogWidgetGTK::ExportSettings(nsIPrintSettings *aNSSettings)
     423             : {
     424           0 :   NS_PRECONDITION(aNSSettings, "aSettings must not be null");
     425           0 :   NS_ENSURE_TRUE(aNSSettings, NS_ERROR_FAILURE);
     426             : 
     427           0 :   GtkPrintSettings* settings = gtk_print_unix_dialog_get_settings(GTK_PRINT_UNIX_DIALOG(dialog));
     428           0 :   GtkPageSetup* setup = gtk_print_unix_dialog_get_page_setup(GTK_PRINT_UNIX_DIALOG(dialog));
     429           0 :   GtkPrinter* printer = gtk_print_unix_dialog_get_selected_printer(GTK_PRINT_UNIX_DIALOG(dialog));
     430           0 :   if (settings && setup && printer) {
     431           0 :     ExportFramePrinting(aNSSettings, settings);
     432           0 :     ExportHeaderFooter(aNSSettings);
     433             : 
     434           0 :     aNSSettings->SetOutputFormat(nsIPrintSettings::kOutputFormatNative);
     435             : 
     436             :     // Print-to-file is true by default. This must be turned off or else printing won't occur!
     437             :     // (We manually copy the spool file when this flag is set, because we love our embedders)
     438             :     // Even if it is print-to-file in GTK's case, GTK does The Right Thing when we send the job.
     439           0 :     aNSSettings->SetPrintToFile(false);
     440             : 
     441           0 :     aNSSettings->SetShrinkToFit(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(shrink_to_fit_toggle)));
     442             : 
     443           0 :     aNSSettings->SetPrintBGColors(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(print_bg_colors_toggle)));
     444           0 :     aNSSettings->SetPrintBGImages(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(print_bg_images_toggle)));
     445             : 
     446             :     // Try to save native settings in the session object
     447           0 :     nsCOMPtr<nsPrintSettingsGTK> aNSSettingsGTK(do_QueryInterface(aNSSettings));
     448           0 :     if (aNSSettingsGTK) {
     449           0 :       aNSSettingsGTK->SetGtkPrintSettings(settings);
     450           0 :       aNSSettingsGTK->SetGtkPageSetup(setup);
     451           0 :       aNSSettingsGTK->SetGtkPrinter(printer);
     452             :       bool printSelectionOnly;
     453           0 :       if (useNativeSelection) {
     454           0 :         _GtkPrintPages pageSetting = (_GtkPrintPages)gtk_print_settings_get_print_pages(settings);
     455           0 :         printSelectionOnly = (pageSetting == _GTK_PRINT_PAGES_SELECTION);
     456             :       } else {
     457           0 :         printSelectionOnly = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(selection_only_toggle));
     458             :       }
     459           0 :       aNSSettingsGTK->SetForcePrintSelectionOnly(printSelectionOnly);
     460             :     }
     461             :   }
     462             : 
     463           0 :   if (settings)
     464           0 :     g_object_unref(settings);
     465           0 :   return NS_OK;
     466             : }
     467             : 
     468             : GtkWidget*
     469           0 : nsPrintDialogWidgetGTK::ConstructHeaderFooterDropdown(const char16_t *currentString)
     470             : {
     471             : #if (MOZ_WIDGET_GTK == 2)
     472             :   GtkWidget* dropdown = gtk_combo_box_new_text();
     473             : #else
     474           0 :   GtkWidget* dropdown = gtk_combo_box_text_new();
     475             : #endif
     476             :   const char hf_options[][22] = {"headerFooterBlank", "headerFooterTitle",
     477             :                                  "headerFooterURL", "headerFooterDate",
     478             :                                  "headerFooterPage", "headerFooterPageTotal",
     479           0 :                                  "headerFooterCustom"};
     480             : 
     481           0 :   for (unsigned int i = 0; i < ArrayLength(hf_options); i++) {
     482             : #if (MOZ_WIDGET_GTK == 2)
     483             :     gtk_combo_box_append_text(GTK_COMBO_BOX(dropdown), GetUTF8FromBundle(hf_options[i]).get());
     484             : #else
     485           0 :     gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(dropdown), nullptr, 
     486           0 :                               GetUTF8FromBundle(hf_options[i]).get());
     487             : #endif
     488             :   }
     489             : 
     490           0 :   bool shouldBeCustom = true;
     491           0 :   NS_ConvertUTF16toUTF8 currentStringUTF8(currentString);
     492             : 
     493           0 :   for (unsigned int i = 0; i < ArrayLength(header_footer_tags); i++) {
     494           0 :     if (!strcmp(currentStringUTF8.get(), header_footer_tags[i])) {
     495           0 :       gtk_combo_box_set_active(GTK_COMBO_BOX(dropdown), i);
     496           0 :       g_object_set_data(G_OBJECT(dropdown), "previous-active", GINT_TO_POINTER(i));
     497           0 :       shouldBeCustom = false;
     498           0 :       break;
     499             :     }
     500             :   }
     501             : 
     502           0 :   if (shouldBeCustom) {
     503           0 :     gtk_combo_box_set_active(GTK_COMBO_BOX(dropdown), CUSTOM_VALUE_INDEX);
     504           0 :     g_object_set_data(G_OBJECT(dropdown), "previous-active", GINT_TO_POINTER(CUSTOM_VALUE_INDEX));
     505           0 :     char* custom_string = strdup(currentStringUTF8.get());
     506           0 :     g_object_set_data_full(G_OBJECT(dropdown), "custom-text", custom_string, (GDestroyNotify) free);
     507             :   }
     508             : 
     509           0 :   g_signal_connect(dropdown, "changed", (GCallback) ShowCustomDialog, dialog);
     510           0 :   return dropdown;
     511             : }
     512             : 
     513           0 : NS_IMPL_ISUPPORTS(nsPrintDialogServiceGTK, nsIPrintDialogService)
     514             : 
     515           0 : nsPrintDialogServiceGTK::nsPrintDialogServiceGTK()
     516             : {
     517           0 : }
     518             : 
     519           0 : nsPrintDialogServiceGTK::~nsPrintDialogServiceGTK()
     520             : {
     521           0 : }
     522             : 
     523             : NS_IMETHODIMP
     524           0 : nsPrintDialogServiceGTK::Init()
     525             : {
     526           0 :   return NS_OK;
     527             : }
     528             : 
     529             : NS_IMETHODIMP
     530           0 : nsPrintDialogServiceGTK::Show(nsPIDOMWindowOuter *aParent,
     531             :                               nsIPrintSettings *aSettings,
     532             :                               nsIWebBrowserPrint *aWebBrowserPrint)
     533             : {
     534           0 :   NS_PRECONDITION(aParent, "aParent must not be null");
     535           0 :   NS_PRECONDITION(aSettings, "aSettings must not be null");
     536             : 
     537           0 :   nsPrintDialogWidgetGTK printDialog(aParent, aSettings);
     538           0 :   nsresult rv = printDialog.ImportSettings(aSettings);
     539             : 
     540           0 :   NS_ENSURE_SUCCESS(rv, rv);
     541             : 
     542           0 :   const gint response = printDialog.Run();
     543             : 
     544             :   // Handle the result
     545           0 :   switch (response) {
     546             :     case GTK_RESPONSE_OK:                // Proceed
     547           0 :       rv = printDialog.ExportSettings(aSettings);
     548           0 :       break;
     549             : 
     550             :     case GTK_RESPONSE_CANCEL:
     551             :     case GTK_RESPONSE_CLOSE:
     552             :     case GTK_RESPONSE_DELETE_EVENT:
     553             :     case GTK_RESPONSE_NONE:
     554           0 :       rv = NS_ERROR_ABORT;
     555           0 :       break;
     556             : 
     557             :     case GTK_RESPONSE_APPLY:                // Print preview
     558             :     default:
     559           0 :       NS_WARNING("Unexpected response");
     560           0 :       rv = NS_ERROR_ABORT;
     561             :   }
     562           0 :   return rv;
     563             : }
     564             : 
     565             : NS_IMETHODIMP
     566           0 : nsPrintDialogServiceGTK::ShowPageSetup(nsPIDOMWindowOuter *aParent,
     567             :                                        nsIPrintSettings *aNSSettings)
     568             : {
     569           0 :   NS_PRECONDITION(aParent, "aParent must not be null");
     570           0 :   NS_PRECONDITION(aNSSettings, "aSettings must not be null");
     571           0 :   NS_ENSURE_TRUE(aNSSettings, NS_ERROR_FAILURE);
     572             : 
     573           0 :   nsCOMPtr<nsIWidget> widget = WidgetUtils::DOMWindowToWidget(aParent);
     574           0 :   NS_ASSERTION(widget, "Need a widget for dialog to be modal.");
     575           0 :   GtkWindow* gtkParent = get_gtk_window_for_nsiwidget(widget);
     576           0 :   NS_ASSERTION(gtkParent, "Need a GTK window for dialog to be modal.");
     577             : 
     578           0 :   nsCOMPtr<nsPrintSettingsGTK> aNSSettingsGTK(do_QueryInterface(aNSSettings));
     579           0 :   if (!aNSSettingsGTK)
     580           0 :     return NS_ERROR_FAILURE;
     581             : 
     582             :   // We need to init the prefs here because aNSSettings in its current form is a dummy in both uses of the word
     583           0 :   nsCOMPtr<nsIPrintSettingsService> psService = do_GetService("@mozilla.org/gfx/printsettings-service;1");
     584           0 :   if (psService) {
     585           0 :     nsXPIDLString printName;
     586           0 :     aNSSettings->GetPrinterName(getter_Copies(printName));
     587           0 :     if (!printName) {
     588           0 :       psService->GetDefaultPrinterName(getter_Copies(printName));
     589           0 :       aNSSettings->SetPrinterName(printName.get());
     590             :     }
     591           0 :     psService->InitPrintSettingsFromPrefs(aNSSettings, true, nsIPrintSettings::kInitSaveAll);
     592             :   }
     593             : 
     594           0 :   GtkPrintSettings* gtkSettings = aNSSettingsGTK->GetGtkPrintSettings();
     595           0 :   GtkPageSetup* oldPageSetup = aNSSettingsGTK->GetGtkPageSetup();
     596             : 
     597           0 :   GtkPageSetup* newPageSetup = gtk_print_run_page_setup_dialog(gtkParent, oldPageSetup, gtkSettings);
     598             : 
     599           0 :   aNSSettingsGTK->SetGtkPageSetup(newPageSetup);
     600             : 
     601             :   // Now newPageSetup has a refcount of 2 (SetGtkPageSetup will addref), put it to 1 so if
     602             :   // this gets replaced we don't leak.
     603           0 :   g_object_unref(newPageSetup);
     604             : 
     605           0 :   if (psService)
     606           0 :     psService->SavePrintSettingsToPrefs(aNSSettings, true, nsIPrintSettings::kInitSaveAll);
     607             : 
     608           0 :   return NS_OK;
     609             : }

Generated by: LCOV version 1.13