X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;f=previewer%2Fev-previewer-window.c;h=67c17086597ae5e2459bcd1c98d3fd7e9e027430;hb=1d0de30170119eade2a7305ffa8ec6d9a3e4af32;hp=686fb0d38ddd4b726f9a5f5c7be1ec1dc3f1aaa0;hpb=a6fd45551db35e90ad13c0c483854740aefa312f;p=evince.git diff --git a/previewer/ev-previewer-window.c b/previewer/ev-previewer-window.c index 686fb0d3..67c17086 100644 --- a/previewer/ev-previewer-window.c +++ b/previewer/ev-previewer-window.c @@ -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 @@ -32,9 +32,11 @@ struct _EvPreviewerWindow { GtkWindow base_instance; + EvDocumentModel *model; EvDocument *document; GtkActionGroup *action_group; + GtkActionGroup *accels_group; GtkUIManager *ui_manager; GtkWidget *swindow; @@ -55,56 +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; -} - -static void -ev_previewer_window_set_view_size (EvPreviewerWindow *window) -{ - gint width, height; - GtkRequisition vsb_requisition; - GtkRequisition hsb_requisition; - gint scrollbar_spacing; - - if (!window->view) - return; - - /* Calculate the width available for the content */ - width = window->swindow->allocation.width; - height = window->swindow->allocation.height; - - if (gtk_scrolled_window_get_shadow_type (GTK_SCROLLED_WINDOW (window->swindow)) == GTK_SHADOW_IN) { - width -= 2 * GTK_WIDGET (window->view)->style->xthickness; - height -= 2 * GTK_WIDGET (window->view)->style->ythickness; - } - gtk_widget_size_request (GTK_SCROLLED_WINDOW (window->swindow)->vscrollbar, - &vsb_requisition); - gtk_widget_size_request (GTK_SCROLLED_WINDOW (window->swindow)->hscrollbar, - &hsb_requisition); - gtk_widget_style_get (window->swindow, - "scrollbar_spacing", - &scrollbar_spacing, - NULL); - - ev_view_set_zoom_for_size (window->view, - MAX (1, width), - MAX (1, height), - vsb_requisition.width + scrollbar_spacing, - hsb_requisition.height + scrollbar_spacing); + screen = gtk_window_get_screen (GTK_WINDOW (window)); + return ev_document_misc_get_screen_dpi (screen); } #if GTKUNIXPRINT_ENABLED @@ -127,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) @@ -145,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); } @@ -153,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); } @@ -161,24 +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); - ev_previewer_window_set_view_size (window); - } 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); - ev_previewer_window_set_view_size (window); - } 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 @@ -190,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, @@ -283,6 +278,9 @@ ev_previewer_window_print (GtkAction *action, #endif static const GtkActionEntry action_entries[] = { + { "FileCloseWindow", GTK_STOCK_CLOSE, NULL, "W", + NULL, + G_CALLBACK (ev_previewer_window_close) }, { "GoPreviousPage", GTK_STOCK_GO_UP, N_("_Previous Page"), "Page_Up", N_("Go to the previous page"), G_CALLBACK (ev_previewer_window_previous_page) }, @@ -302,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, "", "space", NULL, + G_CALLBACK (ev_previewer_window_scroll_backward) }, + { "BackSpace", NULL, "", "BackSpace", NULL, + G_CALLBACK (ev_previewer_window_scroll_backward) }, + { "ShiftBackSpace", NULL, "", "BackSpace", NULL, + G_CALLBACK (ev_previewer_window_scroll_forward) }, + { "Return", NULL, "", "Return", NULL, + G_CALLBACK (ev_previewer_window_scroll_forward) }, + { "ShiftReturn", NULL, "", "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, "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, "KP_Add", NULL, + G_CALLBACK (ev_previewer_window_zoom_in) }, + { "CtrlKpMinus", GTK_STOCK_ZOOM_OUT, NULL, "KP_Subtract", NULL, + G_CALLBACK (ev_previewer_window_zoom_out) }, + { "FocusPageSelector", NULL, "", "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"), @@ -311,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), @@ -348,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; @@ -363,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; @@ -418,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, @@ -443,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 (); @@ -463,78 +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); - g_signal_connect_swapped (window->view, "zoom_invalid", - G_CALLBACK (ev_previewer_window_set_view_size), - 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); + 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