[Commits] callbacks.c 1.10 1.11 contactwindow.c 1.7 1.8 printing.c 1.3 1.4 utils.c 1.6 1.7 utils.h 1.6 1.7

miras at claws-mail.org miras at claws-mail.org
Mon Nov 28 08:34:52 CET 2011


Update of /home/claws-mail/contacts/src
In directory claws-mail:/tmp/cvs-serv28372/src

Modified Files:
	callbacks.c contactwindow.c printing.c utils.c utils.h 
Log Message:
2011-11-28 [mir]	0.6.0cvs28

	* plugins/ldap/ldap-plugin.c
	* src/callbacks.c
	* src/contactwindow.c
	* src/printing.c
	* src/utils.c
	* src/utils.h
	    -Fix lots of bugs
	    -Improfements
	    -Refactoring
	    -And last: Complete LDAP plugin with full support
	     for write/update. Testing is adviceable. 

Index: contactwindow.c
===================================================================
RCS file: /home/claws-mail/contacts/src/contactwindow.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- contactwindow.c	26 Nov 2011 03:09:29 -0000	1.7
+++ contactwindow.c	28 Nov 2011 07:34:50 -0000	1.8
@@ -78,7 +78,7 @@
 	GtkWidget*			image;
 	ContactEntryData**	data;
 	gboolean			new_row;
-	gboolean			image_email_dirty;
+	gboolean			email_dirty;
 } ContactWindow;
 
 static gint contact_entry_data_size = 0;
@@ -87,16 +87,6 @@
 static void email_list_add(GtkTreeView* view, ContactWindow* cw);
 static gchar* hash_table_get_entry(GHashTable* hash, const gchar* key);
 
-/*
-static void contact_entry_data_update(ContactWindow* cw) {
-	gint i;
-
-	for (i = 0; i < contact_entry_data_size; i++) {
-		ContactEntryData* d = cw->data[i];
-		d->contact = cw->contact;
-	}
-}
-*/
 static void contact_entry_data_free(ContactEntryData** data) {
 	gint i;
 
@@ -128,10 +118,20 @@
 	gboolean result = FALSE;
 	gint i;
 	ContactEntryData** data = cw->data;
+	gchar *cur_image, *old_image;
 
-	if (cw->image_email_dirty)
+	if (cw->email_dirty)
 		return TRUE;
 	
+	if (cw->old) {
+		extract_data(cw->contact->data, "image", (gpointer) &cur_image);
+		extract_data(cw->old->data, "image", (gpointer) &old_image);
+		if (utf8_collate(cur_image, old_image) != 0)
+			result = TRUE;
+		g_free(cur_image);
+		g_free(old_image);
+	}
+
 	for (i = 0; !result && i < contact_entry_data_size; i++) {
 		Contact* contact = data[i]->contact;
 		if (contact && contact->data && data[i]->key && data[i]->entry) {
@@ -140,7 +140,7 @@
 			result = entry_dirty(contact->data, data[i]->key, new_data);
 		}
 	}
-
+	
 	return result;
 }
 
@@ -159,11 +159,10 @@
 			show_message(cw->window, GTK_UTIL_MESSAGE_WARNING, "%s", err);
 			g_free(err);
 			err = NULL;
-			contact_free(contact);
-			g_free(contact);
 		}
 		else {
-			cw->image_email_dirty = FALSE;
+			cw->email_dirty = FALSE;
+			//gslist_free(&cw->changed_emails, NULL);
 			if (contact_is_new) {
 				if (debug_get_mode()) {
 					contact_dump(contact, stderr);
@@ -180,6 +179,9 @@
 				}
 			}
 			else {
+				if (debug_get_mode()) {
+					contact_dump(contact, stderr);
+				}
 				row = gtk_tree_view_get_selection(
 						GTK_TREE_VIEW(cw->main->contact_list));
 				if (row) {
@@ -191,6 +193,7 @@
 				if (cw->old) {
 					contact_free(cw->old);
 					g_free(cw->old);
+					cw->old = NULL;
 				}
 			}
 		}
@@ -212,9 +215,10 @@
 	gboolean bool;
 	gchar ch;
 	gint num;
-    GtkTreeModel* model;
+	gchar *cur_image, *old_image;
+/*    GtkTreeModel* model;
     GtkTreeIter iter;
-    GSList* new_list = NULL;
+    GSList* new_list = NULL;*/
 	
 	contact = cw->contact;
 		
@@ -256,20 +260,29 @@
 		}
 	}
 
-	if (cw->image_email_dirty) {
+	if (cw->old) {
+		extract_data(cw->contact->data, "image", (gpointer) &cur_image);
+		extract_data(cw->old->data, "image", (gpointer) &old_image);
+		if (utf8_collate(cur_image, old_image) != 0)
+			changed = TRUE;
+		g_free(cur_image);
+		g_free(old_image);
+	}
+
+	if (cw->email_dirty)
 		changed = TRUE;
-	    model = gtk_tree_view_get_model(GTK_TREE_VIEW(cw->email_list));
+/*	    model = gtk_tree_view_get_model(GTK_TREE_VIEW(cw->email_list));
 	 	if (gtk_tree_model_get_iter_first(model, &iter)) {
 			do {
 				Email* a = g_new0(Email, 1);
 				gtk_tree_model_get(model, &iter, WINDOW_ALIAS, &a->alias,
 					WINDOW_EMAIL, &a->email, WINDOW_REMARKS, &a->remarks, -1);
-				new_list = g_slist_prepend(new_list, a);
+				new_list = g_slist_append(new_list, a);
 			} while (gtk_tree_model_iter_next(model, &iter));
 			gslist_free(&cw->contact->emails, email_free);
 			cw->contact->emails = new_list;
 		}
-	}
+	}*/
 	if (changed)
 		contact_update(cw, cw->contact);
 }
@@ -297,6 +310,7 @@
 
 	gtk_widget_destroy(cw->window);
 	g_free(cw);
+	cw = NULL;
 	
     return FALSE;
 }
@@ -380,7 +394,7 @@
 				email->remarks = gtk_editable_get_chars(GTK_EDITABLE(remark), 0, -1);
 				contact->emails = g_slist_append(contact->emails, email);
 				cw->new_row = TRUE;
-				cw->image_email_dirty = TRUE;
+				cw->email_dirty = TRUE;
 				list_view_append_email(GTK_TREE_VIEW(cw->email_list), email);
 			}
 			else
@@ -398,8 +412,6 @@
     GtkTreeModel* model;
     GtkTreeSelection* row;
     gchar *alias = NULL, *email = NULL, *remark = NULL;
-    GSList* cur;
-    Email* remove = NULL;
 
 	row = gtk_tree_view_get_selection(GTK_TREE_VIEW(cw->email_list));
 	model = gtk_tree_view_get_model(GTK_TREE_VIEW(cw->email_list));
@@ -410,23 +422,12 @@
 			WINDOW_EMAIL, &email,
 			WINDOW_REMARKS, &remark,
 			-1);
-			for (cur = cw->contact->emails; cur;
-					remove = NULL, cur = g_slist_next(cur)) {
-				remove = (Email *) cur->data;
-				if (!xor(remove->alias, alias) &&
-					!xor(remove->email, email) &&
-					!xor(remove->remarks, remark))
-					break;
-			}
-			if (remove) {
+			if (email) {
 				gboolean r = show_question(cw->window,
-					_("%s: Delete contact?"), remove->email);
+					_("%s: Delete email address?"), email);
 				if (r) {
-					cw->contact->emails =
-						g_slist_remove(cw->contact->emails, remove);
-					email_list_add(GTK_TREE_VIEW(cw->email_list), cw);
-					email_free(remove);
-					cw->image_email_dirty = TRUE;
+					gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
+					cw->email_dirty = TRUE;
 				}
 			}
 		}
@@ -466,13 +467,15 @@
 	}
 }
 
-static void contact_set_attr(Contact* contact,
+static void contact_set_attr(ContactWindow* cw,
 							 guint row,
 							 WindowColumn column,
 							 const gchar* value) {
 	Email* mail;
+	Contact* contact = cw->contact;
 	
 	mail = (Email *) g_slist_nth_data(contact->emails, row);
+	
 	switch (column) {
 		case WINDOW_ALIAS:
 			g_free(mail->alias);
@@ -548,6 +551,8 @@
 	gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter);
 	gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), FALSE);
 	home = cw->plugin->default_url(NULL);
+	if (! home)
+		home = get_self_home();
 	gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), home);
 	g_free(home);
 	
@@ -561,16 +566,12 @@
 			gchar* image = base64_encode_data(file);
 			swap_data(cw->contact->data, "image", image);
 			g_free(image);
-			GtkWidget* parent = gtk_widget_get_parent(cw->image);
-			gtk_widget_destroy(cw->image);
-			cw->image = gtk_image_new_from_pixbuf(pixbuf);
-			gtk_widget_show(cw->image);
-			gtk_container_add(GTK_CONTAINER(parent), cw->image);
+			gtk_image_clear(GTK_IMAGE(cw->image));
+			gtk_image_set_from_pixbuf(GTK_IMAGE(cw->image), pixbuf);
 			g_object_unref(pixbuf);
 		}
 		
 		g_free(file);
-		cw->image_email_dirty = TRUE;
 	}
 
 	gtk_widget_destroy(dialog);
@@ -621,10 +622,10 @@
 	}
 
 	if (! contact_is_new) {
-		contact_set_attr(win->contact, atoi(path_string), col, new_text);
+		contact_set_attr(win, atoi(path_string), col, new_text);
 	}
 	
-	win->image_email_dirty = TRUE;
+	win->email_dirty = TRUE;
 	gtk_list_store_set(GTK_LIST_STORE(model), &iter, col, new_text, -1);
 }
 
@@ -743,6 +744,7 @@
 
 static GdkPixbuf* contact_load_image(GtkWidget* parent, gchar* photo) {
 	GdkPixbufLoader* pl;
+	GdkPixbuf* pixbuf;
 	GError *err = NULL;
 	guchar* image_buf;
 	gsize length; 
@@ -750,6 +752,7 @@
 	image_buf = g_base64_decode(photo, &length);
 	
 	pl = gdk_pixbuf_loader_new();
+	gdk_pixbuf_loader_set_size(pl, PHOTO_WIDTH, PHOTO_HEIGHT); 
 	gdk_pixbuf_loader_write(pl, image_buf, length, &err); 
 	g_free(image_buf);
 
@@ -758,10 +761,12 @@
 		g_clear_error(&err); 
 		return NULL; 
 	} 
-	gdk_pixbuf_loader_set_size(pl, PHOTO_WIDTH, PHOTO_HEIGHT); 
 	gdk_pixbuf_loader_close(pl, NULL);
 	
-	return gdk_pixbuf_loader_get_pixbuf(pl); 
+	pixbuf = gdk_pixbuf_copy(gdk_pixbuf_loader_get_pixbuf(pl)); 
+	g_object_unref(pl);
+	
+	return pixbuf;
 }
 
 static gboolean contact_reorder_emails(GtkTreeModel *model,
@@ -799,7 +804,7 @@
 	gslist_free(&cw->contact->emails, email_free);
 	cw->contact->emails = NULL;
 	gtk_tree_model_foreach(tree_model, contact_reorder_emails, cw);
-	cw->image_email_dirty = TRUE;
+	cw->email_dirty = TRUE;
 }
 
 static void contact_widget(ContactWindow* cw) {
@@ -1061,6 +1066,7 @@
 	dialog = g_new0(ContactWindow, 1);
 	dialog->main = main;
 	dialog->old = contact;
+	//dialog->changed_emails = NULL;
 	dialog->contact = contact_copy(contact);
 	dialog->new_row = FALSE;
 	

Index: callbacks.c
===================================================================
RCS file: /home/claws-mail/contacts/src/callbacks.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- callbacks.c	26 Nov 2011 03:06:19 -0000	1.10
+++ callbacks.c	28 Nov 2011 07:34:50 -0000	1.11
@@ -506,9 +506,10 @@
 	gchar* error = NULL;
 	
 	if (! plugin->readonly) {
-		abook->contacts = g_list_remove(abook->contacts, old);
-		if (! plugin->update_contact(abook, new, &error))
+		if (! plugin->update_contact(abook, new, &error)) {
+			abook->contacts = g_list_remove(abook->contacts, old);
 			abook->contacts = g_list_prepend(abook->contacts, new);
+		}
 	}
 	else {
 		error = g_strdup(_("Plugin does not support updates"));

Index: printing.c
===================================================================
RCS file: /home/claws-mail/contacts/src/printing.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- printing.c	4 Oct 2011 20:21:40 -0000	1.3
+++ printing.c	28 Nov 2011 07:34:50 -0000	1.4
@@ -90,7 +90,7 @@
 	g_free(val);
 	
 	if (strcmp(k, "uid") != 0 && strcmp(k, "image") != 0 &&
-				strlen(k) > 0 && strlen(v) > 0) {
+			strcmp(k, "dn") != 0 &&	strlen(k) > 0 && strlen(v) > 0) {
 		pd->lines[pd->total_lines++] = g_strdup_printf("%s: %s", k, v);
 		pd->lines = g_renew(gchar *, pd->lines, pd->total_lines + 1);
 		pd->lines[pd->total_lines] = NULL;

Index: utils.c
===================================================================
RCS file: /home/claws-mail/contacts/src/utils.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- utils.c	20 Nov 2011 21:24:20 -0000	1.6
+++ utils.c	28 Nov 2011 07:34:50 -0000	1.7
@@ -648,24 +648,18 @@
 }
 
 gchar** gslist_to_array(const GSList* list, gint* len) {
-	GString* buf;
 	GSList* cur;
-	gchar** array;
-	int num;
+	gchar **array = NULL, *str;
+	int num = 0;
 
-	buf = g_string_new("");
-	for (cur = (GSList *) list, num = 0;	cur; cur = g_slist_next(cur), num++) {
-		gchar* elem = (gchar *) cur->data;
-		buf = g_string_append(buf, elem);
-		buf = g_string_append(buf, "|");
-	}
-	gchar* str = g_string_free(buf, FALSE);
-	gchar* tmp = str;
-	if (strlen(str) > 0 && str[strlen(str) - 1] == '|') {
-		tmp[strlen(tmp) - 1] = 0;
+	for (cur = (GSList *) list; cur; cur = g_slist_next(cur), num++) {
+		str = (gchar *) cur->data;
+		array = g_renew(gchar *, array, num + 1);
+		array[num] = g_memdup(str, strlen(str) + 1);
 	}
-	array = g_strsplit_set(tmp, "|", 0);
-	g_free(str);
+
+	array = g_renew(gchar *, array, num + 1);
+	array[num] = NULL;
 	
 	if (len)
 		*len = num;
@@ -776,10 +770,41 @@
 }
 */
 
+gboolean compare_attrib(const AttribDef* a, const AttribDef* b, gint type) {
+	gboolean result;
+	gint res;
+	AttribType ctype;
+	
+	if (type >= 0)
+		ctype = type;
+	else
+		ctype = a->type;
+		
+	if (a->type != ctype || b->type != ctype)
+		return FALSE;
+
+	switch (ctype) {
+		case ATTRIB_TYPE_BOOLEAN:
+			result = a->value.boolean == b->value.boolean;
+			break;
+		case ATTRIB_TYPE_INT:
+			result = a->value.number == b->value.number;
+			break;
+		case ATTRIB_TYPE_CHAR:
+			result = a->value.character == b->value.character;
+			break;
+		case ATTRIB_TYPE_STRING:
+			res = g_utf8_collate(a->value.string, b->value.string);
+			result = (res == 0);
+	}
+	
+	return result;
+}
+
 gboolean contact_compare_attrib(Contact* a, Contact* b, const AttribDef* compare) {
 	gboolean result = FALSE;
 	AttribDef *a_id, *b_id;
-	gint res;
+	//gint res;
 	
 	if (!a || !a->data || !b || !b->data || !compare || !compare->attrib_name)
 		return result;
@@ -788,7 +813,8 @@
 	b_id = (AttribDef *) g_hash_table_lookup(b->data, compare->attrib_name);
 	if (!a_id || !b_id)
 		return result;
-	
+
+/*	
 	switch (compare->type) {
 		case ATTRIB_TYPE_BOOLEAN:
 			result = a_id->value.boolean == b_id->value.boolean;
@@ -803,7 +829,9 @@
 			res = g_utf8_collate(a_id->value.string, b_id->value.string);
 			result = (res == 0);
 	}
-	
+*/
+	result = compare_attrib(a_id, b_id, compare->type);
+		
 	return result;
 }
 
@@ -867,7 +895,7 @@
 		if (a) {
 			Email* b = email_copy(a);
 			if (b)
-				new->emails = g_slist_prepend(new->emails, b);
+				new->emails = g_slist_append(new->emails, b);
 		}
 	}
 	
@@ -986,8 +1014,8 @@
 }
 
 gchar* base64_encode_data(const gchar* path) {
-	gchar *contents;
-	gchar *base64;
+	gchar* contents;
+	gchar* base64;
 	gsize length;
 	
 	g_file_get_contents(path, &contents, &length, NULL);
@@ -996,7 +1024,23 @@
 	
 	return base64;
 }
-
+/*
+gchar* base64_encode_pixbuf(GdkPixbuf* pixbuf) {
+	int width, n_channels, bits_per_sample;
+	guchar* pixels;
+	gchar* base64;
+	gsize length;
+	
+	n_channels = gdk_pixbuf_get_n_channels(pixbuf);
+	width = gdk_pixbuf_get_width(pixbuf);
+	pixels = gdk_pixbuf_get_pixels(pixbuf);
+	bits_per_sample = gdk_pixbuf_get_bits_per_sample(pixbuf);
+	length = width * ((n_channels * bits_per_sample + 7) / 8);
+	base64 = g_base64_encode(pixels, length);
+	
+	return base64;
+}
+*/
 guint set_log_handler() {
 	guint id;
 	
@@ -1070,12 +1114,16 @@
 gint utf8_collate(gchar* s1, gchar* s2) {
     gchar *a, *b;
     gint ret;
-    
-    if (!s1)
-        return 1;
-    if (!s2)
-        return -1;
-
+ 
+	if (! s1 && ! s2)
+		return 0;
+		
+	if (! s1 && s2)
+		return 1;
+		
+	if (s1 && ! s2)
+		return -1;
+   
     debug_print("s1: %s s2: %s\n", s1, s2);
     a = g_utf8_collate_key(s1, -1);
     b = g_utf8_collate_key(s2, -1);
@@ -1175,6 +1223,8 @@
 	if (attr) {
 		get_data(attr, value);
 	}
+	else
+		*value = NULL;
 }
 
 void swap_data(GHashTable* data, const gchar* key, void* value) {
@@ -1317,7 +1367,7 @@
 	return index;
 }
 
-#define KEY "This is abook I1"
+#define AES_KEY "This is abook I1"
 static gboolean aes_init(gcry_cipher_hd_t* digest) {
     gcry_error_t err = 0;
     const gchar iv[] = "AbC1234567890xYz";
@@ -1330,7 +1380,7 @@
     	return FALSE;
     }
 
-	err = gcry_cipher_setkey(*digest, KEY, strlen(KEY));
+	err = gcry_cipher_setkey(*digest, AES_KEY, strlen(AES_KEY));
     if (err) {
         g_printerr("%s\n", gcry_strerror(err));
     	gcry_cipher_close(*digest);
@@ -1440,7 +1490,7 @@
 	return hex;
 }
 
-#define key "claws-mail address book"
+#define SHA_KEY "claws-mail address book"
 gchar* sha256(const gchar* plain) {
     gcry_error_t err = 0;
     gcry_md_hd_t digest = NULL;
@@ -1458,7 +1508,7 @@
         gcry_md_close(digest);
     }
 
-    err = gcry_md_setkey(digest, key, strlen(key));
+    err = gcry_md_setkey(digest, SHA_KEY, strlen(SHA_KEY));
     if (err) {
         g_printerr("%s\n", gcry_strerror(err));
         gcry_md_close(digest);
@@ -1745,23 +1795,23 @@
 	return equal;
 }
 
-void contact_compare_values(gpointer k, gpointer v, gpointer data) {
+void contact_compare_values(gpointer key, gpointer value, gpointer data) {
 	Compare* comp = (Compare *) data;
 	AttribDef *attr;
 	const gchar* term;
 	
-	term = ((AttribDef *) v)->value.string;
+	term = ((AttribDef *) value)->value.string;
 	
 	if (debug_get_mode()) {
 		Contact* c = g_new0(Contact, 1);
 		c->data = comp->hash;
 		contact_dump(c, stderr);
-		fprintf(stderr, "Key: %s - Value: %s\n", (gchar *) k, term);
+		fprintf(stderr, "Key: %s - Value: %s\n", (gchar *) key, term);
 		g_free(c);
 	}
 	if ((comp->is_and && comp->equal) ||
 		(!comp->is_and && (comp->equal < 0 || comp->equal == 0))) {
-		attr = g_hash_table_lookup(comp->hash, k);
+		attr = g_hash_table_lookup(comp->hash, key);
 		if (attr) {
 			if (attr->type == ATTRIB_TYPE_STRING) {
 				comp->equal = match_string_pattern(
@@ -1786,3 +1836,192 @@
 	else
 		comp->equal = FALSE;
 }
+
+gchar* create_dummy_dn(const gchar* baseDN) {
+	GTimeVal timeval;
+	GRand* rand;
+	gchar *dn = NULL, *tmp;
+
+	g_get_current_time(&timeval);
+	tmp = g_time_val_to_iso8601(&timeval);
+	rand = g_rand_new();
+	guint32 num = g_rand_int(rand);
+	g_rand_free(rand);
+	gchar* plain = g_strdup_printf("%s %d", tmp, num);
+	g_free(tmp);
+	tmp = sha256(plain);
+	g_free(plain);
+	if (baseDN)
+		dn = g_strconcat("mail=", tmp, ",", baseDN, NULL);
+	else
+		dn = g_strdup(tmp);
+	g_free(tmp);
+	
+	return dn;
+}
+
+gboolean email_equal(Email* a, Email* b) {
+	if (! a && ! b)
+		return TRUE;
+		
+	if ((! a && b) || (a && ! b))
+		return FALSE;
+	
+	if (utf8_collate(a->alias, b->alias) == 0 &&
+		utf8_collate(a->email, b->email) == 0 &&
+		utf8_collate(a->remarks, b->remarks) == 0)
+		return TRUE;
+
+	return FALSE;
+}
+/*
+static gint diff_list_find(gconstpointer a, gconstpointer b) {
+	ContactChange* c = (ContactChange *) a;
+	Email* e = (Email *) b;
+	
+	if (c->type == CONTACT_CHANGE_ATTRIB) {
+		AttribDef* attr = (AttribDef *) c->value;
+		return utf8_collate(e->email, attr->value.string);
+	}
+	else if (c->type == CONTACT_CHANGE_EMAIL) {
+		Email* e1 = (Email *) c->value;
+		return utf8_collate(e->email, e1->email);
+	}
+	
+	return 0;
+}
+*/
+GSList* contact_diff(Contact* a, Contact* b) {
+	GSList* diff = NULL;
+	GHashTableIter iter;
+	gpointer key1, key2, val1, val2;
+	ContactChange* c;
+	GSList /**emaila, *emailb, *cura, *curb*/ *cur;
+	
+	g_hash_table_iter_init(&iter, a->data);
+	while (g_hash_table_iter_next(&iter, &key1, &val1)) {
+		AttribDef* attr1 = (AttribDef *) val1;
+    	if (g_hash_table_lookup_extended(b->data, key1, &key2, &val2)) {
+			AttribDef* attr2 = (AttribDef *) val2;
+			if (! compare_attrib(attr1, attr2, -1)) {
+				c = g_new0(ContactChange, 1);
+				c->action = ATTRIBUTE_MODIFY;
+				c->type = CONTACT_CHANGE_ATTRIB;
+				c->key = g_strdup((gchar *) key2);
+				c->value = (gpointer) attrib_def_copy(attr2);
+				diff = g_slist_prepend(diff, c);
+			}
+		}
+		else {
+			c = g_new0(ContactChange, 1);
+			c->action = ATTRIBUTE_DELETE;
+			c->type = CONTACT_CHANGE_ATTRIB;
+			c->key = g_strdup((gchar *) key1);
+			c->value = (gpointer) attrib_def_copy(attr1);
+			diff = g_slist_prepend(diff, c);
+		}
+	}
+
+	g_hash_table_iter_init(&iter, b->data);
+	while (g_hash_table_iter_next(&iter, &key1, &val1)) {
+		AttribDef* attr1 = (AttribDef *) val1;
+    	if (! g_hash_table_lookup_extended(a->data, key1, &key2, &val2)) {
+			c = g_new0(ContactChange, 1);
+			c->action = ATTRIBUTE_ADD;
+			c->type = CONTACT_CHANGE_ATTRIB;
+			c->key = g_strdup((gchar *) key1);
+			c->value = (gpointer) attrib_def_copy(attr1);
+			diff = g_slist_prepend(diff, c);
+		}
+	}
+	
+	//emaila = g_slist_sort(a->emails, email_sort);
+	//emailb = g_slist_sort(b->emails, email_sort);
+	
+	//cura = a->emails/*emaila*/;
+	cur = b->emails/*emailb*/;
+	while (cur/*a && curb*/) {
+		//if (! email_equal(cura->data, curb->data)) {
+			c = g_new0(ContactChange, 1);
+			c->action = ATTRIBUTE_MODIFY;
+			c->type = CONTACT_CHANGE_EMAIL;
+			c->key = g_strdup(((Email *) cur->data)->email);
+			c->value = (gpointer) email_copy(cur->data);
+			diff = g_slist_prepend(diff, c);
+		//}
+		cur = cur->next;
+		//curb = curb->next;
+	}
+/*	while (cura) {
+		if (! g_slist_find_custom(diff,	(Email *) cura->data, diff_list_find)) {
+			c = g_new0(ContactChange, 1);
+			c->action = ATTRIBUTE_DELETE;
+			c->type = CONTACT_CHANGE_EMAIL;
+			c->key = g_strdup(((Email *) cura->data)->email);
+			c->value = (gpointer) email_copy(cura->data);
+			diff = g_slist_prepend(diff, c);
+		}
+		cura = cura->next;
+	}	
+	while (curb) {
+		if (! g_slist_find_custom(diff,	(Email *) curb->data, diff_list_find)) {
+			c = g_new0(ContactChange, 1);
+			c->action = ATTRIBUTE_ADD;
+			c->type = CONTACT_CHANGE_EMAIL;
+			c->key = g_strdup(((Email *) curb->data)->email);
+			c->value = (gpointer) email_copy(curb->data);
+			diff = g_slist_prepend(diff, c);
+		}
+		curb = curb->next;
+	}*/
+		
+	//gslist_free(&emaila, NULL);
+	//gslist_free(&emailb, NULL);
+
+	return diff;
+}
+
+void contact_change_free(gpointer contact_change) {
+	ContactChange* c;
+	
+	if (! contact_change)
+		return;
+		
+	c = (ContactChange *) contact_change;
+	g_free(c->key);
+	c->key = NULL;
+	if (c->type == CONTACT_CHANGE_ATTRIB) {
+		attrib_def_free(c->value);
+	}
+	else if (c->type == CONTACT_CHANGE_EMAIL) {
+		email_free(c->value);
+	}
+	c->value = NULL;
+	g_free(c);
+	c = NULL;
+}
+
+gint email_sort(gconstpointer a, gconstpointer b) {
+	gint res;
+	const Email *a1, *b1;
+	
+	if (! a && ! b)
+		return 0;
+		
+	if (! a && b)
+		return 1;
+		
+	if (a && ! b)
+		return -1;
+	
+	a1 = (Email *) a;
+	b1 = (Email *) b;
+	
+	if ((res = utf8_collate(a1->email, b1->email)) == 0) {
+		if ((res = utf8_collate(a1->alias, b1->alias)) == 0) {
+			return utf8_collate(a1->remarks, b1->remarks);
+		}
+	}
+		
+	return res;
+}
\ No newline at end of file

Index: utils.h
===================================================================
RCS file: /home/claws-mail/contacts/src/utils.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- utils.h	20 Nov 2011 21:24:20 -0000	1.6
+++ utils.h	28 Nov 2011 07:34:50 -0000	1.7
@@ -68,6 +68,24 @@
 	gint		equal;
 } Compare;
 
+typedef enum {
+	ATTRIBUTE_DELETE,
+	ATTRIBUTE_MODIFY,
+	ATTRIBUTE_ADD
+} AttributeAction;
+
+typedef enum {
+	CONTACT_CHANGE_ATTRIB,
+	CONTACT_CHANGE_EMAIL
+} ContactChangeType;
+
+typedef struct {
+	AttributeAction		action;
+	ContactChangeType	type;
+	gchar*				key;
+	gpointer			value;
+} ContactChange;
+	
 void debug_print_real(const gchar *format, ...);
 const char* debug_srcname(const char *file);
 gboolean debug_get_mode();
@@ -108,10 +126,13 @@
 Contact* contact_new();
 void contact_data_print(gpointer key, gpointer value, gpointer data);
 //gboolean contact_compare(Contact* a, Contact* b, gboolean is_and);
+GSList* contact_diff(Contact* a, Contact* b);
 gboolean contact_compare_attrib(Contact* a, Contact* b, const AttribDef* compare);
+gboolean compare_attrib(const AttribDef* a, const AttribDef* b, gint type);
 void contact_free(gpointer contact);
 void contact_dump(Contact* contact, FILE* f);
-//gboolean email_compare(gpointer comparedata, GSList* a, GSList* b);
+gboolean email_equal(Email* a, Email* b);
+gint email_sort(gconstpointer a, gconstpointer b);
 void email_free(gpointer email);
 Email* email_copy(Email* email);
 void email_dump(Email* email, FILE* f);
@@ -124,6 +145,7 @@
 gint address_book_compare(gconstpointer a, gconstpointer b);
 gboolean xor(const gchar* a, const gchar* b);
 gchar* base64_encode_data(const gchar* path);
+//gchar* base64_encode_pixbuf(GdkPixbuf* pixbuf);
 guint set_log_handler();
 gint utf8_collate(gchar* s1, gchar* s2);
 gboolean attribute_supported(Plugin* plugin, const gchar* attribute);
@@ -141,8 +163,10 @@
 GSList* find_name(GtkContainer* container, const gchar* name);
 GSList* get_basic_attributes(Contact* contact);
 gboolean match_string_pattern(const gchar* pattern, const gchar* haystack, gboolean case_aware);
-void contact_compare_values(gpointer ckey, gpointer value, gpointer data);
+void contact_compare_values(gpointer key, gpointer value, gpointer data);
 gboolean email_compare_values(GSList* a, GSList* b, gboolean is_and);
+gchar* create_dummy_dn(const gchar* baseDN);
+void contact_change_free(gpointer contact_change);
 
 G_END_DECLS
 



More information about the Commits mailing list