[gnome-todo/gnome-3-24] todo-txt: major rework on provider and parser
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-todo/gnome-3-24] todo-txt: major rework on provider and parser
- Date: Wed, 24 May 2017 22:26:53 +0000 (UTC)
commit e1cded19fd5a5349f72e984bab9da8985b7f488b
Author: Rohit Kaushik <kaushikrohit325 gmail com>
Date: Thu May 25 00:37:36 2017 +0530
todo-txt: major rework on provider and parser
Issues like creating task with many subtask and depth greater
than 2 being not save properly has been fixed. Provider has
been restructured and changes has been made according in the
parser.
Changes made:
1) Remove custom structure TaskData from parser.
2) parse_tokens now return GtdTask directly.
3) Provider cache the lists so that updating the source
is easier.
4) Monitor reloads the tasks/lists only when todo.txt file
has been altered from outside.This is fixed using a dummy
should_reload flag.
5) Parser now makes use of GString that can grow, rather than
using g_strconcat.
https://bugzilla.gnome.org/show_bug.cgi?id=781079
plugins/todo-txt/gtd-provider-todo-txt.c | 899 +++++++-----------------------
plugins/todo-txt/gtd-provider-todo-txt.h | 2 +
plugins/todo-txt/gtd-todo-txt-parser.c | 300 ++++-------
plugins/todo-txt/gtd-todo-txt-parser.h | 23 +-
4 files changed, 322 insertions(+), 902 deletions(-)
---
diff --git a/plugins/todo-txt/gtd-provider-todo-txt.c b/plugins/todo-txt/gtd-provider-todo-txt.c
index 7e707e2..e478648 100644
--- a/plugins/todo-txt/gtd-provider-todo-txt.c
+++ b/plugins/todo-txt/gtd-provider-todo-txt.c
@@ -19,8 +19,6 @@
#include "gtd-provider-todo-txt.h"
#include "gtd-plugin-todo-txt.h"
#include "gtd-todo-txt-parser.h"
-#include "gtd-task-list.h"
-#include "gtd-task.h"
#include <string.h>
#include <stdlib.h>
@@ -34,14 +32,14 @@ struct _GtdProviderTodoTxt
GIcon *icon;
GHashTable *lists;
- GHashTable *root_tasks;
+ GHashTable *tasks;
GFileMonitor *monitor;
GFile *source_file;
- GList *tasklists;
-
- gint no_of_lines;
+ GList *task_lists;
+ GPtrArray *cache;
+ gboolean should_reload;
};
static void gtd_provider_iface_init (GtdProviderInterface *iface);
@@ -106,22 +104,6 @@ gtd_provider_todo_txt_get_edit_panel (GtdProvider *provider)
return NULL;
}
-static GtdTask*
-gtd_provider_todo_txt_create_new_task (void)
-{
- ECalComponent *component;
- GtdTask *task;
-
- component = e_cal_component_new ();
-
- e_cal_component_set_new_vtype (component, E_CAL_COMPONENT_TODO);
- e_cal_component_set_uid (component, e_cal_component_gen_uid ());
-
- task = gtd_task_new (component);
-
- return task;
-}
-
static void
emit_generic_error (GError *error)
{
@@ -136,157 +118,127 @@ emit_generic_error (GError *error)
}
static void
-gtd_provider_todo_txt_load_task (TaskData *td,
- GtdProviderTodoTxt *self,
- gint line_number)
+update_source (GtdProviderTodoTxt *self)
{
- GtdTaskList *task_list = NULL;
-
- gchar *task_list_name;
- gchar *root_task_name;
- gchar *title;
-
- GDateTime *due_date;
- gboolean is_subtask;
- gboolean is_task_completed;
- gint priority;
-
- task_list_name = gtd_todo_txt_parser_task_data_get_task_list_name (td);
- root_task_name = gtd_todo_txt_parser_task_data_get_root_task_name (td);
- title = gtd_todo_txt_parser_task_data_get_title (td);
- due_date = gtd_todo_txt_parser_task_data_get_due_date (td);
- is_subtask = gtd_todo_txt_parser_task_data_is_subtask (td);
- is_task_completed = gtd_todo_txt_parser_task_data_is_task_completed (td);
- priority = gtd_todo_txt_parser_task_data_get_priority (td);
-
- if (is_subtask)
+ GFileOutputStream *write_stream;
+ GDataOutputStream *writer;
+ GtdTaskList *list;
+ GError *error;
+ GList *tasks, *l;
+ guint i;
+
+ error = NULL;
+ tasks = NULL;
+ l = NULL;
+ self->should_reload = FALSE;
+
+ write_stream = g_file_replace (self->source_file,
+ NULL,
+ TRUE,
+ G_FILE_CREATE_NONE,
+ NULL,
+ &error);
+ if (error)
{
- GtdTask *root_task;
- GtdTask *sub_task;
-
- if (g_hash_table_contains (self->lists, task_list_name))
- {
- task_list = g_hash_table_lookup (self->lists, task_list_name);
- }
- else
- {
- task_list = gtd_task_list_new (GTD_PROVIDER (self));
- gtd_task_list_set_is_removable (task_list, TRUE);
-
- gtd_task_list_set_name (task_list, task_list_name);
- self->tasklists = g_list_append (self->tasklists,
- task_list);
-
- g_object_set_data (G_OBJECT (task_list), "line", task_list_name);
-
- g_signal_emit_by_name (self, "list-added", task_list);
- g_hash_table_insert (self->lists, task_list_name, task_list);
- }
-
- if (g_hash_table_contains (self->root_tasks, root_task_name))
- {
- root_task = g_hash_table_lookup (self->root_tasks, root_task_name);
- }
- else
- {
- root_task = gtd_provider_todo_txt_create_new_task ();
-
- gtd_task_set_title (root_task, root_task_name);
- gtd_task_set_list (root_task, task_list);
- gtd_task_list_save_task (task_list, root_task);
+ emit_generic_error (error);
+ g_error_free (error);
+ return;
+ }
- g_hash_table_insert (self->root_tasks, root_task_name, root_task);
- }
+ writer = g_data_output_stream_new (G_OUTPUT_STREAM (write_stream));
- sub_task = gtd_provider_todo_txt_create_new_task ();
+ for (i = 0; i < self->cache->len; i++)
+ {
+ gchar *list_line;
+ list = g_ptr_array_index (self->cache, i);
- gtd_task_set_title (sub_task, title);
- gtd_task_set_list (sub_task, task_list);
- gtd_task_set_priority (sub_task, priority);
- gtd_task_set_complete (sub_task, is_task_completed);
- gtd_task_set_due_date (sub_task, due_date);
+ tasks = gtd_task_list_get_tasks (list);
+ tasks = g_list_sort (tasks, (GCompareFunc) gtd_task_compare);
- g_object_set_data (G_OBJECT (sub_task), "line", GINT_TO_POINTER (line_number));
+ list_line = gtd_todo_txt_parser_serialize_list (list);
- gtd_task_add_subtask (root_task, sub_task);
- gtd_task_list_save_task (task_list, sub_task);
- }
- else
- {
- GtdTask *task;
+ g_data_output_stream_put_string (writer,
+ list_line,
+ NULL,
+ NULL);
- if (g_hash_table_contains (self->lists, task_list_name))
+ for (l = tasks; l != NULL; l = l->next)
{
- task_list = g_hash_table_lookup (self->lists, task_list_name);
- }
- else
- {
- task_list = gtd_task_list_new (GTD_PROVIDER (self));
- gtd_task_list_set_is_removable (task_list, TRUE);
+ gchar *task_line;
- gtd_task_list_set_name (task_list, task_list_name);
- self->tasklists = g_list_append (self->tasklists,
- task_list);
+ task_line = gtd_todo_txt_parser_serialize_task (l->data);
- g_object_set_data (G_OBJECT (task_list), "line", task_list_name);
+ g_data_output_stream_put_string (writer,
+ task_line,
+ NULL,
+ NULL);
- g_signal_emit_by_name (self, "list-added", task_list);
- g_hash_table_insert (self->lists, task_list_name, task_list);
+ g_free (task_line);
}
- task = gtd_provider_todo_txt_create_new_task ();
-
- gtd_task_set_title (task, title);
- gtd_task_set_list (task, task_list);
- gtd_task_set_priority (task, priority);
- gtd_task_set_complete (task, is_task_completed);
- gtd_task_set_due_date (task, due_date);
-
- g_object_set_data (G_OBJECT (task), "line", GINT_TO_POINTER (line_number));
- gtd_task_list_save_task (task_list, task);
- g_hash_table_insert (self->root_tasks, title, task);
+ g_free (list_line);
}
+
+ g_output_stream_close (G_OUTPUT_STREAM (writer), NULL, NULL);
+ g_output_stream_close (G_OUTPUT_STREAM (write_stream), NULL, NULL);
}
-static void
-gtd_provider_todo_txt_create_empty_list (GtdProviderTodoTxt *self,
- gchar *name)
+static GtdTaskList*
+create_list (GtdProviderTodoTxt *self,
+ gchar *name)
{
GtdTaskList *task_list;
if (g_hash_table_contains (self->lists, name))
- return;
+ return g_hash_table_lookup (self->lists, name);
task_list = gtd_task_list_new (GTD_PROVIDER (self));
gtd_task_list_set_is_removable (task_list, TRUE);
-
+ g_ptr_array_add (self->cache, task_list);
+ g_hash_table_insert (self->lists, g_strdup (name), task_list);
gtd_task_list_set_name (task_list, name);
- self->tasklists = g_list_append (self->tasklists, task_list);
- g_object_set_data (G_OBJECT (task_list), "line", name);
+ self->task_lists = g_list_append (self->task_lists, task_list);
- g_signal_emit_by_name (self, "list-added", task_list);
- g_hash_table_insert (self->lists, name, task_list);
+ return task_list;
+}
+
+GtdTask*
+create_task (void)
+{
+ ECalComponent *component;
+ GtdTask *task;
+
+ component = e_cal_component_new ();
+
+ e_cal_component_set_new_vtype (component, E_CAL_COMPONENT_TODO);
+ e_cal_component_set_uid (component, e_cal_component_gen_uid ());
+
+ task = gtd_task_new (component);
+
+ return task;
}
static void
-gtd_provider_todo_txt_load_source (GtdProviderTodoTxt *self)
+gtd_provider_todo_txt_load_tasks (GtdProviderTodoTxt *self)
{
GFileInputStream *readstream;
GDataInputStream *reader;
- TaskData *td;
- GError *line_read_error;
+ GtdTaskList *list;
+ GtdTask *parent_task;
+ GtdTask *task;
GError *error;
- gint line_number = 0;
+ GList *tokens;
+ gboolean valid;
gchar *line_read;
+ gchar *list_name;
+ gchar *root_task_name;
g_return_if_fail (G_IS_FILE (self->source_file));
- td = NULL;
- error = line_read_error = NULL;
- readstream = g_file_read (self->source_file,
- NULL,
- &error);
+ tokens = NULL;
+ error = NULL;
+ readstream = g_file_read (self->source_file, NULL, &error);
if (error)
{
@@ -297,55 +249,119 @@ gtd_provider_todo_txt_load_source (GtdProviderTodoTxt *self)
reader = g_data_input_stream_new (G_INPUT_STREAM (readstream));
- self->no_of_lines = 0;
- while (!line_read_error)
+ while (!error)
{
- GList *tokens = NULL;
- gboolean valid;
-
- line_read = g_data_input_stream_read_line (reader,
- NULL,
- NULL,
- &line_read_error);
+ line_read = g_data_input_stream_read_line (reader, NULL, NULL, &error);
- if (line_read_error)
+ if (error)
{
g_warning ("%s: %s: %s",
G_STRFUNC,
_("Error while reading a line from Todo.txt"),
- line_read_error->message);
+ error->message);
gtd_manager_emit_error_message (gtd_manager_get_default (),
_("Error while reading a line from Todo.txt"),
- line_read_error->message);
- g_error_free (line_read_error);
+ error->message);
+ g_error_free (error);
- return;
+ continue;
}
if (!line_read)
break;
- line_number++;
- self->no_of_lines++;
-
+ g_strstrip (line_read);
tokens = gtd_todo_txt_parser_tokenize (line_read);
valid = gtd_todo_txt_parser_validate_token_format (tokens);
if (valid)
{
- td = gtd_todo_txt_parser_parse_tokens (tokens);
+ if (g_list_length (tokens) == 1)
+ {
+ list_name = &((gchar*)tokens->data)[0];
+ list_name++;
+ create_list (self, list_name);
+ continue;
+ }
+
+ task = gtd_todo_txt_parser_parse_tokens (tokens);
+ g_hash_table_insert (self->tasks, g_strdup (gtd_task_get_title (task)), task);
+ list = create_list (self, g_object_get_data (G_OBJECT (task), "list_name"));
+ gtd_task_set_list (task, list);
- if (strcmp (gtd_todo_txt_parser_task_data_get_task_list_name (td), &(line_read[1])) == 0)
- gtd_provider_todo_txt_create_empty_list (self, g_strdup (&(line_read[1])));
- else
- gtd_provider_todo_txt_load_task (td, self, line_number);
+ if (g_object_get_data (G_OBJECT (task), "root_task_name"))
+ {
+ root_task_name = g_object_get_data (G_OBJECT (task), "root_task_name");
+
+ if (g_hash_table_contains (self->tasks, root_task_name))
+ {
+ parent_task = g_hash_table_lookup (self->tasks, root_task_name);
+ }
+ else
+ {
+ parent_task = create_task ();
+ gtd_task_set_list (parent_task, list);
+ gtd_task_set_title (parent_task, g_object_get_data (G_OBJECT (task), "root_task_name"));
+
+ g_hash_table_insert (self->tasks, root_task_name, parent_task);
+ }
+
+ gtd_task_add_subtask (parent_task, task);
+ gtd_task_list_save_task (list, parent_task);
+ }
+
+ gtd_task_list_save_task (list, task);
}
g_list_free_full (tokens, g_free);
g_free (line_read);
}
+
+ g_input_stream_close (G_INPUT_STREAM (reader), NULL, NULL);
+ g_input_stream_close (G_INPUT_STREAM (readstream), NULL, NULL);
+}
+
+static void
+gtd_provider_todo_txt_reload (GFileMonitor *monitor,
+ GFile *first,
+ GFile *second,
+ GFileMonitorEvent event,
+ GtdProviderTodoTxt *self)
+{
+ GList *l;
+ guint i;
+
+ l = NULL;
+
+ if (!self->should_reload)
+ {
+ self->should_reload = TRUE;
+ return;
+ }
+
+ g_clear_pointer (&self->lists, g_hash_table_destroy);
+ g_clear_pointer (&self->tasks, g_hash_table_destroy);
+ g_ptr_array_free (self->cache, TRUE);
+
+ for (l = self->task_lists; l != NULL; l = l->next)
+ g_signal_emit_by_name (self, "list-removed", l->data);
+
+ g_list_free (self->task_lists);
+ self->task_lists = NULL;
+ self->lists = g_hash_table_new ((GHashFunc) g_str_hash, (GEqualFunc) g_str_equal);
+ self->tasks = g_hash_table_new ((GHashFunc) g_str_hash, (GEqualFunc) g_str_equal);
+ self->cache = g_ptr_array_new ();
+
+ gtd_provider_todo_txt_load_tasks (self);
+
+ for (i = 0; i < self->cache->len; i++)
+ {
+ GtdTaskList *list;
+ list = g_ptr_array_index (self->cache, i);
+ g_signal_emit_by_name (self, "list-added", list);
+ }
}
static void
@@ -366,6 +382,8 @@ gtd_provider_todo_txt_load_source_monitor (GtdProviderTodoTxt *self)
g_clear_error (&error);
return;
}
+
+ g_signal_connect (self->monitor, "changed", G_CALLBACK (gtd_provider_todo_txt_reload), self);
}
static void
@@ -373,71 +391,13 @@ gtd_provider_todo_txt_create_task (GtdProvider *provider,
GtdTask *task)
{
GtdProviderTodoTxt *self;
- GFileOutputStream *write_stream;
- GDataOutputStream *writer;
- GtdTaskList *list;
- GError *write_error;
- GError *error;
- const gchar *list_name;
- const gchar *task_description;
- gchar *task_line;
self = GTD_PROVIDER_TODO_TXT (provider);
- error = write_error = NULL;
-
- g_return_if_fail (G_IS_FILE (self->source_file));
-
- list = gtd_task_get_list (task);
- list_name = gtd_task_list_get_name (list);
- task_description = gtd_task_get_title (task);
-
- task_line = g_strconcat (task_description, " ", "@", list_name, "\n", NULL);
-
- write_stream = g_file_append_to (self->source_file,
- G_FILE_CREATE_REPLACE_DESTINATION,
- NULL,
- &error);
- if (error)
- {
- emit_generic_error (error);
- g_error_free (error);
- return;
- }
-
- writer = g_data_output_stream_new (G_OUTPUT_STREAM (write_stream));
-
- g_data_output_stream_put_string (writer,
- task_line,
- NULL,
- &write_error);
-
- if (write_error)
- {
- g_warning ("%s: %s: %s",
- G_STRFUNC,
- _("Error while adding a task to Todo.txt"),
- write_error->message);
+ g_return_if_fail (GTD_IS_TASK (task));
+ g_return_if_fail (GTD_IS_TASK_LIST (gtd_task_get_list (task)));
- gtd_manager_emit_error_message (gtd_manager_get_default (),
- _("Error while adding a task to Todo.txt"),
- write_error->message);
- g_error_free (write_error);
-
- goto out;
- }
-
- g_hash_table_insert (self->root_tasks,
- (gpointer) task_description,
- task);
- self->no_of_lines++;
- g_object_set_data (G_OBJECT (task), "line", GINT_TO_POINTER (self->no_of_lines));
-
- g_output_stream_close (G_OUTPUT_STREAM (writer),
- NULL,
- NULL);
-out:
- g_free (task_line);
+ update_source (self);
}
static void
@@ -445,124 +405,14 @@ gtd_provider_todo_txt_update_task (GtdProvider *provider,
GtdTask *task)
{
GtdProviderTodoTxt *self;
- GFileInputStream *readstream;
- GFileOutputStream *outstream;
- GDataOutputStream *writer;
- GDataInputStream *reader;
- GError *line_read_error;
- GError *error;
- GError *write_error;
- gchar *line_read;
- gint line_to_update;
- gint line_number;
self = GTD_PROVIDER_TODO_TXT (provider);
- line_number = 0;
- error = write_error = line_read_error = NULL;
-
- line_to_update = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (task), "line"));
+ g_return_if_fail (GTD_IS_TASK (task));
+ g_return_if_fail (GTD_IS_TASK_LIST (gtd_task_get_list (task)));
g_return_if_fail (G_IS_FILE (self->source_file));
- readstream = g_file_read (self->source_file,
- NULL,
- &error);
- outstream = g_file_replace (self->source_file,
- NULL,
- TRUE,
- G_FILE_CREATE_NONE,
- NULL,
- &error);
-
- if (error)
- {
- emit_generic_error (error);
- g_error_free (error);
- return;
- }
-
- reader = g_data_input_stream_new (G_INPUT_STREAM (readstream));
- writer = g_data_output_stream_new (G_OUTPUT_STREAM (outstream));
-
- while (!line_read_error)
- {
- gboolean valid;
- GList *tokens = NULL;
-
- line_read = g_data_input_stream_read_line (reader,
- NULL,
- NULL,
- &line_read_error);
-
- if (line_read_error)
- {
- g_warning ("%s: %s: %s",
- G_STRFUNC,
- _("Error while reading tasks from Todo.txt"),
- line_read_error->message);
-
- gtd_manager_emit_error_message (gtd_manager_get_default (),
- _("Error while reading tasks from Todo.txt"),
- line_read_error->message);
- g_error_free (line_read_error);
- }
-
- if (!line_read)
- break;
-
- line_number++;
-
- tokens = gtd_todo_txt_parser_tokenize (line_read);
- valid = gtd_todo_txt_parser_validate_token_format (tokens);
-
- if (valid &&
- line_number == line_to_update)
- {
- GList *update_tokens;
- GList *it;
-
- update_tokens = gtd_todo_txt_parser_get_task_line (task);
- it = NULL;
- for (it = update_tokens; it != NULL; it = it->next)
- {
- g_data_output_stream_put_string (writer,
- it->data,
- NULL,
- &write_error);
- if (it->next == NULL)
- {
- g_data_output_stream_put_string (writer,
- "\n",
- NULL,
- &write_error);
- }
- else
- g_data_output_stream_put_string (writer,
- " ",
- NULL,
- &write_error);
- }
-
- g_list_free_full (update_tokens, g_free);
- }
-
-
- else
- {
- line_read = strcat (line_read, "\n");
-
- g_data_output_stream_put_string (writer,
- line_read,
- NULL,
- &write_error);
- }
-
- g_list_free_full (tokens, g_free);
- }
-
- g_output_stream_close (G_OUTPUT_STREAM (writer),
- NULL,
- NULL);
+ update_source (self);
}
static void
@@ -570,107 +420,14 @@ gtd_provider_todo_txt_remove_task (GtdProvider *provider,
GtdTask *task)
{
GtdProviderTodoTxt *self;
- GFileInputStream *readstream;
- GFileOutputStream *outstream;
- GDataOutputStream *writer;
- GDataInputStream *reader;
- GError *error;
- GError *write_error;
- GError *line_read_error;
- gchar *line_read;
- gboolean skip;
- gint line_number;
- gint line_number_to_remove;
self = GTD_PROVIDER_TODO_TXT (provider);
- error = write_error = line_read_error = NULL;
- line_number = 0;
+ g_return_if_fail (GTD_IS_TASK (task));
+ g_return_if_fail (GTD_IS_TASK_LIST (gtd_task_get_list (task)));
g_return_if_fail (G_IS_FILE (self->source_file));
- line_number_to_remove = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (task), "line"));
- readstream = g_file_read (self->source_file,
- NULL,
- &error);
- outstream = g_file_replace (self->source_file,
- NULL,
- TRUE,
- G_FILE_CREATE_NONE,
- NULL,
- &error);
-
- if (error)
- {
- emit_generic_error (error);
- g_error_free (error);
- return;
- }
-
- reader = g_data_input_stream_new (G_INPUT_STREAM (readstream));
- writer = g_data_output_stream_new (G_OUTPUT_STREAM (outstream));
-
- while (!line_read_error)
- {
- TaskData *td;
- gboolean valid;
- GList *tokens = NULL;
-
- line_read = g_data_input_stream_read_line (reader,
- NULL,
- NULL,
- &line_read_error);
-
- skip = FALSE;
-
- if (line_read_error)
- {
- g_warning ("%s: %s: %s",
- G_STRFUNC,
- _("Error while reading tasks from Todo.txt"),
- line_read_error->message);
-
- gtd_manager_emit_error_message (gtd_manager_get_default (),
- _("Error while reading tasks from Todo.txt"),
- line_read_error->message);
- g_error_free (line_read_error);
- return;
- }
-
- if (!line_read)
- break;
-
- line_number++;
-
- tokens = gtd_todo_txt_parser_tokenize (line_read);
- valid = gtd_todo_txt_parser_validate_token_format (tokens);
-
- if (valid)
- td = gtd_todo_txt_parser_parse_tokens (tokens);
- else
- td = NULL;
-
- if (line_number == line_number_to_remove)
- {
- skip = TRUE;
- self->no_of_lines--;
- }
-
- if (!skip)
- {
- line_read = strcat (line_read, "\n");
-
- g_data_output_stream_put_string (writer,
- line_read,
- NULL,
- &write_error);
- }
-
- g_free (td);
- }
-
- g_output_stream_close (G_OUTPUT_STREAM (writer),
- NULL,
- NULL);
+ update_source (self);
}
static void
@@ -678,61 +435,20 @@ gtd_provider_todo_txt_create_task_list (GtdProvider *provider,
GtdTaskList *list)
{
GtdProviderTodoTxt *self;
- GFileOutputStream *write_stream;
- GDataOutputStream *writer;
- GError *write_error;
- GError *error;
- gchar *put;
- const gchar *name;
+ gchar *name;
+ g_return_if_fail (GTD_IS_TASK_LIST (list));
self = GTD_PROVIDER_TODO_TXT (provider);
- error = write_error = NULL;
-
- g_return_if_fail (G_IS_FILE (self->source_file));
-
- write_stream = g_file_append_to (self->source_file,
- G_FILE_CREATE_REPLACE_DESTINATION,
- NULL,
- &error);
-
- if (error)
- {
- emit_generic_error (error);
- g_error_free (error);
- return;
- }
-
- name = gtd_task_list_get_name (list);
- writer = g_data_output_stream_new (G_OUTPUT_STREAM (write_stream));
+ name = g_strdup (gtd_task_list_get_name (list));
+ gtd_task_list_set_is_removable (list, TRUE);
- put = g_strconcat ("@", name, "\n", NULL);
-
- g_data_output_stream_put_string (writer,
- put,
- NULL,
- &write_error);
-
- if (write_error)
- {
- g_warning ("%s: %s: %s",
- G_STRFUNC,
- _("Error while creating a Todo.txt list"),
- write_error->message);
-
- gtd_manager_emit_error_message (gtd_manager_get_default (),
- _("Error while creating a Todo.txt list"),
- write_error->message);
- g_error_free (write_error);
- goto out;
- }
+ self->task_lists = g_list_append (self->task_lists, list);
+ g_ptr_array_add (self->cache, list);
+ g_hash_table_insert (self->lists, name, list);
- self->tasklists = g_list_append (self->tasklists, list);
- g_hash_table_insert (self->lists, (gpointer) name, list);
- g_signal_emit_by_name (self, "list-added", list);
- self->no_of_lines++;
+ update_source (self);
-out:
- g_free (put);
+ g_signal_emit_by_name (provider, "list-added", list);
}
static void
@@ -740,231 +456,32 @@ gtd_provider_todo_txt_update_task_list (GtdProvider *provider,
GtdTaskList *list)
{
GtdProviderTodoTxt *self;
- GFileInputStream *readstream;
- GFileOutputStream *outstream;
- GDataOutputStream *writer;
- GDataInputStream *reader;
- GError *line_read_error = NULL;
- GError *error;
- GError *write_error;
- const gchar *current_list_name;
- gchar *stored_list_name;
- gchar *line_read;
self = GTD_PROVIDER_TODO_TXT (provider);
- error = write_error = NULL;
-
- g_return_if_fail (G_IS_FILE (self->source_file));
-
- stored_list_name = g_object_get_data (G_OBJECT (list), "line");
- current_list_name = gtd_task_list_get_name (list);
-
- readstream = g_file_read (self->source_file,
- NULL,
- &error);
- outstream = g_file_replace (self->source_file,
- NULL,
- TRUE,
- G_FILE_CREATE_NONE,
- NULL,
- &error);
-
- if (error)
- {
- emit_generic_error (error);
- g_error_free (error);
- return;
- }
- reader = g_data_input_stream_new (G_INPUT_STREAM (readstream));
- writer = g_data_output_stream_new (G_OUTPUT_STREAM (outstream));
-
- while (!line_read_error)
- {
- gboolean valid;
- GList *tokens;
- TaskData *td = NULL;
+ g_return_if_fail (GTD_IS_TASK_LIST (list));
- tokens = NULL;
- line_read = g_data_input_stream_read_line (reader,
- NULL,
- NULL,
- &line_read_error);
-
- if (line_read_error)
- {
- g_warning ("%s: %s: %s",
- G_STRFUNC,
- _("Error while reading tasks from Todo.txt"),
- line_read_error->message);
-
- gtd_manager_emit_error_message (gtd_manager_get_default (),
- _("Error while reading tasks from Todo.txt"),
- line_read_error->message);
- g_error_free (line_read_error);
- continue;
- }
-
- if (!line_read)
- break;
-
- tokens = gtd_todo_txt_parser_tokenize (line_read);
- valid = gtd_todo_txt_parser_validate_token_format (tokens);
+ update_source (self);
- if (valid)
- td = gtd_todo_txt_parser_parse_tokens (tokens);
-
- if (valid &&
- strcmp (stored_list_name, current_list_name) &&
- !(strcmp (gtd_todo_txt_parser_task_data_get_task_list_name (td), stored_list_name)))
- {
- GList *update_tokens;
- GList *it;
-
- update_tokens = gtd_todo_txt_parser_get_list_updated_token (list, g_strdup (line_read));
- it = NULL;
-
- for (it = update_tokens; it != NULL; it = it->next)
- {
- g_data_output_stream_put_string (writer,
- it->data,
- NULL,
- &write_error);
- if (it->next == NULL)
- {
- g_data_output_stream_put_string (writer,
- "\n",
- NULL,
- &write_error);
- }
- else
- g_data_output_stream_put_string (writer,
- " ",
- NULL,
- &write_error);
- }
- g_list_free_full (update_tokens, g_free);
- }
- else
- {
- line_read = strcat (line_read, "\n");
-
- g_data_output_stream_put_string (writer,
- line_read,
- NULL,
- &write_error);
- }
-
- g_list_free_full (tokens, g_free);
- }
-
- g_output_stream_close (G_OUTPUT_STREAM (writer), NULL, NULL);
- g_input_stream_close (G_INPUT_STREAM (reader), NULL, NULL);
-
- g_output_stream_close (G_OUTPUT_STREAM (outstream), NULL, NULL);
- g_input_stream_close (G_INPUT_STREAM (readstream), NULL, NULL);
+ g_signal_emit_by_name (provider, "list-changed", list);
}
static void
gtd_provider_todo_txt_remove_task_list (GtdProvider *provider,
GtdTaskList *list)
{
-
GtdProviderTodoTxt *self;
- GFileOutputStream *outstream;
- GDataOutputStream *writer;
- GFileInputStream *readstream;
- GDataInputStream *reader;
- GError *line_read_error = NULL;
- GError *write_error;
- GError *error;
- const gchar *list_name;
- gboolean skip;
- gchar *line;
self = GTD_PROVIDER_TODO_TXT (provider);
- error = write_error = NULL;
- list_name = gtd_task_list_get_name (list);
-
- g_return_if_fail (G_IS_FILE (self->source_file));
-
- readstream = g_file_read (self->source_file,
- NULL,
- &error);
- outstream = g_file_replace (self->source_file,
- NULL,
- TRUE,
- G_FILE_CREATE_NONE,
- NULL,
- &error);
-
- if (error)
- {
- emit_generic_error (error);
- g_error_free (error);
- return;
- }
-
- reader = g_data_input_stream_new (G_INPUT_STREAM (readstream));
- writer = g_data_output_stream_new (G_OUTPUT_STREAM (outstream));
-
- while (!line_read_error)
- {
- TaskData *td = NULL;
- gboolean valid;
- GList *tokens = NULL;
-
- line = g_data_input_stream_read_line (reader,
- NULL,
- NULL,
- &line_read_error);
- skip = FALSE;
+ g_return_if_fail (GTD_IS_TASK_LIST (list));
- if (line_read_error)
- {
- g_warning ("%s: %s: %s",
- G_STRFUNC,
- _("Error while reading task lists from Todo.txt"),
- line_read_error->message);
-
- gtd_manager_emit_error_message (gtd_manager_get_default (),
- _("Error while reading task lists from Todo.txt"),
- line_read_error->message);
- g_error_free (line_read_error);
- }
-
- if (!line)
- break;
-
- tokens = gtd_todo_txt_parser_tokenize (line);
- valid = gtd_todo_txt_parser_validate_token_format (tokens);
-
- if (valid)
- td = gtd_todo_txt_parser_parse_tokens (tokens);
-
- if (valid && strcmp (gtd_todo_txt_parser_task_data_get_task_list_name (td), list_name) == 0)
- {
- self->no_of_lines--;
- skip = TRUE;
- }
-
- if (!skip)
- {
- line = strcat (line, "\n");
+ g_ptr_array_remove (self->cache, list);
+ self->task_lists = g_list_remove (self->task_lists, list);
- g_data_output_stream_put_string (writer,
- line,
- NULL,
- &write_error);
- }
-
- g_free (td);
- }
+ update_source (self);
- g_output_stream_close (G_OUTPUT_STREAM (writer),
- NULL,
- NULL);
+ g_signal_emit_by_name (provider, "list-removed", list);
}
static GList*
@@ -974,7 +491,7 @@ gtd_provider_todo_txt_get_task_lists (GtdProvider *provider)
self = GTD_PROVIDER_TODO_TXT (provider);
- return self->tasklists;
+ return self->task_lists;
}
static GtdTaskList*
@@ -1025,8 +542,9 @@ gtd_provider_todo_txt_finalize (GObject *object)
GtdProviderTodoTxt *self = (GtdProviderTodoTxt *)object;
g_clear_pointer (&self->lists, g_hash_table_destroy);
- g_clear_pointer (&self->root_tasks, g_hash_table_destroy);
- g_clear_pointer (&self->tasklists, g_clear_object);
+ g_clear_pointer (&self->tasks, g_hash_table_destroy);
+ g_ptr_array_free (self->cache, TRUE);
+ g_clear_pointer (&self->task_lists, g_clear_object);
g_clear_object (&self->source_file);
g_clear_object (&self->icon);
@@ -1083,8 +601,8 @@ gtd_provider_todo_txt_set_property (GObject *object,
{
case PROP_SOURCE:
self->source_file = g_value_dup_object (value);
- gtd_provider_todo_txt_load_source (self);
gtd_provider_todo_txt_load_source_monitor (self);
+ gtd_provider_todo_txt_load_tasks (self);
break;
default:
@@ -1122,9 +640,10 @@ gtd_provider_todo_txt_init (GtdProviderTodoTxt *self)
{
gtd_object_set_ready (GTD_OBJECT (self), TRUE);
- self->no_of_lines = 0;
self->lists = g_hash_table_new ((GHashFunc) g_str_hash, (GEqualFunc) g_str_equal);
- self->root_tasks = g_hash_table_new ((GHashFunc) g_str_hash, (GEqualFunc) g_str_equal);
+ self->tasks = g_hash_table_new ((GHashFunc) g_str_hash, (GEqualFunc) g_str_equal);
+ self->cache = g_ptr_array_new ();
+ self->should_reload = TRUE;
/* icon */
self->icon = G_ICON (g_themed_icon_new_with_default_fallbacks ("computer-symbolic"));
diff --git a/plugins/todo-txt/gtd-provider-todo-txt.h b/plugins/todo-txt/gtd-provider-todo-txt.h
index a4c0705..7d85b4f 100644
--- a/plugins/todo-txt/gtd-provider-todo-txt.h
+++ b/plugins/todo-txt/gtd-provider-todo-txt.h
@@ -31,6 +31,8 @@ G_DECLARE_FINAL_TYPE (GtdProviderTodoTxt, gtd_provider_todo_txt, GTD, PROVIDER_T
GtdProviderTodoTxt* gtd_provider_todo_txt_new (GFile *source_file);
+GtdTask* create_task (void);
+
G_END_DECLS
#endif /* GTD_PROVIDER_TODO_TXT_H */
diff --git a/plugins/todo-txt/gtd-todo-txt-parser.c b/plugins/todo-txt/gtd-todo-txt-parser.c
index a1f96cb..edb763e 100644
--- a/plugins/todo-txt/gtd-todo-txt-parser.c
+++ b/plugins/todo-txt/gtd-todo-txt-parser.c
@@ -18,6 +18,7 @@
#include <glib/gi18n.h>
#include <gtd-todo-txt-parser.h>
+#include <gtd-provider-todo-txt.h>
struct _GtdTodoTxtParser
{
@@ -36,32 +37,6 @@ enum {
G_DEFINE_TYPE (GtdTodoTxtParser, gtd_todo_txt_parser, GTD_TYPE_OBJECT);
-struct _TaskData
-{
- gchar *root_task_name;
- gchar *task_list_name;
- gchar *title;
-
- GDateTime *creation_date;
- GDateTime *completion_date;
- GDateTime *due_date;
-
- gboolean is_subtask;
- gboolean is_task_completed;
- gint priority;
-
-};
-
-static TaskData*
-task_data_new (void)
-{
- TaskData *tdata;
-
- tdata = g_new0 (TaskData, 1);
-
- return tdata;
-}
-
gint
gtd_todo_txt_parser_get_priority (gchar *token)
{
@@ -69,15 +44,12 @@ gtd_todo_txt_parser_get_priority (gchar *token)
{
case 'A':
return 3;
- break;
case 'B':
return 2;
- break;
case 'C':
return 1;
- break;
default:
return 0;
@@ -89,28 +61,27 @@ gtd_todo_txt_parser_get_priority (gchar *token)
GDateTime*
gtd_todo_txt_parser_get_date (gchar *token)
{
- GDate *date = NULL;
- GDateTime *dt = NULL;
- gint year;
- gint month;
- gint day;
-
- date = g_date_new ();
+ GDateTime *dt;
+ GDate date;
+ gint year;
+ gint month;
+ gint day;
- g_date_set_parse (date, token);
+ dt = NULL;
+ g_date_clear (&date, 1);
+ g_date_set_parse (&date, token);
- if (!g_date_valid (date))
+ if (!g_date_valid (&date))
return NULL;
- year = g_date_get_year (date);
- month = g_date_get_month (date);
- day = g_date_get_day (date);
+ year = g_date_get_year (&date);
+ month = g_date_get_month (&date);
+ day = g_date_get_day (&date);
dt = g_date_time_new_utc (year,
month,
day,
0, 0, 0);
- g_date_free (date);
return dt;
}
@@ -118,7 +89,7 @@ gtd_todo_txt_parser_get_date (gchar *token)
gboolean
gtd_todo_txt_parser_is_date (gchar *dt)
{
- GDate date;
+ GDate date;
g_date_clear (&date, 1);
g_date_set_parse (&date, dt);
@@ -154,140 +125,133 @@ gtd_todo_txt_parser_get_token_id (gchar *token,
if (!g_strcmp0 (token, "x"))
return TASK_COMPLETE;
- if (token_length == 3)
- {
- if (token[0] == '(' && token[2] == ')')
- return TASK_PRIORITY;
- }
+ if (token_length == 3 && token[0] == '(' && token[2] == ')')
+ return TASK_PRIORITY;
- if (!g_str_has_prefix (token , "due:") &&
- gtd_todo_txt_parser_is_date (token))
+ if (!g_str_has_prefix (token , "due:") && gtd_todo_txt_parser_is_date (token))
return TASK_DATE;
-
if (gtd_todo_txt_parser_is_word (token) &&
(last_read == TASK_DATE ||
last_read == TASK_PRIORITY ||
last_read == TASK_COMPLETE||
last_read == TASK_TITLE))
- return TASK_TITLE;
-
- if (token_length > 1)
{
- if (token[0] == '@')
- return TASK_LIST_NAME;
+ return TASK_TITLE;
}
- if (token_length > 1)
- {
- if (token[0] == '+')
- return ROOT_TASK_NAME;
- }
+ if (token_length > 1 && token[0] == '@')
+ return TASK_LIST_NAME;
- if (gtd_todo_txt_parser_is_word (token) &&
- last_read == TASK_LIST_NAME)
+ if (token_length > 1 && token[0] == '+')
+ return ROOT_TASK_NAME;
+
+ if (gtd_todo_txt_parser_is_word (token) && last_read == TASK_LIST_NAME)
return TASK_LIST_NAME;
- if (gtd_todo_txt_parser_is_word (token) &&
- last_read == ROOT_TASK_NAME)
+ if (gtd_todo_txt_parser_is_word (token) && last_read == ROOT_TASK_NAME)
return ROOT_TASK_NAME;
if (g_str_has_prefix (token , "due:"))
return TASK_DUE_DATE;
-
-
return -1;
}
-TaskData*
-gtd_todo_txt_parser_parse_tokens (GList *tk)
+GtdTask*
+gtd_todo_txt_parser_parse_tokens (GList *tokens)
{
+ GtdTask *task;
GDateTime *dt;
- TaskData *td;
- GList *it;
+ GString *list_name;
+ GString *title;
+ GString *root_task_name;
+ gboolean is_subtask;
+
+ GList *l;
gint last_read_token;
gint token_id;
dt = NULL;
- it = NULL;
- td = task_data_new ();
+ l = NULL;
+ task = create_task ();
+ list_name = g_string_new (NULL);
+ title = g_string_new (NULL);
+ root_task_name = g_string_new (NULL);
+ is_subtask = FALSE;
last_read_token = TASK_COMPLETE;
- for (it = tk; it != NULL; it = it->next)
+ for (l = tokens; l != NULL; l = l->next)
{
+
gchar *str;
- str = it->data;
- token_id = gtd_todo_txt_parser_get_token_id (it->data, last_read_token);
+ g_strstrip (l->data);
+ str = l->data;
+ token_id = gtd_todo_txt_parser_get_token_id (l->data, last_read_token);
switch (token_id)
{
case TASK_COMPLETE:
last_read_token = TASK_COMPLETE;
- td->is_task_completed = TRUE;
+ gtd_task_set_complete (task, TRUE);
break;
case TASK_PRIORITY:
last_read_token = TASK_PRIORITY;
- td->priority = gtd_todo_txt_parser_get_priority (it->data);
+ gtd_task_set_priority (task, gtd_todo_txt_parser_get_priority (l->data));
break;
case TASK_DATE:
last_read_token = TASK_DATE;
- dt = gtd_todo_txt_parser_get_date (it->data);
- td->creation_date = dt;
+ dt = gtd_todo_txt_parser_get_date (l->data);
break;
case TASK_TITLE:
last_read_token = TASK_TITLE;
- if (td->title == NULL)
- td->title = g_strdup (it->data);
- else
- {
- char *temp = td->title;
- td->title = g_strconcat (td->title, " ",it->data, NULL);
- g_free (temp);
- }
+ g_string_append (title, l->data);
+ g_string_append (title, " ");
break;
case TASK_LIST_NAME:
last_read_token = TASK_LIST_NAME;
- if (td->task_list_name == NULL)
- td->task_list_name = g_strdup (&str[1]);
- else
- {
- gchar *temp = td->task_list_name;
- td->task_list_name = g_strconcat (td->task_list_name, " ",it->data, NULL);
- g_free (temp);
- }
+ g_string_append (list_name, l->data);
+ g_string_append (list_name, " ");
break;
case ROOT_TASK_NAME:
last_read_token = ROOT_TASK_NAME;
- if (td->root_task_name == NULL)
- td->root_task_name = g_strdup (&str[1]);
- else
- {
- gchar *temp = td->root_task_name;
- td->root_task_name = g_strconcat (td->root_task_name, " ",it->data, NULL);
- g_free (temp);
- }
- td->is_subtask = TRUE;
+ is_subtask = TRUE;
+ g_string_append (root_task_name, l->data);
+ g_string_append (root_task_name, " ");
break;
case TASK_DUE_DATE:
last_read_token = TASK_DUE_DATE;
dt = gtd_todo_txt_parser_get_date (&str[4]);
- td->due_date = dt;
+ gtd_task_set_due_date (task, dt);
break;
default:
return NULL;
}
}
- return td;
+
+ g_strstrip (title->str);
+ g_strstrip (list_name->str);
+ g_strstrip (root_task_name->str);
+ gtd_task_set_title (task, title->str);
+ g_object_set_data_full (G_OBJECT (task), "list_name", g_strdup (list_name->str + 1), g_free);
+
+ if (is_subtask)
+ g_object_set_data_full (G_OBJECT (task), "root_task_name", g_strdup (root_task_name->str + 1), g_free);
+
+ g_string_free (root_task_name, TRUE);
+ g_string_free (list_name, TRUE);
+ g_string_free (title, TRUE);
+
+ return task;
}
gboolean
@@ -410,53 +374,36 @@ gtd_todo_txt_parser_tokenize (const gchar *line)
return tokens;
}
-GList*
-gtd_todo_txt_parser_get_list_updated_token (GtdTaskList *list,
- gchar *line)
+gchar*
+gtd_todo_txt_parser_serialize_list (GtdTaskList *list)
{
- gint last_read_token = TASK_COMPLETE;
- gboolean list_name_updated = FALSE;
- GList *tokens = NULL;
- GList *it = NULL;
-
- tokens = gtd_todo_txt_parser_tokenize (line);
+ GString *description;
+ const gchar *list_name;
- for (it = tokens; it != NULL; it = it->next)
- {
- gint token_id;
+ description = g_string_new (NULL);
+ list_name = gtd_task_list_get_name (list);
- token_id = gtd_todo_txt_parser_get_token_id (it->data, last_read_token);
- last_read_token = token_id;
- if (token_id == TASK_LIST_NAME)
- {
- if (list_name_updated)
- {
- it = g_list_remove (tokens, it->data);
- last_read_token = TASK_COMPLETE;
- }
+ g_string_append (description, "@");
+ g_string_append (description, list_name);
- else
- {
- it->data = g_strconcat ("@", gtd_task_list_get_name(list), NULL);
- list_name_updated = TRUE;
- }
- }
- }
+ g_string_append (description, "\n");
- return tokens;
+ return g_string_free (description, FALSE);
}
-GList*
-gtd_todo_txt_parser_get_task_line (GtdTask *task)
+gchar*
+gtd_todo_txt_parser_serialize_task (GtdTask *task)
{
GtdTaskList *list;
GDateTime *dt;
- GtdTask *parent;
- GList *tokens = NULL;
- gint priority;
- gboolean is_complete;
+ GtdTask *parent;
+ GString *description;
const gchar *list_name;
const gchar *title;
+ gint priority;
+ gboolean is_complete;
+
+ description = g_string_new (NULL);
is_complete = gtd_task_get_complete (task);
title = gtd_task_get_title (task);
@@ -468,72 +415,41 @@ gtd_todo_txt_parser_get_task_line (GtdTask *task)
list_name = gtd_task_list_get_name (list);
if (is_complete)
- tokens = g_list_append (tokens, g_strdup ("x"));
+ g_string_append (description, "x ");
if (priority)
{
if (priority == 1)
- tokens = g_list_append (tokens, g_strdup ("(C)"));
+ g_string_append (description, "(C) ");
else if (priority == 2)
- tokens = g_list_append (tokens, g_strdup ("(B)"));
+ g_string_append (description, "(B) ");
else if (priority == 3)
- tokens = g_list_append (tokens, g_strdup ("(A)"));
+ g_string_append (description, "(A) ");
}
- tokens = g_list_append (tokens, g_strdup (title));
- tokens = g_list_append (tokens, g_strconcat ("@", list_name, NULL));
+ g_string_append (description, title);
+ g_string_append (description, " @");
+ g_string_append (description, list_name);
if (parent)
- tokens = g_list_append (tokens, g_strconcat ("+", gtd_task_get_title (parent), NULL));
+ {
+ g_string_append (description, " +");
+ g_string_append (description, gtd_task_get_title (parent));
+ }
if (dt)
- tokens = g_list_append (tokens, g_strconcat ("due:",g_date_time_format (dt, "%F"),NULL));
-
- return tokens;
-}
-
-/* Accessor Methods for the TaskData Structure */
-
-gchar*
-gtd_todo_txt_parser_task_data_get_root_task_name (TaskData *td)
-{
- return td->root_task_name;
-}
-
-gchar*
-gtd_todo_txt_parser_task_data_get_task_list_name (TaskData *td)
-{
- return td->task_list_name;
-}
+ {
+ g_autofree gchar *formatted_time;
-gchar*
-gtd_todo_txt_parser_task_data_get_title (TaskData *td)
-{
- return td->title;
-}
+ formatted_time = g_date_time_format (dt, "%F");
-GDateTime*
-gtd_todo_txt_parser_task_data_get_due_date (TaskData *td)
-{
- return td->due_date;
-}
-
-gboolean
-gtd_todo_txt_parser_task_data_is_subtask (TaskData *td)
-{
- return td->is_subtask;
-}
+ g_string_append (description, " due:");
+ g_string_append (description, formatted_time);
+ }
-gboolean
-gtd_todo_txt_parser_task_data_is_task_completed (TaskData *td)
-{
- return td->is_task_completed;
-}
+ g_string_append (description, "\n");
-gint
-gtd_todo_txt_parser_task_data_get_priority (TaskData *td)
-{
- return td->priority;
+ return g_string_free (description, FALSE);
}
static void
diff --git a/plugins/todo-txt/gtd-todo-txt-parser.h b/plugins/todo-txt/gtd-todo-txt-parser.h
index dfeb081..ff6fe1a 100644
--- a/plugins/todo-txt/gtd-todo-txt-parser.h
+++ b/plugins/todo-txt/gtd-todo-txt-parser.h
@@ -41,32 +41,15 @@ gboolean gtd_todo_txt_parser_is_word (gchar
gint gtd_todo_txt_parser_get_token_id (gchar *token,
gint last_read);
-TaskData* gtd_todo_txt_parser_parse_tokens (GList *tk);
+GtdTask* gtd_todo_txt_parser_parse_tokens (GList *tokens);
gboolean gtd_todo_txt_parser_validate_token_format (GList *tokens);
GList* gtd_todo_txt_parser_tokenize (const gchar *line);
-GList* gtd_todo_txt_parser_get_list_updated_token (GtdTaskList *list,
- gchar *line);
+gchar* gtd_todo_txt_parser_serialize_list (GtdTaskList *list);
-GList* gtd_todo_txt_parser_get_task_line (GtdTask *task);
-
-/*Accessor Methods for TaskData Strcuture*/
-
-gchar* gtd_todo_txt_parser_task_data_get_root_task_name (TaskData *td);
-
-gchar* gtd_todo_txt_parser_task_data_get_task_list_name (TaskData *td);
-
-gchar* gtd_todo_txt_parser_task_data_get_title (TaskData *td);
-
-GDateTime* gtd_todo_txt_parser_task_data_get_due_date (TaskData *td);
-
-gboolean gtd_todo_txt_parser_task_data_is_subtask (TaskData *td);
-
-gboolean gtd_todo_txt_parser_task_data_is_task_completed (TaskData *td);
-
-gint gtd_todo_txt_parser_task_data_get_priority (TaskData *td);
+gchar* gtd_todo_txt_parser_serialize_task (GtdTask *task);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]