[Planner Dev] Third patch for tasj undo removal: solve lincoln problem reported



Hi guys!

Another patch, this one with lincoln problem solved. Time to rest a
little and give Richard time to look at all the patches in the queue and
then, start the commits :)

Cheers

-- Alvaro
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/planner/ChangeLog,v
retrieving revision 1.79
diff -u -b -B -p -r1.79 ChangeLog
--- ChangeLog	29 Mar 2004 15:18:08 -0000	1.79
+++ ChangeLog	3 Apr 2004 11:37:54 -0000
@@ -1,3 +1,9 @@
+2004-04-03 Alvaro del Castillo  <acs barrapunto com>
+
+	* src/planner-task-tree.c: implemented task remove undo
+	Currently only recovers the task, the position in the tasks tree 
+	and the task relations.
+
 2004-03-29  Richard Hult  <richard imendio com>
 
 	* libplanner/mrp-old-xml.c (old_xml_read_assignment): Be more
Index: src/planner-task-tree.c
===================================================================
RCS file: /cvs/gnome/planner/src/planner-task-tree.c,v
retrieving revision 1.14
diff -u -b -B -p -r1.14 planner-task-tree.c
--- src/planner-task-tree.c	28 Mar 2004 23:03:49 -0000	1.14
+++ src/planner-task-tree.c	3 Apr 2004 11:38:02 -0000
@@ -152,6 +152,9 @@ static gint        task_tree_parse_time_
 static MrpProject *task_tree_get_project               (PlannerTaskTree      *tree);
 static MrpTask *   task_tree_get_task_from_path        (PlannerTaskTree      *tree,
 							GtkTreePath          *path);
+static PlannerCmd *task_cmd_remove                     (PlannerTaskTree      *tree,
+							GtkTreePath          *path,
+							MrpTask              *task);
 
 
 static GtkTreeViewClass *parent_class = NULL;
@@ -167,7 +170,6 @@ typedef struct {
 	PlannerTaskTree *tree;
 	MrpProject      *project;
 	
-	gchar           *name;
 	gint             work;
 	gint             duration;
 	
@@ -181,7 +183,7 @@ task_cmd_insert_do (PlannerCmd *cmd_base
 {
 	TaskCmdInsert *cmd;
 	GtkTreePath   *path;
-	MrpTask       *task, *parent;
+	MrpTask       *parent;
 	gint           depth;
 	gint           position;
 
@@ -201,18 +203,19 @@ task_cmd_insert_do (PlannerCmd *cmd_base
 	
 	gtk_tree_path_free (path);
 	
-	task = g_object_new (MRP_TYPE_TASK,
+	if (cmd->task == NULL)
+		cmd->task = g_object_new (MRP_TYPE_TASK,
 			     "work", cmd->work,
 			     "duration", cmd->duration,
-			     "name", cmd->name ? cmd->name : "",
 			     NULL);
 	
+	g_message ("Insert task: %p", cmd->task);
+	
 	mrp_project_insert_task (cmd->project,
 				 parent,
 				 position,
-				 task);
+				 cmd->task);
 
-	cmd->task = task;
 }
 
 static void
@@ -224,8 +227,6 @@ task_cmd_insert_undo (PlannerCmd *cmd_ba
 
 	mrp_project_remove_task (cmd->project,
 				 cmd->task);
-	
-	cmd->task = NULL;
 }
 
 static PlannerCmd *
@@ -249,6 +250,7 @@ task_cmd_insert (PlannerTaskTree *tree,
 
 	cmd->tree = tree;
 	cmd->project = task_tree_get_project (tree);
+	cmd->task = NULL;
 
 	cmd->path = gtk_tree_path_copy (path);
 	cmd->work = work;
@@ -350,6 +352,308 @@ task_cmd_edit_property (PlannerTaskTree 
 	return cmd_base;
 }
 
+typedef struct {
+	PlannerCmd       base;
+
+	PlannerTaskTree *tree;
+	MrpProject      *project;
+
+	GtkTreePath     *path;
+	MrpTask         *task;
+	GList           *childs;
+	GList           *successors;
+	GList           *predecessors;
+} TaskCmdRemove;
+
+static gboolean is_task_in_project (MrpTask *task, PlannerTaskTree *tree)
+{
+	PlannerGanttModel *model; 
+	GtkTreePath       *path;
+
+	model = PLANNER_GANTT_MODEL (gtk_tree_view_get_model (GTK_TREE_VIEW (tree)));
+	path = planner_gantt_model_get_path_from_task (model, task);
+
+	if (path != NULL) {
+		gtk_tree_path_free (path);
+		return TRUE;
+	} else {	
+		return FALSE;
+	}
+}
+
+static void
+task_cmd_save_relations (TaskCmdRemove *cmd)
+{
+	GList *l;
+
+	cmd->predecessors = g_list_copy (mrp_task_get_predecessor_relations (cmd->task));
+	for (l = cmd->predecessors; l; l = l->next) {
+		if (g_getenv ("PLANNER_DEBUG_UNDO_TASK"))
+			g_message ("Predecessor save %s -> %s", 
+				   mrp_task_get_name (mrp_relation_get_predecessor (l->data)), 
+				   mrp_task_get_name (mrp_relation_get_successor (l->data)));
+		
+		g_object_ref (l->data);
+	}
+
+	cmd->successors = g_list_copy (mrp_task_get_successor_relations (cmd->task));
+	for (l = cmd->successors; l; l = l->next) {
+		if (g_getenv ("PLANNER_DEBUG_UNDO_TASK")) 
+			g_message ("Successor save %s -> %s", 
+				   mrp_task_get_name (mrp_relation_get_predecessor (l->data)), 
+				   mrp_task_get_name (mrp_relation_get_successor (l->data)));
+		g_object_ref (l->data);
+	}
+}
+
+static void
+task_cmd_restore_relations (TaskCmdRemove *cmd)
+{
+	GList       *l;
+	MrpRelation *relation;
+	MrpTask     *rel_task;
+		
+
+	for (l = cmd->predecessors; l; l = l->next) {
+		relation = l->data;
+		rel_task = mrp_relation_get_predecessor (relation);
+
+		if (!is_task_in_project (rel_task, cmd->tree)) continue;
+
+		if (g_getenv ("PLANNER_DEBUG_UNDO_TASK"))
+			g_message ("Predecessor recover: %s -> %s",
+				   mrp_task_get_name (mrp_relation_get_predecessor (l->data)),
+				   mrp_task_get_name (mrp_relation_get_successor (l->data)));
+		
+		mrp_task_add_predecessor (cmd->task, rel_task, 
+					  mrp_relation_get_relation_type (relation),
+					  mrp_relation_get_lag (relation), NULL);
+	}
+
+	for (l = cmd->successors; l; l = l->next) {
+		relation = l->data;
+		rel_task = mrp_relation_get_successor (relation);
+
+		if (!is_task_in_project (rel_task, cmd->tree)) continue;	
+
+		if (g_getenv ("PLANNER_DEBUG_UNDO_TASK"))
+			g_message ("Successor recover: %s -> %s",
+				   mrp_task_get_name (mrp_relation_get_predecessor (l->data)),
+				   mrp_task_get_name (mrp_relation_get_successor (l->data)));
+		
+		mrp_task_add_predecessor (rel_task, cmd->task,
+					  mrp_relation_get_relation_type (relation),
+					  mrp_relation_get_lag (relation), NULL);
+	}
+}
+
+static void 
+task_cmd_save_childs (TaskCmdRemove *cmd)
+{
+	gint childs, i;
+	
+	childs = mrp_task_get_n_children (cmd->task);
+
+	for (i = 0; i < childs; i++) {
+		MrpTask           *task;
+		TaskCmdRemove     *cmd_child;
+		GtkTreePath       *path;
+		PlannerGanttModel *model;
+		
+		model = PLANNER_GANTT_MODEL (gtk_tree_view_get_model (GTK_TREE_VIEW (cmd->tree)));
+		task = mrp_task_get_nth_child (cmd->task, i);
+		
+		path = planner_gantt_model_get_path_from_task (model, task);
+		
+		/* We don't insert this command in the undo manager */
+		cmd_child = g_new0 (TaskCmdRemove, 1);
+		cmd_child->tree = cmd->tree;
+		cmd_child->project = task_tree_get_project (cmd->tree);		
+		cmd_child->path = gtk_tree_path_copy (path);		
+		cmd_child->task = g_object_ref (task);
+		task_cmd_save_relations (cmd_child);
+		
+		cmd->childs = g_list_append (cmd->childs, cmd_child);
+		
+		task_cmd_save_childs (cmd_child);
+	}
+
+	if (g_getenv ("PLANNER_DEBUG_UNDO_TASK")) {
+		if (cmd->childs != NULL) {
+			GList *l;
+			for (l = cmd->childs; l; l = l->next) {
+				TaskCmdRemove *cmd_child = l->data;
+				g_message ("Child saved: %s", mrp_task_get_name (cmd_child->task));
+			}
+		}
+	}
+	
+}
+
+static void
+task_cmd_restore_childs (TaskCmdRemove *cmd)
+{
+	PlannerGanttModel *model;
+	gint               position, depth;
+	GtkTreePath       *path;
+	MrpTask           *parent;
+	GList             *l;
+
+	for (l = cmd->childs; l; l = l->next) {
+		TaskCmdRemove *cmd_child;			
+		
+		cmd_child = l->data;
+
+		path = gtk_tree_path_copy (cmd_child->path);
+		model = PLANNER_GANTT_MODEL (gtk_tree_view_get_model 
+					     (GTK_TREE_VIEW (cmd_child->tree)));
+		
+		depth = gtk_tree_path_get_depth (path);
+		position = gtk_tree_path_get_indices (path)[depth - 1];
+		
+		if (depth > 1) {
+			gtk_tree_path_up (path);
+			parent = task_tree_get_task_from_path (cmd_child->tree, path);
+		} else {
+			parent = NULL;
+		}
+		
+		gtk_tree_path_free (path);
+		
+		mrp_project_insert_task (cmd_child->project,
+					 parent,
+					 position,
+					 cmd_child->task);
+		
+		task_cmd_restore_childs (cmd_child);
+		task_cmd_restore_relations (cmd_child);
+	}
+}
+
+static void
+task_cmd_remove_do (PlannerCmd *cmd_base)
+{
+	TaskCmdRemove *cmd;
+	gint           childs;
+
+	cmd = (TaskCmdRemove*) cmd_base;
+
+	task_cmd_save_relations (cmd);
+
+	childs = mrp_task_get_n_children (cmd->task);
+
+	if (childs > 0 && cmd->childs == NULL) task_cmd_save_childs (cmd);
+
+	g_message ("Removing the task : %p", cmd->task);
+
+	mrp_project_remove_task (cmd->project, cmd->task);
+}
+
+static void
+task_cmd_remove_undo (PlannerCmd *cmd_base)
+{
+	PlannerGanttModel *model;
+	TaskCmdRemove     *cmd;
+	gint               position, depth;
+	GtkTreePath       *path;
+	MrpTask           *parent;
+	MrpTask           *child_parent;
+	
+	cmd = (TaskCmdRemove*) cmd_base;
+
+	path = gtk_tree_path_copy (cmd->path);
+	model = PLANNER_GANTT_MODEL (gtk_tree_view_get_model (GTK_TREE_VIEW (cmd->tree)));
+
+	depth = gtk_tree_path_get_depth (path);
+	position = gtk_tree_path_get_indices (path)[depth - 1];
+
+ 	if (depth > 1) {
+		gtk_tree_path_up (path);
+		parent = task_tree_get_task_from_path (cmd->tree, path);
+	} else {
+		parent = NULL;
+	}
+	
+	gtk_tree_path_free (path);
+
+	g_message ("Recovering the task : %p", cmd->task);
+
+	mrp_project_insert_task (cmd->project,
+				 parent,
+				 position,
+				 cmd->task);
+
+	child_parent = planner_gantt_model_get_indent_task_target (model, cmd->task);
+
+	if (cmd->childs != NULL) task_cmd_restore_childs (cmd);
+
+	task_cmd_restore_relations (cmd);
+}
+
+static void
+task_cmd_remove_free (PlannerCmd *cmd_base)
+{
+	TaskCmdRemove *cmd;
+	GList         *l;
+
+	cmd = (TaskCmdRemove*) cmd_base;
+
+	for (l = cmd->childs; l; l = l->next)
+		task_cmd_remove_free (l->data);
+
+	g_object_unref (cmd->task);
+
+	g_list_free (cmd->childs);
+
+	for (l = cmd->predecessors; l; l = l->next) 
+		g_object_unref (l->data);
+	g_list_free (cmd->predecessors);
+
+	for (l = cmd->successors; l; l = l->next)
+		g_object_ref (l->data);
+	g_list_free (cmd->successors);
+		
+	g_free (cmd_base->label);
+	gtk_tree_path_free (cmd->path);
+	
+
+	g_free (cmd);
+	cmd = NULL;
+}
+
+static PlannerCmd *
+task_cmd_remove (PlannerTaskTree *tree,
+		 GtkTreePath     *path,
+		 MrpTask         *task)
+{
+	PlannerTaskTreePriv *priv = tree->priv;
+	PlannerCmd          *cmd_base;
+	TaskCmdRemove       *cmd;
+
+	g_return_val_if_fail (MRP_IS_TASK (task), NULL);
+		
+	cmd = g_new0 (TaskCmdRemove, 1);
+
+	cmd_base = (PlannerCmd*) cmd;
+	cmd_base->label = g_strdup (_("Remove task"));
+	cmd_base->do_func = task_cmd_remove_do;
+	cmd_base->undo_func = task_cmd_remove_undo;
+	cmd_base->free_func = task_cmd_remove_free;
+
+	cmd->tree = tree;
+	cmd->project = task_tree_get_project (tree);
+
+	cmd->path = gtk_tree_path_copy (path);
+
+	cmd->task = g_object_ref (task);
+
+	planner_cmd_manager_insert_and_do (planner_window_get_cmd_manager (priv->main_window),
+					   cmd_base);
+
+	return cmd_base;
+}
+
+
 GType
 planner_task_tree_get_type (void)
 {
@@ -1820,8 +2124,8 @@ void
 planner_task_tree_remove_task (PlannerTaskTree *tree)
 {
 	GList *list, *l;
+	TaskCmdRemove *cmd;
 
-	/* FIXME: undo */
 	
 	list = planner_task_tree_get_selected_tasks (tree);
 	if (list == NULL) {
@@ -1829,7 +2133,18 @@ planner_task_tree_remove_task (PlannerTa
 	}
 
 	for (l = list; l; l = l->next) {
-		mrp_project_remove_task (tree->priv->project, l->data);
+		MrpTask             *task = l->data;
+		PlannerGanttModel   *model;
+		GtkTreePath         *path;
+
+		model = PLANNER_GANTT_MODEL (gtk_tree_view_get_model (GTK_TREE_VIEW (tree)));
+		path = planner_gantt_model_get_path_from_task (model, task);
+
+		/* childs are removed with the parent */
+		if (path != NULL)
+			cmd = (TaskCmdRemove*) task_cmd_remove (tree, path, task);
+		gtk_tree_path_free (path);
+		/* mrp_project_remove_task (tree->priv->project, l->data); */
 	}
 	
 	g_list_free (list);


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