Merge lp:~jeremywootten/pantheon-files/fix-backspace-in-columnv-view into lp:~elementary-apps/pantheon-files/trunk
- fix-backspace-in-columnv-view
- Merge into 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 | ||||||||
Related bugs: |
|
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 : | # |
- 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
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 |
Conflicts with trunk