diff --git a/src/keymanager.c b/src/keymanager.c index 666e725..e05d6b8 100644 --- a/src/keymanager.c +++ b/src/keymanager.c @@ -1,1681 +1,2183 @@ /* keymanager.c - The Key Manager. * Copyright (C) 2000, 2001 G-N-U GmbH. * Copyright (C) 2005, 2008, 2009 g10 Code GmbH. * * This file is part of GPA. * * GPA 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 3 of the License, or * (at your option) any later version. * * GPA 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, see . */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include "gpa.h" #include "gtktools.h" #include "icons.h" #include "helpmenu.h" #include "gpawidgets.h" #include "ownertrustdlg.h" #include "keysigndlg.h" #include "keygendlg.h" #include "keygenwizard.h" #include "keyeditdlg.h" #include "keydeletedlg.h" #include "keylist.h" #include "siglist.h" #include "gpgmetools.h" #include "gpgmeedit.h" #include "keytable.h" #include "server-access.h" #include "options.h" #include "convert.h" #include "gpasubkeylist.h" #include "gpakeydeleteop.h" #include "gpakeysignop.h" #include "gpakeytrustop.h" #include "gpaexportfileop.h" #include "gpaexportclipop.h" #include "gpaexportserverop.h" #include "gpaimportfileop.h" #include "gpaimportclipop.h" #include "gpaimportserverop.h" #include "gpaimportbykeyidop.h" #include "gpabackupop.h" #include "gpagenkeyadvop.h" #include "gpagenkeysimpleop.h" #include "gpa-key-details.h" #include "keymanager.h" #if ! GTK_CHECK_VERSION (2, 10, 0) #define GTK_STOCK_SELECT_ALL "gtk-select-all" #endif /* Object's class definition. */ struct _GpaKeyManagerClass { GtkWindowClass parent_class; }; /* Object definition. */ struct _GpaKeyManager { GtkWindow parent_instance; /* The central list of keys. */ GpaKeyList *keylist; /* The "Show Ownertrust" toggle button. */ GtkWidget *toggle_show; /* The details widget. */ GtkWidget *details; /* Idle handler id for updates of the details widget. Will be nonzero whenever a handler is currently set and zero otherwise. */ guint details_idle_id; /* Labels in the status bar. */ GtkWidget *status_label; GtkWidget *status_key_user; GtkWidget *status_key_id; /* The popup menu. */ GtkWidget *popup_menu; /* List of sensitive widgets. See below. */ GList *selection_sensitive_actions; /* The currently selected key. */ gpgme_key_t current_key; /* Context used for retrieving the current key. */ GpaContext *ctx; /* Hack: warn the selection callback to ignore changes. Don't, ever, assign a value directly. Raise and lower it with increments. */ int freeze_selection; }; /* There is only one instance of the card manager class. Use a global variable to keep track of it. */ static GpaKeyManager *this_instance; /* Prototype of a sensitivity callback. Return TRUE if the widget should be sensitive, FALSE otherwise. The parameter is a pointer to the instance. */ typedef gboolean (*sensitivity_func_t) (gpointer); /* Local prototypes */ static int idle_update_details (gpointer param); static void keyring_update_details (GpaKeyManager *self); static void gpa_key_manager_finalize (GObject *object); /************************************************************ ******************* Implementation ********************* ************************************************************/ /* A simple sensitivity callback mechanism. The basic idea is that buttons (and other widgets like menu items as well) should know when they should be sensitive or not. The implementation here is very simple and quite specific for the key manager's needs. We maintain a list of sensitive widgets each of which has a sensitivity callback associated with them as the "gpa_sensitivity" data. The callback returns TRUE when the widget should be sensitive and FALSE otherwise. Whenever the selection in the key list widget changes we call update_selection_sensitive_actions which iterates through the widgets in the list, calls the sensitivity callback and changes the widget's sensitivity accordingly. */ /* Add widget to the list of sensitive widgets of editor. */ static void add_selection_sensitive_action (GpaKeyManager *self, GtkAction *action, sensitivity_func_t callback) { g_object_set_data (G_OBJECT (action), "gpa_sensitivity", callback); self->selection_sensitive_actions = g_list_append (self->selection_sensitive_actions, action); } /* Update the sensitivity of the widget data and pass param through to the sensitivity callback. Usable as iterator function in g_list_foreach. */ static void update_selection_sensitive_action (gpointer data, gpointer param) { sensitivity_func_t func; func = g_object_get_data (G_OBJECT (data), "gpa_sensitivity"); gtk_action_set_sensitive (GTK_ACTION (data), func (param)); } /* Call update_selection_sensitive_widget for all widgets in the list of sensitive widgets and pass self through as the user data parameter. */ static void update_selection_sensitive_actions (GpaKeyManager *self) { g_list_foreach (self->selection_sensitive_actions, update_selection_sensitive_action, self); } /* Disable all the widgets in the list of sensitive widgets. To be used while the selection changes. */ static void disable_selection_sensitive_actions (GpaKeyManager *self) { GList *cur; cur = self->selection_sensitive_actions; while (cur) { gtk_action_set_sensitive (GTK_ACTION (cur->data), FALSE); cur = g_list_next (cur); } } /* Helper functions to cope with selections. */ /* Return TRUE if the key list widget of the key manager has at least one selected item. Usable as a sensitivity callback. */ static gboolean key_manager_has_selection (gpointer param) { GpaKeyManager *self = param; return gpa_keylist_has_selection (self->keylist); } /* Return TRUE if the key list widget of the key manager has exactly one selected item. Usable as a sensitivity callback. */ static gboolean key_manager_has_single_selection (gpointer param) { GpaKeyManager *self = param; return gpa_keylist_has_single_selection (self->keylist); } /* Return TRUE if the key list widget of the key manager has exactly one selected OpenPGP item. Usable as a sensitivity callback. */ static gboolean key_manager_has_single_selection_OpenPGP (gpointer param) { GpaKeyManager *self = param; int result = 0; if (gpa_keylist_has_single_selection (self->keylist)) { gpgme_key_t key = gpa_keylist_get_selected_key (self->keylist); if (key && key->protocol == GPGME_PROTOCOL_OpenPGP) result = 1; gpgme_key_unref (key); } return result; } /* Return TRUE if the key list widget of the key manager has exactly one selected item and it is a private key. Usable as a sensitivity callback. */ static gboolean key_manager_has_private_selected (gpointer param) { GpaKeyManager *self = param; return gpa_keylist_has_single_secret_selection (GPA_KEYLIST(self->keylist)); } /* Return the the currently selected key. NULL if no key is selected. */ static gpgme_key_t key_manager_current_key (GpaKeyManager *self) { return self->current_key; } /* Action callbacks. */ static void gpa_key_manager_changed_wot_cb (gpointer data) { GpaKeyManager *self = data; gpa_keylist_start_reload (self->keylist); } static void gpa_key_manager_changed_wot_secret_cb (gpointer data) { GpaKeyManager *self = data; gpa_keylist_imported_secret_key (self->keylist); gpa_keylist_start_reload (self->keylist); } static void gpa_key_manager_key_modified (GpaKeyEditDialog *dialog, gpgme_key_t key, gpointer data) { GpaKeyManager *self = data; gpa_keylist_start_reload (self->keylist); } static void gpa_key_manager_new_key_cb (gpointer data, const gchar *fpr) { GpaKeyManager *self = data; gpa_keylist_new_key (GPA_KEYLIST (self->keylist), fpr); gpa_options_update_default_key (gpa_options_get_instance ()); } static void register_key_operation (GpaKeyManager *self, GpaKeyOperation *op) { g_signal_connect_swapped (G_OBJECT (op), "changed_wot", G_CALLBACK (gpa_key_manager_changed_wot_cb), self); g_signal_connect (G_OBJECT (op), "completed", G_CALLBACK (g_object_unref), self); } static void register_import_operation (GpaKeyManager *self, GpaImportOperation *op) { g_signal_connect_swapped (G_OBJECT (op), "imported_keys", G_CALLBACK (gpa_key_manager_changed_wot_cb), self); g_signal_connect_swapped (G_OBJECT (op), "imported_secret_keys", G_CALLBACK (gpa_key_manager_changed_wot_secret_cb), self); g_signal_connect (G_OBJECT (op), "completed", G_CALLBACK (g_object_unref), self); } static void register_generate_operation (GpaKeyManager *self, GpaGenKeyOperation *op) { g_signal_connect_swapped (G_OBJECT (op), "generated_key", G_CALLBACK (gpa_key_manager_new_key_cb), self); g_signal_connect (G_OBJECT (op), "completed", G_CALLBACK (g_object_unref), self); } static void register_operation (GpaKeyManager *self, GpaOperation *op) { g_signal_connect (G_OBJECT (op), "completed", G_CALLBACK (g_object_unref), self); } /* delete the selected keys */ static void key_manager_delete (GtkAction *action, GpaKeyManager *self) { GList *selection = gpa_keylist_get_selected_keys (self->keylist, GPGME_PROTOCOL_UNKNOWN); GpaKeyDeleteOperation *op = gpa_key_delete_operation_new (GTK_WIDGET (self), selection); register_key_operation (self, GPA_KEY_OPERATION (op)); } /* Return true if the public key key has been signed by the key with the id key_id, otherwise return FALSE. */ static gboolean key_has_been_signed (const gpgme_key_t key, const gpgme_key_t signer_key) { gboolean uid_signed, key_signed; const char *signer_id; gpgme_key_sig_t sig; gpgme_user_id_t uid; signer_id = signer_key->subkeys->keyid; /* We consider the key signed if all user IDs have been signed. */ key_signed = TRUE; for (uid = key->uids; key_signed && uid; uid = uid->next) { uid_signed = FALSE; for (sig = uid->signatures; !uid_signed && sig; sig = sig->next) if (g_str_equal (signer_id, sig->keyid)) uid_signed = TRUE; key_signed = key_signed && uid_signed; } return key_signed; } /* Return true if the key sign button should be sensitive, i.e. if there is at least one selected key and there is a default key. */ static gboolean key_manager_can_sign (gpointer param) { gboolean result = FALSE; gpgme_key_t default_key; default_key = gpa_options_get_default_key (gpa_options_get_instance ()); if (default_key && key_manager_has_single_selection (param)) { /* The most important requirements have been met, now check if the selected key was already signed with the default key. */ GpaKeyManager *self = param; gpgme_key_t key = key_manager_current_key (self); if (key->protocol == GPGME_PROTOCOL_OpenPGP) result = ! key_has_been_signed (key, default_key); } else if (default_key && key_manager_has_selection (param)) /* Always allow signing many keys at once. */ result = TRUE; return result; } /* sign the selected keys */ static void key_manager_sign (GtkAction *action, gpointer param) { GpaKeyManager *self = param; GList *selection; GpaKeySignOperation *op; if (! gpa_keylist_has_selection (self->keylist)) { /* This shouldn't happen because the button should be grayed out in this case. */ gpa_window_error (_("No keys selected for signing."), GTK_WIDGET (self)); return; } selection = gpa_keylist_get_selected_keys (self->keylist, GPGME_PROTOCOL_OpenPGP); if (selection) { op = gpa_key_sign_operation_new (GTK_WIDGET (self), selection); register_key_operation (self, GPA_KEY_OPERATION (op)); } } /* Invoke the "edit key" dialog. */ static void key_manager_edit (GtkAction *action, gpointer param) { GpaKeyManager *self = param; gpgme_key_t key; GtkWidget *dialog; if (! key_manager_has_private_selected (self)) return; key = key_manager_current_key (self); if (! key) return; dialog = gpa_key_edit_dialog_new (GTK_WIDGET (self), key); gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE); g_signal_connect (G_OBJECT (dialog), "key_modified", G_CALLBACK (gpa_key_manager_key_modified), self); gtk_widget_show_all (dialog); } static void key_manager_trust (GtkAction *action, gpointer param) { GpaKeyManager *self = param; GList *selection; GpaKeyTrustOperation *op; /* FIXME: Key trust operation currently does not support more than one key at a time. */ if (! key_manager_has_single_selection (self)) return; selection = gpa_keylist_get_selected_keys (self->keylist, GPGME_PROTOCOL_OpenPGP); if (selection) { op = gpa_key_trust_operation_new (GTK_WIDGET (self), selection); register_key_operation (self, GPA_KEY_OPERATION (op)); } } /* Import keys. */ static void key_manager_import (GtkAction *action, gpointer param) { GpaKeyManager *self = param; GpaImportFileOperation *op; op = gpa_import_file_operation_new (GTK_WIDGET (self)); register_import_operation (self, GPA_IMPORT_OPERATION (op)); } /* Export the selected keys to a file. */ static void key_manager_export (GtkAction *action, gpointer param) { GpaKeyManager *self = param; GList *selection; GpaExportFileOperation *op; selection = gpa_keylist_get_selected_keys (self->keylist, GPGME_PROTOCOL_UNKNOWN); if (! selection) return; op = gpa_export_file_operation_new (GTK_WIDGET (self), selection); register_operation (self, GPA_OPERATION (op)); } /* Import a key from the keyserver. */ #ifdef ENABLE_KEYSERVER_SUPPORT static void key_manager_retrieve (GtkAction *action, gpointer param) { GpaKeyManager *self = param; GpaImportServerOperation *op; op = gpa_import_server_operation_new (GTK_WIDGET (self)); register_import_operation (self, GPA_IMPORT_OPERATION (op)); } #endif /*ENABLE_KEYSERVER_SUPPORT*/ /* Refresh keys from the keyserver. */ #ifdef ENABLE_KEYSERVER_SUPPORT static void key_manager_refresh_keys (GtkAction *action, gpointer param) { GpaKeyManager *self = param; GpaImportByKeyidOperation *op; GList *selection; /* FIXME: The refresh-from-server operation currently only supports one key at a time. */ if (!key_manager_has_single_selection (self)) return; selection = gpa_keylist_get_selected_keys (self->keylist, GPGME_PROTOCOL_OPENPGP); if (selection) { op = gpa_import_bykeyid_operation_new (GTK_WIDGET (self), (gpgme_key_t) selection->data); register_import_operation (self, GPA_IMPORT_OPERATION (op)); } } #endif /*ENABLE_KEYSERVER_SUPPORT*/ /* Send a key to the keyserver. */ #ifdef ENABLE_KEYSERVER_SUPPORT static void key_manager_send (GtkAction *action, gpointer param) { GpaKeyManager *self = param; GList *selection; GpaExportServerOperation *op; /* FIXME: The export-to-server operation currently only supports exporting one key at a time. */ if (! key_manager_has_single_selection (self)) return; selection = gpa_keylist_get_selected_keys (self->keylist, GPGME_PROTOCOL_OPENPGP); if (selection) { op = gpa_export_server_operation_new (GTK_WIDGET (self), selection); register_operation (self, GPA_OPERATION (op)); } } #endif /*ENABLE_KEYSERVER_SUPPORT*/ /* Backup the default keys. */ static void key_manager_backup (GtkAction *action, gpointer param) { GpaKeyManager *self = param; gpgme_key_t key; GpaBackupOperation *op; if (! key_manager_has_private_selected (self)) return; key = key_manager_current_key (self); if (! key) return; op = gpa_backup_operation_new (GTK_WIDGET (self), key); register_operation (self, GPA_OPERATION (op)); } /* Run the advanced key generation dialog and if the user clicked OK, generate a new key pair and update the key list. */ static void key_manager_generate_key_advanced (gpointer param) { GpaKeyManager *self = param; GpaGenKeyAdvancedOperation *op; op = gpa_gen_key_advanced_operation_new (GTK_WIDGET (self)); register_generate_operation (self, GPA_GEN_KEY_OPERATION (op)); } /* Call the key generation wizard and update the key list if necessary */ static void key_manager_generate_key_simple (gpointer param) { GpaKeyManager *self = param; GpaGenKeySimpleOperation *op; op = gpa_gen_key_simple_operation_new (GTK_WIDGET (self)); register_generate_operation (self, GPA_GEN_KEY_OPERATION (op)); } /* Generate a key. */ static void key_manager_generate_key (GtkAction *action, gpointer param) { if (gpa_options_get_simplified_ui (gpa_options_get_instance ())) key_manager_generate_key_simple (param); else key_manager_generate_key_advanced (param); } /* Update everything that has to be updated when the selection in the key list changes. */ static void keyring_selection_update_actions (GpaKeyManager *self) { update_selection_sensitive_actions (self); keyring_update_details (self); } /* Callback for key listings invoked with the "next_key" signal. Used to receive and set the new current key. */ static void key_manager_key_listed (GpaContext *ctx, gpgme_key_t key, gpointer param) { GpaKeyManager *self = param; gpgme_key_unref (self->current_key); self->current_key = key; keyring_selection_update_actions (self); } /* FIXME: CHECK! Signal handler for selection changes. */ static void key_manager_selection_changed (GtkTreeSelection *treeselection, gpointer param) { GpaKeyManager *self = param; GList *selection; /* Some other piece of the keyring wants us to ignore this signal. */ if (self->freeze_selection) return; /* Update the current key. */ if (self->current_key) { /* Remove the previous one. */ gpgme_key_unref (self->current_key); self->current_key = NULL; } /* Abort retrieval of the current key. */ if (gpa_context_busy (self->ctx)) gpgme_op_keylist_end (self->ctx->ctx); /* Load the new one. */ if (gpa_keylist_has_single_selection (self->keylist) && (selection = gpa_keylist_get_selected_keys (self->keylist, GPGME_PROTOCOL_UNKNOWN))) { gpg_error_t err; gpgme_key_t key; int old_mode; key = (gpgme_key_t) selection->data; old_mode = gpgme_get_keylist_mode (self->ctx->ctx); /* With all the signatures and validating for the sake of X.509. Note that we should not save and restore the old protocol because the protocol should not be changed before the gpgme_op_keylist_end. Saving and restoring the keylist mode is okay. */ gpgme_set_keylist_mode (self->ctx->ctx, (old_mode #ifdef GPGME_KEYLIST_MODE_WITH_TOFU | GPGME_KEYLIST_MODE_WITH_TOFU #endif | GPGME_KEYLIST_MODE_SIGS | GPGME_KEYLIST_MODE_VALIDATE)); gpgme_set_protocol (self->ctx->ctx, key->protocol); err = gpgme_op_keylist_start (self->ctx->ctx, key->subkeys->fpr, FALSE); if (gpg_err_code (err) != GPG_ERR_NO_ERROR) gpa_gpgme_warning (err); gpgme_set_keylist_mode (self->ctx->ctx, old_mode); g_list_free (selection); /* Make sure the actions that depend on a current key are disabled. */ disable_selection_sensitive_actions (self); } else keyring_selection_update_actions (self); } /* FIXME: CHECK THIS! Signal handler for the map signal. If the simplified_ui flag is set and there's no private key in the key ring, ask the user whether he wants to generate a key. If so, call key_manager_generate_key which runs the appropriate dialog. Also, if the simplified_ui flag is set, remind the user if he has not yet created a backup copy of his private key. */ static void key_manager_mapped (gpointer param) { static gboolean asked_about_key_generation = FALSE; static gboolean asked_about_key_backup = FALSE; GpaKeyManager *self = param; if (gpa_options_get_simplified_ui (gpa_options_get_instance ())) { /* FIXME: We assume that the only reason a user might not have a default key is because he has no private keys. */ if (! asked_about_key_generation && ! gpa_options_have_default_key (gpa_options_get_instance())) { GtkWidget *dialog; GtkResponseType response; dialog = gtk_message_dialog_new (GTK_WINDOW (GTK_WIDGET (self)), GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE, _("You do not have a private key " "yet. Do you want to generate " "one now (recommended) or do it" " later?")); gtk_dialog_add_buttons (GTK_DIALOG (dialog), _("_Generate key now"), GTK_RESPONSE_OK, _("Do it _later"), GTK_RESPONSE_CANCEL, NULL); response = gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (dialog); if (response == GTK_RESPONSE_OK) key_manager_generate_key (NULL, param); asked_about_key_generation = TRUE; } else if (!asked_about_key_backup && !gpa_options_get_backup_generated (gpa_options_get_instance ()) && !gpa_options_have_default_key (gpa_options_get_instance())) { GtkWidget *dialog; GtkResponseType response; dialog = gtk_message_dialog_new (GTK_WINDOW (GTK_WIDGET (self)), GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE, _("You do not have a backup copy of" " your private key yet." " Do you want to backup your key " "now (recommended) or do it " "later?")); gtk_dialog_add_buttons (GTK_DIALOG (dialog), _("_Backup key now"), GTK_RESPONSE_OK, _("Do it _later"), GTK_RESPONSE_CANCEL, NULL); response = gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (dialog); if (response == GTK_RESPONSE_OK) { gpgme_key_t key; GpaBackupOperation *op; key = gpa_options_get_default_key (gpa_options_get_instance ()); if (key) { op = gpa_backup_operation_new (GTK_WIDGET (self), key); register_operation (self, GPA_OPERATION (op)); } } asked_about_key_backup = TRUE; } } } /* Close the key manager. */ static void key_manager_close (GtkAction *action, gpointer param) { - GpaKeyManager *self = param; - - gtk_widget_destroy (GTK_WIDGET (self)); + gtk_widget_destroy (GTK_WIDGET (this_instance)); } /* select all keys in the keyring */ static void key_manager_select_all (GtkAction *action, gpointer param) { GpaKeyManager *self = param; GtkTreeSelection *selection; selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (self->keylist)); gtk_tree_selection_select_all (selection); } /* Paste the clipboard into the keyring. */ static void key_manager_paste (GtkAction *action, gpointer param) { GpaKeyManager *self = param; GpaImportClipboardOperation *op; op = gpa_import_clipboard_operation_new (GTK_WIDGET (self)); register_import_operation (self, GPA_IMPORT_OPERATION (op)); } /* Copy the keys into the clipboard. */ static void key_manager_copy (GtkAction *action, gpointer param) { GpaKeyManager *self = param; GList *selection; GpaExportClipboardOperation *op; selection = gpa_keylist_get_selected_keys (self->keylist, GPGME_PROTOCOL_UNKNOWN); if (! selection) return; op = gpa_export_clipboard_operation_new (GTK_WIDGET (self), selection, 0); register_operation (self, GPA_OPERATION (op)); } /* Copy the secret keys into the clipboard. */ static void key_manager_copy_sec (GtkAction *action, gpointer param) { GpaKeyManager *self = param; GList *selection; GpaExportClipboardOperation *op; selection = gpa_keylist_get_selected_keys (self->keylist, GPGME_PROTOCOL_UNKNOWN); if (!selection || g_list_length (selection) != 1) return; op = gpa_export_clipboard_operation_new (GTK_WIDGET (self), selection, 1); register_operation (self, GPA_OPERATION (op)); } /* Copy the fingerprints of the keys into the clipboard. */ static void key_manager_copy_fpr (GtkAction *action, gpointer param) { GpaKeyManager *self = param; GList *selection, *item; gpgme_protocol_t prot = GPGME_PROTOCOL_UNKNOWN; gpgme_key_t key; char *buffer = NULL; char *p; selection = gpa_keylist_get_selected_keys (self->keylist, GPGME_PROTOCOL_UNKNOWN); if (!selection) return; for (item = selection; item; item = g_list_next (item)) { key = (gpgme_key_t)item->data; if (prot == GPGME_PROTOCOL_UNKNOWN) prot = key->protocol; else if (prot != key->protocol) { gpa_window_error (_("Only keys of the same procotol may be copied."), NULL); g_free (buffer); buffer = NULL; break; } if (prot == GPGME_PROTOCOL_UNKNOWN) ; else if (!buffer) buffer = g_strconcat (key->subkeys->fpr, "\n", NULL); else { p = g_strconcat (buffer, key->subkeys->fpr, "\n", NULL); g_free (buffer); buffer = p; } } if (buffer) { gtk_clipboard_set_text (gtk_clipboard_get (GDK_SELECTION_PRIMARY), buffer, -1); gtk_clipboard_set_text (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD), buffer, -1); } g_free (buffer); } /* Reload the key list. */ static void -key_manager_refresh (GtkAction *action, gpointer param) +key_manager_refresh (GSimpleAction *simple, GVariant *parameter, gpointer user_data) { - GpaKeyManager *self = param; + GpaKeyManager *self = user_data; /* Hack: To force reloading of secret keys we claim that a secret key has been imported. */ gpa_keylist_imported_secret_key (self->keylist); gpa_keylist_start_reload (self->keylist); } static void keyring_set_listing_cb (GtkAction *action, GtkRadioAction *current_action, gpointer param) { GpaKeyManager *self = param; gint detailed; detailed = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (current_action)); if (detailed) { gpa_keylist_set_detailed (self->keylist); gpa_options_set_detailed_view (gpa_options_get_instance (), TRUE); } else { gpa_keylist_set_brief (self->keylist); gpa_options_set_detailed_view (gpa_options_get_instance (), FALSE); } } /* Create and return the menu bar for the key ring editor. */ static void key_manager_action_new (GpaKeyManager *self, GtkWidget **menu, GtkWidget **toolbar, GtkWidget **popup) { + + // Rename this to "entries" when we don't need the GtkActionEntry array below + static const + GActionEntry entries[] = + { + { "file", NULL }, + { "edit", NULL }, + { "keys", NULL }, + + { "file_close", key_manager_close }, + { "file_quit", g_application_quit }, + + { "edit_copy", key_manager_copy }, + { "edit_copy_fprr", key_manager_copy_fpr }, + { "edit_copy_sec", key_manager_copy_sec }, + + { "edit_paste", key_manager_paste }, + { "edit_select_all", key_manager_select_all }, + + { "keys_refresh", key_manager_refresh }, + { "keys_new", key_manager_generate_key }, + { "keys_delete", key_manager_delete }, + { "keys_sign", key_manager_sign }, + { "keys_set_owner_trust", key_manager_trust }, + { "keys_edit_private_key", key_manager_edit }, + { "keys_import_keys", key_manager_import }, + { "keys_export_keys", key_manager_export}, + { "keys_backup_key", key_manager_backup}, + +#ifdef ENABLE_KEYSERVER_SUPPORT + { "server_retrive", key_manager_retrieve }, + { "server_refresh", key_manager_refresh_keys }, + { "server_send", key_manager_send }, +#endif + }; + + /* static const - GtkActionEntry entries[] = + GtkActionEntry old_entries[] = { - /* Toplevel. */ + // Toplevel. { "File", NULL, N_("_File"), NULL }, { "Edit", NULL, N_("_Edit"), NULL }, { "Keys", NULL, N_("_Keys"), NULL }, #ifdef ENABLE_KEYSERVER_SUPPORT { "Server", NULL, N_("_Server"), NULL }, #endif - /* File menu. */ + // File menu. { "FileClose", GTK_STOCK_CLOSE, NULL, NULL, "FIXME", G_CALLBACK (key_manager_close) }, { "FileQuit", GTK_STOCK_QUIT, NULL, NULL, - N_("Quit the program"), G_CALLBACK (g_application_quit) }, + N_("Quit the program"), G_CALLBACK (g_application_quit) }, - /* Edit menu. */ + // Edit menu. { "EditCopy", GTK_STOCK_COPY, NULL, NULL, - N_("Copy the selection"), G_CALLBACK (key_manager_copy) }, + N_("Copy the selection"), G_CALLBACK (key_manager_copy) }, { "EditCopyFpr", GTK_STOCK_COPY, N_("Copy _Fingerprint"), "F", - N_("Copy the fingerprints"), G_CALLBACK (key_manager_copy_fpr) }, + N_("Copy the fingerprints"), G_CALLBACK (key_manager_copy_fpr) }, { "EditCopySec", GTK_STOCK_COPY, N_("Copy Private Key"), NULL, - N_("Copy a single private key"), G_CALLBACK (key_manager_copy_sec) }, + N_("Copy a single private key"), G_CALLBACK (key_manager_copy_sec) }, { "EditPaste", GTK_STOCK_PASTE, NULL, NULL, - N_("Paste the clipboard"), G_CALLBACK (key_manager_paste) }, + N_("Paste the clipboard"), G_CALLBACK (key_manager_paste) }, { "EditSelectAll", GTK_STOCK_SELECT_ALL, NULL, "A", - N_("Select all certificates"), - G_CALLBACK (key_manager_select_all) }, + N_("Select all certificates"), + G_CALLBACK (key_manager_select_all) }, - /* Keys menu. */ + // Keys menu. { "KeysRefresh", GTK_STOCK_REFRESH, NULL, NULL, - N_("Refresh the keyring"), G_CALLBACK (key_manager_refresh) }, + N_("Refresh the keyring"), G_CALLBACK (key_manager_refresh) }, { "KeysNew", GTK_STOCK_NEW, N_("_New key..."), NULL, - N_("Generate a new key"), G_CALLBACK (key_manager_generate_key) }, + N_("Generate a new key"), G_CALLBACK (key_manager_generate_key) }, { "KeysDelete", GTK_STOCK_DELETE, N_("_Delete keys"), NULL, - N_("Remove the selected key"), G_CALLBACK (key_manager_delete) }, + N_("Remove the selected key"), G_CALLBACK (key_manager_delete) }, { "KeysSign", GPA_STOCK_SIGN, N_("_Sign Keys..."), NULL, - N_("Sign the selected key"), G_CALLBACK (key_manager_sign) }, + N_("Sign the selected key"), G_CALLBACK (key_manager_sign) }, { "KeysSetOwnerTrust", NULL, N_("Set _Owner Trust..."), NULL, - N_("Set owner trust of the selected key"), + N_("Set owner trust of the selected key"), G_CALLBACK (key_manager_trust) }, { "KeysEditPrivateKey", GPA_STOCK_EDIT, N_("_Edit Private Key..."), NULL, - N_("Edit the selected private key"), + N_("Edit the selected private key"), G_CALLBACK (key_manager_edit) }, { "KeysImport", GPA_STOCK_IMPORT, N_("_Import Keys..."), NULL, - N_("Import Keys"), G_CALLBACK (key_manager_import) }, + N_("Import Keys"), G_CALLBACK (key_manager_import) }, { "KeysExport", GPA_STOCK_EXPORT, N_("E_xport Keys..."), NULL, - N_("Export Keys"), G_CALLBACK (key_manager_export) }, + N_("Export Keys"), G_CALLBACK (key_manager_export) }, { "KeysBackup", NULL, N_("_Backup..."), NULL, - N_("Backup key"), G_CALLBACK (key_manager_backup) }, + N_("Backup key"), G_CALLBACK (key_manager_backup) }, - /* Server menu. */ + // Server menu. #ifdef ENABLE_KEYSERVER_SUPPORT { "ServerRetrieve", NULL, N_("_Retrieve Keys..."), NULL, N_("Retrieve keys from server"), G_CALLBACK (key_manager_retrieve) }, { "ServerRefresh", NULL, N_("Re_fresh Keys"), NULL, N_("Refresh keys from server"), G_CALLBACK (key_manager_refresh_keys) }, { "ServerSend", NULL, N_("_Send Keys..."), NULL, N_("Send keys to server"), G_CALLBACK (key_manager_send) } -#endif /*ENABLE_KEYSERVER_SUPPORT*/ +#endif //ENABLE_KEYSERVER_SUPPORT }; + */ static const GtkRadioActionEntry radio_entries[] = { - { "DetailsBrief", GPA_STOCK_BRIEF, NULL, NULL, + { "DetailsBrief", "brief", NULL, NULL, N_("Show Brief Keylist"), 0 }, { "DetailsDetailed", GPA_STOCK_DETAILED, NULL, NULL, N_("Show Key Details"), 1 } }; + static const char *menu_string = + "" + "" + "" + "_File" + "" + "Close" + "app.file_close" + "" + "" + "Quit" + "app.file_quit" + "" + "" + "" + "Edit" + "" + "Copy" + "app.edit_copy" + "" + "" + "Paste" + "app.edit_paste" + "" + "
" + "" + "Select All" + "app.edit_select_all" + "" + "
" + "
" + "" + "Preferences" + "app.edit_preferences" + "" + "" + "Backend Preferences" + "app.edit_backend_preferences" + "" + "
" + "
" + "" + "Keys" + "" + "Refresh" + "app.keys_refresh" + "" + "
" + "" + "New Key" + "app.keys_new" + "" + "" + "Delete Keys" + "app.keys_delete" + "" + "
" + "
" + "" + "Sign Keys" + "app.keys_sign" + "" + "" + "Set Owner Trust" + "app.keys_set_owner_trust" + "" + "" + "Edit Private Key" + "app.keys_edit_private_key" + "" + "
" + "
" + "" + "Import Keys" + "app.keys_import_keys" + "" + "" + "Export Keys" + "app.keys_export_keys" + "" + "" + "Backup..." + "app.keys_backup_key" + "" + "
" + "
" + "" + "Windows" + "" + "Keyring Manager" + "app.windows_keyring_editor" + "" + "" + "File Manager" + "app.windows_file_manager" + "" + "" + "Clipboard" + "app.windows_clipboard" + "" + "" + "Card Manager" + "app.windows_card_manager" + "" + "" +#ifdef ENABLE_KEYSERVER_SUPPORT + "" + "Server" + "" + "Retieve Keys..." + "app.server_retrive" + "" + "" + "Send Keys..." + "app.server_send" + "" + "" +#endif // ENABLE_KEYSERVER_SUPPORT + "" + "Help" + "" + "About" + "app.help_about" + "" + "" + "
" + + /* + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " +#ifdef ENABLE_KEYSERVER_SUPPORT + " " + " " +#endif + " " + " " + */ + "" + "
" + "" + "Copy Fingerprint" + "app.file_close" + "" + "" + "Copy" + "app.file_close" + "" + "" + "Paste" + "app.file_close" + "" + "" + "Delete Keys" + "app.file_close" + "" + "
" + "
" + "" + "Sign Keys" + "app.file_close" + "" + "" + "Set Ownertrust" + "app.file_close" + "" + "" + "Edit Private Key" + "app.file_close" + "" + "" + "Copy Private Key" + "app.file_close" + "" + "
" + "
" + "" + "Export Keys" + "app.file_close" + "" + "" + "Update Keys" + "app.file_close" + "" + "" + "Send Keys" + "app.file_close" + "" + "" + "Backup" + "app.file_close" + "" + "
" + "
" + + "" + "True" + "False" + "False" + "" + "" + "True" + "False" + "True" + "edit" + "" + "" + "False" + "True" + "" + "" + "" + "" + "True" + "False" + "True" + "delete" + "" + "" + "False" + "True" + "" + "" + + "" + "" + "True" + "False" + "True" + "sign" + "" + "" + "False" + "True" + "" + "" + + "" + "" + "True" + "False" + "True" + "import" + "" + "" + "False" + "True" + "" + "" + + "" + "" + "True" + "False" + "True" + "export" + "" + "" + "False" + "True" + "" + "" + + "" + "" + "" + "" + + "" + "" + "True" + "False" + "True" + "app.windows_file_manager" + "brief" + "" + "" + "False" + "True" + "" + "" + + "" + "" + "True" + "False" + "True" + "detailed" + "" + "" + "False" + "True" + "" + "" + + "" + "" + "" + "" + + "" + "" + "True" + "False" + "True" + "preferences-desktop" + "app.edit_preferences" + "" + "" + "False" + "True" + "" + "" + + "" + "" + "" + "" + + "" + "" + "True" + "False" + "True" + "view-refresh" + "app.windows_card_manager" + "" + "" + "False" + "True" + "" + "" + + "" + "" + "" + "" + + "" + "" + "True" + "False" + "True" + "folder" + "app.windows_file_manager" + "" + "" + "False" + "True" + "" + "" + + "" + "" + "True" + "False" + "True" + "edit-paste" + "app.windows_clipboard" + "" + "" + "False" + "True" + "" + "" + + "" + "" + "True" + "False" + "True" + "smartcard" + "app.windows_card_manager" + "" + "" + "False" + "True" + "" + "" + "" + "
"; + + static const char *ui_description = "" " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " #ifdef ENABLE_CARD_MANAGER " " #endif " " #ifdef ENABLE_KEYSERVER_SUPPORT " " " " " " " " -#endif /*ENABLE_KEYSERVER_SUPPORT*/ +#endif // ENABLE_KEYSERVER_SUPPORT " " #if 0 " " #endif " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " #ifdef ENABLE_CARD_MANAGER " " #endif #if 0 " " #endif " " " " " " " " " " " " " " " " " " " " " " " " " " #ifdef ENABLE_KEYSERVER_SUPPORT " " " " #endif " " " " ""; +#ifdef OLD_MENU + GtkAccelGroup *accel_group; GtkActionGroup *action_group; GtkAction *action; GtkUIManager *ui_manager; GError *error; int detailed; detailed = gpa_options_get_detailed_view (gpa_options_get_instance()); action_group = gtk_action_group_new ("MenuActions"); gtk_action_group_set_translation_domain (action_group, PACKAGE); gtk_action_group_add_actions (action_group, entries, G_N_ELEMENTS (entries), self); gtk_action_group_add_radio_actions (action_group, radio_entries, G_N_ELEMENTS (radio_entries), detailed ? 1 : 0, G_CALLBACK (keyring_set_listing_cb), self); gtk_action_group_add_actions (action_group, gpa_help_menu_action_entries, G_N_ELEMENTS (gpa_help_menu_action_entries), GTK_WIDGET (self)); gtk_action_group_add_actions (action_group, gpa_windows_menu_action_entries, G_N_ELEMENTS (gpa_windows_menu_action_entries), GTK_WIDGET (self)); gtk_action_group_add_actions (action_group, gpa_preferences_menu_action_entries, G_N_ELEMENTS (gpa_preferences_menu_action_entries), GTK_WIDGET (self)); ui_manager = gtk_ui_manager_new (); gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); accel_group = gtk_ui_manager_get_accel_group (ui_manager); gtk_window_add_accel_group (GTK_WINDOW (GTK_WIDGET (self)), accel_group); if (! gtk_ui_manager_add_ui_from_string (ui_manager, ui_description, -1, &error)) { g_message ("building keyring menus failed: %s", error->message); g_error_free (error); exit (EXIT_FAILURE); } - /* Fixup the icon theme labels which are too long for the toolbar. */ + // Fixup the icon theme labels which are too long for the toolbar. action = gtk_action_group_get_action (action_group, "KeysEditPrivateKey"); g_object_set (action, "short_label", _("Edit"), NULL); action = gtk_action_group_get_action (action_group, "KeysDelete"); g_object_set (action, "short_label", _("Delete"), NULL); action = gtk_action_group_get_action (action_group, "KeysSign"); g_object_set (action, "short_label", _("Sign"), NULL); action = gtk_action_group_get_action (action_group, "KeysExport"); g_object_set (action, "short_label", _("Export"), NULL); action = gtk_action_group_get_action (action_group, "KeysImport"); g_object_set (action, "short_label", _("Import"), NULL); action = gtk_action_group_get_action (action_group, "WindowsFileManager"); g_object_set (action, "short_label", _("Files"), NULL); #ifdef ENABLE_CARD_MANAGER action = gtk_action_group_get_action (action_group, "WindowsCardManager"); g_object_set (action, "short_label", _("Card"), NULL); #endif - /* Take care of sensitiveness of widgets. */ + // Take care of sensitiveness of widgets. action = gtk_action_group_get_action (action_group, "EditCopy"); add_selection_sensitive_action (self, action, key_manager_has_selection); action = gtk_action_group_get_action (action_group, "EditCopyFpr"); add_selection_sensitive_action (self, action, key_manager_has_selection); action = gtk_action_group_get_action (action_group, "EditCopySec"); add_selection_sensitive_action (self, action, key_manager_has_single_selection); action = gtk_action_group_get_action (action_group, "KeysDelete"); add_selection_sensitive_action (self, action, key_manager_has_selection); action = gtk_action_group_get_action (action_group, "KeysExport"); add_selection_sensitive_action (self, action, key_manager_has_selection); #ifdef ENABLE_KEYSERVER_SUPPORT action = gtk_action_group_get_action (action_group, "ServerRefresh"); add_selection_sensitive_action (self, action, key_manager_has_single_selection); action = gtk_action_group_get_action (action_group, "ServerSend"); add_selection_sensitive_action (self, action, key_manager_has_single_selection); -#endif /*ENABLE_KEYSERVER_SUPPORT*/ +#endif // ENABLE_KEYSERVER_SUPPORT action = gtk_action_group_get_action (action_group, "KeysSetOwnerTrust"); add_selection_sensitive_action (self, action, key_manager_has_single_selection_OpenPGP); action = gtk_action_group_get_action (action_group, "KeysSign"); add_selection_sensitive_action (self, action, key_manager_can_sign); action = gtk_action_group_get_action (action_group, "KeysEditPrivateKey"); add_selection_sensitive_action (self, action, key_manager_has_private_selected); action = gtk_action_group_get_action (action_group, "KeysBackup"); add_selection_sensitive_action (self, action, key_manager_has_private_selected); *menu = gtk_ui_manager_get_widget (ui_manager, "/MainMenu"); *toolbar = gtk_ui_manager_get_widget (ui_manager, "/ToolBar"); gpa_toolbar_set_homogeneous (GTK_TOOLBAR (*toolbar), FALSE); *popup = gtk_ui_manager_get_widget (ui_manager, "/PopupMenu"); + +#else + + GError **err; + + GtkBuilder *gtk_builder = gtk_builder_new_from_string (icons_string, -1); + + if (gtk_builder_add_from_string( gtk_builder, menu_string , -1, err) == 0) { + printf("ERROR: %s \n", (*err)->message); + } + + GMenuModel *menu_bar_model = G_MENU_MODEL (gtk_builder_get_object (GTK_BUILDER (gtk_builder), "menu")); + *menu = gtk_menu_bar_new_from_model (menu_bar_model); + + GMenuModel *popup_menu_model = G_MENU_MODEL (gtk_builder_get_object (GTK_BUILDER (gtk_builder), "popupmenu")); + *popup = gtk_menu_new_from_model (popup_menu_model); + + GObject *grid = gtk_builder_get_object (GTK_BUILDER (gtk_builder), "toolbar"); + + GtkCssProvider *css_provider = gtk_css_provider_new(); + GdkDisplay *display = gdk_display_get_default(); + GdkScreen *screen = gdk_display_get_default_screen (display); + gtk_style_context_add_provider_for_screen (screen, GTK_STYLE_PROVIDER(css_provider), GTK_STYLE_PROVIDER_PRIORITY_USER); + + gtk_css_provider_load_from_data(css_provider, + "#toolbar {\n" + //" padding-left: 55px;\n" + // " padding-right: 5px;\n" + // " border-radius: 3px;\n" + "}\n", -1, NULL); + + GtkStyleContext *style_context; + + style_context = gtk_widget_get_style_context (GTK_WIDGET (grid)); + + + //gtk_widget_add_css_class (grid, "toolbar"); + + *toolbar = grid; + + // We must set the name to the toolbar for css to recognize it + gtk_widget_set_name(*toolbar, "toolbar"); + + gtk_style_context_add_class (style_context, "toolbar"); + + GtkApplication *gpa_app = get_gpa_application (); + + g_action_map_add_action_entries (G_ACTION_MAP (gpa_app), + gpa_windows_menu_g_action_entries, + G_N_ELEMENTS (gpa_windows_menu_g_action_entries), + self); + + g_action_map_add_action_entries (G_ACTION_MAP (gpa_app), + entries, + G_N_ELEMENTS (entries), + self); + + g_action_map_add_action_entries (G_ACTION_MAP (gpa_app), + gpa_help_menu_g_action_entries, + G_N_ELEMENTS (gpa_help_menu_g_action_entries), + self); + + g_action_map_add_action_entries (G_ACTION_MAP (gpa_app), + gpa_preferences_menu_g_action_entries, + G_N_ELEMENTS (gpa_preferences_menu_g_action_entries), + self); + +#endif + + + } /* Update the details widget according to the current selection. This means that if there is exactly one key selected, display its properties in the pages, otherwise show the number of currently selected keys. */ static int idle_update_details (gpointer param) { GpaKeyManager *self = param; if (gpa_keylist_has_single_selection (self->keylist)) { gpgme_key_t key = key_manager_current_key (self); if (! key) { /* There is a single key selected, but the current key is NULL. This means the key has not been returned yet, so we exit the function asking GTK to run it again when there is time. */ return TRUE; } gpa_key_details_update (self->details, key, 1); } else { GList *selection = gpa_keylist_get_selected_keys (self->keylist, GPGME_PROTOCOL_UNKNOWN); if (selection) { gpa_key_details_update (self->details, NULL, g_list_length (selection)); g_list_free (selection); } } /* Set the idle id to NULL to indicate that the idle handler has been run. */ self->details_idle_id = 0; /* Return false to indicate that this function shouldn't be called again by GTK, only when we expicitly add it again. */ return FALSE; } /* Add an idle handler to update the details, but only when none has been set yet. */ static void keyring_update_details (GpaKeyManager *self) { if (! self->details_idle_id) self->details_idle_id = g_idle_add (idle_update_details, self); } /* Status bar handling. */ static GtkWidget * keyring_statusbar_new (GpaKeyManager *self) { GtkWidget *hbox; GtkWidget *label; hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); label = gtk_label_new (""); self->status_label = label; gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); label = gtk_label_new (""); self->status_key_id = label; gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 5); label = gtk_label_new (""); self->status_key_user = label; gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); return hbox; } /* Update the status bar. */ static void keyring_update_status_bar (GpaKeyManager *self) { gpgme_key_t key = gpa_options_get_default_key (gpa_options_get_instance ()); if (key) { gchar *string; gtk_label_set_text (GTK_LABEL (self->status_label), _("Selected default key:")); string = gpa_gpgme_key_get_userid (key->uids); gtk_label_set_text (GTK_LABEL (self->status_key_user), string); g_free (string); gtk_label_set_text (GTK_LABEL (self->status_key_id), gpa_gpgme_key_get_short_keyid (key)); } else { gtk_label_set_text (GTK_LABEL (self->status_label), _("No default key selected in the preferences.")); gtk_label_set_text (GTK_LABEL (self->status_key_user), ""); gtk_label_set_text (GTK_LABEL (self->status_key_id), ""); } } /* FIXME: Check. */ /* The context menu of the keyring list. This is the callback for the "button_press_event" signal. */ static gint display_popup_menu (GpaKeyManager *self, GdkEvent *event, GpaKeyList *list) { GtkMenu *menu; GdkEventButton *event_button; g_return_val_if_fail (self != NULL, FALSE); g_return_val_if_fail (event != NULL, FALSE); menu = GTK_MENU (self->popup_menu); if (event->type == GDK_BUTTON_PRESS) { event_button = (GdkEventButton *) event; if (event_button->button == 3) { GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (list)); GtkTreePath *path; GtkTreeIter iter; /* Make sure the clicked key is selected. */ if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (list), event_button->x, event_button->y, &path, NULL, NULL, NULL)) { gtk_tree_model_get_iter (gtk_tree_view_get_model (GTK_TREE_VIEW(list)), &iter, path); if (! gtk_tree_selection_iter_is_selected (selection, &iter)) { /* Block selection updates. */ self->freeze_selection++; gtk_tree_selection_unselect_all (selection); self->freeze_selection--; gtk_tree_selection_select_path (selection, path); } gtk_menu_popup (menu, NULL, NULL, NULL, NULL, event_button->button, event_button->time); } return TRUE; } } return FALSE; } /* Signal handler for the "changed_default_key" signal. */ static void keyring_default_key_changed (GpaOptions *options, gpointer param) { GpaKeyManager *self = param; /* Update the status bar and the selection sensitive widgets because some depend on the default key. */ keyring_update_status_bar (self); update_selection_sensitive_actions (self); } /* Create all the widgets of this window. */ static void construct_widgets (GpaKeyManager *self) { GtkWidget *vbox; GtkWidget *label; GtkWidget *scrolled; GtkWidget *keylist; GtkWidget *menubar; GtkWidget *toolbar; GtkWidget *hbox; GtkWidget *icon; GtkWidget *paned; GtkWidget *statusbar; GtkWidget *main_box; GtkWidget *align; gchar *markup; guint pt, pb, pl, pr; gpa_window_set_title (GTK_WINDOW (self), _("Key Manager")); gtk_window_set_default_size (GTK_WINDOW (self), 680, 600); g_signal_connect_swapped (G_OBJECT (self), "map", G_CALLBACK (key_manager_mapped), self); - vbox = gtk_vbox_new (FALSE, 0); + vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); gtk_container_add (GTK_CONTAINER (self), vbox); /* FIXME: Check next line. */ key_manager_action_new (self, &menubar, &toolbar, &self->popup_menu); gtk_box_pack_start (GTK_BOX (vbox), menubar, FALSE, TRUE, 0); gtk_box_pack_start (GTK_BOX (vbox), toolbar, FALSE, TRUE, 0); /* Add a fancy label that tells us: This is the key manager. */ /* FIXME: We should have a common function for this. */ - hbox = gtk_hbox_new (FALSE, 0); + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 5); - icon = gtk_image_new_from_stock (GPA_STOCK_KEYMAN_SIMPLE, - GTK_ICON_SIZE_DND); + GtkBuilder *gtk_builder = gtk_builder_new_from_string (icons_string, -1); + + icon = gtk_image_new_from_resource ("/org/gnupg/gpa/keyringeditor.xpm"); gtk_box_pack_start (GTK_BOX (hbox), icon, FALSE, TRUE, 0); label = gtk_label_new (NULL); markup = g_strdup_printf ("%s", _("Key Manager")); gtk_label_set_markup (GTK_LABEL (label), markup); g_free (markup); gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 10); gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); paned = gtk_vpaned_new (); - main_box = gtk_hbox_new (TRUE, 0); + main_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); align = gtk_alignment_new (0.5, 0.5, 1, 1); gtk_alignment_get_padding (GTK_ALIGNMENT (align), &pt, &pb, &pl, &pr); gtk_alignment_set_padding (GTK_ALIGNMENT (align), pt, pb + 5, pl + 5, pr + 5); gtk_box_pack_start (GTK_BOX (vbox), align, TRUE, TRUE, 0); gtk_box_pack_start (GTK_BOX (main_box), paned, TRUE, TRUE, 0); gtk_container_add (GTK_CONTAINER (align), main_box); scrolled = gtk_scrolled_window_new (NULL, NULL); gtk_paned_pack1 (GTK_PANED (paned), scrolled, TRUE, TRUE); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); /* FIXME: Which shadow type - get it from a global resource? */ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled), GTK_SHADOW_IN); keylist = gpa_keylist_new (GTK_WIDGET (self)); self->keylist = GPA_KEYLIST (keylist); if (gpa_options_get_detailed_view (gpa_options_get_instance())) gpa_keylist_set_detailed (self->keylist); else gpa_keylist_set_brief (self->keylist); gtk_container_add (GTK_CONTAINER (scrolled), keylist); g_signal_connect (G_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW (keylist))), "changed", G_CALLBACK (key_manager_selection_changed), self); g_signal_connect_swapped (G_OBJECT (keylist), "button_press_event", G_CALLBACK (display_popup_menu), self); self->details = gpa_key_details_new (); gtk_paned_pack2 (GTK_PANED (paned), self->details, TRUE, TRUE); gtk_paned_set_position (GTK_PANED (paned), 250); statusbar = keyring_statusbar_new (self); gtk_box_pack_start (GTK_BOX (vbox), statusbar, FALSE, TRUE, 0); g_signal_connect (G_OBJECT (gpa_options_get_instance ()), "changed_default_key", G_CALLBACK (keyring_default_key_changed), self); keyring_update_status_bar (self); update_selection_sensitive_actions (self); keyring_update_details (self); self->current_key = NULL; self->ctx = gpa_context_new (); self->freeze_selection = 0; g_signal_connect (G_OBJECT (self->ctx), "next_key", G_CALLBACK (key_manager_key_listed), self); } /* Callback for the "destroy" signal. */ static void gpa_key_manager_closed (GtkWidget *widget, gpointer param) { this_instance = NULL; } /************************************************************ ****************** Object Management ******************** ************************************************************/ static void gpa_key_manager_class_init (void *class_ptr, void *class_data) { GpaKeyManagerClass *klass = class_ptr; G_OBJECT_CLASS (klass)->finalize = gpa_key_manager_finalize; } static void gpa_key_manager_init (GTypeInstance *instance, void *class_ptr) { GpaKeyManager *self = GPA_KEY_MANAGER (instance); construct_widgets (self); g_signal_connect (self, "destroy", G_CALLBACK (gpa_key_manager_closed), self); } static void gpa_key_manager_finalize (GObject *object) { GpaKeyManager *self = GPA_KEY_MANAGER (object); g_list_free (self->selection_sensitive_actions); self->selection_sensitive_actions = NULL; G_OBJECT_CLASS (g_type_class_peek_parent (GPA_KEY_MANAGER_GET_CLASS (self)))->finalize (object); } GType gpa_key_manager_get_type (void) { static GType this_type = 0; if (!this_type) { static const GTypeInfo this_info = { sizeof (GpaKeyManagerClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, gpa_key_manager_class_init, NULL, /* class_finalize */ NULL, /* class_data */ sizeof (GpaKeyManager), 0, /* n_preallocs */ gpa_key_manager_init, }; this_type = g_type_register_static (GTK_TYPE_WINDOW, "GpaKeyManager", &this_info, 0); } return this_type; } /************************************************************ ********************** Public API ************************ ************************************************************/ /* Return the instance of the the key manager. If a new instance has been created, TRUE is stored at R_CREATED, otherwise FALSE. */ GtkWidget * gpa_key_manager_get_instance (gboolean *r_created) { if (r_created) *r_created = !this_instance; if (!this_instance) { this_instance = g_object_new (GPA_KEY_MANAGER_TYPE, NULL); /*FIXME load_all_keys (this_instance);*/ } return GTK_WIDGET (this_instance); } gboolean gpa_key_manager_is_open (void) { return !!this_instance; } /* Return true if we should ask for a first time key generation. * * This function basically duplicates the conditions from * key_manager_mapped. However that function mus be used from a * key_manager context and can't easily be used from other GPA * components. */ gboolean key_manager_maybe_firsttime (void) { if (!gpa_options_get_simplified_ui (gpa_options_get_instance ())) return FALSE; if (!gpa_options_have_default_key (gpa_options_get_instance())) return TRUE; if (!gpa_options_get_backup_generated (gpa_options_get_instance ())) return TRUE; return FALSE; }