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, { "N" }); - add_app_accelerators(ACTION_HELP, { "F1" }); - add_app_accelerators(ACTION_INSPECT, { "I" }); - add_app_accelerators(ACTION_QUIT, { "Q" }); + add_app_accelerators(Action.Application.COMPOSE, { "N" }); + add_app_accelerators(Action.Application.HELP, { "F1" }); + add_app_accelerators(Action.Application.INSPECT, { "I" }); + add_app_accelerators(Action.Application.QUIT, { "Q" }); // Common window accels - add_window_accelerators(ACTION_CLOSE, { "W" }); - add_window_accelerators(ACTION_COPY, { "C" }); - add_window_accelerators(ACTION_HELP_OVERLAY, { "F1", "question" }); - add_window_accelerators(ACTION_REDO, { "Z" }); - add_window_accelerators(ACTION_UNDO, { "Z" }); + add_window_accelerators(Action.Window.CLOSE, { "W" }); + add_window_accelerators( + Action.Window.SHORTCUT_HELP, { "F1", "question" } + ); - MainWindow.add_window_accelerators(this); - ComposerWidget.add_window_accelerators(this); - Components.EntryUndo.add_window_accelerators(this); - Components.Inspector.add_window_accelerators(this); + // Common edit accels + add_edit_accelerators(Action.Edit.COPY, { "C" }); + add_edit_accelerators(Action.Edit.REDO, { "Z" }); + add_edit_accelerators(Action.Edit.UNDO, { "Z" }); + + 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 + * + * 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, - { "z" } - ); - application.set_accels_for_action( - ACTION_GROUP + "." + GearyApplication.ACTION_REDO, - { "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, { "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..bc000bbb 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 @@ -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.REDO)); add_notification(ian); } update_command_actions(); @@ -1621,8 +1636,8 @@ public class MainWindow : Gtk.ApplicationWindow, Geary.BaseInterface { private void on_command_redo(Application.Command command) { if (command.executed_label != null) { Components.InAppNotification ian = - new Components.InAppNotification(command.executed_label); - ian.set_button(_("Undo"), "win." + GearyApplication.ACTION_UNDO); + new Components.InAppNotification(command.executed_label); + ian.set_button(_("Undo"), Action.Edit.prefix(Action.Edit.UNDO)); 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, { "x" } ); - application.add_window_accelerators(ACTION_PASTE, { "v" } ); - application.add_window_accelerators(ACTION_PASTE_WITHOUT_FORMATTING, { "v" } ); - application.add_window_accelerators(ACTION_INSERT_IMAGE, { "g" } ); - application.add_window_accelerators(ACTION_INSERT_LINK, { "l" } ); - application.add_window_accelerators(ACTION_INDENT, { "bracketright" } ); - application.add_window_accelerators(ACTION_OUTDENT, { "bracketleft" } ); - application.add_window_accelerators(ACTION_REMOVE_FORMAT, { "space" } ); - application.add_window_accelerators(ACTION_BOLD, { "b" } ); - application.add_window_accelerators(ACTION_ITALIC, { "i" } ); - application.add_window_accelerators(ACTION_UNDERLINE, { "u" } ); - application.add_window_accelerators(ACTION_STRIKETHROUGH, { "k" } ); application.add_window_accelerators(ACTION_ADD_ATTACHMENT, { "t" } ); application.add_window_accelerators(ACTION_DETACH, { "d" } ); + + application.add_edit_accelerators(ACTION_CUT, { "x" } ); + application.add_edit_accelerators(ACTION_PASTE, { "v" } ); + application.add_edit_accelerators(ACTION_PASTE_WITHOUT_FORMATTING, { "v" } ); + application.add_edit_accelerators(ACTION_INSERT_IMAGE, { "g" } ); + application.add_edit_accelerators(ACTION_INSERT_LINK, { "l" } ); + application.add_edit_accelerators(ACTION_INDENT, { "bracketright" } ); + application.add_edit_accelerators(ACTION_OUTDENT, { "bracketleft" } ); + application.add_edit_accelerators(ACTION_REMOVE_FORMAT, { "space" } ); + application.add_edit_accelerators(ACTION_BOLD, { "b" } ); + application.add_edit_accelerators(ACTION_ITALIC, { "i" } ); + application.add_edit_accelerators(ACTION_UNDERLINE, { "u" } ); + application.add_edit_accelerators(ACTION_STRIKETHROUGH, { "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, { "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 @@ True True True - win.undo + edt.undo True 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 @@ True Copy to clipboard - win.copy + edt.copy True 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 @@
S_ans Serif - win.font-family + edt.font-family sans S_erif - win.font-family + edt.font-family serif _Fixed Width - win.font-family + edt.font-family monospace
_Small - win.font-size + edt.font-size small _Medium - win.font-size + edt.font-size medium Lar_ge - win.font-size + edt.font-size large
C_olor - win.color + edt.color
@@ -76,49 +76,49 @@
_Undo - win.undo + edt.undo _Redo - win.redo + edt.redo
Cu_t - win.cut + edt.cut _Copy - win.copy + edt.copy _Paste - win.paste + edt.paste Paste _Without Formatting - win.paste-without-formatting + edt.paste-without-formatting
Cu_t - win.cut + edt.cut _Copy - win.copy + edt.copy _Paste - win.paste + edt.paste
Select _All - win.select-all + edt.select-all
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 @@ False False Undo last edit (Ctrl+Z) - win.undo + edt.undo True @@ -375,7 +375,7 @@ False False Redo last edit (Ctrl+Shift+Z) - win.redo + edt.redo True @@ -413,7 +413,7 @@ False False Bold (Ctrl+B) - win.bold + edt.bold True @@ -437,7 +437,7 @@ False False Italic (Ctrl+I) - win.italic + edt.italic True @@ -461,7 +461,7 @@ False False Underline (Ctrl+U) - win.underline + edt.underline True @@ -485,7 +485,7 @@ False False Strikethrough (Ctrl+K) - win.strikethrough + edt.strikethrough True @@ -523,7 +523,7 @@ False False Insert unordered list - win.ulist + edt.ulist True @@ -547,7 +547,7 @@ False False Insert ordered list - win.olist + edt.olist True @@ -585,7 +585,7 @@ False False Quote text (Ctrl+]) - win.indent + edt.indent True @@ -609,7 +609,7 @@ False False Unquote text (Ctrl+[) - win.outdent + edt.outdent True @@ -647,7 +647,7 @@ False False Insert or update selection link (Ctrl+L) - win.insert-link + edt.insert-link True @@ -671,7 +671,7 @@ False False Insert an image (Ctrl+G) - win.insert-image + edt.insert-image True @@ -705,7 +705,7 @@ False False Remove selection formatting (Ctrl+Space) - win.remove-format + edt.remove-format True