Plugin.Application: Add support for emptying folders

Allow plugins to delete all email from a folder after getting user
confirmation.
This commit is contained in:
Michael Gratton 2020-03-20 18:19:38 +11:00 committed by Michael James Gratton
parent 9b0f359b97
commit cbe5fb6a07
4 changed files with 93 additions and 18 deletions

View file

@ -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 {

View file

@ -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.") +
" <b>" + _("This cannot be undone.") + "</b>",
_("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.") +
" <b>" + _("This cannot be undone.") + "</b>",
_("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<Geary.App.Conversation>
load_conversations_for_email(
Geary.Folder location,

View file

@ -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;

View file

@ -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;
}