notmuch.el: Implement visual feedback for add/remove tags.
[notmuch] / tags.c
1 /* tags.c - Iterator for tags returned from message or thread
2  *
3  * Copyright © 2009 Carl Worth
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see http://www.gnu.org/licenses/ .
17  *
18  * Author: Carl Worth <cworth@cworth.org>
19  */
20
21 #include "notmuch-private.h"
22
23 #include <glib.h> /* GList */
24
25 struct _notmuch_tags {
26     int sorted;
27     GList *tags;
28     GList *iterator;
29 };
30
31 /* XXX: Should write some talloc-friendly list to avoid the need for
32  * this. */
33 static int
34 _notmuch_tags_destructor (notmuch_tags_t *tags)
35 {
36     g_list_free (tags->tags);
37
38     return 0;
39 }
40
41 /* Create a new notmuch_tags_t object, with 'ctx' as its talloc owner.
42  *
43  * This function can return NULL in case of out-of-memory.
44  */
45 notmuch_tags_t *
46 _notmuch_tags_create (void *ctx)
47 {
48     notmuch_tags_t *tags;
49
50     tags = talloc (ctx, notmuch_tags_t);
51     if (unlikely (tags == NULL))
52         return NULL;
53
54     talloc_set_destructor (tags, _notmuch_tags_destructor);
55
56     tags->sorted = 1;
57     tags->tags = NULL;
58     tags->iterator = NULL;
59
60     return tags;
61 }
62
63 /* Add a new tag to 'tags'. The tags object will create its own copy
64  * of the string.
65  *
66  * Note: The tags object will not do anything to prevent duplicate
67  * tags being stored, so the caller really shouldn't pass
68  * duplicates. */
69 void
70 _notmuch_tags_add_tag (notmuch_tags_t *tags, const char *tag)
71 {
72     tags->tags = g_list_prepend (tags->tags, talloc_strdup (tags, tag));
73     tags->sorted = 0;
74 }
75
76 /* Prepare 'tag' for iteration.
77  *
78  * The internal creator of 'tags' should call this function before
79  * returning 'tags' to the user to call the public functions such as
80  * notmuch_tags_has_more, notmuch_tags_get, and notmuch_tags_advance. */
81 void
82 _notmuch_tags_prepare_iterator (notmuch_tags_t *tags)
83 {
84     if (! tags->sorted)
85         tags->tags = g_list_sort (tags->tags, (GCompareFunc) strcmp);
86     tags->sorted = 1;
87
88     tags->iterator = tags->tags;
89 }
90
91 notmuch_bool_t
92 notmuch_tags_has_more (notmuch_tags_t *tags)
93 {
94     return tags->iterator != NULL;
95 }
96
97 const char *
98 notmuch_tags_get (notmuch_tags_t *tags)
99 {
100     if (tags->iterator)
101         return (char *) tags->iterator->data;
102     else
103         return NULL;
104 }
105
106 void
107 notmuch_tags_advance (notmuch_tags_t *tags)
108 {
109     tags->iterator = tags->iterator->next;
110 }
111
112 void
113 notmuch_tags_destroy (notmuch_tags_t *tags)
114 {
115     talloc_free (tags);
116 }