[gnome-todo/wip/gbsneto/subtasks: 10/27] task: add ::is_subtask() API



commit cd5ef0d0386f06de5bdfdafe4bc44b199a6d9771
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Sun Oct 9 22:26:27 2016 -0300

    task: add ::is_subtask() API
    
    Perform a breadth-first search to see if a given task
    is a direct or indirect subtask of another. Will save
    us some trouble later.

 src/gtd-task.c |   56 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 src/gtd-task.h |    3 +++
 2 files changed, 58 insertions(+), 1 deletions(-)
---
diff --git a/src/gtd-task.c b/src/gtd-task.c
index c9ed3e9..02dbccd 100644
--- a/src/gtd-task.c
+++ b/src/gtd-task.c
@@ -1249,7 +1249,7 @@ gtd_task_add_subtask (GtdTask *self,
 
   priv = gtd_task_get_instance_private (self);
 
-  if (!g_list_find (priv->subtasks, subtask))
+  if (!g_list_find (priv->subtasks, subtask) && !gtd_task_is_subtask (subtask, self))
     {
       g_signal_emit (self, signals[SUBTASK_ADDED], 0, subtask);
     }
@@ -1279,3 +1279,57 @@ gtd_task_remove_subtask (GtdTask *self,
     }
 }
 
+/**
+ * gtd_task_is_subtask:
+ * @self: a #GtdTask
+ * @subtask: a #GtdTask
+ *
+ * Checks if @subtask is a subtask of @self, directly or indirectly.
+ *
+ * Returns: %TRUE is @subtask is a subtask of @self, %FALSE otherwise
+ */
+gboolean
+gtd_task_is_subtask (GtdTask *self,
+                     GtdTask *subtask)
+{
+  GtdTask *aux;
+  GQueue *queue;
+  gboolean is_subtask;
+
+  g_return_val_if_fail (GTD_IS_TASK (self), FALSE);
+  g_return_val_if_fail (GTD_IS_TASK (subtask), FALSE);
+
+  aux = self;
+  queue = g_queue_new ();
+  is_subtask = FALSE;
+
+  do
+    {
+      GtdTaskPrivate *priv;
+      GList *l;
+
+      priv = gtd_task_get_instance_private (aux);
+
+      for (l = priv->subtasks; l != NULL; l = l->next)
+        {
+          /* Found it, no need to continue looping */
+          if (l->data == subtask)
+            {
+              is_subtask = TRUE;
+              break;
+            }
+
+          g_queue_push_tail (queue, l->data);
+        }
+
+      if (is_subtask)
+        break;
+
+      aux = g_queue_pop_head (queue);
+    }
+  while (!g_queue_is_empty (queue));
+
+  g_queue_free (queue);
+
+  return is_subtask;
+}
diff --git a/src/gtd-task.h b/src/gtd-task.h
index 9846992..daf3c70 100644
--- a/src/gtd-task.h
+++ b/src/gtd-task.h
@@ -97,6 +97,9 @@ void                gtd_task_add_subtask              (GtdTask              *sel
 void                gtd_task_remove_subtask           (GtdTask              *self,
                                                        GtdTask              *subtask);
 
+gboolean            gtd_task_is_subtask               (GtdTask              *self,
+                                                       GtdTask              *subtask);
+
 G_END_DECLS
 
 #endif /* GTD_TASK_H */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]