LCOV - code coverage report
Current view: directory - widget/gtk2 - nsPrintDialogGTK.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 308 0 0.0 %
Date: 2012-06-02 Functions: 21 0 0.0 %

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

Generated by: LCOV version 1.7