[Planner Dev] Planner Phase undo/redo v0.2 for review.
- From: "lincoln phipps openmutual net" <lincoln phipps openmutual net>
- To: Planner Project Manager - Development List <planner-dev lists imendio com>
- Subject: [Planner Dev] Planner Phase undo/redo v0.2 for review.
- Date: Tue, 27 Apr 2004 19:53:59 +0100
All,
my first attempt at undo/redo. It works on my simple
test cases.
Add Phase, Assign Phase to project, Remove Phase and
then UNDO will add back the phase and its assignment to
the project.
Open an existing project, delete the assigned phase and
UNDDO/REDO will remove phase and replace it including
assignment.
It also fixes the duplicate phase name and empty phase
name errors seen in testing (existing bugz).
Rgds,
Lincoln.
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 */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]