[gtk+/wip/gbsneto/available-space: 1/2] placesview: implement available space
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/gbsneto/available-space: 1/2] placesview: implement available space
- Date: Wed, 9 Dec 2015 14:01:59 +0000 (UTC)
commit 316f325bc07042d6b4edd58a712abe454c463beb
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date: Tue Nov 3 00:50:06 2015 -0200
placesview: implement available space
GtkPlacesView is a widget to display locations
in the computer, such as root ("/") and volumes,
separating the persistent devices from removable
ones.
From the latest mockups[1], GtkPlacesView would
display the available space of local drives like
partitions. This, however, is not implemented in
the current codebase.
Fix that by implementing the measurement of disk
space, and adding a new property GtkPlacesView::show-disk-usage
which controls the visibility of measured disks.
[1]
https://raw.githubusercontent.com/gnome-design-team/gnome-mockups/master/nautilus/nautilus-next/other-locations.png
https://bugzilla.gnome.org/show_bug.cgi?id=759225
gtk/gtkplacesview.c | 75 +++++++++++++++++++
gtk/gtkplacesviewprivate.h | 8 ++
gtk/gtkplacesviewrow.c | 158 +++++++++++++++++++++++++++++++++++++++++
gtk/gtkplacesviewrowprivate.h | 8 ++
gtk/ui/gtkplacesviewrow.ui | 19 ++++-
5 files changed, 265 insertions(+), 3 deletions(-)
---
diff --git a/gtk/gtkplacesview.c b/gtk/gtkplacesview.c
index 011334b..92e62af 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);
}
@@ -431,6 +438,10 @@ gtk_places_view_get_property (GObject *object,
g_value_set_boolean (value, gtk_places_view_get_fetching_networks (self));
break;
+ case PROP_SHOW_DISK_USAGE:
+ g_value_set_boolean (value, gtk_places_view_get_show_disk_usage (self));
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -450,6 +461,10 @@ gtk_places_view_set_property (GObject *object,
gtk_places_view_set_local_only (self, g_value_get_boolean (value));
break;
+ case PROP_SHOW_DISK_USAGE:
+ gtk_places_view_set_show_disk_usage (self, g_value_get_boolean (value));
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -674,6 +689,8 @@ 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_places_view_row_set_show_disk_usage (GTK_PLACES_VIEW_ROW (row), priv->show_disk_usage);
gtk_container_add (GTK_CONTAINER (priv->listbox), row);
}
@@ -2222,6 +2239,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 +2289,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 +2561,46 @@ 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)
+ {
+ GList *children;
+ GList *l;
+
+ priv->show_disk_usage = !!show_disk_usage;
+
+ children = gtk_container_get_children (GTK_CONTAINER (priv->listbox));
+
+ for (l = children; l != NULL; l = l->next)
+ {
+ if (GTK_IS_PLACES_VIEW_ROW (l->data))
+ gtk_places_view_row_set_show_disk_usage (l->data, show_disk_usage);
+ }
+
+ g_object_notify_by_pspec (G_OBJECT (view), properties [PROP_SHOW_DISK_USAGE]);
+
+ g_list_free (children);
+ }
+}
diff --git a/gtk/gtkplacesviewprivate.h b/gtk/gtkplacesviewprivate.h
index 526b09f..4eabf45 100644
--- a/gtk/gtkplacesviewprivate.h
+++ b/gtk/gtkplacesviewprivate.h
@@ -77,6 +77,14 @@ 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_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..2808011 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_disk_usage : 1;
gint is_network : 1;
};
@@ -68,19 +72,105 @@ enum {
PROP_MOUNT,
PROP_FILE,
PROP_IS_NETWORK,
+ PROP_SHOW_DISK_USAGE,
LAST_PROP
};
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 (_("%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_label_set_label (row->available_space_label, "");
+ 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);
+ }
+}
+
+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);
}
@@ -128,6 +218,10 @@ gtk_places_view_row_get_property (GObject *object,
g_value_set_boolean (value, self->is_network);
break;
+ case PROP_SHOW_DISK_USAGE:
+ g_value_set_boolean (value, self->show_disk_usage);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -172,14 +266,30 @@ 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);
+
+ if (self->show_disk_usage)
+ measure_available_space (self);
+
break;
case PROP_FILE:
g_set_object (&self->file, g_value_get_object (value));
+
+ if (self->show_disk_usage)
+ measure_available_space (self);
+
break;
case PROP_IS_NETWORK:
gtk_places_view_row_set_is_network (self, g_value_get_boolean (value));
+
+ if (self->show_disk_usage)
+ measure_available_space (self);
+
+ break;
+
+ case PROP_SHOW_DISK_USAGE:
+ gtk_places_view_row_set_show_disk_usage (self, g_value_get_boolean (value));
break;
default:
@@ -246,10 +356,18 @@ gtk_places_view_row_class_init (GtkPlacesViewRowClass *klass)
FALSE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
+ properties[PROP_SHOW_DISK_USAGE] =
+ g_param_spec_boolean ("show-disk-usage",
+ P_("Whether the row show local disks' usage"),
+ P_("Whether the row show local disks' usage"),
+ FALSE,
+ G_PARAM_READWRITE);
+
g_object_class_install_properties (object_class, LAST_PROP, properties);
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 +458,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 +472,41 @@ 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));
+}
+
+gboolean
+gtk_places_view_row_get_show_disk_usage (GtkPlacesViewRow *row)
+{
+ g_return_val_if_fail (GTK_IS_PLACES_VIEW_ROW (row), FALSE);
+
+ return row->is_network;
+}
+
+void
+gtk_places_view_row_set_show_disk_usage (GtkPlacesViewRow *row,
+ gboolean show_disk_usage)
+{
+ if (row->show_disk_usage != show_disk_usage)
+ {
+ row->show_disk_usage = !!show_disk_usage;
+
+ gtk_widget_set_visible (GTK_WIDGET (row->available_space_label), show_disk_usage);
+
+ if (show_disk_usage)
+ {
+ measure_available_space (row);
+ }
+ else
+ {
+ g_cancellable_cancel (row->cancellable);
+ g_clear_object (&row->cancellable);
+ }
+ }
+}
diff --git a/gtk/gtkplacesviewrowprivate.h b/gtk/gtkplacesviewrowprivate.h
index 5389676..0233188 100644
--- a/gtk/gtkplacesviewrowprivate.h
+++ b/gtk/gtkplacesviewrowprivate.h
@@ -54,9 +54,17 @@ gboolean gtk_places_view_row_get_is_network (GtkPlacesViewR
void gtk_places_view_row_set_is_network (GtkPlacesViewRow *row,
gboolean is_network);
+gboolean gtk_places_view_row_get_show_disk_usage (GtkPlacesViewRow *row);
+
+void gtk_places_view_row_set_show_disk_usage (GtkPlacesViewRow *row,
+ gboolean show_disk_usage);
+
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..89c8404 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">False</property>
+ <property name="xalign">1</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]