Merged in default (pull request #594)
[pidgin-git.git] / pidgin / gtkdialogs.c
blobe4442e923f6839611380a66b9fabb6548a09011e
1 /* pidgin
3 * Pidgin is the legal property of its developers, whose names are too numerous
4 * to list here. Please refer to the COPYRIGHT file distributed with this
5 * source distribution.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
22 #include <talkatu.h>
24 #include "internal.h"
25 #include "pidgin.h"
26 #include "package_revision.h"
27 #ifdef HAVE_MESON_CONFIG
28 #include "meson-config.h"
29 #endif
31 #include "debug.h"
32 #include "notify.h"
33 #include "plugins.h"
34 #include "protocol.h"
35 #include "request.h"
36 #include "util.h"
37 #include "core.h"
39 #include "gtkblist.h"
40 #include "gtkdialogs.h"
41 #include "gtkutils.h"
42 #include "pidginlog.h"
43 #include "pidginstock.h"
45 #ifdef USE_GSTREAMER
46 #include <gst/gst.h>
47 #endif
49 #include "gtk3compat.h"
51 static GList *dialogwindows = NULL;
53 struct _PidginGroupMergeObject {
54 PurpleGroup* parent;
55 char *new_name;
58 void
59 pidgin_dialogs_destroy_all()
61 while (dialogwindows) {
62 gtk_widget_destroy(dialogwindows->data);
63 dialogwindows = g_list_remove(dialogwindows, dialogwindows->data);
67 static void destroy_win(GtkWidget *button, GtkWidget *win)
69 gtk_widget_destroy(win);
72 #if 0
73 /* This function puts the version number onto the pixmap we use in the 'about'
74 * screen in Pidgin. */
75 static void
76 pidgin_logo_versionize(GdkPixbuf **original, GtkWidget *widget) {
77 GdkPixmap *pixmap;
78 GtkStyle *style;
79 PangoContext *context;
80 PangoLayout *layout;
81 gchar *markup;
82 gint width, height;
83 gint lwidth = 0, lheight = 0;
85 style = gtk_widget_get_style(widget);
87 gdk_pixbuf_render_pixmap_and_mask(*original, &pixmap, NULL, 255);
88 width = gdk_pixbuf_get_width(*original);
89 height = gdk_pixbuf_get_height(*original);
90 g_object_unref(G_OBJECT(*original));
92 context = gtk_widget_get_pango_context(widget);
93 layout = pango_layout_new(context);
95 markup = g_strdup_printf("<span foreground=\"#000000\">%s</span>", DISPLAY_VERSION);
96 pango_layout_set_font_description(layout, style->font_desc);
97 pango_layout_set_markup(layout, markup, strlen(markup));
98 g_free(markup);
100 pango_layout_get_pixel_size(layout, &lwidth, &lheight);
101 gdk_draw_layout(GDK_DRAWABLE(pixmap), style->bg_gc[GTK_STATE_NORMAL],
102 width - (lwidth + 3), 1, layout);
103 g_object_unref(G_OBJECT(layout));
105 *original = gdk_pixbuf_get_from_drawable(NULL, pixmap, NULL,
106 0, 0, 0, 0,
107 width, height);
108 g_object_unref(G_OBJECT(pixmap));
110 #endif
112 /* Note: Frees 'string' */
113 static GtkWidget *
114 pidgin_build_help_dialog(const char *title, const char *role, GString *string)
116 GtkWidget *win, *vbox, *logo, *view, *button;
117 GdkPixbuf *pixbuf;
118 GtkTextBuffer *buffer;
119 AtkObject *obj;
120 char *filename, *tmp;
122 win = pidgin_create_dialog(title, 0, role, TRUE);
123 vbox = pidgin_dialog_get_vbox_with_properties(GTK_DIALOG(win), FALSE, 0);
124 gtk_window_set_default_size(GTK_WINDOW(win), 475, 450);
126 /* Generate a logo with a version number */
127 filename = g_build_filename(PURPLE_DATADIR,
128 "pixmaps", "pidgin", "logo.png", NULL);
129 pixbuf = pidgin_pixbuf_new_from_file(filename);
130 g_free(filename);
132 /* Insert the logo */
133 logo = gtk_image_new_from_pixbuf(pixbuf);
134 if (pixbuf)
135 g_object_unref(G_OBJECT(pixbuf));
136 obj = gtk_widget_get_accessible(logo);
137 tmp = g_strconcat(PIDGIN_NAME, " " DISPLAY_VERSION, NULL);
138 atk_object_set_description(obj, tmp);
139 g_free(tmp);
140 gtk_box_pack_start(GTK_BOX(vbox), logo, FALSE, FALSE, 0);
142 buffer = talkatu_html_buffer_new();
143 talkatu_markup_append_html(TALKATU_BUFFER(buffer), string->str, -1);
145 view = talkatu_view_new_with_buffer(buffer);
146 gtk_box_pack_start(GTK_BOX(vbox), view, TRUE, TRUE, 0);
148 button = pidgin_dialog_add_button(GTK_DIALOG(win), _("_Close"),
149 G_CALLBACK(destroy_win), win);
151 gtk_widget_set_can_default(button, TRUE);
152 gtk_widget_grab_default(button);
154 gtk_widget_show_all(win);
155 gtk_window_present(GTK_WINDOW(win));
157 g_string_free(string, TRUE);
159 return win;
162 void pidgin_dialogs_plugins_info(void)
164 GString *str;
165 GList *plugins, *l = NULL;
166 PurplePlugin *plugin = NULL;
167 PurplePluginInfo *info;
168 GPluginPluginInfo *ginfo;
169 PurplePluginExtraCb extra_cb;
170 char *title = g_strdup_printf(_("%s Plugin Information"), PIDGIN_NAME);
171 char *pname = NULL, *authors, *pauthors, *pextra;
172 const char *pver, *plicense, *pwebsite, *pid;
173 gboolean ploaded, ploadable;
174 const char * const *authorlist;
175 guint n_authors;
176 static GtkWidget *plugins_info = NULL;
178 str = g_string_sized_new(4096);
180 g_string_append_printf(str, "<h2>%s</h2><dl>", _("Plugin Information"));
182 plugins = purple_plugins_find_all();
184 for(l = plugins; l; l = l->next) {
185 plugin = PURPLE_PLUGIN(l->data);
186 info = purple_plugin_get_info(plugin);
187 ginfo = GPLUGIN_PLUGIN_INFO(info);
188 extra_cb = purple_plugin_info_get_extra_cb(info);
190 pname = g_markup_escape_text(
191 gplugin_plugin_info_get_name(ginfo), -1);
192 authorlist = gplugin_plugin_info_get_authors(ginfo);
194 if (authorlist) {
195 authors = g_strjoinv(", ", (gchar **)authorlist);
196 n_authors = g_strv_length((gchar **)authorlist);
197 } else {
198 authors = NULL;
199 n_authors = 0;
202 if (authors)
203 pauthors = g_markup_escape_text(authors, -1);
204 else
205 pauthors = NULL;
207 pver = gplugin_plugin_info_get_version(ginfo);
208 plicense = gplugin_plugin_info_get_license_id(ginfo);
209 pwebsite = gplugin_plugin_info_get_website(ginfo);
210 pid = gplugin_plugin_info_get_id(ginfo);
211 ploadable = !purple_plugin_info_get_error(info);
212 ploaded = purple_plugin_is_loaded(plugin);
214 if (ploaded && extra_cb)
215 pextra = extra_cb(plugin);
216 else
217 pextra = NULL;
219 g_string_append_printf(str, "<dt>%s</dt><dd>", pname);
220 if (pauthors) {
221 g_string_append_printf(str, "<b>%s:</b> %s<br/>",
222 (n_authors > 1 ? "Authors" : "Author"),
223 pauthors);
225 g_string_append_printf(str,
226 "<b>Version:</b> %s<br/>"
227 "<b>License:</b> %s<br/>"
228 "<b>Website:</b> %s<br/>"
229 "<b>ID String:</b> %s<br/>"
230 "<b>Extra:</b> %s<br/>"
231 "<b>Loadable:</b> %s<br/>"
232 "<b>Loaded:</b> %s"
233 "</dd><br/>",
234 pver ? pver : "",
235 plicense ? plicense : "",
236 pwebsite ? pwebsite : "",
237 pid,
238 pextra ? pextra : "",
239 ploadable ? "Yes" : "<span style=\"color: #FF0000;\"><b>No</b></span>",
240 ploaded ? "Yes" : "No");
242 g_free(pname);
243 g_free(pextra);
244 g_free(pauthors);
245 g_free(authors);
247 g_list_free(plugins);
249 g_string_append(str, "</dl><br/>");
251 plugins_info = pidgin_build_help_dialog(title, "plugins_info", str);
252 g_signal_connect(G_OBJECT(plugins_info), "destroy",
253 G_CALLBACK(gtk_widget_destroyed), &plugins_info);
254 g_free(title);
257 static void
258 pidgin_dialogs_im_cb(gpointer data, PurpleRequestFields *fields)
260 PurpleAccount *account;
261 const char *username;
263 account = purple_request_fields_get_account(fields, "account");
264 username = purple_request_fields_get_string(fields, "screenname");
266 pidgin_dialogs_im_with_user(account, username);
269 static gboolean
270 pidgin_dialogs_im_name_validator(PurpleRequestField *field, gchar **errmsg,
271 void *_fields)
273 PurpleRequestFields *fields = _fields;
274 PurpleAccount *account;
275 PurpleProtocol *protocol;
276 const char *username;
277 gboolean valid;
279 account = purple_request_fields_get_account(fields, "account");
280 protocol = purple_protocols_find(purple_account_get_protocol_id(account));
281 username = purple_request_fields_get_string(fields, "screenname");
283 valid = purple_validate(protocol, username);
285 if (errmsg && !valid)
286 *errmsg = g_strdup(_("Invalid username"));
288 return valid;
291 void
292 pidgin_dialogs_im(void)
294 PurpleRequestFields *fields;
295 PurpleRequestFieldGroup *group;
296 PurpleRequestField *field;
298 fields = purple_request_fields_new();
300 group = purple_request_field_group_new(NULL);
301 purple_request_fields_add_group(fields, group);
303 field = purple_request_field_string_new("screenname", _("_Name"), NULL, FALSE);
304 purple_request_field_set_type_hint(field, "screenname");
305 purple_request_field_set_required(field, TRUE);
306 purple_request_field_set_validator(field, pidgin_dialogs_im_name_validator, fields);
307 purple_request_field_group_add_field(group, field);
309 field = purple_request_field_account_new("account", _("_Account"), NULL);
310 purple_request_field_set_type_hint(field, "account");
311 purple_request_field_set_visible(field,
312 (purple_connections_get_all() != NULL &&
313 purple_connections_get_all()->next != NULL));
314 purple_request_field_set_required(field, TRUE);
315 purple_request_field_group_add_field(group, field);
317 purple_request_fields(
318 purple_blist_get_default(), _("New Instant Message"), NULL,
319 _("Please enter the username or alias of the person "
320 "you would like to IM."),
321 fields, _("OK"), G_CALLBACK(pidgin_dialogs_im_cb), _("Cancel"),
322 NULL, NULL, NULL);
325 void
326 pidgin_dialogs_im_with_user(PurpleAccount *account, const char *username)
328 PurpleIMConversation *im;
330 g_return_if_fail(account != NULL);
331 g_return_if_fail(username != NULL);
333 im = purple_conversations_find_im_with_account(username, account);
335 if (im == NULL)
336 im = purple_im_conversation_new(account, username);
338 pidgin_conv_attach_to_conversation(PURPLE_CONVERSATION(im));
339 purple_conversation_present(PURPLE_CONVERSATION(im));
342 static gboolean
343 pidgin_dialogs_ee(const char *ee)
345 GtkWidget *window;
346 GtkWidget *hbox;
347 GtkWidget *label;
348 GtkWidget *img;
349 gchar *norm = purple_strreplace(ee, "rocksmyworld", "");
351 label = gtk_label_new(NULL);
352 if (purple_strequal(norm, "zilding"))
353 gtk_label_set_markup(GTK_LABEL(label),
354 "<span weight=\"bold\" size=\"large\" foreground=\"purple\">Amazing! Simply Amazing!</span>");
355 else if (purple_strequal(norm, "robflynn"))
356 gtk_label_set_markup(GTK_LABEL(label),
357 "<span weight=\"bold\" size=\"large\" foreground=\"#1f6bad\">Pimpin\' Penguin Style! *Waddle Waddle*</span>");
358 else if (purple_strequal(norm, "flynorange"))
359 gtk_label_set_markup(GTK_LABEL(label),
360 "<span weight=\"bold\" size=\"large\" foreground=\"blue\">You should be me. I'm so cute!</span>");
361 else if (purple_strequal(norm, "ewarmenhoven"))
362 gtk_label_set_markup(GTK_LABEL(label),
363 "<span weight=\"bold\" size=\"large\" foreground=\"orange\">Now that's what I like!</span>");
364 else if (purple_strequal(norm, "markster97"))
365 gtk_label_set_markup(GTK_LABEL(label),
366 "<span weight=\"bold\" size=\"large\" foreground=\"brown\">Ahh, and excellent choice!</span>");
367 else if (purple_strequal(norm, "seanegn"))
368 gtk_label_set_markup(GTK_LABEL(label),
369 "<span weight=\"bold\" size=\"large\" foreground=\"#009900\">Everytime you click my name, an angel gets its wings.</span>");
370 else if (purple_strequal(norm, "chipx86"))
371 gtk_label_set_markup(GTK_LABEL(label),
372 "<span weight=\"bold\" size=\"large\" foreground=\"red\">This sunflower seed taste like pizza.</span>");
373 else if (purple_strequal(norm, "markdoliner"))
374 gtk_label_set_markup(GTK_LABEL(label),
375 "<span weight=\"bold\" size=\"large\" foreground=\"#6364B1\">Hey! I was in that tumbleweed!</span>");
376 else if (purple_strequal(norm, "lschiere"))
377 gtk_label_set_markup(GTK_LABEL(label),
378 "<span weight=\"bold\" size=\"large\" foreground=\"gray\">I'm not anything.</span>");
379 g_free(norm);
381 if (strlen(gtk_label_get_label(GTK_LABEL(label))) <= 0)
382 return FALSE;
384 window = gtk_dialog_new_with_buttons(PIDGIN_ALERT_TITLE, NULL, 0,
385 _("_Close"), GTK_RESPONSE_OK, NULL);
386 gtk_dialog_set_default_response (GTK_DIALOG(window), GTK_RESPONSE_OK);
387 g_signal_connect(G_OBJECT(window), "response", G_CALLBACK(gtk_widget_destroy), NULL);
389 gtk_container_set_border_width (GTK_CONTAINER(window), PIDGIN_HIG_BOX_SPACE);
390 gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
391 gtk_box_set_spacing(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(window))),
392 PIDGIN_HIG_BORDER);
393 gtk_container_set_border_width(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(window))),
394 PIDGIN_HIG_BOX_SPACE);
396 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, PIDGIN_HIG_BORDER);
397 gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(window))), hbox);
398 img = gtk_image_new_from_icon_name("dialog-cool", GTK_ICON_SIZE_DIALOG);
399 gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0);
401 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
402 gtk_label_set_xalign(GTK_LABEL(label), 0);
403 gtk_label_set_yalign(GTK_LABEL(label), 0);
404 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
406 gtk_widget_show_all(window);
407 return TRUE;
410 static void
411 pidgin_dialogs_info_cb(gpointer data, PurpleRequestFields *fields)
413 char *username;
414 gboolean found = FALSE;
415 PurpleAccount *account;
417 account = purple_request_fields_get_account(fields, "account");
419 username = g_strdup(purple_normalize(account,
420 purple_request_fields_get_string(fields, "screenname")));
422 if (username != NULL && purple_str_has_suffix(username, "rocksmyworld"))
423 found = pidgin_dialogs_ee(username);
425 if (!found && username != NULL && *username != '\0' && account != NULL)
426 pidgin_retrieve_user_info(purple_account_get_connection(account), username);
428 g_free(username);
431 void
432 pidgin_dialogs_info(void)
434 PurpleRequestFields *fields;
435 PurpleRequestFieldGroup *group;
436 PurpleRequestField *field;
438 fields = purple_request_fields_new();
440 group = purple_request_field_group_new(NULL);
441 purple_request_fields_add_group(fields, group);
443 field = purple_request_field_string_new("screenname", _("_Name"), NULL, FALSE);
444 purple_request_field_set_type_hint(field, "screenname");
445 purple_request_field_set_required(field, TRUE);
446 purple_request_field_group_add_field(group, field);
448 field = purple_request_field_account_new("account", _("_Account"), NULL);
449 purple_request_field_set_type_hint(field, "account");
450 purple_request_field_set_visible(field,
451 (purple_connections_get_all() != NULL &&
452 purple_connections_get_all()->next != NULL));
453 purple_request_field_set_required(field, TRUE);
454 purple_request_field_group_add_field(group, field);
456 purple_request_fields(
457 purple_blist_get_default(), _("Get User Info"), NULL,
458 _("Please enter the username or alias of the person "
459 "whose info you would like to view."),
460 fields, _("OK"), G_CALLBACK(pidgin_dialogs_info_cb),
461 _("Cancel"), NULL, NULL, NULL);
464 static void
465 pidgin_dialogs_log_cb(gpointer data, PurpleRequestFields *fields)
467 char *username;
468 PurpleAccount *account;
469 GSList *cur;
471 account = purple_request_fields_get_account(fields, "account");
473 username = g_strdup(purple_normalize(account,
474 purple_request_fields_get_string(fields, "screenname")));
476 if (username != NULL && *username != '\0' && account != NULL)
478 PidginBuddyList *gtkblist = pidgin_blist_get_default_gtk_blist();
479 GSList *buddies;
481 pidgin_set_cursor(gtkblist->window, GDK_WATCH);
483 buddies = purple_blist_find_buddies(account, username);
484 for (cur = buddies; cur != NULL; cur = cur->next)
486 PurpleBlistNode *node = cur->data;
487 if ((node != NULL) && ((node->prev != NULL) || (node->next != NULL)))
489 pidgin_log_show_contact((PurpleContact *)node->parent);
490 g_slist_free(buddies);
491 pidgin_clear_cursor(gtkblist->window);
492 g_free(username);
493 return;
496 g_slist_free(buddies);
498 pidgin_log_show(PURPLE_LOG_IM, username, account);
500 pidgin_clear_cursor(gtkblist->window);
503 g_free(username);
507 * TODO - This needs to deal with logs of all types, not just IM logs.
509 void
510 pidgin_dialogs_log(void)
512 PurpleRequestFields *fields;
513 PurpleRequestFieldGroup *group;
514 PurpleRequestField *field;
516 fields = purple_request_fields_new();
518 group = purple_request_field_group_new(NULL);
519 purple_request_fields_add_group(fields, group);
521 field = purple_request_field_string_new("screenname", _("_Name"), NULL, FALSE);
522 purple_request_field_set_type_hint(field, "screenname-all");
523 purple_request_field_set_required(field, TRUE);
524 purple_request_field_group_add_field(group, field);
526 field = purple_request_field_account_new("account", _("_Account"), NULL);
528 /* purple_request_field_account_new() only sets a default value if you're
529 * connected, and it sets it from the list of connected accounts. Since
530 * we're going to set show_all here, it makes sense to use the first
531 * account, not the first connected account. */
532 if (purple_accounts_get_all() != NULL) {
533 purple_request_field_account_set_default_value(field, purple_accounts_get_all()->data);
534 purple_request_field_account_set_value(field, purple_accounts_get_all()->data);
537 purple_request_field_set_type_hint(field, "account");
538 purple_request_field_account_set_show_all(field, TRUE);
539 purple_request_field_set_visible(field,
540 (purple_accounts_get_all() != NULL &&
541 purple_accounts_get_all()->next != NULL));
542 purple_request_field_set_required(field, TRUE);
543 purple_request_field_group_add_field(group, field);
545 purple_request_fields(
546 purple_blist_get_default(), _("View User Log"), NULL,
547 _("Please enter the username or alias of the person "
548 "whose log you would like to view."),
549 fields, _("OK"), G_CALLBACK(pidgin_dialogs_log_cb), _("Cancel"),
550 NULL, NULL, NULL);
553 static void
554 pidgin_dialogs_alias_buddy_cb(PurpleBuddy *buddy, const char *new_alias)
556 purple_buddy_set_local_alias(buddy, new_alias);
557 purple_serv_alias_buddy(buddy);
560 void
561 pidgin_dialogs_alias_buddy(PurpleBuddy *buddy)
563 gchar *secondary;
565 g_return_if_fail(buddy != NULL);
567 secondary = g_strdup_printf(_("Enter an alias for %s."), purple_buddy_get_name(buddy));
569 purple_request_input(NULL, _("Alias Buddy"), NULL,
570 secondary, purple_buddy_get_local_alias(buddy), FALSE, FALSE, NULL,
571 _("Alias"), G_CALLBACK(pidgin_dialogs_alias_buddy_cb),
572 _("Cancel"), NULL,
573 purple_request_cpar_from_account(purple_buddy_get_account(buddy)),
574 buddy);
576 g_free(secondary);
579 static void
580 pidgin_dialogs_alias_chat_cb(PurpleChat *chat, const char *new_alias)
582 purple_chat_set_alias(chat, new_alias);
585 void
586 pidgin_dialogs_alias_chat(PurpleChat *chat)
588 gchar *alias;
590 g_return_if_fail(chat != NULL);
592 g_object_get(chat, "alias", &alias, NULL);
594 purple_request_input(NULL, _("Alias Chat"), NULL,
595 _("Enter an alias for this chat."),
596 alias, FALSE, FALSE, NULL,
597 _("Alias"), G_CALLBACK(pidgin_dialogs_alias_chat_cb),
598 _("Cancel"), NULL,
599 purple_request_cpar_from_account(purple_chat_get_account(chat)),
600 chat);
602 g_free(alias);
605 static void
606 pidgin_dialogs_remove_contact_cb(PurpleContact *contact)
608 PurpleBlistNode *bnode, *cnode;
609 PurpleGroup *group;
611 cnode = (PurpleBlistNode *)contact;
612 group = (PurpleGroup*)cnode->parent;
613 for (bnode = cnode->child; bnode; bnode = bnode->next) {
614 PurpleBuddy *buddy = (PurpleBuddy*)bnode;
615 if (purple_account_is_connected(purple_buddy_get_account(buddy)))
616 purple_account_remove_buddy(purple_buddy_get_account(buddy), buddy, group);
618 purple_blist_remove_contact(contact);
621 void
622 pidgin_dialogs_remove_contact(PurpleContact *contact)
624 PurpleBuddy *buddy = purple_contact_get_priority_buddy(contact);
626 g_return_if_fail(contact != NULL);
627 g_return_if_fail(buddy != NULL);
629 if (PURPLE_BLIST_NODE(contact)->child == PURPLE_BLIST_NODE(buddy) &&
630 PURPLE_BLIST_NODE(buddy)->next == NULL) {
631 pidgin_dialogs_remove_buddy(buddy);
632 } else {
633 gchar *text;
634 int contact_size = purple_counting_node_get_total_size(PURPLE_COUNTING_NODE(contact));
635 text = g_strdup_printf(
636 ngettext(
637 "You are about to remove the contact containing %s "
638 "and %d other buddy from your buddy list. Do you "
639 "want to continue?",
640 "You are about to remove the contact containing %s "
641 "and %d other buddies from your buddy list. Do you "
642 "want to continue?", contact_size - 1),
643 purple_buddy_get_name(buddy), contact_size - 1);
645 purple_request_action(contact, NULL, _("Remove Contact"), text, 0,
646 NULL,
647 contact, 2,
648 _("_Remove Contact"), G_CALLBACK(pidgin_dialogs_remove_contact_cb),
649 _("Cancel"),
650 NULL);
652 g_free(text);
656 static void free_ggmo(struct _PidginGroupMergeObject *ggp)
658 g_free(ggp->new_name);
659 g_free(ggp);
662 static void
663 pidgin_dialogs_merge_groups_cb(struct _PidginGroupMergeObject *GGP)
665 purple_group_set_name(GGP->parent, GGP->new_name);
666 free_ggmo(GGP);
669 void
670 pidgin_dialogs_merge_groups(PurpleGroup *source, const char *new_name)
672 gchar *text;
673 struct _PidginGroupMergeObject *ggp;
675 g_return_if_fail(source != NULL);
676 g_return_if_fail(new_name != NULL);
678 text = g_strdup_printf(
679 _("You are about to merge the group called %s into the group "
680 "called %s. Do you want to continue?"), purple_group_get_name(source), new_name);
682 ggp = g_new(struct _PidginGroupMergeObject, 1);
683 ggp->parent = source;
684 ggp->new_name = g_strdup(new_name);
686 purple_request_action(source, NULL, _("Merge Groups"), text, 0,
687 NULL,
688 ggp, 2,
689 _("_Merge Groups"), G_CALLBACK(pidgin_dialogs_merge_groups_cb),
690 _("Cancel"), G_CALLBACK(free_ggmo));
692 g_free(text);
695 static void
696 pidgin_dialogs_remove_group_cb(PurpleGroup *group)
698 PurpleBlistNode *cnode, *bnode;
700 cnode = ((PurpleBlistNode*)group)->child;
702 while (cnode) {
703 if (PURPLE_IS_CONTACT(cnode)) {
704 bnode = cnode->child;
705 cnode = cnode->next;
706 while (bnode) {
707 PurpleBuddy *buddy;
708 if (PURPLE_IS_BUDDY(bnode)) {
709 buddy = (PurpleBuddy*)bnode;
710 bnode = bnode->next;
711 if (purple_account_is_connected(purple_buddy_get_account(buddy))) {
712 purple_account_remove_buddy(purple_buddy_get_account(buddy), buddy, group);
713 purple_blist_remove_buddy(buddy);
715 } else {
716 bnode = bnode->next;
719 } else if (PURPLE_IS_CHAT(cnode)) {
720 PurpleChat *chat = (PurpleChat *)cnode;
721 cnode = cnode->next;
722 if (purple_account_is_connected(purple_chat_get_account(chat)))
723 purple_blist_remove_chat(chat);
724 } else {
725 cnode = cnode->next;
729 purple_blist_remove_group(group);
732 void
733 pidgin_dialogs_remove_group(PurpleGroup *group)
735 gchar *text;
737 g_return_if_fail(group != NULL);
739 text = g_strdup_printf(_("You are about to remove the group %s and all its members from your buddy list. Do you want to continue?"),
740 purple_group_get_name(group));
742 purple_request_action(group, NULL, _("Remove Group"), text, 0,
743 NULL,
744 group, 2,
745 _("_Remove Group"), G_CALLBACK(pidgin_dialogs_remove_group_cb),
746 _("Cancel"), NULL);
748 g_free(text);
751 /* XXX - Some of this should be moved into the core, methinks. */
752 static void
753 pidgin_dialogs_remove_buddy_cb(PurpleBuddy *buddy)
755 PurpleGroup *group;
756 gchar *name;
757 PurpleAccount *account;
759 group = purple_buddy_get_group(buddy);
760 name = g_strdup(purple_buddy_get_name(buddy)); /* purple_buddy_get_name() is a crasher after remove_buddy */
761 account = purple_buddy_get_account(buddy);
763 purple_debug_info("blist", "Removing '%s' from buddy list.\n", purple_buddy_get_name(buddy));
764 /* TODO - Should remove from blist first... then call purple_account_remove_buddy()? */
765 purple_account_remove_buddy(account, buddy, group);
766 purple_blist_remove_buddy(buddy);
768 g_free(name);
771 void
772 pidgin_dialogs_remove_buddy(PurpleBuddy *buddy)
774 gchar *text;
776 g_return_if_fail(buddy != NULL);
778 text = g_strdup_printf(_("You are about to remove %s from your buddy list. Do you want to continue?"),
779 purple_buddy_get_name(buddy));
781 purple_request_action(buddy, NULL, _("Remove Buddy"), text, 0,
782 purple_request_cpar_from_account(
783 purple_buddy_get_account(buddy)),
784 buddy, 2, _("_Remove Buddy"),
785 G_CALLBACK(pidgin_dialogs_remove_buddy_cb), _("Cancel"), NULL);
787 g_free(text);
790 static void
791 pidgin_dialogs_remove_chat_cb(PurpleChat *chat)
793 purple_blist_remove_chat(chat);
796 void
797 pidgin_dialogs_remove_chat(PurpleChat *chat)
799 const gchar *name;
800 gchar *text;
802 g_return_if_fail(chat != NULL);
804 name = purple_chat_get_name(chat);
805 text = g_strdup_printf(_("You are about to remove the chat %s from your buddy list. Do you want to continue?"),
806 name ? name : "");
808 purple_request_action(chat, NULL, _("Remove Chat"), text, 0,
809 purple_request_cpar_from_account(purple_chat_get_account(chat)),
810 chat, 2, _("_Remove Chat"),
811 G_CALLBACK(pidgin_dialogs_remove_chat_cb), _("Cancel"), NULL);
813 g_free(text);