Mercurial > pidgin
annotate plugins/chatlist.c @ 5205:fefad67de2c7
[gaim-migrate @ 5573]
I had a damn good commit message, but it was eaten. Let's try it again.
Announcing, Gaim Plugin API version 2.0, or GPAPIV2.0 for short.
There are lots'a cool thingies here.
Okay now, this isn't as cool as the previous message, but:
1) There's now a single entry function for all plugin types. It returns a
detailed information structure on the plugin. This removes a lot of the
ugliness from old plugins. Oh yeah, libicq wasn't converted to this, so
if you use it, well, you shouldn't have used it anyway, but now you
can't! bwahahaha. Use AIM/ICQ.
2) There are now 3 types of plugins: Standard, Loader, and Protocol
plugins.
Standard plugins are, well, standard, compiled plugins.
Loader plugins load other plugins. For example, the perl support is now
a loader plugin. It loads perl scripts. In the future, we'll have
Ruby and Python loader plugins.
Protocol plugins are, well, protocol plugins... yeah...
3) Plugins have unique IDs, so they can be referred to or automatically
updated from a plugin database in the future. Neat, huh?
4) Plugins will have dependency support in the future, and can be hidden,
so if you have, say, a logging core plugin, it won't have to show up,
but then you load the GTK+ logging plugin and it'll auto-load the core
plugin. Core/UI split plugins!
5) There will eventually be custom plugin signals and RPC of some sort, for
the core/ui split plugins.
So, okay, back up .gaimrc.
I'd like to thank my parents for their support, javabsp for helping convert
a bunch of protocol plugins, and Etan for helping convert a bunch of
standard plugins.
Have fun. If you have any problems, please let me know, but you probably
won't have anything major happen. You will have to convert your plugins,
though, and I'm not guaranteeing that all perl scripts will still work.
I'll end up changing the perl script API eventually, so I know they won't
down the road. Don't worry, though. It'll be mass cool.
faceprint wants me to just commit the damn code already. So, here we go!!!
..
..
I need a massage. From a young, cute girl. Are there any young, cute girls
in the audience? IM me plz k thx.
committer: Tailor Script <tailor@pidgin.im>
| author | Christian Hammond <chipx86@chipx86.com> |
|---|---|
| date | Fri, 25 Apr 2003 06:47:33 +0000 |
| parents | 8e55a4d362a3 |
| children | 1f901484599d |
| rev | line source |
|---|---|
|
4202
59751fe608c5
[gaim-migrate @ 4438]
Christian Hammond <chipx86@chipx86.com>
parents:
4165
diff
changeset
|
1 #include "config.h" |
|
59751fe608c5
[gaim-migrate @ 4438]
Christian Hammond <chipx86@chipx86.com>
parents:
4165
diff
changeset
|
2 |
|
59751fe608c5
[gaim-migrate @ 4438]
Christian Hammond <chipx86@chipx86.com>
parents:
4165
diff
changeset
|
3 #ifndef GAIM_PLUGINS |
| 2241 | 4 #define GAIM_PLUGINS |
|
4202
59751fe608c5
[gaim-migrate @ 4438]
Christian Hammond <chipx86@chipx86.com>
parents:
4165
diff
changeset
|
5 #endif |
| 2241 | 6 |
| 4635 | 7 #ifdef GTK_DISABLE_DEPRECATED |
| 8 #undef GTK_DISABLE_DEPRECATED | |
| 9 #endif | |
| 10 | |
| 11 #define GTK_ENABLE_BROKEN | |
| 12 | |
| 2241 | 13 #include "proxy.h" |
| 14 #include "gaim.h" | |
| 15 | |
| 16 #include <stdlib.h> | |
|
2272
4ecc9a9a75d8
[gaim-migrate @ 2282]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2241
diff
changeset
|
17 #include <string.h> |
| 3630 | 18 #ifdef _WIN32 |
| 19 #include "win32dep.h" | |
| 20 #endif | |
| 2241 | 21 |
| 2993 | 22 #define AOL_SRCHSTR "aim:GoChat?RoomName=" |
|
2417
5473c8c5378d
[gaim-migrate @ 2430]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2356
diff
changeset
|
23 |
| 2241 | 24 struct chat_page { |
| 25 GtkWidget *list1; | |
| 26 GtkWidget *list2; | |
| 27 }; | |
| 28 | |
| 29 struct chat_room { | |
| 30 char name[80]; | |
| 31 int exchange; | |
| 32 }; | |
| 33 | |
| 34 static GtkWidget *item = NULL; /* this is the parent tree */ | |
| 35 static GList *chat_rooms = NULL; | |
| 36 | |
| 37 static struct chat_page *cp = NULL; | |
| 38 | |
| 39 static void des_item() | |
| 40 { | |
| 41 if (item) | |
| 42 gtk_widget_destroy(item); | |
| 43 item = NULL; | |
| 44 } | |
| 45 | |
| 46 static void handle_click_chat(GtkWidget *widget, GdkEventButton * event, struct chat_room *cr) | |
| 47 { | |
| 48 if (event->type == GDK_2BUTTON_PRESS && event->button == 1) { | |
| 49 GList *m = g_list_append(NULL, cr->name); | |
| 50 int *x = g_new0(int, 1); | |
| 51 *x = cr->exchange; | |
| 52 m = g_list_append(m, x); | |
| 53 serv_join_chat(connections->data, m); | |
| 54 g_free(x); | |
| 55 g_list_free(m); | |
| 56 } | |
| 57 } | |
| 58 | |
| 59 static void setup_buddy_chats() | |
| 60 { | |
| 61 GList *crs = chat_rooms; | |
| 62 GtkWidget *tree; | |
| 63 | |
| 64 if (!blist) | |
| 65 return; | |
| 66 | |
| 67 if (item) | |
| 68 gtk_tree_remove_item(GTK_TREE(buddies), item); | |
| 69 item = NULL; | |
| 70 | |
| 71 if (!chat_rooms) | |
| 72 return; | |
| 73 | |
| 74 item = gtk_tree_item_new_with_label(_("Buddy Chat")); | |
|
4165
07a3d1fae88f
[gaim-migrate @ 4394]
Christian Hammond <chipx86@chipx86.com>
parents:
4164
diff
changeset
|
75 g_signal_connect(GTK_OBJECT(item), "destroy", G_CALLBACK(des_item), NULL); |
| 2241 | 76 gtk_tree_append(GTK_TREE(buddies), item); |
| 77 gtk_tree_item_expand(GTK_TREE_ITEM(item)); | |
| 78 gtk_widget_show(item); | |
| 79 | |
| 80 tree = gtk_tree_new(); | |
| 81 gtk_tree_item_set_subtree(GTK_TREE_ITEM(item), tree); | |
| 82 gtk_widget_show(tree); | |
| 83 | |
| 84 while (crs) { | |
| 85 struct chat_room *cr = (struct chat_room *)crs->data; | |
| 86 GtkWidget *titem = gtk_tree_item_new_with_label(cr->name); | |
| 87 gtk_object_set_user_data(GTK_OBJECT(titem), cr); | |
| 88 gtk_tree_append(GTK_TREE(tree), titem); | |
| 89 gtk_widget_show(titem); | |
|
4165
07a3d1fae88f
[gaim-migrate @ 4394]
Christian Hammond <chipx86@chipx86.com>
parents:
4164
diff
changeset
|
90 g_signal_connect(GTK_OBJECT(titem), "button_press_event", |
|
07a3d1fae88f
[gaim-migrate @ 4394]
Christian Hammond <chipx86@chipx86.com>
parents:
4164
diff
changeset
|
91 G_CALLBACK(handle_click_chat), cr); |
| 2241 | 92 crs = crs->next; |
| 93 } | |
|
2900
aaaca46b507b
[gaim-migrate @ 2913]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2892
diff
changeset
|
94 |
|
aaaca46b507b
[gaim-migrate @ 2913]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2892
diff
changeset
|
95 gtk_tree_item_expand(GTK_TREE_ITEM(item)); |
| 2241 | 96 } |
| 97 | |
| 98 static void save_chat_prefs() | |
| 99 { | |
| 100 FILE *f; | |
| 101 char path[1024]; | |
| 102 char *x = gaim_user_dir(); | |
| 103 GList *crs = chat_rooms; | |
| 104 | |
| 105 g_snprintf(path, sizeof(path), "%s/%s", x, "chats"); | |
| 106 f = fopen(path, "w"); | |
| 3930 | 107 if (!f) |
| 2241 | 108 return; |
| 109 while (crs) { | |
| 110 struct chat_room *cr = crs->data; | |
| 111 crs = crs->next; | |
| 112 fprintf(f, "%s\n%d\n", cr->name, cr->exchange); | |
| 113 } | |
| 114 fclose(f); | |
| 115 } | |
| 116 | |
| 117 static void restore_chat_prefs() | |
| 118 { | |
| 119 FILE *f; | |
| 120 char path[1024]; | |
| 121 char *x = gaim_user_dir(); | |
| 122 char buf[1024]; | |
| 123 | |
| 124 g_snprintf(path, sizeof(path), "%s/%s", x, "chats"); | |
| 125 f = fopen(path, "r"); | |
| 3930 | 126 if (!f) |
| 2241 | 127 return; |
| 128 while (fgets(buf, 1024, f)) { | |
| 129 struct chat_room *cr = g_new0(struct chat_room, 1); | |
|
2356
ddf404cd9757
[gaim-migrate @ 2369]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2272
diff
changeset
|
130 g_snprintf(cr->name, sizeof(cr->name), "%s", g_strchomp(buf)); |
| 2241 | 131 if (!fgets(buf, 1024, f)) { |
| 132 g_free(cr); | |
| 133 break; | |
| 134 } | |
| 135 cr->exchange = atoi(buf); | |
| 136 chat_rooms = g_list_append(chat_rooms, cr); | |
| 137 } | |
| 138 fclose(f); | |
| 139 setup_buddy_chats(); | |
| 140 } | |
| 141 | |
| 4327 | 142 static void ref_list_callback(gpointer data, char *text, unsigned long len) |
| 2241 | 143 { |
| 144 char *c; | |
| 145 GtkWidget *item; | |
| 146 GList *items = GTK_LIST(cp->list1)->children; | |
| 147 struct chat_room *cr; | |
| 148 c = text; | |
| 149 | |
| 150 if (!text) | |
| 151 return; | |
| 152 | |
| 153 while (items) { | |
| 154 g_free(gtk_object_get_user_data(GTK_OBJECT(items->data))); | |
| 155 items = items->next; | |
| 156 } | |
| 157 | |
| 158 items = NULL; | |
| 159 | |
| 160 gtk_list_clear_items(GTK_LIST(cp->list1), 0, -1); | |
| 161 | |
| 162 item = gtk_list_item_new_with_label(_("Gaim Chat")); | |
| 163 cr = g_new0(struct chat_room, 1); | |
| 164 strcpy(cr->name, _("Gaim Chat")); | |
| 165 cr->exchange = 4; | |
| 166 gtk_object_set_user_data(GTK_OBJECT(item), cr); | |
| 167 gtk_widget_show(item); | |
| 168 | |
| 169 items = g_list_append(NULL, item); | |
| 170 | |
| 171 while (c) { | |
| 172 if (c - text > len - 30) | |
| 173 break; /* assume no chat rooms 30 from end, padding */ | |
| 174 if (!g_strncasecmp(AOL_SRCHSTR, c, strlen(AOL_SRCHSTR))) { | |
| 175 char *t; | |
| 176 int len = 0; | |
| 3000 | 177 int exchange = 5; |
| 2241 | 178 char *name = NULL; |
| 179 | |
| 180 c += strlen(AOL_SRCHSTR); | |
| 181 t = c; | |
| 182 while (t) { | |
| 183 len++; | |
| 184 name = g_realloc(name, len); | |
| 185 if (*t == '+') | |
| 186 name[len - 1] = ' '; | |
| 187 else if (*t == '&') { | |
| 188 name[len - 1] = 0; | |
| 3000 | 189 sscanf(t, "&Exchange=%d", &exchange); |
| 190 c = t + strlen("&Exchange=x"); | |
| 2241 | 191 break; |
| 192 } else | |
| 193 name[len - 1] = *t; | |
| 194 t++; | |
| 195 } | |
| 196 cr = g_new0(struct chat_room, 1); | |
| 197 strcpy(cr->name, name); | |
| 198 cr->exchange = exchange; | |
|
4164
a55c2a0ddcd4
[gaim-migrate @ 4393]
Christian Hammond <chipx86@chipx86.com>
parents:
3930
diff
changeset
|
199 printf("Adding '%s'\n", name); |
| 2241 | 200 item = gtk_list_item_new_with_label(name); |
| 201 gtk_widget_show(item); | |
| 202 items = g_list_append(items, item); | |
| 203 gtk_object_set_user_data(GTK_OBJECT(item), cr); | |
| 204 g_free(name); | |
| 205 } | |
| 206 c++; | |
| 207 } | |
| 208 gtk_list_append_items(GTK_LIST(cp->list1), items); | |
| 209 } | |
| 210 | |
| 211 static void refresh_list(GtkWidget *w, gpointer *m) | |
| 212 { | |
|
2872
30828b83143d
[gaim-migrate @ 2885]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2692
diff
changeset
|
213 grab_url("http://www.aim.com/community/chats.adp", FALSE, ref_list_callback, NULL); |
| 2241 | 214 } |
| 215 | |
| 216 static void add_chat(GtkWidget *w, gpointer *m) | |
| 217 { | |
| 218 GList *sel = GTK_LIST(cp->list1)->selection; | |
| 219 struct chat_room *cr, *cr2; | |
| 220 GList *crs = chat_rooms; | |
| 221 GtkWidget *item; | |
| 222 | |
| 223 if (sel) { | |
| 224 cr = (struct chat_room *)gtk_object_get_user_data(GTK_OBJECT(sel->data)); | |
| 225 } else | |
| 226 return; | |
| 227 | |
| 228 while (crs) { | |
| 229 cr2 = (struct chat_room *)crs->data; | |
| 230 if (!g_strcasecmp(cr->name, cr2->name)) | |
| 231 return; | |
| 232 crs = crs->next; | |
| 233 } | |
| 234 item = gtk_list_item_new_with_label(cr->name); | |
| 235 cr2 = g_new0(struct chat_room, 1); | |
| 236 strcpy(cr2->name, cr->name); | |
| 237 cr2->exchange = cr->exchange; | |
| 238 gtk_object_set_user_data(GTK_OBJECT(item), cr2); | |
| 239 gtk_widget_show(item); | |
| 240 sel = g_list_append(NULL, item); | |
| 241 gtk_list_append_items(GTK_LIST(cp->list2), sel); | |
| 242 chat_rooms = g_list_append(chat_rooms, cr2); | |
| 243 | |
| 244 setup_buddy_chats(); | |
| 245 save_chat_prefs(); | |
| 246 } | |
| 247 | |
| 248 static void remove_chat(GtkWidget *w, gpointer *m) | |
| 249 { | |
| 250 GList *sel = GTK_LIST(cp->list2)->selection; | |
| 251 struct chat_room *cr; | |
| 252 GList *crs; | |
| 253 GtkWidget *item; | |
| 254 | |
| 255 if (sel) { | |
| 256 item = (GtkWidget *)sel->data; | |
| 257 cr = (struct chat_room *)gtk_object_get_user_data(GTK_OBJECT(item)); | |
| 258 } else | |
| 259 return; | |
| 260 | |
| 261 chat_rooms = g_list_remove(chat_rooms, cr); | |
| 262 | |
| 263 | |
| 264 gtk_list_clear_items(GTK_LIST(cp->list2), 0, -1); | |
| 265 | |
| 266 if (g_list_length(chat_rooms) == 0) | |
| 267 chat_rooms = NULL; | |
| 268 | |
| 269 crs = chat_rooms; | |
| 270 | |
| 271 while (crs) { | |
| 272 cr = (struct chat_room *)crs->data; | |
| 273 item = gtk_list_item_new_with_label(cr->name); | |
| 274 gtk_object_set_user_data(GTK_OBJECT(item), cr); | |
| 275 gtk_widget_show(item); | |
| 276 gtk_list_append_items(GTK_LIST(cp->list2), g_list_append(NULL, item)); | |
| 277 | |
| 278 | |
| 279 crs = crs->next; | |
| 280 } | |
| 281 | |
| 282 setup_buddy_chats(); | |
| 283 save_chat_prefs(); | |
| 284 } | |
| 285 | |
| 3630 | 286 G_MODULE_EXPORT GtkWidget *gaim_plugin_config_gtk() |
| 2241 | 287 { |
| 3565 | 288 GtkWidget *ret, *vbox; |
| 2241 | 289 GtkWidget *list1, *list2; |
| 290 GtkWidget *sw1, *sw2; | |
| 3565 | 291 GtkWidget *ref_button, *add_button, *rem_button; |
| 292 GtkWidget *table, *label; | |
| 293 struct chat_room *cr = NULL; | |
| 2241 | 294 GList *items = NULL; |
| 3565 | 295 GList *crs = chat_rooms; |
| 296 | |
| 2241 | 297 if (cp) |
| 3565 | 298 g_free(cp); |
| 299 cp = g_new0(struct chat_page, 1); | |
| 2241 | 300 |
| 301 | |
| 3565 | 302 ret = gtk_vbox_new(FALSE, 18); |
| 303 gtk_container_set_border_width (GTK_CONTAINER (ret), 12); | |
| 2241 | 304 |
| 3565 | 305 vbox = make_frame(ret, _("Chat Rooms")); |
| 2241 | 306 |
| 307 table = gtk_table_new(4, 2, FALSE); | |
| 308 | |
| 3565 | 309 gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, TRUE, 0); |
| 2241 | 310 |
| 311 list1 = gtk_list_new(); | |
| 312 list2 = gtk_list_new(); | |
| 313 sw1 = gtk_scrolled_window_new(NULL, NULL); | |
| 314 sw2 = gtk_scrolled_window_new(NULL, NULL); | |
| 315 | |
| 5024 | 316 ref_button = gaim_pixbuf_button_from_stock(_("Refresh"), GTK_STOCK_REFRESH, GAIM_BUTTON_HORIZONTAL); |
| 317 add_button = gaim_pixbuf_button_from_stock(_("Add"), GTK_STOCK_ADD, GAIM_BUTTON_HORIZONTAL); | |
| 318 rem_button = gaim_pixbuf_button_from_stock(_("Remove"), GTK_STOCK_REMOVE, GAIM_BUTTON_HORIZONTAL); | |
| 2241 | 319 |
| 320 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(sw1), list1); | |
| 321 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(sw2), list2); | |
| 322 | |
| 323 cp->list1 = list1; | |
| 324 cp->list2 = list2; | |
| 325 | |
|
4165
07a3d1fae88f
[gaim-migrate @ 4394]
Christian Hammond <chipx86@chipx86.com>
parents:
4164
diff
changeset
|
326 g_signal_connect(GTK_OBJECT(ref_button), "clicked", G_CALLBACK(refresh_list), cp); |
|
07a3d1fae88f
[gaim-migrate @ 4394]
Christian Hammond <chipx86@chipx86.com>
parents:
4164
diff
changeset
|
327 g_signal_connect(GTK_OBJECT(rem_button), "clicked", G_CALLBACK(remove_chat), cp); |
|
07a3d1fae88f
[gaim-migrate @ 4394]
Christian Hammond <chipx86@chipx86.com>
parents:
4164
diff
changeset
|
328 g_signal_connect(GTK_OBJECT(add_button), "clicked", G_CALLBACK(add_chat), cp); |
| 2241 | 329 |
| 330 label = gtk_label_new(_("List of available chats")); | |
| 331 | |
| 332 gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, GTK_SHRINK, GTK_SHRINK, 0, 0); | |
| 333 gtk_table_attach(GTK_TABLE(table), ref_button, 0, 1, 1, 2, GTK_SHRINK, GTK_SHRINK, 0, 0); | |
| 334 gtk_table_attach(GTK_TABLE(table), sw1, 0, 1, 2, 3, | |
| 335 GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 5, 5); | |
| 336 gtk_table_attach(GTK_TABLE(table), add_button, 0, 1, 3, 4, GTK_SHRINK, GTK_SHRINK, 0, 0); | |
| 337 | |
| 338 | |
| 339 label = gtk_label_new(_("List of subscribed chats")); | |
| 340 | |
| 341 gtk_table_attach(GTK_TABLE(table), label, 1, 2, 0, 1, GTK_SHRINK, GTK_SHRINK, 0, 0); | |
| 342 gtk_table_attach(GTK_TABLE(table), sw2, 1, 2, 2, 3, | |
| 343 GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 5, 5); | |
| 344 gtk_table_attach(GTK_TABLE(table), rem_button, 1, 2, 3, 4, GTK_SHRINK, GTK_SHRINK, 0, 0); | |
| 345 | |
| 346 | |
| 347 item = gtk_list_item_new_with_label(_("Gaim Chat")); | |
| 348 cr = g_new0(struct chat_room, 1); | |
| 349 strcpy(cr->name, _("Gaim Chat")); | |
| 350 cr->exchange = 4; | |
| 351 gtk_object_set_user_data(GTK_OBJECT(item), cr); | |
| 352 gtk_list_append_items(GTK_LIST(list1), g_list_append(NULL, item)); | |
| 353 | |
| 354 | |
| 355 while (crs) { | |
| 356 cr = (struct chat_room *)crs->data; | |
| 357 item = gtk_list_item_new_with_label(cr->name); | |
| 358 gtk_object_set_user_data(GTK_OBJECT(item), cr); | |
| 359 items = g_list_append(items, item); | |
| 360 | |
| 361 crs = crs->next; | |
| 362 } | |
| 363 | |
| 364 gtk_list_append_items(GTK_LIST(list2), items); | |
| 3565 | 365 gtk_widget_show_all(ret); |
| 366 return ret; | |
| 2241 | 367 } |
| 368 | |
| 369 static void handle_signon(struct gaim_connection *gc) | |
| 370 { | |
| 371 setup_buddy_chats(); | |
| 372 } | |
| 373 | |
| 3630 | 374 G_MODULE_EXPORT char *gaim_plugin_init(GModule *m) |
| 2241 | 375 { |
| 376 restore_chat_prefs(); | |
| 377 gaim_signal_connect(m, event_signon, handle_signon, NULL); | |
| 378 return NULL; | |
| 379 } | |
| 380 | |
| 3630 | 381 G_MODULE_EXPORT void gaim_plugin_remove() |
| 2241 | 382 { |
| 383 if (item) | |
| 384 gtk_tree_remove_item(GTK_TREE(buddies), item); | |
| 385 item = NULL; | |
| 386 | |
| 387 while (chat_rooms) { | |
| 388 g_free(chat_rooms->data); | |
| 389 chat_rooms = g_list_remove(chat_rooms, chat_rooms->data); | |
| 390 } | |
| 391 | |
| 392 if (cp) | |
| 393 g_free(cp); | |
| 394 cp = NULL; | |
| 395 } | |
| 396 | |
| 3551 | 397 struct gaim_plugin_description desc; |
| 398 struct gaim_plugin_description *gaim_plugin_desc() { | |
|
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5024
diff
changeset
|
399 desc.api_version = GAIM_PLUGIN_API_VERSION; |
| 4585 | 400 desc.name = g_strdup(_("Chat List")); |
| 3551 | 401 desc.version = g_strdup(VERSION); |
| 4585 | 402 desc.description = g_strdup(_("Allows you to add chat rooms to your buddy list.")); |
| 3551 | 403 desc.authors = g_strdup("Eric Warmenhoven <eric@warmenhoven.org>"); |
| 404 desc.url = g_strdup(WEBSITE); | |
| 405 return &desc; | |
| 406 } | |
| 407 | |
| 3630 | 408 G_MODULE_EXPORT char *name() |
| 2241 | 409 { |
| 4585 | 410 return _("Chat List"); |
| 2241 | 411 } |
| 412 | |
| 3630 | 413 G_MODULE_EXPORT char *description() |
| 2241 | 414 { |
| 4585 | 415 return _("Allows you to add chat rooms to your buddy list. Click the configure button to choose" |
| 416 " which rooms."); | |
| 2241 | 417 } |
