* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*/
-#include <config.h>
+#include "config.h"
+
#include <stdlib.h>
#include <math.h>
#include <string.h>
-#include <gtk/gtkalignment.h>
+
#include <glib/gi18n.h>
-#include <gtk/gtkbindings.h>
-#include <gtk/gtkselection.h>
-#include <gtk/gtkclipboard.h>
+#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
-#include "ev-marshal.h"
-#include "ev-view.h"
-#include "ev-view-private.h"
-#include "ev-utils.h"
-#include "ev-document-links.h"
-#include "ev-document-images.h"
-#include "ev-document-find.h"
-#include "ev-document-transition.h"
+#include "ev-application.h"
#include "ev-document-forms.h"
+#include "ev-document-images.h"
+#include "ev-document-links.h"
#include "ev-document-misc.h"
-#include "ev-job-queue.h"
+#include "ev-document-transition.h"
+#include "ev-marshal.h"
#include "ev-page-cache.h"
#include "ev-pixbuf-cache.h"
#include "ev-transition-animation.h"
+#include "ev-utils.h"
+#include "ev-view.h"
+#include "ev-view-private.h"
+
#if !GTK_CHECK_VERSION (2, 11, 7)
#include "ev-tooltip.h"
#endif
-#include "ev-application.h"
#define EV_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EV_TYPE_VIEW, EvViewClass))
#define EV_IS_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EV_TYPE_VIEW))
#define EV_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EV_TYPE_VIEW, EvViewClass))
-
enum {
PROP_0,
- PROP_FIND_STATUS,
PROP_CONTINUOUS,
PROP_DUAL_PAGE,
PROP_FULLSCREEN,
static void add_scroll_binding_keypad (GtkBindingSet *binding_set,
guint keyval,
GdkModifierType modifiers,
- EvScrollType scroll,
+ GtkScrollType scroll,
gboolean horizontal);
static void ensure_rectangle_is_visible (EvView *view,
GdkRectangle *rect);
GdkRectangle *expose_area);
/*** Callbacks ***/
-static void find_changed_cb (EvDocument *document,
- int page,
- EvView *view);
static void job_finished_cb (EvPixbufCache *pixbuf_cache,
GdkRegion *region,
EvView *view);
gint y);
/*** Find ***/
-static void update_find_status_message (EvView *view,
- gboolean this_page);
-static void ev_view_set_find_status (EvView *view,
- const char *message);
+static gint ev_view_find_get_n_results (EvView *view,
+ gint page);
+static EvRectangle *ev_view_find_get_result (EvView *view,
+ gint page,
+ gint result);
static void jump_to_find_result (EvView *view);
static void jump_to_find_page (EvView *view,
EvViewFindDirection direction,
GdkPoint *start,
GdkPoint *stop);
static void clear_selection (EvView *view);
+static void clear_link_selected (EvView *view);
static void selection_free (EvViewSelection *selection);
static char* get_selected_text (EvView *ev_view);
static void ev_view_primary_get_cb (GtkClipboard *clipboard,
add_scroll_binding_keypad (GtkBindingSet *binding_set,
guint keyval,
GdkModifierType modifiers,
- EvScrollType scroll,
+ GtkScrollType scroll,
gboolean horizontal)
{
guint keypad_keyval = keyval - GDK_Left + GDK_KP_Left;
gtk_binding_entry_add_signal (binding_set, keyval, modifiers,
"binding_activated", 2,
- EV_TYPE_SCROLL_TYPE, scroll,
+ GTK_TYPE_SCROLL_TYPE, scroll,
G_TYPE_BOOLEAN, horizontal);
gtk_binding_entry_add_signal (binding_set, keypad_keyval, modifiers,
"binding_activated", 2,
- EV_TYPE_SCROLL_TYPE, scroll,
+ GTK_TYPE_SCROLL_TYPE, scroll,
G_TYPE_BOOLEAN, horizontal);
}
void
ev_view_scroll (EvView *view,
- EvScrollType scroll,
- gboolean horizontal)
+ GtkScrollType scroll,
+ gboolean horizontal)
{
GtkAdjustment *adjustment;
double value, increment;
if (view->presentation || view->sizing_mode == EV_SIZING_BEST_FIT) {
switch (scroll) {
- case EV_SCROLL_PAGE_BACKWARD:
- case EV_SCROLL_STEP_BACKWARD:
+ case GTK_SCROLL_PAGE_BACKWARD:
+ case GTK_SCROLL_STEP_BACKWARD:
ev_view_previous_page (view);
break;
- case EV_SCROLL_PAGE_FORWARD:
- case EV_SCROLL_STEP_FORWARD:
+ case GTK_SCROLL_PAGE_FORWARD:
+ case GTK_SCROLL_STEP_FORWARD:
ev_view_next_page (view);
break;
default:
last_page = TRUE;
switch (scroll) {
- case EV_SCROLL_PAGE_BACKWARD:
+ case GTK_SCROLL_PAGE_BACKWARD:
/* Do not jump backwards if at the first page */
if (value == (adjustment->lower) && first_page) {
/* Do nothing */
value = MAX (value - increment, adjustment->lower);
}
break;
- case EV_SCROLL_PAGE_FORWARD:
+ case GTK_SCROLL_PAGE_FORWARD:
/* Do not jump forward if at the last page */
if (value == (adjustment->upper - adjustment->page_size) && last_page) {
/* Do nothing */
value = MIN (value + increment, adjustment->upper - adjustment->page_size);
}
break;
- case EV_SCROLL_STEP_BACKWARD:
+ case GTK_SCROLL_STEP_BACKWARD:
value -= adjustment->step_increment;
break;
- case EV_SCROLL_STEP_FORWARD:
+ case GTK_SCROLL_STEP_FORWARD:
value += adjustment->step_increment;
break;
- case EV_SCROLL_STEP_DOWN:
+ case GTK_SCROLL_STEP_DOWN:
value -= adjustment->step_increment / 10;
break;
- case EV_SCROLL_STEP_UP:
+ case GTK_SCROLL_STEP_UP:
value += adjustment->step_increment / 10;
break;
default:
} else {
if (view->cursor == EV_VIEW_CURSOR_LINK ||
view->cursor == EV_VIEW_CURSOR_IBEAM ||
- view->cursor == EV_VIEW_CURSOR_DRAG)
+ view->cursor == EV_VIEW_CURSOR_DRAG ||
+ view->cursor == EV_VIEW_CURSOR_AUTOSCROLL)
ev_view_set_cursor (view, EV_VIEW_CURSOR_NORMAL);
}
}
GList *forms_mapping;
forms_mapping = ev_pixbuf_cache_get_form_field_mapping (view->pixbuf_cache,
- field->page);
+ field->page->index);
ev_form_field_mapping_get_area (forms_mapping, field, &field_area);
- doc_rect_to_view_rect (view, field->page, &field_area, &view_area);
+ doc_rect_to_view_rect (view, field->page->index, &field_area, &view_area);
view_area.x -= view->scroll_x;
view_area.y -= view->scroll_y;
* we need to update also the region for the current selected item
*/
forms_mapping = ev_pixbuf_cache_get_form_field_mapping (view->pixbuf_cache,
- field->page);
+ field->page->index);
for (l = forms_mapping; l; l = g_list_next (l)) {
EvFormField *button = ((EvFormFieldMapping *)(l->data))->field;
GdkRegion *button_region;
ev_pixbuf_cache_reload_page (view->pixbuf_cache,
field_region,
- field->page,
+ field->page->index,
view->rotation,
view->scale);
gdk_region_destroy (field_region);
field->changed = FALSE;
ev_pixbuf_cache_reload_page (view->pixbuf_cache,
field_region,
- field->page,
+ field->page->index,
view->rotation,
view->scale);
gdk_region_destroy (field_region);
field->changed = FALSE;
ev_pixbuf_cache_reload_page (view->pixbuf_cache,
field_region,
- field->page,
+ field->page->index,
view->rotation,
view->scale);
gdk_region_destroy (field_region);
gint item;
item = gtk_combo_box_get_active (GTK_COMBO_BOX (widget));
- if (GPOINTER_TO_INT (field_choice->selected_items->data) != item) {
+ if (!field_choice->selected_items ||
+ GPOINTER_TO_INT (field_choice->selected_items->data) != item) {
g_list_free (field_choice->selected_items);
field_choice->selected_items = NULL;
field_choice->selected_items = g_list_prepend (field_choice->selected_items,
g_object_ref (field),
(GDestroyNotify)g_object_unref);
- form_field_mapping = ev_pixbuf_cache_get_form_field_mapping (view->pixbuf_cache, field->page);
+ form_field_mapping = ev_pixbuf_cache_get_form_field_mapping (view->pixbuf_cache, field->page->index);
ev_form_field_mapping_get_area (form_field_mapping, field, &field_area);
- doc_rect_to_view_rect (view, field->page, &field_area, &view_area);
+ doc_rect_to_view_rect (view, field->page->index, &field_area, &view_area);
view_area.x -= view->scroll_x;
view_area.y -= view->scroll_y;
continue;
form_field_mapping = ev_pixbuf_cache_get_form_field_mapping (view->pixbuf_cache,
- field->page);
+ field->page->index);
ev_form_field_mapping_get_area (form_field_mapping, field, &field_area);
- doc_rect_to_view_rect (view, field->page, &field_area, &view_area);
+ doc_rect_to_view_rect (view, field->page->index, &field_area, &view_area);
view_area.x -= view->scroll_x;
view_area.y -= view->scroll_y;
cairo_t *cr;
gint i;
- if (view->animation) {
+ if (view->animation && ev_transition_animation_ready (view->animation)) {
GdkRectangle page_area;
GtkBorder border;
draw_one_page (view, i, cr, &page_area, &border, &(event->area), &page_ready);
- if (page_ready && EV_IS_DOCUMENT_FIND (view->document) && view->highlight_find_results)
+ if (page_ready && view->find_pages && view->highlight_find_results)
highlight_find_results (view, i);
}
view->pressed_button = event->button;
view->selection_info.in_drag = FALSE;
+
+ if (view->scroll_info.autoscrolling)
+ return TRUE;
switch (event->button) {
case 1: {
-
- if (view->scroll_info.autoscrolling == TRUE) {
- view->scroll_info.autoscrolling = FALSE;
- return TRUE;
- }
-
EvImage *image;
EvFormField *field;
case 2:
/* use root coordinates as reference point because
* scrolling changes window relative coordinates */
- if (view->scroll_info.autoscrolling == TRUE) {
- view->scroll_info.autoscrolling = FALSE;
- return TRUE;
- }
view->drag_info.start.x = event->x_root;
view->drag_info.start.y = event->y_root;
view->drag_info.hadj = gtk_adjustment_get_value (view->hadjustment);
return TRUE;
case 3:
- if (!view->scroll_info.autoscrolling)
- view->scroll_info.start_y = event->y;
+ view->scroll_info.start_y = event->y;
return ev_view_do_popup_menu (view, event->x, event->y);
}
if (view->image_dnd_info.image) {
GdkPixbuf *pixbuf;
- pixbuf = ev_image_get_pixbuf (view->image_dnd_info.image);
+ ev_document_doc_mutex_lock ();
+ pixbuf = ev_document_images_get_image (EV_DOCUMENT_IMAGES (view->document),
+ view->image_dnd_info.image);
+ ev_document_doc_mutex_unlock ();
+
gtk_selection_data_set_pixbuf (selection_data, pixbuf);
+ g_object_unref (pixbuf);
}
break;
case TARGET_DND_URI:
if (view->image_dnd_info.image) {
+ GdkPixbuf *pixbuf;
const gchar *tmp_uri;
gchar **uris;
- tmp_uri = ev_image_save_tmp (view->image_dnd_info.image);
+ ev_document_doc_mutex_lock ();
+ pixbuf = ev_document_images_get_image (EV_DOCUMENT_IMAGES (view->document),
+ view->image_dnd_info.image);
+ ev_document_doc_mutex_unlock ();
+
+ tmp_uri = ev_image_save_tmp (view->image_dnd_info.image, pixbuf);
+ g_object_unref (pixbuf);
uris = g_new0 (gchar *, 2);
uris[0] = (gchar *)tmp_uri;
if (view->scroll_info.autoscrolling) {
view->scroll_info.last_y = y;
+ return TRUE;
}
if (view->selection_info.in_drag) {
}
}
- /* For the Evince 0.4.x release, we limit selection to un-rotated
- * documents only.
- */
- if (view->pressed_button == 1 && view->rotation == 0) {
+ switch (view->pressed_button) {
+ case 1:
+ /* For the Evince 0.4.x release, we limit selection to un-rotated
+ * documents only.
+ */
+ if (view->rotation != 0)
+ return FALSE;
/* Schedule timeout to scroll during selection and additionally
* scroll once to allow arbitrary speed. */
if (!view->selection_scroll_id)
- view->selection_scroll_id = g_timeout_add (SCROLL_TIME, (GSourceFunc)selection_scroll_timeout_cb, view);
+ view->selection_scroll_id = g_timeout_add (SCROLL_TIME,
+ (GSourceFunc)selection_scroll_timeout_cb,
+ view);
else
selection_scroll_timeout_cb (view);
view->selection_update_id = g_idle_add ((GSourceFunc)selection_update_idle_cb, view);
return TRUE;
- } else if (view->pressed_button == 2) {
+ case 2:
if (!view->drag_info.in_drag) {
gboolean start;
int i;
return TRUE;
}
- } else if (view->pressed_button <= 0) {
+
+ break;
+ default:
ev_view_handle_cursor_over_xy (view, x, y);
- return TRUE;
- }
+ }
return FALSE;
}
EvView *view = EV_VIEW (widget);
EvLink *link = NULL;
- view->drag_info.in_drag = FALSE;
view->image_dnd_info.in_drag = FALSE;
-
- view->drag_info.release_timeout_id = g_timeout_add (20,
- (GSourceFunc)ev_view_scroll_drag_release, view);
- if (view->pressed_button == 2) {
- ev_view_handle_cursor_over_xy (view, event->x, event->y);
+ if (view->scroll_info.autoscrolling) {
+ ev_view_autoscroll_stop (view);
+ view->pressed_button = -1;
+
+ return TRUE;
+ }
+
+ if (view->drag_info.in_drag) {
+ view->drag_info.release_timeout_id =
+ g_timeout_add (20,
+ (GSourceFunc)ev_view_scroll_drag_release, view);
}
- if (view->document && view->pressed_button != 3) {
+ if (view->document && !view->drag_info.in_drag && view->pressed_button != 3) {
link = ev_view_get_link_at_location (view, event->x, event->y);
}
+
+ view->drag_info.in_drag = FALSE;
+
+ if (view->pressed_button == 2) {
+ ev_view_handle_cursor_over_xy (view, event->x, event->y);
+ }
view->pressed_button = -1;
}
if (view->selection_info.selections) {
+ clear_link_selected (view);
ev_view_update_primary_selection (view);
if (view->selection_info.in_drag) {
g_signal_connect (view->goto_entry, "activate",
G_CALLBACK (ev_view_goto_entry_activate),
view);
- gtk_box_pack_start_defaults (GTK_BOX (hbox), view->goto_entry);
+ gtk_box_pack_start (GTK_BOX (hbox), view->goto_entry, TRUE, TRUE, 0);
gtk_widget_show (view->goto_entry);
gtk_widget_realize (view->goto_entry);
}
switch (event->keyval) {
case GDK_b:
case GDK_B:
+ case GDK_period:
+ case GDK_KP_Decimal:
view->presentation_state =
(view->presentation_state == EV_PRESENTATION_BLACK) ?
EV_PRESENTATION_NORMAL : EV_PRESENTATION_BLACK;
static void
highlight_find_results (EvView *view, int page)
{
- EvDocumentFind *find;
- int i, results = 0;
-
- find = EV_DOCUMENT_FIND (view->document);
+ gint i, n_results = 0;
- results = ev_document_find_get_n_results (find, page);
+ n_results = ev_view_find_get_n_results (view, page);
- for (i = 0; i < results; i++) {
- EvRectangle rectangle;
+ for (i = 0; i < n_results; i++) {
+ EvRectangle *rectangle;
GdkRectangle view_rectangle;
guchar alpha;
alpha = 0x20;
}
- ev_document_find_get_result (find, page, i, &rectangle);
- doc_rect_to_view_rect (view, page, &rectangle, &view_rectangle);
+ rectangle = ev_view_find_get_result (view, page, i);
+ doc_rect_to_view_rect (view, page, rectangle, &view_rectangle);
draw_rubberband (GTK_WIDGET (view), view->layout.bin_window,
&view_rectangle, alpha);
}
page_surface = ev_pixbuf_cache_get_surface (view->pixbuf_cache, page);
if (!page_surface) {
- draw_loading_text (view,
- &real_page_area,
- expose_area);
+ if (!view->presentation) {
+ draw_loading_text (view,
+ &real_page_area,
+ expose_area);
+ }
+
*page_ready = FALSE;
return;
{
EvView *view = EV_VIEW (object);
- g_free (view->find_status);
-
clear_selection (view);
+ clear_link_selected (view);
if (view->image_dnd_info.image)
g_object_unref (view->image_dnd_info.image);
EvView *view = EV_VIEW (object);
switch (prop_id) {
- case PROP_FIND_STATUS:
- g_value_set_string (value, view->find_status);
- break;
case PROP_CONTINUOUS:
g_value_set_boolean (value, view->continuous);
break;
G_TYPE_OBJECT);
- g_object_class_install_property (object_class,
- PROP_FIND_STATUS,
- g_param_spec_string ("find-status",
- "Find Status Message",
- "The find status message",
- NULL,
- G_PARAM_READABLE));
-
g_object_class_install_property (object_class,
PROP_CONTINUOUS,
g_param_spec_boolean ("continuous",
binding_set = gtk_binding_set_by_class (class);
- add_scroll_binding_keypad (binding_set, GDK_Left, 0, EV_SCROLL_STEP_BACKWARD, TRUE);
- add_scroll_binding_keypad (binding_set, GDK_Right, 0, EV_SCROLL_STEP_FORWARD, TRUE);
- add_scroll_binding_keypad (binding_set, GDK_Left, GDK_MOD1_MASK, EV_SCROLL_STEP_DOWN, TRUE);
- add_scroll_binding_keypad (binding_set, GDK_Right, GDK_MOD1_MASK, EV_SCROLL_STEP_UP, TRUE);
- add_scroll_binding_keypad (binding_set, GDK_Up, 0, EV_SCROLL_STEP_BACKWARD, FALSE);
- add_scroll_binding_keypad (binding_set, GDK_Down, 0, EV_SCROLL_STEP_FORWARD, FALSE);
- add_scroll_binding_keypad (binding_set, GDK_Up, GDK_MOD1_MASK, EV_SCROLL_STEP_DOWN, FALSE);
- add_scroll_binding_keypad (binding_set, GDK_Down, GDK_MOD1_MASK, EV_SCROLL_STEP_UP, FALSE);
- gtk_binding_entry_add_signal (binding_set, GDK_H, 0, "binding_activated", 2, EV_TYPE_SCROLL_TYPE,
- EV_SCROLL_STEP_BACKWARD, G_TYPE_BOOLEAN, TRUE);
- gtk_binding_entry_add_signal (binding_set, GDK_J, 0, "binding_activated", 2, EV_TYPE_SCROLL_TYPE,
- EV_SCROLL_STEP_FORWARD, G_TYPE_BOOLEAN, FALSE);
- gtk_binding_entry_add_signal (binding_set, GDK_K, 0, "binding_activated", 2, EV_TYPE_SCROLL_TYPE,
- EV_SCROLL_STEP_BACKWARD, G_TYPE_BOOLEAN, FALSE);
- gtk_binding_entry_add_signal (binding_set, GDK_L, 0, "binding_activated", 2, EV_TYPE_SCROLL_TYPE,
- EV_SCROLL_STEP_FORWARD, G_TYPE_BOOLEAN, TRUE);
+ add_scroll_binding_keypad (binding_set, GDK_Left, 0, GTK_SCROLL_STEP_BACKWARD, TRUE);
+ add_scroll_binding_keypad (binding_set, GDK_Right, 0, GTK_SCROLL_STEP_FORWARD, TRUE);
+ add_scroll_binding_keypad (binding_set, GDK_Left, GDK_MOD1_MASK, GTK_SCROLL_STEP_DOWN, TRUE);
+ add_scroll_binding_keypad (binding_set, GDK_Right, GDK_MOD1_MASK, GTK_SCROLL_STEP_UP, TRUE);
+ add_scroll_binding_keypad (binding_set, GDK_Up, 0, GTK_SCROLL_STEP_BACKWARD, FALSE);
+ add_scroll_binding_keypad (binding_set, GDK_Down, 0, GTK_SCROLL_STEP_FORWARD, FALSE);
+ add_scroll_binding_keypad (binding_set, GDK_Up, GDK_MOD1_MASK, GTK_SCROLL_STEP_DOWN, FALSE);
+ add_scroll_binding_keypad (binding_set, GDK_Down, GDK_MOD1_MASK, GTK_SCROLL_STEP_UP, FALSE);
+ gtk_binding_entry_add_signal (binding_set, GDK_H, 0, "binding_activated", 2, GTK_TYPE_SCROLL_TYPE,
+ GTK_SCROLL_STEP_BACKWARD, G_TYPE_BOOLEAN, TRUE);
+ gtk_binding_entry_add_signal (binding_set, GDK_J, 0, "binding_activated", 2, GTK_TYPE_SCROLL_TYPE,
+ GTK_SCROLL_STEP_FORWARD, G_TYPE_BOOLEAN, FALSE);
+ gtk_binding_entry_add_signal (binding_set, GDK_K, 0, "binding_activated", 2, GTK_TYPE_SCROLL_TYPE,
+ GTK_SCROLL_STEP_BACKWARD, G_TYPE_BOOLEAN, FALSE);
+ gtk_binding_entry_add_signal (binding_set, GDK_L, 0, "binding_activated", 2, GTK_TYPE_SCROLL_TYPE,
+ GTK_SCROLL_STEP_FORWARD, G_TYPE_BOOLEAN, TRUE);
}
/*** Callbacks ***/
-static void
-find_changed_cb (EvDocument *document, int page, EvView *view)
-{
- double percent;
- int n_pages;
-
- percent = ev_document_find_get_progress
- (EV_DOCUMENT_FIND (view->document));
- n_pages = ev_page_cache_get_n_pages (view->page_cache);
-
- if (view->jump_to_find_result == TRUE) {
- jump_to_find_page (view, EV_VIEW_FIND_NEXT, 0);
- jump_to_find_result (view);
- }
- update_find_status_message (view, percent * n_pages >= n_pages - 1 );
- if (view->current_page == page)
- gtk_widget_queue_draw (GTK_WIDGET (view));
-}
-
static void
ev_view_change_page (EvView *view,
gint new_page)
gtk_widget_queue_draw (GTK_WIDGET (view));
}
- if (EV_IS_DOCUMENT_FIND (view->document)) {
- view->find_result = 0;
- update_find_status_message (view, TRUE);
- }
+ view->find_result = 0;
}
static void
gtk_widget_queue_draw (GTK_WIDGET (view));
}
-static gboolean ev_view_autoscroll_cb (EvView *view)
+static gboolean
+ev_view_autoscroll_cb (EvView *view)
{
gdouble speed, value;
}
-void ev_view_autoscroll(EvView *view)
+void
+ev_view_autoscroll_start (EvView *view)
{
+ gint x, y;
+
+ g_return_if_fail (EV_IS_VIEW (view));
+
+ if (view->scroll_info.autoscrolling)
+ return;
+
view->scroll_info.autoscrolling = TRUE;
- view->scroll_info.timeout_id = g_timeout_add (20, (GSourceFunc)(ev_view_autoscroll_cb), view);
+ view->scroll_info.timeout_id =
+ g_timeout_add (20, (GSourceFunc)ev_view_autoscroll_cb,
+ view);
+
+ gtk_widget_get_pointer (GTK_WIDGET (view), &x, &y);
+ ev_view_handle_cursor_over_xy (view, x, y);
+}
+
+void
+ev_view_autoscroll_stop (EvView *view)
+{
+ gint x, y;
+
+ g_return_if_fail (EV_IS_VIEW (view));
+
+ if (!view->scroll_info.autoscrolling)
+ return;
+
+ view->scroll_info.autoscrolling = FALSE;
+ if (view->scroll_info.timeout_id) {
+ g_source_remove (view->scroll_info.timeout_id);
+ view->scroll_info.timeout_id = 0;
+ }
+
+ gtk_widget_get_pointer (GTK_WIDGET (view), &x, &y);
+ ev_view_handle_cursor_over_xy (view, x, y);
}
void
clear_caches (view);
if (view->document) {
- g_signal_handlers_disconnect_by_func (view->document,
- find_changed_cb,
- view);
g_object_unref (view->document);
view->page_cache = NULL;
-
}
view->document = document;
if (view->document) {
g_object_ref (view->document);
- if (EV_IS_DOCUMENT_FIND (view->document)) {
- g_signal_connect (view->document,
- "find_changed",
- G_CALLBACK (find_changed_cb),
- view);
- }
-
setup_caches (view);
}
duration = ev_document_transition_get_page_duration (EV_DOCUMENT_TRANSITION (view->document),
view->current_page);
if (duration > 0) {
-#if GLIB_CHECK_VERSION (2, 13, 0)
view->trans_timeout_id =
g_timeout_add_seconds (duration,
(GSourceFunc) transition_next_page,
view);
-#else
- view->trans_timeout_id =
- g_timeout_add (duration * 1000,
- (GSourceFunc) transition_next_page,
- view);
-#endif
}
}
}
/*** Find ***/
-static void
-update_find_status_message (EvView *view, gboolean this_page)
-{
- char *message;
-
- if (this_page) {
- int results;
-
- results = ev_document_find_get_n_results
- (EV_DOCUMENT_FIND (view->document),
- view->current_page);
- /* TRANS: Sometimes this could be better translated as
- "%d hit(s) on this page". Therefore this string
- contains plural cases. */
- message = g_strdup_printf (ngettext ("%d found on this page",
- "%d found on this page",
- results),
- results);
- } else {
- double percent;
-
- percent = ev_document_find_get_progress
- (EV_DOCUMENT_FIND (view->document));
- message = g_strdup_printf (_("%3d%% remaining to search"),
- (int) ((1.0 - percent) * 100));
-
- }
- ev_view_set_find_status (view, message);
- g_free (message);
-}
-
-const char *
-ev_view_get_find_status (EvView *view)
+static gint
+ev_view_find_get_n_results (EvView *view, gint page)
{
- g_return_val_if_fail (EV_IS_VIEW (view), NULL);
-
- return view->find_status;
+ return view->find_pages ? g_list_length (view->find_pages[page]) : 0;
}
-static void
-ev_view_set_find_status (EvView *view, const char *message)
+static EvRectangle *
+ev_view_find_get_result (EvView *view, gint page, gint result)
{
- g_return_if_fail (EV_IS_VIEW (view));
-
- g_free (view->find_status);
- view->find_status = g_strdup (message);
- g_object_notify (G_OBJECT (view), "find-status");
+ return view->find_pages ? (EvRectangle *) g_list_nth_data (view->find_pages[page], result) : NULL;
}
static void
jump_to_find_result (EvView *view)
{
- EvDocumentFind *find = EV_DOCUMENT_FIND (view->document);
- EvRectangle rect;
- GdkRectangle view_rect;
- int n_results;
- int page = view->current_page;
+ gint n_results;
+ gint page = view->current_page;
- n_results = ev_document_find_get_n_results (find, page);
+ n_results = ev_view_find_get_n_results (view, page);
- if (n_results > 0 && view->find_result < n_results) {
- ev_document_find_get_result
- (find, page, view->find_result, &rect);
+ if (n_results > 0 && view->find_result < n_results) {
+ EvRectangle *rect;
+ GdkRectangle view_rect;
- doc_rect_to_view_rect (view, page, &rect, &view_rect);
+ rect = ev_view_find_get_result (view, page, view->find_result);
+ doc_rect_to_view_rect (view, page, rect, &view_rect);
ensure_rectangle_is_visible (view, &view_rect);
}
}
n_pages = ev_page_cache_get_n_pages (view->page_cache);
for (i = 0; i < n_pages; i++) {
- int has_results;
int page;
if (direction == EV_VIEW_FIND_NEXT)
if (page >= n_pages) {
page = page - n_pages;
- }
- if (page < 0)
+ } else if (page < 0)
page = page + n_pages;
-
- has_results = ev_document_find_page_has_results
- (EV_DOCUMENT_FIND (view->document), page);
- if (has_results == -1) {
- break;
- } else if (has_results == 1) {
+
+ if (ev_view_find_get_n_results (view, page) > 0) {
ev_page_cache_set_current_page (view->page_cache, page);
break;
}
}
}
-gboolean
-ev_view_can_find_next (EvView *view)
+void
+ev_view_find_changed (EvView *view, GList **results, gint page)
{
- if (EV_IS_DOCUMENT_FIND (view->document)) {
- EvDocumentFind *find = EV_DOCUMENT_FIND (view->document);
- int i, n_pages;
-
- n_pages = ev_page_cache_get_n_pages (view->page_cache);
- for (i = 0; i < n_pages; i++) {
- if (ev_document_find_get_n_results (find, i) > 0) {
- return TRUE;
- }
- }
+ view->find_pages = results;
+
+ if (view->jump_to_find_result == TRUE) {
+ jump_to_find_page (view, EV_VIEW_FIND_NEXT, 0);
+ jump_to_find_result (view);
}
- return FALSE;
+ if (view->current_page == page)
+ gtk_widget_queue_draw (GTK_WIDGET (view));
}
void
ev_view_find_next (EvView *view)
{
- int n_results, n_pages;
- EvDocumentFind *find = EV_DOCUMENT_FIND (view->document);
-
- n_results = ev_document_find_get_n_results (find, view->current_page);
-
- n_pages = ev_page_cache_get_n_pages (view->page_cache);
+ gint n_results;
+ n_results = ev_view_find_get_n_results (view, view->current_page);
view->find_result++;
if (view->find_result >= n_results) {
-
view->find_result = 0;
jump_to_find_page (view, EV_VIEW_FIND_NEXT, 1);
jump_to_find_result (view);
}
}
-gboolean
-ev_view_can_find_previous (EvView *view)
-{
- if (EV_IS_DOCUMENT_FIND (view->document)) {
- EvDocumentFind *find = EV_DOCUMENT_FIND (view->document);
- int i, n_pages;
-
- n_pages = ev_page_cache_get_n_pages (view->page_cache);
- for (i = n_pages - 1; i >= 0; i--) {
- if (ev_document_find_get_n_results (find, i) > 0) {
- return TRUE;
- }
- }
- }
-
- return FALSE;
-}
void
ev_view_find_previous (EvView *view)
{
- int n_results, n_pages;
- EvDocumentFind *find = EV_DOCUMENT_FIND (view->document);
- EvPageCache *page_cache;
-
- page_cache = ev_page_cache_get (view->document);
-
- n_results = ev_document_find_get_n_results (find, view->current_page);
-
- n_pages = ev_page_cache_get_n_pages (page_cache);
-
view->find_result--;
if (view->find_result < 0) {
-
jump_to_find_page (view, EV_VIEW_FIND_PREV, -1);
- view->find_result = ev_document_find_get_n_results (find, view->current_page) - 1;
+ view->find_result = ev_view_find_get_n_results (view, view->current_page) - 1;
jump_to_find_result (view);
} else {
jump_to_find_result (view);
}
}
-void ev_view_search_changed (EvView *view)
+void
+ev_view_find_search_changed (EvView *view)
{
/* search string has changed, focus on new search result */
view->jump_to_find_result = TRUE;
+ view->find_pages = NULL;
}
-void ev_view_set_highlight_search (EvView *view, gboolean value)
+void
+ev_view_find_set_highlight_search (EvView *view, gboolean value)
{
view->highlight_find_results = value;
gtk_widget_queue_draw (GTK_WIDGET (view));
}
+void
+ev_view_find_cancel (EvView *view)
+{
+ view->find_pages = NULL;
+}
+
/*** Selections ***/
/* compute_new_selection_rect/text calculates the area currently selected by
EvRenderContext *rc;
text = g_string_new (NULL);
- rc = ev_render_context_new (view->rotation, 1, view->scale);
+ rc = ev_render_context_new (NULL, view->rotation, view->scale);
ev_document_doc_mutex_lock ();
for (l = view->selection_info.selections; l != NULL; l = l->next) {
EvViewSelection *selection = (EvViewSelection *)l->data;
+ EvPage *page;
gchar *tmp;
- ev_render_context_set_page (rc, selection->page);
+ page = ev_document_get_page (view->document, selection->page);
+ ev_render_context_set_page (rc, page);
+ g_object_unref (page);
+
tmp = ev_selection_get_selected_text (EV_SELECTION (view->document),
rc, selection->style,
&(selection->rect));
g_free (tmp);
}
- ev_document_doc_mutex_unlock ();
-
g_object_unref (rc);
+ ev_document_doc_mutex_unlock ();
+
normalized_text = g_utf8_normalize (text->str, text->len, G_NORMALIZE_NFKC);
g_string_free (text, TRUE);
return normalized_text;
}
+static void
+ev_view_clipboard_copy (EvView *view,
+ const gchar *text)
+{
+ GtkClipboard *clipboard;
+
+ clipboard = gtk_widget_get_clipboard (GTK_WIDGET (view),
+ GDK_SELECTION_CLIPBOARD);
+ gtk_clipboard_set_text (clipboard, text, -1);
+}
+
void
ev_view_copy (EvView *ev_view)
{
- GtkClipboard *clipboard;
char *text;
if (!EV_IS_SELECTION (ev_view->document))
return;
text = get_selected_text (ev_view);
- clipboard = gtk_widget_get_clipboard (GTK_WIDGET (ev_view),
- GDK_SELECTION_CLIPBOARD);
- gtk_clipboard_set_text (clipboard, text, -1);
+ ev_view_clipboard_copy (ev_view, text);
g_free (text);
}
gpointer data)
{
EvView *ev_view = EV_VIEW (data);
- char *text;
-
- if (!EV_IS_SELECTION (ev_view->document))
- return;
- text = get_selected_text (ev_view);
- if (text) {
- gtk_selection_data_set_text (selection_data, text, -1);
- g_free (text);
+ if (ev_view->link_selected) {
+ gtk_selection_data_set_text (selection_data,
+ ev_link_action_get_uri (ev_view->link_selected),
+ -1);
+ } else if (EV_IS_SELECTION (ev_view->document) &&
+ ev_view->selection_info.selections) {
+ gchar *text;
+
+ text = get_selected_text (ev_view);
+ if (text) {
+ gtk_selection_data_set_text (selection_data, text, -1);
+ g_free (text);
+ }
}
}
EvView *view = EV_VIEW (data);
clear_selection (view);
+ clear_link_selected (view);
}
static void
clipboard = gtk_widget_get_clipboard (GTK_WIDGET (ev_view),
GDK_SELECTION_PRIMARY);
- if (ev_view->selection_info.selections) {
+ if (ev_view->selection_info.selections || ev_view->link_selected) {
if (!gtk_clipboard_set_with_owner (clipboard,
clipboard_targets,
G_N_ELEMENTS (clipboard_targets),
}
}
+static void
+clear_link_selected (EvView *view)
+{
+ if (view->link_selected) {
+ g_object_unref (view->link_selected);
+ view->link_selected = NULL;
+ }
+}
+
+void
+ev_view_copy_link_address (EvView *view,
+ EvLinkAction *action)
+{
+ clear_link_selected (view);
+
+ ev_view_clipboard_copy (view, ev_link_action_get_uri (action));
+
+ view->link_selected = g_object_ref (action);
+ ev_view_update_primary_selection (view);
+}
+
/*** Cursor operations ***/
static GdkCursor *
return etype;
}
-GType
-ev_scroll_type_get_type (void)
-{
- static GType etype = 0;
- if (etype == 0) {
- static const GEnumValue values[] = {
- { EV_SCROLL_PAGE_FORWARD, "EV_SCROLL_PAGE_FORWARD", "scroll-page-forward" },
- { EV_SCROLL_PAGE_BACKWARD, "EV_SCROLL_PAGE_BACKWARD", "scroll-page-backward" },
- { EV_SCROLL_STEP_FORWARD, "EV_SCROLL_STEP_FORWARD", "scroll-step-forward" },
- { EV_SCROLL_STEP_FORWARD, "EV_SCROLL_STEP_FORWARD", "scroll-step-forward" },
- { EV_SCROLL_STEP_UP, "EV_SCROLL_STEP_UP", "scroll-step-up" },
- { EV_SCROLL_STEP_DOWN, "EV_SCROLL_STEP_DOWN", "scroll-step-down" },
- { 0, NULL, NULL }
- };
- etype = g_enum_register_static ("EvScrollType", values);
- }
- return etype;
-}
-
void
ev_view_update_view_size (EvView *view, GtkScrolledWindow * scrolled_window)
{