* Pidgin is the legal property of its developers, whose names are too numerous * to list here. Please refer to the COPYRIGHT file distributed with this * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA #include "package_revision.h" #include "meson-config.h" static GList *dialogwindows = NULL; struct _PidginGroupMergeObject { pidgin_dialogs_destroy_all() g_list_free_full(dialogwindows, (GDestroyNotify)gtk_widget_destroy); static void destroy_win(GtkWidget *button, GtkWidget *win) /* This function puts the version number onto the pixmap we use in the 'about' pidgin_logo_versionize(GdkPixbuf **original, GtkWidget *widget) { gint lwidth = 0, lheight = 0; style = gtk_widget_get_style(widget); gdk_pixbuf_render_pixmap_and_mask(*original, &pixmap, NULL, 255); width = gdk_pixbuf_get_width(*original); height = gdk_pixbuf_get_height(*original); g_object_unref(G_OBJECT(*original)); context = gtk_widget_get_pango_context(widget); layout = pango_layout_new(context); markup = g_strdup_printf("<span foreground=\"#000000\">%s</span>", DISPLAY_VERSION); pango_layout_set_font_description(layout, style->font_desc); pango_layout_set_markup(layout, markup, strlen(markup)); pango_layout_get_pixel_size(layout, &lwidth, &lheight); gdk_draw_layout(GDK_DRAWABLE(pixmap), style->bg_gc[GTK_STATE_NORMAL], width - (lwidth + 3), 1, layout); g_object_unref(G_OBJECT(layout)); *original = gdk_pixbuf_get_from_drawable(NULL, pixmap, NULL, g_object_unref(G_OBJECT(pixmap)); /* Note: Frees 'string' */ pidgin_build_help_dialog(const char *title, const char *role, GString *string) GtkWidget *win, *vbox, *logo, *view, *button; win = pidgin_create_dialog(title, 0, role, TRUE); vbox = pidgin_dialog_get_vbox_with_properties(GTK_DIALOG(win), FALSE, 0); gtk_window_set_default_size(GTK_WINDOW(win), 475, 450); /* Generate a logo with a version number */ filename = g_build_filename(PURPLE_DATADIR, "pixmaps", "pidgin", "logo.png", NULL); pixbuf = pidgin_pixbuf_new_from_file(filename); logo = gtk_image_new_from_pixbuf(pixbuf); g_object_unref(G_OBJECT(pixbuf)); obj = gtk_widget_get_accessible(logo); tmp = g_strconcat(PIDGIN_NAME, " " DISPLAY_VERSION, NULL); atk_object_set_description(obj, tmp); gtk_box_pack_start(GTK_BOX(vbox), logo, FALSE, FALSE, 0); buffer = talkatu_html_buffer_new(); talkatu_markup_append_html(TALKATU_BUFFER(buffer), string->str, -1); view = talkatu_view_new_with_buffer(buffer); gtk_box_pack_start(GTK_BOX(vbox), view, TRUE, TRUE, 0); button = pidgin_dialog_add_button(GTK_DIALOG(win), _("_Close"), G_CALLBACK(destroy_win), win); gtk_widget_set_can_default(button, TRUE); gtk_widget_grab_default(button); gtk_widget_show_all(win); gtk_window_present(GTK_WINDOW(win)); g_string_free(string, TRUE); void pidgin_dialogs_plugins_info(void) GList *plugins, *l = NULL; PurplePlugin *plugin = NULL; GPluginPluginInfo *ginfo; PurplePluginExtraCb extra_cb; char *title = g_strdup_printf(_("%s Plugin Information"), PIDGIN_NAME); char *pname = NULL, *authors, *pauthors, *pextra; const char *pver, *plicense, *pwebsite, *pid; gboolean ploaded, ploadable; const char * const *authorlist; static GtkWidget *plugins_info = NULL; str = g_string_sized_new(4096); g_string_append_printf(str, "<h2>%s</h2><dl>", _("Plugin Information")); plugins = purple_plugins_find_all(); for(l = plugins; l; l = l->next) { plugin = PURPLE_PLUGIN(l->data); info = purple_plugin_get_info(plugin); ginfo = GPLUGIN_PLUGIN_INFO(info); extra_cb = purple_plugin_info_get_extra_cb(info); pname = g_markup_escape_text( gplugin_plugin_info_get_name(ginfo), -1); authorlist = gplugin_plugin_info_get_authors(ginfo); authors = g_strjoinv(", ", (gchar **)authorlist); n_authors = g_strv_length((gchar **)authorlist); pauthors = g_markup_escape_text(authors, -1); pver = gplugin_plugin_info_get_version(ginfo); plicense = gplugin_plugin_info_get_license_id(ginfo); pwebsite = gplugin_plugin_info_get_website(ginfo); pid = gplugin_plugin_info_get_id(ginfo); ploadable = !purple_plugin_info_get_error(info); ploaded = purple_plugin_is_loaded(plugin); pextra = extra_cb(plugin); g_string_append_printf(str, "<dt>%s</dt><dd>", pname); g_string_append_printf(str, "<b>%s:</b> %s<br/>", (n_authors > 1 ? "Authors" : "Author"), g_string_append_printf(str, "<b>Version:</b> %s<br/>" "<b>License:</b> %s<br/>" "<b>Website:</b> %s<br/>" "<b>ID String:</b> %s<br/>" "<b>Loadable:</b> %s<br/>" plicense ? plicense : "", pwebsite ? pwebsite : "", ploadable ? "Yes" : "<span style=\"color: #FF0000;\"><b>No</b></span>", g_string_append(str, "</dl><br/>"); plugins_info = pidgin_build_help_dialog(title, "plugins_info", str); g_signal_connect(G_OBJECT(plugins_info), "destroy", G_CALLBACK(gtk_widget_destroyed), &plugins_info); pidgin_dialogs_im_cb(gpointer data, PurpleRequestFields *fields) account = purple_request_fields_get_account(fields, "account"); username = purple_request_fields_get_string(fields, "screenname"); pidgin_dialogs_im_with_user(account, username); pidgin_dialogs_im_name_validator(PurpleRequestField *field, gchar **errmsg, PurpleRequestFields *fields = _fields; PurpleProtocol *protocol; account = purple_request_fields_get_account(fields, "account"); protocol = purple_protocols_find(purple_account_get_protocol_id(account)); username = purple_request_fields_get_string(fields, "screenname"); valid = purple_validate(protocol, username); *errmsg = g_strdup(_("Invalid username")); PurpleRequestFields *fields; PurpleRequestFieldGroup *group; PurpleRequestField *field; fields = purple_request_fields_new(); group = purple_request_field_group_new(NULL); purple_request_fields_add_group(fields, group); field = purple_request_field_string_new("screenname", _("_Name"), NULL, FALSE); purple_request_field_set_type_hint(field, "screenname"); purple_request_field_set_required(field, TRUE); purple_request_field_set_validator(field, pidgin_dialogs_im_name_validator, fields); purple_request_field_group_add_field(group, field); field = purple_request_field_account_new("account", _("_Account"), NULL); purple_request_field_set_type_hint(field, "account"); purple_request_field_set_visible(field, (purple_connections_get_all() != NULL && purple_connections_get_all()->next != NULL)); purple_request_field_set_required(field, TRUE); purple_request_field_group_add_field(group, field); purple_blist_get_default(), _("New Instant Message"), NULL, _("Please enter the username or alias of the person " "you would like to IM."), fields, _("OK"), G_CALLBACK(pidgin_dialogs_im_cb), _("Cancel"), pidgin_dialogs_im_with_user(PurpleAccount *account, const char *username) PurpleIMConversation *im; g_return_if_fail(account != NULL); g_return_if_fail(username != NULL); im = purple_conversations_find_im_with_account(username, account); im = purple_im_conversation_new(account, username); pidgin_conv_attach_to_conversation(PURPLE_CONVERSATION(im)); purple_conversation_present(PURPLE_CONVERSATION(im)); pidgin_dialogs_ee(const char *ee) gchar *norm = purple_strreplace(ee, "rocksmyworld", ""); label = gtk_label_new(NULL); if (purple_strequal(norm, "zilding")) gtk_label_set_markup(GTK_LABEL(label), "<span weight=\"bold\" size=\"large\" foreground=\"purple\">Amazing! Simply Amazing!</span>"); else if (purple_strequal(norm, "robflynn")) gtk_label_set_markup(GTK_LABEL(label), "<span weight=\"bold\" size=\"large\" foreground=\"#1f6bad\">Pimpin\' Penguin Style! *Waddle Waddle*</span>"); else if (purple_strequal(norm, "flynorange")) gtk_label_set_markup(GTK_LABEL(label), "<span weight=\"bold\" size=\"large\" foreground=\"blue\">You should be me. I'm so cute!</span>"); else if (purple_strequal(norm, "ewarmenhoven")) gtk_label_set_markup(GTK_LABEL(label), "<span weight=\"bold\" size=\"large\" foreground=\"orange\">Now that's what I like!</span>"); else if (purple_strequal(norm, "markster97")) gtk_label_set_markup(GTK_LABEL(label), "<span weight=\"bold\" size=\"large\" foreground=\"brown\">Ahh, and excellent choice!</span>"); else if (purple_strequal(norm, "seanegn")) gtk_label_set_markup(GTK_LABEL(label), "<span weight=\"bold\" size=\"large\" foreground=\"#009900\">Everytime you click my name, an angel gets its wings.</span>"); else if (purple_strequal(norm, "chipx86")) gtk_label_set_markup(GTK_LABEL(label), "<span weight=\"bold\" size=\"large\" foreground=\"red\">This sunflower seed taste like pizza.</span>"); else if (purple_strequal(norm, "markdoliner")) gtk_label_set_markup(GTK_LABEL(label), "<span weight=\"bold\" size=\"large\" foreground=\"#6364B1\">Hey! I was in that tumbleweed!</span>"); else if (purple_strequal(norm, "lschiere")) gtk_label_set_markup(GTK_LABEL(label), "<span weight=\"bold\" size=\"large\" foreground=\"gray\">I'm not anything.</span>"); if (strlen(gtk_label_get_label(GTK_LABEL(label))) <= 0) window = gtk_dialog_new_with_buttons(PIDGIN_ALERT_TITLE, NULL, 0, _("_Close"), GTK_RESPONSE_OK, NULL); gtk_dialog_set_default_response (GTK_DIALOG(window), GTK_RESPONSE_OK); g_signal_connect(G_OBJECT(window), "response", G_CALLBACK(gtk_widget_destroy), NULL); gtk_container_set_border_width (GTK_CONTAINER(window), PIDGIN_HIG_BOX_SPACE); gtk_window_set_resizable(GTK_WINDOW(window), FALSE); gtk_box_set_spacing(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(window))), gtk_container_set_border_width(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(window))), hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, PIDGIN_HIG_BORDER); gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(window))), hbox); img = gtk_image_new_from_icon_name("dialog-cool", GTK_ICON_SIZE_DIALOG); gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0); gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); gtk_label_set_xalign(GTK_LABEL(label), 0); gtk_label_set_yalign(GTK_LABEL(label), 0); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); gtk_widget_show_all(window); pidgin_dialogs_info_cb(gpointer data, PurpleRequestFields *fields) account = purple_request_fields_get_account(fields, "account"); username = g_strdup(purple_normalize(account, purple_request_fields_get_string(fields, "screenname"))); if (username != NULL && purple_str_has_suffix(username, "rocksmyworld")) found = pidgin_dialogs_ee(username); if (!found && username != NULL && *username != '\0' && account != NULL) pidgin_retrieve_user_info(purple_account_get_connection(account), username); pidgin_dialogs_info(void) PurpleRequestFields *fields; PurpleRequestFieldGroup *group; PurpleRequestField *field; fields = purple_request_fields_new(); group = purple_request_field_group_new(NULL); purple_request_fields_add_group(fields, group); field = purple_request_field_string_new("screenname", _("_Name"), NULL, FALSE); purple_request_field_set_type_hint(field, "screenname"); purple_request_field_set_required(field, TRUE); purple_request_field_group_add_field(group, field); field = purple_request_field_account_new("account", _("_Account"), NULL); purple_request_field_set_type_hint(field, "account"); purple_request_field_set_visible(field, (purple_connections_get_all() != NULL && purple_connections_get_all()->next != NULL)); purple_request_field_set_required(field, TRUE); purple_request_field_group_add_field(group, field); purple_blist_get_default(), _("Get User Info"), NULL, _("Please enter the username or alias of the person " "whose info you would like to view."), fields, _("OK"), G_CALLBACK(pidgin_dialogs_info_cb), _("Cancel"), NULL, NULL, NULL); pidgin_dialogs_log_cb(gpointer data, PurpleRequestFields *fields) account = purple_request_fields_get_account(fields, "account"); username = g_strdup(purple_normalize(account, purple_request_fields_get_string(fields, "screenname"))); if (username != NULL && *username != '\0' && account != NULL) PidginBuddyList *gtkblist = pidgin_blist_get_default_gtk_blist(); pidgin_set_cursor(gtkblist->window, GDK_WATCH); buddies = purple_blist_find_buddies(account, username); for (cur = buddies; cur != NULL; cur = cur->next) PurpleBlistNode *node = cur->data; if ((node != NULL) && ((node->prev != NULL) || (node->next != NULL))) pidgin_log_show_contact((PurpleContact *)node->parent); pidgin_clear_cursor(gtkblist->window); pidgin_log_show(PURPLE_LOG_IM, username, account); pidgin_clear_cursor(gtkblist->window); * TODO - This needs to deal with logs of all types, not just IM logs. PurpleRequestFields *fields; PurpleRequestFieldGroup *group; PurpleRequestField *field; fields = purple_request_fields_new(); group = purple_request_field_group_new(NULL); purple_request_fields_add_group(fields, group); field = purple_request_field_string_new("screenname", _("_Name"), NULL, FALSE); purple_request_field_set_type_hint(field, "screenname-all"); purple_request_field_set_required(field, TRUE); purple_request_field_group_add_field(group, field); field = purple_request_field_account_new("account", _("_Account"), NULL); /* purple_request_field_account_new() only sets a default value if you're * connected, and it sets it from the list of connected accounts. Since * we're going to set show_all here, it makes sense to use the first * account, not the first connected account. */ if (purple_accounts_get_all() != NULL) { purple_request_field_account_set_default_value(field, purple_accounts_get_all()->data); purple_request_field_account_set_value(field, purple_accounts_get_all()->data); purple_request_field_set_type_hint(field, "account"); purple_request_field_account_set_show_all(field, TRUE); purple_request_field_set_visible(field, (purple_accounts_get_all() != NULL && purple_accounts_get_all()->next != NULL)); purple_request_field_set_required(field, TRUE); purple_request_field_group_add_field(group, field); purple_blist_get_default(), _("View User Log"), NULL, _("Please enter the username or alias of the person " "whose log you would like to view."), fields, _("OK"), G_CALLBACK(pidgin_dialogs_log_cb), _("Cancel"), pidgin_dialogs_alias_buddy_cb(PurpleBuddy *buddy, const char *new_alias) purple_buddy_set_local_alias(buddy, new_alias); purple_serv_alias_buddy(buddy); pidgin_dialogs_alias_buddy(PurpleBuddy *buddy) g_return_if_fail(buddy != NULL); secondary = g_strdup_printf(_("Enter an alias for %s."), purple_buddy_get_name(buddy)); purple_request_input(NULL, _("Alias Buddy"), NULL, secondary, purple_buddy_get_local_alias(buddy), FALSE, FALSE, NULL, _("Alias"), G_CALLBACK(pidgin_dialogs_alias_buddy_cb), purple_request_cpar_from_account(purple_buddy_get_account(buddy)), pidgin_dialogs_alias_chat_cb(PurpleChat *chat, const char *new_alias) purple_chat_set_alias(chat, new_alias); pidgin_dialogs_alias_chat(PurpleChat *chat) g_return_if_fail(chat != NULL); g_object_get(chat, "alias", &alias, NULL); purple_request_input(NULL, _("Alias Chat"), NULL, _("Enter an alias for this chat."), alias, FALSE, FALSE, NULL, _("Alias"), G_CALLBACK(pidgin_dialogs_alias_chat_cb), purple_request_cpar_from_account(purple_chat_get_account(chat)), pidgin_dialogs_remove_contact_cb(PurpleContact *contact) PurpleBlistNode *bnode, *cnode; cnode = (PurpleBlistNode *)contact; group = (PurpleGroup*)cnode->parent; for (bnode = cnode->child; bnode; bnode = bnode->next) { PurpleBuddy *buddy = (PurpleBuddy*)bnode; if (purple_account_is_connected(purple_buddy_get_account(buddy))) purple_account_remove_buddy(purple_buddy_get_account(buddy), buddy, group); purple_blist_remove_contact(contact); pidgin_dialogs_remove_contact(PurpleContact *contact) PurpleBuddy *buddy = purple_contact_get_priority_buddy(contact); g_return_if_fail(contact != NULL); g_return_if_fail(buddy != NULL); if (PURPLE_BLIST_NODE(contact)->child == PURPLE_BLIST_NODE(buddy) && PURPLE_BLIST_NODE(buddy)->next == NULL) { pidgin_dialogs_remove_buddy(buddy); int contact_size = purple_counting_node_get_total_size(PURPLE_COUNTING_NODE(contact)); "You are about to remove the contact containing %s " "and %d other buddy from your buddy list. Do you " "You are about to remove the contact containing %s " "and %d other buddies from your buddy list. Do you " "want to continue?", contact_size - 1), purple_buddy_get_name(buddy), contact_size - 1); purple_request_action(contact, NULL, _("Remove Contact"), text, 0, _("_Remove Contact"), G_CALLBACK(pidgin_dialogs_remove_contact_cb), static void free_ggmo(struct _PidginGroupMergeObject *ggp) pidgin_dialogs_merge_groups_cb(struct _PidginGroupMergeObject *GGP) purple_group_set_name(GGP->parent, GGP->new_name); pidgin_dialogs_merge_groups(PurpleGroup *source, const char *new_name) struct _PidginGroupMergeObject *ggp; g_return_if_fail(source != NULL); g_return_if_fail(new_name != NULL); _("You are about to merge the group called %s into the group " "called %s. Do you want to continue?"), purple_group_get_name(source), new_name); ggp = g_new(struct _PidginGroupMergeObject, 1); ggp->new_name = g_strdup(new_name); purple_request_action(source, NULL, _("Merge Groups"), text, 0, _("_Merge Groups"), G_CALLBACK(pidgin_dialogs_merge_groups_cb), _("Cancel"), G_CALLBACK(free_ggmo)); pidgin_dialogs_remove_group_cb(PurpleGroup *group) PurpleBlistNode *cnode, *bnode; cnode = ((PurpleBlistNode*)group)->child; if (PURPLE_IS_CONTACT(cnode)) { if (PURPLE_IS_BUDDY(bnode)) { buddy = (PurpleBuddy*)bnode; if (purple_account_is_connected(purple_buddy_get_account(buddy))) { purple_account_remove_buddy(purple_buddy_get_account(buddy), buddy, group); purple_blist_remove_buddy(buddy); } else if (PURPLE_IS_CHAT(cnode)) { PurpleChat *chat = (PurpleChat *)cnode; if (purple_account_is_connected(purple_chat_get_account(chat))) purple_blist_remove_chat(chat); purple_blist_remove_group(group); pidgin_dialogs_remove_group(PurpleGroup *group) g_return_if_fail(group != NULL); 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?"), purple_group_get_name(group)); purple_request_action(group, NULL, _("Remove Group"), text, 0, _("_Remove Group"), G_CALLBACK(pidgin_dialogs_remove_group_cb), /* XXX - Some of this should be moved into the core, methinks. */ pidgin_dialogs_remove_buddy_cb(PurpleBuddy *buddy) group = purple_buddy_get_group(buddy); name = g_strdup(purple_buddy_get_name(buddy)); /* purple_buddy_get_name() is a crasher after remove_buddy */ account = purple_buddy_get_account(buddy); purple_debug_info("blist", "Removing '%s' from buddy list.\n", purple_buddy_get_name(buddy)); /* TODO - Should remove from blist first... then call purple_account_remove_buddy()? */ purple_account_remove_buddy(account, buddy, group); purple_blist_remove_buddy(buddy); pidgin_dialogs_remove_buddy(PurpleBuddy *buddy) g_return_if_fail(buddy != NULL); text = g_strdup_printf(_("You are about to remove %s from your buddy list. Do you want to continue?"), purple_buddy_get_name(buddy)); purple_request_action(buddy, NULL, _("Remove Buddy"), text, 0, purple_request_cpar_from_account( purple_buddy_get_account(buddy)), buddy, 2, _("_Remove Buddy"), G_CALLBACK(pidgin_dialogs_remove_buddy_cb), _("Cancel"), NULL); pidgin_dialogs_remove_chat_cb(PurpleChat *chat) purple_blist_remove_chat(chat); pidgin_dialogs_remove_chat(PurpleChat *chat) g_return_if_fail(chat != NULL); name = purple_chat_get_name(chat); text = g_strdup_printf(_("You are about to remove the chat %s from your buddy list. Do you want to continue?"), purple_request_action(chat, NULL, _("Remove Chat"), text, 0, purple_request_cpar_from_account(purple_chat_get_account(chat)), chat, 2, _("_Remove Chat"), G_CALLBACK(pidgin_dialogs_remove_chat_cb), _("Cancel"), NULL);