4 * Finch is the legal property of its developers, whose names are too numerous
5 * to list here. Please refer to the COPYRIGHT file distributed with this
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
26 #include "gntrequest.h"
27 #include "gntroomlist.h"
30 #include "gntbutton.h"
31 #include "gntcombobox.h"
32 #include "gnttextview.h"
34 #include "gntwindow.h"
38 #define PREF_ROOT "/finch/roomlist"
41 /* Yes, just one roomlist at a time. Let's not get greedy. Aight? */
56 PurpleAccount
*account
;
57 PurpleRoomlist
*roomlist
;
60 typedef struct _FinchRoomlist FinchRoomlist
;
63 unset_roomlist(gpointer null
)
65 froomlist
.window
= NULL
;
66 if (froomlist
.roomlist
) {
67 g_object_unref(froomlist
.roomlist
);
68 froomlist
.roomlist
= NULL
;
70 froomlist
.account
= NULL
;
71 froomlist
.tree
= NULL
;
75 update_roomlist(PurpleRoomlist
*list
)
77 if (froomlist
.roomlist
== list
)
80 if (froomlist
.roomlist
)
81 g_object_unref(froomlist
.roomlist
);
83 if ((froomlist
.roomlist
= list
) != NULL
)
87 static void fl_stop(GntWidget
*button
, gpointer null
)
89 if (froomlist
.roomlist
&&
90 purple_roomlist_get_in_progress(froomlist
.roomlist
))
91 purple_roomlist_cancel_get_list(froomlist
.roomlist
);
94 static void fl_get_list(GntWidget
*button
, gpointer null
)
96 PurpleAccount
*account
= gnt_combo_box_get_selected_data(GNT_COMBO_BOX(froomlist
.accounts
));
97 PurpleConnection
*gc
= purple_account_get_connection(account
);
102 update_roomlist(NULL
);
103 froomlist
.roomlist
= purple_roomlist_get_list(gc
);
104 gnt_box_give_focus_to_child(GNT_BOX(froomlist
.window
), froomlist
.tree
);
107 static void fl_add_chat(GntWidget
*button
, gpointer null
)
110 PurpleRoomlistRoom
*room
= gnt_tree_get_selection_data(GNT_TREE(froomlist
.tree
));
111 PurpleConnection
*gc
= purple_account_get_connection(froomlist
.account
);
112 PurpleProtocol
*protocol
= NULL
;
114 if (gc
== NULL
|| room
== NULL
)
117 protocol
= purple_connection_get_protocol(gc
);
119 if (PURPLE_PROTOCOL_IMPLEMENTS(protocol
, ROOMLIST
, room_serialize
)) {
120 name
= purple_protocol_roomlist_iface_room_serialize(protocol
, room
);
122 name
= g_strdup(purple_roomlist_room_get_name(room
));
125 purple_blist_request_add_chat(froomlist
.account
, NULL
, NULL
, name
);
130 static void fl_close(GntWidget
*button
, gpointer null
)
132 gnt_widget_destroy(froomlist
.window
);
136 roomlist_activated(GntWidget
*widget
)
138 PurpleRoomlistRoom
*room
= gnt_tree_get_selection_data(GNT_TREE(widget
));
142 switch (purple_roomlist_room_get_room_type(room
)) {
143 case PURPLE_ROOMLIST_ROOMTYPE_ROOM
:
144 purple_roomlist_room_join(froomlist
.roomlist
, room
);
146 case PURPLE_ROOMLIST_ROOMTYPE_CATEGORY
:
147 if (!purple_roomlist_room_get_expanded_once(room
)) {
148 purple_roomlist_expand_category(froomlist
.roomlist
, room
);
149 purple_roomlist_room_set_expanded_once(room
, TRUE
);
153 gnt_tree_set_expanded(GNT_TREE(widget
), room
, TRUE
);
157 roomlist_selection_changed(GntWidget
*widget
, gpointer old
, gpointer current
, gpointer null
)
160 PurpleRoomlistRoom
*room
= current
;
161 GntTextView
*tv
= GNT_TEXT_VIEW(froomlist
.details
);
162 gboolean first
= TRUE
;
164 gnt_text_view_clear(tv
);
169 for (iter
= purple_roomlist_room_get_fields(room
),
170 field
= purple_roomlist_get_fields(froomlist
.roomlist
);
172 iter
= iter
->next
, field
= field
->next
) {
173 PurpleRoomlistField
*f
= field
->data
;
176 if (purple_roomlist_field_get_hidden(f
)) {
181 gnt_text_view_append_text_with_flags(tv
, "\n", GNT_TEXT_FLAG_NORMAL
);
183 gnt_text_view_append_text_with_flags(tv
,
184 purple_roomlist_field_get_label(f
), GNT_TEXT_FLAG_BOLD
);
185 gnt_text_view_append_text_with_flags(tv
, ": ", GNT_TEXT_FLAG_BOLD
);
187 switch (purple_roomlist_field_get_field_type(f
)) {
188 case PURPLE_ROOMLIST_FIELD_BOOL
:
189 label
= g_strdup(iter
->data
? "True" : "False");
191 case PURPLE_ROOMLIST_FIELD_INT
:
192 label
= g_strdup_printf("%d", GPOINTER_TO_INT(iter
->data
));
194 case PURPLE_ROOMLIST_FIELD_STRING
:
195 label
= g_strdup(iter
->data
);
198 gnt_text_view_append_text_with_flags(tv
, label
, GNT_TEXT_FLAG_NORMAL
);
203 if (purple_roomlist_room_get_room_type(room
) == PURPLE_ROOMLIST_ROOMTYPE_CATEGORY
) {
205 gnt_text_view_append_text_with_flags(tv
, "\n", GNT_TEXT_FLAG_NORMAL
);
206 gnt_text_view_append_text_with_flags(tv
,
207 _("Hit 'Enter' to find more rooms of this category."),
208 GNT_TEXT_FLAG_NORMAL
);
213 roomlist_account_changed(GntWidget
*widget
, gpointer old
, gpointer current
, gpointer null
)
215 if (froomlist
.account
== current
) {
219 froomlist
.account
= current
;
220 if (froomlist
.roomlist
) {
221 if (purple_roomlist_get_in_progress(froomlist
.roomlist
))
222 purple_roomlist_cancel_get_list(froomlist
.roomlist
);
223 update_roomlist(NULL
);
226 gnt_tree_remove_all(GNT_TREE(froomlist
.tree
));
227 gnt_widget_draw(froomlist
.tree
);
231 reset_account_list(PurpleAccount
*account
)
234 GntComboBox
*accounts
= GNT_COMBO_BOX(froomlist
.accounts
);
235 gnt_combo_box_remove_all(accounts
);
236 for (list
= purple_connections_get_all(); list
; list
= list
->next
) {
237 PurpleProtocol
*protocol
= NULL
;
238 PurpleConnection
*gc
= list
->data
;
240 protocol
= purple_connection_get_protocol(gc
);
241 if (PURPLE_CONNECTION_IS_CONNECTED(gc
) &&
242 PURPLE_PROTOCOL_IMPLEMENTS(protocol
, ROOMLIST
, get_list
)) {
243 PurpleAccount
*account
= purple_connection_get_account(gc
);
244 char *text
= g_strdup_printf("%s (%s)",
245 purple_account_get_username(account
),
246 purple_account_get_protocol_name(account
));
247 gnt_combo_box_add_data(accounts
, account
, text
);
254 size_changed_cb(GntWidget
*widget
, int oldw
, int oldh
)
257 gnt_widget_get_size(widget
, &w
, &h
);
258 purple_prefs_set_int(PREF_ROOT
"/size/width", w
);
259 purple_prefs_set_int(PREF_ROOT
"/size/height", h
);
263 setup_roomlist(PurpleAccount
*account
)
265 GntWidget
*window
, *tree
, *hbox
, *accounts
;
272 {_("Stop"), G_CALLBACK(fl_stop
), &froomlist
.stop
},
273 {_("Get"), G_CALLBACK(fl_get_list
), &froomlist
.getlist
},
274 {_("Add"), G_CALLBACK(fl_add_chat
), &froomlist
.add
},
275 {_("Close"), G_CALLBACK(fl_close
), &froomlist
.close
},
279 if (froomlist
.window
)
282 froomlist
.window
= window
= gnt_window_new();
283 g_object_set(G_OBJECT(window
), "vertical", TRUE
, NULL
);
284 gnt_box_set_pad(GNT_BOX(window
), 0);
285 gnt_box_set_title(GNT_BOX(window
), _("Room List"));
286 gnt_box_set_alignment(GNT_BOX(window
), GNT_ALIGN_MID
);
288 froomlist
.accounts
= accounts
= gnt_combo_box_new();
289 reset_account_list(account
);
290 gnt_box_add_widget(GNT_BOX(window
), accounts
);
291 g_signal_connect(G_OBJECT(accounts
), "selection-changed",
292 G_CALLBACK(roomlist_account_changed
), NULL
);
293 froomlist
.account
= gnt_combo_box_get_selected_data(GNT_COMBO_BOX(accounts
));
295 froomlist
.tree
= tree
= gnt_tree_new_with_columns(2);
296 gnt_tree_set_show_title(GNT_TREE(tree
), TRUE
);
297 g_signal_connect(G_OBJECT(tree
), "activate", G_CALLBACK(roomlist_activated
), NULL
);
298 gnt_tree_set_column_titles(GNT_TREE(tree
), _("Name"), "");
299 gnt_tree_set_show_separator(GNT_TREE(tree
), FALSE
);
300 gnt_tree_set_col_width(GNT_TREE(tree
), 1, 1);
301 gnt_tree_set_column_resizable(GNT_TREE(tree
), 1, FALSE
);
302 gnt_tree_set_search_column(GNT_TREE(tree
), 0);
304 gnt_box_add_widget(GNT_BOX(window
), tree
);
306 froomlist
.details
= gnt_text_view_new();
307 gnt_text_view_set_flag(GNT_TEXT_VIEW(froomlist
.details
), GNT_TEXT_VIEW_TOP_ALIGN
);
308 gnt_box_add_widget(GNT_BOX(window
), froomlist
.details
);
309 gnt_widget_set_size(froomlist
.details
, -1, 8);
311 hbox
= gnt_hbox_new(FALSE
);
312 gnt_box_add_widget(GNT_BOX(window
), hbox
);
314 for (iter
= 0; buttons
[iter
].label
; iter
++) {
315 GntWidget
*button
= gnt_button_new(buttons
[iter
].label
);
316 gnt_box_add_widget(GNT_BOX(hbox
), button
);
317 g_signal_connect(G_OBJECT(button
), "activate", buttons
[iter
].callback
, NULL
);
318 *buttons
[iter
].widget
= button
;
319 gnt_text_view_attach_scroll_widget(GNT_TEXT_VIEW(froomlist
.details
), button
);
322 g_signal_connect(G_OBJECT(tree
), "selection-changed", G_CALLBACK(roomlist_selection_changed
), NULL
);
324 g_signal_connect(G_OBJECT(window
), "destroy", G_CALLBACK(unset_roomlist
), NULL
);
328 fl_show_with_account(PurpleAccount
*account
)
330 setup_roomlist(account
);
331 g_signal_handlers_disconnect_matched(G_OBJECT(froomlist
.window
), G_SIGNAL_MATCH_FUNC
,
332 0, 0, NULL
, G_CALLBACK(size_changed_cb
), NULL
);
333 gnt_widget_show(froomlist
.window
);
334 gnt_screen_resize_widget(froomlist
.window
,
335 purple_prefs_get_int(PREF_ROOT
"/size/width"),
336 purple_prefs_get_int(PREF_ROOT
"/size/height"));
337 g_signal_connect(G_OBJECT(froomlist
.window
), "size_changed", G_CALLBACK(size_changed_cb
), NULL
);
338 gnt_window_present(froomlist
.window
);
342 fl_create(PurpleRoomlist
*list
)
344 purple_roomlist_set_ui_data(list
, &froomlist
);
345 setup_roomlist(NULL
);
346 update_roomlist(list
);
350 fl_set_fields(PurpleRoomlist
*list
, GList
*fields
)
355 fl_add_room(PurpleRoomlist
*roomlist
, PurpleRoomlistRoom
*room
)
358 if (froomlist
.roomlist
!= roomlist
)
361 category
= (purple_roomlist_room_get_room_type(room
) == PURPLE_ROOMLIST_ROOMTYPE_CATEGORY
);
362 gnt_tree_remove(GNT_TREE(froomlist
.tree
), room
);
363 gnt_tree_add_row_after(GNT_TREE(froomlist
.tree
), room
,
364 gnt_tree_create_row(GNT_TREE(froomlist
.tree
),
365 purple_roomlist_room_get_name(room
),
366 category
? "<" : ""),
367 purple_roomlist_room_get_parent(room
), NULL
);
368 gnt_tree_set_expanded(GNT_TREE(froomlist
.tree
), room
, !category
);
372 fl_destroy(PurpleRoomlist
*list
)
374 if (!froomlist
.window
)
377 if (froomlist
.roomlist
== list
) {
378 froomlist
.roomlist
= NULL
;
379 gnt_tree_remove_all(GNT_TREE(froomlist
.tree
));
380 gnt_widget_draw(froomlist
.tree
);
384 static PurpleRoomlistUiOps ui_ops
=
386 fl_show_with_account
, /* void (*show_with_account)(PurpleAccount *account); **< Force the ui to pop up a dialog and get the list */
387 fl_create
, /* void (*create)(PurpleRoomlist *list); **< A new list was created. */
388 fl_set_fields
, /* void (*set_fields)(PurpleRoomlist *list, GList *fields); **< Sets the columns. */
389 fl_add_room
, /* void (*add_room)(PurpleRoomlist *list, PurpleRoomlistRoom *room); **< Add a room to the list. */
390 NULL
, /* void (*in_progress)(PurpleRoomlist *list, gboolean flag); **< Are we fetching stuff still? */
391 fl_destroy
, /* void (*destroy)(PurpleRoomlist *list); **< We're destroying list. */
393 NULL
, /* void (*_purple_reserved1)(void); */
394 NULL
, /* void (*_purple_reserved2)(void); */
395 NULL
, /* void (*_purple_reserved3)(void); */
396 NULL
/* void (*_purple_reserved4)(void); */
399 PurpleRoomlistUiOps
*finch_roomlist_get_ui_ops(void)
404 void finch_roomlist_show_all(void)
406 purple_roomlist_show_with_account(NULL
);
409 void finch_roomlist_init(void)
411 purple_prefs_add_none(PREF_ROOT
);
412 purple_prefs_add_none(PREF_ROOT
"/size");
413 purple_prefs_add_int(PREF_ROOT
"/size/width", 60);
414 purple_prefs_add_int(PREF_ROOT
"/size/height", 15);
417 void finch_roomlist_uninit(void)