Merge lp:~jeremywootten/pantheon-files/fix-backspace-in-columnv-view into lp:~elementary-apps/pantheon-files/trunk

Proposed by Jeremy Wootten
Status: Merged
Approved by: Cody Garver
Approved revision: 2031
Merged at revision: 2215
Proposed branch: lp:~jeremywootten/pantheon-files/fix-backspace-in-columnv-view
Merge into: lp:~elementary-apps/pantheon-files/trunk
Diff against target: 456 lines (+152/-52)
9 files modified
libcore/AbstractSlot.vala (+7/-2)
src/View/AbstractDirectoryView.vala (+11/-3)
src/View/AbstractTreeView.vala (+1/-1)
src/View/ColumnView.vala (+5/-2)
src/View/IconView.vala (+3/-3)
src/View/Miller.vala (+103/-27)
src/View/Slot.vala (+15/-8)
src/View/ViewContainer.vala (+6/-5)
src/View/Window.vala (+1/-1)
To merge this branch: bzr merge lp:~jeremywootten/pantheon-files/fix-backspace-in-columnv-view
Reviewer Review Type Date Requested Status
Zisu Andrei (community) Approve
Review via email: mp+290832@code.launchpad.net

Commit message

Fix behaviour of Miller View on pressing BackSpace and history buttons (lp:1074664 lp:1393053)

Description of the change

This branch changes the behaviour of Miller view in response to BackSpace key press and pressing the "Back" button. Instead of always making a new root view, if possible sub-folders are closed until the specified folder is reached.

To post a comment you must log in.
Revision history for this message
Cody Garver (codygarver) wrote :

Conflicts with trunk

2029. By Jeremy Wootten

Merge trunk to r2130

2030. By Jeremy Wootten

Close slots before destroying their container in Miller View to silence terminal warnings

Revision history for this message
Jeremy Wootten (jeremywootten) wrote :

Merged trunk and fixed subsequently noticed terminal warnings when truncating Miller View.

Revision history for this message
Cody Garver (codygarver) wrote :

Commented some code style issues in the diff

2031. By Jeremy Wootten

Fix code style

Revision history for this message
Jeremy Wootten (jeremywootten) wrote :

Code style fixed

Revision history for this message
Zisu Andrei (matzipan) wrote :

LGTM.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'libcore/AbstractSlot.vala'
2--- libcore/AbstractSlot.vala 2015-12-30 12:21:30 +0000
3+++ libcore/AbstractSlot.vala 2016-05-02 11:14:36 +0000
4@@ -32,11 +32,15 @@
5
6 protected set {_directory = value;}
7 }
8+
9+ public GOF.File file {
10+ get {return directory.file;}
11+ }
12 public GLib.File location {
13 get {return directory.location;}
14 }
15 public string uri {
16- get { return directory.file.uri;}
17+ get {return directory.file.uri;}
18 }
19 public bool can_create {get {return directory != null && !directory.is_trash;}}
20 public virtual bool locked_focus {
21@@ -70,7 +74,8 @@
22 public abstract unowned AbstractSlot? get_current_slot ();
23 public abstract void reload (bool non_local_only = false);
24 public abstract void grab_focus ();
25- public abstract void user_path_change_request (GLib.File loc, bool allow_mode_change = true);
26+ public abstract void user_path_change_request (GLib.File loc, bool allow_mode_change, bool make_root);
27+
28 public abstract void select_first_for_empty_selection ();
29 public abstract void select_glib_files (GLib.List<GLib.File> locations, GLib.File? focus_location);
30 protected abstract void make_view ();
31
32=== modified file 'src/View/AbstractDirectoryView.vala'
33--- src/View/AbstractDirectoryView.vala 2016-05-02 07:46:06 +0000
34+++ src/View/AbstractDirectoryView.vala 2016-05-02 11:14:36 +0000
35@@ -374,8 +374,16 @@
36 }
37
38 public void select_first_for_empty_selection () {
39- if (selected_files == null)
40- set_cursor (new Gtk.TreePath.from_indices (0), false, true, true);
41+ if (selected_files == null) {
42+ Idle.add_full (GLib.Priority.LOW, () => {
43+ if (!tree_frozen) {
44+ set_cursor (new Gtk.TreePath.from_indices (0), false, true, true);
45+ return false;
46+ } else {
47+ return true;
48+ }
49+ });
50+ }
51 }
52 public void select_glib_files (GLib.List<GLib.File> location_list, GLib.File? focus_location) {
53 unselect_all ();
54@@ -553,7 +561,7 @@
55 }
56 }
57
58- protected void select_gof_file (GOF.File file) {
59+ public void select_gof_file (GOF.File file) {
60 var iter = Gtk.TreeIter ();
61 if (!model.get_first_iter_for_file (file, out iter))
62 return; /* file not in model */
63
64=== modified file 'src/View/AbstractTreeView.vala'
65--- src/View/AbstractTreeView.vala 2016-04-27 11:49:47 +0000
66+++ src/View/AbstractTreeView.vala 2016-05-02 11:14:36 +0000
67@@ -251,7 +251,7 @@
68 }
69
70 protected override void scroll_to_cell (Gtk.TreePath? path, bool scroll_to_top) {
71- if (tree == null || path == null || slot.directory.permission_denied)
72+ if (tree == null || path == null || slot.directory.permission_denied || slot.directory.is_empty ())
73 return;
74
75 tree.scroll_to_cell (path, name_column, scroll_to_top, 0.5f, 0.5f);
76
77=== modified file 'src/View/ColumnView.vala'
78--- src/View/ColumnView.vala 2015-08-17 09:30:23 +0000
79+++ src/View/ColumnView.vala 2016-05-02 11:14:36 +0000
80@@ -94,9 +94,12 @@
81 /* Do not emit alert sound on left and right cursor keys in Miller View */
82 case Gdk.Key.Left:
83 case Gdk.Key.Right:
84- if (no_mods)
85+ case Gdk.Key.BackSpace:
86+ if (no_mods) {
87+ /* Pass event to MillerView */
88+ slot.colpane.key_press_event (event);
89 return true;
90-
91+ }
92 break;
93
94 default:
95
96=== modified file 'src/View/IconView.vala'
97--- src/View/IconView.vala 2016-04-30 11:18:13 +0000
98+++ src/View/IconView.vala 2016-05-02 11:14:36 +0000
99@@ -129,7 +129,7 @@
100 }
101
102 public override void unselect_all () {
103- tree.unselect_all ();
104+ tree.unselect_all ();
105 }
106
107 public override void select_path (Gtk.TreePath? path) {
108@@ -250,7 +250,7 @@
109 }
110
111 protected override void scroll_to_cell (Gtk.TreePath? path, bool scroll_to_top) {
112- if (tree == null || path == null || slot.directory.permission_denied)
113+ if (tree == null || path == null || slot.directory.permission_denied || slot.directory.is_empty ())
114 return;
115
116 tree.scroll_to_path (path, scroll_to_top, 0.5f, 0.5f);
117@@ -260,7 +260,7 @@
118 Gtk.CellRenderer renderer,
119 bool start_editing,
120 bool scroll_to_top) {
121- scroll_to_cell(path, scroll_to_top);
122+ scroll_to_cell (path, scroll_to_top);
123 tree.set_cursor (path, renderer, start_editing);
124 }
125
126
127=== modified file 'src/View/Miller.vala'
128--- src/View/Miller.vala 2015-12-30 12:21:30 +0000
129+++ src/View/Miller.vala 2016-05-02 11:14:36 +0000
130@@ -55,8 +55,6 @@
131 content_box.pack_start (scrolled_window);
132 content_box.show_all ();
133
134- colpane.add_events (Gdk.EventMask.KEY_RELEASE_MASK);
135- colpane.key_release_event.connect (on_key_released);
136 make_view ();
137 }
138
139@@ -98,6 +96,7 @@
140
141 if (host != null) {
142 truncate_list_after_slot (host);
143+ host.select_gof_file (slot.file);
144 host.colpane.add (hpane1);
145 slot.directory.init ();
146 } else
147@@ -108,11 +107,6 @@
148 if (slot_list.length () <= 0)
149 return;
150
151- /* destroy the nested slots */
152- ((Marlin.View.Slot)(slot)).colpane.@foreach ((w) => {
153- w.destroy ();
154- });
155-
156 uint n = slot.slot_number;
157
158 slot_list.@foreach ((s) => {
159@@ -122,6 +116,10 @@
160 }
161 });
162
163+ ((Marlin.View.Slot)(slot)).colpane.@foreach ((w) => {
164+ w.destroy ();
165+ });
166+
167 slot_list.nth (n).next = null;
168 calculate_total_width ();
169 current_slot = slot;
170@@ -144,13 +142,79 @@
171 /** Signal handling **/
172 /*********************/
173
174- public override void user_path_change_request (GLib.File loc, bool allow_mode_change = false) {
175- /* user request always make new root */
176- var slot = slot_list.first().data;
177- assert (slot != null);
178- truncate_list_after_slot (slot); /* Sets current slot */
179- root_location = loc;
180- slot.user_path_change_request (loc, false);
181+ public override void user_path_change_request (GLib.File loc, bool allow_mode_change = false, bool make_root = false) {
182+ /* Requests from history buttons, pathbar come here with make_root = false.
183+ * These do not create a new root and automatic mode change for icon directories is not allowed.
184+ * Requests from the sidebar have make_root = true
185+ */
186+ change_path (loc, make_root);
187+ }
188+
189+ private void change_path (GLib.File loc, bool make_root) {
190+ var first_slot = slot_list.first ().data;
191+ string root_uri = first_slot.uri;
192+ string target_uri = loc.get_uri ();
193+ bool found = false;
194+
195+ if (!make_root && target_uri.has_prefix (root_uri) && target_uri != root_uri) {
196+ /* Try to add location relative to each slot in turn, starting at end */
197+ var copy_slot_list = slot_list.copy ();
198+ copy_slot_list.reverse ();
199+ foreach (Marlin.View.Slot s in copy_slot_list) {
200+ if (add_relative_path (s, loc)) {
201+ found = true;
202+ break;
203+ }
204+ }
205+ }
206+
207+ /* If requested location is not a child of any slot, start a new tree */
208+ if (!found) {
209+ truncate_list_after_slot (first_slot);
210+ if (loc.get_uri () != first_slot.uri) {
211+ first_slot.user_path_change_request (loc, false, true);
212+ root_location = loc;
213+ /* Sidebar requests make_root true - first directory will be selected;
214+ * Go_up requests make_root false - previous directory will be selected
215+ */
216+ if (make_root) {
217+ first_slot.select_first_for_empty_selection ();
218+ }
219+ }
220+ }
221+ }
222+
223+ private bool add_relative_path (Marlin.View.Slot root, GLib.File loc) {
224+ if (root.location.get_uri () == loc.get_uri ()) {
225+ truncate_list_after_slot (root);
226+ return true;
227+ }
228+ string? relative_path = PF.FileUtils.escape_uri (root.location.get_relative_path (loc), false);
229+ if (relative_path != null && relative_path.length > 0) {
230+ truncate_list_after_slot (root);
231+ string [] dirs = relative_path.split (Path.DIR_SEPARATOR_S);
232+ string last_uri = root.uri;
233+ if (last_uri.has_suffix (Path.DIR_SEPARATOR_S))
234+ last_uri = last_uri.slice (0, -1);
235+
236+ foreach (string d in dirs) {
237+ if (d.length > 0) {
238+ last_uri = GLib.Path.build_path (Path.DIR_SEPARATOR_S, last_uri, d);
239+
240+ var last_slot = slot_list.last ().data;
241+ var file = GLib.File.new_for_uri (last_uri);
242+ var list = new List<File> ();
243+ list.prepend (file);
244+ last_slot.select_glib_files (list, file);
245+ Thread.usleep (100000);
246+ add_location (file, last_slot);
247+
248+ }
249+ }
250+ } else {
251+ return false;
252+ }
253+ return true;
254 }
255
256 private void connect_slot_signals (Slot slot) {
257@@ -160,6 +224,7 @@
258 slot.miller_slot_request.connect (on_miller_slot_request);
259 slot.size_change.connect (update_total_width);
260 slot.folder_deleted.connect (on_slot_folder_deleted);
261+ slot.colpane.key_press_event.connect (on_key_pressed);
262 slot.path_changed.connect (on_slot_path_changed);
263 }
264
265@@ -170,14 +235,18 @@
266 slot.miller_slot_request.disconnect (on_miller_slot_request);
267 slot.size_change.disconnect (update_total_width);
268 slot.folder_deleted.disconnect (on_slot_folder_deleted);
269+ slot.colpane.key_press_event.disconnect (on_key_pressed);
270 slot.path_changed.disconnect (on_slot_path_changed);
271 }
272
273 private void on_miller_slot_request (Marlin.View.Slot slot, GLib.File loc, bool make_root) {
274- if (make_root)
275- user_path_change_request (loc);
276- else
277+ if (make_root) {
278+ /* Start a new tree with root at loc */
279+ change_path (loc, true);
280+ } else {
281+ /* Just add another column to the end. */
282 add_location (loc, slot);
283+ }
284 }
285
286 private bool on_slot_horizontal_scroll_event (double delta_x) {
287@@ -251,7 +320,7 @@
288 }
289 }
290
291- private bool on_key_released (Gtk.Widget box, Gdk.EventKey event) {
292+ private bool on_key_pressed (Gtk.Widget box, Gdk.EventKey event) {
293 /* Only handle unmodified keys */
294 if ((event.state & Gtk.accelerator_get_default_mod_mask ()) > 0)
295 return false;
296@@ -292,23 +361,30 @@
297 return true;
298 }
299 break;
300+
301+ case Gdk.Key.BackSpace:
302+ if (current_position > 0)
303+ truncate_list_after_slot (slot_list.nth_data (current_position - 1));
304+ else {
305+ ctab.go_up ();
306+ return true;
307+ }
308+ break;
309+
310+ default:
311+ break;
312 }
313
314 if (to_activate != null) {
315 to_activate.active ();
316 to_activate.select_first_for_empty_selection ();
317- return true;
318- } else
319- return false;
320+ }
321+
322+ return false;
323 }
324
325 private void on_slot_frozen_changed (Slot slot, bool frozen) {
326- /* Ensure all slots synchronise the frozen state and
327- * suppress key press event processing when frozen */
328- if (frozen)
329- this.colpane.key_release_event.disconnect (on_key_released);
330- else
331- this.colpane.key_release_event.connect (on_key_released);
332+ /* Ensure all slots synchronise the frozen state */
333
334 slot_list.@foreach ((abstract_slot) => {
335 var s = abstract_slot as Marlin.View.Slot;
336
337=== modified file 'src/View/Slot.vala'
338--- src/View/Slot.vala 2016-04-19 10:32:22 +0000
339+++ src/View/Slot.vala 2016-05-02 11:14:36 +0000
340@@ -186,25 +186,27 @@
341 directory.track_longest_name = true;
342 }
343
344+ /* This delay in passing on the path change request is necessary to prevent occasional crashes
345+ * due to undiagnosed bug.
346+ */
347 private void schedule_path_change_request (GLib.File loc, int flag, bool make_root) {
348 if (path_change_timeout_id > 0) {
349 warning ("Path change request received too rapidly");
350 return;
351 }
352 path_change_timeout_id = GLib.Timeout.add (20, () => {
353- on_path_change_request (loc, flag, make_root);
354+ on_dir_view_path_change_request (loc, flag, make_root);
355 path_change_timeout_id = 0;
356 return false;
357 });
358 }
359
360- private void on_path_change_request (GLib.File loc, int flag, bool make_root) {
361+ private void on_dir_view_path_change_request (GLib.File loc, int flag, bool make_root) {
362 if (flag == 0) { /* make view in existing container */
363- if (dir_view is FM.ColumnView) {
364- miller_slot_request (loc, make_root);
365- } else {
366- user_path_change_request (loc);
367- }
368+ if (mode == Marlin.ViewMode.MILLER_COLUMNS)
369+ miller_slot_request (loc, make_root); /* signal to parent MillerView */
370+ else
371+ user_path_change_request (loc, false, make_root); /* Handle ourselves */
372 } else
373 ctab.new_container_request (loc, flag);
374 }
375@@ -251,8 +253,8 @@
376 has_autosized = true;
377 }
378
379+ public override void user_path_change_request (GLib.File loc, bool allow_mode_change = true, bool make_root = true) {
380 /** Only this function must be used to change or reload the path **/
381- public override void user_path_change_request (GLib.File loc, bool allow_mode_change = true) {
382 assert (loc != null);
383 var old_dir = directory;
384 set_up_directory (loc);
385@@ -325,6 +327,11 @@
386 dir_view.select_glib_files (files, focus_location);
387 }
388
389+ public void select_gof_file (GOF.File gof) {
390+ if (dir_view != null)
391+ dir_view.select_gof_file (gof);
392+ }
393+
394 public override void select_first_for_empty_selection () {
395 if (dir_view != null)
396 dir_view.select_first_for_empty_selection ();
397
398=== modified file 'src/View/ViewContainer.vala'
399--- src/View/ViewContainer.vala 2016-04-24 17:37:30 +0000
400+++ src/View/ViewContainer.vala 2016-05-02 11:14:36 +0000
401@@ -148,9 +148,10 @@
402 var parent_path = PF.FileUtils.get_parent_path_from_path (location.get_uri ());
403 parent = PF.FileUtils.get_file_for_path (parent_path);
404 }
405+
406 /* Certain parents such as ftp:// will be returned as null as they are not browsable */
407 if (parent != null) {
408- user_path_change_request (parent);
409+ user_path_change_request (parent, false, false);
410 }
411 }
412
413@@ -159,7 +160,7 @@
414
415 if (loc != null) {
416 selected_locations.append (this.location);
417- user_path_change_request (File.new_for_commandline_arg (loc));
418+ user_path_change_request (File.new_for_commandline_arg (loc), false, false);
419 }
420 }
421
422@@ -167,7 +168,7 @@
423 string? loc = browser.go_forward (n);
424
425 if (loc != null)
426- user_path_change_request (File.new_for_commandline_arg (loc));
427+ user_path_change_request (File.new_for_commandline_arg (loc), false, false);
428 }
429
430 public void add_view (Marlin.ViewMode mode, GLib.File loc) {
431@@ -232,11 +233,11 @@
432 refresh_slot_info (slot.location);
433 }
434
435- private void user_path_change_request (GLib.File loc) {
436+ public void user_path_change_request (GLib.File loc, bool allow_mode_change = true, bool make_root = true) {
437 /* Ony call directly if it is known that a change of folder is required
438 * otherwise call focus_location.
439 */
440- view.user_path_change_request (loc);
441+ view.user_path_change_request (loc, allow_mode_change, make_root);
442 }
443
444 public void new_container_request (GLib.File loc, int flag = 1) {
445
446=== modified file 'src/View/Window.vala'
447--- src/View/Window.vala 2016-04-30 11:18:13 +0000
448+++ src/View/Window.vala 2016-05-02 11:14:36 +0000
449@@ -1001,7 +1001,7 @@
450 mwcols.add_location (gfile, mwcols.current_slot);
451 }
452 } else {
453- warning ("Invalid tip uri for Miller View");
454+ warning ("Invalid tip uri for Miller View %s", unescaped_tip_uri);
455 }
456 }
457

Subscribers

People subscribed via source and target branches

to all changes: