1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * Copyright (C) 2007 Collabora Ltd.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library 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 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 * Authors: Dafydd Harrie <dafydd.harries@collabora.co.uk>
20 * Xavier Claessens <xclaesse@gmail.com>
27 #include <libempathy/empathy-debug.h>
29 #include "empathy-smiley-manager.h"
30 #include "empathy-ui-utils.h"
32 #define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
33 EMPATHY_TYPE_SMILEY_MANAGER, EmpathySmileyManagerPriv))
35 #define DEBUG_DOMAIN "SmileyManager"
43 struct _EmpathySmileyManagerPriv {
44 SmileyManagerTree *tree;
48 static void empathy_smiley_manager_class_init (EmpathySmileyManagerClass *klass);
49 static void empathy_smiley_manager_init (EmpathySmileyManager *manager);
51 G_DEFINE_TYPE (EmpathySmileyManager, empathy_smiley_manager, G_TYPE_OBJECT);
53 static SmileyManagerTree *
54 smiley_manager_tree_new (gunichar c)
56 SmileyManagerTree *tree;
58 tree = g_slice_new0 (SmileyManagerTree);
61 tree->childrens = NULL;
67 smiley_manager_tree_free (SmileyManagerTree *tree)
75 for (l = tree->childrens; l; l = l->next) {
76 smiley_manager_tree_free (l->data);
80 g_object_unref (tree->pixbuf);
82 g_slist_free (tree->childrens);
83 g_slice_free (SmileyManagerTree, tree);
86 static EmpathySmiley *
87 smiley_new (GdkPixbuf *pixbuf, const gchar *str)
89 EmpathySmiley *smiley;
91 smiley = g_slice_new0 (EmpathySmiley);
93 smiley->pixbuf = g_object_ref (pixbuf);
95 smiley->str = g_strdup (str);
101 empathy_smiley_free (EmpathySmiley *smiley)
107 if (smiley->pixbuf) {
108 g_object_unref (smiley->pixbuf);
110 g_free (smiley->str);
111 g_slice_free (EmpathySmiley, smiley);
115 smiley_manager_finalize (GObject *object)
117 EmpathySmileyManagerPriv *priv = GET_PRIV (object);
119 smiley_manager_tree_free (priv->tree);
120 g_slist_foreach (priv->smileys, (GFunc) empathy_smiley_free, NULL);
121 g_slist_free (priv->smileys);
125 empathy_smiley_manager_class_init (EmpathySmileyManagerClass *klass)
127 GObjectClass *object_class = G_OBJECT_CLASS (klass);
129 object_class->finalize = smiley_manager_finalize;
131 g_type_class_add_private (object_class, sizeof (EmpathySmileyManagerPriv));
135 empathy_smiley_manager_init (EmpathySmileyManager *manager)
137 EmpathySmileyManagerPriv *priv = GET_PRIV (manager);
139 priv->tree = smiley_manager_tree_new ('\0');
140 priv->smileys = NULL;
143 EmpathySmileyManager *
144 empathy_smiley_manager_new (void)
146 static EmpathySmileyManager *manager = NULL;
149 manager = g_object_new (EMPATHY_TYPE_SMILEY_MANAGER, NULL);
150 g_object_add_weak_pointer (G_OBJECT (manager), (gpointer) &manager);
151 empathy_smiley_manager_load (manager);
153 g_object_ref (manager);
159 static SmileyManagerTree *
160 smiley_manager_tree_find_child (SmileyManagerTree *tree, gunichar c)
164 for (l = tree->childrens; l; l = l->next) {
165 SmileyManagerTree *child = l->data;
175 static SmileyManagerTree *
176 smiley_manager_tree_find_or_insert_child (SmileyManagerTree *tree, gunichar c)
178 SmileyManagerTree *child;
180 child = smiley_manager_tree_find_child (tree, c);
183 child = smiley_manager_tree_new (c);
184 tree->childrens = g_slist_prepend (tree->childrens, child);
191 smiley_manager_tree_insert (SmileyManagerTree *tree,
195 SmileyManagerTree *child;
197 child = smiley_manager_tree_find_or_insert_child (tree, g_utf8_get_char (str));
199 str = g_utf8_next_char (str);
201 smiley_manager_tree_insert (child, smiley, str);
205 child->pixbuf = g_object_ref (smiley);
209 smiley_manager_add_valist (EmpathySmileyManager *manager,
211 const gchar *first_str,
214 EmpathySmileyManagerPriv *priv = GET_PRIV (manager);
217 for (str = first_str; str; str = va_arg (var_args, gchar*)) {
218 smiley_manager_tree_insert (priv->tree, smiley, str);
221 priv->smileys = g_slist_prepend (priv->smileys, smiley_new (smiley, first_str));
225 empathy_smiley_manager_add (EmpathySmileyManager *manager,
226 const gchar *icon_name,
227 const gchar *first_str,
233 g_return_if_fail (EMPATHY_IS_SMILEY_MANAGER (manager));
234 g_return_if_fail (!G_STR_EMPTY (icon_name));
235 g_return_if_fail (!G_STR_EMPTY (first_str));
237 smiley = empathy_pixbuf_from_icon_name (icon_name, GTK_ICON_SIZE_MENU);
239 va_start (var_args, first_str);
240 smiley_manager_add_valist (manager, smiley, first_str, var_args);
242 g_object_unref (smiley);
247 empathy_smiley_manager_add_from_pixbuf (EmpathySmileyManager *manager,
249 const gchar *first_str,
254 g_return_if_fail (EMPATHY_IS_SMILEY_MANAGER (manager));
255 g_return_if_fail (GDK_IS_PIXBUF (smiley));
256 g_return_if_fail (!G_STR_EMPTY (first_str));
258 va_start (var_args, first_str);
259 smiley_manager_add_valist (manager, smiley, first_str, var_args);
264 empathy_smiley_manager_load (EmpathySmileyManager *manager)
266 g_return_if_fail (EMPATHY_IS_SMILEY_MANAGER (manager));
268 /* From fd.o icon-naming spec */
269 empathy_smiley_manager_add (manager, "face-angel", "0:-)", "0:)", NULL);
270 empathy_smiley_manager_add (manager, "face-crying", ":'(", NULL);
271 empathy_smiley_manager_add (manager, "face-devil-grin", ">:-)", ">:)", NULL);
272 empathy_smiley_manager_add (manager, "face-devil-sad", ">:-(", ">:(", NULL);
273 empathy_smiley_manager_add (manager, "face-glasses", "B-)", "B)", NULL);
274 empathy_smiley_manager_add (manager, "face-kiss", ":-*", ":*", NULL);
275 empathy_smiley_manager_add (manager, "face-monkey", ":-(|)", ":(|)", NULL);
276 empathy_smiley_manager_add (manager, "face-plain", ":-|", ":|", NULL);
277 empathy_smiley_manager_add (manager, "face-sad", ":-(", ":(", NULL);
278 empathy_smiley_manager_add (manager, "face-smile", ":-)", ":)", NULL);
279 empathy_smiley_manager_add (manager, "face-smile-big", ":-D", ":D", NULL);
280 empathy_smiley_manager_add (manager, "face-smirk", ":-!", ":!", NULL);
281 empathy_smiley_manager_add (manager, "face-surprise", ":-0", ":0", NULL);
282 empathy_smiley_manager_add (manager, "face-wink", ";-)", ";)", NULL);
286 empathy_smiley_manager_parse (EmpathySmileyManager *manager,
289 EmpathySmileyManagerPriv *priv = GET_PRIV (manager);
290 EmpathySmiley *smiley;
291 SmileyManagerTree *cur_tree = priv->tree;
293 const gchar *cur_str = text;
294 GSList *smileys = NULL;
296 g_return_val_if_fail (EMPATHY_IS_SMILEY_MANAGER (manager), NULL);
297 g_return_val_if_fail (text != NULL, NULL);
299 for (t = text; *t; t = g_utf8_next_char (t)) {
300 SmileyManagerTree *child;
303 c = g_utf8_get_char (t);
304 child = smiley_manager_tree_find_child (cur_tree, c);
306 if (cur_tree == priv->tree) {
309 smiley = smiley_new (NULL, g_strndup (cur_str, t - cur_str));
310 smileys = g_slist_prepend (smileys, smiley);
324 smiley = smiley_new (cur_tree->pixbuf, g_strndup (cur_str, t - cur_str));
325 smileys = g_slist_prepend (smileys, smiley);
326 if (cur_tree->pixbuf) {
328 cur_tree = smiley_manager_tree_find_child (priv->tree, c);
331 cur_tree = priv->tree;
335 cur_tree = priv->tree;
339 smiley = smiley_new (cur_tree->pixbuf, g_strndup (cur_str, t - cur_str));
340 smileys = g_slist_prepend (smileys, smiley);
342 return g_slist_reverse (smileys);
346 empathy_smiley_manager_get_all (EmpathySmileyManager *manager)
348 EmpathySmileyManagerPriv *priv = GET_PRIV (manager);
350 return priv->smileys;