]> www.fi.muni.cz Git - evince.git/blobdiff - previewer/ev-previewer-window.c
[l10n]Fixes on Catalan translation
[evince.git] / previewer / ev-previewer-window.c
index c406a2237accd1cf15525e2a484b56868601ad47..734941edc99679924d40fd0b3202a2402f80e762 100644 (file)
@@ -15,7 +15,7 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
 #include <config.h>
 struct _EvPreviewerWindow {
        GtkWindow         base_instance;
 
+       EvDocumentModel  *model;
        EvDocument       *document;
 
        GtkActionGroup   *action_group;
+       GtkActionGroup   *accels_group;
        GtkUIManager     *ui_manager;
 
        GtkWidget        *swindow;
@@ -55,20 +57,23 @@ struct _EvPreviewerWindowClass {
        GtkWindowClass base_class;
 };
 
+enum {
+       PROP_0,
+       PROP_MODEL
+};
+
+#define MIN_SCALE 0.05409
+#define MAX_SCALE 4.0
+
 G_DEFINE_TYPE (EvPreviewerWindow, ev_previewer_window, GTK_TYPE_WINDOW)
 
 static gdouble
-get_screen_dpi (GtkWindow *window)
+get_screen_dpi (EvPreviewerWindow *window)
 {
        GdkScreen *screen;
-       gdouble    xdpi, ydpi;
 
-       screen = gtk_window_get_screen (window);
-
-       xdpi = 25.4 * gdk_screen_get_width (screen) / gdk_screen_get_width_mm (screen);
-       ydpi = 25.4 * gdk_screen_get_height (screen) / gdk_screen_get_height_mm (screen);
-
-       return (xdpi + ydpi) / 2.0;
+       screen = gtk_window_get_screen (GTK_WINDOW (window));
+       return ev_document_misc_get_screen_dpi (screen);
 }
 
 #if GTKUNIXPRINT_ENABLED
@@ -91,6 +96,13 @@ ev_previewer_window_error_dialog_run (EvPreviewerWindow *window,
 }
 #endif
 
+static void
+ev_previewer_window_close (GtkAction         *action,
+                          EvPreviewerWindow *window)
+{
+       gtk_widget_destroy (GTK_WIDGET (window));
+}
+
 static void
 ev_previewer_window_previous_page (GtkAction         *action,
                                   EvPreviewerWindow *window)
@@ -109,7 +121,7 @@ static void
 ev_previewer_window_zoom_in (GtkAction         *action,
                             EvPreviewerWindow *window)
 {
-       ev_view_set_sizing_mode (window->view, EV_SIZING_FREE);
+       ev_document_model_set_sizing_mode (window->model, EV_SIZING_FREE);
        ev_view_zoom_in (window->view);
 }
 
@@ -117,7 +129,7 @@ static void
 ev_previewer_window_zoom_out (GtkAction         *action,
                              EvPreviewerWindow *window)
 {
-       ev_view_set_sizing_mode (window->view, EV_SIZING_FREE);
+       ev_document_model_set_sizing_mode (window->model, EV_SIZING_FREE);
        ev_view_zoom_out (window->view);
 }
 
@@ -125,22 +137,18 @@ static void
 ev_previewer_window_zoom_best_fit (GtkToggleAction   *action,
                                   EvPreviewerWindow *window)
 {
-       if (gtk_toggle_action_get_active (action)) {
-               ev_view_set_sizing_mode (window->view, EV_SIZING_BEST_FIT);
-       } else {
-               ev_view_set_sizing_mode (window->view, EV_SIZING_FREE);
-       }
+       ev_document_model_set_sizing_mode (window->model,
+                                          gtk_toggle_action_get_active (action) ?
+                                          EV_SIZING_BEST_FIT : EV_SIZING_FREE);
 }
 
 static void
 ev_previewer_window_zoom_page_width (GtkToggleAction   *action,
                                     EvPreviewerWindow *window)
 {
-       if (gtk_toggle_action_get_active (action)) {
-               ev_view_set_sizing_mode (window->view, EV_SIZING_FIT_WIDTH);
-       } else {
-               ev_view_set_sizing_mode (window->view, EV_SIZING_FREE);
-       }
+       ev_document_model_set_sizing_mode (window->model,
+                                          gtk_toggle_action_get_active (action) ?
+                                          EV_SIZING_FIT_WIDTH : EV_SIZING_FREE);
 }
 
 static void
@@ -152,6 +160,31 @@ ev_previewer_window_action_page_activated (GtkAction         *action,
        gtk_widget_grab_focus (GTK_WIDGET (window->view));
 }
 
+static void
+ev_previewer_window_focus_page_selector (GtkAction         *action,
+                                        EvPreviewerWindow *window)
+{
+       GtkAction *page_action;
+
+       page_action = gtk_action_group_get_action (window->action_group,
+                                                  "PageSelector");
+       ev_page_action_grab_focus (EV_PAGE_ACTION (page_action));
+}
+
+static void
+ev_previewer_window_scroll_forward (GtkAction         *action,
+                                   EvPreviewerWindow *window)
+{
+       ev_view_scroll (window->view, GTK_SCROLL_PAGE_FORWARD, FALSE);
+}
+
+static void
+ev_previewer_window_scroll_backward (GtkAction         *action,
+                                    EvPreviewerWindow *window)
+{
+       ev_view_scroll (window->view, GTK_SCROLL_PAGE_BACKWARD, FALSE);
+}
+
 #if GTKUNIXPRINT_ENABLED
 static void
 ev_previewer_window_print_finished (GtkPrintJob       *print_job,
@@ -245,6 +278,9 @@ ev_previewer_window_print (GtkAction         *action,
 #endif
 
 static const GtkActionEntry action_entries[] = {
+       { "FileCloseWindow", GTK_STOCK_CLOSE, NULL, "<control>W",
+         NULL,
+         G_CALLBACK (ev_previewer_window_close) },
        { "GoPreviousPage", GTK_STOCK_GO_UP, N_("_Previous Page"), "<control>Page_Up",
           N_("Go to the previous page"),
           G_CALLBACK (ev_previewer_window_previous_page) },
@@ -264,6 +300,44 @@ static const GtkActionEntry action_entries[] = {
 #endif
 };
 
+static const GtkActionEntry accel_entries[] = {
+       { "Space", NULL, "", "space", NULL,
+         G_CALLBACK (ev_previewer_window_scroll_forward) },
+       { "ShiftSpace", NULL, "", "<shift>space", NULL,
+         G_CALLBACK (ev_previewer_window_scroll_backward) },
+       { "BackSpace", NULL, "", "BackSpace", NULL,
+         G_CALLBACK (ev_previewer_window_scroll_backward) },
+       { "ShiftBackSpace", NULL, "", "<shift>BackSpace", NULL,
+         G_CALLBACK (ev_previewer_window_scroll_forward) },
+       { "Return", NULL, "", "Return", NULL,
+         G_CALLBACK (ev_previewer_window_scroll_forward) },
+       { "ShiftReturn", NULL, "", "<shift>Return", NULL,
+         G_CALLBACK (ev_previewer_window_scroll_backward) },
+       { "p", GTK_STOCK_GO_UP, "", "p", NULL,
+         G_CALLBACK (ev_previewer_window_previous_page) },
+       { "n", GTK_STOCK_GO_DOWN, "", "n", NULL,
+         G_CALLBACK (ev_previewer_window_next_page) },
+       { "Plus", GTK_STOCK_ZOOM_IN, NULL, "plus", NULL,
+         G_CALLBACK (ev_previewer_window_zoom_in) },
+       { "CtrlEqual", GTK_STOCK_ZOOM_IN, NULL, "<control>equal", NULL,
+         G_CALLBACK (ev_previewer_window_zoom_in) },
+       { "Equal", GTK_STOCK_ZOOM_IN, NULL, "equal", NULL,
+         G_CALLBACK (ev_previewer_window_zoom_in) },
+       { "Minus", GTK_STOCK_ZOOM_OUT, NULL, "minus", NULL,
+         G_CALLBACK (ev_previewer_window_zoom_out) },
+       { "KpPlus", GTK_STOCK_ZOOM_IN, NULL, "KP_Add", NULL,
+         G_CALLBACK (ev_previewer_window_zoom_in) },
+       { "KpMinus", GTK_STOCK_ZOOM_OUT, NULL, "KP_Subtract", NULL,
+         G_CALLBACK (ev_previewer_window_zoom_out) },
+       { "CtrlKpPlus", GTK_STOCK_ZOOM_IN, NULL, "<control>KP_Add", NULL,
+         G_CALLBACK (ev_previewer_window_zoom_in) },
+       { "CtrlKpMinus", GTK_STOCK_ZOOM_OUT, NULL, "<control>KP_Subtract", NULL,
+         G_CALLBACK (ev_previewer_window_zoom_out) },
+       { "FocusPageSelector", NULL, "", "<control>l", NULL,
+         G_CALLBACK (ev_previewer_window_focus_page_selector) }
+
+};
+
 static const GtkToggleActionEntry toggle_action_entries[] = {
        { "ViewBestFit", EV_STOCK_ZOOM_PAGE, N_("_Best Fit"), NULL,
          N_("Make the current document fill the window"),
@@ -273,22 +347,25 @@ static const GtkToggleActionEntry toggle_action_entries[] = {
          G_CALLBACK (ev_previewer_window_zoom_page_width) }
 };
 
-/* EvView callbacks */
+static gboolean
+view_focus_changed (GtkWidget         *widget,
+                   GdkEventFocus     *event,
+                   EvPreviewerWindow *window)
+{
+       if (window->accels_group)
+               gtk_action_group_set_sensitive (window->accels_group, event->in);
+
+       return FALSE;
+}
+
 static void
-view_sizing_mode_changed (EvView            *view,
+view_sizing_mode_changed (EvDocumentModel   *model,
                          GParamSpec        *pspec,
                          EvPreviewerWindow *window)
 {
-       EvSizingMode sizing_mode;
+       EvSizingMode sizing_mode = ev_document_model_get_sizing_mode (model);
        GtkAction   *action;
 
-       if (!window->view)
-               return;
-
-       g_object_get (window->view,
-                     "sizing_mode", &sizing_mode,
-                     NULL);
-
        action = gtk_action_group_get_action (window->action_group, "ViewBestFit");
        g_signal_handlers_block_by_func (action,
                                         G_CALLBACK (ev_previewer_window_zoom_best_fit),
@@ -310,11 +387,45 @@ view_sizing_mode_changed (EvView            *view,
                                           window);
 }
 
+static void
+ev_previewer_window_set_document (EvPreviewerWindow *window,
+                                 GParamSpec        *pspec,
+                                 EvDocumentModel   *model)
+{
+       EvDocument *document = ev_document_model_get_document (model);
+
+       window->document = g_object_ref (document);
+
+       g_signal_connect (model, "notify::sizing-mode",
+                         G_CALLBACK (view_sizing_mode_changed),
+                         window);
+       ev_view_set_loading (window->view, FALSE);
+       gtk_action_group_set_sensitive (window->action_group, TRUE);
+       gtk_action_group_set_sensitive (window->accels_group, TRUE);
+}
+
+static void
+ev_previewer_window_connect_action_accelerators (EvPreviewerWindow *window)
+{
+       GList *actions;
+
+       gtk_ui_manager_ensure_update (window->ui_manager);
+
+       actions = gtk_action_group_list_actions (window->action_group);
+       g_list_foreach (actions, (GFunc)gtk_action_connect_accelerator, NULL);
+       g_list_free (actions);
+}
+
 static void
 ev_previewer_window_dispose (GObject *object)
 {
        EvPreviewerWindow *window = EV_PREVIEWER_WINDOW (object);
 
+       if (window->model) {
+               g_object_unref (window->model);
+               window->model = NULL;
+       }
+
        if (window->document) {
                g_object_unref (window->document);
                window->document = NULL;
@@ -325,6 +436,11 @@ ev_previewer_window_dispose (GObject *object)
                window->action_group = NULL;
        }
 
+       if (window->accels_group) {
+               g_object_unref (window->accels_group);
+               window->accels_group = NULL;
+       }
+
        if (window->ui_manager) {
                g_object_unref (window->ui_manager);
                window->ui_manager = NULL;
@@ -371,7 +487,7 @@ data_dir (void)
        datadir = g_build_filename (dir, "share", "evince", NULL);
        g_free (dir);
 #else
-       datadir = g_strdup (DATADIR);
+       datadir = g_strdup (EVINCEDATADIR);
 #endif
 
        return datadir;
@@ -380,14 +496,53 @@ data_dir (void)
 static void
 ev_previewer_window_init (EvPreviewerWindow *window)
 {
-       GtkWidget *vbox;
-       GtkWidget *toolbar;
-       GtkAction *action;
-       GError    *error = NULL;
-       gchar     *datadir, *ui_path;
-
        gtk_window_set_default_size (GTK_WINDOW (window), 600, 600);
-       
+}
+
+static void
+ev_previewer_window_set_property (GObject      *object,
+                                 guint         prop_id,
+                                 const GValue *value,
+                                 GParamSpec   *pspec)
+{
+       EvPreviewerWindow *window = EV_PREVIEWER_WINDOW (object);
+
+       switch (prop_id) {
+       case PROP_MODEL:
+               window->model = g_value_dup_object (value);
+               break;
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+       }
+}
+
+static GObject *
+ev_previewer_window_constructor (GType                  type,
+                                guint                  n_construct_properties,
+                                GObjectConstructParam *construct_params)
+{
+       GObject           *object;
+       EvPreviewerWindow *window;
+       GtkWidget         *vbox;
+       GtkWidget         *toolbar;
+       GtkAction         *action;
+       GError            *error = NULL;
+       gchar             *datadir, *ui_path;
+       gdouble            dpi;
+
+       object = G_OBJECT_CLASS (ev_previewer_window_parent_class)->constructor (type,
+                                                                                n_construct_properties,
+                                                                                construct_params);
+       window = EV_PREVIEWER_WINDOW (object);
+
+       dpi = get_screen_dpi (window);
+       ev_document_model_set_min_scale (window->model, MIN_SCALE * dpi / 72.0);
+       ev_document_model_set_max_scale (window->model, MAX_SCALE * dpi / 72.0);
+       ev_document_model_set_sizing_mode (window->model, EV_SIZING_FIT_WIDTH);
+       g_signal_connect_swapped (window->model, "notify::document",
+                                 G_CALLBACK (ev_previewer_window_set_document),
+                                 window);
+
        window->action_group = gtk_action_group_new ("PreviewerActions");
        gtk_action_group_set_translation_domain (window->action_group, NULL);
        gtk_action_group_add_actions (window->action_group, action_entries,
@@ -405,15 +560,24 @@ ev_previewer_window_init (EvPreviewerWindow *window)
                               "icon_name", "text-x-generic",
                               "visible_overflown", FALSE,
                               NULL);
+       ev_page_action_set_model (EV_PAGE_ACTION (action), window->model);
        g_signal_connect (action, "activate_link",
                          G_CALLBACK (ev_previewer_window_action_page_activated),
                          window);
        gtk_action_group_add_action (window->action_group, action);
        g_object_unref (action);
 
+       window->accels_group = gtk_action_group_new ("PreviewerAccelerators");
+       gtk_action_group_add_actions (window->accels_group, accel_entries,
+                                     G_N_ELEMENTS (accel_entries),
+                                     window);
+       gtk_action_group_set_sensitive (window->accels_group, FALSE);
+
        window->ui_manager = gtk_ui_manager_new ();
        gtk_ui_manager_insert_action_group (window->ui_manager,
                                            window->action_group, 0);
+       gtk_ui_manager_insert_action_group (window->ui_manager,
+                                           window->accels_group, 1);
        gtk_window_add_accel_group (GTK_WINDOW (window),
                                    gtk_ui_manager_get_accel_group (window->ui_manager));
        datadir = data_dir ();
@@ -425,75 +589,72 @@ ev_previewer_window_init (EvPreviewerWindow *window)
        g_free (ui_path);
        g_free (datadir);
 
+       /* GTKUIManager connects actions accels only for menu items,
+        * but not for tool items. See bug #612972.
+        */
+       ev_previewer_window_connect_action_accelerators (window);
+
+       view_sizing_mode_changed (window->model, NULL, window);
+
        vbox = gtk_vbox_new (FALSE, 0);
 
        toolbar = gtk_ui_manager_get_widget (window->ui_manager, "/PreviewToolbar");
        gtk_box_pack_start (GTK_BOX (vbox), toolbar, FALSE, FALSE, 0);
        gtk_widget_show (toolbar);
-               
+
        window->swindow = gtk_scrolled_window_new (NULL, NULL);
        gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (window->swindow),
                                        GTK_POLICY_AUTOMATIC,
                                        GTK_POLICY_AUTOMATIC);
-       
-       window->view = EV_VIEW (ev_view_new ());
-       g_signal_connect (window->view, "notify::sizing-mode",
-                         G_CALLBACK (view_sizing_mode_changed),
-                         window);
 
-       ev_view_set_screen_dpi (window->view, get_screen_dpi (GTK_WINDOW (window)));
-       ev_view_set_continuous (window->view, FALSE);
-       ev_view_set_sizing_mode (window->view, EV_SIZING_FIT_WIDTH);
+       window->view = EV_VIEW (ev_view_new ());
+       g_signal_connect_object (window->view, "focus_in_event",
+                                G_CALLBACK (view_focus_changed),
+                                window, 0);
+       g_signal_connect_object (window->view, "focus_out_event",
+                                G_CALLBACK (view_focus_changed),
+                                window, 0);
+       ev_view_set_model (window->view, window->model);
+       ev_document_model_set_continuous (window->model, FALSE);
        ev_view_set_loading (window->view, TRUE);
-       view_sizing_mode_changed (window->view, NULL, window);
 
        gtk_container_add (GTK_CONTAINER (window->swindow), GTK_WIDGET (window->view));
        gtk_widget_show (GTK_WIDGET (window->view));
 
        gtk_box_pack_start (GTK_BOX (vbox), window->swindow, TRUE, TRUE, 0);
        gtk_widget_show (window->swindow);
-       
+
        gtk_container_add (GTK_CONTAINER (window), vbox);
        gtk_widget_show (vbox);
+
+       return object;
 }
 
+
 static void
 ev_previewer_window_class_init (EvPreviewerWindowClass *klass)
 {
        GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 
+       gobject_class->constructor = ev_previewer_window_constructor;
+       gobject_class->set_property = ev_previewer_window_set_property;
        gobject_class->dispose = ev_previewer_window_dispose;
+
+       g_object_class_install_property (gobject_class,
+                                        PROP_MODEL,
+                                        g_param_spec_object ("model",
+                                                             "Model",
+                                                             "The document model",
+                                                             EV_TYPE_DOCUMENT_MODEL,
+                                                             G_PARAM_WRITABLE |
+                                                             G_PARAM_CONSTRUCT_ONLY));
 }
 
 /* Public methods */
 GtkWidget *
-ev_previewer_window_new (void)
+ev_previewer_window_new (EvDocumentModel *model)
 {
-       return GTK_WIDGET (g_object_new (EV_TYPE_PREVIEWER_WINDOW, NULL));
-}
-
-void
-ev_previewer_window_set_document (EvPreviewerWindow *window,
-                                 EvDocument        *document)
-{
-       GtkAction *action;
-       
-       g_return_if_fail (EV_IS_PREVIEWER_WINDOW (window));
-       g_return_if_fail (EV_IS_DOCUMENT (document));
-       
-       if (window->document)
-               return;
-
-       action = gtk_action_group_get_action (window->action_group, "PageSelector");
-       ev_page_action_set_document (EV_PAGE_ACTION (action), document);
-       gtk_action_group_set_sensitive (window->action_group, TRUE);
-       
-       window->document = g_object_ref (document);
-       ev_view_set_document (window->view, document);
-       ev_view_set_zoom (window->view,
-                         get_screen_dpi (GTK_WINDOW (window)) / 72.0,
-                         FALSE);
-       ev_view_set_loading (window->view, FALSE);
+       return GTK_WIDGET (g_object_new (EV_TYPE_PREVIEWER_WINDOW, "model", model, NULL));
 }
 
 void