summaryrefslogtreecommitdiff
path: root/src/core/gtd-provider.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/gtd-provider.c')
-rw-r--r--src/core/gtd-provider.c681
1 files changed, 681 insertions, 0 deletions
diff --git a/src/core/gtd-provider.c b/src/core/gtd-provider.c
new file mode 100644
index 0000000..1d69a80
--- /dev/null
+++ b/src/core/gtd-provider.c
@@ -0,0 +1,681 @@
+/* gtd-provider.c
+ *
+ * Copyright (C) 2015-2020 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/>.
+ */
+
+#define G_LOG_DOMAIN "GtdProvider"
+
+#include "gtd-provider.h"
+#include "gtd-task.h"
+#include "gtd-task-list.h"
+#include "gtd-utils.h"
+
+/**
+ * SECTION:gtd-provider
+ * @short_description:data sources for Endeavour
+ * @title: GtdProvider
+ * @stability:Unstable
+ *
+ * The #GtdProvider is the interface that Endeavour uses to
+ * connect to data sources. It must provide ways to create, update
+ * and remove tasks and tasklists.
+ *
+ * A provider implementation must also expose which is the default
+ * tasklist among the tasklists it manages.
+ */
+
+G_DEFINE_INTERFACE (GtdProvider, gtd_provider, GTD_TYPE_OBJECT)
+
+enum
+{
+ LIST_ADDED,
+ LIST_CHANGED,
+ LIST_REMOVED,
+ NUM_SIGNALS
+};
+
+static guint signals[NUM_SIGNALS] = { 0, };
+
+
+static void
+gtd_provider_default_init (GtdProviderInterface *iface)
+{
+ /**
+ * GtdProvider::enabled:
+ *
+ * Whether the #GtdProvider is enabled.
+ */
+ g_object_interface_install_property (iface,
+ g_param_spec_boolean ("enabled",
+ "Identifier of the provider",
+ "The identifier of the provider",
+ FALSE,
+ G_PARAM_READABLE));
+
+ /**
+ * GtdProvider::icon:
+ *
+ * The icon of the #GtdProvider, e.g. the account icon
+ * of a GNOME Online Accounts' account.
+ */
+ g_object_interface_install_property (iface,
+ g_param_spec_object ("icon",
+ "Icon of the provider",
+ "The icon of the provider",
+ G_TYPE_ICON,
+ G_PARAM_READABLE));
+
+ /**
+ * GtdProvider::id:
+ *
+ * The unique identifier of the #GtdProvider.
+ */
+ g_object_interface_install_property (iface,
+ g_param_spec_string ("id",
+ "Identifier of the provider",
+ "The identifier of the provider",
+ NULL,
+ G_PARAM_READABLE));
+
+ /**
+ * GtdProvider::name:
+ *
+ * The user-visible name of the #GtdProvider.
+ */
+ g_object_interface_install_property (iface,
+ g_param_spec_string ("name",
+ "Name of the provider",
+ "The user-visible name of the provider",
+ NULL,
+ G_PARAM_READABLE));
+
+ /**
+ * GtdProvider::provider-type:
+ *
+ * The type of the #GtdProvider.
+ */
+ g_object_interface_install_property (iface,
+ g_param_spec_string ("provider-type",
+ "Type of the provider",
+ "The type of the provider",
+ NULL,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+ /**
+ * GtdProvider::description:
+ *
+ * The description of the #GtdProvider, e.g. the account user
+ * of a GNOME Online Accounts' account.
+ */
+ g_object_interface_install_property (iface,
+ g_param_spec_string ("description",
+ "Description of the provider",
+ "The description of the provider",
+ NULL,
+ G_PARAM_READABLE));
+
+ /**
+ * GtdProvider::list-added:
+ * @provider: a #GtdProvider
+ * @list: a #GtdTaskList
+ *
+ * The ::list-added signal is emmited after a #GtdTaskList
+ * is connected.
+ */
+ signals[LIST_ADDED] = g_signal_new ("list-added",
+ GTD_TYPE_PROVIDER,
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL,
+ NULL,
+ NULL,
+ G_TYPE_NONE,
+ 1,
+ GTD_TYPE_TASK_LIST);
+
+ /**
+ * GtdProvider::list-changed:
+ * @provider: a #GtdProvider
+ * @list: a #GtdTaskList
+ *
+ * The ::list-changed signal is emmited after a #GtdTaskList
+ * has any of it's properties changed.
+ */
+ signals[LIST_CHANGED] = g_signal_new ("list-changed",
+ GTD_TYPE_PROVIDER,
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL,
+ NULL,
+ NULL,
+ G_TYPE_NONE,
+ 1,
+ GTD_TYPE_TASK_LIST);
+
+ /**
+ * GtdProvider::list-removed:
+ * @provider: a #GtdProvider
+ * @list: a #GtdTaskList
+ *
+ * The ::list-removed signal is emmited after a #GtdTaskList
+ * is disconnected.
+ */
+ signals[LIST_REMOVED] = g_signal_new ("list-removed",
+ GTD_TYPE_PROVIDER,
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL,
+ NULL,
+ NULL,
+ G_TYPE_NONE,
+ 1,
+ GTD_TYPE_TASK_LIST);
+}
+
+/**
+ * gtd_provider_get_id:
+ * @provider: a #GtdProvider
+ *
+ * Retrieves the identifier of @provider.
+ *
+ * Returns: (transfer none): the id of @provider
+ */
+const gchar*
+gtd_provider_get_id (GtdProvider *provider)
+{
+ g_return_val_if_fail (GTD_IS_PROVIDER (provider), NULL);
+ g_return_val_if_fail (GTD_PROVIDER_GET_IFACE (provider)->get_id, NULL);
+
+ return GTD_PROVIDER_GET_IFACE (provider)->get_id (provider);
+}
+
+/**
+ * gtd_provider_get_name:
+ * @provider: a #GtdProvider
+ *
+ * Retrieves the user-visible name of @provider.
+ *
+ * Returns: (transfer none): the name of @provider
+ */
+const gchar*
+gtd_provider_get_name (GtdProvider *provider)
+{
+ g_return_val_if_fail (GTD_IS_PROVIDER (provider), NULL);
+ g_return_val_if_fail (GTD_PROVIDER_GET_IFACE (provider)->get_name, NULL);
+
+ return GTD_PROVIDER_GET_IFACE (provider)->get_name (provider);
+}
+
+/**
+ * gtd_provider_get_provider_type:
+ * @provider: a #GtdProvider
+ *
+ * Retrieves the type of the @provider. This should return the
+ * same value, regardless of the account name.
+ *
+ * For example: "todoist", "todo-txt" or "google"
+ *
+ * Returns: (transfer none): the type of the @provider
+ */
+const gchar*
+gtd_provider_get_provider_type (GtdProvider *provider)
+{
+ g_return_val_if_fail (GTD_IS_PROVIDER (provider), NULL);
+ g_return_val_if_fail (GTD_PROVIDER_GET_IFACE (provider)->get_name, NULL);
+
+ return GTD_PROVIDER_GET_IFACE (provider)->get_provider_type (provider);
+}
+
+/**
+ * gtd_provider_get_description:
+ * @provider: a #GtdProvider
+ *
+ * Retrieves the description of @provider.
+ *
+ * Returns: (transfer none): the description of @provider
+ */
+const gchar*
+gtd_provider_get_description (GtdProvider *provider)
+{
+ g_return_val_if_fail (GTD_IS_PROVIDER (provider), NULL);
+ g_return_val_if_fail (GTD_PROVIDER_GET_IFACE (provider)->get_description, NULL);
+
+ return GTD_PROVIDER_GET_IFACE (provider)->get_description (provider);
+}
+
+/**
+ * gtd_provider_get_enabled:
+ * @provider: a #GtdProvider
+ *
+ * Retrieves whether @provider is enabled or not. A disabled
+ * provider cannot be selected to be default nor be selected
+ * to add tasks to it.
+ *
+ * Returns: %TRUE if provider is enabled, %FALSE otherwise.
+ */
+gboolean
+gtd_provider_get_enabled (GtdProvider *provider)
+{
+ g_return_val_if_fail (GTD_IS_PROVIDER (provider), FALSE);
+ g_return_val_if_fail (GTD_PROVIDER_GET_IFACE (provider)->get_enabled, FALSE);
+
+ return GTD_PROVIDER_GET_IFACE (provider)->get_enabled (provider);
+}
+
+/**
+ * gtd_provider_refresh:
+ * @provider: a #GtdProvider
+ *
+ * Asks the provider to refresh. Online providers may want to
+ * synchronize tasks and tasklists, credentials, etc, when this
+ * is called.
+ *
+ * This is an optional feature. Providers that do not implement
+ * the "refresh" vfunc will be ignored.
+ */
+void
+gtd_provider_refresh (GtdProvider *provider)
+{
+ g_return_if_fail (GTD_IS_PROVIDER (provider));
+
+ if (GTD_PROVIDER_GET_IFACE (provider)->refresh)
+ GTD_PROVIDER_GET_IFACE (provider)->refresh (provider);
+}
+
+/**
+ * gtd_provider_get_icon:
+ * @provider: a #GtdProvider
+ *
+ * The icon of @provider.
+ *
+ * Returns: (transfer none): a #GIcon
+ */
+GIcon*
+gtd_provider_get_icon (GtdProvider *provider)
+{
+ g_return_val_if_fail (GTD_IS_PROVIDER (provider), NULL);
+ g_return_val_if_fail (GTD_PROVIDER_GET_IFACE (provider)->get_icon, NULL);
+
+ return GTD_PROVIDER_GET_IFACE (provider)->get_icon (provider);
+}
+
+/**
+ * gtd_provider_create_task:
+ * @provider: a #GtdProvider
+ * @list: a #GtdTaskLast
+ * @title: The task title
+ * @due_date: (nullable): a #GDateTime
+ * @cancellable: (nullable): a #GCancellable
+ * @callback: (scope async): a callback
+ * @user_data: (closure): user data for @callback
+ *
+ * Creates the given task in @provider.
+ */
+void
+gtd_provider_create_task (GtdProvider *provider,
+ GtdTaskList *list,
+ const gchar *title,
+ GDateTime *due_date,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_return_if_fail (GTD_IS_PROVIDER (provider));
+ g_return_if_fail (GTD_PROVIDER_GET_IFACE (provider)->create_task);
+
+ GTD_PROVIDER_GET_IFACE (provider)->create_task (provider,
+ list,
+ title,
+ due_date,
+ cancellable,
+ callback,
+ user_data);
+}
+
+/**
+ * gtd_provider_create_task_finish:
+ * @self: a #GtdProvider
+ * @result: a #GAsyncResult
+ * @error: (out)(nullable): return location for a #GError
+ *
+ * Finishes creating the task.
+ *
+ * Returns: (transfer none)(nullable): a #GtdTask
+ */
+GtdTask*
+gtd_provider_create_task_finish (GtdProvider *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_return_val_if_fail (GTD_IS_PROVIDER (self), FALSE);
+ g_return_val_if_fail (!error || !*error, FALSE);
+ g_return_val_if_fail (GTD_PROVIDER_GET_IFACE (self)->create_task_finish, FALSE);
+
+ return GTD_PROVIDER_GET_IFACE (self)->create_task_finish (self, result, error);
+}
+
+/**
+ * gtd_provider_update_task:
+ * @provider: a #GtdProvider
+ * @task: a #GtdTask
+ * @cancellable: (nullable): a #GCancellable
+ * @callback: (scope async): a callback
+ * @user_data: (closure): user data for @callback
+ *
+ * Updates the given task in @provider.
+ */
+void
+gtd_provider_update_task (GtdProvider *provider,
+ GtdTask *task,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_return_if_fail (GTD_IS_PROVIDER (provider));
+ g_return_if_fail (GTD_PROVIDER_GET_IFACE (provider)->update_task);
+
+ GTD_PROVIDER_GET_IFACE (provider)->update_task (provider,
+ task,
+ cancellable,
+ callback,
+ user_data);
+}
+
+/**
+ * gtd_provider_update_task_finish:
+ * @self: a #GtdProvider
+ * @result: a #GAsyncResult
+ * @error: (out)(nullable): return location for a #GError
+ *
+ * Finishes updating the task list.
+ *
+ * Returns: %TRUE if task list was successfully updated, %FALSE otherwise
+ */
+gboolean
+gtd_provider_update_task_finish (GtdProvider *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_return_val_if_fail (GTD_IS_PROVIDER (self), FALSE);
+ g_return_val_if_fail (!error || !*error, FALSE);
+ g_return_val_if_fail (GTD_PROVIDER_GET_IFACE (self)->update_task_finish, FALSE);
+
+ return GTD_PROVIDER_GET_IFACE (self)->update_task_finish (self, result, error);
+}
+
+/**
+ * gtd_provider_remove_task:
+ * @provider: a #GtdProvider
+ * @task: a #GtdTask
+ * @cancellable: (nullable): a #GCancellable
+ * @callback: (scope async): a callback
+ * @user_data: (closure): user data for @callback
+ *
+ * Removes the given task from @provider.
+ */
+void
+gtd_provider_remove_task (GtdProvider *provider,
+ GtdTask *task,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_return_if_fail (GTD_IS_PROVIDER (provider));
+ g_return_if_fail (GTD_PROVIDER_GET_IFACE (provider)->remove_task);
+
+ GTD_PROVIDER_GET_IFACE (provider)->remove_task (provider,
+ task,
+ cancellable,
+ callback,
+ user_data);
+}
+
+/**
+ * gtd_provider_remove_task_finish:
+ * @self: a #GtdProvider
+ * @result: a #GAsyncResult
+ * @error: (out)(nullable): return location for a #GError
+ *
+ * Finishes removing the task.
+ *
+ * Returns: %TRUE if task was successfully removed, %FALSE otherwise
+ */
+gboolean
+gtd_provider_remove_task_finish (GtdProvider *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_return_val_if_fail (GTD_IS_PROVIDER (self), FALSE);
+ g_return_val_if_fail (!error || !*error, FALSE);
+ g_return_val_if_fail (GTD_PROVIDER_GET_IFACE (self)->remove_task_finish, FALSE);
+
+ return GTD_PROVIDER_GET_IFACE (self)->remove_task_finish (self, result, error);
+}
+
+/**
+ * gtd_provider_create_task_list:
+ * @provider: a #GtdProvider
+ * @name: (nullable): the name of the new task list
+ * @cancellable: (nullable): a #GCancellable
+ * @callback: (scope async): a callback
+ * @user_data: (closure): user data for @callback
+ *
+ * Creates the given list in @provider.
+ */
+void
+gtd_provider_create_task_list (GtdProvider *provider,
+ const gchar *name,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_return_if_fail (GTD_IS_PROVIDER (provider));
+ g_return_if_fail (GTD_PROVIDER_GET_IFACE (provider)->create_task_list);
+
+ GTD_PROVIDER_GET_IFACE (provider)->create_task_list (provider,
+ name,
+ cancellable,
+ callback,
+ user_data);
+}
+
+/**
+ * gtd_provider_create_task_list_finish:
+ * @self: a #GtdProvider
+ * @result: a #GAsyncResult
+ * @error: (out)(nullable): return location for a #GError
+ *
+ * Finishes creating the task list. The provider will emit the
+ * GtdProvider:list-added signal after creating the task list.
+ *
+ * Returns: %TRUE if task list was successfully created, %FALSE otherwise
+ */
+gboolean
+gtd_provider_create_task_list_finish (GtdProvider *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_return_val_if_fail (GTD_IS_PROVIDER (self), FALSE);
+ g_return_val_if_fail (!error || !*error, FALSE);
+ g_return_val_if_fail (GTD_PROVIDER_GET_IFACE (self)->create_task_list_finish, FALSE);
+
+ return GTD_PROVIDER_GET_IFACE (self)->create_task_list_finish (self, result, error);
+}
+
+/**
+ * gtd_provider_update_task_list:
+ * @provider: a #GtdProvider
+ * @list: a #GtdTaskList
+ * @cancellable: (nullable): a #GCancellable
+ * @callback: (scope async): a callback
+ * @user_data: (closure): user data for @callback
+ *
+ * Updates the given list in @provider.
+ */
+void
+gtd_provider_update_task_list (GtdProvider *provider,
+ GtdTaskList *list,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_return_if_fail (GTD_IS_PROVIDER (provider));
+ g_return_if_fail (GTD_PROVIDER_GET_IFACE (provider)->update_task_list);
+
+ GTD_PROVIDER_GET_IFACE (provider)->update_task_list (provider,
+ list,
+ cancellable,
+ callback,
+ user_data);
+}
+
+/**
+ * gtd_provider_update_task_list_finish:
+ * @self: a #GtdProvider
+ * @result: a #GAsyncResult
+ * @error: (out)(nullable): return location for a #GError
+ *
+ * Finishes updating the task list. The provider will emit the
+ * GtdProvider:list-updated signal after updating the task list.
+ *
+ * Returns: %TRUE if task list was successfully updated, %FALSE otherwise
+ */
+gboolean
+gtd_provider_update_task_list_finish (GtdProvider *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_return_val_if_fail (GTD_IS_PROVIDER (self), FALSE);
+ g_return_val_if_fail (!error || !*error, FALSE);
+ g_return_val_if_fail (GTD_PROVIDER_GET_IFACE (self)->update_task_list_finish, FALSE);
+
+ return GTD_PROVIDER_GET_IFACE (self)->update_task_list_finish (self, result, error);
+}
+
+/**
+ * gtd_provider_remove_task_list:
+ * @provider: a #GtdProvider
+ * @list: a #GtdTaskList
+ * @cancellable: (nullable): a #GCancellable
+ * @callback: (scope async): a callback
+ * @user_data: (closure): user data for @callback
+ *
+ * Removes the given list from @provider.
+ */
+void
+gtd_provider_remove_task_list (GtdProvider *provider,
+ GtdTaskList *list,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_return_if_fail (GTD_IS_PROVIDER (provider));
+ g_return_if_fail (GTD_PROVIDER_GET_IFACE (provider)->remove_task_list);
+
+ GTD_PROVIDER_GET_IFACE (provider)->remove_task_list (provider,
+ list,
+ cancellable,
+ callback,
+ user_data);
+}
+
+/**
+ * gtd_provider_remove_task_list_finish:
+ * @self: a #GtdProvider
+ * @result: a #GAsyncResult
+ * @error: (out)(nullable): return location for a #GError
+ *
+ * Finishes removing the task list. The provider will emit the
+ * GtdProvider:list-removed signal after removing the task list.
+ *
+ * Returns: %TRUE if task list was successfully removed, %FALSE otherwise
+ */
+gboolean
+gtd_provider_remove_task_list_finish (GtdProvider *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_return_val_if_fail (GTD_IS_PROVIDER (self), FALSE);
+ g_return_val_if_fail (!error || !*error, FALSE);
+ g_return_val_if_fail (GTD_PROVIDER_GET_IFACE (self)->remove_task_list_finish, FALSE);
+
+ return GTD_PROVIDER_GET_IFACE (self)->remove_task_list_finish (self, result, error);
+}
+
+/**
+ * gtd_provider_get_task_lists:
+ * @provider: a #GtdProvider
+ *
+ * Retrieves the tasklists that this provider contains.
+ *
+ * Returns: (transfer container) (element-type Gtd.TaskList): the list of tasks, or %NULL
+ */
+GList*
+gtd_provider_get_task_lists (GtdProvider *provider)
+{
+ g_return_val_if_fail (GTD_IS_PROVIDER (provider), NULL);
+ g_return_val_if_fail (GTD_PROVIDER_GET_IFACE (provider)->get_task_lists, NULL);
+
+ return GTD_PROVIDER_GET_IFACE (provider)->get_task_lists (provider);
+}
+
+/**
+ * gtd_provider_get_inbox:
+ * @provider: a #GtdProvider
+ *
+ * Retrieves the inbox of @provider.
+ *
+ * Returns: (transfer none)(nullable): a #GtdTaskList
+ */
+GtdTaskList*
+gtd_provider_get_inbox (GtdProvider *provider)
+{
+ g_return_val_if_fail (GTD_IS_PROVIDER (provider), NULL);
+ g_return_val_if_fail (GTD_PROVIDER_GET_IFACE (provider)->get_inbox, NULL);
+
+ return GTD_PROVIDER_GET_IFACE (provider)->get_inbox (provider);
+}
+
+/**
+ * gtd_provider_compare:
+ * @a: a #GtdProvider
+ * @b: a #GtdProvider
+ *
+ * Compares @a and @b. The sorting criteria is internal and
+ * may change.
+ *
+ * Returns: -1 if @a comes before @b, 1 for the oposite, and
+ * 0 if they're equal
+ */
+gint
+gtd_provider_compare (GtdProvider *a,
+ GtdProvider *b)
+{
+ gint result;
+
+ g_return_val_if_fail (GTD_IS_PROVIDER (a), 0);
+ g_return_val_if_fail (GTD_IS_PROVIDER (b), 0);
+
+ if (a == b)
+ return 0;
+
+ result = gtd_collate_compare_strings (gtd_provider_get_name (a), gtd_provider_get_name (b));
+
+ if (result != 0)
+ return result;
+
+ return gtd_collate_compare_strings (gtd_provider_get_description (a), gtd_provider_get_description (b));
+}