[gnome-disk-utility] Disable action buttons during jobs



commit 090c1e40fe92f844fb38d5000104fdedbeeafe5a
Author: Kai Lüke <kailueke riseup net>
Date:   Mon Jul 17 23:15:45 2017 +0200

    Disable action buttons during jobs
    
    While jobs are running all actions like format,
    delete etc. have to be unavailable if they impact
    the same object.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=732565

 src/disks/gduapplication.c |   64 ++++++++++++++++++++++++++++++++++++++++++++
 src/disks/gduapplication.h |    3 ++
 src/disks/gduwindow.c      |   27 ++++++++++++++++--
 src/libgdu/gduutils.c      |   45 ++++++++++++++++++++----------
 src/libgdu/gduutils.h      |    3 ++
 5 files changed, 124 insertions(+), 18 deletions(-)
---
diff --git a/src/disks/gduapplication.c b/src/disks/gduapplication.c
index 61b1f44..113f64e 100644
--- a/src/disks/gduapplication.c
+++ b/src/disks/gduapplication.c
@@ -560,3 +560,67 @@ gdu_application_get_local_jobs_for_object (GduApplication *application,
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
+
+gboolean
+gdu_application_has_running_job (GduApplication *application,
+                                 UDisksObject   *object)
+{
+  UDisksClient *client;
+  GList *l;
+  GList *jobs = NULL;
+  GList *objects_to_check = NULL;
+  gboolean ret = FALSE;
+
+  client = gdu_application_get_client (application);
+  objects_to_check = gdu_utils_get_all_contained_objects (client, object);
+  objects_to_check = g_list_prepend (objects_to_check, g_object_ref (object));
+
+  for (l = objects_to_check; l != NULL; l = l->next)
+    {
+      UDisksObject *object_iter = UDISKS_OBJECT (l->data);
+      UDisksEncrypted *encrypted_for_object;
+
+      jobs = udisks_client_get_jobs_for_object (client, object_iter);
+      if (jobs != NULL)
+        {
+          ret = TRUE;
+          break;
+        }
+
+      jobs = gdu_application_get_local_jobs_for_object (application, object_iter);
+      if (jobs != NULL)
+        {
+          ret = TRUE;
+          break;
+        }
+
+      encrypted_for_object = udisks_object_peek_encrypted (object_iter);
+      if (encrypted_for_object != NULL)
+        {
+          UDisksBlock *block_for_object;
+          UDisksBlock *cleartext;
+
+          block_for_object = udisks_object_peek_block (object_iter);
+          cleartext = udisks_client_get_cleartext_block (client, block_for_object);
+          if (cleartext != NULL)
+            {
+              UDisksObject *cleartext_object;
+
+              cleartext_object = (UDisksObject *) g_dbus_interface_get_object (G_DBUS_INTERFACE (cleartext));
+              g_object_unref (cleartext);
+
+              ret = gdu_application_has_running_job (application, cleartext_object);
+              if (ret)
+                break;
+            }
+        }
+
+    }
+
+  g_list_foreach (jobs, (GFunc) g_object_unref, NULL);
+  g_list_free (jobs);
+  g_list_free_full (objects_to_check, g_object_unref);
+
+  return ret;
+}
+
diff --git a/src/disks/gduapplication.h b/src/disks/gduapplication.h
index fb3911a..5f612a3 100644
--- a/src/disks/gduapplication.h
+++ b/src/disks/gduapplication.h
@@ -36,6 +36,9 @@ void          gdu_application_destroy_local_job (GduApplication *application,
 GList        *gdu_application_get_local_jobs_for_object (GduApplication *application,
                                                          UDisksObject   *object);
 
+gboolean      gdu_application_has_running_job (GduApplication *application,
+                                               UDisksObject   *object);
+
 
 G_END_DECLS
 
diff --git a/src/disks/gduwindow.c b/src/disks/gduwindow.c
index 5a07085..fa8ed0d 100644
--- a/src/disks/gduwindow.c
+++ b/src/disks/gduwindow.c
@@ -52,6 +52,8 @@ struct _GduWindow
   GduDeviceTreeModel *model;
 
   UDisksObject *current_object;
+  gboolean has_drive_job;
+  gboolean has_volume_job;
 
   GtkWidget *volume_grid;
 
@@ -1070,6 +1072,9 @@ gdu_window_constructed (GObject *object)
       g_warn_if_fail (*p != NULL);
     }
 
+  window->has_drive_job = FALSE;
+  window->has_volume_job = FALSE;
+
   window->header = create_header (window);
   if (!in_desktop ("Unity"))
       gtk_window_set_titlebar (GTK_WINDOW (window), window->header);
@@ -1909,6 +1914,8 @@ update_jobs (GduWindow *window,
   GtkWidget *remaining_label = window->devtab_drive_job_remaining_label;
   GtkWidget *no_progress_label = window->devtab_drive_job_no_progress_label;
   GtkWidget *cancel_button = window->devtab_drive_job_cancel_button;
+  gboolean drive_sensitivity;
+  gboolean selected_volume_sensitivity;
 
   if (is_volume)
     {
@@ -1920,6 +1927,15 @@ update_jobs (GduWindow *window,
       cancel_button = window->devtab_job_cancel_button;
     }
 
+  drive_sensitivity = !gdu_application_has_running_job (window->application, window->current_object);
+  gtk_widget_set_sensitive (window->devtab_drive_generic_button, drive_sensitivity);
+  gtk_widget_set_sensitive (window->devtab_drive_eject_button, drive_sensitivity);
+  gtk_widget_set_sensitive (window->devtab_drive_power_off_button, drive_sensitivity);
+  gtk_widget_set_sensitive (window->devtab_drive_loop_detach_button, drive_sensitivity);
+
+  selected_volume_sensitivity = (!window->has_volume_job && !window->has_drive_job);
+  gtk_widget_set_sensitive (window->devtab_grid_toolbar, selected_volume_sensitivity);
+
   if (jobs == NULL)
     {
       gtk_widget_hide (label);
@@ -1991,13 +2007,18 @@ static void
 update_drive_jobs (GduWindow *window,
                    GList     *jobs)
 {
+  window->has_volume_job = FALSE; /* comes before update_volume_jobs */
+  window->has_drive_job = (jobs != NULL);
   update_jobs (window, jobs, FALSE);
 }
 
 static void
-update_volume_jobs (GduWindow *window,
-                    GList     *jobs)
+update_volume_jobs (GduWindow    *window,
+                    GList        *jobs,
+                    UDisksObject *origin_object)
 {
+  /* in contrast to variable 'jobs' this call includes jobs on contained objects */
+  window->has_volume_job = gdu_application_has_running_job (window->application, origin_object);
   update_jobs (window, jobs, TRUE);
 }
 
@@ -2804,7 +2825,7 @@ update_device_page_for_block (GduWindow          *window,
       jobs = udisks_client_get_jobs_for_object (window->client, object);
       jobs = g_list_concat (jobs, gdu_application_get_local_jobs_for_object (window->application, object));
     }
-  update_volume_jobs (window, jobs);
+  update_volume_jobs (window, jobs, object);
   g_list_foreach (jobs, (GFunc) g_object_unref, NULL);
   g_list_free (jobs);
   g_clear_object (&partition_table);
diff --git a/src/libgdu/gduutils.c b/src/libgdu/gduutils.c
index d9ab9e1..76520ba 100644
--- a/src/libgdu/gduutils.c
+++ b/src/libgdu/gduutils.c
@@ -1146,15 +1146,10 @@ gdu_utils_get_pretty_uri (GFile *file)
 
 /* ---------------------------------------------------------------------------------------------------- */
 
-static gboolean
-gdu_utils_is_in_use_full (UDisksClient      *client,
-                          UDisksObject      *object,
-                          UDisksFilesystem **filesystem_to_unmount_out,
-                          UDisksEncrypted  **encrypted_to_lock_out,
-                          gboolean          *last_out)
+GList *
+gdu_utils_get_all_contained_objects (UDisksClient *client,
+                                     UDisksObject *object)
 {
-  UDisksFilesystem *filesystem_to_unmount = NULL;
-  UDisksEncrypted *encrypted_to_lock = NULL;
   UDisksBlock *block = NULL;
   UDisksDrive *drive = NULL;
   UDisksObject *block_object = NULL;
@@ -1162,8 +1157,6 @@ gdu_utils_is_in_use_full (UDisksClient      *client,
   GList *partitions = NULL;
   GList *l;
   GList *objects_to_check = NULL;
-  gboolean ret = FALSE;
-  gboolean last = TRUE;
 
   drive = udisks_object_get_drive (object);
   if (drive != NULL)
@@ -1219,6 +1212,33 @@ gdu_utils_is_in_use_full (UDisksClient      *client,
         }
     }
 
+  g_clear_object (&partition_table);
+  g_list_free_full (partitions, g_object_unref);
+  g_clear_object (&block_object);
+  g_clear_object (&block);
+  g_clear_object (&drive);
+
+  return objects_to_check;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static gboolean
+gdu_utils_is_in_use_full (UDisksClient      *client,
+                          UDisksObject      *object,
+                          UDisksFilesystem **filesystem_to_unmount_out,
+                          UDisksEncrypted  **encrypted_to_lock_out,
+                          gboolean          *last_out)
+{
+  UDisksFilesystem *filesystem_to_unmount = NULL;
+  UDisksEncrypted *encrypted_to_lock = NULL;
+  GList *l;
+  GList *objects_to_check = NULL;
+  gboolean ret = FALSE;
+  gboolean last = TRUE;
+
+  objects_to_check = gdu_utils_get_all_contained_objects (client, object);
+
   /* Check in reverse order, e.g. cleartext before LUKS, partitions before the main block device */
   objects_to_check = g_list_reverse (objects_to_check);
   for (l = objects_to_check; l != NULL; l = l->next)
@@ -1284,14 +1304,9 @@ gdu_utils_is_in_use_full (UDisksClient      *client,
   if (last_out != NULL)
     *last_out = last;
 
-  g_clear_object (&partition_table);
-  g_list_free_full (partitions, g_object_unref);
   g_list_free_full (objects_to_check, g_object_unref);
   g_clear_object (&encrypted_to_lock);
   g_clear_object (&filesystem_to_unmount);
-  g_clear_object (&block_object);
-  g_clear_object (&block);
-  g_clear_object (&drive);
 
   return ret;
 }
diff --git a/src/libgdu/gduutils.h b/src/libgdu/gduutils.h
index c54a39d..815e3ef 100644
--- a/src/libgdu/gduutils.h
+++ b/src/libgdu/gduutils.h
@@ -112,6 +112,9 @@ gboolean gdu_util_is_same_size (GList   *blocks,
 
 gchar *gdu_utils_get_pretty_uri (GFile *file);
 
+GList *gdu_utils_get_all_contained_objects (UDisksClient *client,
+                                            UDisksObject *object);
+
 gboolean gdu_utils_is_in_use (UDisksClient *client,
                               UDisksObject *object);
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]