Merge lp:~jeremywootten/pantheon-files/show-root-file-system-free-space into lp:~elementary-apps/pantheon-files/trunk

Proposed by Jeremy Wootten
Status: Merged
Approved by: Cody Garver
Approved revision: 2141
Merged at revision: 2149
Proposed branch: lp:~jeremywootten/pantheon-files/show-root-file-system-free-space
Merge into: lp:~elementary-apps/pantheon-files/trunk
Diff against target: 479 lines (+146/-91)
6 files modified
libcore/AbstractSidebar.vala (+1/-1)
libcore/FileUtils.vala (+11/-10)
libcore/marlin-icons.h (+2/-2)
libwidgets/View/SearchResults.vala (+14/-7)
src/View/Sidebar.vala (+116/-69)
src/View/Window.vala (+2/-2)
To merge this branch: bzr merge lp:~jeremywootten/pantheon-files/show-root-file-system-free-space
Reviewer Review Type Date Requested Status
Cody Garver (community) Needs Fixing
Review via email: mp+294303@code.launchpad.net

Commit message

Additional information shown for mounts in sidebar (lp:1467672)

Description of the change

This branch changes tooltips in the sidebar to show (where available) the filesystem type, free space and total size of mounts in addition to the mount point - including for network mounts.

It also removes some seemingly redundant tooltips.

It also adds a diskspace graphic to the "File System" bookmark.

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

Mounted samba share tooltips display as "smb://server/mountpoint - Unknown type". Should it really say "Unknown type"?

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

On my system the file type is given as "cifs". I am running a samba server on a Linux machine, not Windows though. It could be a limitation of gvfs and/or the server you are running? Files just shows what GLib.query_filesystem_info () returns so I am not sure it can be fixed other than showing something other than "Unknown".

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'libcore/AbstractSidebar.vala'
2--- libcore/AbstractSidebar.vala 2016-05-06 10:36:16 +0000
3+++ libcore/AbstractSidebar.vala 2016-05-10 21:36:43 +0000
4@@ -122,6 +122,6 @@
5 Volume? volume,
6 Mount? mount,
7 uint index,
8- string tooltip) ;
9+ string? tooltip = null) ;
10 }
11 }
12
13=== modified file 'libcore/FileUtils.vala'
14--- libcore/FileUtils.vala 2016-05-06 10:36:16 +0000
15+++ libcore/FileUtils.vala 2016-05-10 21:36:43 +0000
16@@ -269,23 +269,24 @@
17
18 private bool can_browse_scheme (string scheme) {
19 switch (scheme) {
20- case Marlin.ROOT_FS_URI:
21- case Marlin.TRASH_URI:
22- case Marlin.NETWORK_URI:
23- case Marlin.RECENT_URI:
24- case Marlin.SMB_URI:
25+ case Marlin.AFP_URI:
26+ case Marlin.DAV_URI:
27+ case Marlin.DAVS_URI:
28+ case Marlin.SFTP_URI:
29+ case Marlin.FTP_URI:
30+ case Marlin.MTP_URI:
31+ return false;
32+ default:
33 return true;
34- default:
35- return false;
36 }
37 }
38 }
39
40 namespace Marlin {
41 public const string ROOT_FS_URI = "file://";
42- public const string TRASH_URI = "trash:///";
43- public const string NETWORK_URI = "network:///";
44- public const string RECENT_URI = "recent:///";
45+ public const string TRASH_URI = "trash://";
46+ public const string NETWORK_URI = "network://";
47+ public const string RECENT_URI = "recent://";
48 public const string AFP_URI = "afp://";
49 public const string DAV_URI = "dav://";
50 public const string DAVS_URI = "davs://";
51
52=== modified file 'libcore/marlin-icons.h'
53--- libcore/marlin-icons.h 2015-05-03 06:44:42 +0000
54+++ libcore/marlin-icons.h 2016-05-10 21:36:43 +0000
55@@ -5,8 +5,8 @@
56 #define MARLIN_ICON_NETWORK_SERVER "network-server"
57 #define MARLIN_ICON_FILESYSTEM "drive-harddisk-system"
58
59-#define MARLIN_TRASH_URI "trash:///"
60-#define MARLIN_NETWORK_URI "network:///"
61+#define MARLIN_TRASH_URI "trash://"
62+#define MARLIN_NETWORK_URI "network://"
63
64 #define MARLIN_ICON_FOLDER "folder"
65 #define MARLIN_ICON_FOLDER_REMOTE "folder-remote"
66
67=== modified file 'libwidgets/View/SearchResults.vala'
68--- libwidgets/View/SearchResults.vala 2016-05-06 10:36:16 +0000
69+++ libwidgets/View/SearchResults.vala 2016-05-10 21:36:43 +0000
70@@ -30,7 +30,7 @@
71
72 public Match (FileInfo info, string path_string, File parent)
73 {
74- Object (name: info.get_name (),
75+ Object (name: info.get_display_name (),
76 mime: info.get_content_type (),
77 icon: info.get_icon (),
78 path_string: path_string,
79@@ -817,6 +817,7 @@
80 }
81
82 string ATTRIBUTES = FileAttribute.STANDARD_NAME + "," +
83+ FileAttribute.STANDARD_DISPLAY_NAME + "," +
84 FileAttribute.STANDARD_CONTENT_TYPE + "," +
85 FileAttribute.STANDARD_IS_HIDDEN + "," +
86 FileAttribute.STANDARD_TYPE + "," +
87@@ -824,11 +825,13 @@
88
89 void visit (string term, bool include_hidden, Cancellable cancel)
90 {
91+
92 FileEnumerator enumerator;
93 var folder = directory_queue.poll ();
94
95- if (folder == null)
96+ if (folder == null) {
97 return;
98+ }
99
100 var depth = 0;
101
102@@ -840,8 +843,9 @@
103 depth++;
104 }
105
106- if (depth > MAX_DEPTH)
107+ if ((search_current_directory_only && depth > 1) || depth > MAX_DEPTH) {
108 return;
109+ }
110
111 try {
112 enumerator = folder.enumerate_children (ATTRIBUTES, 0, cancel);
113@@ -854,20 +858,23 @@
114 FileInfo info = null;
115 try {
116 while (!cancel.is_cancelled () && (info = enumerator.next_file (null)) != null) {
117- if (info.get_is_hidden () && !include_hidden)
118+ if (info.get_is_hidden () && !include_hidden) {
119 continue;
120+ }
121
122 if (info.get_file_type () == FileType.DIRECTORY && !search_current_directory_only) {
123 directory_queue.add (folder.resolve_relative_path (info.get_name ()));
124 }
125
126- if (term_matches (term, info.get_name ()))
127+ if (term_matches (term, info.get_display_name ())) {
128 new_results.add (new Match (info, path_string, folder));
129+ }
130 }
131- } catch (Error e) {}
132+ } catch (Error e) {warning ("Error enumerating in visit");}
133
134- if (new_results.size < 1)
135+ if (new_results.size < 1) {
136 return;
137+ }
138
139 if (!cancel.is_cancelled ()) {
140 var new_count = display_count + new_results.size;
141
142=== modified file 'src/View/Sidebar.vala'
143--- src/View/Sidebar.vala 2016-05-06 10:36:16 +0000
144+++ src/View/Sidebar.vala 2016-05-10 21:36:43 +0000
145@@ -344,7 +344,7 @@
146 Volume? volume,
147 Mount? mount,
148 uint index,
149- string tooltip) {
150+ string? tooltip = null) {
151 Gdk.Pixbuf? pixbuf = null;
152 if (icon != null) {
153 Marlin.IconInfo? icon_info = Marlin.IconInfo.lookup (icon, Marlin.IconSize.SMALLEST);
154@@ -421,8 +421,9 @@
155 }
156
157 private void update_places () {
158- Gtk.TreeIter iter;
159+ Gtk.TreeIter iter, last_iter;
160 string mount_uri;
161+ GLib.File root;
162
163 this.last_selected_uri = null;
164 this.n_builtins_before = 0;
165@@ -507,27 +508,29 @@
166
167
168 /* Add Filesystem BUILTIN */
169- add_place (Marlin.PlaceType.BUILT_IN,
170- iter,
171- _("File System"),
172- new ThemedIcon.with_default_fallbacks (Marlin.ICON_FILESYSTEM),
173- "file:///",
174- null,
175- null,
176- null,
177- 0,
178- _("Open the contents of the FileSystem"));
179+ last_iter = add_place (Marlin.PlaceType.BUILT_IN,
180+ iter,
181+ _("File System"),
182+ new ThemedIcon.with_default_fallbacks (Marlin.ICON_FILESYSTEM),
183+ Marlin.ROOT_FS_URI,
184+ null,
185+ null,
186+ null,
187+ 0,
188+ null);
189+
190+ add_device_tooltip (last_iter, PF.FileUtils.get_file_for_path (Marlin.ROOT_FS_URI));
191
192 /* Add all connected drives */
193 GLib.List<GLib.Drive> drives = volume_monitor.get_connected_drives ();
194 GLib.List<GLib.Volume> volumes;
195 foreach (GLib.Drive drive in drives) {
196 volumes = drive.get_volumes ();
197- if (volumes != null)
198+ if (volumes != null) {
199 add_volumes (iter, drive, volumes);
200+ } else if (drive.is_media_removable () &&
201+ !drive.is_media_check_automatic ()) {
202
203- else if (drive.is_media_removable ()
204- && !drive.is_media_check_automatic ()) {
205 /* If the drive has no mountable volumes and we cannot detect media change.. we
206 * display the drive in the sidebar so the user can manually poll the drive by
207 * right clicking and selecting "Rescan..."
208@@ -546,7 +549,7 @@
209 null,
210 null,
211 0,
212- (_("Mount and open %s")).printf (name));
213+ null);
214 }
215 }
216 /* add all volumes that are not associated with a drive */
217@@ -557,23 +560,19 @@
218
219 var mount = volume.get_mount ();
220 if (mount != null) {
221- var root = mount.get_default_location ();
222- var it = add_place (Marlin.PlaceType.MOUNTED_VOLUME,
223- iter,
224- mount.get_name (),
225- mount.get_icon (),
226- root.get_uri (),
227- null,
228- volume,
229- mount,
230- 0,
231- root.get_parse_name ());
232+ root = mount.get_default_location ();
233+ last_iter = add_place (Marlin.PlaceType.MOUNTED_VOLUME,
234+ iter,
235+ mount.get_name (),
236+ mount.get_icon (),
237+ root.get_uri (),
238+ null,
239+ volume,
240+ mount,
241+ 0,
242+ null);
243
244- uint64 fs_capacity, fs_free;
245- get_filesystem_space (root, out fs_capacity, out fs_free);
246- store.@set (it,
247- Column.FREE_SPACE, fs_free,
248- Column.DISK_SIZE, fs_capacity);
249+ add_device_tooltip (last_iter, root);
250 } else {
251 /* see comment above in why we add an icon for an unmounted mountable volume */
252 var name = volume.get_name ();
253@@ -600,7 +599,7 @@
254 if (volume != null)
255 continue;
256
257- var root = mount.get_default_location ();
258+ root = mount.get_default_location ();
259 if (root.is_native ()) {
260 string scheme = root.get_uri_scheme ();
261 if (scheme == "archive" ) {
262@@ -612,16 +611,18 @@
263 continue;
264 }
265
266- add_place (Marlin.PlaceType.MOUNTED_VOLUME,
267- iter,
268- mount.get_name (),
269- mount.get_icon (),
270- root.get_uri (),
271- null,
272- null,
273- mount,
274- 0,
275- root.get_parse_name ());
276+ last_iter = add_place (Marlin.PlaceType.MOUNTED_VOLUME,
277+ iter,
278+ mount.get_name (),
279+ mount.get_icon (),
280+ root.get_uri (),
281+ null,
282+ null,
283+ mount,
284+ 0,
285+ null);
286+
287+ add_device_tooltip (last_iter, root);
288 }
289
290 /* ADD NETWORK CATEGORY */
291@@ -635,7 +636,7 @@
292 /* Add network mounts */
293 network_mounts.reverse ();
294 foreach (Mount mount in network_mounts) {
295- var root = mount.get_default_location ();
296+ root = mount.get_default_location ();
297 /* get_smb_share_from_uri will return the uri unaltered if does not have
298 * the smb scheme so we need not test. This is required because the mount
299 * does not return the true root location of the share but the location used
300@@ -643,16 +644,18 @@
301 */
302 string uri = PF.FileUtils.get_smb_share_from_uri (root.get_uri ());
303
304- add_place (Marlin.PlaceType.BUILT_IN,
305- iter,
306- mount.get_name (),
307- mount.get_icon (),
308- uri,
309- null,
310- null,
311- mount,
312- 0,
313- uri);
314+ last_iter = add_place (Marlin.PlaceType.BUILT_IN,
315+ iter,
316+ mount.get_name (),
317+ mount.get_icon (),
318+ uri,
319+ null,
320+ null,
321+ mount,
322+ 0,
323+ null);
324+
325+ add_device_tooltip (last_iter, root);
326 }
327
328 /* Add Entire Network BUILTIN */
329@@ -714,13 +717,9 @@
330 volume,
331 mount,
332 0,
333- root.get_parse_name ());
334+ null);
335
336- uint64 fs_capacity, fs_free;
337- get_filesystem_space (root, out fs_capacity, out fs_free);
338- store.@set (last_iter,
339- Column.FREE_SPACE, fs_free,
340- Column.DISK_SIZE, fs_capacity);
341+ add_device_tooltip (last_iter, root);
342 } else {
343 /* Do show the unmounted volumes in the sidebar;
344 * this is so the user can mount it (in case automounting
345@@ -740,12 +739,13 @@
346 volume,
347 null,
348 0,
349- (_("Mount and open %s")).printf (name));
350+ null);
351 }
352 }
353 }
354
355- private void get_filesystem_space (GLib.File root, out uint64 fs_capacity, out uint64 fs_free) {
356+ private void get_filesystem_space_and_type (GLib.File root, out uint64 fs_capacity,
357+ out uint64 fs_free, out string type) {
358 GLib.FileInfo info;
359 try {
360 info = root.query_filesystem_info ("filesystem::*", null);
361@@ -756,10 +756,45 @@
362 }
363 fs_capacity = 0;
364 fs_free = 0;
365+ type = _("Unknown type");
366 if (info != null) {
367- fs_capacity = info.get_attribute_uint64 (FileAttribute.FILESYSTEM_SIZE);
368- fs_free = info.get_attribute_uint64 (FileAttribute.FILESYSTEM_FREE);
369- }
370+ if (info.has_attribute (FileAttribute.FILESYSTEM_SIZE)) {
371+ fs_capacity = info.get_attribute_uint64 (FileAttribute.FILESYSTEM_SIZE);
372+ }
373+ if (info.has_attribute (FileAttribute.FILESYSTEM_FREE)) {
374+ fs_free = info.get_attribute_uint64 (FileAttribute.FILESYSTEM_FREE);
375+ }
376+ if (info.has_attribute (FileAttribute.FILESYSTEM_TYPE)) {
377+ type = info.get_attribute_as_string (FileAttribute.FILESYSTEM_TYPE);
378+ }
379+ }
380+ }
381+
382+ private string get_tooltip_for_device (GLib.File location, uint64 fs_capacity,
383+ uint64 fs_free, string type) {
384+ var sb = new StringBuilder ("");
385+ sb.append (PF.FileUtils.sanitize_path (location.get_parse_name ()));
386+ if (type != null && type != "") {
387+ sb.append (" - ");
388+ sb.append (type);
389+ }
390+ if (fs_capacity > 0) {
391+ sb.append (" ");
392+ sb.append (_("(%s Free of %s)").printf (format_size (fs_free), format_size (fs_capacity)));
393+ }
394+
395+ return sb.str.replace ("&", "&amp;").replace (">", "&gt;").replace ("<", "&lt;");
396+ }
397+
398+ private void add_device_tooltip (Gtk.TreeIter iter, GLib.File root) {
399+ uint64 fs_capacity, fs_free;
400+ string fs_type;
401+ get_filesystem_space_and_type (root, out fs_capacity, out fs_free, out fs_type);
402+ var tooltip = get_tooltip_for_device (root, fs_capacity, fs_free, fs_type);
403+ store.@set (iter,
404+ Column.FREE_SPACE, fs_free,
405+ Column.DISK_SIZE, fs_capacity,
406+ Column.TOOLTIP, tooltip);
407 }
408
409 /* DRAG N DROP FUNCTIONS START */
410@@ -967,7 +1002,7 @@
411 var real_action = context.get_selected_action ();
412 if (real_action == Gdk.DragAction.ASK) {
413 var actions = context.get_actions ();
414- if (drop_uri.has_prefix ("trash:///"))
415+ if (drop_uri.has_prefix ("trash://"))
416 actions &= Gdk.DragAction.MOVE;
417
418 real_action = dnd_handler.drag_drop_action_ask ((Gtk.Widget)tree_view, window, actions);
419@@ -1163,7 +1198,7 @@
420 store.@get (iter, Column.URI, out uri, Column.PLUGIN_CALLBACK, out f);
421
422 if (uri != null) {
423- var location = File.new_for_uri (uri);
424+ var location = PF.FileUtils.get_file_for_path (uri);
425 /* Navigate to the clicked location */
426 if (flags == Marlin.OpenFlag.NEW_WINDOW) {
427 window.add_window (location, Marlin.ViewMode.CURRENT);
428@@ -1533,8 +1568,11 @@
429 Gtk.TreeIter iter) {
430
431 var crt = renderer as Gtk.CellRendererText;
432- bool is_category;
433- model.@get (iter, Column.IS_CATEGORY, out is_category, -1);
434+ bool is_category, show_eject_button;
435+ uint64 disk_size = 0;
436+ model.@get (iter, Column.IS_CATEGORY, out is_category,
437+ Column.DISK_SIZE, out disk_size,
438+ Column.SHOW_EJECT, out show_eject_button, -1);
439
440 if (is_category) {
441 crt.weight = 900;
442@@ -1543,6 +1581,15 @@
443 } else {
444 crt.weight_set = false;
445 crt.ypad = BOOKMARK_YPAD;
446+ if (disk_size > 0) {
447+ /* Make disk space graphic same length whether or not eject button displayed */
448+ var crd = renderer as Marlin.CellRendererDisk;
449+ if (!show_eject_button) {
450+ crd.rpad = eject_button_size + ICON_XPAD * 2;
451+ } else {
452+ crd.rpad = 0;
453+ }
454+ }
455 }
456 }
457
458
459=== modified file 'src/View/Window.vala'
460--- src/View/Window.vala 2016-04-30 11:18:13 +0000
461+++ src/View/Window.vala 2016-05-10 21:36:43 +0000
462@@ -986,7 +986,7 @@
463 return;
464 }
465
466- var tip_location = GLib.File.new_for_uri (unescaped_tip_uri);
467+ var tip_location = PF.FileUtils.get_file_for_path (unescaped_tip_uri);
468 var relative_path = root_location.get_relative_path (tip_location);
469 GLib.File gfile;
470
471@@ -996,7 +996,7 @@
472
473 foreach (string dir in dirs) {
474 uri += (GLib.Path.DIR_SEPARATOR_S + dir);
475- gfile = GLib.File.new_for_uri (uri);
476+ gfile = PF.FileUtils.get_file_for_path (uri);
477
478 mwcols.add_location (gfile, mwcols.current_slot);
479 }

Subscribers

People subscribed via source and target branches

to all changes: