]> git.0d.be Git - empathy.git/blob - libempathy/empathy-utils.c
Updated Basque language
[empathy.git] / libempathy / empathy-utils.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * Copyright (C) 2003-2007 Imendio AB
4  * Copyright (C) 2007-2008 Collabora Ltd.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License as
8  * published by the Free Software Foundation; either version 2 of the
9  * License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public
17  * License along with this program; if not, write to the
18  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19  * Boston, MA  02110-1301  USA
20  *
21  * Authors: Richard Hult <richard@imendio.com>
22  *          Martyn Russell <martyn@imendio.com>
23  *          Xavier Claessens <xclaesse@gmail.com>
24  */
25
26 #include "config.h"
27
28 #include <string.h>
29 #include <time.h>
30 #include <sys/types.h>
31
32 #include <glib/gi18n-lib.h>
33
34 #include <libxml/uri.h>
35 #include <telepathy-glib/connection.h>
36 #include <telepathy-glib/channel.h>
37 #include <telepathy-glib/dbus.h>
38 #include <telepathy-glib/util.h>
39
40 #include "empathy-utils.h"
41 #include "empathy-contact-manager.h"
42 #include "empathy-dispatcher.h"
43 #include "empathy-dispatch-operation.h"
44 #include "empathy-idle.h"
45 #include "empathy-tp-call.h"
46
47 #include <extensions/extensions.h>
48
49 #define DEBUG_FLAG EMPATHY_DEBUG_OTHER
50 #include "empathy-debug.h"
51
52 /* Translation between presence types and string */
53 static struct {
54         gchar *name;
55         TpConnectionPresenceType type;
56 } presence_types[] = {
57         { "available", TP_CONNECTION_PRESENCE_TYPE_AVAILABLE },
58         { "busy",      TP_CONNECTION_PRESENCE_TYPE_BUSY },
59         { "away",      TP_CONNECTION_PRESENCE_TYPE_AWAY },
60         { "ext_away",  TP_CONNECTION_PRESENCE_TYPE_EXTENDED_AWAY },
61         { "hidden",    TP_CONNECTION_PRESENCE_TYPE_HIDDEN },
62         { "offline",   TP_CONNECTION_PRESENCE_TYPE_OFFLINE },
63         { "unset",     TP_CONNECTION_PRESENCE_TYPE_UNSET },
64         { "unknown",   TP_CONNECTION_PRESENCE_TYPE_UNKNOWN },
65         { "error",     TP_CONNECTION_PRESENCE_TYPE_ERROR },
66         /* alternative names */
67         { "dnd",      TP_CONNECTION_PRESENCE_TYPE_BUSY },
68         { "brb",      TP_CONNECTION_PRESENCE_TYPE_AWAY },
69         { "xa",       TP_CONNECTION_PRESENCE_TYPE_EXTENDED_AWAY },
70         { NULL, },
71 };
72
73
74
75 void
76 empathy_init (void)
77 {
78         static gboolean initialized = FALSE;
79
80         if (initialized)
81                 return;
82
83         g_type_init ();
84
85         /* Setup gettext */
86         bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
87         bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
88
89         /* Setup debug output for empathy and telepathy-glib */
90         if (g_getenv ("EMPATHY_TIMING") != NULL) {
91                 g_log_set_default_handler (tp_debug_timestamped_log_handler, NULL);
92         }
93         empathy_debug_set_flags (g_getenv ("EMPATHY_DEBUG"));
94         tp_debug_divert_messages (g_getenv ("EMPATHY_LOGFILE"));
95
96         emp_cli_init ();
97
98         initialized = TRUE;
99 }
100
101 gchar *
102 empathy_substring (const gchar *str,
103                   gint         start,
104                   gint         end)
105 {
106         return g_strndup (str + start, end - start);
107 }
108
109 gint
110 empathy_strcasecmp (const gchar *s1,
111                    const gchar *s2)
112 {
113         return empathy_strncasecmp (s1, s2, -1);
114 }
115
116 gint
117 empathy_strncasecmp (const gchar *s1,
118                     const gchar *s2,
119                     gsize        n)
120 {
121         gchar *u1, *u2;
122         gint   ret_val;
123
124         u1 = g_utf8_casefold (s1, n);
125         u2 = g_utf8_casefold (s2, n);
126
127         ret_val = g_utf8_collate (u1, u2);
128         g_free (u1);
129         g_free (u2);
130
131         return ret_val;
132 }
133
134 gboolean
135 empathy_xml_validate (xmlDoc      *doc,
136                      const gchar *dtd_filename)
137 {
138         gchar        *path, *escaped;
139         xmlValidCtxt  cvp;
140         xmlDtd       *dtd;
141         gboolean      ret;
142
143         path = g_build_filename (g_getenv ("EMPATHY_SRCDIR"), "libempathy",
144                                  dtd_filename, NULL);
145         if (!g_file_test (path, G_FILE_TEST_EXISTS)) {
146                 g_free (path);
147                 path = g_build_filename (DATADIR, "empathy", dtd_filename, NULL);
148         }
149         DEBUG ("Loading dtd file %s", path);
150
151         /* The list of valid chars is taken from libxml. */
152         escaped = xmlURIEscapeStr (path, ":@&=+$,/?;");
153         g_free (path);
154
155         memset (&cvp, 0, sizeof (cvp));
156         dtd = xmlParseDTD (NULL, escaped);
157         ret = xmlValidateDtd (&cvp, doc, dtd);
158
159         xmlFree (escaped);
160         xmlFreeDtd (dtd);
161
162         return ret;
163 }
164
165 xmlNodePtr
166 empathy_xml_node_get_child (xmlNodePtr   node,
167                            const gchar *child_name)
168 {
169         xmlNodePtr l;
170
171         g_return_val_if_fail (node != NULL, NULL);
172         g_return_val_if_fail (child_name != NULL, NULL);
173
174         for (l = node->children; l; l = l->next) {
175                 if (l->name && strcmp (l->name, child_name) == 0) {
176                         return l;
177                 }
178         }
179
180         return NULL;
181 }
182
183 xmlChar *
184 empathy_xml_node_get_child_content (xmlNodePtr   node,
185                                    const gchar *child_name)
186 {
187         xmlNodePtr l;
188
189         g_return_val_if_fail (node != NULL, NULL);
190         g_return_val_if_fail (child_name != NULL, NULL);
191
192         l = empathy_xml_node_get_child (node, child_name);
193         if (l) {
194                 return xmlNodeGetContent (l);
195         }
196
197         return NULL;
198 }
199
200 xmlNodePtr
201 empathy_xml_node_find_child_prop_value (xmlNodePtr   node,
202                                        const gchar *prop_name,
203                                        const gchar *prop_value)
204 {
205         xmlNodePtr l;
206         xmlNodePtr found = NULL;
207
208         g_return_val_if_fail (node != NULL, NULL);
209         g_return_val_if_fail (prop_name != NULL, NULL);
210         g_return_val_if_fail (prop_value != NULL, NULL);
211
212         for (l = node->children; l && !found; l = l->next) {
213                 xmlChar *prop;
214
215                 if (!xmlHasProp (l, prop_name)) {
216                         continue;
217                 }
218
219                 prop = xmlGetProp (l, prop_name);
220                 if (prop && strcmp (prop, prop_value) == 0) {
221                         found = l;
222                 }
223
224                 xmlFree (prop);
225         }
226
227         return found;
228 }
229
230 const gchar *
231 empathy_presence_get_default_message (TpConnectionPresenceType presence)
232 {
233         switch (presence) {
234         case TP_CONNECTION_PRESENCE_TYPE_AVAILABLE:
235                 return _("Available");
236         case TP_CONNECTION_PRESENCE_TYPE_BUSY:
237                 return _("Busy");
238         case TP_CONNECTION_PRESENCE_TYPE_AWAY:
239         case TP_CONNECTION_PRESENCE_TYPE_EXTENDED_AWAY:
240                 return _("Away");
241         case TP_CONNECTION_PRESENCE_TYPE_HIDDEN:
242                 return _("Hidden");
243         case TP_CONNECTION_PRESENCE_TYPE_OFFLINE:
244                 return _("Offline");
245         case TP_CONNECTION_PRESENCE_TYPE_UNSET:
246         case TP_CONNECTION_PRESENCE_TYPE_UNKNOWN:
247         case TP_CONNECTION_PRESENCE_TYPE_ERROR:
248                 return NULL;
249         }
250
251         return NULL;
252 }
253
254 const gchar *
255 empathy_presence_to_str (TpConnectionPresenceType presence)
256 {
257         int i;
258
259         for (i = 0 ; presence_types[i].name != NULL; i++)
260                 if (presence == presence_types[i].type)
261                         return presence_types[i].name;
262
263         return NULL;
264 }
265
266 TpConnectionPresenceType
267 empathy_presence_from_str (const gchar *str)
268 {
269         int i;
270
271         for (i = 0 ; presence_types[i].name != NULL; i++)
272                 if (!tp_strdiff (str, presence_types[i].name))
273                         return presence_types[i].type;
274
275         return TP_CONNECTION_PRESENCE_TYPE_UNSET;
276 }
277
278 gchar *
279 empathy_file_lookup (const gchar *filename, const gchar *subdir)
280 {
281         gchar *path;
282
283         if (!subdir) {
284                 subdir = ".";
285         }
286
287         path = g_build_filename (g_getenv ("EMPATHY_SRCDIR"), subdir, filename, NULL);
288         if (!g_file_test (path, G_FILE_TEST_EXISTS)) {
289                 g_free (path);
290                 path = g_build_filename (DATADIR, "empathy", filename, NULL);
291         }
292
293         return path;
294 }
295
296 guint
297 empathy_proxy_hash (gconstpointer key)
298 {
299         TpProxy      *proxy = TP_PROXY (key);
300         TpProxyClass *proxy_class = TP_PROXY_GET_CLASS (key);
301
302         g_return_val_if_fail (TP_IS_PROXY (proxy), 0);
303         g_return_val_if_fail (proxy_class->must_have_unique_name, 0);
304
305         return g_str_hash (proxy->object_path) ^ g_str_hash (proxy->bus_name);
306 }
307
308 gboolean
309 empathy_proxy_equal (gconstpointer a,
310                      gconstpointer b)
311 {
312         TpProxy *proxy_a = TP_PROXY (a);
313         TpProxy *proxy_b = TP_PROXY (b);
314         TpProxyClass *proxy_a_class = TP_PROXY_GET_CLASS (a);
315         TpProxyClass *proxy_b_class = TP_PROXY_GET_CLASS (b);
316
317         g_return_val_if_fail (TP_IS_PROXY (proxy_a), FALSE);
318         g_return_val_if_fail (TP_IS_PROXY (proxy_b), FALSE);
319         g_return_val_if_fail (proxy_a_class->must_have_unique_name, 0);
320         g_return_val_if_fail (proxy_b_class->must_have_unique_name, 0);
321
322         return g_str_equal (proxy_a->object_path, proxy_b->object_path) &&
323                g_str_equal (proxy_a->bus_name, proxy_b->bus_name);
324 }
325
326 gboolean
327 empathy_check_available_state (void)
328 {
329         TpConnectionPresenceType presence;
330         EmpathyIdle *idle;
331
332         idle = empathy_idle_dup_singleton ();
333         presence = empathy_idle_get_state (idle);
334         g_object_unref (idle);
335
336         if (presence != TP_CONNECTION_PRESENCE_TYPE_AVAILABLE &&
337                 presence != TP_CONNECTION_PRESENCE_TYPE_UNSET) {
338                 return FALSE;
339         }
340
341         return TRUE;
342 }
343
344 gint
345 empathy_uint_compare (gconstpointer a,
346                       gconstpointer b)
347 {
348         return *(guint *) a - *(guint *) b;
349 }
350
351 gchar *
352 empathy_protocol_icon_name (const gchar *protocol)
353 {
354   return g_strdup_printf ("im-%s", protocol);
355 }
356
357 GType
358 empathy_type_dbus_ao (void)
359 {
360   static GType t = 0;
361
362   if (G_UNLIKELY (t == 0))
363      t = dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH);
364
365   return t;
366 }
367
368 const char *
369 empathy_protocol_name_to_display_name (const gchar *proto_name)
370 {
371   int i;
372   static struct {
373     const gchar *proto;
374     const gchar *display;
375     gboolean translated;
376   } names[] = {
377     { "jabber", "Jabber", FALSE },
378     { "gtalk", "Google Talk", FALSE },
379     { "msn", "MSN", FALSE, },
380     { "local-xmpp", N_("People Nearby"), TRUE },
381     { "irc", "IRC", FALSE },
382     { "icq", "ICQ", FALSE },
383     { "aim", "AIM", FALSE },
384     { "yahoo", "Yahoo!", FALSE },
385     { "yahoojp", N_("Yahoo! Japan"), TRUE },
386     { "facebook", N_("Facebook Chat"), TRUE },
387     { "groupwise", "GroupWise", FALSE },
388     { "sip", "SIP", FALSE },
389     { NULL, NULL }
390   };
391
392   for (i = 0; names[i].proto != NULL; i++)
393     {
394       if (!tp_strdiff (proto_name, names[i].proto))
395         {
396           if (names[i].translated)
397             return _(names[i].display);
398           else
399             return names[i].display;
400         }
401     }
402
403   return NULL;
404 }
405