2 * @file gntroomlist.c GNT Room List API
8 * Finch is the legal property of its developers, whose names are too numerous
9 * to list here. Please refer to the COPYRIGHT file distributed with this
10 * source distribution.
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
30 #include "gntrequest.h"
31 #include "gntroomlist.h"
34 #include "gntbutton.h"
35 #include "gntcombobox.h"
36 #include "gnttextview.h"
38 #include "gntwindow.h"
42 #define PREF_ROOT "/finch/roomlist"
44 /* Yes, just one roomlist at a time. Let's not get greedy. Aight? */
59 PurpleAccount
*account
;
60 PurpleRoomlist
*roomlist
;
63 typedef struct _FinchRoomlist FinchRoomlist
;
66 unset_roomlist(gpointer null
)
68 froomlist
.window
= NULL
;
69 if (froomlist
.roomlist
) {
70 purple_roomlist_unref(froomlist
.roomlist
);
71 froomlist
.roomlist
= NULL
;
73 froomlist
.account
= NULL
;
74 froomlist
.tree
= NULL
;
78 update_roomlist(PurpleRoomlist
*list
)
80 if (froomlist
.roomlist
== list
)
83 if (froomlist
.roomlist
)
84 purple_roomlist_unref(froomlist
.roomlist
);
86 if ((froomlist
.roomlist
= list
) != NULL
)
87 purple_roomlist_ref(list
);
90 static void fl_stop(GntWidget
*button
, gpointer null
)
92 if (froomlist
.roomlist
&&
93 purple_roomlist_get_in_progress(froomlist
.roomlist
))
94 purple_roomlist_cancel_get_list(froomlist
.roomlist
);
97 static void fl_get_list(GntWidget
*button
, gpointer null
)
99 PurpleAccount
*account
= gnt_combo_box_get_selected_data(GNT_COMBO_BOX(froomlist
.accounts
));
100 PurpleConnection
*gc
= purple_account_get_connection(account
);
105 update_roomlist(NULL
);
106 froomlist
.roomlist
= purple_roomlist_get_list(gc
);
107 gnt_box_give_focus_to_child(GNT_BOX(froomlist
.window
), froomlist
.tree
);
110 static void fl_add_chat(GntWidget
*button
, gpointer null
)
113 PurpleRoomlistRoom
*room
= gnt_tree_get_selection_data(GNT_TREE(froomlist
.tree
));
114 PurpleConnection
*gc
= purple_account_get_connection(froomlist
.account
);
115 PurplePluginProtocolInfo
*prpl_info
= NULL
;
117 if (gc
== NULL
|| room
== NULL
)
120 prpl_info
= PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc
));
122 if(prpl_info
!= NULL
&& prpl_info
->roomlist_room_serialize
)
123 name
= prpl_info
->roomlist_room_serialize(room
);
125 name
= g_strdup(purple_roomlist_room_get_name(room
));
127 purple_blist_request_add_chat(froomlist
.account
, NULL
, NULL
, name
);
132 static void fl_close(GntWidget
*button
, gpointer null
)
134 gnt_widget_destroy(froomlist
.window
);
138 roomlist_activated(GntWidget
*widget
)
140 PurpleRoomlistRoom
*room
= gnt_tree_get_selection_data(GNT_TREE(widget
));
144 switch (purple_roomlist_room_get_type(room
)) {
145 case PURPLE_ROOMLIST_ROOMTYPE_ROOM
:
146 purple_roomlist_room_join(froomlist
.roomlist
, room
);
148 case PURPLE_ROOMLIST_ROOMTYPE_CATEGORY
:
149 if (!room
->expanded_once
) {
150 purple_roomlist_expand_category(froomlist
.roomlist
, room
);
151 room
->expanded_once
= TRUE
;
155 gnt_tree_set_expanded(GNT_TREE(widget
), room
, TRUE
);
159 roomlist_selection_changed(GntWidget
*widget
, gpointer old
, gpointer current
, gpointer null
)
162 PurpleRoomlistRoom
*room
= current
;
163 GntTextView
*tv
= GNT_TEXT_VIEW(froomlist
.details
);
164 gboolean first
= TRUE
;
166 gnt_text_view_clear(tv
);
171 for (iter
= purple_roomlist_room_get_fields(room
),
172 field
= purple_roomlist_get_fields(froomlist
.roomlist
);
174 iter
= iter
->next
, field
= field
->next
) {
175 PurpleRoomlistField
*f
= field
->data
;
178 if (purple_roomlist_field_get_hidden(f
)) {
183 gnt_text_view_append_text_with_flags(tv
, "\n", GNT_TEXT_FLAG_NORMAL
);
185 gnt_text_view_append_text_with_flags(tv
,
186 purple_roomlist_field_get_label(f
), GNT_TEXT_FLAG_BOLD
);
187 gnt_text_view_append_text_with_flags(tv
, ": ", GNT_TEXT_FLAG_BOLD
);
189 switch (purple_roomlist_field_get_type(f
)) {
190 case PURPLE_ROOMLIST_FIELD_BOOL
:
191 label
= g_strdup(iter
->data
? "True" : "False");
193 case PURPLE_ROOMLIST_FIELD_INT
:
194 label
= g_strdup_printf("%d", GPOINTER_TO_INT(iter
->data
));
196 case PURPLE_ROOMLIST_FIELD_STRING
:
197 label
= g_strdup(iter
->data
);
200 gnt_text_view_append_text_with_flags(tv
, label
, GNT_TEXT_FLAG_NORMAL
);
205 if (purple_roomlist_room_get_type(room
) == PURPLE_ROOMLIST_ROOMTYPE_CATEGORY
) {
207 gnt_text_view_append_text_with_flags(tv
, "\n", GNT_TEXT_FLAG_NORMAL
);
208 gnt_text_view_append_text_with_flags(tv
,
209 _("Hit 'Enter' to find more rooms of this category."),
210 GNT_TEXT_FLAG_NORMAL
);
215 roomlist_account_changed(GntWidget
*widget
, gpointer old
, gpointer current
, gpointer null
)
217 if (froomlist
.account
== current
) {
221 froomlist
.account
= current
;
222 if (froomlist
.roomlist
) {
223 if (purple_roomlist_get_in_progress(froomlist
.roomlist
))
224 purple_roomlist_cancel_get_list(froomlist
.roomlist
);
225 update_roomlist(NULL
);
228 gnt_tree_remove_all(GNT_TREE(froomlist
.tree
));
229 gnt_widget_draw(froomlist
.tree
);
233 reset_account_list(PurpleAccount
*account
)
236 GntComboBox
*accounts
= GNT_COMBO_BOX(froomlist
.accounts
);
237 gnt_combo_box_remove_all(accounts
);
238 for (list
= purple_connections_get_all(); list
; list
= list
->next
) {
239 PurplePluginProtocolInfo
*prpl_info
= NULL
;
240 PurpleConnection
*gc
= list
->data
;
242 prpl_info
= PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc
));
243 if (PURPLE_CONNECTION_IS_CONNECTED(gc
) &&
244 prpl_info
->roomlist_get_list
!= NULL
) {
245 PurpleAccount
*account
= purple_connection_get_account(gc
);
246 char *text
= g_strdup_printf("%s (%s)",
247 purple_account_get_username(account
),
248 purple_account_get_protocol_name(account
));
249 gnt_combo_box_add_data(accounts
, account
, text
);
256 size_changed_cb(GntWidget
*widget
, int oldw
, int oldh
)
259 gnt_widget_get_size(widget
, &w
, &h
);
260 purple_prefs_set_int(PREF_ROOT
"/size/width", w
);
261 purple_prefs_set_int(PREF_ROOT
"/size/height", h
);
265 setup_roomlist(PurpleAccount
*account
)
267 GntWidget
*window
, *tree
, *hbox
, *accounts
;
274 {_("Stop"), G_CALLBACK(fl_stop
), &froomlist
.stop
},
275 {_("Get"), G_CALLBACK(fl_get_list
), &froomlist
.getlist
},
276 {_("Add"), G_CALLBACK(fl_add_chat
), &froomlist
.add
},
277 {_("Close"), G_CALLBACK(fl_close
), &froomlist
.close
},
281 if (froomlist
.window
)
284 froomlist
.window
= window
= gnt_window_new();
285 g_object_set(G_OBJECT(window
), "vertical", TRUE
, NULL
);
286 gnt_box_set_pad(GNT_BOX(window
), 0);
287 gnt_box_set_title(GNT_BOX(window
), _("Room List"));
288 gnt_box_set_alignment(GNT_BOX(window
), GNT_ALIGN_MID
);
290 froomlist
.accounts
= accounts
= gnt_combo_box_new();
291 reset_account_list(account
);
292 gnt_box_add_widget(GNT_BOX(window
), accounts
);
293 g_signal_connect(G_OBJECT(accounts
), "selection-changed",
294 G_CALLBACK(roomlist_account_changed
), NULL
);
295 froomlist
.account
= gnt_combo_box_get_selected_data(GNT_COMBO_BOX(accounts
));
297 froomlist
.tree
= tree
= gnt_tree_new_with_columns(2);
298 gnt_tree_set_show_title(GNT_TREE(tree
), TRUE
);
299 g_signal_connect(G_OBJECT(tree
), "activate", G_CALLBACK(roomlist_activated
), NULL
);
300 gnt_tree_set_column_titles(GNT_TREE(tree
), _("Name"), "");
301 gnt_tree_set_show_separator(GNT_TREE(tree
), FALSE
);
302 gnt_tree_set_col_width(GNT_TREE(tree
), 1, 1);
303 gnt_tree_set_column_resizable(GNT_TREE(tree
), 1, FALSE
);
304 gnt_tree_set_search_column(GNT_TREE(tree
), 0);
306 gnt_box_add_widget(GNT_BOX(window
), tree
);
308 froomlist
.details
= gnt_text_view_new();
309 gnt_text_view_set_flag(GNT_TEXT_VIEW(froomlist
.details
), GNT_TEXT_VIEW_TOP_ALIGN
);
310 gnt_box_add_widget(GNT_BOX(window
), froomlist
.details
);
311 gnt_widget_set_size(froomlist
.details
, -1, 8);
313 hbox
= gnt_hbox_new(FALSE
);
314 gnt_box_add_widget(GNT_BOX(window
), hbox
);
316 for (iter
= 0; buttons
[iter
].label
; iter
++) {
317 GntWidget
*button
= gnt_button_new(buttons
[iter
].label
);
318 gnt_box_add_widget(GNT_BOX(hbox
), button
);
319 g_signal_connect(G_OBJECT(button
), "activate", buttons
[iter
].callback
, NULL
);
320 *buttons
[iter
].widget
= button
;
321 gnt_text_view_attach_scroll_widget(GNT_TEXT_VIEW(froomlist
.details
), button
);
324 g_signal_connect(G_OBJECT(tree
), "selection-changed", G_CALLBACK(roomlist_selection_changed
), NULL
);
326 g_signal_connect(G_OBJECT(window
), "destroy", G_CALLBACK(unset_roomlist
), NULL
);
330 fl_show_with_account(PurpleAccount
*account
)
332 setup_roomlist(account
);
333 g_signal_handlers_disconnect_matched(G_OBJECT(froomlist
.window
), G_SIGNAL_MATCH_FUNC
,
334 0, 0, NULL
, G_CALLBACK(size_changed_cb
), NULL
);
335 gnt_widget_show(froomlist
.window
);
336 gnt_screen_resize_widget(froomlist
.window
,
337 purple_prefs_get_int(PREF_ROOT
"/size/width"),
338 purple_prefs_get_int(PREF_ROOT
"/size/height"));
339 g_signal_connect(G_OBJECT(froomlist
.window
), "size_changed", G_CALLBACK(size_changed_cb
), NULL
);
340 gnt_window_present(froomlist
.window
);
344 fl_create(PurpleRoomlist
*list
)
346 FINCH_SET_DATA(list
, &froomlist
);
347 setup_roomlist(NULL
);
348 update_roomlist(list
);
352 fl_set_fields(PurpleRoomlist
*list
, GList
*fields
)
357 fl_add_room(PurpleRoomlist
*roomlist
, PurpleRoomlistRoom
*room
)
360 if (froomlist
.roomlist
!= roomlist
)
363 category
= (purple_roomlist_room_get_type(room
) == PURPLE_ROOMLIST_ROOMTYPE_CATEGORY
);
364 gnt_tree_remove(GNT_TREE(froomlist
.tree
), room
);
365 gnt_tree_add_row_after(GNT_TREE(froomlist
.tree
), room
,
366 gnt_tree_create_row(GNT_TREE(froomlist
.tree
),
367 purple_roomlist_room_get_name(room
),
368 category
? "<" : ""),
369 purple_roomlist_room_get_parent(room
), NULL
);
370 gnt_tree_set_expanded(GNT_TREE(froomlist
.tree
), room
, !category
);
374 fl_destroy(PurpleRoomlist
*list
)
376 if (!froomlist
.window
)
379 if (froomlist
.roomlist
== list
) {
380 froomlist
.roomlist
= NULL
;
381 gnt_tree_remove_all(GNT_TREE(froomlist
.tree
));
382 gnt_widget_draw(froomlist
.tree
);
386 static PurpleRoomlistUiOps ui_ops
=
388 fl_show_with_account
, /* void (*show_with_account)(PurpleAccount *account); **< Force the ui to pop up a dialog and get the list */
389 fl_create
, /* void (*create)(PurpleRoomlist *list); **< A new list was created. */
390 fl_set_fields
, /* void (*set_fields)(PurpleRoomlist *list, GList *fields); **< Sets the columns. */
391 fl_add_room
, /* void (*add_room)(PurpleRoomlist *list, PurpleRoomlistRoom *room); **< Add a room to the list. */
392 NULL
, /* void (*in_progress)(PurpleRoomlist *list, gboolean flag); **< Are we fetching stuff still? */
393 fl_destroy
, /* void (*destroy)(PurpleRoomlist *list); **< We're destroying list. */
395 NULL
, /* void (*_purple_reserved1)(void); */
396 NULL
, /* void (*_purple_reserved2)(void); */
397 NULL
, /* void (*_purple_reserved3)(void); */
398 NULL
/* void (*_purple_reserved4)(void); */
401 PurpleRoomlistUiOps
*finch_roomlist_get_ui_ops(void)
406 void finch_roomlist_show_all(void)
408 purple_roomlist_show_with_account(NULL
);
411 void finch_roomlist_init(void)
413 purple_prefs_add_none(PREF_ROOT
);
414 purple_prefs_add_none(PREF_ROOT
"/size");
415 purple_prefs_add_int(PREF_ROOT
"/size/width", 60);
416 purple_prefs_add_int(PREF_ROOT
"/size/height", 15);
419 void finch_roomlist_uninit(void)