diff options
| author | David Zeuthen <davidz@redhat.com> | 2008-06-08 12:50:32 -0400 |
|---|---|---|
| committer | David Zeuthen <davidz@redhat.com> | 2008-06-08 12:50:32 -0400 |
| commit | ca76f4eebd6e9472393a4d3dcd31dcc79f8a04bf (patch) | |
| tree | 016cc900ac9a4d761a2081857f8d35b406dcf281 /src | |
| parent | 6b4870e7ec566dae67ad2767d4ec4d965b007fb7 (diff) | |
move utility functions depending on GTK+ into a separate file
Diffstat (limited to 'src')
| -rw-r--r-- | src/Makefile.am | 1 | ||||
| -rw-r--r-- | src/gdu-section-activatable-drive.c | 2 | ||||
| -rw-r--r-- | src/gdu-section-create-partition-table.c | 2 | ||||
| -rw-r--r-- | src/gdu-section-encrypted.c | 2 | ||||
| -rw-r--r-- | src/gdu-section-partition.c | 2 | ||||
| -rw-r--r-- | src/gdu-section-unallocated.c | 2 | ||||
| -rw-r--r-- | src/gdu-section-unrecognized.c | 2 | ||||
| -rw-r--r-- | src/gdu-shell.c | 2 | ||||
| -rw-r--r-- | src/gdu-tree.c | 2 | ||||
| -rw-r--r-- | src/gdu-ui-util.c | 1762 | ||||
| -rw-r--r-- | src/gdu-ui-util.h | 98 | ||||
| -rw-r--r-- | src/gdu-util.c | 1710 | ||||
| -rw-r--r-- | src/gdu-util.h | 74 |
13 files changed, 1892 insertions, 1769 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index fd264b3..1e05f2a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -21,6 +21,7 @@ bin_PROGRAMS = gnome-disk-utility gnome_disk_utility_SOURCES = \ gdu-main.c \ gdu-util.h gdu-util.c \ + gdu-ui-util.h gdu-ui-util.c \ gdu-time-label.h gdu-time-label.c \ gdu-shell.h gdu-shell.c \ gdu-section.h gdu-section.c \ diff --git a/src/gdu-section-activatable-drive.c b/src/gdu-section-activatable-drive.c index c1a985d..2bfb9a7 100644 --- a/src/gdu-section-activatable-drive.c +++ b/src/gdu-section-activatable-drive.c @@ -28,7 +28,7 @@ #include <polkit-gnome/polkit-gnome.h> #include "gdu-pool.h" -#include "gdu-util.h" +#include "gdu-ui-util.h" #include "gdu-tree.h" #include "gdu-activatable-drive.h" #include "gdu-section-activatable-drive.h" diff --git a/src/gdu-section-create-partition-table.c b/src/gdu-section-create-partition-table.c index 94aac84..b82d028 100644 --- a/src/gdu-section-create-partition-table.c +++ b/src/gdu-section-create-partition-table.c @@ -28,7 +28,7 @@ #include <polkit-gnome/polkit-gnome.h> #include "gdu-pool.h" -#include "gdu-util.h" +#include "gdu-ui-util.h" #include "gdu-section-create-partition-table.h" struct _GduSectionCreatePartitionTablePrivate diff --git a/src/gdu-section-encrypted.c b/src/gdu-section-encrypted.c index cc8dc7a..e3629a3 100644 --- a/src/gdu-section-encrypted.c +++ b/src/gdu-section-encrypted.c @@ -27,7 +27,7 @@ #include <math.h> #include "gdu-pool.h" -#include "gdu-util.h" +#include "gdu-ui-util.h" #include "gdu-section-encrypted.h" struct _GduSectionEncryptedPrivate diff --git a/src/gdu-section-partition.c b/src/gdu-section-partition.c index ea4d266..1ddb521 100644 --- a/src/gdu-section-partition.c +++ b/src/gdu-section-partition.c @@ -28,7 +28,7 @@ #include <polkit-gnome/polkit-gnome.h> #include "gdu-pool.h" -#include "gdu-util.h" +#include "gdu-ui-util.h" #include "gdu-section-partition.h" struct _GduSectionPartitionPrivate diff --git a/src/gdu-section-unallocated.c b/src/gdu-section-unallocated.c index 4dff984..fb321d5 100644 --- a/src/gdu-section-unallocated.c +++ b/src/gdu-section-unallocated.c @@ -28,7 +28,7 @@ #include <polkit-gnome/polkit-gnome.h> #include "gdu-pool.h" -#include "gdu-util.h" +#include "gdu-ui-util.h" #include "gdu-section-unallocated.h" struct _GduSectionUnallocatedPrivate diff --git a/src/gdu-section-unrecognized.c b/src/gdu-section-unrecognized.c index d6db28b..502d3f1 100644 --- a/src/gdu-section-unrecognized.c +++ b/src/gdu-section-unrecognized.c @@ -28,7 +28,7 @@ #include <polkit-gnome/polkit-gnome.h> #include "gdu-pool.h" -#include "gdu-util.h" +#include "gdu-ui-util.h" #include "gdu-section-unrecognized.h" struct _GduSectionUnrecognizedPrivate diff --git a/src/gdu-shell.c b/src/gdu-shell.c index 7238f91..a6cb5a4 100644 --- a/src/gdu-shell.c +++ b/src/gdu-shell.c @@ -32,7 +32,7 @@ #include <libsexy/sexy.h> #include "gdu-shell.h" -#include "gdu-util.h" +#include "gdu-ui-util.h" #include "gdu-pool.h" #include "gdu-tree.h" #include "gdu-drive.h" diff --git a/src/gdu-tree.c b/src/gdu-tree.c index 66afc55..c2cb5e9 100644 --- a/src/gdu-tree.c +++ b/src/gdu-tree.c @@ -23,7 +23,7 @@ #include <glib/gi18n.h> #include <string.h> -#include "gdu-util.h" +#include "gdu-ui-util.h" #include "gdu-tree.h" diff --git a/src/gdu-ui-util.c b/src/gdu-ui-util.c new file mode 100644 index 0000000..ec17ae7 --- /dev/null +++ b/src/gdu-ui-util.c @@ -0,0 +1,1762 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ +/* gdu-ui-util.c + * + * Copyright (C) 2007 David Zeuthen + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +#include <config.h> +#include <glib-object.h> +#include <string.h> +#include <glib/gi18n.h> +#include <polkit-gnome/polkit-gnome.h> +#include <gnome-keyring.h> +#include <dbus/dbus-glib.h> + +#include "gdu-util.h" +#include "gdu-ui-util.h" + +/* ---------------------------------------------------------------------------------------------------- */ + +static int +_get_icon_size_for_stock_size (GtkIconSize size) +{ + int w, h; + if (gtk_icon_size_lookup (size, &w, &h)) { + return MAX (w, h); + } else { + return 24; + } +} + +static GdkPixbuf * +get_pixbuf_for_icon (GIcon *icon) +{ + GdkPixbuf *pixbuf; + + pixbuf = NULL; + + if (G_IS_FILE_ICON (icon)) { + char *filename; + filename = g_file_get_path (g_file_icon_get_file (G_FILE_ICON (icon))); + if (filename != NULL) { + pixbuf = gdk_pixbuf_new_from_file_at_size (filename, 24, 24, NULL); + g_free (filename); + } + + } else if (G_IS_THEMED_ICON (icon)) { + const char * const *names; + char *icon_no_extension; + char *p; + + names = g_themed_icon_get_names (G_THEMED_ICON (icon)); + + if (names != NULL && names[0] != NULL) { + icon_no_extension = g_strdup (names[0]); + p = strrchr (icon_no_extension, '.'); + if (p != NULL) + *p = '\0'; + pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), + icon_no_extension, 24, 0, NULL); + g_free (icon_no_extension); + } + } + + return pixbuf; +} + +typedef struct { + GduDevice *device; + + GtkWidget *tree_view; + GtkWidget *dialog; +} ShowBusyData; + +static ShowBusyData * +show_busy_data_new (GduDevice *device) +{ + ShowBusyData *data; + data = g_new0 (ShowBusyData, 1); + data->device = g_object_ref (device); + return data; +} + +static void +show_busy_data_free (ShowBusyData *data) +{ + g_object_unref (data->device); + g_free (data); +} + +static int +process_compare (GduProcess *a, GduProcess *b) +{ + return gdu_process_get_id (a) - gdu_process_get_id (b); +} + +static GtkListStore * +show_busy_get_list_store (ShowBusyData *data, int *num_rows) +{ + GtkListStore *store; + GtkTreeIter iter; + GList *processes; + GError *error; + GList *l; + + if (num_rows != NULL) + *num_rows = 0; + + store = gtk_list_store_new (3, GDK_TYPE_PIXBUF, G_TYPE_STRING, GDU_TYPE_PROCESS); + error = NULL; + processes = gdu_device_filesystem_list_open_files_sync (data->device, &error); + if (error != NULL) { + g_warning ("error retrieving list of open files: %s", error->message); + g_error_free (error); + } + processes = g_list_sort (processes, (GCompareFunc) process_compare); + for (l = processes; l != NULL; l = l->next) { + GduProcess *process = GDU_PROCESS (l->data); + char *name; + char *markup; + GAppInfo *app_info; + GdkPixbuf *pixbuf; + + name = NULL; + + app_info = gdu_process_get_app_info (process); + pixbuf = NULL; + if (app_info != NULL) { + GIcon *icon; + + name = g_strdup (g_app_info_get_name (app_info)); + icon = g_app_info_get_icon (app_info); + if (icon != NULL) { + pixbuf = get_pixbuf_for_icon (icon); + } + } else { + const char *command_line; + + command_line = gdu_process_get_command_line (process); + + if (command_line != NULL) { + char *basename; + char *s; + int n; + + for (n = 0; command_line[n] != '\0'; n++) { + if (command_line[n] == ' ') + break; + } + s = g_strndup (command_line, n); + basename = g_path_get_basename (s); + g_free (s); + + /* special handling for common programs without desktop files */ + if (strcmp (basename, "bash") == 0 || + strcmp (basename, "-bash") == 0) { + name = g_strdup (_("Bourne Again Shell")); + pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), + "terminal", 24, 0, NULL); + } else if (strcmp (basename, "sh") == 0 || + strcmp (basename, "-sh") == 0) { + name = g_strdup (_("Bourne Shell")); + pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), + "terminal", 24, 0, NULL); + } else if (strcmp (basename, "csh") == 0 || + strcmp (basename, "-csh") == 0) { + name = g_strdup (_("C Shell")); + pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), + "terminal", 24, 0, NULL); + } else if (strcmp (basename, "tcsh") == 0 || + strcmp (basename, "-tcsh") == 0) { + name = g_strdup (_("TENEX C Shell")); + pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), + "terminal", 24, 0, NULL); + } else if (strcmp (basename, "zsh") == 0 || + strcmp (basename, "-zsh") == 0) { + name = g_strdup (_("Z Shell")); + pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), + "terminal", 24, 0, NULL); + } else if (strcmp (basename, "ksh") == 0 || + strcmp (basename, "-ksh") == 0) { + name = g_strdup (_("Korn Shell")); + pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), + "terminal", 24, 0, NULL); + } else if (strcmp (basename, "top") == 0) { + name = g_strdup (_("Process Viewer (top)")); + pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), + GTK_STOCK_GOTO_TOP, 24, 0, NULL); + } else if (strcmp (basename, "less") == 0) { + name = g_strdup (_("Terminal Pager (less)")); + pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), + GTK_STOCK_FILE, 24, 0, NULL); + } + + if (name != NULL) { + } else { + name = g_strdup (basename); + } + + g_free (basename); + } else { + name = g_strdup (_("Unknown")); + } + } + + /* fall back to generic icon */ + if (pixbuf == NULL) { + pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), + "application-x-executable", 24, 0, NULL); + } + + if (gdu_process_get_owner (process) != getuid ()) { + markup = g_strdup_printf (_("<b>%s</b>\n" + "<small>uid %d, pid %d: %s</small>"), + name, + gdu_process_get_owner (process), + gdu_process_get_id (process), + gdu_process_get_command_line (process)); + } else { + markup = g_strdup_printf (_("<b>%s</b>\n" + "<small>pid %d: %s</small>"), + name, + gdu_process_get_id (process), + gdu_process_get_command_line (process)); + } + + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, + 0, pixbuf, + 1, markup, + 2, process, + -1); + + if (num_rows != NULL) + *num_rows = (*num_rows) + 1; + + g_free (markup); + g_free (name); + if (app_info != NULL) + g_object_unref (app_info); + if (pixbuf != NULL) + g_object_unref (pixbuf); + } + g_list_foreach (processes, (GFunc) g_object_unref, NULL); + g_list_free (processes); + + return store; +} + +static gboolean +show_busy_timeout (gpointer user_data) +{ + ShowBusyData *data = user_data; + GtkListStore *store; + int num_rows; + + store = show_busy_get_list_store (data, &num_rows); + gtk_tree_view_set_model (GTK_TREE_VIEW (data->tree_view), GTK_TREE_MODEL (store)); + gtk_dialog_set_response_sensitive (GTK_DIALOG (data->dialog), 1, num_rows == 0); + g_object_unref (store); + + return TRUE; +} + +gboolean +gdu_util_dialog_show_filesystem_busy (GtkWidget *parent_window, + GduPresentable *presentable) +{ + gboolean ret; + GduDevice *device; + char *window_title; + char *window_icon_name; + GtkWidget *dialog; + GtkWidget *hbox; + GtkWidget *main_vbox; + GtkWidget *label; + GtkWidget *image; + int response; + GtkListStore *store; + GtkWidget *tree_view; + GtkCellRenderer *renderer; + GtkTreeViewColumn *column; + GtkWidget *scrolled_window; + GtkWidget *unmount_button; + GtkWidget *unmount_image; + GdkPixbuf *pixbuf; + ShowBusyData *data; + guint refresh_timer_id; + + ret = FALSE; + window_title = NULL; + window_icon_name = NULL; + device = NULL; + dialog = NULL; + data = NULL; + refresh_timer_id = 0; + + device = gdu_presentable_get_device (presentable); + if (device == NULL) { + g_warning ("%s: presentable has no device", __FUNCTION__); + goto out; + } + + data = show_busy_data_new (device); + + if (gdu_device_is_partition (device)) { + char *s; + GduPresentable *enclosing_drive; + enclosing_drive = gdu_presentable_get_enclosing_presentable (presentable); + s = gdu_presentable_get_name (enclosing_drive); + /* todo: icon list */ + window_icon_name = gdu_presentable_get_icon_name (enclosing_drive); + g_object_unref (enclosing_drive); + window_title = g_strdup_printf (_("Partition %d on %s"), + gdu_device_partition_get_number (device), + s); + g_free (s); + } else { + window_title = gdu_presentable_get_name (presentable); + window_icon_name = gdu_presentable_get_icon_name (presentable); + } + + dialog = gtk_dialog_new_with_buttons (window_title, + GTK_WINDOW (parent_window), + GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT|GTK_DIALOG_NO_SEPARATOR, + NULL); + + gtk_container_set_border_width (GTK_CONTAINER (dialog), 5); + gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 2); + gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area), 5); + gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->action_area), 6); + gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE); + gtk_window_set_icon_name (GTK_WINDOW (dialog), window_icon_name); + + hbox = gtk_hbox_new (FALSE, 12); + gtk_container_set_border_width (GTK_CONTAINER (hbox), 5); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), hbox, TRUE, TRUE, 0); + + image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_ERROR, GTK_ICON_SIZE_DIALOG); + gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.0); + gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0); + + main_vbox = gtk_vbox_new (FALSE, 10); + gtk_box_pack_start (GTK_BOX (hbox), main_vbox, TRUE, TRUE, 0); + + /* main message */ + label = gtk_label_new (NULL); + gtk_label_set_markup (GTK_LABEL (label), + _("<b><big>Cannot unmount volume</big></b>")); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); + gtk_box_pack_start (GTK_BOX (main_vbox), GTK_WIDGET (label), FALSE, FALSE, 0); + + /* secondary message */ + label = gtk_label_new (NULL); + gtk_label_set_markup (GTK_LABEL (label), _("One or more applications are using the volume. " + "Quit the applications, and then try unmounting again.")); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); + gtk_box_pack_start (GTK_BOX (main_vbox), GTK_WIDGET (label), FALSE, FALSE, 0); + + + store = show_busy_get_list_store (data, NULL); + tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store)); + gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)), + GTK_SELECTION_NONE); + data->dialog = dialog; + data->tree_view = tree_view; + g_object_unref (store); + + column = gtk_tree_view_column_new (); + renderer = gtk_cell_renderer_pixbuf_new (); + gtk_tree_view_column_pack_start (column, renderer, FALSE); + gtk_tree_view_column_set_attributes (column, renderer, + "pixbuf", 0, + NULL); + renderer = gtk_cell_renderer_text_new (); + gtk_tree_view_column_pack_start (column, renderer, TRUE); + gtk_tree_view_column_set_attributes (column, renderer, + "markup", 1, + NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column); + gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (tree_view), FALSE); + + scrolled_window = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window), GTK_SHADOW_IN); + + gtk_container_add (GTK_CONTAINER (scrolled_window), tree_view); + gtk_box_pack_start (GTK_BOX (main_vbox), scrolled_window, TRUE, TRUE, 0); + + GtkWidget *cancel_button; + cancel_button = gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); + gtk_widget_grab_focus (cancel_button); + + unmount_button = gtk_button_new_with_mnemonic (_("_Unmount")); + pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), + "gdu-unmount", + _get_icon_size_for_stock_size (GTK_ICON_SIZE_BUTTON), + 0, + NULL); + unmount_image = gtk_image_new_from_pixbuf (pixbuf); + g_object_unref (pixbuf); + gtk_button_set_image (GTK_BUTTON (unmount_button), unmount_image); + gtk_dialog_add_action_widget (GTK_DIALOG (dialog), + unmount_button, + 1); + + /* refresh list of open files every one second... */ + refresh_timer_id = g_timeout_add_seconds (1, show_busy_timeout, data); + + gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), 1, FALSE); + + gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE); + gtk_window_set_default_size (GTK_WINDOW (dialog), -1, 280); + gtk_widget_show_all (dialog); + response = gtk_dialog_run (GTK_DIALOG (dialog)); + if (response == 1) + ret = TRUE; + +out: + if (refresh_timer_id > 0) + g_source_remove (refresh_timer_id); + + g_free (window_title); + g_free (window_icon_name); + if (device != NULL) + g_object_unref (device); + if (dialog != NULL) + gtk_widget_destroy (dialog); + if (data != NULL) + show_busy_data_free (data); + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +typedef struct +{ + gboolean is_new_password; + GtkWidget *password_entry; + GtkWidget *password_entry_new; + GtkWidget *password_entry_verify; + GtkWidget *warning_hbox; + GtkWidget *warning_label; + GtkWidget *button; +} DialogSecretData; + +static void +gdu_util_dialog_secret_update (DialogSecretData *data) +{ + if (strcmp (gtk_entry_get_text (GTK_ENTRY (data->password_entry_new)), + gtk_entry_get_text (GTK_ENTRY (data->password_entry_verify))) != 0) { + gtk_widget_show (data->warning_hbox); + gtk_label_set_markup (GTK_LABEL (data->warning_label), "<i>Passphrases do not match</i>"); + gtk_widget_set_sensitive (data->button, FALSE); + } else if (!data->is_new_password && + (strlen (gtk_entry_get_text (GTK_ENTRY (data->password_entry))) > 0 || + strlen (gtk_entry_get_text (GTK_ENTRY (data->password_entry_new))) > 0) && + strcmp (gtk_entry_get_text (GTK_ENTRY (data->password_entry)), + gtk_entry_get_text (GTK_ENTRY (data->password_entry_new))) == 0) { + gtk_widget_show (data->warning_hbox); + gtk_label_set_markup (GTK_LABEL (data->warning_label), "<i>Passphrases do not differ</i>"); + gtk_widget_set_sensitive (data->button, FALSE); + } else { + gtk_widget_hide (data->warning_hbox); + gtk_widget_set_sensitive (data->button, TRUE); + } +} + +static void +gdu_util_dialog_secret_entry_changed (GtkWidget *entry, gpointer user_data) +{ + DialogSecretData *data = user_data; + gdu_util_dialog_secret_update (data); +} + +static void +secret_dialog_device_removed (GduDevice *device, gpointer user_data) +{ + GtkDialog *dialog = GTK_DIALOG (user_data); + gtk_dialog_response (dialog, GTK_RESPONSE_NONE); +} + +static char * +gdu_util_dialog_secret_internal (GtkWidget *parent_window, + const char *window_title, + const char *window_icon_name, + gboolean is_new_password, + gboolean is_change_password, + const char *old_secret_for_change_password, + char **old_secret_from_dialog, + gboolean *save_in_keyring, + gboolean *save_in_keyring_session, + gboolean indicate_wrong_passphrase, + GduDevice *device) +{ + int row; + int response; + char *secret; + GtkWidget *dialog; + GtkWidget *image; + GtkWidget *hbox; + GtkWidget *main_vbox; + GtkWidget *vbox; + GtkWidget *label; + GtkWidget *table_alignment; + GtkWidget *table; + GtkWidget *never_radio_button; + GtkWidget *session_radio_button; + GtkWidget *always_radio_button; + DialogSecretData *data; + + g_return_val_if_fail (parent_window == NULL || GTK_IS_WINDOW (parent_window), NULL); + + session_radio_button = NULL; + always_radio_button = NULL; + + secret = NULL; + data = g_new0 (DialogSecretData, 1); + data->is_new_password = is_new_password; + + dialog = gtk_dialog_new_with_buttons (window_title, + GTK_WINDOW (parent_window), + GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT|GTK_DIALOG_NO_SEPARATOR, + GTK_STOCK_CANCEL, + GTK_RESPONSE_CANCEL, + NULL); + + if (is_new_password) { + data->button = gtk_dialog_add_button (GTK_DIALOG (dialog), _("Cr_eate"), 0); + } else if (is_change_password) { + data->button = gtk_dialog_add_button (GTK_DIALOG (dialog), _("Change _Passphrase"), 0); + } else { + data->button = gtk_dialog_add_button (GTK_DIALOG (dialog), _("_Unlock"), 0); + } + gtk_dialog_set_default_response (GTK_DIALOG (dialog), 0); + + gtk_container_set_border_width (GTK_CONTAINER (dialog), 5); + gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 2); + gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area), 5); + gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->action_area), 6); + gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE); + if (window_icon_name != NULL) + gtk_window_set_icon_name (GTK_WINDOW (dialog), window_icon_name); + else + gtk_window_set_icon_name (GTK_WINDOW (dialog), GTK_STOCK_DIALOG_AUTHENTICATION); + + hbox = gtk_hbox_new (FALSE, 12); + gtk_container_set_border_width (GTK_CONTAINER (hbox), 5); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), hbox, TRUE, TRUE, 0); + + image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_AUTHENTICATION, GTK_ICON_SIZE_DIALOG); + gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.0); + gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0); + + main_vbox = gtk_vbox_new (FALSE, 10); + gtk_box_pack_start (GTK_BOX (hbox), main_vbox, TRUE, TRUE, 0); + + /* main message */ + label = gtk_label_new (NULL); + if (is_new_password) { + gtk_label_set_markup (GTK_LABEL (label), + _("<b><big>To create an encrypted device, choose a passphrase " + "to protect it</big></b>")); + } else if (is_change_password) { + gtk_label_set_markup (GTK_LABEL (label), + _("<b><big>To change the passphrase, enter both the current and " + "new passphrase</big></b>")); + } else { + gtk_label_set_markup (GTK_LABEL (label), + _("<b><big>Data on this device is stored in an encrypted form " + "protected by a passphrase</big></b>")); + } + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); + gtk_box_pack_start (GTK_BOX (main_vbox), GTK_WIDGET (label), FALSE, FALSE, 0); + + /* secondary message */ + label = gtk_label_new (NULL); + if (is_new_password) { + gtk_label_set_markup (GTK_LABEL (label), _("Data on this device will be stored in an encrypted form " + "protected by a passphrase.")); + } else if (is_change_password) { + gtk_label_set_markup (GTK_LABEL (label), _("Data on this device is stored in an encrypted form " + "protected by a passphrase.")); + } else { + gtk_label_set_markup (GTK_LABEL (label), _("To make the data available for use, enter the " + "passphrase for the device.")); + } + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); + gtk_box_pack_start (GTK_BOX (main_vbox), GTK_WIDGET (label), FALSE, FALSE, 0); + + if (indicate_wrong_passphrase) { + label = gtk_label_new (NULL); + gtk_label_set_markup (GTK_LABEL (label), _("<b>Incorrect Passphrase. Try again.</b>")); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); + gtk_box_pack_start (GTK_BOX (main_vbox), GTK_WIDGET (label), FALSE, FALSE, 0); + } + + /* password entry */ + vbox = gtk_vbox_new (FALSE, 6); + gtk_box_pack_start (GTK_BOX (main_vbox), vbox, FALSE, FALSE, 0); + + table_alignment = gtk_alignment_new (0.0, 0.0, 1.0, 1.0); + gtk_box_pack_start (GTK_BOX (vbox), table_alignment, FALSE, FALSE, 0); + table = gtk_table_new (1, 2, FALSE); + gtk_table_set_col_spacings (GTK_TABLE (table), 12); + gtk_table_set_row_spacings (GTK_TABLE (table), 6); + gtk_container_add (GTK_CONTAINER (table_alignment), table); + + row = 0; + + if (is_change_password || is_new_password) { + + if (is_change_password) { + label = gtk_label_new_with_mnemonic (_("C_urrent Passphrase:")); + gtk_label_set_use_markup (GTK_LABEL (label), TRUE); + gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5); + gtk_table_attach (GTK_TABLE (table), label, + 0, 1, row, row + 1, + GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + data->password_entry = gtk_entry_new (); + gtk_entry_set_visibility (GTK_ENTRY (data->password_entry), FALSE); + gtk_table_attach_defaults (GTK_TABLE (table), data->password_entry, 1, 2, row, row + 1); + gtk_label_set_mnemonic_widget (GTK_LABEL (label), data->password_entry); + + row++; + } + + label = gtk_label_new_with_mnemonic (_("_New Passphrase:")); + gtk_label_set_use_markup (GTK_LABEL (label), TRUE); + gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5); + gtk_table_attach (GTK_TABLE (table), label, + 0, 1, row, row + 1, + GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + data->password_entry_new = gtk_entry_new (); + gtk_entry_set_visibility (GTK_ENTRY (data->password_entry_new), FALSE); + gtk_table_attach_defaults (GTK_TABLE (table), data->password_entry_new, 1, 2, row, row + 1); + gtk_label_set_mnemonic_widget (GTK_LABEL (label), data->password_entry_new); + + row++; + + label = gtk_label_new_with_mnemonic (_("_Verify Passphrase:")); + gtk_label_set_use_markup (GTK_LABEL (label), TRUE); + gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5); + gtk_table_attach (GTK_TABLE (table), label, + 0, 1, row, row + 1, + GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + data->password_entry_verify = gtk_entry_new (); + gtk_entry_set_visibility (GTK_ENTRY (data->password_entry_verify), FALSE); + gtk_table_attach_defaults (GTK_TABLE (table), data->password_entry_verify, 1, 2, row, row + 1); + gtk_label_set_mnemonic_widget (GTK_LABEL (label), data->password_entry_verify); + + data->warning_hbox = gtk_hbox_new (FALSE, 12); + image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_MENU); + data->warning_label = gtk_label_new (NULL); + gtk_box_pack_start (GTK_BOX (data->warning_hbox), image, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (data->warning_hbox), data->warning_label, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (vbox), data->warning_hbox, FALSE, FALSE, 0); + + g_signal_connect (data->password_entry_new, "changed", + (GCallback) gdu_util_dialog_secret_entry_changed, data); + g_signal_connect (data->password_entry_verify, "changed", + (GCallback) gdu_util_dialog_secret_entry_changed, data); + + /* only the verify entry activates the default action */ + gtk_entry_set_activates_default (GTK_ENTRY (data->password_entry_verify), TRUE); + + /* if the old password is supplied (from e.g. the keyring), set it and focus on the new password */ + if (old_secret_for_change_password != NULL) { + gtk_entry_set_text (GTK_ENTRY (data->password_entry), old_secret_for_change_password); + gtk_widget_grab_focus (data->password_entry_new); + } else if (is_new_password) { + gtk_widget_grab_focus (data->password_entry_new); + } + + } else { + label = gtk_label_new_with_mnemonic (_("_Passphrase:")); + gtk_label_set_use_markup (GTK_LABEL (label), TRUE); + gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5); + gtk_table_attach (GTK_TABLE (table), label, + 0, 1, row, row + 1, + GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + data->password_entry = gtk_entry_new (); + gtk_entry_set_visibility (GTK_ENTRY (data->password_entry), FALSE); + gtk_entry_set_activates_default (GTK_ENTRY (data->password_entry), TRUE); + gtk_table_attach_defaults (GTK_TABLE (table), data->password_entry, 1, 2, row, row + 1); + gtk_label_set_mnemonic_widget (GTK_LABEL (label), data->password_entry); + } + + never_radio_button = gtk_radio_button_new_with_mnemonic ( + NULL, + _("_Forget passphrase immediately")); + session_radio_button = gtk_radio_button_new_with_mnemonic_from_widget ( + GTK_RADIO_BUTTON (never_radio_button), + _("Remember passphrase until you _log out")); + always_radio_button = gtk_radio_button_new_with_mnemonic_from_widget ( + GTK_RADIO_BUTTON (never_radio_button), + _("_Remember forever")); + + /* preselect Remember Forever if we've retrieved the existing key from the keyring */ + if (is_change_password && old_secret_for_change_password != NULL) { + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (always_radio_button), TRUE); + } + + gtk_box_pack_start (GTK_BOX (vbox), never_radio_button, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (vbox), session_radio_button, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (vbox), always_radio_button, FALSE, FALSE, 0); + + gtk_widget_show_all (dialog); + if (is_change_password || is_new_password) + gdu_util_dialog_secret_update (data); + + if (device != NULL) + g_signal_connect (device, "removed", (GCallback) secret_dialog_device_removed, dialog); + + response = gtk_dialog_run (GTK_DIALOG (dialog)); + + if (device != NULL) + g_signal_handlers_disconnect_by_func (device, secret_dialog_device_removed, dialog); + + if (response != 0) + goto out; + + if (is_new_password) { + secret = g_strdup (gtk_entry_get_text (GTK_ENTRY (data->password_entry_new))); + } else if (is_change_password) { + *old_secret_from_dialog = g_strdup (gtk_entry_get_text (GTK_ENTRY (data->password_entry))); + secret = g_strdup (gtk_entry_get_text (GTK_ENTRY (data->password_entry_new))); + } else { + secret = g_strdup (gtk_entry_get_text (GTK_ENTRY (data->password_entry))); + } + + if (save_in_keyring != NULL) + *save_in_keyring = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (always_radio_button)); + if (save_in_keyring_session != NULL) + *save_in_keyring_session = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (session_radio_button)); + +out: + if (data == NULL) + g_free (data); + if (dialog != NULL) + gtk_widget_destroy (dialog); + return secret; +} + +static GnomeKeyringPasswordSchema encrypted_device_password_schema = { + GNOME_KEYRING_ITEM_GENERIC_SECRET, + { + { "luks-device-uuid", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, + { NULL, 0 } + } +}; + +char * +gdu_util_dialog_ask_for_new_secret (GtkWidget *parent_window, + gboolean *save_in_keyring, + gboolean *save_in_keyring_session) +{ + return gdu_util_dialog_secret_internal (parent_window, + _("Enter Passphrase"), + NULL, + TRUE, + FALSE, + NULL, + NULL, + save_in_keyring, + save_in_keyring_session, + FALSE, + NULL); +} + +/** + * gdu_util_dialog_ask_for_secret: + * @parent_window: Parent window that dialog will be transient for or #NULL. + * @presentable: A #GduPresentable with a #GduDevice that is encrypted. + * @bypass_keyring: Set to #TRUE to bypass the keyring. + * @indicate_wrong_passphrase: Set to #TRUE to display a message that the last + * entered passphrase was wrong + * @asked_user: Whether the user was asked for the passphrase + * + * Retrieves a secret from the user or the keyring (unless + * @bypass_keyring is set to #TRUE). + * + * Returns: the secret or #NULL if the user cancelled the dialog. + **/ +char * +gdu_util_dialog_ask_for_secret (GtkWidget *parent_window, + GduPresentable *presentable, + gboolean bypass_keyring, + gboolean indicate_wrong_passphrase, + gboolean *asked_user) +{ + char *secret; + char *password; + const char *usage; + const char *uuid; + gboolean save_in_keyring; + gboolean save_in_keyring_session; + GduDevice *device; + char *window_title; + char *window_icon_name; + + window_title = NULL; + window_icon_name = NULL; + device = NULL; + secret = NULL; + save_in_keyring = FALSE; + save_in_keyring_session = FALSE; + if (asked_user != NULL) + *asked_user = FALSE; + + device = gdu_presentable_get_device (presentable); + if (device == NULL) { + g_warning ("%s: presentable has no device", __FUNCTION__); + goto out; + } + + usage = gdu_device_id_get_usage (device); + uuid = gdu_device_id_get_uuid (device); + + if (strcmp (usage, "crypto") != 0) { + g_warning ("%s: device is not a crypto device", __FUNCTION__); + goto out; + } + + if (uuid == NULL || strlen (uuid) == 0) { + g_warning ("%s: device has no UUID", __FUNCTION__); + goto out; + } + + if (!bypass_keyring) { + if (gnome_keyring_find_password_sync (&encrypted_device_password_schema, + &password, + "luks-device-uuid", uuid, + NULL) == GNOME_KEYRING_RESULT_OK) { + /* By contract, the caller is responsible for scrubbing the password + * so dupping the string into pageable memory is "fine". Or not? + */ + secret = g_strdup (password); + gnome_keyring_free_password (password); + goto out; + } + } + + if (gdu_device_is_partition (device)) { + char *s; + GduPresentable *enclosing_drive; + enclosing_drive = gdu_presentable_get_enclosing_presentable (presentable); + s = gdu_presentable_get_name (enclosing_drive); + /* todo: icon list */ + window_icon_name = gdu_presentable_get_icon_name (enclosing_drive); + g_object_unref (enclosing_drive); + window_title = g_strdup_printf (_("Partition %d on %s"), + gdu_device_partition_get_number (device), + s); + g_free (s); + } else { + window_title = gdu_presentable_get_name (presentable); + window_icon_name = gdu_presentable_get_icon_name (presentable); + } + + secret = gdu_util_dialog_secret_internal (parent_window, + window_title, + window_icon_name, + FALSE, + FALSE, + NULL, + NULL, + &save_in_keyring, + &save_in_keyring_session, + indicate_wrong_passphrase, + device); + + if (asked_user != NULL) + *asked_user = TRUE; + + if (secret != NULL && (save_in_keyring || save_in_keyring_session)) { + const char *keyring; + + keyring = NULL; + if (save_in_keyring_session) + keyring = GNOME_KEYRING_SESSION; + + if (gnome_keyring_store_password_sync (&encrypted_device_password_schema, + keyring, + _("Encrypted Disk Passphrase"), + secret, + "luks-device-uuid", uuid, + NULL) != GNOME_KEYRING_RESULT_OK) { + g_warning ("%s: couldn't store passphrase in keyring", __FUNCTION__); + } + } + +out: + if (device != NULL) + g_object_unref (device); + g_free (window_title); + g_free (window_icon_name); + return secret; +} + +/** + * gdu_util_dialog_change_secret: + * @parent_window: Parent window that dialog will be transient for or #NULL. + * @presentable: A #GduPresentable with a #GduDevice that is encrypted. + * @old_secret: Return location for old secret. + * @new_secret: Return location for new secret. + * @save_in_keyring: Return location for whether the new secret should be saved in the keyring. + * @save_in_keyring_session: Return location for whether the new secret should be saved in the session keyring. + * @bypass_keyring: Set to #TRUE to bypass the keyring. + * + * Asks the user to change his secret. The secret in the keyring is + * not updated; that needs to be done manually using the functions + * gdu_util_delete_secret() and gdu_util_save_secret(). + * + * Returns: #TRUE if the user agreed to change the secret. + **/ +gboolean +gdu_util_dialog_change_secret (GtkWidget *parent_window, + GduPresentable *presentable, + char **old_secret, + char **new_secret, + gboolean *save_in_keyring, + gboolean *save_in_keyring_session, + gboolean bypass_keyring, + gboolean indicate_wrong_passphrase) +{ + char *password; + const char *usage; + const char *uuid; + gboolean ret; + char *old_secret_from_keyring; + char *window_title; + char *window_icon_name; + GduDevice *device; + + window_title = NULL; + window_icon_name = NULL; + device = NULL; + *old_secret = NULL; + *new_secret = NULL; + old_secret_from_keyring = NULL; + ret = FALSE; + + device = gdu_presentable_get_device (presentable); + if (device == NULL) { + g_warning ("%s: presentable has no device", __FUNCTION__); + goto out; + } + + usage = gdu_device_id_get_usage (device); + uuid = gdu_device_id_get_uuid (device); + + if (strcmp (usage, "crypto") != 0) { + g_warning ("%s: device is not a crypto device", __FUNCTION__); + goto out; + } + + if (uuid == NULL || strlen (uuid) == 0) { + g_warning ("%s: device has no UUID", __FUNCTION__); + goto out; + } + + if (!bypass_keyring) { + if (gnome_keyring_find_password_sync (&encrypted_device_password_schema, + &password, + "luks-device-uuid", uuid, + NULL) == GNOME_KEYRING_RESULT_OK) { + /* By contract, the caller is responsible for scrubbing the password + * so dupping the string into pageable memory "fine". Or not? + */ + old_secret_from_keyring = g_strdup (password); + gnome_keyring_free_password (password); + } + } + + if (gdu_device_is_partition (device)) { + char *s; + GduPresentable *enclosing_drive; + enclosing_drive = gdu_presentable_get_enclosing_presentable (presentable); + s = gdu_presentable_get_name (enclosing_drive); + /* todo: icon list */ + window_icon_name = gdu_presentable_get_icon_name (enclosing_drive); + g_object_unref (enclosing_drive); + window_title = g_strdup_printf (_("Partition %d on %s"), + gdu_device_partition_get_number (device), + s); + g_free (s); + } else { + window_title = gdu_presentable_get_name (presentable); + window_icon_name = gdu_presentable_get_icon_name (presentable); + } + + *new_secret = gdu_util_dialog_secret_internal (parent_window, + window_title, + window_icon_name, + FALSE, + TRUE, + old_secret_from_keyring, + old_secret, + save_in_keyring, + save_in_keyring_session, + indicate_wrong_passphrase, + device); + + if (old_secret_from_keyring != NULL) { + memset (old_secret_from_keyring, '\0', strlen (old_secret_from_keyring)); + g_free (old_secret_from_keyring); + } + + if (*new_secret == NULL) + goto out; + + ret = TRUE; + +out: + if (!ret) { + if (*old_secret != NULL) { + memset (*old_secret, '\0', strlen (*old_secret)); + g_free (*old_secret); + *old_secret = NULL; + } + if (*new_secret != NULL) { + memset (*new_secret, '\0', strlen (*new_secret)); + g_free (*new_secret); + *new_secret = NULL; + } + } + + g_free (window_title); + g_free (window_icon_name); + if (device != NULL) + g_object_unref (device); + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * gdu_util_delete_confirmation_dialog: + * @parent_window: parent window for transient dialog + * @title: the title of the dialog + * @primary_text: primary text + * @secondary_text: secondary text + * @affirmative_action_button_mnemonic: text to use on the affirmative action button + * + * Utility to show a confirmation dialog for deletion that includes a + * combo box for secure erase options. + * + * Returns: #NULL if the user canceled, otherwise the secure erase + * type. Must be freed by the caller. + **/ +char * +gdu_util_delete_confirmation_dialog (GtkWidget *parent_window, + const char *title, + const char *primary_text, + const char *secondary_text, + const char *affirmative_action_button_mnemonic) +{ + int response; + GtkWidget *dialog; + char *secure_erase; + GtkWidget *hbox; + GtkWidget *image; + GtkWidget *main_vbox; + GtkWidget *label; + int row; + GtkWidget *combo_box; + GtkWidget *table; + + secure_erase = NULL; + + dialog = gtk_dialog_new_with_buttons (title, + GTK_WINDOW (parent_window), + GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT|GTK_DIALOG_NO_SEPARATOR, + NULL); + + gtk_container_set_border_width (GTK_CONTAINER (dialog), 5); + gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 2); + gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area), 5); + gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->action_area), 6); + gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE); + + hbox = gtk_hbox_new (FALSE, 12); + gtk_container_set_border_width (GTK_CONTAINER (hbox), 5); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), hbox, TRUE, TRUE, 0); + + image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_DIALOG); + gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.0); + gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0); + + main_vbox = gtk_vbox_new (FALSE, 10); + gtk_box_pack_start (GTK_BOX (hbox), main_vbox, TRUE, TRUE, 0); + + label = gtk_label_new (NULL); + gtk_label_set_markup (GTK_LABEL (label), primary_text); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); + gtk_box_pack_start (GTK_BOX (main_vbox), GTK_WIDGET (label), FALSE, FALSE, 0); + + label = gtk_label_new (NULL); + gtk_label_set_markup (GTK_LABEL (label), secondary_text); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); + gtk_box_pack_start (GTK_BOX (main_vbox), GTK_WIDGET (label), FALSE, FALSE, 0); + + row = 0; + + table = gtk_table_new (2, 2, FALSE); + gtk_box_pack_start (GTK_BOX (main_vbox), table, FALSE, FALSE, 0); + + /* secure erase */ + label = gtk_label_new (NULL); + gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5); + gtk_label_set_markup_with_mnemonic (GTK_LABEL (label), _("_Erase:")); + gtk_table_attach (GTK_TABLE (table), label, 0, 1, row, row + 1, + GTK_FILL, GTK_EXPAND | GTK_FILL, 2, 2); + combo_box = gdu_util_secure_erase_combo_box_create (); + gtk_table_attach (GTK_TABLE (table), combo_box, 1, 2, row, row + 1, + GTK_FILL, GTK_EXPAND | GTK_FILL, 2, 2); + gtk_label_set_mnemonic_widget (GTK_LABEL (label), combo_box); + + row++; + + /* secure erase desc */ + label = gtk_label_new (NULL); + gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); + gtk_label_set_width_chars (GTK_LABEL (label), 40); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_table_attach (GTK_TABLE (table), label, 1, 2, row, row + 1, + GTK_FILL, GTK_EXPAND | GTK_FILL, 2, 2); + gdu_util_secure_erase_combo_box_set_desc_label (combo_box, label); + + row++; + + gtk_widget_grab_focus (gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL)); + gtk_dialog_add_button (GTK_DIALOG (dialog), affirmative_action_button_mnemonic, 0); + + gtk_widget_show_all (dialog); + response = gtk_dialog_run (GTK_DIALOG (dialog)); + + secure_erase = gdu_util_secure_erase_combo_box_get_selected (combo_box); + + gtk_widget_destroy (dialog); + if (response != 0) { + g_free (secure_erase); + secure_erase = NULL; + goto out; + } + +out: + return secure_erase; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +gdu_util_fstype_combo_box_update_desc_label (GtkWidget *combo_box) +{ + GtkWidget *desc_label; + + desc_label = g_object_get_data (G_OBJECT (combo_box), "gdu-desc-label"); + if (desc_label != NULL) { + char *s; + char *fstype; + char *desc; + + fstype = gdu_util_fstype_combo_box_get_selected (combo_box); + if (fstype != NULL) { + desc = gdu_util_fstype_get_description (fstype); + if (desc != NULL) { + s = g_strdup_printf ("<small><i>%s</i></small>", desc); + gtk_label_set_markup (GTK_LABEL (desc_label), s); + g_free (desc); + } else { + gtk_label_set_markup (GTK_LABEL (desc_label), ""); + } + } else { + gtk_label_set_markup (GTK_LABEL (desc_label), ""); + } + g_free (fstype); + } +} + +static GtkListStore * +gdu_util_fstype_combo_box_create_store (GduPool *pool, const char *include_extended_partitions_for_scheme) +{ + GList *l; + GtkListStore *store; + GList *known_filesystems; + GtkTreeIter iter; + + store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING); + + if (pool != NULL) + known_filesystems = gdu_pool_get_known_filesystems (pool); + else + known_filesystems = NULL; + for (l = known_filesystems; l != NULL; l = l->next) { + GduKnownFilesystem *kfs = l->data; + const char *fstype; + char *fstype_name; + + fstype = gdu_known_filesystem_get_id (kfs); + + if (strcmp (fstype, "empty") == 0) { + fstype_name = g_strdup (_("Empty (don't create a file system)")); + } else { + fstype_name = gdu_util_get_fstype_for_display (fstype, NULL, TRUE); + /* TODO */ + } + + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, + 0, fstype, + 1, fstype_name, + -1); + + g_free (fstype_name); + } + g_list_foreach (known_filesystems, (GFunc) g_object_unref, NULL); + g_list_free (known_filesystems); + + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, + 0, "empty", + 1, _("Empty"), + -1); + + if (include_extended_partitions_for_scheme != NULL && + strcmp (include_extended_partitions_for_scheme, "mbr") == 0) { + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, + 0, "msdos_extended_partition", + 1, "Extended Partition", + -1); + } + + return store; +} + +void +gdu_util_fstype_combo_box_set_desc_label (GtkWidget *combo_box, GtkWidget *desc_label) +{ + g_object_set_data_full (G_OBJECT (combo_box), + "gdu-desc-label", + g_object_ref (desc_label), + g_object_unref); + + gdu_util_fstype_combo_box_update_desc_label (combo_box); +} + +void +gdu_util_fstype_combo_box_rebuild (GtkWidget *combo_box, + GduPool *pool, + const char *include_extended_partitions_for_scheme) +{ + GtkListStore *store; + store = gdu_util_fstype_combo_box_create_store (pool, include_extended_partitions_for_scheme); + gtk_combo_box_set_model (GTK_COMBO_BOX (combo_box), GTK_TREE_MODEL (store)); + g_object_unref (store); + gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box), 0); +} + +static void +gdu_util_fstype_combo_box_changed (GtkWidget *combo_box, gpointer user_data) +{ + gdu_util_fstype_combo_box_update_desc_label (combo_box); +} + +/** + * gdu_util_fstype_combo_box_create: + * @pool: A #GduPool object + * @include_extended_partitions_for_scheme: if not #NULL, includes + * extended partition types. This is currently only relevant for + * Master Boot Record ("mbr") where a single item "Extended Partition" + * will be returned. + * + * Get a combo box with the file system types that the DeviceKit-disks + * daemon can create. + * + * Returns: A #GtkComboBox widget + **/ +GtkWidget * +gdu_util_fstype_combo_box_create (GduPool *pool, const char *include_extended_partitions_for_scheme) +{ + GtkListStore *store; + GtkCellRenderer *renderer; + GtkWidget *combo_box; + + + combo_box = gtk_combo_box_new (); + store = gdu_util_fstype_combo_box_create_store (pool, include_extended_partitions_for_scheme); + gtk_combo_box_set_model (GTK_COMBO_BOX (combo_box), GTK_TREE_MODEL (store)); + g_object_unref (store); + + renderer = gtk_cell_renderer_text_new (); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo_box), renderer, TRUE); + gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo_box), renderer, + "text", 1, + NULL); + + gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box), 0); + + g_signal_connect (combo_box, "changed", (GCallback) gdu_util_fstype_combo_box_changed, NULL); + + return combo_box; +} + +gboolean +gdu_util_fstype_combo_box_select (GtkWidget *combo_box, const char *fstype) +{ + GtkTreeModel *model; + GtkTreeIter iter; + gboolean ret; + + ret = FALSE; + + model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo_box)); + gtk_tree_model_get_iter_first (model, &iter); + do { + char *iter_fstype; + + gtk_tree_model_get (model, &iter, 0, &iter_fstype, -1); + if (iter_fstype != NULL && strcmp (fstype, iter_fstype) == 0) { + gtk_combo_box_set_active_iter (GTK_COMBO_BOX (combo_box), &iter); + ret = TRUE; + } + g_free (iter_fstype); + } while (!ret && gtk_tree_model_iter_next (model, &iter)); + + return ret; +} + +char * +gdu_util_fstype_combo_box_get_selected (GtkWidget *combo_box) +{ + GtkTreeModel *model; + GtkTreeIter iter; + char *fstype; + + model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo_box)); + fstype = NULL; + if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo_box), &iter)) + gtk_tree_model_get (model, &iter, 0, &fstype, -1); + + return fstype; +} + + +/* ---------------------------------------------------------------------------------------------------- */ + +typedef struct { + const char *part_scheme; + GtkListStore *store; +} PartTypeData; + +static void +part_type_foreach_cb (const char *scheme, + const char *type, + const char *name, + gpointer user_data) +{ + PartTypeData *data = (PartTypeData *) user_data; + GtkTreeIter iter; + + if (strcmp (scheme, data->part_scheme) != 0) + return; + + gtk_list_store_append (data->store, &iter); + gtk_list_store_set (data->store, &iter, + 0, type, + 1, name, + -1); +} + +static GtkListStore * +gdu_util_part_type_combo_box_create_store (const char *part_scheme) +{ + GtkListStore *store; + PartTypeData data; + + store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING); + if (part_scheme == NULL) + goto out; + + data.part_scheme = part_scheme; + data.store = store; + + gdu_util_part_type_foreach (part_type_foreach_cb, &data); + +out: + return store; +} + +void +gdu_util_part_type_combo_box_rebuild (GtkWidget *combo_box, const char *part_scheme) +{ + GtkListStore *store; + store = gdu_util_part_type_combo_box_create_store (part_scheme); + gtk_combo_box_set_model (GTK_COMBO_BOX (combo_box), GTK_TREE_MODEL (store)); + g_object_unref (store); + gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box), 0); +} + + +/** + * gdu_util_part_type_combo_box_create: + * @part_scheme: Partitioning scheme to get partitions types for. + * + * Get a combo box with the partition types for a given scheme. + * + * Returns: A #GtkComboBox widget + **/ +GtkWidget * +gdu_util_part_type_combo_box_create (const char *part_scheme) +{ + GtkListStore *store; + GtkCellRenderer *renderer; + GtkWidget *combo_box; + + combo_box = gtk_combo_box_new (); + store = gdu_util_part_type_combo_box_create_store (part_scheme); + gtk_combo_box_set_model (GTK_COMBO_BOX (combo_box), GTK_TREE_MODEL (store)); + g_object_unref (store); + + renderer = gtk_cell_renderer_text_new (); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo_box), renderer, TRUE); + gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo_box), renderer, + "text", 1, + NULL); + + gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box), 0); + + return combo_box; +} + + +gboolean +gdu_util_part_type_combo_box_select (GtkWidget *combo_box, const char *part_type) +{ + GtkTreeModel *model; + GtkTreeIter iter; + gboolean ret; + + ret = FALSE; + + model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo_box)); + if (gtk_tree_model_get_iter_first (model, &iter)) { + do { + char *iter_part_type; + + gtk_tree_model_get (model, &iter, 0, &iter_part_type, -1); + if (iter_part_type != NULL && strcmp (part_type, iter_part_type) == 0) { + gtk_combo_box_set_active_iter (GTK_COMBO_BOX (combo_box), &iter); + ret = TRUE; + } + g_free (iter_part_type); + } while (!ret && gtk_tree_model_iter_next (model, &iter)); + } + + return ret; +} + +char * +gdu_util_part_type_combo_box_get_selected (GtkWidget *combo_box) +{ + GtkTreeModel *model; + GtkTreeIter iter; + char *part_type; + + model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo_box)); + part_type = NULL; + if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo_box), &iter)) + gtk_tree_model_get (model, &iter, 0, &part_type, -1); + + return part_type; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static GtkListStore * +gdu_util_part_table_type_combo_box_create_store (void) +{ + GtkListStore *store; + GtkTreeIter iter; + + store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING); + + /* TODO: get from daemon */ + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, + 0, "gpt", + 1, _("GUID Partition Table"), + -1); + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, + 0, "mbr", + 1, _("Master Boot Record"), + -1); + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, + 0, "none", + 1, _("Don't partition"), + -1); + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, + 0, "apm", + 1, _("Apple Partition Map"), + -1); + + return store; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +gdu_util_part_table_type_combo_box_update_desc_label (GtkWidget *combo_box) +{ + GtkWidget *desc_label; + + desc_label = g_object_get_data (G_OBJECT (combo_box), "gdu-desc-label"); + if (desc_label != NULL) { + char *s; + char *fstype; + char *desc; + + fstype = gdu_util_part_table_type_combo_box_get_selected (combo_box); + if (fstype != NULL) { + desc = gdu_util_part_table_type_get_description (fstype); + if (desc != NULL) { + s = g_strdup_printf ("<small><i>%s</i></small>", desc); + gtk_label_set_markup (GTK_LABEL (desc_label), s); + g_free (desc); + } else { + gtk_label_set_markup (GTK_LABEL (desc_label), ""); + } + } else { + gtk_label_set_markup (GTK_LABEL (desc_label), ""); + } + g_free (fstype); + } +} + +static void +gdu_util_part_table_type_combo_box_changed (GtkWidget *combo_box, gpointer user_data) +{ + gdu_util_part_table_type_combo_box_update_desc_label (combo_box); +} + +void +gdu_util_part_table_type_combo_box_set_desc_label (GtkWidget *combo_box, GtkWidget *desc_label) +{ + g_object_set_data_full (G_OBJECT (combo_box), + "gdu-desc-label", + g_object_ref (desc_label), + g_object_unref); + + gdu_util_part_table_type_combo_box_update_desc_label (combo_box); +} + +/** + * gdu_util_part_table_type_combo_box_create: + * + * Get a combo box with the partition tables types we can create. + * + * Returns: A #GtkComboBox widget + **/ +GtkWidget * +gdu_util_part_table_type_combo_box_create (void) +{ + GtkListStore *store; + GtkCellRenderer *renderer; + GtkWidget *combo_box; + + combo_box = gtk_combo_box_new (); + store = gdu_util_part_table_type_combo_box_create_store (); + gtk_combo_box_set_model (GTK_COMBO_BOX (combo_box), GTK_TREE_MODEL (store)); + g_object_unref (store); + + renderer = gtk_cell_renderer_text_new (); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo_box), renderer, TRUE); + gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo_box), renderer, + "text", 1, + NULL); + + gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box), 0); + + g_signal_connect (combo_box, "changed", (GCallback) gdu_util_part_table_type_combo_box_changed, NULL); + + return combo_box; +} + +gboolean +gdu_util_part_table_type_combo_box_select (GtkWidget *combo_box, const char *part_table_type) +{ + GtkTreeModel *model; + GtkTreeIter iter; + gboolean ret; + + ret = FALSE; + + model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo_box)); + gtk_tree_model_get_iter_first (model, &iter); + do { + char *iter_part_table_type; + + gtk_tree_model_get (model, &iter, 0, &iter_part_table_type, -1); + if (iter_part_table_type != NULL && strcmp (part_table_type, iter_part_table_type) == 0) { + gtk_combo_box_set_active_iter (GTK_COMBO_BOX (combo_box), &iter); + ret = TRUE; + } + g_free (iter_part_table_type); + } while (!ret && gtk_tree_model_iter_next (model, &iter)); + + return ret; +} + +char * +gdu_util_part_table_type_combo_box_get_selected (GtkWidget *combo_box) +{ + GtkTreeModel *model; + GtkTreeIter iter; + char *part_table_type; + + model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo_box)); + part_table_type = NULL; + if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo_box), &iter)) + gtk_tree_model_get (model, &iter, 0, &part_table_type, -1); + + return part_table_type; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +gdu_util_secure_erase_combo_box_update_desc_label (GtkWidget *combo_box) +{ + GtkWidget *desc_label; + + desc_label = g_object_get_data (G_OBJECT (combo_box), "gdu-desc-label"); + if (desc_label != NULL) { + char *s; + char *secure_erase; + char *secure_erase_desc; + + secure_erase = gdu_util_secure_erase_combo_box_get_selected (combo_box); + secure_erase_desc = gdu_util_secure_erase_get_description (secure_erase); + s = g_strdup_printf ("<small><i>%s</i></small>", secure_erase_desc); + gtk_label_set_markup (GTK_LABEL (desc_label), s); + g_free (s); + g_free (secure_erase_desc); + g_free (secure_erase); + } +} + +static void +gdu_util_secure_erase_combo_box_changed (GtkWidget *combo_box, gpointer user_data) +{ + gdu_util_secure_erase_combo_box_update_desc_label (combo_box); +} + +GtkWidget * +gdu_util_secure_erase_combo_box_create (void) +{ + GtkWidget *combo_box; + + combo_box = gtk_combo_box_new_text (); + gtk_combo_box_append_text (GTK_COMBO_BOX (combo_box), _("Don't overwrite data")); + gtk_combo_box_append_text (GTK_COMBO_BOX (combo_box), _("Overwrite data")); + gtk_combo_box_append_text (GTK_COMBO_BOX (combo_box), _("Overwrite data 3 times")); + gtk_combo_box_append_text (GTK_COMBO_BOX (combo_box), _("Overwrite data 7 times")); + gtk_combo_box_append_text (GTK_COMBO_BOX (combo_box), _("Overwrite data 35 times")); + gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box), 0); /* read default from gconf; use lockdown too */ + + g_signal_connect (combo_box, "changed", (GCallback) gdu_util_secure_erase_combo_box_changed, NULL); + return combo_box; +} + +char * +gdu_util_secure_erase_combo_box_get_selected (GtkWidget *combo_box) +{ + const char *result[] = {"none", "full", "full3pass", "full7pass", "full35pass"}; + int active; + + active = gtk_combo_box_get_active (GTK_COMBO_BOX (combo_box)); + g_assert (active >= 0 && active < (int) sizeof (result)); + return g_strdup (result[active]); +} + +void +gdu_util_secure_erase_combo_box_set_desc_label (GtkWidget *combo_box, GtkWidget *desc_label) +{ + g_object_set_data_full (G_OBJECT (combo_box), + "gdu-desc-label", + g_object_ref (desc_label), + g_object_unref); + + gdu_util_secure_erase_combo_box_update_desc_label (combo_box); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +GdkPixbuf * +gdu_util_get_pixbuf_for_presentable (GduPresentable *presentable, GtkIconSize size) +{ + char *icon_name; + GdkPixbuf *pixbuf; + + icon_name = gdu_presentable_get_icon_name (presentable); + + pixbuf = NULL; + if (icon_name != NULL) { + int icon_width, icon_height; + + if (!gtk_icon_size_lookup (size, &icon_width, &icon_height)) + icon_height = 48; + + pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), + icon_name, + icon_height, + GTK_ICON_LOOKUP_GENERIC_FALLBACK, + NULL); + + /* if it's unallocated or unrecognized space, make the icon greyscale */ + if (!gdu_presentable_is_allocated (presentable) || + !gdu_presentable_is_recognized (presentable)) { + GdkPixbuf *pixbuf2; + pixbuf2 = pixbuf; + pixbuf = gdk_pixbuf_copy (pixbuf); + g_object_unref (pixbuf2); + gdk_pixbuf_saturate_and_pixelate (pixbuf, + pixbuf, + 0.0, + FALSE); + } + } + + g_free (icon_name); + + return pixbuf; +} + diff --git a/src/gdu-ui-util.h b/src/gdu-ui-util.h new file mode 100644 index 0000000..969b140 --- /dev/null +++ b/src/gdu-ui-util.h @@ -0,0 +1,98 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ +/* gdu-ui-util.h + * + * Copyright (C) 2007 David Zeuthen + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +#include <gtk/gtk.h> +#include "gdu-presentable.h" +#include "gdu-pool.h" +#include "gdu-util.h" + +#ifndef GDU_UI_UTIL_H +#define GDU_UI_UTIL_H + +gboolean gdu_util_dialog_show_filesystem_busy (GtkWidget *parent_window, GduPresentable *presentable); + + +char *gdu_util_dialog_ask_for_new_secret (GtkWidget *parent_window, + gboolean *save_in_keyring, + gboolean *save_in_keyring_session); + +char *gdu_util_dialog_ask_for_secret (GtkWidget *parent_window, + GduPresentable *presentable, + gboolean bypass_keyring, + gboolean indicate_wrong_passphrase, + gboolean *asked_user); + +gboolean gdu_util_dialog_change_secret (GtkWidget *parent_window, + GduPresentable *presentable, + char **old_secret, + char **new_secret, + gboolean *save_in_keyring, + gboolean *save_in_keyring_session, + gboolean bypass_keyring, + gboolean indicate_wrong_passphrase); + +char *gdu_util_delete_confirmation_dialog (GtkWidget *parent_window, + const char *title, + const char *primary_text, + const char *secondary_text, + const char *affirmative_action_button_mnemonic); + +/* ---------------------------------------------------------------------------------------------------- */ + +GtkWidget *gdu_util_fstype_combo_box_create (GduPool *pool, + const char *include_extended_partitions_for_scheme); +void gdu_util_fstype_combo_box_rebuild (GtkWidget *combo_box, + GduPool *pool, + const char *include_extended_partitions_for_scheme); +void gdu_util_fstype_combo_box_set_desc_label (GtkWidget *combo_box, GtkWidget *desc_label); +gboolean gdu_util_fstype_combo_box_select (GtkWidget *combo_box, + const char *fstype); +char *gdu_util_fstype_combo_box_get_selected (GtkWidget *combo_box); + +/* ---------------------------------------------------------------------------------------------------- */ + +GtkWidget *gdu_util_secure_erase_combo_box_create (void); +void gdu_util_secure_erase_combo_box_set_desc_label (GtkWidget *combo_box, GtkWidget *desc_label); +char *gdu_util_secure_erase_combo_box_get_selected (GtkWidget *combo_box); + +/* ---------------------------------------------------------------------------------------------------- */ + +GtkWidget *gdu_util_part_type_combo_box_create (const char *part_scheme); +void gdu_util_part_type_combo_box_rebuild (GtkWidget *combo_box, + const char *part_scheme); +gboolean gdu_util_part_type_combo_box_select (GtkWidget *combo_box, + const char *part_type); +char *gdu_util_part_type_combo_box_get_selected (GtkWidget *combo_box); + +/* ---------------------------------------------------------------------------------------------------- */ + +GtkWidget *gdu_util_part_table_type_combo_box_create (void); +void gdu_util_part_table_type_combo_box_set_desc_label (GtkWidget *combo_box, GtkWidget *desc_label); +gboolean gdu_util_part_table_type_combo_box_select (GtkWidget *combo_box, + const char *part_table_type); +char *gdu_util_part_table_type_combo_box_get_selected (GtkWidget *combo_box); + +/* ---------------------------------------------------------------------------------------------------- */ + +GdkPixbuf *gdu_util_get_pixbuf_for_presentable (GduPresentable *presentable, GtkIconSize size); + + +#endif /* GDU_UI_UTIL_H */ diff --git a/src/gdu-util.c b/src/gdu-util.c index 8f6b5fe..78807b1 100644 --- a/src/gdu-util.c +++ b/src/gdu-util.c @@ -1,5 +1,5 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ -/* gdu-main.c +/* gdu-util.c * * Copyright (C) 2007 David Zeuthen * @@ -350,6 +350,15 @@ static struct { {NULL, NULL, NULL} }; +void +gdu_util_part_type_foreach (GduUtilPartTypeForeachFunc callback, gpointer user_data) +{ + int n; + for (n = 0; part_type[n].scheme != NULL; n++) { + callback (part_type[n].scheme, part_type[n].type, part_type[n].name, user_data); + } +} + char * gdu_util_get_desc_for_part_type (const char *scheme, const char *type) { @@ -364,7 +373,7 @@ gdu_util_get_desc_for_part_type (const char *scheme, const char *type) } -static char * +char * gdu_util_fstype_get_description (char *fstype) { g_return_val_if_fail (fstype != NULL, NULL); @@ -398,348 +407,8 @@ gdu_util_fstype_get_description (char *fstype) return NULL; } -static void -gdu_util_fstype_combo_box_update_desc_label (GtkWidget *combo_box) -{ - GtkWidget *desc_label; - - desc_label = g_object_get_data (G_OBJECT (combo_box), "gdu-desc-label"); - if (desc_label != NULL) { - char *s; - char *fstype; - char *desc; - - fstype = gdu_util_fstype_combo_box_get_selected (combo_box); - if (fstype != NULL) { - desc = gdu_util_fstype_get_description (fstype); - if (desc != NULL) { - s = g_strdup_printf ("<small><i>%s</i></small>", desc); - gtk_label_set_markup (GTK_LABEL (desc_label), s); - g_free (desc); - } else { - gtk_label_set_markup (GTK_LABEL (desc_label), ""); - } - } else { - gtk_label_set_markup (GTK_LABEL (desc_label), ""); - } - g_free (fstype); - } -} - -static GtkListStore * -gdu_util_fstype_combo_box_create_store (GduPool *pool, const char *include_extended_partitions_for_scheme) -{ - GList *l; - GtkListStore *store; - GList *known_filesystems; - GtkTreeIter iter; - - store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING); - - if (pool != NULL) - known_filesystems = gdu_pool_get_known_filesystems (pool); - else - known_filesystems = NULL; - for (l = known_filesystems; l != NULL; l = l->next) { - GduKnownFilesystem *kfs = l->data; - const char *fstype; - char *fstype_name; - - fstype = gdu_known_filesystem_get_id (kfs); - - if (strcmp (fstype, "empty") == 0) { - fstype_name = g_strdup (_("Empty (don't create a file system)")); - } else { - fstype_name = gdu_util_get_fstype_for_display (fstype, NULL, TRUE); - /* TODO */ - } - - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, - 0, fstype, - 1, fstype_name, - -1); - - g_free (fstype_name); - } - g_list_foreach (known_filesystems, (GFunc) g_object_unref, NULL); - g_list_free (known_filesystems); - - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, - 0, "empty", - 1, _("Empty"), - -1); - - if (include_extended_partitions_for_scheme != NULL && - strcmp (include_extended_partitions_for_scheme, "mbr") == 0) { - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, - 0, "msdos_extended_partition", - 1, "Extended Partition", - -1); - } - - return store; -} - -void -gdu_util_fstype_combo_box_set_desc_label (GtkWidget *combo_box, GtkWidget *desc_label) -{ - g_object_set_data_full (G_OBJECT (combo_box), - "gdu-desc-label", - g_object_ref (desc_label), - g_object_unref); - - gdu_util_fstype_combo_box_update_desc_label (combo_box); -} - -void -gdu_util_fstype_combo_box_rebuild (GtkWidget *combo_box, - GduPool *pool, - const char *include_extended_partitions_for_scheme) -{ - GtkListStore *store; - store = gdu_util_fstype_combo_box_create_store (pool, include_extended_partitions_for_scheme); - gtk_combo_box_set_model (GTK_COMBO_BOX (combo_box), GTK_TREE_MODEL (store)); - g_object_unref (store); - gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box), 0); -} - -static void -gdu_util_fstype_combo_box_changed (GtkWidget *combo_box, gpointer user_data) -{ - gdu_util_fstype_combo_box_update_desc_label (combo_box); -} - -/** - * gdu_util_fstype_combo_box_create: - * @pool: A #GduPool object - * @include_extended_partitions_for_scheme: if not #NULL, includes - * extended partition types. This is currently only relevant for - * Master Boot Record ("mbr") where a single item "Extended Partition" - * will be returned. - * - * Get a combo box with the file system types that the DeviceKit-disks - * daemon can create. - * - * Returns: A #GtkComboBox widget - **/ -GtkWidget * -gdu_util_fstype_combo_box_create (GduPool *pool, const char *include_extended_partitions_for_scheme) -{ - GtkListStore *store; - GtkCellRenderer *renderer; - GtkWidget *combo_box; - - - combo_box = gtk_combo_box_new (); - store = gdu_util_fstype_combo_box_create_store (pool, include_extended_partitions_for_scheme); - gtk_combo_box_set_model (GTK_COMBO_BOX (combo_box), GTK_TREE_MODEL (store)); - g_object_unref (store); - - renderer = gtk_cell_renderer_text_new (); - gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo_box), renderer, TRUE); - gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo_box), renderer, - "text", 1, - NULL); - - gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box), 0); - - g_signal_connect (combo_box, "changed", (GCallback) gdu_util_fstype_combo_box_changed, NULL); - - return combo_box; -} - -gboolean -gdu_util_fstype_combo_box_select (GtkWidget *combo_box, const char *fstype) -{ - GtkTreeModel *model; - GtkTreeIter iter; - gboolean ret; - - ret = FALSE; - - model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo_box)); - gtk_tree_model_get_iter_first (model, &iter); - do { - char *iter_fstype; - - gtk_tree_model_get (model, &iter, 0, &iter_fstype, -1); - if (iter_fstype != NULL && strcmp (fstype, iter_fstype) == 0) { - gtk_combo_box_set_active_iter (GTK_COMBO_BOX (combo_box), &iter); - ret = TRUE; - } - g_free (iter_fstype); - } while (!ret && gtk_tree_model_iter_next (model, &iter)); - - return ret; -} char * -gdu_util_fstype_combo_box_get_selected (GtkWidget *combo_box) -{ - GtkTreeModel *model; - GtkTreeIter iter; - char *fstype; - - model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo_box)); - fstype = NULL; - if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo_box), &iter)) - gtk_tree_model_get (model, &iter, 0, &fstype, -1); - - return fstype; -} - - -/* ---------------------------------------------------------------------------------------------------- */ - -static GtkListStore * -gdu_util_part_type_combo_box_create_store (const char *part_scheme) -{ - int n; - GtkListStore *store; - GtkTreeIter iter; - - store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING); - if (part_scheme == NULL) - goto out; - - for (n = 0; part_type[n].scheme != NULL; n++) { - if (strcmp (part_type[n].scheme, part_scheme) != 0) - continue; - - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, - 0, part_type[n].type, - 1, part_type[n].name, - -1); - } - -out: - return store; -} - -void -gdu_util_part_type_combo_box_rebuild (GtkWidget *combo_box, const char *part_scheme) -{ - GtkListStore *store; - store = gdu_util_part_type_combo_box_create_store (part_scheme); - gtk_combo_box_set_model (GTK_COMBO_BOX (combo_box), GTK_TREE_MODEL (store)); - g_object_unref (store); - gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box), 0); -} - - -/** - * gdu_util_part_type_combo_box_create: - * @part_scheme: Partitioning scheme to get partitions types for. - * - * Get a combo box with the partition types for a given scheme. - * - * Returns: A #GtkComboBox widget - **/ -GtkWidget * -gdu_util_part_type_combo_box_create (const char *part_scheme) -{ - GtkListStore *store; - GtkCellRenderer *renderer; - GtkWidget *combo_box; - - combo_box = gtk_combo_box_new (); - store = gdu_util_part_type_combo_box_create_store (part_scheme); - gtk_combo_box_set_model (GTK_COMBO_BOX (combo_box), GTK_TREE_MODEL (store)); - g_object_unref (store); - - renderer = gtk_cell_renderer_text_new (); - gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo_box), renderer, TRUE); - gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo_box), renderer, - "text", 1, - NULL); - - gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box), 0); - - return combo_box; -} - - -gboolean -gdu_util_part_type_combo_box_select (GtkWidget *combo_box, const char *part_type) -{ - GtkTreeModel *model; - GtkTreeIter iter; - gboolean ret; - - ret = FALSE; - - model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo_box)); - if (gtk_tree_model_get_iter_first (model, &iter)) { - do { - char *iter_part_type; - - gtk_tree_model_get (model, &iter, 0, &iter_part_type, -1); - if (iter_part_type != NULL && strcmp (part_type, iter_part_type) == 0) { - gtk_combo_box_set_active_iter (GTK_COMBO_BOX (combo_box), &iter); - ret = TRUE; - } - g_free (iter_part_type); - } while (!ret && gtk_tree_model_iter_next (model, &iter)); - } - - return ret; -} - -char * -gdu_util_part_type_combo_box_get_selected (GtkWidget *combo_box) -{ - GtkTreeModel *model; - GtkTreeIter iter; - char *part_type; - - model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo_box)); - part_type = NULL; - if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo_box), &iter)) - gtk_tree_model_get (model, &iter, 0, &part_type, -1); - - return part_type; -} - -/* ---------------------------------------------------------------------------------------------------- */ - -static GtkListStore * -gdu_util_part_table_type_combo_box_create_store (void) -{ - GtkListStore *store; - GtkTreeIter iter; - - store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING); - - /* TODO: get from daemon */ - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, - 0, "gpt", - 1, _("GUID Partition Table"), - -1); - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, - 0, "mbr", - 1, _("Master Boot Record"), - -1); - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, - 0, "none", - 1, _("Don't partition"), - -1); - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, - 0, "apm", - 1, _("Apple Partition Map"), - -1); - - return store; -} - -static char * gdu_util_part_table_type_get_description (char *part_type) { g_return_val_if_fail (part_type != NULL, NULL); @@ -767,127 +436,9 @@ gdu_util_part_table_type_get_description (char *part_type) return NULL; } -static void -gdu_util_part_table_type_combo_box_update_desc_label (GtkWidget *combo_box) -{ - GtkWidget *desc_label; - - desc_label = g_object_get_data (G_OBJECT (combo_box), "gdu-desc-label"); - if (desc_label != NULL) { - char *s; - char *fstype; - char *desc; - - fstype = gdu_util_part_table_type_combo_box_get_selected (combo_box); - if (fstype != NULL) { - desc = gdu_util_part_table_type_get_description (fstype); - if (desc != NULL) { - s = g_strdup_printf ("<small><i>%s</i></small>", desc); - gtk_label_set_markup (GTK_LABEL (desc_label), s); - g_free (desc); - } else { - gtk_label_set_markup (GTK_LABEL (desc_label), ""); - } - } else { - gtk_label_set_markup (GTK_LABEL (desc_label), ""); - } - g_free (fstype); - } -} - -static void -gdu_util_part_table_type_combo_box_changed (GtkWidget *combo_box, gpointer user_data) -{ - gdu_util_part_table_type_combo_box_update_desc_label (combo_box); -} - -void -gdu_util_part_table_type_combo_box_set_desc_label (GtkWidget *combo_box, GtkWidget *desc_label) -{ - g_object_set_data_full (G_OBJECT (combo_box), - "gdu-desc-label", - g_object_ref (desc_label), - g_object_unref); - - gdu_util_part_table_type_combo_box_update_desc_label (combo_box); -} - -/** - * gdu_util_part_table_type_combo_box_create: - * - * Get a combo box with the partition tables types we can create. - * - * Returns: A #GtkComboBox widget - **/ -GtkWidget * -gdu_util_part_table_type_combo_box_create (void) -{ - GtkListStore *store; - GtkCellRenderer *renderer; - GtkWidget *combo_box; - - combo_box = gtk_combo_box_new (); - store = gdu_util_part_table_type_combo_box_create_store (); - gtk_combo_box_set_model (GTK_COMBO_BOX (combo_box), GTK_TREE_MODEL (store)); - g_object_unref (store); - - renderer = gtk_cell_renderer_text_new (); - gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo_box), renderer, TRUE); - gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo_box), renderer, - "text", 1, - NULL); - - gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box), 0); - - g_signal_connect (combo_box, "changed", (GCallback) gdu_util_part_table_type_combo_box_changed, NULL); - - return combo_box; -} - -gboolean -gdu_util_part_table_type_combo_box_select (GtkWidget *combo_box, const char *part_table_type) -{ - GtkTreeModel *model; - GtkTreeIter iter; - gboolean ret; - - ret = FALSE; - - model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo_box)); - gtk_tree_model_get_iter_first (model, &iter); - do { - char *iter_part_table_type; - - gtk_tree_model_get (model, &iter, 0, &iter_part_table_type, -1); - if (iter_part_table_type != NULL && strcmp (part_table_type, iter_part_table_type) == 0) { - gtk_combo_box_set_active_iter (GTK_COMBO_BOX (combo_box), &iter); - ret = TRUE; - } - g_free (iter_part_table_type); - } while (!ret && gtk_tree_model_iter_next (model, &iter)); - - return ret; -} - -char * -gdu_util_part_table_type_combo_box_get_selected (GtkWidget *combo_box) -{ - GtkTreeModel *model; - GtkTreeIter iter; - char *part_table_type; - - model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo_box)); - part_table_type = NULL; - if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo_box), &iter)) - gtk_tree_model_get (model, &iter, 0, &part_table_type, -1); - - return part_table_type; -} - - /* ---------------------------------------------------------------------------------------------------- */ -static char * +char * gdu_util_secure_erase_get_description (char *secure_erase_type) { g_return_val_if_fail (secure_erase_type != NULL, NULL); @@ -922,72 +473,6 @@ gdu_util_secure_erase_get_description (char *secure_erase_type) return NULL; } -static void -gdu_util_secure_erase_combo_box_update_desc_label (GtkWidget *combo_box) -{ - GtkWidget *desc_label; - - desc_label = g_object_get_data (G_OBJECT (combo_box), "gdu-desc-label"); - if (desc_label != NULL) { - char *s; - char *secure_erase; - char *secure_erase_desc; - - secure_erase = gdu_util_secure_erase_combo_box_get_selected (combo_box); - secure_erase_desc = gdu_util_secure_erase_get_description (secure_erase); - s = g_strdup_printf ("<small><i>%s</i></small>", secure_erase_desc); - gtk_label_set_markup (GTK_LABEL (desc_label), s); - g_free (s); - g_free (secure_erase_desc); - g_free (secure_erase); - } -} - -static void -gdu_util_secure_erase_combo_box_changed (GtkWidget *combo_box, gpointer user_data) -{ - gdu_util_secure_erase_combo_box_update_desc_label (combo_box); -} - -GtkWidget * -gdu_util_secure_erase_combo_box_create (void) -{ - GtkWidget *combo_box; - - combo_box = gtk_combo_box_new_text (); - gtk_combo_box_append_text (GTK_COMBO_BOX (combo_box), _("Don't overwrite data")); - gtk_combo_box_append_text (GTK_COMBO_BOX (combo_box), _("Overwrite data")); - gtk_combo_box_append_text (GTK_COMBO_BOX (combo_box), _("Overwrite data 3 times")); - gtk_combo_box_append_text (GTK_COMBO_BOX (combo_box), _("Overwrite data 7 times")); - gtk_combo_box_append_text (GTK_COMBO_BOX (combo_box), _("Overwrite data 35 times")); - gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box), 0); /* read default from gconf; use lockdown too */ - - g_signal_connect (combo_box, "changed", (GCallback) gdu_util_secure_erase_combo_box_changed, NULL); - return combo_box; -} - -char * -gdu_util_secure_erase_combo_box_get_selected (GtkWidget *combo_box) -{ - const char *result[] = {"none", "full", "full3pass", "full7pass", "full35pass"}; - int active; - - active = gtk_combo_box_get_active (GTK_COMBO_BOX (combo_box)); - g_assert (active >= 0 && active < (int) sizeof (result)); - return g_strdup (result[active]); -} - -void -gdu_util_secure_erase_combo_box_set_desc_label (GtkWidget *combo_box, GtkWidget *desc_label) -{ - g_object_set_data_full (G_OBJECT (combo_box), - "gdu-desc-label", - g_object_ref (desc_label), - g_object_unref); - - gdu_util_secure_erase_combo_box_update_desc_label (combo_box); -} - /* ---------------------------------------------------------------------------------------------------- */ char * @@ -1022,318 +507,6 @@ gdu_util_get_default_part_type_for_scheme_and_fstype (const char *scheme, const /* ---------------------------------------------------------------------------------------------------- */ -typedef struct -{ - gboolean is_new_password; - GtkWidget *password_entry; - GtkWidget *password_entry_new; - GtkWidget *password_entry_verify; - GtkWidget *warning_hbox; - GtkWidget *warning_label; - GtkWidget *button; -} DialogSecretData; - -static void -gdu_util_dialog_secret_update (DialogSecretData *data) -{ - if (strcmp (gtk_entry_get_text (GTK_ENTRY (data->password_entry_new)), - gtk_entry_get_text (GTK_ENTRY (data->password_entry_verify))) != 0) { - gtk_widget_show (data->warning_hbox); - gtk_label_set_markup (GTK_LABEL (data->warning_label), "<i>Passphrases do not match</i>"); - gtk_widget_set_sensitive (data->button, FALSE); - } else if (!data->is_new_password && - (strlen (gtk_entry_get_text (GTK_ENTRY (data->password_entry))) > 0 || - strlen (gtk_entry_get_text (GTK_ENTRY (data->password_entry_new))) > 0) && - strcmp (gtk_entry_get_text (GTK_ENTRY (data->password_entry)), - gtk_entry_get_text (GTK_ENTRY (data->password_entry_new))) == 0) { - gtk_widget_show (data->warning_hbox); - gtk_label_set_markup (GTK_LABEL (data->warning_label), "<i>Passphrases do not differ</i>"); - gtk_widget_set_sensitive (data->button, FALSE); - } else { - gtk_widget_hide (data->warning_hbox); - gtk_widget_set_sensitive (data->button, TRUE); - } -} - -static void -gdu_util_dialog_secret_entry_changed (GtkWidget *entry, gpointer user_data) -{ - DialogSecretData *data = user_data; - gdu_util_dialog_secret_update (data); -} - -static void -secret_dialog_device_removed (GduDevice *device, gpointer user_data) -{ - GtkDialog *dialog = GTK_DIALOG (user_data); - gtk_dialog_response (dialog, GTK_RESPONSE_NONE); -} - -static char * -gdu_util_dialog_secret_internal (GtkWidget *parent_window, - const char *window_title, - const char *window_icon_name, - gboolean is_new_password, - gboolean is_change_password, - const char *old_secret_for_change_password, - char **old_secret_from_dialog, - gboolean *save_in_keyring, - gboolean *save_in_keyring_session, - gboolean indicate_wrong_passphrase, - GduDevice *device) -{ - int row; - int response; - char *secret; - GtkWidget *dialog; - GtkWidget *image; - GtkWidget *hbox; - GtkWidget *main_vbox; - GtkWidget *vbox; - GtkWidget *label; - GtkWidget *table_alignment; - GtkWidget *table; - GtkWidget *never_radio_button; - GtkWidget *session_radio_button; - GtkWidget *always_radio_button; - DialogSecretData *data; - - g_return_val_if_fail (parent_window == NULL || GTK_IS_WINDOW (parent_window), NULL); - - session_radio_button = NULL; - always_radio_button = NULL; - - secret = NULL; - data = g_new0 (DialogSecretData, 1); - data->is_new_password = is_new_password; - - dialog = gtk_dialog_new_with_buttons (window_title, - GTK_WINDOW (parent_window), - GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT|GTK_DIALOG_NO_SEPARATOR, - GTK_STOCK_CANCEL, - GTK_RESPONSE_CANCEL, - NULL); - - if (is_new_password) { - data->button = gtk_dialog_add_button (GTK_DIALOG (dialog), _("Cr_eate"), 0); - } else if (is_change_password) { - data->button = gtk_dialog_add_button (GTK_DIALOG (dialog), _("Change _Passphrase"), 0); - } else { - data->button = gtk_dialog_add_button (GTK_DIALOG (dialog), _("_Unlock"), 0); - } - gtk_dialog_set_default_response (GTK_DIALOG (dialog), 0); - - gtk_container_set_border_width (GTK_CONTAINER (dialog), 5); - gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 2); - gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area), 5); - gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->action_area), 6); - gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE); - if (window_icon_name != NULL) - gtk_window_set_icon_name (GTK_WINDOW (dialog), window_icon_name); - else - gtk_window_set_icon_name (GTK_WINDOW (dialog), GTK_STOCK_DIALOG_AUTHENTICATION); - - hbox = gtk_hbox_new (FALSE, 12); - gtk_container_set_border_width (GTK_CONTAINER (hbox), 5); - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), hbox, TRUE, TRUE, 0); - - image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_AUTHENTICATION, GTK_ICON_SIZE_DIALOG); - gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.0); - gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0); - - main_vbox = gtk_vbox_new (FALSE, 10); - gtk_box_pack_start (GTK_BOX (hbox), main_vbox, TRUE, TRUE, 0); - - /* main message */ - label = gtk_label_new (NULL); - if (is_new_password) { - gtk_label_set_markup (GTK_LABEL (label), - _("<b><big>To create an encrypted device, choose a passphrase " - "to protect it</big></b>")); - } else if (is_change_password) { - gtk_label_set_markup (GTK_LABEL (label), - _("<b><big>To change the passphrase, enter both the current and " - "new passphrase</big></b>")); - } else { - gtk_label_set_markup (GTK_LABEL (label), - _("<b><big>Data on this device is stored in an encrypted form " - "protected by a passphrase</big></b>")); - } - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); - gtk_box_pack_start (GTK_BOX (main_vbox), GTK_WIDGET (label), FALSE, FALSE, 0); - - /* secondary message */ - label = gtk_label_new (NULL); - if (is_new_password) { - gtk_label_set_markup (GTK_LABEL (label), _("Data on this device will be stored in an encrypted form " - "protected by a passphrase.")); - } else if (is_change_password) { - gtk_label_set_markup (GTK_LABEL (label), _("Data on this device is stored in an encrypted form " - "protected by a passphrase.")); - } else { - gtk_label_set_markup (GTK_LABEL (label), _("To make the data available for use, enter the " - "passphrase for the device.")); - } - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); - gtk_box_pack_start (GTK_BOX (main_vbox), GTK_WIDGET (label), FALSE, FALSE, 0); - - if (indicate_wrong_passphrase) { - label = gtk_label_new (NULL); - gtk_label_set_markup (GTK_LABEL (label), _("<b>Incorrect Passphrase. Try again.</b>")); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); - gtk_box_pack_start (GTK_BOX (main_vbox), GTK_WIDGET (label), FALSE, FALSE, 0); - } - - /* password entry */ - vbox = gtk_vbox_new (FALSE, 6); - gtk_box_pack_start (GTK_BOX (main_vbox), vbox, FALSE, FALSE, 0); - - table_alignment = gtk_alignment_new (0.0, 0.0, 1.0, 1.0); - gtk_box_pack_start (GTK_BOX (vbox), table_alignment, FALSE, FALSE, 0); - table = gtk_table_new (1, 2, FALSE); - gtk_table_set_col_spacings (GTK_TABLE (table), 12); - gtk_table_set_row_spacings (GTK_TABLE (table), 6); - gtk_container_add (GTK_CONTAINER (table_alignment), table); - - row = 0; - - if (is_change_password || is_new_password) { - - if (is_change_password) { - label = gtk_label_new_with_mnemonic (_("C_urrent Passphrase:")); - gtk_label_set_use_markup (GTK_LABEL (label), TRUE); - gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5); - gtk_table_attach (GTK_TABLE (table), label, - 0, 1, row, row + 1, - GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); - data->password_entry = gtk_entry_new (); - gtk_entry_set_visibility (GTK_ENTRY (data->password_entry), FALSE); - gtk_table_attach_defaults (GTK_TABLE (table), data->password_entry, 1, 2, row, row + 1); - gtk_label_set_mnemonic_widget (GTK_LABEL (label), data->password_entry); - - row++; - } - - label = gtk_label_new_with_mnemonic (_("_New Passphrase:")); - gtk_label_set_use_markup (GTK_LABEL (label), TRUE); - gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5); - gtk_table_attach (GTK_TABLE (table), label, - 0, 1, row, row + 1, - GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); - data->password_entry_new = gtk_entry_new (); - gtk_entry_set_visibility (GTK_ENTRY (data->password_entry_new), FALSE); - gtk_table_attach_defaults (GTK_TABLE (table), data->password_entry_new, 1, 2, row, row + 1); - gtk_label_set_mnemonic_widget (GTK_LABEL (label), data->password_entry_new); - - row++; - - label = gtk_label_new_with_mnemonic (_("_Verify Passphrase:")); - gtk_label_set_use_markup (GTK_LABEL (label), TRUE); - gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5); - gtk_table_attach (GTK_TABLE (table), label, - 0, 1, row, row + 1, - GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); - data->password_entry_verify = gtk_entry_new (); - gtk_entry_set_visibility (GTK_ENTRY (data->password_entry_verify), FALSE); - gtk_table_attach_defaults (GTK_TABLE (table), data->password_entry_verify, 1, 2, row, row + 1); - gtk_label_set_mnemonic_widget (GTK_LABEL (label), data->password_entry_verify); - - data->warning_hbox = gtk_hbox_new (FALSE, 12); - image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_MENU); - data->warning_label = gtk_label_new (NULL); - gtk_box_pack_start (GTK_BOX (data->warning_hbox), image, FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (data->warning_hbox), data->warning_label, FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (vbox), data->warning_hbox, FALSE, FALSE, 0); - - g_signal_connect (data->password_entry_new, "changed", - (GCallback) gdu_util_dialog_secret_entry_changed, data); - g_signal_connect (data->password_entry_verify, "changed", - (GCallback) gdu_util_dialog_secret_entry_changed, data); - - /* only the verify entry activates the default action */ - gtk_entry_set_activates_default (GTK_ENTRY (data->password_entry_verify), TRUE); - - /* if the old password is supplied (from e.g. the keyring), set it and focus on the new password */ - if (old_secret_for_change_password != NULL) { - gtk_entry_set_text (GTK_ENTRY (data->password_entry), old_secret_for_change_password); - gtk_widget_grab_focus (data->password_entry_new); - } else if (is_new_password) { - gtk_widget_grab_focus (data->password_entry_new); - } - - } else { - label = gtk_label_new_with_mnemonic (_("_Passphrase:")); - gtk_label_set_use_markup (GTK_LABEL (label), TRUE); - gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5); - gtk_table_attach (GTK_TABLE (table), label, - 0, 1, row, row + 1, - GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); - data->password_entry = gtk_entry_new (); - gtk_entry_set_visibility (GTK_ENTRY (data->password_entry), FALSE); - gtk_entry_set_activates_default (GTK_ENTRY (data->password_entry), TRUE); - gtk_table_attach_defaults (GTK_TABLE (table), data->password_entry, 1, 2, row, row + 1); - gtk_label_set_mnemonic_widget (GTK_LABEL (label), data->password_entry); - } - - never_radio_button = gtk_radio_button_new_with_mnemonic ( - NULL, - _("_Forget passphrase immediately")); - session_radio_button = gtk_radio_button_new_with_mnemonic_from_widget ( - GTK_RADIO_BUTTON (never_radio_button), - _("Remember passphrase until you _log out")); - always_radio_button = gtk_radio_button_new_with_mnemonic_from_widget ( - GTK_RADIO_BUTTON (never_radio_button), - _("_Remember forever")); - - /* preselect Remember Forever if we've retrieved the existing key from the keyring */ - if (is_change_password && old_secret_for_change_password != NULL) { - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (always_radio_button), TRUE); - } - - gtk_box_pack_start (GTK_BOX (vbox), never_radio_button, FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (vbox), session_radio_button, FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (vbox), always_radio_button, FALSE, FALSE, 0); - - gtk_widget_show_all (dialog); - if (is_change_password || is_new_password) - gdu_util_dialog_secret_update (data); - - if (device != NULL) - g_signal_connect (device, "removed", (GCallback) secret_dialog_device_removed, dialog); - - response = gtk_dialog_run (GTK_DIALOG (dialog)); - - if (device != NULL) - g_signal_handlers_disconnect_by_func (device, secret_dialog_device_removed, dialog); - - if (response != 0) - goto out; - - if (is_new_password) { - secret = g_strdup (gtk_entry_get_text (GTK_ENTRY (data->password_entry_new))); - } else if (is_change_password) { - *old_secret_from_dialog = g_strdup (gtk_entry_get_text (GTK_ENTRY (data->password_entry))); - secret = g_strdup (gtk_entry_get_text (GTK_ENTRY (data->password_entry_new))); - } else { - secret = g_strdup (gtk_entry_get_text (GTK_ENTRY (data->password_entry))); - } - - if (save_in_keyring != NULL) - *save_in_keyring = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (always_radio_button)); - if (save_in_keyring_session != NULL) - *save_in_keyring_session = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (session_radio_button)); - -out: - if (data == NULL) - g_free (data); - if (dialog != NULL) - gtk_widget_destroy (dialog); - return secret; -} - static GnomeKeyringPasswordSchema encrypted_device_password_schema = { GNOME_KEYRING_ITEM_GENERIC_SECRET, { @@ -1342,289 +515,6 @@ static GnomeKeyringPasswordSchema encrypted_device_password_schema = { } }; -char * -gdu_util_dialog_ask_for_new_secret (GtkWidget *parent_window, - gboolean *save_in_keyring, - gboolean *save_in_keyring_session) -{ - return gdu_util_dialog_secret_internal (parent_window, - _("Enter Passphrase"), - NULL, - TRUE, - FALSE, - NULL, - NULL, - save_in_keyring, - save_in_keyring_session, - FALSE, - NULL); -} - -/** - * gdu_util_dialog_ask_for_secret: - * @parent_window: Parent window that dialog will be transient for or #NULL. - * @presentable: A #GduPresentable with a #GduDevice that is encrypted. - * @bypass_keyring: Set to #TRUE to bypass the keyring. - * @indicate_wrong_passphrase: Set to #TRUE to display a message that the last - * entered passphrase was wrong - * @asked_user: Whether the user was asked for the passphrase - * - * Retrieves a secret from the user or the keyring (unless - * @bypass_keyring is set to #TRUE). - * - * Returns: the secret or #NULL if the user cancelled the dialog. - **/ -char * -gdu_util_dialog_ask_for_secret (GtkWidget *parent_window, - GduPresentable *presentable, - gboolean bypass_keyring, - gboolean indicate_wrong_passphrase, - gboolean *asked_user) -{ - char *secret; - char *password; - const char *usage; - const char *uuid; - gboolean save_in_keyring; - gboolean save_in_keyring_session; - GduDevice *device; - char *window_title; - char *window_icon_name; - - window_title = NULL; - window_icon_name = NULL; - device = NULL; - secret = NULL; - save_in_keyring = FALSE; - save_in_keyring_session = FALSE; - if (asked_user != NULL) - *asked_user = FALSE; - - device = gdu_presentable_get_device (presentable); - if (device == NULL) { - g_warning ("%s: presentable has no device", __FUNCTION__); - goto out; - } - - usage = gdu_device_id_get_usage (device); - uuid = gdu_device_id_get_uuid (device); - - if (strcmp (usage, "crypto") != 0) { - g_warning ("%s: device is not a crypto device", __FUNCTION__); - goto out; - } - - if (uuid == NULL || strlen (uuid) == 0) { - g_warning ("%s: device has no UUID", __FUNCTION__); - goto out; - } - - if (!bypass_keyring) { - if (gnome_keyring_find_password_sync (&encrypted_device_password_schema, - &password, - "luks-device-uuid", uuid, - NULL) == GNOME_KEYRING_RESULT_OK) { - /* By contract, the caller is responsible for scrubbing the password - * so dupping the string into pageable memory is "fine". Or not? - */ - secret = g_strdup (password); - gnome_keyring_free_password (password); - goto out; - } - } - - if (gdu_device_is_partition (device)) { - char *s; - GduPresentable *enclosing_drive; - enclosing_drive = gdu_presentable_get_enclosing_presentable (presentable); - s = gdu_presentable_get_name (enclosing_drive); - /* todo: icon list */ - window_icon_name = gdu_presentable_get_icon_name (enclosing_drive); - g_object_unref (enclosing_drive); - window_title = g_strdup_printf (_("Partition %d on %s"), - gdu_device_partition_get_number (device), - s); - g_free (s); - } else { - window_title = gdu_presentable_get_name (presentable); - window_icon_name = gdu_presentable_get_icon_name (presentable); - } - - secret = gdu_util_dialog_secret_internal (parent_window, - window_title, - window_icon_name, - FALSE, - FALSE, - NULL, - NULL, - &save_in_keyring, - &save_in_keyring_session, - indicate_wrong_passphrase, - device); - - if (asked_user != NULL) - *asked_user = TRUE; - - if (secret != NULL && (save_in_keyring || save_in_keyring_session)) { - const char *keyring; - - keyring = NULL; - if (save_in_keyring_session) - keyring = GNOME_KEYRING_SESSION; - - if (gnome_keyring_store_password_sync (&encrypted_device_password_schema, - keyring, - _("Encrypted Disk Passphrase"), - secret, - "luks-device-uuid", uuid, - NULL) != GNOME_KEYRING_RESULT_OK) { - g_warning ("%s: couldn't store passphrase in keyring", __FUNCTION__); - } - } - -out: - if (device != NULL) - g_object_unref (device); - g_free (window_title); - g_free (window_icon_name); - return secret; -} - -/** - * gdu_util_dialog_change_secret: - * @parent_window: Parent window that dialog will be transient for or #NULL. - * @presentable: A #GduPresentable with a #GduDevice that is encrypted. - * @old_secret: Return location for old secret. - * @new_secret: Return location for new secret. - * @save_in_keyring: Return location for whether the new secret should be saved in the keyring. - * @save_in_keyring_session: Return location for whether the new secret should be saved in the session keyring. - * @bypass_keyring: Set to #TRUE to bypass the keyring. - * - * Asks the user to change his secret. The secret in the keyring is - * not updated; that needs to be done manually using the functions - * gdu_util_delete_secret() and gdu_util_save_secret(). - * - * Returns: #TRUE if the user agreed to change the secret. - **/ -gboolean -gdu_util_dialog_change_secret (GtkWidget *parent_window, - GduPresentable *presentable, - char **old_secret, - char **new_secret, - gboolean *save_in_keyring, - gboolean *save_in_keyring_session, - gboolean bypass_keyring, - gboolean indicate_wrong_passphrase) -{ - char *password; - const char *usage; - const char *uuid; - gboolean ret; - char *old_secret_from_keyring; - char *window_title; - char *window_icon_name; - GduDevice *device; - - window_title = NULL; - window_icon_name = NULL; - device = NULL; - *old_secret = NULL; - *new_secret = NULL; - old_secret_from_keyring = NULL; - ret = FALSE; - - device = gdu_presentable_get_device (presentable); - if (device == NULL) { - g_warning ("%s: presentable has no device", __FUNCTION__); - goto out; - } - - usage = gdu_device_id_get_usage (device); - uuid = gdu_device_id_get_uuid (device); - - if (strcmp (usage, "crypto") != 0) { - g_warning ("%s: device is not a crypto device", __FUNCTION__); - goto out; - } - - if (uuid == NULL || strlen (uuid) == 0) { - g_warning ("%s: device has no UUID", __FUNCTION__); - goto out; - } - - if (!bypass_keyring) { - if (gnome_keyring_find_password_sync (&encrypted_device_password_schema, - &password, - "luks-device-uuid", uuid, - NULL) == GNOME_KEYRING_RESULT_OK) { - /* By contract, the caller is responsible for scrubbing the password - * so dupping the string into pageable memory "fine". Or not? - */ - old_secret_from_keyring = g_strdup (password); - gnome_keyring_free_password (password); - } - } - - if (gdu_device_is_partition (device)) { - char *s; - GduPresentable *enclosing_drive; - enclosing_drive = gdu_presentable_get_enclosing_presentable (presentable); - s = gdu_presentable_get_name (enclosing_drive); - /* todo: icon list */ - window_icon_name = gdu_presentable_get_icon_name (enclosing_drive); - g_object_unref (enclosing_drive); - window_title = g_strdup_printf (_("Partition %d on %s"), - gdu_device_partition_get_number (device), - s); - g_free (s); - } else { - window_title = gdu_presentable_get_name (presentable); - window_icon_name = gdu_presentable_get_icon_name (presentable); - } - - *new_secret = gdu_util_dialog_secret_internal (parent_window, - window_title, - window_icon_name, - FALSE, - TRUE, - old_secret_from_keyring, - old_secret, - save_in_keyring, - save_in_keyring_session, - indicate_wrong_passphrase, - device); - - if (old_secret_from_keyring != NULL) { - memset (old_secret_from_keyring, '\0', strlen (old_secret_from_keyring)); - g_free (old_secret_from_keyring); - } - - if (*new_secret == NULL) - goto out; - - ret = TRUE; - -out: - if (!ret) { - if (*old_secret != NULL) { - memset (*old_secret, '\0', strlen (*old_secret)); - g_free (*old_secret); - *old_secret = NULL; - } - if (*new_secret != NULL) { - memset (*new_secret, '\0', strlen (*new_secret)); - g_free (*new_secret); - *new_secret = NULL; - } - } - - g_free (window_title); - g_free (window_icon_name); - if (device != NULL) - g_object_unref (device); - return ret; -} - gboolean gdu_util_have_secret (GduDevice *device) { @@ -1804,579 +694,3 @@ gdu_util_get_connection_for_display (const char *connection_interface, guint64 c } /* ---------------------------------------------------------------------------------------------------- */ - -/** - * gdu_util_delete_confirmation_dialog: - * @parent_window: parent window for transient dialog - * @title: the title of the dialog - * @primary_text: primary text - * @secondary_text: secondary text - * @affirmative_action_button_mnemonic: text to use on the affirmative action button - * - * Utility to show a confirmation dialog for deletion that includes a - * combo box for secure erase options. - * - * Returns: #NULL if the user canceled, otherwise the secure erase - * type. Must be freed by the caller. - **/ -char * -gdu_util_delete_confirmation_dialog (GtkWidget *parent_window, - const char *title, - const char *primary_text, - const char *secondary_text, - const char *affirmative_action_button_mnemonic) -{ - int response; - GtkWidget *dialog; - char *secure_erase; - GtkWidget *hbox; - GtkWidget *image; - GtkWidget *main_vbox; - GtkWidget *label; - int row; - GtkWidget *combo_box; - GtkWidget *table; - - secure_erase = NULL; - - dialog = gtk_dialog_new_with_buttons (title, - GTK_WINDOW (parent_window), - GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT|GTK_DIALOG_NO_SEPARATOR, - NULL); - - gtk_container_set_border_width (GTK_CONTAINER (dialog), 5); - gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 2); - gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area), 5); - gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->action_area), 6); - gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE); - - hbox = gtk_hbox_new (FALSE, 12); - gtk_container_set_border_width (GTK_CONTAINER (hbox), 5); - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), hbox, TRUE, TRUE, 0); - - image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_DIALOG); - gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.0); - gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0); - - main_vbox = gtk_vbox_new (FALSE, 10); - gtk_box_pack_start (GTK_BOX (hbox), main_vbox, TRUE, TRUE, 0); - - label = gtk_label_new (NULL); - gtk_label_set_markup (GTK_LABEL (label), primary_text); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); - gtk_box_pack_start (GTK_BOX (main_vbox), GTK_WIDGET (label), FALSE, FALSE, 0); - - label = gtk_label_new (NULL); - gtk_label_set_markup (GTK_LABEL (label), secondary_text); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); - gtk_box_pack_start (GTK_BOX (main_vbox), GTK_WIDGET (label), FALSE, FALSE, 0); - - row = 0; - - table = gtk_table_new (2, 2, FALSE); - gtk_box_pack_start (GTK_BOX (main_vbox), table, FALSE, FALSE, 0); - - /* secure erase */ - label = gtk_label_new (NULL); - gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5); - gtk_label_set_markup_with_mnemonic (GTK_LABEL (label), _("_Erase:")); - gtk_table_attach (GTK_TABLE (table), label, 0, 1, row, row + 1, - GTK_FILL, GTK_EXPAND | GTK_FILL, 2, 2); - combo_box = gdu_util_secure_erase_combo_box_create (); - gtk_table_attach (GTK_TABLE (table), combo_box, 1, 2, row, row + 1, - GTK_FILL, GTK_EXPAND | GTK_FILL, 2, 2); - gtk_label_set_mnemonic_widget (GTK_LABEL (label), combo_box); - - row++; - - /* secure erase desc */ - label = gtk_label_new (NULL); - gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); - gtk_label_set_width_chars (GTK_LABEL (label), 40); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_table_attach (GTK_TABLE (table), label, 1, 2, row, row + 1, - GTK_FILL, GTK_EXPAND | GTK_FILL, 2, 2); - gdu_util_secure_erase_combo_box_set_desc_label (combo_box, label); - - row++; - - gtk_widget_grab_focus (gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL)); - gtk_dialog_add_button (GTK_DIALOG (dialog), affirmative_action_button_mnemonic, 0); - - gtk_widget_show_all (dialog); - response = gtk_dialog_run (GTK_DIALOG (dialog)); - - secure_erase = gdu_util_secure_erase_combo_box_get_selected (combo_box); - - gtk_widget_destroy (dialog); - if (response != 0) { - g_free (secure_erase); - secure_erase = NULL; - goto out; - } - -out: - return secure_erase; -} - -/* ---------------------------------------------------------------------------------------------------- */ - -GdkPixbuf * -gdu_util_get_pixbuf_for_presentable (GduPresentable *presentable, GtkIconSize size) -{ - char *icon_name; - GdkPixbuf *pixbuf; - - icon_name = gdu_presentable_get_icon_name (presentable); - - pixbuf = NULL; - if (icon_name != NULL) { - int icon_width, icon_height; - - if (!gtk_icon_size_lookup (size, &icon_width, &icon_height)) - icon_height = 48; - - pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), - icon_name, - icon_height, - GTK_ICON_LOOKUP_GENERIC_FALLBACK, - NULL); - - /* if it's unallocated or unrecognized space, make the icon greyscale */ - if (!gdu_presentable_is_allocated (presentable) || - !gdu_presentable_is_recognized (presentable)) { - GdkPixbuf *pixbuf2; - pixbuf2 = pixbuf; - pixbuf = gdk_pixbuf_copy (pixbuf); - g_object_unref (pixbuf2); - gdk_pixbuf_saturate_and_pixelate (pixbuf, - pixbuf, - 0.0, - FALSE); - } - } - - g_free (icon_name); - - return pixbuf; -} - -/* ---------------------------------------------------------------------------------------------------- */ - -static int -_get_icon_size_for_stock_size (GtkIconSize size) -{ - int w, h; - if (gtk_icon_size_lookup (size, &w, &h)) { - return MAX (w, h); - } else { - return 24; - } -} - -static GdkPixbuf * -get_pixbuf_for_icon (GIcon *icon) -{ - GdkPixbuf *pixbuf; - - pixbuf = NULL; - - if (G_IS_FILE_ICON (icon)) { - char *filename; - filename = g_file_get_path (g_file_icon_get_file (G_FILE_ICON (icon))); - if (filename != NULL) { - pixbuf = gdk_pixbuf_new_from_file_at_size (filename, 24, 24, NULL); - g_free (filename); - } - - } else if (G_IS_THEMED_ICON (icon)) { - const char * const *names; - char *icon_no_extension; - char *p; - - names = g_themed_icon_get_names (G_THEMED_ICON (icon)); - - if (names != NULL && names[0] != NULL) { - icon_no_extension = g_strdup (names[0]); - p = strrchr (icon_no_extension, '.'); - if (p != NULL) - *p = '\0'; - pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), - icon_no_extension, 24, 0, NULL); - g_free (icon_no_extension); - } - } - - return pixbuf; -} - -typedef struct { - GduDevice *device; - - GtkWidget *tree_view; - GtkWidget *dialog; -} ShowBusyData; - -static ShowBusyData * -show_busy_data_new (GduDevice *device) -{ - ShowBusyData *data; - data = g_new0 (ShowBusyData, 1); - data->device = g_object_ref (device); - return data; -} - -static void -show_busy_data_free (ShowBusyData *data) -{ - g_object_unref (data->device); - g_free (data); -} - -static int -process_compare (GduProcess *a, GduProcess *b) -{ - return gdu_process_get_id (a) - gdu_process_get_id (b); -} - -static GtkListStore * -show_busy_get_list_store (ShowBusyData *data, int *num_rows) -{ - GtkListStore *store; - GtkTreeIter iter; - GList *processes; - GError *error; - GList *l; - - if (num_rows != NULL) - *num_rows = 0; - - store = gtk_list_store_new (3, GDK_TYPE_PIXBUF, G_TYPE_STRING, GDU_TYPE_PROCESS); - error = NULL; - processes = gdu_device_filesystem_list_open_files_sync (data->device, &error); - if (error != NULL) { - g_warning ("error retrieving list of open files: %s", error->message); - g_error_free (error); - } - processes = g_list_sort (processes, (GCompareFunc) process_compare); - for (l = processes; l != NULL; l = l->next) { - GduProcess *process = GDU_PROCESS (l->data); - char *name; - char *markup; - GAppInfo *app_info; - GdkPixbuf *pixbuf; - - name = NULL; - - app_info = gdu_process_get_app_info (process); - pixbuf = NULL; - if (app_info != NULL) { - GIcon *icon; - - name = g_strdup (g_app_info_get_name (app_info)); - icon = g_app_info_get_icon (app_info); - if (icon != NULL) { - pixbuf = get_pixbuf_for_icon (icon); - } - } else { - const char *command_line; - - command_line = gdu_process_get_command_line (process); - - if (command_line != NULL) { - char *basename; - char *s; - int n; - - for (n = 0; command_line[n] != '\0'; n++) { - if (command_line[n] == ' ') - break; - } - s = g_strndup (command_line, n); - basename = g_path_get_basename (s); - g_free (s); - - /* special handling for common programs without desktop files */ - if (strcmp (basename, "bash") == 0 || - strcmp (basename, "-bash") == 0) { - name = g_strdup (_("Bourne Again Shell")); - pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), - "terminal", 24, 0, NULL); - } else if (strcmp (basename, "sh") == 0 || - strcmp (basename, "-sh") == 0) { - name = g_strdup (_("Bourne Shell")); - pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), - "terminal", 24, 0, NULL); - } else if (strcmp (basename, "csh") == 0 || - strcmp (basename, "-csh") == 0) { - name = g_strdup (_("C Shell")); - pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), - "terminal", 24, 0, NULL); - } else if (strcmp (basename, "tcsh") == 0 || - strcmp (basename, "-tcsh") == 0) { - name = g_strdup (_("TENEX C Shell")); - pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), - "terminal", 24, 0, NULL); - } else if (strcmp (basename, "zsh") == 0 || - strcmp (basename, "-zsh") == 0) { - name = g_strdup (_("Z Shell")); - pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), - "terminal", 24, 0, NULL); - } else if (strcmp (basename, "ksh") == 0 || - strcmp (basename, "-ksh") == 0) { - name = g_strdup (_("Korn Shell")); - pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), - "terminal", 24, 0, NULL); - } else if (strcmp (basename, "top") == 0) { - name = g_strdup (_("Process Viewer (top)")); - pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), - GTK_STOCK_GOTO_TOP, 24, 0, NULL); - } else if (strcmp (basename, "less") == 0) { - name = g_strdup (_("Terminal Pager (less)")); - pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), - GTK_STOCK_FILE, 24, 0, NULL); - } - - if (name != NULL) { - } else { - name = g_strdup (basename); - } - - g_free (basename); - } else { - name = g_strdup (_("Unknown")); - } - } - - /* fall back to generic icon */ - if (pixbuf == NULL) { - pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), - "application-x-executable", 24, 0, NULL); - } - - if (gdu_process_get_owner (process) != getuid ()) { - markup = g_strdup_printf (_("<b>%s</b>\n" - "<small>uid %d, pid %d: %s</small>"), - name, - gdu_process_get_owner (process), - gdu_process_get_id (process), - gdu_process_get_command_line (process)); - } else { - markup = g_strdup_printf (_("<b>%s</b>\n" - "<small>pid %d: %s</small>"), - name, - gdu_process_get_id (process), - gdu_process_get_command_line (process)); - } - - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, - 0, pixbuf, - 1, markup, - 2, process, - -1); - - if (num_rows != NULL) - *num_rows = (*num_rows) + 1; - - g_free (markup); - g_free (name); - if (app_info != NULL) - g_object_unref (app_info); - if (pixbuf != NULL) - g_object_unref (pixbuf); - } - g_list_foreach (processes, (GFunc) g_object_unref, NULL); - g_list_free (processes); - - return store; -} - -static gboolean -show_busy_timeout (gpointer user_data) -{ - ShowBusyData *data = user_data; - GtkListStore *store; - int num_rows; - - store = show_busy_get_list_store (data, &num_rows); - gtk_tree_view_set_model (GTK_TREE_VIEW (data->tree_view), GTK_TREE_MODEL (store)); - gtk_dialog_set_response_sensitive (GTK_DIALOG (data->dialog), 1, num_rows == 0); - g_object_unref (store); - - return TRUE; -} - -gboolean -gdu_util_dialog_show_filesystem_busy (GtkWidget *parent_window, - GduPresentable *presentable) -{ - gboolean ret; - GduDevice *device; - char *window_title; - char *window_icon_name; - GtkWidget *dialog; - GtkWidget *hbox; - GtkWidget *main_vbox; - GtkWidget *label; - GtkWidget *image; - int response; - GtkListStore *store; - GtkWidget *tree_view; - GtkCellRenderer *renderer; - GtkTreeViewColumn *column; - GtkWidget *scrolled_window; - GtkWidget *unmount_button; - GtkWidget *unmount_image; - GdkPixbuf *pixbuf; - ShowBusyData *data; - guint refresh_timer_id; - - ret = FALSE; - window_title = NULL; - window_icon_name = NULL; - device = NULL; - dialog = NULL; - data = NULL; - refresh_timer_id = 0; - - device = gdu_presentable_get_device (presentable); - if (device == NULL) { - g_warning ("%s: presentable has no device", __FUNCTION__); - goto out; - } - - data = show_busy_data_new (device); - - if (gdu_device_is_partition (device)) { - char *s; - GduPresentable *enclosing_drive; - enclosing_drive = gdu_presentable_get_enclosing_presentable (presentable); - s = gdu_presentable_get_name (enclosing_drive); - /* todo: icon list */ - window_icon_name = gdu_presentable_get_icon_name (enclosing_drive); - g_object_unref (enclosing_drive); - window_title = g_strdup_printf (_("Partition %d on %s"), - gdu_device_partition_get_number (device), - s); - g_free (s); - } else { - window_title = gdu_presentable_get_name (presentable); - window_icon_name = gdu_presentable_get_icon_name (presentable); - } - - dialog = gtk_dialog_new_with_buttons (window_title, - GTK_WINDOW (parent_window), - GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT|GTK_DIALOG_NO_SEPARATOR, - NULL); - - gtk_container_set_border_width (GTK_CONTAINER (dialog), 5); - gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 2); - gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area), 5); - gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->action_area), 6); - gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE); - gtk_window_set_icon_name (GTK_WINDOW (dialog), window_icon_name); - - hbox = gtk_hbox_new (FALSE, 12); - gtk_container_set_border_width (GTK_CONTAINER (hbox), 5); - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), hbox, TRUE, TRUE, 0); - - image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_ERROR, GTK_ICON_SIZE_DIALOG); - gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.0); - gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0); - - main_vbox = gtk_vbox_new (FALSE, 10); - gtk_box_pack_start (GTK_BOX (hbox), main_vbox, TRUE, TRUE, 0); - - /* main message */ - label = gtk_label_new (NULL); - gtk_label_set_markup (GTK_LABEL (label), - _("<b><big>Cannot unmount volume</big></b>")); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); - gtk_box_pack_start (GTK_BOX (main_vbox), GTK_WIDGET (label), FALSE, FALSE, 0); - - /* secondary message */ - label = gtk_label_new (NULL); - gtk_label_set_markup (GTK_LABEL (label), _("One or more applications are using the volume. " - "Quit the applications, and then try unmounting again.")); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); - gtk_box_pack_start (GTK_BOX (main_vbox), GTK_WIDGET (label), FALSE, FALSE, 0); - - - store = show_busy_get_list_store (data, NULL); - tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store)); - gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)), - GTK_SELECTION_NONE); - data->dialog = dialog; - data->tree_view = tree_view; - g_object_unref (store); - - column = gtk_tree_view_column_new (); - renderer = gtk_cell_renderer_pixbuf_new (); - gtk_tree_view_column_pack_start (column, renderer, FALSE); - gtk_tree_view_column_set_attributes (column, renderer, - "pixbuf", 0, - NULL); - renderer = gtk_cell_renderer_text_new (); - gtk_tree_view_column_pack_start (column, renderer, TRUE); - gtk_tree_view_column_set_attributes (column, renderer, - "markup", 1, - NULL); - gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column); - gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (tree_view), FALSE); - - scrolled_window = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), - GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window), GTK_SHADOW_IN); - - gtk_container_add (GTK_CONTAINER (scrolled_window), tree_view); - gtk_box_pack_start (GTK_BOX (main_vbox), scrolled_window, TRUE, TRUE, 0); - - GtkWidget *cancel_button; - cancel_button = gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); - gtk_widget_grab_focus (cancel_button); - - unmount_button = gtk_button_new_with_mnemonic (_("_Unmount")); - pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), - "gdu-unmount", - _get_icon_size_for_stock_size (GTK_ICON_SIZE_BUTTON), - 0, - NULL); - unmount_image = gtk_image_new_from_pixbuf (pixbuf); - g_object_unref (pixbuf); - gtk_button_set_image (GTK_BUTTON (unmount_button), unmount_image); - gtk_dialog_add_action_widget (GTK_DIALOG (dialog), - unmount_button, - 1); - - /* refresh list of open files every one second... */ - refresh_timer_id = g_timeout_add_seconds (1, show_busy_timeout, data); - - gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), 1, FALSE); - - gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE); - gtk_window_set_default_size (GTK_WINDOW (dialog), -1, 280); - gtk_widget_show_all (dialog); - response = gtk_dialog_run (GTK_DIALOG (dialog)); - if (response == 1) - ret = TRUE; - -out: - if (refresh_timer_id > 0) - g_source_remove (refresh_timer_id); - - g_free (window_title); - g_free (window_icon_name); - if (device != NULL) - g_object_unref (device); - if (dialog != NULL) - gtk_widget_destroy (dialog); - if (data != NULL) - show_busy_data_free (data); - return ret; -} diff --git a/src/gdu-util.h b/src/gdu-util.h index e9a71e7..e165376 100644 --- a/src/gdu-util.h +++ b/src/gdu-util.h @@ -19,7 +19,6 @@ * USA */ -#include <gtk/gtk.h> #include "gdu-presentable.h" #include "gdu-pool.h" @@ -29,6 +28,12 @@ char *gdu_util_get_size_for_display (guint64 size, gboolean long_string); char *gdu_util_get_fstype_for_display (const char *fstype, const char *fsversion, gboolean long_string); +char *gdu_util_fstype_get_description (char *fstype); + +char *gdu_util_part_table_type_get_description (char *part_type); + +char *gdu_util_secure_erase_get_description (char *secure_erase_type); + char *gdu_util_get_speed_for_display (guint64 size); char *gdu_util_get_connection_for_display (const char *connection_interface, guint64 connection_speed); @@ -38,29 +43,12 @@ char *gdu_util_get_desc_for_part_type (const char *part_scheme, const char *part char *gdu_get_job_description (const char *job_id); char *gdu_get_task_description (const char *task_id); -/* ---------------------------------------------------------------------------------------------------- */ +typedef void (*GduUtilPartTypeForeachFunc) (const char *scheme, + const char *type, + const char *name, + gpointer user_data); -GtkWidget *gdu_util_fstype_combo_box_create (GduPool *pool, - const char *include_extended_partitions_for_scheme); -void gdu_util_fstype_combo_box_rebuild (GtkWidget *combo_box, - GduPool *pool, - const char *include_extended_partitions_for_scheme); -void gdu_util_fstype_combo_box_set_desc_label (GtkWidget *combo_box, GtkWidget *desc_label); -gboolean gdu_util_fstype_combo_box_select (GtkWidget *combo_box, - const char *fstype); -char *gdu_util_fstype_combo_box_get_selected (GtkWidget *combo_box); - -/* ---------------------------------------------------------------------------------------------------- */ - -GtkWidget *gdu_util_secure_erase_combo_box_create (void); -void gdu_util_secure_erase_combo_box_set_desc_label (GtkWidget *combo_box, GtkWidget *desc_label); -char *gdu_util_secure_erase_combo_box_get_selected (GtkWidget *combo_box); - -char *gdu_util_delete_confirmation_dialog (GtkWidget *parent_window, - const char *title, - const char *primary_text, - const char *secondary_text, - const char *affirmative_action_button_mnemonic); +void gdu_util_part_type_foreach (GduUtilPartTypeForeachFunc callback, gpointer user_data); /* ---------------------------------------------------------------------------------------------------- */ @@ -68,42 +56,6 @@ char *gdu_util_get_default_part_type_for_scheme_and_fstype (const char *sch /* ---------------------------------------------------------------------------------------------------- */ -GtkWidget *gdu_util_part_type_combo_box_create (const char *part_scheme); -void gdu_util_part_type_combo_box_rebuild (GtkWidget *combo_box, - const char *part_scheme); -gboolean gdu_util_part_type_combo_box_select (GtkWidget *combo_box, - const char *part_type); -char *gdu_util_part_type_combo_box_get_selected (GtkWidget *combo_box); - -/* ---------------------------------------------------------------------------------------------------- */ - -GtkWidget *gdu_util_part_table_type_combo_box_create (void); -void gdu_util_part_table_type_combo_box_set_desc_label (GtkWidget *combo_box, GtkWidget *desc_label); -gboolean gdu_util_part_table_type_combo_box_select (GtkWidget *combo_box, - const char *part_table_type); -char *gdu_util_part_table_type_combo_box_get_selected (GtkWidget *combo_box); - -/* ---------------------------------------------------------------------------------------------------- */ - -char *gdu_util_dialog_ask_for_secret (GtkWidget *parent_window, - GduPresentable *presentable, - gboolean bypass_keyring, - gboolean indicate_wrong_passphrase, - gboolean *asked_user); - -gboolean gdu_util_dialog_change_secret (GtkWidget *parent_window, - GduPresentable *presentable, - char **old_secret, - char **new_secret, - gboolean *save_in_keyring, - gboolean *save_in_keyring_session, - gboolean bypass_keyring, - gboolean indicate_wrong_passphrase); - -char *gdu_util_dialog_ask_for_new_secret (GtkWidget *parent_window, - gboolean *save_in_keyring, - gboolean *save_in_keyring_session); - gboolean gdu_util_save_secret (GduDevice *device, const char *secret, gboolean save_in_keyring_session); @@ -112,8 +64,4 @@ gboolean gdu_util_delete_secret (GduDevice *device); gboolean gdu_util_have_secret (GduDevice *device); -GdkPixbuf *gdu_util_get_pixbuf_for_presentable (GduPresentable *presentable, GtkIconSize size); - -gboolean gdu_util_dialog_show_filesystem_busy (GtkWidget *parent_window, GduPresentable *presentable); - #endif /* GDU_UTIL_H */ |
