# HG changeset patch # User Sadrul Habib Chowdhury # Date 1191390099 0 # Node ID 18cf8aa44f55f6dae377b36e58f49f7046fa94f7 # Parent 61045691aa72b5a26883400cd8e1d169e96d44b6 A request field for buddylist nodes. diff -r 61045691aa72 -r 18cf8aa44f55 libpurple/blist.h --- a/libpurple/blist.h Tue Oct 02 06:13:27 2007 +0000 +++ b/libpurple/blist.h Wed Oct 03 05:41:39 2007 +0000 @@ -41,6 +41,8 @@ typedef struct _PurpleContact PurpleContact; typedef struct _PurpleBuddy PurpleBuddy; +typedef gboolean (*PurpleFilterBlistFunc)(PurpleBlistNode *node); + /**************************************************************************/ /* Enumerations */ /**************************************************************************/ @@ -66,9 +68,12 @@ typedef enum { PURPLE_BLIST_NODE_FLAG_NO_SAVE = 1 << 0, /**< node should not be saved with the buddy list */ + PURPLE_BLIST_NODE_HAS_CONVERSATION = 1 << 1, /**< node (buddy or chat) has an open conversation */ } PurpleBlistNodeFlags; +#define PURPLE_BLIST_NODE_SET_FLAG(node, f) (((PurpleBlistNode *)node)->flags |= (f)) +#define PURPLE_BLIST_NODE_UNSET_FLAG(node, f) (((PurpleBlistNode *)node)->flags &= ~(f)) #define PURPLE_BLIST_NODE_HAS_FLAG(b, f) (((PurpleBlistNode*)(b))->flags & (f)) #define PURPLE_BLIST_NODE_SHOULD_SAVE(b) (! PURPLE_BLIST_NODE_HAS_FLAG(b, PURPLE_BLIST_NODE_FLAG_NO_SAVE)) diff -r 61045691aa72 -r 18cf8aa44f55 libpurple/request.c --- a/libpurple/request.c Tue Oct 02 06:13:27 2007 +0000 +++ b/libpurple/request.c Wed Oct 03 05:41:39 2007 +0000 @@ -377,6 +377,13 @@ g_hash_table_destroy(field->u.list.item_data); g_hash_table_destroy(field->u.list.selected_table); } + else if (field->type == PURPLE_REQUEST_FIELD_BLIST) + { + if (field->u.blist.default_nodes) + g_list_free(field->u.blist.default_nodes); + if (field->u.blist.selecteds) + g_list_free(field->u.blist.selecteds); + } g_free(field); } @@ -1133,6 +1140,85 @@ /* -- */ +PurpleRequestField *purple_request_field_blist_nodes_new(const char *id, + const char *text, PurpleRequestBlistFlags flags, GList *selected) +{ + PurpleRequestField *field; + + g_return_val_if_fail(id != NULL, NULL); + g_return_val_if_fail(text != NULL, NULL); + + field = purple_request_field_new(id, text, PURPLE_REQUEST_FIELD_BLIST); + + field->u.blist.flags = flags; + field->u.blist.default_nodes = selected; + purple_request_field_blist_set_selection_list(field, selected); + + return field; +} + +PurpleFilterBlistFunc +purple_request_field_blist_set_filter(PurpleRequestField *field, PurpleFilterBlistFunc filter) +{ + PurpleFilterBlistFunc old; + g_return_val_if_fail(field != NULL, NULL); + g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_BLIST, NULL); + old = field->u.blist.filter; + field->u.blist.filter = filter; + return old; +} + +PurpleFilterBlistFunc +purple_request_field_blist_get_filter(const PurpleRequestField *field) +{ + g_return_val_if_fail(field != NULL, NULL); + g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_BLIST, NULL); + return field->u.blist.filter; +} + +GList *purple_request_field_blist_get_selection_list(const PurpleRequestField *field) +{ + g_return_val_if_fail(field != NULL, NULL); + g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_BLIST, NULL); + return field->u.blist.selecteds; +} + +gboolean purple_request_field_blist_add(PurpleRequestField *field, PurpleBlistNode *node) +{ + g_return_val_if_fail(field != NULL, FALSE); + g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_BLIST, FALSE); + if (!g_list_find(field->u.blist.selecteds, node)) { + field->u.blist.selecteds = g_list_append(field->u.blist.selecteds, node); + return TRUE; + } else { + return FALSE; + } +} + +gboolean purple_request_field_blist_remove(PurpleRequestField *field, PurpleBlistNode *node) +{ + GList *search; + g_return_val_if_fail(field != NULL, FALSE); + g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_BLIST, FALSE); + if ((search = g_list_find(field->u.blist.selecteds, node)) != NULL) { + field->u.blist.selecteds = g_list_delete_link(field->u.blist.selecteds, search); + return TRUE; + } else { + return FALSE; + } +} + +void purple_request_field_blist_set_selection_list(PurpleRequestField *field, GList *selecteds) +{ + g_return_if_fail(field != NULL); + g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_BLIST); + if (field->u.blist.selecteds) + g_list_free(field->u.blist.selecteds); + field->u.blist.selecteds = selecteds; +} + +/* -- */ + void * purple_request_input(void *handle, const char *title, const char *primary, const char *secondary, const char *default_value, diff -r 61045691aa72 -r 18cf8aa44f55 pidgin/gtkrequest.c --- a/pidgin/gtkrequest.c Tue Oct 02 06:13:27 2007 +0000 +++ b/pidgin/gtkrequest.c Wed Oct 03 05:41:39 2007 +0000 @@ -29,6 +29,7 @@ #include "prefs.h" #include "util.h" +#include "gtkblist.h" #include "gtkimhtml.h" #include "gtkimhtmltoolbar.h" #include "gtkrequest.h" @@ -952,6 +953,92 @@ return widget; } +static GtkWidget * +create_blist_field(PurpleRequestField *field) +{ + GtkTreeStore *model; + GtkWidget *tree, *sw; + PurpleBlistNode *node; + GtkCellRenderer *rend; + GtkTreeViewColumn *column; + GtkTreeIter parent = {0, NULL, NULL, NULL}, iter; + PurpleRequestBlistFlags flags = field->u.blist.flags; + gboolean offline = !!(field->u.blist.flags & PURPLE_REQUEST_BLIST_FLAG_ALLOW_OFFLINE); + + /* Create the treeview. Populate the blistnodes. + * Hook to signed-on, signed-off signals to update the list when account goes online/offline. + * Hook to buddy-signed-on/off, -status-changed signals to update the status pixbuf. + */ + + model = gtk_tree_store_new(3, GDK_TYPE_PIXBUF, G_TYPE_STRING, GDK_TYPE_PIXBUF); + node = purple_blist_get_root(); + while (node) { + GdkPixbuf *status = NULL, *prpl = NULL; + const char *name = NULL; + if ((PURPLE_BLIST_NODE_IS_BUDDY(node) || PURPLE_BLIST_NODE_IS_CONTACT(node)) + && (flags & PURPLE_REQUEST_BLIST_FLAG_BUDDY)) { + PurpleBuddy *buddy; + GtkTreeIter *p = NULL; + if (PURPLE_BLIST_NODE_IS_BUDDY(node)) { + buddy = (PurpleBuddy*)node; + p = &parent; + } else { + buddy = purple_contact_get_priority_buddy((PurpleContact*)node); + parent = iter; + } + if (PURPLE_BUDDY_IS_ONLINE(buddy)) { + gtk_tree_store_append(model, &iter, p); + name = purple_buddy_get_name(buddy); + status = pidgin_blist_get_status_icon(node, PIDGIN_STATUS_ICON_SMALL); + } + } else if (PURPLE_BLIST_NODE_IS_CHAT(node) && (flags & PURPLE_REQUEST_BLIST_FLAG_CHAT)) { + gtk_tree_store_append(model, &iter, NULL); + name = purple_chat_get_name((PurpleChat*)node); + status = pidgin_blist_get_status_icon(node, PIDGIN_STATUS_ICON_SMALL); + } + if (name) + gtk_tree_store_set(model, &iter, + 0, status, + 1, name, + 2, prpl, + -1); + if (prpl) + gdk_pixbuf_unref(prpl); + if (status) + gdk_pixbuf_unref(status); + node = purple_blist_node_next(node, offline); + } + + tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(model)); + gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(tree), FALSE); + gtk_tree_view_set_search_column(GTK_TREE_VIEW(tree), 1); + gtk_tree_view_set_search_equal_func(GTK_TREE_VIEW(tree), pidgin_tree_view_search_equal_func, NULL, NULL); + gtk_widget_show(tree); + + column = gtk_tree_view_column_new(); + gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column); + + rend = gtk_cell_renderer_pixbuf_new(); + gtk_tree_view_column_pack_start(column, rend, FALSE); + gtk_tree_view_column_set_attributes(column, rend, "pixbuf", 0, NULL); + + rend = gtk_cell_renderer_text_new(); + gtk_tree_view_column_pack_start(column, rend, TRUE); + gtk_tree_view_column_set_attributes(column, rend, "markup", 1, NULL); + + rend = gtk_cell_renderer_pixbuf_new(); + gtk_tree_view_column_pack_start(column, rend, FALSE); + gtk_tree_view_column_set_attributes(column, rend, "pixbuf", 2, NULL); + + sw = gtk_scrolled_window_new(NULL,NULL); + gtk_widget_show(sw); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_NONE); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_container_add(GTK_CONTAINER(sw), tree); + + return sw; +} + static void select_field_list_item(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data) @@ -1328,6 +1415,8 @@ widget = create_image_field(field); else if (type == PURPLE_REQUEST_FIELD_ACCOUNT) widget = create_account_field(field); + else if (type == PURPLE_REQUEST_FIELD_BLIST) + widget = create_blist_field(field); else continue;