[gnome-disk-utility] Add support for powering off drives
- From: David Zeuthen <davidz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-disk-utility] Add support for powering off drives
- Date: Mon, 19 Nov 2012 03:12:26 +0000 (UTC)
commit 767510d06ec844e330a5ac3a8057394735e3d39f
Author: David Zeuthen <zeuthen gmail com>
Date: Sun Nov 18 22:10:54 2012 -0500
Add support for powering off drives
This was removed in 3.4, now it's back.
http://people.freedesktop.org/~david/gnome-disks-power-off-drive-1.png
http://people.freedesktop.org/~david/gnome-disks-power-off-drive-2.png
http://people.freedesktop.org/~david/gnome-disks-power-off-drive-3.png
https://bugzilla.gnome.org/show_bug.cgi?id=675542
Signed-off-by: David Zeuthen <zeuthen gmail com>
data/ui/disks.ui | 8 ++
src/disks/gduwindow.c | 208 ++++++++++++++++++++++++++++++++++++++++++-------
src/disks/gduwindow.h | 10 +++
3 files changed, 199 insertions(+), 27 deletions(-)
---
diff --git a/data/ui/disks.ui b/data/ui/disks.ui
index 718ecd6..fbe8d6e 100644
--- a/data/ui/disks.ui
+++ b/data/ui/disks.ui
@@ -1769,6 +1769,14 @@
</object>
</child>
<child>
+ <object class="GtkMenuItem" id="generic-drive-menu-item-power-off">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Power Off...</property>
+ <property name="use_underline">True</property>
+ </object>
+ </child>
+ <child>
<object class="GtkSeparatorMenuItem" id="generic-drive-menu-item-mdraid-sep-1">
<property name="visible">True</property>
<property name="can_focus">False</property>
diff --git a/src/disks/gduwindow.c b/src/disks/gduwindow.c
index fe70953..02de890 100644
--- a/src/disks/gduwindow.c
+++ b/src/disks/gduwindow.c
@@ -124,6 +124,7 @@ struct _GduWindow
GtkWidget *generic_drive_menu_item_drive_sep_2;
GtkWidget *generic_drive_menu_item_standby_now;
GtkWidget *generic_drive_menu_item_resume_now;
+ GtkWidget *generic_drive_menu_item_power_off;
/* MDRaid-specific items */
GtkWidget *generic_drive_menu_item_mdraid_sep_1;
GtkWidget *generic_drive_menu_item_mdraid_disks;
@@ -234,6 +235,7 @@ static const struct {
{G_STRUCT_OFFSET (GduWindow, generic_drive_menu_item_drive_sep_2), "generic-drive-menu-item-drive-sep-2"},
{G_STRUCT_OFFSET (GduWindow, generic_drive_menu_item_standby_now), "generic-drive-menu-item-standby-now"},
{G_STRUCT_OFFSET (GduWindow, generic_drive_menu_item_resume_now), "generic-drive-menu-item-resume-now"},
+ {G_STRUCT_OFFSET (GduWindow, generic_drive_menu_item_power_off), "generic-drive-menu-item-power-off"},
/* MDRaid-specific items */
{G_STRUCT_OFFSET (GduWindow, generic_drive_menu_item_mdraid_sep_1), "generic-drive-menu-item-mdraid-sep-1"},
{G_STRUCT_OFFSET (GduWindow, generic_drive_menu_item_mdraid_disks), "generic-drive-menu-item-mdraid-disks"},
@@ -306,7 +308,8 @@ typedef enum
SHOW_FLAGS_DRIVE_MENU_DISK_SETTINGS = (1<<5),
SHOW_FLAGS_DRIVE_MENU_STANDBY_NOW = (1<<6),
SHOW_FLAGS_DRIVE_MENU_RESUME_NOW = (1<<7),
- SHOW_FLAGS_DRIVE_MENU_MDRAID_DISKS = (1<<8),
+ SHOW_FLAGS_DRIVE_MENU_POWER_OFF = (1<<8),
+ SHOW_FLAGS_DRIVE_MENU_MDRAID_DISKS = (1<<9),
} ShowFlagsDriveMenu;
typedef enum {
@@ -377,6 +380,8 @@ static void on_generic_drive_menu_item_standby_now (GtkMenuItem *menu_item,
gpointer user_data);
static void on_generic_drive_menu_item_resume_now (GtkMenuItem *menu_item,
gpointer user_data);
+static void on_generic_drive_menu_item_power_off (GtkMenuItem *menu_item,
+ gpointer user_data);
static void on_generic_drive_menu_item_format_disk (GtkMenuItem *menu_item,
gpointer user_data);
static void on_generic_drive_menu_item_create_disk_image (GtkMenuItem *menu_item,
@@ -551,6 +556,8 @@ update_for_show_flags (GduWindow *window,
show_flags->drive_menu & SHOW_FLAGS_DRIVE_MENU_BENCHMARK);
gtk_widget_set_sensitive (GTK_WIDGET (window->generic_drive_menu_item_mdraid_disks),
show_flags->drive_menu & SHOW_FLAGS_DRIVE_MENU_MDRAID_DISKS);
+ gtk_widget_set_sensitive (GTK_WIDGET (window->generic_drive_menu_item_power_off),
+ show_flags->drive_menu & SHOW_FLAGS_DRIVE_MENU_POWER_OFF);
gtk_widget_set_sensitive (GTK_WIDGET (window->generic_menu_item_configure_fstab),
show_flags->volume_menu & SHOW_FLAGS_VOLUME_MENU_CONFIGURE_FSTAB);
@@ -1488,6 +1495,10 @@ gdu_window_constructed (GObject *object)
"activate",
G_CALLBACK (on_generic_drive_menu_item_resume_now),
window);
+ g_signal_connect (window->generic_drive_menu_item_power_off,
+ "activate",
+ G_CALLBACK (on_generic_drive_menu_item_power_off),
+ window);
g_signal_connect (window->generic_drive_menu_item_format_disk,
"activate",
G_CALLBACK (on_generic_drive_menu_item_format_disk),
@@ -2671,6 +2682,10 @@ update_device_page_for_drive (GduWindow *window,
}
}
+
+ if (udisks_drive_get_can_power_off (drive))
+ show_flags->drive_menu |= SHOW_FLAGS_DRIVE_MENU_POWER_OFF;
+
size = udisks_drive_get_size (drive);
if (size > 0)
{
@@ -2726,7 +2741,7 @@ update_device_page_for_drive (GduWindow *window,
gtk_widget_show (GTK_WIDGET (window->generic_drive_menu_item_drive_sep_2));
if (!(show_flags->drive_menu & (SHOW_FLAGS_DRIVE_MENU_STANDBY_NOW|SHOW_FLAGS_DRIVE_MENU_RESUME_NOW)))
{
- /* no PM capabilities... only show "standby" greyed out */
+ /* no PM / safely-remove capabilities... only show "standby" greyed out */
gtk_widget_show (GTK_WIDGET (window->generic_drive_menu_item_standby_now));
gtk_widget_set_sensitive (GTK_WIDGET (window->generic_drive_menu_item_standby_now), FALSE);
}
@@ -2740,7 +2755,7 @@ update_device_page_for_drive (GduWindow *window,
else
gtk_widget_show (GTK_WIDGET (window->generic_drive_menu_item_resume_now));
}
-
+ gtk_widget_show (GTK_WIDGET (window->generic_drive_menu_item_power_off));
g_list_foreach (blocks, (GFunc) g_object_unref, NULL);
g_list_free (blocks);
@@ -3379,6 +3394,7 @@ update_device_page (GduWindow *window,
gtk_widget_hide (GTK_WIDGET (window->generic_drive_menu_item_drive_sep_2));
gtk_widget_hide (GTK_WIDGET (window->generic_drive_menu_item_standby_now));
gtk_widget_hide (GTK_WIDGET (window->generic_drive_menu_item_resume_now));
+ gtk_widget_hide (GTK_WIDGET (window->generic_drive_menu_item_power_off));
/* Hide all MDRaid-specific items - will be turned on again in update_device_page_for_mdraid() */
gtk_widget_hide (GTK_WIDGET (window->generic_drive_menu_item_mdraid_sep_1));
@@ -3725,6 +3741,105 @@ on_generic_drive_menu_item_resume_now (GtkMenuItem *menu_item,
/* ---------------------------------------------------------------------------------------------------- */
static void
+power_off_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GduWindow *window = GDU_WINDOW (user_data);
+ GError *error = NULL;
+
+ if (!udisks_drive_call_power_off_finish (UDISKS_DRIVE (source_object),
+ res,
+ &error))
+ {
+ gdu_utils_show_error (GTK_WINDOW (window),
+ _("Error powering off drive"),
+ error);
+ g_clear_error (&error);
+ }
+ g_object_unref (window);
+}
+
+static void
+power_off_ensure_unused_cb (GduWindow *window,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ UDisksObject *object = UDISKS_OBJECT (user_data);
+ if (gdu_window_ensure_unused_finish (window, res, NULL))
+ {
+ UDisksDrive *drive = udisks_object_peek_drive (object);
+ udisks_drive_call_power_off (drive,
+ g_variant_new ("a{sv}", NULL), /* options */
+ NULL, /* GCancellable */
+ (GAsyncReadyCallback) power_off_cb,
+ g_object_ref (window));
+ }
+ g_object_unref (object);
+}
+
+static void
+on_generic_drive_menu_item_power_off (GtkMenuItem *menu_item,
+ gpointer user_data)
+{
+ GduWindow *window = GDU_WINDOW (user_data);
+ UDisksObject *object;
+ GList *objects = NULL;
+ GList *siblings, *l;
+ UDisksDrive *drive;
+ const gchar *heading;
+ const gchar *message;
+
+ object = window->current_object;
+ drive = udisks_object_peek_drive (object);
+ objects = g_list_append (NULL, object);
+
+ /* include other drives this will affect */
+ siblings = udisks_client_get_drive_siblings (window->client, drive);
+ for (l = siblings; l != NULL; l = l->next)
+ {
+ UDisksDrive *sibling = UDISKS_DRIVE (l->data);
+ UDisksObject *sibling_object = (UDisksObject *) g_dbus_interface_get_object (G_DBUS_INTERFACE (sibling));
+ if (sibling_object != NULL)
+ objects = g_list_append (objects, sibling_object);
+ }
+
+ if (siblings == NULL)
+ {
+ /* Translators: Heading for powering off a device with a single drive */
+ heading = _("Are you sure you want to power off the drive?");
+ /* Translators: Message for powering off a device with a single drive */
+ message = _("This operation will prepare the system for the drive to be removed and powered down.");
+ }
+ else
+ {
+ /* Translators: Heading for powering off a device with multiple drives */
+ heading = _("Are you sure you want to power off the drives?");
+ /* Translators: Message for powering off a device with multiple drives */
+ message = _("This operation will prepare the system for the following drives to be removed and powered down.");
+ }
+
+ if (!gdu_utils_show_confirmation (GTK_WINDOW (window),
+ heading,
+ message,
+ _("_Power Off"),
+ NULL, NULL,
+ window->client, objects))
+ goto out;
+
+ gdu_window_ensure_unused_list (window,
+ objects,
+ (GAsyncReadyCallback) power_off_ensure_unused_cb,
+ NULL, /* GCancellable */
+ g_object_ref (object));
+ out:
+ g_list_free_full (siblings, g_object_unref);
+ g_list_free (objects);
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
on_generic_menu_item_configure_crypttab (GtkMenuItem *menu_item,
gpointer user_data)
{
@@ -4647,7 +4762,8 @@ on_ms_raid_menu_item_create_activated (GtkMenuItem *menu_item,
typedef struct
{
GduWindow *window;
- UDisksObject *object;
+ GList *objects;
+ GList *object_iter;
GSimpleAsyncResult *simple;
GCancellable *cancellable; /* borrowed ref */
} UnuseData;
@@ -4656,7 +4772,7 @@ static void
unuse_data_free (UnuseData *data)
{
g_clear_object (&data->window);
- g_clear_object (&data->object);
+ g_list_free_full (data->objects, g_object_unref);
g_clear_object (&data->simple);
g_slice_free (UnuseData, data);
}
@@ -4722,6 +4838,7 @@ unuse_lock_cb (UDisksEncrypted *encrypted,
static void
unuse_data_iterate (UnuseData *data)
{
+ UDisksObject *object;
UDisksFilesystem *filesystem_to_unmount = NULL;
UDisksEncrypted *encrypted_to_lock = NULL;
UDisksBlock *block = NULL;
@@ -4732,7 +4849,9 @@ unuse_data_iterate (UnuseData *data)
GList *l;
GList *objects_to_check = NULL;
- drive = udisks_object_get_drive (data->object);
+ object = UDISKS_OBJECT (data->object_iter->data);
+
+ drive = udisks_object_get_drive (object);
if (drive != NULL)
{
block = udisks_client_get_block_for_drive (data->window->client,
@@ -4741,7 +4860,7 @@ unuse_data_iterate (UnuseData *data)
}
else
{
- block = udisks_object_get_block (data->object);
+ block = udisks_object_get_block (object);
}
if (block != NULL)
@@ -4768,9 +4887,9 @@ unuse_data_iterate (UnuseData *data)
/* Add LUKS objects */
for (l = objects_to_check; l != NULL; l = l->next)
{
- UDisksObject *object = UDISKS_OBJECT (l->data);
+ UDisksObject *object_iter = UDISKS_OBJECT (l->data);
UDisksBlock *block_for_object;
- block_for_object = udisks_object_peek_block (object);
+ block_for_object = udisks_object_peek_block (object_iter);
if (block_for_object != NULL)
{
UDisksBlock *cleartext;
@@ -4790,14 +4909,14 @@ unuse_data_iterate (UnuseData *data)
objects_to_check = g_list_reverse (objects_to_check);
for (l = objects_to_check; l != NULL; l = l->next)
{
- UDisksObject *object = UDISKS_OBJECT (l->data);
+ UDisksObject *object_iter = UDISKS_OBJECT (l->data);
UDisksBlock *block_for_object;
UDisksFilesystem *filesystem_for_object;
UDisksEncrypted *encrypted_for_object;
- block_for_object = udisks_object_peek_block (object);
+ block_for_object = udisks_object_peek_block (object_iter);
- filesystem_for_object = udisks_object_peek_filesystem (object);
+ filesystem_for_object = udisks_object_peek_filesystem (object_iter);
if (filesystem_for_object != NULL)
{
const gchar *const *mount_points = udisks_filesystem_get_mount_points (filesystem_for_object);
@@ -4808,7 +4927,7 @@ unuse_data_iterate (UnuseData *data)
}
}
- encrypted_for_object = udisks_object_peek_encrypted (object);
+ encrypted_for_object = udisks_object_peek_encrypted (object_iter);
if (encrypted_for_object != NULL)
{
UDisksBlock *cleartext;
@@ -4842,8 +4961,17 @@ unuse_data_iterate (UnuseData *data)
}
else
{
- /* nothing left to do, terminate without error */
- unuse_data_complete (data, NULL, NULL);
+ /* nothing left to do, move on to next object */
+ data->object_iter = data->object_iter->next;
+ if (data->object_iter != NULL)
+ {
+ unuse_data_iterate (data);
+ }
+ else
+ {
+ /* yay, no objects left, terminate without error */
+ unuse_data_complete (data, NULL, NULL);
+ }
}
g_clear_object (&partition_table);
@@ -4857,35 +4985,37 @@ unuse_data_iterate (UnuseData *data)
}
void
-gdu_window_ensure_unused (GduWindow *window,
- UDisksObject *object,
- GAsyncReadyCallback callback,
- GCancellable *cancellable,
- gpointer user_data)
+gdu_window_ensure_unused_list (GduWindow *window,
+ GList *objects,
+ GAsyncReadyCallback callback,
+ GCancellable *cancellable,
+ gpointer user_data)
{
UnuseData *data;
g_return_if_fail (GDU_IS_WINDOW (window));
- g_return_if_fail (UDISKS_IS_OBJECT (object));
+ g_return_if_fail (objects != NULL);
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
data = g_slice_new0 (UnuseData);
data->window = g_object_ref (window);
- data->object = g_object_ref (object);
+ data->objects = g_list_copy (objects);
+ g_list_foreach (data->objects, (GFunc) g_object_ref, NULL);
+ data->object_iter = data->objects;
data->cancellable = cancellable;
data->simple = g_simple_async_result_new (G_OBJECT (window),
callback,
user_data,
- gdu_window_ensure_unused);
+ gdu_window_ensure_unused_list);
g_simple_async_result_set_check_cancellable (data->simple, cancellable);
unuse_data_iterate (data);
}
gboolean
-gdu_window_ensure_unused_finish (GduWindow *window,
- GAsyncResult *res,
- GError **error)
+gdu_window_ensure_unused_list_finish (GduWindow *window,
+ GAsyncResult *res,
+ GError **error)
{
GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
gboolean ret = FALSE;
@@ -4893,7 +5023,7 @@ gdu_window_ensure_unused_finish (GduWindow *window,
g_return_val_if_fail (G_IS_ASYNC_RESULT (res), FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
- g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == gdu_window_ensure_unused);
+ g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == gdu_window_ensure_unused_list);
if (g_simple_async_result_propagate_error (simple, error))
goto out;
@@ -4904,3 +5034,27 @@ gdu_window_ensure_unused_finish (GduWindow *window,
return ret;
}
+/* ---------------------------------------------------------------------------------------------------- */
+
+void
+gdu_window_ensure_unused (GduWindow *window,
+ UDisksObject *object,
+ GAsyncReadyCallback callback,
+ GCancellable *cancellable,
+ gpointer user_data)
+{
+ GList *objects;
+ objects = g_list_append (NULL, object);
+ gdu_window_ensure_unused_list (window, objects, callback, cancellable, user_data);
+ g_list_free (objects);
+}
+
+gboolean
+gdu_window_ensure_unused_finish (GduWindow *window,
+ GAsyncResult *res,
+ GError **error)
+{
+ return gdu_window_ensure_unused_list_finish (window, res, error);
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
diff --git a/src/disks/gduwindow.h b/src/disks/gduwindow.h
index a07ab0f..73e3c18 100644
--- a/src/disks/gduwindow.h
+++ b/src/disks/gduwindow.h
@@ -41,6 +41,16 @@ gboolean gdu_window_ensure_unused_finish (GduWindow *window,
GAsyncResult *res,
GError **error);
+void gdu_window_ensure_unused_list (GduWindow *window,
+ GList *objects,
+ GAsyncReadyCallback callback,
+ GCancellable *cancellable,
+ gpointer user_data);
+
+gboolean gdu_window_ensure_unused_list_finish (GduWindow *window,
+ GAsyncResult *res,
+ GError **error);
+
G_END_DECLS
#endif /* __GDU_WINDOW_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]