Hi! The undo system is getting more clear as it is implemented using the object id concept. To undo a user operation, you have to store all the data needed by the user operation to undo the operation. If in this data you need references to other objects in Planner world, you have to be careful because this references could point to objects that has been destroyed in the time window before the user operation and the user trying to undo the operation. This is why we must use object ids in our do/undo world and this patch works in this way for the resource data world, that has for example MrpGroup, MrpCalendar, MrpProject and MrpAssignments. This patch also shows a prob with our way to store a operation data using a object clone. This object clone doens't exist in the project but if you are not careful, some operations like adding the assignments to the clone object could be shown in the project UI. We have to take care for these things and in the patch I propose a to step object clone: - One method to create the object clone (mrp_resource_clone) - One method to add it really to the project (mrp_resource_clone_get_real) Once we have decided to follow some of this ways, we will change all the planner code to follow this standars. Cheers -- Alvaro del Castillo San Félix Lambdaux Software Services S.R.L. Director de Arquitectura y Desarrollo Universidad Rey Juan Carlos Centro de Apoyo Tecnológico C/ Tulipán sn E28933 Mostoles, Madrid-Spain www.lambdaux.com acs lambdaux com
Index: libplanner/mrp-resource.c =================================================================== RCS file: /cvs/gnome/planner/libplanner/mrp-resource.c,v retrieving revision 1.2 diff -u -b -B -p -r1.2 mrp-resource.c --- libplanner/mrp-resource.c 2 Feb 2004 06:08:44 -0000 1.2 +++ libplanner/mrp-resource.c 3 Feb 2004 06:32:57 -0000 @@ -695,8 +695,6 @@ mrp_resource_clone (MrpResource *resourc g_return_if_fail (MRP_IS_RESOURCE (resource)); - priv = clone->priv; - clone = g_object_new (MRP_TYPE_RESOURCE, NULL); priv = clone->priv; @@ -711,8 +709,6 @@ mrp_resource_clone (MrpResource *resourc "project", &project, NULL); - mrp_object_set (clone, "project", project, NULL); - /* Custom properties */ custom_prop = mrp_project_get_properties_from_type (project, MRP_TYPE_RESOURCE); @@ -729,7 +725,69 @@ mrp_resource_clone (MrpResource *resourc mrp_object_get_property (MRP_OBJECT (resource), l->data, &value); mrp_object_set_property (MRP_OBJECT (clone), l->data, &value); } - /* FIXME: assignments */ + /* Assignments: we can't finish them until the clone gets real */ + /* It is like mrp_resource_assign but in 2 steps */ + for (l = resource->priv->assignments; l; l = l->next) { + MrpTask *task; + MrpAssignment *assignment, *clone_assig; + gint units; + + assignment = l->data; + task = mrp_assignment_get_task (assignment); + units = mrp_assignment_get_units (assignment); + + clone_assig = g_object_new (MRP_TYPE_ASSIGNMENT, + "resource", clone, + "task", task, + "units", units, + NULL); + + priv->assignments = g_list_prepend (priv->assignments, clone_assig); + + } return clone; } + +/** + * mrp_resource_clone_get_real: + * @resource: an #MrpResource + * + * Integrate a clone object in the project + * Currently only do the assigments, but could grow + * + * + **/ +void +mrp_resource_clone_to_real (MrpResource *clone) +{ + MrpResourcePriv *priv; + GList *l; + + g_return_if_fail (MRP_IS_RESOURCE (clone)); + + priv = clone->priv; + + for (l = priv->assignments; l; l = l->next) { + MrpTask *task; + MrpAssignment *assignment, *new_assig; + gint units; + GList *clone_assig_list; + + + assignment = l->data; + + task = mrp_assignment_get_task (assignment); + /* We have already done some of this method */ + /* imrp_resource_add_assignment (clone, assignment); */ + g_signal_connect (G_OBJECT (assignment), + "removed", + G_CALLBACK (resource_assignment_removed_cb), + clone); + + g_signal_emit (clone, signals[ASSIGNMENT_ADDED], 0, assignment); + mrp_object_changed (MRP_OBJECT (clone)); + + imrp_task_add_assignment (task, assignment); + } +} Index: libplanner/mrp-resource.h =================================================================== RCS file: /cvs/gnome/planner/libplanner/mrp-resource.h,v retrieving revision 1.2 diff -u -b -B -p -r1.2 mrp-resource.h --- libplanner/mrp-resource.h 2 Feb 2004 06:08:44 -0000 1.2 +++ libplanner/mrp-resource.h 3 Feb 2004 06:32:57 -0000 @@ -77,6 +77,7 @@ void mrp_resource_set_calenda MrpCalendar *calendar); MrpResource * mrp_resource_clone (MrpResource *resource); +void mrp_resource_clone_to_real (MrpResource *clone); Index: src/planner-resource-view.c =================================================================== RCS file: /cvs/gnome/planner/src/planner-resource-view.c,v retrieving revision 1.11 diff -u -b -B -p -r1.11 planner-resource-view.c --- src/planner-resource-view.c 2 Feb 2004 06:08:44 -0000 1.11 +++ src/planner-resource-view.c 3 Feb 2004 06:33:04 -0000 @@ -269,10 +269,10 @@ typedef struct { typedef struct { PlannerCmd base; - MrpProject *project; guint project_id; MrpResource *resource; guint resource_id; + guint calendar_id; guint group_id; MrpResource *clone; @@ -871,25 +871,14 @@ static void resource_cmd_remove_do (PlannerCmd *cmd_base) { ResourceCmdRemove *cmd; - guint resource_removed_id; - MrpGroup *group; + MrpProject *project; cmd = (ResourceCmdRemove*) cmd_base; - resource_removed_id = mrp_object_get_id (MRP_OBJECT (cmd->resource)); - - cmd->project_id = mrp_object_get_id (MRP_OBJECT (cmd->project)); - cmd->resource_id = resource_removed_id; - cmd->clone = mrp_resource_clone (cmd->resource); - mrp_object_get (cmd->clone, "group", &group, NULL); - - if (group != NULL) { - cmd->group_id = mrp_object_get_id (MRP_OBJECT (group)); - } - - mrp_project_remove_resource (cmd->project, cmd->resource); + project = MRP_PROJECT (mrp_application_id_get_data (cmd->project_id)); + mrp_project_remove_resource (project, cmd->resource); cmd->resource = NULL; } @@ -899,6 +888,7 @@ resource_cmd_remove_undo (PlannerCmd *cm { ResourceCmdRemove *cmd; gpointer *data; + MrpProject *project; cmd = (ResourceCmdRemove*) cmd_base; @@ -903,15 +893,29 @@ resource_cmd_remove_undo (PlannerCmd *cm cmd = (ResourceCmdRemove*) cmd_base; data = mrp_application_id_get_data (cmd->project_id); - g_assert (MRP_IS_PROJECT (data)); - + project = MRP_PROJECT (data); mrp_object_set (cmd->clone, "project", MRP_OBJECT (data), NULL); - if (!mrp_object_set_id (MRP_OBJECT (cmd->clone), cmd->resource_id)) - g_warning ("Could't set the id to the object: %d", cmd->resource_id); + if (cmd->group_id > 0) { + data = mrp_application_id_get_data (cmd->group_id); + g_assert (MRP_IS_GROUP (data)); + mrp_object_set (cmd->clone, "group", MRP_OBJECT (data), NULL); + } + + data = mrp_application_id_get_data (cmd->calendar_id); + if (cmd->calendar_id > 0) { + data = mrp_application_id_get_data (cmd->calendar_id); + g_assert (MRP_IS_CALENDAR (data)); + mrp_object_set (cmd->clone, "calendar", MRP_OBJECT (data), NULL); + } + + + g_assert (mrp_object_set_id (MRP_OBJECT (cmd->clone), cmd->resource_id)); + + mrp_project_add_resource (project, cmd->clone); + mrp_resource_clone_to_real (cmd->clone); - mrp_project_add_resource (cmd->project, cmd->clone); cmd->resource = cmd->clone; } @@ -921,6 +925,9 @@ resource_cmd_remove (PlannerView *view, { PlannerCmd *cmd_base; ResourceCmdRemove *cmd; + MrpCalendar *calendar; + MrpProject *project; + MrpGroup *group; cmd = g_new0 (ResourceCmdRemove, 1); @@ -931,12 +938,20 @@ resource_cmd_remove (PlannerView *view, cmd_base->undo_func = resource_cmd_remove_undo; cmd_base->free_func = NULL; /* FIXME */ - cmd->project = planner_window_get_project (view->main_window); + cmd->resource_id = mrp_object_get_id (MRP_OBJECT (resource)); cmd->resource = resource; + project = planner_window_get_project (view->main_window); + cmd->project_id = mrp_object_get_id (MRP_OBJECT (project)); + + mrp_object_get (MRP_OBJECT (resource), "calendar", &calendar, NULL); + cmd->calendar_id = mrp_object_get_id (MRP_OBJECT (calendar)); + + mrp_object_get (MRP_OBJECT (resource), "group", &group, NULL); + cmd->group_id = mrp_object_get_id (MRP_OBJECT (group)); + planner_cmd_manager_insert_and_do (planner_window_get_cmd_manager (view->main_window), cmd_base); - return cmd_base; }
Attachment:
signature.asc
Description: Esta parte del mensaje =?ISO-8859-1?Q?est=E1?= firmada digitalmente