2012-01-01 [mir] 0.6.0cvs70
authorMichael Rasmussen <mir@datanom.net>
Sun, 1 Jan 2012 23:31:53 +0000 (23:31 +0000)
committerMichael Rasmussen <mir@datanom.net>
Sun, 1 Jan 2012 23:31:53 +0000 (23:31 +0000)
* extensions/vcard/src/vcard-extension.c
* extensions/vcard/src/vcard-utils.c
* extensions/vcard/src/vcard-utils.h
    Finished implementation of vCard import.
    Completed extension vCard.

ChangeLog
PATCHSETS
configure.ac
extensions/vcard/src/vcard-extension.c
extensions/vcard/src/vcard-utils.c
extensions/vcard/src/vcard-utils.h

index a2b99b0a0420e6de33b2d0e25f18fc9cad0a7c40..518703b0a4bc9924fb72936360131159254e063e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2012-01-01 [mir]       0.6.0cvs70
+
+       * extensions/vcard/src/vcard-extension.c
+       * extensions/vcard/src/vcard-utils.c
+       * extensions/vcard/src/vcard-utils.h
+           Finished implementation of vCard import.
+           Completed extension vCard.
+
 2012-01-01 [mir]       0.6.0cvs69
 
        * extensions/import/ldifimport_extension.c
index ab5b3c4bc2fb3bd9b3a4e98e790eab559c4d1360..04ba559261a6c3f1ddbcfd1efb055e1a41b93b09 100644 (file)
--- a/PATCHSETS
+++ b/PATCHSETS
@@ -67,3 +67,4 @@
 ( cvs diff -u -r 1.1 -r 1.2 extensions/vcard/src/vcard-extension.c;  cvs diff -u -r 1.1 -r 1.2 extensions/vcard/src/vcard-utils.c;  cvs diff -u -r 1.1 -r 1.2 extensions/vcard/src/libversit/.cvsignore;  ) > 0.6.0cvs67.patchset
 ( cvs diff -u -r 1.2 -r 1.3 extensions/vcard/src/vcard-utils.c;  ) > 0.6.0cvs68.patchset
 ( cvs diff -u -r 1.4 -r 1.5 extensions/import/ldifimport_extension.c;  ) > 0.6.0cvs69.patchset
+( cvs diff -u -r 1.2 -r 1.3 extensions/vcard/src/vcard-extension.c;  cvs diff -u -r 1.3 -r 1.4 extensions/vcard/src/vcard-utils.c;  cvs diff -u -r 1.1 -r 1.2 extensions/vcard/src/vcard-utils.h;  ) > 0.6.0cvs70.patchset
index 36ffeb8efa70f586e707f2eb46d5acb6bc896199..4c825e1236017e65079cd4ff53365fbcfe25d6b2 100644 (file)
@@ -11,7 +11,7 @@ MINOR_VERSION=6
 MICRO_VERSION=0
 INTERFACE_AGE=0
 BINARY_AGE=0
-EXTRA_VERSION=69
+EXTRA_VERSION=70
 EXTRA_RELEASE=
 EXTRA_GTK2_VERSION=
 
index 764ba2c7029b22381df9d121c9a0c07648ed4f03..31588729d991e749ede1dac15ec09c1cfc38778c 100644 (file)
 
 static guint my_id;
 
-static gchar* vcard_file_chooser(MenuItem* item) {
+static gchar* vcard_file_chooser(MenuItem* item, int mode) {
        GtkWidget* dialog;
        gchar* filename = NULL;
                
        dialog = gtk_file_chooser_dialog_new(_("Open file"),
                                              GTK_WINDOW(item->mainwindow->window),
-                                             GTK_FILE_CHOOSER_ACTION_OPEN,
+                                             mode,
                                              GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                                              GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
                                              NULL);
        gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), get_home());
-/*     gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter);
-       gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE);*/
+/*     gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter);*/
+       if (mode == GTK_FILE_CHOOSER_ACTION_SAVE)
+               gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE);
        
        if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
                filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
@@ -97,20 +98,30 @@ static void vcard_import(GtkWidget* widget, gpointer data) {
        gint count = 0, total = 0;
        gchar* leftover;
        FILE* f = NULL;
+       GtkTreeIter* iter = NULL;
+       GtkTreeSelection* row;
+       GtkTreeView* view;
 
-       abook = get_selected_address_book(GTK_TREE_VIEW(item->mainwindow->abook_list));
-       plugin = get_selected_plugin(GTK_TREE_VIEW(item->mainwindow->abook_list));
-       
-       if (!abook && !plugin) {
-               show_message(item->mainwindow->window, GTK_UTIL_MESSAGE_ERROR,
-                       _("Missing address book"));
-               return;
+       view = GTK_TREE_VIEW(item->mainwindow->abook_list);
+       abook = get_selected_address_book(view);
+       if (abook == NULL) {
+               iter = set_selection_combobox(item->mainwindow->window,
+                                               _("[New Contact] Choose address book"),
+                                               gtk_tree_view_get_model(view),
+                                               BOOK_NAME_COLUMN);
+               if (! iter)
+                       return;
+
+               row = gtk_tree_view_get_selection(view);
+               gtk_tree_selection_select_iter(row, iter);
+               g_free(iter);
        }
+       plugin = get_selected_plugin(GTK_TREE_VIEW(item->mainwindow->abook_list));
        
-       gchar* file = vcard_file_chooser(item);
+       gchar* file = vcard_file_chooser(item, GTK_FILE_CHOOSER_ACTION_OPEN);
        if (! file)
                return;
-       fp = fopen(file, "r");
+       fp = g_fopen(file, "r");
        if (! fp) {
                show_message(item->mainwindow->window, GTK_UTIL_MESSAGE_ERROR, strerror(errno));
                g_free(file);
@@ -165,24 +176,84 @@ static void vcard_import(GtkWidget* widget, gpointer data) {
 
 static void vcard_export(GtkWidget* widget, gpointer data) {
        MenuItem* item = (MenuItem *) data;
-       FILE* fp = fopen("/home/mir/CDCARDS/contacts.vcf", "r");
-       VObject *t, *v;
+       FILE* fp;
+       gchar* error = NULL;
+       VObject* o;
+       GSList *list, *cur;
+       AddressBook* abook;
+       Plugin* plugin;
+       gint count = 0;
+       GtkTreeIter* iter = NULL;
+       GtkTreeSelection* row;
+       GtkTreeView* view;
 
-       registerMimeErrorHandler(mime_error_handler, data);
-       v = Parse_MIME_FromFile(fp);
-       while (v) {
-               const gchar* name = vObjectName(v);
-           if (name && strcmp(name,VCCardProp) == 0) {
-                       t = v;
-                       printVObject(stderr, v);
+       view = GTK_TREE_VIEW(item->mainwindow->abook_list);
+       abook = get_selected_address_book(view);
+       if (abook == NULL) {
+               iter = set_selection_combobox(item->mainwindow->window,
+                                               _("[New Contact] Choose address book"),
+                                               gtk_tree_view_get_model(view),
+                                               BOOK_NAME_COLUMN);
+               if (! iter)
+                       return;
+
+               row = gtk_tree_view_get_selection(view);
+               gtk_tree_selection_select_iter(row, iter);
+               g_free(iter);
+       }
+       plugin = get_selected_plugin(GTK_TREE_VIEW(item->mainwindow->abook_list));
+       
+       if (!abook && !plugin) {
+               show_message(item->mainwindow->window, GTK_UTIL_MESSAGE_ERROR,
+                       _("Missing address book"));
+               return;
+       }
+
+       gchar* file = vcard_file_chooser(item, GTK_FILE_CHOOSER_ACTION_SAVE);
+       if (! file)
+               return;
+       fp = g_fopen(file, "w");
+       if (! fp) {
+               show_message(item->mainwindow->window, GTK_UTIL_MESSAGE_ERROR, strerror(errno));
+               g_free(file);
+               return;
+       }
+       g_free(file);
+
+       if (item->menu == CONTACTS_ADDRESSBOOK_MENU ||
+                       item->menu == CONTACTS_MAIN_MENU) {
+               list = contacts2vcard(abook->contacts, plugin, &error);
+               if (error) {
+                       show_message(item->mainwindow->window, GTK_UTIL_MESSAGE_ERROR, error);
                }
-               else
-                       mime_error_handler("Object is not in vCard format", data);
-               v = nextVObjectInList(v);
-               cleanVObject(t);
+               else {
+                       for (cur = list; cur; cur = g_slist_next(cur)) {
+                               count++;
+                               o = (VObject *) cur->data;
+                               writeVObject(fp, o);
+                               cleanVObject(o);
+                       }
+               }
+               gslist_free(&list, NULL);
+       }
+       else {
+               o = contact2vcard(item->mainwindow->selected_contact, plugin, &error);
+               if (error) {
+                       show_message(item->mainwindow->window, GTK_UTIL_MESSAGE_ERROR, error);
+               }
+               else {
+                       count++;
+                       writeVObject(fp, o);
+               }
+               cleanVObject(o);
        }
+       fclose(fp);
 
-       show_message(item->mainwindow->window, GTK_UTIL_MESSAGE_INFO, "test");
+       if (error)
+               g_free(error);
+       else
+               show_message(item->mainwindow->window, GTK_UTIL_MESSAGE_INFO,
+                       _("%s: Exported %d contacts"),  abook->abook_name, count);
 }
 
 static void setup(const MainWindow* mainwindow, gpointer object) {
@@ -257,6 +328,12 @@ gint extension_init(guint id) {
        gchar* error = NULL;
        
        register_hook_function(my_id, EXTENSION_AFTER_INIT_HOOK, setup, &error);
+       if (error) {
+               show_message(NULL, GTK_UTIL_MESSAGE_ERROR, error);
+               g_free(error);
+               return 1;
+       }
+
        return 0;
 }
 
index a0a89ad7c96612ebdd8f6299f54d716bca68b447..2a85e0c483434f291e5a2debe1b8e5015b0acec1 100644 (file)
@@ -58,10 +58,18 @@ enum {
 };
 
 static const gchar* phone[NUMTYPES][NUMPHONES] =
-               { 
-                       {"mobile", "homePhone", "telephoneNumber"}, /* LDAP */
-                       {"mobile phone", "phone", "office phone"}   /* XML  */
-               };
+       { 
+               {"mobile", "homePhone", "telephoneNumber"}, /* LDAP */
+               {"mobile phone", "phone", "office phone"}   /* XML  */
+       };
+
+static const gchar* phone_prop[NUMPHONES] =
+       { VCCellularProp, VCHomeProp, VCWorkProp };
+               
+struct _CBData {
+       VObject* o;
+       Plugin* p;
+} cb_data;
 
 static void strip_whitespace(gchar** s) {
        gchar *ptr, *token;
@@ -374,3 +382,125 @@ Contact* vcard2contact(VObject* vcard, Plugin* plugin, gchar** error) {
        
        return contact;
 }
+
+static void set_prop(VObject* o, Plugin* p, AttribType type, gchar* key, void* value) {
+       VObject* prop;
+       gchar* name = NULL;
+
+       if (strcasecmp("cn", key) == 0)
+               name = g_strdup(VCFullNameProp);
+       else if (strcasecmp("first-name", key) == 0)
+               name = g_strdup(VCGivenNameProp);
+       else if (strcasecmp("last-name", key) == 0)
+               name = g_strdup(VCFamilyNameProp);
+       else if (strcasecmp("nick-name", key) == 0)
+               name = g_strdup("NICKNAME");
+       else if (strcasecmp("image", key) == 0) {
+               name = g_strconcat(VCPhotoProp, ";", VCEncodingProp, "=", VCBase64Prop, NULL);
+       }
+       else {
+               int i, j;
+               for (i = NUMTYPES - 1; !name && i >= 0; i--) {
+                       for (j = NUMPHONES - 1; !name && j >= 0; j--) {
+                               if (strcasecmp(phone[i][j], key) == 0) {
+                                       name = g_strconcat(VCTelephoneProp, ";", phone_prop[j], NULL);
+                               }
+                       }
+               }
+       }
+       if (! name)
+               return;
+       
+       prop = newVObject(name);
+       g_free(name);
+       addVObjectProp(o, prop);
+       switch (type) {
+               case ATTRIB_TYPE_BOOLEAN:
+               case ATTRIB_TYPE_INT: {
+                       int i = *(gint *) value;
+                       setVObjectIntegerValue(prop, i);
+               }
+               case ATTRIB_TYPE_CHAR: {
+                       char c = *(char *) value;
+                       setVObjectStringZValue(prop, &c);
+               }
+               case ATTRIB_TYPE_STRING: {
+                       gchar* s = (gchar *) value;
+                       setVObjectStringZValue(prop, s);
+               }
+       }
+}
+
+static void hash_iter(gpointer k, gpointer v, gpointer u) {
+       gchar* key = (gchar *) k;
+       AttribDef* attr = (AttribDef *) v;
+       struct _CBData* cb_data = (struct _CBData *) u;
+       void* value;
+       
+       AttribType type = get_data(attr, &value);
+       set_prop(cb_data->o, cb_data->p, type, key, value);
+       g_free(value);
+/*     switch (type) {
+               case ATTRIB_TYPE_BOOLEAN:
+               case ATTRIB_TYPE_INT: {
+                       int i = *(gint *) value;
+                       prop = addProp(o, key);
+                       setVObjectIntegerValue(prop, i);
+               }
+               case ATTRIB_TYPE_CHAR: {
+                       char c = *(char *) value;
+                       prop = addProp(o, key);
+                       setVObjectStringZValue(prop, &c);
+               }
+               case ATTRIB_TYPE_STRING: {
+                       gchar* s = (gchar *) value;
+                       addPropValue(o, key, s);
+               }
+       }*/
+}
+
+static void slist_iter(gpointer d, gpointer u) {
+       Email* e = (Email *) d;
+       VObject* o = (VObject *) u;
+
+       addPropValue(o, VCEmailAddressProp, e->email);                  
+}
+
+GSList* contacts2vcard(GList* contacts, Plugin* plugin, gchar** error) {
+       GSList* vcards = NULL;
+       GList* cur;
+
+       cm_return_val_if_fail(plugin != NULL, NULL);
+       cm_return_val_if_fail(contacts != NULL, NULL);
+       
+       for (cur = contacts; cur; cur = g_list_next(cur)) {
+               Contact* c = (Contact *) cur->data;
+               if (c) {
+                       cb_data.o = newVObject(VCCardProp);
+                       cb_data.p = plugin;
+                       addPropValue(cb_data.o, VCVersionProp, "2.1");
+                       g_hash_table_foreach(c->data, hash_iter, &cb_data);
+                       g_slist_foreach(c->emails, slist_iter, cb_data.o);
+                       vcards = g_slist_prepend(vcards, cb_data.o);
+                       printVObject(stderr, cb_data.o);
+               }
+       }
+       
+       return vcards;
+}
+
+VObject* contact2vcard(Contact* contact, Plugin* plugin, gchar** error) {
+       VObject* o = NULL;
+       GList* list = NULL;
+       
+       cm_return_val_if_fail(plugin != NULL, NULL);
+       cm_return_val_if_fail(contact != NULL, NULL);
+
+       list = g_list_append(list, contact);
+       GSList* result = contacts2vcard(list, plugin, error);
+       glist_free(&list, NULL);
+       o = result->data;
+       gslist_free(&result, NULL);
+       
+       return o;
+}
index fdda27af2f43772a74bb36b57408cd8a6cad1102..ef155d6bac3116fa81b51ea72a6865190dffcba8 100644 (file)
@@ -42,6 +42,8 @@ G_BEGIN_DECLS
 #include "vobject.h"
 
 Contact* vcard2contact(VObject* vcard, Plugin* plugin, gchar** error);
+GSList* contacts2vcard(GList* contacts, Plugin* plugin, gchar** error);
+VObject* contact2vcard(Contact* contact, Plugin* plugin, gchar** error);
 
 G_END_DECLS