Task UID



Hi all,

I'm working on adding a unique id to the tasks (bug # 318480).  Attached
is the first draft for your perusal.

It creates a 'uid' attribute for each task and successfully saves it to
the xml file without changing it each time the project is modified and
saved again.  The xml for a task looks like this:

<task id="1" uid="3" name="blah" note="" work="28800"
start="20090908T000000Z" end="20090908T170000Z"
work-start="20090908T080000Z" percent-complete="0" priority="0"
type="normal" scheduling="fixed-work"/>

The uid is unique and constant for each task within a project (but no
attempt is made to make it universally unique).  They're assigned
sequentially as tasks are created (or as they're loaded from a previous
version file where uid is missing).

Maurice - In this patch, I started addressing some compile warnings as
well, specifically for mrp-parser.  I think maybe I should break them
out as a separate patch so as not to muddy the water on this one.

Also curious if you have an opinion as to how to handle patches gong
forward.  I was thinking it might be a good idea to set up a personal
repo on GitHub and host my work there... might be easier than creating
and sending patches via the list, no?



-- 
Kurt Maute <kurt maute us>
diff --git a/data/dtd/Makefile.am b/data/dtd/Makefile.am
index 16ac2ab..cc61dbd 100644
--- a/data/dtd/Makefile.am
+++ b/data/dtd/Makefile.am
@@ -2,7 +2,8 @@ dtddir = $(datadir)/planner/dtd
 
 dtd_DATA = \
 	mrproject-0.5.1.dtd				\
-	mrproject-0.6.dtd
+	mrproject-0.6.dtd					\
+	mrproject-0.7.dtd
 
 EXTRA_DIST = $(dtd_DATA)
 
diff --git a/libplanner/mrp-old-xml.c b/libplanner/mrp-old-xml.c
index 2703a9a..006c5e4 100644
--- a/libplanner/mrp-old-xml.c
+++ b/libplanner/mrp-old-xml.c
@@ -209,6 +209,7 @@ old_xml_read_task (MrpParser *parser, xmlNodePtr tree, MrpTask *parent)
 	xmlNodePtr     child;
 	gchar          *name;
 	gint           id;
+	gint           uid;
 	mrptime        start = 0, end = 0;
 	MrpTask       *task;
 	MrpConstraint  constraint;
@@ -228,6 +229,7 @@ old_xml_read_task (MrpParser *parser, xmlNodePtr tree, MrpTask *parent)
 	name = old_xml_get_string (tree, "name");
 	note = old_xml_get_string (tree, "note");
 	id = old_xml_get_int (tree, "id");
+	uid = old_xml_get_int (tree, "uid");
 	percent_complete = old_xml_get_int (tree, "percent-complete");
 	priority = old_xml_get_int (tree, "priority");
 	type = old_xml_get_task_type (tree, "type");
@@ -250,6 +252,7 @@ old_xml_read_task (MrpParser *parser, xmlNodePtr tree, MrpTask *parent)
 
 		task = g_object_new (MRP_TYPE_TASK,
 				     "project", parser->project,
+             "uid", uid,
 				     "name", name,
 				     "duration", duration,
 				     "percent_complete", percent_complete,
@@ -282,6 +285,7 @@ old_xml_read_task (MrpParser *parser, xmlNodePtr tree, MrpTask *parent)
 
 		task = g_object_new (MRP_TYPE_TASK,
 				     "project", parser->project,
+             "uid", uid,
 				     "name", name,
 				     "sched", sched,
 				     "type", type,
diff --git a/libplanner/mrp-parser.c b/libplanner/mrp-parser.c
index 8548623..1d70e9b 100644
--- a/libplanner/mrp-parser.c
+++ b/libplanner/mrp-parser.c
@@ -119,10 +119,10 @@ mpp_write_project_properties (MrpParser *parser, xmlNodePtr node)
 		      "phase", &phase,
 		      NULL);
 
-	xmlSetProp (node, "name", name);
-	xmlSetProp (node, "company", org);
-	xmlSetProp (node, "manager", manager);
-	xmlSetProp (node, "phase", phase);
+	xmlSetProp (node, (unsigned char*)"name", (unsigned char*)name);
+	xmlSetProp (node, (unsigned char*)"company", (unsigned char*)org);
+	xmlSetProp (node, (unsigned char*)"manager", (unsigned char*)manager);
+	xmlSetProp (node, (unsigned char*)"phase", (unsigned char*)phase);
 
 	mpp_xml_set_date (node, "project-start", pstart);
 	mpp_xml_set_int (node, "mrproject-version", 2);
@@ -233,21 +233,21 @@ mpp_write_property_specs (MrpParser *parser, xmlNodePtr node)
 	properties = mrp_project_get_properties_from_type (parser->project,
 							   MRP_TYPE_PROJECT);
 
-	node = xmlNewChild (node, NULL, "properties", NULL);
+	node = xmlNewChild (node, NULL, (unsigned char*)"properties", NULL);
 
 	for (l = properties; l; l = l->next) {
 		property = l->data;
 
-		child = xmlNewChild (node, NULL, "property", NULL);
+		child = xmlNewChild (node, NULL, (unsigned char*)"property", NULL);
 
-		xmlSetProp (child, "name", mrp_property_get_name (property));
+		xmlSetProp (child, (unsigned char*)"name", (unsigned char*)mrp_property_get_name (property));
 
 		type = mrp_property_get_property_type (property);
-		xmlSetProp (child, "type", mpp_property_type_to_string (type));
+		xmlSetProp (child, (unsigned char*)"type", (unsigned char*)mpp_property_type_to_string (type));
 
-		xmlSetProp (child, "owner", "project");
-		xmlSetProp (child, "label", mrp_property_get_label (property));
-		xmlSetProp (child, "description", mrp_property_get_description (property));
+		xmlSetProp (child, (unsigned char*)"owner", (unsigned char*)"project");
+		xmlSetProp (child, (unsigned char*)"label", (unsigned char*)mrp_property_get_label (property));
+		xmlSetProp (child, (unsigned char*)"description", (unsigned char*)mrp_property_get_description (property));
 	}
 
 	g_list_free (properties);
@@ -258,16 +258,16 @@ mpp_write_property_specs (MrpParser *parser, xmlNodePtr node)
 	for (l = properties; l; l = l->next) {
 		property = l->data;
 
-		child = xmlNewChild (node, NULL, "property", NULL);
+		child = xmlNewChild (node, NULL, (unsigned char*)"property", NULL);
 
-		xmlSetProp (child, "name", mrp_property_get_name (property));
+		xmlSetProp (child, (unsigned char*)"name", (unsigned char*)mrp_property_get_name (property));
 
 		type = mrp_property_get_property_type (property);
-		xmlSetProp (child, "type", mpp_property_type_to_string (type));
+		xmlSetProp (child, (unsigned char*)"type", (unsigned char*)mpp_property_type_to_string (type));
 
-		xmlSetProp (child, "owner", "task");
-		xmlSetProp (child, "label", mrp_property_get_label (property));
-		xmlSetProp (child, "description", mrp_property_get_description (property));
+		xmlSetProp (child, (unsigned char*)"owner", (unsigned char*)"task");
+		xmlSetProp (child, (unsigned char*)"label", (unsigned char*)mrp_property_get_label (property));
+		xmlSetProp (child, (unsigned char*)"description", (unsigned char*)mrp_property_get_description (property));
 	}
 
 	g_list_free (properties);
@@ -278,16 +278,16 @@ mpp_write_property_specs (MrpParser *parser, xmlNodePtr node)
 	for (l = properties; l; l = l->next) {
 		property = l->data;
 
-		child = xmlNewChild (node, NULL, "property", NULL);
+		child = xmlNewChild (node, NULL, (unsigned char*)"property", NULL);
 
-		xmlSetProp (child, "name", mrp_property_get_name (property));
+		xmlSetProp (child, (unsigned char*)"name", (unsigned char*)mrp_property_get_name (property));
 
 		type = mrp_property_get_property_type (property);
-		xmlSetProp (child, "type", mpp_property_type_to_string (type));
+		xmlSetProp (child, (unsigned char*)"type", (unsigned char*)mpp_property_type_to_string (type));
 
-		xmlSetProp (child, "owner", "resource");
-		xmlSetProp (child, "label", mrp_property_get_label (property));
-		xmlSetProp (child, "description", mrp_property_get_description (property));
+		xmlSetProp (child, (unsigned char*)"owner", (unsigned char*)"resource");
+		xmlSetProp (child, (unsigned char*)"label", (unsigned char*)mrp_property_get_label (property));
+		xmlSetProp (child, (unsigned char*)"description", (unsigned char*)mrp_property_get_description (property));
 	}
 
 	g_list_free (properties);
@@ -301,12 +301,12 @@ mpp_write_phases (MrpParser *parser, xmlNodePtr node)
 
 	g_object_get (parser->project, "phases", &phases, NULL);
 
-	node = xmlNewChild (node, NULL, "phases", NULL);
+	node = xmlNewChild (node, NULL, (unsigned char*)"phases", NULL);
 
 	for (l = phases; l; l = l->next) {
-		child = xmlNewChild (node, NULL, "phase", NULL);
+		child = xmlNewChild (node, NULL, (unsigned char*)"phase", NULL);
 
-		xmlSetProp (child, "name", l->data);
+		xmlSetProp (child, (unsigned char*)"name", (unsigned char*)l->data);
 	}
 
 	mrp_string_list_free (phases);
@@ -321,9 +321,9 @@ mpp_write_predecessor (MrpParser   *parser,
 	NodeEntry *entry;
 	gint       lag;
 
-	node = xmlNewChild (node, NULL, "predecessor", NULL);
+	node = xmlNewChild (node, NULL, (unsigned char*)"predecessor", NULL);
 
-	xmlSetProp (node, "id", "1"); /* Don't need id here. */
+	xmlSetProp (node, (unsigned char*)"id", (unsigned char*)"1"); /* Don't need id here. */
 
 	entry = g_hash_table_lookup (parser->task_hash,
 				     mrp_relation_get_predecessor (relation));
@@ -346,7 +346,7 @@ mpp_write_predecessor (MrpParser   *parser,
 		str = "FS";
 	}
 
-	xmlSetProp (node, "type", str);
+	xmlSetProp (node, (unsigned char*)"type", (unsigned char*)str);
 
 	lag = mrp_relation_get_lag (relation);
 	if (lag) {
@@ -383,7 +383,7 @@ mpp_write_constraint (xmlNodePtr node, MrpConstraint *constraint)
 		return;
 	}
 
-	child = xmlNewChild (node, NULL, "constraint", NULL);
+	child = xmlNewChild (node, NULL, (unsigned char*)"constraint", NULL);
 
 	switch (constraint->type) {
 	case MRP_CONSTRAINT_MSO:
@@ -401,7 +401,7 @@ mpp_write_constraint (xmlNodePtr node, MrpConstraint *constraint)
 		break;
 	}
 
-	xmlSetProp (child, "type", str);
+	xmlSetProp (child, (unsigned char*)"type", (unsigned char*)str);
 	mpp_xml_set_date (child, "time", constraint->time);
 }
 
@@ -423,8 +423,8 @@ mpp_write_string_list (xmlNodePtr   node,
 	for (i = 0; i < array->n_values; i++) {
 		value = g_value_array_get_nth (array, i);
 
-		child = xmlNewChild (node, NULL, "list-item", NULL);
-		xmlSetProp (child, "value", g_value_get_string (value));
+		child = xmlNewChild (node, NULL, (unsigned char*)"list-item", NULL);
+		xmlSetProp (child, (unsigned char*)"value", (unsigned char*)g_value_get_string (value));
 	}
 
 	g_value_array_free (array);
@@ -447,21 +447,21 @@ mpp_write_custom_properties (MrpParser  *parser,
 		return;
 	}
 
-	node = xmlNewChild (node, NULL, "properties", NULL);
+	node = xmlNewChild (node, NULL, (unsigned char*)"properties", NULL);
 
 	for (l = properties; l; l = l->next) {
 		property = l->data;
 
-		child = xmlNewChild (node, NULL, "property", NULL);
+		child = xmlNewChild (node, NULL, (unsigned char*)"property", NULL);
 
-		xmlSetProp (child, "name", mrp_property_get_name (property));
+		xmlSetProp (child, (unsigned char*)"name", (unsigned char*)mrp_property_get_name (property));
 
 		if (mrp_property_get_property_type (property) == MRP_PROPERTY_TYPE_STRING_LIST) {
 			mpp_write_string_list (child, property, object);
 		} else {
 			value = mpp_property_to_string (object, property);
 
-			xmlSetProp (child, "value", value);
+			xmlSetProp (child, (unsigned char*)"value", (unsigned char*)value);
 
 			g_free (value);
 		}
@@ -484,6 +484,7 @@ mpp_write_task_cb (MrpTask *task, MrpParser *parser)
 	gint           work;
 	gint           complete;
 	gint           priority;
+	gint           uid;
 	MrpTaskType    type;
 	MrpTaskSched   sched;
 	GList         *predecessors, *l;
@@ -498,12 +499,13 @@ mpp_write_task_cb (MrpTask *task, MrpParser *parser)
 	entry = g_hash_table_lookup (parser->task_hash, parent);
 	parent_node = entry->node;
 
-	node = xmlNewChild (parent_node, NULL, "task", NULL);
+	node = xmlNewChild (parent_node, NULL, (unsigned char*)"task", NULL);
 
 	entry = g_hash_table_lookup (parser->task_hash, task);
 	entry->node = node;
 
 	g_object_get (task,
+          "uid", &uid,
 		      "name", &name,
 		      "note", &note,
 		      "start", &start,
@@ -526,8 +528,9 @@ mpp_write_task_cb (MrpTask *task, MrpParser *parser)
 	}
 
 	mpp_xml_set_int (node, "id", entry->id);
-	xmlSetProp (node, "name", name);
-	xmlSetProp (node, "note", note);
+	mpp_xml_set_int (node, "uid", uid);
+	xmlSetProp (node, (unsigned char*)"name", (unsigned char*)name);
+	xmlSetProp (node, (unsigned char*)"note", (unsigned char*)note);
 	mpp_xml_set_int (node, "work", work);
 
 	if (sched == MRP_TASK_SCHED_FIXED_DURATION) {
@@ -550,7 +553,7 @@ mpp_write_task_cb (MrpTask *task, MrpParser *parser)
 
 	predecessors = mrp_task_get_predecessor_relations (task);
 	if (predecessors != NULL) {
-		node = xmlNewChild (node, NULL, "predecessors", NULL);
+		node = xmlNewChild (node, NULL, (unsigned char*)"predecessors", NULL);
 		for (l = predecessors; l; l = l->next) {
 			mpp_write_predecessor (parser, node, l->data);
 		}
@@ -585,7 +588,7 @@ mpp_write_group (MrpParser *parser, xmlNodePtr parent, MrpGroup *group)
 
 	node = xmlNewChild (parent,
                             NULL,
-			    "group",
+			    (unsigned char*)"group",
 			    NULL);
 
 	entry = g_hash_table_lookup (parser->group_hash, group);
@@ -600,10 +603,10 @@ mpp_write_group (MrpParser *parser, xmlNodePtr parent, MrpGroup *group)
 		      "manager-email", &admin_email,
 		      NULL);
 
-	xmlSetProp (node, "name", name);
-	xmlSetProp (node, "admin-name", admin_name);
-	xmlSetProp (node, "admin-phone", admin_phone);
-	xmlSetProp (node, "admin-email", admin_email);
+	xmlSetProp (node, (unsigned char*)"name", (unsigned char*)name);
+	xmlSetProp (node, (unsigned char*)"admin-name", (unsigned char*)admin_name);
+	xmlSetProp (node, (unsigned char*)"admin-phone", (unsigned char*)admin_phone);
+	xmlSetProp (node, (unsigned char*)"admin-email", (unsigned char*)admin_email);
 
 	g_free (name);
 	g_free (admin_name);
@@ -642,7 +645,7 @@ mpp_write_resource (MrpParser   *parser,
 
 	node = xmlNewChild (parent,
                             NULL,
-			    "resource",
+			    (unsigned char*)"resource",
 			    NULL);
 
 	mrp_object_get (MRP_OBJECT (resource),
@@ -668,15 +671,15 @@ mpp_write_resource (MrpParser   *parser,
 	resource_entry = g_hash_table_lookup (parser->resource_hash, resource);
 	mpp_xml_set_int (node, "id", resource_entry->id);
 
-	xmlSetProp (node, "name", name);
-	xmlSetProp (node, "short-name", short_name);
+	xmlSetProp (node, (unsigned char*)"name", (unsigned char*)name);
+	xmlSetProp (node, (unsigned char*)"short-name", (unsigned char*)short_name);
 
 	mpp_xml_set_int (node, "type", type);
 
 	mpp_xml_set_int (node, "units", units);
-	xmlSetProp (node, "email", email);
+	xmlSetProp (node, (unsigned char*)"email", (unsigned char*)email);
 
-	xmlSetProp (node, "note", note);
+	xmlSetProp (node, (unsigned char*)"note", (unsigned char*)note);
 
 	mpp_xml_set_float (node, "std-rate", std_rate);
 	/*mpp_xml_set_float (node, "ovt-rate", ovt_rate);*/
@@ -715,7 +718,7 @@ mpp_write_assignment (MrpParser     *parser,
 
 	node = xmlNewChild (parent,
                             NULL,
-			    "allocation",
+			    (unsigned char*)"allocation",
 			    NULL);
 
 	g_object_get (assignment,
@@ -739,16 +742,16 @@ mpp_write_interval (xmlNodePtr parent, MrpInterval *interval)
 	mrptime     start, end;
 	gchar      *str;
 
-	child = xmlNewChild (parent, NULL, "interval", NULL);
+	child = xmlNewChild (parent, NULL, (unsigned char*)"interval", NULL);
 
 	mrp_interval_get_absolute (interval, 0, &start, &end);
 
 	str = mrp_time_format ("%H%M", start);
-	xmlSetProp (child, "start", str);
+	xmlSetProp (child, (unsigned char*)"start", (unsigned char*)str);
 	g_free (str);
 
 	str = mrp_time_format ("%H%M", end);
-	xmlSetProp (child, "end", str);
+	xmlSetProp (child, (unsigned char*)"end", (unsigned char*)str);
 	g_free (str);
 }
 
@@ -760,7 +763,7 @@ mpp_write_day (MrpParser *parser, xmlNodePtr parent, MrpDay *day)
 
 	g_return_if_fail (day != NULL);
 
-	node = xmlNewChild (parent, NULL, "day-type", NULL);
+	node = xmlNewChild (parent, NULL, (unsigned char*)"day-type", NULL);
 
 	day_entry = g_new0 (NodeEntry, 1);
 	if (day == mrp_day_get_work ()) {
@@ -778,8 +781,8 @@ mpp_write_day (MrpParser *parser, xmlNodePtr parent, MrpDay *day)
 	g_hash_table_insert (parser->day_hash, day, day_entry);
 
 	mpp_xml_set_int (node, "id", day_entry->id);
-	xmlSetProp (node, "name", mrp_day_get_name (day));
-	xmlSetProp (node, "description", mrp_day_get_description (day));
+	xmlSetProp (node, (unsigned char*)"name", (unsigned char*)mrp_day_get_name (day));
+	xmlSetProp (node, (unsigned char*)"description", (unsigned char*)mrp_day_get_description (day));
 }
 
 static void
@@ -813,7 +816,7 @@ mpp_write_overridden_day (MrpParser           *parser,
 
 	entry = g_hash_table_lookup (parser->day_hash, di->day);
 	if (entry) {
-		child = xmlNewChild (parent, NULL, "overridden-day-type", NULL);
+		child = xmlNewChild (parent, NULL, (unsigned char*)"overridden-day-type", NULL);
 		mpp_xml_set_int (child, "id", entry->id);
 
 		for (l = di->intervals; l; l = l->next) {
@@ -835,13 +838,13 @@ mpp_write_overridden_date (MrpParser      *parser,
 
 	entry = g_hash_table_lookup (parser->day_hash, dd->day);
 	if (entry) {
-		child = xmlNewChild (parent, NULL, "day", NULL);
+		child = xmlNewChild (parent, NULL, (unsigned char*)"day", NULL);
 
 		str = mrp_time_format ("%Y%m%d", dd->date);
-		xmlSetProp (child, "date", str);
+		xmlSetProp (child, (unsigned char*)"date", (unsigned char*)str);
 		g_free (str);
 
-		xmlSetProp (child, "type", "day-type");
+		xmlSetProp (child, (unsigned char*)"type", (unsigned char*)"day-type");
  		mpp_xml_set_int (child, "id", entry->id);
 	}
 
@@ -859,7 +862,7 @@ mpp_write_calendar (MrpParser   *parser,
 
 	g_return_if_fail (MRP_IS_CALENDAR (calendar));
 
-	node = xmlNewChild (parent, NULL, "calendar", NULL);
+	node = xmlNewChild (parent, NULL, (unsigned char*)"calendar", NULL);
 
 	id = parser->next_calendar_id++;
 	mpp_xml_set_int (node, "id", id);
@@ -868,10 +871,10 @@ mpp_write_calendar (MrpParser   *parser,
 			     calendar,
 			     GINT_TO_POINTER (id));
 
-	xmlSetProp (node, "name", mrp_calendar_get_name (calendar));
+	xmlSetProp (node, (unsigned char*)"name", (unsigned char*)mrp_calendar_get_name (calendar));
 
 	/* Write the default week */
-	child = xmlNewChild (node, NULL, "default-week", NULL);
+	child = xmlNewChild (node, NULL, (unsigned char*)"default-week", NULL);
 
 	mpp_write_default_day (parser, child, calendar,
 			       "mon", MRP_CALENDAR_DAY_MON);
@@ -889,7 +892,7 @@ mpp_write_calendar (MrpParser   *parser,
 			       "sun", MRP_CALENDAR_DAY_SUN);
 
 	/* Override days */
-	child = xmlNewChild (node, NULL, "overridden-day-types", NULL);
+	child = xmlNewChild (node, NULL, (unsigned char*)"overridden-day-types", NULL);
 	days = mrp_calendar_get_overridden_days (calendar);
 
 	for (l = days; l; l = l->next) {
@@ -900,7 +903,7 @@ mpp_write_calendar (MrpParser   *parser,
 	g_list_free (days);
 
 	/* Write the overriden dates */
-	child = xmlNewChild (node, NULL, "days", NULL);
+	child = xmlNewChild (node, NULL, (unsigned char*)"days", NULL);
 	dates = mrp_calendar_get_all_overridden_dates (calendar);
 	for (l = dates; l; l = l->next) {
 		MrpDateWithDay *date_day = l->data;
@@ -927,7 +930,7 @@ mpp_write_project (MrpParser *parser)
 	NodeEntry   *entry;
 	MrpCalendar *root_calendar;
 
-	node = xmlNewDocNode (parser->doc, NULL, "project", NULL);
+	node = xmlNewDocNode (parser->doc, NULL, (unsigned char*)"project", NULL);
 	parser->doc->xmlRootNode = node;
 
 	mpp_write_property_specs (parser, node);
@@ -936,8 +939,8 @@ mpp_write_project (MrpParser *parser)
 	mpp_write_phases (parser, node);
 
 	/* Write calendars */
-	calendars_node = xmlNewChild (node, NULL, "calendars", NULL);
-	child = xmlNewChild (calendars_node, NULL, "day-types", NULL);
+	calendars_node = xmlNewChild (node, NULL, (unsigned char*)"calendars", NULL);
+	child = xmlNewChild (calendars_node, NULL, (unsigned char*)"day-types", NULL);
 
 	mpp_write_day (parser, child, mrp_day_get_work ());
 	mpp_write_day (parser, child, mrp_day_get_nonwork ());
@@ -958,7 +961,7 @@ mpp_write_project (MrpParser *parser)
 	mpp_write_project_properties (parser, node);
 
 	/* Write tasks. */
- 	child = xmlNewChild (node, NULL, "tasks",NULL);
+ 	child = xmlNewChild (node, NULL, (unsigned char*)"tasks",NULL);
 
 	entry = g_new0 (NodeEntry, 1);
 	entry->id = 0;
@@ -979,7 +982,7 @@ mpp_write_project (MrpParser *parser)
 				   parser);
 
 	/* Write resource groups. */
- 	child = xmlNewChild (node, NULL, "resource-groups",NULL);
+ 	child = xmlNewChild (node, NULL, (unsigned char*)"resource-groups",NULL);
 	list = mrp_project_get_groups (parser->project);
 
 	/* Generate IDs and hash table. */
@@ -1001,7 +1004,7 @@ mpp_write_project (MrpParser *parser)
 	}
 
 	/* Write resources. */
- 	child = xmlNewChild (node, NULL, "resources",NULL);
+ 	child = xmlNewChild (node, NULL, (unsigned char*)"resources",NULL);
 	list = mrp_project_get_resources (parser->project);
 
 	/* Generate IDs and hash table. */
@@ -1019,7 +1022,7 @@ mpp_write_project (MrpParser *parser)
 	}
 
 	/* Write assignments. */
- 	child = xmlNewChild (node, NULL, "allocations", NULL);
+ 	child = xmlNewChild (node, NULL, (unsigned char*)"allocations", NULL);
 
 	for (l = assignments; l; l = l->next) {
 		mpp_write_assignment (parser, child, l->data);
@@ -1053,7 +1056,7 @@ parser_build_xml_doc (MrpStorageMrproject  *module,
 	parser.next_day_type_id = MRP_DAY_NEXT;
 	parser.next_calendar_id = 1;
 
-	parser.doc = xmlNewDoc ("1.0");
+	parser.doc = xmlNewDoc ((unsigned char*)"1.0");
 
 	if (!mpp_write_project (&parser)) {
 		g_set_error (error,
@@ -1183,7 +1186,7 @@ mpp_xml_set_date (xmlNodePtr node, const gchar *prop, mrptime time)
 	gchar *str;
 
 	str = mrp_time_to_string (time);
-	xmlSetProp (node, prop, str);
+	xmlSetProp (node, (unsigned char*)prop, (unsigned char*)str);
 	g_free (str);
 }
 
@@ -1193,7 +1196,7 @@ mpp_xml_set_int (xmlNodePtr node, const gchar *prop, gint value)
 	gchar *str;
 
 	str = g_strdup_printf ("%d", value);
-	xmlSetProp (node, prop, str);
+	xmlSetProp (node, (unsigned char*)prop, (unsigned char*)str);
 	g_free (str);
 }
 
@@ -1204,7 +1207,7 @@ mpp_xml_set_float (xmlNodePtr node, const gchar *prop, gfloat value)
 	gchar *str;
 
 	str = g_ascii_dtostr (buf, sizeof(buf) - 1, value);
-	xmlSetProp (node, prop, str);
+	xmlSetProp (node, (unsigned char*)prop, (unsigned char*)str);
 }
 
 static void
@@ -1223,7 +1226,7 @@ mpp_xml_set_task_type (xmlNodePtr node, const gchar *prop, MrpTaskType type)
 		break;
 	}
 
-	xmlSetProp (node, prop, str);
+	xmlSetProp (node, (unsigned char*)prop, (unsigned char*)str);
 }
 
 static void
@@ -1242,5 +1245,5 @@ mpp_xml_set_task_sched (xmlNodePtr node, const gchar *prop, MrpTaskSched sched)
 		break;
 	}
 
-	xmlSetProp (node, prop, str);
+	xmlSetProp (node, (unsigned char*)prop, (unsigned char*)str);
 }
diff --git a/libplanner/mrp-project.c b/libplanner/mrp-project.c
index 775f2e0..354a704 100644
--- a/libplanner/mrp-project.c
+++ b/libplanner/mrp-project.c
@@ -56,6 +56,7 @@ struct _MrpProjectPriv {
 	/*GList          *storage_modules;*/        /* <MrpStorageModule> */
 	gboolean          needs_saving;
 	gboolean          empty;
+  gint              maxUID;
 
 	MrpGroup         *default_group;
 
@@ -425,6 +426,7 @@ project_init (MrpProject *project)
 	priv->organization  = g_strdup ("");
 	priv->manager       = g_strdup ("");
 	priv->name          = g_strdup ("");
+  priv->maxUID        = 0;
 
 	priv->property_pool = g_param_spec_pool_new (TRUE);
 	priv->task_manager  = mrp_task_manager_new (project);
@@ -1486,6 +1488,37 @@ mrp_project_set_project_start (MrpProject *project,
 	project->priv->project_start = start;
 }
 /**
+ * mrp_project_get_maxUID:
+ * @project: an #MrpProject
+ *
+ * Fetches the maximum UID from @project.
+ *
+ * Return value: the maximum UID
+ **/
+gint
+mrp_project_get_maxUID (MrpProject *project)
+{
+	g_return_val_if_fail (MRP_IS_PROJECT (project), MRP_TIME_INVALID);
+
+	return project->priv->maxUID;
+}
+
+/**
+ * mrp_project_set_maxUID:
+ * @project: an #MrpProject
+ * @maxUID: project maximum task unique identifier
+ *
+ * Set the maximum UID
+ **/
+void
+mrp_project_set_maxUID (MrpProject *project,
+			       gint     *uid)
+{
+	g_return_if_fail (MRP_IS_PROJECT (project));
+
+	project->priv->maxUID = uid;
+}
+/**
  * imrp_project_add_calendar_day:
  * @project: an #MrpProject
  * @day: #MrpDay to add
diff --git a/libplanner/mrp-project.h b/libplanner/mrp-project.h
index f8162d2..6359065 100644
--- a/libplanner/mrp-project.h
+++ b/libplanner/mrp-project.h
@@ -61,6 +61,9 @@ gboolean         mrp_project_needs_saving             (MrpProject           *pro
 mrptime          mrp_project_get_project_start        (MrpProject           *project);
 void             mrp_project_set_project_start        (MrpProject           *project,
 						       mrptime               start);
+gint             mrp_project_get_maxUID               (MrpProject           *project);
+void             mrp_project_set_maxUID               (MrpProject           *project,
+						       gint                 *uid);
 gboolean         mrp_project_load                     (MrpProject           *project,
 						       const gchar          *uri,
 						       GError              **error);
diff --git a/libplanner/mrp-task-manager.c b/libplanner/mrp-task-manager.c
index 2388959..755c373 100644
--- a/libplanner/mrp-task-manager.c
+++ b/libplanner/mrp-task-manager.c
@@ -1105,8 +1105,13 @@ task_manager_build_dependency_graph (MrpTaskManager *manager)
 	MrpTask            *task;
 	MrpTaskGraphNode   *node;
 	GList              *queue;
+  gint                uid;
+  gint                maxUID;
+  gint                tmp_maxUID;
 
 	priv = manager->priv;
+  maxUID = mrp_project_get_maxUID(priv->project);
+  tmp_maxUID = 0;
 
 	/* Build a directed, acyclic graph, where relation links and children ->
 	 * parent are graph links (children must be calculated before
@@ -1125,8 +1130,20 @@ task_manager_build_dependency_graph (MrpTaskManager *manager)
 	tasks = mrp_task_manager_get_all_tasks (manager);
 	for (l = tasks; l; l = l->next) {
 		add_task_to_dependency_graph (manager, l->data, mrp_task_get_parent (l->data));
+
+    if (maxUID == 0) {
+      task = l->data;
+      uid = mrp_task_get_uid (task);
+      if (uid > tmp_maxUID) {
+        tmp_maxUID = uid;
+      }
+    }
 	}
 
+  if (maxUID == 0) {
+    mrp_project_set_maxUID(priv->project, tmp_maxUID);
+  }
+
 	/* Do a topological sort. Get the tasks without dependencies to start
 	 * with.
 	 */
@@ -2074,14 +2091,26 @@ task_manager_do_forward_pass_helper (MrpTaskManager *manager,
 	gint                work;
 	mrptime             t1, t2;
 	MrpTaskSched        sched;
+  MrpProject         *project;
+  gint                maxUID;
+  gint                uid;
 
 	priv = manager->priv;
+	project = mrp_object_get_project (MRP_OBJECT (task));
+  maxUID = mrp_project_get_maxUID(project);
 
 	old_start = mrp_task_get_start (task);
 	old_finish = mrp_task_get_finish (task);
 	old_duration = old_finish - old_start;
 	duration = 0;
 
+  uid = mrp_task_get_uid(task);
+  if (uid == 0) {
+    uid = maxUID + 1;
+    mrp_project_set_maxUID(project, uid);
+    mrp_task_set_uid(task, uid);
+  }
+
 	if (mrp_task_get_n_children (task) > 0) {
 		MrpTask *child;
 
diff --git a/libplanner/mrp-task.c b/libplanner/mrp-task.c
index 92a95b8..e2a4de0 100644
--- a/libplanner/mrp-task.c
+++ b/libplanner/mrp-task.c
@@ -32,6 +32,7 @@
 /* Properties */
 enum {
 	PROP_0,
+  PROP_UID,
 	PROP_NAME,
 	PROP_START,
 	PROP_FINISH,
@@ -85,6 +86,9 @@ struct _MrpTaskPriv {
 	/* Arbitary range of 0,1..9999. A hint for any (3rd party) resource leveller */
 	gint              priority;
 
+  /* Unique ID (unique within the context of this project), & will not change between saves */
+	gint              uid;
+
 	gchar            *name;
 	gchar            *note;
 
@@ -189,6 +193,7 @@ task_init (MrpTask *task)
 	priv = g_new0 (MrpTaskPriv, 1);
 	task->priv = priv;
 
+  priv->uid = 0; 
 	priv->name = g_strdup ("");
 	priv->node = g_node_new (task);
 	priv->assignments = NULL;
@@ -282,6 +287,15 @@ task_class_init (MrpTaskClass *klass)
 
 	g_object_class_install_property (
 		object_class,
+		PROP_UID,
+		g_param_spec_int ("uid",
+				     "UID",
+				     "Task Unique ID",
+             -1, G_MAXINT, 0,
+				     G_PARAM_READWRITE));
+
+	g_object_class_install_property (
+		object_class,
 		PROP_NAME,
 		g_param_spec_string ("name",
 				     "Name",
@@ -451,6 +465,10 @@ task_set_property (GObject      *object,
 	priv = task->priv;
 
 	switch (prop_id) {
+	case PROP_UID:
+		priv->uid = g_value_get_int (value);
+		break;
+
 	case PROP_NAME:
 		str = g_value_get_string (value);
 
@@ -601,6 +619,9 @@ task_get_property (GObject    *object,
 	priv = task->priv;
 
 	switch (prop_id) {
+	case PROP_UID:
+		g_value_set_int (value, priv->uid);
+		break;
 	case PROP_NAME:
 		g_value_set_string (value, priv->name);
 		break;
@@ -905,6 +926,38 @@ mrp_task_new (void)
 }
 
 /**
+ * mrp_task_get_uid:
+ * @task: an #MrpTask
+ *
+ * Retrives the uid of @task.
+ *
+ * Return value: the unique id
+ **/
+gint 
+mrp_task_get_uid (MrpTask *task)
+{
+	g_return_val_if_fail (MRP_IS_TASK (task), 1);
+
+	return task->priv->uid;
+}
+
+/**
+ * mrp_task_set_uid:
+ * @task: an #MrpTask
+ * @name: new @uid
+ *
+ * Sets the unique id of the task
+ * The uid is unique within the context of the project, 
+ * and remains constant between saves (as apposed to the id
+ * value which can change from one save to the next)
+ **/
+void mrp_task_set_uid (MrpTask *task, gint *uid)
+{
+	g_return_if_fail (MRP_IS_TASK (task));
+
+	mrp_object_set (MRP_OBJECT (task), "uid", uid, NULL);
+}
+/**
  * mrp_task_get_name:
  * @task: an #MrpTask
  *
@@ -1901,6 +1954,7 @@ imrp_task_set_finish (MrpTask *task, mrptime finish)
 	task->priv->finish = finish;
 }
 
+
 void
 imrp_task_set_duration (MrpTask *task, gint duration)
 {
diff --git a/libplanner/mrp-task.h b/libplanner/mrp-task.h
index b9f6a83..eaa0d70 100644
--- a/libplanner/mrp-task.h
+++ b/libplanner/mrp-task.h
@@ -86,6 +86,8 @@ GType            mrp_task_get_type                  (void) G_GNUC_CONST;
 GType            mrp_constraint_get_type            (void) G_GNUC_CONST;
 GType            mrp_relation_get_type              (void) G_GNUC_CONST;
 MrpTask         *mrp_task_new                       (void);
+gint             mrp_task_get_uid                   (MrpTask *task);
+void             mrp_task_set_uid                   (MrpTask *task, gint *uid);
 const gchar     *mrp_task_get_name                  (MrpTask          *task);
 void             mrp_task_set_name                  (MrpTask          *task,
 						     const gchar      *name);
diff --git a/libplanner/mrp-xml.c b/libplanner/mrp-xml.c
index 5fc5b83..184e5c1 100644
--- a/libplanner/mrp-xml.c
+++ b/libplanner/mrp-xml.c
@@ -34,6 +34,7 @@
 typedef enum {
 	XML_TYPE_UNKNOWN,
 	XML_TYPE_MRP_1,
+	XML_TYPE_MRP_0_7,
 	XML_TYPE_MRP_0_6,
 	XML_TYPE_MRP_0_5_1
 } XmlType;
@@ -76,11 +77,15 @@ xml_read_context (xmlParserCtxt  *ctxt,
 		return FALSE;
 	}
 
+/** Note: all versions of the mrp xml format use mrp_old_xml_parse
+ *  don't be confused by the name
+ **/
 	switch (xml_locate_type (doc)) {
 	case XML_TYPE_MRP_1:
 		g_print ("Isn't implemented yet\n");
 		ret_val = FALSE;
 		break;
+	case XML_TYPE_MRP_0_7:
 	case XML_TYPE_MRP_0_6:
 	case XML_TYPE_MRP_0_5_1:
 		ret_val = mrp_old_xml_parse (project, doc, error);
@@ -124,16 +129,21 @@ xml_locate_type (xmlDoc *doc)
 	XmlType  ret_val = XML_TYPE_UNKNOWN;
 	gchar   *filename;
 
-	filename = mrp_paths_get_dtd_dir ("mrproject-0.6.dtd");
-	if (xml_validate (doc, filename)) {
-		ret_val = XML_TYPE_MRP_0_6;
-	} else {
-		g_free (filename);
-		filename = mrp_paths_get_dtd_dir ("mrproject-0.5.1.dtd");
-		if (xml_validate (doc, filename)) {
-			ret_val = XML_TYPE_MRP_0_5_1;
-		}
-	}
+  filename = mrp_paths_get_dtd_dir ("mrproject-0.7.dtd");
+  if (xml_validate (doc, filename)) {
+    ret_val = XML_TYPE_MRP_0_7;
+  } else {
+    filename = mrp_paths_get_dtd_dir ("mrproject-0.6.dtd");
+    if (xml_validate (doc, filename)) {
+      ret_val = XML_TYPE_MRP_0_6;
+    } else {
+      g_free (filename);
+      filename = mrp_paths_get_dtd_dir ("mrproject-0.5.1.dtd");
+      if (xml_validate (doc, filename)) {
+        ret_val = XML_TYPE_MRP_0_5_1;
+      }
+    }
+  }
 
 	g_free (filename);
 
diff --git a/src/planner-msp-plugin.c b/src/planner-msp-plugin.c
index f6e8bd9..cb5ffe7 100644
--- a/src/planner-msp-plugin.c
+++ b/src/planner-msp-plugin.c
@@ -103,7 +103,7 @@ msp_plugin_transform (PlannerPlugin *plugin,
 		return FALSE;
 	}
 
-	filename = mrp_paths_get_dtd_dir ("mrproject-0.6.dtd");
+	filename = mrp_paths_get_dtd_dir ("mrproject-0.7.dtd");
 	if (!xml_validate (final_doc, filename)) {
 		GtkWidget *dialog;
 


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