Re: [Planner Dev] Task/Resource and Project property redo/undo patch.
- From: "lincoln phipps openmutual net" <lincoln phipps openmutual net>
- To: Planner Project Manager - Development List <planner-dev lists imendio com>
- Subject: Re: [Planner Dev] Task/Resource and Project property redo/undo patch.
- Date: Mon, 24 May 2004 05:27:39 +0100
Attached is version 0.9 of this patch.
Main changes -
- Refactored the project value get and set to have its own routines
(mrp_project_property_get_value_string and
mrp_project_property_set_value_string )
- I now use planner_cmd_new ()
- Fix legacy bug in mpp_property_added () (used dialog before
checking) plus add some other checks to protect the dialog
callbacks when they are open (remember we've got different
property types floating around so if more than 1 dialog is
open it can get false property-changed signals that were not
intended for it.
- Other cleanups to patch as per Richard's comments.
****Note ****
This does not restore the resource or task properties if
the custom property was deleted from the project.
Thats a fairly major activity. We could work on that or
simply warn that there is NO undo for the values and add
that in a later Planner version e.g. 0.13 /1.0.
Individual value changes are undone (by acs) and all the
other stuff (property labels/add/remove by me) - its just
whole columns of values are not yet restored.
Rgds,
Lincoln.
Index: src/planner-project-properties.c
===================================================================
RCS file: /cvs/gnome/planner/src/planner-project-properties.c,v
retrieving revision 1.7
diff -u -b -B -p -r1.7 planner-project-properties.c
--- a/src/planner-project-properties.c 2 May 2004 16:21:28 -0000 1.7
+++ b/src/planner-project-properties.c 24 May 2004 04:18:33 -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) 2003 Imendio HB
* Copyright (C) 2001-2002 CodeFactory AB
* Copyright (C) 2001-2002 Richard Hult <richard imendio com>
@@ -52,6 +53,45 @@ typedef struct {
GtkWidget *remove_property_button;
} DialogData;
+/* Start of REDO/UNDO structures */
+
+typedef struct {
+ PlannerCmd base;
+
+ MrpProject *project;
+ gchar *name;
+ MrpPropertyType type;
+ gchar *label;
+ gchar *description;
+ GType owner;
+ gboolean user_defined;
+} MrpPropertyCmdAdd;
+
+typedef struct {
+ PlannerCmd base;
+
+ MrpProject *project;
+ gchar *name;
+ MrpPropertyType type;
+ gchar *label;
+ gchar *description;
+ GType owner;
+ gboolean user_defined;
+ gchar *old_text;
+} MrpPropertyCmdRemove;
+
+typedef struct {
+ PlannerCmd base;
+
+ MrpProject *project;
+ MrpProperty *property;
+ gchar *old_text;
+ gchar *new_text;
+} MrpPropertyCmdValueEdited;
+
+
+/* End of REDO/UNDO structures */
+
#define DIALOG_GET_DATA(d) g_object_get_data ((GObject*)d, "data")
static void mpp_select_calendar_clicked_cb (GtkWidget *button,
@@ -121,6 +161,10 @@ static void mpp_property_added
static void mpp_property_removed (MrpProject *project,
MrpProperty *property,
GtkWidget *dialog);
+static void mpp_property_changed (MrpProject *project,
+ GType object_type,
+ MrpProperty *property,
+ GtkWidget *dialog);
static void mpp_add_property_button_clicked_cb (GtkButton *button,
GtkWidget *dialog);
static void mpp_remove_property_button_clicked_cb (GtkButton *button,
@@ -129,7 +173,46 @@ static void mpp_property_value_edite
gchar *path_string,
gchar *new_text,
GtkWidget *dialog);
+const char *mrp_project_property_get_value_string (MrpProject *project,
+ MrpProperty *property);
+static gboolean mrp_project_property_set_value_string (MrpProject *project,
+ MrpProperty *property,
+ gchar *text);
+
+/* Start of UNDO/REDO Proptotypes */
+
+static PlannerCmd *mrp_property_cmd_add (PlannerWindow *window,
+ MrpProject *project,
+ GType owner,
+ const gchar *name,
+ MrpPropertyType type,
+ const gchar *label,
+ const gchar *description,
+ gboolean user_defined);
+static gboolean mrp_property_cmd_add_do (PlannerCmd *cmd_base);
+static void mrp_property_cmd_add_undo (PlannerCmd *cmd_base);
+static void mrp_property_cmd_add_free (PlannerCmd *cmd_base);
+
+
+static PlannerCmd *mrp_property_cmd_remove (PlannerWindow *window,
+ MrpProject *project,
+ GType owner,
+ const gchar *name);
+static gboolean mrp_property_cmd_remove_do (PlannerCmd *cmd_base);
+static void mrp_property_cmd_remove_undo (PlannerCmd *cmd_base);
+static void mrp_property_cmd_remove_free (PlannerCmd *cmd_base);
+
+
+static PlannerCmd *mrp_property_cmd_value_edited (PlannerWindow *window,
+ MrpProject *project,
+ MrpProperty *property,
+ const gchar *new_text);
+static gboolean mrp_property_cmd_value_edited_do (PlannerCmd *cmd_base);
+static void mrp_property_cmd_value_edited_undo (PlannerCmd *cmd_base);
+static void mrp_property_cmd_value_edited_free (PlannerCmd *cmd_base);
+
+/* End of UNDO/REDO Prototypes */
enum {
@@ -379,6 +462,11 @@ mpp_connect_to_project (MrpProject *proj
G_CALLBACK (mpp_property_removed),
dialog,
0);
+ g_signal_connect_object (project,
+ "property_changed",
+ G_CALLBACK (mpp_property_changed),
+ dialog,
+ 0);
}
static void
@@ -885,12 +973,13 @@ mpp_property_added (MrpProject *project
MrpProperty *property,
GtkWidget *dialog)
{
+
+ g_return_if_fail (GTK_IS_DIALOG (dialog));
+
DialogData *data = DIALOG_GET_DATA (dialog);
GtkTreeModel *model;
GtkTreeIter iter;
- g_return_if_fail (GTK_IS_DIALOG (dialog));
-
model = gtk_tree_view_get_model (data->properties_tree);
if (object_type != MRP_TYPE_PROJECT ||
@@ -942,6 +1031,9 @@ mpp_property_removed (MrpProject *proje
MrpProperty *property,
GtkWidget *dialog)
{
+
+ g_return_if_fail (GTK_IS_DIALOG (dialog));
+
DialogData *data = DIALOG_GET_DATA (dialog);
GtkTreeModel *model;
PropertyFindData *find_data;
@@ -971,6 +1063,50 @@ mpp_property_removed (MrpProject *proje
g_free (find_data);
}
+static void
+mpp_property_changed (MrpProject *project,
+ GType object_type,
+ MrpProperty *property,
+ GtkWidget *dialog)
+{
+
+ DialogData *data;
+ GtkTreeModel *model;
+ PropertyFindData *find_data;
+
+ /* Check for NULL here and shift the check for GTK_IS_DIALOG further in.
+ * The problem is with property_changed due to the way that there are
+ * 3 types of properties so if you have different dialogs opened the
+ * wrong data can upset the open dialogs.
+ */
+ g_return_if_fail (dialog);
+
+ if (object_type == MRP_TYPE_PROJECT) {
+
+ g_return_if_fail (GTK_IS_DIALOG (dialog));
+ data = DIALOG_GET_DATA (dialog);
+ model = gtk_tree_view_get_model (data->properties_tree);
+
+ find_data = g_new0 (PropertyFindData, 1);
+ find_data->property = property;
+ find_data->found_path = NULL;
+ find_data->found_iter = NULL;
+
+ gtk_tree_model_foreach (model,
+ (GtkTreeModelForeachFunc) mpp_property_find,
+ find_data);
+
+ if (find_data->found_path) {
+ gtk_tree_model_row_changed (model,
+ find_data->found_path,
+ find_data->found_iter);
+ }
+ if (find_data) {
+ g_free (find_data);
+ }
+ }
+}
+
static gboolean
mpp_property_dialog_label_changed_cb (GtkWidget *label_entry,
GdkEvent *event,
@@ -1063,7 +1199,6 @@ static void
mpp_add_property_button_clicked_cb (GtkButton *button, GtkWidget *dialog)
{
DialogData *data = DIALOG_GET_DATA (dialog);
- MrpProperty *property;
MrpPropertyType type;
const gchar *label;
const gchar *name;
@@ -1075,6 +1210,7 @@ mpp_add_property_button_clicked_cb (GtkB
GtkWidget *w;
gint response;
gboolean finished = FALSE;
+ MrpPropertyCmdAdd *cmd;
glade = glade_xml_new (GLADEDIR "/new-property.glade",
NULL,
@@ -1148,16 +1284,15 @@ mpp_add_property_button_clicked_cb (GtkB
type = mpp_property_dialog_get_selected (w);
if (type != MRP_PROPERTY_TYPE_NONE) {
- property = mrp_property_new (name,
+
+ cmd = (MrpPropertyCmdAdd*) mrp_property_cmd_add (data->main_window,
+ data->project,
+ MRP_TYPE_PROJECT,
+ name,
type,
label,
description,
TRUE);
-
- mrp_project_add_property (data->project,
- MRP_TYPE_PROJECT,
- property,
- TRUE);
}
finished = TRUE;
@@ -1186,6 +1321,7 @@ mpp_remove_property_button_clicked_cb (G
MrpProperty *property;
GtkWidget *remove_dialog;
gint response;
+ MrpPropertyCmdRemove *cmd;
model = gtk_tree_view_get_model (data->properties_tree);
@@ -1212,7 +1348,9 @@ mpp_remove_property_button_clicked_cb (G
switch (response) {
case GTK_RESPONSE_YES:
- mrp_project_remove_property (data->project,
+
+ cmd = (MrpPropertyCmdRemove *) mrp_property_cmd_remove (data->main_window,
+ data->project,
MRP_TYPE_PROJECT,
mrp_property_get_name (property));
break;
@@ -1240,8 +1378,7 @@ mpp_property_value_edited (GtkCellRender
GtkTreeModel *model;
MrpProperty *property;
MrpProject *project;
- MrpPropertyType type;
- gfloat fvalue;
+ MrpPropertyCmdValueEdited *cmd;
model = gtk_tree_view_get_model (data->properties_tree);
project = data->project;
@@ -1253,58 +1390,10 @@ mpp_property_value_edited (GtkCellRender
COL_PROPERTY, &property,
-1);
- type = mrp_property_get_property_type (property);
- switch (type) {
- case MRP_PROPERTY_TYPE_STRING:
- mrp_object_set (MRP_OBJECT (project),
- mrp_property_get_name (property),
- new_text,
- NULL);
- break;
- case MRP_PROPERTY_TYPE_INT:
- mrp_object_set (MRP_OBJECT (project),
- mrp_property_get_name (property),
- atoi (new_text),
- NULL);
- break;
- case MRP_PROPERTY_TYPE_FLOAT:
- fvalue = g_ascii_strtod (new_text, NULL);
- mrp_object_set (MRP_OBJECT (project),
- mrp_property_get_name (property),
- fvalue,
- NULL);
- break;
-
- case MRP_PROPERTY_TYPE_DURATION:
- /* FIXME: support reading units etc... */
- mrp_object_set (MRP_OBJECT (project),
- mrp_property_get_name (property),
- atoi (new_text) *8*60*60,
- NULL);
- break;
-
-
- case MRP_PROPERTY_TYPE_DATE:
-/* date = PLANNER_CELL_RENDERER_DATE (cell); */
-/* mrp_object_set (MRP_OBJECT (project), */
-/* mrp_property_get_name (property), */
-/* &(date->time), */
-/* NULL); */
- break;
- case MRP_PROPERTY_TYPE_COST:
- fvalue = g_ascii_strtod (new_text, NULL);
- mrp_object_set (MRP_OBJECT (project),
- mrp_property_get_name (property),
- fvalue,
- NULL);
- break;
- case MRP_PROPERTY_TYPE_STRING_LIST:
- /* FIXME: Should string-list still be around? */
- break;
- default:
- g_assert_not_reached ();
- break;
- }
+ cmd = (MrpPropertyCmdValueEdited *) mrp_property_cmd_value_edited (data->main_window,
+ project,
+ property,
+ new_text);
gtk_tree_path_free (path);
}
@@ -1465,3 +1554,480 @@ planner_project_properties_new (PlannerW
return dialog;
}
+
+
+/*
+ * Gets the value of a MrpProperty and converts to a string.
+ *
+ * Return value: A const char *, if found, otherwise NULL.
+ * NOTES: This can't be made part of mrp-project.c as it uses planner-format.h
+ * and thats not in libplanner so a bit messy. Its obviously not able to be in
+ * mrp-properties.c as thats common to all projects and not just one. So this'll
+ * have to stay here for now.
+ *
+ */
+
+const char *
+mrp_project_property_get_value_string (MrpProject *project,
+ MrpProperty *property)
+{
+ MrpPropertyType type;
+ gchar *svalue;
+ gint ivalue;
+ gfloat fvalue;
+ gint work;
+
+ g_return_val_if_fail (MRP_IS_PROJECT (project), NULL);
+
+ g_return_val_if_fail (property != NULL, NULL);
+
+ type = mrp_property_get_property_type (property);
+
+ switch (type) {
+ case MRP_PROPERTY_TYPE_STRING:
+ mrp_object_get (project,
+ mrp_property_get_name (property), &svalue,
+ NULL);
+
+ if (svalue == NULL) {
+ svalue = g_strdup ("");
+ }
+
+ break;
+ case MRP_PROPERTY_TYPE_INT:
+ mrp_object_get (project,
+ mrp_property_get_name (property), &ivalue,
+ NULL);
+ svalue = g_strdup_printf ("%d", ivalue);
+ break;
+
+ case MRP_PROPERTY_TYPE_FLOAT:
+ mrp_object_get (project,
+ mrp_property_get_name (property), &fvalue,
+ NULL);
+
+ svalue = planner_format_float (fvalue, 4, FALSE);
+ break;
+
+ case MRP_PROPERTY_TYPE_DATE:
+ svalue = g_strdup ("");
+
+
+/* mrp_object_get (data->project, */
+/* mrp_property_get_name (property), &tvalue, */
+/* NULL); */
+/* svalue = planner_format_date (tvalue); */
+ break;
+
+ case MRP_PROPERTY_TYPE_DURATION:
+ mrp_object_get (project,
+ mrp_property_get_name (property), &ivalue,
+ NULL);
+
+/* work = mrp_calendar_day_get_total_work (
+ mrp_project_get_calendar (tree->priv->project),
+ mrp_day_get_work ());
+*/
+ work = 8*60*60;
+
+ svalue = planner_format_duration (ivalue, work / (60*60));
+ break;
+
+ case MRP_PROPERTY_TYPE_COST:
+ mrp_object_get (project,
+ mrp_property_get_name (property), &fvalue,
+ NULL);
+
+ svalue = planner_format_float (fvalue, 2, FALSE);
+ break;
+
+ default:
+ g_warning ("Property type not implemented.");
+ break;
+ }
+ return ((const char *) svalue);
+}
+
+static gboolean
+mrp_project_property_set_value_string (MrpProject *project,
+ MrpProperty *property,
+ gchar *text)
+{
+ MrpPropertyType type;
+ gfloat fvalue;
+
+ g_return_val_if_fail (MRP_IS_PROJECT (project), FALSE);
+
+ g_return_val_if_fail (property != NULL, FALSE);
+
+ type = mrp_property_get_property_type (property);
+ switch (type) {
+ case MRP_PROPERTY_TYPE_STRING:
+ mrp_object_set (MRP_OBJECT (project),
+ mrp_property_get_name (property),
+ text,
+ NULL);
+ break;
+ case MRP_PROPERTY_TYPE_INT:
+ mrp_object_set (MRP_OBJECT (project),
+ mrp_property_get_name (property),
+ atoi (text),
+ NULL);
+ break;
+ case MRP_PROPERTY_TYPE_FLOAT:
+ fvalue = g_ascii_strtod (text, NULL);
+ mrp_object_set (MRP_OBJECT (project),
+ mrp_property_get_name (property),
+ fvalue,
+ NULL);
+ break;
+
+ case MRP_PROPERTY_TYPE_DURATION:
+ /* FIXME: support reading units etc... */
+ mrp_object_set (MRP_OBJECT (project),
+ mrp_property_get_name (property),
+ atoi (text) *8*60*60,
+ NULL);
+ break;
+
+ case MRP_PROPERTY_TYPE_DATE:
+ /* date = PLANNER_CELL_RENDERER_DATE (cell); */
+ /* mrp_object_set (MRP_OBJECT (project), */
+ /* mrp_property_get_name (property), */
+ /* &(date->time), */
+ /* NULL); */
+ break;
+ case MRP_PROPERTY_TYPE_COST:
+ fvalue = g_ascii_strtod (text, NULL);
+ mrp_object_set (MRP_OBJECT (project),
+ mrp_property_get_name (property),
+ fvalue,
+ NULL);
+ break;
+ case MRP_PROPERTY_TYPE_STRING_LIST:
+ /* FIXME: Should string-list still be around? */
+ break;
+ default:
+ g_assert_not_reached ();
+ return (FALSE);
+ break;
+ }
+ return (TRUE);
+}
+
+
+/* Start of UNDO/REDO routines */
+
+static gboolean
+mrp_property_cmd_add_do (PlannerCmd *cmd_base)
+{
+ MrpPropertyCmdAdd *cmd;
+ MrpProperty *property;
+
+ cmd = (MrpPropertyCmdAdd*) cmd_base;
+
+ if (cmd->name == NULL) {
+ return FALSE;
+ }
+
+ property = mrp_property_new (cmd->name,
+ cmd->type,
+ cmd->label,
+ cmd->description,
+ cmd->user_defined);
+
+ mrp_project_add_property (cmd->project,
+ cmd->owner,
+ property,
+ cmd->user_defined);
+
+ /* This functions as a simple success check for the REDO/UNDO stuff. Check if its added. */
+ if (!mrp_project_has_property (cmd->project, cmd->owner, cmd->name)) {
+ g_warning ("%s: object of type '%s' still has no property named '%s'",
+ G_STRLOC,
+ g_type_name (cmd->owner),
+ cmd->name);
+ return FALSE;
+ }
+
+ return TRUE;
+
+}
+
+static void
+mrp_property_cmd_add_undo (PlannerCmd *cmd_base)
+{
+ MrpPropertyCmdAdd *cmd;
+
+ cmd = (MrpPropertyCmdAdd*) cmd_base;
+
+ if (cmd->name != NULL) {
+ mrp_project_remove_property (cmd->project,
+ cmd->owner,
+ cmd->name);
+ /* This functions as a simple success check for the REDO/UNDO stuff. Check if its removed. */
+ if (mrp_project_has_property (cmd->project, cmd->owner, cmd->name)) {
+ g_warning ("%s: object of type '%s' still has the property named '%s'",
+ G_STRLOC,
+ g_type_name (cmd->owner),
+ cmd->name);
+ }
+ }
+}
+
+
+static void
+mrp_property_cmd_add_free (PlannerCmd *cmd_base)
+{
+ MrpPropertyCmdAdd *cmd;
+
+ cmd = (MrpPropertyCmdAdd*) cmd_base;
+
+ g_free (cmd->name);
+ g_free (cmd->label);
+ g_free (cmd->description);
+ cmd->project = NULL;
+}
+
+static
+PlannerCmd *
+mrp_property_cmd_add (PlannerWindow *window,
+ MrpProject *project,
+ GType owner,
+ const gchar *name,
+ MrpPropertyType type,
+ const gchar *label,
+ const gchar *description,
+ gboolean user_defined)
+{
+ PlannerCmd *cmd_base;
+ MrpPropertyCmdAdd *cmd;
+
+
+ cmd_base = planner_cmd_new (MrpPropertyCmdAdd,
+ _("Add project property"),
+ mrp_property_cmd_add_do,
+ mrp_property_cmd_add_undo,
+ mrp_property_cmd_add_free);
+
+ cmd = (MrpPropertyCmdAdd *) cmd_base;
+
+ cmd->project = project;
+ cmd->owner = owner;
+ cmd->name = g_strdup (name);
+ cmd->type = type;
+ cmd->label = g_strdup (label);
+ cmd->description = g_strdup (description);
+ cmd->user_defined = user_defined;
+
+ planner_cmd_manager_insert_and_do (planner_window_get_cmd_manager (window),
+ cmd_base);
+
+ return cmd_base;
+}
+
+
+static gboolean
+mrp_property_cmd_remove_do (PlannerCmd *cmd_base)
+{
+ MrpPropertyCmdRemove *cmd;
+
+ cmd = (MrpPropertyCmdRemove*) cmd_base;
+
+ if (!mrp_project_has_property (cmd->project, cmd->owner, cmd->name)) {
+ g_warning ("%s: object of type '%s' has no property named '%s' to remove",
+ G_STRLOC,
+ g_type_name (cmd->owner),
+ cmd->name);
+ return FALSE;
+ }
+
+ mrp_project_remove_property (cmd->project,
+ cmd->owner,
+ cmd->name);
+
+ return TRUE;
+}
+
+
+static void
+mrp_property_cmd_remove_undo (PlannerCmd *cmd_base)
+{
+ MrpPropertyCmdRemove *cmd;
+ MrpProperty *property;
+ MrpProject *project;
+ gchar *new_text;
+
+ cmd = (MrpPropertyCmdRemove*) cmd_base;
+
+ if (cmd->name != NULL) {
+
+ project = cmd->project;
+ new_text = cmd->old_text;
+
+ property = mrp_property_new (cmd->name,
+ cmd->type,
+ cmd->label,
+ cmd->description,
+ cmd->user_defined);
+
+ mrp_project_add_property (project,
+ cmd->owner,
+ property,
+ cmd->user_defined);
+
+ /* Now restore the previous text value We've kept it as new_text so it was easy to cut+paste code */
+
+ mrp_project_property_set_value_string (project, property, new_text);
+
+ /* This functions as a simple success check for the REDO/UNDO stuff. Check if its removed. */
+ if (!mrp_project_has_property (project, cmd->owner, cmd->name)) {
+ g_warning ("%s: object of type '%s' property named '%s' not restored.",
+ G_STRLOC,
+ g_type_name (cmd->owner),
+ cmd->name);
+ }
+ }
+}
+
+static void
+mrp_property_cmd_remove_free (PlannerCmd *cmd_base)
+{
+ MrpPropertyCmdRemove *cmd;
+
+ cmd = (MrpPropertyCmdRemove*) cmd_base;
+
+ g_free (cmd->name);
+ g_free (cmd->label);
+ g_free (cmd->description);
+ g_free (cmd->old_text);
+ cmd->project = NULL;
+}
+
+static PlannerCmd *
+mrp_property_cmd_remove (PlannerWindow *window,
+ MrpProject *project,
+ GType owner,
+ const gchar *name)
+{
+ PlannerCmd *cmd_base;
+ MrpPropertyCmdRemove *cmd;
+ MrpProperty *property;
+
+ cmd_base = planner_cmd_new (MrpPropertyCmdRemove,
+ _("Remove project property"),
+ mrp_property_cmd_remove_do,
+ mrp_property_cmd_remove_undo,
+ mrp_property_cmd_remove_free);
+
+ cmd = (MrpPropertyCmdRemove *) cmd_base;
+
+ cmd->project = project;
+ cmd->owner = owner;
+ cmd->name = g_strdup (name);
+
+ property = mrp_project_get_property (project,
+ name,
+ owner);
+
+ cmd->type = mrp_property_get_property_type (property);
+ cmd->description = g_strdup (mrp_property_get_description (property));
+ cmd->label = g_strdup ( mrp_property_get_label (property));
+ cmd->user_defined = mrp_property_get_user_defined (property);
+
+ cmd->old_text = (gchar *) mrp_project_property_get_value_string (project, property);
+
+ planner_cmd_manager_insert_and_do (planner_window_get_cmd_manager (window),
+ cmd_base);
+
+ return cmd_base;
+}
+
+/* Label Edited Routine */
+
+static gboolean
+mrp_property_cmd_value_edited_do (PlannerCmd *cmd_base)
+{
+ MrpPropertyCmdValueEdited *cmd;
+ MrpProject *project;
+ MrpProperty *property;
+ gchar *new_text;
+
+ cmd = (MrpPropertyCmdValueEdited*) cmd_base;
+
+ project = cmd->project;
+ property = cmd->property;
+ new_text = cmd->new_text;
+
+ if (!cmd->property) {
+ return FALSE;
+ }
+
+ return (mrp_project_property_set_value_string (project, property, new_text));
+}
+
+
+static void
+mrp_property_cmd_value_edited_undo (PlannerCmd *cmd_base)
+{
+ MrpPropertyCmdValueEdited *cmd;
+ MrpProject *project;
+ MrpProperty *property;
+ gchar *new_text;
+
+
+ cmd = (MrpPropertyCmdValueEdited*) cmd_base;
+
+ property = cmd->property;
+ project = cmd->project;
+ new_text = cmd->old_text;
+
+ if (cmd->property != NULL) {
+ mrp_project_property_set_value_string (project, property, new_text);
+ }
+}
+
+static void
+mrp_property_cmd_value_edited_free (PlannerCmd *cmd_base)
+{
+ MrpPropertyCmdValueEdited *cmd;
+
+ cmd = (MrpPropertyCmdValueEdited*) cmd_base;
+
+ g_free (cmd->old_text);
+ g_free (cmd->new_text);
+ cmd->property = NULL;
+ cmd->project = NULL;
+}
+
+static PlannerCmd *
+mrp_property_cmd_value_edited (PlannerWindow *window,
+ MrpProject *project,
+ MrpProperty *property,
+ const gchar *new_text)
+{
+ PlannerCmd *cmd_base;
+ MrpPropertyCmdValueEdited *cmd;
+
+ cmd_base = planner_cmd_new (MrpPropertyCmdValueEdited,
+ _("Edit project property value"),
+ mrp_property_cmd_value_edited_do,
+ mrp_property_cmd_value_edited_undo,
+ mrp_property_cmd_value_edited_free);
+
+ cmd = (MrpPropertyCmdValueEdited *) cmd_base;
+
+ cmd->property = property;
+ cmd->project = project;
+ cmd->new_text = g_strdup (new_text);
+
+ cmd->old_text = (gchar *) mrp_project_property_get_value_string (project, property);
+
+ planner_cmd_manager_insert_and_do (planner_window_get_cmd_manager (window),
+ cmd_base);
+
+ return cmd_base;
+}
+
+/* end of UNDO/REDO routines */
+
Index: src/planner-property-dialog.c
===================================================================
RCS file: /cvs/gnome/planner/src/planner-property-dialog.c,v
retrieving revision 1.2
diff -u -b -B -p -r1.2 planner-property-dialog.c
--- a/src/planner-property-dialog.c 11 Dec 2003 10:52:46 -0000 1.2
+++ b/src/planner-property-dialog.c 24 May 2004 04:18:34 -0000
@@ -4,6 +4,7 @@
* Copyright (C) 2002 Richard Hult <richard imendio com>
* Copyright (C) 2002 Mikael Hallendal <micke imendio com>
* Copyright (C) 2002 Alvaro del Castillo <acs barrapunto com>
+ * Copyright (C) 2004 Lincoln Phipps <lincoln phipps openmutual net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -48,12 +49,132 @@
typedef struct {
- GtkWidget *tree;
- GtkTreeModel *model;
+ PlannerWindow *main_window;
MrpProject *project;
- GType type;
+ GtkTreeModel *model;
+ GtkWidget *tree;
+ GType owner;
+ MrpPropertyStore *shop;
} PlannerPropertyDialogPriv;
+/* Start of REDO/UNDO structures */
+
+typedef struct {
+ PlannerCmd base;
+
+ PlannerWindow *window;
+ MrpProject *project;
+ gchar *name;
+ MrpPropertyType type;
+ gchar *label_text;
+ gchar *description;
+ GType owner;
+ gboolean user_defined;
+} ProjectPropertyCmdAdd;
+
+typedef struct {
+ PlannerCmd base;
+
+ PlannerWindow *window;
+ MrpProject *project;
+ gchar *name;
+ MrpPropertyType type;
+ gchar *label_text;
+ gchar *description;
+ GType owner;
+ gboolean user_defined;
+} ProjectPropertyCmdRemove;
+
+typedef struct {
+ PlannerCmd base;
+
+ PlannerWindow *window;
+ MrpProperty *property;
+ gchar *old_text;
+ gchar *new_text;
+} ProjectPropertyCmdLabelEdited;
+
+
+/* End of REDO/UNDO structures */
+
+static void property_dialog_setup_option_menu (GtkWidget *option_menu,
+ GCallback func,
+ gpointer user_data,
+ gconstpointer str1, ...);
+
+
+static gint property_dialog_get_selected (GtkWidget *option_menu);
+
+static void property_dialog_close_cb (GtkWidget *button,
+ GtkWidget *dialog);
+static void property_dialog_type_selected_cb (GtkWidget *widget,
+ GtkWidget *dialog);
+static gboolean property_dialog_label_changed_cb (GtkWidget *label_entry,
+ GdkEvent *event,
+ GtkWidget *name_entry);
+
+static void property_dialog_add_cb (GtkWidget *button,
+ GtkWidget *dialog);
+
+static void property_dialog_remove_cb (GtkWidget *button,
+ GtkWidget *dialog);
+
+static void property_dialog_label_edited (GtkCellRendererText *cell,
+ gchar *path_str,
+ gchar *new_text,
+ GtkWidget *dialog);
+
+
+static void property_dialog_setup_list (GtkWidget *dialog,
+ guint cols);
+
+static void property_dialog_setup_widgets (GtkWidget *dialog,
+ GladeXML *glade);
+
+GtkWidget *planner_property_dialog_new (PlannerWindow *main_window,
+ MrpProject *project,
+ GType owner,
+ const gchar *title);
+
+void planner_property_dialog_value_edited (GtkCellRendererText *cell,
+ gchar *path_str,
+ gchar *new_text,
+ gpointer data);
+
+/* Start of UNDO/REDO Proptotypes */
+
+static PlannerCmd *project_property_cmd_add (PlannerWindow *window,
+ MrpProject *project,
+ GType owner,
+ const gchar *name,
+ MrpPropertyType type,
+ const gchar *label_text,
+ const gchar *description,
+ gboolean user_defined);
+
+static gboolean project_property_cmd_add_do (PlannerCmd *cmd_base);
+static void project_property_cmd_add_undo (PlannerCmd *cmd_base);
+static void project_property_cmd_add_free (PlannerCmd *cmd_base);
+
+
+static PlannerCmd *project_property_cmd_remove (PlannerWindow *window,
+ MrpProject *project,
+ GType owner,
+ const gchar *name);
+static gboolean project_property_cmd_remove_do (PlannerCmd *cmd_base);
+static void project_property_cmd_remove_undo (PlannerCmd *cmd_base);
+static void project_property_cmd_remove_free (PlannerCmd *cmd_base);
+
+
+static PlannerCmd *project_property_cmd_label_edited (PlannerWindow *window,
+ MrpProperty *property,
+ const gchar *new_text);
+static gboolean project_property_cmd_label_edited_do (PlannerCmd *cmd_base);
+static void project_property_cmd_label_edited_undo (PlannerCmd *cmd_base);
+static void project_property_cmd_label_edited_free (PlannerCmd *cmd_base);
+
+/* End of UNDO/REDO Prototypes */
+
static void
property_dialog_setup_option_menu (GtkWidget *option_menu,
GCallback func,
@@ -132,6 +253,7 @@ property_dialog_type_selected_cb (GtkWid
g_object_set_data (G_OBJECT (dialog), "type", GINT_TO_POINTER (type));
}
+/* Note used for UNDO/REDO just for intra dialog work before the CLOSE button hit */
static gboolean
property_dialog_label_changed_cb (GtkWidget *label_entry,
GdkEvent *event,
@@ -155,7 +277,6 @@ property_dialog_add_cb (GtkWidget *butto
GtkWidget *dialog)
{
PlannerPropertyDialogPriv *priv;
- MrpProperty *property;
MrpPropertyType type;
const gchar *label;
const gchar *name;
@@ -168,6 +289,8 @@ property_dialog_add_cb (GtkWidget *butto
gint response;
gboolean finished = FALSE;
+ ProjectPropertyCmdAdd *cmd;
+
priv = GET_PRIV (dialog);
glade = glade_xml_new (GLADEDIR "/new-property.glade",
@@ -241,17 +364,17 @@ property_dialog_add_cb (GtkWidget *butto
type = property_dialog_get_selected (w);
+ /* Intercept property addition for undo/redo here */
if (type != MRP_PROPERTY_TYPE_NONE) {
- property = mrp_property_new (name,
+
+ cmd = (ProjectPropertyCmdAdd*) project_property_cmd_add (priv->main_window,
+ priv->project,
+ priv->owner,
+ name,
type,
label,
description,
TRUE);
-
- mrp_project_add_property (priv->project,
- priv->type,
- property,
- TRUE);
}
finished = TRUE;
@@ -280,6 +403,8 @@ property_dialog_remove_cb (GtkWidget *bu
GtkWidget *remove_dialog;
gint response;
+ ProjectPropertyCmdRemove *cmd;
+
priv = GET_PRIV (dialog);
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->tree));
@@ -305,9 +430,12 @@ property_dialog_remove_cb (GtkWidget *bu
switch (response) {
case GTK_RESPONSE_YES:
- mrp_project_remove_property (priv->project,
- priv->type,
+
+ cmd = (ProjectPropertyCmdRemove*) project_property_cmd_remove (priv->main_window,
+ priv->project,
+ priv->owner,
name);
+
break;
case GTK_RESPONSE_DELETE_EVENT:
@@ -334,6 +462,7 @@ property_dialog_label_edited (GtkCellRen
GtkTreeIter iter;
GtkTreeModel *model;
MrpProperty *property;
+ ProjectPropertyCmdLabelEdited *cmd;
priv = GET_PRIV (dialog);
@@ -346,7 +475,9 @@ property_dialog_label_edited (GtkCellRen
COL_PROPERTY, &property,
-1);
- mrp_property_set_label (property, new_text);
+ cmd = (ProjectPropertyCmdLabelEdited*) project_property_cmd_label_edited (priv->main_window,
+ property,
+ new_text);
gtk_tree_path_free (path);
}
@@ -442,8 +573,10 @@ property_dialog_setup_list (GtkWidget *d
#endif
}
+ /* Create the shop (a type of store) */
+ priv->shop = g_new0 (MrpPropertyStore, 1);
- model = planner_property_model_new (priv->project, priv->type);
+ model = planner_property_model_new (priv->project, priv->owner, priv->shop);
priv->model = model;
gtk_tree_view_set_model (tree, model);
@@ -483,8 +616,9 @@ property_dialog_setup_widgets (GtkWidget
}
GtkWidget *
-planner_property_dialog_new (MrpProject *project,
- GType owner_type,
+planner_property_dialog_new (PlannerWindow *main_window,
+ MrpProject *project,
+ GType owner,
const gchar *title)
{
GladeXML *glade;
@@ -504,8 +638,9 @@ planner_property_dialog_new (MrpProject
g_object_set_data (G_OBJECT (dialog), "priv", priv);
- priv->type = owner_type;
+ priv->main_window = main_window;
priv->project = project;
+ priv->owner = owner;
property_dialog_setup_widgets (dialog, glade);
@@ -545,3 +680,303 @@ planner_property_dialog_value_edited (Gt
gtk_tree_path_free (path);
}
+
+
+/* Start of UNDO/REDO routines */
+
+static gboolean
+project_property_cmd_add_do (PlannerCmd *cmd_base)
+{
+ ProjectPropertyCmdAdd *cmd;
+ MrpProperty *property;
+
+ cmd = (ProjectPropertyCmdAdd*) cmd_base;
+
+ if (cmd->name == NULL) {
+ return FALSE;
+ }
+
+ property = mrp_property_new (cmd->name,
+ cmd->type,
+ cmd->label_text,
+ cmd->description,
+ cmd->user_defined);
+
+ mrp_project_add_property (cmd->project,
+ cmd->owner,
+ property,
+ cmd->user_defined);
+
+ /* This functions as a simple success check for the REDO/UNDO stuff. Check if its added. */
+ if (!mrp_project_has_property (cmd->project, cmd->owner, cmd->name)) {
+ g_warning ("%s: object of type '%s' still has no property named '%s'",
+ G_STRLOC,
+ g_type_name (cmd->owner),
+ cmd->name);
+ return FALSE;
+ }
+
+ return TRUE;
+
+}
+
+static void
+project_property_cmd_add_undo (PlannerCmd *cmd_base)
+{
+ ProjectPropertyCmdAdd *cmd;
+
+ cmd = (ProjectPropertyCmdAdd*) cmd_base;
+
+ if (cmd->name != NULL) {
+
+ mrp_project_remove_property (cmd->project,
+ cmd->owner,
+ cmd->name);
+
+ /* This functions as a simple success check for the REDO/UNDO stuff. Check if its removed. */
+ if (mrp_project_has_property (cmd->project, cmd->owner, cmd->name)) {
+ g_warning ("%s: object of type '%s' still has the property named '%s'",
+ G_STRLOC,
+ g_type_name (cmd->owner),
+ cmd->name);
+ }
+ }
+}
+
+
+static void
+project_property_cmd_add_free (PlannerCmd *cmd_base)
+{
+ ProjectPropertyCmdAdd *cmd;
+
+ cmd = (ProjectPropertyCmdAdd*) cmd_base;
+
+ g_free (cmd->name);
+ g_free (cmd->label_text);
+ g_free (cmd->description);
+ cmd->project = NULL;
+ cmd->window = NULL;
+}
+
+static
+PlannerCmd *
+project_property_cmd_add (PlannerWindow *window,
+ MrpProject *project,
+ GType owner,
+ const gchar *name,
+ MrpPropertyType type,
+ const gchar *label_text,
+ const gchar *description,
+ gboolean user_defined)
+{
+ PlannerCmd *cmd_base;
+ ProjectPropertyCmdAdd *cmd;
+
+ cmd_base = planner_cmd_new (ProjectPropertyCmdAdd,
+ _("Add property"),
+ project_property_cmd_add_do,
+ project_property_cmd_add_undo,
+ project_property_cmd_add_free);
+
+ cmd = (ProjectPropertyCmdAdd *) cmd_base;
+
+ cmd->window = window;
+ cmd->project = project;
+ cmd->owner = owner;
+ cmd->name = g_strdup (name);
+ cmd->type = type;
+ cmd->label_text = g_strdup (label_text);
+ cmd->description = g_strdup (description);
+ cmd->user_defined = user_defined;
+
+ planner_cmd_manager_insert_and_do (planner_window_get_cmd_manager (window),
+ cmd_base);
+
+ return cmd_base;
+}
+
+
+static gboolean
+project_property_cmd_remove_do (PlannerCmd *cmd_base)
+{
+ ProjectPropertyCmdRemove *cmd;
+
+ cmd = (ProjectPropertyCmdRemove*) cmd_base;
+
+ if (!mrp_project_has_property (cmd->project, cmd->owner, cmd->name)) {
+ g_warning ("%s: object of type '%s' has no property named '%s' to remove",
+ G_STRLOC,
+ g_type_name (cmd->owner),
+ cmd->name);
+ return FALSE;
+ }
+
+ mrp_project_remove_property (cmd->project,
+ cmd->owner,
+ cmd->name);
+
+ return TRUE;
+}
+
+
+static void
+project_property_cmd_remove_undo (PlannerCmd *cmd_base)
+{
+ ProjectPropertyCmdRemove *cmd;
+ MrpProperty *property;
+
+ cmd = (ProjectPropertyCmdRemove*) cmd_base;
+
+ if (cmd->name != NULL) {
+
+ property = mrp_property_new (cmd->name,
+ cmd->type,
+ cmd->label_text,
+ cmd->description,
+ cmd->user_defined);
+
+ mrp_project_add_property (cmd->project,
+ cmd->owner,
+ property,
+ cmd->user_defined);
+
+
+ /* This functions as a simple success check for the REDO/UNDO stuff. Check if its removed. */
+ if (!mrp_project_has_property (cmd->project, cmd->owner, cmd->name)) {
+ g_warning ("%s: object of type '%s' property named '%s' not restored.",
+ G_STRLOC,
+ g_type_name (cmd->owner),
+ cmd->name);
+ }
+ }
+}
+
+static void
+project_property_cmd_remove_free (PlannerCmd *cmd_base)
+{
+ ProjectPropertyCmdRemove *cmd;
+
+ cmd = (ProjectPropertyCmdRemove*) cmd_base;
+
+ g_free (cmd->name);
+ g_free (cmd->label_text);
+ g_free (cmd->description);
+ cmd->project = NULL;
+ cmd->window = NULL;
+}
+
+static PlannerCmd *
+project_property_cmd_remove (PlannerWindow *window,
+ MrpProject *project,
+ GType owner,
+ const gchar *name)
+{
+ PlannerCmd *cmd_base;
+ ProjectPropertyCmdRemove *cmd;
+ MrpProperty *property;
+
+ cmd_base = planner_cmd_new (ProjectPropertyCmdRemove,
+ _("Add property"),
+ project_property_cmd_remove_do,
+ project_property_cmd_remove_undo,
+ project_property_cmd_remove_free);
+
+ cmd = (ProjectPropertyCmdRemove *) cmd_base;
+
+ cmd->window = window;
+ cmd->project = project;
+ cmd->owner = owner;
+ cmd->name = g_strdup (name);
+ /* Now remember also the old data so we can undo the remove */
+ property = mrp_project_get_property (project,
+ name,
+ owner);
+
+ cmd->type = mrp_property_get_property_type (property);
+ cmd->description = g_strdup (mrp_property_get_description (property));
+ cmd->label_text = g_strdup ( mrp_property_get_label (property));
+ cmd->user_defined = mrp_property_get_user_defined (property);
+
+ planner_cmd_manager_insert_and_do (planner_window_get_cmd_manager (window),
+ cmd_base);
+
+ return cmd_base;
+}
+
+/* Label Edited Routine */
+
+static gboolean
+project_property_cmd_label_edited_do (PlannerCmd *cmd_base)
+{
+ ProjectPropertyCmdLabelEdited *cmd;
+
+ cmd = (ProjectPropertyCmdLabelEdited*) cmd_base;
+
+ if (!cmd->property) {
+ return FALSE;
+ }
+
+ mrp_property_set_label (cmd->property, cmd->new_text);
+
+ return TRUE;
+}
+
+
+static void
+project_property_cmd_label_edited_undo (PlannerCmd *cmd_base)
+{
+ ProjectPropertyCmdLabelEdited *cmd;
+
+ cmd = (ProjectPropertyCmdLabelEdited*) cmd_base;
+
+ if (cmd->property != NULL) {
+
+ mrp_property_set_label (cmd->property, cmd->old_text);
+
+ }
+}
+
+static void
+project_property_cmd_label_edited_free (PlannerCmd *cmd_base)
+{
+ ProjectPropertyCmdLabelEdited *cmd;
+
+ cmd = (ProjectPropertyCmdLabelEdited*) cmd_base;
+
+ g_free (cmd->old_text);
+ g_free (cmd->new_text);
+ cmd->property = NULL;
+ cmd->window = NULL;
+}
+
+static PlannerCmd *
+project_property_cmd_label_edited (PlannerWindow *window,
+ MrpProperty *property,
+ const gchar *new_text)
+{
+ PlannerCmd *cmd_base;
+ ProjectPropertyCmdLabelEdited *cmd;
+
+ cmd_base = planner_cmd_new (ProjectPropertyCmdLabelEdited,
+ _("Add property"),
+ project_property_cmd_label_edited_do,
+ project_property_cmd_label_edited_undo,
+ project_property_cmd_label_edited_free);
+
+ cmd = (ProjectPropertyCmdLabelEdited *) cmd_base;
+
+ cmd->window = window;
+ cmd->property = property;
+ cmd->new_text = g_strdup (new_text);
+
+ /* Now remember also the old data so we can undo the label edit */
+
+ cmd->old_text = g_strdup ( mrp_property_get_label (property));
+
+ planner_cmd_manager_insert_and_do (planner_window_get_cmd_manager (window),
+ cmd_base);
+
+ return cmd_base;
+}
+
+/* end of UNDO/REDO routines */
Index: src/planner-property-dialog.h
===================================================================
RCS file: /cvs/gnome/planner/src/planner-property-dialog.h,v
retrieving revision 1.2
diff -u -b -B -p -r1.2 planner-property-dialog.h
--- a/src/planner-property-dialog.h 11 Dec 2003 10:52:46 -0000 1.2
+++ b/src/planner-property-dialog.h 24 May 2004 04:18:34 -0000
@@ -24,8 +24,10 @@
#include <gtk/gtkwidget.h>
#include <libplanner/mrp-project.h>
+#include <planner-window.h>
-GtkWidget *planner_property_dialog_new (MrpProject *project,
+GtkWidget *planner_property_dialog_new (PlannerWindow *main_window,
+ MrpProject *project,
GType owner_type,
const gchar *title);
Index: src/planner-property-model.c
===================================================================
RCS file: /cvs/gnome/planner/src/planner-property-model.c,v
retrieving revision 1.1.1.1
diff -u -b -B -p -r1.1.1.1 planner-property-model.c
--- a/src/planner-property-model.c 1 Dec 2003 17:36:25 -0000 1.1.1.1
+++ b/src/planner-property-model.c 24 May 2004 04:18:34 -0000
@@ -31,13 +31,21 @@
static void
property_model_property_added_cb (MrpProject *project,
- GType object_type,
+ GType owner_type,
MrpProperty *property,
- GtkListStore *store)
+ MrpPropertyStore *shop)
{
GtkTreeIter iter;
MrpPropertyType type;
+ GtkListStore *store;
+
+ if (owner_type != shop->owner_type) {
+ return;
+ }
+
+ store = shop->store;
+ if (store) {
type = mrp_property_get_property_type (property);
gtk_list_store_append (store, &iter);
@@ -48,6 +56,7 @@ property_model_property_added_cb (MrpPro
COL_TYPE, mrp_property_type_as_string (type),
COL_PROPERTY, property,
-1);
+ }
}
static gboolean
@@ -126,7 +135,8 @@ property_model_property_changed_cb (MrpP
GtkTreeModel *
planner_property_model_new (MrpProject *project,
- GType owner_type)
+ GType owner_type,
+ MrpPropertyStore *shop)
{
GtkListStore *store;
GList *properties, *l;
@@ -141,6 +151,9 @@ planner_property_model_new (MrpProject *
G_TYPE_POINTER,
G_TYPE_POINTER);
+ shop->store = store;
+ shop->owner_type = owner_type;
+
properties = mrp_project_get_properties_from_type (project,
owner_type);
@@ -159,10 +172,15 @@ planner_property_model_new (MrpProject *
-1);
}
+ /* We need to know which store to add the property so we pass the shop
+ * reference not the store. The shop is a structure that correlates
+ * which store currently holds which owner. We don't have to bother with
+ * this when changing or removing - just adding.
+ */
g_signal_connect (project,
"property_added",
G_CALLBACK (property_model_property_added_cb),
- store);
+ shop);
g_signal_connect (project,
"property_removed",
Index: src/planner-property-model.h
===================================================================
RCS file: /cvs/gnome/planner/src/planner-property-model.h,v
retrieving revision 1.2
diff -u -b -B -p -r1.2 planner-property-model.h
--- a/src/planner-property-model.h 11 Dec 2003 10:52:46 -0000 1.2
+++ b/src/planner-property-model.h 24 May 2004 04:18:34 -0000
@@ -30,11 +30,22 @@ enum {
COL_LABEL,
COL_TYPE,
COL_VALUE,
- COL_PROPERTY,
+ COL_PROPERTY
};
+/* This was added because we were incorrectly adding properties to
+* a store when we got a property-added message. stores are not typed
+* per se and we can't extend them so created a 'shop' (i.e. a
+* type of store :) with an owner
+*/
+typedef struct {
+ GType owner_type;
+ GtkListStore *store;
+} MrpPropertyStore;
+
GtkTreeModel *planner_property_model_new (MrpProject *project,
- GType owner_type);
+ GType owner_type,
+ MrpPropertyStore *shop);
#endif /* __PLANNER_PROPERTY_MODEL_H__ */
Index: src/planner-resource-view.c
===================================================================
RCS file: /cvs/gnome/planner/src/planner-resource-view.c,v
retrieving revision 1.19
diff -u -b -B -p -r1.19 planner-resource-view.c
--- a/src/planner-resource-view.c 3 May 2004 05:23:52 -0000 1.19
+++ b/src/planner-resource-view.c 24 May 2004 04:18:38 -0000
@@ -166,6 +166,10 @@ static void resource_view_property_re
MrpProperty *property,
PlannerView *view);
+static void resource_view_property_changed (MrpProject *project,
+ MrpProperty *property,
+ PlannerView *view);
+
static void resource_view_name_data_func (GtkTreeViewColumn *tree_column,
GtkCellRenderer *cell,
GtkTreeModel *tree_model,
@@ -450,6 +454,11 @@ get_widget (PlannerView *view)
view);
g_signal_connect (project,
+ "property_changed",
+ G_CALLBACK (resource_view_property_changed),
+ view);
+
+ g_signal_connect (project,
"resource_added",
G_CALLBACK (resource_view_resource_added_cb),
view);
@@ -1046,7 +1055,8 @@ resource_view_edit_custom_props_cb (Bono
project = planner_window_get_project (view->main_window);
- dialog = planner_property_dialog_new (project,
+ dialog = planner_property_dialog_new (view->main_window,
+ project,
MRP_TYPE_RESOURCE,
_("Edit custom resource properties"));
@@ -2020,6 +2030,23 @@ resource_view_property_removed (MrpProje
}
static void
+resource_view_property_changed (MrpProject *project,
+ MrpProperty *property,
+ PlannerView *view)
+{
+ PlannerViewPriv *priv;
+ GtkTreeViewColumn *col;
+
+ priv = view->priv;
+
+ col = g_hash_table_lookup (priv->property_to_column, property);
+ if (col) {
+ gtk_tree_view_column_set_title (col,
+ mrp_property_get_label (property));
+ }
+}
+
+static void
resource_view_popup_menu (GtkWidget *widget,
PlannerView *view)
{
Index: src/planner-task-tree.c
===================================================================
RCS file: /cvs/gnome/planner/src/planner-task-tree.c,v
retrieving revision 1.25
diff -u -b -B -p -r1.25 planner-task-tree.c
--- a/src/planner-task-tree.c 18 May 2004 03:09:41 -0000 1.25
+++ b/src/planner-task-tree.c 24 May 2004 04:18:39 -0000
@@ -2376,6 +2376,23 @@ task_tree_property_removed (MrpProject
}
}
+static void
+task_tree_property_changed (MrpProject *project,
+ MrpProperty *property,
+ PlannerTaskTree *task_tree)
+{
+ PlannerTaskTreePriv *priv;
+ GtkTreeViewColumn *col;
+
+ priv = task_tree->priv;
+
+ col = g_hash_table_lookup (priv->property_to_column, property);
+ if (col) {
+ gtk_tree_view_column_set_title (col,
+ mrp_property_get_label (property));
+ }
+}
+
void
planner_task_tree_set_model (PlannerTaskTree *tree,
PlannerGanttModel *model)
@@ -2447,6 +2464,11 @@ task_tree_setup_tree_view (GtkTreeView
"property_removed",
G_CALLBACK (task_tree_property_removed),
tree);
+
+ g_signal_connect (project,
+ "property_changed",
+ G_CALLBACK (task_tree_property_changed),
+ tree);
}
}
Index: src/planner-task-view.c
===================================================================
RCS file: /cvs/gnome/planner/src/planner-task-view.c,v
retrieving revision 1.9
diff -u -b -B -p -r1.9 planner-task-view.c
--- a/src/planner-task-view.c 27 Apr 2004 18:58:02 -0000 1.9
+++ b/src/planner-task-view.c 24 May 2004 04:18:40 -0000
@@ -474,7 +474,8 @@ task_view_edit_custom_props_cb (BonoboUI
project = planner_window_get_project (view->main_window);
- dialog = planner_property_dialog_new (project,
+ dialog = planner_property_dialog_new (view->main_window,
+ project,
MRP_TYPE_TASK,
_("Edit custom task properties"));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]