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
=== modified file 'libcore/AbstractSlot.vala'
--- libcore/AbstractSlot.vala 2015-12-30 12:21:30 +0000
+++ libcore/AbstractSlot.vala 2016-05-02 11:14:36 +0000
@@ -32,11 +32,15 @@
3232
33 protected set {_directory = value;}33 protected set {_directory = value;}
34 }34 }
35
36 public GOF.File file {
37 get {return directory.file;}
38 }
35 public GLib.File location {39 public GLib.File location {
36 get {return directory.location;}40 get {return directory.location;}
37 }41 }
38 public string uri {42 public string uri {
39 get { return directory.file.uri;}43 get {return directory.file.uri;}
40 }44 }
41 public bool can_create {get {return directory != null && !directory.is_trash;}}45 public bool can_create {get {return directory != null && !directory.is_trash;}}
42 public virtual bool locked_focus {46 public virtual bool locked_focus {
@@ -70,7 +74,8 @@
70 public abstract unowned AbstractSlot? get_current_slot ();74 public abstract unowned AbstractSlot? get_current_slot ();
71 public abstract void reload (bool non_local_only = false);75 public abstract void reload (bool non_local_only = false);
72 public abstract void grab_focus ();76 public abstract void grab_focus ();
73 public abstract void user_path_change_request (GLib.File loc, bool allow_mode_change = true);77 public abstract void user_path_change_request (GLib.File loc, bool allow_mode_change, bool make_root);
78
74 public abstract void select_first_for_empty_selection ();79 public abstract void select_first_for_empty_selection ();
75 public abstract void select_glib_files (GLib.List<GLib.File> locations, GLib.File? focus_location);80 public abstract void select_glib_files (GLib.List<GLib.File> locations, GLib.File? focus_location);
76 protected abstract void make_view ();81 protected abstract void make_view ();
7782
=== modified file 'src/View/AbstractDirectoryView.vala'
--- src/View/AbstractDirectoryView.vala 2016-05-02 07:46:06 +0000
+++ src/View/AbstractDirectoryView.vala 2016-05-02 11:14:36 +0000
@@ -374,8 +374,16 @@
374 }374 }
375375
376 public void select_first_for_empty_selection () {376 public void select_first_for_empty_selection () {
377 if (selected_files == null)377 if (selected_files == null) {
378 set_cursor (new Gtk.TreePath.from_indices (0), false, true, true);378 Idle.add_full (GLib.Priority.LOW, () => {
379 if (!tree_frozen) {
380 set_cursor (new Gtk.TreePath.from_indices (0), false, true, true);
381 return false;
382 } else {
383 return true;
384 }
385 });
386 }
379 }387 }
380 public void select_glib_files (GLib.List<GLib.File> location_list, GLib.File? focus_location) {388 public void select_glib_files (GLib.List<GLib.File> location_list, GLib.File? focus_location) {
381 unselect_all ();389 unselect_all ();
@@ -553,7 +561,7 @@
553 }561 }
554 }562 }
555563
556 protected void select_gof_file (GOF.File file) {564 public void select_gof_file (GOF.File file) {
557 var iter = Gtk.TreeIter ();565 var iter = Gtk.TreeIter ();
558 if (!model.get_first_iter_for_file (file, out iter))566 if (!model.get_first_iter_for_file (file, out iter))
559 return; /* file not in model */567 return; /* file not in model */
560568
=== modified file 'src/View/AbstractTreeView.vala'
--- src/View/AbstractTreeView.vala 2016-04-27 11:49:47 +0000
+++ src/View/AbstractTreeView.vala 2016-05-02 11:14:36 +0000
@@ -251,7 +251,7 @@
251 }251 }
252252
253 protected override void scroll_to_cell (Gtk.TreePath? path, bool scroll_to_top) {253 protected override void scroll_to_cell (Gtk.TreePath? path, bool scroll_to_top) {
254 if (tree == null || path == null || slot.directory.permission_denied)254 if (tree == null || path == null || slot.directory.permission_denied || slot.directory.is_empty ())
255 return;255 return;
256256
257 tree.scroll_to_cell (path, name_column, scroll_to_top, 0.5f, 0.5f);257 tree.scroll_to_cell (path, name_column, scroll_to_top, 0.5f, 0.5f);
258258
=== modified file 'src/View/ColumnView.vala'
--- src/View/ColumnView.vala 2015-08-17 09:30:23 +0000
+++ src/View/ColumnView.vala 2016-05-02 11:14:36 +0000
@@ -94,9 +94,12 @@
94 /* Do not emit alert sound on left and right cursor keys in Miller View */94 /* Do not emit alert sound on left and right cursor keys in Miller View */
95 case Gdk.Key.Left:95 case Gdk.Key.Left:
96 case Gdk.Key.Right:96 case Gdk.Key.Right:
97 if (no_mods)97 case Gdk.Key.BackSpace:
98 if (no_mods) {
99 /* Pass event to MillerView */
100 slot.colpane.key_press_event (event);
98 return true;101 return true;
99102 }
100 break;103 break;
101104
102 default:105 default:
103106
=== modified file 'src/View/IconView.vala'
--- src/View/IconView.vala 2016-04-30 11:18:13 +0000
+++ src/View/IconView.vala 2016-05-02 11:14:36 +0000
@@ -129,7 +129,7 @@
129 }129 }
130130
131 public override void unselect_all () {131 public override void unselect_all () {
132 tree.unselect_all ();132 tree.unselect_all ();
133 }133 }
134134
135 public override void select_path (Gtk.TreePath? path) {135 public override void select_path (Gtk.TreePath? path) {
@@ -250,7 +250,7 @@
250 }250 }
251251
252 protected override void scroll_to_cell (Gtk.TreePath? path, bool scroll_to_top) {252 protected override void scroll_to_cell (Gtk.TreePath? path, bool scroll_to_top) {
253 if (tree == null || path == null || slot.directory.permission_denied)253 if (tree == null || path == null || slot.directory.permission_denied || slot.directory.is_empty ())
254 return;254 return;
255255
256 tree.scroll_to_path (path, scroll_to_top, 0.5f, 0.5f);256 tree.scroll_to_path (path, scroll_to_top, 0.5f, 0.5f);
@@ -260,7 +260,7 @@
260 Gtk.CellRenderer renderer,260 Gtk.CellRenderer renderer,
261 bool start_editing,261 bool start_editing,
262 bool scroll_to_top) {262 bool scroll_to_top) {
263 scroll_to_cell(path, scroll_to_top);263 scroll_to_cell (path, scroll_to_top);
264 tree.set_cursor (path, renderer, start_editing);264 tree.set_cursor (path, renderer, start_editing);
265 }265 }
266266
267267
=== modified file 'src/View/Miller.vala'
--- src/View/Miller.vala 2015-12-30 12:21:30 +0000
+++ src/View/Miller.vala 2016-05-02 11:14:36 +0000
@@ -55,8 +55,6 @@
55 content_box.pack_start (scrolled_window);55 content_box.pack_start (scrolled_window);
56 content_box.show_all ();56 content_box.show_all ();
5757
58 colpane.add_events (Gdk.EventMask.KEY_RELEASE_MASK);
59 colpane.key_release_event.connect (on_key_released);
60 make_view ();58 make_view ();
61 }59 }
6260
@@ -98,6 +96,7 @@
9896
99 if (host != null) {97 if (host != null) {
100 truncate_list_after_slot (host);98 truncate_list_after_slot (host);
99 host.select_gof_file (slot.file);
101 host.colpane.add (hpane1);100 host.colpane.add (hpane1);
102 slot.directory.init ();101 slot.directory.init ();
103 } else102 } else
@@ -108,11 +107,6 @@
108 if (slot_list.length () <= 0)107 if (slot_list.length () <= 0)
109 return;108 return;
110109
111 /* destroy the nested slots */
112 ((Marlin.View.Slot)(slot)).colpane.@foreach ((w) => {
113 w.destroy ();
114 });
115
116 uint n = slot.slot_number;110 uint n = slot.slot_number;
117111
118 slot_list.@foreach ((s) => {112 slot_list.@foreach ((s) => {
@@ -122,6 +116,10 @@
122 }116 }
123 });117 });
124118
119 ((Marlin.View.Slot)(slot)).colpane.@foreach ((w) => {
120 w.destroy ();
121 });
122
125 slot_list.nth (n).next = null;123 slot_list.nth (n).next = null;
126 calculate_total_width ();124 calculate_total_width ();
127 current_slot = slot;125 current_slot = slot;
@@ -144,13 +142,79 @@
144/** Signal handling **/142/** Signal handling **/
145/*********************/143/*********************/
146144
147 public override void user_path_change_request (GLib.File loc, bool allow_mode_change = false) {145 public override void user_path_change_request (GLib.File loc, bool allow_mode_change = false, bool make_root = false) {
148 /* user request always make new root */146 /* Requests from history buttons, pathbar come here with make_root = false.
149 var slot = slot_list.first().data;147 * These do not create a new root and automatic mode change for icon directories is not allowed.
150 assert (slot != null);148 * Requests from the sidebar have make_root = true
151 truncate_list_after_slot (slot); /* Sets current slot */149 */
152 root_location = loc;150 change_path (loc, make_root);
153 slot.user_path_change_request (loc, false);151 }
152
153 private void change_path (GLib.File loc, bool make_root) {
154 var first_slot = slot_list.first ().data;
155 string root_uri = first_slot.uri;
156 string target_uri = loc.get_uri ();
157 bool found = false;
158
159 if (!make_root && target_uri.has_prefix (root_uri) && target_uri != root_uri) {
160 /* Try to add location relative to each slot in turn, starting at end */
161 var copy_slot_list = slot_list.copy ();
162 copy_slot_list.reverse ();
163 foreach (Marlin.View.Slot s in copy_slot_list) {
164 if (add_relative_path (s, loc)) {
165 found = true;
166 break;
167 }
168 }
169 }
170
171 /* If requested location is not a child of any slot, start a new tree */
172 if (!found) {
173 truncate_list_after_slot (first_slot);
174 if (loc.get_uri () != first_slot.uri) {
175 first_slot.user_path_change_request (loc, false, true);
176 root_location = loc;
177 /* Sidebar requests make_root true - first directory will be selected;
178 * Go_up requests make_root false - previous directory will be selected
179 */
180 if (make_root) {
181 first_slot.select_first_for_empty_selection ();
182 }
183 }
184 }
185 }
186
187 private bool add_relative_path (Marlin.View.Slot root, GLib.File loc) {
188 if (root.location.get_uri () == loc.get_uri ()) {
189 truncate_list_after_slot (root);
190 return true;
191 }
192 string? relative_path = PF.FileUtils.escape_uri (root.location.get_relative_path (loc), false);
193 if (relative_path != null && relative_path.length > 0) {
194 truncate_list_after_slot (root);
195 string [] dirs = relative_path.split (Path.DIR_SEPARATOR_S);
196 string last_uri = root.uri;
197 if (last_uri.has_suffix (Path.DIR_SEPARATOR_S))
198 last_uri = last_uri.slice (0, -1);
199
200 foreach (string d in dirs) {
201 if (d.length > 0) {
202 last_uri = GLib.Path.build_path (Path.DIR_SEPARATOR_S, last_uri, d);
203
204 var last_slot = slot_list.last ().data;
205 var file = GLib.File.new_for_uri (last_uri);
206 var list = new List<File> ();
207 list.prepend (file);
208 last_slot.select_glib_files (list, file);
209 Thread.usleep (100000);
210 add_location (file, last_slot);
211
212 }
213 }
214 } else {
215 return false;
216 }
217 return true;
154 }218 }
155219
156 private void connect_slot_signals (Slot slot) {220 private void connect_slot_signals (Slot slot) {
@@ -160,6 +224,7 @@
160 slot.miller_slot_request.connect (on_miller_slot_request);224 slot.miller_slot_request.connect (on_miller_slot_request);
161 slot.size_change.connect (update_total_width);225 slot.size_change.connect (update_total_width);
162 slot.folder_deleted.connect (on_slot_folder_deleted);226 slot.folder_deleted.connect (on_slot_folder_deleted);
227 slot.colpane.key_press_event.connect (on_key_pressed);
163 slot.path_changed.connect (on_slot_path_changed);228 slot.path_changed.connect (on_slot_path_changed);
164 }229 }
165230
@@ -170,14 +235,18 @@
170 slot.miller_slot_request.disconnect (on_miller_slot_request);235 slot.miller_slot_request.disconnect (on_miller_slot_request);
171 slot.size_change.disconnect (update_total_width);236 slot.size_change.disconnect (update_total_width);
172 slot.folder_deleted.disconnect (on_slot_folder_deleted);237 slot.folder_deleted.disconnect (on_slot_folder_deleted);
238 slot.colpane.key_press_event.disconnect (on_key_pressed);
173 slot.path_changed.disconnect (on_slot_path_changed);239 slot.path_changed.disconnect (on_slot_path_changed);
174 }240 }
175241
176 private void on_miller_slot_request (Marlin.View.Slot slot, GLib.File loc, bool make_root) {242 private void on_miller_slot_request (Marlin.View.Slot slot, GLib.File loc, bool make_root) {
177 if (make_root)243 if (make_root) {
178 user_path_change_request (loc);244 /* Start a new tree with root at loc */
179 else245 change_path (loc, true);
246 } else {
247 /* Just add another column to the end. */
180 add_location (loc, slot);248 add_location (loc, slot);
249 }
181 }250 }
182251
183 private bool on_slot_horizontal_scroll_event (double delta_x) {252 private bool on_slot_horizontal_scroll_event (double delta_x) {
@@ -251,7 +320,7 @@
251 }320 }
252 }321 }
253322
254 private bool on_key_released (Gtk.Widget box, Gdk.EventKey event) {323 private bool on_key_pressed (Gtk.Widget box, Gdk.EventKey event) {
255 /* Only handle unmodified keys */324 /* Only handle unmodified keys */
256 if ((event.state & Gtk.accelerator_get_default_mod_mask ()) > 0)325 if ((event.state & Gtk.accelerator_get_default_mod_mask ()) > 0)
257 return false;326 return false;
@@ -292,23 +361,30 @@
292 return true;361 return true;
293 }362 }
294 break;363 break;
364
365 case Gdk.Key.BackSpace:
366 if (current_position > 0)
367 truncate_list_after_slot (slot_list.nth_data (current_position - 1));
368 else {
369 ctab.go_up ();
370 return true;
371 }
372 break;
373
374 default:
375 break;
295 }376 }
296377
297 if (to_activate != null) {378 if (to_activate != null) {
298 to_activate.active ();379 to_activate.active ();
299 to_activate.select_first_for_empty_selection ();380 to_activate.select_first_for_empty_selection ();
300 return true;381 }
301 } else382
302 return false;383 return false;
303 }384 }
304385
305 private void on_slot_frozen_changed (Slot slot, bool frozen) {386 private void on_slot_frozen_changed (Slot slot, bool frozen) {
306 /* Ensure all slots synchronise the frozen state and387 /* Ensure all slots synchronise the frozen state */
307 * suppress key press event processing when frozen */
308 if (frozen)
309 this.colpane.key_release_event.disconnect (on_key_released);
310 else
311 this.colpane.key_release_event.connect (on_key_released);
312388
313 slot_list.@foreach ((abstract_slot) => {389 slot_list.@foreach ((abstract_slot) => {
314 var s = abstract_slot as Marlin.View.Slot;390 var s = abstract_slot as Marlin.View.Slot;
315391
=== modified file 'src/View/Slot.vala'
--- src/View/Slot.vala 2016-04-19 10:32:22 +0000
+++ src/View/Slot.vala 2016-05-02 11:14:36 +0000
@@ -186,25 +186,27 @@
186 directory.track_longest_name = true;186 directory.track_longest_name = true;
187 }187 }
188188
189 /* This delay in passing on the path change request is necessary to prevent occasional crashes
190 * due to undiagnosed bug.
191 */
189 private void schedule_path_change_request (GLib.File loc, int flag, bool make_root) {192 private void schedule_path_change_request (GLib.File loc, int flag, bool make_root) {
190 if (path_change_timeout_id > 0) {193 if (path_change_timeout_id > 0) {
191 warning ("Path change request received too rapidly");194 warning ("Path change request received too rapidly");
192 return;195 return;
193 }196 }
194 path_change_timeout_id = GLib.Timeout.add (20, () => {197 path_change_timeout_id = GLib.Timeout.add (20, () => {
195 on_path_change_request (loc, flag, make_root);198 on_dir_view_path_change_request (loc, flag, make_root);
196 path_change_timeout_id = 0; 199 path_change_timeout_id = 0;
197 return false;200 return false;
198 });201 });
199 }202 }
200203
201 private void on_path_change_request (GLib.File loc, int flag, bool make_root) {204 private void on_dir_view_path_change_request (GLib.File loc, int flag, bool make_root) {
202 if (flag == 0) { /* make view in existing container */205 if (flag == 0) { /* make view in existing container */
203 if (dir_view is FM.ColumnView) {206 if (mode == Marlin.ViewMode.MILLER_COLUMNS)
204 miller_slot_request (loc, make_root);207 miller_slot_request (loc, make_root); /* signal to parent MillerView */
205 } else {208 else
206 user_path_change_request (loc);209 user_path_change_request (loc, false, make_root); /* Handle ourselves */
207 }
208 } else210 } else
209 ctab.new_container_request (loc, flag);211 ctab.new_container_request (loc, flag);
210 }212 }
@@ -251,8 +253,8 @@
251 has_autosized = true;253 has_autosized = true;
252 }254 }
253255
256 public override void user_path_change_request (GLib.File loc, bool allow_mode_change = true, bool make_root = true) {
254 /** Only this function must be used to change or reload the path **/257 /** Only this function must be used to change or reload the path **/
255 public override void user_path_change_request (GLib.File loc, bool allow_mode_change = true) {
256 assert (loc != null);258 assert (loc != null);
257 var old_dir = directory;259 var old_dir = directory;
258 set_up_directory (loc);260 set_up_directory (loc);
@@ -325,6 +327,11 @@
325 dir_view.select_glib_files (files, focus_location);327 dir_view.select_glib_files (files, focus_location);
326 }328 }
327329
330 public void select_gof_file (GOF.File gof) {
331 if (dir_view != null)
332 dir_view.select_gof_file (gof);
333 }
334
328 public override void select_first_for_empty_selection () {335 public override void select_first_for_empty_selection () {
329 if (dir_view != null)336 if (dir_view != null)
330 dir_view.select_first_for_empty_selection ();337 dir_view.select_first_for_empty_selection ();
331338
=== modified file 'src/View/ViewContainer.vala'
--- src/View/ViewContainer.vala 2016-04-24 17:37:30 +0000
+++ src/View/ViewContainer.vala 2016-05-02 11:14:36 +0000
@@ -148,9 +148,10 @@
148 var parent_path = PF.FileUtils.get_parent_path_from_path (location.get_uri ());148 var parent_path = PF.FileUtils.get_parent_path_from_path (location.get_uri ());
149 parent = PF.FileUtils.get_file_for_path (parent_path);149 parent = PF.FileUtils.get_file_for_path (parent_path);
150 }150 }
151
151 /* Certain parents such as ftp:// will be returned as null as they are not browsable */152 /* Certain parents such as ftp:// will be returned as null as they are not browsable */
152 if (parent != null) {153 if (parent != null) {
153 user_path_change_request (parent);154 user_path_change_request (parent, false, false);
154 }155 }
155 }156 }
156157
@@ -159,7 +160,7 @@
159160
160 if (loc != null) {161 if (loc != null) {
161 selected_locations.append (this.location);162 selected_locations.append (this.location);
162 user_path_change_request (File.new_for_commandline_arg (loc));163 user_path_change_request (File.new_for_commandline_arg (loc), false, false);
163 }164 }
164 }165 }
165166
@@ -167,7 +168,7 @@
167 string? loc = browser.go_forward (n);168 string? loc = browser.go_forward (n);
168169
169 if (loc != null)170 if (loc != null)
170 user_path_change_request (File.new_for_commandline_arg (loc));171 user_path_change_request (File.new_for_commandline_arg (loc), false, false);
171 }172 }
172173
173 public void add_view (Marlin.ViewMode mode, GLib.File loc) {174 public void add_view (Marlin.ViewMode mode, GLib.File loc) {
@@ -232,11 +233,11 @@
232 refresh_slot_info (slot.location);233 refresh_slot_info (slot.location);
233 }234 }
234235
235 private void user_path_change_request (GLib.File loc) {236 public void user_path_change_request (GLib.File loc, bool allow_mode_change = true, bool make_root = true) {
236 /* Ony call directly if it is known that a change of folder is required237 /* Ony call directly if it is known that a change of folder is required
237 * otherwise call focus_location.238 * otherwise call focus_location.
238 */239 */
239 view.user_path_change_request (loc);240 view.user_path_change_request (loc, allow_mode_change, make_root);
240 }241 }
241242
242 public void new_container_request (GLib.File loc, int flag = 1) {243 public void new_container_request (GLib.File loc, int flag = 1) {
243244
=== modified file 'src/View/Window.vala'
--- src/View/Window.vala 2016-04-30 11:18:13 +0000
+++ src/View/Window.vala 2016-05-02 11:14:36 +0000
@@ -1001,7 +1001,7 @@
1001 mwcols.add_location (gfile, mwcols.current_slot);1001 mwcols.add_location (gfile, mwcols.current_slot);
1002 }1002 }
1003 } else {1003 } else {
1004 warning ("Invalid tip uri for Miller View");1004 warning ("Invalid tip uri for Miller View %s", unescaped_tip_uri);
1005 }1005 }
1006 }1006 }
10071007

Subscribers

People subscribed via source and target branches

to all changes: