[gnome-disk-utility] Show list of affected devices in confirmation dialogs



commit 3f7d58c468347c264c7277dc182ba3d49deabd40
Author: David Zeuthen <zeuthen gmail com>
Date:   Fri Nov 9 12:35:45 2012 -0500

    Show list of affected devices in confirmation dialogs
    
    This may help prevent a certain class of User Errors (e.g. PEBCAK) and
    is important since we don't have a way to undo most actions.
    
    http://people.freedesktop.org/~david/gnome-disks-confirmation-dialog-shows-affected-devices-1.png
    http://people.freedesktop.org/~david/gnome-disks-confirmation-dialog-shows-affected-devices-2.png
    
    Signed-off-by: David Zeuthen <zeuthen gmail com>

 src/disks/gducreateraidarraydialog.c    |   13 +++++-
 src/disks/gduerasemultipledisksdialog.c |   12 ++++-
 src/disks/gduformatdiskdialog.c         |    7 ++-
 src/disks/gduformatvolumedialog.c       |    9 +++-
 src/disks/gdumdraiddisksdialog.c        |   26 ++++++----
 src/disks/gdurestorediskimagedialog.c   |    8 ++-
 src/disks/gduwindow.c                   |   15 ++++--
 src/libgdu/gduutils.c                   |   82 ++++++++++++++++++++++++++++--
 src/libgdu/gduutils.h                   |   14 +++--
 9 files changed, 151 insertions(+), 35 deletions(-)
---
diff --git a/src/disks/gducreateraidarraydialog.c b/src/disks/gducreateraidarraydialog.c
index cdb265b..32e1f78 100644
--- a/src/disks/gducreateraidarraydialog.c
+++ b/src/disks/gducreateraidarraydialog.c
@@ -564,14 +564,25 @@ gdu_create_raid_array_dialog_show (GduWindow *window,
 
         case GTK_RESPONSE_OK:
           {
+            GList *objects = NULL, *l;
+
+            for (l = data->blocks; l != NULL; l = l->next)
+              {
+                UDisksObject *object = (UDisksObject *) g_dbus_interface_get_object (G_DBUS_INTERFACE (l->data));
+                if (object != NULL)
+                  objects = g_list_append (objects, object);
+              }
             if (!gdu_utils_show_confirmation (GTK_WINDOW (data->window),
                                               _("Are you sure you want to use the disks for a RAID array?"),
                                               _("Existing content on the devices will be erased"),
                                               _("C_reate"),
-                                              NULL, NULL))
+                                              NULL, NULL,
+                                              gdu_window_get_client (data->window), objects))
               {
+                g_list_free (objects);
                 continue;
               }
+            g_list_free (objects);
 
             /* First ensure all disks are unused... then if all that works, we
              * create the array - see ensure_unused_cb() above...
diff --git a/src/disks/gduerasemultipledisksdialog.c b/src/disks/gduerasemultipledisksdialog.c
index d2448e4..b8e5716 100644
--- a/src/disks/gduerasemultipledisksdialog.c
+++ b/src/disks/gduerasemultipledisksdialog.c
@@ -360,6 +360,7 @@ gdu_erase_multiple_disks_dialog_show (GduWindow *window,
           const gchar *primary_message;
           GString *str;
           const gchar *erase_type;
+          GList *objects = NULL, *l;
 
           erase_type = gtk_combo_box_get_active_id (GTK_COMBO_BOX (data->erase_combobox));
 
@@ -383,16 +384,25 @@ gdu_erase_multiple_disks_dialog_show (GduWindow *window,
               g_string_append (str, _("<b>WARNING</b>: The Secure Erase command may take a very long time to complete, can't be canceled and may not work properly with some hardware. In the worst case, your drive may be rendered unusable or your system may crash or lock up. Before proceeding, please read the article about <a href='https://ata.wiki.kernel.org/index.php/ATA_Secure_Erase'>ATA Secure Erase</a> and make sure you understand the risks"));
             }
 
+          for (l = data->blocks; l != NULL; l = l->next)
+            {
+              UDisksObject *object = (UDisksObject *) g_dbus_interface_get_object (G_DBUS_INTERFACE (l->data));
+              if (object != NULL)
+                objects = g_list_append (objects, object);
+            }
           if (!gdu_utils_show_confirmation (GTK_WINDOW (data->dialog),
                                             primary_message,
                                             str->str,
                                             _("_Erase"),
-                                            NULL, NULL))
+                                            NULL, NULL,
+                                            gdu_window_get_client (data->window), objects))
             {
               g_string_free (str, TRUE);
+              g_list_free (objects);
               continue;
             }
           g_string_free (str, TRUE);
+          g_list_free (objects);
           gtk_widget_hide (data->dialog);
           erase_devices (data, erase_type);
           ret = TRUE;
diff --git a/src/disks/gduformatdiskdialog.c b/src/disks/gduformatdiskdialog.c
index 3cf880c..43c862a 100644
--- a/src/disks/gduformatdiskdialog.c
+++ b/src/disks/gduformatdiskdialog.c
@@ -411,6 +411,7 @@ gdu_format_disk_dialog_show (GduWindow    *window,
       const gchar *erase_type;
       const gchar *primary_message;
       GString *str;
+      GList *objects = NULL;
 
       erase_type = gtk_combo_box_get_active_id (GTK_COMBO_BOX (data->erase_combobox));
 
@@ -436,16 +437,20 @@ gdu_format_disk_dialog_show (GduWindow    *window,
           g_string_append (str, _("<b>WARNING</b>: The Secure Erase command may take a very long time to complete, can't be canceled and may not work properly with some hardware. In the worst case, your drive may be rendered unusable or your system may crash or lock up. Before proceeding, please read the article about <a href='https://ata.wiki.kernel.org/index.php/ATA_Secure_Erase'>ATA Secure Erase</a> and make sure you understand the risks"));
         }
 
+      objects = g_list_append (NULL, object);
       gtk_widget_hide (data->dialog);
       if (!gdu_utils_show_confirmation (GTK_WINDOW (window),
                                         primary_message,
                                         str->str,
                                         _("_Format"),
-                                        NULL, NULL))
+                                        NULL, NULL,
+                                        gdu_window_get_client (data->window), objects))
         {
+          g_list_free (objects);
           g_string_free (str, TRUE);
           goto out;
         }
+      g_list_free (objects);
       g_string_free (str, TRUE);
 
       /* ensure the volume is unused (e.g. unmounted) before formatting it... */
diff --git a/src/disks/gduformatvolumedialog.c b/src/disks/gduformatvolumedialog.c
index 43dc9db..e0f872c 100644
--- a/src/disks/gduformatvolumedialog.c
+++ b/src/disks/gduformatvolumedialog.c
@@ -182,6 +182,7 @@ gdu_format_volume_dialog_show (GduWindow    *window,
       const gchar *primary_message;
       const gchar *erase_type;
       GString *str;
+      GList *objects = NULL;
 
       gtk_widget_hide (data->dialog);
 
@@ -201,15 +202,19 @@ gdu_format_volume_dialog_show (GduWindow    *window,
           str = g_string_new (_("All data on the volume will be overwritten and will likely not be recoverable by data recovery services"));
         }
 
-      if (!gdu_utils_show_confirmation (GTK_WINDOW (window),
+      objects = g_list_append (NULL, object);
+      if (!gdu_utils_show_confirmation (GTK_WINDOW (data->window),
                                         primary_message,
                                         str->str,
                                         _("_Format"),
-                                        NULL, NULL))
+                                        NULL, NULL,
+                                        gdu_window_get_client (data->window), objects))
         {
+          g_list_free (objects);
           g_string_free (str, TRUE);
           goto out;
         }
+      g_list_free (objects);
       g_string_free (str, TRUE);
 
       /* ensure the volume is unused (e.g. unmounted) before formatting it... */
diff --git a/src/disks/gdumdraiddisksdialog.c b/src/disks/gdumdraiddisksdialog.c
index 5c5ee4a..ae19512 100644
--- a/src/disks/gdumdraiddisksdialog.c
+++ b/src/disks/gdumdraiddisksdialog.c
@@ -363,18 +363,8 @@ on_remove_toolbutton_clicked (GtkToolButton   *tool_button,
   UDisksBlock *selected_block = NULL;
   UDisksObject *selected_block_object = NULL;
   GtkTreeIter titer;
+  GList *objects = NULL;
 
-  if (!gdu_utils_show_confirmation (GTK_WINDOW (data->dialog),
-                                    C_("mdraid-disks", "Are you sure you want to remove the disk?"),
-                                    C_("mdraid-disks", "Removing a disk from a RAID array may degrade it"),
-                                    C_("mdraid-disks", "_Remove"),
-                                    C_("mdraid-disks", "_Quick-format after removal"),
-                                    &opt_wipe))
-    goto out;
-
-  g_variant_builder_init (&options_builder, G_VARIANT_TYPE_VARDICT);
-  if (opt_wipe)
-    g_variant_builder_add (&options_builder, "{sv}", "wipe", g_variant_new_boolean (TRUE));
   if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (data->treeview)),
                                        NULL, /* out_model */
                                        &titer))
@@ -393,6 +383,19 @@ on_remove_toolbutton_clicked (GtkToolButton   *tool_button,
       goto out;
     }
 
+  objects = g_list_append (NULL, selected_block_object);
+  if (!gdu_utils_show_confirmation (GTK_WINDOW (data->dialog),
+                                    C_("mdraid-disks", "Are you sure you want to remove the disk?"),
+                                    C_("mdraid-disks", "Removing a disk from a RAID array may degrade it"),
+                                    C_("mdraid-disks", "_Remove"),
+                                    C_("mdraid-disks", "_Quick-format after removal"), &opt_wipe,
+                                    gdu_window_get_client (data->window), objects))
+    goto out;
+
+  g_variant_builder_init (&options_builder, G_VARIANT_TYPE_VARDICT);
+  if (opt_wipe)
+    g_variant_builder_add (&options_builder, "{sv}", "wipe", g_variant_new_boolean (TRUE));
+
   udisks_mdraid_call_remove_device (data->mdraid,
                                     g_dbus_object_get_object_path (G_DBUS_OBJECT (selected_block_object)),
                                     g_variant_builder_end (&options_builder),
@@ -403,6 +406,7 @@ on_remove_toolbutton_clicked (GtkToolButton   *tool_button,
  out:
   g_clear_object (&selected_block_object);
   g_clear_object (&selected_block);
+  g_list_free (objects);
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
diff --git a/src/disks/gdurestorediskimagedialog.c b/src/disks/gdurestorediskimagedialog.c
index c8fdf89..5729479 100644
--- a/src/disks/gdurestorediskimagedialog.c
+++ b/src/disks/gdurestorediskimagedialog.c
@@ -776,10 +776,13 @@ on_dialog_response (GtkDialog     *dialog,
                     gpointer       user_data)
 {
   DialogData *data = user_data;
+  GList *objects = NULL;
 
   if (data->dialog == NULL)
     goto out;
 
+  objects = g_list_append (NULL, data->object);
+
   switch (response)
     {
     case GTK_RESPONSE_OK:
@@ -787,7 +790,8 @@ on_dialog_response (GtkDialog     *dialog,
                                         _("Are you sure you want to write the disk image to the device?"),
                                         _("All existing data will be lost"),
                                         _("_Restore"),
-                                        NULL, NULL))
+                                        NULL, NULL,
+                                        gdu_window_get_client (data->window), objects))
         {
           dialog_data_complete_and_unref (data);
           goto out;
@@ -819,7 +823,7 @@ on_dialog_response (GtkDialog     *dialog,
       break;
     }
  out:
-  ;
+  g_list_free (objects);
 }
 
 void
diff --git a/src/disks/gduwindow.c b/src/disks/gduwindow.c
index 76eb1b8..97da277 100644
--- a/src/disks/gduwindow.c
+++ b/src/disks/gduwindow.c
@@ -3899,16 +3899,20 @@ on_devtab_action_partition_delete_activated (GtkAction *action,
   GduWindow *window = GDU_WINDOW (user_data);
   UDisksObject *object;
   UDisksPartition *partition;
+  GList *objects = NULL;
 
+  object = gdu_volume_grid_get_selected_device (GDU_VOLUME_GRID (window->volume_grid));
+  partition = udisks_object_peek_partition (object);
+
+  objects = g_list_append (NULL, object);
   if (!gdu_utils_show_confirmation (GTK_WINDOW (window),
                                     _("Are you sure you want to delete the partition?"),
                                     _("All data on the partition will be lost"),
                                     _("_Delete"),
-                                    NULL, NULL))
+                                    NULL, NULL,
+                                    window->client, objects))
     goto out;
 
-  object = gdu_volume_grid_get_selected_device (GDU_VOLUME_GRID (window->volume_grid));
-  partition = udisks_object_peek_partition (object);
   udisks_partition_call_delete (partition,
                                 g_variant_new ("a{sv}", NULL), /* options */
                                 NULL, /* cancellable */
@@ -3916,7 +3920,7 @@ on_devtab_action_partition_delete_activated (GtkAction *action,
                                 g_object_ref (window));
 
  out:
-  ;
+  g_list_free (objects);
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
@@ -4015,7 +4019,8 @@ on_devtab_drive_action_raid_start_activated (GtkAction *action,
                                         C_("mdraid", "Are you sure you want to start the RAID array degraded?"),
                                         C_("mdraid", "A degraded RAID array is vulnerable to data- and performance-loss"),
                                         C_("mdraid", "_Start"),
-                                        NULL, NULL))
+                                        NULL, NULL,
+                                        window->client, NULL))
         goto out;
 
       g_variant_builder_add (&options_builder, "{sv}", "start-degraded", g_variant_new_boolean (TRUE));
diff --git a/src/libgdu/gduutils.c b/src/libgdu/gduutils.c
index dd574b8..c6167de 100644
--- a/src/libgdu/gduutils.c
+++ b/src/libgdu/gduutils.c
@@ -618,13 +618,41 @@ gdu_utils_show_error (GtkWindow   *parent_window,
 
 /* ---------------------------------------------------------------------------------------------------- */
 
+static GtkWidget *
+get_widget_for_object (UDisksClient *client,
+                       UDisksObject *object)
+{
+  UDisksObjectInfo *info;
+  GtkWidget *hbox;
+  GtkWidget *image;
+  GtkWidget *label;
+
+  info = udisks_client_get_object_info (client, object);
+
+  hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
+
+  image = gtk_image_new_from_gicon (info->icon, GTK_ICON_SIZE_SMALL_TOOLBAR);
+  gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
+
+  label = gtk_label_new (info->one_liner);
+  gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_MIDDLE);
+  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+  gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+
+  udisks_object_info_unref (info);
+
+  return hbox;
+}
+
 gboolean
-gdu_utils_show_confirmation (GtkWindow   *parent_window,
-                             const gchar *message,
-                             const gchar *secondary_message,
-                             const gchar *affirmative_verb,
-                             const gchar *checkbox_mnemonic,
-                             gboolean    *inout_checkbox_value)
+gdu_utils_show_confirmation (GtkWindow    *parent_window,
+                             const gchar  *message,
+                             const gchar  *secondary_message,
+                             const gchar  *affirmative_verb,
+                             const gchar  *checkbox_mnemonic,
+                             gboolean     *inout_checkbox_value,
+                             UDisksClient *client,
+                             GList        *objects)
 {
   GtkWidget *check_button = NULL;
   GtkWidget *dialog;
@@ -650,6 +678,48 @@ gdu_utils_show_confirmation (GtkWindow   *parent_window,
         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button), *inout_checkbox_value);
     }
 
+  if (objects != NULL)
+    {
+      GtkWidget *label;
+      GtkWidget *vbox;
+      GtkWidget *scrolled_window;
+      GList *l;
+      PangoAttrList *attrs;
+
+      vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
+      gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
+      for (l = objects; l != NULL; l = l->next)
+        {
+          UDisksObject *object = UDISKS_OBJECT (l->data);
+          gtk_box_pack_start (GTK_BOX (vbox),
+                              get_widget_for_object (client, object),
+                              FALSE, FALSE, 0);
+        }
+
+      label = gtk_label_new (NULL);
+      gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+      /* Translators: Shown in confirmation dialogs with a list of devices that will be affected by the action */
+      gtk_label_set_markup (GTK_LABEL (label), C_("confirmation-list-of-devices", "Affected Devices"));
+      attrs = pango_attr_list_new ();
+      pango_attr_list_insert (attrs, pango_attr_weight_new (PANGO_WEIGHT_BOLD));
+      gtk_label_set_attributes (GTK_LABEL (label), attrs);
+      pango_attr_list_unref (attrs);
+
+      scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+      gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
+      gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window), GTK_SHADOW_OUT);
+      gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_window), vbox);
+      gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (scrolled_window), 125);
+      gtk_widget_set_margin_left (scrolled_window, 24);
+
+      gtk_box_pack_start (GTK_BOX (gtk_message_dialog_get_message_area (GTK_MESSAGE_DIALOG (dialog))),
+                          label,
+                          FALSE, FALSE, 0);
+      gtk_box_pack_start (GTK_BOX (gtk_message_dialog_get_message_area (GTK_MESSAGE_DIALOG (dialog))),
+                          scrolled_window,
+                          FALSE, FALSE, 0);
+    }
+
   gtk_dialog_add_button (GTK_DIALOG (dialog),
                          affirmative_verb,
                          GTK_RESPONSE_OK);
diff --git a/src/libgdu/gduutils.h b/src/libgdu/gduutils.h
index 7d4ef1c..17293c7 100644
--- a/src/libgdu/gduutils.h
+++ b/src/libgdu/gduutils.h
@@ -50,12 +50,14 @@ void            gdu_utils_show_error      (GtkWindow      *parent_window,
                                            const gchar    *message,
                                            GError         *error);
 
-gboolean        gdu_utils_show_confirmation (GtkWindow   *parent_window,
-                                             const gchar *message,
-                                             const gchar *secondary_message,
-                                             const gchar *affirmative_verb,
-                                             const gchar *checkbox_mnemonic,
-                                             gboolean    *inout_checkbox_value);
+gboolean        gdu_utils_show_confirmation (GtkWindow    *parent_window,
+                                             const gchar  *message,
+                                             const gchar  *secondary_message,
+                                             const gchar  *affirmative_verb,
+                                             const gchar  *checkbox_mnemonic,
+                                             gboolean     *inout_checkbox_value,
+                                             UDisksClient *client,
+                                             GList        *objects);
 
 gboolean gdu_utils_is_ntfs_available (void);
 



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