[baobab] Add a Preferences dialog



commit 62c93fc3817cf496b11ab61d20c187fc0ee5552c
Author: Stefano Facchini <stefano facchini gmail com>
Date:   Tue Jun 23 09:35:34 2020 +0200

    Add a Preferences dialog
    
    This provides a UI to change the list of excluded locations.

 data/baobab.gresource.xml            |   2 +
 data/ui/baobab-excluded-row.ui       |  38 +++++++++++
 data/ui/baobab-main-window.ui        |   4 ++
 data/ui/baobab-preferences-dialog.ui |  53 ++++++++++++++
 po/POTFILES.in                       |   2 +
 src/baobab-preferences-dialog.vala   | 129 +++++++++++++++++++++++++++++++++++
 src/baobab-scanner.vala              |   4 +-
 src/baobab-window.vala               |   8 +++
 src/meson.build                      |   1 +
 9 files changed, 239 insertions(+), 2 deletions(-)
---
diff --git a/data/baobab.gresource.xml b/data/baobab.gresource.xml
index be3480b..d61d46c 100644
--- a/data/baobab.gresource.xml
+++ b/data/baobab.gresource.xml
@@ -2,11 +2,13 @@
 <gresources>
   <gresource prefix="/org/gnome/baobab">
     <file compressed="true">baobab.css</file>
+    <file compressed="true">ui/baobab-excluded-row.ui</file>
     <file compressed="true">ui/baobab-folder-display.ui</file>
     <file compressed="true">ui/baobab-location-list.ui</file>
     <file compressed="true">ui/baobab-location-row.ui</file>
     <file compressed="true">ui/baobab-main-window.ui</file>
     <file compressed="true">ui/baobab-pathbutton.ui</file>
+    <file compressed="true">ui/baobab-preferences-dialog.ui</file>
     <file compressed="true">gtk/help-overlay.ui</file>
     <file compressed="true">gtk/menus.ui</file>
     <file compressed="true">icons/scalable/actions/view-ringschart-symbolic.svg</file>
diff --git a/data/ui/baobab-excluded-row.ui b/data/ui/baobab-excluded-row.ui
new file mode 100644
index 0000000..a5d48f9
--- /dev/null
+++ b/data/ui/baobab-excluded-row.ui
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <template class="BaobabExcludedRow" parent="GtkListBoxRow">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="activatable">False</property>
+    <child>
+      <object class="GtkGrid">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="margin">12</property>
+        <child>
+          <object class="GtkLabel" id="name_label">
+            <property name="visible">True</property>
+            <property name="hexpand">True</property>
+            <property name="halign">start</property>
+            <property name="ellipsize">end</property>
+          </object>
+        </child>
+        <child>
+          <object class="GtkButton" id="remove_button">
+            <property name="visible">True</property>
+            <property name="valign">center</property>
+            <style>
+              <class name="image-button"/>
+            </style>
+            <child>
+              <object class="GtkImage">
+                <property name="visible">True</property>
+                <property name="icon_name">list-remove-symbolic</property>
+              </object>
+            </child>
+          </object>
+        </child>
+      </object>
+    </child>
+  </template>
+</interface>
diff --git a/data/ui/baobab-main-window.ui b/data/ui/baobab-main-window.ui
index c84c4a0..62be25f 100644
--- a/data/ui/baobab-main-window.ui
+++ b/data/ui/baobab-main-window.ui
@@ -11,6 +11,10 @@
         <attribute name="label" translatable="yes">Clear list of recent locations</attribute>
         <attribute name="action">win.clear-recent</attribute>
       </item>
+      <item>
+        <attribute name="label" translatable="yes">Preferences</attribute>
+        <attribute name="action">win.show-preferences</attribute>
+      </item>
     </section>
     <section>
       <item>
diff --git a/data/ui/baobab-preferences-dialog.ui b/data/ui/baobab-preferences-dialog.ui
new file mode 100644
index 0000000..582e9d0
--- /dev/null
+++ b/data/ui/baobab-preferences-dialog.ui
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.0 -->
+<interface>
+  <requires lib="gtk+" version="3.22"/>
+  <template class="BaobabPreferencesDialog" parent="GtkDialog">
+    <property name="can_focus">False</property>
+    <property name="type_hint">dialog</property>
+    <property name="title" translatable="yes">Preferences</property>
+    <child internal-child="vbox">
+      <object class="GtkBox">
+        <property name="can_focus">False</property>
+        <property name="orientation">vertical</property>
+        <property name="margin">12</property>
+        <child>
+          <object class="GtkLabel" id="locations_label">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="halign">start</property>
+            <property name="margin-bottom">12</property>
+            <property name="use_markup">True</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkScrolledWindow">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="shadow_type">in</property>
+            <property name="hscrollbar-policy">never</property>
+            <property name="width_request">500</property>
+            <property name="height_request">300</property>
+            <child>
+              <object class="GtkListBox" id="excluded_list_box">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="selection_mode">none</property>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">True</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+  </template>
+</interface>
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 83bd4e7..31531c3 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -7,9 +7,11 @@ data/gtk/help-overlay.ui
 data/gtk/menus.ui
 data/ui/baobab-folder-display.ui
 data/ui/baobab-location-list.ui
+data/ui/baobab-preferences-dialog.ui
 data/ui/baobab-main-window.ui
 src/baobab-application.vala
 src/baobab-cellrenderers.vala
 src/baobab-location-list.vala
 src/baobab-location.vala
+src/baobab-preferences-dialog.vala
 src/baobab-window.vala
diff --git a/src/baobab-preferences-dialog.vala b/src/baobab-preferences-dialog.vala
new file mode 100644
index 0000000..27cbf1f
--- /dev/null
+++ b/src/baobab-preferences-dialog.vala
@@ -0,0 +1,129 @@
+/* Baobab - disk usage analyzer
+ *
+ * Copyright (C) 2020  Stefano Facchini <stefano facchini gmail com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+namespace Baobab {
+
+    [GtkTemplate (ui = "/org/gnome/baobab/ui/baobab-excluded-row.ui")]
+    class ExcludedRow : Gtk.ListBoxRow {
+        [GtkChild]
+        private Gtk.Label name_label;
+        [GtkChild]
+        private Gtk.Button remove_button;
+
+        public signal void removed ();
+
+        public ExcludedRow (File file) {
+            if (file.has_uri_scheme ("file")) {
+                name_label.label = file.get_path ();
+            } else {
+                name_label.label = file.get_uri ();
+            }
+            remove_button.clicked.connect (() => { removed (); });
+        }
+    }
+
+    [GtkTemplate (ui = "/org/gnome/baobab/ui/baobab-preferences-dialog.ui")]
+    public class PreferencesDialog : Gtk.Dialog {
+        [GtkChild]
+        private Gtk.ListBox excluded_list_box;
+        [GtkChild]
+        private Gtk.Label locations_label;
+
+        private Settings prefs_settings;
+
+        construct {
+            locations_label.label = "<b>%s</b>".printf (_("Locations to ignore"));
+
+            prefs_settings = new Settings ("org.gnome.baobab.preferences");
+
+            excluded_list_box.set_header_func (update_header);
+
+            excluded_list_box.row_activated.connect (() => {
+                // The only activatable row is "Add location"
+                var file_chooser = new Gtk.FileChooserDialog (_("Select Location to Ignore"), this,
+                                                             Gtk.FileChooserAction.SELECT_FOLDER,
+                                                              _("_Cancel"), Gtk.ResponseType.CANCEL,
+                                                              _("_Open"), Gtk.ResponseType.OK);
+
+                file_chooser.local_only = false;
+                file_chooser.modal = true;
+                file_chooser.set_default_response (Gtk.ResponseType.OK);
+
+                file_chooser.response.connect ((response) => {
+                    if (response == Gtk.ResponseType.OK) {
+                        var uri = file_chooser.get_file ().get_uri ();
+                        add_uri (uri);
+                        populate ();
+                    }
+                    file_chooser.destroy ();
+                });
+
+                file_chooser.show ();
+            });
+
+            populate ();
+        }
+
+        void populate () {
+            excluded_list_box.foreach ((widget) => { widget.destroy (); });
+
+            foreach (var uri in prefs_settings.get_strv ("excluded-uris")) {
+                var file = File.new_for_uri (uri);
+                var row = new ExcludedRow (file);
+                excluded_list_box.insert (row, -1);
+
+                row.removed.connect (() => {
+                    remove_uri (uri);
+                    populate ();
+                });
+            }
+
+            var label = new Gtk.Label (_("Add location…"));
+            label.margin = 12;
+            label.show ();
+            excluded_list_box.insert (label, -1);
+        }
+
+        void add_uri (string uri) {
+            var uris = prefs_settings.get_strv ("excluded-uris");
+            if (! (uri in uris)) {
+                uris += uri;
+                prefs_settings.set_strv ("excluded-uris", uris);
+            }
+        }
+
+        void remove_uri (string uri) {
+            string[] uris = {};
+            foreach (var uri_iter in prefs_settings.get_strv ("excluded-uris")) {
+                if (uri_iter != uri) {
+                    uris += uri_iter;
+                }
+            }
+            prefs_settings.set_strv ("excluded-uris", uris);
+        }
+
+        void update_header (Gtk.ListBoxRow row, Gtk.ListBoxRow? before_row) {
+            if (before_row != null && row.get_header () == null) {
+                row.set_header (new Gtk.Separator (Gtk.Orientation.HORIZONTAL));
+            } else {
+                row.set_header (null);
+            }
+        }
+    }
+}
diff --git a/src/baobab-scanner.vala b/src/baobab-scanner.vala
index e56765c..998995e 100644
--- a/src/baobab-scanner.vala
+++ b/src/baobab-scanner.vala
@@ -425,6 +425,8 @@ namespace Baobab {
             scan_error = null;
             total_size = 0;
             total_elements = 0;
+
+            excluded_locations = Application.get_default ().get_excluded_locations ();
         }
 
         public void scan (bool force) {
@@ -483,8 +485,6 @@ namespace Baobab {
                 typeof (State)    // STATE
             });
 
-            excluded_locations = Application.get_default ().get_excluded_locations ();
-
             results_queue = new AsyncQueue<ResultsArray> ();
         }
     }
diff --git a/src/baobab-window.vala b/src/baobab-window.vala
index 7a036c1..c1e733a 100644
--- a/src/baobab-window.vala
+++ b/src/baobab-window.vala
@@ -95,6 +95,7 @@ namespace Baobab {
             { "scan-folder", on_scan_folder_activate },
             { "reload", on_reload_activate },
             { "clear-recent", on_clear_recent },
+            { "show-preferences", on_show_preferences },
             { "help", on_help_activate },
             { "about", on_about_activate }
         };
@@ -268,6 +269,13 @@ namespace Baobab {
             location_list.clear_recent ();
         }
 
+        void on_show_preferences () {
+            var dialog = new PreferencesDialog ();
+            dialog.modal = true;
+            dialog.set_transient_for (this);
+            dialog.show ();
+        }
+
         void on_help_activate () {
             try {
                 Gtk.show_uri (get_screen (), "help:baobab", Gtk.get_current_event_time ());
diff --git a/src/meson.build b/src/meson.build
index b0af92d..c43e5d1 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -10,6 +10,7 @@ baobab_vala_sources = [
   'baobab-location-list.vala',
   'baobab-location.vala',
   'baobab-pathbar.vala',
+  'baobab-preferences-dialog.vala',
   'baobab-ringschart.vala',
   'baobab-scanner.vala',
   'baobab-treemap.vala',


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