Index: src/planner-phase-dialog.c
===================================================================
RCS file: /cvs/gnome/planner/src/planner-phase-dialog.c,v
retrieving revision 1.2
diff -u -B -b -p -r1.2 planner-phase-dialog.c
--- src/planner-phase-dialog.c	11 Dec 2003 10:52:46 -0000	1.2
+++ src/planner-phase-dialog.c	27 Apr 2004 18:48:05 -0000
@@ -1,5 +1,6 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 /*
+ * Copyright (C) 2004 Lincoln Phipps <lincoln.phipps@openmutual.net>
  * Copyright (C) 2002-2003 CodeFactory AB
  * Copyright (C) 2002-2003 Richard Hult <richard@imendio.com>
  * Copyright (C) 2002 Mikael Hallendal <micke@imendio.com>
@@ -37,6 +38,25 @@ enum {
 	NUM_COLS
 };
 
+/* UNDO/REDO Structures */
+
+typedef struct {
+	PlannerCmd   base;
+
+	MrpProject  *project;
+	gchar       *phase;
+} PhaseCmdInsert;
+
+typedef struct {
+	PlannerCmd   base;
+
+	MrpProject  *project;
+	gchar       *phase;
+	gboolean    is_assigned; 
+} PhaseCmdRemove;
+
+/* END of UNDO/REDO Strutures */
+
 typedef struct {
 	PlannerWindow  *main_window;
 	MrpProject    *project;
@@ -87,6 +107,21 @@ static void     phase_dialog_remove_phas
 						     const gchar      *phase);
 static void     phase_dialog_new_dialog_run         (DialogData       *data);
 
+/* UNDO/REDO prototypes */
+static PlannerCmd *phase_cmd_insert 		(PlannerWindow *window,
+						gchar 	*phase);
+				
+static void	phase_cmd_insert_do 		(PlannerCmd *cmd_base);
+static void	phase_cmd_insert_undo 		(PlannerCmd *cmd_base);
+static void	phase_cmd_insert_free 		(PlannerCmd *cmd_base);
+
+static PlannerCmd *phase_cmd_remove 		(PlannerWindow *window, 
+						gchar *phase);
+static void	phase_cmd_remove_do 		(PlannerCmd *cmd_base);
+static void	phase_cmd_remove_undo 		(PlannerCmd *cmd_base);
+static void	phase_cmd_remove_free 		(PlannerCmd *cmd_base);
+
+/* End of UNDO/REDO prototypes */
 
 static void
 phase_dialog_notify_phases (MrpProject  *project,  
@@ -174,6 +209,10 @@ planner_phase_dialog_new (PlannerWindow 
 	
 	data->remove_button = glade_xml_get_widget (glade, "remove_button");
 
+	/* turn remove button off initally until something later selected.*/
+	
+	gtk_widget_set_sensitive (data->remove_button, 0); 
+		
 	data->tree_view = glade_xml_get_widget (glade, "phase_treeview");
 
 	phase_dialog_setup_tree_view (data);
@@ -374,6 +413,8 @@ phase_dialog_remove_phase (DialogData  *
 	GtkListStore *store;
 	gboolean      found = FALSE;
 
+	PhaseCmdRemove *cmd;
+
 	tree_view = GTK_TREE_VIEW (data->tree_view);
 	store = GTK_LIST_STORE (gtk_tree_view_get_model (tree_view));
 
@@ -393,6 +434,7 @@ phase_dialog_remove_phase (DialogData  *
 
 	if (found) {
 		g_object_set (data->project, "phases", list, NULL);
+		cmd = (PhaseCmdRemove*) phase_cmd_remove (data->main_window, g_strdup (phase) );
 	}
 
 	mrp_string_list_free (list);
@@ -419,7 +462,9 @@ phase_dialog_new_dialog_run (DialogData 
 	GtkWidget   *dialog;
 	GtkWidget   *entry;
 	const gchar *name;
-	GList       *list;
+	GList          *list , *l;
+	gboolean	found; /* used to stop duplicated names */
+	PhaseCmdInsert *cmd;
 	
 	glade = glade_xml_new (GLADEDIR "/project-properties.glade",
 			       "new_phase_dialog",
@@ -435,19 +480,216 @@ phase_dialog_new_dialog_run (DialogData 
 			  G_CALLBACK (phase_dialog_new_name_changed_cb),
 			  data);
 
+	g_object_get (data->project, "phases", &list, NULL);
+	
 	if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
 		name = gtk_entry_get_text (GTK_ENTRY (entry));
 
-		/* Get all phases from the project, add the new one, re-set the
-		 * list.
+		if (strlen(name) > 0) { /* Don't add if its blank i.e. User just hit OK on little dialog. */
+			found = FALSE;
+			for (l = list; l ; l = l->next) {
+				if (strcmp (name, (char *) l->data) == 0 ) { 
+					found = TRUE; /* Will be a duplicated name which is messy */
+				}
+			}
+			if (found == FALSE ) {   /* If here then not a blank nor a duplicated name */
+				/* Actual stuff now done in the UNDO/REDO insert. */
+				cmd = (PhaseCmdInsert*) phase_cmd_insert (data->main_window, (gchar *) name);	
+			}
+		}
+	}
+	mrp_string_list_free (list);
+	g_object_unref (glade);
+	gtk_widget_destroy (dialog);
+}
+
+
+
+/* Start of UNDO/REDO routines */
+static void
+phase_cmd_insert_do (PlannerCmd *cmd_base)
+{
+	PhaseCmdInsert *cmd;
+	GList          *list;
+
+	cmd = (PhaseCmdInsert*) cmd_base;
+
+	g_assert (cmd->phase);
+		
+	/* Insert do code added from phase_dialog_new_dialog_run() with changes.
 		 */
-		g_object_get (data->project, "phases", &list, NULL);
-		list = g_list_append (list, g_strdup (name)); 
-		g_object_set (data->project, "phases", list, NULL);
+
+	g_object_get (cmd->project, "phases", &list, NULL);
+	
+	list = g_list_append (list, g_strdup (cmd->phase)); 
+	g_object_set (cmd->project, "phases", list, NULL);
 		mrp_string_list_free (list);
+}
+
+static void
+phase_cmd_insert_undo (PlannerCmd *cmd_base)
+{
+	PhaseCmdInsert *cmd;
+	cmd = (PhaseCmdInsert*) cmd_base;
+	
+	GList        *list, *l;
+	gboolean      found = FALSE;
+	
+
+	/* Insert undo taken from phase_dialog_remove_phase
+	 */
+	g_object_get (cmd->project, "phases", &list, NULL);
+
+	for (l = list; l; l = l->next) {
+		if (!strcmp (cmd->phase, l->data)) {
+			g_free (l->data);
+			list = g_list_remove_link (list, l);
+			found = TRUE;
+			break;
+		}
 	}
 
-	g_object_unref (glade);
-	gtk_widget_destroy (dialog);
+	if (found) {
+		g_object_set (cmd->project, "phases", list, NULL);
+	}
+
+	mrp_string_list_free (list);
+		
 }
 
+
+static void
+phase_cmd_insert_free (PlannerCmd *cmd_base)
+{
+	PhaseCmdInsert  *cmd;
+
+	cmd = (PhaseCmdInsert*) cmd_base;	
+
+	cmd->phase = NULL;  /* TODO: Check if this right regarding leaks ?*/
+	cmd->project = NULL;
+}
+
+static PlannerCmd *
+phase_cmd_insert (PlannerWindow *main_window, 
+		  gchar *phase) 
+{
+	PlannerCmd      *cmd_base;
+	PhaseCmdInsert  *cmd;
+
+	cmd = g_new0 (PhaseCmdInsert, 1);
+
+	cmd_base = (PlannerCmd*) cmd;
+
+	cmd_base->label = g_strdup (_("Insert phase"));
+	cmd_base->do_func = phase_cmd_insert_do;
+	cmd_base->undo_func = phase_cmd_insert_undo;
+	cmd_base->free_func = phase_cmd_insert_free;
+
+	cmd->project = planner_window_get_project (main_window);
+
+	cmd->phase = g_strdup (phase);
+
+	planner_cmd_manager_insert_and_do (planner_window_get_cmd_manager (main_window),
+					   cmd_base);
+
+	return cmd_base;
+}
+
+static void
+phase_cmd_remove_do (PlannerCmd *cmd_base)
+{
+	PhaseCmdRemove *cmd;
+	GList          *list, *l;
+	gchar          *assigned_phase;
+	gboolean      found = FALSE;
+
+	cmd = (PhaseCmdRemove*) cmd_base;
+
+	mrp_object_get (cmd->project, "phase", &assigned_phase, NULL);
+	if (assigned_phase == cmd->phase)
+		cmd->is_assigned = TRUE;
+	
+	/* Insert undo taken from phase_dialog_remove_phase
+	 */
+	g_object_get (cmd->project, "phases", &list, NULL);
+
+	for (l = list; l; l = l->next) {
+		if (!strcmp (cmd->phase, l->data)) {
+			g_free (l->data);
+			list = g_list_remove_link (list, l);
+			found = TRUE;
+			break;
+		}
+	}
+
+	if (found) {
+		g_object_set (cmd->project, "phases", list, NULL);
+	}
+
+	mrp_string_list_free (list);
+}
+
+static void
+phase_cmd_remove_undo (PlannerCmd *cmd_base)
+{
+	PhaseCmdRemove *cmd;
+	GList          *list;
+	
+	cmd = (PhaseCmdRemove*) cmd_base;
+
+	/* We need to recover the phase deleted */
+	
+	g_assert (cmd->phase);
+	
+	/* Insert do code added from phase_dialog_new_dialog_run() with changes.
+	 */
+
+	g_object_get (cmd->project, "phases", &list, NULL);
+	list = g_list_append (list, g_strdup (cmd->phase)); 
+	g_object_set (cmd->project, "phases", list, NULL);
+	mrp_string_list_free (list);	
+	
+
+	if (cmd->is_assigned) 
+		mrp_object_set (cmd->project, "phase", cmd->phase, NULL);
+}
+
+static void
+phase_cmd_remove_free (PlannerCmd *cmd_base)
+{
+	PhaseCmdRemove *cmd;
+
+	cmd = (PhaseCmdRemove*) cmd_base;
+
+	cmd->project = NULL;
+	cmd->phase = NULL;
+	cmd->is_assigned = FALSE;
+}
+
+static PlannerCmd *
+phase_cmd_remove (PlannerWindow *window, 
+		  gchar *phase)
+{
+	PlannerCmd      *cmd_base;
+	PhaseCmdRemove  *cmd;
+
+	cmd = g_new0 (PhaseCmdRemove, 1);
+
+	cmd_base = (PlannerCmd*) cmd;
+
+	cmd_base->label = g_strdup (_("Remove phase"));
+	cmd_base->do_func = phase_cmd_remove_do;
+	cmd_base->undo_func = phase_cmd_remove_undo;
+	cmd_base->free_func = phase_cmd_remove_free;
+
+	cmd->project = planner_window_get_project (window);
+	cmd->phase = phase;
+
+	planner_cmd_manager_insert_and_do (planner_window_get_cmd_manager (window),
+					   cmd_base);
+
+	return cmd_base;
+}
+
+
+/* END of UNDO/REDO routines */
