Merge lp:~bratsche/oif/evince-drag-selection into lp:~oif-team/oif/evince-gestures-trunk

Proposed by Cody Russell
Status: Needs review
Proposed branch: lp:~bratsche/oif/evince-drag-selection
Merge into: lp:~oif-team/oif/evince-gestures-trunk
Diff against target: 345 lines (+203/-24)
3 files modified
libview/ev-view.c (+131/-9)
libview/ev-view.h (+11/-0)
shell/ev-window.c (+61/-15)
To merge this branch: bzr merge lp:~bratsche/oif/evince-drag-selection
Reviewer Review Type Date Requested Status
Duncan McGreggor (community) Needs Fixing
Review via email: mp+42545@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Duncan McGreggor (oubiwann) wrote :

I think that boulabiar mentioned this in another review, but the drag goes the wrong way for touch screen -- dragging left pans the substrate right, and vice versa.

Also, I noted that during pinch, one can't move the substrate, so we didn't get that for free. I'll update the related ticket.

review: Needs Fixing
Revision history for this message
Duncan McGreggor (oubiwann) wrote :

I'm trying to tap the icons in the tool bar (e.g., the previous and next buttons) and there's no response. Has that branch been merged yet? If not, disregard. If so, then there's a problem, 'case tap on the toolbar isn't working...

review: Needs Fixing
Revision history for this message
Duncan McGreggor (oubiwann) wrote :

Now, for the actual functionality implemented in this branch. I'm getting inaccurate selections of text. Here are the steps I'm taking:

 1. double tap to get selection mode
 2. drag my finger down to select text
 3. text selection is off by a little over a line in some areas, a few words in other areas, and several lines in others.

I thought this might be due to the finger overlapping the width of a line, so I zoomed in very large and tried it. In some instances, this actually made the results worse (the selection would jump several lines from where I actually touched).

review: Needs Fixing
Revision history for this message
Mohamed IKBEL Boulabiar (boulabiar) wrote :

> I think that boulabiar mentioned this in another review, but the drag goes the
> wrong way for touch screen -- dragging left pans the substrate right, and vice
> versa.

For this issue, it is corrected in this branch
https://code.launchpad.net/~boulabiar/evince/evince-drag-fixes

Revision history for this message
Duncan McGreggor (oubiwann) wrote :

Thanks, Ikbel. I'm assuming that even though you put this in the evince namespace, you actually branched from Cody's work, yes?

Cody, if you end up using this, please don't patch. Please merge Ikbel's branch to yours. This will preserve his contributions and history.

Thanks!

Unmerged revisions

4213. By Cody Russell

Remove unused commented code.

4212. By Cody Russell

Selection clearing on tap.

4211. By Cody Russell

Tap-and-drag selection

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'libview/ev-view.c'
2--- libview/ev-view.c 2010-11-30 05:18:17 +0000
3+++ libview/ev-view.c 2010-12-02 20:20:11 +0000
4@@ -267,7 +267,6 @@
5 EvSelectionStyle style,
6 GdkPoint *start,
7 GdkPoint *stop);
8-static void clear_selection (EvView *view);
9 static void clear_link_selected (EvView *view);
10 static void selection_free (EvViewSelection *selection);
11 static char* get_selected_text (EvView *ev_view);
12@@ -3526,7 +3525,7 @@
13 start_selection_for_event (EvView *view,
14 GdkEventButton *event)
15 {
16- clear_selection (view);
17+ ev_view_clear_selection (view);
18
19 view->selection_info.start.x = event->x + view->scroll_x;
20 view->selection_info.start.y = event->y + view->scroll_y;
21@@ -4085,7 +4084,7 @@
22 ev_view_update_primary_selection (view);
23
24 if (view->selection_info.in_drag) {
25- clear_selection (view);
26+ ev_view_clear_selection (view);
27 gtk_widget_queue_draw (widget);
28 }
29
30@@ -4511,7 +4510,7 @@
31 {
32 EvView *view = EV_VIEW (object);
33
34- clear_selection (view);
35+ ev_view_clear_selection (view);
36 clear_link_selected (view);
37
38 if (view->synctex_result) {
39@@ -5137,7 +5136,7 @@
40 ev_view_remove_all (view);
41
42 if (rotation != 0)
43- clear_selection (view);
44+ ev_view_clear_selection (view);
45 }
46
47 static void
48@@ -6056,8 +6055,8 @@
49 g_free (selection);
50 }
51
52-static void
53-clear_selection (EvView *view)
54+void
55+ev_view_clear_selection (EvView *view)
56 {
57 if (view->selection_info.selections) {
58 g_list_foreach (view->selection_info.selections, (GFunc)selection_free, NULL);
59@@ -6081,7 +6080,7 @@
60 if (view->rotation != 0)
61 return;
62
63- clear_selection (view);
64+ ev_view_clear_selection (view);
65
66 n_pages = ev_document_get_n_pages (view->document);
67 for (i = 0; i < n_pages; i++) {
68@@ -6104,6 +6103,129 @@
69 gtk_widget_queue_draw (GTK_WIDGET (view));
70 }
71
72+void
73+ev_view_begin_selection (EvView *view,
74+ gdouble x,
75+ gdouble y)
76+{
77+ GtkWidget *widget = GTK_WIDGET (view);
78+
79+ if (!view->document)
80+ return;
81+
82+ if (!gtk_widget_has_focus (widget))
83+ gtk_widget_grab_focus (widget);
84+
85+ if (view->window_child_focus) {
86+ EvAnnotationWindow *window;
87+ EvAnnotation *annot;
88+
89+ window = EV_ANNOTATION_WINDOW (view->window_child_focus->window);
90+ annot = ev_annotation_window_get_annotation (window);
91+ ev_annotation_window_ungrab_focus (window);
92+ view->window_child_focus = NULL;
93+ }
94+
95+ view->selection_info.in_drag = FALSE;
96+ view->selection_info.in_selection = TRUE;
97+
98+ if (EV_IS_SELECTION (view->document) && !view->selection_info.selections) {
99+ ev_view_clear_selection (view);
100+
101+ view->selection_info.start.x = x + view->scroll_x;
102+ view->selection_info.start.y = y + view->scroll_y;
103+ view->selection_info.style = EV_SELECTION_STYLE_GLYPH;
104+
105+ compute_selections (view,
106+ view->selection_info.style,
107+ &(view->selection_info.start),
108+ &(view->selection_info.start));
109+ }
110+}
111+
112+void
113+ev_view_update_selection (EvView *view,
114+ gdouble x,
115+ gdouble y)
116+{
117+ GdkWindow *bin_window;
118+
119+ if (!view->document)
120+ return;
121+
122+ bin_window = gtk_layout_get_bin_window (GTK_LAYOUT (view));
123+
124+ /* TODO: Handle DND stuff here. */
125+
126+ if (!view->selection_scroll_id)
127+ view->selection_scroll_id = g_timeout_add (SCROLL_TIME,
128+ (GSourceFunc)selection_scroll_timeout_cb,
129+ view);
130+ else
131+ selection_scroll_timeout_cb (view);
132+
133+ view->selection_info.in_selection = TRUE;
134+ view->motion.x = x + view->scroll_x;
135+ view->motion.y = y + view->scroll_y;
136+
137+ if (!view->selection_update_id)
138+ view->selection_update_id = g_idle_add ((GSourceFunc)selection_update_idle_cb, view);
139+}
140+
141+void
142+ev_view_end_selection (EvView *view,
143+ gdouble x,
144+ gdouble y)
145+{
146+ view->image_dnd_info.in_drag = FALSE;
147+
148+ if (view->scroll_info.autoscrolling) {
149+ ev_view_autoscroll_stop (view);
150+ return;
151+ }
152+
153+ if (view->drag_info.in_drag) {
154+ view->drag_info.release_timeout_id = g_timeout_add (20,
155+ (GSourceFunc)ev_view_scroll_drag_release, view);
156+ }
157+
158+ view->drag_info.in_drag = FALSE;
159+
160+ if (view->adding_annot) {
161+ view->adding_annot = FALSE;
162+ ev_view_handle_cursor_over_xy (view, x, y);
163+
164+ ev_view_create_annotation (view,
165+ view->adding_annot_type,
166+ x + view->scroll_x,
167+ y + view->scroll_y);
168+
169+ return;
170+ }
171+
172+ if (view->selection_scroll_id) {
173+ g_source_remove (view->selection_scroll_id);
174+ view->selection_scroll_id = 0;
175+ }
176+
177+ if (view->selection_update_id) {
178+ g_source_remove (view->selection_update_id);
179+ view->selection_update_id = 0;
180+ }
181+
182+ if (view->selection_info.selections) {
183+ clear_link_selected (view);
184+ ev_view_update_primary_selection (view);
185+
186+ if (view->selection_info.in_drag) {
187+ ev_view_clear_selection (view);
188+ gtk_widget_queue_draw (GTK_WIDGET (view));
189+ }
190+
191+ view->selection_info.in_drag = FALSE;
192+ }
193+}
194+
195 gboolean
196 ev_view_get_has_selection (EvView *view)
197 {
198@@ -6196,7 +6318,7 @@
199 {
200 EvView *view = EV_VIEW (data);
201
202- clear_selection (view);
203+ ev_view_clear_selection (view);
204 clear_link_selected (view);
205 }
206
207
208=== modified file 'libview/ev-view.h'
209--- libview/ev-view.h 2010-11-30 05:18:17 +0000
210+++ libview/ev-view.h 2010-12-02 20:20:11 +0000
211@@ -62,6 +62,17 @@
212 void ev_view_select_all (EvView *view);
213 gboolean ev_view_get_has_selection (EvView *view);
214
215+void ev_view_begin_selection (EvView *view,
216+ gdouble x,
217+ gdouble y);
218+void ev_view_update_selection (EvView *view,
219+ gdouble x,
220+ gdouble y);
221+void ev_view_end_selection (EvView *view,
222+ gdouble x,
223+ gdouble y);
224+void ev_view_clear_selection (EvView *view);
225+
226 /* Page size */
227 gboolean ev_view_can_zoom_in (EvView *view);
228 void ev_view_zoom_in (EvView *view);
229
230=== modified file 'shell/ev-window.c'
231--- shell/ev-window.c 2010-11-30 15:09:59 +0000
232+++ shell/ev-window.c 2010-12-02 20:20:11 +0000
233@@ -225,6 +225,9 @@
234 gdouble pinch_start_x;
235 gdouble pinch_start_y;
236 gdouble pinch_start_radius;
237+
238+ guint32 last_tap;
239+ gboolean in_selection;
240 };
241
242 #define EV_WINDOW_GET_PRIVATE(object) \
243@@ -5448,6 +5451,15 @@
244 priv->drag_start_x = drag->position_x;
245 priv->drag_start_y = drag->position_y;
246
247+
248+ if (drag->timestamp - priv->last_tap < 500 &&
249+ drag->fingers == 1) {
250+ priv->in_selection = TRUE;
251+ ev_view_begin_selection (EV_VIEW (priv->view),
252+ drag->focus_x,
253+ drag->focus_y);
254+ }
255+
256 break;
257 }
258
259@@ -5468,18 +5480,26 @@
260 case GRIP_GESTURE_DRAG: {
261 GripEventGestureDrag *drag = (GripEventGestureDrag *)event;
262
263- if (drag->velocity_y >= 1.0 &&
264- drag->position_y > priv->drag_start_y) {
265- ev_window_cmd_go_next_page (NULL, EV_WINDOW (window));
266- } else if (drag->velocity_y <= -1.0 &&
267- drag->position_y < priv->drag_start_y) {
268- ev_window_cmd_go_previous_page (NULL, EV_WINDOW (window));
269- } else if (drag->velocity_x >= 1.0 &&
270- drag->position_x > priv->drag_start_x) {
271- ev_window_cmd_go_next_page (NULL, EV_WINDOW (window));
272- } else if (drag->velocity_x <= -1.0 &&
273- drag->position_x < priv->drag_start_x) {
274- ev_window_cmd_go_previous_page (NULL, EV_WINDOW (window));
275+ if (!priv->in_selection) {
276+ if (drag->velocity_y >= 1.0 &&
277+ drag->position_y > priv->drag_start_y) {
278+ ev_window_cmd_go_next_page (NULL, EV_WINDOW (window));
279+ } else if (drag->velocity_y <= -1.0 &&
280+ drag->position_y < priv->drag_start_y) {
281+ ev_window_cmd_go_previous_page (NULL, EV_WINDOW (window));
282+ } else if (drag->velocity_x >= 1.0 &&
283+ drag->position_x > priv->drag_start_x) {
284+ ev_window_cmd_go_next_page (NULL, EV_WINDOW (window));
285+ } else if (drag->velocity_x <= -1.0 &&
286+ drag->position_x < priv->drag_start_x) {
287+ ev_window_cmd_go_previous_page (NULL, EV_WINDOW (window));
288+ }
289+ } else {
290+ priv->in_selection = FALSE;
291+
292+ ev_view_end_selection (EV_VIEW (priv->view),
293+ drag->focus_x,
294+ drag->focus_y);
295 }
296
297 break;
298@@ -5524,12 +5544,31 @@
299 GripEventGestureDrag *drag = (GripEventGestureDrag *)event;
300
301 if (drag->fingers == 1) {
302- ev_view_drag (EV_VIEW (priv->view),
303- (gdouble)drag->delta_x,
304- (gdouble)-drag->delta_y);
305+ if (priv->in_selection) {
306+ ev_view_update_selection (EV_VIEW (priv->view),
307+ drag->position_x + drag->delta_x,
308+ drag->position_y + drag->delta_y);
309+ } else {
310+ ev_view_drag (EV_VIEW (priv->view),
311+ (gdouble)drag->delta_x,
312+ (gdouble)-drag->delta_y);
313+ }
314 }
315 }
316
317+ break;
318+
319+ case GRIP_GESTURE_TAP: {
320+ GripEventGestureTap *tap = (GripEventGestureTap *)event;
321+
322+ priv->last_tap = tap->timestamp;
323+
324+ ev_view_clear_selection (EV_VIEW (priv->view));
325+ gtk_widget_queue_draw (GTK_WIDGET (priv->view));
326+
327+ break;
328+ }
329+
330 default:
331 break;
332 }
333@@ -5574,6 +5613,13 @@
334 2,
335 ev_gesture_callback,
336 NULL, NULL);
337+
338+ grip_gesture_manager_register_window (manager,
339+ window,
340+ GRIP_GESTURE_TAP,
341+ 1,
342+ ev_gesture_callback,
343+ NULL, NULL);
344 }
345 }
346

Subscribers

People subscribed via source and target branches