]> www.fi.muni.cz Git - evince.git/blobdiff - shell/ev-window.c
Fix several history bugs
[evince.git] / shell / ev-window.c
index 19c67342dd016b0d1a40f28cc47e95843cd4176a..64b80c33abdd79d5002eea9572012af1d383b783 100644 (file)
 #endif
 
 #include "ev-window.h"
+#include "ev-navigation-action.h"
+#include "ev-page-action.h"
 #include "ev-sidebar.h"
-#include "ev-sidebar-bookmarks.h"
+#include "ev-sidebar-links.h"
 #include "ev-sidebar-thumbnails.h"
 #include "ev-view.h"
 #include "ev-print-job.h"
@@ -72,6 +74,8 @@ struct _EvWindowPrivate {
        GtkWidget *statusbar;
        guint help_message_cid;
        GtkWidget *exit_fullscreen_popup;
+       char *uri;
+       GtkAction *page_action;
 
        EvDocument *document;
 
@@ -181,11 +185,17 @@ update_action_sensitivity (EvWindow *ev_window)
        page = ev_view_get_page (EV_VIEW (ev_window->priv->view));
 
        set_action_sensitive (ev_window, "GoFirstPage", page > 1);
-       set_action_sensitive (ev_window, "GoPreviousPage", page > 1);
-       set_action_sensitive (ev_window, "GoNextPage", page < n_pages);
+       set_action_sensitive (ev_window, "GoPageDown", page > 1);
+       set_action_sensitive (ev_window, "GoPageUp", page < n_pages);
        set_action_sensitive (ev_window, "GoLastPage", page < n_pages);
 }
 
+void
+ev_window_open_link (EvWindow *ev_window, EvLink *link)
+{
+       ev_view_go_to_link (EV_VIEW (ev_window->priv->view), link);
+}
+
 gboolean
 ev_window_is_empty (const EvWindow *ev_window)
 {
@@ -254,12 +264,14 @@ update_window_title (EvDocument *document, GParamSpec *pspec, EvWindow *ev_windo
 {
        char *title = NULL;
 
-       if (document) {
+       if (document == NULL) {
+               title = g_strdup (_("Document Viewer"));
+       } else {
                title = ev_document_get_title (document);
-       }
 
-       if (title == NULL) {
-               title = g_strdup (_("Document Viewer"));
+               if (title == NULL) {
+                       title = g_path_get_basename (ev_window->priv->uri);
+               }
        }
 
        gtk_window_set_title (GTK_WINDOW (ev_window), title);
@@ -267,11 +279,25 @@ update_window_title (EvDocument *document, GParamSpec *pspec, EvWindow *ev_windo
        g_free (title);
 }
 
+static void
+update_total_pages (EvWindow *ev_window)
+{
+       EvPageAction *page_action;
+       int pages;
+
+       pages = ev_document_get_n_pages (ev_window->priv->document);
+       page_action = EV_PAGE_ACTION (ev_window->priv->page_action);
+       ev_page_action_set_total_pages (page_action, pages);
+}
+
 void
 ev_window_open (EvWindow *ev_window, const char *uri)
 {
        EvDocument *document = NULL;
        char *mime_type;
+       
+       g_free (ev_window->priv->uri);
+       ev_window->priv->uri = g_strdup (uri);
 
        mime_type = gnome_vfs_get_mime_type (uri);
 
@@ -287,6 +313,11 @@ ev_window_open (EvWindow *ev_window, const char *uri)
        if (document) {
                GError *error = NULL;
 
+               g_signal_connect_object (G_OBJECT (document),
+                                        "notify::title",
+                                        G_CALLBACK (update_window_title),
+                                        ev_window, 0);
+
                if (ev_document_load (document, uri, &error)) {
                        if (ev_window->priv->document)
                                g_object_unref (ev_window->priv->document);
@@ -297,13 +328,8 @@ ev_window_open (EvWindow *ev_window, const char *uri)
                        ev_sidebar_set_document (EV_SIDEBAR (ev_window->priv->sidebar),
                                                 document);
 
-                       g_signal_connect_object (G_OBJECT (document),
-                                                "notify::title",
-                                                G_CALLBACK (update_window_title),
-                                                ev_window, 0);
-
+                       update_total_pages (ev_window);
                        update_action_sensitivity (ev_window);
-               
                } else {
                        g_assert (error != NULL);
                        g_object_unref (document);
@@ -328,6 +354,119 @@ ev_window_cmd_file_open (GtkAction *action, EvWindow *ev_window)
        ev_application_open (EV_APP, NULL);
 }
 
+/* FIXME
+static gboolean
+overwrite_existing_file (GtkWindow *window, const gchar *file_name)
+{
+       GtkWidget *msgbox;
+       gchar *utf8_file_name;
+       AtkObject *obj;
+       gint ret;
+
+       utf8_file_name = g_filename_to_utf8 (file_name, -1, NULL, NULL, NULL);
+       msgbox = gtk_message_dialog_new (
+               window,
+               (GtkDialogFlags)GTK_DIALOG_DESTROY_WITH_PARENT,
+               GTK_MESSAGE_QUESTION,
+               GTK_BUTTONS_NONE,
+               _("A file named \"%s\" already exists."),
+               utf8_file_name);
+       g_free (utf8_file_name);
+
+       gtk_message_dialog_format_secondary_text (
+               GTK_MESSAGE_DIALOG (msgbox),
+               _("Do you want to replace it with the one you are saving?"));
+
+       gtk_dialog_add_button (GTK_DIALOG (msgbox), 
+                              GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
+
+       gtk_dialog_add_button (GTK_DIALOG (msgbox),
+                              _("_Replace"), GTK_RESPONSE_YES);
+
+       gtk_dialog_set_default_response (GTK_DIALOG (msgbox),
+                                        GTK_RESPONSE_CANCEL);
+
+       obj = gtk_widget_get_accessible (msgbox);
+
+       if (GTK_IS_ACCESSIBLE (obj))
+               atk_object_set_name (obj, _("Question"));
+
+       ret = gtk_dialog_run (GTK_DIALOG (msgbox));
+       gtk_widget_destroy (msgbox);
+
+       return (ret == GTK_RESPONSE_YES);
+}
+*/
+
+static void
+save_error_dialog (GtkWindow *window, const gchar *file_name)
+{
+       GtkWidget *error_dialog;
+
+       error_dialog = gtk_message_dialog_new (
+               window,
+               (GtkDialogFlags)GTK_DIALOG_DESTROY_WITH_PARENT,
+               GTK_MESSAGE_ERROR,
+               GTK_BUTTONS_CLOSE,
+               _("The file could not be saved as \"%s\"."),
+               file_name);
+
+       /* Easy way to make the text bold while keeping the string
+        * above free from pango markup (FIXME ?) */
+       gtk_message_dialog_format_secondary_text (
+               GTK_MESSAGE_DIALOG (error_dialog), " ");
+
+       gtk_dialog_run (GTK_DIALOG (error_dialog));
+       gtk_widget_destroy (error_dialog);
+}
+
+static void
+ev_window_cmd_save_as (GtkAction *action, EvWindow *ev_window)
+{
+       GtkWidget *fc;
+       GtkFileFilter *pdf_filter, *all_filter;
+       gchar *uri = NULL; 
+
+       fc = gtk_file_chooser_dialog_new (
+               _("Save a Copy"),
+               NULL, GTK_FILE_CHOOSER_ACTION_SAVE,
+               GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+               GTK_STOCK_SAVE, GTK_RESPONSE_OK,
+               NULL);
+       gtk_window_set_modal (GTK_WINDOW (fc), TRUE);
+
+       pdf_filter = gtk_file_filter_new ();
+       gtk_file_filter_set_name (pdf_filter, _("PDF Documents"));
+       gtk_file_filter_add_mime_type (pdf_filter, "application/pdf");
+       gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (fc), pdf_filter);
+
+       all_filter = gtk_file_filter_new ();
+       gtk_file_filter_set_name (all_filter, _("All Files"));
+       gtk_file_filter_add_pattern (all_filter, "*");
+       gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (fc), all_filter);
+       gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (fc), pdf_filter);
+       
+       gtk_dialog_set_default_response (GTK_DIALOG (fc), GTK_RESPONSE_OK);
+
+       gtk_widget_show (fc);
+
+       while (gtk_dialog_run (GTK_DIALOG (fc)) == GTK_RESPONSE_OK) {
+               uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (fc));
+
+/* FIXME
+               if (g_file_test (uri, G_FILE_TEST_EXISTS) &&  
+                   !overwrite_existing_file (GTK_WINDOW (fc), uri))
+                               continue;
+*/
+
+               if (ev_document_save (ev_window->priv->document, uri, NULL))
+                       break;
+               else
+                       save_error_dialog (GTK_WINDOW (fc), uri);    
+       }
+       gtk_widget_destroy (fc);
+}
+
 static gboolean
 using_postscript_printer (GnomePrintConfig *config)
 {
@@ -412,8 +551,10 @@ ev_window_print (EvWindow *ev_window)
                                
        gtk_widget_destroy (print_dialog);
 
-       if (print_job != NULL)
+       if (print_job != NULL) {
                ev_print_job_print (print_job, GTK_WINDOW (ev_window));
+               g_object_unref (print_job);
+       }
 }
 
 static void
@@ -450,6 +591,14 @@ find_not_supported_dialog (EvWindow   *ev_window)
        gtk_widget_destroy (dialog);
 }
 
+static void
+ev_window_cmd_edit_select_all (GtkAction *action, EvWindow *ev_window)
+{
+       g_return_if_fail (EV_IS_WINDOW (ev_window));
+
+       ev_view_select_all (EV_VIEW (ev_window->priv->view));
+}
+
 static void
 ev_window_cmd_edit_find (GtkAction *action, EvWindow *ev_window)
 {
@@ -474,7 +623,7 @@ ev_window_cmd_edit_copy (GtkAction *action, EvWindow *ev_window)
 {
         g_return_if_fail (EV_IS_WINDOW (ev_window));
 
-        /* FIXME */
+       ev_view_copy (EV_VIEW (ev_window->priv->view));
 }
 
 static void
@@ -723,7 +872,7 @@ ev_window_cmd_go_back (GtkAction *action, EvWindow *ev_window)
 {
         g_return_if_fail (EV_IS_WINDOW (ev_window));
 
-        /* FIXME */
+       ev_view_go_back (EV_VIEW (ev_window->priv->view));
 }
 
 static void
@@ -731,11 +880,11 @@ ev_window_cmd_go_forward (GtkAction *action, EvWindow *ev_window)
 {
         g_return_if_fail (EV_IS_WINDOW (ev_window));
 
-        /* FIXME */
+       ev_view_go_forward (EV_VIEW (ev_window->priv->view));
 }
 
 static void
-ev_window_cmd_go_previous_page (GtkAction *action, EvWindow *ev_window)
+ev_window_cmd_go_page_up (GtkAction *action, EvWindow *ev_window)
 {
         g_return_if_fail (EV_IS_WINDOW (ev_window));
 
@@ -744,7 +893,7 @@ ev_window_cmd_go_previous_page (GtkAction *action, EvWindow *ev_window)
 }
 
 static void
-ev_window_cmd_go_next_page (GtkAction *action, EvWindow *ev_window)
+ev_window_cmd_go_page_down (GtkAction *action, EvWindow *ev_window)
 {
         g_return_if_fail (EV_IS_WINDOW (ev_window));
 
@@ -916,10 +1065,22 @@ disconnect_proxy_cb (GtkUIManager *ui_manager, GtkAction *action,
        }
 }
 
+static void
+update_current_page (EvWindow *ev_window)
+{
+       EvPageAction *page_action;
+       int page;
+
+       page = ev_view_get_page (EV_VIEW (ev_window->priv->view));
+       page_action = EV_PAGE_ACTION (ev_window->priv->page_action);
+       ev_page_action_set_current_page (page_action, page);
+}
+
 static void
 view_page_changed_cb (EvView   *view,
                      EvWindow *ev_window)
 {
+       update_current_page (ev_window);
        update_action_sensitivity (ev_window);
 }
 
@@ -1080,7 +1241,10 @@ static GtkActionEntry entries[] = {
        { "FileOpen", GTK_STOCK_OPEN, N_("_Open"), "<control>O",
          N_("Open a file"),
          G_CALLBACK (ev_window_cmd_file_open) },
-        { "FilePrint", GTK_STOCK_PRINT, N_("_Print"), "<control>P",
+               { "FileSaveAs", GTK_STOCK_SAVE_AS, N_("_Save a Copy..."), NULL,
+         N_("Save the current document with a new filename"),
+         G_CALLBACK (ev_window_cmd_save_as) },
+       { "FilePrint", GTK_STOCK_PRINT, N_("_Print"), "<control>P",
          N_("Print this document"),
          G_CALLBACK (ev_window_cmd_file_print) },
        { "FileCloseWindow", GTK_STOCK_CLOSE, N_("_Close"), "<control>W",
@@ -1091,7 +1255,9 @@ static GtkActionEntry entries[] = {
         { "EditCopy", GTK_STOCK_COPY, N_("_Copy"), "<control>C",
           N_("Copy text from the document"),
           G_CALLBACK (ev_window_cmd_edit_copy) },
-        
+       { "EditSelectAll", NULL, N_("Select _All"), "<control>A",
+         N_("Select the entire page"),
+         G_CALLBACK (ev_window_cmd_edit_select_all) }, 
         { "EditFind", GTK_STOCK_FIND, N_("_Find"), "<control>F",
           N_("Find a word or phrase in the document"),
           G_CALLBACK (ev_window_cmd_edit_find) },
@@ -1120,12 +1286,12 @@ static GtkActionEntry entries[] = {
         { "GoForward", GTK_STOCK_GO_FORWARD, N_("Fo_rward"), "<mod1>Right",
           N_("Go to the page viewed before this one"),
           G_CALLBACK (ev_window_cmd_go_forward) },
-        { "GoPreviousPage", GTK_STOCK_GO_BACK, N_("_Previous Page"), "<control>Page_Up",
+        { "GoPageDown", GTK_STOCK_GO_UP, N_("_Page Up"), "<control>Page_Up",
           N_("Go to the previous page"),
-          G_CALLBACK (ev_window_cmd_go_previous_page) },
-        { "GoNextPage", GTK_STOCK_GO_FORWARD, N_("_Next Page"), "<control>Page_Down",
+          G_CALLBACK (ev_window_cmd_go_page_up) },
+        { "GoPageUp", GTK_STOCK_GO_DOWN, N_("_Page Down"), "<control>Page_Down",
           N_("Go to the next page"),
-          G_CALLBACK (ev_window_cmd_go_next_page) },
+          G_CALLBACK (ev_window_cmd_go_page_down) },
         { "GoFirstPage", GTK_STOCK_GOTO_FIRST, N_("_First Page"), "<control>Home",
           N_("Go to the first page"),
           G_CALLBACK (ev_window_cmd_go_first_page) },        
@@ -1160,6 +1326,60 @@ static GtkToggleActionEntry toggle_entries[] = {
           G_CALLBACK (ev_window_cmd_view_fullscreen) },
 };
 
+static void
+goto_page_cb (GtkAction *action, int page_number, EvWindow *ev_window)
+{
+       EvView *view = EV_VIEW (ev_window->priv->view);
+
+       if (ev_view_get_page (view) != page_number) {
+               ev_view_set_page (view, page_number);
+       }
+}
+
+static void
+register_custom_actions (EvWindow *window, GtkActionGroup *group)
+{
+       GtkAction *action;
+
+       action = g_object_new (EV_TYPE_NAVIGATION_ACTION,
+                              "name", "NavigationBack",
+                              "label", _("Back"),
+                              "stock_id", GTK_STOCK_GO_BACK,
+                              "tooltip", _("Go back"),
+                              "arrow-tooltip", _("Back history"),
+                              "direction", EV_NAVIGATION_DIRECTION_BACK,
+                              "is_important", TRUE,
+                              NULL);
+       g_signal_connect (action, "activate",
+                         G_CALLBACK (ev_window_cmd_go_back), window);
+       gtk_action_group_add_action (group, action);
+       g_object_unref (action);
+
+       action = g_object_new (EV_TYPE_NAVIGATION_ACTION,
+                              "name", "NavigationForward",
+                              "label", _("Forward"),
+                              "stock_id", GTK_STOCK_GO_FORWARD,
+                              "tooltip", _("Go forward"),
+                              "arrow-tooltip", _("Forward history"),
+                              "direction", EV_NAVIGATION_DIRECTION_FORWARD,
+                              NULL);
+       g_signal_connect (action, "activate",
+                         G_CALLBACK (ev_window_cmd_go_forward), window);
+       gtk_action_group_add_action (group, action);
+       g_object_unref (action);
+
+       action = g_object_new (EV_TYPE_PAGE_ACTION,
+                              "name", "PageSelector",
+                              "label", _("Page"),
+                              "tooltip", _("Select Page"),
+                              NULL);
+       g_signal_connect (action, "goto_page",
+                         G_CALLBACK (goto_page_cb), window);
+       window->priv->page_action = action;
+       gtk_action_group_add_action (group, action);
+       g_object_unref (action);
+}
+
 static void
 ev_window_init (EvWindow *ev_window)
 {
@@ -1188,6 +1408,8 @@ ev_window_init (EvWindow *ev_window)
                                             G_N_ELEMENTS (toggle_entries),
                                             ev_window);
 
+       register_custom_actions (ev_window, action_group);
+
        ev_window->priv->ui_manager = gtk_ui_manager_new ();
        gtk_ui_manager_insert_action_group (ev_window->priv->ui_manager,
                                            action_group, 0);
@@ -1230,11 +1452,11 @@ ev_window_init (EvWindow *ev_window)
                        ev_window->priv->sidebar);
 
        /* Stub sidebar, for now */
-       sidebar_widget = ev_sidebar_bookmarks_new ();
+       sidebar_widget = ev_sidebar_links_new ();
        gtk_widget_show (sidebar_widget);
        ev_sidebar_add_page (EV_SIDEBAR (ev_window->priv->sidebar),
-                            "bookmarks",
-                            _("Bookmarks"),
+                            "index",
+                            _("Index"),
                             sidebar_widget);
 
        sidebar_widget = ev_sidebar_thumbnails_new ();