aboutsummaryrefslogtreecommitdiffstats
path: root/calendar/gui/dialogs/task-editor.c
diff options
context:
space:
mode:
authorDamon Chaplin <damon@helixcode.com>2000-09-06 08:13:05 +0800
committerDamon Chaplin <damon@src.gnome.org>2000-09-06 08:13:05 +0800
commite8648e48175c1b6d26bff5316c2c7d738245a63c (patch)
treeb6dcd1e5670462fe810b90a601013556d5db2604 /calendar/gui/dialogs/task-editor.c
parent6403bd5b4def7c610285d2aaad10e793b321091d (diff)
downloadgsoc2013-evolution-e8648e48175c1b6d26bff5316c2c7d738245a63c.tar
gsoc2013-evolution-e8648e48175c1b6d26bff5316c2c7d738245a63c.tar.gz
gsoc2013-evolution-e8648e48175c1b6d26bff5316c2c7d738245a63c.tar.bz2
gsoc2013-evolution-e8648e48175c1b6d26bff5316c2c7d738245a63c.tar.lz
gsoc2013-evolution-e8648e48175c1b6d26bff5316c2c7d738245a63c.tar.xz
gsoc2013-evolution-e8648e48175c1b6d26bff5316c2c7d738245a63c.tar.zst
gsoc2013-evolution-e8648e48175c1b6d26bff5316c2c7d738245a63c.zip
uses the new TaskEditor dialog.
2000-09-06 Damon Chaplin <damon@helixcode.com> * 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 <damon@helixcode.com> * 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 <damon@helixcode.com> * 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
Diffstat (limited to 'calendar/gui/dialogs/task-editor.c')
-rw-r--r--calendar/gui/dialogs/task-editor.c929
1 files changed, 903 insertions, 26 deletions
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 <gnome.h>
#include <glade/glade.h>
#include <e-util/e-util.h>
+#include <e-util/e-dialog-widgets.h>
+#include <cal-util/timeutil.h>
#include <cal-client/cal-client.h>
#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;
+}
+