2 * Claws Mail -- a GTK based, lightweight, and fast e-mail client
3 * Copyright (C) 2007-2012 The Claws Mail Team
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.
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.
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/>.
22 #include "claws-features.h"
26 #include <glib/gi18n.h>
31 #include <sys/types.h>
33 # include <sys/wait.h>
41 #include "file-utils.h"
43 static GHashTable
*tags_table
= NULL
;
44 static GHashTable
*tags_reverse_table
= NULL
;
46 static int tag_max_id
= 0;
48 void tags_read_tags(void)
50 gchar
*file
= g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S
,
54 FILE *fp
= claws_fopen(file
, "rb");
58 if (tags_table
== NULL
)
59 tags_table
= g_hash_table_new_full(
60 g_direct_hash
, g_direct_equal
,
62 if (tags_reverse_table
== NULL
)
63 tags_reverse_table
= g_hash_table_new_full(
64 g_str_hash
, g_str_equal
,
69 if (fscanf(fp
, "max_id %d\n", &tag_max_id
) != 1) {
73 while (claws_fgets(tmp
, sizeof(tmp
), fp
) != NULL
) {
74 gchar
*sep
= strchr(tmp
, '\t');
75 gchar
*tag_name
= sep
?(sep
+1):NULL
;
77 if (!tag_name
|| !sep
)
81 if (IS_NOT_RESERVED_TAG(tag_name
)) {
83 g_hash_table_insert(tags_table
,
84 GINT_TO_POINTER(id
), g_strdup(tag_name
));
85 g_hash_table_insert(tags_reverse_table
,
86 g_strdup(tag_name
), GINT_TO_POINTER(id
));
93 typedef struct _TagWriteData
99 static void tag_write(gpointer key
, gpointer value
, gpointer user_data
)
101 TagWriteData
*data
= (TagWriteData
*)user_data
;
102 const gchar
*str
= value
;
103 gint id
= GPOINTER_TO_INT(key
);
108 if (fprintf(data
->fp
, "%d\t%s\n", id
, str
) <= 0) {
109 FILE_OP_ERROR("tagsrc", "fprintf");
114 void tags_write_tags(void)
116 gchar
*file
= g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S
,
117 TAGS_RC
, ".tmp", NULL
);
118 gchar
*file_new
= g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S
,
122 FILE *fp
= claws_fopen(file
, "wb");
125 FILE_OP_ERROR(file
, "claws_fopen");
134 if (fprintf(data
.fp
, "max_id %d\n", tag_max_id
) <= 0) {
135 FILE_OP_ERROR("tagsrc", "fprintf");
138 g_hash_table_foreach(tags_table
, tag_write
, &data
);
148 if (claws_safe_fclose(fp
) == EOF
) {
149 FILE_OP_ERROR(file
, "claws_fclose");
155 if (rename_force(file
, file_new
) < 0) {
156 FILE_OP_ERROR(file
, "rename_force");
163 gint
tags_add_tag(const gchar
*tag
)
168 if (g_hash_table_lookup(tags_reverse_table
, tag
))
171 if (IS_NOT_RESERVED_TAG(tag
)) {
173 g_hash_table_insert(tags_table
, GINT_TO_POINTER(tag_max_id
),
175 g_hash_table_insert(tags_reverse_table
, g_strdup(tag
),
176 GINT_TO_POINTER(tag_max_id
));
184 void tags_remove_tag(gint id
)
186 gchar
*old_tag
= g_hash_table_lookup(tags_table
, GINT_TO_POINTER(id
));
189 g_hash_table_remove(tags_reverse_table
, old_tag
);
191 g_hash_table_remove(tags_table
, GINT_TO_POINTER(id
));
194 /* extern decl. to avoid including ../prefs_filtering.h */
195 extern void prefs_filtering_rename_tag(const gchar
*old_tag
, const gchar
*new_tag
);
197 void tags_update_tag(gint id
, const gchar
*tag
)
199 gchar
*old_tag
= g_hash_table_lookup(tags_table
, GINT_TO_POINTER(id
));
201 if (IS_NOT_RESERVED_TAG(tag
)) {
203 prefs_filtering_rename_tag(old_tag
, tag
);
204 g_hash_table_remove(tags_reverse_table
, old_tag
);
207 g_hash_table_replace(tags_table
, GINT_TO_POINTER(id
),
209 g_hash_table_insert(tags_reverse_table
, g_strdup(tag
),
210 GINT_TO_POINTER(id
));
214 const gchar
*tags_get_tag(gint id
)
216 return (const gchar
*)g_hash_table_lookup(tags_table
,
217 GINT_TO_POINTER(id
));
220 gint
tags_get_id_for_str(const gchar
*str
)
223 if ((id_ptr
= g_hash_table_lookup(tags_reverse_table
, str
)) != NULL
)
224 return GPOINTER_TO_INT(id_ptr
);
229 typedef struct _TagListData
{
233 static void tag_add_list(gpointer key
, gpointer value
, gpointer user_data
)
235 TagListData
*data
= (TagListData
*)user_data
;
237 data
->list
= g_slist_prepend(data
->list
, GINT_TO_POINTER(key
));
240 GSList
*tags_get_list(void)
245 g_hash_table_foreach(tags_table
, tag_add_list
, &data
);
247 data
.list
= g_slist_reverse(data
.list
);
252 guint
tags_get_size(void)
254 return g_hash_table_size(tags_table
);