Since e-util/e-account-list.c in evolution module has been developed
authorSimon Zheng <Simon.Zheng@sun.com>
Fri, 6 Jan 2006 06:24:38 +0000 (06:24 +0000)
committerHarry Lu <haip@src.gnome.org>
Fri, 6 Jan 2006 06:24:38 +0000 (06:24 +0000)
2006-01-06  Simon Zheng  <Simon.Zheng@sun.com>

       * libedataserver/e-account-list.c: Since e-util/e-account-list.c
       in evolution module has been developed further, merge those
       changes into libedataserver and drop e-util/e-account-list.c.

       libedataserver/e-account-list.h: Since e-util/e-account-list.h in
       evolution module has been developed further, merge those changes
       into libedataserver and drop e-util/e-account-list.h.

       libedataserver/e-account.c: Since e-util/e-account.c in
       evolution module has been developed further, merge those changes
       into libedataserver and drop e-util/e-account.c.

       libedataserver/e-account.h: Since e-util/e-account.h in
       evolution module has been developed further, merge those changes
       into libedataserver and drop e-util/e-account.h.

ChangeLog
libedataserver/e-account-list.c
libedataserver/e-account-list.h
libedataserver/e-account.c
libedataserver/e-account.h

index 2fe7aaa..d2d8a57 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2006-01-06  Simon Zheng  <Simon.Zheng@sun.com>
+       * libedataserver/e-account-list.c: Since e-util/e-account-list.c 
+       in evolution module has been developed further, merge those 
+       changes into libedataserver and drop e-util/e-account-list.c.
+       libedataserver/e-account-list.h: Since e-util/e-account-list.h in
+       evolution module has been developed further, merge those changes 
+       into libedataserver and drop e-util/e-account-list.h.
+       libedataserver/e-account.c: Since e-util/e-account.c in
+       evolution module has been developed further, merge those changes 
+       into libedataserver and drop e-util/e-account.c.
+       libedataserver/e-account.h: Since e-util/e-account.h in
+       evolution module has been developed further, merge those changes 
+       into libedataserver and drop e-util/e-account.h.
+
 2006-01-04  Tor Lillqvist  <tml@novell.com>
 
        * libedataserver/e-util.c (e_util_replace_prefix): As this
index f70eec7..a9c640a 100644 (file)
@@ -292,6 +292,46 @@ e_account_list_save (EAccountList *account_list)
        gconf_client_suggest_sync (account_list->priv->gconf, NULL);
 }
 
+void 
+e_account_list_prune_proxies (EAccountList *account_list)
+{
+       EAccount *account;
+       EIterator *iter;
+       
+       for (iter = e_list_get_iterator (E_LIST (account_list));
+            e_iterator_is_valid (iter);
+            e_iterator_next (iter)) {
+               account = (EAccount *)e_iterator_get (iter);
+               if (account->parent_uid) 
+                       e_account_list_remove (account_list, account);
+       }
+
+       e_account_list_save (account_list);
+       g_object_unref (iter);
+}
+
+void 
+e_account_list_remove_account_proxies (EAccountList *accounts, EAccount *account)
+{
+       EAccount *child_account;
+
+       while ( (child_account = (EAccount *)e_account_list_find (accounts, E_ACCOUNT_FIND_PARENT_UID, account->uid))) {
+               e_account_list_remove (accounts, child_account);
+               child_account = NULL;
+       }
+
+       e_account_list_save (accounts);
+}
+
+int
+e_account_list_account_has_proxies (EAccountList *accounts, EAccount *account)
+{
+       if (e_account_list_find (accounts, E_ACCOUNT_FIND_PARENT_UID, account->uid))
+               return TRUE;
+
+       return FALSE;
+}
+
 /**
  * e_account_list_add:
  * @accounts: 
@@ -451,6 +491,10 @@ e_account_list_find(EAccountList *accounts, e_account_find_t type, const char *k
                        if (account->id)
                                found = g_ascii_strcasecmp(account->id->address, key) == 0;
                        break;
+               case E_ACCOUNT_FIND_PARENT_UID:
+                       if (account->parent_uid)
+                               found = strcmp(account->parent_uid, key) == 0;
+                       break;
                }
 
                if (found)
index 033322c..2534e62 100644 (file)
@@ -40,9 +40,10 @@ typedef enum _e_account_find_t {
        E_ACCOUNT_FIND_UID,
        E_ACCOUNT_FIND_ID_NAME,
        E_ACCOUNT_FIND_ID_ADDRESS,
+       E_ACCOUNT_FIND_PARENT_UID,
 } e_account_find_t;
 
-typedef struct {
+typedef struct _EAccountList {
        EList parent_object;
 
        EAccountListPrivate *priv;
@@ -74,6 +75,10 @@ const EAccount *e_account_list_get_default(EAccountList *);
 void            e_account_list_set_default(EAccountList *, EAccount *);
 const EAccount *e_account_list_find       (EAccountList *, e_account_find_t type, const char *key);
 
+void e_account_list_prune_proxies (EAccountList *);
+void e_account_list_remove_account_proxies (EAccountList *, EAccount *);
+int e_account_list_account_has_proxies (EAccountList *, EAccount *);
+
 G_END_DECLS
 
 #endif /* __E_ACCOUNT_LIST__ */
index efdbfe6..be58cea 100644 (file)
 #include <libxml/tree.h>
 #include <libxml/xmlmemory.h>
 
+#include <gconf/gconf-client.h>
+
+#define d(x)
+
+enum {
+       CHANGED,
+       LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
 static void finalize (GObject *);
 
 G_DEFINE_TYPE (EAccount, e_account, G_TYPE_OBJECT);
 
+/*
+lock mail accounts     Relatively difficult -- involves redesign of the XML blobs which describe accounts
+disable adding mail accounts   Simple -- can be done with just a Gconf key and some UI work to make assoc. widgets unavailable
+disable editing mail accounts  Relatively difficult -- involves redesign of the XML blobs which describe accounts
+disable removing mail accounts 
+lock default character encoding        Simple -- Gconf key + a little UI work to desensitize widgets, etc
+disable free busy publishing   
+disable specific mime types (from being viewed)        90% done already (Unknown MIME types still pose a problem)
+lock image loading preference  
+lock junk mail filtering settings      
+**  junk mail per account
+lock work week 
+lock first day of work week    
+lock working hours     
+disable forward as icalendar   
+lock color options for tasks   
+lock default contact filing format     
+* forbid signatures    Simple -- can be done with just a Gconf key and some UI work to make assoc. widgets unavailable
+* lock user to having 1 specific signature     Simple -- can be done with just a Gconf key and some UI work to make assoc. widgets unavailable
+* forbid adding/removing signatures    Simple -- can be done with just a Gconf key and some UI work to make assoc. widgets unavailable
+* lock each account to a certain signature     Relatively difficult -- involved redesign of the XML blobs which describe accounts 
+* set default folders  
+set trash emptying frequency   
+* lock displayed mail headers  Simple -- can be done with just a Gconf key and some UI work to make assoc. widgets unavailable
+* lock authentication type (for incoming mail) Relatively difficult -- involves redesign of the XML blobs which describe accounts
+* lock authentication type (for outgoing mail) Relatively difficult -- involves redesign of the XML blobs which describe accounts
+* lock minimum check mail on server frequency  Simple -- can be done with just a Gconf key and some UI work to make assoc. widgets unavailable
+** lock save password
+* require ssl always   Relatively difficult -- involves redesign of the XML blobs which describe accounts
+** lock imap subscribed folder option
+** lock filtering of inbox
+** lock source account/options
+** lock destination account/options
+*/
+
 static void
 e_account_class_init (EAccountClass *account_class)
 {
@@ -42,6 +88,16 @@ e_account_class_init (EAccountClass *account_class)
 
        /* virtual method override */
        object_class->finalize = finalize;
+
+       signals[CHANGED] =
+               g_signal_new("changed",
+                            G_OBJECT_CLASS_TYPE (object_class),
+                            G_SIGNAL_RUN_LAST,
+                            G_STRUCT_OFFSET (EAccountClass, changed),
+                            NULL, NULL,
+                            g_cclosure_marshal_VOID__INT,
+                            G_TYPE_NONE, 1,
+                            G_TYPE_INT);
 }
 
 static void
@@ -50,6 +106,11 @@ e_account_init (EAccount *account)
        account->id = g_new0 (EAccountIdentity, 1);
        account->source = g_new0 (EAccountService, 1);
        account->transport = g_new0 (EAccountService, 1);
+
+       account->parent_uid = NULL;
+       
+       account->source->auto_check = FALSE;
+       account->source->auto_check_time = 10;
 }
 
 static void
@@ -62,6 +123,7 @@ identity_destroy (EAccountIdentity *id)
        g_free (id->address);
        g_free (id->reply_to);
        g_free (id->organization);
+       g_free (id->sig_uid);
 
        g_free (id);
 }
@@ -99,6 +161,8 @@ finalize (GObject *object)
        g_free (account->smime_sign_key);
        g_free (account->smime_encrypt_key);
 
+       g_free (account->parent_uid);
+
        G_OBJECT_CLASS (e_account_parent_class)->finalize (object);
 }
 
@@ -182,45 +246,101 @@ xml_set_int (xmlNodePtr node, const char *name, int *val)
 static gboolean
 xml_set_prop (xmlNodePtr node, const char *name, char **val)
 {
-       char *buf, *new_val;
+       char *buf;
+       int res;
 
        buf = xmlGetProp (node, name);
-       new_val = g_strdup (buf);
-       xmlFree (buf);
-
-       /* We can use strcmp here whether the value is UTF8 or
-        * not, since we only care if the bytes changed.
-        */
-       if (!*val || strcmp (*val, new_val)) {
-               g_free (*val);
-               *val = new_val;
-               return TRUE;
+       if (buf == NULL) {
+               res = (*val != NULL);
+               if (res) {
+                       g_free(*val);
+                       *val = NULL;
+               }
        } else {
-               g_free (new_val);
-               return FALSE;
+               res = *val == NULL || strcmp(*val, buf) != 0;
+               if (res) {
+                       g_free(*val);
+                       *val = g_strdup(buf);
+               }
+               xmlFree(buf);
+       }
+
+       return res;
+}
+
+static EAccountReceiptPolicy
+str_to_receipt_policy (const char *str)
+{
+       if (!strcmp (str, "ask"))
+               return E_ACCOUNT_RECEIPT_ASK;
+       if (!strcmp (str, "always"))
+               return E_ACCOUNT_RECEIPT_ALWAYS;
+
+       return E_ACCOUNT_RECEIPT_NEVER;
+}
+
+static char*
+receipt_policy_to_str (EAccountReceiptPolicy val)
+{
+       char *ret = 0;
+       
+       switch (val) {
+       case E_ACCOUNT_RECEIPT_NEVER:
+               ret = "never";
+               break;
+       case E_ACCOUNT_RECEIPT_ASK:
+               ret = "ask";
+               break;
+       case E_ACCOUNT_RECEIPT_ALWAYS:
+               ret = "always";
+               break;
        }
+
+       return ret;
+}
+
+static gboolean
+xml_set_receipt_policy (xmlNodePtr node, const char *name, EAccountReceiptPolicy *val)
+{
+       EAccountReceiptPolicy new_val;
+       char *buf;
+
+       if ((buf = xmlGetProp (node, name))) {
+               new_val = str_to_receipt_policy (buf);
+               xmlFree (buf);
+
+               if (new_val != *val) {
+                       *val = new_val;
+                       return TRUE;
+               }
+       }
+
+       return FALSE;
 }
 
 static gboolean
 xml_set_content (xmlNodePtr node, char **val)
 {
-       char *buf, *new_val;
-
-       buf = xmlNodeGetContent (node);
-        new_val = g_strdup (buf);
-       xmlFree (buf);
-
-       /* We can use strcmp here whether the value is UTF8 or
-        * not, since we only care if the bytes changed.
-        */
-       if (!*val || strcmp (*val, new_val)) {
-               g_free (*val);
-               *val = new_val;
-               return TRUE;
+       char *buf;
+       int res;
+
+       buf = xmlNodeGetContent(node);
+       if (buf == NULL) {
+               res = (*val != NULL);
+               if (res) {
+                       g_free(*val);
+                       *val = NULL;
+               }
        } else {
-               g_free (new_val);
-               return FALSE;
+               res = *val == NULL || strcmp(*val, buf) != 0;
+               if (res) {
+                       g_free(*val);
+                       *val = g_strdup(buf);
+               }
+               xmlFree(buf);
        }
+
+       return res;
 }
 
 static gboolean
@@ -238,8 +358,26 @@ xml_set_identity (xmlNodePtr node, EAccountIdentity *id)
                else if (!strcmp (node->name, "organization"))
                        changed |= xml_set_content (node, &id->organization);
                else if (!strcmp (node->name, "signature")) {
-                       changed |= xml_set_bool (node, "auto", &id->auto_signature);
-                       changed |= xml_set_int (node, "default", &id->def_signature);
+                       changed |= xml_set_prop (node, "uid", &id->sig_uid);
+                       if (!id->sig_uid) {
+
+                               /* WTF is this shit doing here?  Migrate is supposed to "handle this" */
+
+                               /* set a fake sig uid so the migrate code can handle this */
+                               gboolean autogen = FALSE;
+                               int sig_id = 0;
+                               
+                               xml_set_bool (node, "auto", &autogen);
+                               xml_set_int (node, "default", &sig_id);
+                               
+                               if (autogen) {
+                                       id->sig_uid = g_strdup ("::0");
+                                       changed = TRUE;
+                               } else if (sig_id) {
+                                       id->sig_uid = g_strdup_printf ("::%d", sig_id + 1);
+                                       changed = TRUE;
+                               }
+                       }
                }
        }
 
@@ -320,6 +458,8 @@ e_account_set_from_xml (EAccount *account, const char *xml)
                } else if (!strcmp (node->name, "auto-bcc")) {
                        changed |= xml_set_bool (node, "always", &account->always_bcc);
                        changed |= xml_set_content (node, &account->bcc_addrs);
+               } else if (!strcmp (node->name, "receipt-policy")) {
+                       changed |= xml_set_receipt_policy (node, "policy", &account->receipt_policy);
                } else if (!strcmp (node->name, "pgp")) {
                        changed |= xml_set_bool (node, "encrypt-to-self", &account->pgp_encrypt_to_self);
                        changed |= xml_set_bool (node, "always-trust", &account->pgp_always_trust);
@@ -349,11 +489,22 @@ e_account_set_from_xml (EAccount *account, const char *xml)
                                        }
                                }
                        }
+               } else if (!strcmp (node->name, "proxy")) {
+                       if (node->children) {
+                               for (cur = node->children; cur; cur = cur->next) {
+                                       if (!strcmp (cur->name, "parent-uid")) {
+                                               changed |= xml_set_content (cur, &account->parent_uid);
+                                               break;
+                                       }
+                               }
+                       }
                }
        }
 
        xmlFreeDoc (doc);
 
+       g_signal_emit(account, signals[CHANGED], 0, -1);
+
        return changed;
 }
 
@@ -381,8 +532,7 @@ e_account_import (EAccount *dest, EAccount *src)
        dest->id->reply_to = g_strdup (src->id->reply_to);
        g_free (dest->id->organization);
        dest->id->organization = g_strdup (src->id->organization);
-       dest->id->def_signature = src->id->def_signature;
-       dest->id->auto_signature = src->id->auto_signature;
+       dest->id->sig_uid = g_strdup (src->id->sig_uid);
        
        g_free (dest->source->url);
        dest->source->url = g_strdup (src->source->url);
@@ -409,6 +559,8 @@ e_account_import (EAccount *dest, EAccount *src)
        g_free (dest->bcc_addrs);
        dest->bcc_addrs = g_strdup (src->bcc_addrs);
        
+       dest->receipt_policy = src->receipt_policy;
+       
        g_free (dest->pgp_key);
        dest->pgp_key = g_strdup (src->pgp_key);
        dest->pgp_encrypt_to_self = src->pgp_encrypt_to_self;
@@ -424,6 +576,8 @@ e_account_import (EAccount *dest, EAccount *src)
        dest->smime_encrypt_to_self = src->smime_encrypt_to_self;
        g_free (dest->smime_encrypt_key);
        dest->smime_encrypt_key = g_strdup (src->smime_encrypt_key);
+       
+       g_signal_emit(dest, signals[CHANGED], 0, -1);
 }
 
 
@@ -463,9 +617,7 @@ e_account_to_xml (EAccount *account)
                xmlNewTextChild (id, NULL, "organization", account->id->organization);
 
        node = xmlNewChild (id, NULL, "signature",NULL);
-       xmlSetProp (node, "auto", account->id->auto_signature ? "true" : "false");
-       sprintf (buf, "%d", account->id->def_signature);
-       xmlSetProp (node, "default", buf);
+       xmlSetProp (node, "uid", account->id->sig_uid);
 
        src = xmlNewChild (root, NULL, "source", NULL);
        xmlSetProp (src, "save-passwd", account->source->save_passwd ? "true" : "false");
@@ -494,6 +646,9 @@ e_account_to_xml (EAccount *account)
        if (account->bcc_addrs)
                xmlNewTextChild (node, NULL, "recipients", account->bcc_addrs);
 
+       node = xmlNewChild (root, NULL, "receipt-policy", NULL);
+       xmlSetProp (node, "policy", receipt_policy_to_str (account->receipt_policy));
+       
        node = xmlNewChild (root, NULL, "pgp", NULL);
        xmlSetProp (node, "encrypt-to-self", account->pgp_encrypt_to_self ? "true" : "false");
        xmlSetProp (node, "always-trust", account->pgp_always_trust ? "true" : "false");
@@ -511,6 +666,11 @@ e_account_to_xml (EAccount *account)
        if (account->smime_encrypt_key)
                xmlNewTextChild (node, NULL, "encrypt-key-id", account->smime_encrypt_key);
 
+       if (account->parent_uid) {
+               node = xmlNewChild (root, NULL, "proxy", NULL);
+               xmlNewTextChild (node, NULL, "parent-uid", account->parent_uid);
+       }       
+
        xmlDocDumpMemory (doc, &xmlbuf, &n);
        xmlFreeDoc (doc);
 
@@ -553,3 +713,286 @@ e_account_uid_from_xml (const char *xml)
 
        return uid;
 }
+
+enum {
+       EAP_IMAP_SUBSCRIBED = 0,
+       EAP_IMAP_NAMESPACE,
+       EAP_FILTER_INBOX,
+       EAP_FILTER_JUNK,
+       EAP_FORCE_SSL,
+       EAP_LOCK_SIGNATURE,
+       EAP_LOCK_AUTH,
+       EAP_LOCK_AUTOCHECK,
+       EAP_LOCK_DEFAULT_FOLDERS,
+       EAP_LOCK_SAVE_PASSWD,
+       EAP_LOCK_SOURCE,
+       EAP_LOCK_TRANSPORT,
+};
+
+static struct _system_info {
+       const char *key;
+       guint32 perm;
+} system_perms[] = {
+       { "imap_subscribed", 1<<EAP_IMAP_SUBSCRIBED },
+       { "imap_namespace", 1<<EAP_IMAP_NAMESPACE },
+       { "filter_inbox", 1<<EAP_FILTER_INBOX },
+       { "filter_junk", 1<<EAP_FILTER_JUNK },
+       { "ssl", 1<<EAP_FORCE_SSL },
+       { "signature", 1<<EAP_LOCK_SIGNATURE },
+       { "authtype", 1<<EAP_LOCK_AUTH },
+       { "autocheck", 1<<EAP_LOCK_AUTOCHECK },
+       { "default_folders", 1<<EAP_LOCK_DEFAULT_FOLDERS },
+       { "save_passwd" , 1<<EAP_LOCK_SAVE_PASSWD },
+       { "source", 1<<EAP_LOCK_SOURCE },
+       { "transport", 1<<EAP_LOCK_TRANSPORT },
+};
+
+#define TYPE_STRING (1)
+#define TYPE_INT (2)
+#define TYPE_BOOL (3)
+#define TYPE_MASK (0xff)
+#define TYPE_STRUCT (1<<8)
+
+static struct _account_info {
+       guint32 perms;
+       guint32 type;
+       unsigned int offset;
+       unsigned int struct_offset;
+} account_info[E_ACCOUNT_ITEM_LAST] = {
+       { /* E_ACCOUNT_NAME */ 0, TYPE_STRING, G_STRUCT_OFFSET(EAccount, name) },
+
+       { /* E_ACCOUNT_ID_NAME, */ 0, TYPE_STRING|TYPE_STRUCT, G_STRUCT_OFFSET(EAccount, id), G_STRUCT_OFFSET(EAccountIdentity, name) },
+       { /* E_ACCOUNT_ID_ADDRESS, */ 0, TYPE_STRING|TYPE_STRUCT, G_STRUCT_OFFSET(EAccount, id), G_STRUCT_OFFSET(EAccountIdentity, address) },
+       { /* E_ACCOUNT_ID_REPLY_TO, */ 0, TYPE_STRING|TYPE_STRUCT, G_STRUCT_OFFSET(EAccount, id), G_STRUCT_OFFSET(EAccountIdentity, reply_to) },
+       { /* E_ACCOUNT_ID_ORGANIZATION */ 0, TYPE_STRING|TYPE_STRUCT, G_STRUCT_OFFSET(EAccount, id), G_STRUCT_OFFSET(EAccountIdentity, organization) },
+       { /* E_ACCOUNT_ID_SIGNATURE */ 1<<EAP_LOCK_SIGNATURE, TYPE_STRING|TYPE_STRUCT, G_STRUCT_OFFSET(EAccount, id), G_STRUCT_OFFSET(EAccountIdentity, sig_uid) },
+
+       { /* E_ACCOUNT_SOURCE_URL */ 1<<EAP_LOCK_SOURCE, TYPE_STRING|TYPE_STRUCT, G_STRUCT_OFFSET(EAccount, source), G_STRUCT_OFFSET(EAccountService, url) },
+       { /* E_ACCOUNT_SOURCE_KEEP_ON_SERVER */ 0, TYPE_BOOL|TYPE_STRUCT, G_STRUCT_OFFSET(EAccount, source), G_STRUCT_OFFSET(EAccountService, keep_on_server) },
+       { /* E_ACCOUNT_SOURCE_AUTO_CHECK */ 1<<EAP_LOCK_AUTOCHECK, TYPE_BOOL|TYPE_STRUCT, G_STRUCT_OFFSET(EAccount, source), G_STRUCT_OFFSET(EAccountService, auto_check) },
+       { /* E_ACCOUNT_SOURCE_AUTO_CHECK_TIME */ 1<<EAP_LOCK_AUTOCHECK, TYPE_INT|TYPE_STRUCT, G_STRUCT_OFFSET(EAccount, source), G_STRUCT_OFFSET(EAccountService, auto_check_time) },
+       { /* E_ACCOUNT_SOURCE_SAVE_PASSWD */ 1<<EAP_LOCK_SAVE_PASSWD, TYPE_BOOL|TYPE_STRUCT, G_STRUCT_OFFSET(EAccount, source), G_STRUCT_OFFSET(EAccountService, save_passwd) },
+
+       { /* E_ACCOUNT_TRANSPORT_URL */ 1<<EAP_LOCK_TRANSPORT, TYPE_STRING|TYPE_STRUCT, G_STRUCT_OFFSET(EAccount, transport), G_STRUCT_OFFSET(EAccountService, url) },
+       { /* E_ACCOUNT_TRANSPORT_SAVE_PASSWD */ 1<<EAP_LOCK_SAVE_PASSWD, TYPE_BOOL|TYPE_STRUCT, G_STRUCT_OFFSET(EAccount, transport), G_STRUCT_OFFSET(EAccountService, save_passwd) },
+
+       { /* E_ACCOUNT_DRAFTS_FOLDER_URI */ 1<<EAP_LOCK_DEFAULT_FOLDERS, TYPE_STRING, G_STRUCT_OFFSET(EAccount, drafts_folder_uri) },
+       { /* E_ACCOUNT_SENT_FOLDER_URI */ 1<<EAP_LOCK_DEFAULT_FOLDERS, TYPE_STRING, G_STRUCT_OFFSET(EAccount, sent_folder_uri) },
+
+       { /* E_ACCOUNT_CC_ALWAYS */ 0, TYPE_BOOL, G_STRUCT_OFFSET(EAccount, always_cc) },
+       { /* E_ACCOUNT_CC_ADDRS */ 0, TYPE_STRING, G_STRUCT_OFFSET(EAccount, cc_addrs) },
+
+       { /* E_ACCOUNT_BCC_ALWAYS */ 0, TYPE_BOOL, G_STRUCT_OFFSET(EAccount, always_bcc) },
+       { /* E_ACCOUNT_BCC_ADDRS */ 0, TYPE_STRING, G_STRUCT_OFFSET(EAccount, bcc_addrs) },
+
+       { /* E_ACCOUNT_RECEIPT_POLICY */ 0, TYPE_INT, G_STRUCT_OFFSET(EAccount, receipt_policy) },
+       
+       { /* E_ACCOUNT_PGP_KEY */ 0, TYPE_STRING, G_STRUCT_OFFSET(EAccount, pgp_key) },
+       { /* E_ACCOUNT_PGP_ENCRYPT_TO_SELF */ 0, TYPE_BOOL, G_STRUCT_OFFSET(EAccount, pgp_encrypt_to_self) },
+       { /* E_ACCOUNT_PGP_ALWAYS_SIGN */ 0, TYPE_BOOL, G_STRUCT_OFFSET(EAccount, pgp_always_sign) },
+       { /* E_ACCOUNT_PGP_NO_IMIP_SIGN */ 0, TYPE_BOOL, G_STRUCT_OFFSET(EAccount, pgp_no_imip_sign) },
+       { /* E_ACCOUNT_PGP_ALWAYS_TRUST */ 0, TYPE_BOOL, G_STRUCT_OFFSET(EAccount, pgp_always_trust) },
+
+       { /* E_ACCOUNT_SMIME_SIGN_KEY */ 0, TYPE_STRING, G_STRUCT_OFFSET(EAccount, smime_sign_key) },
+       { /* E_ACCOUNT_SMIME_ENCRYPT_KEY */ 0, TYPE_STRING, G_STRUCT_OFFSET(EAccount, smime_encrypt_key) },
+       { /* E_ACCOUNT_SMIME_SIGN_DEFAULT */ 0, TYPE_BOOL, G_STRUCT_OFFSET(EAccount, smime_sign_default) },
+       { /* E_ACCOUNT_SMIME_ENCRYPT_TO_SELF */ 0, TYPE_BOOL, G_STRUCT_OFFSET(EAccount, smime_encrypt_to_self) },
+       { /* E_ACCOUNT_SMIME_ENCRYPT_DEFAULT */ 0, TYPE_BOOL, G_STRUCT_OFFSET(EAccount, smime_encrypt_default) },
+
+       { /* E_ACCOUNT_PROXY_PARENT_UID, */ 0, TYPE_STRING, G_STRUCT_OFFSET(EAccount, parent_uid) },
+};
+
+static GHashTable *ea_option_table;
+static GHashTable *ea_system_table;
+static guint32 ea_perms;
+
+static struct _option_info {
+       char *key;
+       guint32 perms;
+} ea_option_list[] = {
+       { "imap_use_lsub", 1<<EAP_IMAP_SUBSCRIBED },
+       { "imap_override_namespace", 1<<EAP_IMAP_NAMESPACE },
+       { "imap_filter", 1<<EAP_FILTER_INBOX },
+       { "imap_filter_junk", 1<<EAP_FILTER_JUNK },
+       { "imap_filter_junk_inbox", 1<<EAP_FILTER_JUNK },
+       { "*_use_ssl", 1<<EAP_FORCE_SSL },
+       { "*_auth", 1<<EAP_LOCK_AUTH },
+};
+
+#define LOCK_BASE "/apps/evolution/lock/mail/accounts"
+
+static void
+ea_setting_notify(GConfClient *gconf, guint cnxn_id, GConfEntry *entry, void *crap)
+{
+       GConfValue *value;
+       char *tkey;
+       struct _system_info *info;
+
+       g_return_if_fail (gconf_entry_get_key (entry) != NULL);
+       
+       if (!(value = gconf_entry_get_value (entry)))
+               return;
+       
+       tkey = strrchr(entry->key, '/');
+       g_return_if_fail (tkey != NULL);
+
+       info = g_hash_table_lookup(ea_system_table, tkey+1);
+       if (info) {
+               if (gconf_value_get_bool(value))
+                       ea_perms |= info->perm;
+               else
+                       ea_perms &= ~info->perm;
+       }
+}
+
+static void
+ea_setting_setup(void)
+{
+       GConfClient *gconf = gconf_client_get_default();
+       GConfEntry *entry;
+       GError *err = NULL;
+       int i;
+       char key[64];
+
+       if (ea_option_table != NULL)
+               return;
+
+       ea_option_table = g_hash_table_new(g_str_hash, g_str_equal);
+       for (i=0;i<sizeof(ea_option_list)/sizeof(ea_option_list[0]);i++)
+               g_hash_table_insert(ea_option_table, ea_option_list[i].key, &ea_option_list[i]);
+
+       gconf_client_add_dir(gconf, LOCK_BASE, GCONF_CLIENT_PRELOAD_NONE, NULL);
+
+       ea_system_table = g_hash_table_new(g_str_hash, g_str_equal);
+       for (i=0;i<sizeof(system_perms)/sizeof(system_perms[0]);i++) {
+               g_hash_table_insert(ea_system_table, (char *)system_perms[i].key, &system_perms[i]);
+               sprintf(key, LOCK_BASE "/%s", system_perms[i].key);
+               entry = gconf_client_get_entry(gconf, key, NULL, TRUE, &err);
+               if (entry)
+                       ea_setting_notify(gconf, 0, entry, NULL);
+               gconf_entry_free(entry);
+       }
+
+       if (err) {
+               g_warning("Could not load account lock settings: %s", err->message);
+               g_error_free(err);
+       }
+
+       gconf_client_notify_add(gconf, LOCK_BASE, (GConfClientNotifyFunc)ea_setting_notify, NULL, NULL, NULL);
+       g_object_unref(gconf);
+}
+
+/* look up the item in the structure or the substructure using our table of reflection data */
+#define addr(ea, type) \
+       ((account_info[type].type & TYPE_STRUCT)? \
+       (((char **)(((char *)ea)+account_info[type].offset))[0] + account_info[type].struct_offset): \
+       (((char *)ea)+account_info[type].offset))
+       
+const char *e_account_get_string(EAccount *ea, e_account_item_t type)
+{
+       return *((const char **)addr(ea, type));
+}
+
+int e_account_get_int(EAccount *ea, e_account_item_t type)
+{
+       return *((int *)addr(ea, type));
+}
+
+gboolean e_account_get_bool(EAccount *ea, e_account_item_t type)
+{
+       return *((gboolean *)addr(ea, type));
+}
+
+#if d(!)0
+static void
+dump_account(EAccount *ea)
+{
+       char *xml;
+
+       printf("Account changed\n");
+       xml = e_account_to_xml(ea);
+       printf(" ->\n%s\n", xml);
+       g_free(xml);
+}
+#endif
+
+/* TODO: should it return true if it changed? */
+void e_account_set_string(EAccount *ea, e_account_item_t type, const char *val)
+{
+       char **p;
+
+       if (!e_account_writable(ea, type)) {
+               g_warning("Trying to set non-writable option account value");
+       } else {
+               p = (char **)addr(ea, type);
+               d(printf("Setting string %d: old '%s' new '%s'\n", type, *p, val));
+               if (*p != val
+                   && (*p == NULL || val == NULL || strcmp(*p, val) != 0)) {
+                       g_free(*p);
+                       *p = g_strdup(val);
+                       d(dump_account(ea));
+                       g_signal_emit(ea, signals[CHANGED], 0, type);
+               }
+       }
+}
+
+void e_account_set_int(EAccount *ea, e_account_item_t type, int val)
+{
+       if (!e_account_writable(ea, type)) {
+               g_warning("Trying to set non-writable option account value");
+       } else {
+               int *p = (int *)addr(ea, type);
+
+               if (*p != val) {
+                       *p = val;
+                       d(dump_account(ea));
+                       g_signal_emit(ea, signals[CHANGED], 0, type);
+               }
+       }
+}
+
+void e_account_set_bool(EAccount *ea, e_account_item_t type, gboolean val)
+{
+       if (!e_account_writable(ea, type)) {
+               g_warning("Trying to set non-writable option account value");
+       } else {
+               gboolean *p = (gboolean *)addr(ea, type);
+
+               if (*p != val) {
+                       *p = val;
+                       d(dump_account(ea));
+                       g_signal_emit(ea, signals[CHANGED], 0, type);
+               }
+       }
+}
+
+gboolean
+e_account_writable_option(EAccount *ea, const char *protocol, const char *option)
+{
+       char *key;
+       struct _option_info *info;
+
+       ea_setting_setup();
+
+       key = alloca(strlen(protocol)+strlen(option)+2);
+       sprintf(key, "%s_%s", protocol, option);
+
+       info = g_hash_table_lookup(ea_option_table, key);
+       if (info == NULL) {
+               sprintf(key, "*_%s", option);
+               info = g_hash_table_lookup(ea_option_table, key);
+       }
+
+       d(printf("checking writable option '%s' perms=%08x\n", option, info?info->perms:0));
+
+       return info == NULL
+               || (info->perms & ea_perms) == 0;
+}
+
+gboolean
+e_account_writable(EAccount *ea, e_account_item_t type)
+{
+       ea_setting_setup();
+
+       return (account_info[type].perms & ea_perms) == 0;
+}
index 1bb23f6..f9f9e57 100644 (file)
@@ -30,17 +30,72 @@ G_BEGIN_DECLS
 #define E_IS_ACCOUNT(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_ACCOUNT))
 #define E_IS_ACCOUNT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_ACCOUNT))
 
-typedef struct {
+typedef enum _e_account_item_t {
+       E_ACCOUNT_NAME,
+
+       E_ACCOUNT_ID_NAME,
+       E_ACCOUNT_ID_ADDRESS,
+       E_ACCOUNT_ID_REPLY_TO,
+       E_ACCOUNT_ID_ORGANIZATION,
+       E_ACCOUNT_ID_SIGNATURE,
+
+       E_ACCOUNT_SOURCE_URL,   /* what about separating out host/user/path settings??  sigh */
+       E_ACCOUNT_SOURCE_KEEP_ON_SERVER,
+       E_ACCOUNT_SOURCE_AUTO_CHECK,
+       E_ACCOUNT_SOURCE_AUTO_CHECK_TIME,
+       E_ACCOUNT_SOURCE_SAVE_PASSWD,
+
+       E_ACCOUNT_TRANSPORT_URL,
+       E_ACCOUNT_TRANSPORT_SAVE_PASSWD,
+
+       E_ACCOUNT_DRAFTS_FOLDER_URI,
+       E_ACCOUNT_SENT_FOLDER_URI,
+
+       E_ACCOUNT_CC_ALWAYS,
+       E_ACCOUNT_CC_ADDRS,
+
+       E_ACCOUNT_BCC_ALWAYS,
+       E_ACCOUNT_BCC_ADDRS,
+
+       E_ACCOUNT_RECEIPT_POLICY,
+       
+       E_ACCOUNT_PGP_KEY,
+       E_ACCOUNT_PGP_ENCRYPT_TO_SELF,
+       E_ACCOUNT_PGP_ALWAYS_SIGN,
+       E_ACCOUNT_PGP_NO_IMIP_SIGN,
+       E_ACCOUNT_PGP_ALWAYS_TRUST,
+
+       E_ACCOUNT_SMIME_SIGN_KEY,
+       E_ACCOUNT_SMIME_ENCRYPT_KEY,
+       E_ACCOUNT_SMIME_SIGN_DEFAULT,
+       E_ACCOUNT_SMIME_ENCRYPT_TO_SELF,
+       E_ACCOUNT_SMIME_ENCRYPT_DEFAULT,
+
+       E_ACCOUNT_PROXY_PARENT_UID,
+
+       E_ACCOUNT_ITEM_LAST
+} e_account_item_t;
+
+typedef enum _e_account_access_t {
+       E_ACCOUNT_ACCESS_WRITE = 1<<0,
+} e_account_access_t;
+
+typedef struct _EAccountIdentity {
        char *name;
        char *address;
        char *reply_to;
        char *organization;
        
-       int def_signature;
-       gboolean auto_signature;
+       char *sig_uid;
 } EAccountIdentity;
 
-typedef struct {
+typedef enum _EAccountReceiptPolicy {
+       E_ACCOUNT_RECEIPT_NEVER,
+       E_ACCOUNT_RECEIPT_ASK,
+       E_ACCOUNT_RECEIPT_ALWAYS
+} EAccountReceiptPolicy;
+
+typedef struct _EAccountService {
        char *url;
        gboolean keep_on_server;
        gboolean auto_check;
@@ -48,8 +103,7 @@ typedef struct {
        gboolean save_passwd;
 } EAccountService;
 
-
-typedef struct {
+typedef struct _EAccount {
        GObject parent_object;
 
        char *name;
@@ -68,12 +122,16 @@ typedef struct {
        gboolean always_bcc;
        char *bcc_addrs;
 
+       EAccountReceiptPolicy receipt_policy;
+
        char *pgp_key;
        gboolean pgp_encrypt_to_self;
        gboolean pgp_always_sign;
        gboolean pgp_no_imip_sign;
        gboolean pgp_always_trust;
 
+       char *parent_uid;
+
        char *smime_sign_key;
        char *smime_encrypt_key;
        gboolean smime_sign_default;
@@ -84,6 +142,7 @@ typedef struct {
 typedef struct {
        GObjectClass parent_class;
 
+       void (*changed)(EAccount *, int field);
 } EAccountClass;
 
 
@@ -104,6 +163,31 @@ char     *e_account_to_xml       (EAccount   *account);
 
 char     *e_account_uid_from_xml (const char *xml);
 
+const char *e_account_get_string (EAccount *,
+                                 e_account_item_t type);
+
+int       e_account_get_int      (EAccount *,
+                                 e_account_item_t type);
+
+gboolean  e_account_get_bool     (EAccount *,
+                                 e_account_item_t type);
+
+void      e_account_set_string   (EAccount *,
+                                 e_account_item_t type, const char *);
+
+void      e_account_set_int      (EAccount *,
+                                 e_account_item_t type, int);
+
+void      e_account_set_bool     (EAccount *,
+                                 e_account_item_t type, gboolean);
+
+gboolean  e_account_writable     (EAccount *ea,
+                                 e_account_item_t type);
+
+gboolean  e_account_writable_option (EAccount *ea,
+                                 const char *protocol,
+                                 const char *option);
+
 G_END_DECLS
 
 #endif /* __E_ACCOUNT__ */