]> git.0d.be Git - empathy.git/blob - libempathy/empathy-contact-groups.c
Updated Swedish translation
[empathy.git] / libempathy / empathy-contact-groups.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * Copyright (C) 2005-2007 Imendio AB
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation; either version 2 of the
8  * License, or (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 GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public
16  * License along with this program; if not, write to the
17  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18  * Boston, MA  02110-1301  USA
19  *
20  * Authors: Martyn Russell <martyn@imendio.com>
21  */
22
23 #include "config.h"
24 #include "empathy-contact-groups.h"
25
26 #include <sys/stat.h>
27 #include <tp-account-widgets/tpaw-utils.h>
28
29 #include "empathy-utils.h"
30
31 #define DEBUG_FLAG EMPATHY_DEBUG_CONTACT
32 #include "empathy-debug.h"
33
34 #define CONTACT_GROUPS_XML_FILENAME "contact-groups.xml"
35 #define CONTACT_GROUPS_DTD_RESOURCENAME "/org/gnome/Empathy/empathy-contact-groups.dtd"
36
37 typedef struct {
38         gchar    *name;
39         gboolean  expanded;
40 } ContactGroup;
41
42 static void          contact_groups_file_parse (const gchar  *filename);
43 static gboolean      contact_groups_file_save  (void);
44 static ContactGroup *contact_group_new         (const gchar  *name,
45                                                 gboolean      expanded);
46 static void          contact_group_free        (ContactGroup *group);
47
48 static GList *groups = NULL;
49
50 void
51 empathy_contact_groups_get_all (void)
52 {
53         gchar *dir;
54         gchar *file_with_path;
55
56         /* If already set up clean up first */
57         if (groups) {
58                 g_list_foreach (groups, (GFunc)contact_group_free, NULL);
59                 g_list_free (groups);
60                 groups = NULL;
61         }
62
63         dir = g_build_filename (g_get_user_config_dir (), PACKAGE_NAME, NULL);
64         file_with_path = g_build_filename (dir, CONTACT_GROUPS_XML_FILENAME, NULL);
65         g_free (dir);
66
67         if (g_file_test (file_with_path, G_FILE_TEST_EXISTS)) {
68                 contact_groups_file_parse (file_with_path);
69         }
70
71         g_free (file_with_path);
72 }
73
74 static void
75 contact_groups_file_parse (const gchar *filename)
76 {
77         xmlParserCtxtPtr ctxt;
78         xmlDocPtr        doc;
79         xmlNodePtr       contacts;
80         xmlNodePtr       account;
81         xmlNodePtr       node;
82
83         DEBUG ("Attempting to parse file:'%s'...", filename);
84
85         ctxt = xmlNewParserCtxt ();
86
87         /* Parse and validate the file. */
88         doc = xmlCtxtReadFile (ctxt, filename, NULL, 0);
89         if (!doc) {
90                 g_warning ("Failed to parse file:'%s'", filename);
91                 xmlFreeParserCtxt (ctxt);
92                 return;
93         }
94
95         if (!tpaw_xml_validate_from_resource (doc, CONTACT_GROUPS_DTD_RESOURCENAME)) {
96                 g_warning ("Failed to validate file:'%s'", filename);
97                 xmlFreeDoc (doc);
98                 xmlFreeParserCtxt (ctxt);
99                 return;
100         }
101
102         /* The root node, contacts. */
103         contacts = xmlDocGetRootElement (doc);
104
105         account = NULL;
106         node = contacts->children;
107         while (node) {
108                 if (strcmp ((gchar *) node->name, "account") == 0) {
109                         account = node;
110                         break;
111                 }
112                 node = node->next;
113         }
114
115         node = NULL;
116         if (account) {
117                 node = account->children;
118         }
119
120         while (node) {
121                 if (strcmp ((gchar *) node->name, "group") == 0) {
122                         gchar        *name;
123                         gchar        *expanded_str;
124                         gboolean      expanded;
125                         ContactGroup *contact_group;
126
127                         name = (gchar *) xmlGetProp (node, (const xmlChar *) "name");
128                         expanded_str = (gchar *) xmlGetProp (node, (const xmlChar *) "expanded");
129
130                         if (expanded_str && strcmp (expanded_str, "yes") == 0) {
131                                 expanded = TRUE;
132                         } else {
133                                 expanded = FALSE;
134                         }
135
136                         contact_group = contact_group_new (name, expanded);
137                         groups = g_list_append (groups, contact_group);
138
139                         xmlFree (name);
140                         xmlFree (expanded_str);
141                 }
142
143                 node = node->next;
144         }
145
146         DEBUG ("Parsed %d contact groups", g_list_length (groups));
147
148         xmlFreeDoc (doc);
149         xmlFreeParserCtxt (ctxt);
150 }
151
152 static ContactGroup *
153 contact_group_new (const gchar *name,
154                    gboolean     expanded)
155 {
156         ContactGroup *group;
157
158         group = g_new0 (ContactGroup, 1);
159
160         group->name = g_strdup (name);
161         group->expanded = expanded;
162
163         return group;
164 }
165
166 static void
167 contact_group_free (ContactGroup *group)
168 {
169         g_return_if_fail (group != NULL);
170
171         g_free (group->name);
172
173         g_free (group);
174 }
175
176 static gboolean
177 contact_groups_file_save (void)
178 {
179         xmlDocPtr   doc;
180         xmlNodePtr  root;
181         xmlNodePtr  node;
182         GList      *l;
183         gchar      *dir;
184         gchar      *file;
185
186         dir = g_build_filename (g_get_user_config_dir (), PACKAGE_NAME, NULL);
187         g_mkdir_with_parents (dir, S_IRUSR | S_IWUSR | S_IXUSR);
188         file = g_build_filename (dir, CONTACT_GROUPS_XML_FILENAME, NULL);
189         g_free (dir);
190
191         doc = xmlNewDoc ((const xmlChar *) "1.0");
192         root = xmlNewNode (NULL, (const xmlChar *) "contacts");
193         xmlDocSetRootElement (doc, root);
194
195         node = xmlNewChild (root, NULL, (const xmlChar *) "account", NULL);
196         xmlNewProp (node, (const xmlChar *) "name", (const xmlChar *) "Default");
197
198         for (l = groups; l; l = l->next) {
199                 ContactGroup *cg;
200                 xmlNodePtr    subnode;
201
202                 cg = l->data;
203
204                 subnode = xmlNewChild (node, NULL, (const xmlChar *) "group", NULL);
205                 xmlNewProp (subnode, (const xmlChar *) "expanded", cg->expanded ?
206                                 (const xmlChar *) "yes" : (const xmlChar *) "no");
207                 xmlNewProp (subnode, (const xmlChar *) "name", (const xmlChar *) cg->name);
208         }
209
210         /* Make sure the XML is indented properly */
211         xmlIndentTreeOutput = 1;
212
213         DEBUG ("Saving file:'%s'", file);
214         xmlSaveFormatFileEnc (file, doc, "utf-8", 1);
215         xmlFreeDoc (doc);
216
217         xmlMemoryDump ();
218
219         g_free (file);
220
221         return TRUE;
222 }
223
224 gboolean
225 empathy_contact_group_get_expanded (const gchar *group)
226 {
227         GList    *l;
228         gboolean  default_val = TRUE;
229
230         g_return_val_if_fail (group != NULL, default_val);
231
232         for (l = groups; l; l = l->next) {
233                 ContactGroup *cg = l->data;
234
235                 if (!cg || !cg->name) {
236                         continue;
237                 }
238
239                 if (strcmp (cg->name, group) == 0) {
240                         return cg->expanded;
241                 }
242         }
243
244         return default_val;
245 }
246
247 void
248 empathy_contact_group_set_expanded (const gchar *group,
249                                    gboolean     expanded)
250 {
251         GList        *l;
252         ContactGroup *cg;
253         gboolean      changed = FALSE;
254
255         g_return_if_fail (group != NULL);
256
257         for (l = groups; l; l = l->next) {
258                 cg = l->data;
259
260                 if (!cg || !cg->name) {
261                         continue;
262                 }
263
264                 if (strcmp (cg->name, group) == 0) {
265                         cg->expanded = expanded;
266                         changed = TRUE;
267                         break;
268                 }
269         }
270
271         /* if here... we don't have a ContactGroup for the group. */
272         if (!changed) {
273                 cg = contact_group_new (group, expanded);
274                 groups = g_list_append (groups, cg);
275         }
276
277         contact_groups_file_save ();
278 }