From 0a71e82d1e6ca31f6e00a5b22ede0ccdc9913c35 Mon Sep 17 00:00:00 2001 From: Carlos Garcia Campos Date: Fri, 11 May 2007 12:43:02 +0000 Subject: [PATCH] Add print button in preview mode. Fixes bug #396475. 2007-05-11 Carlos Garcia Campos * data/evince-ui.xml: * shell/ev-application.[ch]: (get_print_settings_from_args), (ev_application_open_uri_at_dest), (ev_application_open_uri), (ev_application_open_uri_list): * shell/ev-window.[ch]: (ev_window_clear_print_settings_file), (ev_window_open_uri), (ev_window_cmd_file_open_copy_at_dest), (ev_window_cmd_recent_file_activate), (ev_window_run_preview), (ev_window_cmd_view_reload), (lookup_printer_from_name), (ev_window_preview_print_finished), (ev_window_cmd_preview_print), (ev_window_dispose): * shell/main.c: (arguments_parse): Add print button in preview mode. Fixes bug #396475. svn path=/trunk/; revision=2450 --- ChangeLog | 16 ++++ data/evince-ui.xml | 2 + shell/ev-application.c | 32 ++++++-- shell/ev-application.h | 1 + shell/ev-window.c | 165 ++++++++++++++++++++++++++++++++++++++++- shell/ev-window.h | 3 +- shell/main.c | 17 +++++ 7 files changed, 225 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2288a65c..98c80839 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2007-05-11 Carlos Garcia Campos + + * data/evince-ui.xml: + * shell/ev-application.[ch]: (get_print_settings_from_args), + (ev_application_open_uri_at_dest), (ev_application_open_uri), + (ev_application_open_uri_list): + * shell/ev-window.[ch]: (ev_window_clear_print_settings_file), + (ev_window_open_uri), (ev_window_cmd_file_open_copy_at_dest), + (ev_window_cmd_recent_file_activate), (ev_window_run_preview), + (ev_window_cmd_view_reload), (lookup_printer_from_name), + (ev_window_preview_print_finished), (ev_window_cmd_preview_print), + (ev_window_dispose): + * shell/main.c: (arguments_parse): + + Add print button in preview mode. Fixes bug #396475. + 2007-05-10 Nickolay V. Shmyrev * cut-n-paste/zoom-control/ephy-zoom.h: diff --git a/data/evince-ui.xml b/data/evince-ui.xml index 685d47d5..f85bd42f 100644 --- a/data/evince-ui.xml +++ b/data/evince-ui.xml @@ -132,5 +132,7 @@ + + diff --git a/shell/ev-application.c b/shell/ev-application.c index ce67ebbf..d2fe2dca 100644 --- a/shell/ev-application.c +++ b/shell/ev-application.c @@ -352,6 +352,22 @@ get_unlink_temp_file_from_args (GHashTable *args) return unlink_temp_file; } +static const gchar * +get_print_settings_from_args (GHashTable *args) +{ + const gchar *print_settings = NULL; + GValue *value = NULL; + + g_assert (args != NULL); + + value = g_hash_table_lookup (args, "print-settings"); + if (value) { + print_settings = g_value_get_string (value); + } + + return print_settings; +} + /** * ev_application_open_window: * @application: The instance of the application. @@ -509,9 +525,10 @@ ev_application_open_uri_at_dest (EvApplication *application, EvLinkDest *dest, EvWindowRunMode mode, gboolean unlink_temp_file, + const gchar *print_settings, guint timestamp) { - EvWindow *new_window; + EvWindow *new_window; g_return_if_fail (uri != NULL); @@ -532,7 +549,8 @@ ev_application_open_uri_at_dest (EvApplication *application, /* We need to load uri before showing the window, so we can restore window size without flickering */ - ev_window_open_uri (new_window, uri, dest, mode, unlink_temp_file); + ev_window_open_uri (new_window, uri, dest, mode, + unlink_temp_file, print_settings); ev_document_fc_mutex_lock (); gtk_widget_show (GTK_WIDGET (new_window)); @@ -560,6 +578,7 @@ ev_application_open_uri (EvApplication *application, EvLinkDest *dest = NULL; EvWindowRunMode mode = EV_WINDOW_MODE_NORMAL; gboolean unlink_temp_file = FALSE; + const gchar *print_settings; GdkScreen *screen = NULL; if (args) { @@ -568,11 +587,12 @@ ev_application_open_uri (EvApplication *application, mode = get_window_run_mode_from_args (args); unlink_temp_file = (mode == EV_WINDOW_MODE_PREVIEW && get_unlink_temp_file_from_args (args)); + print_settings = get_print_settings_from_args (args); } ev_application_open_uri_at_dest (application, uri, screen, - dest, mode, unlink_temp_file, - timestamp); + dest, mode, unlink_temp_file, + print_settings, timestamp); if (dest) g_object_unref (dest); @@ -590,8 +610,8 @@ ev_application_open_uri_list (EvApplication *application, for (l = uri_list; l != NULL; l = l->next) { ev_application_open_uri_at_dest (application, (char *)l->data, - screen, NULL, 0, FALSE, - timestamp); + screen, NULL, 0, FALSE, + NULL, timestamp); } } diff --git a/shell/ev-application.h b/shell/ev-application.h index 0ba1851b..fbe992ac 100644 --- a/shell/ev-application.h +++ b/shell/ev-application.h @@ -76,6 +76,7 @@ void ev_application_open_uri_at_dest (EvApplication *applicati EvLinkDest *dest, EvWindowRunMode mode, gboolean unlink_temp_file, + const gchar *print_settings, guint32 timestamp); void ev_application_open_uri_list (EvApplication *application, GSList *uri_list, diff --git a/shell/ev-window.c b/shell/ev-window.c index 939f510b..079cb1c3 100644 --- a/shell/ev-window.c +++ b/shell/ev-window.c @@ -157,6 +157,7 @@ struct _EvWindowPrivate { /* Preview mode */ GtkWidget *preview_toolbar; + gchar *print_settings_file; /* Popup view */ GtkWidget *view_popup; @@ -392,6 +393,7 @@ ev_window_setup_action_sensitivity (EvWindow *ev_window) ev_window_set_action_sensitive (ev_window, PAGE_SELECTOR_ACTION, has_pages); ev_window_set_action_sensitive (ev_window, ZOOM_CONTROL_ACTION, has_pages); ev_window_set_action_sensitive (ev_window, NAVIGATION_ACTION, FALSE); + ev_window_set_action_sensitive (ev_window, "PreviewPrint", has_pages && ok_to_print); ev_window_update_actions (ev_window); } @@ -1242,6 +1244,16 @@ ev_window_clear_local_uri (EvWindow *ev_window) } } +static void +ev_window_clear_print_settings_file (EvWindow *ev_window) +{ + if (ev_window->priv->print_settings_file) { + g_unlink (ev_window->priv->print_settings_file); + g_free (ev_window->priv->print_settings_file); + ev_window->priv->print_settings_file = NULL; + } +} + static void ev_window_clear_temp_file (EvWindow *ev_window) { @@ -1428,7 +1440,8 @@ ev_window_open_uri (EvWindow *ev_window, const char *uri, EvLinkDest *dest, EvWindowRunMode mode, - gboolean unlink_temp_file) + gboolean unlink_temp_file, + const gchar *print_settings) { GnomeVFSURI *source_uri; GnomeVFSURI *target_uri; @@ -1436,10 +1449,16 @@ ev_window_open_uri (EvWindow *ev_window, ev_window_close_dialogs (ev_window); ev_window_clear_load_job (ev_window); ev_window_clear_local_uri (ev_window); + ev_window_clear_print_settings_file (ev_window); ev_view_set_loading (EV_VIEW (ev_window->priv->view), TRUE); ev_window->priv->unlink_temp_file = unlink_temp_file; + if (mode == EV_WINDOW_MODE_PREVIEW) { + ev_window->priv->print_settings_file = print_settings ? + g_strdup (print_settings) : NULL; + } + if (ev_window->priv->uri) g_free (ev_window->priv->uri); ev_window->priv->uri = g_strdup (uri); @@ -1636,6 +1655,7 @@ ev_window_cmd_file_open_copy_at_dest (EvWindow *window, EvLinkDest *dest) dest, 0, TRUE, + NULL, GDK_CURRENT_TIME); g_free (symlink_uri); } @@ -1670,7 +1690,7 @@ ev_window_cmd_recent_file_activate (GtkAction *action, ev_application_open_uri_at_dest (EV_APP, uri, gtk_window_get_screen (GTK_WINDOW (window)), - NULL, 0, FALSE, + NULL, 0, FALSE, NULL, GDK_CURRENT_TIME); } #else @@ -1688,7 +1708,7 @@ ev_window_cmd_recent_file_activate (GtkAction *action, ev_application_open_uri_at_dest (EV_APP, uri, gtk_window_get_screen (GTK_WINDOW (ev_window)), - NULL, 0, FALSE, + NULL, 0, FALSE, NULL, GDK_CURRENT_TIME); g_free (uri); @@ -2897,6 +2917,8 @@ ev_window_cmd_view_presentation (GtkAction *action, EvWindow *window) static void ev_window_run_preview (EvWindow *window) { + GtkAction *action; + if (!window->priv->preview_toolbar) { window->priv->preview_toolbar = gtk_ui_manager_get_widget (window->priv->ui_manager, @@ -2916,6 +2938,14 @@ ev_window_run_preview (EvWindow *window) update_chrome_flag (window, EV_CHROME_SIDEBAR, FALSE); update_chrome_flag (window, EV_CHROME_PREVIEW_TOOLBAR, TRUE); + + action = gtk_action_group_get_action (window->priv->action_group, + "PreviewPrint"); +#if GTK_CHECK_VERSION (2, 11, 0) + gtk_action_set_visible (action, TRUE); +#else + gtk_action_set_visible (action, FALSE); +#endif update_chrome_visibility (window); } @@ -3130,7 +3160,7 @@ ev_window_cmd_view_reload (GtkAction *action, EvWindow *ev_window) gchar *uri; uri = g_strdup (ev_window->priv->uri); - ev_window_open_uri (ev_window, uri, NULL, 0, FALSE); + ev_window_open_uri (ev_window, uri, NULL, 0, FALSE, NULL); g_free (uri); } @@ -3192,6 +3222,124 @@ ev_window_cmd_start_presentation (GtkAction *action, EvWindow *window) ev_window_run_presentation (window); } +#ifdef WITH_GTK_PRINT +static gboolean +lookup_printer_from_name (GtkPrinter *printer, + EvWindow *window) +{ + const gchar *printer_name; + + printer_name = gtk_print_settings_get_printer (window->priv->print_settings); + + if ((printer_name + && g_ascii_strcasecmp (printer_name, gtk_printer_get_name (printer)) == 0) || + (!printer_name && gtk_printer_is_default (printer))) { + if (window->priv->printer) + g_object_unref (window->priv->printer); + window->priv->printer = g_object_ref (printer); + + return TRUE; + } + + return FALSE; +} + +static void +ev_window_preview_print_finished (GtkPrintJob *print_job, + EvWindow *window, + GError *error) +{ + if (error) { + GtkWidget *dialog; + + dialog = gtk_message_dialog_new (GTK_WINDOW (window), + GTK_DIALOG_MODAL, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + _("Failed to print document")); + gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), + error->message); + + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + } + + g_object_unref (print_job); + gtk_widget_destroy (GTK_WIDGET (window)); +} +#endif /* WITH_GTK_PRINT */ + +static void +ev_window_cmd_preview_print (GtkAction *action, EvWindow *window) +{ +#ifdef WITH_GTK_PRINT + GtkPrintSettings *print_settings = NULL; + GtkPageSetup *page_setup; + GtkPrintJob *job; + gchar *filename; + GError *error = NULL; +#if GTK_CHECK_VERSION (2, 11, 0) + const gchar *print_settings_file = window->priv->print_settings_file; + + if (print_settings_file) { + if (g_file_test (print_settings_file, G_FILE_TEST_IS_REGULAR)) { + GError *error = NULL; + + print_settings = gtk_print_settings_new_from_file (print_settings_file, + &error); + + if (error) { + g_warning (error->message); + g_error_free (error); + print_settings = NULL; + } + } + } +#endif /* GTK 2.11.0 */ + + if (!print_settings) + print_settings = gtk_print_settings_new (); + + if (window->priv->print_settings) + g_object_unref (window->priv->print_settings); + window->priv->print_settings = print_settings; + + gtk_enumerate_printers ((GtkPrinterFunc) lookup_printer_from_name, + window, NULL, TRUE); + g_assert (GTK_IS_PRINTER (window->priv->printer)); + + page_setup = gtk_page_setup_new (); + + job = gtk_print_job_new ("evince-print", + window->priv->printer, + window->priv->print_settings, + page_setup); + + g_object_unref (window->priv->print_settings); + window->priv->print_settings = NULL; + g_object_unref (window->priv->printer); + window->priv->printer = NULL; + g_object_unref (page_setup); + + filename = g_filename_from_uri (window->priv->local_uri ? + window->priv->local_uri : window->priv->uri, + NULL, NULL); + + if (gtk_print_job_set_source_file (job, filename, &error)) { + gtk_print_job_send (job, + (GtkPrintJobCompleteFunc)ev_window_preview_print_finished, + window, NULL); + } else { + g_warning (error->message); + g_error_free (error); + } + + g_free (filename); + + gtk_widget_hide (GTK_WIDGET (window)); +#endif /* WITH_GTK_PRINT */ +} + static void ev_window_cmd_escape (GtkAction *action, EvWindow *window) { @@ -3966,6 +4114,11 @@ ev_window_dispose (GObject *object) priv->history = NULL; } + if (priv->print_settings_file) { + ev_window_clear_print_settings_file (window); + priv->print_settings_file = NULL; + } + if (priv->presentation_timeout_id > 0) { g_source_remove (priv->presentation_timeout_id); priv->presentation_timeout_id = 0; @@ -4079,6 +4232,9 @@ static const GtkActionEntry entries[] = { { "StartPresentation", EV_STOCK_RUN_PRESENTATION, N_("Start Presentation"), NULL, N_("Start a presentation"), G_CALLBACK (ev_window_cmd_start_presentation) }, + { "PreviewPrint", GTK_STOCK_PRINT, N_("Print"), NULL, + N_("Print this document"), + G_CALLBACK (ev_window_cmd_preview_print) }, /* Accellerators */ { "Escape", NULL, "", "Escape", "", @@ -4489,6 +4645,7 @@ open_remote_link (EvWindow *window, EvLinkAction *action) ev_link_action_get_dest (action), 0, FALSE, + NULL, GDK_CURRENT_TIME); g_free (uri); diff --git a/shell/ev-window.h b/shell/ev-window.h index a60b123d..d269b7de 100644 --- a/shell/ev-window.h +++ b/shell/ev-window.h @@ -77,7 +77,8 @@ void ev_window_open_uri (EvWindow *ev_window, const char *uri, EvLinkDest *dest, EvWindowRunMode mode, - gboolean unlink_temp_file); + gboolean unlink_temp_file, + const gchar *print_settings); gboolean ev_window_is_empty (const EvWindow *ev_window); #ifdef WITH_PRINT void ev_window_print_range (EvWindow *ev_window, diff --git a/shell/main.c b/shell/main.c index 64b86dfa..01d6c318 100644 --- a/shell/main.c +++ b/shell/main.c @@ -51,6 +51,7 @@ static gboolean preview_mode = FALSE; static gboolean fullscren_mode = FALSE; static gboolean presentation_mode = FALSE; static gboolean unlink_temp_file = FALSE; +static gchar *print_settings; static const char **file_arguments = NULL; static const GOptionEntry goption_options[] = @@ -60,6 +61,7 @@ static const GOptionEntry goption_options[] = { "presentation", 's', 0, G_OPTION_ARG_NONE, &presentation_mode, N_("Run evince in presentation mode"), NULL }, { "preview", 'w', 0, G_OPTION_ARG_NONE, &preview_mode, N_("Run evince as a previewer"), NULL }, { "unlink-tempfile", 'u', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &unlink_temp_file, NULL, NULL }, + { "print-settings", 't', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_FILENAME, &print_settings, NULL, NULL }, { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &file_arguments, NULL, N_("[FILE...]") }, { NULL } }; @@ -127,6 +129,9 @@ arguments_parse (void) g_value_set_string (value, ev_page_label); g_hash_table_insert (args, g_strdup ("page-label"), value); + + g_free (ev_page_label); + ev_page_label = NULL; } if (fullscren_mode) @@ -154,6 +159,18 @@ arguments_parse (void) value); } + if (mode == EV_WINDOW_MODE_PREVIEW && print_settings) { + value = g_new0 (GValue, 1); + g_value_init (value, G_TYPE_STRING); + g_value_set_string (value, print_settings); + + g_hash_table_insert (args, + g_strdup ("print-settings"), + value); + g_free (print_settings); + print_settings = NULL; + } + return args; } -- 2.43.5