X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;f=shell%2Fev-window.c;h=5acc5422bd41b0842f7849b06849925209a8e64a;hb=efec6a4b614de84b8639977f278159aa28c38994;hp=aad7dee7413a0f1f78681f3ebd61b23cf2810b55;hpb=71cc5e5d293c22041da7dcc0abd465005975851e;p=evince.git diff --git a/shell/ev-window.c b/shell/ev-window.c index aad7dee7..5acc5422 100644 --- a/shell/ev-window.c +++ b/shell/ev-window.c @@ -51,6 +51,7 @@ #include "ephy-zoom.h" #include "ev-application.h" +#include "ev-dualscreen.h" #include "ev-document-factory.h" #include "ev-document-find.h" #include "ev-document-fonts.h" @@ -75,6 +76,7 @@ #include "ev-properties-dialog.h" #include "ev-sidebar-annotations.h" #include "ev-sidebar-attachments.h" +#include "ev-sidebar-bookmarks.h" #include "ev-sidebar.h" #include "ev-sidebar-links.h" #include "ev-sidebar-page.h" @@ -91,6 +93,8 @@ #include "ev-print-operation.h" #include "ev-progress-message-area.h" #include "ev-annotation-properties-dialog.h" +#include "ev-bookmarks.h" +#include "ev-bookmark-action.h" #ifdef ENABLE_DBUS #include "ev-media-player-keys.h" @@ -138,6 +142,7 @@ struct _EvWindowPrivate { GtkWidget *sidebar_attachments; GtkWidget *sidebar_layers; GtkWidget *sidebar_annots; + GtkWidget *sidebar_bookmarks; /* Settings */ GSettings *settings; @@ -163,6 +168,8 @@ struct _EvWindowPrivate { GtkRecentManager *recent_manager; GtkActionGroup *recent_action_group; guint recent_ui_id; + GtkActionGroup *bookmarks_action_group; + guint bookmarks_ui_id; GtkUIManager *ui_manager; /* Fullscreen mode */ @@ -192,6 +199,7 @@ struct _EvWindowPrivate { EvWindowPageMode page_mode; EvWindowTitle *title; EvMetadata *metadata; + EvBookmarks *bookmarks; gboolean is_new_doc; /* Load params */ @@ -246,6 +254,7 @@ struct _EvWindowPrivate { #define ATTACHMENTS_SIDEBAR_ID "attachments" #define LAYERS_SIDEBAR_ID "layers" #define ANNOTS_SIDEBAR_ID "annotations" +#define BOOKMARKS_SIDEBAR_ID "bookmarks" #define EV_PRINT_SETTINGS_FILE "print-settings" #define EV_PRINT_SETTINGS_GROUP "Print Settings" @@ -301,9 +310,6 @@ static void ev_window_stop_fullscreen (EvWindow *windo gboolean unfullscreen_window); static void ev_window_cmd_view_fullscreen (GtkAction *action, EvWindow *window); -static void ev_window_run_presentation (EvWindow *window); -static void ev_window_stop_presentation (EvWindow *window, - gboolean unfullscreen_window); static void ev_window_cmd_view_presentation (GtkAction *action, EvWindow *window); static void ev_view_popup_cmd_open_link (GtkAction *action, @@ -335,6 +341,8 @@ static void ev_window_cmd_edit_find (GtkAction *actio static void find_bar_search_changed_cb (EggFindBar *find_bar, GParamSpec *param, EvWindow *ev_window); +static void view_external_link_cb (EvWindow *window, + EvLinkAction *action); static void ev_window_load_file_remote (EvWindow *ev_window, GFile *source_file); static void ev_window_media_player_key_pressed (EvWindow *window, @@ -343,7 +351,9 @@ static void ev_window_media_player_key_pressed (EvWindow *windo static void ev_window_update_max_min_scale (EvWindow *window); #ifdef ENABLE_DBUS static void ev_window_emit_closed (EvWindow *window); +static void ev_window_emit_doc_loaded (EvWindow *window); #endif +static void ev_window_setup_bookmarks (EvWindow *window); static guint ev_window_n_copies = 0; @@ -358,6 +368,12 @@ get_screen_dpi (EvWindow *window) return ev_document_misc_get_screen_dpi (screen); } +static gboolean +ev_window_is_editing_toolbar (EvWindow *ev_window) +{ + return egg_editable_toolbar_get_edit_mode (EGG_EDITABLE_TOOLBAR (ev_window->priv->toolbar)); +} + static void ev_window_set_action_sensitive (EvWindow *ev_window, const char *name, @@ -430,6 +446,7 @@ ev_window_setup_action_sensitivity (EvWindow *ev_window) ev_window_set_action_sensitive (ev_window, "FileSaveAs", has_document && ok_to_copy); ev_window_set_action_sensitive (ev_window, "FilePrint", has_pages && ok_to_print); ev_window_set_action_sensitive (ev_window, "FileProperties", has_document && has_properties); + ev_window_set_action_sensitive (ev_window, "FileOpenContainingFolder", has_document); /* Edit menu */ ev_window_set_action_sensitive (ev_window, "EditSelectAll", has_pages && can_get_text); @@ -439,6 +456,7 @@ ev_window_setup_action_sensitivity (EvWindow *ev_window) ev_window_set_action_sensitive (ev_window, "EditRotateRight", has_pages); /* View menu */ + ev_window_set_action_sensitive (ev_window, "ViewToolbar", !ev_window_is_editing_toolbar (ev_window)); ev_window_set_action_sensitive (ev_window, "ViewContinuous", has_pages); ev_window_set_action_sensitive (ev_window, "ViewDual", has_pages); ev_window_set_action_sensitive (ev_window, "ViewBestFit", has_pages); @@ -447,6 +465,10 @@ ev_window_setup_action_sensitivity (EvWindow *ev_window) ev_window_set_action_sensitive (ev_window, "ViewAutoscroll", has_pages); ev_window_set_action_sensitive (ev_window, "ViewInvertedColors", has_pages); + /* Bookmarks menu */ + ev_window_set_action_sensitive (ev_window, "BookmarksAdd", + has_pages && ev_window->priv->bookmarks); + /* Toolbar-specific actions: */ ev_window_set_action_sensitive (ev_window, PAGE_SELECTOR_ACTION, has_pages); ev_window_set_action_sensitive (ev_window, ZOOM_CONTROL_ACTION, has_pages); @@ -783,18 +805,17 @@ ev_window_warning_message (EvWindow *window, ev_window_set_message_area (window, area); } -typedef struct _FindTask { +typedef struct _PageTitleData { const gchar *page_label; - gchar *chapter; -} FindTask; + gchar *page_title; +} PageTitleData; static gboolean -ev_window_find_chapter (GtkTreeModel *tree_model, - GtkTreePath *path, - GtkTreeIter *iter, - gpointer data) +ev_window_find_page_title (GtkTreeModel *tree_model, + GtkTreePath *path, + GtkTreeIter *iter, + PageTitleData *data) { - FindTask *task = (FindTask *)data; gchar *page_string; gtk_tree_model_get (tree_model, iter, @@ -804,9 +825,9 @@ ev_window_find_chapter (GtkTreeModel *tree_model, if (!page_string) return FALSE; - if (!strcmp (page_string, task->page_label)) { + if (!strcmp (page_string, data->page_label)) { gtk_tree_model_get (tree_model, iter, - EV_DOCUMENT_LINKS_COLUMN_MARKUP, &task->chapter, + EV_DOCUMENT_LINKS_COLUMN_MARKUP, &data->page_title, -1); g_free (page_string); return TRUE; @@ -816,12 +837,41 @@ ev_window_find_chapter (GtkTreeModel *tree_model, return FALSE; } +static gchar * +ev_window_get_page_title (EvWindow *window, + const gchar *page_label) +{ + if (EV_IS_DOCUMENT_LINKS (window->priv->document) && + ev_document_links_has_document_links (EV_DOCUMENT_LINKS (window->priv->document))) { + PageTitleData data; + GtkTreeModel *model; + + data.page_label = page_label; + data.page_title = NULL; + + g_object_get (G_OBJECT (window->priv->sidebar_links), + "model", &model, + NULL); + if (model) { + gtk_tree_model_foreach (model, + (GtkTreeModelForeachFunc)ev_window_find_page_title, + &data); + + g_object_unref (model); + } + + return data.page_title; + } + + return NULL; +} + static void ev_window_add_history (EvWindow *window, gint page, EvLink *link) { gchar *page_label = NULL; + gchar *page_title; gchar *link_title; - FindTask find_task; EvLink *real_link; EvLinkAction *action; EvLinkDest *dest; @@ -844,34 +894,19 @@ ev_window_add_history (EvWindow *window, gint page, EvLink *link) if (!page_label) return; - - find_task.page_label = page_label; - find_task.chapter = NULL; - - if (ev_document_links_has_document_links (EV_DOCUMENT_LINKS (window->priv->document))) { - GtkTreeModel *model; - - g_object_get (G_OBJECT (window->priv->sidebar_links), "model", &model, NULL); - - if (model) { - gtk_tree_model_foreach (model, - ev_window_find_chapter, - &find_task); - - g_object_unref (model); - } - } - if (find_task.chapter) - link_title = g_strdup_printf (_("Page %s — %s"), page_label, find_task.chapter); - else + page_title = ev_window_get_page_title (window, page_label); + if (page_title) { + link_title = g_strdup_printf (_("Page %s — %s"), page_label, page_title); + g_free (page_title); + } else { link_title = g_strdup_printf (_("Page %s"), page_label); - + } + real_link = ev_link_new (link_title, action); ev_history_add_link (window->priv->history, real_link); - g_free (find_task.chapter); g_free (link_title); g_free (page_label); g_object_unref (real_link); @@ -894,6 +929,13 @@ view_selection_changed_cb (EvView *view, ev_view_get_has_selection (view)); } +static void +view_layers_changed_cb (EvView *view, + EvWindow *window) +{ + ev_sidebar_layers_update_layers_state (EV_SIDEBAR_LAYERS (window->priv->sidebar_layers)); +} + static void ev_window_page_changed_cb (EvWindow *ev_window, gint old_page, @@ -933,6 +975,8 @@ ev_window_sidebar_get_current_page_id (EvWindow *ev_window) id = LAYERS_SIDEBAR_ID; } else if (current_page == ev_window->priv->sidebar_annots) { id = ANNOTS_SIDEBAR_ID; + } else if (current_page == ev_window->priv->sidebar_bookmarks) { + id = BOOKMARKS_SIDEBAR_ID; } else { g_assert_not_reached(); } @@ -953,6 +997,7 @@ ev_window_sidebar_set_current_page (EvWindow *window, GtkWidget *attachments = window->priv->sidebar_attachments; GtkWidget *annots = window->priv->sidebar_annots; GtkWidget *layers = window->priv->sidebar_layers; + GtkWidget *bookmarks = window->priv->sidebar_bookmarks; if (strcmp (page_id, LINKS_SIDEBAR_ID) == 0 && ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (links), document)) { @@ -969,6 +1014,9 @@ ev_window_sidebar_set_current_page (EvWindow *window, } else if (strcmp (page_id, ANNOTS_SIDEBAR_ID) == 0 && ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (annots), document)) { ev_sidebar_set_page (sidebar, annots); + } else if (strcmp (page_id, BOOKMARKS_SIDEBAR_ID) == 0 && + ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (bookmarks), document)) { + ev_sidebar_set_page (sidebar, bookmarks); } } @@ -1424,8 +1472,15 @@ ev_window_set_document (EvWindow *ev_window, EvDocument *document) } if (EV_WINDOW_IS_PRESENTATION (ev_window)) { + gint current_page; + + current_page = ev_view_presentation_get_current_page ( + EV_VIEW_PRESENTATION (ev_window->priv->presentation_view)); gtk_widget_destroy (ev_window->priv->presentation_view); ev_window->priv->presentation_view = NULL; + + /* Update the model with the current presentation page */ + ev_document_model_set_page (ev_window->priv->model, current_page); ev_window_run_presentation (ev_window); } @@ -1529,6 +1584,9 @@ ev_window_load_job_cb (EvJob *job, if (!ev_job_is_failed (job)) { ev_document_model_set_document (ev_window->priv->model, document); +#ifdef ENABLE_DBUS + ev_window_emit_doc_loaded (ev_window); +#endif setup_chrome_from_metadata (ev_window); update_chrome_actions (ev_window); setup_document_from_metadata (ev_window); @@ -1997,6 +2055,8 @@ ev_window_open_uri (EvWindow *ev_window, if (ev_window->priv->metadata) g_object_unref (ev_window->priv->metadata); + if (ev_window->priv->bookmarks) + g_object_unref (ev_window->priv->bookmarks); source_file = g_file_new_for_uri (uri); if (!ev_file_is_temp (source_file) && ev_is_metadata_supported_for_file (source_file)) { @@ -2006,6 +2066,17 @@ ev_window_open_uri (EvWindow *ev_window, ev_window->priv->metadata = NULL; } + if (ev_window->priv->metadata) { + ev_window->priv->bookmarks = ev_bookmarks_new (ev_window->priv->metadata); + ev_sidebar_bookmarks_set_bookmarks (EV_SIDEBAR_BOOKMARKS (ev_window->priv->sidebar_bookmarks), + ev_window->priv->bookmarks); + g_signal_connect_swapped (ev_window->priv->bookmarks, "changed", + G_CALLBACK (ev_window_setup_bookmarks), + ev_window); + } else { + ev_window->priv->bookmarks = NULL; + } + if (ev_window->priv->search_string) g_free (ev_window->priv->search_string); ev_window->priv->search_string = search_string ? @@ -2017,6 +2088,7 @@ ev_window_open_uri (EvWindow *ev_window, setup_size_from_metadata (ev_window); setup_model_from_metadata (ev_window); + ev_window_setup_bookmarks (ev_window); ev_window->priv->load_job = ev_job_load_new (uri); g_signal_connect (ev_window->priv->load_job, @@ -3787,22 +3859,19 @@ fullscreen_toolbar_setup_item_properties (GtkUIManager *ui_manager) static void fullscreen_toolbar_remove_shadow (GtkWidget *toolbar) { - static gboolean done = FALSE; + GtkCssProvider *provider; - if (!done) { - gtk_rc_parse_string ( - "\n" - " style \"fullscreen-toolbar-style\"\n" - " {\n" - " GtkToolbar::shadow-type=GTK_SHADOW_NONE\n" - " }\n" - "\n" - " widget \"*.fullscreen-toolbar\" style \"fullscreen-toolbar-style\"\n" - "\n"); - done = TRUE; - } - - gtk_widget_set_name (toolbar, "fullscreen-toolbar"); + gtk_widget_set_name (toolbar, "ev-fullscreen-toolbar"); + + provider = gtk_css_provider_new (); + gtk_css_provider_load_from_data (provider, + "#ev-fullscreen-toolbar {\n" + " -GtkToolbar-shadow-type: none; }", + -1, NULL); + gtk_style_context_add_provider (gtk_widget_get_style_context (toolbar), + GTK_STYLE_PROVIDER (provider), + GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); + g_object_unref (provider); } static void @@ -3912,7 +3981,23 @@ ev_window_view_presentation_finished (EvWindow *window) ev_window_stop_presentation (window, TRUE); } -static void +static gboolean +ev_window_view_presentation_focus_in (EvWindow *window) +{ + ev_application_screensaver_disable (EV_APP); + + return FALSE; +} + +static gboolean +ev_window_view_presentation_focus_out (EvWindow *window) +{ + ev_application_screensaver_enable (EV_APP); + + return FALSE; +} + +void ev_window_run_presentation (EvWindow *window) { gboolean fullscreen_window = TRUE; @@ -3935,9 +4020,19 @@ ev_window_run_presentation (EvWindow *window) current_page, rotation, inverted_colors); + g_signal_connect_swapped (window->priv->presentation_view, "finished", G_CALLBACK (ev_window_view_presentation_finished), window); + g_signal_connect_swapped (window->priv->presentation_view, "external-link", + G_CALLBACK (view_external_link_cb), + window); + g_signal_connect_swapped (window->priv->presentation_view, "focus-in-event", + G_CALLBACK (ev_window_view_presentation_focus_in), + window); + g_signal_connect_swapped (window->priv->presentation_view, "focus-out-event", + G_CALLBACK (ev_window_view_presentation_focus_out), + window); gtk_box_pack_start (GTK_BOX (window->priv->main_box), window->priv->presentation_view, @@ -3957,19 +4052,30 @@ ev_window_run_presentation (EvWindow *window) if (window->priv->metadata && !ev_window_is_empty (window)) ev_metadata_set_boolean (window->priv->metadata, "presentation", TRUE); + //if ( get_num_monitors(GTK_WINDOW(window)) > 1) { + + EvDSCWindow *control = ev_dscwindow_get_control(); + ev_dscwindow_set_presentation (control, window, + window->priv->document, + EV_VIEW_PRESENTATION(window->priv->presentation_view)); + gtk_window_present (GTK_WINDOW (control)); + //} } -static void +void ev_window_stop_presentation (EvWindow *window, gboolean unfullscreen_window) { guint current_page; + guint rotation; if (!EV_WINDOW_IS_PRESENTATION (window)) return; current_page = ev_view_presentation_get_current_page (EV_VIEW_PRESENTATION (window->priv->presentation_view)); ev_document_model_set_page (window->priv->model, current_page); + rotation = ev_view_presentation_get_rotation (EV_VIEW_PRESENTATION (window->priv->presentation_view)); + ev_document_model_set_rotation (window->priv->model, rotation); gtk_container_remove (GTK_CONTAINER (window->priv->main_box), window->priv->presentation_view); @@ -4141,17 +4247,33 @@ ev_window_set_page_mode (EvWindow *window, static void ev_window_cmd_edit_rotate_left (GtkAction *action, EvWindow *ev_window) { - gint rotation = ev_document_model_get_rotation (ev_window->priv->model); + gint rotation; - ev_document_model_set_rotation (ev_window->priv->model, rotation - 90); + if (EV_WINDOW_IS_PRESENTATION (ev_window)) { + rotation = ev_view_presentation_get_rotation (EV_VIEW_PRESENTATION (ev_window->priv->presentation_view)); + ev_view_presentation_set_rotation (EV_VIEW_PRESENTATION (ev_window->priv->presentation_view), + rotation - 90); + } else { + rotation = ev_document_model_get_rotation (ev_window->priv->model); + + ev_document_model_set_rotation (ev_window->priv->model, rotation - 90); + } } static void ev_window_cmd_edit_rotate_right (GtkAction *action, EvWindow *ev_window) { - gint rotation = ev_document_model_get_rotation (ev_window->priv->model); + gint rotation; + + if (EV_WINDOW_IS_PRESENTATION (ev_window)) { + rotation = ev_view_presentation_get_rotation (EV_VIEW_PRESENTATION (ev_window->priv->presentation_view)); + ev_view_presentation_set_rotation (EV_VIEW_PRESENTATION (ev_window->priv->presentation_view), + rotation + 90); + } else { + rotation = ev_document_model_get_rotation (ev_window->priv->model); - ev_document_model_set_rotation (ev_window->priv->model, rotation + 90); + ev_document_model_set_rotation (ev_window->priv->model, rotation + 90); + } } static void @@ -4172,6 +4294,7 @@ ev_window_cmd_edit_toolbar_cb (GtkDialog *dialog, toolbar = EGG_EDITABLE_TOOLBAR (ev_window->priv->toolbar); egg_editable_toolbar_set_edit_mode (toolbar, FALSE); + ev_window_set_action_sensitive (ev_window, "ViewToolbar", TRUE); toolbars_file = g_build_filename (ev_application_get_dot_dir (EV_APP, TRUE), "evince_toolbar.xml", NULL); @@ -4200,7 +4323,6 @@ ev_window_cmd_edit_toolbar (GtkAction *action, EvWindow *ev_window) gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CLOSE); gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)), 5); gtk_box_set_spacing (GTK_BOX (content_area), 2); - gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); gtk_window_set_default_size (GTK_WINDOW (dialog), 500, 400); toolbar = EGG_EDITABLE_TOOLBAR (ev_window->priv->toolbar); @@ -4210,9 +4332,10 @@ ev_window_cmd_edit_toolbar (GtkAction *action, EvWindow *ev_window) gtk_container_set_border_width (GTK_CONTAINER (editor), 5); gtk_box_set_spacing (GTK_BOX (EGG_TOOLBAR_EDITOR (editor)), 5); - gtk_container_add (GTK_CONTAINER (content_area), editor); + gtk_box_pack_start (GTK_BOX (content_area), editor, TRUE, TRUE, 0); egg_editable_toolbar_set_edit_mode (toolbar, TRUE); + ev_window_set_action_sensitive (ev_window, "ViewToolbar", FALSE); g_signal_connect (dialog, "response", G_CALLBACK (ev_window_cmd_edit_toolbar_cb), @@ -4328,6 +4451,92 @@ ev_window_cmd_go_backward (GtkAction *action, EvWindow *ev_window) } } +static void +ev_window_cmd_bookmark_activate (GtkAction *action, + EvWindow *window) +{ + guint page = ev_bookmark_action_get_page (EV_BOOKMARK_ACTION (action)); + + ev_document_model_set_page (window->priv->model, page); +} + +static gint +compare_bookmarks (EvBookmark *a, + EvBookmark *b) +{ + return strcmp (a->title, b->title); +} + +static void +ev_window_setup_bookmarks (EvWindow *window) +{ + GList *items, *l; + + if (!window->priv->bookmarks) + return; + + if (window->priv->bookmarks_ui_id > 0) { + gtk_ui_manager_remove_ui (window->priv->ui_manager, + window->priv->bookmarks_ui_id); + gtk_ui_manager_ensure_update (window->priv->ui_manager); + } + window->priv->bookmarks_ui_id = gtk_ui_manager_new_merge_id (window->priv->ui_manager); + + if (window->priv->bookmarks_action_group) { + gtk_ui_manager_remove_action_group (window->priv->ui_manager, + window->priv->bookmarks_action_group); + g_object_unref (window->priv->bookmarks_action_group); + } + window->priv->bookmarks_action_group = gtk_action_group_new ("BookmarksActions"); + gtk_ui_manager_insert_action_group (window->priv->ui_manager, + window->priv->bookmarks_action_group, -1); + + items = ev_bookmarks_get_bookmarks (window->priv->bookmarks); + items = g_list_sort (items, (GCompareFunc)compare_bookmarks); + + for (l = items; l && l->data; l = g_list_next (l)) { + EvBookmark *bm = (EvBookmark *)l->data; + GtkAction *action; + + action = ev_bookmark_action_new (bm); + g_signal_connect (action, "activate", + G_CALLBACK (ev_window_cmd_bookmark_activate), + window); + gtk_action_group_add_action (window->priv->bookmarks_action_group, + action); + + gtk_ui_manager_add_ui (window->priv->ui_manager, + window->priv->bookmarks_ui_id, + "/MainMenu/BookmarksMenu/BookmarksItems", + gtk_action_get_label (action), + gtk_action_get_name (action), + GTK_UI_MANAGER_MENUITEM, + FALSE); + + g_object_unref (action); + } + + g_list_free (items); +} + +static void +ev_window_cmd_bookmarks_add (GtkAction *action, + EvWindow *window) +{ + EvBookmark bm; + gchar *page_label; + gchar *page_title; + + bm.page = ev_document_model_get_page (window->priv->model); + page_label = ev_document_get_page_label (window->priv->document, bm.page); + page_title = ev_window_get_page_title (window, page_label); + bm.title = page_title ? page_title : g_strdup_printf (_("Page %s"), page_label); + g_free (page_label); + + /* EvBookmarks takes ownership of bookmark */ + ev_bookmarks_add (window->priv->bookmarks, &bm); +} + static void ev_window_cmd_view_reload (GtkAction *action, EvWindow *ev_window) { @@ -4596,6 +4805,8 @@ ev_window_cmd_help_about (GtkAction *action, EvWindow *ev_window) const char *documenters[] = { "Nickolay V. Shmyrev ", + "Phil Bull ", + "Tiffany Antpolski ", NULL }; @@ -4636,7 +4847,7 @@ ev_window_cmd_help_about (GtkAction *action, EvWindow *ev_window) "name", _("Evince"), "version", VERSION, "copyright", - _("© 1996–2009 The Evince authors"), + _("© 1996–2010 The Evince authors"), "license", license_trans, "website", "http://www.gnome.org/projects/evince", "comments", comments, @@ -4703,6 +4914,8 @@ ev_window_sidebar_visibility_changed_cb (EvSidebar *ev_sidebar, if (ev_window->priv->metadata) ev_metadata_set_boolean (ev_window->priv->metadata, "sidebar_visibility", visible); + if (!visible) + gtk_widget_grab_focus (ev_window->priv->view); } } @@ -4990,30 +5203,23 @@ find_bar_close_cb (EggFindBar *find_bar, } static void -find_bar_search_changed_cb (EggFindBar *find_bar, - GParamSpec *param, - EvWindow *ev_window) +ev_window_search_start (EvWindow *ev_window) { - gboolean case_sensitive; + EggFindBar *find_bar = EGG_FIND_BAR (ev_window->priv->find_bar); const char *search_string; if (!ev_window->priv->document || !EV_IS_DOCUMENT_FIND (ev_window->priv->document)) return; - - /* Either the string or case sensitivity could have changed. */ - case_sensitive = egg_find_bar_get_case_sensitive (find_bar); - search_string = egg_find_bar_get_search_string (find_bar); - ev_view_find_search_changed (EV_VIEW (ev_window->priv->view)); + search_string = egg_find_bar_get_search_string (find_bar); ev_window_clear_find_job (ev_window); - if (search_string && search_string[0]) { ev_window->priv->find_job = ev_job_find_new (ev_window->priv->document, ev_document_model_get_page (ev_window->priv->model), ev_document_get_n_pages (ev_window->priv->document), search_string, - case_sensitive); + egg_find_bar_get_case_sensitive (find_bar)); g_signal_connect (ev_window->priv->find_job, "finished", G_CALLBACK (ev_window_find_job_finished_cb), ev_window); @@ -5023,12 +5229,21 @@ find_bar_search_changed_cb (EggFindBar *find_bar, ev_job_scheduler_push_job (ev_window->priv->find_job, EV_JOB_PRIORITY_NONE); } else { ev_window_update_actions (ev_window); - egg_find_bar_set_status_text (EGG_FIND_BAR (ev_window->priv->find_bar), - NULL); + egg_find_bar_set_status_text (find_bar, NULL); gtk_widget_queue_draw (GTK_WIDGET (ev_window->priv->view)); } } +static void +find_bar_search_changed_cb (EggFindBar *find_bar, + GParamSpec *param, + EvWindow *ev_window) +{ + /* Either the string or case sensitivity could have changed. */ + ev_view_find_search_changed (EV_VIEW (ev_window->priv->view)); + ev_window_search_start (ev_window); +} + static void find_bar_visibility_changed_cb (EggFindBar *find_bar, GParamSpec *param, @@ -5041,11 +5256,10 @@ find_bar_visibility_changed_cb (EggFindBar *find_bar, if (ev_window->priv->document && EV_IS_DOCUMENT_FIND (ev_window->priv->document)) { ev_view_find_set_highlight_search (EV_VIEW (ev_window->priv->view), visible); - ev_view_find_search_changed (EV_VIEW (ev_window->priv->view)); ev_window_update_actions (ev_window); if (visible) - find_bar_search_changed_cb (find_bar, NULL, ev_window); + ev_window_search_start (ev_window); else egg_find_bar_set_status_text (EGG_FIND_BAR (ev_window->priv->find_bar), NULL); } @@ -5162,6 +5376,11 @@ ev_window_dispose (GObject *object) } #endif /* ENABLE_DBUS */ + if (priv->bookmarks) { + g_object_unref (priv->bookmarks); + priv->bookmarks = NULL; + } + if (priv->metadata) { g_object_unref (priv->metadata); priv->metadata = NULL; @@ -5207,6 +5426,11 @@ ev_window_dispose (GObject *object) priv->recent_action_group = NULL; } + if (priv->bookmarks_action_group) { + g_object_unref (priv->bookmarks_action_group); + priv->bookmarks_action_group = NULL; + } + if (priv->recent_manager) { g_signal_handlers_disconnect_by_func (priv->recent_manager, ev_window_setup_recent, @@ -5436,6 +5660,7 @@ static const GtkActionEntry entries[] = { { "Edit", NULL, N_("_Edit") }, { "View", NULL, N_("_View") }, { "Go", NULL, N_("_Go") }, + { "Bookmarks", NULL, N_("_Bookmarks") }, { "Help", NULL, N_("_Help") }, /* File menu */ @@ -5509,6 +5734,11 @@ static const GtkActionEntry entries[] = { N_("Go to the last page"), G_CALLBACK (ev_window_cmd_go_last_page) }, + /* Bookmarks menu */ + { "BookmarksAdd", GTK_STOCK_ADD, N_("_Add Bookmark"), "D", + N_("Add a bookmark for the current page"), + G_CALLBACK (ev_window_cmd_bookmarks_add) }, + /* Help menu */ { "HelpContents", GTK_STOCK_HELP, N_("_Contents"), "F1", NULL, G_CALLBACK (ev_window_cmd_help_contents) }, @@ -5696,6 +5926,13 @@ sidebar_annots_annot_add_cancelled (EvSidebarAnnotations *sidebar_annots, ev_view_cancel_add_annotation (EV_VIEW (window->priv->view)); } +static void +sidebar_bookmarks_add_bookmark (EvSidebarBookmarks *sidebar_bookmarks, + EvWindow *window) +{ + ev_window_cmd_bookmarks_add (NULL, window); +} + static void register_custom_actions (EvWindow *window, GtkActionGroup *group) { @@ -5823,7 +6060,8 @@ view_actions_focus_in_cb (GtkWidget *widget, GdkEventFocus *event, EvWindow *win #endif /* ENABLE_DBUS */ update_chrome_flag (window, EV_CHROME_RAISE_TOOLBAR, FALSE); - ev_window_set_action_sensitive (window, "ViewToolbar", TRUE); + ev_window_set_action_sensitive (window, "ViewToolbar", + !ev_window_is_editing_toolbar (window)); ev_window_set_view_accels_sensitivity (window, TRUE); @@ -6067,7 +6305,7 @@ do_action_named (EvWindow *window, EvLinkAction *action) } static void -view_external_link_cb (EvView *view, EvLinkAction *action, EvWindow *window) +view_external_link_cb (EvWindow *window, EvLinkAction *action) { switch (ev_link_action_get_action_type (action)) { case EV_LINK_ACTION_TYPE_GOTO_DEST: { @@ -6133,6 +6371,30 @@ ev_view_popup_cmd_copy_link_address (GtkAction *action, EvWindow *window) ev_action); } +static GFile * +create_file_from_uri_for_format (const gchar *uri, + GdkPixbufFormat *format) +{ + GFile *target_file; + gchar **extensions; + gchar *uri_extension; + gint i; + + extensions = gdk_pixbuf_format_get_extensions (format); + for (i = 0; extensions[i]; i++) { + if (g_str_has_suffix (uri, extensions[i])) { + g_strfreev (extensions); + return g_file_new_for_uri (uri); + } + } + + uri_extension = g_strconcat (uri, ".", extensions[0], NULL); + target_file = g_file_new_for_uri (uri_extension); + g_free (uri_extension); + g_strfreev (extensions); + + return target_file; +} static void image_save_dialog_response_cb (GtkWidget *fc, @@ -6144,7 +6406,6 @@ image_save_dialog_response_cb (GtkWidget *fc, GError *error = NULL; GdkPixbuf *pixbuf; gchar *uri; - gchar **extensions; gchar *filename; gchar *file_format; GdkPixbufFormat *format; @@ -6182,19 +6443,9 @@ image_save_dialog_response_cb (GtkWidget *fc, return; } - extensions = gdk_pixbuf_format_get_extensions (format); - if (!g_str_has_suffix (uri, extensions[0])) { - gchar *uri_extension; - - uri_extension = g_strconcat (uri, ".", extensions[0], NULL); - target_file = g_file_new_for_uri (uri_extension); - g_free (uri_extension); - } else { - target_file = g_file_new_for_uri (uri); - } - g_strfreev (extensions); + target_file = create_file_from_uri_for_format (uri, format); g_free (uri); - + is_native = g_file_is_native (target_file); if (is_native) { filename = g_file_get_path (target_file); @@ -6522,9 +6773,15 @@ ev_window_media_player_key_pressed (EvWindow *window, if (strcmp (key, "Play") == 0) { ev_window_run_presentation (window); } else if (strcmp (key, "Previous") == 0) { - ev_window_cmd_go_previous_page (NULL, window); + if (EV_WINDOW_IS_PRESENTATION (window)) + ev_view_presentation_previous_page (EV_VIEW_PRESENTATION (window->priv->presentation_view)); + else + ev_window_cmd_go_previous_page (NULL, window); } else if (strcmp (key, "Next") == 0) { - ev_window_cmd_go_next_page (NULL, window); + if (EV_WINDOW_IS_PRESENTATION (window)) + ev_view_presentation_next_page (EV_VIEW_PRESENTATION (window->priv->presentation_view)); + else + ev_window_cmd_go_next_page (NULL, window); } else if (strcmp (key, "FastForward") == 0) { ev_window_cmd_go_last_page (NULL, window); } else if (strcmp (key, "Rewind") == 0) { @@ -6585,6 +6842,9 @@ ev_window_sync_source (EvWindow *window, { GDBusConnection *connection; GError *error = NULL; + guint32 timestamp; + gchar *uri_input; + GFile *input_gfile; if (window->priv->dbus_object_id <= 0) return; @@ -6593,16 +6853,41 @@ ev_window_sync_source (EvWindow *window, if (!connection) return; + timestamp = gtk_get_current_event_time (); + if (g_path_is_absolute (link->filename)) { + input_gfile = g_file_new_for_path (link->filename); + } else { + GFile *gfile, *parent_gfile; + + gfile = g_file_new_for_uri (window->priv->uri); + parent_gfile = g_file_get_parent (gfile); + + /* parent_gfile should never be NULL */ + if (parent_gfile == NULL) { + g_printerr ("Document URI is '/'\n"); + return; + } + + input_gfile = g_file_get_child (parent_gfile, link->filename); + g_object_unref (parent_gfile); + g_object_unref (gfile); + } + + uri_input = g_file_get_uri (input_gfile); + g_object_unref (input_gfile); + g_dbus_connection_emit_signal (connection, NULL, window->priv->dbus_object_path, EV_WINDOW_DBUS_INTERFACE, "SyncSource", - g_variant_new ("(s(ii))", - link->filename, + g_variant_new ("(s(ii)u)", + uri_input, link->line, - link->col), + link->col, + timestamp), &error); + g_free (uri_input); if (error) { g_printerr ("Failed to emit DBus signal SyncSource: %s\n", error->message); @@ -6645,6 +6930,35 @@ ev_window_emit_closed (EvWindow *window) g_dbus_connection_flush_sync (connection, NULL, NULL); } +static void +ev_window_emit_doc_loaded (EvWindow *window) +{ + GDBusConnection *connection; + GError *error = NULL; + + if (window->priv->dbus_object_id <= 0) + return; + + connection = ev_application_get_dbus_connection (EV_APP); + if (!connection) + return; + + g_dbus_connection_emit_signal (connection, + NULL, + window->priv->dbus_object_path, + EV_WINDOW_DBUS_INTERFACE, + "DocumentLoaded", + g_variant_new("(s)", window->priv->uri), + &error); + if (error) { + g_printerr ("Failed to emit DBus signal DocumentLoaded: %s\n", + error->message); + g_error_free (error); + + return; + } +} + static void method_call_cb (GDBusConnection *connection, const gchar *sender, @@ -6662,10 +6976,11 @@ method_call_cb (GDBusConnection *connection, if (window->priv->document && ev_document_has_synctex (window->priv->document)) { EvSourceLink link; + guint32 timestamp; - g_variant_get (parameters, "(&s(ii))", &link.filename, &link.line, &link.col); + g_variant_get (parameters, "(&s(ii)u)", &link.filename, &link.line, &link.col, ×tamp); ev_view_highlight_forward_search (EV_VIEW (window->priv->view), &link); - gtk_window_present (GTK_WINDOW (window)); + gtk_window_present_with_time (GTK_WINDOW (window), timestamp); } g_dbus_method_invocation_return_value (invocation, g_variant_new ("()")); @@ -6677,12 +6992,17 @@ static const char introspection_xml[] = "" "" "" + "" "" "" "" "" + "" "" "" + "" + "" + "" "" ""; @@ -6835,6 +7155,10 @@ ev_window_init (EvWindow *ev_window) NULL)); g_object_unref (toolbars_model); + gtk_style_context_add_class + (gtk_widget_get_style_context (GTK_WIDGET (ev_window->priv->toolbar)), + GTK_STYLE_CLASS_PRIMARY_TOOLBAR); + egg_editable_toolbar_show (EGG_EDITABLE_TOOLBAR (ev_window->priv->toolbar), "DefaultToolBar"); gtk_box_pack_start (GTK_BOX (ev_window->priv->main_box), @@ -6843,7 +7167,7 @@ ev_window_init (EvWindow *ev_window) gtk_widget_show (ev_window->priv->toolbar); /* Add the main area */ - ev_window->priv->hpaned = gtk_hpaned_new (); + ev_window->priv->hpaned = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL); g_signal_connect (ev_window->priv->hpaned, "notify::position", G_CALLBACK (ev_window_sidebar_position_change_cb), @@ -6927,6 +7251,16 @@ ev_window_init (EvWindow *ev_window) ev_sidebar_add_page (EV_SIDEBAR (ev_window->priv->sidebar), sidebar_widget); + sidebar_widget = ev_sidebar_bookmarks_new (); + ev_window->priv->sidebar_bookmarks = sidebar_widget; + g_signal_connect (sidebar_widget, + "add-bookmark", + G_CALLBACK (sidebar_bookmarks_add_bookmark), + 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, @@ -6956,9 +7290,9 @@ ev_window_init (EvWindow *ev_window) g_signal_connect_object (ev_window->priv->view, "focus_out_event", G_CALLBACK (view_actions_focus_out_cb), ev_window, 0); - g_signal_connect_object (ev_window->priv->view, "external-link", - G_CALLBACK (view_external_link_cb), - ev_window, 0); + g_signal_connect_swapped (ev_window->priv->view, "external-link", + G_CALLBACK (view_external_link_cb), + ev_window); g_signal_connect_object (ev_window->priv->view, "handle-link", G_CALLBACK (view_handle_link_cb), ev_window, 0); @@ -6971,6 +7305,9 @@ ev_window_init (EvWindow *ev_window) g_signal_connect_object (ev_window->priv->view, "annot-added", G_CALLBACK (view_annot_added), ev_window, 0); + g_signal_connect_object (ev_window->priv->view, "layers-changed", + G_CALLBACK (view_layers_changed_cb), + ev_window, 0); #ifdef ENABLE_DBUS g_signal_connect_swapped (ev_window->priv->view, "sync-source", G_CALLBACK (ev_window_sync_source),