3 * Finch is the legal property of its developers, whose names are too numerous
4 * to list here. Please refer to the COPYRIGHT file distributed with this
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
25 #include "gntrequest.h"
26 #include "gntroomlist.h"
29 #include "gntbutton.h"
30 #include "gntcombobox.h"
31 #include "gnttextview.h"
33 #include "gntwindow.h"
37 #define PREF_ROOT "/finch/roomlist"
40 /* Yes, just one roomlist at a time. Let's not get greedy. Aight? */
55 PurpleAccount
*account
;
56 PurpleRoomlist
*roomlist
;
59 typedef struct _FinchRoomlist FinchRoomlist
;
62 unset_roomlist(gpointer null
)
64 froomlist
.window
= NULL
;
65 if (froomlist
.roomlist
) {
66 g_object_unref(froomlist
.roomlist
);
67 froomlist
.roomlist
= NULL
;
69 froomlist
.account
= NULL
;
70 froomlist
.tree
= NULL
;
74 update_roomlist(PurpleRoomlist
*list
)
76 if (froomlist
.roomlist
== list
)
79 if (froomlist
.roomlist
)
80 g_object_unref(froomlist
.roomlist
);
82 if ((froomlist
.roomlist
= list
) != NULL
)
86 static void fl_stop(GntWidget
*button
, gpointer null
)
88 if (froomlist
.roomlist
&&
89 purple_roomlist_get_in_progress(froomlist
.roomlist
))
90 purple_roomlist_cancel_get_list(froomlist
.roomlist
);
93 static void fl_get_list(GntWidget
*button
, gpointer null
)
95 PurpleAccount
*account
= gnt_combo_box_get_selected_data(GNT_COMBO_BOX(froomlist
.accounts
));
96 PurpleConnection
*gc
= purple_account_get_connection(account
);
101 update_roomlist(NULL
);
102 froomlist
.roomlist
= purple_roomlist_get_list(gc
);
103 gnt_box_give_focus_to_child(GNT_BOX(froomlist
.window
), froomlist
.tree
);
106 static void fl_add_chat(GntWidget
*button
, gpointer null
)
109 PurpleRoomlistRoom
*room
= gnt_tree_get_selection_data(GNT_TREE(froomlist
.tree
));
110 PurpleConnection
*gc
= purple_account_get_connection(froomlist
.account
);
111 PurpleProtocol
*protocol
= NULL
;
113 if (gc
== NULL
|| room
== NULL
)
116 protocol
= purple_connection_get_protocol(gc
);
118 if(protocol
!= NULL
&& PURPLE_PROTOCOL_IMPLEMENTS(protocol
, ROOMLIST_IFACE
, room_serialize
))
119 name
= purple_protocol_roomlist_iface_room_serialize(protocol
, room
);
121 name
= g_strdup(purple_roomlist_room_get_name(room
));
123 purple_blist_request_add_chat(froomlist
.account
, NULL
, NULL
, name
);
128 static void fl_close(GntWidget
*button
, gpointer null
)
130 gnt_widget_destroy(froomlist
.window
);
134 roomlist_activated(GntWidget
*widget
)
136 PurpleRoomlistRoom
*room
= gnt_tree_get_selection_data(GNT_TREE(widget
));
140 switch (purple_roomlist_room_get_room_type(room
)) {
141 case PURPLE_ROOMLIST_ROOMTYPE_ROOM
:
142 purple_roomlist_room_join(froomlist
.roomlist
, room
);
144 case PURPLE_ROOMLIST_ROOMTYPE_CATEGORY
:
145 if (!purple_roomlist_room_get_expanded_once(room
)) {
146 purple_roomlist_expand_category(froomlist
.roomlist
, room
);
147 purple_roomlist_room_set_expanded_once(room
, TRUE
);
151 gnt_tree_set_expanded(GNT_TREE(widget
), room
, TRUE
);
155 roomlist_selection_changed(GntWidget
*widget
, gpointer old
, gpointer current
, gpointer null
)
158 PurpleRoomlistRoom
*room
= current
;
159 GntTextView
*tv
= GNT_TEXT_VIEW(froomlist
.details
);
160 gboolean first
= TRUE
;
162 gnt_text_view_clear(tv
);
167 for (iter
= purple_roomlist_room_get_fields(room
),
168 field
= purple_roomlist_get_fields(froomlist
.roomlist
);
170 iter
= iter
->next
, field
= field
->next
) {
171 PurpleRoomlistField
*f
= field
->data
;
174 if (purple_roomlist_field_get_hidden(f
)) {
179 gnt_text_view_append_text_with_flags(tv
, "\n", GNT_TEXT_FLAG_NORMAL
);
181 gnt_text_view_append_text_with_flags(tv
,
182 purple_roomlist_field_get_label(f
), GNT_TEXT_FLAG_BOLD
);
183 gnt_text_view_append_text_with_flags(tv
, ": ", GNT_TEXT_FLAG_BOLD
);
185 switch (purple_roomlist_field_get_field_type(f
)) {
186 case PURPLE_ROOMLIST_FIELD_BOOL
:
187 label
= g_strdup(iter
->data
? "True" : "False");
189 case PURPLE_ROOMLIST_FIELD_INT
:
190 label
= g_strdup_printf("%d", GPOINTER_TO_INT(iter
->data
));
192 case PURPLE_ROOMLIST_FIELD_STRING
:
193 label
= g_strdup(iter
->data
);
196 gnt_text_view_append_text_with_flags(tv
, label
, GNT_TEXT_FLAG_NORMAL
);
201 if (purple_roomlist_room_get_room_type(room
) == PURPLE_ROOMLIST_ROOMTYPE_CATEGORY
) {
203 gnt_text_view_append_text_with_flags(tv
, "\n", GNT_TEXT_FLAG_NORMAL
);
204 gnt_text_view_append_text_with_flags(tv
,
205 _("Hit 'Enter' to find more rooms of this category."),
206 GNT_TEXT_FLAG_NORMAL
);
211 roomlist_account_changed(GntWidget
*widget
, gpointer old
, gpointer current
, gpointer null
)
213 if (froomlist
.account
== current
) {
217 froomlist
.account
= current
;
218 if (froomlist
.roomlist
) {
219 if (purple_roomlist_get_in_progress(froomlist
.roomlist
))
220 purple_roomlist_cancel_get_list(froomlist
.roomlist
);
221 update_roomlist(NULL
);
224 gnt_tree_remove_all(GNT_TREE(froomlist
.tree
));
225 gnt_widget_draw(froomlist
.tree
);
229 reset_account_list(PurpleAccount
*account
)
232 GntComboBox
*accounts
= GNT_COMBO_BOX(froomlist
.accounts
);
233 gnt_combo_box_remove_all(accounts
);
234 for (list
= purple_connections_get_all(); list
; list
= list
->next
) {
235 PurpleProtocol
*protocol
= NULL
;
236 PurpleConnection
*gc
= list
->data
;
238 protocol
= purple_connection_get_protocol(gc
);
239 if (PURPLE_CONNECTION_IS_CONNECTED(gc
) &&
240 PURPLE_PROTOCOL_IMPLEMENTS(protocol
, ROOMLIST_IFACE
, get_list
)) {
241 PurpleAccount
*account
= purple_connection_get_account(gc
);
242 char *text
= g_strdup_printf("%s (%s)",
243 purple_account_get_username(account
),
244 purple_account_get_protocol_name(account
));
245 gnt_combo_box_add_data(accounts
, account
, text
);
252 size_changed_cb(GntWidget
*widget
, int oldw
, int oldh
)
255 gnt_widget_get_size(widget
, &w
, &h
);
256 purple_prefs_set_int(PREF_ROOT
"/size/width", w
);
257 purple_prefs_set_int(PREF_ROOT
"/size/height", h
);
261 setup_roomlist(PurpleAccount
*account
)
263 GntWidget
*window
, *tree
, *hbox
, *accounts
;
270 {_("Stop"), G_CALLBACK(fl_stop
), &froomlist
.stop
},
271 {_("Get"), G_CALLBACK(fl_get_list
), &froomlist
.getlist
},
272 {_("Add"), G_CALLBACK(fl_add_chat
), &froomlist
.add
},
273 {_("Close"), G_CALLBACK(fl_close
), &froomlist
.close
},
277 if (froomlist
.window
)
280 froomlist
.window
= window
= gnt_window_new();
281 g_object_set(G_OBJECT(window
), "vertical", TRUE
, NULL
);
282 gnt_box_set_pad(GNT_BOX(window
), 0);
283 gnt_box_set_title(GNT_BOX(window
), _("Room List"));
284 gnt_box_set_alignment(GNT_BOX(window
), GNT_ALIGN_MID
);
286 froomlist
.accounts
= accounts
= gnt_combo_box_new();
287 reset_account_list(account
);
288 gnt_box_add_widget(GNT_BOX(window
), accounts
);
289 g_signal_connect(G_OBJECT(accounts
), "selection-changed",
290 G_CALLBACK(roomlist_account_changed
), NULL
);
291 froomlist
.account
= gnt_combo_box_get_selected_data(GNT_COMBO_BOX(accounts
));
293 froomlist
.tree
= tree
= gnt_tree_new_with_columns(2);
294 gnt_tree_set_show_title(GNT_TREE(tree
), TRUE
);
295 g_signal_connect(G_OBJECT(tree
), "activate", G_CALLBACK(roomlist_activated
), NULL
);
296 gnt_tree_set_column_titles(GNT_TREE(tree
), _("Name"), "");
297 gnt_tree_set_show_separator(GNT_TREE(tree
), FALSE
);
298 gnt_tree_set_col_width(GNT_TREE(tree
), 1, 1);
299 gnt_tree_set_column_resizable(GNT_TREE(tree
), 1, FALSE
);
300 gnt_tree_set_search_column(GNT_TREE(tree
), 0);
302 gnt_box_add_widget(GNT_BOX(window
), tree
);
304 froomlist
.details
= gnt_text_view_new();
305 gnt_text_view_set_flag(GNT_TEXT_VIEW(froomlist
.details
), GNT_TEXT_VIEW_TOP_ALIGN
);
306 gnt_box_add_widget(GNT_BOX(window
), froomlist
.details
);
307 gnt_widget_set_size(froomlist
.details
, -1, 8);
309 hbox
= gnt_hbox_new(FALSE
);
310 gnt_box_add_widget(GNT_BOX(window
), hbox
);
312 for (iter
= 0; buttons
[iter
].label
; iter
++) {
313 GntWidget
*button
= gnt_button_new(buttons
[iter
].label
);
314 gnt_box_add_widget(GNT_BOX(hbox
), button
);
315 g_signal_connect(G_OBJECT(button
), "activate", buttons
[iter
].callback
, NULL
);
316 *buttons
[iter
].widget
= button
;
317 gnt_text_view_attach_scroll_widget(GNT_TEXT_VIEW(froomlist
.details
), button
);
320 g_signal_connect(G_OBJECT(tree
), "selection-changed", G_CALLBACK(roomlist_selection_changed
), NULL
);
322 g_signal_connect(G_OBJECT(window
), "destroy", G_CALLBACK(unset_roomlist
), NULL
);
326 fl_show_with_account(PurpleAccount
*account
)
328 setup_roomlist(account
);
329 g_signal_handlers_disconnect_matched(G_OBJECT(froomlist
.window
), G_SIGNAL_MATCH_FUNC
,
330 0, 0, NULL
, G_CALLBACK(size_changed_cb
), NULL
);
331 gnt_widget_show(froomlist
.window
);
332 gnt_screen_resize_widget(froomlist
.window
,
333 purple_prefs_get_int(PREF_ROOT
"/size/width"),
334 purple_prefs_get_int(PREF_ROOT
"/size/height"));
335 g_signal_connect(G_OBJECT(froomlist
.window
), "size_changed", G_CALLBACK(size_changed_cb
), NULL
);
336 gnt_window_present(froomlist
.window
);
340 fl_create(PurpleRoomlist
*list
)
342 purple_roomlist_set_ui_data(list
, &froomlist
);
343 setup_roomlist(NULL
);
344 update_roomlist(list
);
348 fl_set_fields(PurpleRoomlist
*list
, GList
*fields
)
353 fl_add_room(PurpleRoomlist
*roomlist
, PurpleRoomlistRoom
*room
)
356 if (froomlist
.roomlist
!= roomlist
)
359 category
= (purple_roomlist_room_get_room_type(room
) == PURPLE_ROOMLIST_ROOMTYPE_CATEGORY
);
360 gnt_tree_remove(GNT_TREE(froomlist
.tree
), room
);
361 gnt_tree_add_row_after(GNT_TREE(froomlist
.tree
), room
,
362 gnt_tree_create_row(GNT_TREE(froomlist
.tree
),
363 purple_roomlist_room_get_name(room
),
364 category
? "<" : ""),
365 purple_roomlist_room_get_parent(room
), NULL
);
366 gnt_tree_set_expanded(GNT_TREE(froomlist
.tree
), room
, !category
);
370 fl_destroy(PurpleRoomlist
*list
)
372 if (!froomlist
.window
)
375 if (froomlist
.roomlist
== list
) {
376 froomlist
.roomlist
= NULL
;
377 gnt_tree_remove_all(GNT_TREE(froomlist
.tree
));
378 gnt_widget_draw(froomlist
.tree
);
382 static PurpleRoomlistUiOps ui_ops
=
384 fl_show_with_account
, /* void (*show_with_account)(PurpleAccount *account); **< Force the ui to pop up a dialog and get the list */
385 fl_create
, /* void (*create)(PurpleRoomlist *list); **< A new list was created. */
386 fl_set_fields
, /* void (*set_fields)(PurpleRoomlist *list, GList *fields); **< Sets the columns. */
387 fl_add_room
, /* void (*add_room)(PurpleRoomlist *list, PurpleRoomlistRoom *room); **< Add a room to the list. */
388 NULL
, /* void (*in_progress)(PurpleRoomlist *list, gboolean flag); **< Are we fetching stuff still? */
389 fl_destroy
, /* void (*destroy)(PurpleRoomlist *list); **< We're destroying list. */
391 NULL
, /* void (*_purple_reserved1)(void); */
392 NULL
, /* void (*_purple_reserved2)(void); */
393 NULL
, /* void (*_purple_reserved3)(void); */
394 NULL
/* void (*_purple_reserved4)(void); */
397 PurpleRoomlistUiOps
*finch_roomlist_get_ui_ops(void)
402 void finch_roomlist_show_all(void)
404 purple_roomlist_show_with_account(NULL
);
407 void finch_roomlist_init(void)
409 purple_prefs_add_none(PREF_ROOT
);
410 purple_prefs_add_none(PREF_ROOT
"/size");
411 purple_prefs_add_int(PREF_ROOT
"/size/width", 60);
412 purple_prefs_add_int(PREF_ROOT
"/size/height", 15);
415 void finch_roomlist_uninit(void)