libpurple/smiley-list.c

changeset 35728
6cd9aee7f276
parent 35717
45bde03f86a6
child 35738
030ce6840163
--- a/libpurple/smiley-list.c	Wed Apr 02 20:24:19 2014 +0200
+++ b/libpurple/smiley-list.c	Wed Apr 02 21:03:24 2014 +0200
@@ -34,7 +34,8 @@
 	GList *smileys;
 	GList *smileys_end;
 	PurpleTrie *trie;
-	GHashTable *unique_map;
+	GHashTable *path_map;
+	GHashTable *shortcut_map;
 } PurpleSmileyListPrivate;
 
 enum
@@ -108,10 +109,15 @@
 	}
 
 	shortcut = purple_smiley_get_shortcut(smiley);
+
+	if (g_hash_table_lookup(priv->shortcut_map, shortcut) != NULL)
+		return FALSE;
+
 	if (purple_smiley_parse_escape())
 		shortcut = tmp = g_markup_escape_text(shortcut, -1);
 	succ = purple_trie_add(priv->trie, shortcut, smiley);
 	g_free(tmp);
+	shortcut = purple_smiley_get_shortcut(smiley);
 	if (!succ)
 		return FALSE;
 
@@ -122,10 +128,11 @@
 		priv->smileys_end);
 
 	smiley_path = purple_smiley_get_path(smiley);
-	if (g_hash_table_lookup(priv->unique_map, smiley_path) == NULL) {
-		g_hash_table_insert(priv->unique_map,
+	if (g_hash_table_lookup(priv->path_map, smiley_path) == NULL) {
+		g_hash_table_insert(priv->path_map,
 			g_strdup(smiley_path), smiley);
 	}
+	g_hash_table_insert(priv->shortcut_map, g_strdup(shortcut), smiley);
 
 	return TRUE;
 }
@@ -134,7 +141,9 @@
 purple_smiley_list_remove(PurpleSmileyList *list, PurpleSmiley *smiley)
 {
 	PurpleSmileyListPrivate *priv = PURPLE_SMILEY_LIST_GET_PRIVATE(list);
-	GList *list_elem;
+	GList *list_elem, *it;
+	const gchar *shortcut, *path;
+	gchar *tmp;
 
 	g_return_if_fail(priv != NULL);
 	g_return_if_fail(PURPLE_IS_SMILEY(smiley));
@@ -147,9 +156,31 @@
 	list_elem = g_object_get_data(G_OBJECT(smiley),
 		"purple-smiley-list-elem");
 
-	purple_trie_remove(priv->trie, purple_smiley_get_shortcut(smiley));
+	shortcut = purple_smiley_get_shortcut(smiley);
+	path = purple_smiley_get_path(smiley);
+
+	g_hash_table_remove(priv->shortcut_map, shortcut);
+	g_hash_table_remove(priv->path_map, path);
+
+	if (purple_smiley_parse_escape())
+		shortcut = tmp = g_markup_escape_text(shortcut, -1);
+	purple_trie_remove(priv->trie, shortcut);
+	g_free(tmp);
+	shortcut = purple_smiley_get_shortcut(smiley);
+
 	_list_remove_link2(&priv->smileys, &priv->smileys_end, list_elem);
 
+	/* re-add entry to path_map if smiley was not unique */
+	for (it = priv->smileys; it; it = g_list_next(it)) {
+		PurpleSmiley *smiley = it->data;
+
+		if (g_strcmp0(purple_smiley_get_path(smiley), path) == 0) {
+			g_hash_table_insert(priv->path_map,
+				g_strdup(path), smiley);
+			break;
+		}
+	}
+
 	g_object_set_data(G_OBJECT(smiley), "purple-smiley-list", NULL);
 	g_object_set_data(G_OBJECT(smiley), "purple-smiley-list-elem", NULL);
 	g_object_unref(smiley);
@@ -163,7 +194,7 @@
 
 	g_return_val_if_fail(priv != NULL, NULL);
 
-	return g_hash_table_lookup(priv->unique_map, shortcut);
+	return g_hash_table_lookup(priv->shortcut_map, shortcut);
 }
 
 PurpleTrie *
@@ -183,7 +214,17 @@
 
 	g_return_val_if_fail(priv != NULL, NULL);
 
-	return g_hash_table_get_values(priv->unique_map);
+	return g_hash_table_get_values(priv->path_map);
+}
+
+GList *
+purple_smiley_list_get_all(PurpleSmileyList *list)
+{
+	PurpleSmileyListPrivate *priv = PURPLE_SMILEY_LIST_GET_PRIVATE(list);
+
+	g_return_val_if_fail(priv != NULL, NULL);
+
+	return g_hash_table_get_values(priv->shortcut_map);
 }
 
 
@@ -198,7 +239,9 @@
 	PurpleSmileyListPrivate *priv = PURPLE_SMILEY_LIST_GET_PRIVATE(sl);
 
 	priv->trie = purple_trie_new();
-	priv->unique_map = g_hash_table_new_full(g_str_hash, g_str_equal,
+	priv->path_map = g_hash_table_new_full(g_str_hash, g_str_equal,
+		g_free, NULL);
+	priv->shortcut_map = g_hash_table_new_full(g_str_hash, g_str_equal,
 		g_free, NULL);
 
 	PURPLE_DBUS_REGISTER_POINTER(sl, PurpleSmileyList);
@@ -212,7 +255,8 @@
 	GList *it;
 
 	g_object_unref(priv->trie);
-	g_hash_table_destroy(priv->unique_map);
+	g_hash_table_destroy(priv->path_map);
+	g_hash_table_destroy(priv->shortcut_map);
 
 	for (it = priv->smileys; it; it = g_list_next(it)) {
 		PurpleSmiley *smiley = it->data;

mercurial