Re: [Planner Dev] Undoing add and remove calendars



Hi!

Here goes a more complete patch tha finished ALL the undo work in
calendar dialogs. Richard has implemented the "Default week" dialog
undoing and I have added to the last patch the "Working time" dialog
undoing, so with this patch, all the calendar undo work ins done!.

As you know, the undo system only needed the calendar undo to be
finished so, now all the code for undo in Planner is finished. We need
to test more and more the undo system before 0.12 release, but I feel we
have few bugs in it so we are very near to be in release time for 0.12.

Cheers

-- Alvaro

El sáb, 19-06-2004 a las 11:15, Alvaro del Castillo escribió:
> Hi guys!
> 
> Here goes the patch for undo adding and removing calendars. It has been
> easy to implement (very similar to the work done in tasks) and I think
> it is bug free with my tests, but more testing is needing ;-)
> 
> Cheers
Index: libplanner/mrp-calendar.c
===================================================================
RCS file: /cvs/gnome/planner/libplanner/mrp-calendar.c,v
retrieving revision 1.2
diff -u -b -B -p -r1.2 mrp-calendar.c
--- libplanner/mrp-calendar.c	18 Jun 2004 23:55:42 -0000	1.2
+++ libplanner/mrp-calendar.c	20 Jun 2004 09:39:45 -0000
@@ -396,6 +396,24 @@ foreach_copy_days (gpointer     key,
 }
 
 /**
+ * mrp_calendar_add:
+ * @calendar: a #MrpCalendar to add
+ * @parent: a #MrpCalendar to inherit from 
+ * 
+ * Add @calendar to the project 
+ * 
+ * Return value:
+ **/
+void
+mrp_calendar_add (MrpCalendar *calendar, MrpCalendar *parent)
+{
+	calendar_add_child (parent, calendar);
+
+	imrp_project_signal_calendar_tree_changed (calendar->priv->project);
+	imrp_project_set_needs_saving (calendar->priv->project, TRUE);
+}
+
+/**
  * mrp_calendar_copy:
  * @name: the name of the new calendar
  * @calendar: a #MrpCalendar to copy
Index: libplanner/mrp-calendar.h
===================================================================
RCS file: /cvs/gnome/planner/libplanner/mrp-calendar.h,v
retrieving revision 1.1.1.1
diff -u -b -B -p -r1.1.1.1 mrp-calendar.h
--- libplanner/mrp-calendar.h	1 Dec 2003 17:36:22 -0000	1.1.1.1
+++ libplanner/mrp-calendar.h	20 Jun 2004 09:39:46 -0000
@@ -80,6 +80,8 @@ enum {
 GType        mrp_calendar_get_type                 (void) G_GNUC_CONST;
 MrpCalendar *mrp_calendar_new                      (const gchar *name,
 						    MrpProject  *project);
+void         mrp_calendar_add                      (MrpCalendar *calendar,
+						    MrpCalendar *parent);
 MrpCalendar *mrp_calendar_copy                     (const gchar *name,
 						    MrpCalendar *calendar);
 MrpCalendar *mrp_calendar_derive                   (const gchar *name,
Index: libplanner/mrp-task.c
===================================================================
RCS file: /cvs/gnome/planner/libplanner/mrp-task.c,v
retrieving revision 1.7
diff -u -b -B -p -r1.7 mrp-task.c
Index: src/planner-calendar-dialog.c
===================================================================
RCS file: /cvs/gnome/planner/src/planner-calendar-dialog.c,v
retrieving revision 1.4
diff -u -b -B -p -r1.4 planner-calendar-dialog.c
--- src/planner-calendar-dialog.c	18 Jun 2004 04:47:12 -0000	1.4
+++ src/planner-calendar-dialog.c	20 Jun 2004 09:39:52 -0000
@@ -4,6 +4,7 @@
  * Copyright (C) 2002 Richard Hult <richard imendio com>
  * Copyright (C) 2002 Mikael Hallendal <micke imendio com>
  * Copyright (C) 2004 Imendio HB
+ * Copyright (C) 2004 Alvaro del Castillo <acs barrapunto com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -201,6 +202,228 @@ planner_cal_cmd_day_type (PlannerWindow 
 	return cmd_base;
 }
 
+typedef struct {
+	PlannerCmd   base;
+
+	MrpProject  *project;
+	MrpCalendar *calendar;
+	MrpCalendar *parent;
+	/* Resources that use this calendar */
+	GList       *resources;
+	/* Calendar that inherits from this calendar */
+	GList       *children;
+} CalCmdRemove;
+
+static gboolean
+cal_cmd_remove_do (PlannerCmd *cmd_base)
+{
+	GList *all_resources, *r;
+
+	CalCmdRemove *cmd = (CalCmdRemove*) cmd_base;
+
+	if (g_getenv ("PLANNER_DEBUG_UNDO_CAL")) {
+		g_message ("Removing a calendar ...");
+	}
+
+	all_resources = mrp_project_get_resources (cmd->project);
+	for (r = all_resources; r; r = r->next) {
+		MrpResource *resource = r->data;
+		MrpCalendar *tmp_cal;
+		
+		tmp_cal = mrp_resource_get_calendar (resource);
+		if (tmp_cal == cmd->calendar) {			
+			cmd->resources = g_list_append (cmd->resources, 
+							g_object_ref (resource));
+		} 
+	}
+
+	cmd->children = g_list_copy (mrp_calendar_get_children (cmd->calendar));
+	if (cmd->children) {
+		g_list_foreach (cmd->children, (GFunc) g_object_ref, NULL);
+	}
+		
+	mrp_calendar_remove (cmd->calendar);
+
+	return TRUE;
+}
+
+/* Reassign resources and calendar childs */
+static void
+cal_cmd_remove_undo (PlannerCmd *cmd_base)
+{
+	GList        *r;
+	GList        *c;
+	CalCmdRemove *cmd = (CalCmdRemove*) cmd_base;
+
+	if (g_getenv ("PLANNER_DEBUG_UNDO_CAL")) {
+		g_message ("Undo removing calendar ...");
+	}
+
+	mrp_calendar_add (cmd->calendar, cmd->parent);
+
+	if (cmd->resources != NULL) {
+		for (r = cmd->resources; r; r = r->next) {
+			mrp_resource_set_calendar (r->data, cmd->calendar);
+		}
+		g_list_foreach (cmd->resources, (GFunc) g_object_unref, NULL);
+		g_list_free (cmd->resources);
+		cmd->resources = NULL;
+	}
+
+	if (cmd->children != NULL) {
+		for (c = cmd->children; c; c = c->next) {
+			mrp_calendar_reparent (cmd->calendar, c->data);
+		}
+		g_list_foreach (cmd->children, (GFunc) g_object_unref, NULL);
+		g_list_free (cmd->children);
+		cmd->children = NULL;
+	}
+}
+
+
+static void
+cal_cmd_remove_free (PlannerCmd *cmd_base)
+{
+	CalCmdRemove *cmd = (CalCmdRemove*) cmd_base;
+
+	g_object_unref (cmd->calendar);
+	g_object_unref (cmd->project);
+
+	if (cmd->resources != NULL) {
+		g_list_foreach (cmd->resources, (GFunc) g_object_unref, NULL);
+		g_list_free (cmd->resources);
+		cmd->resources = NULL;
+	}
+	if (cmd->children != NULL) {
+		g_list_foreach (cmd->children, (GFunc) g_object_unref, NULL);
+		g_list_free (cmd->children);
+		cmd->children = NULL;
+	}
+}
+
+static PlannerCmd *
+planner_cal_cmd_remove (PlannerWindow  *main_window,
+			MrpProject     *project,
+			MrpCalendar    *calendar)
+{
+	PlannerCmd   *cmd_base;
+	CalCmdRemove *cmd;
+
+	cmd_base = planner_cmd_new (CalCmdRemove,
+				    _("Remove calendar"),
+				    cal_cmd_remove_do,
+				    cal_cmd_remove_undo,
+				    cal_cmd_remove_free);
+
+	cmd = (CalCmdRemove*) cmd_base;
+
+	cmd->project = g_object_ref (project);
+	cmd->calendar = g_object_ref (calendar);
+	cmd->parent = g_object_ref (mrp_calendar_get_parent (cmd->calendar));
+
+	planner_cmd_manager_insert_and_do (planner_window_get_cmd_manager 
+					   (main_window),
+					   cmd_base);
+	return cmd_base;
+}
+
+typedef struct {
+	PlannerCmd   base;
+
+	gchar       *name;
+	MrpProject  *project;
+	MrpCalendar *calendar;
+	MrpCalendar *parent;
+	MrpCalendar *copy;
+} CalCmdAdd;
+
+static gboolean
+cal_cmd_add_do (PlannerCmd *cmd_base)
+{
+	CalCmdAdd *cmd = (CalCmdAdd*) cmd_base;
+
+	if (g_getenv ("PLANNER_DEBUG_UNDO_CAL")) {
+		g_message ("Adding a new calendar ...");
+	}
+
+	if (cmd->calendar == NULL) {
+		if (cmd->parent != NULL && cmd->copy == NULL) {
+			cmd->calendar = mrp_calendar_derive (cmd->name, cmd->parent);
+			g_object_unref (cmd->parent);
+			cmd->parent = NULL;
+		} else if (cmd->parent == NULL && cmd->copy != NULL) {
+			cmd->calendar = mrp_calendar_copy (cmd->name, cmd->copy);
+			g_object_unref (cmd->copy);
+			cmd->copy = NULL;
+		} else if (cmd->parent == NULL && cmd->copy == NULL) {
+			cmd->calendar = mrp_calendar_new (cmd->name, cmd->project);
+			cmd->parent = g_object_ref (mrp_calendar_get_parent (cmd->calendar));
+		} else {
+			g_warning ("Incorrect use adding new calendar");
+		}
+		cmd->parent = g_object_ref (mrp_calendar_get_parent (cmd->calendar));
+	} else {
+		mrp_calendar_add (cmd->calendar, cmd->parent);
+	}
+
+	return TRUE;
+}
+
+static void
+cal_cmd_add_undo (PlannerCmd *cmd_base)
+{
+	CalCmdAdd *cmd = (CalCmdAdd*) cmd_base;
+
+	if (g_getenv ("PLANNER_DEBUG_UNDO_CAL")) {
+		g_message ("Undo adding calendar ...");
+	}
+	mrp_calendar_remove (cmd->calendar);
+}
+
+
+static void
+cal_cmd_add_free (PlannerCmd *cmd_base)
+{
+	CalCmdAdd *cmd = (CalCmdAdd*) cmd_base;
+
+	g_object_unref (cmd->calendar);
+	g_object_unref (cmd->parent);
+	g_object_unref (cmd->project);
+
+	g_free (cmd->name);
+}
+
+static PlannerCmd *
+planner_cal_cmd_add (PlannerWindow  *main_window,
+		     const gchar    *name,
+		     MrpCalendar    *parent,
+		     MrpCalendar    *copy)
+{
+	PlannerCmd *cmd_base;
+	CalCmdAdd  *cmd;
+
+	cmd_base = planner_cmd_new (CalCmdAdd,
+				    _("Add new calendar"),
+				    cal_cmd_add_do,
+				    cal_cmd_add_undo,
+				    cal_cmd_add_free);
+
+	cmd = (CalCmdAdd*) cmd_base;
+
+	cmd->project = g_object_ref (planner_window_get_project (main_window));
+	cmd->name = g_strdup (name);
+	if (parent != NULL) {
+		cmd->parent = g_object_ref (parent);
+	}
+	if (copy != NULL) {
+		cmd->copy = g_object_ref (copy);
+	}
+			
+	planner_cmd_manager_insert_and_do (planner_window_get_cmd_manager 
+					   (main_window),
+					   cmd_base);
+	return cmd_base;
+}
 
 static void
 cal_dialog_setup_option_menu (DialogData *data)
@@ -292,7 +515,8 @@ cal_dialog_response_cb (GtkWidget  *dial
 	
 	switch (response) {
 	case RESPONSE_REMOVE:
-		mrp_calendar_remove (calendar);
+		/* mrp_calendar_remove (calendar); */
+		planner_cal_cmd_remove (data->main_window, data->project, calendar);
 		break;
 
 	case RESPONSE_ADD:
@@ -1026,7 +1250,6 @@ cal_dialog_new_dialog_run (DialogData *d
 	GladeXML         *glade;
 	GtkWidget        *dialog;
 	MrpCalendar      *parent;
-	MrpCalendar      *calendar;
 	GtkTreeSelection *selection;
 	GtkWidget        *entry;
 	GtkWidget        *tree_view;
@@ -1081,13 +1304,17 @@ cal_dialog_new_dialog_run (DialogData *d
 		parent = cal_dialog_get_selected_calendar (GTK_TREE_VIEW (tree_view));
 
 		if (parent && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->new_copy_radiobutton))) {
-			calendar = mrp_calendar_copy (name, parent);
+			/* calendar = mrp_calendar_copy (name, parent); */
+			planner_cal_cmd_add (data->main_window, name, NULL, parent);
 		}
 		else if (parent && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->new_derive_radiobutton))) {
-			calendar = mrp_calendar_derive (name, parent);
+			/* calendar = mrp_calendar_derive (name, parent); */
+			planner_cal_cmd_add (data->main_window, name, parent, NULL);
 		}
 		else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->new_empty_radiobutton))) {
-			calendar = mrp_calendar_new (name, data->project);
+			/* calendar = mrp_calendar_new (name, data->project); */
+			planner_cal_cmd_add (data->main_window, name, NULL, NULL);
+			   
 		}
 	}
 
Index: src/planner-gantt-chart.c
===================================================================
RCS file: /cvs/gnome/planner/src/planner-gantt-chart.c,v
retrieving revision 1.8
diff -u -b -B -p -r1.8 planner-gantt-chart.c
Index: src/planner-working-time-dialog.c
===================================================================
RCS file: /cvs/gnome/planner/src/planner-working-time-dialog.c,v
retrieving revision 1.2
diff -u -b -B -p -r1.2 planner-working-time-dialog.c
--- src/planner-working-time-dialog.c	11 Dec 2003 10:52:47 -0000	1.2
+++ src/planner-working-time-dialog.c	20 Jun 2004 09:39:57 -0000
@@ -3,6 +3,7 @@
  * Copyright (C) 2002-2003 CodeFactory AB
  * Copyright (C) 2002-2003 Richard Hult <richard imendio com>
  * Copyright (C) 2002 Mikael Hallendal <micke imendio com>
+ * Copyright (C) 2004 Alvaro del Castillo <acs barrapunto com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -85,6 +86,84 @@ static void          working_time_dialog
 							       DialogData       *data);
 
 
+typedef struct {
+	PlannerCmd   base;
+
+	MrpDay      *day;
+	MrpCalendar *calendar;
+	GList       *ivals;
+	GList       *old_ivals;
+} WorkingTimeCmdEdit;
+
+static gboolean
+working_time_cmd_edit_do (PlannerCmd *cmd_base)
+{
+	WorkingTimeCmdEdit *cmd = (WorkingTimeCmdEdit*) cmd_base;
+
+	mrp_calendar_day_set_intervals (cmd->calendar, cmd->day, cmd->ivals);
+
+	return TRUE;
+}
+
+static void
+working_time_cmd_edit_undo (PlannerCmd *cmd_base)
+{
+	WorkingTimeCmdEdit *cmd = (WorkingTimeCmdEdit*) cmd_base;
+
+	mrp_calendar_day_set_intervals (cmd->calendar, cmd->day, cmd->old_ivals);
+}
+
+static void
+working_time_cmd_edit_free (PlannerCmd *cmd_base)
+{
+	WorkingTimeCmdEdit *cmd = (WorkingTimeCmdEdit*) cmd_base;
+
+	g_list_foreach (cmd->ivals, (GFunc) mrp_interval_unref, NULL);
+	g_list_free (cmd->ivals);
+	cmd->ivals = NULL;
+
+	g_list_foreach (cmd->old_ivals, (GFunc) mrp_interval_unref, NULL);
+	g_list_free (cmd->old_ivals);
+	cmd->old_ivals = NULL;
+
+	mrp_day_unref (cmd->day);
+	g_object_unref (cmd->calendar);
+}
+
+static PlannerCmd *
+working_time_cmd_edit (PlannerWindow   *main_window,
+		       MrpCalendar     *calendar,
+		       MrpDay          *day,
+		       GList           *ivals)
+{
+	PlannerCmd          *cmd_base;
+	WorkingTimeCmdEdit  *cmd;
+
+	cmd_base = planner_cmd_new (WorkingTimeCmdEdit,
+				    _("Edit working time"),
+				    working_time_cmd_edit_do,
+				    working_time_cmd_edit_undo,
+				    working_time_cmd_edit_free);
+	
+	cmd = (WorkingTimeCmdEdit *) cmd_base;
+
+	cmd->calendar = g_object_ref (calendar);
+	cmd->day = mrp_day_ref (day);
+
+	cmd->ivals = g_list_copy (ivals);
+	g_list_foreach (ivals, (GFunc) mrp_interval_ref, NULL);
+
+	cmd->old_ivals = g_list_copy (mrp_calendar_day_get_intervals 
+				      (cmd->calendar, cmd->day, TRUE));
+	g_list_foreach (cmd->old_ivals, (GFunc) mrp_interval_ref, NULL);
+			
+	planner_cmd_manager_insert_and_do (planner_window_get_cmd_manager 
+					   (main_window),
+					   cmd_base);
+	return cmd_base;
+}
+
+
 static void
 working_time_dialog_response_cb (GtkWidget  *dialog,
 				 gint        response,
@@ -490,7 +569,8 @@ working_time_dialog_apply (DialogData *d
 		}
 	}
 
-	mrp_calendar_day_set_intervals (data->calendar, day, ivals);
+	/* mrp_calendar_day_set_intervals (data->calendar, day, ivals); */
+	working_time_cmd_edit (data->main_window, data->calendar, day, ivals);		     
 
 	g_list_foreach (ivals, (GFunc) mrp_interval_unref, NULL);
 	g_list_free (ivals);

Attachment: signature.asc
Description: Esta parte del mensaje =?ISO-8859-1?Q?est=E1?= firmada digitalmente



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