[Planner Dev] Second patch to task removal undo: Now also recover the relations between tasks
- From: Alvaro del Castillo <acs lambdaux com>
- To: Planner Project Manager - Development List <planner-dev lists imendio com>
- Subject: [Planner Dev] Second patch to task removal undo: Now also recover the relations between tasks
- Date: Sat, 03 Apr 2004 12:59:23 +0000
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]