X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;f=shell%2Fev-window.c;h=47ce4c77a5c4824893b4b1ee0cb64cf0727fb63a;hb=c077e7131bdd63aeaee762b69d77f3881ff496b1;hp=60ea87c15dbd81983121706f40ea5cbc6d826015;hpb=81c134286178c1b09b7505c1a9e8fba0c612fe1f;p=evince.git diff --git a/shell/ev-window.c b/shell/ev-window.c index 60ea87c1..47ce4c77 100644 --- a/shell/ev-window.c +++ b/shell/ev-window.c @@ -37,7 +37,11 @@ #include #include #include +#if GTK_CHECK_VERSION (2, 14, 0) #include +#else +#include +#endif #include #include "egg-editable-toolbar.h" @@ -77,6 +81,7 @@ #include "ev-sidebar-links.h" #include "ev-sidebar-page.h" #include "ev-sidebar-thumbnails.h" +#include "ev-sidebar-layers.h" #include "ev-stock-icons.h" #include "ev-utils.h" #include "ev-view.h" @@ -125,6 +130,7 @@ struct _EvWindowPrivate { GtkWidget *sidebar_thumbs; GtkWidget *sidebar_links; GtkWidget *sidebar_attachments; + GtkWidget *sidebar_layers; /* Dialogs */ GtkWidget *properties; @@ -161,6 +167,7 @@ struct _EvWindowPrivate { /* Document */ char *uri; + glong uri_mtime; char *local_uri; EvLinkDest *dest; gboolean unlink_temp_file; @@ -207,6 +214,7 @@ struct _EvWindowPrivate { #define LINKS_SIDEBAR_ID "links" #define THUMBNAILS_SIDEBAR_ID "thumbnails" #define ATTACHMENTS_SIDEBAR_ID "attachments" +#define LAYERS_SIDEBAR_ID "layers" static const gchar *document_print_settings[] = { GTK_PRINT_SETTINGS_N_COPIES, @@ -654,46 +662,66 @@ ev_window_message_area_response_cb (EvMessageArea *area, } static void -ev_window_error_message (GtkWindow *window, const gchar *msg, GError *error) +ev_window_error_message (EvWindow *window, + GError *error, + const gchar *format, + ...) { GtkWidget *area; + va_list args; + gchar *msg = NULL; - if (EV_WINDOW (window)->priv->message_area) + if (window->priv->message_area) return; + va_start (args, format); + msg = g_strdup_vprintf (format, args); + va_end (args); + area = ev_message_area_new (GTK_MESSAGE_ERROR, msg, GTK_STOCK_CLOSE, GTK_RESPONSE_CANCEL, NULL); + g_free (msg); + if (error) ev_message_area_set_secondary_text (EV_MESSAGE_AREA (area), error->message); g_signal_connect (area, "response", G_CALLBACK (ev_window_message_area_response_cb), window); gtk_widget_show (area); - ev_window_set_message_area (EV_WINDOW (window), area); + ev_window_set_message_area (window, area); } static void -ev_window_warning_message (GtkWindow *window, const gchar *msg) +ev_window_warning_message (EvWindow *window, + const gchar *format, + ...) { GtkWidget *area; + va_list args; + gchar *msg = NULL; - if (EV_WINDOW (window)->priv->message_area) + if (window->priv->message_area) return; + va_start (args, format); + msg = g_strdup_vprintf (format, args); + va_end (args); + area = ev_message_area_new (GTK_MESSAGE_WARNING, msg, GTK_STOCK_CLOSE, GTK_RESPONSE_CANCEL, NULL); + g_free (msg); g_signal_connect (area, "response", G_CALLBACK (ev_window_message_area_response_cb), window); gtk_widget_show (area); - ev_window_set_message_area (EV_WINDOW (window), area); + ev_window_set_message_area (window, area); } static void @@ -882,6 +910,7 @@ setup_sidebar_from_metadata (EvWindow *window, EvDocument *document) GtkWidget *links = window->priv->sidebar_links; GtkWidget *thumbs = window->priv->sidebar_thumbs; GtkWidget *attachments = window->priv->sidebar_attachments; + GtkWidget *layers = window->priv->sidebar_layers; GValue sidebar_size = { 0, }; GValue sidebar_page = { 0, }; GValue sidebar_visibility = { 0, }; @@ -892,19 +921,29 @@ setup_sidebar_from_metadata (EvWindow *window, EvDocument *document) g_value_unset(&sidebar_size); } - if (document && ev_metadata_manager_get (uri, "sidebar_page", &sidebar_page, FALSE)) { + if (document && ev_metadata_manager_get (uri, "sidebar_page", &sidebar_page, TRUE)) { const char *page_id = g_value_get_string (&sidebar_page); - + if (strcmp (page_id, LINKS_SIDEBAR_ID) == 0 && ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (links), document)) { ev_sidebar_set_page (EV_SIDEBAR (sidebar), links); - } else if (strcmp (page_id, THUMBNAILS_SIDEBAR_ID) && ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (thumbs), document)) { + } else if (strcmp (page_id, THUMBNAILS_SIDEBAR_ID) == 0 && ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (thumbs), document)) { ev_sidebar_set_page (EV_SIDEBAR (sidebar), thumbs); - } else if (strcmp (page_id, ATTACHMENTS_SIDEBAR_ID) && ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (attachments), document)) { + } else if (strcmp (page_id, ATTACHMENTS_SIDEBAR_ID) == 0 && ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (attachments), document)) { ev_sidebar_set_page (EV_SIDEBAR (sidebar), attachments); + } else if (strcmp (page_id, LAYERS_SIDEBAR_ID) == 0 && ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (layers), document)) { + ev_sidebar_set_page (EV_SIDEBAR (sidebar), layers); } g_value_unset (&sidebar_page); - } else if (document && ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (links), document)) { - ev_sidebar_set_page (EV_SIDEBAR (sidebar), links); + } else if (document) { + if (ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (links), document)) { + ev_sidebar_set_page (EV_SIDEBAR (sidebar), links); + } else if (ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (thumbs), document)) { + ev_sidebar_set_page (EV_SIDEBAR (sidebar), thumbs); + } else if (ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (attachments), document)) { + ev_sidebar_set_page (EV_SIDEBAR (sidebar), attachments); + } else if (ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (layers), document)) { + ev_sidebar_set_page (EV_SIDEBAR (sidebar), layers); + } } if (ev_metadata_manager_get (uri, "sidebar_visibility", &sidebar_visibility, FALSE)) { @@ -1200,7 +1239,7 @@ ev_window_set_document (EvWindow *ev_window, EvDocument *document) if (ev_page_cache_get_n_pages (ev_window->priv->page_cache) > 0) { ev_view_set_document (view, document); } else { - ev_window_warning_message (GTK_WINDOW (ev_window), + ev_window_warning_message (ev_window, "%s", _("The document contains no pages")); } @@ -1398,7 +1437,7 @@ ev_window_load_job_cb (EvJob *job, } /* Create a monitor for the document */ - ev_window->priv->monitor = ev_file_monitor_new (job_load->uri); + ev_window->priv->monitor = ev_file_monitor_new (ev_window->priv->uri); g_signal_connect_swapped (G_OBJECT (ev_window->priv->monitor), "changed", G_CALLBACK (ev_window_document_changed), ev_window); @@ -1424,9 +1463,8 @@ ev_window_load_job_cb (EvJob *job, ev_window_popup_password_dialog (ev_window); } else { - ev_window_error_message (GTK_WINDOW (ev_window), - _("Unable to open document"), - job->error); + ev_window_error_message (ev_window, job->error, + "%s", _("Unable to open document")); ev_window_clear_load_job (ev_window); } } @@ -1499,11 +1537,35 @@ ev_window_load_remote_failed (EvWindow *ev_window, { ev_view_set_loading (EV_VIEW (ev_window->priv->view), FALSE); ev_window->priv->in_reload = FALSE; - ev_window_error_message (GTK_WINDOW (ev_window), - _("Unable to open document"), - error); + ev_window_error_message (ev_window, error, + "%s", _("Unable to open document")); g_free (ev_window->priv->local_uri); ev_window->priv->local_uri = NULL; + ev_window->priv->uri_mtime = 0; +} + +static void +set_uri_mtime (GFile *source, + GAsyncResult *async_result, + EvWindow *ev_window) +{ + GFileInfo *info; + GError *error = NULL; + + info = g_file_query_info_finish (source, async_result, &error); + + if (error) { + ev_window->priv->uri_mtime = 0; + g_error_free (error); + } else { + GTimeVal mtime; + + g_file_info_get_modification_time (info, &mtime); + ev_window->priv->uri_mtime = mtime.tv_sec; + g_object_unref (info); + } + + g_object_unref (source); } static void @@ -1536,8 +1598,12 @@ window_open_file_copy_ready_cb (GFile *source, g_file_copy_finish (source, async_result, &error); if (!error) { ev_job_scheduler_push_job (ev_window->priv->load_job, EV_JOB_PRIORITY_NONE); - g_object_unref (source); - + g_file_query_info_async (source, + G_FILE_ATTRIBUTE_TIME_MODIFIED, + 0, G_PRIORITY_DEFAULT, + NULL, + (GAsyncReadyCallback)set_uri_mtime, + ev_window); return; } @@ -1650,12 +1716,9 @@ ev_window_open_uri (EvWindow *ev_window, } static void -ev_window_reload_document (EvWindow *ev_window) +ev_window_reload_local (EvWindow *ev_window) { const gchar *uri; - - ev_window_clear_reload_job (ev_window); - ev_window->priv->in_reload = TRUE; uri = ev_window->priv->local_uri ? ev_window->priv->local_uri : ev_window->priv->uri; ev_window->priv->reload_job = ev_job_load_new (uri, NULL, 0, NULL); @@ -1665,6 +1728,84 @@ ev_window_reload_document (EvWindow *ev_window) ev_job_scheduler_push_job (ev_window->priv->reload_job, EV_JOB_PRIORITY_NONE); } +static void +reload_remote_copy_ready_cb (GFile *remote, + GAsyncResult *async_result, + EvWindow *ev_window) +{ + g_file_copy_finish (remote, async_result, NULL); + ev_window_reload_local (ev_window); + g_object_unref (remote); +} + +static void +query_remote_uri_mtime_cb (GFile *remote, + GAsyncResult *async_result, + EvWindow *ev_window) +{ + GFileInfo *info; + GTimeVal mtime; + GError *error = NULL; + + info = g_file_query_info_finish (remote, async_result, &error); + if (error) { + g_error_free (error); + g_object_unref (remote); + ev_window_reload_local (ev_window); + + return; + } + + g_file_info_get_modification_time (info, &mtime); + if (ev_window->priv->uri_mtime != mtime.tv_sec) { + GFile *target_file; + + /* Remote file has changed */ + ev_window->priv->uri_mtime = mtime.tv_sec; + target_file = g_file_new_for_uri (ev_window->priv->local_uri); + g_file_copy_async (remote, target_file, + G_FILE_COPY_OVERWRITE, + G_PRIORITY_DEFAULT, NULL, + NULL, NULL, /* no progress callback */ + (GAsyncReadyCallback) reload_remote_copy_ready_cb, + ev_window); + g_object_unref (target_file); + } else { + g_object_unref (remote); + ev_window_reload_local (ev_window); + } + + g_object_unref (info); +} + +static void +ev_window_reload_remote (EvWindow *ev_window) +{ + GFile *remote; + + remote = g_file_new_for_uri (ev_window->priv->uri); + /* Reload the remote uri only if it has changed */ + g_file_query_info_async (remote, + G_FILE_ATTRIBUTE_TIME_MODIFIED, + 0, G_PRIORITY_DEFAULT, + NULL, + (GAsyncReadyCallback)query_remote_uri_mtime_cb, + ev_window); +} + +static void +ev_window_reload_document (EvWindow *ev_window) +{ + ev_window_clear_reload_job (ev_window); + ev_window->priv->in_reload = TRUE; + + if (ev_window->priv->local_uri) { + ev_window_reload_remote (ev_window); + } else { + ev_window_reload_local (ev_window); + } +} + static void file_open_dialog_response_cb (GtkWidget *chooser, gint response_id, @@ -1786,10 +1927,8 @@ 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_message (GTK_WINDOW (window), - _("Cannot open a copy."), - error); - + ev_window_error_message (window, error, + "%s", _("Cannot open a copy.")); g_error_free (error); g_free (old_filename); g_free (new_filename); @@ -2016,7 +2155,6 @@ window_save_file_copy_ready_cb (GFile *src, GFile *dst) { EvWindow *window; - GtkWidget *dialog; gchar *name; GError *error = NULL; @@ -2025,22 +2163,12 @@ window_save_file_copy_ready_cb (GFile *src, return; } - window = g_object_get_data (G_OBJECT (dst), "ev-window"); + window = EV_WINDOW (g_object_get_data (G_OBJECT (dst), "ev-window")); name = g_file_get_basename (dst); - dialog = gtk_message_dialog_new (GTK_WINDOW (window), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_CLOSE, - _("The file could not be saved as “%s”."), - name); - gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), - "%s", error->message); - g_signal_connect (dialog, "response", - G_CALLBACK (gtk_widget_destroy), - NULL); - gtk_widget_show (dialog); + ev_window_error_message (window, error, + _("The file could not be saved as “%s”."), + name); ev_tmp_file_unlink (src); - g_free (name); g_error_free (error); } @@ -2079,12 +2207,9 @@ ev_window_save_job_cb (EvJob *job, EvWindow *window) { if (ev_job_is_failed (job)) { - gchar *msg; - - msg = g_strdup_printf (_("The file could not be saved as “%s”."), - EV_JOB_SAVE (job)->uri); - ev_window_error_message (GTK_WINDOW (window), msg, job->error); - g_free (msg); + ev_window_error_message (window, job->error, + _("The file could not be saved as “%s”."), + EV_JOB_SAVE (job)->uri); } ev_window_clear_save_job (window); @@ -2241,18 +2366,8 @@ ev_window_print_finished (GtkPrintJob *print_job, ev_window_clear_print_job (window); 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), - "%s", error->message); - - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); + ev_window_error_message (window, error, + "%s", _("Failed to print document")); } else { /* If printed successfully, save print settings */ ev_application_set_print_settings (EV_APP, @@ -2405,17 +2520,8 @@ ev_window_print_dialog_response_cb (GtkDialog *dialog, GTK_PRINT_SETTINGS_OUTPUT_FILE_FORMAT); if (!gtk_printer_accepts_ps (window->priv->printer)) { - GtkWidget *msgdialog; - - msgdialog = gtk_message_dialog_new (GTK_WINDOW (dialog), - GTK_DIALOG_MODAL, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_OK, - _("Printing is not supported on this printer.")); - - gtk_dialog_run (GTK_DIALOG (msgdialog)); - gtk_widget_destroy (msgdialog); - + ev_window_error_message (window, NULL, "%s", + _("Printing is not supported on this printer.")); return FALSE; } @@ -3318,6 +3424,23 @@ ev_window_cmd_view_autoscroll (GtkAction *action, EvWindow *ev_window) ev_view_autoscroll_start (EV_VIEW (ev_window->priv->view)); } +#if GTK_CHECK_VERSION (2, 14, 0) +static void +ev_window_cmd_help_contents (GtkAction *action, EvWindow *ev_window) +{ + GError *error = NULL; + + gtk_show_uri (gtk_window_get_screen (GTK_WINDOW (ev_window)), + "ghelp:evince", + GDK_CURRENT_TIME, + &error); + if (error) { + ev_window_error_message (ev_window, error, + "%s", _("There was an error displaying help")); + g_error_free (error); + } +} +#else /* !GTK_CHECK_VERSION (2, 14, 0) */ static void ev_window_cmd_help_contents (GtkAction *action, EvWindow *ev_window) { @@ -3366,6 +3489,7 @@ ev_window_cmd_help_contents (GtkAction *action, EvWindow *ev_window) } g_free (command); } +#endif /* GTK_CHECK_VERSION (2, 14, 0) */ static void ev_window_cmd_leave_fullscreen (GtkAction *action, EvWindow *window) @@ -3409,18 +3533,8 @@ ev_window_preview_print_finished (GtkPrintJob *print_job, 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), - "%s", error->message); - - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); + ev_window_error_message (window, error, + "%s", _("Failed to print document")); } g_object_unref (print_job); @@ -3824,6 +3938,8 @@ ev_window_sidebar_current_page_changed_cb (EvSidebar *ev_sidebar, id = THUMBNAILS_SIDEBAR_ID; } else if (current_page == ev_window->priv->sidebar_attachments) { id = ATTACHMENTS_SIDEBAR_ID; + } else if (current_page == ev_window->priv->sidebar_layers) { + id = LAYERS_SIDEBAR_ID; } else { g_assert_not_reached(); } @@ -4597,6 +4713,13 @@ navigation_action_activate_link_cb (EvNavigationAction *action, EvLink *link, Ev gtk_widget_grab_focus (window->priv->view); } +static void +sidebar_layers_visibility_changed (EvSidebarLayers *layers, + EvWindow *window) +{ + ev_view_reload (EV_VIEW (window->priv->view)); +} + static void register_custom_actions (EvWindow *window, GtkActionGroup *group) { @@ -4849,9 +4972,11 @@ launch_action (EvWindow *window, EvLinkAction *action) app_info = g_file_query_default_handler (file, NULL, &error); if (!app_info) { - /* FIXME: use ev_window_error_message */ - g_warning ("%s", error->message); + ev_window_error_message (window, error, + "%s", + _("Unable to launch external application.")); g_object_unref (file); + g_error_free (error); return; } @@ -4865,8 +4990,9 @@ launch_action (EvWindow *window, EvLinkAction *action) file_list.data = file; if (!g_app_info_launch (app_info, &file_list, context, &error)) { - /* FIXME: use ev_window_error_message */ - g_warning ("%s", error->message); + ev_window_error_message (window, error, + "%s", + _("Unable to launch external application.")); g_error_free (error); } @@ -4881,9 +5007,11 @@ static void launch_external_uri (EvWindow *window, EvLinkAction *action) { const gchar *uri = ev_link_action_get_uri (action); - GAppLaunchContext *context = NULL; GError *error = NULL; gboolean ret; +#if GTK_CHECK_VERSION (2, 14, 0) + GAppLaunchContext *context = NULL; +#endif #if GTK_CHECK_VERSION (2, 14, 0) context = G_APP_LAUNCH_CONTEXT (gdk_app_launch_context_new ()); @@ -4906,9 +5034,8 @@ launch_external_uri (EvWindow *window, EvLinkAction *action) } if (ret == FALSE) { - ev_window_error_message (GTK_WINDOW (window), - _("Unable to open external link"), - error); + ev_window_error_message (window, error, + "%s", _("Unable to open external link")); g_error_free (error); } } @@ -5062,9 +5189,9 @@ image_save_dialog_response_cb (GtkWidget *fc, } if (format == NULL) { - ev_window_error_message (GTK_WINDOW (ev_window), - _("Couldn't find appropriate format to save image"), - NULL); + ev_window_error_message (ev_window, NULL, + "%s", + _("Couldn't find appropriate format to save image")); g_free (uri); gtk_widget_destroy (fc); @@ -5102,9 +5229,8 @@ image_save_dialog_response_cb (GtkWidget *fc, g_object_unref (pixbuf); if (error) { - ev_window_error_message (GTK_WINDOW (ev_window), - _("The image could not be saved."), - error); + ev_window_error_message (ev_window, error, + "%s", _("The image could not be saved.")); g_error_free (error); g_free (filename); g_object_unref (target_file); @@ -5196,9 +5322,8 @@ ev_attachment_popup_cmd_open_attachment (GtkAction *action, EvWindow *window) ev_attachment_open (attachment, screen, GDK_CURRENT_TIME, &error); if (error) { - ev_window_error_message (GTK_WINDOW (window), - _("Unable to open attachment"), - error); + ev_window_error_message (window, error, + "%s", _("Unable to open attachment")); g_error_free (error); } } @@ -5248,9 +5373,8 @@ attachment_save_dialog_response_cb (GtkWidget *fc, ev_attachment_save (attachment, save_to, &error); if (error) { - ev_window_error_message (GTK_WINDOW (ev_window), - _("The attachment could not be saved."), - error); + ev_window_error_message (ev_window, error, + "%s", _("The attachment could not be saved.")); g_error_free (error); g_object_unref (save_to); @@ -5499,6 +5623,16 @@ ev_window_init (EvWindow *ev_window) ev_sidebar_add_page (EV_SIDEBAR (ev_window->priv->sidebar), sidebar_widget); + sidebar_widget = ev_sidebar_layers_new (); + ev_window->priv->sidebar_layers = sidebar_widget; + g_signal_connect (sidebar_widget, + "layers_visibility_changed", + G_CALLBACK (sidebar_layers_visibility_changed), + ev_window); + gtk_widget_show (sidebar_widget); + 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,