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
This commit is contained in:
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -27,11 +27,24 @@
|
||||
<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>
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user