These changes are reuired to make the Windows installer build.
[pidgin-git.git] / finch / gntroomlist.c
blob92299d3a5c8f4bd17f82811520ee1208a9dbf9b8
1 /**
2 * @file gntroomlist.c GNT Room List API
3 * @ingroup finch
4 */
6 /* finch
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
27 #include "finch.h"
28 #include <internal.h>
30 #include "gntrequest.h"
31 #include "gntroomlist.h"
33 #include "gntbox.h"
34 #include "gntbutton.h"
35 #include "gntcombobox.h"
36 #include "gnttextview.h"
37 #include "gnttree.h"
38 #include "gntwindow.h"
40 #include "debug.h"
42 #define PREF_ROOT "/finch/roomlist"
44 /* Yes, just one roomlist at a time. Let's not get greedy. Aight? */
45 struct _FinchRoomlist
47 GntWidget *window;
49 GntWidget *accounts;
50 GntWidget *tree;
51 GntWidget *details;
53 GntWidget *getlist;
54 GntWidget *add;
55 GntWidget *join;
56 GntWidget *stop;
57 GntWidget *close;
59 PurpleAccount *account;
60 PurpleRoomlist *roomlist;
61 } froomlist;
63 typedef struct _FinchRoomlist FinchRoomlist;
65 static void
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;
77 static void
78 update_roomlist(PurpleRoomlist *list)
80 if (froomlist.roomlist == list)
81 return;
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);
102 if (!gc)
103 return;
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)
112 char *name;
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)
118 return;
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);
124 else
125 name = g_strdup(purple_roomlist_room_get_name(room));
127 purple_blist_request_add_chat(froomlist.account, NULL, NULL, name);
129 g_free(name);
132 static void fl_close(GntWidget *button, gpointer null)
134 gnt_widget_destroy(froomlist.window);
137 static void
138 roomlist_activated(GntWidget *widget)
140 PurpleRoomlistRoom *room = gnt_tree_get_selection_data(GNT_TREE(widget));
141 if (!room)
142 return;
144 switch (purple_roomlist_room_get_type(room)) {
145 case PURPLE_ROOMLIST_ROOMTYPE_ROOM:
146 purple_roomlist_room_join(froomlist.roomlist, room);
147 break;
148 case PURPLE_ROOMLIST_ROOMTYPE_CATEGORY:
149 if (!room->expanded_once) {
150 purple_roomlist_expand_category(froomlist.roomlist, room);
151 room->expanded_once = TRUE;
153 break;
155 gnt_tree_set_expanded(GNT_TREE(widget), room, TRUE);
158 static void
159 roomlist_selection_changed(GntWidget *widget, gpointer old, gpointer current, gpointer null)
161 GList *iter, *field;
162 PurpleRoomlistRoom *room = current;
163 GntTextView *tv = GNT_TEXT_VIEW(froomlist.details);
164 gboolean first = TRUE;
166 gnt_text_view_clear(tv);
168 if (!room)
169 return;
171 for (iter = purple_roomlist_room_get_fields(room),
172 field = purple_roomlist_get_fields(froomlist.roomlist);
173 iter && field;
174 iter = iter->next, field = field->next) {
175 PurpleRoomlistField *f = field->data;
176 char *label = NULL;
178 if (purple_roomlist_field_get_hidden(f)) {
179 continue;
182 if (!first)
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");
192 break;
193 case PURPLE_ROOMLIST_FIELD_INT:
194 label = g_strdup_printf("%d", GPOINTER_TO_INT(iter->data));
195 break;
196 case PURPLE_ROOMLIST_FIELD_STRING:
197 label = g_strdup(iter->data);
198 break;
200 gnt_text_view_append_text_with_flags(tv, label, GNT_TEXT_FLAG_NORMAL);
201 g_free(label);
202 first = FALSE;
205 if (purple_roomlist_room_get_type(room) == PURPLE_ROOMLIST_ROOMTYPE_CATEGORY) {
206 if (!first)
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);
214 static void
215 roomlist_account_changed(GntWidget *widget, gpointer old, gpointer current, gpointer null)
217 if (froomlist.account == current) {
218 return;
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);
232 static void
233 reset_account_list(PurpleAccount *account)
235 GList *list;
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);
250 g_free(text);
255 static void
256 size_changed_cb(GntWidget *widget, int oldw, int oldh)
258 int w, h;
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);
264 static void
265 setup_roomlist(PurpleAccount *account)
267 GntWidget *window, *tree, *hbox, *accounts;
268 int iter;
269 struct {
270 const char *label;
271 GCallback callback;
272 GntWidget **widget;
273 } buttons[] = {
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},
278 {NULL, NULL, NULL}
281 if (froomlist.window)
282 return;
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);
329 static void
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);
343 static void
344 fl_create(PurpleRoomlist *list)
346 FINCH_SET_DATA(list, &froomlist);
347 setup_roomlist(NULL);
348 update_roomlist(list);
351 static void
352 fl_set_fields(PurpleRoomlist *list, GList *fields)
356 static void
357 fl_add_room(PurpleRoomlist *roomlist, PurpleRoomlistRoom *room)
359 gboolean category;
360 if (froomlist.roomlist != roomlist)
361 return;
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);
373 static void
374 fl_destroy(PurpleRoomlist *list)
376 if (!froomlist.window)
377 return;
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)
403 return &ui_ops;
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)