summaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
Diffstat (limited to 'shell')
-rw-r--r--shell/Makefile.am2
-rw-r--r--shell/atril-ui.xml4
-rw-r--r--shell/eggfindbar.c68
-rw-r--r--shell/eggfindbar.h1
-rw-r--r--shell/ev-application.c16
-rw-r--r--shell/ev-bookmarks.h2
-rw-r--r--shell/ev-daemon.c1
-rw-r--r--shell/ev-find-sidebar.c681
-rw-r--r--shell/ev-find-sidebar.h63
-rw-r--r--shell/ev-history.c1
-rw-r--r--shell/ev-loading-message.c1
-rw-r--r--shell/ev-media-player-keys.h1
-rw-r--r--shell/ev-navigation-action.c3
-rw-r--r--shell/ev-open-recent-action.c5
-rw-r--r--shell/ev-password-view.c2
-rw-r--r--shell/ev-sidebar-annotations.c2
-rw-r--r--shell/ev-sidebar-attachments.c1
-rw-r--r--shell/ev-sidebar-bookmarks.c1
-rw-r--r--shell/ev-sidebar-layers.c1
-rw-r--r--shell/ev-sidebar-links.c158
-rw-r--r--shell/ev-sidebar-links.h1
-rw-r--r--shell/ev-sidebar-page.c1
-rw-r--r--shell/ev-sidebar-page.h1
-rw-r--r--shell/ev-sidebar-thumbnails.c7
-rw-r--r--shell/ev-sidebar-thumbnails.h1
-rw-r--r--shell/ev-sidebar.c8
-rw-r--r--shell/ev-sidebar.h1
-rw-r--r--shell/ev-window.c263
-rw-r--r--shell/ev-window.h2
-rw-r--r--shell/main.c5
-rw-r--r--shell/meson.build168
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,
+)