forked from mirrors/gecko-dev
		
	This avoids a lot of mismatches between nsAString and char16_t*, thus removing many getter_Copies() and ToNewUnicode() and get() calls, and generally making things simpler. Note: the patch removes GetDefaultPrinterNameFromGlobalPrinters() by simply inlining it at its two callsites, which is easy with the changed types. --HG-- extra : rebase_source : 9ab9b3694f093fc9b22c7f8e2394a98674d76c11
		
			
				
	
	
		
			609 lines
		
	
	
	
		
			26 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			609 lines
		
	
	
	
		
			26 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 | 
						|
/* This Source Code Form is subject to the terms of the Mozilla Public
 | 
						|
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
						|
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | 
						|
 | 
						|
#include <gtk/gtk.h>
 | 
						|
#include <gtk/gtkunixprint.h>
 | 
						|
#include <stdlib.h>
 | 
						|
 | 
						|
#include "mozilla/ArrayUtils.h"
 | 
						|
 | 
						|
#include "mozcontainer.h"
 | 
						|
#include "nsIPrintSettings.h"
 | 
						|
#include "nsIWidget.h"
 | 
						|
#include "nsPrintDialogGTK.h"
 | 
						|
#include "nsPrintSettingsGTK.h"
 | 
						|
#include "nsString.h"
 | 
						|
#include "nsReadableUtils.h"
 | 
						|
#include "nsIFile.h"
 | 
						|
#include "nsIStringBundle.h"
 | 
						|
#include "nsIPrintSettingsService.h"
 | 
						|
#include "nsIDOMWindow.h"
 | 
						|
#include "nsPIDOMWindow.h"
 | 
						|
#include "nsIBaseWindow.h"
 | 
						|
#include "nsIDocShellTreeItem.h"
 | 
						|
#include "nsIDocShell.h"
 | 
						|
#include "WidgetUtils.h"
 | 
						|
 | 
						|
using namespace mozilla;
 | 
						|
using namespace mozilla::widget;
 | 
						|
 | 
						|
static const char header_footer_tags[][4] =  {"", "&T", "&U", "&D", "&P", "&PT"};
 | 
						|
 | 
						|
#define CUSTOM_VALUE_INDEX gint(ArrayLength(header_footer_tags))
 | 
						|
 | 
						|
static GtkWindow *
 | 
						|
get_gtk_window_for_nsiwidget(nsIWidget *widget)
 | 
						|
{
 | 
						|
  return GTK_WINDOW(widget->GetNativeData(NS_NATIVE_SHELLWIDGET));
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
ShowCustomDialog(GtkComboBox *changed_box, gpointer user_data)
 | 
						|
{
 | 
						|
  if (gtk_combo_box_get_active(changed_box) != CUSTOM_VALUE_INDEX) {
 | 
						|
    g_object_set_data(G_OBJECT(changed_box), "previous-active", GINT_TO_POINTER(gtk_combo_box_get_active(changed_box)));
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  GtkWindow* printDialog = GTK_WINDOW(user_data);
 | 
						|
  nsCOMPtr<nsIStringBundleService> bundleSvc =
 | 
						|
       do_GetService(NS_STRINGBUNDLE_CONTRACTID);
 | 
						|
 | 
						|
  nsCOMPtr<nsIStringBundle> printBundle;
 | 
						|
  bundleSvc->CreateBundle("chrome://global/locale/printdialog.properties", getter_AddRefs(printBundle));
 | 
						|
  nsAutoString intlString;
 | 
						|
 | 
						|
  printBundle->GetStringFromName("headerFooterCustom", intlString);
 | 
						|
  GtkWidget* prompt_dialog = gtk_dialog_new_with_buttons(NS_ConvertUTF16toUTF8(intlString).get(), printDialog,
 | 
						|
#if (MOZ_WIDGET_GTK == 2)
 | 
						|
                                                         (GtkDialogFlags)(GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR),
 | 
						|
#else
 | 
						|
                                                         (GtkDialogFlags)(GTK_DIALOG_MODAL),
 | 
						|
#endif
 | 
						|
                                                         GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
 | 
						|
                                                         GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
 | 
						|
                                                         nullptr);
 | 
						|
  gtk_dialog_set_default_response(GTK_DIALOG(prompt_dialog), GTK_RESPONSE_ACCEPT);
 | 
						|
  gtk_dialog_set_alternative_button_order(GTK_DIALOG(prompt_dialog),
 | 
						|
                                          GTK_RESPONSE_ACCEPT,
 | 
						|
                                          GTK_RESPONSE_REJECT,
 | 
						|
                                          -1);
 | 
						|
 | 
						|
  printBundle->GetStringFromName("customHeaderFooterPrompt", intlString);
 | 
						|
  GtkWidget* custom_label = gtk_label_new(NS_ConvertUTF16toUTF8(intlString).get());
 | 
						|
  GtkWidget* custom_entry = gtk_entry_new();
 | 
						|
  GtkWidget* question_icon = gtk_image_new_from_stock(GTK_STOCK_DIALOG_QUESTION, GTK_ICON_SIZE_DIALOG);
 | 
						|
 | 
						|
  // To be convenient, prefill the textbox with the existing value, if any, and select it all so they can easily
 | 
						|
  // both edit it and type in a new one.
 | 
						|
  const char* current_text = (const char*) g_object_get_data(G_OBJECT(changed_box), "custom-text");
 | 
						|
  if (current_text) {
 | 
						|
    gtk_entry_set_text(GTK_ENTRY(custom_entry), current_text);
 | 
						|
    gtk_editable_select_region(GTK_EDITABLE(custom_entry), 0, -1);
 | 
						|
  }
 | 
						|
  gtk_entry_set_activates_default(GTK_ENTRY(custom_entry), TRUE);
 | 
						|
 | 
						|
  GtkWidget* custom_vbox = gtk_vbox_new(TRUE, 2);
 | 
						|
  gtk_box_pack_start(GTK_BOX(custom_vbox), custom_label, FALSE, FALSE, 0);
 | 
						|
  gtk_box_pack_start(GTK_BOX(custom_vbox), custom_entry, FALSE, FALSE, 5); // Make entry 5px underneath label
 | 
						|
  GtkWidget* custom_hbox = gtk_hbox_new(FALSE, 2);
 | 
						|
  gtk_box_pack_start(GTK_BOX(custom_hbox), question_icon, FALSE, FALSE, 0);
 | 
						|
  gtk_box_pack_start(GTK_BOX(custom_hbox), custom_vbox, FALSE, FALSE, 10); // Make question icon 10px away from content
 | 
						|
  gtk_container_set_border_width(GTK_CONTAINER(custom_hbox), 2);
 | 
						|
  gtk_widget_show_all(custom_hbox);
 | 
						|
 | 
						|
  gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(prompt_dialog))), 
 | 
						|
                     custom_hbox, FALSE, FALSE, 0);
 | 
						|
  gint diag_response = gtk_dialog_run(GTK_DIALOG(prompt_dialog));
 | 
						|
 | 
						|
  if (diag_response == GTK_RESPONSE_ACCEPT) {
 | 
						|
    const gchar* response_text = gtk_entry_get_text(GTK_ENTRY(custom_entry));
 | 
						|
    g_object_set_data_full(G_OBJECT(changed_box), "custom-text", strdup(response_text), (GDestroyNotify) free);
 | 
						|
    g_object_set_data(G_OBJECT(changed_box), "previous-active", GINT_TO_POINTER(CUSTOM_VALUE_INDEX));
 | 
						|
  } else {
 | 
						|
    // Go back to the previous index
 | 
						|
    gint previous_active = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(changed_box), "previous-active"));
 | 
						|
    gtk_combo_box_set_active(changed_box, previous_active);
 | 
						|
  }
 | 
						|
 | 
						|
  gtk_widget_destroy(prompt_dialog);
 | 
						|
}
 | 
						|
 | 
						|
class nsPrintDialogWidgetGTK {
 | 
						|
  public:
 | 
						|
    nsPrintDialogWidgetGTK(nsPIDOMWindowOuter *aParent,
 | 
						|
                           nsIPrintSettings *aPrintSettings);
 | 
						|
    ~nsPrintDialogWidgetGTK() { gtk_widget_destroy(dialog); }
 | 
						|
    NS_ConvertUTF16toUTF8 GetUTF8FromBundle(const char* aKey);
 | 
						|
    gint Run();
 | 
						|
 | 
						|
    nsresult ImportSettings(nsIPrintSettings *aNSSettings);
 | 
						|
    nsresult ExportSettings(nsIPrintSettings *aNSSettings);
 | 
						|
 | 
						|
  private:
 | 
						|
    GtkWidget* dialog;
 | 
						|
    GtkWidget* radio_as_laid_out;
 | 
						|
    GtkWidget* radio_selected_frame;
 | 
						|
    GtkWidget* radio_separate_frames;
 | 
						|
    GtkWidget* shrink_to_fit_toggle;
 | 
						|
    GtkWidget* print_bg_colors_toggle;
 | 
						|
    GtkWidget* print_bg_images_toggle;
 | 
						|
    GtkWidget* selection_only_toggle;
 | 
						|
    GtkWidget* header_dropdown[3];  // {left, center, right}
 | 
						|
    GtkWidget* footer_dropdown[3];
 | 
						|
 | 
						|
    nsCOMPtr<nsIStringBundle> printBundle;
 | 
						|
 | 
						|
    bool useNativeSelection;
 | 
						|
 | 
						|
    GtkWidget* ConstructHeaderFooterDropdown(const char16_t *currentString);
 | 
						|
    const char* OptionWidgetToString(GtkWidget *dropdown);
 | 
						|
 | 
						|
    /* Code to copy between GTK and NS print settings structures.
 | 
						|
     * In the following, 
 | 
						|
     *   "Import" means to copy from NS to GTK
 | 
						|
     *   "Export" means to copy from GTK to NS
 | 
						|
     */
 | 
						|
    void ExportFramePrinting(nsIPrintSettings *aNS, GtkPrintSettings *aSettings);
 | 
						|
    void ExportHeaderFooter(nsIPrintSettings *aNS);
 | 
						|
};
 | 
						|
 | 
						|
nsPrintDialogWidgetGTK::nsPrintDialogWidgetGTK(nsPIDOMWindowOuter *aParent,
 | 
						|
                                               nsIPrintSettings *aSettings)
 | 
						|
{
 | 
						|
  nsCOMPtr<nsIWidget> widget = WidgetUtils::DOMWindowToWidget(aParent);
 | 
						|
  NS_ASSERTION(widget, "Need a widget for dialog to be modal.");
 | 
						|
  GtkWindow* gtkParent = get_gtk_window_for_nsiwidget(widget);
 | 
						|
  NS_ASSERTION(gtkParent, "Need a GTK window for dialog to be modal.");
 | 
						|
 | 
						|
  nsCOMPtr<nsIStringBundleService> bundleSvc = do_GetService(NS_STRINGBUNDLE_CONTRACTID);
 | 
						|
  bundleSvc->CreateBundle("chrome://global/locale/printdialog.properties", getter_AddRefs(printBundle));
 | 
						|
 | 
						|
  dialog = gtk_print_unix_dialog_new(GetUTF8FromBundle("printTitleGTK").get(), gtkParent);
 | 
						|
 | 
						|
  gtk_print_unix_dialog_set_manual_capabilities(GTK_PRINT_UNIX_DIALOG(dialog),
 | 
						|
                    GtkPrintCapabilities(
 | 
						|
                        GTK_PRINT_CAPABILITY_PAGE_SET
 | 
						|
                      | GTK_PRINT_CAPABILITY_COPIES
 | 
						|
                      | GTK_PRINT_CAPABILITY_COLLATE
 | 
						|
                      | GTK_PRINT_CAPABILITY_REVERSE
 | 
						|
                      | GTK_PRINT_CAPABILITY_SCALE
 | 
						|
                      | GTK_PRINT_CAPABILITY_GENERATE_PDF
 | 
						|
                      | GTK_PRINT_CAPABILITY_GENERATE_PS
 | 
						|
                    )
 | 
						|
                  );
 | 
						|
 | 
						|
  // The vast majority of magic numbers in this widget construction are padding. e.g. for
 | 
						|
  // the set_border_width below, 12px matches that of just about every other window.
 | 
						|
  GtkWidget* custom_options_tab = gtk_vbox_new(FALSE, 0);
 | 
						|
  gtk_container_set_border_width(GTK_CONTAINER(custom_options_tab), 12);
 | 
						|
  GtkWidget* tab_label = gtk_label_new(GetUTF8FromBundle("optionsTabLabelGTK").get());
 | 
						|
 | 
						|
  int16_t frameUIFlag;
 | 
						|
  aSettings->GetHowToEnableFrameUI(&frameUIFlag);
 | 
						|
  radio_as_laid_out = gtk_radio_button_new_with_mnemonic(nullptr, GetUTF8FromBundle("asLaidOut").get());
 | 
						|
  if (frameUIFlag == nsIPrintSettings::kFrameEnableNone)
 | 
						|
    gtk_widget_set_sensitive(radio_as_laid_out, FALSE);
 | 
						|
 | 
						|
  radio_selected_frame = gtk_radio_button_new_with_mnemonic_from_widget(GTK_RADIO_BUTTON(radio_as_laid_out),
 | 
						|
                                                                        GetUTF8FromBundle("selectedFrame").get());
 | 
						|
  if (frameUIFlag == nsIPrintSettings::kFrameEnableNone ||
 | 
						|
      frameUIFlag == nsIPrintSettings::kFrameEnableAsIsAndEach)
 | 
						|
    gtk_widget_set_sensitive(radio_selected_frame, FALSE);
 | 
						|
 | 
						|
  radio_separate_frames = gtk_radio_button_new_with_mnemonic_from_widget(GTK_RADIO_BUTTON(radio_as_laid_out),
 | 
						|
                                                                         GetUTF8FromBundle("separateFrames").get());
 | 
						|
  if (frameUIFlag == nsIPrintSettings::kFrameEnableNone)
 | 
						|
    gtk_widget_set_sensitive(radio_separate_frames, FALSE);
 | 
						|
 | 
						|
  // "Print Frames" options label, bold and center-aligned
 | 
						|
  GtkWidget* print_frames_label = gtk_label_new(nullptr);
 | 
						|
  char* pangoMarkup = g_markup_printf_escaped("<b>%s</b>", GetUTF8FromBundle("printFramesTitleGTK").get());
 | 
						|
  gtk_label_set_markup(GTK_LABEL(print_frames_label), pangoMarkup);
 | 
						|
  g_free(pangoMarkup);
 | 
						|
  gtk_misc_set_alignment(GTK_MISC(print_frames_label), 0, 0);
 | 
						|
 | 
						|
  // Align the radio buttons slightly so they appear to fall under the aforementioned label as per the GNOME HIG
 | 
						|
  GtkWidget* frames_radio_container = gtk_alignment_new(0, 0, 0, 0);
 | 
						|
  gtk_alignment_set_padding(GTK_ALIGNMENT(frames_radio_container), 8, 0, 12, 0);
 | 
						|
 | 
						|
  // Radio buttons for the print frames options
 | 
						|
  GtkWidget* frames_radio_list = gtk_vbox_new(TRUE, 2);
 | 
						|
  gtk_box_pack_start(GTK_BOX(frames_radio_list), radio_as_laid_out, FALSE, FALSE, 0);
 | 
						|
  gtk_box_pack_start(GTK_BOX(frames_radio_list), radio_selected_frame, FALSE, FALSE, 0);
 | 
						|
  gtk_box_pack_start(GTK_BOX(frames_radio_list), radio_separate_frames, FALSE, FALSE, 0);
 | 
						|
  gtk_container_add(GTK_CONTAINER(frames_radio_container), frames_radio_list);
 | 
						|
 | 
						|
  // Check buttons for shrink-to-fit and print selection
 | 
						|
  GtkWidget* check_buttons_container = gtk_vbox_new(TRUE, 2);
 | 
						|
  shrink_to_fit_toggle = gtk_check_button_new_with_mnemonic(GetUTF8FromBundle("shrinkToFit").get());
 | 
						|
  gtk_box_pack_start(GTK_BOX(check_buttons_container), shrink_to_fit_toggle, FALSE, FALSE, 0);
 | 
						|
 | 
						|
  // GTK+2.18 and above allow us to add a "Selection" option to the main settings screen,
 | 
						|
  // rather than adding an option on a custom tab like we must do on older versions.
 | 
						|
  bool canSelectText;
 | 
						|
  aSettings->GetPrintOptions(nsIPrintSettings::kEnableSelectionRB, &canSelectText);
 | 
						|
  if (gtk_major_version > 2 ||
 | 
						|
      (gtk_major_version == 2 && gtk_minor_version >= 18)) {
 | 
						|
    useNativeSelection = true;
 | 
						|
    g_object_set(dialog,
 | 
						|
                 "support-selection", TRUE,
 | 
						|
                 "has-selection", canSelectText,
 | 
						|
                 "embed-page-setup", TRUE,
 | 
						|
                 nullptr);
 | 
						|
  } else {
 | 
						|
    useNativeSelection = false;
 | 
						|
    selection_only_toggle = gtk_check_button_new_with_mnemonic(GetUTF8FromBundle("selectionOnly").get());
 | 
						|
    gtk_widget_set_sensitive(selection_only_toggle, canSelectText);
 | 
						|
    gtk_box_pack_start(GTK_BOX(check_buttons_container), selection_only_toggle, FALSE, FALSE, 0);
 | 
						|
  }
 | 
						|
 | 
						|
  // Check buttons for printing background
 | 
						|
  GtkWidget* appearance_buttons_container = gtk_vbox_new(TRUE, 2);
 | 
						|
  print_bg_colors_toggle = gtk_check_button_new_with_mnemonic(GetUTF8FromBundle("printBGColors").get());
 | 
						|
  print_bg_images_toggle = gtk_check_button_new_with_mnemonic(GetUTF8FromBundle("printBGImages").get());
 | 
						|
  gtk_box_pack_start(GTK_BOX(appearance_buttons_container), print_bg_colors_toggle, FALSE, FALSE, 0);
 | 
						|
  gtk_box_pack_start(GTK_BOX(appearance_buttons_container), print_bg_images_toggle, FALSE, FALSE, 0);
 | 
						|
 | 
						|
  // "Appearance" options label, bold and center-aligned
 | 
						|
  GtkWidget* appearance_label = gtk_label_new(nullptr);
 | 
						|
  pangoMarkup = g_markup_printf_escaped("<b>%s</b>", GetUTF8FromBundle("printBGOptions").get());
 | 
						|
  gtk_label_set_markup(GTK_LABEL(appearance_label), pangoMarkup);
 | 
						|
  g_free(pangoMarkup);
 | 
						|
  gtk_misc_set_alignment(GTK_MISC(appearance_label), 0, 0);
 | 
						|
 | 
						|
  GtkWidget* appearance_container = gtk_alignment_new(0, 0, 0, 0);
 | 
						|
  gtk_alignment_set_padding(GTK_ALIGNMENT(appearance_container), 8, 0, 12, 0);
 | 
						|
  gtk_container_add(GTK_CONTAINER(appearance_container), appearance_buttons_container);
 | 
						|
 | 
						|
  GtkWidget* appearance_vertical_squasher = gtk_vbox_new(FALSE, 0);
 | 
						|
  gtk_box_pack_start(GTK_BOX(appearance_vertical_squasher), appearance_label, FALSE, FALSE, 0);
 | 
						|
  gtk_box_pack_start(GTK_BOX(appearance_vertical_squasher), appearance_container, FALSE, FALSE, 0);
 | 
						|
 | 
						|
  // "Header & Footer" options label, bold and center-aligned
 | 
						|
  GtkWidget* header_footer_label = gtk_label_new(nullptr);
 | 
						|
  pangoMarkup = g_markup_printf_escaped("<b>%s</b>", GetUTF8FromBundle("headerFooter").get());
 | 
						|
  gtk_label_set_markup(GTK_LABEL(header_footer_label), pangoMarkup);
 | 
						|
  g_free(pangoMarkup);
 | 
						|
  gtk_misc_set_alignment(GTK_MISC(header_footer_label), 0, 0);
 | 
						|
 | 
						|
  GtkWidget* header_footer_container = gtk_alignment_new(0, 0, 0, 0);
 | 
						|
  gtk_alignment_set_padding(GTK_ALIGNMENT(header_footer_container), 8, 0, 12, 0);
 | 
						|
 | 
						|
 | 
						|
  // --- Table for making the header and footer options ---
 | 
						|
  GtkWidget* header_footer_table = gtk_table_new(3, 3, FALSE); // 3x3 table
 | 
						|
  nsString header_footer_str[3];
 | 
						|
 | 
						|
  aSettings->GetHeaderStrLeft(header_footer_str[0]);
 | 
						|
  aSettings->GetHeaderStrCenter(header_footer_str[1]);
 | 
						|
  aSettings->GetHeaderStrRight(header_footer_str[2]);
 | 
						|
 | 
						|
  for (unsigned int i = 0; i < ArrayLength(header_dropdown); i++) {
 | 
						|
    header_dropdown[i] = ConstructHeaderFooterDropdown(header_footer_str[i].get());
 | 
						|
    // Those 4 magic numbers in the middle provide the position in the table.
 | 
						|
    // The last two numbers mean 2 px padding on every side.
 | 
						|
    gtk_table_attach(GTK_TABLE(header_footer_table), header_dropdown[i], i, (i + 1),
 | 
						|
                     0, 1, (GtkAttachOptions) 0, (GtkAttachOptions) 0, 2, 2);
 | 
						|
  }
 | 
						|
 | 
						|
  const char labelKeys[][7] = {"left", "center", "right"};
 | 
						|
  for (unsigned int i = 0; i < ArrayLength(labelKeys); i++) {
 | 
						|
    gtk_table_attach(GTK_TABLE(header_footer_table),
 | 
						|
                     gtk_label_new(GetUTF8FromBundle(labelKeys[i]).get()),
 | 
						|
                     i, (i + 1), 1, 2, (GtkAttachOptions) 0, (GtkAttachOptions) 0, 2, 2);
 | 
						|
  }
 | 
						|
 | 
						|
  aSettings->GetFooterStrLeft(header_footer_str[0]);
 | 
						|
  aSettings->GetFooterStrCenter(header_footer_str[1]);
 | 
						|
  aSettings->GetFooterStrRight(header_footer_str[2]);
 | 
						|
 | 
						|
  for (unsigned int i = 0; i < ArrayLength(footer_dropdown); i++) {
 | 
						|
    footer_dropdown[i] = ConstructHeaderFooterDropdown(header_footer_str[i].get());
 | 
						|
    gtk_table_attach(GTK_TABLE(header_footer_table), footer_dropdown[i], i, (i + 1),
 | 
						|
                     2, 3, (GtkAttachOptions) 0, (GtkAttachOptions) 0, 2, 2);
 | 
						|
  }
 | 
						|
  // ---
 | 
						|
 | 
						|
  gtk_container_add(GTK_CONTAINER(header_footer_container), header_footer_table);
 | 
						|
 | 
						|
  GtkWidget* header_footer_vertical_squasher = gtk_vbox_new(FALSE, 0);
 | 
						|
  gtk_box_pack_start(GTK_BOX(header_footer_vertical_squasher), header_footer_label, FALSE, FALSE, 0);
 | 
						|
  gtk_box_pack_start(GTK_BOX(header_footer_vertical_squasher), header_footer_container, FALSE, FALSE, 0);
 | 
						|
 | 
						|
  // Construction of everything
 | 
						|
  gtk_box_pack_start(GTK_BOX(custom_options_tab), print_frames_label, FALSE, FALSE, 0);
 | 
						|
  gtk_box_pack_start(GTK_BOX(custom_options_tab), frames_radio_container, FALSE, FALSE, 0);
 | 
						|
  gtk_box_pack_start(GTK_BOX(custom_options_tab), check_buttons_container, FALSE, FALSE, 10); // 10px padding
 | 
						|
  gtk_box_pack_start(GTK_BOX(custom_options_tab), appearance_vertical_squasher, FALSE, FALSE, 10);
 | 
						|
  gtk_box_pack_start(GTK_BOX(custom_options_tab), header_footer_vertical_squasher, FALSE, FALSE, 0);
 | 
						|
 | 
						|
  gtk_print_unix_dialog_add_custom_tab(GTK_PRINT_UNIX_DIALOG(dialog), custom_options_tab, tab_label);
 | 
						|
  gtk_widget_show_all(custom_options_tab);
 | 
						|
}
 | 
						|
 | 
						|
NS_ConvertUTF16toUTF8
 | 
						|
nsPrintDialogWidgetGTK::GetUTF8FromBundle(const char *aKey)
 | 
						|
{
 | 
						|
  nsAutoString intlString;
 | 
						|
  printBundle->GetStringFromName(aKey, intlString);
 | 
						|
  return NS_ConvertUTF16toUTF8(intlString);  // Return the actual object so we don't lose reference
 | 
						|
}
 | 
						|
 | 
						|
const char*
 | 
						|
nsPrintDialogWidgetGTK::OptionWidgetToString(GtkWidget *dropdown)
 | 
						|
{
 | 
						|
  gint index = gtk_combo_box_get_active(GTK_COMBO_BOX(dropdown));
 | 
						|
 | 
						|
  NS_ASSERTION(index <= CUSTOM_VALUE_INDEX, "Index of dropdown is higher than expected!");
 | 
						|
 | 
						|
  if (index == CUSTOM_VALUE_INDEX)
 | 
						|
    return (const char*) g_object_get_data(G_OBJECT(dropdown), "custom-text");
 | 
						|
  else
 | 
						|
    return header_footer_tags[index];
 | 
						|
}
 | 
						|
 | 
						|
gint
 | 
						|
nsPrintDialogWidgetGTK::Run()
 | 
						|
{
 | 
						|
  const gint response = gtk_dialog_run(GTK_DIALOG(dialog));
 | 
						|
  gtk_widget_hide(dialog);
 | 
						|
  return response;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
nsPrintDialogWidgetGTK::ExportFramePrinting(nsIPrintSettings *aNS, GtkPrintSettings *aSettings)
 | 
						|
{
 | 
						|
  if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radio_as_laid_out)))
 | 
						|
    aNS->SetPrintFrameType(nsIPrintSettings::kFramesAsIs);
 | 
						|
  else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radio_selected_frame)))
 | 
						|
    aNS->SetPrintFrameType(nsIPrintSettings::kSelectedFrame);
 | 
						|
  else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radio_separate_frames)))
 | 
						|
    aNS->SetPrintFrameType(nsIPrintSettings::kEachFrameSep);
 | 
						|
  else
 | 
						|
    aNS->SetPrintFrameType(nsIPrintSettings::kNoFrames);
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
nsPrintDialogWidgetGTK::ExportHeaderFooter(nsIPrintSettings *aNS)
 | 
						|
{
 | 
						|
  const char* header_footer_str;
 | 
						|
  header_footer_str = OptionWidgetToString(header_dropdown[0]);
 | 
						|
  aNS->SetHeaderStrLeft(NS_ConvertUTF8toUTF16(header_footer_str));
 | 
						|
 | 
						|
  header_footer_str = OptionWidgetToString(header_dropdown[1]);
 | 
						|
  aNS->SetHeaderStrCenter(NS_ConvertUTF8toUTF16(header_footer_str));
 | 
						|
 | 
						|
  header_footer_str = OptionWidgetToString(header_dropdown[2]);
 | 
						|
  aNS->SetHeaderStrRight(NS_ConvertUTF8toUTF16(header_footer_str));
 | 
						|
 | 
						|
  header_footer_str = OptionWidgetToString(footer_dropdown[0]);
 | 
						|
  aNS->SetFooterStrLeft(NS_ConvertUTF8toUTF16(header_footer_str));
 | 
						|
 | 
						|
  header_footer_str = OptionWidgetToString(footer_dropdown[1]);
 | 
						|
  aNS->SetFooterStrCenter(NS_ConvertUTF8toUTF16(header_footer_str));
 | 
						|
 | 
						|
  header_footer_str = OptionWidgetToString(footer_dropdown[2]);
 | 
						|
  aNS->SetFooterStrRight(NS_ConvertUTF8toUTF16(header_footer_str));
 | 
						|
}
 | 
						|
 | 
						|
nsresult
 | 
						|
nsPrintDialogWidgetGTK::ImportSettings(nsIPrintSettings *aNSSettings)
 | 
						|
{
 | 
						|
  NS_PRECONDITION(aNSSettings, "aSettings must not be null");
 | 
						|
  NS_ENSURE_TRUE(aNSSettings, NS_ERROR_FAILURE);
 | 
						|
 | 
						|
  nsCOMPtr<nsPrintSettingsGTK> aNSSettingsGTK(do_QueryInterface(aNSSettings));
 | 
						|
  if (!aNSSettingsGTK)
 | 
						|
    return NS_ERROR_FAILURE;
 | 
						|
 | 
						|
  GtkPrintSettings* settings = aNSSettingsGTK->GetGtkPrintSettings();
 | 
						|
  GtkPageSetup* setup = aNSSettingsGTK->GetGtkPageSetup();
 | 
						|
 | 
						|
  bool geckoBool;
 | 
						|
  aNSSettings->GetShrinkToFit(&geckoBool);
 | 
						|
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(shrink_to_fit_toggle), geckoBool);
 | 
						|
 | 
						|
  aNSSettings->GetPrintBGColors(&geckoBool);
 | 
						|
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(print_bg_colors_toggle), geckoBool);
 | 
						|
 | 
						|
  aNSSettings->GetPrintBGImages(&geckoBool);
 | 
						|
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(print_bg_images_toggle), geckoBool);
 | 
						|
 | 
						|
  gtk_print_unix_dialog_set_settings(GTK_PRINT_UNIX_DIALOG(dialog), settings);
 | 
						|
  gtk_print_unix_dialog_set_page_setup(GTK_PRINT_UNIX_DIALOG(dialog), setup);
 | 
						|
  
 | 
						|
  return NS_OK;
 | 
						|
}
 | 
						|
 | 
						|
nsresult
 | 
						|
nsPrintDialogWidgetGTK::ExportSettings(nsIPrintSettings *aNSSettings)
 | 
						|
{
 | 
						|
  NS_PRECONDITION(aNSSettings, "aSettings must not be null");
 | 
						|
  NS_ENSURE_TRUE(aNSSettings, NS_ERROR_FAILURE);
 | 
						|
 | 
						|
  GtkPrintSettings* settings = gtk_print_unix_dialog_get_settings(GTK_PRINT_UNIX_DIALOG(dialog));
 | 
						|
  GtkPageSetup* setup = gtk_print_unix_dialog_get_page_setup(GTK_PRINT_UNIX_DIALOG(dialog));
 | 
						|
  GtkPrinter* printer = gtk_print_unix_dialog_get_selected_printer(GTK_PRINT_UNIX_DIALOG(dialog));
 | 
						|
  if (settings && setup && printer) {
 | 
						|
    ExportFramePrinting(aNSSettings, settings);
 | 
						|
    ExportHeaderFooter(aNSSettings);
 | 
						|
 | 
						|
    aNSSettings->SetOutputFormat(nsIPrintSettings::kOutputFormatNative);
 | 
						|
 | 
						|
    // Print-to-file is true by default. This must be turned off or else printing won't occur!
 | 
						|
    // (We manually copy the spool file when this flag is set, because we love our embedders)
 | 
						|
    // Even if it is print-to-file in GTK's case, GTK does The Right Thing when we send the job.
 | 
						|
    aNSSettings->SetPrintToFile(false);
 | 
						|
 | 
						|
    aNSSettings->SetShrinkToFit(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(shrink_to_fit_toggle)));
 | 
						|
 | 
						|
    aNSSettings->SetPrintBGColors(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(print_bg_colors_toggle)));
 | 
						|
    aNSSettings->SetPrintBGImages(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(print_bg_images_toggle)));
 | 
						|
 | 
						|
    // Try to save native settings in the session object
 | 
						|
    nsCOMPtr<nsPrintSettingsGTK> aNSSettingsGTK(do_QueryInterface(aNSSettings));
 | 
						|
    if (aNSSettingsGTK) {
 | 
						|
      aNSSettingsGTK->SetGtkPrintSettings(settings);
 | 
						|
      aNSSettingsGTK->SetGtkPageSetup(setup);
 | 
						|
      aNSSettingsGTK->SetGtkPrinter(printer);
 | 
						|
      bool printSelectionOnly;
 | 
						|
      if (useNativeSelection) {
 | 
						|
        _GtkPrintPages pageSetting = (_GtkPrintPages)gtk_print_settings_get_print_pages(settings);
 | 
						|
        printSelectionOnly = (pageSetting == _GTK_PRINT_PAGES_SELECTION);
 | 
						|
      } else {
 | 
						|
        printSelectionOnly = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(selection_only_toggle));
 | 
						|
      }
 | 
						|
      aNSSettingsGTK->SetForcePrintSelectionOnly(printSelectionOnly);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (settings)
 | 
						|
    g_object_unref(settings);
 | 
						|
  return NS_OK;
 | 
						|
}
 | 
						|
 | 
						|
GtkWidget*
 | 
						|
nsPrintDialogWidgetGTK::ConstructHeaderFooterDropdown(const char16_t *currentString)
 | 
						|
{
 | 
						|
#if (MOZ_WIDGET_GTK == 2)
 | 
						|
  GtkWidget* dropdown = gtk_combo_box_new_text();
 | 
						|
#else
 | 
						|
  GtkWidget* dropdown = gtk_combo_box_text_new();
 | 
						|
#endif
 | 
						|
  const char hf_options[][22] = {"headerFooterBlank", "headerFooterTitle",
 | 
						|
                                 "headerFooterURL", "headerFooterDate",
 | 
						|
                                 "headerFooterPage", "headerFooterPageTotal",
 | 
						|
                                 "headerFooterCustom"};
 | 
						|
 | 
						|
  for (unsigned int i = 0; i < ArrayLength(hf_options); i++) {
 | 
						|
#if (MOZ_WIDGET_GTK == 2)
 | 
						|
    gtk_combo_box_append_text(GTK_COMBO_BOX(dropdown), GetUTF8FromBundle(hf_options[i]).get());
 | 
						|
#else
 | 
						|
    gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(dropdown), nullptr, 
 | 
						|
                              GetUTF8FromBundle(hf_options[i]).get());
 | 
						|
#endif
 | 
						|
  }
 | 
						|
 | 
						|
  bool shouldBeCustom = true;
 | 
						|
  NS_ConvertUTF16toUTF8 currentStringUTF8(currentString);
 | 
						|
 | 
						|
  for (unsigned int i = 0; i < ArrayLength(header_footer_tags); i++) {
 | 
						|
    if (!strcmp(currentStringUTF8.get(), header_footer_tags[i])) {
 | 
						|
      gtk_combo_box_set_active(GTK_COMBO_BOX(dropdown), i);
 | 
						|
      g_object_set_data(G_OBJECT(dropdown), "previous-active", GINT_TO_POINTER(i));
 | 
						|
      shouldBeCustom = false;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (shouldBeCustom) {
 | 
						|
    gtk_combo_box_set_active(GTK_COMBO_BOX(dropdown), CUSTOM_VALUE_INDEX);
 | 
						|
    g_object_set_data(G_OBJECT(dropdown), "previous-active", GINT_TO_POINTER(CUSTOM_VALUE_INDEX));
 | 
						|
    char* custom_string = strdup(currentStringUTF8.get());
 | 
						|
    g_object_set_data_full(G_OBJECT(dropdown), "custom-text", custom_string, (GDestroyNotify) free);
 | 
						|
  }
 | 
						|
 | 
						|
  g_signal_connect(dropdown, "changed", (GCallback) ShowCustomDialog, dialog);
 | 
						|
  return dropdown;
 | 
						|
}
 | 
						|
 | 
						|
NS_IMPL_ISUPPORTS(nsPrintDialogServiceGTK, nsIPrintDialogService)
 | 
						|
 | 
						|
nsPrintDialogServiceGTK::nsPrintDialogServiceGTK()
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
nsPrintDialogServiceGTK::~nsPrintDialogServiceGTK()
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
NS_IMETHODIMP
 | 
						|
nsPrintDialogServiceGTK::Init()
 | 
						|
{
 | 
						|
  return NS_OK;
 | 
						|
}
 | 
						|
 | 
						|
NS_IMETHODIMP
 | 
						|
nsPrintDialogServiceGTK::Show(nsPIDOMWindowOuter *aParent,
 | 
						|
                              nsIPrintSettings *aSettings,
 | 
						|
                              nsIWebBrowserPrint *aWebBrowserPrint)
 | 
						|
{
 | 
						|
  NS_PRECONDITION(aParent, "aParent must not be null");
 | 
						|
  NS_PRECONDITION(aSettings, "aSettings must not be null");
 | 
						|
 | 
						|
  nsPrintDialogWidgetGTK printDialog(aParent, aSettings);
 | 
						|
  nsresult rv = printDialog.ImportSettings(aSettings);
 | 
						|
 | 
						|
  NS_ENSURE_SUCCESS(rv, rv);
 | 
						|
 | 
						|
  const gint response = printDialog.Run();
 | 
						|
 | 
						|
  // Handle the result
 | 
						|
  switch (response) {
 | 
						|
    case GTK_RESPONSE_OK:                // Proceed
 | 
						|
      rv = printDialog.ExportSettings(aSettings);
 | 
						|
      break;
 | 
						|
 | 
						|
    case GTK_RESPONSE_CANCEL:
 | 
						|
    case GTK_RESPONSE_CLOSE:
 | 
						|
    case GTK_RESPONSE_DELETE_EVENT:
 | 
						|
    case GTK_RESPONSE_NONE:
 | 
						|
      rv = NS_ERROR_ABORT;
 | 
						|
      break;
 | 
						|
 | 
						|
    case GTK_RESPONSE_APPLY:                // Print preview
 | 
						|
    default:
 | 
						|
      NS_WARNING("Unexpected response");
 | 
						|
      rv = NS_ERROR_ABORT;
 | 
						|
  }
 | 
						|
  return rv;
 | 
						|
}
 | 
						|
 | 
						|
NS_IMETHODIMP
 | 
						|
nsPrintDialogServiceGTK::ShowPageSetup(nsPIDOMWindowOuter *aParent,
 | 
						|
                                       nsIPrintSettings *aNSSettings)
 | 
						|
{
 | 
						|
  NS_PRECONDITION(aParent, "aParent must not be null");
 | 
						|
  NS_PRECONDITION(aNSSettings, "aSettings must not be null");
 | 
						|
  NS_ENSURE_TRUE(aNSSettings, NS_ERROR_FAILURE);
 | 
						|
 | 
						|
  nsCOMPtr<nsIWidget> widget = WidgetUtils::DOMWindowToWidget(aParent);
 | 
						|
  NS_ASSERTION(widget, "Need a widget for dialog to be modal.");
 | 
						|
  GtkWindow* gtkParent = get_gtk_window_for_nsiwidget(widget);
 | 
						|
  NS_ASSERTION(gtkParent, "Need a GTK window for dialog to be modal.");
 | 
						|
 | 
						|
  nsCOMPtr<nsPrintSettingsGTK> aNSSettingsGTK(do_QueryInterface(aNSSettings));
 | 
						|
  if (!aNSSettingsGTK)
 | 
						|
    return NS_ERROR_FAILURE;
 | 
						|
 | 
						|
  // We need to init the prefs here because aNSSettings in its current form is a dummy in both uses of the word
 | 
						|
  nsCOMPtr<nsIPrintSettingsService> psService = do_GetService("@mozilla.org/gfx/printsettings-service;1");
 | 
						|
  if (psService) {
 | 
						|
    nsString printName;
 | 
						|
    aNSSettings->GetPrinterName(printName);
 | 
						|
    if (printName.IsVoid()) {
 | 
						|
      psService->GetDefaultPrinterName(printName);
 | 
						|
      aNSSettings->SetPrinterName(printName);
 | 
						|
    }
 | 
						|
    psService->InitPrintSettingsFromPrefs(aNSSettings, true, nsIPrintSettings::kInitSaveAll);
 | 
						|
  }
 | 
						|
 | 
						|
  GtkPrintSettings* gtkSettings = aNSSettingsGTK->GetGtkPrintSettings();
 | 
						|
  GtkPageSetup* oldPageSetup = aNSSettingsGTK->GetGtkPageSetup();
 | 
						|
 | 
						|
  GtkPageSetup* newPageSetup = gtk_print_run_page_setup_dialog(gtkParent, oldPageSetup, gtkSettings);
 | 
						|
 | 
						|
  aNSSettingsGTK->SetGtkPageSetup(newPageSetup);
 | 
						|
 | 
						|
  // Now newPageSetup has a refcount of 2 (SetGtkPageSetup will addref), put it to 1 so if
 | 
						|
  // this gets replaced we don't leak.
 | 
						|
  g_object_unref(newPageSetup);
 | 
						|
 | 
						|
  if (psService)
 | 
						|
    psService->SavePrintSettingsToPrefs(aNSSettings, true, nsIPrintSettings::kInitSaveAll);
 | 
						|
 | 
						|
  return NS_OK;
 | 
						|
}
 |