[Planner Dev] Second patch to task removal undo: Now also recover the relations between tasks



Hi guys!

A new version of the task removal undo has born. Now it also restore
relations between tasks, but we miss the recover also of assgignmentes,
but this seems to be the simpler task from the three: task tree,
relations and assingments.

When I finish the undo remove, I will continue with all the commands in
the task world, atomic cases of the removal task undo (I hope ;-))

Now, time to solve the problem Lincoln has found this morning/night.

Cheers

-- Alvaro
? task-tree-remove-undo1.diff
? task-tree-remove-undo2.diff
? dotnet/Makefile
? dotnet/Makefile.in
? dotnet/libplanner/Makefile
? dotnet/libplanner/Makefile.in
? dotnet/samples/Makefile
? dotnet/samples/Makefile.in
? src/tasks-undo.diff
? tests/tasks-undo
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 10:52:24 -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: gtk-doc.make
===================================================================
RCS file: /cvs/gnome/planner/gtk-doc.make,v
retrieving revision 1.3
diff -u -b -B -p -r1.3 gtk-doc.make
--- gtk-doc.make	16 Mar 2004 20:39:02 -0000	1.3
+++ gtk-doc.make	3 Apr 2004 10:52:24 -0000
@@ -39,7 +39,7 @@ SCANOBJ_FILES = 		 \
 	$(DOC_MODULE).prerequisites \
 	$(DOC_MODULE).signals
 
-CLEANFILES = $(SCANOBJ_FILES) $(DOC_MODULE)-unused.txt $(DOC_STAMPS)
+CLEANFILES = $(SCANOBJ_FILES) $(DOC_MODULE)-scan.o $(DOC_MODULE)-unused.txt $(DOC_STAMPS)
 
 if ENABLE_GTK_DOC
 all-local: html-build.stamp
@@ -99,32 +99,29 @@ html-build.stamp: sgml.stamp $(DOC_MAIN_
 	@echo '-- Fixing Crossreferences' 
 	cd $(srcdir) && gtkdoc-fixxref --module-dir=html --html-dir=$(HTML_DIR) $(FIXXREF_OPTIONS)
 	touch html-build.stamp
-else
-all-local:
 endif
 
 ##############
 
 clean-local:
 	rm -f *~ *.bak
-	rm -rf .libs
 
 maintainer-clean-local: clean
 	cd $(srcdir) && rm -rf xml html $(DOC_MODULE)-decl-list.txt $(DOC_MODULE)-decl.txt
 
 install-data-local:
-	installfiles=`echo $(srcdir)/html/*`; \
+	$(mkinstalldirs) $(DESTDIR)$(TARGET_DIR)
+	(installfiles=`echo $(srcdir)/html/*`; \
 	if test "$$installfiles" = '$(srcdir)/html/*'; \
 	then echo '-- Nothing to install' ; \
 	else \
-	  $(mkinstalldirs) $(DESTDIR)$(TARGET_DIR); \
 	  for i in $$installfiles; do \
 	    echo '-- Installing '$$i ; \
 	    $(INSTALL_DATA) $$i $(DESTDIR)$(TARGET_DIR); \
 	  done; \
 	  echo '-- Installing $(srcdir)/html/index.sgml' ; \
 	  $(INSTALL_DATA) $(srcdir)/html/index.sgml $(DESTDIR)$(TARGET_DIR) || :; \
-	fi
+	fi)
 
 uninstall-local:
 	rm -f $(DESTDIR)$(TARGET_DIR)/*
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 10:52:32 -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;
 	
@@ -204,7 +206,6 @@ task_cmd_insert_do (PlannerCmd *cmd_base
 	task = g_object_new (MRP_TYPE_TASK,
 			     "work", cmd->work,
 			     "duration", cmd->duration,
-			     "name", cmd->name ? cmd->name : "",
 			     NULL);
 	
 	mrp_project_insert_task (cmd->project,
@@ -350,6 +351,306 @@ 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;
+
+	g_message ("Storing relations for: %s", mrp_task_get_name (cmd->task));
+
+	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);
+
+	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);
+
+	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 +2121,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 +2130,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]