[gtk+/wip/gbsneto/available-space] show available space



commit 0c27e130de00edf54c80374d281dea162427bf57
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Tue Nov 3 00:50:06 2015 -0200

    show available space

 gtk/gtkplacesview.c           |   90 ++++++++++++++++++++++++++++++++++-
 gtk/gtkplacesviewprivate.h    |   15 ++++++
 gtk/gtkplacesviewrow.c        |  105 +++++++++++++++++++++++++++++++++++++++++
 gtk/gtkplacesviewrowprivate.h |    3 +
 gtk/ui/gtkplacesviewrow.ui    |   19 ++++++-
 5 files changed, 226 insertions(+), 6 deletions(-)
---
diff --git a/gtk/gtkplacesview.c b/gtk/gtkplacesview.c
index 011334b..db0322f 100644
--- a/gtk/gtkplacesview.c
+++ b/gtk/gtkplacesview.c
@@ -73,6 +73,7 @@ struct _GtkPlacesViewPrivate
   GtkWidget                     *network_placeholder_label;
 
   GtkSizeGroup                  *path_size_group;
+  GtkSizeGroup                  *space_size_group;
 
   GtkEntryCompletion            *address_entry_completion;
   GtkListStore                  *completion_store;
@@ -88,6 +89,9 @@ struct _GtkPlacesViewPrivate
   guint                          unmounting_mount : 1;
   guint                          fetching_networks : 1;
   guint                          loading : 1;
+
+  gboolean                       show_disk_usage : 1;
+  gboolean                       show_path : 1;
 };
 
 static void        mount_volume                                  (GtkPlacesView *view,
@@ -122,6 +126,8 @@ enum {
   PROP_OPEN_FLAGS,
   PROP_FETCHING_NETWORKS,
   PROP_LOADING,
+  PROP_SHOW_DISK_USAGE,
+  PROP_SHOW_PATH,
   LAST_PROP
 };
 
@@ -405,6 +411,7 @@ gtk_places_view_finalize (GObject *object)
   g_clear_object (&priv->cancellable);
   g_clear_object (&priv->networks_fetching_cancellable);
   g_clear_object (&priv->path_size_group);
+  g_clear_object (&priv->space_size_group);
 
   G_OBJECT_CLASS (gtk_places_view_parent_class)->finalize (object);
 }
@@ -674,6 +681,7 @@ insert_row (GtkPlacesView *view,
                     row);
 
   gtk_places_view_row_set_path_size_group (GTK_PLACES_VIEW_ROW (row), priv->path_size_group);
+  gtk_places_view_row_set_space_size_group (GTK_PLACES_VIEW_ROW (row), priv->space_size_group);
 
   gtk_container_add (GTK_CONTAINER (priv->listbox), row);
 }
@@ -709,12 +717,12 @@ add_volume (GtkPlacesView *view,
 
       row = g_object_new (GTK_TYPE_PLACES_VIEW_ROW,
                           "icon", icon,
+                          "is-network", is_network,
                           "name", name,
                           "path", path ? path : "",
                           "volume", volume,
                           "mount", mount,
                           "file", NULL,
-                          "is-network", is_network,
                           NULL);
 
       insert_row (view, row, is_network);
@@ -757,12 +765,12 @@ add_mount (GtkPlacesView *view,
 
       row = g_object_new (GTK_TYPE_PLACES_VIEW_ROW,
                           "icon", icon,
+                          "is-network", is_network,
                           "name", name,
                           "path", path ? path : "",
                           "volume", NULL,
                           "mount", mount,
                           "file", NULL,
-                          "is-network", is_network,
                           NULL);
 
       insert_row (view, row, is_network);
@@ -802,12 +810,12 @@ add_file (GtkPlacesView *view,
   GtkWidget *row;
   row = g_object_new (GTK_TYPE_PLACES_VIEW_ROW,
                       "icon", icon,
+                      "is_network", is_network,
                       "name", display_name,
                       "path", path,
                       "volume", NULL,
                       "mount", NULL,
                       "file", file,
-                      "is_network", is_network,
                       NULL);
 
   insert_row (view, row, is_network);
@@ -2222,6 +2230,20 @@ gtk_places_view_class_init (GtkPlacesViewClass *klass)
                               GTK_PLACES_OPEN_NORMAL,
                               G_PARAM_READWRITE);
 
+  properties[PROP_SHOW_DISK_USAGE] =
+          g_param_spec_boolean ("show-disk-usage",
+                                P_("Disk usage"),
+                                P_("Whether it should show disk usage"),
+                                FALSE,
+                                G_PARAM_READWRITE);
+
+  properties[PROP_SHOW_PATH] =
+          g_param_spec_boolean ("show-path",
+                                P_("Show path"),
+                                P_("Whether it should show the path"),
+                                TRUE,
+                                G_PARAM_READWRITE);
+
   g_object_class_install_properties (object_class, LAST_PROP, properties);
 
   /* Bind class to template */
@@ -2258,6 +2280,7 @@ gtk_places_view_init (GtkPlacesView *self)
   priv->volume_monitor = g_volume_monitor_get ();
   priv->open_flags = GTK_PLACES_OPEN_NORMAL;
   priv->path_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+  priv->space_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
 
   gtk_widget_init_template (GTK_WIDGET (self));
 }
@@ -2529,3 +2552,64 @@ gtk_places_view_set_local_only (GtkPlacesView *view,
       g_object_notify_by_pspec (G_OBJECT (view), properties [PROP_LOCAL_ONLY]);
     }
 }
+
+gboolean
+gtk_places_view_get_show_disk_usage (GtkPlacesView *view)
+{
+  GtkPlacesViewPrivate *priv;
+
+  g_return_val_if_fail (GTK_IS_PLACES_VIEW (view), FALSE);
+
+  priv = gtk_places_view_get_instance_private (view);
+
+  return priv->show_disk_usage;
+}
+
+void
+gtk_places_view_set_show_disk_usage (GtkPlacesView *view,
+                                     gboolean       show_disk_usage)
+{
+  GtkPlacesViewPrivate *priv;
+
+  g_return_if_fail (GTK_IS_PLACES_VIEW (view));
+
+  priv = gtk_places_view_get_instance_private (view);
+
+  if (priv->show_disk_usage != !!show_disk_usage)
+    {
+      priv->show_disk_usage = !!show_disk_usage;
+
+      g_object_notify_by_pspec (G_OBJECT (view), properties [PROP_SHOW_DISK_USAGE]);
+    }
+}
+
+gboolean
+gtk_places_view_get_show_path (GtkPlacesView *view)
+{
+  GtkPlacesViewPrivate *priv;
+
+  g_return_val_if_fail (GTK_IS_PLACES_VIEW (view), FALSE);
+
+  priv = gtk_places_view_get_instance_private (view);
+
+  return priv->show_path;
+}
+
+GDK_AVAILABLE_IN_3_20
+void
+gtk_places_view_set_show_path (GtkPlacesView *view,
+                               gboolean       show_path)
+{
+  GtkPlacesViewPrivate *priv;
+
+  g_return_if_fail (GTK_IS_PLACES_VIEW (view));
+
+  priv = gtk_places_view_get_instance_private (view);
+
+  if (priv->show_path != !!show_path)
+    {
+      priv->show_path = !!show_path;
+
+      g_object_notify_by_pspec (G_OBJECT (view), properties [PROP_SHOW_PATH]);
+    }
+}
diff --git a/gtk/gtkplacesviewprivate.h b/gtk/gtkplacesviewprivate.h
index 526b09f..a712b1d 100644
--- a/gtk/gtkplacesviewprivate.h
+++ b/gtk/gtkplacesviewprivate.h
@@ -77,6 +77,21 @@ gboolean           gtk_places_view_get_local_only                (GtkPlacesView
 void               gtk_places_view_set_local_only                (GtkPlacesView         *view,
                                                                   gboolean               local_only);
 
+GDK_AVAILABLE_IN_3_20
+gboolean           gtk_places_view_get_show_disk_usage           (GtkPlacesView         *view);
+
+GDK_AVAILABLE_IN_3_20
+void               gtk_places_view_set_show_disk_usage           (GtkPlacesView         *view,
+                                                                  gboolean               show_disk_usage);
+
+GDK_AVAILABLE_IN_3_20
+gboolean           gtk_places_view_get_show_path                 (GtkPlacesView         *view);
+
+GDK_AVAILABLE_IN_3_20
+void               gtk_places_view_set_show_path                 (GtkPlacesView         *view,
+                                                                  gboolean               show_path);
+
+GDK_AVAILABLE_IN_3_18
 gboolean           gtk_places_view_get_loading                   (GtkPlacesView         *view);
 
 GtkWidget *        gtk_places_view_new                           (void);
diff --git a/gtk/gtkplacesviewrow.c b/gtk/gtkplacesviewrow.c
index f6d5658..90c46d0 100644
--- a/gtk/gtkplacesviewrow.c
+++ b/gtk/gtkplacesviewrow.c
@@ -42,6 +42,7 @@ struct _GtkPlacesViewRow
 {
   GtkListBoxRow  parent_instance;
 
+  GtkLabel      *available_space_label;
   GtkSpinner    *busy_spinner;
   GtkButton     *eject_button;
   GtkImage      *eject_icon;
@@ -54,6 +55,9 @@ struct _GtkPlacesViewRow
   GMount        *mount;
   GFile         *file;
 
+  GCancellable  *cancellable;
+
+  gboolean       show_available_space : 1;
   gint           is_network : 1;
 };
 
@@ -74,13 +78,99 @@ enum {
 static GParamSpec *properties [LAST_PROP];
 
 static void
+measure_available_space_finished (GObject      *object,
+                                  GAsyncResult *res,
+                                  gpointer      user_data)
+{
+  GtkPlacesViewRow *row = user_data;
+  GFileInfo *info;
+  GError *error;
+  guint64 free_space;
+  guint64 total_space;
+  gchar *formatted_free_size;
+  gchar *formatted_total_size;
+  gchar *label;
+
+  error = NULL;
+
+  info = g_file_query_filesystem_info_finish (G_FILE (object),
+                                              res,
+                                              &error);
+
+  if (error)
+    {
+      if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+        g_warning ("Failed to measure available space: %s", error->message);
+
+      g_clear_error (&error);
+      goto out;
+    }
+
+  if (!g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_FILESYSTEM_FREE) ||
+      !g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_FILESYSTEM_SIZE))
+    {
+      g_object_unref (info);
+      goto out;
+    }
+
+  free_space = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_FILESYSTEM_FREE);
+  total_space = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_FILESYSTEM_SIZE);
+
+  formatted_free_size = g_format_size (free_space);
+  formatted_total_size = g_format_size (total_space);
+  label = g_strdup_printf (P_("%s / %s available"), formatted_free_size, formatted_total_size);
+
+  gtk_label_set_label (row->available_space_label, label);
+
+  g_object_unref (info);
+  g_free (formatted_total_size);
+  g_free (formatted_free_size);
+  g_free (label);
+out:
+  g_object_unref (object);
+}
+
+static void
+measure_available_space (GtkPlacesViewRow *row)
+{
+  gboolean should_measure;
+
+  should_measure = (!row->is_network && (row->volume || row->mount || row->file));
+
+  gtk_widget_set_visible (GTK_WIDGET (row->available_space_label), should_measure);
+
+  if (should_measure)
+    {
+      GFile *file;
+
+      file = row->file ? g_object_ref (row->file) : g_mount_get_root (row->mount);
+
+      g_cancellable_cancel (row->cancellable);
+      g_clear_object (&row->cancellable);
+      row->cancellable = g_cancellable_new ();
+
+      g_file_query_filesystem_info_async (file,
+                                          G_FILE_ATTRIBUTE_FILESYSTEM_FREE "," 
G_FILE_ATTRIBUTE_FILESYSTEM_SIZE,
+                                          G_PRIORITY_DEFAULT,
+                                          row->cancellable,
+                                          measure_available_space_finished,
+                                          row);
+
+      gtk_label_set_label (row->available_space_label, P_("Measuring..."));
+    }
+}
+
+static void
 gtk_places_view_row_finalize (GObject *object)
 {
   GtkPlacesViewRow *self = GTK_PLACES_VIEW_ROW (object);
 
+  g_cancellable_cancel (self->cancellable);
+
   g_clear_object (&self->volume);
   g_clear_object (&self->mount);
   g_clear_object (&self->file);
+  g_clear_object (&self->cancellable);
 
   G_OBJECT_CLASS (gtk_places_view_row_parent_class)->finalize (object);
 }
@@ -172,14 +262,18 @@ gtk_places_view_row_set_property (GObject      *object,
        * size but it stays hidden when needed.
        */
       gtk_widget_set_child_visible (GTK_WIDGET (self->eject_button), self->mount != NULL);
+
+      measure_available_space (self);
       break;
 
     case PROP_FILE:
       g_set_object (&self->file, g_value_get_object (value));
+      measure_available_space (self);
       break;
 
     case PROP_IS_NETWORK:
       gtk_places_view_row_set_is_network (self, g_value_get_boolean (value));
+      measure_available_space (self);
       break;
 
     default:
@@ -250,6 +344,7 @@ gtk_places_view_row_class_init (GtkPlacesViewRowClass *klass)
 
   gtk_widget_class_set_template_from_resource (widget_class, "/org/gtk/libgtk/ui/gtkplacesviewrow.ui");
 
+  gtk_widget_class_bind_template_child (widget_class, GtkPlacesViewRow, available_space_label);
   gtk_widget_class_bind_template_child (widget_class, GtkPlacesViewRow, busy_spinner);
   gtk_widget_class_bind_template_child (widget_class, GtkPlacesViewRow, eject_button);
   gtk_widget_class_bind_template_child (widget_class, GtkPlacesViewRow, eject_icon);
@@ -340,6 +435,8 @@ gtk_places_view_row_set_is_network (GtkPlacesViewRow *row,
     {
       row->is_network = is_network;
 
+      gtk_widget_set_visible (GTK_WIDGET (row->path_label), !is_network);
+
       gtk_image_set_from_icon_name (row->eject_icon, "media-eject-symbolic", GTK_ICON_SIZE_BUTTON);
       gtk_widget_set_tooltip_text (GTK_WIDGET (row->eject_button), is_network ? _("Disconnect") : 
_("Unmount"));
     }
@@ -352,3 +449,11 @@ gtk_places_view_row_set_path_size_group (GtkPlacesViewRow *row,
   if (group)
     gtk_size_group_add_widget (group, GTK_WIDGET (row->path_label));
 }
+
+void
+gtk_places_view_row_set_space_size_group (GtkPlacesViewRow *row,
+                                          GtkSizeGroup     *group)
+{
+  if (group)
+    gtk_size_group_add_widget (group, GTK_WIDGET (row->available_space_label));
+}
diff --git a/gtk/gtkplacesviewrowprivate.h b/gtk/gtkplacesviewrowprivate.h
index 5389676..24e39d5 100644
--- a/gtk/gtkplacesviewrowprivate.h
+++ b/gtk/gtkplacesviewrowprivate.h
@@ -57,6 +57,9 @@ void               gtk_places_view_row_set_is_network            (GtkPlacesViewR
 void               gtk_places_view_row_set_path_size_group       (GtkPlacesViewRow   *row,
                                                                   GtkSizeGroup       *group);
 
+void               gtk_places_view_row_set_space_size_group      (GtkPlacesViewRow   *row,
+                                                                  GtkSizeGroup       *group);
+
 G_END_DECLS
 
 #endif /* GTK_PLACES_VIEW_ROW_H */
diff --git a/gtk/ui/gtkplacesviewrow.ui b/gtk/ui/gtkplacesviewrow.ui
index 8c888f0..d606453 100644
--- a/gtk/ui/gtkplacesviewrow.ui
+++ b/gtk/ui/gtkplacesviewrow.ui
@@ -27,12 +27,25 @@
                 <property name="visible">1</property>
                 <property name="hexpand">1</property>
                 <property name="xalign">0</property>
+                <property name="ellipsize">end</property>
               </object>
               <packing>
                 <property name="position">1</property>
               </packing>
             </child>
             <child>
+              <object class="GtkLabel" id="available_space_label">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <style>
+                  <class name="dim-label" />
+                </style>
+              </object>
+              <packing>
+                <property name="position">2</property>
+              </packing>
+            </child>
+            <child>
               <object class="GtkLabel" id="path_label">
                 <property name="visible">1</property>
                 <property name="justify">right</property>
@@ -44,7 +57,7 @@
                 </style>
               </object>
               <packing>
-                <property name="position">2</property>
+                <property name="position">3</property>
               </packing>
             </child>
             <child>
@@ -66,7 +79,7 @@
                 </style>
               </object>
               <packing>
-                <property name="position">3</property>
+                <property name="position">4</property>
               </packing>
             </child>
             <child>
@@ -74,7 +87,7 @@
                 <property name="active">1</property>
               </object>
               <packing>
-                <property name="position">4</property>
+                <property name="position">5</property>
               </packing>
             </child>
           </object>


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