[Planner Dev] New undo patch: Link/unlink tasks
- From: Alvaro del Castillo <acs lambdaux com>
- To: Planner Project Manager - Development List <planner-dev lists imendio com>
- Subject: [Planner Dev] New undo patch: Link/unlink tasks
- Date: Wed, 05 May 2004 07:57:00 +0000
Hi guys!
Here goes another patch for the undo system. With this one you can
do/undo link/unlink tasks, using the link/unlink button and also,
linking tasks with drag and drop.
I have had to modify a little the PlannerCmd and here goes a proposal to
add 2 new fields: error and success. Richard, what do you think? I am
not sure I like to add new fields in this way to PlannerCmd.
Also, when a "_do" command returns fails, showing that it can't complete
the operation, the command is inserted in the CmdManager also. Is that
right? Or is something wrong (something I think)?
Cheers
-- Alvaro
Index: src/planner-cmd-manager.c
===================================================================
RCS file: /cvs/gnome/planner/src/planner-cmd-manager.c,v
retrieving revision 1.9
diff -u -b -B -p -r1.9 planner-cmd-manager.c
--- src/planner-cmd-manager.c 2 May 2004 16:21:28 -0000 1.9
+++ src/planner-cmd-manager.c 5 May 2004 05:47:27 -0000
@@ -258,6 +258,8 @@ cmd_manager_free_func (PlannerCmd *cmd,
/* g_free (cmd->label);
g_free (cmd);
*/
+
+ g_free (cmd->error);
}
static gboolean
@@ -320,6 +322,8 @@ cmd_manager_insert (PlannerCmdManager *m
} else {
retval = TRUE;
}
+
+ cmd->success = retval;
cmd_manager_dump (manager);
Index: src/planner-cmd-manager.h
===================================================================
RCS file: /cvs/gnome/planner/src/planner-cmd-manager.h,v
retrieving revision 1.3
diff -u -b -B -p -r1.3 planner-cmd-manager.h
--- src/planner-cmd-manager.h 2 May 2004 16:21:28 -0000 1.3
+++ src/planner-cmd-manager.h 5 May 2004 05:47:27 -0000
@@ -58,6 +58,8 @@ typedef enum {
struct _PlannerCmd {
gchar *label;
+ gboolean success;
+ gchar *error;
PlannerCmdManager *manager;
Index: src/planner-gantt-chart.h
===================================================================
RCS file: /cvs/gnome/planner/src/planner-gantt-chart.h,v
retrieving revision 1.3
diff -u -b -B -p -r1.3 planner-gantt-chart.h
Index: src/planner-gantt-row.c
===================================================================
RCS file: /cvs/gnome/planner/src/planner-gantt-row.c,v
retrieving revision 1.10
diff -u -b -B -p -r1.10 planner-gantt-row.c
--- src/planner-gantt-row.c 27 Apr 2004 18:58:02 -0000 1.10
+++ src/planner-gantt-row.c 5 May 2004 05:47:32 -0000
@@ -2049,16 +2048,24 @@ gantt_row_event (GnomeCanvasItem *item,
event->button.y);
if (target_item && target_item != item) {
- GError *error = NULL;
+ /* GError *error; */
+ PlannerCmd *cmd;
+ PlannerGanttChart *chart;
+ PlannerTaskTree *tree;
task = priv->task;
target_task = PLANNER_GANTT_ROW (target_item)->priv->task;
- if (!mrp_task_add_predecessor (target_task,
+ chart = g_object_get_data (G_OBJECT (item->canvas), "chart");
+ tree = planner_gantt_chart_get_view (chart);
+
+ cmd = planner_task_tree_task_cmd_link (tree,
task,
+ target_task,
MRP_RELATION_FS,
- 0,
- &error)) {
+ 0);
+
+ if (cmd->success == FALSE) {
GtkWidget *dialog;
gnome_canvas_item_ungrab (item, event->button.time);
@@ -2067,11 +2074,10 @@ gantt_row_event (GnomeCanvasItem *item,
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_OK,
- "%s", error->message);
+ "%s", cmd->error);
gtk_dialog_run (GTK_DIALOG (dialog));
gtk_widget_destroy (dialog);
- g_error_free (error);
}
}
Index: src/planner-task-tree.c
===================================================================
RCS file: /cvs/gnome/planner/src/planner-task-tree.c,v
retrieving revision 1.23
diff -u -b -B -p -r1.23 planner-task-tree.c
--- src/planner-task-tree.c 2 May 2004 16:21:28 -0000 1.23
+++ src/planner-task-tree.c 5 May 2004 05:47:38 -0000
@@ -193,7 +193,6 @@ task_cmd_insert_free (PlannerCmd *cmd_ba
gtk_tree_path_free (cmd->path);
g_object_unref (cmd->task);
cmd->task = NULL;
- g_free (cmd);
}
static gboolean
@@ -329,13 +328,9 @@ task_cmd_edit_property_free (PlannerCmd
cmd = (TaskCmdEditProperty*) cmd_base;
- g_free (cmd_base->label);
g_free (cmd->property);
g_value_unset (cmd->value);
g_value_unset (cmd->old_value);
- g_free (cmd);
-
-
}
static PlannerCmd *
@@ -701,10 +696,7 @@ task_cmd_remove_free (PlannerCmd *cmd_ba
g_list_foreach (cmd->assignments, (GFunc) g_object_unref, NULL);
g_list_free (cmd->assignments);
- g_free (cmd_base->label);
gtk_tree_path_free (cmd->path);
-
- g_free (cmd);
}
static PlannerCmd *
@@ -781,8 +773,6 @@ task_cmd_constraint_free (PlannerCmd *cm
g_object_unref (cmd->task);
g_free (cmd->constraint);
g_free (cmd->constraint_old);
-
- g_free (cmd);
}
@@ -829,15 +819,15 @@ typedef struct {
gboolean before;
gboolean before_old;
gboolean success;
-} TaskCmdTaskMove;
+} TaskCmdMove;
static gboolean
-task_cmd_task_move_do (PlannerCmd *cmd_base)
+task_cmd_move_do (PlannerCmd *cmd_base)
{
- TaskCmdTaskMove *cmd;
+ TaskCmdMove *cmd;
GError *error;
- cmd = (TaskCmdTaskMove*) cmd_base;
+ cmd = (TaskCmdMove*) cmd_base;
if (g_getenv ("PLANNER_DEBUG_UNDO_TASK")) {
if (cmd->before) {
@@ -864,17 +854,14 @@ task_cmd_task_move_do (PlannerCmd *cmd_b
}
static void
-task_cmd_task_move_undo (PlannerCmd *cmd_base)
+task_cmd_move_undo (PlannerCmd *cmd_base)
{
- TaskCmdTaskMove *cmd;
+ TaskCmdMove *cmd;
GError *error;
- cmd = (TaskCmdTaskMove*) cmd_base;
-
- if (!cmd->success) {
- return;
- }
+ cmd = (TaskCmdMove*) cmd_base;
+ g_assert (cmd->success);
if (g_getenv ("PLANNER_DEBUG_UNDO_TASK")) {
if (cmd->before_old) {
@@ -901,11 +888,11 @@ task_cmd_task_move_undo (PlannerCmd *cmd
}
static void
-task_cmd_task_move_free (PlannerCmd *cmd_base)
+task_cmd_move_free (PlannerCmd *cmd_base)
{
- TaskCmdTaskMove *cmd;
+ TaskCmdMove *cmd;
- cmd = (TaskCmdTaskMove*) cmd_base;
+ cmd = (TaskCmdMove*) cmd_base;
g_object_unref (cmd->project);
g_object_unref (cmd->task);
@@ -916,12 +903,11 @@ task_cmd_task_move_free (PlannerCmd *cmd
if (cmd->sibling != NULL) {
g_object_unref (cmd->sibling);
}
- g_free (cmd);
}
static PlannerCmd *
-task_cmd_task_move (PlannerTaskTree *tree,
+task_cmd_move (PlannerTaskTree *tree,
MrpTask *task,
MrpTask *sibling,
MrpTask *parent,
@@ -929,7 +915,7 @@ task_cmd_task_move (PlannerTaskTree *tre
{
PlannerTaskTreePriv *priv = tree->priv;
PlannerCmd *cmd_base;
- TaskCmdTaskMove *cmd;
+ TaskCmdMove *cmd;
GError *error;
gboolean success;
MrpTask *parent_old;
@@ -951,13 +937,13 @@ task_cmd_task_move (PlannerTaskTree *tre
return NULL;
}
- cmd = g_new0 (TaskCmdTaskMove, 1);
+ cmd = g_new0 (TaskCmdMove, 1);
cmd_base = (PlannerCmd*) cmd;
cmd_base->label = g_strdup (_("Move task"));
- cmd_base->do_func = task_cmd_task_move_do;
- cmd_base->undo_func = task_cmd_task_move_undo;
- cmd_base->free_func = task_cmd_task_move_free;
+ cmd_base->do_func = task_cmd_move_do;
+ cmd_base->undo_func = task_cmd_move_undo;
+ cmd_base->free_func = task_cmd_move_free;
cmd->project = g_object_ref (tree->priv->project);
cmd->task = g_object_ref (task);
@@ -987,6 +973,159 @@ task_cmd_task_move (PlannerTaskTree *tre
return cmd_base;
}
+typedef struct {
+ PlannerCmd base;
+
+ MrpProject *project;
+ MrpTask *before;
+ MrpTask *after;
+ MrpRelationType relationship;
+ glong lag;
+} TaskCmdLink;
+
+static gboolean
+task_cmd_link_do (PlannerCmd *cmd_base)
+{
+ TaskCmdLink *cmd;
+ GError *error = NULL;
+ MrpRelation *relation;
+ gboolean retval;
+
+ cmd = (TaskCmdLink *) cmd_base;
+
+ relation = mrp_task_add_predecessor (cmd->after,
+ cmd->before,
+ cmd->relationship,
+ cmd->lag,
+ &error);
+ if (relation) {
+ retval = TRUE;
+ } else {
+ cmd_base->error = g_strdup (error->message);
+ g_error_free (error);
+ retval = FALSE;
+ }
+
+ return retval;
+}
+
+static void
+task_cmd_link_undo (PlannerCmd *cmd_base)
+{
+ TaskCmdLink *cmd;
+
+ cmd = (TaskCmdLink*) cmd_base;
+
+ mrp_task_remove_predecessor (cmd->after, cmd->before);
+}
+
+static void
+task_cmd_link_free (PlannerCmd *cmd_base)
+{
+ TaskCmdLink *cmd;
+
+ cmd = (TaskCmdLink *) cmd_base;
+
+ g_object_unref (cmd->project);
+ g_object_unref (cmd->before);
+ g_object_unref (cmd->after);
+}
+
+
+PlannerCmd *
+planner_task_tree_task_cmd_link (PlannerTaskTree *tree,
+ MrpTask *before,
+ MrpTask *after,
+ MrpRelationType relationship,
+ glong lag)
+{
+ PlannerTaskTreePriv *priv = tree->priv;
+ PlannerCmd *cmd_base;
+ TaskCmdLink *cmd;
+
+ cmd = g_new0 (TaskCmdLink, 1);
+
+ cmd_base = (PlannerCmd*) cmd;
+ cmd_base->label = g_strdup (_("Link task"));
+ cmd_base->do_func = task_cmd_link_do;
+ cmd_base->undo_func = task_cmd_link_undo;
+ cmd_base->free_func = task_cmd_link_free;
+
+ cmd->project = g_object_ref (tree->priv->project);
+
+ cmd->before = g_object_ref (before);
+ cmd->after = g_object_ref (after);
+ cmd->relationship = relationship;
+ cmd->lag = lag;
+
+ planner_cmd_manager_insert_and_do (planner_window_get_cmd_manager
+ (priv->main_window),
+ cmd_base);
+ return cmd_base;
+}
+
+static gboolean
+task_cmd_unlink_do (PlannerCmd *cmd_base)
+{
+ TaskCmdLink *cmd;
+
+ cmd = (TaskCmdLink*) cmd_base;
+
+ if (g_getenv ("PLANNER_DEBUG_UNDO_TASK")) {
+ g_message ("Removing the link ...");
+ }
+
+ mrp_task_remove_predecessor (cmd->after, cmd->before);
+
+ return TRUE;
+}
+
+static void
+task_cmd_unlink_undo (PlannerCmd *cmd_base)
+{
+ TaskCmdLink *cmd;
+ GError *error;
+ MrpRelation *relation;
+
+ cmd = (TaskCmdLink *) cmd_base;
+
+ relation = mrp_task_add_predecessor (cmd->after,
+ cmd->before,
+ cmd->relationship,
+ cmd->lag,
+ &error);
+ g_assert (relation);
+}
+
+static PlannerCmd *
+task_cmd_unlink (PlannerTaskTree *tree,
+ MrpRelation *relation)
+{
+ PlannerTaskTreePriv *priv = tree->priv;
+ PlannerCmd *cmd_base;
+ TaskCmdLink *cmd;
+
+ cmd = g_new0 (TaskCmdLink, 1);
+
+ cmd_base = (PlannerCmd*) cmd;
+ cmd_base->label = g_strdup (_("Unlink task"));
+ cmd_base->do_func = task_cmd_unlink_do;
+ cmd_base->undo_func = task_cmd_unlink_undo;
+ cmd_base->free_func = task_cmd_link_free;
+
+ cmd->project = g_object_ref (tree->priv->project);
+
+ cmd->before = g_object_ref (mrp_relation_get_predecessor (relation));
+ cmd->after = g_object_ref (mrp_relation_get_successor (relation));
+ cmd->relationship = mrp_relation_get_relation_type (relation);
+ cmd->lag = mrp_relation_get_lag (relation);
+
+ 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)
@@ -2662,8 +2801,6 @@ planner_task_tree_unlink_task (PlannerTa
GList *relations, *r;
MrpRelation *relation;
- /* FIXME: undo */
-
list = planner_task_tree_get_selected_tasks (tree);
if (list == NULL) {
return;
@@ -2676,8 +2813,10 @@ planner_task_tree_unlink_task (PlannerTa
for (r = relations; r; r = r->next) {
relation = r->data;
- mrp_task_remove_predecessor (
- task, mrp_relation_get_predecessor (relation));
+ /* mrp_task_remove_predecessor (
+ task, mrp_relation_get_predecessor (relation)); */
+
+ task_cmd_unlink (tree, relation);
}
g_list_free (relations);
@@ -2686,8 +2825,10 @@ planner_task_tree_unlink_task (PlannerTa
for (r = relations; r; r = r->next) {
relation = r->data;
- mrp_task_remove_predecessor (
- mrp_relation_get_successor (relation), task);
+ /* mrp_task_remove_predecessor (
+ mrp_relation_get_successor (relation), task); */
+
+ task_cmd_unlink (tree, relation);
}
g_list_free (relations);
@@ -2705,8 +2846,6 @@ planner_task_tree_link_tasks (PlannerTas
GList *list, *l;
GtkWidget *dialog;
- /* FIXME: undo */
-
list = planner_task_tree_get_selected_tasks (tree);
if (list == NULL) {
return;
@@ -2716,23 +2855,26 @@ planner_task_tree_link_tasks (PlannerTas
target_task = list->data;
for (l = list->next; l; l = l->next) {
- GError *error = NULL;
+ PlannerCmd *cmd;
task = l->data;
- if (!mrp_task_add_predecessor (target_task,
+ cmd = planner_task_tree_task_cmd_link (tree, task, target_task,
+ relationship, 0);
+
+ /* cmd = mrp_task_add_predecessor (target_task,
task,
relationship,
0,
- &error)) {
+ &error)); */
+ if (cmd->success == FALSE) {
dialog = gtk_message_dialog_new (NULL,
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_OK,
- "%s", error->message);
+ "%s", cmd->error);
gtk_dialog_run (GTK_DIALOG (dialog));
gtk_widget_destroy (dialog);
- g_error_free (error);
}
target_task = task;
@@ -2788,12 +2930,12 @@ planner_task_tree_indent_task (PlannerTa
indent_tasks = g_list_reverse (indent_tasks);
for (l = indent_tasks; l; l = l->next) {
- TaskCmdTaskMove *cmd;
+ TaskCmdMove *cmd;
task = l->data;
- cmd = (TaskCmdTaskMove *)
- task_cmd_task_move (tree, task, NULL, new_parent, FALSE);
+ cmd = (TaskCmdMove *)
+ task_cmd_move (tree, task, NULL, new_parent, FALSE);
/* cmd = mrp_project_move_task (project,
task,
@@ -2881,7 +3023,7 @@ planner_task_tree_unindent_task (Planner
for (l = unindent_tasks; l; l = l->next) {
task = l->data;
- task_cmd_task_move (tree, task, NULL, new_parent, FALSE);
+ task_cmd_move (tree, task, NULL, new_parent, FALSE);
/* mrp_project_move_task (project,
task,
@@ -2975,7 +3117,7 @@ planner_task_tree_move_task_up (PlannerT
if (!skip && position != 0 && proceed) {
/* Move task from position to position - 1. */
sibling = mrp_task_get_nth_child (parent, position - 1);
- task_cmd_task_move (tree, task, sibling, parent, TRUE);
+ task_cmd_move (tree, task, sibling, parent, TRUE);
/* mrp_project_move_task (project, task, sibling,
parent, TRUE, NULL);*/
}
@@ -3086,7 +3228,7 @@ planner_task_tree_move_task_down (Planne
sibling = mrp_task_get_nth_child (parent, position + 1);
/* Moving task from 'position' to 'position + 1' */
- task_cmd_task_move (tree, task, sibling, parent, FALSE);
+ task_cmd_move (tree, task, sibling, parent, FALSE);
/* mrp_project_move_task (project, task, sibling,
parent, FALSE, NULL); */
}
Index: src/planner-task-tree.h
===================================================================
RCS file: /cvs/gnome/planner/src/planner-task-tree.h,v
retrieving revision 1.7
diff -u -b -B -p -r1.7 planner-task-tree.h
--- src/planner-task-tree.h 27 Apr 2004 18:58:02 -0000 1.7
+++ src/planner-task-tree.h 5 May 2004 05:47:39 -0000
@@ -85,6 +85,12 @@ void planner_task_tree_set_ancho
GtkTreePath *anchor);
GtkTreePath* planner_task_tree_get_anchor (PlannerTaskTree *tree);
+/* Undo support */
+PlannerCmd* planner_task_tree_task_cmd_link (PlannerTaskTree *tree,
+ MrpTask *before,
+ MrpTask *after,
+ MrpRelationType relationship,
+ glong lag);
#endif /* __PLANNER_TASK_TREE_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]