[Xfce4-commits] <postler:master> Parse localised and non-standard folder names

Christian Dywan noreply at xfce.org
Sat Nov 20 02:32:01 CET 2010


Updating branch refs/heads/master
         to 01245025647998a48ad63a76675465f24f8f44c4 (commit)
       from 484476bbd07e37c9c9fc29403b4ac610e430f7c9 (commit)

commit 01245025647998a48ad63a76675465f24f8f44c4
Author: Christian Dywan <christian at twotoasts.de>
Date:   Fri Nov 19 23:11:18 2010 +0100

    Parse localised and non-standard folder names
    
    MailFolder defines a special folder. The supported folder types
    are listed in localized_folders, with the standard name/ role,
    stock_id and icon plus a list of localised names.
    
    The name lists currently work for US, British and German GMail
    as well as other localised German providers.
    
    verify_folders() is necessary to iterate over all folders in
    the case where localised folders were not found.

 postler/postler-accounts.vala |   69 +++++++++++++++++++++++++
 postler/postler-folders.vala  |  114 +++++++++++++++++++++--------------------
 2 files changed, 127 insertions(+), 56 deletions(-)

diff --git a/postler/postler-accounts.vala b/postler/postler-accounts.vala
index fc6842a..a0eed96 100644
--- a/postler/postler-accounts.vala
+++ b/postler/postler-accounts.vala
@@ -16,6 +16,52 @@ namespace Postler {
         SEARCH
     }
 
+    enum FolderType {
+        SENT,
+        DRAFTS,
+        QUEUE,
+        TRASH,
+        ARCHIVE,
+        MAX
+    }
+    public struct MailFolder {
+        public string? role;
+        public string? stock_id;
+        public string label;
+        string[]? localized;
+        int n_localized;
+    }
+
+    const string[] sent_folders = {
+        "[GMail]~-Sent", "[Google Mail]~-Sent",
+        "[Google Mail]~-Gesendet", "Gesendet"
+    };
+    const string[] drafts_folders = {
+        "[GMail]~-Drafts", "[Google Mail]~-Drafts",
+        "[Google Mail]~-Entw&APw-rfe", "Entwurf"
+    };
+    const string[] queue_folders = {
+        "Postausgang"
+    };
+    const string[] trash_folders = {
+        "[GMail]~-Trash", "[Google Mail]~-Trash",
+        "[Google Mail]~-Papierkorb", "Papierkorb"
+    };
+    const string[] archive_folders = {
+        "Archive"
+    };
+
+    /* The length values must be in the array to work around Vala mistakenly
+       optimizing the value away when using arrays indirectly with MailFolder */
+    const MailFolder[] localized_folders = {
+        { "Sent", STOCK_SENT_MAIL, N_("Sent"), sent_folders, sent_folders.length },
+        { "Drafts", null, N_("Drafts"), drafts_folders, drafts_folders.length },
+        { "Queue", STOCK_OUTBOX, N_("Outbox"), queue_folders, queue_folders.length },
+        { "Trash", STOCK_USER_TRASH, N_("Trash"), trash_folders, trash_folders.length },
+        { "Archive", STOCK_USER_TRASH, N_("Archive"), archive_folders, archive_folders.length }
+    };
+    const MailFolder generic_folder = { null, Gtk.STOCK_DIRECTORY, null, null };
+
     public class AccountInfo : GLib.Object {
         public string name;
         public AccountType type;
@@ -32,6 +78,29 @@ namespace Postler {
         public string reply;
         public string organization;
         public string hide;
+        public string[]? folders = { null, null, null, null, null };
+
+        public unowned MailFolder get_localized_folder (string folder_name) {
+            for (int type = 0; type < FolderType.MAX; type++)
+                if (this.folders[type] == folder_name)
+                    return localized_folders[type];
+            for (int type = 0; type < FolderType.MAX; type++) {
+                if (this.folders[type] == null
+                 && folder_name in localized_folders[type].localized) {
+                    this.folders[type] = folder_name;
+                    this.hide += ("," + localized_folders[type].role);
+                    return localized_folders[type];
+                }
+            }
+            return generic_folder;
+        }
+
+        public delegate void MailFolderCallback (int type, MailFolder folder);
+        public void verify_folders (MailFolderCallback callback) {
+            for (int type = 0; type < FolderType.MAX; type++)
+                if (this.folders[type] == null)
+                    callback (type, localized_folders[type]);
+        }
     }
 }
 
diff --git a/postler/postler-folders.vala b/postler/postler-folders.vala
index 9fed53a..bfaf051 100644
--- a/postler/postler-folders.vala
+++ b/postler/postler-folders.vala
@@ -9,12 +9,6 @@
  See the file COPYING for the full license text.
 */
 
-struct Postler.MailFolder {
-    public string name;
-    public string stock_id;
-    public string localized;
-}
-
 public class Postler.Folders : Gtk.TreeView {
     Accounts accounts;
     Gtk.TreeStore store;
@@ -70,14 +64,6 @@ public class Postler.Folders : Gtk.TreeView {
         GLib.Idle.add (populate);
     }
 
-    const MailFolder[] localized_folders = {
-        { "Sent", STOCK_SENT_MAIL, N_("Sent") },
-        { "Drafts", null, N_("Drafts") },
-        { "Queue", STOCK_OUTBOX, N_("Outbox") },
-        { "Trash", STOCK_USER_TRASH, N_("Trash") },
-        { "Archive", STOCK_ARCHIVE, N_("Archive") }
-    };
-
     static Canberra.Context sound_context = null;
     void play_sound (string sound) {
         if (sound_context == null)
@@ -119,6 +105,24 @@ public class Postler.Folders : Gtk.TreeView {
         return populate_accounts (accounts.get_infos ());
     }
 
+    bool get_folder_iter (string location, Gtk.TreeIter account_iter,
+        out Gtk.TreeIter iter) {
+
+        Gtk.TreeIter folder_iter;
+        if (!store.iter_children (out folder_iter, account_iter))
+            return false;
+        do {
+            string existing_location;
+            store.get (folder_iter, Columns.LOCATION, out existing_location);
+            if (existing_location == location) {
+                if (&iter != null)
+                    iter = folder_iter;
+                return true;
+            }
+        } while (store.iter_next (ref folder_iter));
+        return false;
+    }
+
     public bool populate_accounts (GLib.List<AccountInfo> infos) {
         /* foreach (unowned AccountInfo account_info in infos) { */
         for (unowned GLib.List<AccountInfo> info_iter = infos;
@@ -182,15 +186,10 @@ public class Postler.Folders : Gtk.TreeView {
                     if (account_info.hide != null && name in account_info.hide)
                         continue;
 
-                    var account_dir = folder_dir.resolve_relative_path (name);
-                    var monitor = account_dir.monitor_directory (0, null);
-                    monitor.changed.connect ((monitor, file, other, event) => {
-                        var account_infos = new GLib.List<AccountInfo> ();
-                        account_infos.prepend (account_info);
-                        populate_accounts (account_infos);
-                    });
-                    store.set (account_iter,
-                        Columns.FOLDER_MONITOR, monitor);
+                    var status_dir = folder_dir.resolve_relative_path (name);
+                    var new_dir = status_dir.resolve_relative_path ("new");
+                    if (!new_dir.query_exists (null))
+                        continue;
 
                     Gtk.TreeIter parent_iter = account_iter;
                     Gtk.TreeIter folder_iter;
@@ -200,20 +199,9 @@ public class Postler.Folders : Gtk.TreeView {
                     if ("~-" in name) {
                         string[]? name_pieces = name.split ("~-");
                         string folder_dir_path = folder_dir.get_path ();
-                        existing_iter = false;
-                        if (store.iter_children (out folder_iter, account_iter)) {
-                            do {
-                                string existing_parent;
-                                store.get (folder_iter,
-                                    Columns.LOCATION, out existing_parent);
-                                if (folder_dir_path == existing_parent) {
-                                    parent_iter = folder_iter;
-                                    existing_iter = true;
-                                    break;
-                                }
-                            } while (store.iter_next (ref folder_iter));
-                        }
-                        if (!existing_iter) {
+                        if (get_folder_iter (folder_dir_path, account_iter, out folder_iter))
+                            parent_iter = folder_iter;
+                        else {
                             store.insert_with_values (out parent_iter, account_iter, -1,
                                 Columns.ICON, Gtk.STOCK_DIRECTORY,
                                 Columns.NAME, name_pieces[0],
@@ -228,7 +216,7 @@ public class Postler.Folders : Gtk.TreeView {
                     if (name == "INBOX") {
                         var msg_dir = folder_dir.resolve_relative_path (
                             account_info.path + "/" + name + "/new");
-                        monitor = msg_dir.monitor_directory (0, null);
+                        var monitor = msg_dir.monitor_directory (0, null);
                         string path = store.get_string_from_iter (account_iter);
                         monitor.changed.connect ((monitor, file, other, event) => {
                             unread_monitor_changed (msg_dir, path, account_info.name);
@@ -242,27 +230,41 @@ public class Postler.Folders : Gtk.TreeView {
                         continue;
                     }
 
-                    string localized_name = null;
-                    string stock_id = Gtk.STOCK_DIRECTORY;
-                    foreach (var localized_folder in localized_folders) {
-                        if (localized_folder.name == name) {
-                            localized_name = localized_folder.localized;
-                            if (localized_folder.stock_id != null)
-                                stock_id = localized_folder.stock_id;
-                            break;
-                        }
-                    }
+                    var account_dir = folder_dir.resolve_relative_path (name);
+                    var monitor = account_dir.monitor_directory (0, null);
+                    monitor.changed.connect ((monitor, file, other, event) => {
+                        var account_infos = new GLib.List<AccountInfo> ();
+                        account_infos.prepend (account_info);
+                        populate_accounts (account_infos);
+                    });
 
-                    store.insert_with_values (out folder_iter, parent_iter, -1,
-                        Columns.ICON, stock_id,
-                        Columns.NAME, localized_name ?? folder_name,
-                        Columns.LOCATION, account_info.path + "/" + name,
-                        Columns.INFO, account_info);
-                    var status_dir = folder_dir.resolve_relative_path (name);
-                    var new_dir = status_dir.resolve_relative_path ("new");
-                    if (!new_dir.query_exists (null))
+                    unowned MailFolder folder = account_info.get_localized_folder (name);
+                    folder_iter = new Gtk.TreeIter ();
+                    if (folder.role != null
+                     && get_folder_iter (account_info.path + "/" + folder.role,
+                                         account_iter, out folder_iter))
                         store.remove (folder_iter);
+
+                    store.insert_with_values (null,
+                        folder.role != null ? account_iter : parent_iter, -1,
+                        Columns.ICON, folder.stock_id ?? Gtk.STOCK_DIRECTORY,
+                        Columns.NAME, folder.label ?? folder_name,
+                        Columns.LOCATION, account_info.path + "/" + name,
+                        Columns.INFO, account_info,
+                        Columns.FOLDER_MONITOR, monitor);
                 }
+
+                Gtk.TreeIter folder_iter = new Gtk.TreeIter ();
+                account_info.verify_folders ((type, folder) => {
+                    if (get_folder_iter (account_info.path + "/" + folder.role,
+                                         account_iter, out folder_iter)) {
+                        account_info.folders[type] = folder.role;
+                        store.set (folder_iter,
+                                   Columns.ICON, folder.stock_id ?? Gtk.STOCK_DIRECTORY,
+                                   Columns.NAME, folder.label);
+                    }
+                });
+
                 expand_row (store.get_path (account_iter), false);
             }
             catch (GLib.Error error) {



More information about the Xfce4-commits mailing list