diff --git a/gtk/gtkplacesview.c b/gtk/gtkplacesview.c
index 011334b803..958887732f 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;
@@ -405,6 +406,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 +676,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);
}
@@ -2258,6 +2261,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));
}
diff --git a/gtk/gtkplacesviewrow.c b/gtk/gtkplacesviewrow.c
index f6d5658f51..d797c18e8a 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,8 @@ struct _GtkPlacesViewRow
GMount *mount;
GFile *file;
+ GCancellable *cancellable;
+
gint is_network : 1;
};
@@ -73,14 +76,124 @@ 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_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_MOUNTED))
+ {
+ 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);
+ /* Translators: respectively, free and total space of the drive */
+ 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 = NULL;
+
+ if (row->file)
+ {
+ file = g_object_ref (row->file);
+ }
+ else if (row->mount)
+ {
+ file = g_mount_get_root (row->mount);
+ }
+ else if (row->volume)
+ {
+ GMount *mount;
+
+ mount = g_volume_get_mount (row->volume);
+
+ if (mount)
+ file = g_mount_get_root (row->mount);
+
+ g_clear_object (&mount);
+ }
+
+ if (file)
+ {
+ 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);
}
@@ -172,14 +285,17 @@ 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 +366,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);
@@ -352,3 +469,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 5389676d12..0233188977 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 8c888f0be8..89c840416d 100644
--- a/gtk/ui/gtkplacesviewrow.ui
+++ b/gtk/ui/gtkplacesviewrow.ui
@@ -27,11 +27,24 @@
1
1
0
+ end
1
+
+
+
+ 2
+
+
- 2
+ 3
@@ -66,7 +79,7 @@
- 3
+ 4
@@ -74,7 +87,7 @@
1
- 4
+ 5