diff --git a/src/client/application/application-controller.vala b/src/client/application/application-controller.vala index 613c9d24..08d7fdc2 100644 --- a/src/client/application/application-controller.vala +++ b/src/client/application/application-controller.vala @@ -828,6 +828,30 @@ internal class Application.Controller : Geary.BaseObject { } } + public async void empty_folder(Geary.Folder target) + throws GLib.Error { + AccountContext? context = this.accounts.get(target.account.information); + if (context != null) { + Geary.FolderSupport.Empty? emptyable = ( + target as Geary.FolderSupport.Empty + ); + if (emptyable == null) { + throw new Geary.EngineError.UNSUPPORTED( + "Emptying folder not supported %s", target.path.to_string() + ); + } + + Command command = new EmptyFolderCommand(emptyable); + command.executed.connect( + // Not quite accurate, but close enough + () => context.controller_stack.folders_removed( + Geary.Collection.single(emptyable) + ) + ); + yield context.commands.execute(command, context.cancellable); + } + } + public async void empty_folder_special(Geary.Account source, Geary.SpecialFolderType type) throws GLib.Error { diff --git a/src/client/application/application-main-window.vala b/src/client/application/application-main-window.vala index 2b97de96..9c7c7afd 100644 --- a/src/client/application/application-main-window.vala +++ b/src/client/application/application-main-window.vala @@ -1285,6 +1285,22 @@ public class Application.MainWindow : return base.key_release_event(event); } + internal bool prompt_empty_folder(Geary.SpecialFolderType type) { + ConfirmationDialog dialog = new ConfirmationDialog( + this, + _("Empty all email from your %s folder?").printf( + type.get_display_name() + ), + _("This removes the email from Geary and your email server.") + + " " + _("This cannot be undone.") + "", + _("Empty %s").printf(type.get_display_name()), + "destructive-action" + ); + dialog.use_secondary_markup(true); + dialog.set_focus_response(Gtk.ResponseType.CANCEL); + return (dialog.run() == Gtk.ResponseType.OK); + } + /** Un-does the last executed application command, if any. */ private async void undo() { AccountContext? selected = get_selected_account_context(); @@ -1359,23 +1375,6 @@ public class Application.MainWindow : return (dialog.run() == Gtk.ResponseType.OK); } - private bool prompt_empty_folder(Geary.SpecialFolderType type) { - ConfirmationDialog dialog = new ConfirmationDialog( - this, - _("Empty all email from your %s folder?").printf( - type.get_display_name() - ), - _("This removes the email from Geary and your email server.") + - " " + _("This cannot be undone.") + "", - _("Empty %s").printf(type.get_display_name()), - "destructive-action" - ); - dialog.use_secondary_markup(true); - dialog.set_focus_response(Gtk.ResponseType.CANCEL); - return (dialog.run() == Gtk.ResponseType.OK); - } - - private async Gee.Collection load_conversations_for_email( Geary.Folder location, diff --git a/src/client/application/application-plugin-manager.vala b/src/client/application/application-plugin-manager.vala index fd89c5d7..6db8a788 100644 --- a/src/client/application/application-plugin-manager.vala +++ b/src/client/application/application-plugin-manager.vala @@ -16,7 +16,7 @@ public class Application.PluginManager : GLib.Object { private const string[] AUTOLOAD_MODULES = { "desktop-notifications", "folder-highlight", - "notification-badge", + "notification-badge" }; @@ -89,6 +89,42 @@ public class Application.PluginManager : GLib.Object { } } + public override async void empty_folder(Plugin.Folder folder) + throws Plugin.Error.PERMISSION_DENIED { + MainWindow main = this.backing.last_active_main_window; + if (main == null) { + throw new Plugin.Error.PERMISSION_DENIED( + "Cannot prompt for permission" + ); + } + + Geary.Folder? target = this.folders.get_engine_folder(folder); + if (target != null) { + if (!main.prompt_empty_folder(target.special_folder_type)) { + throw new Plugin.Error.PERMISSION_DENIED( + "Permission not granted" + ); + } + + Application.Controller controller = this.backing.controller; + controller.empty_folder.begin( + target, + (obj, res) => { + try { + controller.empty_folder.end(res); + } catch (GLib.Error error) { + controller.report_problem( + new Geary.AccountProblemReport( + target.account.information, + error + ) + ); + } + } + ); + } + } + private void on_window_added(Gtk.Window window) { if (this.action_group != null) { var main = window as MainWindow; diff --git a/src/client/plugin/plugin-application.vala b/src/client/plugin/plugin-application.vala index 0d0687ef..585f2b7a 100644 --- a/src/client/plugin/plugin-application.vala +++ b/src/client/plugin/plugin-application.vala @@ -37,4 +37,20 @@ public interface Plugin.Application : Geary.BaseObject { /** Displays a folder in the most recently used main window. */ public abstract void show_folder(Folder folder); + /** + * Reversibly deletes all email from a folder. + * + * A prompt will be displayed for confirmation before the folder + * is actually emptied, if declined an exception will be thrown. + * + * This method will return once the engine has completed emptying + * the folder, however it may take additional time for the changes + * to be fully committed and reflected on the remote server. + * + * @throws Error.PERMISSIONS if permission was not granted to + * empty the folder + */ + public abstract async void empty_folder(Folder folder) + throws Error.PERMISSION_DENIED; + }