[baobab] Move scanner object into the location



commit bfce83413db398abc8cfd355a811181b02f91ce6
Author: Paolo Borelli <pborelli gnome org>
Date:   Sun Jul 29 16:37:29 2012 +0200

    Move scanner object into the location
    
    This way we can preserve the scanner for a location and show again the
    results without having to rescan.

 src/baobab-location-list.vala |   18 ++++----
 src/baobab-location.vala      |   79 +++++++++++++++++++++++++-------
 src/baobab-scanner.vala       |   20 +++++++--
 src/baobab-window.vala        |  101 ++++++++++++++++++++---------------------
 4 files changed, 137 insertions(+), 81 deletions(-)
---
diff --git a/src/baobab-location-list.vala b/src/baobab-location-list.vala
index b4f6d31..21b217a 100644
--- a/src/baobab-location-list.vala
+++ b/src/baobab-location-list.vala
@@ -161,7 +161,14 @@ namespace Baobab {
             show_all ();
         }
 
-        public void recent_add (File directory) {
+        public void add_location (Location location) {
+            if (!already_present (location.file)) {
+                locations.append (location);
+            }
+
+            update ();
+
+            // Add to recent files
             Gtk.RecentData data = Gtk.RecentData ();
             data.display_name = null;
             data.description = null;
@@ -172,14 +179,7 @@ namespace Baobab {
             groups[0] = "baobab";
             groups[1] = null;
             data.groups = groups;
-
-            Gtk.RecentManager.get_default ().add_full (directory.get_uri (), data);
-
-            // FIXME: it would probably be cleaner to add the dir to the list of
-            // locations ourselves, but for now we cheat and just rebuild the list
-            // from scratch so that we get the proper ordering and deduplication
-            locations = null;
-            populate ();
+            Gtk.RecentManager.get_default ().add_full (location.file.get_uri (), data);
         }
     }
 }
diff --git a/src/baobab-location.vala b/src/baobab-location.vala
index 9352717..a810df9 100644
--- a/src/baobab-location.vala
+++ b/src/baobab-location.vala
@@ -24,6 +24,7 @@ namespace Baobab {
     public class Location {
         public string name { get; private set; }
         public File? file { get; private set; }
+        public FileInfo? info { get; private set; }
         public bool is_volume { get; private set; default = true; }
 
         public uint64? size { get; private set; }
@@ -34,18 +35,35 @@ namespace Baobab {
         public Volume? volume { get; private set; }
         public Mount? mount { get; private set; }
 
+        public Scanner? scanner { get; private set; }
+
         private static const string FS_ATTRIBUTES =
             FileAttribute.FILESYSTEM_SIZE + "," +
             FileAttribute.FILESYSTEM_USED;
 
+        private static const string FILE_ATTRIBUTES =
+            FileAttribute.STANDARD_DISPLAY_NAME + "," +
+            FileAttribute.STANDARD_ICON + "," +
+            FileAttribute.STANDARD_TYPE;
+
         private static Location? home_location = null;
 
+        void make_this_home_location () {
+            name = _("Home folder");
+            icon = new ThemedIcon ("user-home");
+
+            home_location = this;
+        }
+
         Location.for_home_folder () {
             is_volume = false;
             file = File.new_for_path (GLib.Environment.get_home_dir ());
+            get_file_info ();
+            get_fs_usage ();
+
             make_this_home_location ();
 
-            get_fs_usage ();
+            scanner = new Scanner (file, ScanFlags.NONE);
         }
 
         public static Location get_home_location () {
@@ -72,31 +90,47 @@ namespace Baobab {
         public Location.for_main_volume () {
             name = _("Main volume");
             file = File.new_for_path ("/");
+            get_file_info ();
             icon = new ThemedIcon ("drive-harddisk-system");
 
             get_fs_usage ();
+
+            scanner = new Scanner (file, ScanFlags.NONE);
         }
 
-        public Location.for_recent_info (Gtk.RecentInfo info) {
+        public Location.for_recent_info (Gtk.RecentInfo recent_info) {
             is_volume = false; // we assume recent locations are just folders
-            name = info.get_display_name ();
-            file = File.new_for_uri (info.get_uri ());
-            icon = info.get_gicon ();
+            file = File.new_for_uri (recent_info.get_uri ());
+            name = recent_info.get_display_name ();
+            icon = recent_info.get_gicon ();
 
-            if (info.is_local ()) {
+            if (recent_info.is_local ()) {
                 get_fs_usage ();
             }
-        }
 
-        public void update () {
-            update_volume_info ();
+            scanner = new Scanner (file, ScanFlags.NONE);
         }
 
-        void make_this_home_location () {
-            name = _("Home folder");
-            icon = new ThemedIcon ("user-home");
+        public Location.for_file (File file_) {
+            is_volume = false;
+            file = file_;
+            get_file_info ();
 
-            home_location = this;
+            if (info != null) {
+                name = info.get_display_name ();
+                icon = info.get_icon ();
+            } else {
+                name = file_.get_parse_name ();
+                icon = null;
+            }
+
+            get_fs_usage ();
+
+            scanner = new Scanner (file, ScanFlags.NONE);
+        }
+
+        public void update () {
+            update_volume_info ();
         }
 
         void update_volume_info () {
@@ -108,8 +142,10 @@ namespace Baobab {
                 name = volume.get_name ();
                 icon = volume.get_icon ();
                 file = null;
-                size = null;
-                used = null;
+                info = null;
+                size = 0;
+                used = 0;
+                scanner = null;
             }
         }
 
@@ -117,15 +153,26 @@ namespace Baobab {
             name = mount.get_name ();
             icon = mount.get_icon ();
             file = mount.get_root ();
+            get_file_info ();
 
             if (file != null && file.equal (File.new_for_path (Environment.get_home_dir ()))) {
                 make_this_home_location ();
             }
 
             get_fs_usage ();
+
+            scanner = new Scanner (file, ScanFlags.EXCLUDE_MOUNTS);
+        }
+
+        void get_file_info () {
+            try {
+                info = file.query_info (FILE_ATTRIBUTES, FileQueryInfoFlags.NONE, null);
+            } catch (Error e) {
+                info = null;
+            }
         }
 
-        private void get_fs_usage () {
+        void get_fs_usage () {
             size = null;
             used = null;
             reserved = null;
diff --git a/src/baobab-scanner.vala b/src/baobab-scanner.vala
index 0682798..1168a76 100644
--- a/src/baobab-scanner.vala
+++ b/src/baobab-scanner.vala
@@ -28,7 +28,7 @@ namespace Baobab {
         EXCLUDE_MOUNTS
     }
 
-    class Scanner : Gtk.TreeStore {
+    public class Scanner : Gtk.TreeStore {
         public enum Columns {
             DISPLAY_NAME,
             PARSE_NAME,
@@ -81,6 +81,8 @@ namespace Baobab {
         HardLink[] hardlinks;
         HashTable<File, unowned File> excluded_locations;
 
+        bool successful = false;
+
         /* General overview:
          *
          * We cannot directly modify the treemodel from the worker thread, so we have to have a way to dispatch
@@ -304,6 +306,7 @@ namespace Baobab {
                     }
 
                     if (results.parent == null) {
+                        successful = true;
                         completed ();
                         return false;
                     }
@@ -313,9 +316,18 @@ namespace Baobab {
             return this.self != null;
         }
 
-        public void scan () {
-            new GLib2.Thread ("scanner", scan_in_thread);
-            Timeout.add (100, process_results);
+        public void scan (bool force) {
+            if (force) {
+                successful = false;
+                clear ();
+            }
+
+            if (!successful) {
+                new GLib2.Thread ("scanner", scan_in_thread);
+                Timeout.add (100, process_results);
+            } else {
+                completed ();
+            }
         }
 
         public virtual void cancel () {
diff --git a/src/baobab-window.vala b/src/baobab-window.vala
index 4db501b..200991f 100644
--- a/src/baobab-window.vala
+++ b/src/baobab-window.vala
@@ -39,7 +39,8 @@ namespace Baobab {
         Chart rings_chart;
         Chart treemap_chart;
         Gtk.Spinner spinner;
-        Scanner? scanner;
+        Location? active_location;
+        ulong scan_completed_handler;
 
         static Gdk.Cursor busy_cursor;
 
@@ -156,14 +157,17 @@ namespace Baobab {
             set_default_size (960, 600);
             set_hide_titlebar_when_maximized (true);
 
+            active_location = null;
+            scan_completed_handler = 0;
+
             set_ui_state (UIPage.HOME, false);
 
             show ();
         }
 
         void on_show_home_page_activate () {
-            if (scanner != null) {
-                scanner.cancel ();
+            if (active_location != null && active_location.scanner != null) {
+                active_location.scanner.cancel ();
             }
 
             clear_message ();
@@ -187,8 +191,7 @@ namespace Baobab {
         }
 
         void on_scan_home_activate () {
-            var dir = File.new_for_path (GLib.Environment.get_home_dir ());
-            scan_directory (dir);
+            scan_directory (File.new_for_path (GLib.Environment.get_home_dir ()));
         }
 
         void on_scan_folder_activate () {
@@ -201,8 +204,7 @@ namespace Baobab {
 
             file_chooser.response.connect ((response) => {
                 if (response == Gtk.ResponseType.ACCEPT) {
-                    var dir = file_chooser.get_file ();
-                    scan_directory (dir);
+                    scan_directory (file_chooser.get_file ());
                 }
                 file_chooser.destroy ();
             });
@@ -215,8 +217,7 @@ namespace Baobab {
 
             connect_server.selected.connect ((uri) => {
                 if (uri != null) {
-                    var dir = File.new_for_uri (uri);
-                    scan_directory (dir);
+                    scan_directory (File.new_for_uri (uri));
                 }
             });
 
@@ -224,29 +225,30 @@ namespace Baobab {
         }
 
         void on_scan_location_activate (Location location) {
+            active_location = location;
             if (location.is_volume) {
                 location.mount_volume.begin ((location_, res) => {
                     try {
                         location.mount_volume.end (res);
-                        scan_directory (location.file, ScanFlags.EXCLUDE_MOUNTS);
+                        scan_active_location (false);
                     } catch (Error e) {
                         message (_("Could not analyze volume."), e.message, Gtk.MessageType.ERROR);
                     }
                 });
             } else {
-                scan_directory (location.file);
+                scan_active_location (false);
             }
         }
 
         void on_stop_activate () {
-            if (scanner != null) {
-                scanner.cancel ();
+            if (active_location != null && active_location.scanner != null) {
+                active_location.scanner.cancel ();
             }
         }
 
         void on_reload_activate () {
-            if (scanner != null) {
-                scan_directory (scanner.directory, scanner.scan_flags);
+            if (active_location != null) {
+                scan_active_location (true);
             }
         }
 
@@ -295,7 +297,7 @@ namespace Baobab {
         }
 
         void on_chart_item_activated (Chart chart, Gtk.TreeIter iter) {
-            var path = scanner.get_path (iter);
+            var path = active_location.scanner.get_path (iter);
 
             if (!treeview.is_row_expanded (path)) {
                 treeview.expand_to_path (path);
@@ -367,7 +369,7 @@ namespace Baobab {
                 Gtk.TreeIter iter;
                 if (selection.get_selected (null, out iter)) {
                     string parse_name;
-                    scanner.get (iter, Scanner.Columns.PARSE_NAME, out parse_name);
+                    active_location.scanner.get (iter, Scanner.Columns.PARSE_NAME, out parse_name);
                     var file = File.parse_name (parse_name);
                     try {
                         var info = file.query_info (FileAttribute.STANDARD_CONTENT_TYPE, 0, null);
@@ -387,11 +389,11 @@ namespace Baobab {
                 Gtk.TreeIter iter;
                 if (selection.get_selected (null, out iter)) {
                     string parse_name;
-                    scanner.get (iter, Scanner.Columns.PARSE_NAME, out parse_name);
+                    active_location.scanner.get (iter, Scanner.Columns.PARSE_NAME, out parse_name);
                     var file = File.parse_name (parse_name);
                     try {
                         file.trash ();
-                        scanner.remove (ref iter);
+                        active_location.scanner.remove (ref iter);
                     } catch (Error e) {
                         warning ("Failed to move file to the trash: %s", e.message);
                     }
@@ -402,7 +404,7 @@ namespace Baobab {
             selection.changed.connect (() => {
                 Gtk.TreeIter iter;
                 if (selection.get_selected (null, out iter)) {
-                    var path = scanner.get_path (iter);
+                    var path = active_location.scanner.get_path (iter);
                     rings_chart.set_root (path);
                     treemap_chart.set_root (path);
                 }
@@ -468,27 +470,6 @@ namespace Baobab {
             main_notebook.page = page;
         }
 
-        public bool check_dir (File directory) {
-            //if (Application.is_excluded_location (directory)) {
-            //    message("", _("Cannot check an excluded folder!"), Gtk.MessageType.INFO);
-            //    return false;
-            //}
-
-            try {
-                var info = directory.query_info (FileAttribute.STANDARD_TYPE, FileQueryInfoFlags.NONE, null);
-                if (info.get_file_type () != FileType.DIRECTORY/* || is_virtual_filesystem ()*/) {
-                    var primary = _("\"%s\" is not a valid folder").printf (directory.get_parse_name ());
-                    message (primary, _("Could not analyze disk usage."), Gtk.MessageType.ERROR);
-                    return false;
-                }
-                return true;
-            } catch (Error e) {
-                var primary = _("\"%s\" is not a valid folder").printf (directory.get_parse_name ());
-                message (primary, e.message, Gtk.MessageType.ERROR);
-                return false;
-            }
-        }
-
         void first_row_has_child (Gtk.TreeModel model, Gtk.TreePath path, Gtk.TreeIter iter) {
             model.row_has_child_toggled.disconnect (first_row_has_child);
             treeview.expand_row (path, false);
@@ -521,18 +502,13 @@ namespace Baobab {
                                                 Scanner.Columns.ELEMENTS, null);
         }
 
-        public void scan_directory (File directory, ScanFlags flags = ScanFlags.NONE) {
-            if (!check_dir (directory)) {
-                return;
-            }
-
-            // FIXME: only add folders and skip volumes?
-            location_list.recent_add (directory);
+        void scan_active_location (bool force) {
+            var scanner = active_location.scanner;
 
-            scanner = new Scanner (directory, flags);
-            set_model (scanner);
+            set_model (active_location.scanner);
 
-            scanner.completed.connect(() => {
+            scanner.disconnect (scan_completed_handler);
+            scan_completed_handler = scanner.completed.connect(() => {
                 set_ui_state (UIPage.RESULT, false);
                 try {
                     scanner.finish();
@@ -548,7 +524,28 @@ namespace Baobab {
             clear_message ();
             set_ui_state (UIPage.RESULT, true);
 
-            scanner.scan ();
+            scanner.scan (force);
+        }
+
+        public void scan_directory (File directory) {
+            var location = new Location.for_file (directory);
+
+            if (location.info == null) {
+                var primary = _("\"%s\" is not a valid folder").printf (directory.get_parse_name ());
+                message (primary, _("Could not analyze disk usage."), Gtk.MessageType.ERROR);
+                return;
+            }
+
+            if (location.info.get_file_type () != FileType.DIRECTORY/* || is_virtual_filesystem ()*/) {
+                var primary = _("\"%s\" is not a valid folder").printf (directory.get_parse_name ());
+                message (primary, _("Could not analyze disk usage."), Gtk.MessageType.ERROR);
+                return;
+            }
+
+            location_list.add_location (location);
+
+            active_location = location;
+            scan_active_location (false);
         }
     }
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]