summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorges Basile Stavracas Neto <georges.stavracas@gmail.com>2015-11-03 00:50:06 -0200
committerGeorges Basile Stavracas Neto <georges.stavracas@gmail.com>2015-12-09 20:30:10 -0200
commit67125ae4e0fc404eb33eaced49888828c8348453 (patch)
treee3fa059db1a960936ac76002714a47eb6b39e9d5
parent5f45878133945e1ce28d39df8cacddb53512758f (diff)
downloadgtk+-67125ae4e0fc404eb33eaced49888828c8348453.tar.gz
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
-rw-r--r--gtk/gtkplacesview.c4
-rw-r--r--gtk/gtkplacesviewrow.c125
-rw-r--r--gtk/gtkplacesviewrowprivate.h8
-rw-r--r--gtk/ui/gtkplacesviewrow.ui19
4 files changed, 153 insertions, 3 deletions
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;
};
@@ -74,13 +77,123 @@ 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,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>