From e8648e48175c1b6d26bff5316c2c7d738245a63c Mon Sep 17 00:00:00 2001 From: Damon Chaplin Date: Wed, 6 Sep 2000 00:13:05 +0000 Subject: uses the new TaskEditor dialog. 2000-09-06 Damon Chaplin * gui/e-calendar-table.c (e_calendar_table_open_task): uses the new TaskEditor dialog. * gui/dialogs/task-editor.[hc]: * gui/dialogs/task-editor-dialog.glade: updated. Still need to fix the 'Status' property (CalComponent doesn't support it yet), and use a replacement for GnomeDateEdit, since we need to support setting 'None' as the date. 2000-09-04 Damon Chaplin * gui/event-editor.c (obj_updated_cb): (obj_removed_cb): compare the updated object's uid with the one we are editing, and just return if it doesn't match. 2000-09-01 Damon Chaplin * gui/gnome-cal.c (gnome_calendar_tag_calendar): added check to see if the client has loaded successfully. Gets rid of a few warnings. svn path=/trunk/; revision=5217 --- calendar/gui/dialogs/task-editor-dialog.glade | 386 ++++------ calendar/gui/dialogs/task-editor-dialog.glade.h | 16 +- calendar/gui/dialogs/task-editor.c | 929 +++++++++++++++++++++++- calendar/gui/dialogs/task-editor.h | 5 + calendar/gui/dialogs/task-page.glade | 386 ++++------ 5 files changed, 1186 insertions(+), 536 deletions(-) (limited to 'calendar/gui/dialogs') diff --git a/calendar/gui/dialogs/task-editor-dialog.glade b/calendar/gui/dialogs/task-editor-dialog.glade index 56f7f83422..8a8ca800d6 100644 --- a/calendar/gui/dialogs/task-editor-dialog.glade +++ b/calendar/gui/dialogs/task-editor-dialog.glade @@ -18,9 +18,11 @@ GnomeApp task-editor-dialog False + task-editor-dialog GTK_WINDOW_TOPLEVEL GTK_WIN_POS_NONE False + 350 False True False @@ -61,7 +63,7 @@ GtkTable table3 - 2 + 1 2 False 4 @@ -75,19 +77,19 @@ GtkLabel label3 - + GTK_JUSTIFY_CENTER False 0.5 0.5 0 0 - entry1 + summary 0 1 - 1 - 2 + 0 + 1 0 0 False @@ -101,7 +103,7 @@ GtkEntry - entry1 + summary True True True @@ -110,63 +112,11 @@ 1 2 - 1 - 2 - 0 - 0 - True - False - False - False - True - False - - - - - GtkLabel - label10 - - GTK_JUSTIFY_CENTER - False - 0 - 0.5 - 0 - 0 - - 0 - 1 0 1 0 0 - False - False - False - False - True - False - - - - - GtkLabel - label11 - - GTK_JUSTIFY_CENTER - False - 0 - 0.5 - 0 - 0 - - 1 - 2 - 0 - 1 - 0 - 0 - False + True False False False @@ -201,7 +151,7 @@ GtkTable table1 2 - 2 + 4 False 2 4 @@ -213,9 +163,9 @@ GnomeDateEdit - dateedit1 + due-date True - False + True False 7 19 @@ -237,7 +187,7 @@ GnomeDateEdit - dateedit2 + start-date True True False @@ -310,6 +260,66 @@ False + + + GtkLabel + label9 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + percent-complete + + 2 + 3 + 0 + 1 + 0 + 0 + False + False + False + False + False + False + + + + + GtkSpinButton + percent-complete + 60 + True + 1 + 0 + False + GTK_UPDATE_ALWAYS + False + False + 0 + 0 + 100 + 10 + 10 + 10 + + 3 + 4 + 0 + 1 + 0 + 0 + True + False + False + False + True + False + + @@ -344,7 +354,7 @@ 0.5 0 0 - combo-entry1 + status 0 False @@ -353,35 +363,20 @@ - GtkCombo - combo1 - False - True - False - True - False + GtkOptionMenu + status + True Not Started In Progress Completed Cancelled + 0 0 - True - True + False + False - - - GtkEntry - GtkCombo:entry - combo-entry1 - 60 - True - True - True - 0 - Not Started - @@ -394,7 +389,7 @@ Cancelled 0.5 0 0 - combo-entry2 + priority 0 False @@ -403,47 +398,32 @@ Cancelled - GtkCombo - combo2 - False - True - False - True - False + GtkOptionMenu + priority + True High Normal Low + 0 0 - True - True + False + False - - - GtkEntry - GtkCombo:entry - combo-entry2 - 60 - True - False - True - 0 - High - GtkLabel - label9 - + label18 + GTK_JUSTIFY_CENTER False 0.5 0.5 0 0 - spinbutton1 + classification 0 False @@ -452,25 +432,18 @@ Low - GtkSpinButton - spinbutton1 + GtkOptionMenu + classification True - 1 - 0 - False - GTK_UPDATE_ALWAYS - False - False - 0 - 0 - 100 - 10 - 10 - 10 + Public +Private +Confidential + + 0 0 - True - True + False + False @@ -490,8 +463,7 @@ Low GtkText - text1 - 150 + description True True @@ -513,17 +485,30 @@ Low GtkButton button3 True - 0 False False + + + GtkLabel + label16 + False + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 4 + 0 + GtkEntry - entry2 + contacts + False True True True @@ -540,17 +525,30 @@ Low GtkButton button4 True - 0 False False + + + GtkLabel + label17 + False + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 4 + 0 + GtkEntry - entry3 + categories + False True True True @@ -562,20 +560,6 @@ Low True - - - GtkCheckButton - checkbutton1 - True - - False - True - - 0 - False - False - - @@ -596,7 +580,7 @@ Low GtkTable table4 4 - 4 + 2 2 False 2 @@ -604,7 +588,7 @@ Low GnomeDateEdit - dateedit3 + completed-date True True False @@ -652,32 +636,6 @@ Low - - GtkLabel - label13 - - GTK_JUSTIFY_CENTER - False - 0 - 0.5 - 0 - 0 - - 0 - 1 - 1 - 2 - 0 - 0 - False - False - False - False - True - False - - - GtkLabel label14 @@ -691,84 +649,10 @@ Low 0 1 - 2 - 3 - 0 - 0 - False - False - False - False - True - False - - - - - GtkEntry - entry4 - True - True - True - 0 - - - 1 - 2 1 2 0 0 - True - False - False - False - True - False - - - - - GtkEntry - entry5 - True - True - True - 0 - - - 1 - 2 - 2 - 3 - 0 - 0 - True - False - False - False - True - False - - - - - GtkLabel - label15 - - GTK_JUSTIFY_CENTER - False - 0 - 0.5 - 0 - 0 - - 0 - 1 - 3 - 4 - 0 - 0 False False False @@ -780,7 +664,7 @@ Low GtkEntry - entry6 + url True True True @@ -789,8 +673,8 @@ Low 1 2 - 3 - 4 + 1 + 2 0 0 True diff --git a/calendar/gui/dialogs/task-editor-dialog.glade.h b/calendar/gui/dialogs/task-editor-dialog.glade.h index 9ee959817f..9c20880b51 100644 --- a/calendar/gui/dialogs/task-editor-dialog.glade.h +++ b/calendar/gui/dialogs/task-editor-dialog.glade.h @@ -4,30 +4,30 @@ * DO NOT compile it as part of your application. */ -gchar *s = N_("S_ubject:"); -gchar *s = N_("Owner:"); +gchar *s = N_("task-editor-dialog"); +gchar *s = N_("S_ummary"); gchar *s = N_("Sta_rt Date:"); gchar *s = N_("_Due Date:"); +gchar *s = N_("% Comp_lete:"); gchar *s = N_("_Status:"); gchar *s = N_("Not Started\n" "In Progress\n" "Completed\n" "Cancelled\n" ""); -gchar *s = N_("Not Started"); gchar *s = N_("_Priority:"); gchar *s = N_("High\n" "Normal\n" "Low\n" ""); -gchar *s = N_("High"); -gchar *s = N_("% Comp_lete:"); +gchar *s = N_("C_lassification:"); +gchar *s = N_("Public\n" + "Private\n" + "Confidential\n" + ""); gchar *s = N_("_Contacts..."); gchar *s = N_("Ca_tegories..."); -gchar *s = N_("Private"); gchar *s = N_("Task"); gchar *s = N_("Date Completed:"); -gchar *s = N_("Location:"); gchar *s = N_("URL:"); -gchar *s = N_("Resources:"); gchar *s = N_("Details"); diff --git a/calendar/gui/dialogs/task-editor.c b/calendar/gui/dialogs/task-editor.c index dd40c1b9df..a91278b84a 100644 --- a/calendar/gui/dialogs/task-editor.c +++ b/calendar/gui/dialogs/task-editor.c @@ -31,6 +31,8 @@ #include #include #include +#include +#include #include #include "task-editor.h" @@ -42,25 +44,118 @@ typedef struct { /* UI handler */ BonoboUIHandler *uih; + /* Client to use */ + CalClient *client; + /* Calendar component we are editing; this is an internal copy and is * not one of the read-only objects from the parent calendar. */ CalComponent *comp; + + /* This is TRUE while we are setting the widget values. We just return + from any signal handlers. */ + gboolean ignore_callbacks; + /* Widgets from the Glade file */ GtkWidget *app; + + GtkWidget *summary; + + GtkWidget *due_date; + GtkWidget *start_date; + + GtkWidget *percent_complete; + + GtkWidget *status; + GtkWidget *priority; + GtkWidget *classification; + + GtkWidget *description; + + GtkWidget *contacts; + GtkWidget *categories; + + GtkWidget *completed_date; + GtkWidget *url; } TaskEditorPrivate; +/* CalComponent doesn't support status yet, so we use this temporarily. */ +typedef enum { + STATUS_NOT_STARTED, + STATUS_IN_PROGRESS, + STATUS_COMPLETED, + STATUS_CANCELLED +} TaskEditorStatus; + +static const int status_map[] = { + STATUS_NOT_STARTED, + STATUS_IN_PROGRESS, + STATUS_COMPLETED, + STATUS_CANCELLED, + -1 +}; + +typedef enum { + PRIORITY_HIGH, + PRIORITY_NORMAL, + PRIORITY_LOW, + PRIORITY_UNDEFINED, +} TaskEditorPriority; + +static const int priority_map[] = { + PRIORITY_HIGH, + PRIORITY_NORMAL, + PRIORITY_LOW, + PRIORITY_UNDEFINED, + -1 +}; + +static const int classification_map[] = { + CAL_COMPONENT_CLASS_PUBLIC, + CAL_COMPONENT_CLASS_PRIVATE, + CAL_COMPONENT_CLASS_CONFIDENTIAL, + -1 +}; + static void task_editor_class_init (TaskEditorClass *class); static void task_editor_init (TaskEditor *tedit); -TaskEditor * task_editor_construct (TaskEditor *tedit); +static gint app_delete_event_cb (GtkWidget *widget, + GdkEvent *event, + gpointer data); +static void close_dialog (TaskEditor *tedit); static gboolean get_widgets (TaskEditor *tedit); static void init_widgets (TaskEditor *tedit); static void create_menu (TaskEditor *tedit); static void create_toolbar (TaskEditor *tedit); static void task_editor_destroy (GtkObject *object); +static char * make_title_from_comp (CalComponent *comp); +static void clear_widgets (TaskEditor *tedit); +static void fill_widgets (TaskEditor *tedit); + +static void file_save_cb (GtkWidget *widget, gpointer data); +static void file_save_and_close_cb (GtkWidget *widget, gpointer data); +static void file_delete_cb (GtkWidget *widget, gpointer data); +static void file_close_cb (GtkWidget *widget, gpointer data); + +static void save_todo_object (TaskEditor *tedit); +static void dialog_to_comp_object (TaskEditor *tedit); + +static void obj_updated_cb (CalClient *client, const char *uid, gpointer data); +static void obj_removed_cb (CalClient *client, const char *uid, gpointer data); +static void raise_and_focus (GtkWidget *widget); + +static TaskEditorPriority priority_value_to_index (int priority_value); +static int priority_index_to_value (TaskEditorPriority priority); + +static void completed_date_changed (GnomeDateEdit *dedit, + TaskEditor *tedit); +static void status_changed (GtkMenu *menu, + TaskEditor *tedit); +static void percent_complete_changed (GtkAdjustment *adj, + TaskEditor *tedit); static GtkObjectClass *parent_class; @@ -77,7 +172,6 @@ task_editor_class_init (TaskEditorClass *class) parent_class = gtk_type_class (GTK_TYPE_OBJECT); - object_class->destroy = task_editor_destroy; } @@ -89,6 +183,8 @@ task_editor_init (TaskEditor *tedit) priv = g_new0 (TaskEditorPrivate, 1); tedit->priv = priv; + + priv->ignore_callbacks = FALSE; } @@ -104,7 +200,6 @@ task_editor_new (void) TaskEditor *tedit; tedit = TASK_EDITOR (gtk_type_new (task_editor_get_type ())); - return task_editor_construct (tedit); } @@ -159,10 +254,8 @@ task_editor_construct (TaskEditor *tedit) /* Hook to destruction of the dialog */ -#if 0 gtk_signal_connect (GTK_OBJECT (priv->app), "delete_event", GTK_SIGNAL_FUNC (app_delete_event_cb), tedit); -#endif /* Show the dialog */ @@ -177,6 +270,35 @@ task_editor_construct (TaskEditor *tedit) } +/* Callback used when the dialog box is destroyed */ +static gint +app_delete_event_cb (GtkWidget *widget, GdkEvent *event, gpointer data) +{ + TaskEditor *tedit; + + /* FIXME: need to check for a dirty object */ + + tedit = TASK_EDITOR (data); + close_dialog (tedit); + + return TRUE; +} + + +/* Closes the dialog box and emits the appropriate signals */ +static void +close_dialog (TaskEditor *tedit) +{ + TaskEditorPrivate *priv; + + priv = tedit->priv; + + g_assert (priv->app != NULL); + + gtk_object_destroy (GTK_OBJECT (tedit)); +} + + /* Gets the widgets from the XML file and returns if they are all available. * For the widgets whose values can be simply set with e-dialog-utils, it does * that as well. @@ -192,7 +314,40 @@ get_widgets (TaskEditor *tedit) priv->app = GW ("task-editor-dialog"); - return TRUE; + priv->summary = GW ("summary"); + + priv->due_date = GW ("due-date"); + priv->start_date = GW ("start-date"); + + priv->percent_complete = GW ("percent-complete"); + + priv->status = GW ("status"); + priv->priority = GW ("priority"); + priv->classification = GW ("classification"); + + priv->description = GW ("description"); + + priv->contacts = GW ("contacts"); + priv->categories = GW ("categories"); + + priv->completed_date = GW ("completed-date"); + priv->url = GW ("url"); + +#undef GW + + return (priv->app + && priv->summary + && priv->due_date + && priv->start_date + && priv->percent_complete + && priv->status + && priv->priority + && priv->classification + && priv->description + && priv->contacts + && priv->categories + && priv->completed_date + && priv->url); } @@ -201,9 +356,59 @@ static void init_widgets (TaskEditor *tedit) { TaskEditorPrivate *priv; + GnomeDateEdit *gde; + GtkWidget *widget; priv = tedit->priv; + + /* Connect signals. The Status, Percent Complete & Date Completed + properties are closely related so whenever one changes we may need + to update the other 2. */ + gtk_signal_connect (GTK_OBJECT (priv->completed_date), "date_changed", + GTK_SIGNAL_FUNC (completed_date_changed), tedit); + gtk_signal_connect (GTK_OBJECT (priv->completed_date), "time_changed", + GTK_SIGNAL_FUNC (completed_date_changed), tedit); + + gtk_signal_connect (GTK_OBJECT (GTK_OPTION_MENU (priv->status)->menu), + "deactivate", + GTK_SIGNAL_FUNC (status_changed), tedit); + + gtk_signal_connect (GTK_OBJECT (GTK_SPIN_BUTTON (priv->percent_complete)->adjustment), + "value_changed", + GTK_SIGNAL_FUNC (percent_complete_changed), tedit); + + + /* Hide the stupid 'Calendar' labels. */ + gde = GNOME_DATE_EDIT (priv->due_date); + gtk_widget_hide (gde->cal_label); + widget = gde->date_entry; + gtk_box_set_child_packing (GTK_BOX (widget->parent), widget, + FALSE, FALSE, 0, GTK_PACK_START); + widget = gde->time_entry; + gtk_box_set_child_packing (GTK_BOX (widget->parent), widget, + FALSE, FALSE, 0, GTK_PACK_START); + gtk_box_set_spacing (GTK_BOX (widget->parent), 2); + + gde = GNOME_DATE_EDIT (priv->start_date); + gtk_widget_hide (gde->cal_label); + widget = gde->date_entry; + gtk_box_set_child_packing (GTK_BOX (widget->parent), widget, + FALSE, FALSE, 0, GTK_PACK_START); + widget = gde->time_entry; + gtk_box_set_child_packing (GTK_BOX (widget->parent), widget, + FALSE, FALSE, 0, GTK_PACK_START); + gtk_box_set_spacing (GTK_BOX (widget->parent), 2); + + gde = GNOME_DATE_EDIT (priv->completed_date); + gtk_widget_hide (gde->cal_label); + widget = gde->date_entry; + gtk_box_set_child_packing (GTK_BOX (widget->parent), widget, + FALSE, FALSE, 0, GTK_PACK_START); + widget = gde->time_entry; + gtk_box_set_child_packing (GTK_BOX (widget->parent), widget, + FALSE, FALSE, 0, GTK_PACK_START); + gtk_box_set_spacing (GTK_BOX (widget->parent), 2); } @@ -238,11 +443,12 @@ static GnomeUIInfo file_menu[] = { GNOMEUIINFO_SEPARATOR, GNOMEUIINFO_ITEM_NONE (N_("FIXME: S_end"), NULL, NULL), GNOMEUIINFO_SEPARATOR, - GNOMEUIINFO_MENU_SAVE_ITEM (NULL, NULL), + GNOMEUIINFO_MENU_SAVE_ITEM (file_save_cb, NULL), GNOMEUIINFO_MENU_SAVE_AS_ITEM (NULL, NULL), GNOMEUIINFO_ITEM_NONE (N_("FIXME: Save Attac_hments..."), NULL, NULL), GNOMEUIINFO_SEPARATOR, - GNOMEUIINFO_ITEM_NONE (N_("FIXME: _Delete"), NULL, NULL), + GNOMEUIINFO_ITEM_STOCK (N_("_Delete"), NULL, + file_delete_cb, GNOME_STOCK_PIXMAP_TRASH), GNOMEUIINFO_ITEM_NONE (N_("FIXME: _Move to Folder..."), NULL, NULL), GNOMEUIINFO_ITEM_NONE (N_("FIXME: Cop_y to Folder..."), NULL, NULL), GNOMEUIINFO_SEPARATOR, @@ -252,7 +458,7 @@ static GnomeUIInfo file_menu[] = { GNOMEUIINFO_SEPARATOR, GNOMEUIINFO_MENU_PROPERTIES_ITEM (NULL, NULL), GNOMEUIINFO_SEPARATOR, - GNOMEUIINFO_MENU_CLOSE_ITEM (NULL, NULL), + GNOMEUIINFO_MENU_CLOSE_ITEM (file_close_cb, NULL), GNOMEUIINFO_END }; @@ -406,31 +612,43 @@ create_menu (TaskEditor *tedit) /* Toolbar */ static GnomeUIInfo toolbar[] = { - GNOMEUIINFO_ITEM_STOCK (N_("FIXME: Save and Close"), + GNOMEUIINFO_ITEM_STOCK (N_("Save and Close"), N_("Save the task and close the dialog box"), - NULL, + file_save_and_close_cb, GNOME_STOCK_PIXMAP_SAVE), GNOMEUIINFO_SEPARATOR, - GNOMEUIINFO_ITEM_NONE (N_("FIXME: Print..."), - N_("Print this item"), NULL), - GNOMEUIINFO_ITEM_NONE (N_("FIXME: Insert File..."), - N_("Insert a file as an attachment"), NULL), - GNOMEUIINFO_SEPARATOR, - GNOMEUIINFO_ITEM_NONE (N_("FIXME: Recurrence..."), - N_("Configure recurrence rules"), NULL), + GNOMEUIINFO_ITEM_STOCK (N_("FIXME: Print..."), + N_("Print this item"), + NULL, + GNOME_STOCK_PIXMAP_PRINT), + GNOMEUIINFO_ITEM_STOCK (N_("FIXME: Insert File..."), + N_("Insert a file as an attachment"), + NULL, + GNOME_STOCK_PIXMAP_ATTACH), GNOMEUIINFO_SEPARATOR, +#if 0 GNOMEUIINFO_ITEM_NONE (N_("FIXME: Assign Task..."), - N_("Assign the task to someone"), NULL), + N_("Assign the task to someone"), + NULL), GNOMEUIINFO_SEPARATOR, - GNOMEUIINFO_ITEM_NONE (N_("FIXME: Delete"), - N_("Delete this item"), NULL), +#endif + GNOMEUIINFO_ITEM_STOCK (N_("Delete"), + N_("Delete this task"), + file_delete_cb, + GNOME_STOCK_PIXMAP_TRASH), GNOMEUIINFO_SEPARATOR, - GNOMEUIINFO_ITEM_NONE (N_("FIXME: Previous"), - N_("Go to the previous item"), NULL), - GNOMEUIINFO_ITEM_NONE (N_("FIXME: Next"), - N_("Go to the next item"), NULL), + GNOMEUIINFO_ITEM_STOCK (N_("FIXME: Previous"), + N_("Go to the previous item"), + NULL, + GNOME_STOCK_PIXMAP_BACK), + GNOMEUIINFO_ITEM_STOCK (N_("FIXME: Next"), + N_("Go to the next item"), + NULL, + GNOME_STOCK_PIXMAP_FORWARD), GNOMEUIINFO_ITEM_STOCK (N_("FIXME: Help"), - N_("See online help"), NULL, GNOME_STOCK_PIXMAP_HELP), + N_("See online help"), + NULL, + GNOME_STOCK_PIXMAP_HELP), GNOMEUIINFO_END }; @@ -469,13 +687,672 @@ static void task_editor_destroy (GtkObject *object) { TaskEditor *tedit; + TaskEditorPrivate *priv; g_return_if_fail (object != NULL); g_return_if_fail (IS_TASK_EDITOR (object)); tedit = TASK_EDITOR (object); + priv = tedit->priv; + if (priv->uih) { + bonobo_object_unref (BONOBO_OBJECT (priv->uih)); + priv->uih = NULL; + } + + if (priv->app) { + gtk_widget_destroy (priv->app); + priv->app = NULL; + } + + if (priv->comp) { + gtk_object_unref (GTK_OBJECT (priv->comp)); + priv->comp = NULL; + } + + if (priv->client) { + gtk_signal_disconnect_by_data (GTK_OBJECT (priv->client), + tedit); + gtk_object_unref (GTK_OBJECT (priv->client)); + priv->client = NULL; + } + + if (priv->xml) { + gtk_object_unref (GTK_OBJECT (priv->xml)); + priv->xml = NULL; + } + g_free (priv); + tedit->priv = NULL; + + if (GTK_OBJECT_CLASS (parent_class)->destroy) + (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); } +void +task_editor_set_cal_client (TaskEditor *tedit, + CalClient *client) +{ + TaskEditorPrivate *priv; + + g_return_if_fail (tedit != NULL); + g_return_if_fail (IS_TASK_EDITOR (tedit)); + + priv = tedit->priv; + + if (client == priv->client) + return; + + if (client) + g_return_if_fail (IS_CAL_CLIENT (client)); + + if (client) + g_return_if_fail (cal_client_is_loaded (client)); + + if (client) + gtk_object_ref (GTK_OBJECT (client)); + + if (priv->client) { + gtk_signal_disconnect_by_data (GTK_OBJECT (priv->client), + tedit); + gtk_object_unref (GTK_OBJECT (priv->client)); + } + + priv->client = client; + + if (priv->client) { + gtk_signal_connect (GTK_OBJECT (priv->client), "obj_updated", + GTK_SIGNAL_FUNC (obj_updated_cb), tedit); + gtk_signal_connect (GTK_OBJECT (priv->client), "obj_removed", + GTK_SIGNAL_FUNC (obj_removed_cb), tedit); + } +} + + +/* Callback used when the calendar client tells us that an object changed */ +static void +obj_updated_cb (CalClient *client, const char *uid, gpointer data) +{ + TaskEditor *tedit; + TaskEditorPrivate *priv; + CalComponent *comp; + CalClientGetStatus status; + const gchar *editing_uid; + + tedit = TASK_EDITOR (data); + + g_return_if_fail (IS_TASK_EDITOR (tedit)); + + priv = tedit->priv; + + /* If we aren't showing the object which has been updated, return. */ + if (!priv->comp) + return; + cal_component_get_uid (priv->comp, &editing_uid); + if (strcmp (uid, editing_uid)) + return; + + + /* Get the task from the server. */ + status = cal_client_get_object (priv->client, uid, &comp); + + switch (status) { + case CAL_CLIENT_GET_SUCCESS: + /* Everything is fine */ + break; + + case CAL_CLIENT_GET_SYNTAX_ERROR: + g_message ("obj_updated_cb(): Syntax error when getting object `%s'", uid); + return; + + case CAL_CLIENT_GET_NOT_FOUND: + /* The object is no longer in the server, so do nothing */ + return; + + default: + g_assert_not_reached (); + return; + } + + raise_and_focus (priv->app); +} + +/* Callback used when the calendar client tells us that an object was removed */ +static void +obj_removed_cb (CalClient *client, const char *uid, gpointer data) +{ + TaskEditor *tedit; + TaskEditorPrivate *priv; + const gchar *editing_uid; + + tedit = TASK_EDITOR (data); + + g_return_if_fail (tedit != NULL); + g_return_if_fail (IS_TASK_EDITOR (tedit)); + + priv = tedit->priv; + + /* If we aren't showing the object which has been updated, return. */ + if (!priv->comp) + return; + cal_component_get_uid (priv->comp, &editing_uid); + if (strcmp (uid, editing_uid)) + return; + + + raise_and_focus (priv->app); +} + + +/* Brings attention to a window by raising it and giving it focus */ +static void +raise_and_focus (GtkWidget *widget) +{ + g_assert (GTK_WIDGET_REALIZED (widget)); + gdk_window_show (widget->window); + gtk_widget_grab_focus (widget); +} + + +/** + * task_editor_set_todo_object: + * @tedit: A #TaskEditor. + * @comp: A todo object. + * + * Sets the todo object that a task editor dialog will manipulate. + **/ +void +task_editor_set_todo_object (TaskEditor *tedit, + CalComponent *comp) +{ + TaskEditorPrivate *priv; + char *title; + + g_return_if_fail (tedit != NULL); + g_return_if_fail (IS_TASK_EDITOR (tedit)); + + priv = tedit->priv; + + if (priv->comp) { + gtk_object_unref (GTK_OBJECT (priv->comp)); + priv->comp = NULL; + } + + if (comp) + priv->comp = cal_component_clone (comp); + + title = make_title_from_comp (priv->comp); + gtk_window_set_title (GTK_WINDOW (priv->app), title); + g_free (title); + + fill_widgets (tedit); +} + + +/* Creates an appropriate title for the task editor dialog */ +static char * +make_title_from_comp (CalComponent *comp) +{ + const char *summary; + CalComponentVType type; + CalComponentText text; + + if (!comp) + return g_strdup (_("Edit Task")); + + cal_component_get_summary (comp, &text); + if (text.value) + summary = text.value; + else + summary = _("No summary"); + + + type = cal_component_get_vtype (comp); + switch (type) { + case CAL_COMPONENT_EVENT: + return g_strdup_printf (_("Appointment - %s"), summary); + + case CAL_COMPONENT_TODO: + return g_strdup_printf (_("Task - %s"), summary); + + case CAL_COMPONENT_JOURNAL: + return g_strdup_printf (_("Journal entry - %s"), summary); + + default: + g_message ("make_title_from_comp(): Cannot handle object of type %d", type); + return NULL; + } +} + + +/* Fills the widgets with default values */ +static void +clear_widgets (TaskEditor *tedit) +{ + TaskEditorPrivate *priv; + + priv = tedit->priv; + + +} + +/* Fills in the widgets with the proper values */ +static void +fill_widgets (TaskEditor *tedit) +{ + TaskEditorPrivate *priv; + CalComponentText text; + CalComponentDateTime d; + struct icaltimetype *completed; + CalComponentClassification classification; + GSList *l; + time_t t; + int *priority_value, *percent; + TaskEditorPriority priority; + const char *url; + + priv = tedit->priv; + + clear_widgets (tedit); + + if (!priv->comp) + return; + + /* We want to ignore any signals emitted while changing fields. */ + priv->ignore_callbacks = TRUE; + + + cal_component_get_summary (priv->comp, &text); + e_dialog_editable_set (priv->summary, text.value); + + cal_component_get_description_list (priv->comp, &l); + if (l) { + text = *(CalComponentText *)l->data; + e_dialog_editable_set (priv->description, text.value); + } else { + e_dialog_editable_set (priv->description, NULL); + } + cal_component_free_text_list (l); + + /* Due Date. */ + cal_component_get_due (priv->comp, &d); + if (d.value) { + t = icaltime_as_timet (*d.value); + } else { + /* FIXME: Can't set GnomeDateEdit to a date of 'None'. */ + t = time (NULL); + } + e_dialog_dateedit_set (priv->due_date, t); + + /* Start Date. */ + cal_component_get_dtstart (priv->comp, &d); + if (d.value) { + t = icaltime_as_timet (*d.value); + } else { + /* FIXME: Can't set GnomeDateEdit to a date of 'None'. */ + t = time (NULL); + } + e_dialog_dateedit_set (priv->start_date, t); + + /* Completed Date. */ + cal_component_get_completed (priv->comp, &completed); + if (completed) { + t = icaltime_as_timet (*completed); + cal_component_free_icaltimetype (completed); + } else { + /* FIXME: Can't set GnomeDateEdit to a date of 'None'. */ + t = time (NULL); + } + e_dialog_dateedit_set (priv->completed_date, t); + + /* Percent Complete. */ + cal_component_get_percent (priv->comp, &percent); + if (percent) { + e_dialog_spin_set (priv->percent_complete, *percent); + cal_component_free_percent (percent); + } else { + /* FIXME: Could check if task is completed and set 100%. */ + e_dialog_spin_set (priv->percent_complete, 0); + } + + /* Status. FIXME: CalComponent doesn't support this yet. */ + e_dialog_option_menu_set (priv->status, STATUS_IN_PROGRESS, + status_map); + + /* Priority. */ + cal_component_get_priority (priv->comp, &priority_value); + if (priority_value) { + priority = priority_value_to_index (*priority_value); + cal_component_free_priority (priority_value); + } else { + priority = PRIORITY_UNDEFINED; + } + e_dialog_option_menu_set (priv->priority, priority, priority_map); + + + /* Classification. */ + cal_component_get_classification (priv->comp, &classification); + e_dialog_option_menu_set (priv->classification, classification, + classification_map); + + + /* URL. */ + cal_component_get_url (priv->comp, &url); + e_dialog_editable_set (priv->url, url); + + priv->ignore_callbacks = FALSE; +} + + +static void +save_todo_object (TaskEditor *tedit) +{ + TaskEditorPrivate *priv; + char *title; + + priv = tedit->priv; + + g_return_if_fail (priv->client != NULL); + + if (!priv->comp) + return; + + dialog_to_comp_object (tedit); + + title = make_title_from_comp (priv->comp); + gtk_window_set_title (GTK_WINDOW (priv->app), title); + g_free (title); + + if (!cal_client_update_object (priv->client, priv->comp)) + g_message ("save_todo_object(): Could not update the object!"); +} + + +/* Get the values of the widgets in the event editor and put them in the iCalObject */ +static void +dialog_to_comp_object (TaskEditor *tedit) +{ + TaskEditorPrivate *priv; + CalComponent *comp; + CalComponentText *text; + CalComponentDateTime date; + time_t t; + GSList *list; + TaskEditorStatus status; + TaskEditorPriority priority; + int priority_value, percent; + CalComponentClassification classification; + char *url; + + priv = tedit->priv; + comp = priv->comp; + + /* Summary. */ + text = g_new0 (CalComponentText, 1); + text->value = e_dialog_editable_get (priv->summary); + cal_component_set_summary (comp, text); + + /* Description. Note that we use the text variable again, and it is + freed in cal_component_free_text_list(). */ + list = NULL; + text->value = e_dialog_editable_get (priv->description); + list = g_slist_prepend (list, text); + cal_component_set_description_list (comp, list); + cal_component_free_text_list (list); + + + date.value = g_new (struct icaltimetype, 1); + date.tzid = NULL; + + /* Due Date. */ + t = e_dialog_dateedit_get (priv->due_date); + *date.value = icaltime_from_timet (t, FALSE, FALSE); + cal_component_set_due (comp, &date); + + /* Start Date. */ + t = e_dialog_dateedit_get (priv->start_date); + *date.value = icaltime_from_timet (t, FALSE, FALSE); + cal_component_set_dtstart (comp, &date); + + /* Completed Date. */ + t = e_dialog_dateedit_get (priv->completed_date); + *date.value = icaltime_from_timet (t, FALSE, FALSE); + cal_component_set_completed (comp, date.value); + + g_free (date.value); + + /* Percent Complete. */ + percent = e_dialog_spin_get_int (priv->percent_complete); + cal_component_set_percent (comp, &percent); + + /* Status. FIXME: CalComponent doesn't support it. */ + status = e_dialog_option_menu_get (priv->status, status_map); +#if 0 + cal_component_set_status (comp, status); +#endif + + /* Priority. */ + priority = e_dialog_option_menu_get (priv->priority, priority_map); + priority_value = priority_index_to_value (priority); + cal_component_set_priority (comp, &priority_value); + + /* Classification. */ + classification = e_dialog_option_menu_get (priv->classification, + classification_map); + cal_component_set_classification (comp, classification); + + + /* URL. */ + url = e_dialog_editable_get (priv->url); + cal_component_set_url (comp, url); + + + + + cal_component_commit_sequence (comp); +} + + + +/* File/Save callback */ +static void +file_save_cb (GtkWidget *widget, gpointer data) +{ + TaskEditor *tedit; + + tedit = TASK_EDITOR (data); + save_todo_object (tedit); +} + +/* File/Save and Close callback */ +static void +file_save_and_close_cb (GtkWidget *widget, gpointer data) +{ + TaskEditor *tedit; + + tedit = TASK_EDITOR (data); + save_todo_object (tedit); + close_dialog (tedit); +} + +/* File/Delete callback */ +static void +file_delete_cb (GtkWidget *widget, gpointer data) +{ + TaskEditor *tedit; + TaskEditorPrivate *priv; + const char *uid; + + tedit = TASK_EDITOR (data); + + g_return_if_fail (IS_TASK_EDITOR (tedit)); + + priv = tedit->priv; + + g_return_if_fail (priv->comp); + + cal_component_get_uid (priv->comp, &uid); + + /* We don't check the return value; FALSE can mean the object was not in + * the server anyways. + */ + cal_client_remove_object (priv->client, uid); + + close_dialog (tedit); +} + +/* File/Close callback */ +static void +file_close_cb (GtkWidget *widget, gpointer data) +{ + TaskEditor *tedit; + + tedit = TASK_EDITOR (data); + + g_return_if_fail (IS_TASK_EDITOR (tedit)); + + close_dialog (tedit); +} + + +static TaskEditorPriority +priority_value_to_index (int priority_value) +{ + TaskEditorPriority retval; + + if (priority_value == 0) + retval = PRIORITY_UNDEFINED; + else if (priority_value <= 4) + retval = PRIORITY_HIGH; + else if (priority_value == 5) + retval = PRIORITY_NORMAL; + else + retval = PRIORITY_LOW; + + return retval; +} + + +static int +priority_index_to_value (TaskEditorPriority priority) +{ + int retval; + + switch (priority) { + case PRIORITY_UNDEFINED: + retval = 0; + break; + case PRIORITY_HIGH: + retval = 3; + break; + case PRIORITY_NORMAL: + retval = 5; + break; + case PRIORITY_LOW: + retval = 7; + break; + } + + return retval; +} + + +static void +completed_date_changed (GnomeDateEdit *dedit, + TaskEditor *tedit) +{ + TaskEditorPrivate *priv; + time_t t; + + g_return_if_fail (IS_TASK_EDITOR (tedit)); + + priv = tedit->priv; + + if (priv->ignore_callbacks) + return; + + t = e_dialog_dateedit_get (priv->completed_date); + /* FIXME: We want to check for 'None' here. */ + priv->ignore_callbacks = TRUE; + if (0) { + /* What do we do if the 'Date Completed' property is set to + 'None' ? The status should not be 'Completed' and the + percent-complete should not be 100%, but what do we set + them to? */ + + } else { + e_dialog_option_menu_set (priv->status, STATUS_COMPLETED, + status_map); + e_dialog_spin_set (priv->percent_complete, 100); + } + priv->ignore_callbacks = FALSE; +} + + +static void +status_changed (GtkMenu *menu, + TaskEditor *tedit) +{ + TaskEditorPrivate *priv; + TaskEditorStatus status; + + g_return_if_fail (IS_TASK_EDITOR (tedit)); + + priv = tedit->priv; + + if (priv->ignore_callbacks) + return; + + status = e_dialog_option_menu_get (priv->status, status_map); + priv->ignore_callbacks = TRUE; + if (status == STATUS_NOT_STARTED) { + e_dialog_spin_set (priv->percent_complete, 0); + /* FIXME: Set to 'None'. */ + e_dialog_dateedit_set (priv->completed_date, time (NULL)); + } else if (status == STATUS_COMPLETED) { + e_dialog_spin_set (priv->percent_complete, 100); + e_dialog_dateedit_set (priv->completed_date, time (NULL)); + } + priv->ignore_callbacks = FALSE; +} + + +static void +percent_complete_changed (GtkAdjustment *adj, + TaskEditor *tedit) +{ + TaskEditorPrivate *priv; + gint percent; + TaskEditorStatus status; + time_t date_completed; + + g_return_if_fail (IS_TASK_EDITOR (tedit)); + + priv = tedit->priv; + + if (priv->ignore_callbacks) + return; + + percent = e_dialog_spin_get_int (priv->percent_complete); + priv->ignore_callbacks = TRUE; + + if (percent == 100) { + date_completed = time (NULL); + status = STATUS_COMPLETED; + } else { + /* FIXME: Set to 'None'. */ + date_completed = time (NULL); + + if (percent == 0) + status = STATUS_NOT_STARTED; + else + status = STATUS_IN_PROGRESS; + } + + e_dialog_dateedit_set (priv->completed_date, date_completed); + e_dialog_option_menu_set (priv->status, status, status_map); + + priv->ignore_callbacks = FALSE; +} + diff --git a/calendar/gui/dialogs/task-editor.h b/calendar/gui/dialogs/task-editor.h index 159b969ab9..a53d29c2a2 100644 --- a/calendar/gui/dialogs/task-editor.h +++ b/calendar/gui/dialogs/task-editor.h @@ -54,8 +54,13 @@ struct _TaskEditorClass GtkType task_editor_get_type (void); +TaskEditor* task_editor_construct (TaskEditor *tedit); TaskEditor* task_editor_new (void); +void task_editor_set_cal_client (TaskEditor *tedit, + CalClient *client); +void task_editor_set_todo_object (TaskEditor *tedit, + CalComponent *comp); END_GNOME_DECLS diff --git a/calendar/gui/dialogs/task-page.glade b/calendar/gui/dialogs/task-page.glade index 56f7f83422..8a8ca800d6 100644 --- a/calendar/gui/dialogs/task-page.glade +++ b/calendar/gui/dialogs/task-page.glade @@ -18,9 +18,11 @@ GnomeApp task-editor-dialog False + task-editor-dialog GTK_WINDOW_TOPLEVEL GTK_WIN_POS_NONE False + 350 False True False @@ -61,7 +63,7 @@ GtkTable table3 - 2 + 1 2 False 4 @@ -75,19 +77,19 @@ GtkLabel label3 - + GTK_JUSTIFY_CENTER False 0.5 0.5 0 0 - entry1 + summary 0 1 - 1 - 2 + 0 + 1 0 0 False @@ -101,7 +103,7 @@ GtkEntry - entry1 + summary True True True @@ -110,63 +112,11 @@ 1 2 - 1 - 2 - 0 - 0 - True - False - False - False - True - False - - - - - GtkLabel - label10 - - GTK_JUSTIFY_CENTER - False - 0 - 0.5 - 0 - 0 - - 0 - 1 0 1 0 0 - False - False - False - False - True - False - - - - - GtkLabel - label11 - - GTK_JUSTIFY_CENTER - False - 0 - 0.5 - 0 - 0 - - 1 - 2 - 0 - 1 - 0 - 0 - False + True False False False @@ -201,7 +151,7 @@ GtkTable table1 2 - 2 + 4 False 2 4 @@ -213,9 +163,9 @@ GnomeDateEdit - dateedit1 + due-date True - False + True False 7 19 @@ -237,7 +187,7 @@ GnomeDateEdit - dateedit2 + start-date True True False @@ -310,6 +260,66 @@ False + + + GtkLabel + label9 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + percent-complete + + 2 + 3 + 0 + 1 + 0 + 0 + False + False + False + False + False + False + + + + + GtkSpinButton + percent-complete + 60 + True + 1 + 0 + False + GTK_UPDATE_ALWAYS + False + False + 0 + 0 + 100 + 10 + 10 + 10 + + 3 + 4 + 0 + 1 + 0 + 0 + True + False + False + False + True + False + + @@ -344,7 +354,7 @@ 0.5 0 0 - combo-entry1 + status 0 False @@ -353,35 +363,20 @@ - GtkCombo - combo1 - False - True - False - True - False + GtkOptionMenu + status + True Not Started In Progress Completed Cancelled + 0 0 - True - True + False + False - - - GtkEntry - GtkCombo:entry - combo-entry1 - 60 - True - True - True - 0 - Not Started - @@ -394,7 +389,7 @@ Cancelled 0.5 0 0 - combo-entry2 + priority 0 False @@ -403,47 +398,32 @@ Cancelled - GtkCombo - combo2 - False - True - False - True - False + GtkOptionMenu + priority + True High Normal Low + 0 0 - True - True + False + False - - - GtkEntry - GtkCombo:entry - combo-entry2 - 60 - True - False - True - 0 - High - GtkLabel - label9 - + label18 + GTK_JUSTIFY_CENTER False 0.5 0.5 0 0 - spinbutton1 + classification 0 False @@ -452,25 +432,18 @@ Low - GtkSpinButton - spinbutton1 + GtkOptionMenu + classification True - 1 - 0 - False - GTK_UPDATE_ALWAYS - False - False - 0 - 0 - 100 - 10 - 10 - 10 + Public +Private +Confidential + + 0 0 - True - True + False + False @@ -490,8 +463,7 @@ Low GtkText - text1 - 150 + description True True @@ -513,17 +485,30 @@ Low GtkButton button3 True - 0 False False + + + GtkLabel + label16 + False + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 4 + 0 + GtkEntry - entry2 + contacts + False True True True @@ -540,17 +525,30 @@ Low GtkButton button4 True - 0 False False + + + GtkLabel + label17 + False + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 4 + 0 + GtkEntry - entry3 + categories + False True True True @@ -562,20 +560,6 @@ Low True - - - GtkCheckButton - checkbutton1 - True - - False - True - - 0 - False - False - - @@ -596,7 +580,7 @@ Low GtkTable table4 4 - 4 + 2 2 False 2 @@ -604,7 +588,7 @@ Low GnomeDateEdit - dateedit3 + completed-date True True False @@ -652,32 +636,6 @@ Low - - GtkLabel - label13 - - GTK_JUSTIFY_CENTER - False - 0 - 0.5 - 0 - 0 - - 0 - 1 - 1 - 2 - 0 - 0 - False - False - False - False - True - False - - - GtkLabel label14 @@ -691,84 +649,10 @@ Low 0 1 - 2 - 3 - 0 - 0 - False - False - False - False - True - False - - - - - GtkEntry - entry4 - True - True - True - 0 - - - 1 - 2 1 2 0 0 - True - False - False - False - True - False - - - - - GtkEntry - entry5 - True - True - True - 0 - - - 1 - 2 - 2 - 3 - 0 - 0 - True - False - False - False - True - False - - - - - GtkLabel - label15 - - GTK_JUSTIFY_CENTER - False - 0 - 0.5 - 0 - 0 - - 0 - 1 - 3 - 4 - 0 - 0 False False False @@ -780,7 +664,7 @@ Low GtkEntry - entry6 + url True True True @@ -789,8 +673,8 @@ Low 1 2 - 3 - 4 + 1 + 2 0 0 True -- cgit v1.2.3