summaryrefslogtreecommitdiff
path: root/libview/ev-view.c
diff options
context:
space:
mode:
Diffstat (limited to 'libview/ev-view.c')
-rw-r--r--libview/ev-view.c101
1 files changed, 75 insertions, 26 deletions
diff --git a/libview/ev-view.c b/libview/ev-view.c
index f1d9f5f0..155e8a64 100644
--- a/libview/ev-view.c
+++ b/libview/ev-view.c
@@ -4234,30 +4234,19 @@ start_selection_for_event (EvView *view,
}
static gboolean
-position_caret_cursor_at_location (EvView *view,
- gdouble x,
- gdouble y)
+position_caret_cursor_at_doc_point (EvView *view,
+ gint page,
+ gdouble doc_x,
+ gdouble doc_y)
{
EvRectangle *areas = NULL;
guint n_areas = 0;
- gint page;
- gint offset = -1 ;
+ gint offset = -1;
gint first_line_offset;
gint last_line_offset = -1;
- gint doc_x, doc_y;
EvRectangle *rect;
guint i;
- if (!view->caret_enabled || view->rotation != 0)
- return FALSE;
-
- if (!view->page_cache)
- return FALSE;
-
- /* Get the offset from the doc point */
- if (!get_doc_point_from_location (view, x, y, &page, &doc_x, &doc_y))
- return FALSE;
-
ev_page_cache_get_text_layout (view->page_cache, page, &areas, &n_areas);
if (!areas)
return FALSE;
@@ -4332,6 +4321,27 @@ position_caret_cursor_at_location (EvView *view,
}
static gboolean
+position_caret_cursor_at_location (EvView *view,
+ gdouble x,
+ gdouble y)
+{
+ gint page;
+ gint doc_x, doc_y;
+
+ if (!view->caret_enabled || view->rotation != 0)
+ return FALSE;
+
+ if (!view->page_cache)
+ return FALSE;
+
+ /* Get the offset from the doc point */
+ if (!get_doc_point_from_location (view, x, y, &page, &doc_x, &doc_y))
+ return FALSE;
+
+ return position_caret_cursor_at_doc_point (view, page, doc_x, doc_y);
+}
+
+static gboolean
position_caret_cursor_for_event (EvView *view,
GdkEventButton *event)
{
@@ -5279,14 +5289,48 @@ extend_selection_from_cursor (EvView *view,
}
static gboolean
+cursor_clear_selection (EvView *view,
+ gboolean forward)
+{
+ GList *l;
+ EvViewSelection *selection;
+ cairo_rectangle_int_t rect;
+ gint doc_x, doc_y;
+
+ /* When clearing the selection, move the cursor to
+ * the limits of the selection region.
+ */
+ if (!view->selection_info.selections)
+ return FALSE;
+
+ l = forward ? g_list_last (view->selection_info.selections) : view->selection_info.selections;
+ selection = (EvViewSelection *)l->data;
+ if (!selection->covered_region || cairo_region_is_empty (selection->covered_region))
+ return FALSE;
+
+ cairo_region_get_rectangle (selection->covered_region,
+ forward ? cairo_region_num_rectangles (selection->covered_region) - 1 : 0,
+ &rect);
+
+ if (!get_doc_point_from_offset (view, selection->page,
+ forward ? rect.x + rect.width : rect.x,
+ rect.y + (rect.height / 2), &doc_x, &doc_y))
+ return FALSE;
+
+ position_caret_cursor_at_doc_point (view, selection->page, doc_x, doc_y);
+ return TRUE;
+}
+
+static gboolean
ev_view_move_cursor (EvView *view,
GtkMovementStep step,
gint count,
gboolean extend_selection)
{
GdkRectangle rect;
- gint prev_offset;
- gint prev_page;
+ gint prev_offset;
+ gint prev_page;
+ gboolean clearing_selections = FALSE;
if (!view->caret_enabled || view->rotation != 0)
return FALSE;
@@ -5299,13 +5343,17 @@ ev_view_move_cursor (EvView *view,
switch (step) {
case GTK_MOVEMENT_VISUAL_POSITIONS:
- while (count > 0) {
- cursor_forward_char (view);
- count--;
- }
- while (count < 0) {
- cursor_backward_char (view);
- count++;
+ if (!extend_selection && cursor_clear_selection (view, count > 0)) {
+ clearing_selections = TRUE;
+ } else {
+ while (count > 0) {
+ cursor_forward_char (view);
+ count--;
+ }
+ while (count < 0) {
+ cursor_backward_char (view);
+ count++;
+ }
}
break;
case GTK_MOVEMENT_WORDS:
@@ -5341,7 +5389,8 @@ ev_view_move_cursor (EvView *view,
ev_view_pend_cursor_blink (view);
/* Notify the user that it was not possible to move the caret cursor */
- if (prev_offset == view->cursor_offset && prev_page == view->cursor_page) {
+ if (!clearing_selections &&
+ prev_offset == view->cursor_offset && prev_page == view->cursor_page) {
gtk_widget_error_bell (GTK_WIDGET (view));
return TRUE;
}