summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorges Basile Stavracas Neto <georges.stavracas@gmail.com>2017-09-23 11:33:19 -0300
committerGeorges Basile Stavracas Neto <georges.stavracas@gmail.com>2017-09-27 23:30:33 -0300
commit75dc5720956f54c6f78b6340b4e3fa9aa3ba51a9 (patch)
tree72e8853fee6d569e3b755644e48d089c1238d13e
parentcd2b2d864c0d04fd19c9367f087b7edc2ebfb249 (diff)
downloadgnome-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.c9
-rw-r--r--plugins/eds/gtd-task-eds.c592
-rw-r--r--plugins/eds/gtd-task-eds.h39
-rw-r--r--plugins/eds/gtd-task-list-eds.c116
-rw-r--r--plugins/eds/meson.build13
-rw-r--r--plugins/todo-txt/gtd-provider-todo-txt.c18
-rw-r--r--plugins/todo-txt/gtd-todo-txt-parser.c2
-rw-r--r--plugins/todoist/gtd-provider-todoist.c7
-rw-r--r--src/gtd-dnd-row.c2
-rw-r--r--src/gtd-edit-pane.c7
-rw-r--r--src/gtd-new-task-row.c3
-rw-r--r--src/gtd-task-list.c129
-rw-r--r--src/gtd-task-list.h3
-rw-r--r--src/gtd-task.c593
-rw-r--r--src/gtd-task.h34
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, &note);
+}
+
+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, &current_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 (&current_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, &current_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, &note);
+ 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 (&current_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);