[geary] Remove folders locally that were removed on server
- From: Charles Lindsay <clindsay src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [geary] Remove folders locally that were removed on server
- Date: Sat, 15 Feb 2014 00:04:36 +0000 (UTC)
commit aca1e5398472b731d4ad7a10443a133f3aa460c7
Author: Charles Lindsay <chaz yorba org>
Date: Fri Feb 14 16:03:19 2014 -0800
Remove folders locally that were removed on server
Closes: bgo #714357
src/client/application/geary-controller.vala | 11 +++++++
.../folder-list/folder-list-account-branch.vala | 9 ++++++
src/engine/imap-db/imap-db-account.vala | 30 ++++++++++++++++++++
.../imap-engine/imap-engine-generic-account.vala | 23 ++++++++++++---
4 files changed, 68 insertions(+), 5 deletions(-)
---
diff --git a/src/client/application/geary-controller.vala b/src/client/application/geary-controller.vala
index a198bcf..c3429af 100644
--- a/src/client/application/geary-controller.vala
+++ b/src/client/application/geary-controller.vala
@@ -1230,10 +1230,21 @@ public class GearyController : Geary.BaseObject {
if (unavailable != null) {
foreach (Geary.Folder folder in unavailable) {
+ main_window.folder_list.remove_folder(folder);
+ if (folder.account == current_account) {
+ if (main_window.main_toolbar.copy_folder_menu.has_folder(folder))
+ main_window.main_toolbar.copy_folder_menu.remove_folder(folder);
+ if (main_window.main_toolbar.move_folder_menu.has_folder(folder))
+ main_window.main_toolbar.move_folder_menu.remove_folder(folder);
+ }
+
if (folder.special_folder_type == Geary.SpecialFolderType.INBOX &&
inboxes.has_key(folder.account)) {
+ inboxes.unset(folder.account);
new_messages_monitor.remove_folder(folder);
}
+
+ folder.special_folder_type_changed.disconnect(on_special_folder_type_changed);
}
}
}
diff --git a/src/client/folder-list/folder-list-account-branch.vala
b/src/client/folder-list/folder-list-account-branch.vala
index f6af521..bda2d54 100644
--- a/src/client/folder-list/folder-list-account-branch.vala
+++ b/src/client/folder-list/folder-list-account-branch.vala
@@ -23,10 +23,13 @@ public class FolderList.AccountBranch : Sidebar.Branch {
account.information.notify["nickname"].connect(on_nicknamed_changed);
graft(get_root(), user_folder_group);
+
+ entry_removed.connect(on_entry_removed);
}
~AccountBranch() {
account.information.notify["nickname"].disconnect(on_nicknamed_changed);
+ entry_removed.disconnect(on_entry_removed);
}
private void on_nicknamed_changed() {
@@ -123,4 +126,10 @@ public class FolderList.AccountBranch : Sidebar.Branch {
prune(entry);
folder_entries.unset(folder.path);
}
+
+ private void on_entry_removed(Sidebar.Entry entry) {
+ FolderEntry? folder_entry = entry as FolderEntry;
+ if (folder_entry != null && folder_entries.has_key(folder_entry.folder.path))
+ folder_entries.unset(folder_entry.folder.path);
+ }
}
diff --git a/src/engine/imap-db/imap-db-account.vala b/src/engine/imap-db/imap-db-account.vala
index db21827..1d4c1bb 100644
--- a/src/engine/imap-db/imap-db-account.vala
+++ b/src/engine/imap-db/imap-db-account.vala
@@ -213,6 +213,29 @@ private class Geary.ImapDB.Account : BaseObject {
}, cancellable);
}
+ public async void delete_folder_async(Geary.Folder folder, Cancellable? cancellable)
+ throws Error {
+ check_open();
+
+ Geary.FolderPath path = folder.path;
+
+ yield db.exec_transaction_async(Db.TransactionType.RW, (cx) => {
+ int64 folder_id;
+ do_fetch_folder_id(cx, path, false, out folder_id, cancellable);
+ if (folder_id == Db.INVALID_ROWID)
+ return Db.TransactionOutcome.ROLLBACK;
+
+ if (do_has_children(cx, folder_id, cancellable)) {
+ debug("Can't delete folder %s because it has children", folder.to_string());
+ return Db.TransactionOutcome.ROLLBACK;
+ }
+
+ do_delete_folder(cx, folder_id, cancellable);
+
+ return Db.TransactionOutcome.COMMIT;
+ }, cancellable);
+ }
+
/**
* Only updates folder's STATUS message count, attributes, recent, and unseen; UIDVALIDITY and UIDNEXT
* updated when the folder is SELECT/EXAMINED (see update_folder_select_examine_async()) unless
@@ -1245,6 +1268,13 @@ private class Geary.ImapDB.Account : BaseObject {
return do_fetch_folder_id(cx, path.get_parent(), create, out parent_id, cancellable);
}
+ private bool do_has_children(Db.Connection cx, int64 folder_id, Cancellable? cancellable) throws Error {
+ Db.Statement stmt = cx.prepare("SELECT 1 FROM FolderTable WHERE parent_id = ?");
+ stmt.bind_rowid(0, folder_id);
+ Db.Result result = stmt.exec(cancellable);
+ return !result.finished;
+ }
+
// Turn the collection of folder paths into actual folder ids. As a
// special case, if "folderless" or orphan emails are to be blacklisted,
// set the out bool to true.
diff --git a/src/engine/imap-engine/imap-engine-generic-account.vala
b/src/engine/imap-engine/imap-engine-generic-account.vala
index 87741b6..cd3b24c 100644
--- a/src/engine/imap-engine/imap-engine-generic-account.vala
+++ b/src/engine/imap-engine/imap-engine-generic-account.vala
@@ -633,12 +633,25 @@ private abstract class Geary.ImapEngine.GenericAccount : Geary.AbstractAccount {
Gee.Collection<MinimalFolder> engine_added = new Gee.ArrayList<Geary.Folder>();
engine_added.add_all(build_folders(folders_to_build));
- // TODO: Remove local folders no longer available remotely.
- foreach (Geary.Folder folder in to_remove)
- debug(@"Need to remove folder $folder");
+ notify_folders_available_unavailable(null, to_remove);
- if (engine_added.size > 0)
- notify_folders_added_removed(sort_by_path(engine_added), null);
+ Gee.ArrayList<Geary.Folder> engine_removed = new Gee.ArrayList<Geary.Folder>();
+
+ // Sort by path length descending, so we always remove children first.
+ to_remove.sort((a, b) => b.path.get_path_length() - a.path.get_path_length());
+ foreach (Geary.Folder folder in to_remove) {
+ try {
+ debug("Locally deleting removed folder %s", folder.to_string());
+
+ yield local.delete_folder_async(folder, cancellable);
+ engine_removed.add(folder);
+ } catch (Error e) {
+ debug("Unable to locally delete removed folder %s: %s", folder.to_string(), e.message);
+ }
+ }
+
+ if (engine_added.size > 0 || engine_removed.size > 0)
+ notify_folders_added_removed(sort_by_path(engine_added), sort_by_path(engine_removed));
// report all altered folders
if (altered_paths.size > 0) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]