diff options
author | Antia Puentes <[email protected]> | 2013-06-20 18:37:12 +0200 |
---|---|---|
committer | raveit65 <[email protected]> | 2017-09-06 18:25:34 +0200 |
commit | 2a5caa32b6a98cf6a0e34c8f5ec79f94060932b3 (patch) | |
tree | 3e241ef0513a26463a50ee624980b80bbe0e0bba | |
parent | 82dfff8ecf567c443d49569c76f69e91f1c7776e (diff) | |
download | atril-2a5caa32b6a98cf6a0e34c8f5ec79f94060932b3.tar.bz2 atril-2a5caa32b6a98cf6a0e34c8f5ec79f94060932b3.tar.xz |
libview: Text selection using the caret cursor.
https://bugzilla.gnome.org/show_bug.cgi?id=702073
origin commit:
https://git.gnome.org/browse/evince/commit/?h=gnome-3-10&id=a6e3834
-rw-r--r-- | libview/ev-view-marshal.list | 2 | ||||
-rw-r--r-- | libview/ev-view-private.h | 3 | ||||
-rw-r--r-- | libview/ev-view.c | 96 |
3 files changed, 77 insertions, 24 deletions
diff --git a/libview/ev-view-marshal.list b/libview/ev-view-marshal.list index 0ead4025..97bcc59f 100644 --- a/libview/ev-view-marshal.list +++ b/libview/ev-view-marshal.list @@ -1,3 +1,3 @@ VOID:ENUM,ENUM VOID:INT,INT -BOOLEAN:ENUM,INT +BOOLEAN:ENUM,INT,BOOLEAN diff --git a/libview/ev-view-private.h b/libview/ev-view-private.h index 696a043f..b91b54d6 100644 --- a/libview/ev-view-private.h +++ b/libview/ev-view-private.h @@ -258,7 +258,8 @@ struct _EvViewClass { void (*layers_changed) (EvView *view); gboolean (*move_cursor) (EvView *view, GtkMovementStep step, - gint count); + gint count, + gboolean extend_selection); }; void _get_page_size_for_scale_and_rotation (EvDocument *document, diff --git a/libview/ev-view.c b/libview/ev-view.c index fdbebed7..801dfda3 100644 --- a/libview/ev-view.c +++ b/libview/ev-view.c @@ -5186,11 +5186,31 @@ cursor_forward_line (EvView *view) return TRUE; } +static void +extend_selection_from_cursor (EvView *view, + GdkPoint *start_point, + GdkPoint *end_point) +{ + if (!(view->selection_info.in_selection && view->selection_info.selections)) { + clear_selection (view); + view->selection_info.start.x = start_point->x; + view->selection_info.start.y = start_point->y; + view->selection_info.in_selection = TRUE; + } + + compute_selections (view, + EV_SELECTION_STYLE_GLYPH, + &(view->selection_info.start), + end_point); +} + static gboolean ev_view_move_cursor (EvView *view, GtkMovementStep step, - gint count) + gint count, + gboolean extend_selection) { + GdkRectangle rect; gint prev_offset; gint prev_page; @@ -5246,24 +5266,41 @@ ev_view_move_cursor (EvView *view, ev_view_pend_cursor_blink (view); - /* If the caret cursor was updated, make it visible */ - if (prev_offset != view->cursor_offset || prev_page != view->cursor_page) { - GdkRectangle view_rect; + /* Notify the user that it was not possible to move the caret cursor */ + if (prev_offset == view->cursor_offset && prev_page == view->cursor_page) { + gtk_widget_error_bell (GTK_WIDGET (view)); + return TRUE; + } + + /* Scroll to make the caret visible */ + if (!get_caret_cursor_area (view, view->cursor_page, view->cursor_offset, &rect)) + return TRUE; - /* scroll to view the caret cursor */ - if (!get_caret_cursor_area (view, view->cursor_page, view->cursor_offset, &view_rect)) + rect.x += view->scroll_x; + rect.y += view->scroll_y; + + ev_document_model_set_page (view->model, view->cursor_page); + ensure_rectangle_is_visible (view, &rect); + + /* Select text */ + if (extend_selection && EV_IS_SELECTION (view->document)) { + GdkRectangle prev_rect; + GdkPoint start_point, end_point; + + if (!get_caret_cursor_area (view, prev_page, prev_offset, &prev_rect)) return TRUE; - view_rect.x += view->scroll_x; - view_rect.y += view->scroll_y; + start_point.x = prev_rect.x + view->scroll_x; + start_point.y = prev_rect.y + (prev_rect.height / 2) + view->scroll_y; - ev_document_model_set_page (view->model, view->cursor_page); - ensure_rectangle_is_visible (view, &view_rect); - gtk_widget_queue_draw (GTK_WIDGET (view)); - } else { - /* Notify the user that it was not possible to move the caret cursor */ - gtk_widget_error_bell (GTK_WIDGET (view)); - } + end_point.x = rect.x; + end_point.y = rect.y + rect.height / 2; + + extend_selection_from_cursor (view, &start_point, &end_point); + } else + clear_selection (view); + + gtk_widget_queue_draw (GTK_WIDGET (view)); return TRUE; } @@ -5976,13 +6013,27 @@ add_move_binding_keypad (GtkBindingSet *binding_set, guint keypad_keyval = keyval - GDK_KEY_Left + GDK_KEY_KP_Left; gtk_binding_entry_add_signal (binding_set, keyval, modifiers, - "move-cursor", 2, + "move-cursor", 3, GTK_TYPE_MOVEMENT_STEP, step, - G_TYPE_INT, count); + G_TYPE_INT, count, + G_TYPE_BOOLEAN, FALSE); gtk_binding_entry_add_signal (binding_set, keypad_keyval, modifiers, - "move-cursor", 2, + "move-cursor", 3, + GTK_TYPE_MOVEMENT_STEP, step, + G_TYPE_INT, count, + G_TYPE_BOOLEAN, FALSE); + + /* Selection-extending version */ + gtk_binding_entry_add_signal (binding_set, keyval, modifiers | GDK_SHIFT_MASK, + "move-cursor", 3, + GTK_TYPE_MOVEMENT_STEP, step, + G_TYPE_INT, count, + G_TYPE_BOOLEAN, TRUE); + gtk_binding_entry_add_signal (binding_set, keypad_keyval, modifiers | GDK_SHIFT_MASK, + "move-cursor", 3, GTK_TYPE_MOVEMENT_STEP, step, - G_TYPE_INT, count); + G_TYPE_INT, count, + G_TYPE_BOOLEAN, TRUE); } static void @@ -6116,10 +6167,11 @@ ev_view_class_init (EvViewClass *class) G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (EvViewClass, move_cursor), NULL, NULL, - ev_view_marshal_BOOLEAN__ENUM_INT, - G_TYPE_BOOLEAN, 2, + ev_view_marshal_BOOLEAN__ENUM_INT_BOOLEAN, + G_TYPE_BOOLEAN, 3, GTK_TYPE_MOVEMENT_STEP, - G_TYPE_INT); + G_TYPE_INT, + G_TYPE_BOOLEAN); binding_set = gtk_binding_set_by_class (class); |