comparison finch/gntroomlist.c @ 22006:1278280fa0b6

Implementation of the roomlist API.
author Sadrul Habib Chowdhury <imadil@gmail.com>
date Sun, 06 Jan 2008 19:01:24 +0000
parents
children d65fd48a3ad9
comparison
equal deleted inserted replaced
22005:829d054f4f1a 22006:1278280fa0b6
1 /**
2 * @file gntroomlist.c GNT Room List API
3 * @ingroup finch
4 */
5
6 /* finch
7 *
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.
11 *
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.
16 *
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.
21 *
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
25 */
26
27 #include"internal.h"
28
29 #include "gntrequest.h"
30 #include "gntroomlist.h"
31
32 #include "gntbox.h"
33 #include "gntbutton.h"
34 #include "gntcombobox.h"
35 #include "gnttextview.h"
36 #include "gnttree.h"
37 #include "gntwindow.h"
38
39 #include "debug.h"
40
41 /* Yes, just one roomlist at a time. Let's not get greedy. Aight? */
42 struct _FinchRoomlist
43 {
44 GntWidget *window;
45
46 GntWidget *accounts;
47 GntWidget *tree;
48 GntWidget *details;
49
50 GntWidget *getlist;
51 GntWidget *add;
52 GntWidget *join;
53 GntWidget *stop;
54 GntWidget *close;
55
56 PurpleAccount *account;
57 PurpleRoomlist *roomlist;
58 } froomlist;
59
60 typedef struct _FinchRoomlist FinchRoomlist;
61
62 static void
63 unset_roomlist(gpointer null)
64 {
65 froomlist.window = NULL;
66 if (froomlist.roomlist)
67 purple_roomlist_unref(froomlist.roomlist);
68 }
69
70 static void
71 update_roomlist(PurpleRoomlist *list)
72 {
73 if (froomlist.roomlist == list)
74 return;
75
76 if (froomlist.roomlist)
77 purple_roomlist_unref(froomlist.roomlist);
78
79 if ((froomlist.roomlist = list) != NULL)
80 purple_roomlist_ref(list);
81 }
82
83 static void fl_stop(GntWidget *button, gpointer null)
84 {
85 if (froomlist.roomlist &&
86 purple_roomlist_get_in_progress(froomlist.roomlist))
87 purple_roomlist_cancel_get_list(froomlist.roomlist);
88 }
89
90 static void fl_get_list(GntWidget *button, gpointer null)
91 {
92 PurpleAccount *account = gnt_combo_box_get_selected_data(GNT_COMBO_BOX(froomlist.accounts));
93 PurpleConnection *gc = purple_account_get_connection(account);
94
95 if (!gc)
96 return;
97
98 froomlist.roomlist = purple_roomlist_get_list(gc);
99 gnt_box_give_focus_to_child(GNT_BOX(froomlist.window), froomlist.tree);
100 }
101
102 static void fl_add_chat(GntWidget *button, gpointer null)
103 {
104 char *name;
105 PurpleRoomlistRoom *room = gnt_tree_get_selection_data(GNT_TREE(froomlist.tree));
106 PurpleConnection *gc = purple_account_get_connection(froomlist.account);
107 PurplePluginProtocolInfo *prpl_info = NULL;
108
109 if (gc == NULL || room == NULL)
110 return;
111
112 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
113
114 if(prpl_info != NULL && prpl_info->roomlist_room_serialize)
115 name = prpl_info->roomlist_room_serialize(room);
116 else
117 name = g_strdup(purple_roomlist_room_get_name(room));
118
119 purple_blist_request_add_chat(froomlist.account, NULL, NULL, name);
120
121 g_free(name);
122 }
123
124 static void fl_close(GntWidget *button, gpointer null)
125 {
126 gnt_widget_destroy(froomlist.window);
127 }
128
129 static void
130 roomlist_activated(GntWidget *widget)
131 {
132 PurpleRoomlistRoom *room = gnt_tree_get_selection_data(GNT_TREE(widget));
133 if (!room)
134 return;
135
136 switch (purple_roomlist_room_get_type(room)) {
137 case PURPLE_ROOMLIST_ROOMTYPE_ROOM:
138 purple_roomlist_room_join(froomlist.roomlist, room);
139 break;
140 case PURPLE_ROOMLIST_ROOMTYPE_CATEGORY:
141 purple_roomlist_expand_category(froomlist.roomlist, room);
142 break;
143 }
144 }
145
146 static void
147 roomlist_selection_changed(GntWidget *widget, gpointer old, gpointer current, gpointer null)
148 {
149 GList *iter, *field;
150 PurpleRoomlistRoom *room = current;
151 GntTextView *tv = GNT_TEXT_VIEW(froomlist.details);
152 gboolean first = TRUE;
153
154 gnt_text_view_clear(tv);
155
156 if (!room)
157 return;
158
159 for (iter = purple_roomlist_room_get_fields(room),
160 field = purple_roomlist_get_fields(froomlist.roomlist);
161 iter && field;
162 iter = iter->next, field = field->next) {
163 PurpleRoomlistField *f = field->data;
164 char *label = NULL;
165
166 if (purple_roomlist_field_get_hidden(f)) {
167 continue;
168 }
169
170 if (!first)
171 gnt_text_view_append_text_with_flags(tv, "\n", GNT_TEXT_FLAG_NORMAL);
172
173 gnt_text_view_append_text_with_flags(tv,
174 purple_roomlist_field_get_label(f), GNT_TEXT_FLAG_BOLD);
175 gnt_text_view_append_text_with_flags(tv, ": ", GNT_TEXT_FLAG_BOLD);
176
177 switch (purple_roomlist_field_get_type(f)) {
178 case PURPLE_ROOMLIST_FIELD_BOOL:
179 label = g_strdup(iter->data ? "True" : "False");
180 break;
181 case PURPLE_ROOMLIST_FIELD_INT:
182 label = g_strdup_printf("%d", (int)iter->data);
183 break;
184 case PURPLE_ROOMLIST_FIELD_STRING:
185 label = g_strdup(iter->data);
186 break;
187 }
188 gnt_text_view_append_text_with_flags(tv, label, GNT_TEXT_FLAG_NORMAL);
189 g_free(label);
190 first = FALSE;
191 }
192
193 if (purple_roomlist_room_get_type(room) == PURPLE_ROOMLIST_ROOMTYPE_CATEGORY) {
194 gnt_text_view_append_text_with_flags(tv,
195 _("\nHit 'Enter' to find more rooms of this category."),
196 GNT_TEXT_FLAG_NORMAL);
197 }
198 }
199
200 static void
201 roomlist_account_changed(GntWidget *widget, gpointer old, gpointer current, gpointer null)
202 {
203 if (froomlist.account == current) {
204 return;
205 }
206
207 froomlist.account = current;
208 if (froomlist.roomlist) {
209 if (purple_roomlist_get_in_progress(froomlist.roomlist))
210 purple_roomlist_cancel_get_list(froomlist.roomlist);
211 update_roomlist(NULL);
212 }
213
214 gnt_tree_remove_all(GNT_TREE(froomlist.tree));
215 gnt_widget_draw(froomlist.tree);
216 }
217
218 static void
219 reset_account_list(PurpleAccount *account)
220 {
221 GList *list;
222 GntComboBox *accounts = GNT_COMBO_BOX(froomlist.accounts);
223 gnt_combo_box_remove_all(accounts);
224 for (list = purple_connections_get_all(); list; list = list->next) {
225 PurplePluginProtocolInfo *prpl_info = NULL;
226 PurpleConnection *gc = list->data;
227
228 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
229 if (prpl_info->roomlist_get_list != NULL) {
230 PurpleAccount *account = purple_connection_get_account(gc);
231 char *text = g_strdup_printf("%s (%s)",
232 purple_account_get_username(account),
233 purple_account_get_protocol_name(account));
234 gnt_combo_box_add_data(accounts, account, text);
235 g_free(text);
236 }
237 }
238 }
239
240 static void
241 setup_roomlist(PurpleAccount *account)
242 {
243 GntWidget *window, *tree, *hbox, *accounts;
244 int iter;
245 struct {
246 const char *label;
247 GCallback callback;
248 GntWidget **widget;
249 } buttons[] = {
250 {_("Stop"), G_CALLBACK(fl_stop), &froomlist.stop},
251 {_("Get"), G_CALLBACK(fl_get_list), &froomlist.getlist},
252 {_("Add"), G_CALLBACK(fl_add_chat), &froomlist.add},
253 {_("Close"), G_CALLBACK(fl_close), &froomlist.close},
254 {NULL, NULL, NULL}
255 };
256
257 if (froomlist.window)
258 return;
259
260 froomlist.window = window = gnt_window_new();
261 g_object_set(G_OBJECT(window), "vertical", TRUE, NULL);
262 gnt_box_set_pad(GNT_BOX(window), 0);
263 gnt_box_set_title(GNT_BOX(window), _("Room List"));
264 gnt_box_set_alignment(GNT_BOX(window), GNT_ALIGN_MID);
265
266 froomlist.accounts = accounts = gnt_combo_box_new();
267 reset_account_list(account);
268 gnt_box_add_widget(GNT_BOX(window), froomlist.accounts);
269 g_signal_connect(G_OBJECT(froomlist.accounts), "selection-changed",
270 G_CALLBACK(roomlist_account_changed), NULL);
271 froomlist.account = gnt_combo_box_get_selected_data(GNT_COMBO_BOX(froomlist.accounts));
272
273 froomlist.tree = tree = gnt_tree_new_with_columns(2);
274 gnt_tree_set_show_title(GNT_TREE(tree), TRUE);
275 g_signal_connect(G_OBJECT(tree), "activate", G_CALLBACK(roomlist_activated), NULL);
276 gnt_tree_set_column_titles(GNT_TREE(tree), _("Name"), "");
277 gnt_tree_set_show_separator(GNT_TREE(tree), FALSE);
278 gnt_tree_set_col_width(GNT_TREE(tree), 1, 1);
279 gnt_tree_set_column_resizable(GNT_TREE(tree), 1, FALSE);
280 gnt_tree_set_search_column(GNT_TREE(tree), 0);
281
282 gnt_box_add_widget(GNT_BOX(window), tree);
283
284 froomlist.details = gnt_text_view_new();
285 gnt_text_view_set_flag(GNT_TEXT_VIEW(froomlist.details), GNT_TEXT_VIEW_TOP_ALIGN);
286 gnt_box_add_widget(GNT_BOX(window), froomlist.details);
287 gnt_widget_set_size(froomlist.details, -1, 10);
288
289 hbox = gnt_hbox_new(FALSE);
290 gnt_box_add_widget(GNT_BOX(window), hbox);
291
292 for (iter = 0; buttons[iter].label; iter++) {
293 GntWidget *button = gnt_button_new(buttons[iter].label);
294 gnt_box_add_widget(GNT_BOX(hbox), button);
295 g_signal_connect(G_OBJECT(button), "activate", buttons[iter].callback, NULL);
296 *buttons[iter].widget = button;
297 gnt_text_view_attach_scroll_widget(GNT_TEXT_VIEW(froomlist.details), button);
298 }
299
300 g_signal_connect(G_OBJECT(tree), "selection-changed", G_CALLBACK(roomlist_selection_changed), NULL);
301
302 g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(unset_roomlist), NULL);
303 }
304
305 static void
306 fl_show_with_account(PurpleAccount *account)
307 {
308 setup_roomlist(account);
309 gnt_window_present(froomlist.window);
310 }
311
312 static void
313 fl_create(PurpleRoomlist *list)
314 {
315 list->ui_data = &froomlist;
316 setup_roomlist(NULL);
317 update_roomlist(list);
318 }
319
320 static void
321 fl_set_fields(PurpleRoomlist *list, GList *fields)
322 {
323 }
324
325 static void
326 fl_add_room(PurpleRoomlist *roomlist, PurpleRoomlistRoom *room)
327 {
328 if (froomlist.roomlist != roomlist)
329 return;
330
331 gnt_tree_remove(GNT_TREE(froomlist.tree), room);
332 gnt_tree_add_row_after(GNT_TREE(froomlist.tree), room,
333 gnt_tree_create_row(GNT_TREE(froomlist.tree),
334 purple_roomlist_room_get_name(room),
335 purple_roomlist_room_get_type(room) == PURPLE_ROOMLIST_ROOMTYPE_CATEGORY ? "<" : ""),
336 purple_roomlist_room_get_parent(room), NULL);
337 }
338
339 static void
340 fl_destroy(PurpleRoomlist *list)
341 {
342 if (!froomlist.window)
343 return;
344
345 if (froomlist.roomlist == list) {
346 froomlist.roomlist = NULL;
347 gnt_tree_remove_all(GNT_TREE(froomlist.tree));
348 gnt_widget_destroy(froomlist.tree);
349 }
350 }
351
352 static PurpleRoomlistUiOps ui_ops =
353 {
354 fl_show_with_account, /* void (*show_with_account)(PurpleAccount *account); **< Force the ui to pop up a dialog and get the list */
355 fl_create, /* void (*create)(PurpleRoomlist *list); **< A new list was created. */
356 fl_set_fields, /* void (*set_fields)(PurpleRoomlist *list, GList *fields); **< Sets the columns. */
357 fl_add_room, /* void (*add_room)(PurpleRoomlist *list, PurpleRoomlistRoom *room); **< Add a room to the list. */
358 NULL, /* void (*in_progress)(PurpleRoomlist *list, gboolean flag); **< Are we fetching stuff still? */
359 fl_destroy, /* void (*destroy)(PurpleRoomlist *list); **< We're destroying list. */
360
361 NULL, /* void (*_purple_reserved1)(void); */
362 NULL, /* void (*_purple_reserved2)(void); */
363 NULL, /* void (*_purple_reserved3)(void); */
364 NULL /* void (*_purple_reserved4)(void); */
365 };
366 PurpleRoomlistUiOps *finch_roomlist_get_ui_ops(void)
367 {
368 return &ui_ops;
369 }
370
371 void finch_roomlist_show_all(void)
372 {
373 purple_roomlist_show_with_account(NULL);
374 }
375