--- a/libpurple/protocols/jabber/chat.c Sat Apr 30 02:31:54 2022 -0500
+++ b/libpurple/protocols/jabber/chat.c Mon May 02 21:57:35 2022 -0500
@@ -802,11 +802,11 @@
name = purple_xmlnode_get_attrib(item, "name");
- room = purple_roomlist_room_new(PURPLE_ROOMLIST_ROOMTYPE_ROOM, jid->node, NULL);
- purple_roomlist_room_add_field(js->roomlist, room, jid->node);
- purple_roomlist_room_add_field(js->roomlist, room, jid->domain);
- purple_roomlist_room_add_field(js->roomlist, room, name ? name : "");
+ room = purple_roomlist_room_new(jid->node, name); + purple_roomlist_room_add_field(room, "room", g_strdup(jid->node)); + purple_roomlist_room_add_field(room, "server", g_strdup(jid->domain)); purple_roomlist_room_add(js->roomlist, room);
@@ -854,26 +854,12 @@
JabberStream *js = purple_connection_get_protocol_data(gc);
- PurpleRoomlistField *f;
g_object_unref(js->roomlist);
js->roomlist = purple_roomlist_new(purple_connection_get_account(js->gc));
- f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, "", "room", TRUE);
- fields = g_list_append(fields, f);
- f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, "", "server", TRUE);
- fields = g_list_append(fields, f);
- f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, _("Description"), "description", FALSE);
- fields = g_list_append(fields, f);
- purple_roomlist_set_fields(js->roomlist, fields);
purple_request_input(gc, _("Enter a Conference Server"), _("Enter a Conference Server"),
_("Select a conference server to query"),
js->chat_servers ? js->chat_servers->data : NULL,
@@ -910,8 +896,12 @@
jabber_roomlist_room_serialize(PurpleProtocolRoomlist *protocol_roomlist,
PurpleRoomlistRoom *room)
- GList *fields = purple_roomlist_room_get_fields(room);
- return g_strdup_printf("%s@%s", (char*)fields->data, (char*)fields->next->data);
+ const gchar *room_name = NULL, *server = NULL; + room_name = purple_roomlist_room_get_field(room, "room"); + server = purple_roomlist_room_get_field(room, "server"); + return g_strdup_printf("%s@%s", room_name, server); void jabber_chat_member_free(JabberChatMember *jcm)
--- a/libpurple/protocols/null/nullprpl.c Sat Apr 30 02:31:54 2022 -0500
+++ b/libpurple/protocols/null/nullprpl.c Mon May 02 21:57:35 2022 -0500
@@ -1081,23 +1081,11 @@
const char *username = purple_account_get_username(purple_connection_get_account(gc));
PurpleConversationManager *manager;
PurpleRoomlist *roomlist = purple_roomlist_new(purple_connection_get_account(gc));
- PurpleRoomlistField *field;
purple_debug_info("nullprpl", "%s asks for room list; returning:\n", username);
- /* set up the room list */
- field = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, "room",
- "room", TRUE /* hidden */);
- fields = g_list_append(fields, field);
- field = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_INT, "Id", "Id", FALSE);
- fields = g_list_append(fields, field);
- purple_roomlist_set_fields(roomlist, fields);
manager = purple_conversation_manager_get_default();
/* add each chat room. the chat ids are cached in seen_ids so that each room
@@ -1126,10 +1114,10 @@
seen_ids = g_list_prepend(seen_ids, (char *)name); /* no, it's new. */
purple_debug_info("nullprpl", "%s (%d), ", name, id);
- room = purple_roomlist_room_new(PURPLE_ROOMLIST_ROOMTYPE_ROOM, name, NULL);
- purple_roomlist_room_add_field(roomlist, room, name);
- purple_roomlist_room_add_field(roomlist, room, &id);
+ room = purple_roomlist_room_new(name, NULL); + purple_roomlist_room_add_field(room, "room", g_strdup(name)); purple_roomlist_room_add(roomlist, room);
--- a/libpurple/roomlist.c Sat Apr 30 02:31:54 2022 -0500
+++ b/libpurple/roomlist.c Mon May 02 21:57:35 2022 -0500
@@ -36,38 +36,15 @@
PurpleAccount *account; /* The account this list belongs to. */
- GList *fields; /* The fields. */
GList *rooms; /* The list of rooms. */
gboolean in_progress; /* The listing is in progress. */
-struct _PurpleRoomlistRoom {
- PurpleRoomlistRoomType type; /* The type of room. */
- gchar *name; /* The name of the room. */
- GList *fields; /* Other fields. */
- PurpleRoomlistRoom *parent; /* The parent room, or NULL. */
- gboolean expanded_once; /* A flag the UI uses to avoid multiple expand protocol cbs. */
- * A field a room might have.
-struct _PurpleRoomlistField {
- PurpleRoomlistFieldType type; /* The type of field. */
- gchar *label; /* The i18n user displayed name of the field. */
- gchar *name; /* The internal name of the field. */
- gboolean hidden; /* Hidden? */
/* Room list property enums */
@@ -77,10 +54,6 @@
G_DEFINE_TYPE_WITH_PRIVATE(PurpleRoomlist, purple_roomlist, G_TYPE_OBJECT);
-static void purple_roomlist_room_free(PurpleRoomlistRoom *r);
-static void purple_roomlist_field_free(PurpleRoomlistField *f);
-static void purple_roomlist_room_destroy(PurpleRoomlist *list, PurpleRoomlistRoom *r);
/**************************************************************************/
/**************************************************************************/
@@ -101,21 +74,6 @@
-void purple_roomlist_set_fields(PurpleRoomlist *list, GList *fields)
- PurpleRoomlistPrivate *priv = NULL;
- g_return_if_fail(PURPLE_IS_ROOMLIST(list));
- priv = purple_roomlist_get_instance_private(list);
- if (ops && ops->set_fields)
- ops->set_fields(list, fields);
- g_object_notify_by_pspec(G_OBJECT(list), properties[PROP_FIELDS]);
void purple_roomlist_set_in_progress(PurpleRoomlist *list, gboolean in_progress)
PurpleRoomlistPrivate *priv = NULL;
@@ -190,39 +148,40 @@
-void purple_roomlist_expand_category(PurpleRoomlist *list, PurpleRoomlistRoom *category)
+purple_roomlist_join_room(PurpleRoomlist *roomlist, PurpleRoomlistRoom *room) { PurpleRoomlistPrivate *priv = NULL;
- PurpleProtocol *protocol = NULL;
+ PurpleConnection *connection = NULL; + GHashTable *components = NULL, *adjusted = NULL; + const gchar *name = NULL; - g_return_if_fail(PURPLE_IS_ROOMLIST(list));
- g_return_if_fail(category != NULL);
- g_return_if_fail(category->type & PURPLE_ROOMLIST_ROOMTYPE_CATEGORY);
- priv = purple_roomlist_get_instance_private(list);
+ g_return_if_fail(PURPLE_IS_ROOMLIST(roomlist)); + g_return_if_fail(PURPLE_IS_ROOMLIST_ROOM(room)); - gc = purple_account_get_connection(priv->account);
- g_return_if_fail(PURPLE_IS_CONNECTION(gc));
+ priv = purple_roomlist_get_instance_private(roomlist);
- protocol = purple_connection_get_protocol(gc);
+ connection = purple_account_get_connection(priv->account); + if(connection == NULL) { - if(PURPLE_IS_PROTOCOL_ROOMLIST(protocol)) {
- purple_protocol_roomlist_expand_category(PURPLE_PROTOCOL_ROOMLIST(protocol),
+ components = purple_roomlist_room_get_components(room); -GList * purple_roomlist_get_fields(PurpleRoomlist *list)
- PurpleRoomlistPrivate *priv = NULL;
+ /* Make a copy of the components as we make sure the name is included. */ + adjusted = g_hash_table_new(g_str_hash, g_str_equal); + g_hash_table_iter_init(&iter, components); + while(g_hash_table_iter_next(&iter, &key, &value)) { + g_hash_table_insert(adjusted, key, value); - g_return_val_if_fail(PURPLE_IS_ROOMLIST(list), NULL);
+ name = purple_roomlist_room_get_name(room); + g_hash_table_replace(adjusted, "name", (gpointer)name); - priv = purple_roomlist_get_instance_private(list);
+ purple_serv_join_chat(connection, adjusted); + g_hash_table_destroy(adjusted); /**************************************************************************/
@@ -242,9 +201,6 @@
priv->account = g_value_get_object(value);
- purple_roomlist_set_fields(list, g_value_get_pointer(value));
purple_roomlist_set_in_progress(list, g_value_get_boolean(value));
@@ -265,9 +221,6 @@
g_value_set_object(value, purple_roomlist_get_account(list));
- g_value_set_pointer(value, purple_roomlist_get_fields(list));
g_value_set_boolean(value, purple_roomlist_get_in_progress(list));
@@ -301,17 +254,10 @@
PurpleRoomlist *list = PURPLE_ROOMLIST(object);
PurpleRoomlistPrivate *priv =
purple_roomlist_get_instance_private(list);
purple_debug_misc("roomlist", "destroying list %p\n", list);
- for (l = priv->rooms; l; l = l->next) {
- PurpleRoomlistRoom *r = l->data;
- purple_roomlist_room_destroy(list, r);
- g_list_free(priv->rooms);
- g_list_free_full(priv->fields, (GDestroyNotify)purple_roomlist_field_free);
+ g_list_free_full(priv->rooms, g_object_unref); G_OBJECT_CLASS(purple_roomlist_parent_class)->finalize(object);
@@ -335,10 +281,6 @@
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
- properties[PROP_FIELDS] = g_param_spec_pointer("fields", "Fields",
- "The list of fields for a roomlist.",
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
properties[PROP_IN_PROGRESS] = g_param_spec_boolean("in-progress",
"Whether the room list is being fetched.", FALSE,
@@ -356,244 +298,6 @@
/**************************************************************************/
-/**************************************************************************/
-PurpleRoomlistRoom *purple_roomlist_room_new(PurpleRoomlistRoomType type, const gchar *name,
- PurpleRoomlistRoom *parent)
- PurpleRoomlistRoom *room;
- g_return_val_if_fail(name != NULL, NULL);
- room = g_new0(PurpleRoomlistRoom, 1);
- room->name = g_strdup(name);
-void purple_roomlist_room_add_field(PurpleRoomlist *list, PurpleRoomlistRoom *room, gconstpointer field)
- PurpleRoomlistPrivate *priv = NULL;
- PurpleRoomlistField *f;
- g_return_if_fail(PURPLE_IS_ROOMLIST(list));
- g_return_if_fail(room != NULL);
- priv = purple_roomlist_get_instance_private(list);
- g_return_if_fail(priv->fields != NULL);
- /* If this is the first call for this room, grab the first field in
- * the Roomlist's fields. Otherwise, grab the field that is one
- * more than the number of fields already present for the room.
- * (This works because g_list_nth_data() is zero-indexed and
- * g_list_length() is one-indexed.) */
- f = priv->fields->data;
- f = g_list_nth_data(priv->fields, g_list_length(room->fields));
- g_return_if_fail(f != NULL);
- case PURPLE_ROOMLIST_FIELD_STRING:
- room->fields = g_list_append(room->fields, g_strdup(field));
- case PURPLE_ROOMLIST_FIELD_BOOL:
- case PURPLE_ROOMLIST_FIELD_INT:
- room->fields = g_list_append(room->fields, GINT_TO_POINTER(field));
- g_object_notify_by_pspec(G_OBJECT(list), properties[PROP_FIELDS]);
-void purple_roomlist_room_join(PurpleRoomlist *list, PurpleRoomlistRoom *room)
- PurpleRoomlistPrivate *priv = NULL;
- GHashTable *components;
- g_return_if_fail(PURPLE_IS_ROOMLIST(list));
- g_return_if_fail(room != NULL);
- priv = purple_roomlist_get_instance_private(list);
- gc = purple_account_get_connection(priv->account);
- components = g_hash_table_new(g_str_hash, g_str_equal);
- g_hash_table_replace(components, "name", room->name);
- for (l = priv->fields, j = room->fields; l && j; l = l->next, j = j->next) {
- PurpleRoomlistField *f = l->data;
- g_hash_table_replace(components, f->name, j->data);
- purple_serv_join_chat(gc, components);
- g_hash_table_destroy(components);
-PurpleRoomlistRoomType purple_roomlist_room_get_room_type(PurpleRoomlistRoom *room)
-const char * purple_roomlist_room_get_name(PurpleRoomlistRoom *room)
-PurpleRoomlistRoom * purple_roomlist_room_get_parent(PurpleRoomlistRoom *room)
-gboolean purple_roomlist_room_get_expanded_once(PurpleRoomlistRoom *room)
- g_return_val_if_fail(room != NULL, FALSE);
- return room->expanded_once;
-void purple_roomlist_room_set_expanded_once(PurpleRoomlistRoom *room, gboolean expanded_once)
- g_return_if_fail(room != NULL);
- room->expanded_once = expanded_once;
-GList *purple_roomlist_room_get_fields(PurpleRoomlistRoom *room)
-static void purple_roomlist_room_destroy(PurpleRoomlist *list, PurpleRoomlistRoom *r)
- PurpleRoomlistPrivate *priv =
- purple_roomlist_get_instance_private(list);
- for (l = priv->fields, j = r->fields; l && j; l = l->next, j = j->next) {
- PurpleRoomlistField *f = l->data;
- if (f->type == PURPLE_ROOMLIST_FIELD_STRING)
- purple_roomlist_room_free(r);
-/**************************************************************************/
-/**************************************************************************/
-static PurpleRoomlistRoom *purple_roomlist_room_copy(PurpleRoomlistRoom *r)
- g_return_val_if_fail(r != NULL, NULL);
- return purple_roomlist_room_new(r->type, r->name, r->parent);
-static void purple_roomlist_room_free(PurpleRoomlistRoom *r)
- g_return_if_fail(r != NULL);
- g_list_free(r->fields);
-GType purple_roomlist_room_get_type(void)
- type = g_boxed_type_register_static("PurpleRoomlistRoom",
- (GBoxedCopyFunc)purple_roomlist_room_copy,
- (GBoxedFreeFunc)purple_roomlist_room_free);
-/**************************************************************************/
-/**************************************************************************/
-PurpleRoomlistField *purple_roomlist_field_new(PurpleRoomlistFieldType type,
- const gchar *label, const gchar *name,
- PurpleRoomlistField *f;
- g_return_val_if_fail(label != NULL, NULL);
- g_return_val_if_fail(name != NULL, NULL);
- f = g_new0(PurpleRoomlistField, 1);
- f->label = g_strdup(label);
- f->name = g_strdup(name);
-PurpleRoomlistFieldType purple_roomlist_field_get_field_type(PurpleRoomlistField *field)
-const char * purple_roomlist_field_get_label(PurpleRoomlistField *field)
-gboolean purple_roomlist_field_get_hidden(PurpleRoomlistField *field)
-/**************************************************************************/
-/* Room Field GBoxed code */
-/**************************************************************************/
-static PurpleRoomlistField *purple_roomlist_field_copy(PurpleRoomlistField *f)
- g_return_val_if_fail(f != NULL, NULL);
- return purple_roomlist_field_new(f->type, f->label, f->name, f->hidden);
-static void purple_roomlist_field_free(PurpleRoomlistField *f)
- g_return_if_fail(f != NULL);
-GType purple_roomlist_field_get_type(void)
- type = g_boxed_type_register_static("PurpleRoomlistField",
- (GBoxedCopyFunc)purple_roomlist_field_copy,
- (GBoxedFreeFunc)purple_roomlist_field_free);
-/**************************************************************************/
/* UI Registration Functions */
/**************************************************************************/
--- a/pidgin/gtkroomlist.c Sat Apr 30 02:31:54 2022 -0500
+++ b/pidgin/gtkroomlist.c Mon May 02 21:57:35 2022 -0500
@@ -41,7 +41,7 @@
GtkWidget *account_widget;
@@ -61,17 +61,35 @@
PidginRoomlistDialog *dialog;
- GHashTable *cats; /* Meow. */
- gint num_rooms, total_rooms;
+_search_func(GtkTreeModel *model, gint column, const gchar *key, + GtkTreeIter *iter, gpointer search_data) + gchar *name, *fold, *fkey; + gtk_tree_model_get(model, iter, column, &name, -1); + fold = g_utf8_casefold(name, -1); + fkey = g_utf8_casefold(key, -1); + result = (g_strstr_len(fold, strlen(fold), fkey) == NULL); static gint delete_win_cb(GtkWidget *w, GdkEventAny *e, gpointer d)
PidginRoomlistDialog *dialog = PIDGIN_ROOMLIST_DIALOG(w);
@@ -114,10 +132,8 @@
rl = g_object_get_data(G_OBJECT(dialog->roomlist),
PIDGIN_ROOMLIST_UI_DATA);
- gtk_widget_destroy(rl->tree);
+ g_clear_object(&rl->model); g_object_unref(dialog->roomlist);
@@ -136,7 +152,7 @@
rl = g_object_get_data(G_OBJECT(dialog->roomlist),
PIDGIN_ROOMLIST_UI_DATA);
- gtk_widget_destroy(rl->tree);
+ g_clear_object(&rl->model); g_object_unref(dialog->roomlist);
@@ -151,7 +167,8 @@
gtk_widget_set_sensitive(dialog->account_widget, FALSE);
- gtk_container_add(GTK_CONTAINER(dialog->sw), rl->tree);
+ gtk_tree_view_set_model(GTK_TREE_VIEW(dialog->tree), + GTK_TREE_MODEL(rl->model)); /* some protocols (not bundled with libpurple) finish getting their
* room list immediately */
@@ -184,22 +201,21 @@
-selection_changed_cb(GtkTreeSelection *selection, PidginRoomlist *grl) {
+selection_changed_cb(GtkTreeSelection *selection, + PidginRoomlistDialog *dialog)
PurpleRoomlistRoom *room;
static struct _menu_cb_info *info;
- PidginRoomlistDialog *dialog = grl->dialog;
+ PidginRoomlist *grl = NULL; + grl = g_object_get_data(G_OBJECT(dialog->roomlist), + PIDGIN_ROOMLIST_UI_DATA); if (gtk_tree_selection_get_selected(selection, NULL, &iter)) {
- gtk_tree_model_get_value(GTK_TREE_MODEL(grl->model), &iter, ROOM_COLUMN, &val);
- room = g_value_get_pointer(&val);
- if (!room || !(purple_roomlist_room_get_room_type(room) & PURPLE_ROOMLIST_ROOMTYPE_ROOM)) {
- gtk_widget_set_sensitive(dialog->join_button, FALSE);
- gtk_widget_set_sensitive(dialog->add_button, FALSE);
+ gtk_tree_model_get(GTK_TREE_MODEL(grl->model), &iter, info = g_new0(struct _menu_cb_info, 1);
info->list = dialog->roomlist;
@@ -211,6 +227,8 @@
gtk_widget_set_sensitive(dialog->add_button, TRUE);
gtk_widget_set_sensitive(dialog->join_button, TRUE);
gtk_widget_set_sensitive(dialog->add_button, FALSE);
gtk_widget_set_sensitive(dialog->join_button, FALSE);
@@ -252,50 +270,45 @@
-do_join_cb(G_GNUC_UNUSED GtkWidget *w, struct _menu_cb_info *info)
- purple_roomlist_room_join(info->list, info->room);
+do_join_cb(G_GNUC_UNUSED GtkWidget *w, struct _menu_cb_info *info) { + purple_roomlist_join_room(info->list, info->room); -join_button_cb(GtkButton *button, G_GNUC_UNUSED gpointer data)
+join_button_cb(GtkButton *button, G_GNUC_UNUSED gpointer data) { struct _menu_cb_info *info = g_object_get_data(G_OBJECT(button), "room-info");
- do_join_cb(NULL, info);
+ purple_roomlist_join_room(info->list, info->room); -static void row_activated_cb(GtkTreeView *tv, GtkTreePath *path, GtkTreeViewColumn *arg2,
+row_activated_cb(GtkTreeView *tv, GtkTreePath *path, GtkTreeViewColumn *arg2, + PidginRoomlistDialog *dialog = data; PidginRoomlist *grl = NULL;
PurpleRoomlistRoom *room;
struct _menu_cb_info info;
- grl = g_object_get_data(G_OBJECT(list), PIDGIN_ROOMLIST_UI_DATA);
+ grl = g_object_get_data(G_OBJECT(dialog->roomlist), PIDGIN_ROOMLIST_UI_DATA); gtk_tree_model_get_iter(GTK_TREE_MODEL(grl->model), &iter, path);
- gtk_tree_model_get_value(GTK_TREE_MODEL(grl->model), &iter, ROOM_COLUMN, &val);
- room = g_value_get_pointer(&val);
- if (!room || !(purple_roomlist_room_get_room_type(room) & PURPLE_ROOMLIST_ROOMTYPE_ROOM))
+ gtk_tree_model_get(GTK_TREE_MODEL(grl->model), &iter, ROOM_COLUMN, &room, -1);
+ info.list = dialog->roomlist; -static gboolean room_click_cb(GtkWidget *tv, GdkEventButton *event, PurpleRoomlist *list)
+room_click_cb(GtkWidget *tv, GdkEventButton *event, gpointer data) { + PidginRoomlistDialog *dialog = data; PidginRoomlist *grl = NULL;
PurpleRoomlistRoom *room;
@@ -305,22 +318,22 @@
if (!gdk_event_triggers_context_menu((GdkEvent *)event))
- grl = g_object_get_data(G_OBJECT(list), PIDGIN_ROOMLIST_UI_DATA);
+ grl = g_object_get_data(G_OBJECT(dialog->roomlist), PIDGIN_ROOMLIST_UI_DATA); /* Here we figure out which room was clicked */
if (!gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(tv), event->x, event->y, &path, NULL, NULL, NULL))
gtk_tree_model_get_iter(GTK_TREE_MODEL(grl->model), &iter, path);
gtk_tree_path_free(path);
- gtk_tree_model_get_value (GTK_TREE_MODEL(grl->model), &iter, ROOM_COLUMN, &val);
- room = g_value_get_pointer(&val);
+ gtk_tree_model_get(GTK_TREE_MODEL(grl->model), &iter, ROOM_COLUMN, &room, -1); + info.list = dialog->roomlist; - if (!room || !(purple_roomlist_room_get_room_type(room) & PURPLE_ROOMLIST_ROOMTYPE_ROOM))
+ /* The current implementation isn't expecting a ref to unref the one we got + * when we pulled the room out of the model. @@ -340,22 +353,6 @@
-static void row_expanded_cb(GtkTreeView *treeview, GtkTreeIter *arg1, GtkTreePath *arg2, gpointer user_data)
- PurpleRoomlist *list = user_data;
- PurpleRoomlistRoom *category;
- gtk_tree_model_get_value(gtk_tree_view_get_model(treeview), arg1, ROOM_COLUMN, &val);
- category = g_value_get_pointer(&val);
- if (!purple_roomlist_room_get_expanded_once(category)) {
- purple_roomlist_expand_category(list, category);
- purple_roomlist_room_set_expanded_once(category, TRUE);
@@ -363,19 +360,14 @@
gboolean keyboard_mode, GtkTooltip *tooltip,
- PurpleRoomlist *list = data;
+ PidginRoomlistDialog *dialog = data; PidginRoomlist *grl = NULL;
GtkTreePath *path = NULL;
- PurpleRoomlistRoom *room;
GString *tooltip_text = NULL;
- grl = g_object_get_data(G_OBJECT(list), PIDGIN_ROOMLIST_UI_DATA);
+ grl = g_object_get_data(G_OBJECT(dialog->roomlist), PIDGIN_ROOMLIST_UI_DATA); GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget));
@@ -400,18 +392,6 @@
- gtk_tree_model_get_value(GTK_TREE_MODEL(grl->model), &iter, ROOM_COLUMN,
- room = g_value_get_pointer(&val);
- !(purple_roomlist_room_get_room_type(room) & PURPLE_ROOMLIST_ROOMTYPE_ROOM))
- gtk_tree_path_free(path);
tooltip_text = g_string_new("");
gtk_tree_model_get(GTK_TREE_MODEL(grl->model), &iter, NAME_COLUMN, &name, -1);
@@ -421,41 +401,6 @@
tooltip_text, "<span size='x-large' weight='bold'>%s</span>\n", tmp);
- for (j = NUM_OF_COLUMNS,
- l = purple_roomlist_room_get_fields(room),
- k = purple_roomlist_get_fields(list);
- j++, l = l->next, k = k->next)
- PurpleRoomlistField *f = k->data;
- if (purple_roomlist_field_get_hidden(f)) {
- label = g_markup_escape_text(purple_roomlist_field_get_label(f), -1);
- switch (purple_roomlist_field_get_field_type(f)) {
- case PURPLE_ROOMLIST_FIELD_BOOL:
- g_string_append_printf(
- tooltip_text, "%s<b>%s:</b> %s", first ? "" : "\n", label,
- l->data ? "True" : "False");
- case PURPLE_ROOMLIST_FIELD_INT:
- g_string_append_printf(
- tooltip_text, "%s<b>%s:</b> %d", first ? "" : "\n", label,
- GPOINTER_TO_INT(l->data));
- case PURPLE_ROOMLIST_FIELD_STRING:
- tmp = g_markup_escape_text((char *)l->data, -1);
- g_string_append_printf(
- tooltip_text, "%s<b>%s:</b> %s", first ? "" : "\n", label,
gtk_tooltip_set_markup(tooltip, tooltip_text->str);
gtk_tree_view_set_tooltip_row(GTK_TREE_VIEW(widget), tooltip, path);
g_string_free(tooltip_text, TRUE);
@@ -502,6 +447,8 @@
gtk_widget_class_bind_template_child(widget_class, PidginRoomlistDialog,
gtk_widget_class_bind_template_child(widget_class, PidginRoomlistDialog,
+ gtk_widget_class_bind_template_child(widget_class, PidginRoomlistDialog, gtk_widget_class_bind_template_child(widget_class, PidginRoomlistDialog,
@@ -513,14 +460,18 @@
gtk_widget_class_bind_template_child(widget_class, PidginRoomlistDialog,
- gtk_widget_class_bind_template_child(widget_class, PidginRoomlistDialog,
gtk_widget_class_bind_template_callback(widget_class,
gtk_widget_class_bind_template_callback(widget_class, delete_win_cb);
+ gtk_widget_class_bind_template_callback(widget_class, row_activated_cb); + gtk_widget_class_bind_template_callback(widget_class, room_click_cb); gtk_widget_class_bind_template_callback(widget_class,
dialog_select_account_cb);
+ gtk_widget_class_bind_template_callback(widget_class, + gtk_widget_class_bind_template_callback(widget_class, + pidgin_roomlist_query_tooltip); gtk_widget_class_bind_template_callback(widget_class, join_button_cb);
gtk_widget_class_bind_template_callback(widget_class, list_button_cb);
gtk_widget_class_bind_template_callback(widget_class, stop_button_cb);
@@ -534,6 +485,9 @@
pidgin_account_chooser_set_filter_func(
PIDGIN_ACCOUNT_CHOOSER(self->account_widget),
+ gtk_tree_view_set_search_equal_func(GTK_TREE_VIEW(self->tree), + _search_func, NULL, NULL); static PidginRoomlistDialog *
@@ -576,161 +530,6 @@
pidgin_roomlist_dialog_new_with_account(NULL);
-static void int_cell_data_func(GtkTreeViewColumn *col, GtkCellRenderer *renderer,
- GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
- gtk_tree_model_get(model, iter, GPOINTER_TO_INT(user_data), &myint, -1);
- g_snprintf(buf, sizeof(buf), "%d", myint);
- g_object_set(renderer, "text", buf, NULL);
-/* this sorts backwards on purpose, so that clicking name sorts a-z, while clicking users sorts
- infinity-0. you can still click again to reverse it on any of them. */
-static gint int_sort_func(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data)
- gtk_tree_model_get(model, a, GPOINTER_TO_INT(user_data), &c, -1);
- gtk_tree_model_get(model, b, GPOINTER_TO_INT(user_data), &d, -1);
-_search_func(GtkTreeModel *model, gint column, const gchar *key, GtkTreeIter *iter, gpointer search_data)
- gchar *name, *fold, *fkey;
- gtk_tree_model_get(model, iter, column, &name, -1);
- fold = g_utf8_casefold(name, -1);
- fkey = g_utf8_casefold(key, -1);
- result = (g_strstr_len(fold, strlen(fold), fkey) == NULL);
-static void pidgin_roomlist_set_fields(PurpleRoomlist *list, GList *fields)
- PidginRoomlist *grl = NULL;
- gint columns = NUM_OF_COLUMNS;
- GtkCellRenderer *renderer;
- GtkTreeViewColumn *column;
- GtkTreeSelection *selection;
- grl = g_object_get_data(G_OBJECT(list), PIDGIN_ROOMLIST_UI_DATA);
- g_return_if_fail(grl != NULL);
- columns += g_list_length(fields);
- types = g_new(GType, columns);
- types[NAME_COLUMN] = G_TYPE_STRING;
- types[ROOM_COLUMN] = G_TYPE_POINTER;
- for (j = NUM_OF_COLUMNS, l = fields; l; l = l->next, j++) {
- PurpleRoomlistField *f = l->data;
- switch (purple_roomlist_field_get_field_type(f)) {
- case PURPLE_ROOMLIST_FIELD_BOOL:
- types[j] = G_TYPE_BOOLEAN;
- case PURPLE_ROOMLIST_FIELD_INT:
- case PURPLE_ROOMLIST_FIELD_STRING:
- types[j] = G_TYPE_STRING;
- model = gtk_tree_store_newv(columns, types);
- tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(model));
- selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree));
- g_signal_connect(G_OBJECT(selection), "changed",
- G_CALLBACK(selection_changed_cb), grl);
- gtk_widget_show(grl->tree);
- renderer = gtk_cell_renderer_text_new();
- column = gtk_tree_view_column_new_with_attributes(_("Name"), renderer,
- "text", NAME_COLUMN, NULL);
- gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN(column),
- GTK_TREE_VIEW_COLUMN_GROW_ONLY);
- gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(column), TRUE);
- gtk_tree_view_column_set_sort_column_id(GTK_TREE_VIEW_COLUMN(column), NAME_COLUMN);
- gtk_tree_view_column_set_reorderable(GTK_TREE_VIEW_COLUMN(column), TRUE);
- gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column);
- for (j = NUM_OF_COLUMNS, l = fields; l; l = l->next, j++) {
- PurpleRoomlistField *f = l->data;
- if (purple_roomlist_field_get_hidden(f))
- renderer = gtk_cell_renderer_text_new();
- column = gtk_tree_view_column_new_with_attributes(
- purple_roomlist_field_get_label(f), renderer,
- gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN(column),
- GTK_TREE_VIEW_COLUMN_GROW_ONLY);
- gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(column), TRUE);
- gtk_tree_view_column_set_sort_column_id(GTK_TREE_VIEW_COLUMN(column), j);
- gtk_tree_view_column_set_reorderable(GTK_TREE_VIEW_COLUMN(column), TRUE);
- if (purple_roomlist_field_get_field_type(f) == PURPLE_ROOMLIST_FIELD_INT) {
- gtk_tree_view_column_set_cell_data_func(column, renderer, int_cell_data_func,
- GINT_TO_POINTER(j), NULL);
- gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(model), j, int_sort_func,
- GINT_TO_POINTER(j), NULL);
- gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column);
- g_signal_connect(G_OBJECT(tree), "button-press-event", G_CALLBACK(room_click_cb), list);
- g_signal_connect(G_OBJECT(tree), "row-expanded", G_CALLBACK(row_expanded_cb), list);
- g_signal_connect(G_OBJECT(tree), "row-activated", G_CALLBACK(row_activated_cb), list);
- gtk_widget_set_has_tooltip(tree, TRUE);
- g_signal_connect(G_OBJECT(tree), "query-tooltip",
- G_CALLBACK(pidgin_roomlist_query_tooltip), list);
- /* Enable CTRL+F searching */
- gtk_tree_view_set_search_column(GTK_TREE_VIEW(tree), NAME_COLUMN);
- gtk_tree_view_set_search_equal_func(GTK_TREE_VIEW(tree), _search_func, NULL, NULL);
static gboolean pidgin_progress_bar_pulse(gpointer data)
PurpleRoomlist *list = data;
@@ -749,22 +548,14 @@
-static void pidgin_roomlist_add_room(PurpleRoomlist *list, PurpleRoomlistRoom *room)
+pidgin_roomlist_add_room(PurpleRoomlist *list, PurpleRoomlistRoom *room) { PidginRoomlist *rl = NULL;
- GtkTreeRowReference *rr, *parentrr = NULL;
- GtkTreeIter iter, parent, child;
- gboolean append = TRUE;
rl = g_object_get_data(G_OBJECT(list), PIDGIN_ROOMLIST_UI_DATA);
- if (purple_roomlist_room_get_room_type(room) == PURPLE_ROOMLIST_ROOMTYPE_ROOM)
if (rl->dialog->pg_update_to == 0) {
@@ -774,53 +565,18 @@
rl->dialog->pg_needs_pulse = TRUE;
- if (purple_roomlist_room_get_parent(room)) {
- parentrr = g_hash_table_lookup(rl->cats, purple_roomlist_room_get_parent(room));
- path = gtk_tree_row_reference_get_path(parentrr);
- PurpleRoomlistRoom *tmproom = NULL;
- gtk_tree_model_get_iter(GTK_TREE_MODEL(rl->model), &parent, path);
- gtk_tree_path_free(path);
- if (gtk_tree_model_iter_children(GTK_TREE_MODEL(rl->model), &child, &parent)) {
- gtk_tree_model_get(GTK_TREE_MODEL(rl->model), &child, ROOM_COLUMN, &tmproom, -1);
- gtk_tree_store_append(rl->model, &iter, (parentrr ? &parent : NULL));
- if (purple_roomlist_room_get_room_type(room) & PURPLE_ROOMLIST_ROOMTYPE_CATEGORY)
- gtk_tree_store_append(rl->model, &child, &iter);
+ gtk_tree_store_append(rl->model, &iter, NULL); path = gtk_tree_model_get_path(GTK_TREE_MODEL(rl->model), &iter);
- if (purple_roomlist_room_get_room_type(room) & PURPLE_ROOMLIST_ROOMTYPE_CATEGORY) {
- rr = gtk_tree_row_reference_new(GTK_TREE_MODEL(rl->model), path);
- g_hash_table_insert(rl->cats, room, rr);
gtk_tree_path_free(path);
- gtk_tree_store_set(rl->model, &iter, NAME_COLUMN, purple_roomlist_room_get_name(room), -1);
- gtk_tree_store_set(rl->model, &iter, ROOM_COLUMN, room, -1);
- for (j = NUM_OF_COLUMNS,
- l = purple_roomlist_room_get_fields(room),
- k = purple_roomlist_get_fields(list);
- l && k; j++, l = l->next, k = k->next)
- PurpleRoomlistField *f = k->data;
- if (purple_roomlist_field_get_hidden(f))
- gtk_tree_store_set(rl->model, &iter, j, l->data, -1);
+ NAME_COLUMN, purple_roomlist_room_get_name(room), + DESCRIPTION_COLUMN, purple_roomlist_room_get_description(room), @@ -850,7 +606,6 @@
pidgin_roomlist_destroy(PidginRoomlist *rl)
- g_hash_table_destroy(rl->cats);
@@ -862,8 +617,8 @@
g_object_set_data_full(G_OBJECT(list), PIDGIN_ROOMLIST_UI_DATA, rl,
(GDestroyNotify)pidgin_roomlist_destroy);
- rl->cats = g_hash_table_new_full(
- NULL, NULL, NULL, (GDestroyNotify)gtk_tree_row_reference_free);
+ rl->model = gtk_tree_store_new(3, G_TYPE_OBJECT, G_TYPE_STRING, g_signal_connect(list, "notify::in-progress",
G_CALLBACK(pidgin_roomlist_in_progress), rl);
@@ -872,7 +627,7 @@
static PurpleRoomlistUiOps ops = {
pidgin_roomlist_dialog_show_with_account,
- pidgin_roomlist_set_fields,
pidgin_roomlist_add_room,