diff options
Diffstat (limited to 'embed/xulrunner/components/GeckoPrintService.cpp')
-rw-r--r-- | embed/xulrunner/components/GeckoPrintService.cpp | 713 |
1 files changed, 713 insertions, 0 deletions
diff --git a/embed/xulrunner/components/GeckoPrintService.cpp b/embed/xulrunner/components/GeckoPrintService.cpp new file mode 100644 index 000000000..b1d34a960 --- /dev/null +++ b/embed/xulrunner/components/GeckoPrintService.cpp @@ -0,0 +1,713 @@ +/* + * Copyright © 2006, 2007 Christian Persch + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $Id$ + */ + +#include <xpcom-config.h> +#include "config.h" + +#include <glib.h> +#include <glib/gi18n.h> +#include <gtk/gtkcheckbutton.h> +#include <gtk/gtkdialog.h> +#include <gtk/gtklabel.h> +#include <gtk/gtkmessagedialog.h> +#include <gtk/gtkprintunixdialog.h> +#include <gtk/gtkstock.h> +#include <gtk/gtkwindow.h> +#include <glade/glade-xml.h> + +#include <nsStringGlue.h> + +#include <nsCOMPtr.h> +#include <nsIDOMWindow.h> +#include <nsIDOMWindowInternal.h> + +#include "eel-gconf-extensions.h" +#include "ephy-debug.h" +#include "ephy-embed-shell.h" +#include "ephy-file-helpers.h" +#include "ephy-gui.h" +#include "ephy-prefs.h" +#include "ephy-stock-icons.h" + +#include "AutoJSContextStack.h" +#include "AutoWindowModalState.h" +#include "EphyUtils.h" +#include "GeckoPrintSession.h" + +#include "GeckoPrintService.h" + +/* Some printing keys */ + +#define CONF_PRINT_BG_COLORS "/apps/epiphany/dialogs/print_background_colors" +#define CONF_PRINT_BG_IMAGES "/apps/epiphany/dialogs/print_background_images" +#define CONF_PRINT_COLOR "/apps/epiphany/dialogs/print_color" +#define CONF_PRINT_DATE "/apps/epiphany/dialogs/print_date" +#define CONF_PRINT_PAGE_NUMBERS "/apps/epiphany/dialogs/print_page_numbers" +#define CONF_PRINT_PAGE_TITLE "/apps/epiphany/dialogs/print_page_title" +#define CONF_PRINT_PAGE_URL "/apps/epiphany/dialogs/print_page_url" + +#define LITERAL(s) reinterpret_cast<const nsAString::char_type*>(NS_L(s)) + +/* From nsIDeviceContext.h */ +#define NS_ERROR_GFX_PRINTER_BASE (1) /* adjustable :-) */ +#define NS_ERROR_GFX_PRINTER_ACCESS_DENIED \ + NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_GFX,NS_ERROR_GFX_PRINTER_BASE+5) +#define NS_ERROR_GFX_PRINTER_NAME_NOT_FOUND \ + NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_GFX,NS_ERROR_GFX_PRINTER_BASE+4) + +NS_IMPL_ISUPPORTS1 (GeckoPrintService, + nsIPrintingPromptService) + +GeckoPrintService::GeckoPrintService() +{ + LOG ("GeckoPrintService ctor [%p]", this); +} + +GeckoPrintService::~GeckoPrintService() +{ + LOG ("GeckoPrintService dtor [%p]", this); +} + +/* nsIPrintingPromptService implementation */ + +/* void showPrintDialog (in nsIDOMWindow parent, + in nsIWebBrowserPrint webBrowserPrint, + in nsIPrintSettings printSettings); */ +NS_IMETHODIMP +GeckoPrintService::ShowPrintDialog (nsIDOMWindow *aParent, + nsIWebBrowserPrint *aWebBrowserPrint, + nsIPrintSettings *aSettings) +{ + /* Locked down? */ + if (eel_gconf_get_boolean (CONF_LOCKDOWN_DISABLE_PRINTING)) { + return NS_ERROR_GFX_PRINTER_ACCESS_DENIED; + } + + GeckoPrintSession *session = GeckoPrintSession::FromSettings (aSettings); + NS_ENSURE_TRUE (session, NS_ERROR_INVALID_POINTER); + + /* Print settings changes disallowed, just translate the settings */ + if (eel_gconf_get_boolean (CONF_LOCKDOWN_DISABLE_PRINT_SETUP)) { + return PrintUnattended (aParent, aSettings); + } + + /* Not locked down, show the dialogue */ + + nsresult rv; +#if 0 + PRBool haveSelection = PR_FALSE; + rv = aSettings->GetPrintOptions(nsIPrintSettings::kEnableSelectionRB, &haveSelection); + NS_ENSURE_SUCCESS (rv, rv); +#endif + + PRInt16 frameUI = nsIPrintSettings::kFrameEnableAll; + rv = aSettings->GetHowToEnableFrameUI (&frameUI); + NS_ENSURE_SUCCESS (rv, rv); + + GtkWidget *parent = EphyUtils::FindGtkParent (aParent); + NS_ENSURE_TRUE(parent, NS_ERROR_INVALID_POINTER); + + AutoJSContextStack stack; + rv = stack.Init (); + if (NS_FAILED (rv)) { + return rv; + } + + AutoWindowModalState modalState (aParent); + + EphyEmbedShell *shell = ephy_embed_shell_get_default (); + + GladeXML *xml = glade_xml_new (ephy_file ("print.glade"), + "print_dialog_custom_tab", NULL); + if (!xml) { + return NS_ERROR_FAILURE; + } + + /* Build the custom tab */ + GtkWidget *custom_tab = glade_xml_get_widget (xml, "custom_tab_container"); + ephy_gui_connect_checkbutton_to_gconf (glade_xml_get_widget (xml, "print_bg_colors_checkbutton"), CONF_PRINT_BG_COLORS); + ephy_gui_connect_checkbutton_to_gconf (glade_xml_get_widget (xml, "print_bg_images_checkbutton"), CONF_PRINT_BG_IMAGES); + ephy_gui_connect_checkbutton_to_gconf (glade_xml_get_widget (xml, "print_date_checkbutton"), CONF_PRINT_DATE); + ephy_gui_connect_checkbutton_to_gconf (glade_xml_get_widget (xml, "print_page_numbers_checkbutton"), CONF_PRINT_PAGE_NUMBERS); + ephy_gui_connect_checkbutton_to_gconf (glade_xml_get_widget (xml, "print_page_title_checkbutton"), CONF_PRINT_PAGE_TITLE); + ephy_gui_connect_checkbutton_to_gconf (glade_xml_get_widget (xml, "print_page_url_checkbutton"), CONF_PRINT_PAGE_URL); + + GtkWidget *frame_box = glade_xml_get_widget (xml, "frame_box"); + GtkWidget *print_frames_normal = glade_xml_get_widget (xml, "print_frames_normal"); + GtkWidget *print_frames_selected = glade_xml_get_widget (xml, "print_frames_selected"); + GtkWidget *print_frames_separately = glade_xml_get_widget (xml, "print_frames_separately"); + + /* FIXME: store/load from pref */ + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (print_frames_normal), TRUE); + + if (frameUI == nsIPrintSettings::kFrameEnableAll) { + /* Allow all frame options */ + gtk_widget_set_sensitive (frame_box, TRUE); + } else if (frameUI == nsIPrintSettings::kFrameEnableAsIsAndEach) { + /* Allow all except "selected frame" */ + gtk_widget_set_sensitive (frame_box, TRUE); + gtk_widget_set_sensitive (print_frames_selected, FALSE); + /* Preselect this one, since the default above only prints _one page_ ! */ + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (print_frames_separately), TRUE); + } + + /* FIXME: this sucks! find some way to do all of this async! */ + GtkWidget *dialog = gtk_print_unix_dialog_new (NULL /* FIXME title */, + GTK_WINDOW (parent)); + GtkPrintUnixDialog *print_dialog = GTK_PRINT_UNIX_DIALOG (dialog); + + GtkPrintCapabilities capabilities = + 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_PS | + GTK_PRINT_CAPABILITY_GENERATE_PDF); + gtk_print_unix_dialog_set_manual_capabilities (print_dialog, capabilities); + + gtk_print_unix_dialog_set_page_setup (print_dialog, + ephy_embed_shell_get_page_setup (shell)); + gtk_print_unix_dialog_set_settings (print_dialog, + ephy_embed_shell_get_print_settings (shell)); + + /* Remove custom tab from its dummy window and put it in the print dialogue */ + g_object_ref_sink (custom_tab); + gtk_container_remove (GTK_CONTAINER (custom_tab->parent), custom_tab); + gtk_print_unix_dialog_add_custom_tab (print_dialog, custom_tab, + gtk_label_new (_("Options"))); /* FIXME better name! */ + g_object_unref (custom_tab); + g_object_unref (xml); + + gtk_window_set_icon_name (GTK_WINDOW (dialog), EPHY_STOCK_EPHY); + + int response = gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_hide (dialog); + + GtkPrinter *printer = gtk_print_unix_dialog_get_selected_printer (print_dialog); + + if (response != GTK_RESPONSE_OK || !printer) { + gtk_widget_destroy (dialog); + + return NS_ERROR_ABORT; + } + + PRInt16 printFrames = nsIPrintSettings::kNoFrames; + if (frameUI != nsIPrintSettings::kFrameEnableNone) { + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (print_frames_normal))) { + printFrames = nsIPrintSettings::kFramesAsIs; + } else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (print_frames_selected))) { + printFrames = nsIPrintSettings::kSelectedFrame; + } if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (print_frames_separately))) { + printFrames = nsIPrintSettings::kEachFrameSep; + } + } + + GtkPageSetup *pageSetup = gtk_print_unix_dialog_get_page_setup (print_dialog); /* no reference owned */ + ephy_embed_shell_set_page_setup (shell, pageSetup); + + GtkPrintSettings *settings = gtk_print_unix_dialog_get_settings (print_dialog); + ephy_embed_shell_set_print_settings (shell, settings); + + /* We copy the setup and settings so we can modify them to unset + * options handled by gecko. + */ + GtkPageSetup *pageSetupCopy = gtk_page_setup_copy (pageSetup); + pageSetup = pageSetupCopy; + + GtkPrintSettings *settingsCopy = gtk_print_settings_copy (settings); + g_object_unref (settings); + settings = settingsCopy; + + rv = session->SetSettings (aSettings, settings, pageSetup, printer); + + /* Now translate the settings to nsIPrintSettings */ + if (NS_SUCCEEDED (rv)) { + nsCString sourceFile; + session->GetSourceFile (sourceFile); + if (!sourceFile.IsEmpty ()) { + rv = TranslateSettings (settings, pageSetup, printer, sourceFile, printFrames, PR_TRUE, aSettings); + } else { + rv = NS_ERROR_FAILURE; + } + } + + gtk_widget_destroy (dialog); + + g_object_unref (settings); + g_object_unref (pageSetup); + + return rv; +} + +/* void showProgress (in nsIDOMWindow parent, + in nsIWebBrowserPrint webBrowserPrint, + in nsIPrintSettings printSettings, + in nsIObserver openDialogObserver, + in boolean isForPrinting, + out nsIWebProgressListener webProgressListener, + out nsIPrintProgressParams printProgressParams, + out boolean notifyOnOpen); */ +NS_IMETHODIMP +GeckoPrintService::ShowProgress (nsIDOMWindow *aParent, + nsIWebBrowserPrint *aWebBrowserPrint, + nsIPrintSettings *aPrintSettings, + nsIObserver *aOpenDialogObserver, + PRBool aIsForPrinting, + nsIWebProgressListener **_webProgressListener, + nsIPrintProgressParams **_printProgressParams, + PRBool *_notifyOnOpen) +{ + /* Print preview */ + if (!aIsForPrinting) { + return NS_OK; + } + + nsresult rv; + nsCOMPtr<nsIDOMWindowInternal> domWin (do_QueryInterface (aParent, &rv)); + NS_ENSURE_SUCCESS (rv, rv); + + nsCOMPtr<nsIPrintSession> session; + rv = aPrintSettings->GetPrintSession (getter_AddRefs (session)); + NS_ENSURE_TRUE (NS_SUCCEEDED (rv) && session, nsnull); + + nsCOMPtr<nsIPrintProgress> progress (do_QueryInterface (session, &rv)); + NS_ENSURE_SUCCESS (rv, rv); + + /* Our print session implements those interfaces */ + rv = CallQueryInterface (session, _webProgressListener); + rv |= CallQueryInterface (session, _printProgressParams); + NS_ENSURE_SUCCESS (rv, rv); + + /* Setting this to PR_FALSE will make gecko immediately start printing + * when we return from this function. + * If we set this to PR_TRUE, we need to call aOpenDialogObserver::Observe + * (topic, subject and data don't matter) when we're ready for printing. + */ + *_notifyOnOpen = PR_FALSE; + + return progress->OpenProgressDialog (domWin, nsnull, nsnull, aOpenDialogObserver, _notifyOnOpen); +} + +/* void showPageSetup (in nsIDOMWindow parent, + in nsIPrintSettings printSettings, + in nsIObserver aObs); */ +NS_IMETHODIMP GeckoPrintService::ShowPageSetup (nsIDOMWindow *aParent, + nsIPrintSettings *aPrintSettings, + nsIObserver *aObserver) +{ + /* This function is never called from gecko code */ +#if 0 + /* Locked down? */ + if (eel_gconf_get_boolean (CONF_LOCKDOWN_DISABLE_PRINTING) || + eel_gconf_get_boolean (CONF_LOCKDOWN_DISABLE_PRINT_SETUP)) { + return NS_ERROR_ABORT; + } + + GtkWidget *parent = EphyUtils::FindGtkParent (aParent); + NS_ENSURE_TRUE(parent, NS_ERROR_INVALID_POINTER); + + AutoJSContextStack stack; + nsresult rv = stack.Init (); + if (NS_FAILED (rv)) { + return rv; + } + + AutoWindowModalState modalState (aParent); + + EphyEmbedShell *shell = ephy_embed_shell_get_default (); + GtkPageSetup *new_setup = + gtk_print_run_page_setup_dialog (GTK_WINDOW (parent), + ephy_embed_shell_get_page_setup (shell), + ephy_embed_shell_get_print_settings (shell)); + if (new_setup) { + ephy_embed_shell_set_page_setup (shell, new_setup); + g_object_unref (new_setup); + } + + /* FIXME do we need to notify aObserver somehow? */ + return NS_OK; +#endif + return NS_ERROR_NOT_IMPLEMENTED; +} + +/* void showPrinterProperties (in nsIDOMWindow parent, + in wstring printerName, + in nsIPrintSettings printSettings); */ +NS_IMETHODIMP +GeckoPrintService::ShowPrinterProperties (nsIDOMWindow *aParent, + const PRUnichar *aPrinterName, + nsIPrintSettings *aPrintSettings) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +/* Private methods */ + +#if 0 +typedef struct +{ + GMainLoop *mainLoop; + GtkPrinter *mPrinter; + guint timeout; + int response; + guint cancelled : 1; +} FindPrinterData; + +static void +FreeFindPrinterData (FindPrinterData *data) +{ + if (data->printer) { + g_object_unref (data->printer); + } +} + +static void +DialogResponseCallback (GtkWidget *aDialog, + int aResponse, + FindPrinterData *data) +{ + data->response = aResponse; + g_main_loop_quit (data->mainloop); +} + +static void +TimeoutCallback (FindPrinterData *data) +{ + data->cancelled = TRUE; + g_main_loop_quit (data->mainLoop); + data->mainLoop = NULL; + return FALSE; +} + +static gboolean +PrinterEnumerateCallback (GtkPrinter *aPrinter, + FindPrinterData *data) +{ + if (data->cancelled) + return TRUE; + + if ((data->printerName && + strcmp (data->printerName, gtk_printer_get_name (aPrinter)) == 0) || + (!data->printerName && + gtk_printer_is_default (aPrinter))) { + data->printer = g_object_ref (aPrinter); + return TRUE; + } + + return FALSE; +} +#endif + +nsresult +GeckoPrintService::PrintUnattended (nsIDOMWindow *aParent, + nsIPrintSettings *aPrintSettings) +{ + return NS_ERROR_NOT_IMPLEMENTED; +#if 0 + GtkWidget *parent = EphyUtils::FindGtkParent (aParent); + NS_ENSURE_TRUE(parent, NS_ERROR_INVALID_POINTER); + + PRBool isCalledFromScript = EphyJSUtils::IsCalledFromScript (); + + nsresult rv; + AutoJSContextStack stack; + rv = stack.Init (); + if (NS_FAILED (rv)) { + return rv; + } + + AutoWindowModalState modalState (aParent); + + EphyEmbedShell *shell = ephy_embed_shell_get_default (); + GtkPrintSettings *settings = ephy_embed_shell_get_print_settings (shell); + NS_ENSURE_TRUE (settings, NS_ERROR_FAILURE); + + const char *printer = gtk_print_settings_get (settings, GTK_PRINT_SETTINGS_PRINTER); +#if 0 + if (!printer || !printer[0]) { + return NS_ERROR_GFX_PRINTER_NAME_NOT_FOUND; + } +#endif + /* We need to find the printer, so we need to run a mainloop. + * If called from a script, give the user a way to cancel the print; + * otherwise we'll just show a generic progress message. + */ + GtkWidget *dialog; + if (isCalledFromScript) { + dialog = gtk_message_dialog_new (GTK_WINDOW (parent), + GtkDialogFlags (0), + GTK_MESSAGE_QUESTION, + GTK_BUTTONS_CANCEL, + "%s", _("Print this page?")); + gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_PRINT, + GTK_RESPONSE_ACCEPT); + } else { + dialog = gtk_message_dialog_new (GTK_WINDOW (parent), + GtkDialogFlags (0), + GTK_MESSAGE_QUESTION, + GTK_BUTTONS_CANCEL, + "%s", _("Preparing to print")); + } + gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CANCEL); + gtk_window_set_icon_name (GTK_WINDOW (dialog), EPHY_STOCK_EPHY); + gtk_window_set_modal (GTK_WINDOW (dialog), TRUE); + + FindPrinterData *data = g_new0 (PrinterData, 1); + data->dialog = dialog; + + g_signal_connect (dialog, "response", + G_CALLBACK (DialogResponseCallback), data); + + /* Don't run forever */ + data->timeoutId = g_timeout_add (PRINTER_ENUMERATE_TIMEOUT, + (GSourceFunc) EnumerateTimoutCallback, + data); + /* Enumerate printers until we find our printer */ + gtk_enumerate_printers ((GtkPrinterFunc) PrinterEnumerateCallback, + data, + (GDestroyNotify) EnumerateDestroyCallback, FALSE); + + /* Now run the mainloop */ + int response = gtk_dialog_run (GTK_DIALOG (dialog)); + Printer + gtk_widget_destroy (dialog); + + if (response != GTK_RESPONSE_ACCEPT) { + return NS_ERROR_ABORT; + } + + nsCString sourceFile; + session->GetSourceFile (sourceFile); + if (!sourceFile.IsEmpty ()) { + rv = TranslateSettings (settings, + ephy_embed_shell_get_page_setup (shell), + sourceFile, PR_TRUE, aSettings); + } else { + rv = NS_ERROR_FAILURE; + } + + return rv; + } +#endif /* if 0 */ +} + +/* Static methods */ + +/* static */ nsresult +GeckoPrintService::TranslateSettings (GtkPrintSettings *aGtkSettings, + GtkPageSetup *aPageSetup, + GtkPrinter *aPrinter, + const nsACString &aSourceFile, + PRInt16 aPrintFrames, + PRBool aIsForPrinting, + nsIPrintSettings *aSettings) +{ + NS_ENSURE_ARG (aPrinter); + NS_ENSURE_ARG (aGtkSettings); + NS_ENSURE_ARG (aPageSetup); + +#if 0 + /* Locked down? */ + if (gtk_print_settings_get_print_to_file (aGtkSettings) && + eel_gconf_get_boolean (CONF_LOCKDOWN_DISABLE_SAVE_TO_DISK)) { + return NS_ERROR_GFX_PRINTER_ACCESS_DENIED; + } +#endif + + GtkPrintCapabilities capabilities = gtk_printer_get_capabilities (aPrinter); + + /* Initialisation */ + aSettings->SetIsInitializedFromPrinter (PR_FALSE); /* FIXME: PR_TRUE? */ + aSettings->SetIsInitializedFromPrefs (PR_FALSE); /* FIXME: PR_TRUE? */ + aSettings->SetPrintSilent (PR_FALSE); + aSettings->SetShowPrintProgress (PR_TRUE); + + /* We always print PS to a file and then hand that off to gtk-print */ + aSettings->SetPrinterName (LITERAL ("PostScript/default")); + + if (aIsForPrinting) { + aSettings->SetPrintToFile (PR_TRUE); + + nsString sourceFile; + NS_CStringToUTF16 (aSourceFile, + NS_CSTRING_ENCODING_NATIVE_FILESYSTEM, + sourceFile); + + aSettings->SetToFileName (sourceFile.get ()); + } else { + /* Otherwise mozilla will create the file nevertheless and + * fail since we haven't set a name! + */ + aSettings->SetPrintToFile (PR_FALSE); + } + + /* This is the time between printing each page, in ms. + * It 'gives the user more time to press cancel' ! + * We don't want any of this nonsense, so set this to a low value, + * just enough to update the print dialogue. + */ + aSettings->SetPrintPageDelay (50); + + if (aIsForPrinting) { + NS_ENSURE_TRUE (aPrinter, NS_ERROR_FAILURE); + + const char *format = gtk_print_settings_get (aGtkSettings, GTK_PRINT_SETTINGS_OUTPUT_FILE_FORMAT); + if (!format) + format = "ps"; + + if (strcmp (format, "pdf") == 0 && + gtk_printer_accepts_pdf (aPrinter)) { + aSettings->SetOutputFormat (nsIPrintSettings::kOutputFormatPDF); + } else if (strcmp (format, "ps") == 0 && + gtk_printer_accepts_ps (aPrinter)) { + aSettings->SetOutputFormat (nsIPrintSettings::kOutputFormatPS); + } else { + g_warning ("Output format '%s' specified, but printer '%s' does not support it!", + format, gtk_printer_get_name (aPrinter)); + return NS_ERROR_FAILURE; + } + + int n_copies = gtk_print_settings_get_n_copies (aGtkSettings); + if (n_copies <= 0) + return NS_ERROR_FAILURE; + if (capabilities & GTK_PRINT_CAPABILITY_COPIES) { + aSettings->SetNumCopies (1); + } else { + /* We have to copy them ourself */ + aSettings->SetNumCopies (n_copies); + gtk_print_settings_set_n_copies (aGtkSettings, 1); + } + + gboolean reverse = gtk_print_settings_get_reverse (aGtkSettings); + if (capabilities & GTK_PRINT_CAPABILITY_REVERSE) { + aSettings->SetPrintReversed (PR_FALSE); + } else { + aSettings->SetPrintReversed (reverse); + gtk_print_settings_set_reverse (aGtkSettings, FALSE); + } + + GtkPageSet pageSet = gtk_print_settings_get_page_set (aGtkSettings); + aSettings->SetPrintOptions (nsIPrintSettings::kPrintEvenPages, + pageSet != GTK_PAGE_SET_ODD); + aSettings->SetPrintOptions (nsIPrintSettings::kPrintEvenPages, + pageSet != GTK_PAGE_SET_EVEN); + + GtkPrintPages printPages = gtk_print_settings_get_print_pages (aGtkSettings); + switch (printPages) { + case GTK_PRINT_PAGES_RANGES: { + int numRanges = 0; + GtkPageRange *pageRanges = gtk_print_settings_get_page_ranges (aGtkSettings, &numRanges); + if (numRanges > 0) { + /* FIXME: We can only support one range, ignore more ranges or raise error? */ + aSettings->SetPrintRange (nsIPrintSettings::kRangeSpecifiedPageRange); + /* Gecko page numbers start at 1, while gtk page numbers start at 0 */ + aSettings->SetStartPageRange (pageRanges[0].start + 1); + aSettings->SetEndPageRange (pageRanges[0].end + 1); + + g_free (pageRanges); + break; + } + /* Fall-through to PAGES_ALL */ + } + case GTK_PRINT_PAGES_CURRENT: + /* not supported, fall through */ + case GTK_PRINT_PAGES_ALL: + aSettings->SetPrintRange (nsIPrintSettings::kRangeAllPages); + break; + /* FIXME: we need some custom ranges here, "Selection" and "Focused Frame" */ + } + } else { + aSettings->SetPrintOptions (nsIPrintSettings::kPrintEvenPages, PR_TRUE); + aSettings->SetPrintOptions (nsIPrintSettings::kPrintEvenPages, PR_TRUE); + aSettings->SetPrintReversed (PR_FALSE); + aSettings->SetPrintRange (nsIPrintSettings::kRangeAllPages); + } + + /* And clear those in the settings, so the printer doesn't try to apply them too */ + gtk_print_settings_set_print_pages (aGtkSettings, GTK_PRINT_PAGES_ALL); + gtk_print_settings_set_page_ranges (aGtkSettings, NULL, 0); + gtk_print_settings_set_page_set (aGtkSettings, GTK_PAGE_SET_ALL); + + switch (gtk_print_settings_get_orientation (aGtkSettings)) { + case GTK_PAGE_ORIENTATION_PORTRAIT: + case GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT: /* not supported */ + aSettings->SetOrientation (nsIPrintSettings::kPortraitOrientation); + break; + case GTK_PAGE_ORIENTATION_LANDSCAPE: + case GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE: /* not supported */ + aSettings->SetOrientation (nsIPrintSettings::kLandscapeOrientation); + break; + } + + aSettings->SetPrintInColor (gtk_print_settings_get_use_color (aGtkSettings)); + + aSettings->SetPaperSizeUnit(nsIPrintSettings::kPaperSizeMillimeters); + + GtkPaperSize *paperSize = gtk_page_setup_get_paper_size (aPageSetup); + if (!paperSize) { + return NS_ERROR_FAILURE; + } + + aSettings->SetPaperSizeType (nsIPrintSettings::kPaperSizeDefined); + aSettings->SetPaperWidth (gtk_paper_size_get_width (paperSize, GTK_UNIT_MM)); + aSettings->SetPaperHeight (gtk_paper_size_get_height (paperSize, GTK_UNIT_MM)); + aSettings->SetPaperName (NS_ConvertUTF8toUTF16 (gtk_paper_size_get_name (paperSize)).get ()); + + /* Sucky mozilla wants margins in inch! */ + aSettings->SetMarginTop (gtk_page_setup_get_top_margin (aPageSetup, GTK_UNIT_INCH)); + aSettings->SetMarginBottom (gtk_page_setup_get_bottom_margin (aPageSetup, GTK_UNIT_INCH)); + aSettings->SetMarginLeft (gtk_page_setup_get_left_margin (aPageSetup, GTK_UNIT_INCH)); + aSettings->SetMarginRight (gtk_page_setup_get_right_margin (aPageSetup, GTK_UNIT_INCH)); + + aSettings->SetHeaderStrLeft (eel_gconf_get_boolean (CONF_PRINT_PAGE_TITLE) ? LITERAL ("&T") : LITERAL ("")); + aSettings->SetHeaderStrCenter (LITERAL ("")); + aSettings->SetHeaderStrRight (eel_gconf_get_boolean (CONF_PRINT_PAGE_URL) ? LITERAL ("&U") : LITERAL ("")); + aSettings->SetFooterStrLeft (eel_gconf_get_boolean (CONF_PRINT_PAGE_NUMBERS) ? LITERAL ("&PT") : LITERAL ("")); + aSettings->SetFooterStrCenter (LITERAL ("")); + aSettings->SetFooterStrRight (eel_gconf_get_boolean (CONF_PRINT_DATE) ? LITERAL ("&D") : LITERAL ("")); + + aSettings->SetPrintFrameType (aPrintFrames); + aSettings->SetPrintFrameTypeUsage (nsIPrintSettings::kUseSettingWhenPossible); + + /* FIXME: only if GTK_PRINT_CAPABILITY_SCALE is not set? */ + aSettings->SetScaling (gtk_print_settings_get_scale (aGtkSettings) / 100.0); + gtk_print_settings_set_scale (aGtkSettings, 1.0); + + aSettings->SetShrinkToFit (PR_FALSE); /* FIXME setting */ + + aSettings->SetPrintBGColors (eel_gconf_get_boolean (CONF_PRINT_BG_COLORS) != FALSE); + aSettings->SetPrintBGImages (eel_gconf_get_boolean (CONF_PRINT_BG_IMAGES) != FALSE); + + /* aSettings->SetPlexName (LITERAL ("default")); */ + /* aSettings->SetColorspace (LITERAL ("default")); */ + /* aSettings->SetResolutionName (LITERAL ("default")); */ + /* aSettings->SetDownloadFonts (PR_TRUE); */ + + /* Unset those setting that we can handle, so they don't get applied + * again for the print job. + */ + /* gtk_print_settings_set_collate (aGtkSettings, FALSE); not yet */ + /* FIXME: Unset the orientation for the print job? */ + /* gtk_print_settings_set_orientation (aGtkSettings, GTK_PAGE_ORIENTATION_PORTRAIT); */ + /* FIXME: unset output format -> "ps" ? */ + + return NS_OK; +} |