[gnome-disk-utility/udisks2-port] Show spinners in device-list and volume grid for jobs on both disks and devices
- From: David Zeuthen <davidz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-disk-utility/udisks2-port] Show spinners in device-list and volume grid for jobs on both disks and devices
- Date: Tue, 22 Nov 2011 18:50:57 +0000 (UTC)
commit 512b01cb0f7d9bd66b516119213630ad812de722
Author: David Zeuthen <davidz redhat com>
Date: Tue Nov 22 13:49:43 2011 -0500
Show spinners in device-list and volume grid for jobs on both disks and devices
http://people.freedesktop.org/~david/gdu2-spinners.png
Signed-off-by: David Zeuthen <davidz redhat com>
src/palimpsest/gdudevicetreemodel.c | 226 ++++++++++++++++++++++++++++++++++-
src/palimpsest/gdudevicetreemodel.h | 2 +
src/palimpsest/gduvolumegrid.c | 7 +
src/palimpsest/gduwindow.c | 7 +
4 files changed, 237 insertions(+), 5 deletions(-)
---
diff --git a/src/palimpsest/gdudevicetreemodel.c b/src/palimpsest/gdudevicetreemodel.c
index e061a4a..bd6674e 100644
--- a/src/palimpsest/gdudevicetreemodel.c
+++ b/src/palimpsest/gdudevicetreemodel.c
@@ -59,6 +59,17 @@ static void coldplug (GduDeviceTreeModel *model);
static void on_client_changed (UDisksClient *client,
gpointer user_data);
+
+static void update_drive (GduDeviceTreeModel *model,
+ UDisksObject *object,
+ gboolean from_timer);
+
+static void
+update_block (GduDeviceTreeModel *model,
+ UDisksObject *object,
+ gboolean from_timer);
+
+
static void
gdu_device_tree_model_finalize (GObject *object)
{
@@ -295,7 +306,9 @@ gdu_device_tree_model_constructed (GObject *object)
types[4] = G_TYPE_STRING;
types[5] = G_TYPE_DBUS_OBJECT;
types[6] = G_TYPE_BOOLEAN;
- G_STATIC_ASSERT (7 == GDU_DEVICE_TREE_MODEL_N_COLUMNS);
+ types[7] = G_TYPE_BOOLEAN;
+ types[8] = G_TYPE_UINT;
+ G_STATIC_ASSERT (9 == GDU_DEVICE_TREE_MODEL_N_COLUMNS);
gtk_tree_store_set_column_types (GTK_TREE_STORE (model),
GDU_DEVICE_TREE_MODEL_N_COLUMNS,
types);
@@ -446,9 +459,177 @@ remove_drive (GduDeviceTreeModel *model,
;
}
+/* ---------------------------------------------------------------------------------------------------- */
+
+static gboolean
+object_has_jobs (UDisksClient *client,
+ UDisksObject *object)
+{
+ GList *jobs;
+ gboolean ret;
+
+ jobs = udisks_client_get_jobs_for_object (client, object);
+ ret = (jobs != NULL);
+ g_list_foreach (jobs, (GFunc) g_object_unref, NULL);
+ g_list_free (jobs);
+
+ return ret;
+}
+
+static gboolean
+iface_has_jobs (UDisksClient *client,
+ GDBusInterface *iface)
+{
+ GDBusObject *object;
+ object = g_dbus_interface_get_object (G_DBUS_INTERFACE (iface));
+ if (object != NULL)
+ return object_has_jobs (client, UDISKS_OBJECT (object));
+ else
+ return FALSE;
+}
+
+static gboolean
+block_has_jobs (UDisksClient *client,
+ UDisksBlock *block)
+{
+ gboolean ret = FALSE;
+ GDBusObject *block_object;
+ UDisksPartitionTable *part_table = NULL;
+ UDisksEncrypted *encrypted = NULL;
+ GList *partitions = NULL, *l;
+ UDisksBlock *cleartext_block = NULL;
+
+ if (iface_has_jobs (client, G_DBUS_INTERFACE (block)))
+ {
+ ret = TRUE;
+ goto out;
+ }
+
+ block_object = g_dbus_interface_get_object (G_DBUS_INTERFACE (block));
+ if (block_object == NULL)
+ goto out;
+
+ part_table = udisks_object_get_partition_table (UDISKS_OBJECT (block_object));
+ if (part_table != NULL)
+ {
+ partitions = udisks_client_get_partitions (client, part_table);
+ for (l = partitions; l != NULL; l = l->next)
+ {
+ UDisksPartition *partition = UDISKS_PARTITION (l->data);
+ GDBusObject *partition_object;
+ UDisksBlock *partition_block;
+
+ partition_object = g_dbus_interface_get_object (G_DBUS_INTERFACE (partition));
+ if (partition_object != NULL)
+ {
+ partition_block = udisks_object_get_block (UDISKS_OBJECT (partition_object));
+ if (block_has_jobs (client, partition_block))
+ {
+ ret = TRUE;
+ goto out;
+ }
+ }
+ }
+ }
+
+ encrypted = udisks_object_get_encrypted (UDISKS_OBJECT (block_object));
+ if (encrypted != NULL)
+ {
+ cleartext_block = udisks_client_get_cleartext_block (client, block);
+ if (cleartext_block != NULL)
+ {
+ if (block_has_jobs (client, cleartext_block))
+ {
+ ret = TRUE;
+ goto out;
+ }
+ }
+ }
+
+ out:
+ g_clear_object (&part_table);
+ g_clear_object (&encrypted);
+ g_clear_object (&cleartext_block);
+ g_list_foreach (partitions, (GFunc) g_object_unref, NULL);
+ g_list_free (partitions);
+ return ret;
+}
+
+static gboolean
+drive_has_jobs (UDisksClient *client,
+ UDisksDrive *drive)
+{
+ gboolean ret = FALSE;
+ UDisksBlock *block = NULL;
+
+ if (iface_has_jobs (client, G_DBUS_INTERFACE (drive)))
+ {
+ ret = TRUE;
+ goto out;
+ }
+
+ block = udisks_client_get_block_for_drive (client, drive, FALSE); /* get_physical */
+ if (block_has_jobs (client, block))
+ {
+ ret = TRUE;
+ goto out;
+ }
+
+ out:
+ g_clear_object (&block);
+ return ret;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+typedef struct
+{
+ GduDeviceTreeModel *model;
+ UDisksObject *object;
+} SpinnerTimeoutData;
+
+static SpinnerTimeoutData *
+spinner_timeout_data_new (GduDeviceTreeModel *model,
+ UDisksObject *object)
+{
+ SpinnerTimeoutData *data = g_slice_new0 (SpinnerTimeoutData);
+ data->model = g_object_ref (model);
+ data->object = g_object_ref (object);
+ return data;
+}
+
+static void
+spinner_timeout_data_free (SpinnerTimeoutData *data)
+{
+ g_object_unref (data->model);
+ g_object_unref (data->object);
+ g_slice_free (SpinnerTimeoutData, data);
+}
+
+static gboolean
+spinner_timeout_drive (gpointer user_data)
+{
+ SpinnerTimeoutData *data = user_data;
+ update_drive (data->model, data->object, TRUE);
+ spinner_timeout_data_free (data);
+ return FALSE; /* remove the timeout source */
+}
+
+static gboolean
+spinner_timeout_block (gpointer user_data)
+{
+ SpinnerTimeoutData *data = user_data;
+ update_block (data->model, data->object, TRUE);
+ spinner_timeout_data_free (data);
+ return FALSE; /* remove the timeout source */
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
static void
update_drive (GduDeviceTreeModel *model,
- UDisksObject *object)
+ UDisksObject *object,
+ gboolean from_timer)
{
UDisksDrive *drive = NULL;
UDisksDriveAta *ata = NULL;
@@ -460,7 +641,9 @@ update_drive (GduDeviceTreeModel *model,
gchar *s = NULL;
gchar *sort_key = NULL;
gboolean warning = FALSE;
+ gboolean jobs_running = FALSE;
GtkTreeIter iter;
+ guint pulse;
if (!find_iter_for_object (model,
object,
@@ -503,14 +686,29 @@ update_drive (GduDeviceTreeModel *model,
name);
}
+ jobs_running = drive_has_jobs (model->client, drive);
+
+ gtk_tree_model_get (GTK_TREE_MODEL (model),
+ &iter,
+ GDU_DEVICE_TREE_MODEL_COLUMN_PULSE, &pulse,
+ -1);
+ if (from_timer)
+ pulse += 1;
+
gtk_tree_store_set (GTK_TREE_STORE (model),
&iter,
GDU_DEVICE_TREE_MODEL_COLUMN_ICON, drive_icon,
GDU_DEVICE_TREE_MODEL_COLUMN_NAME, s,
GDU_DEVICE_TREE_MODEL_COLUMN_SORT_KEY, sort_key,
GDU_DEVICE_TREE_MODEL_COLUMN_WARNING, warning,
+ GDU_DEVICE_TREE_MODEL_COLUMN_JOBS_RUNNING, jobs_running,
+ GDU_DEVICE_TREE_MODEL_COLUMN_PULSE, pulse,
-1);
+ /* update spinner, if jobs are running */
+ if (jobs_running)
+ g_timeout_add (80, spinner_timeout_drive, spinner_timeout_data_new (model, object));
+
out:
if (media_icon != NULL)
g_object_unref (media_icon);
@@ -575,7 +773,7 @@ update_drives (GduDeviceTreeModel *model)
for (l = model->current_drives; l != NULL; l = l->next)
{
UDisksObject *object = UDISKS_OBJECT (l->data);
- update_drive (model, object);
+ update_drive (model, object, FALSE);
}
if (g_list_length (model->current_drives) == 0)
@@ -665,7 +863,8 @@ remove_block (GduDeviceTreeModel *model,
static void
update_block (GduDeviceTreeModel *model,
- UDisksObject *object)
+ UDisksObject *object,
+ gboolean from_timer)
{
GtkTreeIter iter;
UDisksBlock *block;
@@ -677,6 +876,8 @@ update_block (GduDeviceTreeModel *model,
const gchar *loop_backing_file;
guint64 size;
gchar *size_str = NULL;
+ gboolean jobs_running = FALSE;
+ guint pulse;
if (!find_iter_for_object (model,
object,
@@ -733,13 +934,28 @@ update_block (GduDeviceTreeModel *model,
sort_key = g_strdup_printf ("01_block_1_%s",
g_dbus_object_get_object_path (G_DBUS_OBJECT (object)));
+ jobs_running = block_has_jobs (model->client, block);
+
+ gtk_tree_model_get (GTK_TREE_MODEL (model),
+ &iter,
+ GDU_DEVICE_TREE_MODEL_COLUMN_PULSE, &pulse,
+ -1);
+ if (from_timer)
+ pulse += 1;
+
gtk_tree_store_set (GTK_TREE_STORE (model),
&iter,
GDU_DEVICE_TREE_MODEL_COLUMN_ICON, icon,
GDU_DEVICE_TREE_MODEL_COLUMN_NAME, s,
GDU_DEVICE_TREE_MODEL_COLUMN_SORT_KEY, sort_key,
+ GDU_DEVICE_TREE_MODEL_COLUMN_JOBS_RUNNING, jobs_running,
+ GDU_DEVICE_TREE_MODEL_COLUMN_PULSE, pulse,
-1);
+ /* update spinner, if jobs are running */
+ if (jobs_running)
+ g_timeout_add (80, spinner_timeout_block, spinner_timeout_data_new (model, object));
+
out:
g_object_unref (icon);
g_free (sort_key);
@@ -848,7 +1064,7 @@ update_blocks (GduDeviceTreeModel *model)
for (l = model->current_blocks; l != NULL; l = l->next)
{
UDisksObject *object = UDISKS_OBJECT (l->data);
- update_block (model, object);
+ update_block (model, object, FALSE);
}
if (g_list_length (model->current_blocks) == 0)
diff --git a/src/palimpsest/gdudevicetreemodel.h b/src/palimpsest/gdudevicetreemodel.h
index d110d00..abb0d33 100644
--- a/src/palimpsest/gdudevicetreemodel.h
+++ b/src/palimpsest/gdudevicetreemodel.h
@@ -41,6 +41,8 @@ enum
GDU_DEVICE_TREE_MODEL_COLUMN_NAME,
GDU_DEVICE_TREE_MODEL_COLUMN_OBJECT,
GDU_DEVICE_TREE_MODEL_COLUMN_WARNING,
+ GDU_DEVICE_TREE_MODEL_COLUMN_JOBS_RUNNING,
+ GDU_DEVICE_TREE_MODEL_COLUMN_PULSE,
GDU_DEVICE_TREE_MODEL_N_COLUMNS
};
diff --git a/src/palimpsest/gduvolumegrid.c b/src/palimpsest/gduvolumegrid.c
index 1b2ed54..358b45d 100644
--- a/src/palimpsest/gduvolumegrid.c
+++ b/src/palimpsest/gduvolumegrid.c
@@ -771,6 +771,7 @@ render_spinner (cairo_t *cr,
cairo_set_source_rgba (cr, 0, 0, 0, t);
cairo_set_line_width (cr, 2.0);
+ cairo_set_dash (cr, NULL, 0, 0.0);
cairo_move_to (cr,
cx + (radius - inset) * cos (n * M_PI / half),
cy + (radius - inset) * sin (n * M_PI / half));
@@ -1928,6 +1929,7 @@ grid_element_set_details (GduVolumeGrid *grid,
UDisksFilesystem *filesystem;
UDisksPartition *partition;
GPtrArray *lines;
+ GList *jobs;
size_str = udisks_client_get_size_for_display (grid->client, element->size, FALSE, FALSE);
block = udisks_object_peek_block (element->object);
@@ -1944,6 +1946,11 @@ grid_element_set_details (GduVolumeGrid *grid,
if (g_variant_n_children (udisks_block_get_configuration (block)) > 0)
element->show_configured = TRUE;
+ jobs = udisks_client_get_jobs_for_object (grid->client, element->object);
+ element->show_spinner = (jobs != NULL);
+ g_list_foreach (jobs, (GFunc) g_object_unref, NULL);
+ g_list_free (jobs);
+
if (partition != NULL && udisks_partition_get_is_container (partition))
{
g_ptr_array_add (lines, g_strdup (C_("volume-grid", "Extended Partition")));
diff --git a/src/palimpsest/gduwindow.c b/src/palimpsest/gduwindow.c
index 5bddc03..37f5f1b 100644
--- a/src/palimpsest/gduwindow.c
+++ b/src/palimpsest/gduwindow.c
@@ -894,6 +894,13 @@ gdu_window_constructed (GObject *object)
renderer,
"markup", GDU_DEVICE_TREE_MODEL_COLUMN_NAME,
NULL);
+ renderer = gtk_cell_renderer_spinner_new ();
+ gtk_tree_view_column_pack_end (column, renderer, FALSE);
+ gtk_tree_view_column_set_attributes (column,
+ renderer,
+ "active", GDU_DEVICE_TREE_MODEL_COLUMN_JOBS_RUNNING,
+ "pulse", GDU_DEVICE_TREE_MODEL_COLUMN_PULSE,
+ NULL);
/* expand on insertion - hmm, I wonder if there's an easier way to do this */
g_signal_connect (window->model,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]