[evince/wip/find_results: 1/2] libview: add Model for find_results to EvJobFind.
- From: Jose Aliste <jaliste src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evince/wip/find_results: 1/2] libview: add Model for find_results to EvJobFind.
- Date: Thu, 10 Jan 2013 01:07:54 +0000 (UTC)
commit 6d09c5e323e2b23288117d6a2879161d7f18debb
Author: Josà Aliste <jaliste src gnome org>
Date: Wed Nov 7 16:02:21 2012 +0100
libview: add Model for find_results to EvJobFind.
libview/ev-jobs.c | 150 +++++++++++++++++++++++++++++++++++++++++-
libview/ev-jobs.h | 3 +
libview/ev-view-marshal.list | 1 +
libview/ev-view.c | 33 +++++++++
libview/ev-view.h | 3 +
5 files changed, 188 insertions(+), 2 deletions(-)
---
diff --git a/libview/ev-jobs.c b/libview/ev-jobs.c
index 63097d6..fb4a915 100644
--- a/libview/ev-jobs.c
+++ b/libview/ev-jobs.c
@@ -1512,6 +1512,138 @@ ev_job_save_new (EvDocument *document,
}
/* EvJobFind */
+static gchar *
+get_surrounding_text_markup (GtkTextIter *match_start,
+ GtkTextIter *match_end)
+{
+ gchar *match, *prec, *succ, *markup;
+ GtkTextIter surrounding_start = *match_start;
+ GtkTextIter surrounding_end = *match_end;
+
+ gtk_text_iter_backward_word_start (&surrounding_start);
+ gtk_text_iter_forward_word_ends (&surrounding_end, 2);
+
+ match = gtk_text_iter_get_text (match_start, match_end);
+ prec = gtk_text_iter_get_text (&surrounding_start, match_start);
+ succ = gtk_text_iter_get_text (match_end, &surrounding_end);
+
+ markup = g_markup_printf_escaped ("%s<span weight = \"bold\">%s</span>%s",
+ prec, match, succ);
+ g_free (match);
+ g_free (prec);
+ g_free (succ);
+
+ return markup;
+}
+
+static gchar *
+ev_job_find_get_matched_line (EvJob *job, EvPage *page, EvRectangle *match)
+{
+ EvRectangle r;
+ gchar *tmp, *result;
+
+ r = *match;
+ r.y1 = r.y2 = (r.y1 + r.y2)/2;
+ r.x1 = r.x2 = (r.x1 + r.x2)/2;
+
+ tmp = ev_selection_get_selected_text (
+ EV_SELECTION (job->document),
+ page,
+ EV_SELECTION_STYLE_LINE,
+ &r);
+ result = g_utf8_normalize (tmp, -1, G_NORMALIZE_ALL);
+ g_free (tmp);
+
+ return result;
+
+}
+
+static void
+ev_job_find_process_matches (EvJob *job)
+{
+ EvJobFind *job_find;
+ GList *matches;
+ EvPage *page;
+ GtkTreeIter iter;
+ gint occno, j, k;
+ gchar *matched_line, *text_to_find;
+ GtkTextBuffer *buffer;
+ GtkTextIter find_iter, start, end;
+ gchar *markup;
+
+ job_find = EV_JOB_FIND (job);
+ buffer = gtk_text_buffer_new (NULL);
+ matches = job_find->pages[job_find->current_page];
+
+ if (!matches)
+ return;
+
+
+ page = ev_document_get_page (job->document, job_find->current_page);
+
+ occno = 0;
+ j = 0;
+
+ if (job_find->case_sensitive)
+ text_to_find = g_strdup (job_find->text);
+ else
+ text_to_find = g_utf8_strdown (job_find->text, -1);
+
+ while (matches != NULL) {
+
+ matched_line = ev_job_find_get_matched_line (job, page, (EvRectangle *) matches->data);
+ g_assert (matched_line != NULL);
+
+ if (!job_find->case_sensitive) {
+ gchar *tmp = matched_line;
+
+ matched_line = g_utf8_strdown (tmp, -1);
+ g_free (tmp);
+ }
+
+ gtk_text_buffer_set_text (buffer, matched_line, -1);
+ gtk_text_buffer_get_start_iter (buffer, &find_iter);
+
+ /* search the proper occurrence of text in the line */
+ occno++;
+ for (k = 0; k < occno; k++ ) {
+ if (!gtk_text_iter_forward_search (&find_iter, text_to_find, 0, &start, &end, NULL))
+ break;
+ find_iter = end;
+ gtk_text_iter_forward_char (&find_iter);
+ }
+
+ /* additional search to determine that current match is the last one on the line */
+ if (!gtk_text_iter_forward_search (&find_iter, text_to_find, 0, NULL, NULL, NULL))
+ occno = 0;
+
+ markup = get_surrounding_text_markup (&start, &end);
+
+ if (job_find->current_page >= job_find->start_page) {
+ gtk_list_store_append (GTK_LIST_STORE (job_find->model), &iter);
+ } else {
+ gtk_list_store_insert (
+ GTK_LIST_STORE (job_find->model),
+ &iter,
+ job_find->insert_position);
+ job_find->insert_position++;
+ };
+ gtk_list_store_set (GTK_LIST_STORE (job_find->model), &iter,
+ 0, markup,
+ 1, job_find->current_page + 1,
+ 2, j,
+ - 1);
+
+ g_free (markup);
+ g_free (matched_line);
+
+ matches = g_list_next (matches);
+ j++;
+ }
+ g_free (text_to_find);
+
+}
+
static void
ev_job_find_init (EvJobFind *job)
{
@@ -1541,7 +1673,13 @@ ev_job_find_dispose (GObject *object)
g_free (job->pages);
job->pages = NULL;
}
-
+
+ if (job->model) {
+ gtk_list_store_clear (GTK_LIST_STORE (job->model));
+ g_object_unref (job->model);
+ job->model = NULL;
+ };
+
(* G_OBJECT_CLASS (ev_job_find_parent_class)->dispose) (object);
}
@@ -1570,12 +1708,15 @@ ev_job_find_run (EvJob *job)
job_find->options);
g_object_unref (ev_page);
- ev_document_doc_mutex_unlock ();
if (!job_find->has_results)
job_find->has_results = (matches != NULL);
job_find->pages[job_find->current_page] = matches;
+ ev_job_find_process_matches (job);
+
+ ev_document_doc_mutex_unlock ();
+
g_signal_emit (job_find, job_find_signals[FIND_UPDATED], 0, job_find->current_page);
job_find->current_page = (job_find->current_page + 1) % job_find->n_pages;
@@ -1633,6 +1774,11 @@ ev_job_find_new (EvDocument *document,
if (case_sensitive)
job->options |= EV_FIND_CASE_SENSITIVE;
+ job->model = (GtkTreeModel *)gtk_list_store_new (3,
+ G_TYPE_STRING,
+ G_TYPE_INT,
+ G_TYPE_INT);
+ job->insert_position = 0;
return EV_JOB (job);
}
diff --git a/libview/ev-jobs.h b/libview/ev-jobs.h
index cc9b7ad..8b4234d 100644
--- a/libview/ev-jobs.h
+++ b/libview/ev-jobs.h
@@ -392,6 +392,9 @@ struct _EvJobFind
gboolean case_sensitive;
gboolean has_results;
EvFindOptions options;
+
+ GtkTreeModel *model;
+ gint insert_position;
};
struct _EvJobFindClass
diff --git a/libview/ev-view-marshal.list b/libview/ev-view-marshal.list
index d7b0e75..cd02f42 100644
--- a/libview/ev-view-marshal.list
+++ b/libview/ev-view-marshal.list
@@ -1,2 +1,3 @@
VOID:ENUM,BOOLEAN
VOID:INT,INT
+VOID:POINTER,INT,INT
diff --git a/libview/ev-view.c b/libview/ev-view.c
index 7aa2c73..dfc4085 100644
--- a/libview/ev-view.c
+++ b/libview/ev-view.c
@@ -57,6 +57,7 @@ enum {
SIGNAL_SYNC_SOURCE,
SIGNAL_ANNOT_ADDED,
SIGNAL_LAYERS_CHANGED,
+ SIGNAL_FIND_RESULT_HIGHLIGHT_CHANGED,
N_SIGNALS
};
@@ -4875,6 +4876,15 @@ ev_view_class_init (EvViewClass *class)
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0,
G_TYPE_NONE);
+ signals[SIGNAL_FIND_RESULT_HIGHLIGHT_CHANGED] = g_signal_new ("find-result-highlight-changed",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ 0,
+ NULL, NULL,
+ ev_view_marshal_VOID__POINTER_INT_INT,
+ G_TYPE_NONE, 3,
+ G_TYPE_POINTER, G_TYPE_INT, G_TYPE_INT);
+
binding_set = gtk_binding_set_by_class (class);
@@ -4992,6 +5002,13 @@ ev_view_page_changed_cb (EvDocumentModel *model,
}
view->find_result = 0;
+
+ g_signal_emit (view,
+ signals[SIGNAL_FIND_RESULT_HIGHLIGHT_CHANGED],
+ 0,
+ view->find_pages,
+ new_page,
+ view->find_result);
}
static void
@@ -5821,6 +5838,13 @@ jump_to_find_result (EvView *view)
ensure_rectangle_is_visible (view, &view_rect);
view->jump_to_find_result = FALSE;
}
+
+ g_signal_emit (view,
+ signals[SIGNAL_FIND_RESULT_HIGHLIGHT_CHANGED],
+ 0,
+ view->find_pages,
+ page,
+ view->find_result);
}
/**
@@ -5927,6 +5951,15 @@ ev_view_find_previous (EvView *view)
}
void
+ev_view_find_arbitrary (EvView *view, gint page, gint result)
+{
+ ev_document_model_set_page (view->model, page);
+ view->find_result = result;
+ jump_to_find_page (view, EV_VIEW_FIND_NEXT, 0);
+ jump_to_find_result (view);
+}
+
+void
ev_view_find_search_changed (EvView *view)
{
/* search string has changed, focus on new search result */
diff --git a/libview/ev-view.h b/libview/ev-view.h
index f82dc9a..4ede1ec 100644
--- a/libview/ev-view.h
+++ b/libview/ev-view.h
@@ -75,6 +75,9 @@ void ev_view_find_started (EvView *view,
EvJobFind *job);
void ev_view_find_next (EvView *view);
void ev_view_find_previous (EvView *view);
+void ev_view_find_arbitrary (EvView *view,
+ gint page,
+ gint result);
void ev_view_find_search_changed (EvView *view);
void ev_view_find_set_highlight_search (EvView *view,
gboolean value);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]