[Planner Dev] More complete patch for undo in predecessor editor in task dialog



Hi guys!

Here goes a fresh new patch that completes the yesterday patch. The
planner_cmd_new is used now in all places and we have undo for editing
predecessors fields already added to a task, the harder undo ins this
zone.

For the task dialog only I have to implement the note undo, a cake using
the focus in/out, so this week we will close the task dialog undo. We
need to catch some bugs in the undo and gantt chart relations but the
implementation will be finished.

Cheers

-- 
Alvaro del Castillo San Félix
Lambdaux Software Services S.R.L.
Universidad Rey Juan Carlos
Centro de Apoyo Tecnológico
C/ Tulipán sn 28933 Mostoles, Madrid-Spain
www.lambdaux.com
acs lambdaux com
Index: src/planner-task-dialog.c
===================================================================
RCS file: /cvs/gnome/planner/src/planner-task-dialog.c,v
retrieving revision 1.14
diff -u -b -B -p -r1.14 planner-task-dialog.c
--- src/planner-task-dialog.c	7 Jun 2004 06:30:57 -0000	1.14
+++ src/planner-task-dialog.c	10 Jun 2004 05:53:47 -0000
@@ -220,6 +220,38 @@ typedef struct {
 	guint          old_units;
 } TaskCmdEditAssignment;
 
+typedef struct {
+	PlannerCmd base;
+
+	MrpTask         *task;
+	MrpTask         *predecessor;
+	MrpTask         *old_predecessor;
+	guint            lag;
+	guint            old_lag;
+	MrpRelationType  rel_type;
+	MrpRelationType  old_rel_type;
+	GError          *error;
+} TaskCmdEditPredecessor;
+
+
+typedef struct {
+	PlannerCmd        base;
+
+	MrpProject       *project;
+	MrpTask          *before;
+	MrpTask          *after;
+	MrpRelationType   relationship;
+	glong             lag;
+	GError           *error;
+} TaskCmdLink;
+
+typedef struct {
+	PlannerCmd base;
+
+	MrpRelation  *relation;
+	guint         lag;
+	guint         old_lag;
+} TaskCmdEditLag;
 
 static void
 task_dialog_setup_option_menu (GtkWidget     *option_menu,
@@ -754,6 +786,337 @@ task_cmd_assign_units (PlannerWindow *ma
 	return cmd_base;
 }
 
+/* link and unlink shared with planner-task-tree.c */
+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 (!error) {
+		retval = TRUE;
+	} else {
+		cmd->error = 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_cmd_link (PlannerWindow   *main_window,
+		       MrpTask         *before,
+		       MrpTask         *after,
+		       MrpRelationType  relationship,
+		       glong            lag,
+		       GError         **error)
+{
+	PlannerCmd          *cmd_base;
+	TaskCmdLink         *cmd;
+
+	cmd_base = planner_cmd_new (TaskCmdLink,
+				    _("Link task"),
+				    task_cmd_link_do,
+				    task_cmd_link_undo,
+				    task_cmd_link_free);
+
+	cmd = (TaskCmdLink *) cmd_base;
+
+	cmd->project = g_object_ref (planner_window_get_project (main_window));
+
+	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 
+					   (main_window),
+					   cmd_base);
+
+	if (cmd->error) {
+		g_propagate_error (error, cmd->error);
+		/* FIXME: who clean the cmd memory? */
+		return NULL;
+	}
+
+	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 void
+task_cmd_unlink_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_cmd_unlink (PlannerWindow   *main_window,
+			 MrpRelation     *relation)
+{
+	PlannerCmd          *cmd_base;
+	TaskCmdLink         *cmd;
+
+	cmd_base = planner_cmd_new (TaskCmdLink,
+				    _("Unkink task"),
+				    task_cmd_unlink_do,
+				    task_cmd_unlink_undo,
+				    task_cmd_unlink_free);
+	
+	cmd = (TaskCmdLink *) cmd_base;
+
+	cmd->project = g_object_ref (planner_window_get_project (main_window));
+
+	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 
+					   (main_window),
+					   cmd_base);
+	return cmd_base;
+}
+
+static gboolean
+task_cmd_edit_pred_do (PlannerCmd *cmd_base)
+{
+	GError                 *error = NULL;
+	gboolean                retval;
+	TaskCmdEditPredecessor *cmd = (TaskCmdEditPredecessor*) cmd_base;
+	
+	if (g_getenv ("PLANNER_DEBUG_UNDO_TASK")) {
+		g_message ("Editing predecessor from dialog ...");
+	}
+	
+	mrp_task_remove_predecessor (cmd->task, cmd->old_predecessor);
+
+	mrp_task_add_predecessor (cmd->task,
+				  cmd->predecessor,
+				  cmd->rel_type,
+				  cmd->lag,
+				  &error);
+
+	if (!error) {
+		retval = TRUE;
+	} else {
+		cmd->error = error;
+		retval = FALSE;		
+	} 
+
+	return retval;
+}
+
+static void
+task_cmd_edit_pred_undo (PlannerCmd *cmd_base)
+{
+	GError                 *error = NULL;
+	TaskCmdEditPredecessor *cmd = (TaskCmdEditPredecessor*) cmd_base;
+	
+	if (g_getenv ("PLANNER_DEBUG_UNDO_TASK")) {
+		g_message ("UNDO Editing predecessor from dialog ...");
+	}
+	
+	mrp_task_remove_predecessor (cmd->task, cmd->predecessor);
+
+	mrp_task_add_predecessor (cmd->task,
+				  cmd->old_predecessor,
+				  cmd->old_rel_type,
+				  cmd->old_lag,
+				  &error);
+
+	g_assert (error == NULL);
+}
+
+static void
+task_cmd_edit_pred_free (PlannerCmd *cmd_base)
+{
+	TaskCmdEditPredecessor *cmd;
+
+	cmd = (TaskCmdEditPredecessor *) cmd_base;
+
+	g_object_unref (cmd->task);
+	g_object_unref (cmd->predecessor);
+	g_object_unref (cmd->old_predecessor);
+}
+
+
+
+static PlannerCmd *
+planner_task_cmd_edit_predecessor (PlannerWindow   *main_window,
+				   MrpTask         *task,
+				   MrpTask         *old_predecessor,
+				   MrpTask         *predecessor,
+				   MrpRelationType  relationship,
+				   glong            lag,
+				   GError         **error)
+{
+	PlannerCmd             *cmd_base;
+	TaskCmdEditPredecessor *cmd;
+	MrpRelation            *relation;
+
+	cmd_base = planner_cmd_new (TaskCmdEditPredecessor,
+				    _("Edit task predecessor"),
+				    task_cmd_edit_pred_do,
+				    task_cmd_edit_pred_undo,
+				    task_cmd_edit_pred_free);
+
+	cmd = (TaskCmdEditPredecessor *) cmd_base;
+	
+	cmd->old_predecessor = g_object_ref (old_predecessor);
+	cmd->predecessor = g_object_ref (predecessor);
+	cmd->task = g_object_ref (task);
+
+	relation = mrp_task_get_relation (task, old_predecessor);
+
+	cmd->old_rel_type = mrp_relation_get_relation_type (relation);
+	cmd->rel_type = relationship;
+	cmd->old_lag = mrp_relation_get_lag (relation);
+	cmd->lag = lag;
+			
+	planner_cmd_manager_insert_and_do (planner_window_get_cmd_manager 
+					   (main_window),
+					   cmd_base);
+
+	if (cmd->error) {
+		/* FIXME: who clean the cmd memory? */
+		g_propagate_error (error, cmd->error);
+		return NULL;
+	}
+
+	return cmd_base;
+}
+
+static gboolean
+task_cmd_edit_lag_do (PlannerCmd *cmd_base)
+{
+	TaskCmdEditLag *cmd = (TaskCmdEditLag* ) cmd_base;
+
+	mrp_object_set (cmd->relation, "lag", cmd->lag, NULL);
+
+	return TRUE;
+}
+
+static void
+task_cmd_edit_lag_undo (PlannerCmd *cmd_base)
+{
+	TaskCmdEditLag *cmd = (TaskCmdEditLag* ) cmd_base;
+
+	mrp_object_set (cmd->relation, "lag", cmd->old_lag, NULL);
+}
+
+static void
+task_cmd_edit_lag_free (PlannerCmd *cmd_base)
+{
+	TaskCmdEditLag *cmd = (TaskCmdEditLag* ) cmd_base;
+
+	g_object_unref (cmd->relation);
+}
+
+static PlannerCmd *
+task_cmd_edit_lag (PlannerWindow *main_window,
+		   MrpRelation   *relation,
+		   guint          lag)
+{
+	PlannerCmd          *cmd_base;
+	TaskCmdEditLag      *cmd;
+	guint                old_lag;
+
+	mrp_object_get (relation, "lag", &old_lag, NULL);
+
+	if (old_lag == lag) {
+		return NULL;
+	}
+
+	cmd_base = planner_cmd_new (TaskCmdEditType,
+				    _("Edit lag predecessor from dialog"),
+				    task_cmd_edit_lag_do,
+				    task_cmd_edit_lag_undo,
+				    task_cmd_edit_lag_free);
+
+	
+	cmd = (TaskCmdEditLag *) cmd_base;
+	
+	cmd->relation = g_object_ref (relation);
+
+	cmd->old_lag = old_lag;
+	cmd->lag = lag;
+
+	planner_cmd_manager_insert_and_do (planner_window_get_cmd_manager (main_window),
+					   cmd_base);
+
+	return cmd_base;
+}
+
 static void
 task_dialog_close_clicked_cb (GtkWidget *w, DialogData *data)
 {
@@ -1518,7 +1881,8 @@ task_dialog_task_child_added_or_removed_
 }
 
 static GtkWidget *  
-task_dialog_predecessor_dialog_new (MrpTask *task)
+task_dialog_predecessor_dialog_new (MrpTask       *task,
+				    PlannerWindow *main_window)
 {
 	MrpProject *project;
 	GladeXML   *glade;
@@ -1533,8 +1897,9 @@ task_dialog_predecessor_dialog_new (MrpT
 			       NULL);
 
 	dialog = glade_xml_get_widget (glade, "add_predecessor_dialog");
-	g_object_set_data (G_OBJECT (dialog), "task_main", task);
 	
+	g_object_set_data (G_OBJECT (dialog), "task_main", task);
+	g_object_set_data (G_OBJECT (dialog), "main_window", main_window);
 	w = glade_xml_get_widget (glade, "predecessor_combo");
 	g_object_set_data (G_OBJECT (dialog), "predecessor_combo", w);
 	
@@ -1575,6 +1940,8 @@ static void  
 task_dialog_new_pred_ok_clicked_cb (GtkWidget *button, 
 				    GtkWidget *dialog)
 {
+	PlannerWindow *main_window;
+	PlannerCmd    *cmd;
 	GtkWidget   *w;
 	GError      *error = NULL;
 	MrpTask     *task_main;
@@ -1584,6 +1951,8 @@ task_dialog_new_pred_ok_clicked_cb (GtkW
 	gint         pred_type; 
 	gchar       *str;
 	
+	main_window = g_object_get_data (G_OBJECT (dialog), "main_window");
+
 	task_main = g_object_get_data (G_OBJECT (dialog), "task_main");
 	mrp_object_get (task_main, "project", &project, NULL);
 
@@ -1606,11 +1975,10 @@ task_dialog_new_pred_ok_clicked_cb (GtkW
 	
 	mrp_object_get (MRP_OBJECT (new_task_pred), "name", &str, NULL);
 
-	if (!mrp_task_add_predecessor (task_main,
-				       new_task_pred,
-				       pred_type,
-				       lag,
-				       &error)) {
+	cmd = planner_task_cmd_link (main_window, new_task_pred, task_main,
+				     pred_type, lag, &error);
+	
+	if (!cmd) {
 		GtkWidget *err_dialog;
 		
 		err_dialog = gtk_message_dialog_new (GTK_WINDOW (dialog),
@@ -1642,7 +2010,7 @@ task_dialog_add_predecessor_cb (GtkWidge
 {
 	GtkWidget *dialog;
 	
-	dialog = task_dialog_predecessor_dialog_new (data->task);
+	dialog = task_dialog_predecessor_dialog_new (data->task, data->main_window);
 	gtk_widget_show (dialog);
 }
 
@@ -1652,6 +2020,7 @@ task_dialog_remove_predecessor_cb (GtkWi
 {
 	GtkTreeView        *tree;
 	MrpTask            *predecessor;
+	MrpRelation             *relation;
 	PlannerPredecessorModel *model;
 	GtkTreeSelection   *selection;
 	GtkTreeIter         iter;
@@ -1665,7 +2034,9 @@ task_dialog_remove_predecessor_cb (GtkWi
         }
 	
 	predecessor = MRP_TASK (planner_list_model_get_object (PLANNER_LIST_MODEL (model), &iter));
-	mrp_task_remove_predecessor (data->task, predecessor);
+	/* mrp_task_remove_predecessor (data->task, predecessor); */
+	relation = mrp_task_get_relation (data->task, predecessor);
+	planner_task_cmd_unlink (data->main_window, relation);
 }
 
 static void  
@@ -1721,6 +2092,8 @@ task_dialog_pred_cell_edited (GtkCellRen
 	gint                lag;
 	MrpRelationType     type;
 
+	/* FIXME: Undo support */
+
 	tree = GTK_TREE_VIEW (data->predecessor_list);
 	
 	model = gtk_tree_view_get_model (tree);
@@ -1750,14 +2123,21 @@ task_dialog_pred_cell_edited (GtkCellRen
 
 		if (new_task_pred != task_pred) {
 			GError *error = NULL;
+			PlannerCmd *cmd;
+
+			cmd = planner_task_cmd_edit_predecessor (data->main_window, 
+								 task_main, task_pred,
+								 new_task_pred,
+								 type, lag, &error);
 
-			mrp_task_remove_predecessor (task_main, task_pred);
+			/* mrp_task_remove_predecessor (task_main, task_pred);
 
 			if (!mrp_task_add_predecessor (task_main,
 						       new_task_pred,
 						       type,
 						       lag,
-						       &error)) {
+						       &error)) { */
+			if (!cmd) {
 				GtkWidget *dialog;
 				
 				dialog = gtk_message_dialog_new (
@@ -1787,13 +2167,22 @@ task_dialog_pred_cell_edited (GtkCellRen
 
 		{	
 			GError *error = NULL;
-			mrp_task_remove_predecessor (task_main, task_pred);
+			PlannerCmd *cmd;
+
+			cmd = planner_task_cmd_edit_predecessor (data->main_window, 
+								 task_main, task_pred,
+								 task_pred,
+								 planner_cell->selected_index + 1,
+								 lag, &error);
+
+			/* mrp_task_remove_predecessor (task_main, task_pred);
 
 			if (!mrp_task_add_predecessor (task_main,
 						       task_pred,
 						       planner_cell->selected_index + 1,
 						       lag,
-						       &error)) {
+						       &error)) {*/
+			if (!cmd) {
 				GtkWidget *dialog;
 				
 				dialog = gtk_message_dialog_new (
@@ -1830,10 +2219,12 @@ task_dialog_pred_cell_edited (GtkCellRen
 		break;
 
 	case PREDECESSOR_COL_LAG:
-		mrp_object_set (relation,
+		/* mrp_object_set (relation,
 				"lag",
 				60*60 * atoi (new_text),
-				NULL);
+				NULL);*/
+		task_cmd_edit_lag (data->main_window, relation, 60*60 * atoi (new_text));
+
 		break;
 
 	default:
Index: src/planner-task-dialog.h
===================================================================
RCS file: /cvs/gnome/planner/src/planner-task-dialog.h,v
retrieving revision 1.3
diff -u -b -B -p -r1.3 planner-task-dialog.h
--- src/planner-task-dialog.h	27 Apr 2004 18:58:02 -0000	1.3
+++ src/planner-task-dialog.h	10 Jun 2004 05:53:47 -0000
@@ -37,6 +37,16 @@ typedef enum {
 GtkWidget * planner_task_dialog_new (PlannerWindow         *window,
 				     MrpTask               *task,
 				     PlannerTaskDialogPage  page);
+
+PlannerCmd * planner_task_cmd_link   (PlannerWindow   *main_window,
+				      MrpTask         *before,
+				      MrpTask         *after,
+				      MrpRelationType  relationship,
+				      glong            lag,
+				      GError         **error);
+
+PlannerCmd * planner_task_cmd_unlink (PlannerWindow   *main_window,
+				      MrpRelation     *relation);
 
 
 #endif /* __PLANNER_TASK_DIALOG_H__ */


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