Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCarlos Garcia Campos <carlosgc@gnome.org>2010-06-28 09:43:06 (GMT)
committer Carlos Garcia Campos <carlosgc@gnome.org>2010-06-28 09:43:06 (GMT)
commit065ca13c80f87bdf729f906d0c6c47b0b55a4fb1 (patch)
tree2980c90041cd469058f01c3123167014df8534ed
parent2de1a33a123dea2aa16154e5beec5b3a57c939fc (diff)
[libview] Add support for synctex in EvView
- A signal with a source link is emitted on CTRL + click - A new public method has been added to highlight the view rectangle corresponding to a source link
-rw-r--r--libview/ev-view-private.h5
-rw-r--r--libview/ev-view.c108
-rw-r--r--libview/ev-view.h4
3 files changed, 115 insertions, 2 deletions
diff --git a/libview/ev-view-private.h b/libview/ev-view-private.h
index 0362bcd..79e6cdb 100644
--- a/libview/ev-view-private.h
+++ b/libview/ev-view-private.h
@@ -184,6 +184,9 @@ struct _EvView {
/* Annotations */
GList *window_children;
EvViewWindowChild *window_child_focus;
+
+ /* Synctex */
+ EvMapping *synctex_result;
};
struct _EvViewClass {
@@ -199,6 +202,8 @@ struct _EvViewClass {
void (*popup_menu) (EvView *view,
GList *items);
void (*selection_changed) (EvView *view);
+ void (*sync_source) (EvView *view,
+ EvSourceLink *link);
};
void _get_page_size_for_scale_and_rotation (EvDocument *document,
diff --git a/libview/ev-view.c b/libview/ev-view.c
index d1b6f33..a473d0a 100644
--- a/libview/ev-view.c
+++ b/libview/ev-view.c
@@ -54,6 +54,7 @@ enum {
SIGNAL_EXTERNAL_LINK,
SIGNAL_POPUP_MENU,
SIGNAL_SELECTION_CHANGED,
+ SIGNAL_SYNC_SOURCE,
N_SIGNALS
};
@@ -175,6 +176,8 @@ static AtkObject *ev_view_get_accessible (GtkWidget *widget)
/*** Drawing ***/
static void highlight_find_results (EvView *view,
int page);
+static void highlight_forward_search_results (EvView *view,
+ int page);
static void draw_one_page (EvView *view,
gint page,
cairo_t *cr,
@@ -253,7 +256,6 @@ static void jump_to_find_result (EvView
static void jump_to_find_page (EvView *view,
EvViewFindDirection direction,
gint shift);
-
/*** Selection ***/
static void compute_selections (EvView *view,
EvSelectionStyle style,
@@ -2735,6 +2737,32 @@ ev_view_handle_annotation (EvView *view,
}
}
+static gboolean
+ev_view_synctex_backward_search (EvView *view,
+ gdouble x,
+ gdouble y)
+{
+ gint page = -1;
+ gint x_new = 0, y_new = 0;
+ EvSourceLink *link;
+
+ if (!ev_document_has_synctex (view->document))
+ return FALSE;
+
+ if (!get_doc_point_from_location (view, x, y, &page, &x_new, &y_new))
+ return FALSE;
+
+ link = ev_document_synctex_backward_search (view->document, page, x_new, y_new);
+ if (link) {
+ g_signal_emit (view, signals[SIGNAL_SYNC_SOURCE], 0, link);
+ g_free (link);
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
/*** GtkWidget implementation ***/
static void
@@ -3138,6 +3166,8 @@ ev_view_expose_event (GtkWidget *widget,
highlight_find_results (view, i);
if (page_ready && EV_IS_DOCUMENT_ANNOTATIONS (view->document))
show_annotation_windows (view, i);
+ if (page_ready && view->synctex_result)
+ highlight_forward_search_results (view, i);
}
cairo_destroy (cr);
@@ -3334,6 +3364,9 @@ ev_view_button_press_event (GtkWidget *widget,
EvAnnotation *annot;
EvFormField *field;
+ if (event->state & GDK_CONTROL_MASK)
+ return ev_view_synctex_backward_search (view, event->x , event->y);
+
if (EV_IS_SELECTION (view->document) && view->selection_info.selections) {
if (event->type == GDK_3BUTTON_PRESS) {
start_selection_for_event (view, event);
@@ -3362,7 +3395,13 @@ ev_view_button_press_event (GtkWidget *widget,
view->image_dnd_info.start.y = event->y + view->scroll_y;
} else {
ev_view_remove_all (view);
-
+
+ if (view->synctex_result) {
+ g_free (view->synctex_result);
+ view->synctex_result = NULL;
+ gtk_widget_queue_draw (widget);
+ }
+
if (EV_IS_SELECTION (view->document))
start_selection_for_event (view, event);
}
@@ -3981,6 +4020,30 @@ highlight_find_results (EvView *view, int page)
}
static void
+highlight_forward_search_results (EvView *view, int page)
+{
+ GdkWindow *bin_window;
+ GdkRectangle rect;
+ cairo_t *cr;
+ EvMapping *mapping = view->synctex_result;
+
+ if (GPOINTER_TO_INT (mapping->data) != page)
+ return;
+
+ bin_window = gtk_layout_get_bin_window (GTK_LAYOUT (view));
+ doc_rect_to_view_rect (view, page, &mapping->area, &rect);
+
+ cr = gdk_cairo_create (bin_window);
+ cairo_set_source_rgb (cr, 1., 0., 0.);
+ cairo_rectangle (cr,
+ rect.x - view->scroll_x,
+ rect.y - view->scroll_y,
+ rect.width, rect.height);
+ cairo_stroke (cr);
+ cairo_destroy (cr);
+}
+
+static void
ev_view_loading_window_move (EvView *view)
{
GtkWidget *widget = GTK_WIDGET (view);
@@ -4184,6 +4247,11 @@ ev_view_finalize (GObject *object)
clear_selection (view);
clear_link_selected (view);
+ if (view->synctex_result) {
+ g_free (view->synctex_result);
+ view->synctex_result = NULL;
+ }
+
if (view->image_dnd_info.image)
g_object_unref (view->image_dnd_info.image);
view->image_dnd_info.image = NULL;
@@ -4362,6 +4430,14 @@ ev_view_class_init (EvViewClass *class)
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0,
G_TYPE_NONE);
+ signals[SIGNAL_SYNC_SOURCE] = g_signal_new ("sync-source",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (EvViewClass, sync_source),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1,
+ G_TYPE_POINTER);
binding_set = gtk_binding_set_by_class (class);
@@ -5274,6 +5350,34 @@ ev_view_find_cancel (EvView *view)
view->find_pages = NULL;
}
+/*** Synctex ***/
+void
+ev_view_highlight_forward_search (EvView *view,
+ EvSourceLink *link)
+{
+ EvMapping *mapping;
+ gint page;
+ GdkRectangle view_rect;
+
+ if (!ev_document_has_synctex (view->document))
+ return;
+
+ mapping = ev_document_synctex_forward_search (view->document, link);
+ if (!mapping)
+ return;
+
+ if (view->synctex_result)
+ g_free (view->synctex_result);
+ view->synctex_result = mapping;
+
+ page = GPOINTER_TO_INT (mapping->data);
+ ev_document_model_set_page (view->model, page);
+
+ doc_rect_to_view_rect (view, page, &mapping->area, &view_rect);
+ ensure_rectangle_is_visible (view, &view_rect);
+ gtk_widget_queue_draw (GTK_WIDGET (view));
+}
+
/*** Selections ***/
/* compute_new_selection_rect/text calculates the area currently selected by
diff --git a/libview/ev-view.h b/libview/ev-view.h
index 307793a..d4ee577 100644
--- a/libview/ev-view.h
+++ b/libview/ev-view.h
@@ -79,6 +79,10 @@ void ev_view_find_changed (EvView *view,
gint page);
void ev_view_find_cancel (EvView *view);
+/* Synctex */
+void ev_view_highlight_forward_search (EvView *view,
+ EvSourceLink *link);
+
/* Cursor */
void ev_view_hide_cursor (EvView *view);
void ev_view_show_cursor (EvView *view);