]> www.fi.muni.cz Git - evince.git/blobdiff - shell/ev-window.c
Implement Close named action. Patch by Carlos Garcia Campos.
[evince.git] / shell / ev-window.c
index 6b80ed5cac131389b2574d7a77e352944e149af6..cbd504ca5eacb50c48741a266d7af7f47247695d 100644 (file)
 #include "ev-jobs.h"
 #include "ev-sidebar-page.h"
 #include "eggfindbar.h"
+
+#ifndef HAVE_GTK_RECENT
 #include "egg-recent-view-uimanager.h"
 #include "egg-recent-view.h"
+#include "egg-recent-model.h"
+#endif
+
 #include "egg-toolbar-editor.h"
 #include "egg-editable-toolbar.h"
-#include "egg-recent-model.h"
 #include "egg-toolbars-model.h"
 #include "ephy-zoom.h"
 #include "ephy-zoom-action.h"
@@ -125,10 +129,15 @@ struct _EvWindowPrivate {
        GtkWidget *password_dialog;
 
        /* UI Builders */
-       GtkActionGroup *action_group;
-       GtkActionGroup *view_popup_action_group;
-       GtkActionGroup *attachment_popup_action_group;
-       GtkUIManager   *ui_manager;
+       GtkActionGroup   *action_group;
+       GtkActionGroup   *view_popup_action_group;
+       GtkActionGroup   *attachment_popup_action_group;
+#ifdef HAVE_GTK_RECENT
+       GtkRecentManager *recent_manager;
+       GtkActionGroup   *recent_action_group;
+       guint             recent_ui_id;
+#endif
+       GtkUIManager     *ui_manager;
 
        /* Fullscreen mode */
        GtkWidget *fullscreen_toolbar;
@@ -153,7 +162,9 @@ struct _EvWindowPrivate {
        EvPageCache *page_cache;
        EvWindowPageMode page_mode;
        EvWindowTitle *title;
+#ifndef HAVE_GTK_RECENT
        EggRecentViewUIManager *recent_view;
+#endif
 
        EvJob *xfer_job;
 #ifdef WITH_GNOME_PRINT
@@ -200,8 +211,10 @@ static void     ev_window_set_page_mode                 (EvWindow         *windo
                                                         EvWindowPageMode  page_mode);
 static void    ev_window_xfer_job_cb                   (EvJobXfer        *job,
                                                         gpointer          data);
+#ifdef WITH_GTK_PRINT
 static void     ev_window_print_job_cb                  (EvJobPrint       *job,
                                                         EvWindow         *window);
+#endif
 static void     ev_window_sizing_mode_changed_cb        (EvView           *view,
                                                         GParamSpec       *pspec,
                                                         EvWindow         *ev_window);
@@ -605,6 +618,7 @@ setup_document_from_metadata (EvWindow *window)
                new_page = CLAMP (g_value_get_int (&page), 0, ev_page_cache_get_n_pages (window->priv->page_cache) - 1);
                ev_page_cache_set_current_page (window->priv->page_cache,
                                                new_page);
+               g_value_unset (&page);
        }
 }
 
@@ -617,6 +631,7 @@ setup_chrome_from_metadata (EvWindow *window)
        if (ev_metadata_manager_get (NULL, "show_toolbar", &show_toolbar, FALSE)) {
                if (!g_value_get_boolean (&show_toolbar))
                        chrome &= ~EV_CHROME_TOOLBAR;
+               g_value_unset (&show_toolbar);
        }
        window->priv->chrome = chrome;
 }
@@ -636,11 +651,12 @@ setup_sidebar_from_metadata (EvWindow *window, EvDocument *document)
        if (ev_metadata_manager_get (uri, "sidebar_size", &sidebar_size, FALSE)) {
                gtk_paned_set_position (GTK_PANED (window->priv->hpaned),
                                        g_value_get_int (&sidebar_size));
+               g_value_unset(&sidebar_size);
        }
        
        if (document && ev_metadata_manager_get (uri, "sidebar_page", &sidebar_page, FALSE)) {
                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)) {
@@ -648,12 +664,14 @@ setup_sidebar_from_metadata (EvWindow *window, EvDocument *document)
                } else if (strcmp (page_id, ATTACHMENTS_SIDEBAR_ID) && ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (attachments), document)) {
                        ev_sidebar_set_page (EV_SIDEBAR (sidebar), thumbs);
                }
+               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);
        }
 
        if (ev_metadata_manager_get (uri, "sidebar_visibility", &sidebar_visibility, FALSE)) {
                update_chrome_flag (window, EV_CHROME_SIDEBAR, g_value_get_boolean (&sidebar_visibility));
+               g_value_unset (&sidebar_visibility);
        }
 }
 
@@ -686,6 +704,7 @@ setup_view_from_metadata (EvWindow *window)
                } else {
                        gtk_window_unmaximize (GTK_WINDOW (window));
                }
+               g_value_unset (&maximized);
        }
 
        if (restore_size &&
@@ -694,12 +713,16 @@ setup_view_from_metadata (EvWindow *window)
                gtk_window_resize (GTK_WINDOW (window),
                                   g_value_get_int (&width),
                                   g_value_get_int (&height));
+               g_value_unset (&width);
+               g_value_unset (&height);                
        }
        if (restore_size &&
            ev_metadata_manager_get (uri, "window_x", &x, TRUE) &&
            ev_metadata_manager_get (uri, "window_y", &y, TRUE)) {
                gtk_window_move (GTK_WINDOW (window), g_value_get_int (&x),
                                 g_value_get_int (&y));
+               g_value_unset (&x);
+               g_value_unset (&y);
        }
 
        /* Sizing mode */
@@ -714,16 +737,19 @@ setup_view_from_metadata (EvWindow *window)
        if (ev_metadata_manager_get (uri, "zoom", &zoom, FALSE) &&
            ev_view_get_sizing_mode (view) == EV_SIZING_FREE) {
                ev_view_set_zoom (view, g_value_get_double (&zoom), FALSE);
+               g_value_unset (&zoom);
        }
 
        /* Continuous */
        if (ev_metadata_manager_get (uri, "continuous", &continuous, FALSE)) {
                ev_view_set_continuous (view, g_value_get_boolean (&continuous));
+               g_value_unset (&continuous);
        }
 
        /* Dual page */
        if (ev_metadata_manager_get (uri, "dual-page", &dual_page, FALSE)) {
                ev_view_set_dual_page (view, g_value_get_boolean (&dual_page));
+               g_value_unset (&dual_page);
        }
 
        /* Presentation */
@@ -731,6 +757,7 @@ setup_view_from_metadata (EvWindow *window)
                if (g_value_get_boolean (&presentation) && uri) {
                        ev_window_run_presentation (window);
                }
+               g_value_unset (&presentation);
        }
 
        /* Fullscreen */
@@ -738,6 +765,7 @@ setup_view_from_metadata (EvWindow *window)
                if (g_value_get_boolean (&fullscreen) && uri) {
                        ev_window_run_fullscreen (window);
                }
+               g_value_unset (&fullscreen);
        }
 
        /* Rotation */
@@ -757,6 +785,7 @@ setup_view_from_metadata (EvWindow *window)
                                        break;
                        }
                }
+               g_value_unset (&rotation);
        }
 }
 
@@ -934,7 +963,7 @@ ev_window_xfer_job_cb  (EvJobXfer *job,
                if (ev_window->priv->document)
                        g_object_unref (ev_window->priv->document);
                ev_window->priv->document = g_object_ref (document);
-               
+
                ev_window_setup_document (ev_window);
                ev_window_add_recent (ev_window, ev_window->priv->uri);         
 
@@ -1027,7 +1056,7 @@ ev_window_open_uri (EvWindow       *ev_window,
        ev_window_clear_xfer_job (ev_window);
        ev_window_clear_local_uri (ev_window);
        ev_view_set_loading (EV_VIEW (ev_window->priv->view), TRUE);
-       
+
        ev_window->priv->xfer_job = ev_job_xfer_new (uri, dest, mode);
        g_signal_connect (ev_window->priv->xfer_job,
                          "finished",
@@ -1090,6 +1119,19 @@ ev_window_cmd_file_open (GtkAction *action, EvWindow *window)
        gtk_widget_show (chooser);
 }
 
+#ifdef HAVE_GTK_RECENT
+static void
+ev_window_cmd_recent_file_activate (GtkAction     *action,
+                                   GtkRecentInfo *info)
+{
+       const gchar *uri;
+
+       uri = gtk_recent_info_get_uri (info);
+       
+       ev_application_open_uri (EV_APP, uri, NULL,
+                                GDK_CURRENT_TIME, NULL);
+}
+#else
 static void
 ev_window_cmd_recent_file_activate (GtkAction *action,
                                    EvWindow *ev_window)
@@ -1102,25 +1144,131 @@ ev_window_cmd_recent_file_activate (GtkAction *action,
 
        uri = egg_recent_item_get_uri (item);
 
-       ev_application_open_uri (EV_APP, uri, NULL, GDK_CURRENT_TIME, NULL);
+       ev_application_open_uri (EV_APP, uri, NULL,
+                                GDK_CURRENT_TIME, NULL);
        
        g_free (uri);
 }
+#endif /* HAVE_GTK_RECENT */
 
 static void
 ev_window_add_recent (EvWindow *window, const char *filename)
 {
+#ifdef HAVE_GTK_RECENT
+       gtk_recent_manager_add_item (window->priv->recent_manager, filename);
+#else
        EggRecentItem *item;
 
        item = egg_recent_item_new_from_uri (filename);
        egg_recent_item_add_group (item, "Evince");
        egg_recent_model_add_full (ev_application_get_recent_model (EV_APP), item);
+#endif /* HAVE_GTK_RECENT */
 }
 
+#ifdef HAVE_GTK_RECENT
+static gint
+compare_recent_items (GtkRecentInfo *a, GtkRecentInfo *b)
+{
+       gboolean     has_ev_a, has_ev_b;
+       const gchar *evince = g_get_application_name ();
+
+       has_ev_a = gtk_recent_info_has_application (a, evince);
+       has_ev_b = gtk_recent_info_has_application (b, evince);
+       
+       if (has_ev_a && has_ev_b) {
+               time_t time_a, time_b;
+
+               time_a = gtk_recent_info_get_modified (a);
+               time_b = gtk_recent_info_get_modified (b);
+
+               return (time_b - time_a);
+       } else if (has_ev_a) {
+               return -1;
+       } else if (has_ev_b) {
+               return 1;
+       }
+
+       return 0;
+}
+#endif /* HAVE_GTK_RECENT */
+
 static void
 ev_window_setup_recent (EvWindow *ev_window)
 {
+#ifdef HAVE_GTK_RECENT
+       GList        *items, *l;
+       guint         n_items = 0;
+       const gchar  *evince = g_get_application_name ();
+       static guint  i = 0;
+
+       if (ev_window->priv->recent_ui_id > 0) {
+               gtk_ui_manager_remove_ui (ev_window->priv->ui_manager,
+                                         ev_window->priv->recent_ui_id);
+               gtk_ui_manager_ensure_update (ev_window->priv->ui_manager);
+       }
+       ev_window->priv->recent_ui_id = gtk_ui_manager_new_merge_id (ev_window->priv->ui_manager);
+
+       if (ev_window->priv->recent_action_group) {
+               gtk_ui_manager_remove_action_group (ev_window->priv->ui_manager,
+                                                   ev_window->priv->recent_action_group);
+               g_object_unref (ev_window->priv->recent_action_group);
+       }
+       ev_window->priv->recent_action_group = gtk_action_group_new ("RecentFilesActions");
+       gtk_ui_manager_insert_action_group (ev_window->priv->ui_manager,
+                                           ev_window->priv->recent_action_group, 0);
+
+       items = gtk_recent_manager_get_items (ev_window->priv->recent_manager);
+       items = g_list_sort (items, (GCompareFunc) compare_recent_items);
+
+       for (l = items; l && l->data; l = g_list_next (l)) {
+               GtkRecentInfo *info;
+               GtkAction     *action;
+               gchar         *action_name;
+               gchar         *label;
 
+               info = (GtkRecentInfo *) l->data;
+
+               if (!gtk_recent_info_has_application (info, evince))
+                       continue;
+
+               action_name = g_strdup_printf ("RecentFile%u", i++);
+               label = g_strdup_printf ("_%d.  %s",
+                                        n_items + 1,
+                                        gtk_recent_info_get_display_name (info));
+               
+               action = g_object_new (GTK_TYPE_ACTION,
+                                      "name", action_name,
+                                      "label", label,
+                                      NULL);
+
+               g_object_weak_ref (G_OBJECT (action),
+                                  (GWeakNotify) gtk_recent_info_unref,
+                                  gtk_recent_info_ref (info));
+               g_signal_connect (G_OBJECT (action), "activate",
+                                 G_CALLBACK (ev_window_cmd_recent_file_activate),
+                                 (gpointer) info);
+
+               gtk_action_group_add_action (ev_window->priv->recent_action_group,
+                                            action);
+               g_object_unref (action);
+
+               gtk_ui_manager_add_ui (ev_window->priv->ui_manager,
+                                      ev_window->priv->recent_ui_id,
+                                      "/MainMenu/FileMenu/RecentFilesMenu",
+                                      label,
+                                      action_name,
+                                      GTK_UI_MANAGER_MENUITEM,
+                                      FALSE);
+               g_free (action_name);
+               g_free (label);
+
+               if (++n_items == 5)
+                       break;
+       }
+       
+       g_list_foreach (items, (GFunc) gtk_recent_info_unref, NULL);
+       g_list_free (items);
+#else /* HAVE_GTK_RECENT */
        ev_window->priv->recent_view = egg_recent_view_uimanager_new (ev_window->priv->ui_manager,
                                                                      "/MainMenu/FileMenu/RecentFilesMenu",
                                                                      G_CALLBACK (ev_window_cmd_recent_file_activate), 
@@ -1135,6 +1283,7 @@ ev_window_setup_recent (EvWindow *ev_window)
        
        g_signal_connect (ev_window->priv->recent_view, "activate",
                        G_CALLBACK (ev_window_cmd_recent_file_activate), ev_window);
+#endif /* HAVE_GTK_RECENT */
 }
 
 static void
@@ -2220,6 +2369,24 @@ ev_window_screen_changed (GtkWidget *widget,
        EvWindowPrivate *priv = window->priv;
        GdkScreen *screen;
 
+       screen = gtk_widget_get_screen (widget);
+       if (screen == old_screen)
+               return;
+
+#ifdef HAVE_GTK_RECENT
+       if (old_screen) {
+               g_signal_handlers_disconnect_by_func (
+                       gtk_recent_manager_get_for_screen (old_screen),
+                       G_CALLBACK (ev_window_setup_recent), window);
+       }
+
+       priv->recent_manager = gtk_recent_manager_get_for_screen (screen);
+       g_signal_connect_swapped (priv->recent_manager,
+                                 "changed",
+                                 G_CALLBACK (ev_window_setup_recent),
+                                 window);
+#endif
+       
        if (GTK_WIDGET_CLASS (ev_window_parent_class)->screen_changed) {
                GTK_WIDGET_CLASS (ev_window_parent_class)->screen_changed (widget, old_screen);
        }
@@ -2228,7 +2395,6 @@ ev_window_screen_changed (GtkWidget *widget,
                g_signal_handlers_disconnect_by_func
                        (old_screen, G_CALLBACK (screen_size_changed_cb), window);
 
-               screen = gtk_widget_get_screen (widget);
                g_signal_connect_object (screen, "size-changed",
                                         G_CALLBACK (screen_size_changed_cb),
                                         window, 0);
@@ -2461,10 +2627,14 @@ ev_window_cmd_escape (GtkAction *action, EvWindow *window)
                              "presentation", &presentation,
                              NULL);
 
-               if (fullscreen)
+               if (fullscreen) {
                        ev_window_stop_fullscreen (window);
-               if (presentation)
+               } else if (presentation) {
                        ev_window_stop_presentation (window);
+                       gtk_widget_grab_focus (window->priv->view);
+               } else {
+                       gtk_widget_grab_focus (window->priv->view);
+               }
 
                if (fullscreen && presentation)
                        g_warning ("Both fullscreen and presentation set somehow");
@@ -3024,11 +3194,6 @@ ev_window_dispose (GObject *object)
                priv->title = NULL;
        }
 
-       if (priv->recent_view) {
-               g_object_unref (priv->recent_view);
-               priv->recent_view = NULL;
-       }
-
        if (priv->ui_manager) {
                g_object_unref (priv->ui_manager);
                priv->ui_manager = NULL;
@@ -3049,6 +3214,27 @@ ev_window_dispose (GObject *object)
                priv->attachment_popup_action_group = NULL;
        }
 
+#ifdef HAVE_GTK_RECENT
+       if (priv->recent_action_group) {
+               g_object_unref (priv->recent_action_group);
+               priv->recent_action_group = NULL;
+       }
+
+       if (priv->recent_manager) {
+               g_signal_handlers_disconnect_by_func (priv->recent_manager,
+                                                     ev_window_setup_recent,
+                                                     window);
+               priv->recent_manager = NULL;
+       }
+
+       priv->recent_ui_id = 0;
+#else
+       if (priv->recent_view) {
+               g_object_unref (priv->recent_view);
+               priv->recent_view = NULL;
+       }
+#endif /* HAVE_GTK_RECENT */
+
        if (priv->page_cache) {
                g_signal_handlers_disconnect_by_func (priv->page_cache, page_changed_cb, window);
                priv->page_cache = NULL;
@@ -3064,6 +3250,11 @@ ev_window_dispose (GObject *object)
                priv->view = NULL;
        }
 
+       if (priv->password_view) {
+               g_object_unref (priv->password_view);
+               priv->password_view = NULL;
+       }
+
        if (priv->xfer_job) {
                ev_window_clear_xfer_job (window);
        }
@@ -3281,7 +3472,7 @@ static const GtkActionEntry entries[] = {
 /* Toggle items */
 static const GtkToggleActionEntry toggle_entries[] = {
        /* View Menu */
-       { "ViewToolbar", NULL, N_("_Toolbar"), "<shift><control>T",
+       { "ViewToolbar", NULL, N_("_Toolbar"), NULL,
          N_("Show or hide the toolbar"),
          G_CALLBACK (ev_window_view_toolbar_cb), TRUE },
         { "ViewSidebar", GTK_STOCK_INDEX, N_("Side _Pane"), "F9",
@@ -3614,7 +3805,7 @@ open_remote_link (EvWindow *window, EvLinkAction *action)
        uri = g_build_filename (dir, ev_link_action_get_filename (action),
                                NULL);
        g_free (dir);
-       
+
        ev_application_open_uri_at_dest (EV_APP, uri,
                                         ev_link_action_get_dest (action),
                                         0,
@@ -3640,6 +3831,8 @@ do_action_named (EvWindow *window, EvLinkAction *action)
                ev_window_cmd_focus_page_selector (NULL, window);
        } else if (g_ascii_strcasecmp (name, "Find") == 0) {
                ev_window_cmd_edit_find (NULL, window);
+       } else if (g_ascii_strcasecmp (name, "Close") == 0) {
+               ev_window_cmd_file_close_window (NULL, window);
        } else {
                g_warning ("Unimplemented named action: %s, please post a "
                           "bug report in Evince bugzilla "
@@ -3871,7 +4064,18 @@ ev_window_init (EvWindow *ev_window)
                g_warning ("building menus failed: %s", error->message);
                g_error_free (error);
        }
-
+       
+#ifdef HAVE_GTK_RECENT
+       ev_window->priv->recent_manager = gtk_recent_manager_get_for_screen (
+               gtk_widget_get_screen (GTK_WIDGET (ev_window)));
+       ev_window->priv->recent_action_group = NULL;
+       ev_window->priv->recent_ui_id = 0;
+       g_signal_connect_swapped (ev_window->priv->recent_manager,
+                                 "changed",
+                                 G_CALLBACK (ev_window_setup_recent),
+                                 ev_window);
+#endif /* HAVE_GTK_RECENT */
+       
        ev_window->priv->menubar =
                 gtk_ui_manager_get_widget (ev_window->priv->ui_manager,
                                            "/MainMenu");