Smiley list: add/remove

Sat, 29 Mar 2014 18:14:02 +0100

author
Tomasz Wasilczyk <twasilczyk@pidgin.im>
date
Sat, 29 Mar 2014 18:14:02 +0100
changeset 35702
06a934baa610
parent 35701
34f4a4318d19
child 35703
238e0042049a

Smiley list: add/remove

libpurple/dbus-server.c file | annotate | diff | comparison | revisions
libpurple/smiley-list.c file | annotate | diff | comparison | revisions
libpurple/smiley-list.h file | annotate | diff | comparison | revisions
--- a/libpurple/dbus-server.c	Sat Mar 29 17:25:19 2014 +0100
+++ b/libpurple/dbus-server.c	Sat Mar 29 18:14:02 2014 +0100
@@ -46,6 +46,7 @@
 #include "core.h"
 #include "savedstatuses.h"
 #include "smiley.h"
+#include "smiley-list.h"
 #include "util.h"
 #include "xmlnode.h"
 
--- a/libpurple/smiley-list.c	Sat Mar 29 17:25:19 2014 +0100
+++ b/libpurple/smiley-list.c	Sat Mar 29 18:14:02 2014 +0100
@@ -22,13 +22,17 @@
 #include "smiley-list.h"
 
 #include "dbus-maybe.h"
+#include "debug.h"
+#include "trie.h"
 
 #define PURPLE_SMILEY_LIST_GET_PRIVATE(obj) \
 	(G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_SMILEY_LIST, \
 	PurpleSmileyListPrivate))
 
 typedef struct {
-	int x;
+	GList *smileys;
+	GList *smileys_end;
+	PurpleTrie *trie;
 } PurpleSmileyListPrivate;
 
 enum
@@ -40,6 +44,101 @@
 static GObjectClass *parent_class;
 static GParamSpec *properties[PROP_LAST];
 
+static void
+_list_append2(GList **head_p, GList **tail_p, gpointer data)
+{
+	GList *head = *head_p;
+	GList *tail = *tail_p;
+	GList *elem;
+
+	g_return_if_fail((head == NULL) == (tail == NULL));
+	g_return_if_fail((tail == NULL) || (tail->next == NULL));
+
+	elem = g_list_alloc();
+	elem->data = data;
+	elem->prev = tail;
+	elem->next = NULL;
+
+	if (head) {
+		tail->next = elem;
+		*tail_p = elem;
+	} else
+		*head_p = *tail_p = elem;
+}
+
+static void
+_list_remove_link2(GList **head_p, GList **tail_p, GList *link)
+{
+	GList *head = *head_p;
+	GList *tail = *tail_p;
+
+	g_return_if_fail(head != NULL);
+	g_return_if_fail(tail != NULL);
+
+	if (link == tail)
+		*tail_p = tail->prev;
+	*head_p = g_list_remove_link(head, link);
+}
+
+/*******************************************************************************
+ * API implementation
+ ******************************************************************************/
+
+gboolean
+purple_smiley_list_add(PurpleSmileyList *list, PurpleSmiley *smiley)
+{
+	PurpleSmileyListPrivate *priv = PURPLE_SMILEY_LIST_GET_PRIVATE(list);
+	gboolean succ;
+
+	g_return_val_if_fail(priv != NULL, FALSE);
+	g_return_val_if_fail(PURPLE_IS_SMILEY(smiley), FALSE);
+
+	if (g_object_get_data(G_OBJECT(smiley), "purple-smiley-list") != NULL) {
+		purple_debug_warning("smiley-list",
+			"smiley is already associated with some list");
+		return FALSE;
+	}
+
+	succ = purple_trie_add(priv->trie,
+		purple_smiley_get_shortcut(smiley), smiley);
+	if (!succ)
+		return FALSE;
+
+	g_object_ref(smiley);
+	_list_append2(&priv->smileys, &priv->smileys_end, smiley);
+	g_object_set_data(G_OBJECT(smiley), "purple-smiley-list", list);
+	g_object_set_data(G_OBJECT(smiley), "purple-smiley-list-elem",
+		priv->smileys_end);
+
+	return TRUE;
+}
+
+void
+purple_smiley_list_remove(PurpleSmileyList *list, PurpleSmiley *smiley)
+{
+	PurpleSmileyListPrivate *priv = PURPLE_SMILEY_LIST_GET_PRIVATE(list);
+	GList *list_elem;
+
+	g_return_if_fail(priv != NULL);
+	g_return_if_fail(PURPLE_IS_SMILEY(smiley));
+
+	if (g_object_get_data(G_OBJECT(smiley), "purple-smiley-list") != list) {
+		purple_debug_warning("smiley-list", "remove: invalid list");
+		return;
+	}
+
+	list_elem = g_object_get_data(G_OBJECT(smiley),
+		"purple-smiley-list-elem");
+
+	purple_trie_remove(priv->trie, purple_smiley_get_shortcut(smiley));
+	_list_remove_link2(&priv->smileys, &priv->smileys_end, list_elem);
+
+	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);
+}
+
+
 /*******************************************************************************
  * Object stuff
  ******************************************************************************/
@@ -48,6 +147,10 @@
 purple_smiley_list_init(GTypeInstance *instance, gpointer klass)
 {
 	PurpleSmileyList *sl = PURPLE_SMILEY_LIST(instance);
+	PurpleSmileyListPrivate *priv = PURPLE_SMILEY_LIST_GET_PRIVATE(sl);
+
+	priv->trie = purple_trie_new();
+
 	PURPLE_DBUS_REGISTER_POINTER(sl, PurpleSmileyList);
 }
 
@@ -56,8 +159,17 @@
 {
 	PurpleSmileyList *sl = PURPLE_SMILEY_LIST(obj);
 	PurpleSmileyListPrivate *priv = PURPLE_SMILEY_LIST_GET_PRIVATE(sl);
+	GList *it;
 
-	(void)priv;
+	g_object_unref(priv->trie);
+
+	for (it = priv->smileys; it; it = g_list_next(it)) {
+		PurpleSmiley *smiley = it->data;
+		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);
+	}
+	g_list_free(priv->smileys);
 
 	PURPLE_DBUS_UNREGISTER_POINTER(sl);
 }
--- a/libpurple/smiley-list.h	Sat Mar 29 17:25:19 2014 +0100
+++ b/libpurple/smiley-list.h	Sat Mar 29 18:14:02 2014 +0100
@@ -24,6 +24,8 @@
 
 #include <glib-object.h>
 
+#include "smiley.h"
+
 typedef struct _PurpleSmileyList PurpleSmileyList;
 typedef struct _PurpleSmileyListClass PurpleSmileyListClass;
 
@@ -66,6 +68,12 @@
 GType
 purple_smiley_list_get_type(void);
 
+gboolean
+purple_smiley_list_add(PurpleSmileyList *list, PurpleSmiley *smiley);
+
+void
+purple_smiley_list_remove(PurpleSmileyList *list, PurpleSmiley *smiley);
+
 G_END_DECLS
 
 #endif /* _PURPLE_SMILEY_H_ */

mercurial