diff options
author | Georges Basile Stavracas Neto <georges.stavracas@gmail.com> | 2017-09-23 11:33:19 -0300 |
---|---|---|
committer | Georges Basile Stavracas Neto <georges.stavracas@gmail.com> | 2017-09-27 23:30:33 -0300 |
commit | 75dc5720956f54c6f78b6340b4e3fa9aa3ba51a9 (patch) | |
tree | 72e8853fee6d569e3b755644e48d089c1238d13e | |
parent | cd2b2d864c0d04fd19c9367f087b7edc2ebfb249 (diff) | |
download | gnome-todo-wip/gbsneto/component-to-eds.tar.gz |
task: Move ECalComponent to EDS pluginwip/gbsneto/component-to-eds
This was the last big remaining Evolution-Data-Server
bit in GNOME To Do's core codebase. Now, everything
related to EDS is in EDS plugin, and the core of To Do
is truly binding-friendly.
-rw-r--r-- | plugins/eds/gtd-provider-eds.c | 9 | ||||
-rw-r--r-- | plugins/eds/gtd-task-eds.c | 592 | ||||
-rw-r--r-- | plugins/eds/gtd-task-eds.h | 39 | ||||
-rw-r--r-- | plugins/eds/gtd-task-list-eds.c | 116 | ||||
-rw-r--r-- | plugins/eds/meson.build | 13 | ||||
-rw-r--r-- | plugins/todo-txt/gtd-provider-todo-txt.c | 18 | ||||
-rw-r--r-- | plugins/todo-txt/gtd-todo-txt-parser.c | 2 | ||||
-rw-r--r-- | plugins/todoist/gtd-provider-todoist.c | 7 | ||||
-rw-r--r-- | src/gtd-dnd-row.c | 2 | ||||
-rw-r--r-- | src/gtd-edit-pane.c | 7 | ||||
-rw-r--r-- | src/gtd-new-task-row.c | 3 | ||||
-rw-r--r-- | src/gtd-task-list.c | 129 | ||||
-rw-r--r-- | src/gtd-task-list.h | 3 | ||||
-rw-r--r-- | src/gtd-task.c | 593 | ||||
-rw-r--r-- | src/gtd-task.h | 34 |
15 files changed, 968 insertions, 599 deletions
diff --git a/plugins/eds/gtd-provider-eds.c b/plugins/eds/gtd-provider-eds.c index b7b33e79..61b0ec59 100644 --- a/plugins/eds/gtd-provider-eds.c +++ b/plugins/eds/gtd-provider-eds.c @@ -17,6 +17,7 @@ */ #include "gtd-provider-eds.h" +#include "gtd-task-eds.h" #include "gtd-task-list-eds.h" #include <glib/gi18n.h> @@ -121,7 +122,7 @@ gtd_provider_eds_fill_task_list (GObject *client, { GtdTask *task; - task = gtd_task_new (l->data); + task = gtd_task_eds_new (l->data); gtd_task_set_list (task, list); gtd_task_list_save_task (list, task); @@ -879,7 +880,7 @@ gtd_provider_eds_create_task (GtdProviderEds *provider, tasklist = GTD_TASK_LIST_EDS (gtd_task_get_list (task)); source = gtd_task_list_eds_get_source (tasklist); client = g_hash_table_lookup (priv->clients, source); - component = gtd_task_get_component (task); + component = gtd_task_eds_get_component (GTD_TASK_EDS (task)); /* Temporary data for async operation */ data = task_data_new (provider, (gpointer) task); @@ -912,7 +913,7 @@ gtd_provider_eds_update_task (GtdProviderEds *provider, tasklist = GTD_TASK_LIST_EDS (gtd_task_get_list (task)); source = gtd_task_list_eds_get_source (tasklist); client = g_hash_table_lookup (priv->clients, source); - component = gtd_task_get_component (task); + component = gtd_task_eds_get_component (GTD_TASK_EDS (task)); /* Temporary data for async operation */ data = task_data_new (provider, (gpointer) task); @@ -948,7 +949,7 @@ gtd_provider_eds_remove_task (GtdProviderEds *provider, tasklist = GTD_TASK_LIST_EDS (gtd_task_get_list (task)); source = gtd_task_list_eds_get_source (tasklist); client = g_hash_table_lookup (priv->clients, source); - component = gtd_task_get_component (task); + component = gtd_task_eds_get_component (GTD_TASK_EDS (task)); id = e_cal_component_get_id (component); /* Temporary data for async operation */ diff --git a/plugins/eds/gtd-task-eds.c b/plugins/eds/gtd-task-eds.c new file mode 100644 index 00000000..4739f7df --- /dev/null +++ b/plugins/eds/gtd-task-eds.c @@ -0,0 +1,592 @@ +/* gtd-task-eds.c + * + * Copyright (C) 2017 Georges Basile Stavracas Neto <georges.stavracas@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "gtd-task-eds.h" + +struct _GtdTaskEds +{ + GtdTask parent; + + ECalComponent *component; +}; + +G_DEFINE_TYPE (GtdTaskEds, gtd_task_eds, GTD_TYPE_TASK) + +enum +{ + PROP_0, + PROP_COMPONENT, + N_PROPS +}; + +static GParamSpec *properties [N_PROPS]; + + +/* + * Auxiliary methods + */ + +static GDateTime* +convert_icaltime (const icaltimetype *date) +{ + GDateTime *dt; + + if (!date) + return NULL; + + dt = g_date_time_new_utc (date->year, + date->month, + date->day, + date->is_date ? 0 : date->hour, + date->is_date ? 0 : date->minute, + date->is_date ? 0 : date->second); + + return dt; +} + +static void +set_description (GtdTaskEds *self, + const gchar *description) +{ + ECalComponentText text; + GSList note; + + text.value = description && *description ? description : ""; + text.altrep = NULL; + + note.data = &text; + note.next = NULL; + + e_cal_component_set_description_list (self->component, ¬e); +} + +static void +setup_description (GtdTaskEds *self) +{ + g_autofree gchar *desc = NULL; + GSList *text_list; + GSList *l; + + /* concatenates the multiple descriptions a task may have */ + e_cal_component_get_description_list (self->component, &text_list); + + for (l = text_list; l != NULL; l = l->next) + { + if (l->data != NULL) + { + ECalComponentText *text; + gchar *carrier; + + text = l->data; + + if (desc) + { + carrier = g_strconcat (desc, + "\n", + text->value, + NULL); + g_free (desc); + desc = carrier; + } + else + { + desc = g_strdup (text->value); + } + } + } + + set_description (self, desc); + + e_cal_component_free_text_list (text_list); +} + + +/* + * GtdObject overrides + */ + +static const gchar* +gtd_task_eds_get_uid (GtdObject *object) +{ + GtdTaskEds *self; + const gchar *uid; + + g_return_val_if_fail (GTD_IS_TASK (object), NULL); + + self = GTD_TASK_EDS (object); + + if (self->component) + e_cal_component_get_uid (self->component, &uid); + else + uid = NULL; + + return uid; +} + +static void +gtd_task_eds_set_uid (GtdObject *object, + const gchar *uid) +{ + GtdTaskEds *self; + const gchar *current_uid; + + g_return_if_fail (GTD_IS_TASK (object)); + + self = GTD_TASK_EDS (object); + + if (!self->component) + return; + + e_cal_component_get_uid (self->component, ¤t_uid); + + if (g_strcmp0 (current_uid, uid) != 0) + { + e_cal_component_set_uid (self->component, uid); + + g_object_notify (G_OBJECT (object), "uid"); + } +} + + +/* + * GtdTask overrides + */ + +static gboolean +gtd_task_eds_get_complete (GtdTask *task) +{ + GtdTaskEds *self; + icaltimetype *dt; + gboolean completed; + + g_return_val_if_fail (GTD_IS_TASK_EDS (task), FALSE); + + self = GTD_TASK_EDS (task); + + e_cal_component_get_completed (self->component, &dt); + completed = (dt != NULL); + + g_clear_pointer (&dt, e_cal_component_free_icaltimetype); + + return completed; +} + +static void +gtd_task_eds_set_complete (GtdTask *task, + gboolean complete) +{ + icalproperty_status status; + icaltimetype *dt; + GtdTaskEds *self; + gint percent; + + self = GTD_TASK_EDS (task); + + if (complete) + { + GDateTime *now = g_date_time_new_now_utc (); + + percent = 100; + status = ICAL_STATUS_COMPLETED; + + dt = g_new0 (icaltimetype, 1); + dt->year = g_date_time_get_year (now); + dt->month = g_date_time_get_month (now); + dt->day = g_date_time_get_day_of_month (now); + dt->hour = g_date_time_get_hour (now); + dt->minute = g_date_time_get_minute (now); + dt->second = g_date_time_get_seconds (now); + dt->is_date = 0; + dt->is_utc = 1; + + /* convert timezone + * + * FIXME: This does not do anything until we have an ical + * timezone associated with the task + */ + icaltimezone_convert_time (dt, + NULL, + icaltimezone_get_utc_timezone ()); + g_date_time_unref (now); + } + else + { + dt = NULL; + percent = 0; + status = ICAL_STATUS_NEEDSACTION; + } + + e_cal_component_set_percent_as_int (self->component, percent); + e_cal_component_set_status (self->component, status); + e_cal_component_set_completed (self->component, dt); + + if (dt) + e_cal_component_free_icaltimetype (dt); +} + +static GDateTime* +gtd_task_eds_get_creation_date (GtdTask *task) +{ + icaltimetype *idt; + GtdTaskEds *self; + GDateTime *dt; + + self = GTD_TASK_EDS (task); + idt = NULL; + dt = NULL; + + e_cal_component_get_created (self->component, &idt); + + if (idt) + dt = convert_icaltime (idt); + + g_clear_pointer (&idt, e_cal_component_free_icaltimetype); + + return dt; +} + +static void +gtd_task_eds_set_description (GtdTask *task, + const gchar *description) +{ + set_description (GTD_TASK_EDS (task), description); +} + +static GDateTime* +gtd_task_eds_get_due_date (GtdTask *task) +{ + ECalComponentDateTime comp_dt; + GtdTaskEds *self; + GDateTime *date; + + g_return_val_if_fail (GTD_IS_TASK_EDS (task), NULL); + + self = GTD_TASK_EDS (task); + + e_cal_component_get_due (self->component, &comp_dt); + + date = convert_icaltime (comp_dt.value); + e_cal_component_free_datetime (&comp_dt); + + return date; +} + +static void +gtd_task_eds_set_due_date (GtdTask *task, + GDateTime *dt) +{ + GtdTaskEds *self; + GDateTime *current_dt; + + g_assert (GTD_IS_TASK_EDS (task)); + + self = GTD_TASK_EDS (task); + + current_dt = gtd_task_get_due_date (task); + + if (dt != current_dt) + { + ECalComponentDateTime comp_dt; + icaltimetype *idt; + + comp_dt.value = NULL; + comp_dt.tzid = NULL; + idt = NULL; + + if (!current_dt || + (current_dt && + dt && + g_date_time_compare (current_dt, dt) != 0)) + { + idt = g_new0 (icaltimetype, 1); + + g_date_time_ref (dt); + + /* Copy the given dt */ + idt->year = g_date_time_get_year (dt); + idt->month = g_date_time_get_month (dt); + idt->day = g_date_time_get_day_of_month (dt); + idt->hour = g_date_time_get_hour (dt); + idt->minute = g_date_time_get_minute (dt); + idt->second = g_date_time_get_seconds (dt); + idt->is_date = (idt->hour == 0 && + idt->minute == 0 && + idt->second == 0); + + comp_dt.tzid = g_strdup ("UTC"); + + comp_dt.value = idt; + + e_cal_component_set_due (self->component, &comp_dt); + + e_cal_component_free_datetime (&comp_dt); + + g_date_time_unref (dt); + } + else if (!dt) + { + idt = NULL; + comp_dt.tzid = NULL; + + e_cal_component_set_due (self->component, NULL); + } + } + + g_clear_pointer (¤t_dt, g_date_time_unref); +} + +static gint32 +gtd_task_eds_get_priority (GtdTask *task) +{ + g_autofree gint *priority = NULL; + GtdTaskEds *self; + + g_assert (GTD_IS_TASK_EDS (task)); + + self = GTD_TASK_EDS (task); + + e_cal_component_get_priority (self->component, &priority); + + if (!priority) + return -1; + + return *priority; +} + +static void +gtd_task_eds_set_priority (GtdTask *task, + gint32 priority) +{ + GtdTaskEds *self; + + g_assert (GTD_IS_TASK_EDS (task)); + + self = GTD_TASK_EDS (task); + + e_cal_component_set_priority (self->component, &priority); +} + +static const gchar* +gtd_task_eds_get_title (GtdTask *task) +{ + ECalComponentText summary; + GtdTaskEds *self; + + g_return_val_if_fail (GTD_IS_TASK_EDS (task), NULL); + + self = GTD_TASK_EDS (task); + + e_cal_component_get_summary (self->component, &summary); + + return summary.value; +} + +static void +gtd_task_eds_set_title (GtdTask *task, + const gchar *title) +{ + ECalComponentText new_summary; + GtdTaskEds *self; + + g_return_if_fail (GTD_IS_TASK_EDS (task)); + g_return_if_fail (g_utf8_validate (title, -1, NULL)); + + self = GTD_TASK_EDS (task); + + new_summary.value = title; + new_summary.altrep = NULL; + + e_cal_component_set_summary (self->component, &new_summary); +} + + +static void +gtd_task_eds_subtask_added (GtdTask *task, + GtdTask *subtask) +{ + g_autoptr (GList) subtasks = NULL; + ECalComponentId *id; + ECalComponent *comp; + icalcomponent *ical_comp; + icalproperty *property; + GtdTaskEds *subtask_self; + GtdTaskEds *self; + + self = GTD_TASK_EDS (task); + subtask_self = GTD_TASK_EDS (subtask); + subtasks = gtd_task_get_subtasks (task); + + if (g_list_find (subtasks, subtask)) + return; + + id = e_cal_component_get_id (self->component); + comp = subtask_self->component; + ical_comp = e_cal_component_get_icalcomponent (comp); + property = icalcomponent_get_first_property (ical_comp, ICAL_RELATEDTO_PROPERTY); + + if (property) + icalproperty_set_relatedto (property, id->uid); + else + icalcomponent_add_property (ical_comp, icalproperty_new_relatedto (id->uid)); + + /* Hook with parent's :subtask_added */ + GTD_TASK_CLASS (gtd_task_eds_parent_class)->subtask_added (task, subtask); + + e_cal_component_free_id (id); +} + +static void +gtd_task_eds_subtask_removed (GtdTask *task, + GtdTask *subtask) +{ + g_autoptr (GList) subtasks = NULL; + icalcomponent *ical_comp; + icalproperty *property; + GtdTaskEds *subtask_self; + + subtask_self = GTD_TASK_EDS (subtask); + subtasks = gtd_task_get_subtasks (task); + + if (g_list_find (subtasks, subtask)) + return; + + /* Remove the parent link from the subtask's component */ + ical_comp = e_cal_component_get_icalcomponent (subtask_self->component); + property = icalcomponent_get_first_property (ical_comp, ICAL_RELATEDTO_PROPERTY); + + if (!property) + return; + + icalcomponent_remove_property (ical_comp, property); + + /* Hook with parent's :subtask_added */ + GTD_TASK_CLASS (gtd_task_eds_parent_class)->subtask_removed (task, subtask); +} + +/* + * GObject overrides + */ + +static void +gtd_task_eds_finalize (GObject *object) +{ + GtdTaskEds *self = (GtdTaskEds *)object; + + g_clear_object (&self->component); + + G_OBJECT_CLASS (gtd_task_eds_parent_class)->finalize (object); +} + +static void +gtd_task_eds_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GtdTaskEds *self = GTD_TASK_EDS (object); + + switch (prop_id) + { + case PROP_COMPONENT: + g_value_set_object (value, self->component); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +gtd_task_eds_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GtdTaskEds *self = GTD_TASK_EDS (object); + + switch (prop_id) + { + case PROP_COMPONENT: + if (g_set_object (&self->component, g_value_get_object (value))) + { + setup_description (self); + g_object_notify_by_pspec (object, properties[PROP_COMPONENT]); + } + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +gtd_task_eds_class_init (GtdTaskEdsClass *klass) +{ + GtdObjectClass *gtd_object_class = GTD_OBJECT_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtdTaskClass *task_class = GTD_TASK_CLASS (klass); + + object_class->finalize = gtd_task_eds_finalize; + object_class->get_property = gtd_task_eds_get_property; + object_class->set_property = gtd_task_eds_set_property; + + task_class->get_complete = gtd_task_eds_get_complete; + task_class->set_complete = gtd_task_eds_set_complete; + task_class->get_creation_date = gtd_task_eds_get_creation_date; + task_class->set_description = gtd_task_eds_set_description; + task_class->get_due_date = gtd_task_eds_get_due_date; + task_class->set_due_date = gtd_task_eds_set_due_date; + task_class->get_priority = gtd_task_eds_get_priority; + task_class->set_priority = gtd_task_eds_set_priority; + task_class->get_title = gtd_task_eds_get_title; + task_class->set_title = gtd_task_eds_set_title; + task_class->subtask_added = gtd_task_eds_subtask_added; + task_class->subtask_removed = gtd_task_eds_subtask_removed; + + gtd_object_class->get_uid = gtd_task_eds_get_uid; + gtd_object_class->set_uid = gtd_task_eds_set_uid; + + properties[PROP_COMPONENT] = g_param_spec_object ("component", + "Component", + "Component", + E_TYPE_CAL_COMPONENT, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, N_PROPS, properties); +} + +static void +gtd_task_eds_init (GtdTaskEds *self) +{ +} + +GtdTask* +gtd_task_eds_new (ECalComponent *component) +{ + return g_object_new (GTD_TYPE_TASK_EDS, + "component", component, + NULL); +} + +ECalComponent* +gtd_task_eds_get_component (GtdTaskEds *self) +{ + g_return_val_if_fail (GTD_IS_TASK_EDS (self), NULL); + + return self->component; +} diff --git a/plugins/eds/gtd-task-eds.h b/plugins/eds/gtd-task-eds.h new file mode 100644 index 00000000..30096724 --- /dev/null +++ b/plugins/eds/gtd-task-eds.h @@ -0,0 +1,39 @@ +/* gtd-task-eds.h + * + * Copyright (C) 2017 Georges Basile Stavracas Neto <georges.stavracas@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef GTD_TASK_EDS_H +#define GTD_TASK_EDS_H + +#include "gnome-todo.h" + +#include <libecal/libecal.h> + +G_BEGIN_DECLS + +#define GTD_TYPE_TASK_EDS (gtd_task_eds_get_type()) + +G_DECLARE_FINAL_TYPE (GtdTaskEds, gtd_task_eds, GTD, TASK_EDS, GtdTask) + +GtdTask* gtd_task_eds_new (ECalComponent *component); + +ECalComponent* gtd_task_eds_get_component (GtdTaskEds *self); + +G_END_DECLS + +#endif /* GTD_TASK_EDS_H */ + diff --git a/plugins/eds/gtd-task-list-eds.c b/plugins/eds/gtd-task-list-eds.c index 677c6a0c..a9594b89 100644 --- a/plugins/eds/gtd-task-list-eds.c +++ b/plugins/eds/gtd-task-list-eds.c @@ -16,6 +16,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "gtd-task-eds.h" #include "gtd-task-list-eds.h" #include <glib/gi18n.h> @@ -26,9 +27,17 @@ struct _GtdTaskListEds ESource *source; + GPtrArray *pending_subtasks; + GCancellable *cancellable; }; +typedef struct +{ + GtdTask *child; + gchar *parent_uid; +} PendingSubtaskData; + G_DEFINE_TYPE (GtdTaskListEds, gtd_task_list_eds, GTD_TYPE_TASK_LIST) enum { @@ -37,6 +46,90 @@ enum { N_PROPS }; + +/* + * Auxiliary methods + */ + +static PendingSubtaskData* +pending_subtask_data_new (GtdTask *child, + const gchar *parent_uid) +{ + PendingSubtaskData *data; + + data = g_new0 (PendingSubtaskData, 1); + data->child = child; + data->parent_uid = g_strdup (parent_uid); + + return data; +} + +static void +pending_subtask_data_free (PendingSubtaskData *data) +{ + g_free (data->parent_uid); + g_free (data); +} + +static void +setup_parent_task (GtdTaskListEds *self, + GtdTask *task) +{ + ECalComponent *component; + icalcomponent *ical_comp; + icalproperty *property; + GtdTask *parent_task; + const gchar *parent_uid; + + component = gtd_task_eds_get_component (GTD_TASK_EDS (task)); + ical_comp = e_cal_component_get_icalcomponent (component); + property = icalcomponent_get_first_property (ical_comp, ICAL_RELATEDTO_PROPERTY); + + if (!property) + return; + + parent_uid = icalproperty_get_relatedto (property); + parent_task = gtd_task_list_get_task_by_id (GTD_TASK_LIST (self), parent_uid); + + if (parent_task) + { + gtd_task_add_subtask (parent_task, task); + } + else + { + PendingSubtaskData *data; + + data = pending_subtask_data_new (task, parent_uid); + + g_ptr_array_add (self->pending_subtasks, data); + } +} + +static void +process_pending_subtasks (GtdTaskListEds *self, + GtdTask *task) +{ + const gchar *uid; + guint i; + + uid = gtd_object_get_uid (GTD_OBJECT (task)); + + for (i = 0; i < self->pending_subtasks->len; i++) + { + PendingSubtaskData *data; + + data = g_ptr_array_index (self->pending_subtasks, i); + + if (g_strcmp0 (uid, data->parent_uid) == 0) + { + gtd_task_add_subtask (task, data->child); + g_ptr_array_remove (self->pending_subtasks, data); + i--; + } + } +} + + static void source_removable_changed (GtdTaskListEds *list) { @@ -123,6 +216,25 @@ string_to_color (GBinding *binding, return TRUE; } + +/* + * GtdTaskList overrides + */ +static void +gtd_task_list_eds_task_added (GtdTaskList *list, + GtdTask *task) +{ + GtdTaskListEds *self = GTD_TASK_LIST_EDS (list); + + process_pending_subtasks (self, task); + setup_parent_task (self, task); +} + + +/* + * GObject overrides + */ + static void gtd_task_list_eds_finalize (GObject *object) { @@ -178,6 +290,9 @@ static void gtd_task_list_eds_class_init (GtdTaskListEdsClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtdTaskListClass *task_list_class = GTD_TASK_LIST_CLASS (klass); + + task_list_class->task_added = gtd_task_list_eds_task_added; object_class->finalize = gtd_task_list_eds_finalize; object_class->get_property = gtd_task_list_eds_get_property; @@ -200,6 +315,7 @@ gtd_task_list_eds_class_init (GtdTaskListEdsClass *klass) static void gtd_task_list_eds_init (GtdTaskListEds *self) { + self->pending_subtasks = g_ptr_array_new_with_free_func ((GDestroyNotify) pending_subtask_data_free); } GtdTaskListEds* diff --git a/plugins/eds/meson.build b/plugins/eds/meson.build index 6f4cb0d0..458e3c59 100644 --- a/plugins/eds/meson.build +++ b/plugins/eds/meson.build @@ -7,20 +7,21 @@ sources = files( 'gtd-provider-' + plugin_name + '.c', 'gtd-provider-goa.c', 'gtd-provider-local.c', - 'gtd-task-list-' + plugin_name + '.c' + 'gtd-task-' + plugin_name + '.c', + 'gtd-task-list-' + plugin_name + '.c', ) plugins_libs += static_library( - plugin_name, - sources: sources, + plugin_name, + sources: sources, include_directories: plugins_incs, - dependencies: gnome_todo_deps + dependencies: gnome_todo_deps ) plugin_data = plugin_name + '.plugin' plugins_confs += configure_file( - input: plugin_data + '.in', - output: plugin_data, + input: plugin_data + '.in', + output: plugin_data, configuration: plugins_conf ) diff --git a/plugins/todo-txt/gtd-provider-todo-txt.c b/plugins/todo-txt/gtd-provider-todo-txt.c index 50421d90..4f698963 100644 --- a/plugins/todo-txt/gtd-provider-todo-txt.c +++ b/plugins/todo-txt/gtd-provider-todo-txt.c @@ -205,22 +205,6 @@ create_list (GtdProviderTodoTxt *self, return task_list; } -GtdTask* -create_task (void) -{ - ECalComponent *component; - GtdTask *task; - - component = e_cal_component_new (); - - e_cal_component_set_new_vtype (component, E_CAL_COMPONENT_TODO); - e_cal_component_set_uid (component, e_cal_component_gen_uid ()); - - task = gtd_task_new (component); - - return task; -} - static void gtd_provider_todo_txt_load_tasks (GtdProviderTodoTxt *self) { @@ -305,7 +289,7 @@ gtd_provider_todo_txt_load_tasks (GtdProviderTodoTxt *self) } else { - parent_task = create_task (); + parent_task = gtd_task_new (); gtd_task_set_list (parent_task, list); gtd_task_set_title (parent_task, g_object_get_data (G_OBJECT (task), "root_task_name")); diff --git a/plugins/todo-txt/gtd-todo-txt-parser.c b/plugins/todo-txt/gtd-todo-txt-parser.c index 0e03458e..012a50ed 100644 --- a/plugins/todo-txt/gtd-todo-txt-parser.c +++ b/plugins/todo-txt/gtd-todo-txt-parser.c @@ -175,7 +175,7 @@ gtd_todo_txt_parser_parse_tokens (GList *tokens) dt = NULL; l = NULL; - task = create_task (); + task = gtd_task_new (); list_name = g_string_new (NULL); title = g_string_new (NULL); root_task_name = g_string_new (NULL); diff --git a/plugins/todoist/gtd-provider-todoist.c b/plugins/todoist/gtd-provider-todoist.c index d55ff271..5d07549a 100644 --- a/plugins/todoist/gtd-provider-todoist.c +++ b/plugins/todoist/gtd-provider-todoist.c @@ -331,7 +331,6 @@ parse_array_to_task (GtdProviderTodoist *self, { JsonObject *object; GtdTaskList *list; - ECalComponent *component; GtdTask *task; const gchar *title; const gchar *due_date; @@ -341,10 +340,6 @@ parse_array_to_task (GtdProviderTodoist *self, gint priority; guint is_complete; - component = e_cal_component_new (); - e_cal_component_set_new_vtype (component, E_CAL_COMPONENT_TODO); - e_cal_component_set_uid (component, e_cal_component_gen_uid ()); - object = json_node_get_object (l->data); title = json_object_get_string_member (object, "content"); @@ -358,7 +353,7 @@ parse_array_to_task (GtdProviderTodoist *self, uid = g_strdup_printf ("%u", id); /* Setup the task */ - task = gtd_task_new (component); + task = gtd_task_new (); gtd_object_set_uid (GTD_OBJECT (task), uid); gtd_task_set_title (task, title); gtd_task_set_list (task, list); diff --git a/src/gtd-dnd-row.c b/src/gtd-dnd-row.c index 11c9a4a4..5b4520d6 100644 --- a/src/gtd-dnd-row.c +++ b/src/gtd-dnd-row.c @@ -278,8 +278,6 @@ gtd_dnd_row_drag_drop (GtkWidget *widget, /* Save the task */ provider = gtd_task_list_get_provider (gtd_task_get_list (row_task)); - - gtd_task_save (row_task); gtd_provider_update_task (provider, row_task); gtk_list_box_invalidate_sort (GTK_LIST_BOX (gtk_widget_get_parent (widget))); diff --git a/src/gtd-edit-pane.c b/src/gtd-edit-pane.c index dacedd77..e007031b 100644 --- a/src/gtd-edit-pane.c +++ b/src/gtd-edit-pane.c @@ -75,12 +75,7 @@ gtd_edit_pane__no_date_button_clicked (GtkButton *button, static void save_task (GtdEditPane *self) { - GtdManager *manager; - - manager = gtd_manager_get_default (); - - gtd_task_save (self->task); - gtd_manager_update_task (manager, self->task); + gtd_manager_update_task (gtd_manager_get_default (), self->task); } static void diff --git a/src/gtd-new-task-row.c b/src/gtd-new-task-row.c index f004ed8c..8c3b9c5b 100644 --- a/src/gtd-new-task-row.c +++ b/src/gtd-new-task-row.c @@ -142,9 +142,8 @@ entry_activated_cb (GtdNewTaskRow *self) if (gtk_entry_get_text_length (self->entry) == 0) return; - new_task = gtd_task_new (NULL); + new_task = gtd_task_new (); gtd_task_set_title (new_task, gtk_entry_get_text (self->entry)); - gtd_task_save (new_task); g_signal_emit (self, signals[CREATE_TASK], 0, new_task, self->selected_tasklist); diff --git a/src/gtd-task-list.c b/src/gtd-task-list.c index 1bff3b75..956cd72a 100644 --- a/src/gtd-task-list.c +++ b/src/gtd-task-list.c @@ -36,18 +36,11 @@ typedef struct { - gchar *parent_uid; - GtdTask *child; -} PendingSubtaskData; - -typedef struct -{ GList *tasks; GtdProvider *provider; GdkRGBA *color; GHashTable *uid_to_task; - GPtrArray *pending_subtasks; gchar *name; gboolean removable : 1; @@ -75,91 +68,6 @@ enum LAST_PROP }; -static PendingSubtaskData* -pending_subtask_data_new (GtdTaskList *self, - GtdTask *child, - const gchar *parent_uid) -{ - PendingSubtaskData *data; - - data = g_new0 (PendingSubtaskData, 1); - data->child = child; - data->parent_uid = g_strdup (parent_uid); - - return data; -} - -static void -pending_subtask_data_free (PendingSubtaskData *data) -{ - g_free (data->parent_uid); - g_free (data); -} - -static void -setup_parent_task (GtdTaskList *self, - GtdTask *task) -{ - GtdTaskListPrivate *priv; - ECalComponent *component; - icalcomponent *ical_comp; - icalproperty *property; - GtdTask *parent_task; - const gchar *parent_uid; - - priv = gtd_task_list_get_instance_private (self); - component = gtd_task_get_component (task); - ical_comp = e_cal_component_get_icalcomponent (component); - property = icalcomponent_get_first_property (ical_comp, ICAL_RELATEDTO_PROPERTY); - - if (!property) - return; - - parent_uid = icalproperty_get_relatedto (property); - parent_task = g_hash_table_lookup (priv->uid_to_task, parent_uid); - - if (parent_task) - { - gtd_task_add_subtask (parent_task, task); - } - else - { - PendingSubtaskData *data; - - data = pending_subtask_data_new (self, task, parent_uid); - - g_ptr_array_add (priv->pending_subtasks, data); - } -} - -static void -process_pending_subtasks (GtdTaskList *self, - GtdTask *task) -{ - GtdTaskListPrivate *priv; - ECalComponentId *id; - guint i; - - priv = gtd_task_list_get_instance_private (self); - id = e_cal_component_get_id (gtd_task_get_component (task)); - - for (i = 0; i < priv->pending_subtasks->len; i++) - { - PendingSubtaskData *data; - - data = g_ptr_array_index (priv->pending_subtasks, i); - - if (g_strcmp0 (id->uid, data->parent_uid) == 0) - { - gtd_task_add_subtask (task, data->child); - g_ptr_array_remove (priv->pending_subtasks, data); - i--; - } - } - - e_cal_component_free_id (id); -} - static void task_changed_cb (GtdTask *task, GParamSpec *pspec, @@ -174,7 +82,6 @@ gtd_task_list_finalize (GObject *object) GtdTaskList *self = (GtdTaskList*) object; GtdTaskListPrivate *priv = gtd_task_list_get_instance_private (self); - g_clear_object (&priv->pending_subtasks); g_clear_object (&priv->provider); g_clear_pointer (&priv->uid_to_task, g_hash_table_destroy); @@ -385,8 +292,6 @@ gtd_task_list_init (GtdTaskList *self) g_str_equal, g_free, NULL); - - priv->pending_subtasks = g_ptr_array_new_with_free_func ((GDestroyNotify) pending_subtask_data_free); } /** @@ -595,15 +500,13 @@ gtd_task_list_save_task (GtdTaskList *list, } else { - ECalComponentId *id; + const gchar *uid; - id = e_cal_component_get_id (gtd_task_get_component (task)); + uid = gtd_object_get_uid (GTD_OBJECT (task)); - priv->tasks = g_list_append (priv->tasks, task); + priv->tasks = g_list_prepend (priv->tasks, task); - g_hash_table_insert (priv->uid_to_task, g_strdup (id->uid), task); - process_pending_subtasks (list, task); - setup_parent_task (list, task); + g_hash_table_insert (priv->uid_to_task, g_strdup (uid), task); g_signal_connect (task, "notify", @@ -611,8 +514,6 @@ gtd_task_list_save_task (GtdTaskList *list, list); g_signal_emit (list, signals[TASK_ADDED], 0, task); - - e_cal_component_free_id (id); } } @@ -715,3 +616,25 @@ gtd_task_list_set_is_removable (GtdTaskList *list, g_object_notify (G_OBJECT (list), "is-removable"); } } + +/** + * gtd_task_list_get_task_by_id: + * @list: a #GtdTaskList + * @id: the id of the task + * + * Retrieves a task from @self with the given @id. + * + * Returns: (transfer none)(nullable): a #GtdTask, or %NULL + */ +GtdTask* +gtd_task_list_get_task_by_id (GtdTaskList *self, + const gchar *id) +{ + GtdTaskListPrivate *priv; + + g_return_val_if_fail (GTD_IS_TASK_LIST (self), NULL); + + priv = gtd_task_list_get_instance_private (self); + + return g_hash_table_lookup (priv->uid_to_task, id); +} diff --git a/src/gtd-task-list.h b/src/gtd-task-list.h index 6528240b..8550dd5a 100644 --- a/src/gtd-task-list.h +++ b/src/gtd-task-list.h @@ -80,6 +80,9 @@ void gtd_task_list_remove_task (GtdTaskList gboolean gtd_task_list_contains (GtdTaskList *list, GtdTask *task); +GtdTask* gtd_task_list_get_task_by_id (GtdTaskList *self, + const gchar *id); + G_END_DECLS #endif /* GTD_TASK_LIST_H */ diff --git a/src/gtd-task.c b/src/gtd-task.c index 1143dad3..5a8a4176 100644 --- a/src/gtd-task.c +++ b/src/gtd-task.c @@ -20,9 +20,6 @@ #include "gtd-task-list.h" #include <glib/gi18n.h> -#include <libecal/libecal.h> -#include <libical/icaltime.h> -#include <libical/icaltimezone.h> /** * SECTION:gtd-task @@ -39,10 +36,17 @@ typedef struct { gchar *description; GtdTaskList *list; - ECalComponent *component; GtdTask *parent; GList *subtasks; gint depth; + + GDateTime *creation_date; + GDateTime *due_date; + + gchar *title; + + gint32 priority; + gboolean complete : 1; } GtdTaskPrivate; G_DEFINE_TYPE_WITH_PRIVATE (GtdTask, gtd_task, GTD_TYPE_OBJECT) @@ -51,7 +55,6 @@ enum { PROP_0, PROP_COMPLETE, - PROP_COMPONENT, PROP_DEPTH, PROP_DESCRIPTION, PROP_CREATION_DATE, @@ -178,25 +181,6 @@ compare_by_subtasks (GtdTask **t1, return 0; } - -static GDateTime* -gtd_task__convert_icaltime (const icaltimetype *date) -{ - GDateTime *dt; - - if (!date) - return NULL; - - dt = g_date_time_new_utc (date->year, - date->month, - date->day, - date->is_date ? 0 : date->hour, - date->is_date ? 0 : date->minute, - date->is_date ? 0 : date->second); - - return dt; -} - static void set_depth (GtdTask *self, gint depth) @@ -216,32 +200,18 @@ real_add_subtask (GtdTask *self, GtdTask *subtask) { GtdTaskPrivate *priv, *subtask_priv; - ECalComponentId *id; - ECalComponent *comp; - icalcomponent *ical_comp; - icalproperty *property; priv = gtd_task_get_instance_private (self); if (g_list_find (priv->subtasks, subtask)) return; - id = e_cal_component_get_id (priv->component); subtask_priv = gtd_task_get_instance_private (subtask); - comp = subtask_priv->component; /* First, remove the subtask from it's parent's subtasks list */ if (subtask_priv->parent) gtd_task_remove_subtask (subtask_priv->parent, subtask); - ical_comp = e_cal_component_get_icalcomponent (comp); - property = icalcomponent_get_first_property (ical_comp, ICAL_RELATEDTO_PROPERTY); - - if (property) - icalproperty_set_relatedto (property, id->uid); - else - icalcomponent_add_property (ical_comp, icalproperty_new_relatedto (id->uid)); - /* Add to this task's list of subtasks */ priv->subtasks = g_list_prepend (priv->subtasks, subtask); @@ -251,8 +221,6 @@ real_add_subtask (GtdTask *self, /* And also the task's depth */ set_depth (subtask, priv->depth + 1); - - e_cal_component_free_id (id); } static void @@ -260,8 +228,6 @@ real_remove_subtask (GtdTask *self, GtdTask *subtask) { GtdTaskPrivate *priv, *subtask_priv; - icalcomponent *ical_comp; - icalproperty *property; priv = gtd_task_get_instance_private (self); @@ -270,15 +236,6 @@ real_remove_subtask (GtdTask *self, subtask_priv = gtd_task_get_instance_private (subtask); - /* Remove the parent link from the subtask's component */ - ical_comp = e_cal_component_get_icalcomponent (subtask_priv->component); - property = icalcomponent_get_first_property (ical_comp, ICAL_RELATEDTO_PROPERTY); - - if (!property) - return; - - icalcomponent_remove_property (ical_comp, property); - /* Add to this task's list of subtasks */ priv->subtasks = g_list_remove (priv->subtasks, subtask); @@ -299,58 +256,124 @@ task_list_weak_notified (gpointer data, priv->list = NULL; } -static void -gtd_task_finalize (GObject *object) +/* + * GtdTask default implementations + */ + +static gboolean +gtd_task_real_get_complete (GtdTask *self) { - GtdTask *self = (GtdTask*) object; GtdTaskPrivate *priv = gtd_task_get_instance_private (self); - if (priv->list) - g_object_weak_unref (G_OBJECT (priv->list), task_list_weak_notified, self); + return priv->complete; +} - priv->list = NULL; - g_free (priv->description); - g_object_unref (priv->component); +static void +gtd_task_real_set_complete (GtdTask *self, + gboolean complete) +{ + GtdTaskPrivate *priv = gtd_task_get_instance_private (self); - G_OBJECT_CLASS (gtd_task_parent_class)->finalize (object); + priv->complete = complete; +} + +static GDateTime* +gtd_task_real_get_creation_date (GtdTask *self) +{ + return NULL; } static const gchar* -gtd_task__get_uid (GtdObject *object) +gtd_task_real_get_description (GtdTask *self) { - GtdTaskPrivate *priv = gtd_task_get_instance_private (GTD_TASK (object)); - const gchar *uid; + GtdTaskPrivate *priv = gtd_task_get_instance_private (self); - g_return_val_if_fail (GTD_IS_TASK (object), NULL); + return priv->description ? priv->description : ""; +} - if (priv->component) - e_cal_component_get_uid (priv->component, &uid); - else - uid = NULL; +static void +gtd_task_real_set_description (GtdTask *self, + const gchar *description) +{ + GtdTaskPrivate *priv = gtd_task_get_instance_private (self); - return uid; + g_clear_pointer (&priv->description, g_free); + priv->description = g_strdup (description); +} + +static GDateTime* +gtd_task_real_get_due_date (GtdTask *self) +{ + GtdTaskPrivate *priv = gtd_task_get_instance_private (self); + + return priv->due_date; } static void -gtd_task__set_uid (GtdObject *object, - const gchar *uid) +gtd_task_real_set_due_date (GtdTask *self, + GDateTime *due_date) { - GtdTaskPrivate *priv = gtd_task_get_instance_private (GTD_TASK (object)); - const gchar *current_uid; + GtdTaskPrivate *priv = gtd_task_get_instance_private (self); - g_return_if_fail (GTD_IS_TASK (object)); + g_clear_pointer (&priv->due_date, g_date_time_unref); - if (!priv->component) - return; + if (due_date) + priv->due_date = g_date_time_ref (due_date); +} - e_cal_component_get_uid (priv->component, ¤t_uid); +static gint32 +gtd_task_real_get_priority (GtdTask *self) +{ + GtdTaskPrivate *priv = gtd_task_get_instance_private (self); - if (g_strcmp0 (current_uid, uid) != 0) - { - e_cal_component_set_uid (priv->component, uid); + return priv->priority; +} - g_object_notify (G_OBJECT (object), "uid"); - } +static void +gtd_task_real_set_priority (GtdTask *self, + gint32 priority) +{ + GtdTaskPrivate *priv = gtd_task_get_instance_private (self); + + priv->priority = priority; +} + +static const gchar* +gtd_task_real_get_title (GtdTask *self) +{ + GtdTaskPrivate *priv = gtd_task_get_instance_private (self); + + return priv->title; +} + +static void +gtd_task_real_set_title (GtdTask *self, + const gchar *title) +{ + GtdTaskPrivate *priv = gtd_task_get_instance_private (self); + + g_clear_pointer (&priv->title, g_free); + priv->title = title ? g_strdup (title) : NULL; +} + + +/* + * GObject overrides + */ + +static void +gtd_task_finalize (GObject *object) +{ + GtdTask *self = (GtdTask*) object; + GtdTaskPrivate *priv = gtd_task_get_instance_private (self); + + if (priv->list) + g_object_weak_unref (G_OBJECT (priv->list), task_list_weak_notified, self); + + priv->list = NULL; + g_free (priv->description); + + G_OBJECT_CLASS (gtd_task_parent_class)->finalize (object); } static void @@ -369,10 +392,6 @@ gtd_task_get_property (GObject *object, g_value_set_boolean (value, gtd_task_get_complete (self)); break; - case PROP_COMPONENT: - g_value_set_object (value, priv->component); - break; - case PROP_CREATION_DATE: g_value_set_boxed (value, gtd_task_get_creation_date (self)); break; @@ -419,7 +438,6 @@ gtd_task_set_property (GObject *object, GParamSpec *pspec) { GtdTask *self = GTD_TASK (object); - GtdTaskPrivate *priv = gtd_task_get_instance_private (self); switch (prop_id) { @@ -427,21 +445,6 @@ gtd_task_set_property (GObject *object, gtd_task_set_complete (self, g_value_get_boolean (value)); break; - case PROP_COMPONENT: - priv->component = g_value_get_object (value); - - if (!priv->component) - { - priv->component = e_cal_component_new (); - e_cal_component_set_new_vtype (priv->component, E_CAL_COMPONENT_TODO); - } - else - { - g_object_ref (priv->component); - } - - break; - case PROP_DESCRIPTION: gtd_task_set_description (self, g_value_get_string (value)); break; @@ -471,8 +474,18 @@ static void gtd_task_class_init (GtdTaskClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); - GtdObjectClass *obj_class = GTD_OBJECT_CLASS (klass); + klass->get_complete = gtd_task_real_get_complete; + klass->set_complete = gtd_task_real_set_complete; + klass->get_creation_date = gtd_task_real_get_creation_date; + klass->get_description = gtd_task_real_get_description; + klass->set_description = gtd_task_real_set_description; + klass->get_due_date = gtd_task_real_get_due_date; + klass->set_due_date = gtd_task_real_set_due_date; + klass->get_priority = gtd_task_real_get_priority; + klass->set_priority = gtd_task_real_set_priority; + klass->get_title = gtd_task_real_get_title; + klass->set_title = gtd_task_real_set_title; klass->subtask_added = real_add_subtask; klass->subtask_removed = real_remove_subtask; @@ -480,9 +493,6 @@ gtd_task_class_init (GtdTaskClass *klass) object_class->get_property = gtd_task_get_property; object_class->set_property = gtd_task_set_property; - obj_class->get_uid = gtd_task__get_uid; - obj_class->set_uid = gtd_task__set_uid; - /** * GtdTask::complete: * @@ -499,20 +509,6 @@ gtd_task_class_init (GtdTaskClass *klass) G_PARAM_READWRITE)); /** - * GtdTask::component: - * - * The #ECalComponent of the task. - */ - g_object_class_install_property ( - object_class, - PROP_COMPONENT, - g_param_spec_object ("component", - "Component of the task", - "The #ECalComponent this task handles.", - E_TYPE_CAL_COMPONENT, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - - /** * GtdTask::creation-date: * * The @GDateTime that represents the time in which the task was created. @@ -666,78 +662,35 @@ gtd_task_class_init (GtdTaskClass *klass) static void gtd_task_init (GtdTask *self) { - ; } /** * gtd_task_new: - * @component: (nullable): a #ECalComponent * * Creates a new #GtdTask * * Returns: (transfer full): a #GtdTask */ GtdTask * -gtd_task_new (ECalComponent *component) +gtd_task_new (void) { - const gchar *uid; - - if (component) - e_cal_component_get_uid (component, &uid); - else - uid = NULL; - - return g_object_new (GTD_TYPE_TASK, - "component", component, - NULL); + return g_object_new (GTD_TYPE_TASK, NULL); } /** * gtd_task_get_complete: - * @task: a #GtdTask + * @self: a #GtdTask * * Retrieves whether the task is complete or not. * * Returns: %TRUE if the task is complete, %FALSE otherwise */ gboolean -gtd_task_get_complete (GtdTask *task) +gtd_task_get_complete (GtdTask *self) { - GtdTaskPrivate *priv; - icaltimetype *dt; - gboolean completed; - - g_return_val_if_fail (GTD_IS_TASK (task), FALSE); - - priv = gtd_task_get_instance_private (task); - - e_cal_component_get_completed (priv->component, &dt); - completed = (dt != NULL); - - if (dt) - e_cal_component_free_icaltimetype (dt); - - return completed; -} - -/** - * gtd_task_get_component: - * @task: a #GtdTask - * - * Retrieves the internal #ECalComponent of @task. - * - * Returns: (transfer none): a #ECalComponent - */ -ECalComponent* -gtd_task_get_component (GtdTask *task) -{ - GtdTaskPrivate *priv; - - g_return_val_if_fail (GTD_IS_TASK (task), NULL); - - priv = gtd_task_get_instance_private (task); + g_return_val_if_fail (GTD_IS_TASK (self), FALSE); - return priv->component; + return GTD_TASK_CLASS (G_OBJECT_GET_CLASS (self))->get_complete (self); } /** @@ -751,61 +704,14 @@ void gtd_task_set_complete (GtdTask *task, gboolean complete) { - GtdTaskPrivate *priv; - g_assert (GTD_IS_TASK (task)); - priv = gtd_task_get_instance_private (task); - - if (gtd_task_get_complete (task) != complete) - { - icaltimetype *dt; - icalproperty_status status; - gint percent; - - if (complete) - { - GDateTime *now = g_date_time_new_now_utc (); - - percent = 100; - status = ICAL_STATUS_COMPLETED; - - dt = g_new0 (icaltimetype, 1); - dt->year = g_date_time_get_year (now); - dt->month = g_date_time_get_month (now); - dt->day = g_date_time_get_day_of_month (now); - dt->hour = g_date_time_get_hour (now); - dt->minute = g_date_time_get_minute (now); - dt->second = g_date_time_get_seconds (now); - dt->is_date = 0; - dt->is_utc = 1; - - /* convert timezone - * - * FIXME: This does not do anything until we have an ical - * timezone associated with the task - */ - icaltimezone_convert_time (dt, - NULL, - icaltimezone_get_utc_timezone ()); - g_date_time_unref (now); - } - else - { - dt = NULL; - percent = 0; - status = ICAL_STATUS_NEEDSACTION; - } - - e_cal_component_set_percent_as_int (priv->component, percent); - e_cal_component_set_status (priv->component, status); - e_cal_component_set_completed (priv->component, dt); + if (gtd_task_get_complete (task) == complete) + return; - if (dt) - e_cal_component_free_icaltimetype (dt); + GTD_TASK_CLASS (G_OBJECT_GET_CLASS (task))->set_complete (task, complete); - g_object_notify (G_OBJECT (task), "complete"); - } + g_object_notify (G_OBJECT (task), "complete"); } /** @@ -822,24 +728,9 @@ gtd_task_set_complete (GtdTask *task, GDateTime* gtd_task_get_creation_date (GtdTask *task) { - GtdTaskPrivate *priv; - icaltimetype *idt; - GDateTime *dt; - g_return_val_if_fail (GTD_IS_TASK (task), NULL); - priv = gtd_task_get_instance_private (task); - - idt = NULL; - dt = NULL; - e_cal_component_get_created (priv->component, &idt); - - if (idt) - dt = gtd_task__convert_icaltime (idt); - - g_clear_pointer (&idt, e_cal_component_free_icaltimetype); - - return dt; + return GTD_TASK_CLASS (G_OBJECT_GET_CLASS (task))->get_creation_date (task); } /** @@ -853,52 +744,9 @@ gtd_task_get_creation_date (GtdTask *task) const gchar* gtd_task_get_description (GtdTask *task) { - GtdTaskPrivate *priv; - GSList *text_list; - GSList *l; - gchar *desc = NULL; - g_return_val_if_fail (GTD_IS_TASK (task), NULL); - priv = gtd_task_get_instance_private (task); - - /* concatenates the multiple descriptions a task may have */ - e_cal_component_get_description_list (priv->component, &text_list); - for (l = text_list; l != NULL; l = l->next) - { - if (l->data != NULL) - { - ECalComponentText *text; - gchar *carrier; - text = l->data; - - if (desc != NULL) - { - carrier = g_strconcat (desc, - "\n", - text->value, - NULL); - g_free (desc); - desc = carrier; - } - else - { - desc = g_strdup (text->value); - } - } - } - - if (g_strcmp0 (priv->description, desc) != 0) - { - g_clear_pointer (&priv->description, g_free); - - priv->description = g_strdup (desc); - } - - g_free (desc); - e_cal_component_free_text_list (text_list); - - return priv->description ? priv->description : ""; + return GTD_TASK_CLASS (G_OBJECT_GET_CLASS (task))->get_description (task); } /** @@ -920,25 +768,12 @@ gtd_task_set_description (GtdTask *task, priv = gtd_task_get_instance_private (task); - if (g_strcmp0 (priv->description, description) != 0) - { - GSList note; - ECalComponentText text; - - g_clear_pointer (&priv->description, g_free); - - priv->description = g_strdup (description); - - text.value = priv->description; - text.altrep = NULL; - - note.data = &text; - note.next = NULL; + if (g_strcmp0 (priv->description, description) == 0) + return; - e_cal_component_set_description_list (priv->component, ¬e); + GTD_TASK_CLASS (G_OBJECT_GET_CLASS (task))->set_description (task, description); - g_object_notify (G_OBJECT (task), "description"); - } + g_object_notify (G_OBJECT (task), "description"); } /** @@ -955,19 +790,9 @@ gtd_task_set_description (GtdTask *task, GDateTime* gtd_task_get_due_date (GtdTask *task) { - ECalComponentDateTime comp_dt; - GtdTaskPrivate *priv; - GDateTime *date; - g_return_val_if_fail (GTD_IS_TASK (task), NULL); - priv = gtd_task_get_instance_private (task); - - e_cal_component_get_due (priv->component, &comp_dt); - - date = gtd_task__convert_icaltime (comp_dt.value); - e_cal_component_free_datetime (&comp_dt); - return date; + return GTD_TASK_CLASS (G_OBJECT_GET_CLASS (task))->get_due_date (task); } /** @@ -981,72 +806,19 @@ void gtd_task_set_due_date (GtdTask *task, GDateTime *dt) { - GtdTaskPrivate *priv; - GDateTime *current_dt; + g_autoptr (GDateTime) current_dt = NULL; g_assert (GTD_IS_TASK (task)); - priv = gtd_task_get_instance_private (task); - current_dt = gtd_task_get_due_date (task); - if (dt != current_dt) - { - ECalComponentDateTime comp_dt; - icaltimetype *idt; - gboolean changed = FALSE; - - comp_dt.value = NULL; - comp_dt.tzid = NULL; - idt = NULL; - - if (!current_dt || - (current_dt && - dt && - g_date_time_compare (current_dt, dt) != 0)) - { - idt = g_new0 (icaltimetype, 1); - - g_date_time_ref (dt); - - /* Copy the given dt */ - idt->year = g_date_time_get_year (dt); - idt->month = g_date_time_get_month (dt); - idt->day = g_date_time_get_day_of_month (dt); - idt->hour = g_date_time_get_hour (dt); - idt->minute = g_date_time_get_minute (dt); - idt->second = g_date_time_get_seconds (dt); - idt->is_date = (idt->hour == 0 && - idt->minute == 0 && - idt->second == 0); - - comp_dt.tzid = g_strdup ("UTC"); - - comp_dt.value = idt; - - e_cal_component_set_due (priv->component, &comp_dt); - - e_cal_component_free_datetime (&comp_dt); - - g_date_time_unref (dt); - - changed = TRUE; - } - else if (!dt) - { - idt = NULL; - comp_dt.tzid = NULL; - - e_cal_component_set_due (priv->component, NULL); - - changed = TRUE; - } + /* Don't do anything if the date is equal */ + if (current_dt == dt || (current_dt && dt && g_date_time_equal (current_dt, dt))) + return; - if (changed) - g_object_notify (G_OBJECT (task), "due-date"); - } + GTD_TASK_CLASS (G_OBJECT_GET_CLASS (task))->set_due_date (task, dt); - g_clear_pointer (¤t_dt, g_date_time_unref); + g_object_notify (G_OBJECT (task), "due-date"); } /** @@ -1112,24 +884,9 @@ gtd_task_set_list (GtdTask *task, gint gtd_task_get_priority (GtdTask *task) { - GtdTaskPrivate *priv; - gint *priority = NULL; - gint p; - g_assert (GTD_IS_TASK (task)); - priv = gtd_task_get_instance_private (task); - - e_cal_component_get_priority (priv->component, &priority); - - if (!priority) - return -1; - - p = *priority; - - g_free (priority); - - return p; + return GTD_TASK_CLASS (G_OBJECT_GET_CLASS (task))->get_priority (task); } /** @@ -1145,18 +902,16 @@ void gtd_task_set_priority (GtdTask *task, gint priority) { - GtdTaskPrivate *priv; gint current; g_assert (GTD_IS_TASK (task)); g_assert (priority >= -1); - priv = gtd_task_get_instance_private (task); current = gtd_task_get_priority (task); if (priority != current) { - e_cal_component_set_priority (priv->component, &priority); + GTD_TASK_CLASS (G_OBJECT_GET_CLASS (task))->set_priority (task, priority); g_object_notify (G_OBJECT (task), "priority"); } } @@ -1172,16 +927,13 @@ gtd_task_set_priority (GtdTask *task, const gchar* gtd_task_get_title (GtdTask *task) { - GtdTaskPrivate *priv; - ECalComponentText summary; + const gchar *title; g_return_val_if_fail (GTD_IS_TASK (task), NULL); - priv = gtd_task_get_instance_private (task); - - e_cal_component_get_summary (priv->component, &summary); + title = GTD_TASK_CLASS (G_OBJECT_GET_CLASS (task))->get_title (task); - return summary.value ? summary.value : ""; + return title ? title : ""; } /** @@ -1196,64 +948,19 @@ void gtd_task_set_title (GtdTask *task, const gchar *title) { - GtdTaskPrivate *priv; - ECalComponentText summary; + const gchar *current_title; g_return_if_fail (GTD_IS_TASK (task)); g_return_if_fail (g_utf8_validate (title, -1, NULL)); - priv = gtd_task_get_instance_private (task); - - e_cal_component_get_summary (priv->component, &summary); + current_title = gtd_task_get_title (task); - if (g_strcmp0 (summary.value, title) != 0) - { - ECalComponentText new_summary; - - new_summary.value = title; - new_summary.altrep = NULL; - - e_cal_component_set_summary (priv->component, &new_summary); - - g_object_notify (G_OBJECT (task), "title"); - } -} - -/** - * gtd_task_abort: - * @task: a #GtdTask - * - * Cancels any editing made on @task after the latest - * call of @gtd_task_save. - */ -void -gtd_task_abort (GtdTask *task) -{ - GtdTaskPrivate *priv; - - g_return_if_fail (GTD_IS_TASK (task)); - - priv = gtd_task_get_instance_private (task); - - e_cal_component_abort_sequence (priv->component); -} - -/** - * gtd_task_save: - * @task: a #GtdTask - * - * Save any changes made on @task. - */ -void -gtd_task_save (GtdTask *task) -{ - GtdTaskPrivate *priv; - - g_return_if_fail (GTD_IS_TASK (task)); + if (g_strcmp0 (current_title, title) == 0) + return; - priv = gtd_task_get_instance_private (task); + GTD_TASK_CLASS (G_OBJECT_GET_CLASS (task))->set_title (task, title); - e_cal_component_commit_sequence (priv->component); + g_object_notify (G_OBJECT (task), "title"); } /** diff --git a/src/gtd-task.h b/src/gtd-task.h index 4dfb7109..81040aae 100644 --- a/src/gtd-task.h +++ b/src/gtd-task.h @@ -22,7 +22,6 @@ #include "gtd-object.h" #include <glib-object.h> -#include <libecal/libecal.h> G_BEGIN_DECLS @@ -34,25 +33,46 @@ struct _GtdTaskClass { GtdObjectClass parent; + gboolean (*get_complete) (GtdTask *self); + void (*set_complete) (GtdTask *self, + gboolean complete); + + GDateTime* (*get_creation_date) (GtdTask *self); + + const gchar* (*get_description) (GtdTask *self); + void (*set_description) (GtdTask *self, + const gchar *description); + + GDateTime* (*get_due_date) (GtdTask *self); + void (*set_due_date) (GtdTask *self, + GDateTime *due_date); + + gint32 (*get_priority) (GtdTask *self); + void (*set_priority) (GtdTask *self, + gint32 priority); + + const gchar* (*get_title) (GtdTask *self); + void (*set_title) (GtdTask *self, + const gchar *title); + /*< signals >*/ + void (*subtask_added) (GtdTask *self, GtdTask *subtask); void (*subtask_removed) (GtdTask *self, GtdTask *subtask); - gpointer padding[8]; + gpointer padding[6]; }; -GtdTask* gtd_task_new (ECalComponent *component); +GtdTask* gtd_task_new (void); gboolean gtd_task_get_complete (GtdTask *task); void gtd_task_set_complete (GtdTask *task, gboolean complete); -ECalComponent* gtd_task_get_component (GtdTask *task); - GDateTime* gtd_task_get_creation_date (GtdTask *task); const gchar* gtd_task_get_description (GtdTask *task); @@ -80,10 +100,6 @@ const gchar* gtd_task_get_title (GtdTask *tas void gtd_task_set_title (GtdTask *task, const gchar *title); -void gtd_task_abort (GtdTask *task); - -void gtd_task_save (GtdTask *task); - gint gtd_task_compare (GtdTask *t1, GtdTask *t2); |