[geary/mjog/233-entry-undo: 4/5] Rework action names groups across the client



commit ffc7873a8773b5f67d9e31cdcd1f114fdc3c8153
Author: Michael Gratton <mike vee net>
Date:   Thu Nov 7 11:47:41 2019 +1100

    Rework action names groups across the client
    
    Introduce a new standard edit action group "edt" for editing actions
    such as copy and undo, separate from the "win" window action group, so
    that editing actions can be scoped to specific widgets and overridden
    by children. Add new Action namespace with sub-namespaces for the
    app, win and edt namespaces and move consts from GearyApplication there.
    Update call sites and UI files, use consistent approach to setting up
    action groups across all classes that use them.

 po/POTFILES.in                                     |   1 +
 src/client/accounts/accounts-editor-list-pane.vala |   4 +-
 src/client/accounts/accounts-editor.vala           |  18 +--
 src/client/application/geary-application.vala      |  90 ++++++------
 src/client/client-action.vala                      |  73 ++++++++++
 src/client/components/components-entry-undo.vala   |  35 ++---
 src/client/components/components-inspector.vala    |  28 ++--
 src/client/components/main-window.vala             |  79 ++++++-----
 src/client/composer/composer-widget.vala           | 151 ++++++++++-----------
 .../dialogs/dialogs-problem-details-dialog.vala    |  29 ++--
 src/client/meson.build                             |   2 +
 .../desktop-notifications.vala                     |   6 +-
 ui/accounts_editor_edit_pane.ui                    |   2 +-
 ui/components-inspector.ui                         |   2 +-
 ui/composer-menus.ui                               |  34 ++---
 ui/composer-widget.ui                              |  26 ++--
 16 files changed, 333 insertions(+), 247 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 2a4b49a4..4cc9fb4d 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -28,6 +28,7 @@ src/client/application/geary-application.vala
 src/client/application/goa-mediator.vala
 src/client/application/main.vala
 src/client/application/secret-mediator.vala
+src/client/client-action.vala
 src/client/components/client-web-view.vala
 src/client/components/components-attachment-pane.vala
 src/client/components/components-entry-undo.vala
diff --git a/src/client/accounts/accounts-editor-list-pane.vala 
b/src/client/accounts/accounts-editor-list-pane.vala
index 17676098..67b7c26b 100644
--- a/src/client/accounts/accounts-editor-list-pane.vala
+++ b/src/client/accounts/accounts-editor-list-pane.vala
@@ -245,7 +245,7 @@ internal class Accounts.EditorListPane : Gtk.Grid, EditorPane, CommandPane {
         if (command.executed_label != null) {
             Components.InAppNotification ian =
                 new Components.InAppNotification(command.executed_label);
-            ian.set_button(_("Undo"), "win." + GearyApplication.ACTION_UNDO);
+            ian.set_button(_("Undo"), Action.Edit.prefix(Action.Edit.UNDO));
             this.editor.add_notification(ian);
         }
     }
@@ -254,7 +254,7 @@ internal class Accounts.EditorListPane : Gtk.Grid, EditorPane, CommandPane {
         if (command.undone_label != null) {
             Components.InAppNotification ian =
                 new Components.InAppNotification(command.undone_label);
-            ian.set_button(_("Redo"), "win." + GearyApplication.ACTION_REDO);
+            ian.set_button(_("Redo"), Action.Edit.prefix(Action.Edit.REDO));
             this.editor.add_notification(ian);
         }
     }
diff --git a/src/client/accounts/accounts-editor.vala b/src/client/accounts/accounts-editor.vala
index 740de633..7f3252bb 100644
--- a/src/client/accounts/accounts-editor.vala
+++ b/src/client/accounts/accounts-editor.vala
@@ -18,9 +18,9 @@
 public class Accounts.Editor : Gtk.Dialog {
 
 
-    private const ActionEntry[] ACTION_ENTRIES = {
-        { GearyApplication.ACTION_REDO, on_redo },
-        { GearyApplication.ACTION_UNDO, on_undo },
+    private const ActionEntry[] EDIT_ACTIONS = {
+        { Action.Edit.REDO, on_redo },
+        { Action.Edit.UNDO, on_undo },
     };
 
 
@@ -40,7 +40,7 @@ public class Accounts.Editor : Gtk.Dialog {
         get; private set;
     }
 
-    private SimpleActionGroup actions = new SimpleActionGroup();
+    private GLib.SimpleActionGroup edit_actions = new GLib.SimpleActionGroup();
 
     [GtkChild]
     private Gtk.Overlay notifications_pane;
@@ -67,8 +67,8 @@ public class Accounts.Editor : Gtk.Dialog {
 
         this.accounts = application.controller.account_manager;
 
-        this.actions.add_action_entries(ACTION_ENTRIES, this);
-        insert_action_group("win", this.actions);
+        this.edit_actions.add_action_entries(EDIT_ACTIONS, this);
+        insert_action_group(Action.Edit.GROUP_NAME, this.edit_actions);
 
         this.editor_list_pane = new EditorListPane(this);
         push(this.editor_list_pane);
@@ -227,8 +227,8 @@ public class Accounts.Editor : Gtk.Dialog {
             can_redo = pane.commands.can_redo;
         }
 
-        get_action(GearyApplication.ACTION_UNDO).set_enabled(can_undo);
-        get_action(GearyApplication.ACTION_REDO).set_enabled(can_redo);
+        get_action(Action.Edit.UNDO).set_enabled(can_undo);
+        get_action(Action.Edit.REDO).set_enabled(can_redo);
     }
 
     private inline EditorPane? get_current_pane() {
@@ -236,7 +236,7 @@ public class Accounts.Editor : Gtk.Dialog {
     }
 
     private inline GLib.SimpleAction get_action(string name) {
-        return (GLib.SimpleAction) this.actions.lookup_action(name);
+        return (GLib.SimpleAction) this.edit_actions.lookup_action(name);
     }
 
     private void on_undo() {
diff --git a/src/client/application/geary-application.vala b/src/client/application/geary-application.vala
index 3b416cd5..2b633edc 100644
--- a/src/client/application/geary-application.vala
+++ b/src/client/application/geary-application.vala
@@ -20,6 +20,7 @@ extern const string _PROFILE;
 extern const string _VERSION;
 extern const string _REVNO;
 
+
 /**
  * The interface between Geary and the desktop environment.
  */
@@ -52,25 +53,6 @@ public class GearyApplication : Gtk.Application {
         null
     };
 
-    // Common window actions
-    public const string ACTION_CLOSE = "close";
-    public const string ACTION_COPY = "copy";
-    public const string ACTION_HELP_OVERLAY = "show-help-overlay";
-    public const string ACTION_REDO = "redo";
-    public const string ACTION_UNDO = "undo";
-
-    // App-wide actions
-    public const string ACTION_ABOUT = "about";
-    public const string ACTION_ACCOUNTS = "accounts";
-    public const string ACTION_COMPOSE = "compose";
-    public const string ACTION_INSPECT = "inspect";
-    public const string ACTION_HELP = "help";
-    public const string ACTION_MAILTO = "mailto";
-    public const string ACTION_PREFERENCES = "preferences";
-    public const string ACTION_SHOW_EMAIL = "show-email";
-    public const string ACTION_SHOW_FOLDER = "show-folder";
-    public const string ACTION_QUIT = "quit";
-
     // Local-only command line options
     private const string OPTION_VERSION = "version";
 
@@ -90,16 +72,16 @@ public class GearyApplication : Gtk.Application {
     private const string OPTION_REVOKE_CERTS = "revoke-certs";
 
     private const ActionEntry[] ACTION_ENTRIES = {
-        {ACTION_ABOUT, on_activate_about},
-        {ACTION_ACCOUNTS, on_activate_accounts},
-        {ACTION_COMPOSE, on_activate_compose},
-        {ACTION_HELP, on_activate_help},
-        {ACTION_INSPECT, on_activate_inspect},
-        {ACTION_MAILTO, on_activate_mailto, "s"},
-        {ACTION_PREFERENCES, on_activate_preferences},
-        {ACTION_QUIT, on_activate_quit},
-        {ACTION_SHOW_EMAIL, on_activate_show_email, "(svv)"},
-        {ACTION_SHOW_FOLDER, on_activate_show_folder, "(sv)"}
+        { Action.Application.ABOUT, on_activate_about},
+        { Action.Application.ACCOUNTS, on_activate_accounts},
+        { Action.Application.COMPOSE, on_activate_compose},
+        { Action.Application.HELP, on_activate_help},
+        { Action.Application.INSPECT, on_activate_inspect},
+        { Action.Application.MAILTO, on_activate_mailto, "s"},
+        { Action.Application.PREFERENCES, on_activate_preferences},
+        { Action.Application.QUIT, on_activate_quit},
+        { Action.Application.SHOW_EMAIL, on_activate_show_email, "(svv)"},
+        { Action.Application.SHOW_FOLDER, on_activate_show_folder, "(sv)"}
     };
 
     // This is also the order in which they are presented to the user,
@@ -435,22 +417,26 @@ public class GearyApplication : Gtk.Application {
         Gtk.Window.set_default_icon_name(APP_ID);
 
         // Application accels
-        add_app_accelerators(ACTION_COMPOSE, { "<Ctrl>N" });
-        add_app_accelerators(ACTION_HELP, { "F1" });
-        add_app_accelerators(ACTION_INSPECT, { "<Alt><Shift>I" });
-        add_app_accelerators(ACTION_QUIT, { "<Ctrl>Q" });
+        add_app_accelerators(Action.Application.COMPOSE, { "<Ctrl>N" });
+        add_app_accelerators(Action.Application.HELP, { "F1" });
+        add_app_accelerators(Action.Application.INSPECT, { "<Alt><Shift>I" });
+        add_app_accelerators(Action.Application.QUIT, { "<Ctrl>Q" });
 
         // Common window accels
-        add_window_accelerators(ACTION_CLOSE, { "<Ctrl>W" });
-        add_window_accelerators(ACTION_COPY, { "<Ctrl>C" });
-        add_window_accelerators(ACTION_HELP_OVERLAY, { "<Ctrl>F1", "<Ctrl>question" });
-        add_window_accelerators(ACTION_REDO, { "<Ctrl><Shift>Z" });
-        add_window_accelerators(ACTION_UNDO, { "<Ctrl>Z" });
+        add_window_accelerators(Action.Window.CLOSE, { "<Ctrl>W" });
+        add_window_accelerators(
+            Action.Window.SHORTCUT_HELP, { "<Ctrl>F1", "<Ctrl>question" }
+        );
+
+        // Common edit accels
+        add_edit_accelerators(Action.Edit.COPY, { "<Ctrl>C" });
+        add_edit_accelerators(Action.Edit.REDO, { "<Ctrl><Shift>Z" });
+        add_edit_accelerators(Action.Edit.UNDO, { "<Ctrl>Z" });
 
-        MainWindow.add_window_accelerators(this);
-        ComposerWidget.add_window_accelerators(this);
-        Components.EntryUndo.add_window_accelerators(this);
-        Components.Inspector.add_window_accelerators(this);
+        MainWindow.add_accelerators(this);
+        ComposerWidget.add_accelerators(this);
+        Components.Inspector.add_accelerators(this);
+        Dialogs.ProblemDetailsDialog.add_accelerators(this);
 
         if (this.is_background_service) {
             // Since command_line won't be called below if running as
@@ -495,7 +481,18 @@ public class GearyApplication : Gtk.Application {
     public void add_window_accelerators(string action,
                                         string[] accelerators,
                                         Variant? param = null) {
-        string name = "win." + action;
+        string name = Action.Window.prefix(action);
+        string[] all_accel = get_accels_for_action(name);
+        foreach (string accel in accelerators) {
+            all_accel += accel;
+        }
+        set_accels_for_action(name, all_accel);
+    }
+
+    public void add_edit_accelerators(string action,
+                                      string[] accelerators,
+                                      Variant? param = null) {
+        string name = Action.Edit.prefix(action);
         string[] all_accel = get_accels_for_action(name);
         foreach (string accel in accelerators) {
             all_accel += accel;
@@ -876,13 +873,10 @@ public class GearyApplication : Gtk.Application {
             foreach (string arg in args) {
                 // the only acceptable arguments are mailto:'s
                 if (arg == MAILTO_URI_SCHEME_PREFIX) {
-                    activate_action(GearyApplication.ACTION_COMPOSE, null);
+                    activate_action(Action.Application.COMPOSE, null);
                     activated = true;
                 } else if (arg.down().has_prefix(MAILTO_URI_SCHEME_PREFIX)) {
-                    activate_action(
-                        GearyApplication.ACTION_MAILTO,
-                        new GLib.Variant.string(arg)
-                    );
+                    activate_action(Action.Application.MAILTO, new GLib.Variant.string(arg));
                     activated = true;
                 } else {
                     command_line.printerr("%s: ", this.binary);
diff --git a/src/client/client-action.vala b/src/client/client-action.vala
new file mode 100644
index 00000000..a5bcf047
--- /dev/null
+++ b/src/client/client-action.vala
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2019 Michael Gratton <mike vee net>
+ *
+ * This software is licensed under the GNU Lesser General Public License
+ * (version 2.1 or later). See the COPYING file in this distribution.
+ */
+
+/** Common client GAction and action group names */
+namespace Action {
+
+
+    /** Common application GAction names. */
+    namespace Application {
+
+        /** Application GAction group name */
+        public const string GROUP_NAME = "app";
+
+        public const string ABOUT = "about";
+        public const string ACCOUNTS = "accounts";
+        public const string COMPOSE = "compose";
+        public const string INSPECT = "inspect";
+        public const string HELP = "help";
+        public const string MAILTO = "mailto";
+        public const string PREFERENCES = "preferences";
+        public const string SHOW_EMAIL = "show-email";
+        public const string SHOW_FOLDER = "show-folder";
+        public const string QUIT = "quit";
+
+
+        /** Returns the given action name prefixed with the group name. */
+        public string prefix(string action_name) {
+            return GROUP_NAME + "." + action_name;
+        }
+
+    }
+
+
+    /** Common window GAction names. */
+    namespace Window {
+
+        /** Window GAction group name */
+        public const string GROUP_NAME = "win";
+
+        public const string CLOSE = "close";
+        public const string SHORTCUT_HELP = "show-help-overlay";
+
+
+        /** Returns the given action name prefixed with the group name. */
+        public string prefix(string action_name) {
+            return GROUP_NAME + "." + action_name;
+        }
+
+    }
+
+    /** Common editing GAction names. */
+    namespace Edit {
+
+        /** Editing GAction group name */
+        public const string GROUP_NAME = "edt";
+
+        public const string COPY = "copy";
+        public const string REDO = "redo";
+        public const string UNDO = "undo";
+
+
+        /** Returns the given action name prefixed with the group name. */
+        public string prefix(string action_name) {
+            return GROUP_NAME + "." + action_name;
+        }
+
+    }
+
+}
diff --git a/src/client/components/components-entry-undo.vala 
b/src/client/components/components-entry-undo.vala
index 18382e34..9928c524 100644
--- a/src/client/components/components-entry-undo.vala
+++ b/src/client/components/components-entry-undo.vala
@@ -11,10 +11,9 @@
 public class Components.EntryUndo : Geary.BaseObject {
 
 
-    private const string ACTION_GROUP = "ceu";
-    private const ActionEntry[] action_entries = {
-        { GearyApplication.ACTION_UNDO, on_undo },
-        { GearyApplication.ACTION_REDO, on_redo },
+    private const ActionEntry[] EDIT_ACTIONS = {
+        { Action.Edit.UNDO, on_undo },
+        { Action.Edit.REDO, on_redo },
     };
 
 
@@ -94,18 +93,6 @@ public class Components.EntryUndo : Geary.BaseObject {
     }
 
 
-    public static void add_window_accelerators(GearyApplication application) {
-        application.set_accels_for_action(
-            ACTION_GROUP + "." + GearyApplication.ACTION_UNDO,
-            { "<Ctrl>z" }
-        );
-        application.set_accels_for_action(
-            ACTION_GROUP + "." + GearyApplication.ACTION_REDO,
-            { "<Ctrl><Shift>z" }
-        );
-    }
-
-
     /** The entry being managed */
     public Gtk.Entry target { get; private set; }
 
@@ -117,12 +104,14 @@ public class Components.EntryUndo : Geary.BaseObject {
 
     private bool events_enabled = true;
 
-    private GLib.SimpleActionGroup entry_actions = new SimpleActionGroup();
+    private GLib.SimpleActionGroup edit_actions = new GLib.SimpleActionGroup();
 
 
     public EntryUndo(Gtk.Entry target) {
+        this.edit_actions.add_action_entries(EDIT_ACTIONS, this);
+
         this.target = target;
-        this.target.insert_action_group(ACTION_GROUP, this.entry_actions);
+        this.target.insert_action_group(Action.Edit.GROUP_NAME, this.edit_actions);
         this.target.insert_text.connect(on_inserted);
         this.target.delete_text.connect(on_deleted);
 
@@ -130,8 +119,6 @@ public class Components.EntryUndo : Geary.BaseObject {
         this.commands.executed.connect(this.update_command_actions);
         this.commands.undone.connect(this.update_command_actions);
         this.commands.redone.connect(this.update_command_actions);
-
-        this.entry_actions.add_action_entries(EntryUndo.action_entries, this);
     }
 
     ~EntryUndo() {
@@ -234,10 +221,10 @@ public class Components.EntryUndo : Geary.BaseObject {
     }
 
     private void update_command_actions() {
-        ((GLib.SimpleAction) this.entry_actions.lookup_action(
-            GearyApplication.ACTION_UNDO)).set_enabled(this.commands.can_undo);
-        ((GLib.SimpleAction) this.entry_actions.lookup_action(
-            GearyApplication.ACTION_REDO)).set_enabled(this.commands.can_redo);
+        ((GLib.SimpleAction) this.edit_actions.lookup_action(Action.Edit.UNDO))
+            .set_enabled(this.commands.can_undo);
+        ((GLib.SimpleAction) this.edit_actions.lookup_action(Action.Edit.REDO))
+            .set_enabled(this.commands.can_redo);
     }
 
     private void on_inserted(string inserted, int inserted_len, ref int pos) {
diff --git a/src/client/components/components-inspector.vala b/src/client/components/components-inspector.vala
index f7d1b1a4..5af29b41 100644
--- a/src/client/components/components-inspector.vala
+++ b/src/client/components/components-inspector.vala
@@ -28,16 +28,20 @@ public class Components.Inspector : Gtk.ApplicationWindow {
     private const string ACTION_SEARCH_TOGGLE = "toggle-search";
     private const string ACTION_SEARCH_ACTIVATE = "activate-search";
 
-    private const ActionEntry[] action_entries = {
-        {GearyApplication.ACTION_CLOSE, on_close },
-        {GearyApplication.ACTION_COPY,  on_copy_clicked },
-        {ACTION_CLOSE,                  on_close },
-        {ACTION_PLAY_TOGGLE,            on_logs_play_toggled, null, "true" },
-        {ACTION_SEARCH_TOGGLE,          on_logs_search_toggled, null, "false" },
-        {ACTION_SEARCH_ACTIVATE,        on_logs_search_activated },
+    private const ActionEntry[] EDIT_ACTIONS = {
+        { Action.Edit.COPY,  on_copy_clicked },
     };
 
-    public static void add_window_accelerators(GearyApplication app) {
+    private const ActionEntry[] WINDOW_ACTIONS = {
+        { Action.Window.CLOSE, on_close },
+        { ACTION_CLOSE,                  on_close },
+        { ACTION_PLAY_TOGGLE,            on_logs_play_toggled, null, "true" },
+        { ACTION_SEARCH_TOGGLE,          on_logs_search_toggled, null, "false" },
+        { ACTION_SEARCH_ACTIVATE,        on_logs_search_activated },
+    };
+
+
+    public static void add_accelerators(GearyApplication app) {
         app.add_window_accelerators(ACTION_CLOSE, { "Escape" } );
         app.add_window_accelerators(ACTION_PLAY_TOGGLE, { "space" } );
         app.add_window_accelerators(ACTION_SEARCH_ACTIVATE, { "<Ctrl>F" } );
@@ -67,7 +71,13 @@ public class Components.Inspector : Gtk.ApplicationWindow {
         Object(application: application);
         this.title = this.header_bar.title = _("Inspector");
 
-        add_action_entries(Inspector.action_entries, this);
+        // Edit actions
+        GLib.SimpleActionGroup edit_actions = new GLib.SimpleActionGroup();
+        edit_actions.add_action_entries(EDIT_ACTIONS, this);
+        insert_action_group(Action.Edit.GROUP_NAME, edit_actions);
+
+        // Window actions
+        add_action_entries(WINDOW_ACTIONS, this);
 
         this.log_pane = new InspectorLogView(application.config, null);
         this.log_pane.record_selection_changed.connect(
diff --git a/src/client/components/main-window.vala b/src/client/components/main-window.vala
index 397ffce4..f904f53c 100644
--- a/src/client/components/main-window.vala
+++ b/src/client/components/main-window.vala
@@ -34,14 +34,13 @@ public class MainWindow : Gtk.ApplicationWindow, Geary.BaseInterface {
     public const string ACTION_TRASH_CONVERSATION = "trash-conversation";
     public const string ACTION_ZOOM = "zoom";
 
-    private const int STATUS_BAR_HEIGHT = 18;
-    private const int UPDATE_UI_INTERVAL = 60;
-    private const int MIN_CONVERSATION_COUNT = 50;
+    private const ActionEntry[] EDIT_ACTIONS = {
+        { Action.Edit.UNDO, on_undo },
+        { Action.Edit.REDO, on_redo },
+    };
 
-    private const ActionEntry[] win_action_entries = {
-        { GearyApplication.ACTION_CLOSE, on_close },
-        { GearyApplication.ACTION_UNDO, on_undo },
-        { GearyApplication.ACTION_REDO, on_redo },
+    private const ActionEntry[] WINDOW_ACTIONS = {
+        { Action.Window.CLOSE, on_close },
 
         { ACTION_CONVERSATION_LIST, on_conversation_list },
         { ACTION_FIND_IN_CONVERSATION, on_find_in_conversation_action },
@@ -70,8 +69,12 @@ public class MainWindow : Gtk.ApplicationWindow, Geary.BaseInterface {
         { ACTION_ZOOM, on_zoom, "s" },
     };
 
+    private const int STATUS_BAR_HEIGHT = 18;
+    private const int UPDATE_UI_INTERVAL = 60;
+    private const int MIN_CONVERSATION_COUNT = 50;
 
-    public static void add_window_accelerators(GearyApplication owner) {
+
+    public static void add_accelerators(GearyApplication owner) {
         // Marking actions
         //
         // Unread is the primary action, so it doesn't get the <Shift>
@@ -209,6 +212,8 @@ public class MainWindow : Gtk.ApplicationWindow, Geary.BaseInterface {
 
     private Application.Controller.AccountContext? context = null;
 
+    private GLib.SimpleActionGroup edit_actions = new GLib.SimpleActionGroup();
+
     // Determines if the conversation viewer should autoselect on next
     // load
     private bool previous_selection_was_interactive = false;
@@ -277,7 +282,13 @@ public class MainWindow : Gtk.ApplicationWindow, Geary.BaseInterface {
 
         load_config(application.config);
         restore_saved_window_state();
-        add_action_entries(win_action_entries, this);
+
+        // Edit actions
+        this.edit_actions.add_action_entries(EDIT_ACTIONS, this);
+        insert_action_group(Action.Edit.GROUP_NAME, this.edit_actions);
+
+        // Window actions
+        add_action_entries(MainWindow.WINDOW_ACTIONS, this);
 
         set_styling();
         setup_layout(application.config);
@@ -572,7 +583,7 @@ public class MainWindow : Gtk.ApplicationWindow, Geary.BaseInterface {
             new ComposerWindow(composer, this.application);
         } else {
             this.conversation_viewer.do_compose(composer);
-            get_action(ACTION_FIND_IN_CONVERSATION).set_enabled(false);
+            get_window_action(ACTION_FIND_IN_CONVERSATION).set_enabled(false);
         }
     }
 
@@ -971,10 +982,10 @@ public class MainWindow : Gtk.ApplicationWindow, Geary.BaseInterface {
 
     private void update_command_actions() {
         Application.Controller.AccountContext? selected = this.context;
-        get_action(GearyApplication.ACTION_UNDO).set_enabled(
+        get_edit_action(Action.Edit.UNDO).set_enabled(
             selected != null && selected.commands.can_undo
         );
-        get_action(GearyApplication.ACTION_REDO).set_enabled(
+        get_edit_action(Action.Edit.REDO).set_enabled(
             selected != null && selected.commands.can_redo
         );
     }
@@ -1381,7 +1392,7 @@ public class MainWindow : Gtk.ApplicationWindow, Geary.BaseInterface {
         bool sensitive = (count != NONE);
         bool multiple = (count == MULTIPLE);
 
-        get_action(ACTION_FIND_IN_CONVERSATION).set_enabled(
+        get_window_action(ACTION_FIND_IN_CONVERSATION).set_enabled(
             sensitive && !multiple
         );
 
@@ -1391,29 +1402,29 @@ public class MainWindow : Gtk.ApplicationWindow, Geary.BaseInterface {
             this.selected_folder != null &&
             this.selected_folder.special_folder_type != DRAFTS
         );
-        get_action(ACTION_REPLY_CONVERSATION).set_enabled(reply_sensitive);
-        get_action(ACTION_REPLY_ALL_CONVERSATION).set_enabled(reply_sensitive);
-        get_action(ACTION_FORWARD_CONVERSATION).set_enabled(reply_sensitive);
+        get_window_action(ACTION_REPLY_CONVERSATION).set_enabled(reply_sensitive);
+        get_window_action(ACTION_REPLY_ALL_CONVERSATION).set_enabled(reply_sensitive);
+        get_window_action(ACTION_FORWARD_CONVERSATION).set_enabled(reply_sensitive);
 
         bool move_enabled = (
             sensitive && (selected_folder is Geary.FolderSupport.Move)
         );
         this.main_toolbar.move_message_button.set_sensitive(move_enabled);
-        get_action(ACTION_SHOW_MOVE_MENU).set_enabled(move_enabled);
+        get_window_action(ACTION_SHOW_MOVE_MENU).set_enabled(move_enabled);
 
         bool copy_enabled = (
             sensitive && (selected_folder is Geary.FolderSupport.Copy)
         );
         this.main_toolbar.copy_message_button.set_sensitive(copy_enabled);
-        get_action(ACTION_SHOW_COPY_MENU).set_enabled(move_enabled);
+        get_window_action(ACTION_SHOW_COPY_MENU).set_enabled(move_enabled);
 
-        get_action(ACTION_ARCHIVE_CONVERSATION).set_enabled(
+        get_window_action(ACTION_ARCHIVE_CONVERSATION).set_enabled(
             sensitive && (selected_folder is Geary.FolderSupport.Archive)
         );
-        get_action(ACTION_TRASH_CONVERSATION).set_enabled(
+        get_window_action(ACTION_TRASH_CONVERSATION).set_enabled(
             sensitive && this.selected_folder_supports_trash
         );
-        get_action(ACTION_DELETE_CONVERSATION).set_enabled(
+        get_window_action(ACTION_DELETE_CONVERSATION).set_enabled(
             sensitive && (selected_folder is Geary.FolderSupport.Remove)
         );
 
@@ -1456,15 +1467,15 @@ public class MainWindow : Gtk.ApplicationWindow, Geary.BaseInterface {
                 supported_operations.add_all(selected_operations.get_values());
             }
 
-            get_action(ACTION_SHOW_MARK_MENU).set_enabled(
+            get_window_action(ACTION_SHOW_MARK_MENU).set_enabled(
                 sensitive &&
                 (typeof(Geary.FolderSupport.Mark) in supported_operations)
             );
-            get_action(ACTION_SHOW_COPY_MENU).set_enabled(
+            get_window_action(ACTION_SHOW_COPY_MENU).set_enabled(
                 sensitive &&
                 (supported_operations.contains(typeof(Geary.FolderSupport.Copy)))
             );
-            get_action(ACTION_SHOW_MOVE_MENU).set_enabled(
+            get_window_action(ACTION_SHOW_MOVE_MENU).set_enabled(
                 sensitive &&
                 (supported_operations.contains(typeof(Geary.FolderSupport.Move)))
             );
@@ -1491,10 +1502,14 @@ public class MainWindow : Gtk.ApplicationWindow, Geary.BaseInterface {
         }
     }
 
-    private SimpleAction get_action(string name) {
+    private SimpleAction get_window_action(string name) {
         return (SimpleAction) lookup_action(name);
     }
 
+    private SimpleAction get_edit_action(string name) {
+        return (SimpleAction) this.edit_actions.lookup_action(name);
+    }
+
     private void on_scan_completed(Geary.App.ConversationMonitor monitor) {
         // Done scanning.  Check if we have enough messages to fill
         // the conversation list; if not, trigger a load_more();
@@ -1612,7 +1627,7 @@ public class MainWindow : Gtk.ApplicationWindow, Geary.BaseInterface {
         if (command.undone_label != null) {
             Components.InAppNotification ian =
                 new Components.InAppNotification(command.undone_label);
-            ian.set_button(_("Redo"), "win." + GearyApplication.ACTION_REDO);
+            ian.set_button(_("Redo"), Action.Edit.prefix(Action.Edit.UNDO));
             add_notification(ian);
         }
         update_command_actions();
@@ -1622,7 +1637,7 @@ public class MainWindow : Gtk.ApplicationWindow, Geary.BaseInterface {
         if (command.executed_label != null) {
             Components.InAppNotification ian =
             new Components.InAppNotification(command.executed_label);
-            ian.set_button(_("Undo"), "win." + GearyApplication.ACTION_UNDO);
+            ian.set_button(_("Undo"), Action.Edit.prefix(Action.Edit.REDO));
             add_notification(ian);
         }
         update_command_actions();
@@ -1783,14 +1798,14 @@ public class MainWindow : Gtk.ApplicationWindow, Geary.BaseInterface {
                 unstarred_selected = true;
             }
         }
-        get_action(ACTION_MARK_AS_READ).set_enabled(unread_selected);
-        get_action(ACTION_MARK_AS_UNREAD).set_enabled(read_selected);
-        get_action(ACTION_MARK_AS_STARRED).set_enabled(unstarred_selected);
-        get_action(ACTION_MARK_AS_UNSTARRED).set_enabled(starred_selected);
+        get_window_action(ACTION_MARK_AS_READ).set_enabled(unread_selected);
+        get_window_action(ACTION_MARK_AS_UNREAD).set_enabled(read_selected);
+        get_window_action(ACTION_MARK_AS_STARRED).set_enabled(unstarred_selected);
+        get_window_action(ACTION_MARK_AS_UNSTARRED).set_enabled(starred_selected);
 
         // If we're in Drafts/Outbox, we also shouldn't set a message as SPAM.
         bool in_spam_folder = selected_folder.special_folder_type == Geary.SpecialFolderType.SPAM;
-        get_action(ACTION_TOGGLE_SPAM).set_enabled(!in_spam_folder &&
+        get_window_action(ACTION_TOGGLE_SPAM).set_enabled(!in_spam_folder &&
             selected_folder.special_folder_type != Geary.SpecialFolderType.DRAFTS &&
             selected_folder.special_folder_type != Geary.SpecialFolderType.OUTBOX);
     }
diff --git a/src/client/composer/composer-widget.vala b/src/client/composer/composer-widget.vala
index 791a285b..11ce04f5 100644
--- a/src/client/composer/composer-widget.vala
+++ b/src/client/composer/composer-widget.vala
@@ -90,70 +90,71 @@ public class ComposerWidget : Gtk.EventBox, Geary.BaseInterface {
 
     // ACTION_INSERT_LINK and ACTION_REMOVE_FORMAT are missing from
     // here since they are handled in update_selection_actions
-    private const string[] html_actions = {
+    private const string[] HTML_ACTIONS = {
         ACTION_BOLD, ACTION_ITALIC, ACTION_UNDERLINE, ACTION_STRIKETHROUGH,
         ACTION_FONT_SIZE, ACTION_FONT_FAMILY, ACTION_COLOR, ACTION_JUSTIFY,
         ACTION_INSERT_IMAGE, ACTION_COPY_LINK,
         ACTION_OLIST, ACTION_ULIST
     };
 
-    private const ActionEntry[] editor_action_entries = {
-        {GearyApplication.ACTION_UNDO,    on_undo                                       },
-        {GearyApplication.ACTION_REDO,    on_redo                                       },
-        {GearyApplication.ACTION_COPY,    on_copy                                       },
-        {ACTION_CUT,                      on_cut                                        },
-        {ACTION_COPY_LINK,                on_copy_link                                  },
-        {ACTION_PASTE,                    on_paste                                      },
-        {ACTION_PASTE_WITHOUT_FORMATTING, on_paste_without_formatting                   },
-        {ACTION_SELECT_ALL,               on_select_all                                 },
-        {ACTION_BOLD,                     on_action,                null,      "false"  },
-        {ACTION_ITALIC,                   on_action,                null,      "false"  },
-        {ACTION_UNDERLINE,                on_action,                null,      "false"  },
-        {ACTION_STRIKETHROUGH,            on_action,                null,      "false"  },
-        {ACTION_FONT_SIZE,                on_font_size,              "s",   "'medium'"  },
-        {ACTION_FONT_FAMILY,              on_font_family,            "s",     "'sans'"  },
-        {ACTION_REMOVE_FORMAT,            on_remove_format,         null,      "false"  },
-        {ACTION_INDENT,                   on_indent                                     },
-        {ACTION_OLIST,                    on_olist                                      },
-        {ACTION_ULIST,                    on_ulist                                      },
-        {ACTION_OUTDENT,                  on_action                                     },
-        {ACTION_JUSTIFY,                  on_justify,                "s",     "'left'"  },
-        {ACTION_COLOR,                    on_select_color                               },
-        {ACTION_INSERT_IMAGE,             on_insert_image                               },
-        {ACTION_INSERT_LINK,              on_insert_link                                },
-        {ACTION_OPEN_INSPECTOR,           on_open_inspector                             },
+    private const ActionEntry[] EDITOR_ACTIONS = {
+        { Action.Edit.COPY,                on_copy                            },
+        { Action.Edit.REDO,                on_redo                            },
+        { Action.Edit.UNDO,                on_undo                            },
+        { ACTION_BOLD,                     on_action,        null, "false"    },
+        { ACTION_COLOR,                    on_select_color                    },
+        { ACTION_COPY_LINK,                on_copy_link                       },
+        { ACTION_CUT,                      on_cut                             },
+        { ACTION_FONT_FAMILY,              on_font_family,   "s",  "'sans'"   },
+        { ACTION_FONT_SIZE,                on_font_size,     "s",  "'medium'" },
+        { ACTION_INDENT,                   on_indent                          },
+        { ACTION_INSERT_IMAGE,             on_insert_image                    },
+        { ACTION_INSERT_LINK,              on_insert_link                     },
+        { ACTION_ITALIC,                   on_action,        null, "false"    },
+        { ACTION_JUSTIFY,                  on_justify,       "s",  "'left'"   },
+        { ACTION_OLIST,                    on_olist                           },
+        { ACTION_OUTDENT,                  on_action                          },
+        { ACTION_PASTE,                    on_paste                           },
+        { ACTION_PASTE_WITHOUT_FORMATTING, on_paste_without_formatting        },
+        { ACTION_REMOVE_FORMAT,            on_remove_format, null, "false"    },
+        { ACTION_SELECT_ALL,               on_select_all                      },
+        { ACTION_STRIKETHROUGH,            on_action,        null, "false"    },
+        { ACTION_ULIST,                    on_ulist                           },
+        { ACTION_UNDERLINE,                on_action,        null, "false"    },
     };
 
-    private const ActionEntry[] composer_action_entries = {
-        {GearyApplication.ACTION_CLOSE,   on_close                                                           
  },
-        {ACTION_CLOSE,                    on_close                                                           
  },
-        {ACTION_ADD_ATTACHMENT,           on_add_attachment                                                  
  },
-        {ACTION_ADD_ORIGINAL_ATTACHMENTS, on_pending_attachments                                             
  },
-        {ACTION_CLOSE_AND_DISCARD,        on_close_and_discard                                               
  },
-        {ACTION_CLOSE_AND_SAVE,           on_close_and_save                                                  
  },
-        {ACTION_COMPOSE_AS_HTML,          on_toggle_action,        null,   "true",  
on_compose_as_html_toggled },
-        {ACTION_DETACH,                   on_detach                                                          
  },
-        {ACTION_SELECT_DICTIONARY,        on_select_dictionary                                               
  },
-        {ACTION_SEND,                     on_send                                                            
  },
-        {ACTION_SHOW_EXTENDED,            on_toggle_action,        null,  "false",  on_show_extended_toggled 
  },
+    private const ActionEntry[] COMPOSER_ACTIONS = {
+        { Action.Window.CLOSE,             on_close                                                   },
+        { ACTION_ADD_ATTACHMENT,           on_add_attachment                                          },
+        { ACTION_ADD_ORIGINAL_ATTACHMENTS, on_pending_attachments                                     },
+        { ACTION_CLOSE,                    on_close                                                   },
+        { ACTION_CLOSE_AND_DISCARD,        on_close_and_discard                                       },
+        { ACTION_CLOSE_AND_SAVE,           on_close_and_save                                          },
+        { ACTION_COMPOSE_AS_HTML,          on_toggle_action, null, "true", on_compose_as_html_toggled },
+        { ACTION_DETACH,                   on_detach                                                  },
+        { ACTION_OPEN_INSPECTOR,           on_open_inspector                  },
+        { ACTION_SELECT_DICTIONARY,        on_select_dictionary                                       },
+        { ACTION_SEND,                     on_send                                                    },
+        { ACTION_SHOW_EXTENDED,            on_toggle_action, null, "false", on_show_extended_toggled  },
     };
 
-    public static void add_window_accelerators(GearyApplication application) {
+    public static void add_accelerators(GearyApplication application) {
         application.add_window_accelerators(ACTION_CLOSE, { "Escape" } );
-        application.add_window_accelerators(ACTION_CUT, { "<Ctrl>x" } );
-        application.add_window_accelerators(ACTION_PASTE, { "<Ctrl>v" } );
-        application.add_window_accelerators(ACTION_PASTE_WITHOUT_FORMATTING, { "<Ctrl><Shift>v" } );
-        application.add_window_accelerators(ACTION_INSERT_IMAGE, { "<Ctrl>g" } );
-        application.add_window_accelerators(ACTION_INSERT_LINK, { "<Ctrl>l" } );
-        application.add_window_accelerators(ACTION_INDENT, { "<Ctrl>bracketright" } );
-        application.add_window_accelerators(ACTION_OUTDENT, { "<Ctrl>bracketleft" } );
-        application.add_window_accelerators(ACTION_REMOVE_FORMAT, { "<Ctrl>space" } );
-        application.add_window_accelerators(ACTION_BOLD, { "<Ctrl>b" } );
-        application.add_window_accelerators(ACTION_ITALIC, { "<Ctrl>i" } );
-        application.add_window_accelerators(ACTION_UNDERLINE, { "<Ctrl>u" } );
-        application.add_window_accelerators(ACTION_STRIKETHROUGH, { "<Ctrl>k" } );
         application.add_window_accelerators(ACTION_ADD_ATTACHMENT, { "<Ctrl>t" } );
         application.add_window_accelerators(ACTION_DETACH, { "<Ctrl>d" } );
+
+        application.add_edit_accelerators(ACTION_CUT, { "<Ctrl>x" } );
+        application.add_edit_accelerators(ACTION_PASTE, { "<Ctrl>v" } );
+        application.add_edit_accelerators(ACTION_PASTE_WITHOUT_FORMATTING, { "<Ctrl><Shift>v" } );
+        application.add_edit_accelerators(ACTION_INSERT_IMAGE, { "<Ctrl>g" } );
+        application.add_edit_accelerators(ACTION_INSERT_LINK, { "<Ctrl>l" } );
+        application.add_edit_accelerators(ACTION_INDENT, { "<Ctrl>bracketright" } );
+        application.add_edit_accelerators(ACTION_OUTDENT, { "<Ctrl>bracketleft" } );
+        application.add_edit_accelerators(ACTION_REMOVE_FORMAT, { "<Ctrl>space" } );
+        application.add_edit_accelerators(ACTION_BOLD, { "<Ctrl>b" } );
+        application.add_edit_accelerators(ACTION_ITALIC, { "<Ctrl>i" } );
+        application.add_edit_accelerators(ACTION_UNDERLINE, { "<Ctrl>u" } );
+        application.add_edit_accelerators(ACTION_STRIKETHROUGH, { "<Ctrl>k" } );
     }
 
     private const string DRAFT_SAVED_TEXT = _("Saved");
@@ -338,8 +339,8 @@ public class ComposerWidget : Gtk.EventBox, Geary.BaseInterface {
     [GtkChild]
     private Gtk.Label info_label;
 
-    private SimpleActionGroup composer_actions = new SimpleActionGroup();
-    private SimpleActionGroup editor_actions = new SimpleActionGroup();
+    private GLib.SimpleActionGroup composer_actions = new GLib.SimpleActionGroup();
+    private GLib.SimpleActionGroup editor_actions = new GLib.SimpleActionGroup();
 
     private Menu html_menu;
     private Menu plain_menu;
@@ -875,29 +876,23 @@ public class ComposerWidget : Gtk.EventBox, Geary.BaseInterface {
     // Initializes all actions and adds them to the action group
     private void initialize_actions() {
         // Composer actions
-        this.composer_actions.add_action_entries(
-            ComposerWidget.composer_action_entries, this
-        );
-        // Main actions use 'win' prefix so they override main window
-        // action. But for some reason, we can't use the same prefix
-        // for the headerbar.
-        insert_action_group("win", this.composer_actions);
+        this.composer_actions.add_action_entries(COMPOSER_ACTIONS, this);
+        // Main actions use the window prefix so they override main
+        // window actions. But for some reason, we can't use the same
+        // prefix for the headerbar.
+        insert_action_group(Action.Window.GROUP_NAME, this.composer_actions);
         this.header.insert_action_group("cmh", this.composer_actions);
 
-        // Editor actions - scoped to the editor only. Need to include
-        // composer actions however since if not found in this group,
-        // ancestors (including the composer's) will not be consulted.
-        this.editor_actions.add_action_entries(
-            ComposerWidget.composer_action_entries, this
+        // Editor actions - scoped to the editor only.
+        this.editor_actions.add_action_entries(EDITOR_ACTIONS, this);
+        this.editor_container.insert_action_group(
+            Action.Edit.GROUP_NAME, this.editor_actions
         );
-        this.editor_actions.add_action_entries(
-            ComposerWidget.editor_action_entries, this
-        );
-        this.editor_container.insert_action_group("win", this.editor_actions);
 
-        SimpleActionGroup[] composer_action_entries_users
-            = {this.editor_actions, this.composer_actions};
-        foreach (SimpleActionGroup entries_users in composer_action_entries_users) {
+        GLib.SimpleActionGroup[] composer_action_entries_users = {
+            this.editor_actions, this.composer_actions
+        };
+        foreach (var entries_users in composer_action_entries_users) {
             entries_users.change_action_state(ACTION_SHOW_EXTENDED, false);
             entries_users.change_action_state(
                 ACTION_COMPOSE_AS_HTML, this.application.config.compose_as_html
@@ -905,8 +900,8 @@ public class ComposerWidget : Gtk.EventBox, Geary.BaseInterface {
         }
 
         get_action(ACTION_CLOSE_AND_SAVE).set_enabled(false);
-        get_action(GearyApplication.ACTION_UNDO).set_enabled(false);
-        get_action(GearyApplication.ACTION_REDO).set_enabled(false);
+        get_action(Action.Edit.UNDO).set_enabled(false);
+        get_action(Action.Edit.REDO).set_enabled(false);
 
         update_cursor_actions();
     }
@@ -914,7 +909,7 @@ public class ComposerWidget : Gtk.EventBox, Geary.BaseInterface {
     private void update_cursor_actions() {
         bool has_selection = this.editor.has_selection;
         get_action(ACTION_CUT).set_enabled(has_selection);
-        get_action(GearyApplication.ACTION_COPY).set_enabled(has_selection);
+        get_action(Action.Edit.COPY).set_enabled(has_selection);
 
         get_action(ACTION_INSERT_LINK).set_enabled(
             this.editor.is_rich_text && (has_selection || this.cursor_url != null)
@@ -1913,7 +1908,7 @@ public class ComposerWidget : Gtk.EventBox, Geary.BaseInterface {
         bool compose_as_html = new_state.get_boolean();
         action.set_state(compose_as_html);
 
-        foreach (string html_action in html_actions)
+        foreach (string html_action in HTML_ACTIONS)
             get_action(html_action).set_enabled(compose_as_html);
 
         update_cursor_actions();
@@ -2362,8 +2357,8 @@ public class ComposerWidget : Gtk.EventBox, Geary.BaseInterface {
     }
 
     private void on_command_state_changed(bool can_undo, bool can_redo) {
-        get_action(GearyApplication.ACTION_UNDO).set_enabled(can_undo);
-        get_action(GearyApplication.ACTION_REDO).set_enabled(can_redo);
+        get_action(Action.Edit.UNDO).set_enabled(can_undo);
+        get_action(Action.Edit.REDO).set_enabled(can_redo);
     }
 
     private void on_editor_content_loaded() {
diff --git a/src/client/dialogs/dialogs-problem-details-dialog.vala 
b/src/client/dialogs/dialogs-problem-details-dialog.vala
index 72478079..59e4c97f 100644
--- a/src/client/dialogs/dialogs-problem-details-dialog.vala
+++ b/src/client/dialogs/dialogs-problem-details-dialog.vala
@@ -16,15 +16,18 @@ public class Dialogs.ProblemDetailsDialog : Hdy.Dialog {
     private const string ACTION_SEARCH_TOGGLE = "toggle-search";
     private const string ACTION_SEARCH_ACTIVATE = "activate-search";
 
-    private const ActionEntry[] action_entries = {
-        {GearyApplication.ACTION_CLOSE, on_close },
-        {GearyApplication.ACTION_COPY,  on_copy_clicked },
-        {ACTION_CLOSE,                  on_close },
-        {ACTION_SEARCH_TOGGLE,          on_logs_search_toggled, null, "false" },
-        {ACTION_SEARCH_ACTIVATE,        on_logs_search_activated },
+    private const ActionEntry[] EDIT_ACTIONS = {
+        { Action.Edit.COPY,  on_copy_clicked },
     };
 
-    public static void add_window_accelerators(GearyApplication app) {
+    private const ActionEntry[] WINDOW_ACTIONS = {
+        { Action.Window.CLOSE, on_close },
+        { ACTION_CLOSE, on_close },
+        { ACTION_SEARCH_TOGGLE, on_logs_search_toggled, null, "false" },
+        { ACTION_SEARCH_ACTIVATE, on_logs_search_activated },
+    };
+
+    public static void add_accelerators(GearyApplication app) {
         app.add_window_accelerators(ACTION_CLOSE, { "Escape" } );
         app.add_window_accelerators(ACTION_SEARCH_ACTIVATE, { "<Ctrl>F" } );
     }
@@ -64,9 +67,15 @@ public class Dialogs.ProblemDetailsDialog : Hdy.Dialog {
         this.account = (account_report != null) ? account_report.account : null;
         this.service = (service_report != null) ? service_report.service : null;
 
-        GLib.SimpleActionGroup actions = new GLib.SimpleActionGroup();
-        actions.add_action_entries(ProblemDetailsDialog.action_entries, this);
-        insert_action_group("win", actions);
+        // Edit actions
+        GLib.SimpleActionGroup edit_actions = new GLib.SimpleActionGroup();
+        edit_actions.add_action_entries(EDIT_ACTIONS, this);
+        insert_action_group(Action.Edit.GROUP_NAME, edit_actions);
+
+        // Window actions
+        GLib.SimpleActionGroup window_actions = new GLib.SimpleActionGroup();
+        window_actions.add_action_entries(WINDOW_ACTIONS, this);
+        insert_action_group(Action.Window.GROUP_NAME, window_actions);
 
         this.error_pane = new Components.InspectorErrorView(
             error, account, service
diff --git a/src/client/meson.build b/src/client/meson.build
index 47a261f6..405e93af 100644
--- a/src/client/meson.build
+++ b/src/client/meson.build
@@ -25,6 +25,8 @@ geary_client_vala_sources = files(
   'accounts/accounts-signature-web-view.vala',
   'accounts/accounts-manager.vala',
 
+  'client-action.vala',
+
   'components/client-web-view.vala',
   'components/components-attachment-pane.vala',
   'components/components-entry-undo.vala',
diff --git a/src/client/plugin/desktop-notifications/desktop-notifications.vala 
b/src/client/plugin/desktop-notifications/desktop-notifications.vala
index 506fa3c3..700a0db6 100644
--- a/src/client/plugin/desktop-notifications/desktop-notifications.vala
+++ b/src/client/plugin/desktop-notifications/desktop-notifications.vala
@@ -149,9 +149,9 @@ public class Plugin.DesktopNotifications : Notification {
         };
 
         if (id == null) {
-            action = GearyApplication.ACTION_SHOW_FOLDER;
+            action = Action.Application.SHOW_FOLDER;
         } else {
-            action = GearyApplication.ACTION_SHOW_EMAIL;
+            action = Action.Application.SHOW_EMAIL;
             target_param += new GLib.Variant.variant(id.to_variant());
         }
 
@@ -159,7 +159,7 @@ public class Plugin.DesktopNotifications : Notification {
             ARRIVED_ID,
             summary,
             body,
-            "app." + action,
+            Action.Application.prefix(action),
             new GLib.Variant.tuple(target_param)
         );
     }
diff --git a/ui/accounts_editor_edit_pane.ui b/ui/accounts_editor_edit_pane.ui
index 2ece4d54..3516e5aa 100644
--- a/ui/accounts_editor_edit_pane.ui
+++ b/ui/accounts_editor_edit_pane.ui
@@ -44,7 +44,7 @@
             <property name="visible">True</property>
             <property name="can_focus">True</property>
             <property name="receives_default">True</property>
-            <property name="action_name">win.undo</property>
+            <property name="action_name">edt.undo</property>
             <child>
               <object class="GtkImage">
                 <property name="visible">True</property>
diff --git a/ui/components-inspector.ui b/ui/components-inspector.ui
index b910e61d..6cc06fe8 100644
--- a/ui/components-inspector.ui
+++ b/ui/components-inspector.ui
@@ -82,7 +82,7 @@
             <property name="receives_default">True</property>
             <property name="tooltip_text" translatable="yes"
                       comments="Tooltip for inspector button">Copy to clipboard</property>
-            <property name="action_name">win.copy</property>
+            <property name="action_name">edt.copy</property>
             <child>
               <object class="GtkImage">
                 <property name="visible">True</property>
diff --git a/ui/composer-menus.ui b/ui/composer-menus.ui
index e6854a4e..1bd5b64b 100644
--- a/ui/composer-menus.ui
+++ b/ui/composer-menus.ui
@@ -5,41 +5,41 @@
     <section>
       <item>
         <attribute name="label" translatable="yes">S_ans Serif</attribute>
-        <attribute name="action">win.font-family</attribute>
+        <attribute name="action">edt.font-family</attribute>
         <attribute name="target">sans</attribute>
       </item>
       <item>
         <attribute name="label" translatable="yes">S_erif</attribute>
-        <attribute name="action">win.font-family</attribute>
+        <attribute name="action">edt.font-family</attribute>
         <attribute name="target">serif</attribute>
       </item>
       <item>
         <attribute name="label" translatable="yes">_Fixed Width</attribute>
-        <attribute name="action">win.font-family</attribute>
+        <attribute name="action">edt.font-family</attribute>
         <attribute name="target">monospace</attribute>
       </item>
     </section>
     <section>
       <item>
         <attribute name="label" translatable="yes">_Small</attribute>
-        <attribute name="action">win.font-size</attribute>
+        <attribute name="action">edt.font-size</attribute>
         <attribute name="target">small</attribute>
       </item>
       <item>
         <attribute name="label" translatable="yes">_Medium</attribute>
-        <attribute name="action">win.font-size</attribute>
+        <attribute name="action">edt.font-size</attribute>
         <attribute name="target">medium</attribute>
       </item>
       <item>
         <attribute name="label" translatable="yes">Lar_ge</attribute>
-        <attribute name="action">win.font-size</attribute>
+        <attribute name="action">edt.font-size</attribute>
         <attribute name="target">large</attribute>
       </item>
     </section>
     <section>
       <item>
         <attribute name="label" translatable="yes">C_olor</attribute>
-        <attribute name="action">win.color</attribute>
+        <attribute name="action">edt.color</attribute>
       </item>
     </section>
     <section>
@@ -76,49 +76,49 @@
     <section>
       <item>
         <attribute name="label" translatable="yes">_Undo</attribute>
-        <attribute name="action">win.undo</attribute>
+        <attribute name="action">edt.undo</attribute>
       </item>
       <item>
         <attribute name="label" translatable="yes">_Redo</attribute>
-        <attribute name="action">win.redo</attribute>
+        <attribute name="action">edt.redo</attribute>
       </item>
     </section>
     <section id="context_menu_rich_text">
       <item>
         <attribute name="label" translatable="yes">Cu_t</attribute>
-        <attribute name="action">win.cut</attribute>
+        <attribute name="action">edt.cut</attribute>
       </item>
       <item>
         <attribute name="label" translatable="yes">_Copy</attribute>
-        <attribute name="action">win.copy</attribute>
+        <attribute name="action">edt.copy</attribute>
       </item>
       <item>
         <attribute name="label" translatable="yes">_Paste</attribute>
-        <attribute name="action">win.paste</attribute>
+        <attribute name="action">edt.paste</attribute>
       </item>
       <item>
         <attribute name="label" translatable="yes" context="Clipboard paste as plain text">Paste _Without 
Formatting</attribute>
-        <attribute name="action">win.paste-without-formatting</attribute>
+        <attribute name="action">edt.paste-without-formatting</attribute>
       </item>
     </section>
     <section id="context_menu_plain_text">
       <item>
         <attribute name="label" translatable="yes">Cu_t</attribute>
-        <attribute name="action">win.cut</attribute>
+        <attribute name="action">edt.cut</attribute>
       </item>
       <item>
         <attribute name="label" translatable="yes">_Copy</attribute>
-        <attribute name="action">win.copy</attribute>
+        <attribute name="action">edt.copy</attribute>
       </item>
       <item>
         <attribute name="label" translatable="yes">_Paste</attribute>
-        <attribute name="action">win.paste</attribute>
+        <attribute name="action">edt.paste</attribute>
       </item>
     </section>
     <section>
       <item>
         <attribute name="label" translatable="yes">Select _All</attribute>
-        <attribute name="action">win.select-all</attribute>
+        <attribute name="action">edt.select-all</attribute>
       </item>
     </section>
     <section id="context_menu_webkit_text_entry"/>
diff --git a/ui/composer-widget.ui b/ui/composer-widget.ui
index 95e1ef46..b65a91ff 100644
--- a/ui/composer-widget.ui
+++ b/ui/composer-widget.ui
@@ -351,7 +351,7 @@
                         <property name="focus_on_click">False</property>
                         <property name="receives_default">False</property>
                         <property name="tooltip_text" translatable="yes">Undo last edit (Ctrl+Z)</property>
-                        <property name="action_name">win.undo</property>
+                        <property name="action_name">edt.undo</property>
                         <property name="always_show_image">True</property>
                         <child>
                           <object class="GtkImage">
@@ -375,7 +375,7 @@
                         <property name="focus_on_click">False</property>
                         <property name="receives_default">False</property>
                         <property name="tooltip_text" translatable="yes">Redo last edit  
(Ctrl+Shift+Z)</property>
-                        <property name="action_name">win.redo</property>
+                        <property name="action_name">edt.redo</property>
                         <property name="always_show_image">True</property>
                         <child>
                           <object class="GtkImage">
@@ -413,7 +413,7 @@
                         <property name="focus_on_click">False</property>
                         <property name="receives_default">False</property>
                         <property name="tooltip_text" translatable="yes">Bold (Ctrl+B)</property>
-                        <property name="action_name">win.bold</property>
+                        <property name="action_name">edt.bold</property>
                         <property name="always_show_image">True</property>
                         <child>
                           <object class="GtkImage" id="bold_image">
@@ -437,7 +437,7 @@
                         <property name="focus_on_click">False</property>
                         <property name="receives_default">False</property>
                         <property name="tooltip_text" translatable="yes">Italic (Ctrl+I)</property>
-                        <property name="action_name">win.italic</property>
+                        <property name="action_name">edt.italic</property>
                         <property name="always_show_image">True</property>
                         <child>
                           <object class="GtkImage" id="italics_image">
@@ -461,7 +461,7 @@
                         <property name="focus_on_click">False</property>
                         <property name="receives_default">False</property>
                         <property name="tooltip_text" translatable="yes">Underline (Ctrl+U)</property>
-                        <property name="action_name">win.underline</property>
+                        <property name="action_name">edt.underline</property>
                         <property name="always_show_image">True</property>
                         <child>
                           <object class="GtkImage" id="underline_image">
@@ -485,7 +485,7 @@
                         <property name="focus_on_click">False</property>
                         <property name="receives_default">False</property>
                         <property name="tooltip_text" translatable="yes">Strikethrough (Ctrl+K)</property>
-                        <property name="action_name">win.strikethrough</property>
+                        <property name="action_name">edt.strikethrough</property>
                         <property name="always_show_image">True</property>
                         <child>
                           <object class="GtkImage" id="strikethrough_image">
@@ -523,7 +523,7 @@
                         <property name="focus_on_click">False</property>
                         <property name="receives_default">False</property>
                         <property name="tooltip_text" translatable="yes">Insert unordered list</property>
-                        <property name="action_name">win.ulist</property>
+                        <property name="action_name">edt.ulist</property>
                         <property name="always_show_image">True</property>
                         <child>
                           <object class="GtkImage" id="ulist_image">
@@ -547,7 +547,7 @@
                         <property name="focus_on_click">False</property>
                         <property name="receives_default">False</property>
                         <property name="tooltip_text" translatable="yes">Insert ordered list</property>
-                        <property name="action_name">win.olist</property>
+                        <property name="action_name">edt.olist</property>
                         <property name="always_show_image">True</property>
                         <child>
                           <object class="GtkImage" id="olist_image">
@@ -585,7 +585,7 @@
                         <property name="focus_on_click">False</property>
                         <property name="receives_default">False</property>
                         <property name="tooltip_text" translatable="yes">Quote text  (Ctrl+])</property>
-                        <property name="action_name">win.indent</property>
+                        <property name="action_name">edt.indent</property>
                         <property name="always_show_image">True</property>
                         <child>
                           <object class="GtkImage" id="indent_image">
@@ -609,7 +609,7 @@
                         <property name="focus_on_click">False</property>
                         <property name="receives_default">False</property>
                         <property name="tooltip_text" translatable="yes">Unquote text  (Ctrl+[)</property>
-                        <property name="action_name">win.outdent</property>
+                        <property name="action_name">edt.outdent</property>
                         <property name="always_show_image">True</property>
                         <child>
                           <object class="GtkImage" id="outdent_image">
@@ -647,7 +647,7 @@
                         <property name="focus_on_click">False</property>
                         <property name="receives_default">False</property>
                         <property name="tooltip_text" translatable="yes">Insert or update selection link 
(Ctrl+L)</property>
-                        <property name="action_name">win.insert-link</property>
+                        <property name="action_name">edt.insert-link</property>
                         <property name="always_show_image">True</property>
                         <child>
                           <object class="GtkImage" id="insert_link_image">
@@ -671,7 +671,7 @@
                         <property name="focus_on_click">False</property>
                         <property name="receives_default">False</property>
                         <property name="tooltip_text" translatable="yes">Insert an image (Ctrl+G)</property>
-                        <property name="action_name">win.insert-image</property>
+                        <property name="action_name">edt.insert-image</property>
                         <property name="always_show_image">True</property>
                         <child>
                           <object class="GtkImage">
@@ -705,7 +705,7 @@
                     <property name="focus_on_click">False</property>
                     <property name="receives_default">False</property>
                     <property name="tooltip_text" translatable="yes">Remove selection formatting 
(Ctrl+Space)</property>
-                    <property name="action_name">win.remove-format</property>
+                    <property name="action_name">edt.remove-format</property>
                     <property name="always_show_image">True</property>
                     <child>
                       <object class="GtkImage" id="remove_format_image">


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