X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;f=shell%2Fev-window.c;h=79dff08b97c30cec70e01d00e2811a816802b548;hb=3e9c324a5f8be62b6e360cfc358bbd3d24986e22;hp=c53b772b448f761de91ecf50a151ae5285a750b3;hpb=e03ccc6269d7e687b4f5a67a0c07a014f301930b;p=evince.git diff --git a/shell/ev-window.c b/shell/ev-window.c index c53b772b..79dff08b 100644 --- a/shell/ev-window.c +++ b/shell/ev-window.c @@ -46,6 +46,7 @@ #include "ev-document-links.h" #include "ev-document-fonts.h" #include "ev-document-find.h" +#include "ev-document-images.h" #include "ev-document-security.h" #include "ev-document-factory.h" #include "ev-job-queue.h" @@ -64,6 +65,7 @@ #include "ev-utils.h" #include "ev-history.h" #include "ev-image.h" +#include "ev-message-area.h" #ifdef WITH_GNOME_PRINT #include "ev-print-job.h" @@ -119,10 +121,12 @@ struct _EvWindowPrivate { GtkWidget *menubar; GtkWidget *toolbar; GtkWidget *hpaned; + GtkWidget *view_box; GtkWidget *sidebar; GtkWidget *find_bar; GtkWidget *scrolled_window; GtkWidget *view; + GtkWidget *message_area; GtkWidget *password_view; GtkWidget *sidebar_thumbs; GtkWidget *sidebar_links; @@ -211,6 +215,19 @@ struct _EvWindowPrivate { #define THUMBNAILS_SIDEBAR_ID "thumbnails" #define ATTACHMENTS_SIDEBAR_ID "attachments" +#ifdef WITH_GTK_PRINT +static const gchar *document_print_settings[] = { + GTK_PRINT_SETTINGS_N_COPIES, + GTK_PRINT_SETTINGS_COLLATE, + GTK_PRINT_SETTINGS_REVERSE, + GTK_PRINT_SETTINGS_NUMBER_UP, + GTK_PRINT_SETTINGS_SCALE, + GTK_PRINT_SETTINGS_PRINT_PAGES, + GTK_PRINT_SETTINGS_PAGE_RANGES, + GTK_PRINT_SETTINGS_PAGE_SET +}; +#endif /* WITH_GTK_PRINT */ + static void ev_window_update_actions (EvWindow *ev_window); static void ev_window_sidebar_visibility_changed_cb (EvSidebar *ev_sidebar, GParamSpec *pspec, @@ -376,6 +393,7 @@ ev_window_setup_action_sensitivity (EvWindow *ev_window) ev_window_set_action_sensitive (ev_window, "ViewBestFit", has_pages); ev_window_set_action_sensitive (ev_window, "ViewPageWidth", has_pages); ev_window_set_action_sensitive (ev_window, "ViewReload", has_pages); + ev_window_set_action_sensitive (ev_window, "ViewAutoscroll", has_pages); /* Toolbar-specific actions: */ ev_window_set_action_sensitive (ev_window, PAGE_SELECTOR_ACTION, has_pages); @@ -611,29 +629,56 @@ ev_window_is_empty (const EvWindow *ev_window) } static void -ev_window_error_dialog_response_cb (GtkWidget *dialog, - gint response_id, - EvWindow *ev_window) +ev_window_set_message_area (EvWindow *window, + GtkWidget *area) { - gtk_widget_destroy (dialog); + if (window->priv->message_area == area) + return; + + if (window->priv->message_area) + gtk_widget_destroy (window->priv->message_area); + window->priv->message_area = area; + + if (!area) + return; + + gtk_box_pack_start (GTK_BOX (window->priv->view_box), + window->priv->message_area, + FALSE, FALSE, 0); + gtk_box_reorder_child (GTK_BOX (window->priv->view_box), + window->priv->message_area, 0); + g_object_add_weak_pointer (G_OBJECT (window->priv->message_area), + (gpointer) &(window->priv->message_area)); } static void -ev_window_error_dialog (GtkWindow *window, const gchar *msg, GError *error) +ev_window_error_message_response_cb (EvMessageArea *area, + gint response_id, + EvWindow *window) { - GtkWidget *dialog; + ev_window_set_message_area (window, NULL); +} - dialog = gtk_message_dialog_new (GTK_WINDOW (window), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_CLOSE, - msg); - gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), - "%s", error->message); - g_signal_connect (dialog, "response", - G_CALLBACK (ev_window_error_dialog_response_cb), - window); - gtk_widget_show (dialog); +static void +ev_window_error_message (GtkWindow *window, const gchar *msg, GError *error) +{ + GtkWidget *area; + + if (EV_WINDOW (window)->priv->message_area) + return; + + area = ev_message_area_new (GTK_MESSAGE_ERROR, + msg, + GTK_STOCK_CLOSE, + GTK_RESPONSE_CANCEL, + NULL); + if (error) + ev_message_area_set_secondary_text (EV_MESSAGE_AREA (area), error->message); + g_signal_connect (area, "response", + G_CALLBACK (ev_window_error_message_response_cb), + window); + gtk_widget_show (area); + ev_window_set_message_area (EV_WINDOW (window), area); } static void @@ -1136,6 +1181,8 @@ ev_window_set_document (EvWindow *ev_window, EvDocument *document) if (ev_window->priv->document) g_object_unref (ev_window->priv->document); ev_window->priv->document = g_object_ref (document); + + ev_window_set_message_area (ev_window, NULL); ev_window->priv->page_cache = ev_page_cache_get (ev_window->priv->document); g_signal_connect (ev_window->priv->page_cache, "page-changed", @@ -1371,9 +1418,9 @@ ev_window_load_job_cb (EvJobLoad *job, ev_window_popup_password_dialog (ev_window); } else { - ev_window_error_dialog (GTK_WINDOW (ev_window), - _("Unable to open document"), - job->error); + ev_window_error_message (GTK_WINDOW (ev_window), + _("Unable to open document"), + job->error); ev_window_clear_load_job (ev_window); ev_window->priv->in_reload = FALSE; } @@ -1666,9 +1713,9 @@ ev_window_cmd_file_open_copy_at_dest (EvWindow *window, EvLinkDest *dest) new_filename = ev_window_create_tmp_symlink (old_filename, &error); if (error) { - ev_window_error_dialog (GTK_WINDOW (window), - _("Cannot open a copy."), - error); + ev_window_error_message (GTK_WINDOW (window), + _("Cannot open a copy."), + error); g_error_free (error); g_free (old_filename); @@ -1779,12 +1826,15 @@ ev_window_get_recent_file_label (gint index, const gchar *filename) gint length; const gchar *p; const gchar *end; - + gboolean is_rtl; + + is_rtl = (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL); + g_return_val_if_fail (filename != NULL, NULL); length = strlen (filename); str = g_string_sized_new (length + 10); - g_string_printf (str, "_%d. ", index); + g_string_printf (str, "%s_%d. ", is_rtl ? "\xE2\x80\x8F" : "", index); p = filename; end = filename + length; @@ -1985,7 +2035,7 @@ ev_window_save_job_cb (EvJobSave *job, gchar *msg; msg = g_strdup_printf (_("The file could not be saved as “%s”."), job->uri); - ev_window_error_dialog (GTK_WINDOW (window), msg, job->error); + ev_window_error_message (GTK_WINDOW (window), msg, job->error); g_free (msg); } @@ -2117,6 +2167,40 @@ ev_window_clear_print_job (EvWindow *window) } } +static void +ev_window_load_print_settings_from_metadata (EvWindow *window) +{ + gchar *uri = window->priv->uri; + gint i; + + /* Load print setting that are specific to the document */ + for (i = 0; i < G_N_ELEMENTS (document_print_settings); i++) { + GValue value = { 0, }; + gboolean success; + + success = ev_metadata_manager_get (uri, document_print_settings[i], &value, TRUE); + gtk_print_settings_set (window->priv->print_settings, + document_print_settings[i], + success ? g_value_get_string (&value) : NULL); + } +} + +static void +ev_window_save_print_settings (EvWindow *window) +{ + gchar *uri = window->priv->uri; + gint i; + + /* Save print settings that are specific to the document */ + for (i = 0; i < G_N_ELEMENTS (document_print_settings); i++) { + const gchar *value; + + value = gtk_print_settings_get (window->priv->print_settings, + document_print_settings[i]); + ev_metadata_manager_set_string (uri, document_print_settings[i], value); + } +} + static void ev_window_print_finished (GtkPrintJob *print_job, EvWindow *window, @@ -2141,6 +2225,7 @@ ev_window_print_finished (GtkPrintJob *print_job, /* If printed successfully, save print settings */ ev_application_set_print_settings (EV_APP, window->priv->print_settings); + ev_window_save_print_settings (window); } } @@ -2402,8 +2487,9 @@ ev_window_print_range (EvWindow *ev_window, int first_page, int last_page) document_last_page = ev_page_cache_get_n_pages (page_cache); if (!ev_window->priv->print_settings) { - ev_window->priv->print_settings = g_object_ref ( + ev_window->priv->print_settings = gtk_print_settings_copy ( ev_application_get_print_settings (EV_APP)); + ev_window_load_print_settings_from_metadata (ev_window); } if (first_page != 1 || last_page != document_last_page) { @@ -2781,6 +2867,27 @@ fullscreen_toolbar_setup_item_properties (GtkUIManager *ui_manager) g_object_set (item, "is-important", TRUE, NULL); } +static void +fullscreen_toolbar_remove_shadow (GtkWidget *toolbar) +{ + static gboolean done = FALSE; + + if (!done) { + gtk_rc_parse_string ( + "\n" + " style \"fullscreen-toolbar-style\"\n" + " {\n" + " GtkToolbar::shadow-type=GTK_SHADOW_NONE\n" + " }\n" + "\n" + " widget \"*.fullscreen-toolbar\" style \"fullscreen-toolbar-style\"\n" + "\n"); + done = TRUE; + } + + gtk_widget_set_name (toolbar, "fullscreen-toolbar"); +} + static void ev_window_run_fullscreen (EvWindow *window) { @@ -2791,6 +2898,7 @@ ev_window_run_fullscreen (EvWindow *window) gtk_toolbar_set_style (GTK_TOOLBAR (window->priv->fullscreen_toolbar), GTK_TOOLBAR_BOTH_HORIZ); + fullscreen_toolbar_remove_shadow (window->priv->fullscreen_toolbar); fullscreen_toolbar_setup_item_properties (window->priv->ui_manager); gtk_box_pack_start (GTK_BOX (window->priv->main_box), @@ -3255,6 +3363,12 @@ ev_window_cmd_view_reload (GtkAction *action, EvWindow *ev_window) g_free (uri); } +static void +ev_window_cmd_view_autoscroll (GtkAction *action, EvWindow *ev_window) +{ + ev_view_autoscroll (EV_VIEW (ev_window->priv->view)); +} + static void ev_window_cmd_help_contents (GtkAction *action, EvWindow *ev_window) { @@ -4296,6 +4410,9 @@ static const GtkActionEntry entries[] = { N_("Reload the document"), G_CALLBACK (ev_window_cmd_view_reload) }, + { "ViewAutoscroll", GTK_STOCK_MEDIA_PLAY, N_("Auto_scroll"), NULL, NULL, + G_CALLBACK (ev_window_cmd_view_autoscroll) }, + /* Go menu */ { "GoPreviousPage", GTK_STOCK_GO_BACK, N_("_Previous Page"), "Page_Up", N_("Go to the previous page"), @@ -4482,6 +4599,7 @@ register_custom_actions (EvWindow *window, GtkActionGroup *group) "is_important", TRUE, "short_label", _("Back"), "stock_id", GTK_STOCK_GO_DOWN, + /*translators: this is the history action*/ "tooltip", _("Move across visited pages"), NULL); g_signal_connect (action, "activate_link", @@ -4856,16 +4974,23 @@ ev_view_popup_cmd_copy_link_address (GtkAction *action, EvWindow *window) gtk_clipboard_set_text (clipboard, uri, -1); } + static void image_save_dialog_response_cb (GtkWidget *fc, gint response_id, EvWindow *ev_window) { - GnomeVFSURI *target_uri; - gchar *uri; - gchar *filename; - gboolean is_local; - GError *error = NULL; + GnomeVFSURI *target_uri; + gboolean is_local; + GError *error = NULL; + GdkPixbuf *pixbuf; + gchar *uri; + gchar *uri_extension; + gchar **extensions; + gchar *filename; + gchar *file_format; + GdkPixbufFormat *format; + GtkFileFilter *filter; if (response_id != GTK_RESPONSE_OK) { gtk_widget_destroy (fc); @@ -4873,25 +4998,52 @@ image_save_dialog_response_cb (GtkWidget *fc, } uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (fc)); - target_uri = gnome_vfs_uri_new (uri); + filter = gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (fc)); + format = g_object_get_data (G_OBJECT (filter), "pixbuf-format"); + + if (format == NULL) { + format = get_gdk_pixbuf_format_by_extension (uri); + } + + if (format == NULL) { + ev_window_error_message (GTK_WINDOW (ev_window), + _("Couldn't find appropriate format to save image"), + NULL); + g_free (uri); + gtk_widget_destroy (fc); + + return; + } + + extensions = gdk_pixbuf_format_get_extensions (format); + uri_extension = g_strconcat (uri, ".", extensions[0], NULL); + g_strfreev(extensions); + file_format = gdk_pixbuf_format_get_name (format); + + target_uri = gnome_vfs_uri_new (uri_extension); is_local = gnome_vfs_uri_is_local (target_uri); if (is_local) { - filename = g_filename_from_uri (uri, NULL, NULL); + filename = g_filename_from_uri (uri_extension, NULL, NULL); } else { filename = ev_tmp_filename ("saveimage"); } g_free (uri); + g_free (uri_extension); + + ev_document_doc_mutex_lock (); + pixbuf = ev_document_images_get_image (EV_DOCUMENT_IMAGES (ev_window->priv->document), + ev_window->priv->image); + ev_document_doc_mutex_unlock (); - /* FIXME: allow saving in other image formats than png */ - gdk_pixbuf_save (ev_image_get_pixbuf (ev_window->priv->image), - filename, "png", &error, NULL); + gdk_pixbuf_save (pixbuf, filename, file_format, &error, NULL); + g_object_unref (pixbuf); if (error) { - ev_window_error_dialog (GTK_WINDOW (ev_window), - _("The image could not be saved."), - error); + ev_window_error_message (GTK_WINDOW (ev_window), + _("The image could not be saved."), + error); g_error_free (error); g_free (filename); gnome_vfs_uri_unref (target_uri); @@ -4919,8 +5071,7 @@ image_save_dialog_response_cb (GtkWidget *fc, static void ev_view_popup_cmd_save_image_as (GtkAction *action, EvWindow *window) { - GtkWidget *fc; - GtkFileFilter *filter; + GtkWidget *fc; if (!window->priv->image) return; @@ -4936,12 +5087,9 @@ ev_view_popup_cmd_save_image_as (GtkAction *action, EvWindow *window) gtk_dialog_set_default_response (GTK_DIALOG (fc), GTK_RESPONSE_OK); gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (fc), FALSE); gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (fc), TRUE); - - filter = gtk_file_filter_new (); - gtk_file_filter_set_name (filter, _("Images")); - gtk_file_filter_add_pixbuf_formats (filter); - gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (fc), filter); - + + file_chooser_dialog_add_writable_pixbuf_formats (GTK_FILE_CHOOSER (fc)); + g_signal_connect (fc, "response", G_CALLBACK (image_save_dialog_response_cb), window); @@ -4953,14 +5101,20 @@ static void ev_view_popup_cmd_copy_image (GtkAction *action, EvWindow *window) { GtkClipboard *clipboard; + GdkPixbuf *pixbuf; if (!window->priv->image) return; clipboard = gtk_widget_get_clipboard (GTK_WIDGET (window), GDK_SELECTION_CLIPBOARD); - gtk_clipboard_set_image (clipboard, - ev_image_get_pixbuf (window->priv->image)); + ev_document_doc_mutex_lock (); + pixbuf = ev_document_images_get_image (EV_DOCUMENT_IMAGES (window->priv->document), + window->priv->image); + ev_document_doc_mutex_unlock (); + + gtk_clipboard_set_image (clipboard, pixbuf); + g_object_unref (pixbuf); } static void @@ -4980,9 +5134,9 @@ ev_attachment_popup_cmd_open_attachment (GtkAction *action, EvWindow *window) ev_attachment_open (attachment, &error); if (error) { - ev_window_error_dialog (GTK_WINDOW (window), - _("Unable to open attachment"), - error); + ev_window_error_message (GTK_WINDOW (window), + _("Unable to open attachment"), + error); g_error_free (error); } } @@ -5033,9 +5187,9 @@ attachment_save_dialog_response_cb (GtkWidget *fc, ev_attachment_save (attachment, filename, &error); if (error) { - ev_window_error_dialog (GTK_WINDOW (ev_window), - _("The attachment could not be saved."), - error); + ev_window_error_message (GTK_WINDOW (ev_window), + _("The attachment could not be saved."), + error); g_error_free (error); g_free (filename); @@ -5267,14 +5421,19 @@ ev_window_init (EvWindow *ev_window) ev_sidebar_add_page (EV_SIDEBAR (ev_window->priv->sidebar), sidebar_widget); + ev_window->priv->view_box = gtk_vbox_new (FALSE, 0); ev_window->priv->scrolled_window = GTK_WIDGET (g_object_new (GTK_TYPE_SCROLLED_WINDOW, "shadow-type", GTK_SHADOW_IN, NULL)); + gtk_box_pack_start (GTK_BOX (ev_window->priv->view_box), + ev_window->priv->scrolled_window, + TRUE, TRUE, 0); gtk_widget_show (ev_window->priv->scrolled_window); gtk_paned_add2 (GTK_PANED (ev_window->priv->hpaned), - ev_window->priv->scrolled_window); + ev_window->priv->view_box); + gtk_widget_show (ev_window->priv->view_box); ev_window->priv->view = ev_view_new (); ev_view_set_screen_dpi (EV_VIEW (ev_window->priv->view),