diff options
Diffstat (limited to 'shell')
31 files changed, 1226 insertions, 246 deletions
diff --git a/shell/Makefile.am b/shell/Makefile.am index 4fd2ad8f..3f09ea3d 100644 --- a/shell/Makefile.am +++ b/shell/Makefile.am @@ -36,6 +36,8 @@ atril_SOURCES= \ ev-bookmark-action.c \ ev-application.c \ ev-application.h \ + ev-find-sidebar.h \ + ev-find-sidebar.c \ ev-file-monitor.h \ ev-file-monitor.c \ ev-history.c \ diff --git a/shell/atril-ui.xml b/shell/atril-ui.xml index 851a014c..3ba59ee7 100644 --- a/shell/atril-ui.xml +++ b/shell/atril-ui.xml @@ -24,8 +24,8 @@ <menuitem name="EditFindNextMenu" action="EditFindNext"/> <menuitem name="EditFindPreviousMenu" action="EditFindPrevious"/> <separator/> - <menuitem name="EditRotateLeftMenu" action="EditRotateLeft"/> - <menuitem name="EditRotateRightMenu" action="EditRotateRight"/> + <menuitem name="EditRotateLeftMenu" action="EditRotateLeft" always-show-image="true"/> + <menuitem name="EditRotateRightMenu" action="EditRotateRight" always-show-image="true"/> <separator/> <menuitem name="EditToolbarMenu" action="EditToolbar"/> <separator/> diff --git a/shell/eggfindbar.c b/shell/eggfindbar.c index 438c5dc7..b61e5919 100644 --- a/shell/eggfindbar.c +++ b/shell/eggfindbar.c @@ -39,7 +39,6 @@ struct _EggFindBarPrivate GtkWidget *find_entry; GtkWidget *status_label; - gulong set_focus_handler; guint case_sensitive : 1; }; @@ -91,9 +90,6 @@ egg_find_bar_class_init (EggFindBarClass *klass) object_class->finalize = egg_find_bar_finalize; - widget_class->show = egg_find_bar_show; - widget_class->hide = egg_find_bar_hide; - widget_class->grab_focus = egg_find_bar_grab_focus; find_bar_signals[NEXT] = @@ -257,27 +253,6 @@ entry_changed_callback (GtkEntry *entry, } static void -set_focus_cb (GtkWidget *window, - GtkWidget *widget, - EggFindBar *bar) -{ - GtkWidget *wbar = GTK_WIDGET (bar); - - while (widget != NULL && widget != wbar) - { - widget = gtk_widget_get_parent (widget); - } - - /* if widget == bar, the new focus widget is in the bar, so we - * don't deactivate. - */ - if (widget != wbar) - { - g_signal_emit (bar, find_bar_signals[CLOSE], 0); - } -} - -static void egg_find_bar_init (EggFindBar *find_bar) { EggFindBarPrivate *priv; @@ -443,46 +418,6 @@ egg_find_bar_get_property (GObject *object, } } -static void -egg_find_bar_show (GtkWidget *widget) -{ - EggFindBar *bar = EGG_FIND_BAR (widget); - EggFindBarPrivate *priv = bar->priv; - - GTK_WIDGET_CLASS (egg_find_bar_parent_class)->show (widget); - - if (priv->set_focus_handler == 0) - { - GtkWidget *toplevel; - - toplevel = gtk_widget_get_toplevel (widget); - - priv->set_focus_handler = - g_signal_connect (toplevel, "set-focus", - G_CALLBACK (set_focus_cb), bar); - } -} - -static void -egg_find_bar_hide (GtkWidget *widget) -{ - EggFindBar *bar = EGG_FIND_BAR (widget); - EggFindBarPrivate *priv = bar->priv; - - if (priv->set_focus_handler != 0) - { - GtkWidget *toplevel; - - toplevel = gtk_widget_get_toplevel (widget); - - g_signal_handlers_disconnect_by_func - (toplevel, (void (*)) G_CALLBACK (set_focus_cb), bar); - priv->set_focus_handler = 0; - } - - GTK_WIDGET_CLASS (egg_find_bar_parent_class)->hide (widget); -} - void egg_find_bar_grab_focus (GtkWidget *widget) { @@ -573,7 +508,6 @@ egg_find_bar_set_search_string (EggFindBar *find_bar, g_object_thaw_notify (G_OBJECT (find_bar)); } - /** * egg_find_bar_get_search_string: * @@ -618,7 +552,7 @@ egg_find_bar_set_case_sensitive (EggFindBar *find_bar, if (priv->case_sensitive != case_sensitive) { - priv->case_sensitive = case_sensitive; + priv->case_sensitive = (case_sensitive != FALSE); gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (priv->case_button), priv->case_sensitive); diff --git a/shell/eggfindbar.h b/shell/eggfindbar.h index df7157e1..5f41cc17 100644 --- a/shell/eggfindbar.h +++ b/shell/eggfindbar.h @@ -77,4 +77,3 @@ G_END_DECLS #endif /* __EGG_FIND_BAR_H__ */ - diff --git a/shell/ev-application.c b/shell/ev-application.c index 8cff194f..57f1b922 100644 --- a/shell/ev-application.c +++ b/shell/ev-application.c @@ -21,7 +21,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - #include <config.h> #include <stdlib.h> #include <string.h> @@ -311,7 +310,6 @@ ev_application_get_empty_window (EvApplication *application, return empty_window; } - #ifdef ENABLE_DBUS typedef struct { gchar *uri; @@ -421,9 +419,17 @@ on_register_uri_cb (GObject *source_object, g_variant_builder_add (&builder, "{sv}", "display", g_variant_new_string (gdk_display_get_name (gdk_screen_get_display (data->screen)))); - g_variant_builder_add (&builder, "{sv}", - "screen", - g_variant_new_int32 (gdk_x11_screen_get_screen_number (data->screen))); + + if (GDK_IS_X11_SCREEN (data->screen)) { + g_variant_builder_add (&builder, "{sv}", + "screen", + g_variant_new_int32 (gdk_x11_screen_get_screen_number (data->screen))); + } else { + /*Do not crash on wayland, use the first monitor for now*/ + g_variant_builder_add (&builder, "{sv}", + "screen", + g_variant_new_int32 (0)); + } if (data->dest) { switch (ev_link_dest_get_dest_type (data->dest)) { case EV_LINK_DEST_TYPE_PAGE_LABEL: diff --git a/shell/ev-bookmarks.h b/shell/ev-bookmarks.h index d15ebad9..ac6ef524 100644 --- a/shell/ev-bookmarks.h +++ b/shell/ev-bookmarks.h @@ -50,8 +50,6 @@ void ev_bookmarks_delete (EvBookmarks *bookmarks, void ev_bookmarks_update (EvBookmarks *bookmarks, EvBookmark *bookmark); - - G_END_DECLS #endif /* EV_BOOKMARKS_H */ diff --git a/shell/ev-daemon.c b/shell/ev-daemon.c index a45adefb..bf552f5d 100644 --- a/shell/ev-daemon.c +++ b/shell/ev-daemon.c @@ -43,7 +43,6 @@ #define LOG g_debug - #define EV_TYPE_DAEMON_APPLICATION (ev_daemon_application_get_type ()) #define EV_DAEMON_APPLICATION(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), EV_TYPE_DAEMON_APPLICATION, EvDaemonApplication)) diff --git a/shell/ev-find-sidebar.c b/shell/ev-find-sidebar.c new file mode 100644 index 00000000..30718ec7 --- /dev/null +++ b/shell/ev-find-sidebar.c @@ -0,0 +1,681 @@ +/* ev-find-sidebar.c + * this file is part of evince, a gnome document viewer + * + * Copyright (C) 2013 Carlos Garcia Campos <[email protected]> + * Copyright (C) 2008 Sergey Pushkin <[email protected] > + * + * Evince is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Evince is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "ev-find-sidebar.h" + +#include "ev-document-text.h" + +#include <string.h> + +typedef struct { + GtkWidget *tree_view; + + guint selection_id; + guint process_matches_idle_id; + + GtkTreePath *highlighted_result; + gint first_match_page; + + EvJobFind *job; + gint job_current_page; + gint current_page; + gint insert_position; +} EvFindSidebarPrivate; + +enum { + TEXT_COLUMN, + PAGE_LABEL_COLUMN, + PAGE_COLUMN, + RESULT_COLUMN, + + N_COLUMNS +}; + +enum { + RESULT_ACTIVATED, + N_SIGNALS +}; + +static guint signals[N_SIGNALS]; + +G_DEFINE_TYPE_WITH_PRIVATE (EvFindSidebar, ev_find_sidebar, GTK_TYPE_BOX) + +#define GET_PRIVATE(o) ev_find_sidebar_get_instance_private (o) + +static void +ev_find_sidebar_cancel (EvFindSidebar *sidebar) +{ + EvFindSidebarPrivate *priv = GET_PRIVATE (sidebar); + + if (priv->process_matches_idle_id > 0) { + g_source_remove (priv->process_matches_idle_id); + priv->process_matches_idle_id = 0; + } + g_clear_object (&priv->job); +} + +static void +ev_find_sidebar_dispose (GObject *object) +{ + EvFindSidebar *sidebar = EV_FIND_SIDEBAR (object); + EvFindSidebarPrivate *priv = GET_PRIVATE (sidebar); + + ev_find_sidebar_cancel (sidebar); + g_clear_pointer (&(priv->highlighted_result), gtk_tree_path_free); + + G_OBJECT_CLASS (ev_find_sidebar_parent_class)->dispose (object); +} + +static void +ev_find_sidebar_class_init (EvFindSidebarClass *find_sidebar_class) +{ + GObjectClass *g_object_class = G_OBJECT_CLASS (find_sidebar_class); + + g_object_class->dispose = ev_find_sidebar_dispose; + + signals[RESULT_ACTIVATED] = + g_signal_new ("result-activated", + G_TYPE_FROM_CLASS (g_object_class), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, + g_cclosure_marshal_generic, + G_TYPE_NONE, 2, + G_TYPE_INT, + G_TYPE_INT); +} + +static void +ev_find_sidebar_activate_result_at_iter (EvFindSidebar *sidebar, + GtkTreeModel *model, + GtkTreeIter *iter) +{ + EvFindSidebarPrivate *priv = GET_PRIVATE (sidebar); + gint page; + gint result; + + + if (priv->highlighted_result) + gtk_tree_path_free (priv->highlighted_result); + priv->highlighted_result = gtk_tree_model_get_path (model, iter); + + gtk_tree_model_get (model, iter, + PAGE_COLUMN, &page, + RESULT_COLUMN, &result, + -1); + g_signal_emit (sidebar, signals[RESULT_ACTIVATED], 0, page - 1, result); +} + +static void +selection_changed_callback (GtkTreeSelection *selection, + EvFindSidebar *sidebar) +{ + GtkTreeModel *model; + GtkTreeIter iter; + + if (gtk_tree_selection_get_selected (selection, &model, &iter)) + ev_find_sidebar_activate_result_at_iter (sidebar, model, &iter); +} + +static gboolean +sidebar_tree_button_press_cb (GtkTreeView *view, + GdkEventButton *event, + EvFindSidebar *sidebar) +{ + EvFindSidebarPrivate *priv = GET_PRIVATE (sidebar); + GtkTreeModel *model; + GtkTreePath *path; + GtkTreeIter iter; + + gtk_tree_view_get_path_at_pos (view, event->x, event->y, &path, + NULL, NULL, NULL); + if (!path) + return FALSE; + + if (priv->highlighted_result && + gtk_tree_path_compare (priv->highlighted_result, path) != 0) { + gtk_tree_path_free (path); + return FALSE; + } + + model = gtk_tree_view_get_model (view); + gtk_tree_model_get_iter (model, &iter, path); + gtk_tree_path_free (path); + + ev_find_sidebar_activate_result_at_iter (sidebar, model, &iter); + + /* Always return FALSE so the tree view gets the event and can update + * the selection etc. + */ + return FALSE; +} + +static void +ev_find_sidebar_reset_model (EvFindSidebar *sidebar) +{ + EvFindSidebarPrivate *priv = GET_PRIVATE (sidebar); + GtkListStore *model; + + model = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT); + gtk_tree_view_set_model (GTK_TREE_VIEW (priv->tree_view), + GTK_TREE_MODEL (model)); + g_object_unref (model); +} + +static void +ev_find_sidebar_init (EvFindSidebar *sidebar) +{ + EvFindSidebarPrivate *priv; + GtkWidget *swindow; + GtkTreeViewColumn *column; + GtkCellRenderer *renderer; + GtkTreeSelection *selection; + + priv = GET_PRIVATE (sidebar); + + swindow = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + + priv->tree_view = gtk_tree_view_new (); + ev_find_sidebar_reset_model (sidebar); + + gtk_tree_view_set_search_column (GTK_TREE_VIEW (priv->tree_view), -1); + gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (priv->tree_view), FALSE); + gtk_container_add (GTK_CONTAINER (swindow), priv->tree_view); + gtk_widget_show (priv->tree_view); + + gtk_box_pack_start (GTK_BOX (sidebar), swindow, TRUE, TRUE, 0); + gtk_widget_show (swindow); + + column = gtk_tree_view_column_new (); + gtk_tree_view_column_set_expand (GTK_TREE_VIEW_COLUMN (column), TRUE); + gtk_tree_view_append_column (GTK_TREE_VIEW (priv->tree_view), column); + + renderer = (GtkCellRenderer *)g_object_new (GTK_TYPE_CELL_RENDERER_TEXT, + "ellipsize", + PANGO_ELLIPSIZE_END, + NULL); + gtk_tree_view_column_pack_start (GTK_TREE_VIEW_COLUMN (column), renderer, TRUE); + gtk_tree_view_column_set_attributes (GTK_TREE_VIEW_COLUMN (column), renderer, + "markup", TEXT_COLUMN, + NULL); + + renderer = gtk_cell_renderer_text_new (); + gtk_tree_view_column_pack_end (GTK_TREE_VIEW_COLUMN (column), renderer, FALSE); + gtk_tree_view_column_set_attributes (GTK_TREE_VIEW_COLUMN (column), renderer, + "text", PAGE_LABEL_COLUMN, + NULL); + g_object_set (G_OBJECT (renderer), "style", PANGO_STYLE_ITALIC, NULL); + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->tree_view)); + priv->selection_id = g_signal_connect (selection, "changed", + G_CALLBACK (selection_changed_callback), + sidebar); + g_signal_connect (priv->tree_view, "button-press-event", + G_CALLBACK (sidebar_tree_button_press_cb), + sidebar); +} + +GtkWidget * +ev_find_sidebar_new (void) +{ + return g_object_new (EV_TYPE_FIND_SIDEBAR, + "orientation", GTK_ORIENTATION_VERTICAL, + NULL); +} + +static void +ev_find_sidebar_select_highlighted_result (EvFindSidebar *sidebar) +{ + EvFindSidebarPrivate *priv = GET_PRIVATE (sidebar); + GtkTreeSelection *selection; + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->tree_view)); + + g_signal_handler_block (selection, priv->selection_id); + gtk_tree_view_set_cursor (GTK_TREE_VIEW (priv->tree_view), priv->highlighted_result, NULL, FALSE); + g_signal_handler_unblock (selection, priv->selection_id); +} + +static void +ev_find_sidebar_highlight_first_match_of_page (EvFindSidebar *sidebar, + gint page) +{ + EvFindSidebarPrivate *priv = GET_PRIVATE (sidebar); + gint index = 0; + gint i; + + if (!priv->job) + return; + + for (i = 0; i < page; i++) + index += ev_job_find_get_n_results (priv->job, i); + + if (priv->highlighted_result) + gtk_tree_path_free (priv->highlighted_result); + priv->highlighted_result = gtk_tree_path_new_from_indices (index, -1); + ev_find_sidebar_select_highlighted_result (sidebar); +} + +static gchar * +sanitized_substring (const gchar *text, + gint start, + gint end) +{ + const gchar *p; + const gchar *start_ptr; + const gchar *end_ptr; + guint len = 0; + gchar *retval; + + if (end - start <= 0) + return NULL; + + start_ptr = g_utf8_offset_to_pointer (text, start); + end_ptr = g_utf8_offset_to_pointer (start_ptr, end - start); + + retval = g_malloc (end_ptr - start_ptr + 1); + p = start_ptr; + + while (p != end_ptr) { + const gchar *next; + + next = g_utf8_next_char (p); + + if (next != end_ptr) { + GUnicodeBreakType break_type; + + break_type = g_unichar_break_type (g_utf8_get_char (p)); + if (break_type == G_UNICODE_BREAK_HYPHEN && *next == '\n') { + p = g_utf8_next_char (next); + continue; + } + } + + if (*p != '\n') { + strncpy (retval + len, p, next - p); + len += next - p; + } else { + *(retval + len) = ' '; + len++; + } + + p = next; + } + + if (len == 0) { + g_free (retval); + + return NULL; + } + + retval[len] = 0; + + return retval; +} + +static gchar * +get_surrounding_text_markup (const gchar *text, + const gchar *find_text, + gboolean case_sensitive, + PangoLogAttr *log_attrs, + gint log_attrs_length, + gint offset) +{ + gint iter; + gchar *prec = NULL; + gchar *succ = NULL; + gchar *match = NULL; + gchar *markup; + gint max_chars; + + iter = MAX (0, offset - 1); + while (!log_attrs[iter].is_word_start && iter > 0) + iter--; + + prec = sanitized_substring (text, iter, offset); + + iter = offset; + offset += g_utf8_strlen (find_text, -1); + if (!case_sensitive) + match = g_utf8_substring (text, iter, offset); + + iter = MIN (log_attrs_length, offset + 1); + max_chars = MIN (log_attrs_length - 1, iter + 100); + while (TRUE) { + gint word = iter; + + while (!log_attrs[word].is_word_end && word < max_chars) + word++; + + if (word > max_chars) + break; + + iter = word + 1; + } + + succ = sanitized_substring (text, offset, iter); + + markup = g_markup_printf_escaped ("%s<span weight=\"bold\">%s</span>%s", + prec ? prec : "", match ? match : find_text, succ ? succ : ""); + g_free (prec); + g_free (succ); + g_free (match); + + return markup; +} + +static gchar * +get_page_text (EvDocument *document, + EvPage *page, + EvRectangle **areas, + guint *n_areas) +{ + gchar *text; + gboolean success; + + ev_document_doc_mutex_lock (); + text = ev_document_text_get_text (EV_DOCUMENT_TEXT (document), page); + success = ev_document_text_get_text_layout (EV_DOCUMENT_TEXT (document), page, areas, n_areas); + ev_document_doc_mutex_unlock (); + + if (!success) { + g_free (text); + return NULL; + } + + return text; +} + +static gint +get_match_offset (EvRectangle *areas, + guint n_areas, + EvRectangle *match, + gint offset) +{ + gdouble x, y; + gint i; + + x = match->x1; + y = (match->y1 + match->y2) / 2; + + i = offset; + + do { + EvRectangle *area = areas + i; + + if (x >= area->x1 && x < area->x2 && + y >= area->y1 && y <= area->y2) { + return i; + } + + i = (i + 1) % n_areas; + } while (i != offset); + + return -1; +} + +static gboolean +process_matches_idle (EvFindSidebar *sidebar) +{ + EvFindSidebarPrivate *priv = GET_PRIVATE (sidebar); + GtkTreeModel *model; + gint current_page; + EvDocument *document; + + priv->process_matches_idle_id = 0; + + if (!ev_job_find_has_results (priv->job)) { + if (ev_job_is_finished (EV_JOB (priv->job))) + g_clear_object (&priv->job); + return FALSE; + } + + document = EV_JOB (priv->job)->document; + model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->tree_view)); + + do { + GList *matches, *l; + EvPage *page; + gint result; + gchar *page_label; + gchar *page_text; + EvRectangle *areas = NULL; + guint n_areas; + PangoLogAttr *text_log_attrs; + gulong text_log_attrs_length; + gint offset; + + current_page = priv->current_page; + priv->current_page = (priv->current_page + 1) % priv->job->n_pages; + + matches = priv->job->pages[current_page]; + if (!matches) + continue; + + page = ev_document_get_page (document, current_page); + page_label = ev_document_get_page_label (document, current_page); + page_text = get_page_text (document, page, &areas, &n_areas); + g_object_unref (page); + if (!page_text) + continue; + + text_log_attrs_length = g_utf8_strlen (page_text, -1); + text_log_attrs = g_new0 (PangoLogAttr, text_log_attrs_length + 1); + pango_get_log_attrs (page_text, -1, -1, NULL, text_log_attrs, text_log_attrs_length + 1); + + if (priv->first_match_page == -1) + priv->first_match_page = current_page; + + offset = 0; + + for (l = matches, result = 0; l; l = g_list_next (l), result++) { + EvRectangle *match = (EvRectangle *)l->data; + gchar *markup; + GtkTreeIter iter; + gint new_offset; + + new_offset = get_match_offset (areas, n_areas, match, offset); + if (new_offset == -1) { + g_warning ("No offset found for match \"%s\" at page %d after processing %d results\n", + priv->job->text, current_page, result); + /* It may happen that a vertical text match has no corresponding text area, skip + * that but keep iterating to show any other matches in page (issue #1545) */ + continue; + } + offset = new_offset; + + if (current_page >= priv->job->start_page) { + gtk_list_store_append (GTK_LIST_STORE (model), &iter); + } else { + gtk_list_store_insert (GTK_LIST_STORE (model), &iter, + priv->insert_position); + priv->insert_position++; + } + + markup = get_surrounding_text_markup (page_text, + priv->job->text, + priv->job->case_sensitive, + text_log_attrs, + text_log_attrs_length, + offset); + + gtk_list_store_set (GTK_LIST_STORE (model), &iter, + TEXT_COLUMN, markup, + PAGE_LABEL_COLUMN, page_label, + PAGE_COLUMN, current_page + 1, + RESULT_COLUMN, result, + -1); + g_free (markup); + } + + g_free (page_label); + g_free (page_text); + g_free (text_log_attrs); + g_free (areas); + } while (current_page != priv->job_current_page); + + if (ev_job_is_finished (EV_JOB (priv->job)) && priv->current_page == priv->job->start_page) + ev_find_sidebar_highlight_first_match_of_page (sidebar, priv->first_match_page); + + return FALSE; +} + +static void +find_job_updated_cb (EvJobFind *job, + gint page, + EvFindSidebar *sidebar) +{ + EvFindSidebarPrivate *priv = GET_PRIVATE (sidebar); + + priv->job_current_page = page; +} + +static void +find_job_cancelled_cb (EvJob *job, + EvFindSidebar *sidebar) +{ + ev_find_sidebar_cancel (sidebar); +} + +void +ev_find_sidebar_start (EvFindSidebar *sidebar, + EvJobFind *job) +{ + EvFindSidebarPrivate *priv = GET_PRIVATE (sidebar); + + if (priv->job == job) + return; + + ev_find_sidebar_clear (sidebar); + priv->job = g_object_ref (job); + g_signal_connect_object (job, "updated", + G_CALLBACK (find_job_updated_cb), + sidebar, 0); + g_signal_connect_object (job, "cancelled", + G_CALLBACK (find_job_cancelled_cb), + sidebar, 0); + priv->job_current_page = -1; + priv->first_match_page = -1; + priv->current_page = job->start_page; + priv->insert_position = 0; +} + +void +ev_find_sidebar_restart (EvFindSidebar *sidebar, + gint page) +{ + EvFindSidebarPrivate *priv = GET_PRIVATE (sidebar); + gint first_match_page = -1; + gint i; + + if (!priv->job) + return; + + for (i = 0; i < priv->job->n_pages; i++) { + int index; + + index = page + i; + + if (index >= priv->job->n_pages) + index -= priv->job->n_pages; + + if (priv->job->pages[index]) { + first_match_page = index; + break; + } + } + + if (first_match_page != -1) + ev_find_sidebar_highlight_first_match_of_page (sidebar, first_match_page); +} + +void +ev_find_sidebar_update (EvFindSidebar *sidebar) +{ + EvFindSidebarPrivate *priv = GET_PRIVATE (sidebar); + + if (!priv->job) + return; + + if (priv->process_matches_idle_id == 0) + priv->process_matches_idle_id = g_idle_add ((GSourceFunc)process_matches_idle, sidebar); +} + +void +ev_find_sidebar_clear (EvFindSidebar *sidebar) +{ + EvFindSidebarPrivate *priv = GET_PRIVATE (sidebar); + + ev_find_sidebar_cancel (sidebar); + + /* It seems it's more efficient to set a new model in the tree view instead of + * clearing the model that would emit row-deleted signal for every row in the model + */ + ev_find_sidebar_reset_model (sidebar); + g_clear_pointer (&priv->highlighted_result, gtk_tree_path_free); +} + +void +ev_find_sidebar_previous (EvFindSidebar *sidebar) +{ + EvFindSidebarPrivate *priv = GET_PRIVATE (sidebar); + + if (!priv->highlighted_result) + return; + + if (!gtk_tree_path_prev (priv->highlighted_result)) { + GtkTreeModel *model; + GtkTreeIter iter; + + model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->tree_view)); + gtk_tree_model_get_iter (model, &iter, priv->highlighted_result); + while (gtk_tree_model_iter_next (model, &iter)) + gtk_tree_path_next (priv->highlighted_result); + } + ev_find_sidebar_select_highlighted_result (sidebar); +} + +void +ev_find_sidebar_next (EvFindSidebar *sidebar) +{ + EvFindSidebarPrivate *priv = GET_PRIVATE (sidebar); + GtkTreeModel *model; + GtkTreeIter iter; + + if (!priv->highlighted_result) + return; + + model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->tree_view)); + gtk_tree_model_get_iter (model, &iter, priv->highlighted_result); + if (gtk_tree_model_iter_next (model, &iter)) { + gtk_tree_path_next (priv->highlighted_result); + } else { + gtk_tree_path_free (priv->highlighted_result); + priv->highlighted_result = gtk_tree_path_new_first (); + } + ev_find_sidebar_select_highlighted_result (sidebar); +} + diff --git a/shell/ev-find-sidebar.h b/shell/ev-find-sidebar.h new file mode 100644 index 00000000..61920c6a --- /dev/null +++ b/shell/ev-find-sidebar.h @@ -0,0 +1,63 @@ +/* ev-find-sidebar.h + * this file is part of evince, a gnome document viewer + * + * Copyright (C) 2013 Carlos Garcia Campos <[email protected]> + * Copyright (C) 2008 Sergey Pushkin <[email protected] > + * + * Evince is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Evince is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef EV_FIND_SIDEBAR_H +#define EV_FIND_SIDEBAR_H + +#include <gtk/gtk.h> + +#include "ev-jobs.h" + +G_BEGIN_DECLS + +#define EV_TYPE_FIND_SIDEBAR (ev_find_sidebar_get_type ()) +#define EV_FIND_SIDEBAR(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), EV_TYPE_FIND_SIDEBAR, EvFindSidebar)) +#define EV_IS_FIND_SIDEBAR(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), EV_TYPE_FIND_SIDEBAR)) +#define EV_FIND_SIDEBAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EV_TYPE_FIND_SIDEBAR, EvFindSidebarClass)) +#define EV_IS_FIND_SIDEBAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EV_TYPE_FIND_SIDEBAR)) +#define EV_FIND_SIDEBAR_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS ((object), EV_TYPE_FIND_SIDEBAR, EvFindSidebarClass)) + +typedef struct _EvFindSidebar EvFindSidebar; +typedef struct _EvFindSidebarClass EvFindSidebarClass; + +struct _EvFindSidebar { + GtkBox base_instance; +}; + +struct _EvFindSidebarClass { + GtkBoxClass base_class; +}; + +GType ev_find_sidebar_get_type (void); +GtkWidget *ev_find_sidebar_new (void); + +void ev_find_sidebar_start (EvFindSidebar *find_sidebar, + EvJobFind *job); +void ev_find_sidebar_restart (EvFindSidebar *find_sidebar, + gint page); +void ev_find_sidebar_update (EvFindSidebar *find_sidebar); +void ev_find_sidebar_clear (EvFindSidebar *find_sidebar); +void ev_find_sidebar_previous (EvFindSidebar *find_sidebar); +void ev_find_sidebar_next (EvFindSidebar *find_sidebar); + +G_END_DECLS + +#endif /* EV_FIND_SIDEBAR_H */ diff --git a/shell/ev-history.c b/shell/ev-history.c index 940c66f9..7fc3c824 100644 --- a/shell/ev-history.c +++ b/shell/ev-history.c @@ -24,7 +24,6 @@ #include "ev-history.h" - enum { HISTORY_CHANGED, diff --git a/shell/ev-loading-message.c b/shell/ev-loading-message.c index aa7014e5..530f4e73 100644 --- a/shell/ev-loading-message.c +++ b/shell/ev-loading-message.c @@ -174,4 +174,3 @@ ev_loading_message_new (void) return message; } - diff --git a/shell/ev-media-player-keys.h b/shell/ev-media-player-keys.h index f18f192a..fb69aa47 100644 --- a/shell/ev-media-player-keys.h +++ b/shell/ev-media-player-keys.h @@ -37,7 +37,6 @@ G_BEGIN_DECLS typedef struct _EvMediaPlayerKeys EvMediaPlayerKeys; typedef struct _EvMediaPlayerKeysClass EvMediaPlayerKeysClass; - GType ev_media_player_keys_get_type (void) G_GNUC_CONST; EvMediaPlayerKeys *ev_media_player_keys_new (void); diff --git a/shell/ev-navigation-action.c b/shell/ev-navigation-action.c index 57b4c463..181b0a51 100644 --- a/shell/ev-navigation-action.c +++ b/shell/ev-navigation-action.c @@ -26,6 +26,7 @@ #include "ev-navigation-action.h" #include "ev-navigation-action-widget.h" +#include <libmate-desktop/mate-image-menu-item.h> enum { @@ -100,7 +101,7 @@ new_history_menu_item (EvNavigationAction *action, const char *title; title = ev_link_get_title (link); - item = gtk_image_menu_item_new_with_label (title); + item = mate_image_menu_item_new_with_label (title); label = GTK_LABEL (gtk_bin_get_child (GTK_BIN (item))); gtk_label_set_use_markup (label, TRUE); g_object_set_data (G_OBJECT (item), "index", diff --git a/shell/ev-open-recent-action.c b/shell/ev-open-recent-action.c index 0c1a21dc..46d5eda8 100644 --- a/shell/ev-open-recent-action.c +++ b/shell/ev-open-recent-action.c @@ -24,7 +24,6 @@ #include "ev-open-recent-action.h" - enum { ITEM_ACTIVATED, N_SIGNALS @@ -66,7 +65,9 @@ ev_open_recent_action_create_tool_item (GtkAction *action) gtk_recent_filter_add_application (filter, g_get_application_name ()); gtk_recent_chooser_set_filter (GTK_RECENT_CHOOSER (toolbar_recent_menu), filter); - tool_item = GTK_WIDGET (gtk_menu_tool_button_new_from_stock ("gtk-open")); + GtkWidget *icon = gtk_image_new_from_icon_name ("document-open", GTK_ICON_SIZE_SMALL_TOOLBAR); + tool_item = GTK_WIDGET (gtk_menu_tool_button_new (icon, NULL)); + gtk_menu_tool_button_set_arrow_tooltip_text (GTK_MENU_TOOL_BUTTON (tool_item), _("Open a recently used document")); gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), diff --git a/shell/ev-password-view.c b/shell/ev-password-view.c index e720a7f5..601a5e5e 100644 --- a/shell/ev-password-view.c +++ b/shell/ev-password-view.c @@ -18,7 +18,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -47,7 +46,6 @@ struct _EvPasswordViewPrivate { static guint password_view_signals [LAST_SIGNAL] = { 0 }; - G_DEFINE_TYPE_WITH_PRIVATE (EvPasswordView, ev_password_view, GTK_TYPE_VIEWPORT) static void diff --git a/shell/ev-sidebar-annotations.c b/shell/ev-sidebar-annotations.c index f445cd35..cc39617f 100644 --- a/shell/ev-sidebar-annotations.c +++ b/shell/ev-sidebar-annotations.c @@ -56,7 +56,7 @@ struct _EvSidebarAnnotationsPrivate { GtkWidget *annot_text_item; EvJob *job; - guint selection_changed_id; + gulong selection_changed_id; }; static void ev_sidebar_annotations_page_iface_init (EvSidebarPageInterface *iface); diff --git a/shell/ev-sidebar-attachments.c b/shell/ev-sidebar-attachments.c index 81aee149..007322f4 100644 --- a/shell/ev-sidebar-attachments.c +++ b/shell/ev-sidebar-attachments.c @@ -631,7 +631,6 @@ job_finished_callback (EvJobAttachments *job, g_object_unref (job); } - static void ev_sidebar_attachments_document_changed_cb (EvDocumentModel *model, GParamSpec *pspec, diff --git a/shell/ev-sidebar-bookmarks.c b/shell/ev-sidebar-bookmarks.c index 2abdd695..214ca61a 100644 --- a/shell/ev-sidebar-bookmarks.c +++ b/shell/ev-sidebar-bookmarks.c @@ -122,7 +122,6 @@ ev_bookmarks_popup_cmd_rename_bookmark (GtkAction *action, GtkTreeModel *model; GtkTreeIter iter; - selection = gtk_tree_view_get_selection (tree_view); if (gtk_tree_selection_get_selected (selection, &model, &iter)) { GtkTreePath *path; diff --git a/shell/ev-sidebar-layers.c b/shell/ev-sidebar-layers.c index 1326e381..5518f4a9 100644 --- a/shell/ev-sidebar-layers.c +++ b/shell/ev-sidebar-layers.c @@ -239,7 +239,6 @@ ev_sidebar_layers_create_tree_view (EvSidebarLayers *ev_layers) gtk_tree_selection_set_mode (gtk_tree_view_get_selection (tree_view), GTK_SELECTION_NONE); - column = gtk_tree_view_column_new (); renderer = gtk_cell_renderer_toggle_new (); diff --git a/shell/ev-sidebar-links.c b/shell/ev-sidebar-links.c index 92caa959..e6531cae 100644 --- a/shell/ev-sidebar-links.c +++ b/shell/ev-sidebar-links.c @@ -29,6 +29,8 @@ #include <glib/gi18n.h> #include <gtk/gtk.h> +#include <libmate-desktop/mate-image-menu-item.h> + #include "ev-document-links.h" #include "ev-job-scheduler.h" #include "ev-sidebar-links.h" @@ -39,14 +41,16 @@ struct _EvSidebarLinksPrivate { GtkWidget *tree_view; /* Keep these ids around for blocking */ - guint selection_id; - guint page_changed_id; - guint row_activated_id; + gulong selection_id; + gulong page_changed_id; + gulong row_activated_id; EvJob *job; GtkTreeModel *model; EvDocument *document; EvDocumentModel *doc_model; + + GTree *page_link_tree; }; enum { @@ -149,6 +153,11 @@ ev_sidebar_links_dispose (GObject *object) sidebar->priv->model = NULL; } + if (sidebar->priv->page_link_tree) { + g_tree_unref (sidebar->priv->page_link_tree); + sidebar->priv->page_link_tree = NULL; + } + if (sidebar->priv->document) { g_object_unref (sidebar->priv->document); sidebar->priv->document = NULL; @@ -324,11 +333,13 @@ static GtkMenu * build_popup_menu (EvSidebarLinks *sidebar) { GtkWidget *menu; + GtkWidget *image; GtkWidget *item; menu = gtk_menu_new (); - item = gtk_image_menu_item_new_from_stock ("gtk-print", NULL); - gtk_label_set_label (GTK_LABEL (gtk_bin_get_child (GTK_BIN (item))), _("Print…")); + item = mate_image_menu_item_new_with_label ("Print…"); + image = gtk_image_new_from_icon_name ("gtk-print", GTK_ICON_SIZE_MENU); + mate_image_menu_item_set_image (MATE_IMAGE_MENU_ITEM (item), image); gtk_widget_show (item); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); g_signal_connect (item, "activate", @@ -372,7 +383,6 @@ button_press_cb (GtkWidget *treeview, return FALSE; } - static void ev_sidebar_links_construct (EvSidebarLinks *ev_sidebar_links) { @@ -418,7 +428,6 @@ ev_sidebar_links_construct (EvSidebarLinks *ev_sidebar_links) "markup", EV_DOCUMENT_LINKS_COLUMN_MARKUP, NULL); - renderer = gtk_cell_renderer_text_new (); gtk_tree_view_column_pack_end (GTK_TREE_VIEW_COLUMN (column), renderer, FALSE); gtk_tree_view_column_set_attributes (GTK_TREE_VIEW_COLUMN (column), renderer, @@ -461,40 +470,19 @@ ev_sidebar_links_new (void) return ev_sidebar_links; } -static gboolean -update_page_callback_foreach (GtkTreeModel *model, - GtkTreePath *path, - GtkTreeIter *iter, - gpointer data) -{ - EvSidebarLinks *sidebar_links = (data); - EvLink *link; - - gtk_tree_model_get (model, iter, - EV_DOCUMENT_LINKS_COLUMN_LINK, &link, - -1); - - if (link) { - int current_page; - int dest_page; - EvDocumentLinks *document_links = EV_DOCUMENT_LINKS (sidebar_links->priv->document); - - dest_page = ev_document_links_get_link_page (document_links, link); - g_object_unref (link); +typedef struct EvSidebarLinkPageSearch { + gint page; + gint best_existing; +} EvSidebarLinkPageSearch; - current_page = ev_document_model_get_page (sidebar_links->priv->doc_model); - - if (dest_page == current_page) { - gtk_tree_view_expand_to_path (GTK_TREE_VIEW (sidebar_links->priv->tree_view), - path); - gtk_tree_view_set_cursor (GTK_TREE_VIEW (sidebar_links->priv->tree_view), - path, NULL, FALSE); - - return TRUE; - } - } +static gint +page_link_tree_search_best_page (gpointer page_ptr, EvSidebarLinkPageSearch* data) +{ + gint page = GPOINTER_TO_INT (page_ptr); + if (page <= data->page && page > data->best_existing) + data->best_existing = page; - return FALSE; + return data->page - page; } static void @@ -502,44 +490,34 @@ ev_sidebar_links_set_current_page (EvSidebarLinks *sidebar_links, gint current_page) { GtkTreeSelection *selection; - GtkTreeModel *model; - GtkTreeIter iter; + GtkTreePath *path; + EvSidebarLinkPageSearch search_data; /* Widget is not currently visible */ - if (!gtk_widget_get_mapped (GTK_WIDGET (sidebar_links))) + if (!gtk_widget_is_visible (GTK_WIDGET (sidebar_links))) return; - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (sidebar_links->priv->tree_view)); + search_data.page = current_page; + search_data.best_existing = G_MININT; - if (gtk_tree_selection_get_selected (selection, &model, &iter)) { - EvLink *link; - - gtk_tree_model_get (model, &iter, - EV_DOCUMENT_LINKS_COLUMN_LINK, &link, - -1); - if (link) { - gint dest_page; - EvDocumentLinks *document_links = EV_DOCUMENT_LINKS (sidebar_links->priv->document); + path = g_tree_search (sidebar_links->priv->page_link_tree, (GCompareFunc) page_link_tree_search_best_page, &search_data); + /* No direct hit, try a lookup on the best match. */ + if (!path) + path = g_tree_lookup (sidebar_links->priv->page_link_tree, GINT_TO_POINTER (search_data.best_existing)); - dest_page = ev_document_links_get_link_page (document_links, link); - g_object_unref (link); + /* Still no hit, give up. */ + if (!path) + return; - if (dest_page == current_page) - return; - } - } + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (sidebar_links->priv->tree_view)); - /* We go through the tree linearly looking for the first page that - * matches. This is pretty inefficient. We can do something neat with - * a GtkTreeModelSort here to make it faster, if it turns out to be - * slow. - */ g_signal_handler_block (selection, sidebar_links->priv->selection_id); g_signal_handler_block (sidebar_links->priv->tree_view, sidebar_links->priv->row_activated_id); - gtk_tree_model_foreach (model, - update_page_callback_foreach, - sidebar_links); + gtk_tree_view_expand_to_path (GTK_TREE_VIEW (sidebar_links->priv->tree_view), + path); + gtk_tree_view_set_cursor (GTK_TREE_VIEW (sidebar_links->priv->tree_view), + path, NULL, FALSE); g_signal_handler_unblock (selection, sidebar_links->priv->selection_id); g_signal_handler_unblock (sidebar_links->priv->tree_view, sidebar_links->priv->row_activated_id); @@ -590,6 +568,41 @@ expand_open_links (GtkTreeView *tree_view, GtkTreeModel *model, GtkTreeIter *par } } +static gint +page_link_tree_sort (gconstpointer a, gconstpointer b, void *data) +{ + return GPOINTER_TO_INT (a) - GPOINTER_TO_INT (b); +} + +static gboolean +update_page_link_tree_foreach (GtkTreeModel *model, + GtkTreePath *path, + GtkTreeIter *iter, + gpointer data) +{ + EvSidebarLinks *sidebar_links = data; + EvSidebarLinksPrivate *priv = sidebar_links->priv; + EvDocumentLinks *document_links = EV_DOCUMENT_LINKS (priv->document); + EvLink *link; + int page; + + gtk_tree_model_get (model, iter, + EV_DOCUMENT_LINKS_COLUMN_LINK, &link, + -1); + + if (!link) + return FALSE; + + page = ev_document_links_get_link_page (document_links, link); + g_object_unref (link); + + /* Only save the first link we find per page. */ + if (!g_tree_lookup (priv->page_link_tree, GINT_TO_POINTER (page))) + g_tree_insert (priv->page_link_tree, GINT_TO_POINTER (page), gtk_tree_path_copy (path)); + + return FALSE; +} + static void ev_sidebar_links_set_links_model (EvSidebarLinks *sidebar_links, GtkTreeModel *model) @@ -603,6 +616,15 @@ ev_sidebar_links_set_links_model (EvSidebarLinks *sidebar_links, g_object_unref (priv->model); priv->model = g_object_ref (model); + /* Rebuild the binary search tree for finding links on pages. */ + if (priv->page_link_tree) + g_tree_unref (priv->page_link_tree); + priv->page_link_tree = g_tree_new_full (page_link_tree_sort, NULL, NULL, (GDestroyNotify) gtk_tree_path_free); + + gtk_tree_model_foreach (model, + update_page_link_tree_foreach, + sidebar_links); + g_object_notify (G_OBJECT (sidebar_links), "model"); } @@ -625,7 +647,7 @@ job_finished_callback (EvJobLinks *job, selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->tree_view)); gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE); - if (priv->selection_id <= 0) { + if (priv->selection_id == 0) { priv->selection_id = g_signal_connect (selection, "changed", G_CALLBACK (selection_changed_callback), @@ -635,7 +657,7 @@ job_finished_callback (EvJobLinks *job, g_signal_connect_swapped (priv->doc_model, "page-changed", G_CALLBACK (update_page_callback), sidebar_links); - if (priv->row_activated_id <= 0) { + if (priv->row_activated_id == 0) { priv->row_activated_id = g_signal_connect (priv->tree_view, "row-activated", G_CALLBACK (row_activated_callback), diff --git a/shell/ev-sidebar-links.h b/shell/ev-sidebar-links.h index eb4ae8ff..d0475dc5 100644 --- a/shell/ev-sidebar-links.h +++ b/shell/ev-sidebar-links.h @@ -63,4 +63,3 @@ G_END_DECLS #endif /* __EV_SIDEBAR_LINKS_H__ */ - diff --git a/shell/ev-sidebar-page.c b/shell/ev-sidebar-page.c index 0b216bd8..bd5b85c2 100644 --- a/shell/ev-sidebar-page.c +++ b/shell/ev-sidebar-page.c @@ -74,7 +74,6 @@ ev_sidebar_page_get_label (EvSidebarPage *sidebar_page) return iface->get_label (sidebar_page); } - static void ev_sidebar_page_default_init (EvSidebarPageInterface *iface) { diff --git a/shell/ev-sidebar-page.h b/shell/ev-sidebar-page.h index 21ef92cf..21791aaa 100644 --- a/shell/ev-sidebar-page.h +++ b/shell/ev-sidebar-page.h @@ -58,7 +58,6 @@ void ev_sidebar_page_set_model (EvSidebarPage *sidebar_page, EvDocumentModel *model); const gchar* ev_sidebar_page_get_label (EvSidebarPage *page); - G_END_DECLS #endif /* EV_SIDEBAR_PAGE */ diff --git a/shell/ev-sidebar-thumbnails.c b/shell/ev-sidebar-thumbnails.c index 05a9049f..c12a7a10 100644 --- a/shell/ev-sidebar-thumbnails.c +++ b/shell/ev-sidebar-thumbnails.c @@ -245,7 +245,6 @@ ev_thumbnails_size_cache_get (EvDocument *document) return cache; } - static void ev_sidebar_thumbnails_dispose (GObject *object) { @@ -582,6 +581,10 @@ ev_sidebar_thumbnails_fill_model (EvSidebarThumbnails *sidebar_thumbnails) GtkTreeIter iter; int i; + if (priv->document->iswebdocument) { + return; + } + for (i = 0; i < sidebar_thumbnails->priv->n_pages; i++) { gchar *page_label; gchar *page_string; @@ -1019,7 +1022,7 @@ static gboolean ev_sidebar_thumbnails_support_document (EvSidebarPage *sidebar_page, EvDocument *document) { - return (EV_IS_DOCUMENT_THUMBNAILS (document)); + return (EV_IS_DOCUMENT_THUMBNAILS (document) && !document->iswebdocument); } static const gchar* diff --git a/shell/ev-sidebar-thumbnails.h b/shell/ev-sidebar-thumbnails.h index ed10ac39..3a0186cd 100644 --- a/shell/ev-sidebar-thumbnails.h +++ b/shell/ev-sidebar-thumbnails.h @@ -56,4 +56,3 @@ G_END_DECLS #endif /* __EV_SIDEBAR_THUMBNAILS_H__ */ - diff --git a/shell/ev-sidebar.c b/shell/ev-sidebar.c index b9173cdd..f05721de 100644 --- a/shell/ev-sidebar.c +++ b/shell/ev-sidebar.c @@ -26,9 +26,13 @@ #include <string.h> +#include <glib.h> +#include <glib/gi18n.h> #include <gtk/gtk.h> #include <gdk/gdkkeysyms.h> +#include <libmate-desktop/mate-image-menu-item.h> + #include "ev-sidebar.h" #include "ev-sidebar-page.h" @@ -362,6 +366,7 @@ ev_sidebar_init (EvSidebar *ev_sidebar) g_signal_connect (close_button, "clicked", G_CALLBACK (ev_sidebar_close_clicked_cb), ev_sidebar); + gtk_widget_set_tooltip_text (close_button, _("Hide sidebar")); image = gtk_image_new_from_icon_name ("window-close", GTK_ICON_SIZE_MENU); @@ -424,7 +429,7 @@ ev_sidebar_add_page (EvSidebar *ev_sidebar, index = gtk_notebook_append_page (GTK_NOTEBOOK (ev_sidebar->priv->notebook), main_widget, NULL); - menu_item = gtk_image_menu_item_new_with_label (title); + menu_item = mate_image_menu_item_new_with_label (title); g_signal_connect (menu_item, "activate", G_CALLBACK (ev_sidebar_menu_item_activate_cb), ev_sidebar); @@ -443,7 +448,6 @@ ev_sidebar_add_page (EvSidebar *ev_sidebar, gtk_list_store_move_before(GTK_LIST_STORE(ev_sidebar->priv->page_model), &iter, NULL); - /* Set the first item added as active */ gtk_tree_model_get_iter_first (ev_sidebar->priv->page_model, &iter); gtk_tree_model_get (ev_sidebar->priv->page_model, diff --git a/shell/ev-sidebar.h b/shell/ev-sidebar.h index 11d16632..20a73e3a 100644 --- a/shell/ev-sidebar.h +++ b/shell/ev-sidebar.h @@ -64,4 +64,3 @@ G_END_DECLS #endif /* __EV_SIDEBAR_H__ */ - diff --git a/shell/ev-window.c b/shell/ev-window.c index 348e62b9..1023f545 100644 --- a/shell/ev-window.c +++ b/shell/ev-window.c @@ -47,6 +47,7 @@ #include "egg-toolbars-model.h" #include "eggfindbar.h" +#include "ev-find-sidebar.h" #include "ephy-zoom-action.h" #include "ephy-zoom.h" @@ -144,6 +145,7 @@ struct _EvWindowPrivate { GtkWidget *password_view; GtkWidget *sidebar_thumbs; GtkWidget *sidebar_links; + GtkWidget *find_sidebar; GtkWidget *sidebar_attachments; GtkWidget *sidebar_layers; GtkWidget *sidebar_annots; @@ -384,6 +386,9 @@ static void zoom_control_changed_cb (EphyZoomAction *action, float zoom, EvWindow *ev_window); +static void ev_window_show_find_bar (EvWindow *ev_window); +static void ev_window_close_find_bar (EvWindow *ev_window); + static gchar *caja_sendto = NULL; G_DEFINE_TYPE_WITH_PRIVATE (EvWindow, ev_window, GTK_TYPE_APPLICATION_WINDOW) @@ -418,7 +423,6 @@ ev_window_set_action_sensitive (EvWindow *ev_window, G_GNUC_END_IGNORE_DEPRECATIONS; } - static void ev_window_setup_action_sensitivity (EvWindow *ev_window) { @@ -538,7 +542,7 @@ ev_window_update_actions (EvWindow *ev_window) page = ev_document_model_get_page (ev_window->priv->model); n_pages = ev_document_get_n_pages (ev_window->priv->document); has_pages = n_pages > 0; - dual_mode = ev_document_model_get_dual_page (ev_window->priv->model); + dual_mode = ev_document_model_get_page_layout (ev_window->priv->model); } #if ENABLE_EPUB if (ev_window->priv->document && ev_window->priv->document->iswebdocument == TRUE ) { @@ -1555,7 +1559,6 @@ ev_window_setup_default (EvWindow *ev_window) ev_document_model_set_scale (model, g_settings_get_double (settings, "zoom")); } - static void ev_window_clear_thumbnail_job (EvWindow *ev_window) { @@ -1594,7 +1597,8 @@ ev_window_refresh_window_thumbnail (EvWindow *ev_window) EvDocument *document = ev_window->priv->document; if (!document || ev_document_get_n_pages (document) <= 0 || - !ev_document_check_dimensions (document)) { + !ev_document_check_dimensions (document) || + document->iswebdocument) { return; } @@ -1733,7 +1737,7 @@ ev_window_setup_document (EvWindow *ev_window) if (EV_IS_DOCUMENT_FIND (document)) { if (ev_window->priv->search_string && !EV_WINDOW_IS_PRESENTATION (ev_window)) { - ev_window_cmd_edit_find (NULL, ev_window); + ev_window_show_find_bar (ev_window); egg_find_bar_set_search_string (EGG_FIND_BAR (ev_window->priv->find_bar), ev_window->priv->search_string); } @@ -1787,6 +1791,14 @@ ev_window_set_document (EvWindow *ev_window, EvDocument *document) ev_view_disconnect_handlers(EV_VIEW(ev_window->priv->view)); g_object_unref(ev_window->priv->view); ev_window->priv->view = NULL; + + if (ev_window->priv->webview == NULL) + { + ev_window->priv->webview = ev_web_view_new(); + ev_web_view_set_model(EV_WEB_VIEW(ev_window->priv->webview),ev_window->priv->model); + ev_web_view_reload(EV_WEB_VIEW(ev_window->priv->webview)); + } + gtk_container_add (GTK_CONTAINER (ev_window->priv->scrolled_window), ev_window->priv->webview); gtk_widget_show(ev_window->priv->webview); @@ -2166,6 +2178,19 @@ show_loading_progress (EvWindow *ev_window) return FALSE; } +#if !GLIB_CHECK_VERSION(2, 62, 0) +/* Non-year-2038-proof compatibility with GLib < 2.62 */ +static GDateTime * +_g_file_info_get_modification_date_time (GFileInfo *info) +{ + GTimeVal mtime; + + g_file_info_get_modification_time (info, &mtime); + return g_date_time_new_from_timeval_utc (&mtime); +} +#define g_file_info_get_modification_date_time _g_file_info_get_modification_date_time +#endif + static void ev_window_load_remote_failed (EvWindow *ev_window, GError *error) @@ -2487,7 +2512,7 @@ ev_window_open_document (EvWindow *ev_window, if (search_string && EV_IS_DOCUMENT_FIND (document) && mode != EV_WINDOW_MODE_PRESENTATION) { - ev_window_cmd_edit_find (NULL, ev_window); + ev_window_show_find_bar (ev_window); egg_find_bar_set_search_string (EGG_FIND_BAR (ev_window->priv->find_bar), search_string); } @@ -3628,7 +3653,6 @@ ev_window_print_operation_done (EvPrintOperation *op, GtkWidget *dialog; GError *error = NULL; - ev_print_operation_get_error (op, &error); /* The message area is already used by @@ -3883,7 +3907,6 @@ ev_window_check_document_modified (EvWindow *ev_window) return FALSE; } - text = g_markup_printf_escaped (_("Save a copy of document “%s” before closing?"), gtk_window_get_title (GTK_WINDOW (ev_window))); @@ -4184,32 +4207,61 @@ ev_window_cmd_edit_select_all (GtkAction *action, EvWindow *ev_window) } static void +ev_window_cmd_toggle_find (GtkAction *action, EvWindow *ev_window) +{ + gboolean show_find_bar; + + show_find_bar = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)); + if (show_find_bar) + ev_window_show_find_bar (ev_window); + else + ev_window_close_find_bar (ev_window); +} + +static void ev_window_cmd_edit_find (GtkAction *action, EvWindow *ev_window) { - if (ev_window->priv->document == NULL || !EV_IS_DOCUMENT_FIND (ev_window->priv->document)) { - g_error ("Find action should be insensitive since document doesn't support find"); - return; - } + ev_window_show_find_bar (ev_window); +} - if (EV_WINDOW_IS_PRESENTATION (ev_window)) - return; +static void +ev_window_find_previous (EvWindow *ev_window) +{ + ev_view_find_previous (EV_VIEW (ev_window->priv->view)); + ev_find_sidebar_previous (EV_FIND_SIDEBAR (ev_window->priv->find_sidebar)); +} - update_chrome_flag (ev_window, EV_CHROME_FINDBAR, TRUE); - update_chrome_visibility (ev_window); - gtk_widget_grab_focus (ev_window->priv->find_bar); +static void +ev_window_find_next (EvWindow *ev_window) +{ + ev_view_find_next (EV_VIEW (ev_window->priv->view)); + ev_find_sidebar_next (EV_FIND_SIDEBAR (ev_window->priv->find_sidebar)); +} + +static gboolean +find_next_idle_cb (EvWindow *ev_window) +{ + ev_window_find_next (ev_window); + return FALSE; } static void ev_window_cmd_edit_find_next (GtkAction *action, EvWindow *ev_window) { + gboolean find_bar_hidden; + if (EV_WINDOW_IS_PRESENTATION (ev_window)) return; - update_chrome_flag (ev_window, EV_CHROME_FINDBAR, TRUE); - update_chrome_visibility (ev_window); - gtk_widget_grab_focus (ev_window->priv->find_bar); + find_bar_hidden = !gtk_widget_get_visible (ev_window->priv->find_bar); + ev_window_show_find_bar (ev_window); + if (ev_window->priv->document && ev_window->priv->document->iswebdocument == FALSE) { - ev_view_find_next (EV_VIEW (ev_window->priv->view)); + /* Use idle to make sure view allocation happens before find */ + if (find_bar_hidden) + g_idle_add ((GSourceFunc)find_next_idle_cb, ev_window); + else + ev_window_find_next (ev_window); } #if ENABLE_EPUB else { @@ -4218,17 +4270,30 @@ ev_window_cmd_edit_find_next (GtkAction *action, EvWindow *ev_window) #endif } +static gboolean +find_previous_idle_cb (EvWindow *ev_window) +{ + ev_window_find_previous (ev_window); + return FALSE; +} + static void ev_window_cmd_edit_find_previous (GtkAction *action, EvWindow *ev_window) { + gboolean find_bar_hidden; + if (EV_WINDOW_IS_PRESENTATION (ev_window)) return; - update_chrome_flag (ev_window, EV_CHROME_FINDBAR, TRUE); - update_chrome_visibility (ev_window); - gtk_widget_grab_focus (ev_window->priv->find_bar); + find_bar_hidden = !gtk_widget_get_visible (ev_window->priv->find_bar); + ev_window_show_find_bar (ev_window); + if (ev_window->priv->document && ev_window->priv->document->iswebdocument == FALSE) { - ev_view_find_previous (EV_VIEW (ev_window->priv->view)); + /* Use idle to make sure view allocation happens before find */ + if (find_bar_hidden) + g_idle_add ((GSourceFunc)find_previous_idle_cb, ev_window); + else + ev_window_find_previous (ev_window); } #if ENABLE_EPUB else { @@ -4406,7 +4471,6 @@ ev_window_inhibit_screensaver (EvWindow *window) _("Running in presentation mode")); } - static void ev_window_uninhibit_screensaver (EvWindow *window) { @@ -4719,7 +4783,6 @@ ev_window_set_page_mode (EvWindow *window, ev_window_update_actions (window); } - static void ev_window_cmd_edit_rotate_left (GtkAction *action, EvWindow *ev_window) { @@ -4828,7 +4891,7 @@ ev_window_cmd_edit_save_settings (GtkAction *action, EvWindow *ev_window) g_settings_set_boolean (settings, "continuous", ev_document_model_get_continuous (model)); g_settings_set_boolean (settings, "dual-page", - ev_document_model_get_dual_page (model)); + ev_document_model_get_page_layout (model)); g_settings_set_boolean (settings, "dual-page-odd-left", ev_document_model_get_dual_page_odd_pages_left (model)); g_settings_set_boolean (settings, "fullscreen", @@ -5140,14 +5203,9 @@ ev_window_cmd_escape (GtkAction *action, EvWindow *window) widget = gtk_window_get_focus (GTK_WINDOW (window)); if (widget && gtk_widget_get_ancestor (widget, EGG_TYPE_FIND_BAR)) { - update_chrome_flag (window, EV_CHROME_FINDBAR, FALSE); - update_chrome_visibility (window); - - if (window->priv->view) - gtk_widget_grab_focus (window->priv->view); + ev_window_close_find_bar (window); #if ENABLE_EPUB - else - gtk_widget_grab_focus (window->priv->webview); + gtk_widget_grab_focus (window->priv->webview); #endif } else { gboolean fullscreen; @@ -5317,7 +5375,7 @@ ev_window_update_dual_page_action (EvWindow *window) g_signal_handlers_block_by_func (action, G_CALLBACK (ev_window_cmd_dual), window); gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), - ev_document_model_get_dual_page (window->priv->model)); + ev_document_model_get_page_layout (window->priv->model)); G_GNUC_END_IGNORE_DEPRECATIONS; g_signal_handlers_unblock_by_func (action, G_CALLBACK (ev_window_cmd_dual), window); @@ -5332,7 +5390,7 @@ ev_window_dual_mode_changed_cb (EvDocumentModel *model, if (ev_window->priv->metadata && !ev_window_is_empty (ev_window)) ev_metadata_set_boolean (ev_window->priv->metadata, "dual-page", - ev_document_model_get_dual_page (model)); + ev_document_model_get_page_layout (model)); } static void @@ -5730,6 +5788,15 @@ attachment_bar_menu_popup_cb (EvSidebarAttachments *attachbar, } static void +find_sidebar_result_activated_cb (EvFindSidebar *find_sidebar, + gint page, + gint result, + EvWindow *window) +{ + ev_view_find_set_result (EV_VIEW (window->priv->view), page, result); +} + +static void ev_window_update_find_status_message (EvWindow *ev_window) { gchar *message; @@ -5794,6 +5861,7 @@ ev_window_find_job_updated_cb (EvJobFind *job, page); } ev_window_update_find_status_message (ev_window); + ev_find_sidebar_update (EV_FIND_SIDEBAR (ev_window->priv->find_sidebar)); } static void @@ -5821,10 +5889,10 @@ find_bar_previous_cb (EggFindBar *find_bar, #if ENABLE_EPUB if (ev_window->priv->document && ev_window->priv->document->iswebdocument == TRUE ) { ev_web_view_find_previous(EV_WEB_VIEW(ev_window->priv->webview)); - }else + } else #endif { - ev_view_find_previous (EV_VIEW (ev_window->priv->view)); + ev_window_find_previous (ev_window); } } @@ -5838,7 +5906,7 @@ find_bar_next_cb (EggFindBar *find_bar, } else #endif { - ev_view_find_next (EV_VIEW (ev_window->priv->view)); + ev_window_find_next (ev_window); } } @@ -5850,14 +5918,8 @@ find_bar_close_cb (EggFindBar *find_bar, if (ev_window->priv->document && ev_window->priv->document->iswebdocument == TRUE ) { ev_web_view_find_cancel(EV_WEB_VIEW(ev_window->priv->webview)); } - else #endif - { - ev_view_find_cancel (EV_VIEW (ev_window->priv->view)); - } - ev_window_clear_find_job (ev_window); - update_chrome_flag (ev_window, EV_CHROME_FINDBAR, FALSE); - update_chrome_visibility (ev_window); + ev_window_close_find_bar (ev_window); } static void @@ -5880,6 +5942,9 @@ ev_window_search_start (EvWindow *ev_window) search_string, egg_find_bar_get_case_sensitive (find_bar)); + ev_find_sidebar_start (EV_FIND_SIDEBAR (ev_window->priv->find_sidebar), + EV_JOB_FIND (ev_window->priv->find_job)); + g_signal_connect (ev_window->priv->find_job, "finished", G_CALLBACK (ev_window_find_job_finished_cb), ev_window); @@ -5890,6 +5955,7 @@ ev_window_search_start (EvWindow *ev_window) } else { ev_window_update_actions (ev_window); egg_find_bar_set_status_text (find_bar, NULL); + ev_find_sidebar_clear (EV_FIND_SIDEBAR (ev_window->priv->find_sidebar)); if (ev_window->priv->document->iswebdocument == FALSE) { gtk_widget_queue_draw (GTK_WIDGET (ev_window->priv->view)); } @@ -5936,14 +6002,71 @@ find_bar_visibility_changed_cb (EggFindBar *find_bar, #endif ev_window_update_actions (ev_window); - if (visible) - ev_window_search_start (ev_window); - else + if (!visible) egg_find_bar_set_status_text (EGG_FIND_BAR (ev_window->priv->find_bar), NULL); } } static void +update_toggle_find_action (EvWindow *ev_window, + gboolean active) +{ + GtkAction *action; + + action = gtk_action_group_get_action (ev_window->priv->action_group, "EditFind"); + if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)) == active) + return; + + g_signal_handlers_block_by_func (action, G_CALLBACK (ev_window_cmd_toggle_find), ev_window); + gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), active); + g_signal_handlers_unblock_by_func (action, G_CALLBACK (ev_window_cmd_toggle_find), ev_window); +} + +static void +ev_window_show_find_bar (EvWindow *ev_window) +{ + if (gtk_widget_get_visible (ev_window->priv->find_bar)) + return; + + if (ev_window->priv->document == NULL || !EV_IS_DOCUMENT_FIND (ev_window->priv->document)) { + g_error ("Find action should be insensitive since document doesn't support find"); + return; + } + + if (EV_WINDOW_IS_PRESENTATION (ev_window)) + return; + + g_object_ref (ev_window->priv->sidebar); + gtk_container_remove (GTK_CONTAINER (ev_window->priv->hpaned), ev_window->priv->sidebar); + gtk_paned_pack1 (GTK_PANED (ev_window->priv->hpaned), + ev_window->priv->find_sidebar, FALSE, FALSE); + gtk_widget_show (ev_window->priv->find_sidebar); + + update_chrome_flag (ev_window, EV_CHROME_FINDBAR, TRUE); + update_chrome_visibility (ev_window); + gtk_widget_grab_focus (ev_window->priv->find_bar); + update_toggle_find_action (ev_window, TRUE); +} + +static void +ev_window_close_find_bar (EvWindow *ev_window) +{ + if (!gtk_widget_get_visible (ev_window->priv->find_bar)) + return; + + g_object_ref (ev_window->priv->find_sidebar); + gtk_container_remove (GTK_CONTAINER (ev_window->priv->hpaned), + ev_window->priv->find_sidebar); + gtk_paned_pack1 (GTK_PANED (ev_window->priv->hpaned), + ev_window->priv->sidebar, FALSE, FALSE); + + update_chrome_flag (ev_window, EV_CHROME_FINDBAR, FALSE); + update_chrome_visibility (ev_window); + gtk_widget_grab_focus (ev_window->priv->view); + update_toggle_find_action (ev_window, FALSE); +} + +static void zoom_control_changed_cb (EphyZoomAction *action, float zoom, EvWindow *ev_window) @@ -5969,7 +6092,6 @@ zoom_control_changed_cb (EphyZoomAction *action, * the new expanded window size. */ - if (ev_window->priv->chrome & EV_CHROME_SIDEBAR) { GtkAllocation alloc; @@ -6467,9 +6589,6 @@ static const GtkActionEntry entries[] = { G_CALLBACK (ev_window_cmd_edit_copy) }, { "EditSelectAll", "edit-select-all", N_("Select _All"), "<control>A", NULL, G_CALLBACK (ev_window_cmd_edit_select_all) }, - { "EditFind", "edit-find", N_("_Find…"), "<control>F", - N_("Find a word or phrase in the document"), - G_CALLBACK (ev_window_cmd_edit_find) }, { "EditFindNext", NULL, N_("Find Ne_xt"), "<control>G", NULL, G_CALLBACK (ev_window_cmd_edit_find_next) }, { "EditFindPrevious", NULL, N_("Find Pre_vious"), "<shift><control>G", NULL, @@ -6483,7 +6602,6 @@ static const GtkActionEntry entries[] = { { "EditSaveSettings", NULL, N_("Save Current Settings as _Default"), "<control>T", NULL, G_CALLBACK (ev_window_cmd_edit_save_settings) }, - /* View menu */ { "ViewZoomIn", "zoom-in", N_("Zoom _In"), "<control>plus", N_("Enlarge the document"), @@ -6624,6 +6742,9 @@ static const GtkToggleActionEntry toggle_entries[] = { N_("Activate or disable caret-navigation"), G_CALLBACK (ev_window_cmd_view_toggle_caret_navigation) }, + { "EditFind", GTK_STOCK_FIND, N_("_Find…"), "<control>F", + N_("Find a word or phrase in the document"), + G_CALLBACK (ev_window_cmd_toggle_find) }, }; /* Popups specific items */ @@ -7116,7 +7237,7 @@ do_action_named (EvWindow *window, EvLinkAction *action) } else if (g_ascii_strcasecmp (name, "GoToPage") == 0) { ev_window_cmd_focus_page_selector (NULL, window); } else if (g_ascii_strcasecmp (name, "Find") == 0) { - ev_window_cmd_edit_find (NULL, window); + ev_window_show_find_bar (window); } else if (g_ascii_strcasecmp (name, "Close") == 0) { ev_window_cmd_file_close_window (NULL, window); } else if (g_ascii_strcasecmp (name, "Print") == 0) { @@ -7738,7 +7859,6 @@ ev_window_emit_doc_loaded (EvWindow *window) ev_atril_window_emit_document_loaded (window->priv->skeleton, window->priv->uri); } - #ifdef ENABLE_SYNCTEX static gboolean handle_sync_view_cb (EvAtrilWindow *object, @@ -7792,7 +7912,6 @@ ev_window_init (EvWindow *ev_window) GtkCssProvider *css_provider; GError *error = NULL; GtkWidget *sidebar_widget; - GtkWidget *menuitem; GtkWidget *overlay; GObject *mpkeys; guint page_cache_mb; @@ -7928,12 +8047,6 @@ ev_window_init (EvWindow *ev_window) gtk_box_pack_start (GTK_BOX (ev_window->priv->main_box), ev_window->priv->menubar, FALSE, FALSE, 0); - menuitem = gtk_ui_manager_get_widget (ev_window->priv->ui_manager, - "/MainMenu/EditMenu/EditRotateLeftMenu"); - gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (menuitem), TRUE); - menuitem = gtk_ui_manager_get_widget (ev_window->priv->ui_manager, - "/MainMenu/EditMenu/EditRotateRightMenu"); - gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (menuitem), TRUE); ev_window->priv->toolbars_model = get_toolbars_model (); ev_window->priv->toolbar = GTK_WIDGET @@ -7966,6 +8079,12 @@ ev_window_init (EvWindow *ev_window) FALSE, FALSE, 0); gtk_widget_show (ev_window->priv->toolbar); + /* Find Bar */ + ev_window->priv->find_bar = egg_find_bar_new (); + gtk_box_pack_end (GTK_BOX (ev_window->priv->main_box), + ev_window->priv->find_bar, + FALSE, TRUE, 0); + /* Add the main area */ ev_window->priv->hpaned = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL); g_signal_connect (ev_window->priv->hpaned, @@ -8089,9 +8208,8 @@ ev_window_init (EvWindow *ev_window) ev_window->priv->view = ev_view_new (); -#if ENABLE_EPUB /*The webview, we won't add it now but it will replace the atril-view if a web(epub) document is encountered.*/ - ev_window->priv->webview = ev_web_view_new(); - ev_web_view_set_model(EV_WEB_VIEW(ev_window->priv->webview),ev_window->priv->model); +#if ENABLE_EPUB /* The webview is created in ev_window_set_document only if the document is a webdocument. */ + ev_window->priv->webview = NULL; #endif page_cache_mb = g_settings_get_uint (ev_window_ensure_settings (ev_window), GS_PAGE_CACHE_SIZE); @@ -8142,11 +8260,12 @@ ev_window_init (EvWindow *ev_window) gtk_widget_show (ev_window->priv->view); gtk_widget_show (ev_window->priv->password_view); - /* Find Bar */ - ev_window->priv->find_bar = egg_find_bar_new (); - gtk_box_pack_end (GTK_BOX (ev_window->priv->main_box), - ev_window->priv->find_bar, - FALSE, TRUE, 0); + /* Find results sidebar */ + ev_window->priv->find_sidebar = ev_find_sidebar_new (); + g_signal_connect (ev_window->priv->find_sidebar, + "result-activated", + G_CALLBACK (find_sidebar_result_activated_cb), + ev_window); /* We own a ref on these widgets, as we can swap them in and out */ g_object_ref (ev_window->priv->view); diff --git a/shell/ev-window.h b/shell/ev-window.h index 32d303aa..8e4dd9cf 100644 --- a/shell/ev-window.h +++ b/shell/ev-window.h @@ -58,7 +58,6 @@ typedef struct _EvWindowPrivate EvWindowPrivate; #define EV_IS_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), EV_TYPE_WINDOW)) #define EV_WINDOW_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS((object), EV_TYPE_WINDOW, EvWindowClass)) - struct _EvWindow { GtkApplicationWindow base_instance; EvWindowPrivate *priv; @@ -87,7 +86,6 @@ void ev_window_print_range (EvWindow *ev_window, int last_page); const gchar * ev_window_get_dbus_object_path (EvWindow *ev_window); - G_END_DECLS #endif /* !EV_WINDOW_H */ diff --git a/shell/main.c b/shell/main.c index 79b92524..321bdaa5 100644 --- a/shell/main.c +++ b/shell/main.c @@ -36,7 +36,6 @@ #include "eggsmclient.h" #include "eggdesktopfile.h" - static gchar *ev_page_label; static gchar *ev_find_string; static gint ev_page_index = 0; @@ -48,7 +47,6 @@ static gboolean unlink_temp_file = FALSE; static gchar *print_settings; static const char **file_arguments = NULL; - static gboolean option_version_cb (const gchar *option_name, const gchar *value, @@ -206,8 +204,6 @@ load_files (const char **files) continue; } - - ev_application_open_uri_at_dest (EV_APP, uri, screen, dest, mode, ev_find_string, GDK_CURRENT_TIME); @@ -285,7 +281,6 @@ main (int argc, char *argv[]) done: ev_shutdown (); - ev_stock_icons_shutdown (); g_object_unref (application); return status; diff --git a/shell/meson.build b/shell/meson.build new file mode 100644 index 00000000..17d093ec --- /dev/null +++ b/shell/meson.build @@ -0,0 +1,168 @@ +# Define include directories +include_dirs = include_directories( + '.', # Current directory + '..', # Parent directory + '../cut-n-paste/zoom-control', + '../cut-n-paste/toolbar-editor', + '../libdocument', + '../libview', + '../libmisc', + '../properties' +) + +# Define preprocessor definitions +c_args = [ + '-DATRILDATADIR="' + join_paths(get_option('prefix'), get_option('datadir'), 'atril') + '"', + '-DATRIL_COMPILATION' +] + +shell_sources = [ + 'eggfindbar.c', + 'eggfindbar.h', + 'ev-annotation-properties-dialog.h', + 'ev-annotation-properties-dialog.c', + 'ev-bookmarks.h', + 'ev-bookmarks.c', + 'ev-bookmark-action.h', + 'ev-bookmark-action.c', + 'ev-application.c', + 'ev-application.h', + 'ev-file-monitor.h', + 'ev-file-monitor.c', + 'ev-history.c', + 'ev-history.h', + 'ev-loading-message.h', + 'ev-loading-message.c', + 'ev-keyring.h', + 'ev-keyring.c', + 'ev-message-area.c', + 'ev-message-area.h', + 'ev-media-player-keys.h', + 'ev-media-player-keys.c', + 'ev-metadata.c', + 'ev-metadata.h', + 'ev-navigation-action.h', + 'ev-navigation-action.c', + 'ev-navigation-action-widget.h', + 'ev-navigation-action-widget.c', + 'ev-password-view.h', + 'ev-password-view.c', + 'ev-progress-message-area.h', + 'ev-progress-message-area.c', + 'ev-properties-dialog.c', + 'ev-properties-dialog.h', + 'ev-properties-fonts.c', + 'ev-properties-fonts.h', + 'ev-properties-license.c', + 'ev-properties-license.h', + 'ev-open-recent-action.c', + 'ev-open-recent-action.h', + 'ev-utils.c', + 'ev-utils.h', + 'ev-window.c', + 'ev-window.h', + 'ev-window-title.c', + 'ev-window-title.h', + 'ev-sidebar.c', + 'ev-sidebar.h', + 'ev-find-sidebar.c', + 'ev-find-sidebar.h', + 'ev-sidebar-annotations.c', + 'ev-sidebar-annotations.h', + 'ev-sidebar-attachments.c', + 'ev-sidebar-attachments.h', + 'ev-sidebar-bookmarks.h', + 'ev-sidebar-bookmarks.c', + 'ev-sidebar-layers.c', + 'ev-sidebar-layers.h', + 'ev-sidebar-links.c', + 'ev-sidebar-links.h', + 'ev-sidebar-page.c', + 'ev-sidebar-page.h', + 'ev-sidebar-thumbnails.c', + 'ev-sidebar-thumbnails.h', +] + +ev_resources = gnome.compile_resources( + 'atril-resources', + 'atril.gresource.xml', + source_dir: '../data', + c_name: 'ev', +) + +shell_sources += ev_resources + +atril_deps = [ + libdocument_dep, + config_h, + gio, + glib, + gtk, + libsecret, + math, + mate_desktop, + mate_submodules_dep, + libtoolbareditor_dep, + libevproperties_dep +] + +if get_option('enable_dbus') + dbus_generated = gnome.gdbus_codegen( + 'ev-gdbus-generated', + 'ev-gdbus.xml', + interface_prefix: 'org.mate.atril', + namespace: 'Ev', + object_manager: true, + ) + + shell_sources += dbus_generated + + # Generate the daemon D-Bus code + dbus_daemon_generated = gnome.gdbus_codegen( + 'ev-daemon-gdbus-generated', + 'ev-daemon-gdbus.xml', + interface_prefix: 'org.mate.atril', + namespace: 'Ev', + object_manager: true, + ) + + executable( + 'atrild', + sources: ['ev-daemon.c', ] + dbus_daemon_generated, + include_directories: include_dirs, + dependencies: atril_deps, + c_args: c_args, + install: true, + install_dir: libexecdir, + ) +endif + +libshell_deps = [ + atril_deps, + libview_dep, + libmisc_dep, + mate_submodules_dep, + libephyzoom_dep, +] + +libshell = static_library( + 'shell', + shell_sources, + dependencies: libshell_deps, + include_directories: include_dirs, +) + +libshell_dep = declare_dependency( + link_whole: libshell, # Need the whole lib for gresource lookup + dependencies: libshell_deps, + include_directories: include_dirs, +) + +atril = executable( + 'atril', + 'main.c', + dependencies: [libshell_dep] + atril_deps, + include_directories: include_dirs, + c_args: c_args, + install: true, +) |
