Re: Category support in adsressbook




----- Original Message -----
From: Matt Davey
Time: 10-01-07 15:52
>> The rest of the category syncing mainly is written in the 2 functions
>> "comp_from_remote_record" and "local_record_from_comp" . The code that's
>> written there for the category support can actually be the same for the
>> three conduits I think.  The code there is actually (almost) exact the
>> same for the todo and the memo's conduit. It differs a bit from the
>> calendar conduit as I made the sync only adapt the first category in
>> evolution if there is more than 1 assigned, thus keeping the evolution
>> structure more intact.
>>     
>
> Sounds good.  Presumably the other conduits should be modified to
> conform to this behaviour too.
>   
> [...]
> It's probably easier to move all the common code to the existing
> "e-util/e-pilot-util.c"
>
> Matt
>   
Okay,
So I've done this now.
All the common code for categories is now moved to
e-util/e-pilot-util.c, and all the conduits now use a few lines to make
category support possible. This means all the conduits now have the same
behavior, they only look to the first category assigned in evolution if
there are more, and leave the other untouched.
This patch needs to be applied after the pilot-link-0.12 patch, which is
here: http://bugzilla.gnome.org/show_bug.cgi?id=389664

Still I have 2 questions:
1) In the conduits there is a LOG function which is used quite a lot.
It's defined there as a macro. When moving some of the code to e-util I
did not know how to keep the logging possible there, so I just commented
it out, maybe somebody else has another solutions?
2) what do I do with this patch? Do I submit it as a bug in bugzilla, or
do I send it to the patch mailinglist from evolution?

Feel free to test it and report any problems.

Greetings,
Tom
--- evolution-2.8.2.1/e-util/e-pilot-util.c	2004-08-02 20:34:56.000000000 +0200
+++ edit/e-util/e-pilot-util.c	2007-01-16 09:38:15.000000000 +0100
@@ -25,6 +25,10 @@
 #include <time.h>
 #include <libxml/parser.h>
 #include <pi-util.h>
+#include <string.h>
+
+#include <libedataserver/e-categories.h>
+#include <pi-appinfo.h>
 
 #include "e-pilot-util.h"
 
@@ -105,3 +109,140 @@
 		e_source_set_property (source, "pilot-sync", "true");
 	e_source_list_sync (source_list, NULL);
 }
+
+/*
+ * Adds a category to the category app info structure (name and ID),
+ * sets category->renamed[i] to true if possible to rename.
+ * 
+ * This will be packed and written to the app info block during post_sync.
+ */
+int
+e_pilot_add_category_if_possible(char *cat_to_add, struct CategoryAppInfo *category)
+{
+	int i, j;
+	int retval = 0; /* 0 is the Unfiled category */
+	//LOG(g_message("e_pilot_add_category_if_possible\n"));
+	
+	for(i=0; i<PILOT_MAX_CATEGORIES; i++){
+		/* if strlen is 0, then the category is empty
+		   the PalmOS doesn't let 0-length strings for
+		   categories */
+		if(strlen(category->name[i]) == 0){
+			int cat_to_add_len;
+			
+			cat_to_add_len = strlen(cat_to_add);
+			retval = i;
+			
+			/* only 15 characters for category, 16th is
+			 * '\0' can't do direct mem transfer due to
+			 * declaration type
+			 */
+			for(j=0; j<cat_to_add_len; j++){
+				category->name[i][j] = cat_to_add[j];
+			}
+
+			for(j=cat_to_add_len; j<16; j++)
+				category->name[i][j] = '\0';
+			
+			//category->ID[i] = lastDesktopUniqueID;
+			//lastDesktopUniqueID++;
+			category->renamed[i] = TRUE;
+			
+			break;
+		}
+	}
+	
+	if(retval == 0){
+		//LOG(g_warning( _("*** not adding category - category list already full ***") ));
+	}
+	
+	return retval;
+}
+
+/*
+ *conversion from an evolution category to a palm category
+ */
+void e_pilot_local_category_to_remote(int * pilotCategory, ECalComponent *comp, struct CategoryAppInfo *category)
+{
+	GSList *c_list = NULL;
+	char * category_string;
+	int i;
+	e_cal_component_get_categories_list (comp, &c_list);
+	if (c_list) {
+		//list != 0, so at least 1 category is assigned
+		category_string = (char *) c_list->data;
+		if (c_list->next != 0) {
+			//LOG (g_message ("Note: item has more categories in evolution, first chosen"));
+		}
+		i=1;
+		while (1) {
+			if (strcmp(category_string,category->name[i]) == 0) {
+				*pilotCategory = i;
+				break;
+			}
+			i++;
+			if (i == PILOT_MAX_CATEGORIES) {
+				/*category not available on palm, try to create it*/
+				*pilotCategory = e_pilot_add_category_if_possible(category_string,category);
+				break;
+			}
+		}
+		e_cal_component_free_categories_list(c_list);
+		c_list = NULL;
+	} else {
+		*pilotCategory = 0;
+	}
+	/*end category*/
+}
+
+/*
+ *conversion from a palm category to an evolution category
+ */
+void e_pilot_remote_category_to_local(int pilotCategory, ECalComponent *comp, struct CategoryAppInfo *category)
+{
+	GSList *new_category = NULL;
+	GSList *c_list = NULL;
+	char *category_string;
+
+	/*Category*/
+	if (pilotCategory != 0) {
+		/*pda has category assigned*/
+		//LOG(g_message("Category: %s\n",categoryInfo.name[remote->category]));
+		new_category = g_slist_append(new_category, category->name[pilotCategory]); /*put the pda category on the first place*/
+		/* TODO The calendar editor page and search bar are not updated until a restart of the evolution client */
+		if(e_categories_exist(category->name[pilotCategory]) == FALSE){
+			/* add if it doesn't exist */
+			//LOG(g_message("Category created on pc\n"));
+			e_categories_add(category->name[pilotCategory], NULL, NULL, TRUE);
+		}
+	}
+		
+	/*Add the remaining categories already assigned on the pc*/
+	e_cal_component_get_categories_list (comp, &c_list);
+	if (c_list != 0) {
+		/*there were already categories assigned on the pc*/
+		category_string = (char *) c_list->data;
+		/*Only the first category on the pc is synced with palm, so we only replace this one with the one from the PDA
+		Note that this is NOT foolproof, but it will handle most situations*/
+		
+		/*now add the rest of the categories from the pc (if there are) */
+		c_list = c_list->next;
+		while (c_list != 0) {
+			category_string = (char *) c_list->data;
+			if (strcmp(category_string, category->name[pilotCategory]) != 0) {
+				/*different category from pda, so add it*/
+				new_category = g_slist_append(new_category, category_string);
+			}
+		c_list = c_list->next;
+		}
+	}
+	e_cal_component_free_categories_list(c_list);
+	/*store the data on pc*/
+	if (new_category == 0) {
+		e_cal_component_set_categories (comp, " "); /*note: this space is needed to make shure evolution clears the category*/
+	} 
+	else {
+		e_cal_component_set_categories_list (comp, new_category);
+	}
+	/*end category*/
+}
--- evolution-2.8.2.1/e-util/e-pilot-util.h	2004-08-02 20:34:56.000000000 +0200
+++ edit/e-util/e-pilot-util.h	2007-01-16 09:38:27.000000000 +0100
@@ -22,15 +22,24 @@
 
 #include <libedataserver/e-source-list.h>
 #include <libedataserver/e-source.h>
+#include <libedataserver/e-categories.h>
+#include <libecal/e-cal.h>
+#include <pi-appinfo.h>
 
 #ifndef E_PILOT_UTIL_H
 #define E_PILOT_UTIL_H
 
+#define PILOT_MAX_CATEGORIES 16
+
 char *e_pilot_utf8_to_pchar (const char *string);
 char *e_pilot_utf8_from_pchar (const char *string);
 
 ESource *e_pilot_get_sync_source (ESourceList *source_list);
 void e_pilot_set_sync_source (ESourceList *source_list, ESource *source);
 
+int e_pilot_add_category_if_possible(char *cat_to_add, struct CategoryAppInfo *category);
+void e_pilot_local_category_to_remote(int * pilotCategory, ECalComponent *comp, struct CategoryAppInfo *category);
+void e_pilot_remote_category_to_local(int   pilotCategory, ECalComponent *comp, struct CategoryAppInfo *category);
+
 
 #endif /* E_PILOT_UTIL_H */
--- patch/calendar/conduits/calendar/calendar-conduit.c	2007-01-13 12:40:19.000000000 +0100
+++ edit/calendar/conduits/calendar/calendar-conduit.c	2007-01-16 09:57:21.000000000 +0100
@@ -940,6 +940,9 @@
 		pi_buffer_free (record);
 #endif
 	}
+	
+	/*Category support*/
+	e_pilot_local_category_to_remote(&(local->local.category), comp, &(ctxt->ai.category));
 
 	/* STOP: don't replace these with g_strdup, since free_Appointment
 	   uses free to deallocate */
@@ -1185,7 +1188,8 @@
 			 GnomePilotRecord *remote,
 			 ECalComponent *in_comp,
 			 ECal *client,
-			 icaltimezone *timezone)
+			 icaltimezone *timezone,
+			 struct CategoryAppInfo *category)
 {
 	ECalComponent *comp;
 	struct Appointment appt;
@@ -1231,6 +1235,9 @@
 	summary.value = txt = e_pilot_utf8_from_pchar (appt.description);
 	e_cal_component_set_summary (comp, &summary);
 	free (txt);
+	
+	/*Category support*/
+	e_pilot_remote_category_to_local(remote->category, comp, category);
 
 	/* The iCal description field */
 	if (!appt.note) {
@@ -1623,6 +1630,7 @@
 	pi_buffer_free(buffer);
 #endif
 	unpack_AppointmentAppInfo (&(ctxt->ai), buf, len);
+	//unpack_CategoryAppInfo (&(ctxt->ai.category), buf, len);
 	g_free (buf);
 
 	check_for_slow_setting (conduit, ctxt);
@@ -1640,8 +1648,28 @@
 {
 	GList *changed;
 	gchar *filename, *change_id;
+	unsigned char *buf;
+	int dlpRetVal, len;
 	
 	LOG (g_message ( "post_sync: Calendar Conduit v.%s", CONDUIT_VERSION ));
+	
+	/* Write AppBlock to PDA - updates categories */
+	buf = (unsigned char*)g_malloc (0xffff);
+	
+	len = pack_AppointmentAppInfo (&(ctxt->ai), buf, 0xffff);
+	
+	dlpRetVal = dlp_WriteAppBlock (dbi->pilot_socket, dbi->db_handle, 
+			      (unsigned char *)buf, len);
+	
+	g_free (buf);
+			      
+	if (dlpRetVal < 0) {
+		WARN (_("Could not write pilot's Calendar application block"));
+		WARN ("dlp_WriteAppBlock(...) = %d", dlpRetVal);
+		gnome_pilot_conduit_error (conduit,
+					   _("Could not write pilot's Calendar application block"));
+		return -1;
+	}
 
 	g_free (ctxt->cfg->last_uri);
 	ctxt->cfg->last_uri = g_strdup (e_cal_get_uri (ctxt->client));
@@ -1839,7 +1867,7 @@
 
 	LOG (g_message ( "add_record: adding %s to desktop\n", print_remote (remote) ));
 
-	comp = comp_from_remote_record (conduit, remote, ctxt->default_comp, ctxt->client, ctxt->timezone);
+	comp = comp_from_remote_record (conduit, remote, ctxt->default_comp, ctxt->client, ctxt->timezone, &(ctxt->ai.category));
 
 	/* Give it a new UID otherwise it will be the uid of the default comp */
 	uid = e_cal_component_gen_uid ();
@@ -1871,7 +1899,7 @@
 	LOG (g_message ("replace_record: replace %s with %s\n",
 			print_local (local), print_remote (remote)));
 
-	new_comp = comp_from_remote_record (conduit, remote, local->comp, ctxt->client, ctxt->timezone);
+	new_comp = comp_from_remote_record (conduit, remote, local->comp, ctxt->client, ctxt->timezone, &(ctxt->ai.category));
 	g_object_unref (local->comp);
 	local->comp = new_comp;
 
--- patch/calendar/conduits/memo/memo-conduit.c	2007-01-13 12:40:19.000000000 +0100
+++ edit/calendar/conduits/memo/memo-conduit.c	2007-01-16 10:13:37.000000000 +0100
@@ -506,70 +506,6 @@
 }
 
 /*
- * Adds a category to the category app info structure (name and ID),
- * sets category->renamed[i] to true if possible to rename.
- * 
- * This will be packed and written to the app info block during post_sync.
- */
- 
-static int
-add_category_if_possible(char *cat_to_add, struct CategoryAppInfo *category)
-{
-	int i, j;
-	int retval = 0; /* 0 is the Unfiled category */
-	LOG(fprintf(stderr, "add_category_if_possible: called\n"));
-	
-	for(i=0; i<16; i++){
-		/* if strlen is 0, then the category is empty
-		   the PalmOS doesn't let 0-length strings for
-		   categories */
-		LOG(fprintf(stderr, "add_category_if_possible: calling strlen, i==%d\n", i));
-		if(strlen(category->name[i]) == 0){
-			int cat_to_add_len;
-			LOG(fprintf(stderr, "add_category_if_possible: strlen == 0\n"));
-			
-			cat_to_add_len = strlen(cat_to_add);
-			LOG(fprintf(stderr, "add_category_if_possible: cat_to_add_len: %d\n",
-					cat_to_add_len));
-			retval = i;
-			
-			/* only 15 characters for category, 16th is
-			 * '\0' can't do direct mem transfer due to
-			 * declaration type
-			 */
-			LOG(fprintf(stderr, "add_category_if_possible: copying first 15 of category\n"));
-			for(j=0; j<cat_to_add_len; j++){
-				category->name[i][j] = cat_to_add[j];
-			}
-			LOG(fprintf(stderr,
-				"add_category_if_possible: setting from %d to i==15 to \\0\n",
-				cat_to_add_len));
-
-			for(j=cat_to_add_len; j<16; j++)
-				category->name[i][j] = '\0';
-			
-			LOG(fprintf(stderr, "add_category_if_possible: setting ID[%d] to %d\n",
-				category->ID[i], lastDesktopUniqueID));
-			category->ID[i] = lastDesktopUniqueID;
-			lastDesktopUniqueID++;
-			
-			LOG(fprintf(stderr, "add_category_if_possible: setting renamed[%d] to TRUE\n", i));
-			category->renamed[i] = TRUE;
-			
-			LOG(g_message("*** adding category '%s', ID %d ***",
-				category->name[i], category->ID[i]));
-			break;
-		}
-	}
-	
-	if(retval == 0){
-		LOG(g_message("*** not adding category - category list already full ***"));
-	}
-	
-	return retval;
-}
-
-/*
  * converts a ECalComponent object to a EMemoLocalRecord
  */
 static void
@@ -640,51 +576,8 @@
 		LOG(fprintf(stderr, "local_record_from_comp: done calling dlp_ReadRecordById\n"));
 	}
 	
-	/*
-	 * Grab category from existing category list in ctxt->ai.category
-	 */
-	if(local->local.category == 0){
-		GSList *categ_list_head, *categ_list_cur;
-		int cat = -1;
-		int i;
-		
-		LOG(fprintf(stderr, "local_record_from_comp: trying to set category"));
-		LOG(fprintf(stderr, "local_record_from_comp: calling e_cal_component_get_categories_list\n"));
-		
-		e_cal_component_get_categories_list(comp, &categ_list_head);
-		LOG(fprintf(stderr, "local_record_from_comp: got list, setting categ_list_cur to head\n"));
-		
-		categ_list_cur = categ_list_head;
-		while (categ_list_cur && cat == -1)
-		{	
-			LOG(fprintf(stderr, "local_record_from_comp: iterating, data == %s",
-				(char *)categ_list_cur->data));
-			for(i=0; i<16; i++){
-				LOG(fprintf(stderr, "local_record_from_comp: i == %d\n", i));
-				if(strcmp((char *)categ_list_cur->data,
-					  ctxt->ai.category.name[i]) == 0){
-					cat = i;
-					LOG(fprintf(stderr, "local_record_from_comp: found category, name: %s\n",
-							ctxt->ai.category.name[i]));
-					break;
-				}
-			}
-			
-			LOG(fprintf(stderr, "local_record_from_comp: calling g_slist_next\n"));
-			categ_list_cur = g_slist_next(categ_list_cur);
-		}
-		
-		if(cat != -1){
-			LOG(fprintf(stderr, "local_record_from_comp: setting category\n"));
-			local->local.category = cat;
-		}
-		else if(categ_list_head != NULL){
-			local->local.category =
-				add_category_if_possible(
-					(char *)(categ_list_head->data),
-					&(ctxt->ai.category));
-		}
-	}
+	/*Category support*/
+	e_pilot_local_category_to_remote(&(local->local.category), comp, &(ctxt->ai.category));
 
 	/* STOP: don't replace these with g_strdup, since free_Memo
 	   uses free to deallocate */
@@ -799,6 +692,9 @@
 
 	e_cal_component_set_last_modified (comp, &now);
 	
+	/*Category support*/
+	e_pilot_remote_category_to_local(remote->category, comp, &(ai->category));
+	
 	/* The iCal description field */
 	if (!memo.text) {
 		e_cal_component_set_comment_list (comp, NULL);
@@ -853,19 +749,6 @@
 		e_cal_component_set_classification (comp, E_CAL_COMPONENT_CLASS_PRIVATE);
 	else
 		e_cal_component_set_classification (comp, E_CAL_COMPONENT_CLASS_PUBLIC);
-	
-	
-	/* set the category properly */
-	category = ai->category.name[remote->category];
-	
-	/* TODO The Memos editor page and search bar are not updated until
-	  a restart of the evolution client */
-	if(e_categories_exist(category) == FALSE){
-		/* add if it doesn't exist */
-		e_categories_add(category, NULL, NULL, TRUE);
-	}
-	
-	e_cal_component_set_categories(comp, category);
 
 	e_cal_component_commit_sequence (comp);
 	
--- patch/calendar/conduits/todo/todo-conduit.c	2007-01-13 12:40:19.000000000 +0100
+++ edit/calendar/conduits/todo/todo-conduit.c	2007-01-16 13:49:09.000000000 +0100
@@ -648,55 +648,6 @@
 }
 
 /*
- * Adds a category to the category app info structure (name and ID),
- * sets category->renamed[i] to true if possible to rename.
- * 
- * This will be packed and written to the app info block during post_sync.
- */
- 
-static int
-add_category_if_possible(char *cat_to_add, struct CategoryAppInfo *category)
-{
-	int i, j;
-	int retval = 0; // 0 is the Unfiled category
-	
-	for(i=0; i<16; i++){
-		// if strlen is 0, then the category is empty
-		// the PalmOS doesn't let 0-length strings for
-		// categories
-		if(strlen(category->name[i]) == 0){
-			int cat_to_add_len = strlen(cat_to_add);
-			retval = i;
-			
-			/* only 15 characters for category, 16th is
-			 * '\0' can't do direct mem transfer due to
-			 * declaration type
-			 */
-			for(j=0; j<cat_to_add_len; j++)
-				category->name[i][j] = cat_to_add[j];
-
-			for(j=cat_to_add_len; j<16; j++)
-				category->name[i][j] = '\0';
-			
-			category->ID[i] = lastDesktopUniqueID;
-			lastDesktopUniqueID++;
-			
-			category->renamed[i] = TRUE;
-			
-			LOG(g_message("*** adding category '%s', ID %d ***",
-				category->name[i], category->ID[i]));
-			break;
-		}
-	}
-	
-	if(retval == 0){
-		LOG(g_message("*** not adding category - category list already full ***"));
-	}
-	
-	return retval;
-}
-
-/*
  * converts a ECalComponent object to a EToDoLocalRecord
  */
 static void
@@ -757,42 +708,8 @@
 #endif
 	}
 	
-	/*
-	 * Grab category from existing category list in ctxt->ai.category
-	 */
-	if(local->local.category == 0){
-		GSList *categ_list_head, *categ_list_cur;
-		int cat = -1;
-		int i;
-		
-		e_cal_component_get_categories_list(comp, &categ_list_head);
-		
-		categ_list_cur = categ_list_head;
-		while (categ_list_cur && cat == -1)
-		{	
-			for(i=0; i<16; i++){
-				if(strcmp((char *)categ_list_cur->data,
-					  ctxt->ai.category.name[i]) == 0){
-					cat = i;
-					break;
-				}
-			}
-			
-			categ_list_cur = g_slist_next(categ_list_cur);
-		}
-		
-		if(cat != -1){
-			local->local.category = cat;
-		}
-		else{
-			if(categ_list_head != NULL){
-				local->local.category =
-					add_category_if_possible(
-						(char *)(categ_list_head->data),
-						&(ctxt->ai.category));
-			}
-		}
-	}
+	/*Category support*/
+	e_pilot_local_category_to_remote(&(local->local.category), comp, &(ctxt->ai.category));
 
 	/* STOP: don't replace these with g_strdup, since free_ToDo
 	   uses free to deallocate */
@@ -951,6 +868,9 @@
 	e_cal_component_set_summary (comp, &summary);
 	free (txt);
 	
+	/*Category support*/
+	e_pilot_remote_category_to_local(remote->category, comp, &(ai->category));
+	
 	/* The iCal description field */
 	if (!todo.note) {
 		e_cal_component_set_comment_list (comp, NULL);
@@ -1022,20 +942,6 @@
 		e_cal_component_set_classification (comp, E_CAL_COMPONENT_CLASS_PRIVATE);
 	else
 		e_cal_component_set_classification (comp, E_CAL_COMPONENT_CLASS_PUBLIC);
-	
-	
-	// set the category properly
-	category = ai->category.name[remote->category];
-	
-	
-	// TODO The Tasks editor page and search bar are not updated until
-	// a restart of the evolution client
-	if(e_categories_exist(category) == FALSE){
-		// add if it doesn't exist
-		e_categories_add(category, NULL, NULL, TRUE);
-	}
-	
-	e_cal_component_set_categories(comp, category);
 
 	e_cal_component_commit_sequence (comp);
 	


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]