summaryrefslogtreecommitdiff
path: root/gdata/services/tasks
diff options
context:
space:
mode:
authorPeteris Krisjanis <pecisk@gmail.com>2013-10-12 15:49:13 +0300
committerPhilip Withnall <philip@tecnocode.co.uk>2013-10-26 00:48:30 +0100
commit1e32273ff60b20da66a5334b911b2346d2af017a (patch)
tree8c426862d0ae7ebf1f98186c1963285cb7d05e0f /gdata/services/tasks
parent3ed33acfa1012f1795907c864d0b3d9a81285140 (diff)
downloadlibgdata-1e32273ff60b20da66a5334b911b2346d2af017a.tar.gz
tasks: Add Google Tasks service support
Adds GDataTasks classes to libgdata: • GDataTasksService • GDataTasksQuery • GDataTasksTasklist • GDataTasksTask This includes full documentation, but no test cases. No new dependencies have been added to libgdata, as all the necessary ones were added with the core JSON work. https://bugzilla.gnome.org/show_bug.cgi?id=657539
Diffstat (limited to 'gdata/services/tasks')
-rw-r--r--gdata/services/tasks/gdata-tasks-query.c638
-rw-r--r--gdata/services/tasks/gdata-tasks-query.h85
-rw-r--r--gdata/services/tasks/gdata-tasks-service.c681
-rw-r--r--gdata/services/tasks/gdata-tasks-service.h108
-rw-r--r--gdata/services/tasks/gdata-tasks-task.c635
-rw-r--r--gdata/services/tasks/gdata-tasks-task.h84
-rw-r--r--gdata/services/tasks/gdata-tasks-tasklist.c80
-rw-r--r--gdata/services/tasks/gdata-tasks-tasklist.h68
8 files changed, 2379 insertions, 0 deletions
diff --git a/gdata/services/tasks/gdata-tasks-query.c b/gdata/services/tasks/gdata-tasks-query.c
new file mode 100644
index 00000000..61f008ca
--- /dev/null
+++ b/gdata/services/tasks/gdata-tasks-query.c
@@ -0,0 +1,638 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * GData Client
+ * Copyright (C) Peteris Krisjanis 2013 <pecisk@gmail.com>
+ *
+ * GData Client is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * GData Client 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GData Client. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * SECTION:gdata-tasks-query
+ * @short_description: GData Tasks query object
+ * @stability: Unstable
+ * @include: gdata/services/tasks/gdata-tasks-query.h
+ *
+ * #GDataTasksQuery represents a collection of query parameters specific to the Google Tasks service, which go above and beyond
+ * those catered for by #GDataQuery.
+ *
+ * For more details of Google Tasks API, see the <ulink type="http" url="https://developers.google.com/google-apps/tasks/v1/reference/">
+ * online documentation</ulink>.
+ *
+ * Since: UNRELEASED
+ */
+
+#include <config.h>
+#include <glib.h>
+#include <glib/gi18n-lib.h>
+#include <string.h>
+
+#include "gdata-tasks-query.h"
+#include "gdata-query.h"
+#include "gdata-parser.h"
+
+static void gdata_tasks_query_finalize (GObject *object);
+static void gdata_tasks_query_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec);
+static void gdata_tasks_query_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec);
+static void get_query_uri (GDataQuery *self, const gchar *feed_uri, GString *query_uri, gboolean *params_started);
+
+struct _GDataTasksQueryPrivate {
+ gint64 completed_max;
+ gint64 completed_min;
+ gint64 due_max;
+ gint64 due_min;
+ gboolean show_completed;
+ gboolean show_deleted;
+ gboolean show_hidden;
+
+ /* These params are here not in GDataQuery due of differently named query params for JSON protocols therefore need for different parse_uri */
+ gint max_results;
+ gchar *page_token;
+ gint64 updated_min;
+};
+
+enum {
+ PROP_COMPLETED_MAX = 1,
+ PROP_COMPLETED_MIN,
+ PROP_DUE_MAX,
+ PROP_DUE_MIN,
+ PROP_SHOW_COMPLETED,
+ PROP_SHOW_DELETED,
+ PROP_SHOW_HIDDEN,
+ PROP_MAX_RESULTS,
+ PROP_PAGE_TOKEN,
+ PROP_UPDATED_MIN,
+};
+
+G_DEFINE_TYPE (GDataTasksQuery, gdata_tasks_query, GDATA_TYPE_QUERY)
+
+static void
+gdata_tasks_query_class_init (GDataTasksQueryClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GDataQueryClass *query_class = GDATA_QUERY_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (GDataTasksQueryPrivate));
+
+ gobject_class->set_property = gdata_tasks_query_set_property;
+ gobject_class->get_property = gdata_tasks_query_get_property;
+ gobject_class->finalize = gdata_tasks_query_finalize;
+
+ query_class->get_query_uri = get_query_uri;
+
+ /**
+ * GDataTasksQuery:completed-max:
+ *
+ * Upper bound for a task's completion date (as a RFC 3339 timestamp) to filter by. Optional.
+ * The default is not to filter by completion date.
+ *
+ * Since: UNRELEASED
+ */
+ g_object_class_install_property (gobject_class, PROP_COMPLETED_MAX,
+ g_param_spec_int64 ("completed-max",
+ "Max task completion date", "Upper bound for a task's completion date to filter by.",
+ -1, G_MAXINT64, -1,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ /**
+ * GDataTasksQuery:completed-min:
+ *
+ * Lower bound for a task's completion date (as a RFC 3339 timestamp) to filter by. Optional.
+ * The default is not to filter by completion date.
+ *
+ * Since: UNRELEASED
+ */
+ g_object_class_install_property (gobject_class, PROP_COMPLETED_MIN,
+ g_param_spec_int64 ("completed-min",
+ "Min task completion date", "Lower bound for a task's completion date to filter by.",
+ -1, G_MAXINT64, -1,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ /**
+ * GDataTasksQuery:due-max:
+ *
+ * Upper bound for a task's due date (as a RFC 3339 timestamp) to filter by. Optional.
+ * The default is not to filter by completion date.
+ *
+ * Since: UNRELEASED
+ */
+ g_object_class_install_property (gobject_class, PROP_DUE_MAX,
+ g_param_spec_int64 ("due-max",
+ "Max task completion date", "Upper bound for a task's completion date to filter by.",
+ -1, G_MAXINT64, -1,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ /**
+ * GDataTasksQuery:due-min:
+ *
+ * Lower bound for a task's due date (as a RFC 3339 timestamp) to filter by. Optional.
+ * The default is not to filter by completion date.
+ * Since: UNRELEASED
+ */
+ g_object_class_install_property (gobject_class, PROP_DUE_MIN,
+ g_param_spec_int64 ("due-min",
+ "Min task completion date", "Lower bound for a task's completion date to filter by.",
+ -1, G_MAXINT64, -1,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ /**
+ * GDataTasksQuery:show-completed:
+ *
+ * Flag indicating whether completed tasks are returned in the result. Optional. The default is %FALSE.
+ *
+ * Since: UNRELEASED
+ */
+ g_object_class_install_property (gobject_class, PROP_SHOW_COMPLETED,
+ g_param_spec_boolean ("show-completed",
+ "Show completed tasks?", "Indicated whatever completed tasks are returned in the result.",
+ FALSE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ /**
+ * GDataTasksQuery:show-deleted:
+ *
+ * Flag indicating whether deleted tasks are returned in the result. Optional. The default is %FALSE.
+ *
+ * Since: UNRELEASED
+ */
+ g_object_class_install_property (gobject_class, PROP_SHOW_DELETED,
+ g_param_spec_boolean ("show-deleted",
+ "Show deleted tasks?", "Indicated whatever deleted tasks are returned in the result.",
+ FALSE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ /**
+ * GDataTasksQuery:show-hidden:
+ *
+ * Flag indicating whether hidden tasks are returned in the result. Optional. The default is %FALSE.
+ *
+ * Since: UNRELEASED
+ */
+ g_object_class_install_property (gobject_class, PROP_SHOW_HIDDEN,
+ g_param_spec_boolean ("show-hidden",
+ "Show hidden tasks?", "Indicated whatever hidden tasks are returned in the result.",
+ FALSE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+}
+
+static void
+gdata_tasks_query_init (GDataTasksQuery *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GDATA_TYPE_TASKS_QUERY, GDataTasksQueryPrivate);
+ self->priv->completed_min = -1;
+ self->priv->completed_max = -1;
+ self->priv->due_min = -1;
+ self->priv->due_max = -1;
+}
+
+static void
+gdata_tasks_query_finalize (GObject *object)
+{
+ /* Chain up to the parent class */
+ G_OBJECT_CLASS (gdata_tasks_query_parent_class)->finalize (object);
+}
+
+static void
+gdata_tasks_query_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+{
+ GDataTasksQueryPrivate *priv = GDATA_TASKS_QUERY (object)->priv;
+
+ switch (property_id) {
+ case PROP_COMPLETED_MAX:
+ g_value_set_int64 (value, priv->completed_max);
+ break;
+ case PROP_COMPLETED_MIN:
+ g_value_set_int64 (value, priv->completed_min);
+ break;
+ case PROP_DUE_MAX:
+ g_value_set_int64 (value, priv->due_max);
+ break;
+ case PROP_DUE_MIN:
+ g_value_set_int64 (value, priv->due_min);
+ break;
+ case PROP_SHOW_COMPLETED:
+ g_value_set_boolean (value, priv->show_completed);
+ break;
+ case PROP_SHOW_DELETED:
+ g_value_set_boolean (value, priv->show_deleted);
+ break;
+ case PROP_SHOW_HIDDEN:
+ g_value_set_boolean (value, priv->show_hidden);
+ break;
+ default:
+ /* We don't have any other property... */
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gdata_tasks_query_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+{
+ GDataTasksQuery *self = GDATA_TASKS_QUERY (object);
+
+ switch (property_id) {
+ case PROP_COMPLETED_MAX:
+ gdata_tasks_query_set_completed_max (self, g_value_get_int64 (value));
+ break;
+ case PROP_COMPLETED_MIN:
+ gdata_tasks_query_set_completed_min (self, g_value_get_int64 (value));
+ break;
+ case PROP_DUE_MAX:
+ gdata_tasks_query_set_due_max (self, g_value_get_int64 (value));
+ break;
+ case PROP_DUE_MIN:
+ gdata_tasks_query_set_due_min (self, g_value_get_int64 (value));
+ break;
+ case PROP_SHOW_COMPLETED:
+ gdata_tasks_query_set_show_completed (self, g_value_get_boolean (value));
+ break;
+ case PROP_SHOW_DELETED:
+ gdata_tasks_query_set_show_deleted (self, g_value_get_boolean (value));
+ break;
+ case PROP_SHOW_HIDDEN:
+ gdata_tasks_query_set_show_hidden (self, g_value_get_boolean (value));
+ break;
+ default:
+ /* We don't have any other property... */
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+get_query_uri (GDataQuery *self, const gchar *feed_uri, GString *query_uri, gboolean *params_started)
+{
+ GDataTasksQueryPrivate *priv = GDATA_TASKS_QUERY (self)->priv;
+
+ #define APPEND_SEP g_string_append_c (query_uri, (*params_started == FALSE) ? '?' : '&'); *params_started = TRUE;
+
+ if (gdata_query_get_max_results (GDATA_QUERY (self)) > 0) {
+ APPEND_SEP
+ g_string_append_printf (query_uri, "maxResults=%u", gdata_query_get_max_results (GDATA_QUERY (self)));
+ }
+
+ if (gdata_query_get_updated_min (GDATA_QUERY (self)) != -1) {
+ gchar *updated_min;
+
+ APPEND_SEP
+ g_string_append (query_uri, "updatedMin=");
+ updated_min = gdata_parser_int64_to_iso8601 (gdata_query_get_updated_min (GDATA_QUERY (self)));
+ g_string_append (query_uri, updated_min);
+ g_free (updated_min);
+ }
+
+ if (priv->completed_min != -1) {
+ gchar *completed_min;
+
+ APPEND_SEP
+ g_string_append (query_uri, "completedMin=");
+ completed_min = gdata_parser_int64_to_iso8601 (priv->completed_min);
+ g_string_append (query_uri, completed_min);
+ g_free (completed_min);
+ }
+
+ if (priv->completed_max != -1) {
+ gchar *completed_max;
+
+ APPEND_SEP
+ g_string_append (query_uri, "completedMax=");
+ completed_max = gdata_parser_int64_to_iso8601 (priv->completed_max);
+ g_string_append (query_uri, completed_max);
+ g_free (completed_max);
+ }
+
+ if (priv->due_min != -1) {
+ gchar *due_min;
+
+ APPEND_SEP
+ g_string_append (query_uri, "dueMin=");
+ due_min = gdata_parser_int64_to_iso8601 (priv->due_min);
+ g_string_append (query_uri, due_min);
+ g_free (due_min);
+ }
+
+ if (priv->due_max != -1) {
+ gchar *due_max;
+
+ APPEND_SEP
+ g_string_append (query_uri, "dueMax=");
+ due_max = gdata_parser_int64_to_iso8601 (priv->due_max);
+ g_string_append (query_uri, due_max);
+ g_free (due_max);
+ }
+
+ APPEND_SEP
+ if (priv->show_completed == TRUE) {
+ g_string_append (query_uri, "showCompleted=true");
+ } else {
+ g_string_append (query_uri, "showCompleted=false");
+ }
+
+ APPEND_SEP
+ if (priv->show_deleted == TRUE) {
+ g_string_append (query_uri, "showDeleted=true");
+ } else {
+ g_string_append (query_uri, "showDeleted=false");
+ }
+
+ APPEND_SEP
+ if (priv->show_hidden == TRUE) {
+ g_string_append (query_uri, "showHidden=true");
+ } else {
+ g_string_append (query_uri, "showHidden=false");
+ }
+
+ /* We don't chain up with parent class get_query_uri because it uses
+ * GData protocol parameters and they aren't compatible with newest API family
+ */
+ #undef APPEND_SEP
+}
+
+/**
+ * gdata_tasks_query_new:
+ * @q: (allow-none): a query string, or %NULL
+ *
+ * Creates a new #GDataTasksQuery with its #GDataQuery:q property set to @q.
+ *
+ * Return value: a new #GDataTasksQuery
+ *
+ * Since: UNRELEASED
+ */
+GDataTasksQuery *
+gdata_tasks_query_new (const gchar *q)
+{
+ return g_object_new (GDATA_TYPE_TASKS_QUERY, "q", q, NULL);
+}
+
+/**
+ * gdata_tasks_query_get_completed_max:
+ * @self: a #GDataTasksQuery
+ *
+ * Gets the #GDataTasksQuery:completed-max property. If the property is unset, <code class="literal">-1</code> will be returned.
+ *
+ * Return value: the UNIX timestamp for the completed-max property, or <code class="literal">-1</code>
+ *
+ * Since: UNRELEASED
+ */
+gint64
+gdata_tasks_query_get_completed_max (GDataTasksQuery *self)
+{
+ g_return_val_if_fail (GDATA_IS_TASKS_QUERY (self), -1);
+ return self->priv->completed_max;
+}
+
+/**
+ * gdata_tasks_query_set_completed_max:
+ * @self: a #GDataTasksQuery
+ * @completed_max: upper bound for a task's completion date by UNIX timestamp, or <code class="literal">-1</code>
+ *
+ * Sets the #GDataTasksQuery:completed-max property of the #GDataTasksQuery
+ * to the new time/date, @completed_max.
+ *
+ * Set @completed_max to <code class="literal">-1</code> to unset the property in the query URI.
+ *
+ * Since: UNRELEASED
+ */
+void
+gdata_tasks_query_set_completed_max (GDataTasksQuery *self, gint64 completed_max)
+{
+ g_return_if_fail (GDATA_IS_TASKS_QUERY (self));
+ g_return_if_fail (completed_max >= -1);
+
+ self->priv->completed_max = completed_max;
+ g_object_notify (G_OBJECT (self), "completed-max");
+}
+
+/**
+ * gdata_tasks_query_get_completed_min:
+ * @self: a #GDataTasksQuery
+ *
+ * Gets the #GDataTasksQuery:completed-min property. If the property is unset, <code class="literal">-1</code> will be returned.
+ *
+ * Return value: the UNIX timestamp for the completed-min property, or <code class="literal">-1</code>
+ *
+ * Since: UNRELEASED
+ */
+gint64
+gdata_tasks_query_get_completed_min (GDataTasksQuery *self)
+{
+ g_return_val_if_fail (GDATA_IS_TASKS_QUERY (self), -1);
+ return self->priv->completed_min;
+}
+
+/**
+ * gdata_tasks_query_set_completed_min:
+ * @self: a #GDataTasksQuery
+ * @completed_min: lower bound for a task's completion date by UNIX timestamp, or <code class="literal">-1</code>
+ *
+ * Sets the #GDataTasksQuery:completed-min property of the #GDataTasksQuery
+ * to the new time/date, @completed_min.
+ *
+ * Set @completed_min to <code class="literal">-1</code> to unset the property in the query URI.
+ *
+ * Since: UNRELEASED
+ */
+void
+gdata_tasks_query_set_completed_min (GDataTasksQuery *self, gint64 completed_min)
+{
+ g_return_if_fail (GDATA_IS_TASKS_QUERY (self));
+ g_return_if_fail (completed_min >= -1);
+
+ self->priv->completed_min = completed_min;
+ g_object_notify (G_OBJECT (self), "completed-min");
+}
+
+/**
+ * gdata_tasks_query_get_due_max:
+ * @self: a #GDataTasksQuery
+ *
+ * Gets the #GDataTasksQuery:due-max property. If the property is unset, <code class="literal">-1</code> will be returned.
+ *
+ * Return value: the UNIX timestamp for the due-max property, or <code class="literal">-1</code>
+ *
+ * Since: UNRELEASED
+ */
+gint64
+gdata_tasks_query_get_due_max (GDataTasksQuery *self)
+{
+ g_return_val_if_fail (GDATA_IS_TASKS_QUERY (self), -1);
+ return self->priv->due_max;
+}
+
+/**
+ * gdata_tasks_query_set_due_max:
+ * @self: a #GDataTasksQuery
+ * @due_max: upper bound for a task's due date by UNIX timestamp, or <code class="literal">-1</code>
+ *
+ * Sets the #GDataTasksQuery:due-max property of the #GDataTasksQuery
+ * to the new time/date, @due_max.
+ *
+ * Set @due_max to <code class="literal">-1</code> to unset the property in the query URI.
+ *
+ * Since: UNRELEASED
+ */
+void
+gdata_tasks_query_set_due_max (GDataTasksQuery *self, gint64 due_max)
+{
+ g_return_if_fail (GDATA_IS_TASKS_QUERY (self));
+ g_return_if_fail (due_max >= -1);
+
+ self->priv->due_max = due_max;
+ g_object_notify (G_OBJECT (self), "due-max");
+}
+
+
+/**
+ * gdata_tasks_query_get_due_min:
+ * @self: a #GDataTasksQuery
+ *
+ * Gets the #GDataTasksQuery:due-min property. If the property is unset, <code class="literal">-1</code> will be returned.
+ *
+ * Return value: the UNIX timestamp for the due-min property, or <code class="literal">-1</code>
+ *
+ * Since: UNRELEASED
+ */
+gint64
+gdata_tasks_query_get_due_min (GDataTasksQuery *self)
+{
+ g_return_val_if_fail (GDATA_IS_TASKS_QUERY (self), -1);
+ return self->priv->due_min;
+}
+
+/**
+ * gdata_tasks_query_set_due_min:
+ * @self: a #GDataTasksQuery
+ * @due_min: lower bound for a task's due date by UNIX timestamp, or <code class="literal">-1</code>
+ *
+ * Sets the #GDataTasksQuery:due-min property of the #GDataTasksQuery
+ * to the new time/date, @due_min.
+ *
+ * Set @due_min to <code class="literal">-1</code> to unset the property in the query URI.
+ *
+ * Since: UNRELEASED
+ */
+void
+gdata_tasks_query_set_due_min (GDataTasksQuery *self, gint64 due_min)
+{
+ g_return_if_fail (GDATA_IS_TASKS_QUERY (self));
+ g_return_if_fail (due_min >= -1);
+
+ self->priv->due_min = due_min;
+ g_object_notify (G_OBJECT (self), "due-min");
+}
+
+/**
+ * gdata_tasks_query_get_show_completed:
+ * @self: a #GDataTasksQuery
+ *
+ * Gets the #GDataTasksQuery:show-completed property.
+ *
+ * Return value: the show-completed property
+ *
+ * Since: UNRELEASED
+ */
+gboolean
+gdata_tasks_query_get_show_completed (GDataTasksQuery *self)
+{
+ g_return_val_if_fail (GDATA_IS_TASKS_QUERY (self), FALSE);
+ return self->priv->show_completed;
+}
+
+/**
+ * gdata_tasks_query_set_show_completed:
+ * @self: a #GDataTasksQuery
+ * @show_completed: %TRUE to show completed tasks, %FALSE otherwise
+ *
+ * Sets the #GDataTasksQuery:show-completed property of the #GDataTasksQuery.
+ *
+ * Since: UNRELEASED
+ */
+void
+gdata_tasks_query_set_show_completed (GDataTasksQuery *self, gboolean show_completed)
+{
+ g_return_if_fail (GDATA_IS_TASKS_QUERY (self));
+
+ self->priv->show_completed = show_completed;
+ g_object_notify (G_OBJECT (self), "show-completed");
+}
+
+/**
+ * gdata_tasks_query_get_show_deleted:
+ * @self: a #GDataTasksQuery
+ *
+ * Gets the #GDataTasksQuery:show-deleted property.
+ *
+ * Return value: the show-deleted property
+ *
+ * Since: UNRELEASED
+ */
+gboolean
+gdata_tasks_query_get_show_deleted (GDataTasksQuery *self)
+{
+ g_return_val_if_fail (GDATA_IS_TASKS_QUERY (self), FALSE);
+ return self->priv->show_deleted;
+}
+
+/**
+ * gdata_tasks_query_set_show_deleted:
+ * @self: a #GDataTasksQuery
+ * @show_deleted: %TRUE to show deleted tasks, %FALSE otherwise
+ *
+ * Sets the #GDataTasksQuery:show-deleted property of the #GDataTasksQuery.
+ *
+ * Since: UNRELEASED
+ */
+void
+gdata_tasks_query_set_show_deleted (GDataTasksQuery *self, gboolean show_deleted)
+{
+ g_return_if_fail (GDATA_IS_TASKS_QUERY (self));
+
+ self->priv->show_deleted = show_deleted;
+ g_object_notify (G_OBJECT (self), "show-deleted");
+}
+
+/**
+ * gdata_tasks_query_get_show_hidden:
+ * @self: a #GDataTasksQuery
+ *
+ * Gets the #GDataTasksQuery:show-hidden property.
+ *
+ * Return value: the show-hidden property
+ *
+ * Since: UNRELEASED
+ */
+gboolean
+gdata_tasks_query_get_show_hidden (GDataTasksQuery *self)
+{
+ g_return_val_if_fail (GDATA_IS_TASKS_QUERY (self), FALSE);
+ return self->priv->show_hidden;
+}
+
+/**
+ * gdata_tasks_query_set_show_hidden:
+ * @self: a #GDataTasksQuery
+ * @show_hidden: %TRUE to show hidden tasks, %FALSE otherwise
+ *
+ * Sets the #GDataTasksQuery:show-hidden property of the #GDataTasksQuery.
+ *
+ * Since: UNRELEASED
+ */
+void
+gdata_tasks_query_set_show_hidden (GDataTasksQuery *self, gboolean show_hidden)
+{
+ g_return_if_fail (GDATA_IS_TASKS_QUERY (self));
+
+ self->priv->show_hidden = show_hidden;
+ g_object_notify (G_OBJECT (self), "show-hidden");
+}
diff --git a/gdata/services/tasks/gdata-tasks-query.h b/gdata/services/tasks/gdata-tasks-query.h
new file mode 100644
index 00000000..0882b268
--- /dev/null
+++ b/gdata/services/tasks/gdata-tasks-query.h
@@ -0,0 +1,85 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * GData Client
+ * Copyright (C) Peteris Krisjanis 2013 <pecisk@gmail.com>
+ *
+ * GData Client is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * GData Client 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GData Client. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GDATA_TASKS_QUERY_H
+#define GDATA_TASKS_QUERY_H
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include <gdata/gdata-query.h>
+#include <gdata/gdata-types.h>
+
+G_BEGIN_DECLS
+
+#define GDATA_TYPE_TASKS_QUERY (gdata_tasks_query_get_type ())
+#define GDATA_TASKS_QUERY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDATA_TYPE_TASKS_QUERY, GDataTasksQuery))
+#define GDATA_TASKS_QUERY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GDATA_TYPE_TASKS_QUERY, GDataTasksQueryClass))
+#define GDATA_IS_TASKS_QUERY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDATA_TYPE_TASKS_QUERY))
+#define GDATA_IS_TASKS_QUERY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GDATA_TYPE_TASKS_QUERY))
+#define GDATA_TASKS_QUERY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDATA_TYPE_TASKS_QUERY, GDataTasksQueryClass))
+
+typedef struct _GDataTasksQueryPrivate GDataTasksQueryPrivate;
+
+/**
+ * GDataTasksQuery:
+ *
+ * All the fields in the #GDataTasksQuery structure are private and should never be accessed directly.
+ *
+ * Since: UNRELEASED
+ */
+typedef struct {
+ GDataQuery parent;
+ GDataTasksQueryPrivate *priv;
+} GDataTasksQuery;
+
+/**
+ * GDataTasksQueryClass:
+ *
+ * All the fields in the #GDataTasksQueryClass structure are private and should never be accessed directly.
+ *
+ * Since: UNRELEASED
+ */
+typedef struct {
+ /*< private >*/
+ GDataQueryClass parent;
+} GDataTasksQueryClass;
+
+GType gdata_tasks_query_get_type (void) G_GNUC_CONST;
+
+GDataTasksQuery *gdata_tasks_query_new (const gchar *q) G_GNUC_WARN_UNUSED_RESULT G_GNUC_MALLOC;
+
+gint64 gdata_tasks_query_get_completed_max (GDataTasksQuery *self) G_GNUC_PURE;
+void gdata_tasks_query_set_completed_max (GDataTasksQuery *self, gint64 completed_max);
+gint64 gdata_tasks_query_get_completed_min (GDataTasksQuery *self) G_GNUC_PURE;
+void gdata_tasks_query_set_completed_min (GDataTasksQuery *self, gint64 completed_min);
+gint64 gdata_tasks_query_get_due_max (GDataTasksQuery *self) G_GNUC_PURE;
+void gdata_tasks_query_set_due_max (GDataTasksQuery *self, gint64 due_max);
+gint64 gdata_tasks_query_get_due_min (GDataTasksQuery *self) G_GNUC_PURE;
+void gdata_tasks_query_set_due_min (GDataTasksQuery *self, gint64 due_min);
+gboolean gdata_tasks_query_get_show_completed (GDataTasksQuery *self) G_GNUC_PURE;
+void gdata_tasks_query_set_show_completed (GDataTasksQuery *self, gboolean show_completed);
+gboolean gdata_tasks_query_get_show_deleted (GDataTasksQuery *self) G_GNUC_PURE;
+void gdata_tasks_query_set_show_deleted (GDataTasksQuery *self, gboolean show_deleted);
+gboolean gdata_tasks_query_get_show_hidden (GDataTasksQuery *self) G_GNUC_PURE;
+void gdata_tasks_query_set_show_hidden (GDataTasksQuery *self, gboolean show_hidden);
+
+G_END_DECLS
+
+#endif /* !GDATA_TASKS_QUERY_H */
diff --git a/gdata/services/tasks/gdata-tasks-service.c b/gdata/services/tasks/gdata-tasks-service.c
new file mode 100644
index 00000000..5e18f4ae
--- /dev/null
+++ b/gdata/services/tasks/gdata-tasks-service.c
@@ -0,0 +1,681 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * GData Client
+ * Copyright (C) Peteris Krisjanis 2013 <pecisk@gmail.com>
+ *
+ * GData Client is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * GData Client 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GData Client. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * SECTION:gdata-tasks-service
+ * @short_description: GData Tasks service object
+ * @stability: Unstable
+ * @include: gdata/services/tasks/gdata-tasks-service.h
+ *
+ * #GDataTasksService is a subclass of #GDataService for communicating with the API of Google Tasks. It supports querying
+ * for, inserting, editing and deleting tasks from tasklists, as well as operations on the tasklists themselves.
+ *
+ * For more details of Google Tasks API, see the <ulink type="http" url="https://developers.google.com/google-apps/tasks/v1/reference/">
+ * online documentation</ulink>.
+ *
+ * Since: UNRELEASED
+ */
+
+#include <config.h>
+#include <glib.h>
+#include <glib/gi18n-lib.h>
+#include <string.h>
+
+#include "gdata-tasks-service.h"
+#include "gdata-service.h"
+#include "gdata-private.h"
+#include "gdata-query.h"
+#include "gdata-feed.h"
+
+/* Standards reference here: https://developers.google.com/google-apps/tasks/v1/reference/ */
+
+static GList *get_authorization_domains (void);
+_GDATA_DEFINE_AUTHORIZATION_DOMAIN (tasks, "tasks", "https://www.googleapis.com/auth/tasks")
+G_DEFINE_TYPE (GDataTasksService, gdata_tasks_service, GDATA_TYPE_SERVICE)
+
+static void
+gdata_tasks_service_class_init (GDataTasksServiceClass *klass)
+{
+ GDataServiceClass *service_class = GDATA_SERVICE_CLASS (klass);
+ service_class->feed_type = GDATA_TYPE_FEED;
+ service_class->get_authorization_domains = get_authorization_domains;
+}
+
+static void
+gdata_tasks_service_init (GDataTasksService *self)
+{
+ /* Nothing to see here */
+}
+
+static GList *
+get_authorization_domains (void)
+{
+ return g_list_prepend (NULL, get_tasks_authorization_domain ());
+}
+
+/**
+ * gdata_tasks_service_new:
+ * @authorizer: (allow-none): a #GDataAuthorizer to authorize the service's requests, or %NULL
+ *
+ * Creates a new #GDataTasksService using the given #GDataAuthorizer. If @authorizer is %NULL, all requests are made as an unauthenticated user.
+ *
+ * Return value: a new #GDataTasksService, or %NULL; unref with g_object_unref()
+ *
+ * Since: UNRELEASED
+ */
+GDataTasksService *
+gdata_tasks_service_new (GDataAuthorizer *authorizer)
+{
+ g_return_val_if_fail (authorizer == NULL || GDATA_IS_AUTHORIZER (authorizer), NULL);
+
+ return g_object_new (GDATA_TYPE_TASKS_SERVICE,
+ "authorizer", authorizer,
+ NULL);
+}
+
+/**
+ * gdata_tasks_service_get_primary_authorization_domain:
+ *
+ * The primary #GDataAuthorizationDomain for interacting with Google Tasks. This will not normally need to be used, as it's used internally
+ * by the #GDataTasksService methods. However, if using the plain #GDataService methods to implement custom queries or requests which libgdata
+ * does not support natively, then this domain may be needed to authorize the requests.
+ *
+ * The domain never changes, and is interned so that pointer comparison can be used to differentiate it from other authorization domains.
+ *
+ * Return value: (transfer none): the service's authorization domain
+ *
+ * Since: UNRELEASED
+ */
+GDataAuthorizationDomain *
+gdata_tasks_service_get_primary_authorization_domain (void)
+{
+ return get_tasks_authorization_domain ();
+}
+
+/**
+ * gdata_tasks_service_query_all_tasklists:
+ * @self: a #GDataTasksService
+ * @query: (allow-none): a #GDataQuery with the query parameters, or %NULL
+ * @cancellable: (allow-none): optional #GCancellable object, or %NULL
+ * @progress_callback: (allow-none) (scope call) (closure progress_user_data): a #GDataQueryProgressCallback to call when an entry is loaded, or %NULL
+ * @progress_user_data: (closure): data to pass to the @progress_callback function
+ * @error: (allow-none): a #GError, or %NULL
+ *
+ * Queries the service to return a list of all tasklists from the authenticated account which match the given
+ * @query. It will return all tasklists the user has read access to.
+ *
+ * For more details, see gdata_service_query().
+ *
+ * Return value: (transfer full): a #GDataFeed of query results; unref with g_object_unref()
+ *
+ * Since: UNRELEASED
+ */
+GDataFeed *
+gdata_tasks_service_query_all_tasklists (GDataTasksService *self, GDataQuery *query, GCancellable *cancellable,
+ GDataQueryProgressCallback progress_callback, gpointer progress_user_data, GError **error)
+{
+ GDataFeed *feed;
+ gchar *request_uri;
+
+ g_return_val_if_fail (GDATA_IS_TASKS_SERVICE (self), NULL);
+ g_return_val_if_fail (query == NULL || GDATA_IS_QUERY (query), NULL);
+ g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+ /* Ensure we're authenticated first */
+ if (gdata_authorizer_is_authorized_for_domain (gdata_service_get_authorizer (GDATA_SERVICE (self)),
+ get_tasks_authorization_domain ()) == FALSE) {
+ g_set_error_literal (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_AUTHENTICATION_REQUIRED,
+ _("You must be authenticated to query all tasklists."));
+ return NULL;
+ }
+
+ request_uri = g_strconcat (_gdata_service_get_scheme (), "://www.googleapis.com/tasks/v1/users/@me/lists", NULL);
+ feed = gdata_service_query (GDATA_SERVICE (self), get_tasks_authorization_domain (), request_uri, query, GDATA_TYPE_TASKS_TASKLIST,
+ cancellable, progress_callback, progress_user_data, error);
+ g_free (request_uri);
+
+ return feed;
+}
+
+/**
+ * gdata_tasks_service_query_all_tasklists_async:
+ * @self: a #GDataTasksService
+ * @query: (allow-none): a #GDataQuery with the query parameters, or %NULL
+ * @cancellable: (allow-none): optional #GCancellable object, or %NULL
+ * @progress_callback: (allow-none) (closure progress_user_data): a #GDataQueryProgressCallback to call when an entry is loaded, or %NULL
+ * @progress_user_data: (closure): data to pass to the @progress_callback function
+ * @destroy_progress_user_data: (allow-none): the function to call when @progress_callback will not be called any more, or %NULL. This function will be
+ * called with @progress_user_data as a parameter and can be used to free any memory allocated for it.
+ * @callback: a #GAsyncReadyCallback to call when authentication is finished
+ * @user_data: (closure): data to pass to the @callback function
+ *
+ * Queries the service to return a list of all tasklists from the authenticated account which match the given
+ * @query. @self and @query are all reffed when this function is called, so can safely be unreffed after
+ * this function returns.
+ *
+ * For more details, see gdata_tasks_service_query_all_tasklists(), which is the synchronous version of
+ * this function, and gdata_service_query_async(), which is the base asynchronous query function.
+ *
+ * Since: UNRELEASED
+ */
+void
+gdata_tasks_service_query_all_tasklists_async (GDataTasksService *self, GDataQuery *query, GCancellable *cancellable,
+ GDataQueryProgressCallback progress_callback, gpointer progress_user_data,
+ GDestroyNotify destroy_progress_user_data,
+ GAsyncReadyCallback callback, gpointer user_data)
+{
+ gchar *request_uri;
+
+ g_return_if_fail (GDATA_IS_TASKS_SERVICE (self));
+ g_return_if_fail (query == NULL || GDATA_IS_QUERY (query));
+ g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+ g_return_if_fail (callback != NULL);
+
+ /* Ensure we're authenticated first */
+ if (gdata_authorizer_is_authorized_for_domain (gdata_service_get_authorizer (GDATA_SERVICE (self)),
+ get_tasks_authorization_domain ()) == FALSE) {
+ GSimpleAsyncResult *result = g_simple_async_result_new (G_OBJECT (self), callback, user_data, gdata_service_query_async);
+ g_simple_async_result_set_error (result, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_AUTHENTICATION_REQUIRED, "%s",
+ _("You must be authenticated to query all tasklists."));
+ g_simple_async_result_complete_in_idle (result);
+ g_object_unref (result);
+
+ return;
+ }
+
+ request_uri = g_strconcat (_gdata_service_get_scheme (), "://www.googleapis.com/tasks/v1/users/@me/lists", NULL);
+ gdata_service_query_async (GDATA_SERVICE (self), get_tasks_authorization_domain (), request_uri, query, GDATA_TYPE_TASKS_TASKLIST,
+ cancellable, progress_callback, progress_user_data, destroy_progress_user_data, callback, user_data);
+ g_free (request_uri);
+}
+
+/**
+ * gdata_tasks_service_query_tasks:
+ * @self: a #GDataTasksService
+ * @tasklist: a #GDataTasksTasklist
+ * @query: (allow-none): a #GDataQuery with the query parameters, or %NULL
+ * @cancellable: (allow-none): optional #GCancellable object, or %NULL
+ * @progress_callback: (allow-none) (scope call) (closure progress_user_data): a #GDataQueryProgressCallback to call when an entry is loaded, or %NULL
+ * @progress_user_data: (closure): data to pass to the @progress_callback function
+ * @error: (allow-none): a #GError, or %NULL
+ *
+ * Queries the service to return a list of tasks in the given @tasklist, which match @query.
+ *
+ * For more details, see gdata_service_query().
+ *
+ * Return value: (transfer full): a #GDataFeed of query results; unref with g_object_unref()
+ *
+ * Since: UNRELEASED
+ */
+GDataFeed *
+gdata_tasks_service_query_tasks (GDataTasksService *self, GDataTasksTasklist *tasklist, GDataQuery *query, GCancellable *cancellable,
+ GDataQueryProgressCallback progress_callback, gpointer progress_user_data, GError **error)
+{
+ gchar* request_uri;
+ GDataFeed *feed;
+
+ g_return_val_if_fail (GDATA_IS_TASKS_SERVICE (self), NULL);
+ g_return_val_if_fail (GDATA_IS_TASKS_TASKLIST (tasklist), NULL);
+ g_return_val_if_fail (query == NULL || GDATA_IS_QUERY (query), NULL);
+ g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+ /* Ensure we're authenticated first */
+ if (gdata_authorizer_is_authorized_for_domain (gdata_service_get_authorizer (GDATA_SERVICE (self)),
+ get_tasks_authorization_domain ()) == FALSE) {
+ g_set_error_literal (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_AUTHENTICATION_REQUIRED,
+ _("You must be authenticated to query your own tasks."));
+ return NULL;
+ }
+
+ /* Should add /tasks as requested by API */
+ request_uri = g_strconcat (_gdata_service_get_scheme (), "://www.googleapis.com/tasks/v1/lists/", gdata_entry_get_id (GDATA_ENTRY (tasklist)), "/tasks", NULL);
+ /* Execute the query */
+ feed = gdata_service_query (GDATA_SERVICE (self), get_tasks_authorization_domain (), request_uri, query, GDATA_TYPE_TASKS_TASK, cancellable,
+ progress_callback, progress_user_data, error);
+ g_free (request_uri);
+
+ return feed;
+}
+
+/**
+ * gdata_tasks_service_query_tasks_async:
+ * @self: a #GDataTasksService
+ * @tasklist: a #GDataTasksTasklist
+ * @query: (allow-none): a #GDataQuery with the query parameters, or %NULL
+ * @cancellable: (allow-none): optional #GCancellable object, or %NULL
+ * @progress_callback: (allow-none) (closure progress_user_data): a #GDataQueryProgressCallback to call when an entry is loaded, or %NULL
+ * @progress_user_data: (closure): data to pass to the @progress_callback function
+ * @destroy_progress_user_data: (allow-none): the function to call when @progress_callback will not be called any more, or %NULL. This function will be
+ * called with @progress_user_data as a parameter and can be used to free any memory allocated for it.
+ * @callback: a #GAsyncReadyCallback to call when the query is finished
+ * @user_data: (closure): data to pass to the @callback function
+ *
+ * Queries the service to return a list of tasks in the given @tasklist, which match @query. @self, @tasklist and @query are all reffed when this
+ * function is called, so can safely be unreffed after this function returns.
+ *
+ * Get the results of the query using gdata_service_query_finish() in the @callback.
+ *
+ * For more details, see gdata_tasks_service_query_tasks(), which is the synchronous version of this function, and gdata_service_query_async(),
+ * which is the base asynchronous query function.
+ *
+ * Since: UNRELEASED
+ */
+void
+gdata_tasks_service_query_tasks_async (GDataTasksService *self, GDataTasksTasklist *tasklist, GDataQuery *query, GCancellable *cancellable,
+ GDataQueryProgressCallback progress_callback, gpointer progress_user_data,
+ GDestroyNotify destroy_progress_user_data,
+ GAsyncReadyCallback callback, gpointer user_data)
+{
+ gchar *request_uri;
+
+ g_return_if_fail (GDATA_IS_TASKS_SERVICE (self));
+ g_return_if_fail (GDATA_IS_TASKS_TASKLIST (tasklist));
+ g_return_if_fail (query == NULL || GDATA_IS_QUERY (query));
+ g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+ g_return_if_fail (callback != NULL);
+
+ /* Ensure we're authenticated first */
+ if (gdata_authorizer_is_authorized_for_domain (gdata_service_get_authorizer (GDATA_SERVICE (self)),
+ get_tasks_authorization_domain ()) == FALSE) {
+ GSimpleAsyncResult *result = g_simple_async_result_new (G_OBJECT (self), callback, user_data, gdata_service_query_async);
+ g_simple_async_result_set_error (result, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_AUTHENTICATION_REQUIRED, "%s",
+ _("You must be authenticated to query your own tasks."));
+ g_simple_async_result_complete_in_idle (result);
+ g_object_unref (result);
+
+ return;
+ }
+
+ /* Should add /tasks as requested by API */
+ request_uri = g_strconcat (_gdata_service_get_scheme (), "://www.googleapis.com/tasks/v1/lists/", gdata_entry_get_id (GDATA_ENTRY (tasklist)), "/tasks", NULL);
+ /* Execute the query */
+ gdata_service_query_async (GDATA_SERVICE (self), get_tasks_authorization_domain (), request_uri, query, GDATA_TYPE_TASKS_TASK, cancellable,
+ progress_callback, progress_user_data, destroy_progress_user_data, callback, user_data);
+ g_free (request_uri);
+}
+
+/**
+ * gdata_tasks_service_insert_task:
+ * @self: a #GDataTasksService
+ * @task: the #GDataTasksTask to insert
+ * @tasklist: #GDataTasksTasklist to insert into
+ * @cancellable: (allow-none): optional #GCancellable object, or %NULL
+ * @error: (allow-none): a #GError, or %NULL
+ *
+ * Inserts @task by uploading it to the online tasks service into tasklist @tasklist. It is safe to unref @tasklist after function returns.
+ *
+ * For more details, see gdata_service_insert_entry().
+ *
+ * Return value: (transfer full): an updated #GDataTasksTask, or %NULL; unref with g_object_unref()
+ *
+ * Since: UNRELEASED
+ */
+GDataTasksTask *
+gdata_tasks_service_insert_task (GDataTasksService *self, GDataTasksTask *task, GDataTasksTasklist *tasklist, GCancellable *cancellable, GError **error)
+{
+ gchar *request_uri;
+ GDataEntry *entry;
+
+ g_return_val_if_fail (GDATA_IS_TASKS_SERVICE (self), NULL);
+ g_return_val_if_fail (GDATA_IS_TASKS_TASK (task), NULL);
+ g_return_val_if_fail (GDATA_IS_TASKS_TASKLIST (tasklist), NULL);
+ g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+ request_uri = g_strconcat (_gdata_service_get_scheme (), "://www.googleapis.com/tasks/v1/lists/", gdata_entry_get_id (GDATA_ENTRY (tasklist)), "/tasks", NULL);
+ entry = gdata_service_insert_entry (GDATA_SERVICE (self), get_tasks_authorization_domain (), request_uri, GDATA_ENTRY (task), cancellable, error);
+ g_free (request_uri);
+
+ return GDATA_TASKS_TASK (entry);
+}
+
+/**
+ * gdata_tasks_service_insert_task_async:
+ * @self: a #GDataTasksService
+ * @task: the #GDataTasksTask to insert
+ * @tasklist: #GDataTasksTasklist to insert into
+ * @cancellable: (allow-none): optional #GCancellable object, or %NULL
+ * @callback: a #GAsyncReadyCallback to call when insertion is finished
+ * @user_data: (closure): data to pass to the @callback function
+ *
+ * Inserts @task by uploading it to the online tasks service into tasklist @tasklist. @self, @task and @tasklist are all reffed when this function is called, so can safely be
+ * unreffed after this function returns.
+ *
+ * @callback should call gdata_service_insert_entry_finish() to obtain a #GDataTasksTask representing the inserted task and to check for possible
+ * errors.
+ *
+ * For more details, see gdata_tasks_service_insert_task(), which is the synchronous version of this function, and
+ * gdata_service_insert_entry_async(), which is the base asynchronous insertion function.
+ *
+ * Since: UNRELEASED
+ */
+void
+gdata_tasks_service_insert_task_async (GDataTasksService *self, GDataTasksTask *task, GDataTasksTasklist *tasklist, GCancellable *cancellable,
+ GAsyncReadyCallback callback, gpointer user_data)
+{
+ gchar *request_uri;
+
+ g_return_val_if_fail (GDATA_IS_TASKS_SERVICE (self), NULL);
+ g_return_val_if_fail (GDATA_IS_TASKS_TASK (task), NULL);
+ g_return_val_if_fail (GDATA_IS_TASKS_TASKLIST (tasklist), NULL);
+ g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+
+ request_uri = g_strconcat (_gdata_service_get_scheme (), "://www.googleapis.com/tasks/v1/lists/", gdata_entry_get_id (GDATA_ENTRY (tasklist)), "/tasks", NULL);
+ gdata_service_insert_entry_async (GDATA_SERVICE (self), get_tasks_authorization_domain (), request_uri, GDATA_ENTRY (task), cancellable,
+ callback, user_data);
+ g_free (request_uri);
+}
+
+/**
+ * gdata_tasks_service_insert_tasklist:
+ * @self: a #GDataTasksService
+ * @tasklist: #GDataTasksTasklist to insert
+ * @cancellable: (allow-none): optional #GCancellable object, or %NULL
+ * @error: (allow-none): a #GError, or %NULL
+ *
+ * Inserts @tasklist by uploading it to the online tasks service.
+ *
+ * For more details, see gdata_service_insert_entry().
+ *
+ * Return value: (transfer full): an updated #GDataTasksTasklist, or %NULL; unref with g_object_unref()
+ *
+ * Since: UNRELEASED
+ */
+GDataTasksTasklist *
+gdata_tasks_service_insert_tasklist (GDataTasksService *self, GDataTasksTasklist *tasklist, GCancellable *cancellable, GError **error)
+{
+ gchar *request_uri;
+ GDataEntry *entry;
+
+ g_return_val_if_fail (GDATA_IS_TASKS_SERVICE (self), NULL);
+ g_return_val_if_fail (GDATA_IS_TASKS_TASKLIST (tasklist), NULL);
+ g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+ request_uri = g_strconcat (_gdata_service_get_scheme (), "://www.googleapis.com/tasks/v1/users/@me/lists", NULL);
+ entry = gdata_service_insert_entry (GDATA_SERVICE (self), get_tasks_authorization_domain (), request_uri, GDATA_ENTRY (tasklist), cancellable, error);
+ g_free (request_uri);
+
+ return GDATA_TASKS_TASKLIST (entry);
+}
+
+/**
+ * gdata_tasks_service_insert_tasklist_async:
+ * @self: a #GDataTasksService
+ * @tasklist: #GDataTasksTasklist to insert
+ * @cancellable: (allow-none): optional #GCancellable object, or %NULL
+ * @callback: a #GAsyncReadyCallback to call when insertion is finished
+ * @user_data: (closure): data to pass to the @callback function
+ *
+ * Inserts @tasklist by uploading it to the online tasks service. @self and @tasklist are both reffed when this function is called, so can safely be
+ * unreffed after this function returns.
+ *
+ * @callback should call gdata_service_insert_entry_finish() to obtain a #GDataTasksTasklist representing the inserted tasklist and to check for possible
+ * errors.
+ *
+ * For more details, see gdata_tasks_service_insert_tasklist(), which is the synchronous version of this function, and
+ * gdata_service_insert_entry_async(), which is the base asynchronous insertion function.
+ *
+ * Since: UNRELEASED
+ */
+void
+gdata_tasks_service_insert_tasklist_async (GDataTasksService *self, GDataTasksTasklist *tasklist, GCancellable *cancellable,
+ GAsyncReadyCallback callback, gpointer user_data)
+{
+ gchar *request_uri;
+
+ g_return_val_if_fail (GDATA_IS_TASKS_SERVICE (self), NULL);
+ g_return_val_if_fail (GDATA_IS_TASKS_TASKLIST (tasklist), NULL);
+ g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+
+ request_uri = g_strconcat (_gdata_service_get_scheme (), "://www.googleapis.com/tasks/v1/users/@me/lists", NULL);
+ gdata_service_insert_entry_async (GDATA_SERVICE (self), get_tasks_authorization_domain (), request_uri, GDATA_ENTRY (tasklist), cancellable,
+ callback, user_data);
+ g_free (request_uri);
+}
+
+/**
+ * gdata_tasks_service_delete_task:
+ * @self: a #GDataTasksService
+ * @task: the #GDataTasksTask to delete
+ * @cancellable: (allow-none): optional #GCancellable object, or %NULL
+ * @error: (allow-none): a #GError, or %NULL
+ *
+ * Delete @task from online tasks service.
+ *
+ * For more details, see gdata_service_delete_entry().
+ *
+ * Return value: %TRUE on success, %FALSE otherwise
+ *
+ * Since: UNRELEASED
+ */
+gboolean
+gdata_tasks_service_delete_task (GDataTasksService *self, GDataTasksTask *task, GCancellable *cancellable, GError **error)
+{
+ g_return_val_if_fail (GDATA_IS_TASKS_SERVICE (self), NULL);
+ g_return_val_if_fail (GDATA_IS_TASKS_TASK (task), NULL);
+ g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+ return gdata_service_delete_entry (GDATA_SERVICE (self), get_tasks_authorization_domain (), GDATA_ENTRY (task), cancellable, error);
+}
+
+/**
+ * gdata_tasks_service_delete_task_async:
+ * @self: a #GDataTasksService
+ * @task: #GDataTasksTask to delete
+ * @cancellable: (allow-none): optional #GCancellable object, or %NULL
+ * @callback: a #GAsyncReadyCallback to call when insertion is finished
+ * @user_data: (closure): data to pass to the @callback function
+ *
+ * Deletes @task from online tasks service. @self and @task are both reffed when this function is called, so can safely be
+ * unreffed after this function returns.
+ *
+ * @callback should call gdata_service_delete_entry_finish() to finish deleting task and to check for possible
+ * errors.
+ *
+ * For more details, see gdata_tasks_service_delete_task(), which is the synchronous version of this function, and
+ * gdata_service_delete_entry_async(), which is the base asynchronous insertion function.
+ *
+ * Since: UNRELEASED
+ */
+void
+gdata_tasks_service_delete_task_async (GDataTasksService *self, GDataTasksTask *task, GCancellable *cancellable,
+ GAsyncReadyCallback callback, gpointer user_data)
+{
+ g_return_val_if_fail (GDATA_IS_TASKS_SERVICE (self), NULL);
+ g_return_val_if_fail (GDATA_IS_TASKS_TASK (task), NULL);
+ g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+
+ gdata_service_delete_entry_async (GDATA_SERVICE (self), get_tasks_authorization_domain (), GDATA_ENTRY (task), cancellable,
+ callback, user_data);
+}
+
+/**
+ * gdata_tasks_service_delete_tasklist:
+ * @self: a #GDataTasksService
+ * @tasklist: the #GDataTasksTasklist to delete
+ * @cancellable: (allow-none): optional #GCancellable object, or %NULL
+ * @error: (allow-none): a #GError, or %NULL
+ *
+ * Delete @tasklist from online tasks service.
+ *
+ * For more details, see gdata_service_delete_entry().
+ *
+ * Return value: %TRUE on success, %FALSE otherwise
+ *
+ * Since: UNRELEASED
+ */
+gboolean
+gdata_tasks_service_delete_tasklist (GDataTasksService *self, GDataTasksTasklist *tasklist, GCancellable *cancellable, GError **error)
+{
+ g_return_val_if_fail (GDATA_IS_TASKS_SERVICE (self), NULL);
+ g_return_val_if_fail (GDATA_IS_TASKS_TASKLIST (tasklist), NULL);
+ g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+ return gdata_service_delete_entry (GDATA_SERVICE (self), get_tasks_authorization_domain (), GDATA_ENTRY (tasklist), cancellable, error);
+}
+
+/**
+ * gdata_tasks_service_delete_tasklist_async:
+ * @self: a #GDataTasksService
+ * @tasklist: #GDataTasksTasklist to delete
+ * @cancellable: (allow-none): optional #GCancellable object, or %NULL
+ * @callback: a #GAsyncReadyCallback to call when insertion is finished
+ * @user_data: (closure): data to pass to the @callback function
+ *
+ * Deletes @tasklist from online tasks service. @self and @tasklist are both reffed when this function is called, so can safely be
+ * unreffed after this function returns.
+ *
+ * @callback should call gdata_service_delete_entry_finish() to finish deleting tasklist and to check for possible
+ * errors.
+ *
+ * For more details, see gdata_tasks_service_delete_tasklist(), which is the synchronous version of this function, and
+ * gdata_service_delete_entry_async(), which is the base asynchronous insertion function.
+ *
+ * Since: UNRELEASED
+ */
+void
+gdata_tasks_service_delete_tasklist_async (GDataTasksService *self, GDataTasksTasklist *tasklist, GCancellable *cancellable,
+ GAsyncReadyCallback callback, gpointer user_data)
+{
+ g_return_val_if_fail (GDATA_IS_TASKS_SERVICE (self), NULL);
+ g_return_val_if_fail (GDATA_IS_TASKS_TASKLIST (tasklist), NULL);
+ g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+
+ gdata_service_delete_entry_async (GDATA_SERVICE (self), get_tasks_authorization_domain (), GDATA_ENTRY (tasklist), cancellable,
+ callback, user_data);
+}
+
+/**
+ * gdata_tasks_service_update_task:
+ * @self: a #GDataTasksService
+ * @task: the #GDataTasksTask to update
+ * @cancellable: (allow-none): optional #GCancellable object, or %NULL
+ * @error: (allow-none): a #GError, or %NULL
+ *
+ * Update @task in online tasks service.
+ *
+ * For more details, see gdata_service_update_entry().
+ *
+ * Return value: (transfer full): an updated #GDataTasksTask, or %NULL; unref with g_object_unref()
+ *
+ * Since: UNRELEASED
+ */
+GDataTasksTask *
+gdata_tasks_service_update_task (GDataTasksService *self, GDataTasksTask *task, GCancellable *cancellable, GError **error)
+{
+ g_return_val_if_fail (GDATA_IS_TASKS_SERVICE (self), NULL);
+ g_return_val_if_fail (GDATA_IS_TASKS_TASK (task), NULL);
+ g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+ return GDATA_TASKS_TASK (gdata_service_update_entry (GDATA_SERVICE (self), get_tasks_authorization_domain (), GDATA_ENTRY (task), cancellable, error));
+}
+
+/**
+ * gdata_tasks_service_update_task_async:
+ * @self: a #GDataTasksService
+ * @task: #GDataTasksTask to update
+ * @cancellable: (allow-none): optional #GCancellable object, or %NULL
+ * @callback: a #GAsyncReadyCallback to call when insertion is finished
+ * @user_data: (closure): data to pass to the @callback function
+ *
+ * Updates @task to online tasks service. @self and @task are both reffed when this function is called, so can safely be
+ * unreffed after this function returns.
+ *
+ * @callback should call gdata_service_update_entry_finish() to obtain a #GDataTasksTask representing the updated task and to check for possible
+ * errors.
+ *
+ * For more details, see gdata_tasks_service_update_task(), which is the synchronous version of this function, and
+ * gdata_service_update_entry_async(), which is the base asynchronous insertion function.
+ *
+ * Since: UNRELEASED
+ */
+void
+gdata_tasks_service_update_task_async (GDataTasksService *self, GDataTasksTask *task, GCancellable *cancellable,
+ GAsyncReadyCallback callback, gpointer user_data)
+{
+ g_return_val_if_fail (GDATA_IS_TASKS_SERVICE (self), NULL);
+ g_return_val_if_fail (GDATA_IS_TASKS_TASK (task), NULL);
+ g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+
+ gdata_service_update_entry_async (GDATA_SERVICE (self), get_tasks_authorization_domain (), GDATA_ENTRY (task), cancellable,
+ callback, user_data);
+}
+
+/**
+ * gdata_tasks_service_update_tasklist:
+ * @self: a #GDataTasksService
+ * @tasklist: the #GDataTasksTasklist to update
+ * @cancellable: (allow-none): optional #GCancellable object, or %NULL
+ * @error: (allow-none): a #GError, or %NULL
+ *
+ * Update @tasklist in online tasks service.
+ *
+ * For more details, see gdata_service_update_entry().
+ *
+ * Return value: (transfer full): an updated #GDataTasksTasklist, or %NULL; unref with g_object_unref()
+ *
+ * Since: UNRELEASED
+ */
+GDataTasksTasklist *
+gdata_tasks_service_update_tasklist (GDataTasksService *self, GDataTasksTasklist *tasklist, GCancellable *cancellable, GError **error)
+{
+ g_return_val_if_fail (GDATA_IS_TASKS_SERVICE (self), NULL);
+ g_return_val_if_fail (GDATA_IS_TASKS_TASKLIST (tasklist), NULL);
+ g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+ return GDATA_TASKS_TASKLIST (gdata_service_update_entry (GDATA_SERVICE (self), get_tasks_authorization_domain (), GDATA_ENTRY (tasklist), cancellable, error));
+}
+
+/**
+ * gdata_tasks_service_update_tasklist_async:
+ * @self: a #GDataTasksService
+ * @tasklist: #GDataTasksTasklist to update
+ * @cancellable: (allow-none): optional #GCancellable object, or %NULL
+ * @callback: a #GAsyncReadyCallback to call when insertion is finished
+ * @user_data: (closure): data to pass to the @callback function
+ *
+ * Updates @tasklist from online tasks service. @self and @tasklist are both reffed when this function is called, so can safely be
+ * unreffed after this function returns.
+ *
+ * @callback should call gdata_service_update_entry_finish() to obtain a #GDataTasksTasklist representing the updated task and to check for possible
+ * errors.
+ *
+ * For more details, see gdata_tasks_service_update_tasklist(), which is the synchronous version of this function, and
+ * gdata_service_update_entry_async(), which is the base asynchronous insertion function.
+ *
+ * Since: UNRELEASED
+ */
+void
+gdata_tasks_service_update_tasklist_async (GDataTasksService *self, GDataTasksTasklist *tasklist, GCancellable *cancellable,
+ GAsyncReadyCallback callback, gpointer user_data)
+{
+ g_return_val_if_fail (GDATA_IS_TASKS_SERVICE (self), NULL);
+ g_return_val_if_fail (GDATA_IS_TASKS_TASKLIST (tasklist), NULL);
+ g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+
+ gdata_service_update_entry_async (GDATA_SERVICE (self), get_tasks_authorization_domain (), GDATA_ENTRY (tasklist), cancellable,
+ callback, user_data);
+}
diff --git a/gdata/services/tasks/gdata-tasks-service.h b/gdata/services/tasks/gdata-tasks-service.h
new file mode 100644
index 00000000..9cd80682
--- /dev/null
+++ b/gdata/services/tasks/gdata-tasks-service.h
@@ -0,0 +1,108 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * GData Client
+ * Copyright (C) Peteris Krisjanis 2013 <pecisk@gmail.com>
+ *
+ * GData Client is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * GData Client 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GData Client. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GDATA_TASKS_SERVICE_H
+#define GDATA_TASKS_SERVICE_H
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include <gdata/gdata-service.h>
+#include <gdata/gdata-query.h>
+#include <gdata/services/tasks/gdata-tasks-tasklist.h>
+#include <gdata/services/tasks/gdata-tasks-task.h>
+
+G_BEGIN_DECLS
+
+#define GDATA_TYPE_TASKS_SERVICE (gdata_tasks_service_get_type ())
+#define GDATA_TASKS_SERVICE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDATA_TYPE_TASKS_SERVICE, GDataTasksService))
+#define GDATA_TASKS_SERVICE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GDATA_TYPE_TASKS_SERVICE, GDataTasksServiceClass))
+#define GDATA_IS_TASKS_SERVICE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDATA_TYPE_TASKS_SERVICE))
+#define GDATA_IS_TASKS_SERVICE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GDATA_TYPE_TASKS_SERVICE))
+#define GDATA_TASKS_SERVICE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDATA_TYPE_TASKS_SERVICE, GDataTasksServiceClass))
+
+/**
+ * GDataTasksService:
+ *
+ * All the fields in the #GDataTasksService structure are private and should never be accessed directly.
+ *
+ * Since: UNRELEASED
+ */
+typedef struct {
+ GDataService parent;
+} GDataTasksService;
+
+/**
+ * GDataTasksServiceClass:
+ *
+ * All the fields in the #GDataTasksServiceClass structure are private and should never be accessed directly.
+ *
+ * Since: UNRELEASED
+ */
+typedef struct {
+ /*< private >*/
+ GDataServiceClass parent;
+} GDataTasksServiceClass;
+
+GType gdata_tasks_service_get_type (void) G_GNUC_CONST;
+
+GDataTasksService *gdata_tasks_service_new (GDataAuthorizer *authorizer) G_GNUC_WARN_UNUSED_RESULT G_GNUC_MALLOC;
+
+GDataAuthorizationDomain *gdata_tasks_service_get_primary_authorization_domain (void) G_GNUC_CONST;
+
+GDataFeed *gdata_tasks_service_query_all_tasklists (GDataTasksService *self, GDataQuery *query, GCancellable *cancellable,
+ GDataQueryProgressCallback progress_callback, gpointer progress_user_data,
+ GError **error) G_GNUC_WARN_UNUSED_RESULT G_GNUC_MALLOC;
+void gdata_tasks_service_query_all_tasklists_async (GDataTasksService *self, GDataQuery *query, GCancellable *cancellable,
+ GDataQueryProgressCallback progress_callback, gpointer progress_user_data,
+ GDestroyNotify destroy_progress_user_data, GAsyncReadyCallback callback, gpointer user_data);
+
+GDataFeed *gdata_tasks_service_query_tasks (GDataTasksService *self, GDataTasksTasklist *tasklist, GDataQuery *query,
+ GCancellable *cancellable, GDataQueryProgressCallback progress_callback, gpointer progress_user_data,
+ GError **error) G_GNUC_WARN_UNUSED_RESULT G_GNUC_MALLOC;
+void gdata_tasks_service_query_tasks_async (GDataTasksService *self, GDataTasksTasklist *tasklist, GDataQuery *query,
+ GCancellable *cancellable, GDataQueryProgressCallback progress_callback, gpointer progress_user_data,
+ GDestroyNotify destroy_progress_user_data, GAsyncReadyCallback callback, gpointer user_data);
+
+GDataTasksTask *gdata_tasks_service_insert_task (GDataTasksService *self, GDataTasksTask *task, GDataTasksTasklist *tasklist,
+ GCancellable *cancellable, GError **error) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
+void gdata_tasks_service_insert_task_async (GDataTasksService *self, GDataTasksTask *task, GDataTasksTasklist *tasklist,
+ GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
+GDataTasksTasklist *gdata_tasks_service_insert_tasklist (GDataTasksService *self, GDataTasksTasklist *tasklist,
+ GCancellable *cancellable, GError **error) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
+void gdata_tasks_service_insert_tasklist_async (GDataTasksService *self, GDataTasksTasklist *tasklist,
+ GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
+gboolean gdata_tasks_service_delete_task (GDataTasksService *self, GDataTasksTask *task,
+ GCancellable *cancellable, GError **error);
+void gdata_tasks_service_delete_task_async (GDataTasksService *self, GDataTasksTask *task,
+ GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
+gboolean gdata_tasks_service_delete_tasklist (GDataTasksService *self, GDataTasksTasklist *tasklist,
+ GCancellable *cancellable, GError **error);
+void gdata_tasks_service_delete_tasklist_async (GDataTasksService *self, GDataTasksTasklist *tasklist,
+ GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
+GDataTasksTask *gdata_tasks_service_update_task (GDataTasksService *self, GDataTasksTask *task,
+ GCancellable *cancellable, GError **error) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
+void gdata_tasks_service_update_task_async (GDataTasksService *self, GDataTasksTask *task,
+ GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
+GDataTasksTasklist *gdata_tasks_service_update_tasklist (GDataTasksService *self, GDataTasksTasklist *tasklist,
+ GCancellable *cancellable, GError **error) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
+void gdata_tasks_service_update_tasklist_async (GDataTasksService *self, GDataTasksTasklist *tasklist,
+ GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
+
+#endif /* !GDATA_TASKS_SERVICE_H */
diff --git a/gdata/services/tasks/gdata-tasks-task.c b/gdata/services/tasks/gdata-tasks-task.c
new file mode 100644
index 00000000..7dcb438f
--- /dev/null
+++ b/gdata/services/tasks/gdata-tasks-task.c
@@ -0,0 +1,635 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * GData Client
+ * Copyright (C) Peteris Krisjanis 2013 <pecisk@gmail.com>
+ *
+ * GData Client is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * GData Client 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GData Client. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * SECTION:gdata-tasks-task
+ * @short_description: GData Tasks task object
+ * @stability: Unstable
+ * @include: gdata/services/tasks/gdata-tasks-task.h
+ *
+ * #GDataTasksTask is a subclass of #GDataEntry to represent a task in a tasklist from Google Tasks.
+ *
+ * For more details of Google Tasks API, see the <ulink type="http" url="https://developers.google.com/google-apps/tasks/v1/reference/">
+ * online documentation</ulink>.
+ *
+ * Since: UNRELEASED
+ */
+
+#include <config.h>
+#include <glib.h>
+#include <glib/gi18n-lib.h>
+#include <string.h>
+
+#include "gdata-tasks-task.h"
+#include "gdata-private.h"
+#include "gdata-service.h"
+#include "gdata-parser.h"
+#include "gdata-types.h"
+#include "gdata-comparable.h"
+
+static void gdata_tasks_task_finalize (GObject *object);
+static void gdata_tasks_task_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec);
+static void gdata_tasks_task_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec);
+static void get_json (GDataParsable *parsable, JsonBuilder *builder);
+static gboolean parse_json (GDataParsable *parsable, JsonReader *reader, gpointer user_data, GError **error);
+static const gchar *get_content_type (void);
+
+struct _GDataTasksTaskPrivate {
+ gchar *parent;
+ gchar *position;
+ gchar *notes;
+ gchar *status;
+ gint64 due;
+ gint64 completed;
+ gboolean deleted;
+ gboolean hidden;
+};
+
+enum {
+ PROP_PARENT = 1,
+ PROP_POSITION,
+ PROP_NOTES,
+ PROP_STATUS,
+ PROP_DUE,
+ PROP_COMPLETED,
+ PROP_DELETED,
+ PROP_HIDDEN,
+};
+
+G_DEFINE_TYPE (GDataTasksTask, gdata_tasks_task, GDATA_TYPE_ENTRY)
+
+static void
+gdata_tasks_task_class_init (GDataTasksTaskClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GDataParsableClass *parsable_class = GDATA_PARSABLE_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (GDataTasksTaskPrivate));
+
+ gobject_class->get_property = gdata_tasks_task_get_property;
+ gobject_class->set_property = gdata_tasks_task_set_property;
+ gobject_class->finalize = gdata_tasks_task_finalize;
+
+ parsable_class->parse_json = parse_json;
+ parsable_class->get_json = get_json;
+ parsable_class->get_content_type = get_content_type;
+
+ /**
+ * GDataTasksTask:parent:
+ *
+ * Parent task identifier. This field is omitted if it is a top-level task. This field is read-only.
+ *
+ * Since: UNRELEASED
+ */
+ g_object_class_install_property (gobject_class, PROP_PARENT,
+ g_param_spec_string ("parent",
+ "Parent of task", "Identifier of parent task.",
+ NULL,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+ /**
+ * GDataTasksTask:position:
+ *
+ * String indicating the position of the task among its sibling tasks under the same parent task
+ * or at the top level. If this string is greater than another task's corresponding position string
+ * according to lexicographical ordering, the task is positioned after the other task under the same
+ * parent task (or at the top level). This field is read-only.
+ *
+ * Since: UNRELEASED
+ */
+ g_object_class_install_property (gobject_class, PROP_STATUS,
+ g_param_spec_string ("position",
+ "Position of task", "Position of the task among sibling tasks using lexicographical order.",
+ NULL,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+ /**
+ * GDataTasksTask:notes:
+ *
+ * This is where the description of what needs to be done in the task is stored.
+ *
+ * Since: UNRELEASED
+ */
+ g_object_class_install_property (gobject_class, PROP_NOTES,
+ g_param_spec_string ("notes",
+ "Notes of task", "Notes describing the task.",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ /**
+ * GDataTasksTask:status:
+ *
+ * Status of the task. This is either "needsAction" or "completed".
+ *
+ * Since: UNRELEASED
+ */
+ g_object_class_install_property (gobject_class, PROP_STATUS,
+ g_param_spec_string ("status",
+ "Status of task", "Status of the task. This is either \"needsAction\" or \"completed\".",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ /**
+ * GDataTasksTask:due:
+ *
+ * Due date of the task (as a RFC 3339 timestamp).
+ * This field is <code class="literal">-1</code> if task has not due date asigned.
+ *
+ * Since: UNRELEASED
+ */
+ g_object_class_install_property (gobject_class, PROP_DUE,
+ g_param_spec_int64 ("due",
+ "Due date of the task", "Due date of the task.",
+ -1, G_MAXINT64, -1,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ /**
+ * GDataTasksTask:completed:
+ *
+ * Completion date of the task (as a RFC 3339 timestamp).
+ * This field is <code class="literal">-1</code> if the task has not been completed.
+ *
+ * Since: UNRELEASED
+ */
+ g_object_class_install_property (gobject_class, PROP_COMPLETED,
+ g_param_spec_int64 ("completed",
+ "Completion date of task", "Completion date of the task.",
+ -1, G_MAXINT64, -1,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ /**
+ * GDataTasksTask:is-deleted:
+ *
+ * Flag indicating whether the task has been deleted. The default is %FALSE.
+ *
+ * Since: UNRELEASED
+ */
+ g_object_class_install_property (gobject_class, PROP_DELETED,
+ g_param_spec_boolean ("is-deleted",
+ "Deleted?", "Indicated whatever task is deleted.",
+ FALSE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ /**
+ * GDataTasksTask:is-hidden:
+ *
+ * Flag indicating whether the task is hidden. This is the case if the task
+ * had been marked completed when the task list was last cleared.
+ * The default is %FALSE. This field is read-only.
+ *
+ * Since: UNRELEASED
+ */
+ g_object_class_install_property (gobject_class, PROP_HIDDEN,
+ g_param_spec_boolean ("is-hidden",
+ "Hidden?", "Indicated whatever task is hidden.",
+ FALSE,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+}
+
+static void
+gdata_tasks_task_init (GDataTasksTask *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GDATA_TYPE_TASKS_TASK, GDataTasksTaskPrivate);
+ self->priv->due = -1;
+ self->priv->completed = -1;
+}
+
+static void
+gdata_tasks_task_finalize (GObject *object)
+{
+ GDataTasksTaskPrivate *priv = GDATA_TASKS_TASK (object)->priv;
+
+ g_free (priv->parent);
+ g_free (priv->position);
+ g_free (priv->notes);
+ g_free (priv->status);
+
+ /* Chain up to the parent class */
+ G_OBJECT_CLASS (gdata_tasks_task_parent_class)->finalize (object);
+}
+
+static void
+gdata_tasks_task_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+{
+ GDataTasksTaskPrivate *priv = GDATA_TASKS_TASK (object)->priv;
+
+ switch (property_id) {
+ case PROP_PARENT:
+ g_value_set_string (value, priv->parent);
+ break;
+ case PROP_POSITION:
+ g_value_set_string (value, priv->position);
+ break;
+ case PROP_NOTES:
+ g_value_set_string (value, priv->notes);
+ break;
+ case PROP_STATUS:
+ g_value_set_string (value, priv->status);
+ break;
+ case PROP_DUE:
+ g_value_set_int64 (value, priv->due);
+ break;
+ case PROP_COMPLETED:
+ g_value_set_int64 (value, priv->completed);
+ break;
+ case PROP_DELETED:
+ g_value_set_boolean (value, priv->deleted);
+ break;
+ case PROP_HIDDEN:
+ g_value_set_boolean (value, priv->hidden);
+ break;
+ default:
+ /* We don't have any other property... */
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gdata_tasks_task_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+{
+ GDataTasksTask *self = GDATA_TASKS_TASK (object);
+
+ switch (property_id) {
+ case PROP_NOTES:
+ gdata_tasks_task_set_notes (self, g_value_get_string (value));
+ break;
+ case PROP_STATUS:
+ gdata_tasks_task_set_status (self, g_value_get_string (value));
+ break;
+ case PROP_DUE:
+ gdata_tasks_task_set_due (self, g_value_get_int64 (value));
+ break;
+ case PROP_COMPLETED:
+ gdata_tasks_task_set_completed (self, g_value_get_int64 (value));
+ break;
+ case PROP_DELETED:
+ gdata_tasks_task_set_is_deleted (self, g_value_get_boolean (value));
+ break;
+ case PROP_PARENT:
+ case PROP_POSITION:
+ case PROP_HIDDEN:
+ /* Read-only */
+ default:
+ /* We don't have any other property... */
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static gboolean
+parse_json (GDataParsable *parsable, JsonReader *reader, gpointer user_data, GError **error)
+{
+ gboolean success;
+ GDataTasksTask *self = GDATA_TASKS_TASK (parsable);
+
+ if (gdata_parser_string_from_json_member (reader, "parent", P_DEFAULT, &(self->priv->parent), &success, error) == TRUE ||
+ gdata_parser_string_from_json_member (reader, "position", P_DEFAULT, &(self->priv->position), &success, error) == TRUE ||
+ gdata_parser_string_from_json_member (reader, "notes", P_DEFAULT, &(self->priv->notes), &success, error) == TRUE ||
+ gdata_parser_string_from_json_member (reader, "status", P_DEFAULT, &(self->priv->status), &success, error) == TRUE ||
+ gdata_parser_int64_time_from_json_member (reader, "due", P_DEFAULT, &(self->priv->due), &success, error) == TRUE ||
+ gdata_parser_int64_time_from_json_member (reader, "completed", P_DEFAULT, &(self->priv->completed), &success, error) == TRUE ||
+ gdata_parser_boolean_from_json_member (reader, "deleted", P_DEFAULT, &(self->priv->deleted), &success, error) == TRUE ||
+ gdata_parser_boolean_from_json_member (reader, "hidden", P_DEFAULT, &(self->priv->hidden), &success, error) == TRUE) {
+ return success;
+ } else {
+ return GDATA_PARSABLE_CLASS (gdata_tasks_task_parent_class)->parse_json (parsable, reader, user_data, error);
+ }
+
+ return TRUE;
+}
+
+static gchar*
+iso8601_to_google (gchar* datetime_string) {
+ return g_strjoinv (".000001+00:00", g_strsplit ((const gchar*) datetime_string, "Z", -1));
+}
+
+static void
+get_json (GDataParsable *parsable, JsonBuilder *builder)
+{
+ gchar *due;
+ gchar *completed;
+
+ GDataTasksTaskPrivate *priv = GDATA_TASKS_TASK (parsable)->priv;
+
+ /* Chain up to the parent class */
+ GDATA_PARSABLE_CLASS (gdata_tasks_task_parent_class)->get_json (parsable, builder);
+
+ /* Add all the task specific JSON */
+
+ if (priv->parent != NULL) {
+ json_builder_set_member_name (builder, "parent");
+ json_builder_add_string_value (builder, priv->parent);
+ }
+ if (priv->position != NULL) {
+ json_builder_set_member_name (builder, "position");
+ json_builder_add_string_value (builder, priv->position);
+ }
+ if (priv->notes != NULL) {
+ json_builder_set_member_name (builder, "notes");
+ json_builder_add_string_value (builder, priv->notes);
+ }
+ if (priv->status != NULL) {
+ json_builder_set_member_name (builder, "status");
+ json_builder_add_string_value (builder, priv->status);
+ }
+ if (priv->due != -1) {
+ due = iso8601_to_google (gdata_parser_int64_to_iso8601 (priv->due));
+ json_builder_set_member_name (builder, "due");
+ json_builder_add_string_value (builder, due);
+ g_free (due);
+ }
+ if (priv->completed != -1) {
+ completed = iso8601_to_google (gdata_parser_int64_to_iso8601 (priv->completed));
+ json_builder_set_member_name (builder, "completed");
+ json_builder_add_string_value (builder, completed);
+ g_free (completed);
+ }
+
+ if (priv->deleted == TRUE) {
+ json_builder_set_member_name (builder, "deleted");
+ json_builder_add_boolean_value (builder, TRUE);
+ } else {
+ json_builder_set_member_name (builder, "deleted");
+ json_builder_add_boolean_value (builder, FALSE);
+ }
+}
+
+static const gchar *
+get_content_type (void)
+{
+ return "application/json";
+}
+
+/**
+ * gdata_tasks_task_new:
+ * @id: (allow-none): the task's ID, or %NULL
+ *
+ * Creates a new #GDataTasksTask with the given ID and default properties.
+ *
+ * Return value: a new #GDataTasksTask; unref with g_object_unref()
+ *
+ * Since: UNRELEASED
+ */
+GDataTasksTask *
+gdata_tasks_task_new (const gchar *id)
+{
+ return GDATA_TASKS_TASK (g_object_new (GDATA_TYPE_TASKS_TASK, "id", id, NULL));
+}
+
+/**
+ * gdata_tasks_task_get_parent:
+ * @self: a #GDataTasksTask
+ *
+ * Gets the #GDataTasksTask:parent property.
+ *
+ * Return value: (allow-none): the parent of the task, or %NULL
+ *
+ * Since: UNRELEASED
+ */
+const gchar *
+gdata_tasks_task_get_parent (GDataTasksTask *self)
+{
+ g_return_val_if_fail (GDATA_IS_TASKS_TASK (self), NULL);
+ return self->priv->parent;
+}
+
+/**
+ * gdata_tasks_task_get_position:
+ * @self: a #GDataTasksTask
+ *
+ * Gets the #GDataTasksTask:position property.
+ *
+ * Return value: (allow-none): the position of the task, or %NULL
+ *
+ * Since: UNRELEASED
+ */
+const gchar *
+gdata_tasks_task_get_position (GDataTasksTask *self)
+{
+ g_return_val_if_fail (GDATA_IS_TASKS_TASK (self), NULL);
+ return self->priv->position;
+}
+
+/**
+ * gdata_tasks_task_get_notes:
+ * @self: a #GDataTasksTask
+ *
+ * Gets the #GDataTasksTask:notes property.
+ *
+ * Return value: (allow-none): notes of the task, or %NULL
+ *
+ * Since: UNRELEASED
+ */
+const gchar *
+gdata_tasks_task_get_notes (GDataTasksTask *self)
+{
+ g_return_val_if_fail (GDATA_IS_TASKS_TASK (self), NULL);
+ return self->priv->notes;
+}
+
+/**
+ * gdata_tasks_task_set_notes:
+ * @self: a #GDataTasksTask
+ * @notes: (allow-none): a new notes of the task, or %NULL
+ *
+ * Sets the #GDataTasksTask:notes property to the new notes, @notes.
+ *
+ * Set @notes to %NULL to unset the property in the task.
+ *
+ * Since: UNRELEASED
+ */
+void
+gdata_tasks_task_set_notes (GDataTasksTask *self, const gchar *notes)
+{
+ gchar *local_notes;
+ g_return_if_fail (GDATA_IS_TASKS_TASK (self));
+
+ local_notes = self->priv->notes;
+ self->priv->notes = g_strdup (notes);
+ g_free (local_notes);
+ g_object_notify (G_OBJECT (self), "notes");
+}
+
+/**
+ * gdata_tasks_task_get_status:
+ * @self: a #GDataTasksTask
+ *
+ * Gets the #GDataTasksTask:status property.
+ *
+ * Return value: (allow-none): the status of the task, or %NULL
+ *
+ * Since: UNRELEASED
+ */
+const gchar *
+gdata_tasks_task_get_status (GDataTasksTask *self)
+{
+ g_return_val_if_fail (GDATA_IS_TASKS_TASK (self), NULL);
+ return self->priv->status;
+}
+
+/**
+ * gdata_tasks_task_set_status:
+ * @self: a #GDataTasksTask
+ * @status: (allow-none): a new status of the task, or %NULL
+ *
+ * Sets the #GDataTasksTask:status property to the new status, @status.
+ *
+ * Set @status to %NULL to unset the property in the task.
+ *
+ * Since: UNRELEASED
+ */
+void
+gdata_tasks_task_set_status (GDataTasksTask *self, const gchar *status)
+{
+ gchar *local_status;
+ g_return_if_fail (GDATA_IS_TASKS_TASK (self));
+
+ local_status = self->priv->status;
+ self->priv->status = g_strdup (status);
+ g_free (local_status);
+ g_object_notify (G_OBJECT (self), "status");
+}
+
+/**
+ * gdata_tasks_task_get_due:
+ * @self: a #GDataTasksTask
+ *
+ * Gets the #GDataTasksTask:due property. If the property is unset, <code class="literal">-1</code> will be returned.
+ *
+ * Return value: the due property, or <code class="literal">-1</code>
+ *
+ * Since: UNRELEASED
+ */
+gint64
+gdata_tasks_task_get_due (GDataTasksTask *self)
+{
+ g_return_val_if_fail (GDATA_IS_TASKS_TASK (self), -1);
+ return self->priv->due;
+}
+
+/**
+ * gdata_tasks_task_set_due:
+ * @self: a #GDataTasksTask
+ * @due: due time of the task, or <code class="literal">-1</code>
+ *
+ * Sets the #GDataTasksTask:due property of the #GDataTasksTask to the new due time of the task, @due.
+ *
+ * Set @due to <code class="literal">-1</code> to unset the property in the due time of the task
+ *
+ * Since: UNRELEASED
+ */
+void
+gdata_tasks_task_set_due (GDataTasksTask *self, gint64 due)
+{
+ g_return_if_fail (GDATA_IS_TASKS_TASK (self));
+ g_return_if_fail (due >= -1);
+
+ self->priv->due = due;
+ g_object_notify (G_OBJECT (self), "due");
+}
+
+/**
+ * gdata_tasks_task_get_completed:
+ * @self: a #GDataTasksTask
+ *
+ * Gets the #GDataTasksTask:completed property. If the property is unset, <code class="literal">-1</code> will be returned.
+ *
+ * Return value: the completed property, or <code class="literal">-1</code>
+ *
+ * Since: UNRELEASED
+ */
+gint64
+gdata_tasks_task_get_completed (GDataTasksTask *self)
+{
+ g_return_val_if_fail (GDATA_IS_TASKS_TASK (self), -1);
+ return self->priv->completed;
+}
+
+/**
+ * gdata_tasks_task_set_completed:
+ * @self: a #GDataTasksTask
+ * @completed: completion time of the task, or <code class="literal">-1</code>
+ *
+ * Sets the #GDataTasksTask:completed property of the #GDataTasksTask to the new completion time of the task, @completed.
+ *
+ * Set @completed to <code class="literal">-1</code> to unset the property in the completion time of the task
+ *
+ * Since: UNRELEASED
+ */
+void
+gdata_tasks_task_set_completed (GDataTasksTask *self, gint64 completed)
+{
+ g_return_if_fail (GDATA_IS_TASKS_TASK (self));
+ g_return_if_fail (completed >= -1);
+
+ self->priv->completed = completed;
+ g_object_notify (G_OBJECT (self), "completed");
+}
+
+/**
+ * gdata_tasks_task_is_deleted:
+ * @self: a #GDataTasksTask
+ *
+ * Gets the #GDataTasksTask:is-deleted property.
+ *
+ * Return value: %TRUE if task is deleted, %FALSE otherwise
+ *
+ * Since: UNRELEASED
+ */
+gboolean
+gdata_tasks_task_is_deleted (GDataTasksTask *self)
+{
+ g_return_val_if_fail (GDATA_IS_TASKS_TASK (self), FALSE);
+ return self->priv->deleted;
+}
+
+/**
+ * gdata_tasks_task_set_is_deleted:
+ * @self: a #GDataTasksTask
+ * @deleted: %TRUE if task is deleted, %FALSE otherwise
+ *
+ * Sets the #GDataTasksTask:is-deleted property to @deleted.
+ *
+ * Since: UNRELEASED
+ */
+void
+gdata_tasks_task_set_is_deleted (GDataTasksTask *self, gboolean deleted)
+{
+ g_return_if_fail (GDATA_IS_TASKS_TASK (self));
+ self->priv->deleted = deleted;
+ g_object_notify (G_OBJECT (self), "is-deleted");
+}
+
+/**
+ * gdata_tasks_task_is_hidden:
+ * @self: a #GDataTasksTask
+ *
+ * Gets the #GDataTasksTask:is-hidden property.
+ *
+ * Return value: %TRUE if task is hidden, %FALSE otherwise
+ *
+ * Since: UNRELEASED
+ */
+gboolean
+gdata_tasks_task_is_hidden (GDataTasksTask *self)
+{
+ g_return_val_if_fail (GDATA_IS_TASKS_TASK (self), FALSE);
+ return self->priv->hidden;
+}
diff --git a/gdata/services/tasks/gdata-tasks-task.h b/gdata/services/tasks/gdata-tasks-task.h
new file mode 100644
index 00000000..e791c7d3
--- /dev/null
+++ b/gdata/services/tasks/gdata-tasks-task.h
@@ -0,0 +1,84 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * GData Client
+ * Copyright (C) Peteris Krisjanis 2013 <pecisk@gmail.com>
+ *
+ * GData Client is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * GData Client 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GData Client. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GDATA_TASKS_TASK_H
+#define GDATA_TASKS_TASK_H
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include <gdata/gdata-entry.h>
+#include <gdata/gdata-types.h>
+
+G_BEGIN_DECLS
+
+#define GDATA_TYPE_TASKS_TASK (gdata_tasks_task_get_type ())
+#define GDATA_TASKS_TASK(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDATA_TYPE_TASKS_TASK, GDataTasksTask))
+#define GDATA_TASKS_TASK_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GDATA_TYPE_TASKS_TASK, GDataTasksTaskClass))
+#define GDATA_IS_TASKS_TASK(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDATA_TYPE_TASKS_TASK))
+#define GDATA_IS_TASKS_TASK_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GDATA_TYPE_TASKS_TASK))
+#define GDATA_TASKS_TASK_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDATA_TYPE_TASKS_TASK, GDataTasksTaskClass))
+
+typedef struct _GDataTasksTaskPrivate GDataTasksTaskPrivate;
+
+/**
+ * GDataTasksTask:
+ *
+ * All the fields in the #GDataTasksTask structure are private and should never be accessed directly.
+ *
+ * Since: UNRELEASED
+ */
+typedef struct {
+ GDataEntry parent;
+ GDataTasksTaskPrivate *priv;
+} GDataTasksTask;
+
+/**
+ * GDataTasksTaskClass:
+ *
+ * All the fields in the #GDataTasksTaskClass structure are private and should never be accessed directly.
+ *
+ * Since: UNRELEASED
+ */
+typedef struct {
+ /*< private >*/
+ GDataEntryClass parent;
+} GDataTasksTaskClass;
+
+GType gdata_tasks_task_get_type (void) G_GNUC_CONST;
+
+GDataTasksTask *gdata_tasks_task_new (const gchar *id) G_GNUC_WARN_UNUSED_RESULT G_GNUC_MALLOC;
+
+const gchar *gdata_tasks_task_get_parent (GDataTasksTask *self) G_GNUC_PURE;
+const gchar *gdata_tasks_task_get_position (GDataTasksTask *self) G_GNUC_PURE;
+const gchar *gdata_tasks_task_get_notes (GDataTasksTask *self) G_GNUC_PURE;
+void gdata_tasks_task_set_notes (GDataTasksTask *self, const gchar *notes);
+const gchar *gdata_tasks_task_get_status (GDataTasksTask *self) G_GNUC_PURE;
+void gdata_tasks_task_set_status (GDataTasksTask *self, const gchar *status);
+gint64 gdata_tasks_task_get_due (GDataTasksTask *self) G_GNUC_PURE;
+void gdata_tasks_task_set_due (GDataTasksTask *self, gint64 due);
+gint64 gdata_tasks_task_get_completed (GDataTasksTask *self) G_GNUC_PURE;
+void gdata_tasks_task_set_completed (GDataTasksTask *self, gint64 completed);
+gboolean gdata_tasks_task_is_deleted (GDataTasksTask *self) G_GNUC_PURE;
+void gdata_tasks_task_set_is_deleted (GDataTasksTask *self, gboolean deleted);
+gboolean gdata_tasks_task_is_hidden (GDataTasksTask *self) G_GNUC_PURE;
+
+G_END_DECLS
+
+#endif /* !GDATA_TASKS_TASK_H */
diff --git a/gdata/services/tasks/gdata-tasks-tasklist.c b/gdata/services/tasks/gdata-tasks-tasklist.c
new file mode 100644
index 00000000..eba4dcf4
--- /dev/null
+++ b/gdata/services/tasks/gdata-tasks-tasklist.c
@@ -0,0 +1,80 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * GData Client
+ * Copyright (C) Peteris Krisjanis 2013 <pecisk@gmail.com>
+ *
+ * GData Client is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * GData Client 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GData Client. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * SECTION:gdata-tasks-tasklist
+ * @short_description: GData Tasks tasklist object
+ * @stability: Unstable
+ * @include: gdata/services/tasks/gdata-tasks-tasklist.h
+ *
+ * #GDataTasksTasklist is a subclass of #GDataEntry to represent a tasklist from Google Tasks.
+ *
+ * For more details of Google Tasks API, see the <ulink type="http" url="https://developers.google.com/google-apps/tasks/v1/reference/">
+ * online documentation</ulink>.
+ *
+ * Since: UNRELEASED
+ */
+
+#include <config.h>
+#include <glib.h>
+#include <glib/gi18n-lib.h>
+#include <string.h>
+
+#include "gdata-tasks-tasklist.h"
+#include "gdata-private.h"
+#include "gdata-types.h"
+
+static const gchar *get_content_type (void);
+
+G_DEFINE_TYPE (GDataTasksTasklist, gdata_tasks_tasklist, GDATA_TYPE_ENTRY)
+
+static void
+gdata_tasks_tasklist_class_init (GDataTasksTasklistClass *klass)
+{
+ GDataParsableClass *parsable_class = GDATA_PARSABLE_CLASS (klass);
+ parsable_class->get_content_type = get_content_type;
+}
+
+static void
+gdata_tasks_tasklist_init (GDataTasksTasklist *self)
+{
+ /* Empty */
+}
+
+static const gchar *
+get_content_type (void)
+{
+ return "application/json";
+}
+
+/**
+ * gdata_tasks_tasklist_new:
+ * @id: (allow-none): the tasklist's ID, or %NULL
+ *
+ * Creates a new #GDataTasksTasklist with the given ID and default properties.
+ *
+ * Return value: (transfer full): a new #GDataTasksTasklist; unref with g_object_unref()
+ *
+ * Since: UNRELEASED
+ */
+GDataTasksTasklist *
+gdata_tasks_tasklist_new (const gchar *id)
+{
+ return GDATA_TASKS_TASKLIST (g_object_new (GDATA_TYPE_TASKS_TASKLIST, "id", id, NULL));
+}
diff --git a/gdata/services/tasks/gdata-tasks-tasklist.h b/gdata/services/tasks/gdata-tasks-tasklist.h
new file mode 100644
index 00000000..db5d792f
--- /dev/null
+++ b/gdata/services/tasks/gdata-tasks-tasklist.h
@@ -0,0 +1,68 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * GData Client
+ * Copyright (C) Peteris Krisjanis 2013 <pecisk@gmail.com>
+ *
+ * GData Client is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * GData Client 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GData Client. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GDATA_TASKS_TASKLIST_H
+#define GDATA_TASKS_TASKLIST_H
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include <gdata/gdata-entry.h>
+#include <gdata/gdata-types.h>
+
+G_BEGIN_DECLS
+
+#define GDATA_TYPE_TASKS_TASKLIST (gdata_tasks_tasklist_get_type ())
+#define GDATA_TASKS_TASKLIST(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDATA_TYPE_TASKS_TASKLIST, GDataTasksTasklist))
+#define GDATA_TASKS_TASKLIST_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GDATA_TYPE_TASKS_TASKLIST, GDataTasksTasklistClass))
+#define GDATA_IS_TASKS_TASKLIST(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDATA_TYPE_TASKS_TASKLIST))
+#define GDATA_IS_TASKS_TASKLIST_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GDATA_TYPE_TASKS_TASKLIST))
+#define GDATA_TASKS_TASKLIST_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDATA_TYPE_TASKS_TASKLIST, GDataTasksTasklistClass))
+
+/**
+ * GDataTasksTasklist:
+ *
+ * All the fields in the #GDataTasksTasklist structure are private and should never be accessed directly.
+ *
+ * Since: UNRELEASED
+ */
+typedef struct {
+ GDataEntry parent;
+} GDataTasksTasklist;
+
+/**
+ * GDataTasksTasklistClass:
+ *
+ * All the fields in the #GDataTasksTasklistClass structure are private and should never be accessed directly.
+ *
+ * Since: UNRELEASED
+ */
+
+typedef struct {
+ /*< private >*/
+ GDataEntryClass parent;
+} GDataTasksTasklistClass;
+
+GType gdata_tasks_tasklist_get_type (void) G_GNUC_CONST;
+
+GDataTasksTasklist *gdata_tasks_tasklist_new (const gchar *id) G_GNUC_WARN_UNUSED_RESULT G_GNUC_MALLOC;
+
+G_END_DECLS
+
+#endif /* !GDATA_TASKS_TASKLIST_H */