[gaim-migrate @ 2949]
[pidgin-git.git] / plugins / chatlist.c
blob6bb2680b1fd2ee1ff3ad682aba0a7c7646a8bee6
1 #define GAIM_PLUGINS
3 #include "pixmaps/cancel.xpm"
4 #include "pixmaps/refresh.xpm"
5 #include "pixmaps/gnome_add.xpm"
6 #include "pixmaps/gnome_remove.xpm"
8 #include "proxy.h"
9 #include "gaim.h"
11 #include <stdlib.h>
12 #include <string.h>
14 #define AOL_SRCHSTR "/community/aimcheck.adp/url="
16 struct chat_page {
17 GtkWidget *list1;
18 GtkWidget *list2;
21 struct chat_room {
22 char name[80];
23 int exchange;
26 static GtkWidget *item = NULL; /* this is the parent tree */
27 static GList *chat_rooms = NULL;
29 static GtkWidget *parent = NULL; /* this is the config thing where you can see the list */
30 static struct chat_page *cp = NULL;
32 static void des_item()
34 if (item)
35 gtk_widget_destroy(item);
36 item = NULL;
39 static void handle_click_chat(GtkWidget *widget, GdkEventButton * event, struct chat_room *cr)
41 if (event->type == GDK_2BUTTON_PRESS && event->button == 1) {
42 GList *m = g_list_append(NULL, cr->name);
43 int *x = g_new0(int, 1);
44 *x = cr->exchange;
45 m = g_list_append(m, x);
46 serv_join_chat(connections->data, m);
47 g_free(x);
48 g_list_free(m);
52 static void setup_buddy_chats()
54 GList *crs = chat_rooms;
55 GtkWidget *tree;
57 if (!blist)
58 return;
60 if (item)
61 gtk_tree_remove_item(GTK_TREE(buddies), item);
62 item = NULL;
64 if (!chat_rooms)
65 return;
67 item = gtk_tree_item_new_with_label(_("Buddy Chat"));
68 gtk_signal_connect(GTK_OBJECT(item), "destroy", GTK_SIGNAL_FUNC(des_item), NULL);
69 gtk_tree_append(GTK_TREE(buddies), item);
70 gtk_tree_item_expand(GTK_TREE_ITEM(item));
71 gtk_widget_show(item);
73 tree = gtk_tree_new();
74 gtk_tree_item_set_subtree(GTK_TREE_ITEM(item), tree);
75 gtk_widget_show(tree);
77 while (crs) {
78 struct chat_room *cr = (struct chat_room *)crs->data;
79 GtkWidget *titem = gtk_tree_item_new_with_label(cr->name);
80 gtk_object_set_user_data(GTK_OBJECT(titem), cr);
81 gtk_tree_append(GTK_TREE(tree), titem);
82 gtk_widget_show(titem);
83 gtk_signal_connect(GTK_OBJECT(titem), "button_press_event",
84 GTK_SIGNAL_FUNC(handle_click_chat), cr);
85 crs = crs->next;
88 gtk_tree_item_expand(GTK_TREE_ITEM(item));
91 static void save_chat_prefs()
93 FILE *f;
94 char path[1024];
95 char *x = gaim_user_dir();
96 GList *crs = chat_rooms;
98 g_snprintf(path, sizeof(path), "%s/%s", x, "chats");
99 f = fopen(path, "w");
100 if (!f) {
101 g_free(x);
102 return;
104 while (crs) {
105 struct chat_room *cr = crs->data;
106 crs = crs->next;
107 fprintf(f, "%s\n%d\n", cr->name, cr->exchange);
109 g_free(x);
110 fclose(f);
113 static void restore_chat_prefs()
115 FILE *f;
116 char path[1024];
117 char *x = gaim_user_dir();
118 char buf[1024];
120 g_snprintf(path, sizeof(path), "%s/%s", x, "chats");
121 f = fopen(path, "r");
122 if (!f) {
123 g_free(x);
124 return;
126 while (fgets(buf, 1024, f)) {
127 struct chat_room *cr = g_new0(struct chat_room, 1);
128 g_snprintf(cr->name, sizeof(cr->name), "%s", g_strchomp(buf));
129 if (!fgets(buf, 1024, f)) {
130 g_free(cr);
131 break;
133 cr->exchange = atoi(buf);
134 chat_rooms = g_list_append(chat_rooms, cr);
136 g_free(x);
137 fclose(f);
138 setup_buddy_chats();
141 static void ref_list_callback(gpointer data, char *text)
143 char *c;
144 int len;
145 GtkWidget *item;
146 GList *items = GTK_LIST(cp->list1)->children;
147 struct chat_room *cr;
148 c = text;
150 if (!text)
151 return;
152 if (!parent)
153 return;
155 len = strlen(text);
157 while (items) {
158 g_free(gtk_object_get_user_data(GTK_OBJECT(items->data)));
159 items = items->next;
162 items = NULL;
164 gtk_list_clear_items(GTK_LIST(cp->list1), 0, -1);
166 item = gtk_list_item_new_with_label(_("Gaim Chat"));
167 cr = g_new0(struct chat_room, 1);
168 strcpy(cr->name, _("Gaim Chat"));
169 cr->exchange = 4;
170 gtk_object_set_user_data(GTK_OBJECT(item), cr);
171 gtk_widget_show(item);
173 items = g_list_append(NULL, item);
175 while (c) {
176 if (c - text > len - 30)
177 break; /* assume no chat rooms 30 from end, padding */
178 if (!g_strncasecmp(AOL_SRCHSTR, c, strlen(AOL_SRCHSTR))) {
179 char *t;
180 int len = 0;
181 int exchange = 4;
182 char *name = NULL;
184 c += strlen(AOL_SRCHSTR);
185 t = c;
186 while (t) {
187 len++;
188 name = g_realloc(name, len);
189 if (*t == '+')
190 name[len - 1] = ' ';
191 else if (*t == '&') {
192 name[len - 1] = 0;
193 sscanf(t, "&amp;Exchange=%d", &exchange);
194 c = t + strlen("&amp;Exchange=x");
195 break;
196 } else
197 name[len - 1] = *t;
198 t++;
200 cr = g_new0(struct chat_room, 1);
201 strcpy(cr->name, name);
202 cr->exchange = exchange;
203 item = gtk_list_item_new_with_label(name);
204 gtk_widget_show(item);
205 items = g_list_append(items, item);
206 gtk_object_set_user_data(GTK_OBJECT(item), cr);
207 g_free(name);
209 c++;
211 gtk_list_append_items(GTK_LIST(cp->list1), items);
214 static void refresh_list(GtkWidget *w, gpointer *m)
216 grab_url("http://www.aim.com/community/chats.adp", FALSE, ref_list_callback, NULL);
219 static void add_chat(GtkWidget *w, gpointer *m)
221 GList *sel = GTK_LIST(cp->list1)->selection;
222 struct chat_room *cr, *cr2;
223 GList *crs = chat_rooms;
224 GtkWidget *item;
226 if (sel) {
227 cr = (struct chat_room *)gtk_object_get_user_data(GTK_OBJECT(sel->data));
228 } else
229 return;
231 while (crs) {
232 cr2 = (struct chat_room *)crs->data;
233 if (!g_strcasecmp(cr->name, cr2->name))
234 return;
235 crs = crs->next;
237 item = gtk_list_item_new_with_label(cr->name);
238 cr2 = g_new0(struct chat_room, 1);
239 strcpy(cr2->name, cr->name);
240 cr2->exchange = cr->exchange;
241 gtk_object_set_user_data(GTK_OBJECT(item), cr2);
242 gtk_widget_show(item);
243 sel = g_list_append(NULL, item);
244 gtk_list_append_items(GTK_LIST(cp->list2), sel);
245 chat_rooms = g_list_append(chat_rooms, cr2);
247 setup_buddy_chats();
248 save_chat_prefs();
251 static void remove_chat(GtkWidget *w, gpointer *m)
253 GList *sel = GTK_LIST(cp->list2)->selection;
254 struct chat_room *cr;
255 GList *crs;
256 GtkWidget *item;
258 if (sel) {
259 item = (GtkWidget *)sel->data;
260 cr = (struct chat_room *)gtk_object_get_user_data(GTK_OBJECT(item));
261 } else
262 return;
264 chat_rooms = g_list_remove(chat_rooms, cr);
267 gtk_list_clear_items(GTK_LIST(cp->list2), 0, -1);
269 if (g_list_length(chat_rooms) == 0)
270 chat_rooms = NULL;
272 crs = chat_rooms;
274 while (crs) {
275 cr = (struct chat_room *)crs->data;
276 item = gtk_list_item_new_with_label(cr->name);
277 gtk_object_set_user_data(GTK_OBJECT(item), cr);
278 gtk_widget_show(item);
279 gtk_list_append_items(GTK_LIST(cp->list2), g_list_append(NULL, item));
282 crs = crs->next;
285 setup_buddy_chats();
286 save_chat_prefs();
289 static void parent_destroy()
291 if (parent)
292 gtk_widget_destroy(parent);
293 parent = NULL;
296 void gaim_plugin_config()
298 GtkWidget *vbox;
299 GtkWidget *frame;
300 GtkWidget *box;
301 GtkWidget *table;
302 GtkWidget *rem_button, *add_button, *ref_button;
303 GtkWidget *list1, *list2;
304 GtkWidget *label;
305 GtkWidget *sw1, *sw2;
306 GtkWidget *item;
307 GtkWidget *hbox;
308 GtkWidget *button;
309 GList *crs = chat_rooms;
310 GList *items = NULL;
311 struct chat_room *cr;
313 if (parent) {
314 gtk_widget_show(parent);
315 return;
318 if (cp)
319 g_free(cp);
320 cp = g_new0(struct chat_page, 1);
322 parent = gtk_window_new(GTK_WINDOW_TOPLEVEL);
323 gtk_widget_set_usize(parent, 300, 400);
324 gtk_window_set_title(GTK_WINDOW(parent), "Chat Rooms");
325 gtk_window_set_wmclass(GTK_WINDOW(parent), "chatlist", "Gaim");
326 gtk_widget_realize(parent);
327 aol_icon(parent->window);
328 gtk_signal_connect(GTK_OBJECT(parent), "destroy",
329 GTK_SIGNAL_FUNC(parent_destroy), NULL);
331 vbox = gtk_vbox_new(FALSE, 0);
332 gtk_container_add(GTK_CONTAINER(parent), vbox);
333 gtk_widget_show(vbox);
335 hbox = gtk_hbox_new(FALSE, 0);
336 gtk_box_pack_end(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
337 gtk_widget_show(hbox);
339 button = picture_button(parent, _("Close"), cancel_xpm);
340 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 5);
341 gtk_signal_connect(GTK_OBJECT(button), "clicked",
342 GTK_SIGNAL_FUNC(parent_destroy), NULL);
344 frame = gtk_frame_new(_("Chat Rooms"));
345 gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 5);
346 gtk_widget_show(frame);
348 box = gtk_vbox_new(FALSE, 5);
349 gtk_container_set_border_width(GTK_CONTAINER(box), 5);
350 gtk_container_add(GTK_CONTAINER(frame), box);
351 gtk_widget_show(box);
353 table = gtk_table_new(4, 2, FALSE);
354 gtk_widget_show(table);
356 gtk_box_pack_start(GTK_BOX(box), table, TRUE, TRUE, 0);
358 list1 = gtk_list_new();
359 list2 = gtk_list_new();
360 sw1 = gtk_scrolled_window_new(NULL, NULL);
361 sw2 = gtk_scrolled_window_new(NULL, NULL);
363 ref_button = picture_button(parent, _("Refresh"), refresh_xpm);
364 add_button = picture_button(parent, _("Add"), gnome_add_xpm);
365 rem_button = picture_button(parent, _("Remove"), gnome_remove_xpm);
366 gtk_widget_show(list1);
367 gtk_widget_show(sw1);
368 gtk_widget_show(list2);
369 gtk_widget_show(sw2);
371 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(sw1), list1);
372 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(sw2), list2);
374 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw1),
375 GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
376 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw2),
377 GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
379 cp->list1 = list1;
380 cp->list2 = list2;
382 gtk_signal_connect(GTK_OBJECT(ref_button), "clicked", GTK_SIGNAL_FUNC(refresh_list), cp);
383 gtk_signal_connect(GTK_OBJECT(rem_button), "clicked", GTK_SIGNAL_FUNC(remove_chat), cp);
384 gtk_signal_connect(GTK_OBJECT(add_button), "clicked", GTK_SIGNAL_FUNC(add_chat), cp);
388 label = gtk_label_new(_("List of available chats"));
389 gtk_widget_show(label);
391 gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, GTK_SHRINK, GTK_SHRINK, 0, 0);
392 gtk_table_attach(GTK_TABLE(table), ref_button, 0, 1, 1, 2, GTK_SHRINK, GTK_SHRINK, 0, 0);
393 gtk_table_attach(GTK_TABLE(table), sw1, 0, 1, 2, 3,
394 GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 5, 5);
395 gtk_table_attach(GTK_TABLE(table), add_button, 0, 1, 3, 4, GTK_SHRINK, GTK_SHRINK, 0, 0);
398 label = gtk_label_new(_("List of subscribed chats"));
399 gtk_widget_show(label);
401 gtk_table_attach(GTK_TABLE(table), label, 1, 2, 0, 1, GTK_SHRINK, GTK_SHRINK, 0, 0);
402 gtk_table_attach(GTK_TABLE(table), sw2, 1, 2, 2, 3,
403 GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 5, 5);
404 gtk_table_attach(GTK_TABLE(table), rem_button, 1, 2, 3, 4, GTK_SHRINK, GTK_SHRINK, 0, 0);
407 item = gtk_list_item_new_with_label(_("Gaim Chat"));
408 cr = g_new0(struct chat_room, 1);
409 strcpy(cr->name, _("Gaim Chat"));
410 cr->exchange = 4;
411 gtk_object_set_user_data(GTK_OBJECT(item), cr);
412 gtk_widget_show(item);
413 gtk_list_append_items(GTK_LIST(list1), g_list_append(NULL, item));
416 while (crs) {
417 cr = (struct chat_room *)crs->data;
418 item = gtk_list_item_new_with_label(cr->name);
419 gtk_object_set_user_data(GTK_OBJECT(item), cr);
420 gtk_widget_show(item);
421 items = g_list_append(items, item);
423 crs = crs->next;
426 gtk_list_append_items(GTK_LIST(list2), items);
428 gtk_widget_show(parent);
431 static void handle_signon(struct gaim_connection *gc)
433 setup_buddy_chats();
436 char *gaim_plugin_init(GModule *m)
438 restore_chat_prefs();
439 gaim_signal_connect(m, event_signon, handle_signon, NULL);
440 return NULL;
443 void gaim_plugin_remove()
445 if (parent)
446 gtk_widget_destroy(parent);
447 parent = NULL;
449 if (item)
450 gtk_tree_remove_item(GTK_TREE(buddies), item);
451 item = NULL;
453 while (chat_rooms) {
454 g_free(chat_rooms->data);
455 chat_rooms = g_list_remove(chat_rooms, chat_rooms->data);
458 if (cp)
459 g_free(cp);
460 cp = NULL;
463 char *name()
465 return "Chat List";
468 char *description()
470 return "Allows you to add chat rooms to your buddy list. Click the configure button to choose"
471 " which rooms.";