Change XMPP http connection set to a SoupSession.
[pidgin-git.git] / finch / gntroomlist.c
blobe1fc8b828e49b00f51300dc85aaf93fd1d77e9c7
1 /*
2 * finch
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
6 * source distribution.
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
23 #include "finch.h"
24 #include <internal.h>
26 #include "gntrequest.h"
27 #include "gntroomlist.h"
29 #include "gntbox.h"
30 #include "gntbutton.h"
31 #include "gntcombobox.h"
32 #include "gnttextview.h"
33 #include "gnttree.h"
34 #include "gntwindow.h"
36 #include "debug.h"
38 #define PREF_ROOT "/finch/roomlist"
41 /* Yes, just one roomlist at a time. Let's not get greedy. Aight? */
42 struct _FinchRoomlist
44 GntWidget *window;
46 GntWidget *accounts;
47 GntWidget *tree;
48 GntWidget *details;
50 GntWidget *getlist;
51 GntWidget *add;
52 GntWidget *join;
53 GntWidget *stop;
54 GntWidget *close;
56 PurpleAccount *account;
57 PurpleRoomlist *roomlist;
58 } froomlist;
60 typedef struct _FinchRoomlist FinchRoomlist;
62 static void
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;
74 static void
75 update_roomlist(PurpleRoomlist *list)
77 if (froomlist.roomlist == list)
78 return;
80 if (froomlist.roomlist)
81 g_object_unref(froomlist.roomlist);
83 if ((froomlist.roomlist = list) != NULL)
84 g_object_ref(list);
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);
99 if (!gc)
100 return;
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)
109 char *name;
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)
115 return;
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);
121 } else {
122 name = g_strdup(purple_roomlist_room_get_name(room));
125 purple_blist_request_add_chat(froomlist.account, NULL, NULL, name);
127 g_free(name);
130 static void fl_close(GntWidget *button, gpointer null)
132 gnt_widget_destroy(froomlist.window);
135 static void
136 roomlist_activated(GntWidget *widget)
138 PurpleRoomlistRoom *room = gnt_tree_get_selection_data(GNT_TREE(widget));
139 if (!room)
140 return;
142 switch (purple_roomlist_room_get_room_type(room)) {
143 case PURPLE_ROOMLIST_ROOMTYPE_ROOM:
144 purple_roomlist_room_join(froomlist.roomlist, room);
145 break;
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);
151 break;
153 gnt_tree_set_expanded(GNT_TREE(widget), room, TRUE);
156 static void
157 roomlist_selection_changed(GntWidget *widget, gpointer old, gpointer current, gpointer null)
159 GList *iter, *field;
160 PurpleRoomlistRoom *room = current;
161 GntTextView *tv = GNT_TEXT_VIEW(froomlist.details);
162 gboolean first = TRUE;
164 gnt_text_view_clear(tv);
166 if (!room)
167 return;
169 for (iter = purple_roomlist_room_get_fields(room),
170 field = purple_roomlist_get_fields(froomlist.roomlist);
171 iter && field;
172 iter = iter->next, field = field->next) {
173 PurpleRoomlistField *f = field->data;
174 char *label = NULL;
176 if (purple_roomlist_field_get_hidden(f)) {
177 continue;
180 if (!first)
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");
190 break;
191 case PURPLE_ROOMLIST_FIELD_INT:
192 label = g_strdup_printf("%d", GPOINTER_TO_INT(iter->data));
193 break;
194 case PURPLE_ROOMLIST_FIELD_STRING:
195 label = g_strdup(iter->data);
196 break;
198 gnt_text_view_append_text_with_flags(tv, label, GNT_TEXT_FLAG_NORMAL);
199 g_free(label);
200 first = FALSE;
203 if (purple_roomlist_room_get_room_type(room) == PURPLE_ROOMLIST_ROOMTYPE_CATEGORY) {
204 if (!first)
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);
212 static void
213 roomlist_account_changed(GntWidget *widget, gpointer old, gpointer current, gpointer null)
215 if (froomlist.account == current) {
216 return;
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);
230 static void
231 reset_account_list(PurpleAccount *account)
233 GList *list;
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);
248 g_free(text);
253 static void
254 size_changed_cb(GntWidget *widget, int oldw, int oldh)
256 int w, h;
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);
262 static void
263 setup_roomlist(PurpleAccount *account)
265 GntWidget *window, *tree, *hbox, *accounts;
266 int iter;
267 struct {
268 const char *label;
269 GCallback callback;
270 GntWidget **widget;
271 } buttons[] = {
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},
276 {NULL, NULL, NULL}
279 if (froomlist.window)
280 return;
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);
327 static void
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);
341 static void
342 fl_create(PurpleRoomlist *list)
344 purple_roomlist_set_ui_data(list, &froomlist);
345 setup_roomlist(NULL);
346 update_roomlist(list);
349 static void
350 fl_set_fields(PurpleRoomlist *list, GList *fields)
354 static void
355 fl_add_room(PurpleRoomlist *roomlist, PurpleRoomlistRoom *room)
357 gboolean category;
358 if (froomlist.roomlist != roomlist)
359 return;
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);
371 static void
372 fl_destroy(PurpleRoomlist *list)
374 if (!froomlist.window)
375 return;
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)
401 return &ui_ops;
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)