2 * Claws Mail -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 1999-2007 Hiroyuki Yamamoto & 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/>.
27 #include <glib/gi18n.h>
32 #include <sys/types.h>
34 # include <sys/wait.h>
42 static GHashTable
*tags_table
= NULL
;
43 static GHashTable
*tags_reverse_table
= NULL
;
45 static int tag_max_id
= 0;
47 void tags_read_tags(void)
49 gchar
*file
= g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S
,
53 FILE *fp
= fopen(file
, "rb");
57 if (tags_table
== NULL
)
58 tags_table
= g_hash_table_new_full(
59 g_direct_hash
, g_direct_equal
,
61 if (tags_reverse_table
== NULL
)
62 tags_reverse_table
= g_hash_table_new_full(
63 g_str_hash
, g_str_equal
,
68 if (fscanf(fp
, "max_id %d\n", &tag_max_id
) != 1) {
72 while (fgets(&tmp
, sizeof(tmp
), fp
) != NULL
) {
73 gchar
*sep
= strchr(tmp
, '\t');
74 gchar
*tag_name
= sep
?(sep
+1):NULL
;
76 if (!tag_name
|| !sep
)
81 g_hash_table_insert(tags_table
,
82 GINT_TO_POINTER(id
), g_strdup(tag_name
));
83 g_hash_table_insert(tags_reverse_table
,
84 g_strdup(tag_name
), GINT_TO_POINTER(id
));
90 typedef struct _TagWriteData
96 static void tag_write(gpointer key
, gpointer value
, gpointer user_data
)
98 TagWriteData
*data
= (TagWriteData
*)user_data
;
99 const gchar
*str
= value
;
100 gint id
= GPOINTER_TO_INT(key
);
105 if (fprintf(data
->fp
, "%d\t%s\n", id
, str
) <= 0) {
106 FILE_OP_ERROR("tagsrc", "fprintf");
111 void tags_write_tags(void)
113 gchar
*file
= g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S
,
114 TAGS_RC
, ".tmp", NULL
);
115 gchar
*file_new
= g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S
,
119 FILE *fp
= fopen(file
, "wb");
122 FILE_OP_ERROR(file
, "fopen");
131 if (fprintf(data
.fp
, "max_id %d\n", tag_max_id
) <= 0) {
132 FILE_OP_ERROR("tagsrc", "fprintf");
135 g_hash_table_foreach(tags_table
, tag_write
, &data
);
145 if (fclose(fp
) == EOF
) {
146 FILE_OP_ERROR(file
, "fclose");
152 if (rename_force(file
, file_new
) < 0) {
153 FILE_OP_ERROR(file
, "rename_force");
160 gint
tags_add_tag(const gchar
*tag
)
165 if (g_hash_table_lookup(tags_reverse_table
, tag
))
169 g_hash_table_insert(tags_table
, GINT_TO_POINTER(tag_max_id
),
171 g_hash_table_insert(tags_reverse_table
, g_strdup(tag
),
172 GINT_TO_POINTER(tag_max_id
));
177 void tags_remove_tag(gint id
)
179 gchar
*old_tag
= g_hash_table_lookup(tags_table
, GINT_TO_POINTER(id
));
182 g_hash_table_remove(tags_reverse_table
, old_tag
);
184 g_hash_table_remove(tags_table
, GINT_TO_POINTER(id
));
187 /* extern decl. to avoid including ../prefs_filtering.h */
188 extern void prefs_filtering_rename_tag(const gchar
*old_tag
, const gchar
*new_tag
);
190 void tags_update_tag(gint id
, const gchar
*tag
)
192 gchar
*old_tag
= g_hash_table_lookup(tags_table
, GINT_TO_POINTER(id
));
195 prefs_filtering_rename_tag(old_tag
, tag
);
196 g_hash_table_remove(tags_reverse_table
, old_tag
);
199 g_hash_table_replace(tags_table
, GINT_TO_POINTER(id
),
201 g_hash_table_insert(tags_reverse_table
, g_strdup(tag
),
202 GINT_TO_POINTER(id
));
205 const gchar
*tags_get_tag(gint id
)
207 return (const gchar
*)g_hash_table_lookup(tags_table
,
208 GINT_TO_POINTER(id
));
211 gint
tags_get_id_for_str(const gchar
*str
)
214 if ((id_ptr
= g_hash_table_lookup(tags_reverse_table
, str
)) != NULL
)
215 return GPOINTER_TO_INT(id_ptr
);
220 typedef struct _TagListData
{
224 static void tag_add_list(gpointer key
, gpointer value
, gpointer user_data
)
226 TagListData
*data
= (TagListData
*)user_data
;
228 data
->list
= g_slist_prepend(data
->list
, GINT_TO_POINTER(key
));
231 GSList
*tags_get_list(void)
236 g_hash_table_foreach(tags_table
, tag_add_list
, &data
);
238 data
.list
= g_slist_reverse(data
.list
);