Mercurial > pidgin.yaz
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 |