[seahorse/wip/nielsdg/gaction-app] Port most uses of Gtk.Action to GLib.Action
- From: Niels De Graef <nielsdg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [seahorse/wip/nielsdg/gaction-app] Port most uses of Gtk.Action to GLib.Action
- Date: Mon, 7 Jan 2019 02:14:16 +0000 (UTC)
commit f360df4232b18c08a125ce6c3ad4597097d99d47
Author: Niels De Graef <nielsdegraef gmail com>
Date: Mon Dec 31 11:47:14 2018 +0100
Port most uses of Gtk.Action to GLib.Action
I wasn't planning on doing this in such a huge rework, but given that
the way the Gtk.ActionGroups were handled was so tightly coupled
throughout the codebase, I barely had a choice.
A list of the most major changed:
* Since it was easier to setup (compared to migrating the menubar), we
now use a popover for our menu (together with a GMenuModel in the
builder file).
* A SeahorseBackend's `actions`-property can no longer be null
* Moved some GActions from KeyManager/Catalog to SeahorseApplication
where appropriate.
* Moved the actions that were being registered from the Generate dialogs
(e.g. Seahorse.Ssh.Generate) to their respective backends.
common/actions.vala | 60 +-------
common/backend.vala | 2 +-
common/catalog.vala | 264 ++++--------------------------------
common/key-manager-store.vala | 2 +
common/object.vala | 5 -
gkr/gkr-backend.vala | 76 +++++------
gkr/gkr-keyring.vala | 6 +-
pgp/seahorse-gpgme-generate.c | 52 -------
pgp/seahorse-gpgme-key.c | 8 +-
pgp/seahorse-pgp-actions.c | 120 ++++++++--------
pgp/seahorse-pgp-actions.h | 6 +-
pgp/seahorse-pgp-backend.c | 6 +-
pkcs11/pkcs11-generate.vala | 18 ---
pkcs11/seahorse-pkcs11-backend.c | 55 +++++++-
src/application.vala | 96 ++++++++++++-
src/generate-select.vala | 69 +++++-----
src/key-manager.vala | 193 +++++++++-----------------
src/seahorse-key-manager-widgets.ui | 67 ++++-----
src/seahorse-key-manager.ui | 170 ++++++++++++++++-------
ssh/actions.vala | 66 +++++----
ssh/backend.vala | 3 +-
ssh/generate.vala | 21 ---
ssh/key.vala | 1 -
23 files changed, 576 insertions(+), 790 deletions(-)
---
diff --git a/common/actions.vala b/common/actions.vala
index 08cd7bb2..b3252c17 100644
--- a/common/actions.vala
+++ b/common/actions.vala
@@ -18,62 +18,12 @@
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
-namespace Seahorse {
+public class Seahorse.ActionGroup : SimpleActionGroup {
-public class Action {
- public static void pre_activate(Gtk.Action action,
- Catalog? catalog,
- Gtk.Window? window) {
- action.set_data("seahorse-action-window", window);
- action.set_data("seahorse-action-catalog", catalog);
- }
+ public string prefix { get; construct set; }
- public static void activate_with_window(Gtk.Action action,
- Catalog? catalog,
- Gtk.Window? window) {
- pre_activate(action, catalog, window);
- action.activate();
- post_activate(action);
- }
-
- public static void post_activate(Gtk.Action action) {
- action.set_data("seahorse-action-window", null);
- action.set_data("seahorse-action-catalog", null);
- }
-
- public static Gtk.Window? get_window(Gtk.Action action) {
- Gtk.Window? window = action.get_data("seahorse-action-window");
- return window;
- }
-
- public static Catalog? get_catalog(Gtk.Action action) {
- Catalog? catalog = action.get_data("seahorse-action-catalog");
- return catalog;
- }
-}
-
-public class Actions : Gtk.ActionGroup {
- public Catalog? catalog {
- owned get { return (Catalog)this._catalog.get(); }
- set { this._catalog.set(value); }
- }
-
- public string? definition {
- get { return this._definition; }
- }
-
- private unowned string? _definition;
- private WeakRef _catalog;
-
- public Actions(string name) {
- GLib.Object(
- name: name
- );
- }
-
- public void register_definition (string definition) {
- this._definition = definition;
- }
-}
+ public Catalog catalog { owned get; set; }
+ public virtual void set_actions_for_selected_objects(List<GLib.Object> objects) {
+ }
}
diff --git a/common/backend.vala b/common/backend.vala
index 9f245ecb..ec0508cc 100644
--- a/common/backend.vala
+++ b/common/backend.vala
@@ -22,7 +22,7 @@ public interface Backend : Gcr.Collection {
public abstract string name { get; }
public abstract string label { get; }
public abstract string description { get; }
- public abstract Gtk.ActionGroup? actions { owned get; }
+ public abstract ActionGroup actions { owned get; }
public abstract bool loaded { get; }
public abstract Place? lookup_place(string uri);
diff --git a/common/catalog.vala b/common/catalog.vala
index c61a56fc..f9c35565 100644
--- a/common/catalog.vala
+++ b/common/catalog.vala
@@ -21,43 +21,26 @@
namespace Seahorse {
public abstract class Catalog : Gtk.ApplicationWindow {
- public const string MENU_OBJECT = "ObjectPopup";
/* Set by the derived classes */
public string ui_name { construct; get; }
- private Gtk.UIManager _ui_manager;
- private GLib.GenericSet<Gtk.ActionGroup> _actions;
- private Gtk.Action _edit_delete;
- private Gtk.Action _properties_object;
- private Gtk.Action _file_export;
- private Gtk.Action _edit_copy;
- private GLib.List<Gtk.ActionGroup> _selection_actions;
+ protected MenuModel context_menu;
private bool _disposed;
private GLib.Settings _settings;
public abstract GLib.List<weak Backend> get_backends();
public abstract Place? get_focused_place();
public abstract GLib.List<GLib.Object> get_selected_objects();
- protected abstract void add_menu(Gtk.Widget menu);
- construct {
- this._actions = new GLib.GenericSet<Gtk.ActionGroup>(GLib.direct_hash, GLib.direct_equal);
- this._ui_manager = new Gtk.UIManager();
-
- this._ui_manager.add_widget.connect((widget) => {
- if (widget is Gtk.MenuBar)
- add_menu(widget);
- });
-
- this._ui_manager.pre_activate.connect((action) => {
- Action.pre_activate(action, this, this);
- });
-
- this._ui_manager.post_activate.connect((action) => {
- Action.post_activate(action);
- });
+ private const ActionEntry[] ACTION_ENTRIES = {
+ { "file-export", on_key_export_file },
+ { "copy", on_key_export_clipboard },
+ { "edit-delete", on_object_delete },
+ { "properties-object", on_properties_object },
+ };
+ construct {
/* Load window size for windows that aren't dialogs */
var key = "/apps/seahorse/windows/%s/".printf(this.ui_name);
this._settings = new GLib.Settings.with_path("org.gnome.seahorse.window", key);
@@ -66,43 +49,15 @@ public abstract class Catalog : Gtk.ApplicationWindow {
if (width > 0 && height > 0)
this.resize (width, height);
- /* The widgts get added in an idle loop later */
- try {
- var path = "/org/gnome/Seahorse/seahorse-%s-widgets.ui".printf(this.ui_name);
- this._ui_manager.add_ui_from_resource(path);
- } catch (GLib.Error err) {
- GLib.warning("couldn't load ui description for '%s': %s",
- this.ui_name, err.message);
- }
-
- this.add_accel_group (this._ui_manager.get_accel_group());
-
- var actions = new Gtk.ActionGroup("main");
- actions.set_translation_domain(Config.GETTEXT_PACKAGE);
- actions.add_actions(UI_ENTRIES, this);
+ Gtk.Builder builder = new Gtk.Builder.from_resource(
+ "/org/gnome/Seahorse/seahorse-%s-widgets.ui".printf(this.ui_name)
+ );
+ this.context_menu = (MenuModel) builder.get_object("context_menu");
- var action = actions.get_action("app-preferences");
- action.set_visible (Prefs.available());
- this._edit_delete = actions.get_action("edit-delete");
- this._properties_object = actions.get_action("properties-object");
- this._edit_copy = actions.get_action("edit-export-clipboard");
- this._file_export = actions.get_action("file-export");
- this._ui_manager.insert_action_group (actions, 0);
+ add_action_entries (ACTION_ENTRIES, this);
}
public override void dispose() {
- this._edit_copy = null;
- this._edit_delete = null;
- this._file_export = null;
- this._properties_object = null;
-
- foreach (var group in this._selection_actions)
- this._ui_manager.remove_action_group(group);
- this._selection_actions = null;
-
- this._ui_manager = null;
- this._actions.remove_all();
-
if (!this._disposed) {
this._disposed = true;
@@ -132,140 +87,28 @@ public abstract class Catalog : Gtk.ApplicationWindow {
break;
}
- this._properties_object.sensitive = can_properties;
- this._edit_delete.sensitive = can_delete;
- this._edit_copy.sensitive = can_export;
- this._file_export.sensitive = can_export;
-
- foreach (var group in this._selection_actions)
- group.visible = false;
- this._selection_actions = lookup_actions_for_objects(objects);
- foreach (var group in this._selection_actions)
- group.visible = true;
- }
-
- public void ensure_updated() {
- this._ui_manager.ensure_update();
- }
-
- public void include_actions(Gtk.ActionGroup group) {
- this._ui_manager.insert_action_group(group, 10);
-
- if (group is Actions) {
- var actions = (Actions)group;
- actions.catalog = this;
-
- var definition = actions.definition;
- if (definition != null) {
- try {
- this._ui_manager.add_ui_from_string (definition, -1);
- } catch (GLib.Error err) {
- GLib.warning ("couldn't add ui defintion for action group: %s: %s",
- actions.name, definition);
- }
- }
- }
-
- this._actions.add(group);
- }
+ ((SimpleAction) lookup_action("properties-object")).set_enabled(can_properties);
+ ((SimpleAction) lookup_action("edit-delete")).set_enabled(can_delete);;
+ ((SimpleAction) lookup_action("copy")).set_enabled(can_export);
+ ((SimpleAction) lookup_action("file-export")).set_enabled(can_export);
+ }
public void show_properties(GLib.Object obj) {
Viewable.view(obj, this);
}
- public void show_context_menu(string name, Gdk.Event? event) {
- var widget = this._ui_manager.get_widget("/%s".printf(name));
-
- Gtk.Menu? menu = widget as Gtk.Menu;
- if (menu == null) {
- warning("the object /%s isn't a menu", name);
- return;
+ public void show_context_menu(Gdk.Event? event) {
+ Gtk.Menu menu = new Gtk.Menu.from_model(this.context_menu);
+ menu.insert_action_group("win", this);
+ foreach (weak Backend backend in get_backends()) {
+ ActionGroup actions = backend.actions;
+ menu.insert_action_group(actions.prefix, actions);
}
menu.popup_at_pointer(event);
menu.show();
}
- private GLib.List<Gtk.ActionGroup> lookup_actions_for_objects (GLib.List<GLib.Object> objects) {
- var table = new GLib.HashTable<Gtk.ActionGroup, weak Gtk.ActionGroup>(GLib.direct_hash,
GLib.direct_equal);
- foreach (var object in objects) {
- Gtk.ActionGroup? actions = null;
- object.get("actions", out actions, null);
- if (actions == null)
- continue;
- if (!this._actions.contains(actions))
- this.include_actions(actions);
- this._actions.add(actions);
- }
-
- var iter = GLib.HashTableIter<Gtk.ActionGroup, weak Gtk.ActionGroup>(table);
- var results = new GLib.List<Gtk.ActionGroup>();
- Gtk.ActionGroup group;
- while (iter.next(out group, null))
- results.prepend(group);
-
- return results;
- }
-
- [CCode (instance_pos = -1)]
- private void on_app_preferences (Gtk.Action action) {
- Prefs prefs_dialog = new Prefs(this);
- prefs_dialog.run();
- prefs_dialog.destroy();
- }
-
- private const string[] AUTHORS = {
- "Jacob Perkins <jap1 users sourceforge net>",
- "Jose Carlos Garcia Sogo <jsogo users sourceforge net>",
- "Jean Schurger <yshark schurger org>",
- "Stef Walter <stef memberwebs com>",
- "Adam Schreiber <sadam clemson edu>",
- "Niels De Graef <nielsdegraef gmail com>",
- "",
- N_("Contributions:"),
- "Albrecht Dreß <albrecht dress arcor de>",
- "Jim Pharis <binbrain gmail com>",
- null
- };
-
- private const string[] DOCUMENTERS = {
- "Jacob Perkins <jap1 users sourceforge net>",
- "Adam Schreiber <sadam clemson edu>",
- "Milo Casagrande <milo_casagrande yahoo it>",
- null
- };
-
- private const string[] ARTISTS = {
- "Jacob Perkins <jap1 users sourceforge net>",
- "Stef Walter <stef memberwebs com>",
- null
- };
-
- [CCode (instance_pos = -1)]
- private void on_app_about(Gtk.Action action) {
- var about = new Gtk.AboutDialog();
- about.set_artists(ARTISTS);
- about.set_authors(AUTHORS);
- about.set_documenters(DOCUMENTERS);
- about.set_version(Config.VERSION);
- about.set_comments(_("Passwords and Keys"));
- about.set_copyright("© 2002 - 2018 Seahorse Contributors");
- about.set_translator_credits(_("translator-credits"));
- about.set_logo_icon_name("seahorse");
- about.set_website("https://wiki.gnome.org/Apps/Seahorse");
- about.set_website_label(_("Seahorse Project Homepage"));
-
- about.response.connect((response) => {
- about.hide();
- });
-
- about.set_transient_for(this);
- about.run();
- about.destroy();
- }
-
- [CCode (instance_pos = -1)]
- private void on_object_delete(Gtk.Action action)
- {
+ private void on_object_delete(SimpleAction action, Variant? param) {
try {
var objects = this.get_selected_objects();
Deletable.delete_with_prompt_wait(objects, this);
@@ -274,31 +117,21 @@ public abstract class Catalog : Gtk.ApplicationWindow {
}
}
- [CCode (instance_pos = -1)]
- private void on_properties_object(Gtk.Action action) {
+ private void on_properties_object(SimpleAction action, Variant? param) {
var objects = get_selected_objects();
if (objects.length() > 0)
- this.show_properties(objects.data);
- }
-
- [CCode (instance_pos = -1)]
- private void on_properties_place (Gtk.Action action) {
- var place = this.get_focused_place ();
- if (place != null)
- this.show_properties (place);
+ show_properties(objects.data);
}
- [CCode (instance_pos = -1)]
- private void on_key_export_file (Gtk.Action action) {
+ private void on_key_export_file(SimpleAction action, Variant? param) {
try {
- Exportable.export_to_prompt_wait(this.get_selected_objects(), this);
+ Exportable.export_to_prompt_wait(get_selected_objects(), this);
} catch (GLib.Error err) {
Util.show_error(this, _("Couldn’t export keys"), err.message);
}
}
- [CCode (instance_pos = -1)]
- private void on_key_export_clipboard (Gtk.Action action) {
+ private void on_key_export_clipboard (SimpleAction action, Variant? param) {
uint8[] output;
try {
var objects = this.get_selected_objects ();
@@ -313,43 +146,6 @@ public abstract class Catalog : Gtk.ApplicationWindow {
var board = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD);
board.set_text ((string)output, output.length);
}
-
- [CCode (instance_pos = -1)]
- private void on_help_show(Gtk.Action action) {
- try {
- var document = "help:%s".printf(Config.PACKAGE);
- GLib.AppInfo.launch_default_for_uri(document, null);
- } catch (GLib.Error err) {
- Util.show_error(this, _("Could not display help: %s"), err.message);
- }
- }
-
- private const Gtk.ActionEntry[] UI_ENTRIES = {
- /* Top menu items */
- { "file-menu", null, N_("_File") },
- { "file-export", null, N_("E_xport…"), null,
- N_("Export to a file"), on_key_export_file },
- { "edit-menu", null, N_("_Edit") },
- { "edit-export-clipboard", null, N_("_Copy"), "<control>C",
- N_("Copy to the clipboard"), on_key_export_clipboard },
- /*Translators: This text refers to deleting an item from its type's backing store*/
- { "edit-delete", null, N_("_Delete"), null,
- N_("Delete selected items"), on_object_delete },
- { "properties-object", null, N_("_Properties"), null,
- N_("Show the properties of this item"), on_properties_object },
- { "properties-keyring", null, N_("_Properties"), null,
- N_("Show the properties of this keyring"), on_properties_place },
- { "app-preferences", null, N_("Prefere_nces"), null,
- N_("Change preferences for this program"), on_app_preferences },
- { "view-menu", null, N_("_View") },
- { "help-menu", null, N_("_Help") },
- { "app-about", null, N_("_About"), null,
- N_("About this program"), on_app_about },
- { "help-show", null, N_("_Contents"), "F1",
- N_("Show Seahorse help"), on_help_show }
- };
-
-
}
}
diff --git a/common/key-manager-store.vala b/common/key-manager-store.vala
index 16a811ae..d7e7aa9a 100644
--- a/common/key-manager-store.vala
+++ b/common/key-manager-store.vala
@@ -49,12 +49,14 @@ public class Seahorse.KeyManagerStore : Gcr.CollectionModel {
switch (str) {
case null:
case "":
+ case "any":
return ShowFilter.ANY;
case "personal":
return ShowFilter.PERSONAL;
case "trusted":
return ShowFilter.TRUSTED;
default:
+ critical ("Got unknown ShowFilter string: %s", str);
assert_not_reached();
}
}
diff --git a/common/object.vala b/common/object.vala
index 52f4435a..4fa7bfc1 100644
--- a/common/object.vala
+++ b/common/object.vala
@@ -31,11 +31,6 @@ public class Seahorse.Object : GLib.Object {
*/
public weak Place place { get; set; default = null; }
- /**
- * Actions for the object
- */
- public Gtk.ActionGroup? actions { get; set; default = null; }
-
/**
* Stock ID for this Object.
*/
diff --git a/gkr/gkr-backend.vala b/gkr/gkr-backend.vala
index 1abdab52..6d74ac1c 100644
--- a/gkr/gkr-backend.vala
+++ b/gkr/gkr-backend.vala
@@ -47,9 +47,9 @@ public class Backend: GLib.Object , Gcr.Collection, Seahorse.Backend {
get { return _("Stored personal passwords, credentials and secrets"); }
}
- public Gtk.ActionGroup? actions {
- owned get { return this._actions; }
- }
+ public ActionGroup actions {
+ owned get { return this._actions; }
+ }
public GLib.HashTable<string, string> aliases {
get { return this._aliases; }
@@ -68,7 +68,7 @@ public class Backend: GLib.Object , Gcr.Collection, Seahorse.Backend {
private Secret.Service _service;
private GLib.HashTable<string, Keyring> _keyrings;
private GLib.HashTable<string, string> _aliases;
- private Gtk.ActionGroup _actions;
+ private ActionGroup _actions;
construct {
return_val_if_fail(_instance == null, null);
@@ -100,7 +100,7 @@ public class Backend: GLib.Object , Gcr.Collection, Seahorse.Backend {
public override void dispose() {
this._aliases.remove_all();
this._keyrings.remove_all();
- this._actions.sensitive = false;
+ /* this._actions.sensitive = false; */
base.dispose();
}
@@ -208,14 +208,18 @@ public class Backend: GLib.Object , Gcr.Collection, Seahorse.Backend {
}
}
-public class BackendActions : Seahorse.Actions {
+public class BackendActions : Seahorse.ActionGroup {
public Backend backend { construct; get; }
private static WeakRef _instance;
private bool _initialized;
+ private const ActionEntry[] BACKEND_ACTIONS = {
+ { "keyring-new", on_new_keyring },
+ { "keyring-item-new", on_new_item },
+ };
+
construct {
this._initialized = false;
- this.set_translation_domain(Config.GETTEXT_PACKAGE);
this.backend.notify.connect_after((pspec) => {
if (pspec.name == "service")
@@ -226,53 +230,41 @@ public class BackendActions : Seahorse.Actions {
return;
this._initialized = true;
- this.add_actions(BACKEND_ACTIONS, null);
- this.register_definition(BACKEND_UI);
-
- /* Register another set of actions as a generator */
- var actions = new Gtk.ActionGroup("gkr-generate");
- actions.set_translation_domain(Config.GETTEXT_PACKAGE);
- actions.add_actions(ENTRIES_NEW, null);
- Registry.register_object(actions, "generator");
+ add_action_entries(BACKEND_ACTIONS, this);
+ register_generator_actions();
});
this.backend.notify_property("service");
}
private BackendActions(Backend backend) {
- GLib.Object(name: "KeyringBackend", backend: backend);
- }
-
- private static void on_new_keyring(Gtk.Action action) {
- new KeyringAdd(Action.get_window(action));
+ GLib.Object(
+ prefix: "gkr",
+ backend: backend
+ );
}
- private static void on_new_item(Gtk.Action action) {
- new ItemAdd(Action.get_window(action));
- }
+ public void register_generator_actions() {
+ var new_keyring_action = lookup_action("keyring-new");
+ new_keyring_action.set_data("label", _("Password keyring"));
+ new_keyring_action.set_data("description", _("Used to store application and network passwords"));
+ Registry.register_object(new_keyring_action, "generator");
- private const Gtk.ActionEntry[] BACKEND_ACTIONS = {
- { "keyring-new", null, N_("New password keyring"), "",
- N_("Used to store application and network passwords"), on_new_keyring },
- { "keyring-item-new", null, N_("New password…"), "",
- N_("Safely store a password or secret."), on_new_item },
- };
+ var new_pw_action = lookup_action("keyring-item-new");
+ new_pw_action.set_data("label", _("Password"));
+ new_pw_action.set_data("description", _("Safely store a password or secret."));
+ Registry.register_object(new_pw_action, "generator");
+ }
- private const Gtk.ActionEntry[] ENTRIES_NEW = {
- { "keyring-new", "folder", N_("Password Keyring"), "",
- N_("Used to store application and network passwords"), on_new_keyring },
- { "keyring-item-new", ICON_PASSWORD, N_("Stored Password"), "",
- N_("Safely store a password or secret."), on_new_item }
- };
+ private void on_new_keyring(SimpleAction action, Variant? param) {
+ new KeyringAdd(this.catalog);
+ }
- private const string BACKEND_UI =
- """"<ui>
- <popup name='SeahorseGkrBackend'>
- <menuitem action='keyring-new'/>
- </popup>
- </ui>""";
+ private void on_new_item(SimpleAction action, Variant? param) {
+ new ItemAdd(this.catalog);
+ }
- public static Gtk.ActionGroup instance(Backend backend) {
+ public static ActionGroup instance(Backend backend) {
BackendActions? actions = (BackendActions?)_instance.get();
if (actions != null)
return actions;
diff --git a/gkr/gkr-keyring.vala b/gkr/gkr-keyring.vala
index 096bb0ae..306c6a19 100644
--- a/gkr/gkr-keyring.vala
+++ b/gkr/gkr-keyring.vala
@@ -163,7 +163,8 @@ public class Keyring : Secret.Collection, Gcr.Collection, Place, Deletable, Lock
[CCode (instance_pos = -1)]
public void on_keyring_default(Gtk.Action? action) {
- var parent = (action != null)? Action.get_window(action) : null;
+ /* var parent = (action != null)? Action.get_window(action) : null; */
+ var parent = null;
var service = this.service;
service.set_alias.begin("default", this, null, (obj, res) => {
@@ -178,7 +179,8 @@ public class Keyring : Secret.Collection, Gcr.Collection, Place, Deletable, Lock
[CCode (instance_pos = -1)]
public void on_keyring_password (Gtk.Action? action) {
- var parent = (action != null)? Action.get_window(action) : null;
+ /* var parent = (action != null)? Action.get_window(action) : null; */
+ var parent = null;
var service = this.service;
service.get_connection().call.begin(service.get_name(),
service.get_object_path(),
diff --git a/pgp/seahorse-gpgme-generate.c b/pgp/seahorse-gpgme-generate.c
index 466b2b9f..abcf6a82 100644
--- a/pgp/seahorse-gpgme-generate.c
+++ b/pgp/seahorse-gpgme-generate.c
@@ -60,58 +60,6 @@ void on_gpgme_generate_expires_toggled (GtkToggleButton *b
void on_gpgme_generate_algorithm_changed (GtkComboBox *combo,
gpointer user_data);
-/* --------------------------------------------------------------------------
- * ACTIONS
- */
-
-/**
- * on_pgp_generate_key:
- * @action: verified to be an action, not more
- * @unused: not used
- *
- * Calls the function that displays the key creation dialog
- *
- */
-static void
-on_pgp_generate_key (GtkAction *action, gpointer unused)
-{
- SeahorseGpgmeKeyring* keyring;
-
- g_return_if_fail (GTK_IS_ACTION (action));
-
- keyring = seahorse_pgp_backend_get_default_keyring (NULL);
- g_return_if_fail (keyring != NULL);
-
- seahorse_gpgme_generate_show (keyring,
- seahorse_action_get_window (action),
- NULL, NULL, NULL);
-}
-
-static const GtkActionEntry ACTION_ENTRIES[] = {
- { "pgp-generate-key", GCR_ICON_KEY_PAIR, N_ ("PGP Key"), "",
- N_("Used to encrypt email and files"), G_CALLBACK (on_pgp_generate_key) }
-};
-
-/**
- * seahorse_gpgme_generate_register:
- *
- * Registers the action group for the pgp key creation dialog
- *
- */
-void
-seahorse_gpgme_generate_register (void)
-{
- GtkActionGroup *actions;
-
- actions = gtk_action_group_new ("gpgme-generate");
-
- gtk_action_group_set_translation_domain (actions, GETTEXT_PACKAGE);
- gtk_action_group_add_actions (actions, ACTION_ENTRIES, G_N_ELEMENTS (ACTION_ENTRIES), NULL);
-
- /* Register this as a generator */
- seahorse_registry_register_object (G_OBJECT (actions), "generator");
-}
-
/* --------------------------------------------------------------------------
* DIALOGS
*/
diff --git a/pgp/seahorse-gpgme-key.c b/pgp/seahorse-gpgme-key.c
index ac52c2a9..69807de5 100644
--- a/pgp/seahorse-gpgme-key.c
+++ b/pgp/seahorse-gpgme-key.c
@@ -308,7 +308,7 @@ void
seahorse_gpgme_key_realize (SeahorseGpgmeKey *self)
{
SeahorseUsage usage;
- GtkActionGroup *actions;
+ /* GtkActionGroup *actions; */
guint flags;
if (!self->pv->pubkey)
@@ -359,13 +359,13 @@ seahorse_gpgme_key_realize (SeahorseGpgmeKey *self)
usage = SEAHORSE_USAGE_PUBLIC_KEY;
}
- actions = seahorse_gpgme_key_actions_instance ();
+ /* actions = seahorse_gpgme_key_actions_instance (); */
g_object_set (self,
"usage", usage,
"object-flags", flags,
- "actions", actions,
+ /* "actions", actions, */
NULL);
- g_object_unref (actions);
+ /* g_object_unref (actions); */
seahorse_pgp_key_realize (SEAHORSE_PGP_KEY (self));
}
diff --git a/pgp/seahorse-pgp-actions.c b/pgp/seahorse-pgp-actions.c
index 3bffb92d..dd17b437 100644
--- a/pgp/seahorse-pgp-actions.c
+++ b/pgp/seahorse-pgp-actions.c
@@ -47,48 +47,43 @@ GType seahorse_pgp_backend_actions_get_type (void) G_GNUC_CONST;
#define SEAHORSE_PGP_BACKEND_ACTIONS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),
SEAHORSE_PGP_TYPE_BACKEND_ACTIONS, SeahorsePgpBackendActionsClass))
typedef struct {
- SeahorseActions parent_instance;
+ SeahorseActionGroup parent_instance;
} SeahorsePgpBackendActions;
typedef struct {
- SeahorseActionsClass parent_class;
+ SeahorseActionGroupClass parent_class;
} SeahorsePgpBackendActionsClass;
-G_DEFINE_TYPE (SeahorsePgpBackendActions, seahorse_pgp_backend_actions, SEAHORSE_TYPE_ACTIONS);
+G_DEFINE_TYPE (SeahorsePgpBackendActions, seahorse_pgp_backend_actions, SEAHORSE_TYPE_ACTION_GROUP);
#ifdef WITH_KEYSERVER
-static const gchar* BACKEND_DEFINITION = ""\
-"<ui>"\
-" <menubar>"\
-" <placeholder name='RemoteMenu'>"\
-" <menu name='Remote' action='remote-menu'>"\
-" <menuitem action='remote-find'/>"\
-" <menuitem action='remote-sync'/>"\
-" </menu>"\
-" </placeholder>"\
-" </menubar>"\
-"</ui>";
-
static void
-on_remote_find (GtkAction* action,
+on_remote_find (GSimpleAction *action,
+ GVariant *param,
gpointer user_data)
{
- seahorse_keyserver_search_show (seahorse_action_get_window (action));
+ SeahorseActionGroup *actions = SEAHORSE_ACTION_GROUP (user_data);
+ SeahorseCatalog *catalog;
+
+ catalog = seahorse_action_group_get_catalog (actions);
+ seahorse_keyserver_search_show (GTK_WINDOW (catalog));
+ g_clear_object (&catalog);
}
static void
-on_remote_sync (GtkAction* action,
+on_remote_sync (GSimpleAction *action,
+ GVariant *param,
gpointer user_data)
{
- SeahorseActions *actions = SEAHORSE_ACTIONS (user_data);
+ SeahorseActionGroup *actions = SEAHORSE_ACTION_GROUP (user_data);
SeahorseGpgmeKeyring *keyring;
SeahorseCatalog *catalog;
GList *objects = NULL;
GList *keys = NULL;
GList *l;
- catalog = seahorse_actions_get_catalog (actions);
+ catalog = seahorse_action_group_get_catalog (actions);
if (catalog != NULL) {
objects = seahorse_catalog_get_selected_objects (catalog);
for (l = objects; l != NULL; l = g_list_next (l)) {
@@ -104,34 +99,59 @@ on_remote_sync (GtkAction* action,
keys = gcr_collection_get_objects (GCR_COLLECTION (keyring));
}
- seahorse_keyserver_sync_show (keys, seahorse_action_get_window (action));
+ seahorse_keyserver_sync_show (keys, GTK_WINDOW (catalog));
g_list_free (keys);
}
-static const GtkActionEntry FIND_ACTIONS[] = {
- { "remote-find", GTK_STOCK_FIND, N_("_Find Remote Keys…"), "",
- N_("Search for keys on a key server"), G_CALLBACK (on_remote_find) },
-};
+#endif /* WITH_KEYSERVER */
-static const GtkActionEntry SYNC_ACTIONS[] = {
- { "remote-sync", GTK_STOCK_REFRESH, N_("_Sync and Publish Keys…"), "",
- N_("Publish and/or synchronize your keys with those online."), G_CALLBACK (on_remote_sync) }
-};
+static void
+on_pgp_generate_key (GSimpleAction *action,
+ GVariant *param,
+ gpointer user_data)
+{
+ SeahorseActionGroup *actions = SEAHORSE_ACTION_GROUP (user_data);
+ SeahorseGpgmeKeyring* keyring;
+ SeahorseCatalog *catalog;
+
+ keyring = seahorse_pgp_backend_get_default_keyring (NULL);
+ g_return_if_fail (keyring != NULL);
+
+ catalog = seahorse_action_group_get_catalog (actions);
+ seahorse_gpgme_generate_show (keyring,
+ GTK_WINDOW (catalog),
+ NULL, NULL, NULL);
+ g_clear_object (&catalog);
+}
+static const GActionEntry ACTION_ENTRIES[] = {
+ { "pgp-generate-key", on_pgp_generate_key },
+#ifdef WITH_KEYSERVER
+ { "remote-sync", on_remote_sync },
+ { "remote-find", on_remote_find }
#endif /* WITH_KEYSERVER */
+};
static void
seahorse_pgp_backend_actions_init (SeahorsePgpBackendActions *self)
{
-#ifdef WITH_KEYSERVER
- GtkActionGroup *actions = GTK_ACTION_GROUP (self);
- gtk_action_group_set_translation_domain (actions, GETTEXT_PACKAGE);
- gtk_action_group_add_actions (actions, FIND_ACTIONS,
- G_N_ELEMENTS (FIND_ACTIONS), NULL);
- gtk_action_group_add_actions (actions, SYNC_ACTIONS,
- G_N_ELEMENTS (SYNC_ACTIONS), self);
- seahorse_actions_register_definition (SEAHORSE_ACTIONS (self), BACKEND_DEFINITION);
-#endif
+ GActionMap *action_map = G_ACTION_MAP (self);
+ GAction *generator_action = NULL;
+
+ g_action_map_add_action_entries (action_map,
+ ACTION_ENTRIES,
+ G_N_ELEMENTS (ACTION_ENTRIES),
+ self);
+
+ /* Register generator actions */
+ generator_action = g_action_map_lookup_action (action_map,
+ "pgp-generate-key");
+ g_object_set_data (G_OBJECT (generator_action),
+ "label", _("PGP Key"));
+ g_object_set_data (G_OBJECT (generator_action),
+ "description", _("Used to encrypt email and files"));
+ seahorse_registry_register_object (G_OBJECT (generator_action),
+ "generator");
}
static void
@@ -140,14 +160,14 @@ seahorse_pgp_backend_actions_class_init (SeahorsePgpBackendActionsClass *klass)
}
-GtkActionGroup *
+SeahorseActionGroup *
seahorse_pgp_backend_actions_instance (void)
{
- static GtkActionGroup *actions = NULL;
+ static SeahorseActionGroup *actions = NULL;
if (actions == NULL) {
actions = g_object_new (SEAHORSE_PGP_TYPE_BACKEND_ACTIONS,
- "name", "pgp-backend",
+ "prefix", "pgp",
NULL);
g_object_add_weak_pointer (G_OBJECT (actions),
(gpointer *)&actions);
@@ -167,24 +187,18 @@ GType seahorse_gpgme_key_actions_get_type (void) G_GNUC_CONST;
#define seahorse_gpgme_key_actions_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),
SEAHORSE_PGP_TYPE_ACTIONS, SeahorseGpgmeKeyActionsClass))
typedef struct {
- SeahorseActions parent_instance;
+ SeahorseActionGroup parent_instance;
} SeahorseGpgmeKeyActions;
typedef struct {
- SeahorseActionsClass parent_class;
+ SeahorseActionGroupClass parent_class;
} SeahorseGpgmeKeyActionsClass;
-G_DEFINE_TYPE (SeahorseGpgmeKeyActions, seahorse_gpgme_key_actions, SEAHORSE_TYPE_ACTIONS);
+G_DEFINE_TYPE (SeahorseGpgmeKeyActions, seahorse_gpgme_key_actions, SEAHORSE_TYPE_ACTION_GROUP);
static void
seahorse_gpgme_key_actions_init (SeahorseGpgmeKeyActions *self)
{
-#ifdef WITH_KEYSERVER
- GtkActionGroup *actions = GTK_ACTION_GROUP (self);
- gtk_action_group_set_translation_domain (actions, GETTEXT_PACKAGE);
- gtk_action_group_add_actions (actions, SYNC_ACTIONS,
- G_N_ELEMENTS (SYNC_ACTIONS), NULL);
-#endif
}
static void
@@ -193,14 +207,14 @@ seahorse_gpgme_key_actions_class_init (SeahorseGpgmeKeyActionsClass *klass)
}
-GtkActionGroup *
+SeahorseActionGroup *
seahorse_gpgme_key_actions_instance (void)
{
- static GtkActionGroup *actions = NULL;
+ static SeahorseActionGroup *actions = NULL;
if (actions == NULL) {
actions = g_object_new (SEAHORSE_TYPE_GPGME_KEY_ACTIONS,
- "name", "gpgme-key",
+ "prefix", "gpgme",
NULL);
g_object_add_weak_pointer (G_OBJECT (actions),
(gpointer *)&actions);
diff --git a/pgp/seahorse-pgp-actions.h b/pgp/seahorse-pgp-actions.h
index 2e131442..12370321 100644
--- a/pgp/seahorse-pgp-actions.h
+++ b/pgp/seahorse-pgp-actions.h
@@ -21,8 +21,8 @@
#pragma once
-#include <gtk/gtk.h>
+#include <seahorse-common.h>
-GtkActionGroup * seahorse_pgp_backend_actions_instance (void);
+SeahorseActionGroup * seahorse_pgp_backend_actions_instance (void);
-GtkActionGroup * seahorse_gpgme_key_actions_instance (void);
+SeahorseActionGroup * seahorse_gpgme_key_actions_instance (void);
diff --git a/pgp/seahorse-pgp-backend.c b/pgp/seahorse-pgp-backend.c
index fa190cd3..a525b1c1 100644
--- a/pgp/seahorse-pgp-backend.c
+++ b/pgp/seahorse-pgp-backend.c
@@ -54,7 +54,7 @@ struct _SeahorsePgpBackend {
SeahorseDiscovery *discovery;
SeahorseUnknownSource *unknown;
GHashTable *remotes;
- GtkActionGroup *actions;
+ SeahorseActionGroup *actions;
gboolean loaded;
};
@@ -77,8 +77,6 @@ seahorse_pgp_backend_init (SeahorsePgpBackend *self)
g_free, g_object_unref);
self->actions = seahorse_pgp_backend_actions_instance ();
-
- seahorse_gpgme_generate_register ();
}
#ifdef WITH_KEYSERVER
@@ -195,7 +193,7 @@ seahorse_pgp_backend_get_description (SeahorseBackend *backend)
return _("PGP keys are for encrypting email or files");
}
-static GtkActionGroup *
+static SeahorseActionGroup *
seahorse_pgp_backend_get_actions (SeahorseBackend *backend)
{
SeahorsePgpBackend *self = SEAHORSE_PGP_BACKEND (backend);
diff --git a/pkcs11/pkcs11-generate.vala b/pkcs11/pkcs11-generate.vala
index 8e72cd72..adb575aa 100644
--- a/pkcs11/pkcs11-generate.vala
+++ b/pkcs11/pkcs11-generate.vala
@@ -273,22 +273,4 @@ public class Seahorse.Pkcs11.Generate : Gtk.Dialog {
publi.clear();
priva.clear();
}
-
- private static void on_generate_activate(Gtk.Action action) {
- Generate dialog = new Generate(null);
- dialog.run();
- dialog.destroy();
- }
-
- private const Gtk.ActionEntry ACTION_ENTRIES[] = {
- { "pkcs11-generate-key", Gcr.ICON_KEY_PAIR, N_ ("Private key"), "",
- N_("Used to request a certificate"), on_generate_activate }
- };
-
- public static void register () {
- Gtk.ActionGroup actions = new Gtk.ActionGroup("pkcs11-generate");
- actions.set_translation_domain(Config.GETTEXT_PACKAGE);
- actions.add_actions(ACTION_ENTRIES, null);
- Registry.register_object(actions, "generator");
- }
}
diff --git a/pkcs11/seahorse-pkcs11-backend.c b/pkcs11/seahorse-pkcs11-backend.c
index fe907635..15318040 100644
--- a/pkcs11/seahorse-pkcs11-backend.c
+++ b/pkcs11/seahorse-pkcs11-backend.c
@@ -49,6 +49,7 @@ static SeahorsePkcs11Backend *pkcs11_backend = NULL;
struct _SeahorsePkcs11Backend {
GObject parent;
+ SeahorseActionGroup *actions;
GList *tokens;
GList *blacklist;
gboolean loaded;
@@ -65,6 +66,13 @@ static const char *token_blacklist[] = {
NULL
};
+static void
+on_generate_activate (GSimpleAction *action, GVariant *param, gpointer user_data);
+
+static const GActionEntry ACTION_ENTRIES[] = {
+ { "pkcs11-generate-key", on_generate_activate }
+};
+
static void seahorse_pkcs11_backend_iface (SeahorseBackendIface *iface);
static void seahorse_pkcs11_backend_collection_init (GcrCollectionIface *iface);
@@ -74,6 +82,30 @@ G_DEFINE_TYPE_WITH_CODE (SeahorsePkcs11Backend, seahorse_pkcs11_backend, G_TYPE_
G_IMPLEMENT_INTERFACE (SEAHORSE_TYPE_BACKEND, seahorse_pkcs11_backend_iface);
);
+static void
+init_actions (SeahorsePkcs11Backend *self)
+{
+ GAction *generator_action;
+
+ self->actions = g_object_new (SEAHORSE_TYPE_ACTION_GROUP,
+ "prefix", "pkcs11",
+ NULL);
+ g_action_map_add_action_entries (G_ACTION_MAP (self->actions),
+ ACTION_ENTRIES,
+ G_N_ELEMENTS (ACTION_ENTRIES),
+ self->actions);
+
+ /* Register the generator actions */
+ generator_action = g_action_map_lookup_action(G_ACTION_MAP (self->actions),
+ "pkcs11-generate-key");
+ g_object_set_data (G_OBJECT (generator_action),
+ "label", _("Private key"));
+ g_object_set_data (G_OBJECT (generator_action),
+ "description", _("Used to request a certificate"));
+ seahorse_registry_register_object (G_OBJECT (generator_action),
+ "generator");
+}
+
static void
seahorse_pkcs11_backend_init (SeahorsePkcs11Backend *self)
{
@@ -93,7 +125,7 @@ seahorse_pkcs11_backend_init (SeahorsePkcs11Backend *self)
self->blacklist = g_list_prepend (self->blacklist, uri);
}
- seahorse_pkcs11_generate_register ();
+ init_actions (self);
}
static gboolean
@@ -201,10 +233,10 @@ seahorse_pkcs11_backend_get_loaded (SeahorseBackend *backend)
return SEAHORSE_PKCS11_BACKEND (backend)->loaded;
}
-static GtkActionGroup *
+static SeahorseActionGroup *
seahorse_pkcs11_backend_get_actions (SeahorseBackend *backend)
{
- return NULL;
+ return g_object_ref (SEAHORSE_PKCS11_BACKEND (backend)->actions);
}
static void
@@ -254,6 +286,7 @@ seahorse_pkcs11_backend_finalize (GObject *obj)
SeahorsePkcs11Backend *self = SEAHORSE_PKCS11_BACKEND (obj);
g_list_free_full (self->blacklist, (GDestroyNotify)gck_uri_data_free);
+ g_clear_object (&self->actions);
g_assert (self->tokens == NULL);
g_return_if_fail (pkcs11_backend == self);
pkcs11_backend = NULL;
@@ -404,3 +437,19 @@ seahorse_pkcs11_backend_get_writable_tokens (SeahorsePkcs11Backend *self,
on_filter_writable,
mechanism, NULL);
}
+
+static void
+on_generate_activate (GSimpleAction *action,
+ GVariant *param,
+ gpointer user_data)
+{
+ SeahorseActionGroup *actions = SEAHORSE_ACTION_GROUP (user_data);
+ SeahorseCatalog *catalog;
+ SeahorsePkcs11Generate *dialog;
+
+ catalog = seahorse_action_group_get_catalog (actions);
+ dialog = seahorse_pkcs11_generate_new (GTK_WINDOW (catalog));
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+ g_clear_object (&catalog);
+}
diff --git a/src/application.vala b/src/application.vala
index e4762670..102a4e94 100644
--- a/src/application.vala
+++ b/src/application.vala
@@ -25,6 +25,42 @@ public class Seahorse.Application : Gtk.Application {
private SearchProvider? search_provider;
private uint search_provider_dbus_id = 0;
+ private KeyManager? key_mgr = null;
+
+ private const string[] AUTHORS = {
+ "Jacob Perkins <jap1 users sourceforge net>",
+ "Jose Carlos Garcia Sogo <jsogo users sourceforge net>",
+ "Jean Schurger <yshark schurger org>",
+ "Stef Walter <stef memberwebs com>",
+ "Adam Schreiber <sadam clemson edu>",
+ "Niels De Graef <nielsdegraef gmail com>",
+ "",
+ N_("Contributions:"),
+ "Albrecht Dreß <albrecht dress arcor de>",
+ "Jim Pharis <binbrain gmail com>",
+ null
+ };
+
+ private const string[] DOCUMENTERS = {
+ "Jacob Perkins <jap1 users sourceforge net>",
+ "Adam Schreiber <sadam clemson edu>",
+ "Milo Casagrande <milo_casagrande yahoo it>",
+ null
+ };
+
+ private const string[] ARTISTS = {
+ "Jacob Perkins <jap1 users sourceforge net>",
+ "Stef Walter <stef memberwebs com>",
+ null
+ };
+
+ private const GLib.ActionEntry[] action_entries = {
+ { "quit", quit },
+ { "help", on_app_help },
+ { "about", on_app_about },
+ { "preferences", on_app_preferences },
+ };
+
const OptionEntry[] cmd_options = {
{ "version", 'v', 0, OptionArg.NONE, null, N_("Version of this application"), null },
{ null }
@@ -36,9 +72,25 @@ public class Seahorse.Application : Gtk.Application {
flags: ApplicationFlags.FLAGS_NONE
);
this.search_provider = new SearchProvider(this);
+
+ add_action_entries(action_entries, this);
+ var pref_action = lookup_action("preferences") as SimpleAction;
+ pref_action.set_enabled(Prefs.available());
+ add_action_accelerators();
+
add_main_option_entries(cmd_options);
}
+ private void add_action_accelerators() {
+ set_accels_for_action ("app.help", {"F1"});
+ set_accels_for_action ("app.quit", {"<control>Q"});
+
+ set_accels_for_action ("win.new-item", { "<control>N" });
+ set_accels_for_action ("win.import-file", { "<control>I" });
+ set_accels_for_action ("win.copy", { "<control>C" });
+ set_accels_for_action ("win.paste", { "<control>V" });
+ }
+
public override void startup() {
base.startup();
@@ -57,12 +109,10 @@ public class Seahorse.Application : Gtk.Application {
}
public override void activate() {
- var key_mgr = get_active_window();
-
- if (key_mgr == null)
- key_mgr = new Seahorse.KeyManager(this);
+ if (get_active_window() == null)
+ this.key_mgr = new Seahorse.KeyManager(this);
- key_mgr.present();
+ this.key_mgr.present();
}
public override int handle_local_options (VariantDict options) {
@@ -97,4 +147,40 @@ public class Seahorse.Application : Gtk.Application {
public void initialize_search () {
this.search_provider.load.begin();
}
+
+ private void on_app_about(SimpleAction action, Variant? param) {
+ var about = new Gtk.AboutDialog();
+ about.set_artists(ARTISTS);
+ about.set_authors(AUTHORS);
+ about.set_documenters(DOCUMENTERS);
+ about.set_version(Config.VERSION);
+ about.set_comments(_("Passwords and Keys"));
+ about.set_copyright("© 2002 - 2018 Seahorse Contributors");
+ about.set_translator_credits(_("translator-credits"));
+ about.set_logo_icon_name("seahorse");
+ about.set_website("https://wiki.gnome.org/Apps/Seahorse");
+ about.set_website_label(_("Seahorse Project Homepage"));
+
+ about.response.connect((response) => {
+ about.hide();
+ });
+
+ about.set_transient_for(this.key_mgr);
+ about.run();
+ about.destroy();
+ }
+
+ private void on_app_help(SimpleAction action, Variant? param) {
+ try {
+ Gtk.show_uri_on_window(this.key_mgr, "help:seahorse", Gtk.get_current_event_time ());
+ } catch (GLib.Error err) {
+ warning("Error showing help: %s", err.message);
+ }
+ }
+
+ private void on_app_preferences(SimpleAction action, Variant? param) {
+ Prefs prefs_dialog = new Prefs(this.key_mgr);
+ prefs_dialog.run();
+ prefs_dialog.destroy();
+ }
}
diff --git a/src/generate-select.vala b/src/generate-select.vala
index 9bd42b0a..3c6e80b4 100644
--- a/src/generate-select.vala
+++ b/src/generate-select.vala
@@ -30,6 +30,8 @@ public class Seahorse.GenerateSelect : Gtk.Dialog {
[GtkChild]
private Gtk.ListBox generate_list;
+ private SimpleActionGroup action_group = new SimpleActionGroup();
+
public GenerateSelect(Gtk.Window? parent) {
GLib.Object(
use_header_bar: 1,
@@ -37,19 +39,16 @@ public class Seahorse.GenerateSelect : Gtk.Dialog {
modal: true
);
- ListStore store = new ListStore(typeof(Gtk.Action));
+ ListStore store = new ListStore(typeof(Action));
this.generate_list.bind_model(store, on_create_row);
- // Fill up the model
- var action_groups = (List<Gtk.ActionGroup>) Registry.object_instances("generator");
- foreach (var action_group in action_groups) {
- action_group.post_activate.connect(this.switch_view);
- foreach (var action in action_group.list_actions())
- store.append(action);
+ // Fetch and process the generator actions
+ var actions = (List<Action>) Registry.object_instances("generator");
+ foreach (var action in actions) {
+ this.action_group.add_action(action);
+ store.insert_sorted(action, compare_generator_actions);
}
- store.sort((a, b) => {
- return ((Gtk.Action) a).label.collate(((Gtk.Action) b).label);
- });
+ insert_action_group("gen", action_group);
// Select first item (and grab focus, so user can use the keyboard immediately)
weak Gtk.ListBoxRow? row = this.generate_list.get_row_at_index(0);
@@ -59,20 +58,19 @@ public class Seahorse.GenerateSelect : Gtk.Dialog {
}
}
+ private int compare_generator_actions(GLib.Object a, GLib.Object b) {
+ unowned string? a_label = a.get_data("label");
+ unowned string? b_label = b.get_data("label");
+ return a_label.collate(b_label);
+ }
+
private void switch_view(Gtk.Action action) {
string target = action.action_group.name.split("-", 2)[0];
((KeyManager) this.transient_for).set_focused_place(target);
}
private Gtk.ListBoxRow on_create_row(GLib.Object item) {
- return new GenerateSelectRow((Gtk.Action) item);
- }
-
- [GtkCallback]
- private void on_row_activated(Gtk.ListBoxRow row) {
- Gtk.Action action = ((GenerateSelectRow) row).action;
- Action.activate_with_window(action, null, this.transient_for);
- destroy();
+ return new GenerateSelectRow((Action) item);
}
public override void response(int response) {
@@ -83,16 +81,24 @@ public class Seahorse.GenerateSelect : Gtk.Dialog {
if (row == null)
return;
- Action.activate_with_window(row.action, null, this.transient_for);
+ row.activate();
+ }
+
+ [GtkCallback]
+ private void on_row_activated(Gtk.ListBox listbox, Gtk.ListBoxRow row) {
+ var generate_row = (GenerateSelectRow) row;
+ this.action_group.activate_action(generate_row.action_name, null);
+ destroy();
}
}
private class Seahorse.GenerateSelectRow : Gtk.ListBoxRow {
- private Gtk.Image icon;
private Gtk.Label title;
private Gtk.Label description;
- public Gtk.Action action { get; private set; }
+ // Note that we can't use the actual "action-name" property,
+ // or the row-activated signal doesn't get emitted for some reason
+ public unowned string? action_name;
construct {
var grid = new Gtk.Grid();
@@ -100,29 +106,22 @@ private class Seahorse.GenerateSelectRow : Gtk.ListBoxRow {
grid.margin = 3;
add(grid);
- this.icon = new Gtk.Image();
- this.icon.icon_size = Gtk.IconSize.DND;
- grid.attach(this.icon, 0, 0, 1, 2);
-
this.title = new Gtk.Label(null);
this.title.halign = Gtk.Align.START;
- grid.attach(this.title, 1, 0);
+ grid.attach(this.title, 0, 0);
this.description = new Gtk.Label(null);
this.description.get_style_context().add_class("dim-label");
- grid.attach(this.description, 1, 1);
+ grid.attach(this.description, 0, 1);
}
- public GenerateSelectRow(Gtk.Action action) {
- this.action = action;
+ public GenerateSelectRow(Action action) {
+ this.action_name = action.name;
- this.title.set_markup("<b>%s</b>".printf(action.label));
- this.description.label = action.tooltip;
+ unowned string? label = action.get_data<string?>("label");
- if (action.gicon != null)
- this.icon.gicon = action.gicon;
- else if (action.icon_name != null)
- this.icon.icon_name = action.icon_name;
+ this.title.set_markup("<b>%s</b>".printf(label));
+ this.description.label = action.get_data<string?>("description");
show_all();
}
diff --git a/src/key-manager.vala b/src/key-manager.vala
index 25870b1d..40d31866 100644
--- a/src/key-manager.vala
+++ b/src/key-manager.vala
@@ -24,56 +24,32 @@
public class Seahorse.KeyManager : Catalog {
[GtkChild]
- private Gtk.Container menu_placeholder;
- [GtkChild]
- private Gtk.TreeView key_list;
+ private Gtk.SearchEntry filter_entry;
+
[GtkChild]
private Gtk.Paned sidebar_panes;
[GtkChild]
- private Gtk.Button import_button;
- [GtkChild]
- private Gtk.Button new_button;
- [GtkChild]
- private Gtk.Button new_item_button;
- [GtkChild]
- private Gtk.SearchEntry filter_entry;
- [GtkChild]
private Gtk.Container sidebar_area;
private Sidebar sidebar;
- private Gtk.ActionGroup view_actions;
- private Gtk.RadioAction show_action;
-
+ [GtkChild]
+ private Gtk.TreeView key_list;
private Gcr.Collection collection;
private KeyManagerStore store;
private GLib.Settings settings;
- private int sidebar_width;
- private uint sidebar_width_sig;
private enum DndTarget { // Drag 'n Drop target type
PLAIN,
URIS
}
- private const Gtk.ActionEntry[] GENERAL_ACTIONS = {
- // TRANSLATORS: The "Remote" menu contains key operations on remote systems.
- { "remote-menu", null, N_("_Remote") },
- { "new-menu", null, N_("_New") },
- { "app-quit", null, N_("_Quit"), "<control>Q", N_("Close this program") },
- { "file-new", null, N_("_New…"), "<control>N", N_("Create a new key or item") },
- { "file-import", null, N_("_Import…"), "<control>I", N_("Import from a file") },
- { "edit-import-clipboard", null, N_("_Paste"), "<control>V", N_("Import from the clipboard") }
- };
-
- private const Gtk.ToggleActionEntry[] SIDEBAR_ACTIONS = {
- { "view-sidebar", null, N_("By _Keyring"), null, N_("Show sidebar listing keyrings"), null, false },
- };
-
- private const Gtk.RadioActionEntry[] VIEW_RADIO_ACTIONS = {
- { "view-personal", null, N_("Show _Personal"), null, N_("Only show personal keys, certificates and
passwords"), KeyManagerStore.ShowFilter.PERSONAL },
- { "view-trusted", null, N_("Show _Trusted"), null, N_("Only show trusted keys, certificates and
passwords"), KeyManagerStore.ShowFilter.TRUSTED },
- { "view-any", null, N_("Show _Any"), null, N_("Show all keys, certificates and passwords"),
KeyManagerStore.ShowFilter.ANY },
+ private const GLib.ActionEntry[] action_entries = {
+ { "new-item", on_new_item },
+ { "filter-items", on_filter_items, "s", "'any'" },
+ { "import-file", on_import_file },
+ { "combine-keyrings", on_toggle_action, null, "false", on_combine_keyrings_toggled },
+ { "paste", on_paste, },
};
public KeyManager(Application app) {
@@ -106,18 +82,8 @@ public class Seahorse.KeyManager : Catalog {
this.settings.changed["item-filter"].connect(on_item_filter_changed);
on_item_filter_changed(this.settings, "item-filter");
- // first time signals
- this.import_button.clicked.connect(on_keymanager_import_button);
- this.new_button.clicked.connect(on_keymanager_new_button);
-
- // Flush all updates
- ensure_updated();
-
- // The toolbar
- this.new_item_button.clicked.connect(on_keymanager_new_button);
- on_filter_changed(this.filter_entry);
-
// For the filtering
+ on_filter_changed(this.filter_entry);
this.filter_entry.search_changed.connect(on_filter_changed);
this.key_list.start_interactive_search.connect(() => {
this.filter_entry.grab_focus();
@@ -128,9 +94,6 @@ public class Seahorse.KeyManager : Catalog {
this.key_list.grab_focus();
selection_changed();
- // To avoid flicker
- show();
-
// Setup drops
Gtk.drag_dest_set(this, Gtk.DestDefaults.ALL, {}, Gdk.DragAction.COPY);
Gtk.TargetList targets = new Gtk.TargetList(null);
@@ -144,42 +107,8 @@ public class Seahorse.KeyManager : Catalog {
this.key_list.popup_menu.connect(on_keymanager_key_list_popup_menu);
}
- ~KeyManager() {
- if (this.sidebar_width_sig != 0) {
- Source.remove(this.sidebar_width_sig);
- this.sidebar_width_sig = 0;
- }
- }
-
private void init_actions() {
- // General actions
- Gtk.ActionGroup actions = new Gtk.ActionGroup("general");
- actions.set_translation_domain(Config.GETTEXT_PACKAGE);
- actions.add_actions(GENERAL_ACTIONS, null);
- actions.get_action("app-quit").activate.connect(on_app_quit);
- actions.get_action("file-new").activate.connect(on_file_new);
- actions.get_action("file-import").activate.connect(on_key_import_file);
- actions.get_action("edit-import-clipboard").activate.connect(on_key_import_clipboard);
- include_actions(actions);
-
- // View actions
- this.view_actions = new Gtk.ActionGroup("view");
- this.view_actions.set_translation_domain(Config.GETTEXT_PACKAGE);
- this.view_actions.add_radio_actions(VIEW_RADIO_ACTIONS, -1, () => {
- this.settings.set_string("item-filter", update_view_filter());
- });
- this.show_action = (Gtk.RadioAction) this.view_actions.get_action("view-personal");
- include_actions(this.view_actions);
-
- // Make sure import is only available with clipboard content
- Gtk.Clipboard clipboard = Gtk.Clipboard.get(Gdk.SELECTION_PRIMARY);
- clipboard.owner_change.connect((c, e) => update_clipboard_state(c, e, actions));
- update_clipboard_state(clipboard, null, actions);
- }
-
- protected override void add_menu(Gtk.Widget menu) {
- this.menu_placeholder.add(menu);
- menu.show();
+ add_action_entries (action_entries, this);
}
private void on_view_selection_changed(Gtk.TreeSelection selection) {
@@ -191,6 +120,14 @@ public class Seahorse.KeyManager : Catalog {
});
}
+ public override void selection_changed() {
+ base.selection_changed();
+
+ var objects = get_selected_objects();
+ foreach (weak Backend backend in get_backends())
+ backend.actions.set_actions_for_selected_objects(objects);
+ }
+
private void on_keymanager_row_activated(Gtk.TreeView key_list, Gtk.TreePath? path, Gtk.TreeViewColumn
column) {
if (path == null)
return;
@@ -202,7 +139,7 @@ public class Seahorse.KeyManager : Catalog {
private bool on_keymanager_key_list_button_pressed(Gdk.EventButton event) {
if (event.button == 3) {
- show_context_menu(Catalog.MENU_OBJECT, event);
+ show_context_menu(event);
GLib.List<GLib.Object> objects = get_selected_objects();
if (objects.length() > 1) {
return true;
@@ -215,20 +152,29 @@ public class Seahorse.KeyManager : Catalog {
private bool on_keymanager_key_list_popup_menu() {
GLib.List<GLib.Object> objects = get_selected_objects();
if (objects != null)
- show_context_menu(Catalog.MENU_OBJECT, null);
+ show_context_menu(null);
return false;
}
- private void on_file_new(Gtk.Action action) {
+ private void on_new_item(SimpleAction action, GLib.Variant? param) {
GenerateSelect dialog = new GenerateSelect(this);
dialog.run();
dialog.destroy();
}
- private void on_keymanager_new_button(Gtk.Button button) {
- GenerateSelect dialog = new GenerateSelect(this);
- dialog.run();
- dialog.destroy();
+ private void on_toggle_action(SimpleAction action, GLib.Variant? param) {
+ action.change_state(!action.state.get_boolean());
+ }
+
+ private void on_combine_keyrings_toggled(SimpleAction action, GLib.Variant? new_state) {
+ bool combined = new_state.get_boolean();
+ action.set_state(combined);
+
+ this.sidebar.combined = combined;
+
+ /* Don't show the sidebar if everyhing is combined */
+ this.sidebar_area.visible = !combined;
+ this.settings.set_boolean("sidebar-visible", !combined);
}
private void on_filter_changed(Gtk.Editable entry) {
@@ -242,7 +188,7 @@ public class Seahorse.KeyManager : Catalog {
dialog.destroy();
}
- private void import_prompt() {
+ private void on_import_file(SimpleAction action, GLib.Variant? parameter) {
Gtk.FileChooserDialog dialog =
new Gtk.FileChooserDialog(_("Import Key"), this,
Gtk.FileChooserAction.OPEN,
@@ -305,14 +251,6 @@ public class Seahorse.KeyManager : Catalog {
}
}
- private void on_key_import_file(Gtk.Action action) {
- import_prompt();
- }
-
- private void on_keymanager_import_button(Gtk.Button button) {
- import_prompt();
- }
-
private void import_text(string? display_name, string? text) {
ImportDialog dialog = new ImportDialog(this);
dialog.add_text(display_name, text);
@@ -336,9 +274,14 @@ public class Seahorse.KeyManager : Catalog {
}
}
- private void update_clipboard_state(Gtk.Clipboard clipboard, Gdk.Event? event, Gtk.ActionGroup group) {
- Gtk.Action action = group.get_action("edit-import-clipboard");
- action.set_sensitive(clipboard.wait_is_text_available());
+ private void on_paste(SimpleAction action, Variant? param) {
+ Gdk.Atom atom = Gdk.Atom.intern("CLIPBOARD", false);
+ Gtk.Clipboard clipboard = Gtk.Clipboard.get(atom);
+
+ if (clipboard.wait_is_text_available())
+ return;
+
+ clipboard.request_text(on_clipboard_received);
}
private void on_clipboard_received(Gtk.Clipboard board, string? text) {
@@ -353,26 +296,26 @@ public class Seahorse.KeyManager : Catalog {
import_text(_("Clipboard text"), text);
}
- private void on_key_import_clipboard(Gtk.Action action) {
- Gdk.Atom atom = Gdk.Atom.intern("CLIPBOARD", false);
- Gtk.Clipboard clipboard = Gtk.Clipboard.get(atom);
- clipboard.request_text(on_clipboard_received);
- }
+ private void update_view_filter(string filter_str, bool update_settings = true) {
+ // Update the setting
+ if (update_settings)
+ this.settings.set_string("item-filter", filter_str);
- private void on_app_quit(Gtk.Action action) {
- this.application.quit();
- }
+ // Update the action
+ SimpleAction action = lookup_action("filter-items") as SimpleAction;
+ action.set_state(filter_str);
- private unowned string update_view_filter() {
- this.store.showfilter = (KeyManagerStore.ShowFilter) this.show_action.current_value;
+ // Update the store
+ this.store.showfilter = KeyManagerStore.ShowFilter.from_string(filter_str);
this.store.refilter();
- return this.store.showfilter.to_string();
+ }
+
+ private void on_filter_items(SimpleAction action, Variant? param) {
+ update_view_filter (param.get_string());
}
private void on_item_filter_changed(GLib.Settings settings, string? key) {
- int radio = KeyManagerStore.ShowFilter.from_string(settings.get_string(key));
- this.show_action.set_current_value(radio);
- update_view_filter();
+ update_view_filter(settings.get_string("item-filter"), false);
}
public override GLib.List<GLib.Object> get_selected_objects() {
@@ -406,9 +349,7 @@ public class Seahorse.KeyManager : Catalog {
this.sidebar = new Sidebar();
sidebar.hexpand = true;
- this.sidebar_width = this.settings.get_int("sidebar-width");
-
- this.sidebar_panes.position = this.sidebar_width;
+ this.sidebar_panes.position = this.settings.get_int("sidebar-width");
this.sidebar_panes.realize.connect(() => { this.sidebar_panes.position =
this.settings.get_int("sidebar-width"); });
this.sidebar_panes.unrealize.connect(() => { this.settings.set_int("sidebar-width",
this.sidebar_panes.position); });
@@ -416,22 +357,14 @@ public class Seahorse.KeyManager : Catalog {
this.sidebar_panes.get_child2().set_size_request(150, -1);
foreach (weak Backend backend in get_backends()) {
- if (backend.actions != null)
- include_actions(backend.actions);
+ ActionGroup actions = backend.actions;
+ actions.catalog = this;
+ insert_action_group(actions.prefix, actions);
}
this.sidebar_area.add(this.sidebar);
this.sidebar.show();
- Gtk.ActionGroup actions = new Gtk.ActionGroup("sidebar");
- actions.set_translation_domain(Config.GETTEXT_PACKAGE);
- actions.add_toggle_actions(SIDEBAR_ACTIONS, null);
- Gtk.Action action = actions.get_action("view-sidebar");
- this.settings.bind("sidebar-visible", action, "active", SettingsBindFlags.DEFAULT);
- action.bind_property("active", this.sidebar_area, "visible", BindingFlags.SYNC_CREATE);
- action.bind_property("active", this.sidebar, "combined", BindingFlags.INVERT_BOOLEAN |
BindingFlags.SYNC_CREATE);
- include_actions(actions);
-
this.settings.bind("keyrings-selected", this.sidebar, "selected-uris", SettingsBindFlags.DEFAULT);
return this.sidebar.collection;
diff --git a/src/seahorse-key-manager-widgets.ui b/src/seahorse-key-manager-widgets.ui
index 97d15fc8..9c861740 100644
--- a/src/seahorse-key-manager-widgets.ui
+++ b/src/seahorse-key-manager-widgets.ui
@@ -1,38 +1,29 @@
-<ui>
- <menubar>
- <menu name="File" action="file-menu">
- <menuitem action="file-new"/>
- <menuitem action="file-import"/>
- <menuitem action="file-export"/>
- <separator/>
- <menuitem action="app-quit"/>
- </menu>
- <menu name="Edit" action="edit-menu">
- <menuitem action="edit-export-clipboard"/>
- <menuitem action="edit-import-clipboard"/>
- <menuitem action="edit-delete"/>
- <separator/>
- <menuitem action="app-preferences"/>
- </menu>
- <placeholder name="RemoteMenu">
- </placeholder>
- <menu name="View" action="view-menu">
- <menuitem action="view-sidebar"/>
- <separator/>
- <menuitem action="view-personal"/>
- <menuitem action="view-trusted"/>
- <menuitem action="view-any"/>
- </menu>
- <menu name="Help" action="help-menu">
- <menuitem action="help-show"/>
- <menuitem action="app-about"/>
- </menu>
-
- </menubar>
-
- <popup name="ObjectPopup">
- <menuitem action="edit-delete"/>
- <separator/>
- <menuitem action="properties-object"/>
- </popup>
-</ui>
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <menu id="context_menu">
+ <section>
+ <item>
+ <attribute name="label" translatable="yes">Export…</attribute>
+ <attribute name="action">win.file-export</attribute>
+ <attribute name="hidden-when">action-disabled</attribute>
+ </item>
+ <item>
+ <!-- Translators: This text refers to deleting an item from its type's backing store -->
+ <attribute name="label" translatable="yes">Delete</attribute>
+ <attribute name="action">win.edit-delete</attribute>
+ <attribute name="hidden-when">action-disabled</attribute>
+ </item>
+ </section>
+ <section>
+ <item>
+ <attribute name="label" translatable="yes">Properties</attribute>
+ <attribute name="action">win.properties-object</attribute>
+ </item>
+ <item>
+ <attribute name="label" translatable="yes">Configure Key for Secure Shell……</attribute>
+ <attribute name="action">ssh.remote-upload</attribute>
+ <attribute name="hidden-when">action-disabled</attribute>
+ </item>
+ </section>
+ </menu>
+</interface>
diff --git a/src/seahorse-key-manager.ui b/src/seahorse-key-manager.ui
index e98c1d90..2467804d 100644
--- a/src/seahorse-key-manager.ui
+++ b/src/seahorse-key-manager.ui
@@ -1,31 +1,128 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="3.22"/>
+ <menu id="main_menu">
+ <section>
+ <attribute name="label" translatable="yes">Filter items:</attribute>
+ <item>
+ <attribute name="label" translatable="yes">Show personal</attribute>
+ <attribute name="action">win.filter-items</attribute>
+ <attribute name="target">personal</attribute>
+ </item>
+ <item>
+ <attribute name="label" translatable="yes">Show trusted</attribute>
+ <attribute name="action">win.filter-items</attribute>
+ <attribute name="target">trusted</attribute>
+ </item>
+ <item>
+ <attribute name="label" translatable="yes">Show any</attribute>
+ <attribute name="action">win.filter-items</attribute>
+ <attribute name="target">any</attribute>
+ </item>
+ </section>
+ <section>
+ <item>
+ <attribute name="label" translatable="yes">Combine all keyrings</attribute>
+ <attribute name="action">win.combine-keyrings</attribute>
+ </item>
+ </section>
+ <section>
+ <item>
+ <attribute name="label" translatable="yes">Import from file…</attribute>
+ <attribute name="action">win.import-file</attribute>
+ </item>
+ <item>
+ <attribute name="label" translatable="yes">Find remote keys…</attribute>
+ <attribute name="action">pgp.remote-find</attribute>
+ <attribute name="hidden-when">action-missing</attribute>
+ </item>
+ <item>
+ <attribute name="label" translatable="yes">Sync and publish keys…</attribute>
+ <attribute name="action">pgp.remote-sync</attribute>
+ <attribute name="hidden-when">action-missing</attribute>
+ </item>
+ </section>
+ <section>
+ <item>
+ <attribute name="label" translatable="yes">Preferences</attribute>
+ <attribute name="action">app.preferences</attribute>
+ <attribute name="hidden-when">action-disabled</attribute>
+ </item>
+ <item>
+ <attribute name="label" translatable="yes">Help</attribute>
+ <attribute name="action">app.help</attribute>
+ </item>
+ <item>
+ <attribute name="label" translatable="yes">About</attribute>
+ <attribute name="action">app.about</attribute>
+ </item>
+ </section>
+ </menu>
<template class="SeahorseKeyManager" parent="SeahorseCatalog">
- <property name="title" translatable="yes">Passwords and Keys</property>
- <child>
- <object class="GtkBox">
+ <child type="titlebar">
+ <object class="GtkHeaderBar">
<property name="visible">True</property>
- <property name="orientation">vertical</property>
- <property name="can_focus">False</property>
+ <property name="show-close-button">True</property>
+ <property name="title" translatable="yes">Passwords and Keys</property>
+ <child>
+ <object class="GtkButton" id="new_item_button">
+ <property name="visible">True</property>
+ <property name="hexpand">True</property>
+ <property name="halign">start</property>
+ <property name="tooltip_text" translatable="yes">Add a new key or item</property>
+ <property name="action-name">win.new-item</property>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">True</property>
+ <property name="icon_name">list-add-symbolic</property>
+ </object>
+ </child>
+ </object>
+ </child>
<child>
- <object class="GtkBox" id="menu_placeholder">
+ <object class="GtkMenuButton" id="main_menu_button">
<property name="visible">True</property>
- <property name="orientation">vertical</property>
- <property name="can_focus">False</property>
+ <property name="can_focus">True</property>
+ <property name="focus_on_click">False</property>
+ <property name="menu-model">main_menu</property>
<child>
- <placeholder/>
+ <object class="GtkImage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon_name">open-menu-symbolic</property>
+ </object>
</child>
</object>
<packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
+ <property name="pack_type">end</property>
</packing>
</child>
+ <child>
+ <object class="GtkToggleButton" id="show_search_button">
+ <property name="visible">True</property>
+ <property name="tooltip_text" translatable="yes">Search for a key or password</property>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">True</property>
+ <property name="icon_name">edit-find-symbolic</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="pack_type">end</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="can_focus">False</property>
<child>
<object class="GtkPaned" id="sidebar_panes">
<property name="visible">True</property>
+ <property name="vexpand">True</property>
<property name="can_focus">True</property>
<child>
<object class="GtkBox" id="sidebar_area">
@@ -35,43 +132,17 @@
<placeholder/>
</child>
</object>
- <packing>
- <property name="resize">False</property>
- <property name="shrink">False</property>
- </packing>
</child>
<child>
- <object class="GtkBox" id="box1">
+ <object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
- <object class="GtkBox">
+ <object class="GtkSearchBar">
<property name="visible">True</property>
- <property name="orientation">horizontal</property>
+ <property name="search-mode-enabled" bind-source="show_search_button"
bind-property="active" bind-flags="bidirectional|sync-create" />
<property name="can_focus">False</property>
- <property name="margin_start">12</property>
- <property name="margin_end">12</property>
- <property name="margin_top">6</property>
- <property name="margin_bottom">6</property>
- <child>
- <object class="GtkButton" id="new_item_button">
- <property name="visible">True</property>
- <property name="hexpand">True</property>
- <property name="halign">start</property>
- <property name="tooltip_text" translatable="yes">Add a new key or item</property>
- <child>
- <object class="GtkImage">
- <property name="visible">True</property>
- <property name="icon_name">list-add</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- </packing>
- </child>
<child>
<object class="GtkSearchEntry" id="filter_entry">
<property name="visible">True</property>
@@ -89,8 +160,10 @@
<object class="GtkTreeView" id="key_list">
<property name="visible">True</property>
<property name="can_focus">True</property>
- <property name="margin_left">12</property>
- <property name="margin_right">12</property>
+ <property name="margin-top">12</property>
+ <property name="margin-bottom">12</property>
+ <property name="margin-left">18</property>
+ <property name="margin-right">18</property>
<property name="rules_hint">True</property>
<child internal-child="selection">
<object class="GtkTreeSelection" id="treeview-selection"/>
@@ -199,6 +272,7 @@
<property name="can_default">True</property>
<property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
+ <property name="action-name">win.import-file</property>
<child>
<object class="GtkAlignment" id="alignment6">
<property name="visible">True</property>
@@ -266,6 +340,7 @@
<property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
<property name="use_stock">True</property>
+ <property name="action-name">win.new-item</property>
</object>
<packing>
<property name="top_attach">2</property>
@@ -284,17 +359,8 @@
</object>
</child>
</object>
- <packing>
- <property name="resize">True</property>
- <property name="shrink">False</property>
- </packing>
</child>
</object>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
</child>
</object>
</child>
diff --git a/ssh/actions.vala b/ssh/actions.vala
index 71770d68..b721e169 100644
--- a/ssh/actions.vala
+++ b/ssh/actions.vala
@@ -20,49 +20,55 @@
* <http://www.gnu.org/licenses/>.
*/
-public class Seahorse.Ssh.Actions : Seahorse.Actions {
+public class Seahorse.Ssh.Actions : ActionGroup {
- private const Gtk.ActionEntry KEYS_ACTIONS[] = {
- { "remote-ssh-upload", null, N_("Configure Key for _Secure Shell…"), null,
- N_("Send public Secure Shell key to another machine, and enable logins using that key."),
- on_ssh_upload }
+ private const ActionEntry KEYS_ACTIONS[] = {
+ { "generate-key", on_ssh_generate_key },
+ { "remote-upload", on_ssh_upload },
};
- public const string UI_DEFINITION = """
- <ui>
- <menubar>
- <placeholder name="RemoteMenu">
- <menu name="Remote" action="remote-menu">
- <menuitem action="remote-ssh-upload"/>
- </menu>
- </placeholder>
- </menubar>
- <popup name="ObjectPopup">
- <menuitem action="remote-ssh-upload"/>
- </popup>
- </ui>""";
-
construct {
- set_translation_domain(Config.GETTEXT_PACKAGE);
- add_actions(KEYS_ACTIONS, this);
- register_definition(UI_DEFINITION);
+ add_action_entries(KEYS_ACTIONS, this);
+
+ // Register generator action
+ var action = lookup_action("generate-key");
+ action.set_data("label", _("Secure Shell Key"));
+ action.set_data("description", _("Used to access other computers (eg: via a terminal)"));
+ Registry.register_object(action, "generator");
}
- private Actions(string name) {
- base(name);
+ private Actions() {
+ GLib.Object(prefix: "ssh");
}
private static Actions _instance = null;
-
public static unowned Actions instance() {
- if (_instance == null) {
- _instance = new Actions("SshKey");
- }
+ if (_instance == null)
+ _instance = new Actions();
return _instance;
}
- private void on_ssh_upload (Gtk.Action action) {
+ public override void set_actions_for_selected_objects(List<GLib.Object> objects) {
+ bool is_ssh_key = false;
+
+ foreach (var object in objects) {
+ if (object is Ssh.Key) {
+ is_ssh_key = true;
+ break;
+ }
+ }
+
+ ((SimpleAction) lookup_action("remote-upload")).set_enabled(is_ssh_key);
+ }
+
+ private void on_ssh_generate_key(SimpleAction action, Variant? param) {
+ Generate generate_dialog = new Generate(Backend.instance.get_dot_ssh(),
+ this.catalog);
+ generate_dialog.show();
+ }
+
+ private void on_ssh_upload(SimpleAction action, Variant? param) {
List<Key> keys = new List<Key>();
if (this.catalog != null) {
@@ -73,6 +79,6 @@ public class Seahorse.Ssh.Actions : Seahorse.Actions {
}
}
- Upload.prompt(keys, Seahorse.Action.get_window(action));
+ Upload.prompt(keys, this.catalog);
}
}
diff --git a/ssh/backend.vala b/ssh/backend.vala
index 4865070a..84ea529a 100644
--- a/ssh/backend.vala
+++ b/ssh/backend.vala
@@ -26,7 +26,7 @@ public class Seahorse.Ssh.Backend : GLib.Object, Gcr.Collection, Seahorse.Backen
public string name { get { return SEAHORSE_SSH_NAME; } }
public string label { get { return _("Secure Shell"); } }
public string description { get { return _("Keys used to connect securely to other computers"); } }
- public Gtk.ActionGroup? actions { owned get { return null; } }
+ public ActionGroup actions { owned get { return Ssh.Actions.instance(); } }
private bool _loaded;
public bool loaded { get { return _loaded; } }
@@ -73,7 +73,6 @@ public class Seahorse.Ssh.Backend : GLib.Object, Gcr.Collection, Seahorse.Backen
public static void initialize() {
instance = new Backend();
- Generate.register();
}
public Source get_dot_ssh() {
diff --git a/ssh/generate.vala b/ssh/generate.vala
index 9d0ed390..f52cb136 100644
--- a/ssh/generate.vala
+++ b/ssh/generate.vala
@@ -24,11 +24,6 @@ public class Seahorse.Ssh.Generate : Gtk.Dialog {
public const int DEFAULT_DSA_SIZE = 1024;
public const int DEFAULT_RSA_SIZE = 2048;
- private const Gtk.ActionEntry ACTION_ENTRIES[] = {
- { "ssh-generate-key", Gcr.ICON_KEY_PAIR, N_ ("Secure Shell Key"), "",
- N_("Used to access other computers (eg: via a terminal)"), on_ssh_generate_key }
- };
-
private Source source;
[GtkChild]
@@ -58,22 +53,6 @@ public class Seahorse.Ssh.Generate : Gtk.Dialog {
algorithm_combo_box.set_active(0);
}
- private static void on_ssh_generate_key(Gtk.Action action) {
- Generate generate_dialog = new Generate(Backend.instance.get_dot_ssh(),
- Action.get_window(action));
- generate_dialog.show();
- }
-
- public static void register() {
- Gtk.ActionGroup actions = new Gtk.ActionGroup("ssh-generate");
-
- actions.set_translation_domain(Config.GETTEXT_PACKAGE);
- actions.add_actions(ACTION_ENTRIES, null);
-
- // Register this as a generator
- Seahorse.Registry.register_object(actions, "generator");
- }
-
[GtkCallback]
private void on_algo_changed(Gtk.ComboBox combo) {
string t = algorithm_combo_box.get_active_text();
diff --git a/ssh/key.vala b/ssh/key.vala
index 3ee6c761..1b1bf8ee 100644
--- a/ssh/key.vala
+++ b/ssh/key.vala
@@ -140,7 +140,6 @@ public class Seahorse.Ssh.Key : Seahorse.Object, Seahorse.Exportable, Seahorse.D
this.markup = Markup.printf_escaped("%s<span size='small' rise='0' foreground='#555555'>\n%s</span>",
this.label, filename);
- this.actions = Actions.instance();
this.identifier = calc_identifier(this.key_data.fingerprint);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]