Commit 968743ac authored by Charles Lindsay's avatar Charles Lindsay

Add separate trash/archive/delete buttons

Archive shows up as its own button for any account that supports
archiving (currently only Gmail).  Trash or delete shows up as one
button, depending on what the folder supports and whether you've got the
shift key held down.  Future work will extend supporting archive to
other account types and getting the trash special folder recognized in
more accounts.

Closes: bgo #714212
parent 54dad5e1
......@@ -15,6 +15,8 @@ public class GearyController : Geary.BaseObject {
public const string ACTION_REPLY_TO_MESSAGE = "GearyReplyToMessage";
public const string ACTION_REPLY_ALL_MESSAGE = "GearyReplyAllMessage";
public const string ACTION_FORWARD_MESSAGE = "GearyForwardMessage";
public const string ACTION_ARCHIVE_MESSAGE = "GearyArchiveMessage";
public const string ACTION_TRASH_MESSAGE = "GearyTrashMessage";
public const string ACTION_DELETE_MESSAGE = "GearyDeleteMessage";
public const string ACTION_FIND_IN_CONVERSATION = "GearyFindInConversation";
public const string ACTION_FIND_NEXT_IN_CONVERSATION = "GearyFindNextInConversation";
......@@ -40,13 +42,18 @@ public class GearyController : Geary.BaseObject {
public const int MIN_CONVERSATION_COUNT = 50;
private const string DELETE_MESSAGE_LABEL = _("_Delete");
private const string DELETE_MESSAGE_TOOLTIP_SINGLE = _("Delete conversation (Delete, Backspace, A)");
private const string DELETE_MESSAGE_TOOLTIP_MULTIPLE = _("Delete conversations (Delete, Backspace, A)");
private const string DELETE_MESSAGE_ICON_NAME = "user-trash-symbolic";
private const string DELETE_MESSAGE_TOOLTIP_SINGLE = _("Delete conversation (Shift+Delete)");
private const string DELETE_MESSAGE_TOOLTIP_MULTIPLE = _("Delete conversations (Shift+Delete)");
private const string DELETE_MESSAGE_ICON_NAME = "edit-delete-symbolic";
private const string TRASH_MESSAGE_LABEL = _("_Trash");
private const string TRASH_MESSAGE_TOOLTIP_SINGLE = _("Move conversation to trash (Delete, Backspace)");
private const string TRASH_MESSAGE_TOOLTIP_MULTIPLE = _("Move conversations to trash (Delete, Backspace)");
private const string TRASH_MESSAGE_ICON_NAME = "user-trash-symbolic";
private const string ARCHIVE_MESSAGE_LABEL = _("_Archive");
private const string ARCHIVE_MESSAGE_TOOLTIP_SINGLE = _("Archive conversation (Delete, Backspace, A)");
private const string ARCHIVE_MESSAGE_TOOLTIP_MULTIPLE = _("Archive conversations (Delete, Backspace, A)");
private const string ARCHIVE_MESSAGE_TOOLTIP_SINGLE = _("Archive conversation (A)");
private const string ARCHIVE_MESSAGE_TOOLTIP_MULTIPLE = _("Archive conversations (A)");
private const string ARCHIVE_MESSAGE_ICON_NAME = "archive-symbolic";
private const string MARK_AS_SPAM_LABEL = _("Mark as S_pam");
......@@ -156,6 +163,7 @@ public class GearyController : Geary.BaseObject {
// Create the main window (must be done after creating actions.)
main_window = new MainWindow(GearyApplication.instance);
main_window.on_shift_key.connect(on_shift_key);
main_window.notify["has-toplevel-focus"].connect(on_has_toplevel_focus);
enable_message_buttons(false);
......@@ -338,14 +346,24 @@ public class GearyController : Geary.BaseObject {
null, null, "<Shift><Ctrl>G", null, on_find_previous_in_conversation_action };
entries += find_previous_in_conversation;
// although this action changes according to Geary.Folder capabilities, set to Archive
Gtk.ActionEntry archive_message = { ACTION_ARCHIVE_MESSAGE, ARCHIVE_MESSAGE_ICON_NAME,
ARCHIVE_MESSAGE_LABEL, "A", null, on_archive_message };
archive_message.tooltip = ARCHIVE_MESSAGE_TOOLTIP_SINGLE;
entries += archive_message;
// although this action changes according to the account's capabilities, set to Delete
// until they're known so the "translatable" string doesn't first appear
Gtk.ActionEntry delete_message = { ACTION_DELETE_MESSAGE, ARCHIVE_MESSAGE_ICON_NAME,
ARCHIVE_MESSAGE_LABEL, "A", null, on_delete_message };
delete_message.tooltip = ARCHIVE_MESSAGE_TOOLTIP_SINGLE;
Gtk.ActionEntry trash_message = { ACTION_TRASH_MESSAGE, TRASH_MESSAGE_ICON_NAME,
TRASH_MESSAGE_LABEL, "Delete", null, on_trash_message };
trash_message.tooltip = TRASH_MESSAGE_TOOLTIP_SINGLE;
entries += trash_message;
add_accelerator("BackSpace", ACTION_TRASH_MESSAGE);
Gtk.ActionEntry delete_message = { ACTION_DELETE_MESSAGE, DELETE_MESSAGE_ICON_NAME,
DELETE_MESSAGE_LABEL, "<Shift>Delete", null, on_delete_message };
delete_message.tooltip = DELETE_MESSAGE_TOOLTIP_SINGLE;
entries += delete_message;
add_accelerator("Delete", ACTION_DELETE_MESSAGE);
add_accelerator("BackSpace", ACTION_DELETE_MESSAGE);
add_accelerator("<Shift>BackSpace", ACTION_DELETE_MESSAGE);
Gtk.ActionEntry zoom_in = { ACTION_ZOOM_IN, null, null, "<Ctrl>equal",
null, on_zoom_in };
......@@ -387,6 +405,8 @@ public class GearyController : Geary.BaseObject {
ACTION_REPLY_TO_MESSAGE,
ACTION_REPLY_ALL_MESSAGE,
ACTION_FORWARD_MESSAGE,
ACTION_ARCHIVE_MESSAGE,
ACTION_TRASH_MESSAGE,
ACTION_DELETE_MESSAGE,
};
const string[] exported_actions = {
......@@ -908,16 +928,9 @@ public class GearyController : Geary.BaseObject {
// by other utility methods
private void update_ui() {
update_tooltips();
Gtk.Action delete_message = GearyApplication.instance.actions.get_action(ACTION_DELETE_MESSAGE);
if (current_folder is Geary.FolderSupport.Archive) {
delete_message.label = ARCHIVE_MESSAGE_LABEL;
delete_message.icon_name = ARCHIVE_MESSAGE_ICON_NAME;
} else {
// even if not Geary.FolderSupportsrRemove, use delete icons and label, although they
// may be insensitive the entire time
delete_message.label = DELETE_MESSAGE_LABEL;
delete_message.icon_name = DELETE_MESSAGE_ICON_NAME;
}
main_window.main_toolbar.update_trash_buttons(
current_folder_supports_trash() || !(current_folder is Geary.FolderSupport.Remove),
current_account.can_support_archive);
}
private void on_folder_selected(Geary.Folder? folder) {
......@@ -1291,6 +1304,12 @@ public class GearyController : Geary.BaseObject {
}
}
private void on_shift_key(bool pressed) {
main_window.main_toolbar.update_trash_buttons(
(!pressed && current_folder_supports_trash()) || !(current_folder is Geary.FolderSupport.Remove),
current_account.can_support_archive);
}
// this signal does not necessarily indicate that the application previously didn't have
// focus and now it does
private void on_has_toplevel_focus() {
......@@ -1833,54 +1852,96 @@ public class GearyController : Geary.BaseObject {
main_window.conversation_viewer.find(false);
}
// This method is used for both removing and archive a message; currently Geary only supports
// one or the other in a folder
private void on_archive_message() {
archive_or_delete_selection_async.begin(true, false, cancellable_folder,
on_archive_or_delete_selection_finished);
}
private void on_trash_message() {
archive_or_delete_selection_async.begin(false, true, cancellable_folder,
on_archive_or_delete_selection_finished);
}
private void on_delete_message() {
// Prevent deletes of the same conversation from repeating.
archive_or_delete_selection_async.begin(false, false, cancellable_folder,
on_archive_or_delete_selection_finished);
}
private bool current_folder_supports_trash(out Geary.FolderSupport.Move? move = null,
out Geary.FolderPath? trash_path = null) {
try {
if (current_folder != null && current_folder.special_folder_type != Geary.SpecialFolderType.TRASH
&& !current_folder.properties.is_local_only && current_account != null) {
Geary.FolderSupport.Move? supports_move = current_folder as Geary.FolderSupport.Move;
Geary.Folder? trash_folder = current_account.get_special_folder(Geary.SpecialFolderType.TRASH);
if (supports_move != null && trash_folder != null) {
move = supports_move;
trash_path = trash_folder.path;
return true;
}
}
} catch (Error e) {
debug("Error finding trash folder: %s", e.message);
}
move = null;
trash_path = null;
return false;
}
private async void archive_or_delete_selection_async(bool archive, bool trash,
Cancellable? cancellable) throws Error {
if (main_window.conversation_viewer.current_conversation != null
&& main_window.conversation_viewer.current_conversation == last_deleted_conversation) {
debug("not archiving/deleting, viewed conversation is last deleted conversation");
debug("Not archiving/trashing/deleting; viewed conversation is last deleted conversation");
return;
}
// There should always be at least one conversation selected here, otherwise the archive
// button is disabled, but better safe than segfaulted.
last_deleted_conversation = selected_conversations.size > 0
? Geary.Collection.get_first<Geary.App.Conversation>(selected_conversations) : null;
? Geary.traverse<Geary.App.Conversation>(selected_conversations).first() : null;
// If the user clicked the toolbar button, we want to move focus back to the message list.
// Return focus to the conversation list from the clicked toolbar button.
main_window.conversation_list_view.grab_focus();
delete_messages.begin(get_selected_email_ids(false), cancellable_folder, on_delete_messages_completed);
}
// This method is used for both removing and archive a message; currently Geary only supports
// one or the other in a folder. This will try archiving first, then remove.
private async void delete_messages(Gee.List<Geary.EmailIdentifier> ids, Cancellable? cancellable)
throws Error {
Geary.FolderSupport.Archive? supports_archive = current_folder as Geary.FolderSupport.Archive;
if (supports_archive != null) {
yield supports_archive.archive_email_async(ids, cancellable);
Gee.List<Geary.EmailIdentifier> ids = get_selected_email_ids(false);
if (archive) {
debug("Archiving selected messages");
Geary.FolderSupport.Archive? supports_archive = current_folder as Geary.FolderSupport.Archive;
if (supports_archive == null)
debug("Folder %s doesn't support archive", current_folder.to_string());
else
yield supports_archive.archive_email_async(ids, cancellable);
return;
}
Geary.FolderSupport.Remove? supports_remove = current_folder as Geary.FolderSupport.Remove;
if (supports_remove != null) {
yield supports_remove.remove_email_async(ids, cancellable);
if (trash) {
debug("Trashing selected messages");
Geary.FolderPath? trash_path;
Geary.FolderSupport.Move? supports_move;
if (!current_folder_supports_trash(out supports_move, out trash_path))
debug("Folder %s doesn't support move or account %s doesn't have a trash folder",
current_folder.to_string(), current_account.to_string());
else
yield supports_move.move_email_async(ids, trash_path, cancellable);
return;
}
debug("Folder %s supports neither remove nor archive", current_folder.to_string());
debug("Deleting selected messages");
Geary.FolderSupport.Remove? supports_remove = current_folder as Geary.FolderSupport.Remove;
if (supports_remove == null)
debug("Folder %s doesn't support remove", current_folder.to_string());
else
yield supports_remove.remove_email_async(ids, cancellable);
}
private void on_delete_messages_completed(Object? source, AsyncResult result) {
private void on_archive_or_delete_selection_finished(Object? source, AsyncResult result) {
try {
delete_messages.end(result);
} catch (Error err) {
debug("Error, unable to delete messages: %s", err.message);
archive_or_delete_selection_async.end(result);
} catch (Error e) {
debug("Unable to archive/trash/delete messages: %s", e.message);
}
}
......@@ -1924,8 +1985,12 @@ public class GearyController : Geary.BaseObject {
// Mutliple message buttons.
GearyApplication.instance.actions.get_action(ACTION_MOVE_MENU).sensitive =
(current_folder is Geary.FolderSupport.Move);
GearyApplication.instance.actions.get_action(ACTION_ARCHIVE_MESSAGE).sensitive =
(current_folder is Geary.FolderSupport.Archive);
GearyApplication.instance.actions.get_action(ACTION_TRASH_MESSAGE).sensitive =
current_folder_supports_trash();
GearyApplication.instance.actions.get_action(ACTION_DELETE_MESSAGE).sensitive =
(current_folder is Geary.FolderSupport.Remove) || (current_folder is Geary.FolderSupport.Archive);
(current_folder is Geary.FolderSupport.Remove);
cancel_context_dependent_buttons();
enable_context_dependent_buttons_async.begin(true, cancellable_context_dependent_buttons);
......@@ -1945,8 +2010,12 @@ public class GearyController : Geary.BaseObject {
GearyApplication.instance.actions.get_action(ACTION_FORWARD_MESSAGE).sensitive = respond_sensitive;
GearyApplication.instance.actions.get_action(ACTION_MOVE_MENU).sensitive =
sensitive && (current_folder is Geary.FolderSupport.Move);
GearyApplication.instance.actions.get_action(ACTION_ARCHIVE_MESSAGE).sensitive = sensitive
&& (current_folder is Geary.FolderSupport.Archive);
GearyApplication.instance.actions.get_action(ACTION_TRASH_MESSAGE).sensitive = sensitive
&& current_folder_supports_trash();
GearyApplication.instance.actions.get_action(ACTION_DELETE_MESSAGE).sensitive = sensitive
&& ((current_folder is Geary.FolderSupport.Remove) || (current_folder is Geary.FolderSupport.Archive));
&& (current_folder is Geary.FolderSupport.Remove);
cancel_context_dependent_buttons();
enable_context_dependent_buttons_async.begin(sensitive, cancellable_context_dependent_buttons);
......@@ -1992,13 +2061,12 @@ public class GearyController : Geary.BaseObject {
GearyApplication.instance.actions.get_action(ACTION_MOVE_MENU).tooltip = single ?
MOVE_MESSAGE_TOOLTIP_SINGLE : MOVE_MESSAGE_TOOLTIP_MULTIPLE;
if (current_folder is Geary.FolderSupport.Archive) {
GearyApplication.instance.actions.get_action(ACTION_DELETE_MESSAGE).tooltip = single ?
ARCHIVE_MESSAGE_TOOLTIP_SINGLE : ARCHIVE_MESSAGE_TOOLTIP_MULTIPLE;
} else {
GearyApplication.instance.actions.get_action(ACTION_DELETE_MESSAGE).tooltip = single ?
DELETE_MESSAGE_TOOLTIP_SINGLE : DELETE_MESSAGE_TOOLTIP_MULTIPLE;
}
GearyApplication.instance.actions.get_action(ACTION_ARCHIVE_MESSAGE).tooltip = single ?
ARCHIVE_MESSAGE_TOOLTIP_SINGLE : ARCHIVE_MESSAGE_TOOLTIP_MULTIPLE;
GearyApplication.instance.actions.get_action(ACTION_TRASH_MESSAGE).tooltip = single ?
TRASH_MESSAGE_TOOLTIP_SINGLE : TRASH_MESSAGE_TOOLTIP_MULTIPLE;
GearyApplication.instance.actions.get_action(ACTION_DELETE_MESSAGE).tooltip = single ?
DELETE_MESSAGE_TOOLTIP_SINGLE : DELETE_MESSAGE_TOOLTIP_MULTIPLE;
}
public void compose_mailto(string mailto) {
......
......@@ -13,7 +13,10 @@ public class MainToolbar : PillToolbar {
public FolderMenu copy_folder_menu { get; private set; default = new FolderMenu(); }
public FolderMenu move_folder_menu { get; private set; default = new FolderMenu(); }
public string search_text { get { return search_entry.text; } }
public bool search_entry_has_focus { get { return search_entry.has_focus; } }
private Gtk.Button archive_button;
private Gtk.Button trash_buttons[2];
private Gtk.ToolItem search_container = new Gtk.ToolItem();
private Gtk.SearchEntry search_entry = new Gtk.SearchEntry();
private Geary.ProgressMonitor? search_upgrade_progress_monitor = null;
......@@ -61,11 +64,17 @@ public class MainToolbar : PillToolbar {
insert.add(create_menu_button("folder-symbolic", move_folder_menu, GearyController.ACTION_MOVE_MENU));
add(create_pill_buttons(insert));
// Archive/delete button.
// For this button, the controller sets the tooltip and icon depending on the context.
// The toolbar looks bad when you hide one of a pair of pill buttons.
// Unfortunately, this means we have to have one pair for archive/trash
// and one single button for just trash, for when the archive button is
// hidden.
insert.clear();
insert.add(create_toolbar_button("", GearyController.ACTION_DELETE_MESSAGE, true));
insert.add(archive_button = create_toolbar_button(null, GearyController.ACTION_ARCHIVE_MESSAGE, true));
insert.add(trash_buttons[0] = create_toolbar_button(null, GearyController.ACTION_TRASH_MESSAGE, true));
add(create_pill_buttons(insert));
insert.clear();
insert.add(trash_buttons[1] = create_toolbar_button(null, GearyController.ACTION_TRASH_MESSAGE, true));
add(create_pill_buttons(insert, false));
// Spacer.
add(create_spacer());
......@@ -101,6 +110,28 @@ public class MainToolbar : PillToolbar {
set_search_placeholder_text(DEFAULT_SEARCH_TEXT);
}
private void show_archive_button(bool show) {
if (show) {
archive_button.show();
trash_buttons[0].show();
trash_buttons[1].hide();
} else {
archive_button.hide();
trash_buttons[0].hide();
trash_buttons[1].show();
}
}
/// Updates the trash button as trash or delete, and shows or hides the archive button.
public void update_trash_buttons(bool trash, bool archive) {
string action_name = (trash ? GearyController.ACTION_TRASH_MESSAGE
: GearyController.ACTION_DELETE_MESSAGE);
foreach (Gtk.Button b in trash_buttons)
setup_button(b, null, action_name, true);
show_archive_button(archive);
}
public void set_search_text(string text) {
search_entry.text = text;
}
......
......@@ -9,6 +9,9 @@ public class MainWindow : Gtk.ApplicationWindow {
private const int FOLDER_LIST_WIDTH = 100;
private const int STATUS_BAR_HEIGHT = 18;
/// Fired when the shift key is pressed or released.
public signal void on_shift_key(bool pressed);
public FolderList.Tree folder_list { get; private set; default = new FolderList.Tree(); }
public ConversationListStore conversation_list_store { get; private set; default = new ConversationListStore(); }
public MainToolbar main_toolbar { get; private set; }
......@@ -35,6 +38,8 @@ public class MainWindow : Gtk.ApplicationWindow {
conversation_list_view = new ConversationListView(conversation_list_store);
add_events(Gdk.EventMask.KEY_PRESS_MASK | Gdk.EventMask.KEY_RELEASE_MASK);
// This code both loads AND saves the pane positions with live
// updating. This is more resilient against crashes because
// the value in dconf changes *immediately*, and stays saved
......@@ -57,6 +62,7 @@ public class MainWindow : Gtk.ApplicationWindow {
delete_event.connect(on_delete_event);
key_press_event.connect(on_key_press_event);
key_release_event.connect(on_key_release_event);
GearyApplication.instance.controller.notify[GearyController.PROP_CURRENT_CONVERSATION].
connect(on_conversation_monitor_changed);
Geary.Engine.instance.account_available.connect(on_account_available);
......@@ -66,12 +72,15 @@ public class MainWindow : Gtk.ApplicationWindow {
}
public override void show_all() {
set_default_size(GearyApplication.instance.config.window_width,
set_default_size(GearyApplication.instance.config.window_width,
GearyApplication.instance.config.window_height);
if (GearyApplication.instance.config.window_maximize)
maximize();
base.show_all();
// Some buttons need to be hidden, so we have to do this after we show everything.
main_toolbar.update_trash_buttons(true, true);
}
private bool on_delete_event() {
......@@ -149,8 +158,6 @@ public class MainWindow : Gtk.ApplicationWindow {
main_layout.pack_end(folder_paned, true, true, 0);
add(main_layout);
this.key_press_event.connect(on_key_press_event);
}
// Returns true when there's a conversation list scrollbar visible, i.e. the list is tall
......@@ -161,11 +168,26 @@ public class MainWindow : Gtk.ApplicationWindow {
}
private bool on_key_press_event(Gdk.EventKey event) {
if ((event.keyval == Gdk.Key.Shift_L || event.keyval == Gdk.Key.Shift_R)
&& (event.state & Gdk.ModifierType.SHIFT_MASK) == 0 && !main_toolbar.search_entry_has_focus)
on_shift_key(true);
// Check whether the focused widget wants to handle it, if not let the accelerators kick in
// via the default handling
return propagate_key_event(event);
}
private bool on_key_release_event(Gdk.EventKey event) {
// FIXME: it's possible the user will press two shift keys. We want
// the shift key to report as released when they release ALL of them.
// There doesn't seem to be an easy way to do this in Gdk.
if ((event.keyval == Gdk.Key.Shift_L || event.keyval == Gdk.Key.Shift_R)
&& !main_toolbar.search_entry_has_focus)
on_shift_key(false);
return propagate_key_event(event);
}
private void on_conversation_monitor_changed() {
Geary.App.ConversationMonitor? conversation_monitor =
GearyApplication.instance.controller.current_conversations;
......
......@@ -14,7 +14,7 @@ public class PillToolbar : Gtk.Toolbar {
action_group = toolbar_action_group;
}
private void setup_button(Gtk.Button b, string? icon_name, string action_name,
protected void setup_button(Gtk.Button b, string? icon_name, string action_name,
bool show_label = false) {
b.related_action = action_group.get_action(action_name);
b.tooltip_text = b.related_action.tooltip;
......
......@@ -11,11 +11,14 @@ public abstract class Geary.AbstractAccount : BaseObject, Geary.Account {
public Geary.ProgressMonitor opening_monitor { get; protected set; }
public Geary.ProgressMonitor sending_monitor { get; protected set; }
public virtual bool can_support_archive { get; protected set; }
private string name;
public AbstractAccount(string name, AccountInformation information) {
public AbstractAccount(string name, AccountInformation information, bool can_support_archive) {
this.name = name;
this.information = information;
this.can_support_archive = can_support_archive;
}
protected virtual void notify_folders_available_unavailable(Gee.List<Geary.Folder>? available,
......
......@@ -21,6 +21,14 @@ public interface Geary.Account : BaseObject {
public abstract Geary.ProgressMonitor opening_monitor { get; protected set; }
public abstract Geary.ProgressMonitor sending_monitor { get; protected set; }
/**
* HACK: for now, only certain account types support folders with
* FolderSupport.Archive. It's useful to know whether an account supports
* archive because the button is hidden for accounts that will never
* support it.
*/
public abstract bool can_support_archive { get; protected set; }
public signal void opened();
public signal void closed();
......
......@@ -38,7 +38,7 @@ private class Geary.ImapEngine.GmailAccount : Geary.ImapEngine.GenericAccount {
public GmailAccount(string name, Geary.AccountInformation account_information,
Imap.Account remote, ImapDB.Account local) {
base (name, account_information, remote, local);
base (name, account_information, true, remote, local);
if (path_type_map == null) {
path_type_map = new Gee.HashMap<Geary.FolderPath, Geary.SpecialFolderType>();
......
......@@ -21,9 +21,9 @@ private abstract class Geary.ImapEngine.GenericAccount : Geary.AbstractAccount {
private Cancellable refresh_cancellable = new Cancellable();
private bool awaiting_credentials = false;
public GenericAccount(string name, Geary.AccountInformation information, Imap.Account remote,
ImapDB.Account local) {
base (name, information);
public GenericAccount(string name, Geary.AccountInformation information, bool can_support_archive,
Imap.Account remote, ImapDB.Account local) {
base (name, information, can_support_archive);
this.remote = remote;
this.local = local;
......
......@@ -7,7 +7,7 @@
private class Geary.ImapEngine.OtherAccount : Geary.ImapEngine.GenericAccount {
public OtherAccount(string name, AccountInformation account_information,
Imap.Account remote, ImapDB.Account local) {
base (name, account_information, remote, local);
base (name, account_information, false, remote, local);
}
protected override GenericFolder new_folder(Geary.FolderPath path, Imap.Account remote_account,
......
......@@ -33,7 +33,7 @@ private class Geary.ImapEngine.OutlookAccount : Geary.ImapEngine.GenericAccount
public OutlookAccount(string name, AccountInformation account_information, Imap.Account remote,
ImapDB.Account local) {
base (name, account_information, remote, local);
base (name, account_information, false, remote, local);
}
protected override GenericFolder new_folder(Geary.FolderPath path, Imap.Account remote_account,
......
......@@ -35,7 +35,7 @@ private class Geary.ImapEngine.YahooAccount : Geary.ImapEngine.GenericAccount {
public YahooAccount(string name, AccountInformation account_information,
Imap.Account remote, ImapDB.Account local) {
base (name, account_information, remote, local);
base (name, account_information, false, remote, local);
if (special_map == null) {
special_map = new Gee.HashMap<Geary.FolderPath, Geary.SpecialFolderType>();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment