Yo.
gtk1-stable
v0_59_9
2003-03-01, Sean Egan
* Copyright (C) 1998-1999, Mark Spencer <markster@marko.net> * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include <gdk/gdkkeysyms.h> #include "pixmaps/tb_forward.xpm" #include "pixmaps/join.xpm" #include "pixmaps/close.xpm" static struct gaim_connection *joinchatgc; static GtkWidget *invite; static GtkWidget *inviteentry; static GtkWidget *invitemess; static GtkWidget *jc_vbox = NULL; static GList *chatentries = NULL; GtkWidget *all_chats = NULL; GtkWidget *chat_notebook = NULL; static char *ignored(struct conversation *b, char *who) GList *ignore = b->ignored; char *ign = ignore->data; if (!g_strcasecmp(who, ign)) if (*ign == '+' && !g_strcasecmp(who, ign + 1)) if (*ign == '+' && !g_strcasecmp(who, ign + 1)) if (*ign != '+' && !g_strcasecmp(who, ign)) static void destroy_join_chat() gtk_widget_destroy(joinchat); static void destroy_invite() gtk_widget_destroy(invite); GList *tmp = chatentries; if (gtk_object_get_user_data(tmp->data)) { *ival = gtk_spin_button_get_value_as_int(tmp->data); data = g_list_append(data, ival); sval = g_strdup(gtk_entry_get_text(tmp->data)); data = g_list_append(data, sval); serv_join_chat(joinchatgc, data); gtk_widget_destroy(joinchat); g_list_free(chatentries); struct proto_chat_entry *pce; while (GTK_BOX(jc_vbox)->children) gtk_container_remove(GTK_CONTAINER(jc_vbox), ((GtkBoxChild *)GTK_BOX(jc_vbox)->children->data)->widget); g_list_free(chatentries); tmp = list = joinchatgc->prpl->chat_info(joinchatgc); rowbox = gtk_hbox_new(FALSE, 5); gtk_box_pack_start(GTK_BOX(jc_vbox), rowbox, TRUE, TRUE, 0); label = gtk_label_new(pce->label); gtk_box_pack_start(GTK_BOX(rowbox), label, FALSE, FALSE, 0); adjust = gtk_adjustment_new(pce->min, pce->min, pce->max, 1, 10, 10); spin = gtk_spin_button_new(GTK_ADJUSTMENT(adjust), 1, 0); gtk_object_set_user_data(GTK_OBJECT(spin), (void *)1); chatentries = g_list_append(chatentries, spin); gtk_widget_set_usize(spin, 50, -1); gtk_box_pack_end(GTK_BOX(rowbox), spin, FALSE, FALSE, 0); chatentries = g_list_append(chatentries, entry); gtk_box_pack_end(GTK_BOX(rowbox), entry, FALSE, FALSE, 0); gtk_entry_set_text(GTK_ENTRY(entry), pce->def); gtk_widget_grab_focus(entry); gtk_signal_connect(GTK_OBJECT(entry), "activate", GTK_SIGNAL_FUNC(do_join_chat), NULL); static void joinchat_choose(GtkWidget *w, struct gaim_connection *g) static void create_joinchat_menu(GtkWidget *box) struct gaim_connection *g; optmenu = gtk_option_menu_new(); gtk_box_pack_start(GTK_BOX(box), optmenu, FALSE, FALSE, 0); g = (struct gaim_connection *)c->data; g_snprintf(buf, sizeof buf, "%s (%s)", g->username, g->prpl->name()); opt = gtk_menu_item_new_with_label(buf); gtk_object_set_user_data(GTK_OBJECT(opt), g); gtk_signal_connect(GTK_OBJECT(opt), "activate", GTK_SIGNAL_FUNC(joinchat_choose), g); gtk_menu_append(GTK_MENU(menu), opt); gtk_option_menu_set_menu(GTK_OPTION_MENU(optmenu), menu); gtk_option_menu_set_history(GTK_OPTION_MENU(optmenu), 0); struct gaim_connection *gc = NULL; do_error_dialog("You are not currently signed on with any protocols that have " "the ability to chat.", "Unable to chat"); gtk_window_set_wmclass(GTK_WINDOW(joinchat), "joinchat", "Gaim"); gtk_window_set_policy(GTK_WINDOW(joinchat), FALSE, TRUE, TRUE); gtk_widget_realize(joinchat); gtk_signal_connect(GTK_OBJECT(joinchat), "delete_event", GTK_SIGNAL_FUNC(destroy_join_chat), joinchat); gtk_window_set_title(GTK_WINDOW(joinchat), _("Join Chat")); aol_icon(joinchat->window); mainbox = gtk_vbox_new(FALSE, 5); gtk_container_set_border_width(GTK_CONTAINER(mainbox), 5); gtk_container_add(GTK_CONTAINER(joinchat), mainbox); frame = gtk_frame_new(_("Buddy Chat")); gtk_box_pack_start(GTK_BOX(mainbox), frame, TRUE, TRUE, 0); fbox = gtk_vbox_new(FALSE, 5); gtk_container_set_border_width(GTK_CONTAINER(fbox), 5); gtk_container_add(GTK_CONTAINER(frame), fbox); rowbox = gtk_hbox_new(FALSE, 5); gtk_box_pack_start(GTK_BOX(fbox), rowbox, TRUE, TRUE, 0); label = gtk_label_new(_("Join Chat As:")); gtk_box_pack_start(GTK_BOX(rowbox), label, FALSE, FALSE, 0); create_joinchat_menu(rowbox); fbox = gtk_vbox_new(FALSE, 5); gtk_container_add(GTK_CONTAINER(tmp), fbox); gtk_container_set_border_width(GTK_CONTAINER(fbox), 0); joinchatgc = connections->data; bbox = gtk_hbox_new(FALSE, 5); gtk_box_pack_start(GTK_BOX(mainbox), bbox, FALSE, FALSE, 0); cancel = picture_button(joinchat, _("Cancel"), cancel_xpm); gtk_box_pack_end(GTK_BOX(bbox), cancel, FALSE, FALSE, 0); gtk_signal_connect(GTK_OBJECT(cancel), "clicked", GTK_SIGNAL_FUNC(destroy_join_chat), joinchat); join = picture_button(joinchat, _("Join"), join_xpm); gtk_box_pack_end(GTK_BOX(bbox), join, FALSE, FALSE, 0); gtk_signal_connect(GTK_OBJECT(join), "clicked", GTK_SIGNAL_FUNC(do_join_chat), NULL); gtk_widget_show_all(joinchat); static void do_invite(GtkWidget *w, struct conversation *b) debug_printf("do_invite: expecting chat, got IM\n"); buddy = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(inviteentry)->entry)); mess = gtk_entry_get_text(GTK_ENTRY(invitemess)); serv_chat_invite(b->gc, b->id, mess, buddy); gtk_widget_destroy(invite); GList *generate_invite_user_names(struct gaim_connection *gc) static GList *tmp = NULL; tmp = g_list_append(tmp, ""); g = (struct group *)grp->data; buddy = (struct buddy *)bl->data; tmp = g_list_append(tmp, buddy->name); void invite_callback(GtkWidget *w, struct conversation *b) gtk_widget_realize(invite); cancel = picture_button(invite, _("Cancel"), cancel_xpm); invite_btn = picture_button(invite, _("Invite"), join_xpm); inviteentry = gtk_combo_new(); invitemess = gtk_entry_new(); frame = gtk_frame_new(_("Invite")); table = gtk_table_new(2, 2, FALSE); gtk_table_set_row_spacings(GTK_TABLE(table), 5); gtk_table_set_col_spacings(GTK_TABLE(table), 5); gtk_container_set_border_width(GTK_CONTAINER(table), 5); gtk_container_set_border_width(GTK_CONTAINER(frame), 5); /* Now we should fill out all of the names */ gtk_combo_set_popdown_strings(GTK_COMBO(inviteentry), generate_invite_user_names(b->gc)); vbox = gtk_vbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0); gtk_container_add(GTK_CONTAINER(frame), table); label = gtk_label_new(_("Buddy")); gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, GTK_FILL, 0, 0, 0); label = gtk_label_new(_("Message")); gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2, GTK_FILL, 0, 0, 0); /* Now the right side of the table */ gtk_table_attach(GTK_TABLE(table), inviteentry, 1, 2, 0, 1, GTK_FILL | GTK_EXPAND, 0, 0, gtk_table_attach(GTK_TABLE(table), invitemess, 1, 2, 1, 2, GTK_FILL | GTK_EXPAND, 0, 0, /* And now for the button box */ bbox = gtk_hbox_new(FALSE, 10); gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 0); gtk_box_pack_end(GTK_BOX(bbox), cancel, FALSE, FALSE, 0); gtk_box_pack_end(GTK_BOX(bbox), invite_btn, FALSE, FALSE, 0); /* Handle closes right */ gtk_signal_connect(GTK_OBJECT(invite), "delete_event", GTK_SIGNAL_FUNC(destroy_invite), invite); gtk_signal_connect(GTK_OBJECT(cancel), "clicked", GTK_SIGNAL_FUNC(destroy_invite), b); gtk_signal_connect(GTK_OBJECT(invite_btn), "clicked", GTK_SIGNAL_FUNC(do_invite), b); gtk_signal_connect(GTK_OBJECT(GTK_ENTRY(GTK_COMBO(inviteentry)->entry)), "activate", GTK_SIGNAL_FUNC(do_invite), b); gtk_widget_set_usize(GTK_WIDGET(invite), 550, 115); gtk_widget_show(invite_btn); gtk_widget_show(inviteentry); gtk_widget_show(invitemess); gtk_window_set_title(GTK_WINDOW(invite), _("Gaim - Invite Buddy Into Chat Room")); gtk_window_set_focus(GTK_WINDOW(invite), GTK_WIDGET(GTK_COMBO(inviteentry)->entry)); gtk_container_add(GTK_CONTAINER(invite), vbox); aol_icon(invite->window); void tab_complete(struct conversation *c) int pos = GTK_OLD_EDITABLE(c->entry)->current_pos; char *entered, *partial = NULL; GList *nicks = c->in_room; /* if there's nothing there just return */ text = gtk_editable_get_chars(GTK_EDITABLE(c->entry), 0, pos); /* if we're at the end of ": " we need to move back 2 spaces */ if (start >= 2 && text[start - 1] == ' ' && text[start - 2] == ':') /* find the start of the word that we're tabbing */ while (start > 0 && text[start - 1] != ' ') if (chat_options & OPT_CHAT_OLD_STYLE_TAB) { if (strlen(entered) >= 2 && !strncmp(": ", entered + strlen(entered) - 2, 2)) entered[strlen(entered) - 2] = 0; debug_printf("checking tab-completion for %s\n", entered); char *nick = nicks->data; /* this checks to see if the current nick could be a completion */ if (g_strncasecmp(nick, entered, strlen(entered))) { if (nick[0] != '+' && nick[0] != '@') { if (g_strncasecmp(nick + 1, entered, strlen(entered))) { if (nick[0] != '@' || nick[1] != '+') { if (g_strncasecmp(nick + 2, entered, strlen(entered))) { /* if we're here, it's a possible completion */ debug_printf("possible completion: %s\n", nick); /* if we're doing old-style, just fill in the completion */ if (chat_options & OPT_CHAT_OLD_STYLE_TAB) { gtk_editable_delete_text(GTK_EDITABLE(c->entry), start, pos); if (strlen(nick) == strlen(entered)) { nicks = nicks->next ? nicks->next : c->in_room; char *tmp = g_strdup_printf("%s: ", nick); gtk_editable_insert_text(GTK_EDITABLE(c->entry), tmp, strlen(tmp), &start); gtk_editable_set_position(GTK_EDITABLE(c->entry), t); gtk_editable_insert_text(GTK_EDITABLE(c->entry), nick, strlen(nick), &start); t = start + strlen(nick); gtk_editable_set_position(GTK_EDITABLE(c->entry), t); /* we're only here if we're doing new style */ if (most_matched == -1) { /* this will only get called once, since from now on most_matched is >= 0 */ most_matched = strlen(nick); partial = g_strdup(nick); } else if (most_matched) { while (g_strncasecmp(nick, partial, most_matched)) partial[most_matched] = 0; matches = g_list_append(matches, nick); /* we're only here if we're doing new style */ /* if there weren't any matches, return */ /* if matches isn't set partials won't be either */ gtk_editable_delete_text(GTK_EDITABLE(c->entry), start, pos); /* there was only one match. fill it in. */ char *tmp = g_strdup_printf("%s: ", (char *)matches->data); gtk_editable_insert_text(GTK_EDITABLE(c->entry), tmp, strlen(tmp), &start); gtk_editable_set_position(GTK_EDITABLE(c->entry), t); gtk_editable_insert_text(GTK_EDITABLE(c->entry), matches->data, strlen(matches->data), &start); matches = g_list_remove(matches, matches->data); /* there were lots of matches, fill in as much as possible and display all of them */ char *addthis = g_malloc0(1); addthis = g_strconcat(tmp, matches->data, " ", NULL); matches = g_list_remove(matches, matches->data); write_to_conv(c, addthis, WFLAG_NOLOG, NULL, time(NULL), -1); gtk_editable_insert_text(GTK_EDITABLE(c->entry), partial, strlen(partial), &start); t = start + strlen(partial); gtk_editable_set_position(GTK_EDITABLE(c->entry), t); gboolean meify(char *message, int len) /* read /me-ify : if the message (post-HTML) starts with /me, remove * the "/me " part of it (including that space) and return TRUE */ int inside_HTML = 0; /* i really don't like descriptive names */ return FALSE; /* um... this would be very bad if this happens */ c++; /* i really don't like c++ either */ /* k, so now we've gotten past all the HTML crap. */ if (!g_strncasecmp(c, "/me ", 4)) { memmove(c, c + 4, len - 3); static gboolean find_nick(struct gaim_connection *gc, char *message) char *msg = g_strdup(message), *who, *p; who = g_strdup(gc->username); if ((p = strstr(msg, who)) != NULL) { if (((p == msg) || !isalnum(*(p - 1))) && !isalnum(*(p + n))) { if (!g_strcasecmp(gc->username, gc->displayname)) { who = g_strdup(gc->displayname); if ((p = strstr(msg, who)) != NULL) { if (((p == msg) || !isalnum(*(p - 1))) && !isalnum(*(p + n))) { void chat_write(struct conversation *b, char *who, int flag, char *message, time_t mtime) debug_printf("chat_write: expecting chat, got IM\n"); if (!(flag & WFLAG_WHISPER)) { str = g_strdup(normalize (who)); if (!g_strcasecmp(str, normalize(b->gc->username))) { play_sound(SND_CHAT_YOU_SAY); } else if (!g_strcasecmp(str, normalize(b->gc->displayname))) { play_sound(SND_CHAT_YOU_SAY); if (find_nick(b->gc, message)) if (flag & WFLAG_RECV && b->makesound) { if (flag & WFLAG_NICK && (sound_options & OPT_SOUND_CHAT_NICK)) { play_sound(SND_CHAT_NICK); play_sound(SND_CHAT_SAY); write_to_conv(b, message, flag, who, mtime, -1); void whisper_callback(GtkWidget *widget, struct conversation *b) strncpy(buf, gtk_editable_get_chars(GTK_EDITABLE(b->entry), 0, -1), sizeof(buf) / 2); selected = GTK_LIST(b->list)->selection; who = GTK_LABEL(gtk_container_children(GTK_CONTAINER(selected->data))->data)->label; gtk_editable_delete_text(GTK_EDITABLE(b->entry), 0, -1); serv_chat_whisper(b->gc, b->id, who, buf); g_snprintf(buf2, sizeof(buf2), "%s->%s", b->gc->username, who); chat_write(b, buf2, WFLAG_WHISPER, buf, time(NULL)); gtk_widget_grab_focus(GTK_WIDGET(b->entry)); static gint insertname(gconstpointer one, gconstpointer two) const char *a = (const char *)one; const char *b = (const char *)two; return (strcasecmp(a + 1, b + 1)); return (strcasecmp(a + 1, b + 1)); if (*b == '@' || *b == '+') static void chat_press_im(GtkObject *obj, struct conversation *b) c = find_conversation(gtk_object_get_user_data(obj)); gdk_window_show(c->window->window); c = new_conversation(gtk_object_get_user_data(obj)); static void chat_press_ign(GtkWidget *obj, struct conversation *b) gtk_list_select_child(GTK_LIST(b->list), gtk_object_get_user_data(GTK_OBJECT(obj))); static void chat_press_info(GtkObject *obj, struct conversation *b) * If there are special needs for getting info on users in if(b->gc->prpl->get_cb_info != NULL) { b->gc->prpl->get_cb_info(b->gc, b->id, gtk_object_get_user_data(obj)); b->gc->prpl->get_info(b->gc, gtk_object_get_user_data(obj)); static void chat_press_away(GtkObject *obj, struct conversation *b) * May want to expand this to work similarly to chat_press_info? if(b->gc->prpl->get_cb_away != NULL) { b->gc->prpl->get_cb_away(b->gc, b->id, gtk_object_get_user_data(obj)); static gint right_click_chat(GtkObject *obj, GdkEventButton *event, struct conversation *b) if (event->button == 1 && event->type == GDK_2BUTTON_PRESS) { if ((c = find_conversation(gtk_object_get_user_data(obj))) == NULL) c = new_conversation(gtk_object_get_user_data(obj)); } else if (event->button == 3 && event->type == GDK_BUTTON_PRESS) { static GtkWidget *menu = NULL; * If a menu already exists, destroy it before creating a new one, * thus freeing-up the memory it occupied. gtk_widget_destroy(menu); button = gtk_menu_item_new_with_label(_("IM")); gtk_signal_connect(GTK_OBJECT(button), "activate", GTK_SIGNAL_FUNC(chat_press_im), b); gtk_object_set_user_data(GTK_OBJECT(button), gtk_object_get_user_data(obj)); gtk_menu_append(GTK_MENU(menu), button); if (ignored(b, gtk_object_get_user_data(obj))) button = gtk_menu_item_new_with_label(_("Un-Ignore")); button = gtk_menu_item_new_with_label(_("Ignore")); gtk_signal_connect(GTK_OBJECT(button), "activate", GTK_SIGNAL_FUNC(chat_press_ign), b); gtk_object_set_user_data(GTK_OBJECT(button), obj); gtk_menu_append(GTK_MENU(menu), button); if (b->gc && b->gc->prpl->get_info) { button = gtk_menu_item_new_with_label(_("Info")); gtk_signal_connect(GTK_OBJECT(button), "activate", GTK_SIGNAL_FUNC(chat_press_info), b); gtk_object_set_user_data(GTK_OBJECT(button), gtk_object_get_user_data(obj)); gtk_menu_append(GTK_MENU(menu), button); if (b->gc && b->gc->prpl->get_cb_away) { button = gtk_menu_item_new_with_label(_("Get Away Msg")); gtk_signal_connect(GTK_OBJECT(button), "activate", GTK_SIGNAL_FUNC(chat_press_away), b); gtk_object_set_user_data(GTK_OBJECT(button), gtk_object_get_user_data(obj)); gtk_menu_append(GTK_MENU(menu), button); gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, event->button, event->time); * Common code for adding a chat buddy to the list static void add_chat_buddy_common(struct conversation *b, char *name, int pos) g_snprintf(tmp, sizeof(tmp), "X %s", name); list_item = gtk_list_item_new_with_label(tmp); list_item = gtk_list_item_new_with_label(name); gtk_object_set_user_data(GTK_OBJECT(list_item), name); gtk_signal_connect(GTK_OBJECT(list_item), "button_press_event", GTK_SIGNAL_FUNC(right_click_chat), b); gtk_list_insert_items(GTK_LIST(b->list), g_list_append(NULL, list_item), pos); gtk_widget_show(list_item); void add_chat_buddy(struct conversation *b, char *buddy) char *name = g_strdup(buddy); plugin_event(event_chat_buddy_join, b->gc, (void *)b->id, name, 0); b->in_room = g_list_insert_sorted(b->in_room, name, insertname); pos = g_list_index(b->in_room, name); add_chat_buddy_common(b, name, pos); g_snprintf(tmp, sizeof(tmp), _("%d %s in room"), g_list_length(b->in_room), g_list_length(b->in_room) == 1 ? "person" : "people"); gtk_label_set_text(GTK_LABEL(b->count), tmp); play_sound(SND_CHAT_JOIN); if (chat_options & OPT_CHAT_LOGON) { g_snprintf(tmp, sizeof(tmp), _("%s entered the room."), name); write_to_conv(b, tmp, WFLAG_SYSTEM, NULL, time(NULL), -1); void rename_chat_buddy(struct conversation *b, char *old, char *new) GList *names = b->in_room; GList *items = GTK_LIST(b->list)->children; char *name = g_strdup(new); if (!g_strcasecmp((char *)names->data, old)) { char *tmp2 = names->data; b->in_room = g_list_remove(b->in_room, names->data); if (tmp2 == gtk_object_get_user_data(items->data)) { gtk_list_remove_items(GTK_LIST(b->list), g_list_append(NULL, items->data)); b->in_room = g_list_insert_sorted(b->in_room, name, insertname); pos = g_list_index(b->in_room, name); b->ignored = g_list_remove(b->ignored, ign); /* we haven't added them yet. if we find them, don't add them again */ b->ignored = g_list_append(b->ignored, g_strdup(name)); if ((ign = ignored(b, new)) != NULL) { /* if they weren't ignored and change to someone who is ignored, * assume it's someone else. that may seem a little backwards but * it's better when it *is* actually someone else. Sorry Sean. */ b->ignored = g_list_remove(b->ignored, ign); add_chat_buddy_common(b, name, pos); if (chat_options & OPT_CHAT_LOGON) { g_snprintf(tmp, sizeof(tmp), _("%s is now known as %s"), old, new); write_to_conv(b, tmp, WFLAG_SYSTEM, NULL, time(NULL), -1); void remove_chat_buddy(struct conversation *b, char *buddy, char *reason) GList *names = b->in_room; GList *items = GTK_LIST(b->list)->children; plugin_event(event_chat_buddy_leave, b->gc, (void *)b->id, buddy, 0); if (!g_strcasecmp((char *)names->data, buddy)) { b->in_room = g_list_remove(b->in_room, names->data); if (tmp == gtk_object_get_user_data(items->data)) { gtk_list_remove_items(GTK_LIST(b->list), g_list_append(NULL, items->data)); /* don't remove them from ignored in case they re-enter */ g_snprintf(tmp, sizeof(tmp), _("%d %s in room"), g_list_length(b->in_room), g_list_length(b->in_room) == 1 ? "person" : "people"); gtk_label_set_text(GTK_LABEL(b->count), tmp); play_sound(SND_CHAT_LEAVE); if (chat_options & OPT_CHAT_LOGON) { g_snprintf(tmp, sizeof(tmp), _("%s left the room (%s)."), buddy, reason); g_snprintf(tmp, sizeof(tmp), _("%s left the room."), buddy); write_to_conv(b, tmp, WFLAG_SYSTEM, NULL, time(NULL), -1); void im_callback(GtkWidget *w, struct conversation *b) i = GTK_LIST(b->list)->selection; name = (char *)gtk_object_get_user_data(GTK_OBJECT(i->data)); c = find_conversation(name); gdk_window_raise(c->window->window); c = new_conversation(name); void ignore_callback(GtkWidget *w, struct conversation *b) i = GTK_LIST(b->list)->selection; name = (char *)gtk_object_get_user_data(GTK_OBJECT(i->data)); pos = gtk_list_child_position(GTK_LIST(b->list), i->data); b->ignored = g_list_remove(b->ignored, ign); b->ignored = g_list_append(b->ignored, g_strdup(name)); gtk_widget_destroy(i->data); add_chat_buddy_common(b, name, pos); void show_new_buddy_chat(struct conversation *b) GtkWidget *im, *ignore, *info; int dispstyle = set_dispstyle(1); if (chat_options & OPT_CHAT_ONE_WINDOW) { win = all_chats = b->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); if ((convo_options & OPT_CONVO_COMBINE) && (im_options & OPT_IM_ONE_WINDOW)) gtk_window_set_wmclass(GTK_WINDOW(win), "buddy_chat", "Gaim"); gtk_window_set_policy(GTK_WINDOW(win), TRUE, TRUE, FALSE); gtk_container_border_width(GTK_CONTAINER(win), 0); gtk_window_set_title(GTK_WINDOW(win), _("Gaim - Group Chats")); gtk_signal_connect(GTK_OBJECT(win), "delete_event", GTK_SIGNAL_FUNC(delete_all_convo), NULL); chat_notebook = gtk_notebook_new(); if ((convo_options & OPT_CONVO_COMBINE) && (im_options & OPT_IM_ONE_WINDOW)) convo_notebook = chat_notebook; if (chat_options & OPT_CHAT_SIDE_TAB) { if (chat_options & OPT_CHAT_BR_TAB) { gtk_notebook_set_tab_pos(GTK_NOTEBOOK(chat_notebook), gtk_notebook_set_tab_pos(GTK_NOTEBOOK(chat_notebook), if (chat_options & OPT_CHAT_BR_TAB) { gtk_notebook_set_tab_pos(GTK_NOTEBOOK(chat_notebook), gtk_notebook_set_tab_pos(GTK_NOTEBOOK(chat_notebook), gtk_notebook_set_scrollable(GTK_NOTEBOOK(chat_notebook), TRUE); gtk_notebook_popup_enable(GTK_NOTEBOOK(chat_notebook)); gtk_container_add(GTK_CONTAINER(win), chat_notebook); gtk_signal_connect(GTK_OBJECT(chat_notebook), "switch-page", GTK_SIGNAL_FUNC(convo_switch), NULL); gtk_widget_show(chat_notebook); win = b->window = all_chats; cont = gtk_vbox_new(FALSE, 5); gtk_container_set_border_width(GTK_CONTAINER(cont), 5); gtk_notebook_append_page(GTK_NOTEBOOK(chat_notebook), cont, gtk_label_new(b->name)); win = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_object_set_user_data(GTK_OBJECT(win), b); gtk_window_set_wmclass(GTK_WINDOW(win), "buddy_chat", "Gaim"); gtk_window_set_policy(GTK_WINDOW(win), TRUE, TRUE, TRUE); gtk_container_border_width(GTK_CONTAINER(win), 10); g_snprintf(buf, sizeof(buf), "Gaim - %s (chat)", b->name); gtk_window_set_title(GTK_WINDOW(win), buf); gtk_signal_connect(GTK_OBJECT(win), "destroy", GTK_SIGNAL_FUNC(close_callback), b); cont = gtk_vbox_new(FALSE, 5); gtk_container_add(GTK_CONTAINER(win), cont); if (b->gc->prpl->options & OPT_PROTO_CHAT_TOPIC) { hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(cont), hbox, FALSE, FALSE, 5); label = gtk_label_new(_("Topic:")); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5); b->topic_text = gtk_entry_new(); gtk_entry_set_editable(GTK_ENTRY(b->topic_text), FALSE); gtk_box_pack_start(GTK_BOX(hbox), b->topic_text, TRUE, TRUE, 5); gtk_widget_show(b->topic_text); vpaned = gtk_vpaned_new(); gtk_paned_set_gutter_size(GTK_PANED(vpaned), 15); gtk_container_add(GTK_CONTAINER(cont), vpaned); hpaned = gtk_hpaned_new(); gtk_paned_set_gutter_size(GTK_PANED(hpaned), 15); gtk_paned_pack1(GTK_PANED(vpaned), hpaned, TRUE, FALSE); sw = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS); gtk_paned_pack1(GTK_PANED(hpaned), sw, TRUE, TRUE); gtk_widget_set_usize(sw, buddy_chat_size.width, buddy_chat_size.height); text = gtk_imhtml_new(NULL, NULL); gtk_container_add(GTK_CONTAINER(sw), text); GTK_LAYOUT(text)->hadjustment->step_increment = 10.0; GTK_LAYOUT(text)->vadjustment->step_increment = 10.0; if (convo_options & OPT_CONVO_SHOW_TIME) gtk_imhtml_show_comments(GTK_IMHTML(text), TRUE); gtk_imhtml_set_use_pointsize(GTK_IMHTML(text), b->gc->prpl->options & OPT_PROTO_USE_POINT_SIZE); lbox = gtk_vbox_new(FALSE, 5); gtk_paned_pack2(GTK_PANED(hpaned), lbox, TRUE, TRUE); b->count = gtk_label_new(_("0 people in room")); gtk_box_pack_start(GTK_BOX(lbox), b->count, FALSE, FALSE, 0); gtk_widget_show(b->count); sw2 = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw2), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); gtk_box_pack_start(GTK_BOX(lbox), sw2, TRUE, TRUE, 0); gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(sw2), list); gtk_widget_set_usize(list, 150, -1); bbox2 = gtk_hbox_new(TRUE, 5); gtk_box_pack_start(GTK_BOX(lbox), bbox2, FALSE, FALSE, 0); im = picture_button2(win, _("IM"), tmp_send_xpm, FALSE); gtk_box_pack_start(GTK_BOX(bbox2), im, dispstyle, dispstyle, 0); gtk_signal_connect(GTK_OBJECT(im), "clicked", GTK_SIGNAL_FUNC(im_callback), b); ignore = picture_button2(win, _("Ignore"), close_xpm, FALSE); gtk_box_pack_start(GTK_BOX(bbox2), ignore, dispstyle, dispstyle, 0); gtk_signal_connect(GTK_OBJECT(ignore), "clicked", GTK_SIGNAL_FUNC(ignore_callback), b); info = picture_button2(win, _("Info"), tb_search_xpm, FALSE); gtk_box_pack_start(GTK_BOX(bbox2), info, dispstyle, dispstyle, 0); gtk_signal_connect(GTK_OBJECT(info), "clicked", GTK_SIGNAL_FUNC(info_callback), b); vbox = gtk_vbox_new(FALSE, 5); gtk_paned_pack2(GTK_PANED(vpaned), vbox, TRUE, FALSE); chatentry = gtk_text_new(NULL, NULL); if (!(chat_options & OPT_CHAT_ONE_WINDOW)) gtk_window_set_focus(GTK_WINDOW(b->window), b->entry); toolbar = build_conv_toolbar(b); gtk_box_pack_start(GTK_BOX(vbox), toolbar, FALSE, FALSE, 0); gtk_object_set_user_data(GTK_OBJECT(chatentry), b); gtk_text_set_editable(GTK_TEXT(chatentry), TRUE); gtk_text_set_word_wrap(GTK_TEXT(chatentry), TRUE); gtk_signal_connect(GTK_OBJECT(chatentry), "activate", GTK_SIGNAL_FUNC(send_callback), b); gtk_signal_connect(GTK_OBJECT(chatentry), "key_press_event", GTK_SIGNAL_FUNC(keypress_callback), gtk_signal_connect(GTK_OBJECT(chatentry), "key_press_event", GTK_SIGNAL_FUNC(entry_key_pressed), if (convo_options & OPT_CONVO_CHECK_SPELLING) gtkspell_attach(GTK_TEXT(chatentry)); gtk_box_pack_start(GTK_BOX(vbox), chatentry, TRUE, TRUE, 0); gtk_widget_set_usize(chatentry, buddy_chat_size.width, MAX(buddy_chat_size.entry_height, 25)); gtk_window_set_focus(GTK_WINDOW(win), chatentry); gtk_widget_show(chatentry); bbox = gtk_hbox_new(FALSE, 5); gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 0); close = picture_button2(win, _("Close"), cancel_xpm, dispstyle); gtk_object_set_user_data(GTK_OBJECT(close), b); gtk_signal_connect(GTK_OBJECT(close), "clicked", GTK_SIGNAL_FUNC(close_callback), b); gtk_box_pack_end(GTK_BOX(bbox), close, dispstyle, dispstyle, 0); invite_btn = picture_button2(win, _("Invite"), join_xpm, dispstyle); gtk_signal_connect(GTK_OBJECT(invite_btn), "clicked", GTK_SIGNAL_FUNC(invite_callback), b); gtk_box_pack_end(GTK_BOX(bbox), invite_btn, dispstyle, dispstyle, 0); whisper = picture_button2(win, _("Whisper"), tb_forward_xpm, dispstyle); gtk_signal_connect(GTK_OBJECT(whisper), "clicked", GTK_SIGNAL_FUNC(whisper_callback), b); gtk_box_pack_end(GTK_BOX(bbox), whisper, dispstyle, dispstyle, 0); send = picture_button2(win, _("Send"), tmp_send_xpm, dispstyle); gtk_signal_connect(GTK_OBJECT(send), "clicked", GTK_SIGNAL_FUNC(send_callback), b); gtk_box_pack_end(GTK_BOX(bbox), send, dispstyle, dispstyle, 0); b->fg_color_dialog = NULL; b->bg_color_dialog = NULL; sprintf(b->fontface, "%s", fontface); update_buttons_by_protocol(b); void chat_set_topic(struct conversation *b, char *who, char *topic) gtk_entry_set_text(GTK_ENTRY(b->topic_text), topic); b->topic = g_strdup(topic); void delete_chat(struct conversation *b) g_free(b->in_room->data); b->in_room = g_list_remove(b->in_room, b->in_room->data); g_free(b->ignored->data); b->ignored = g_list_remove(b->ignored, b->ignored->data); g_string_free(b->history, TRUE); static GtkWidget *change_text(GtkWidget *win, char *text, GtkWidget *button, char **xpm, int chat) int dispstyle = set_dispstyle(chat); GtkWidget *parent = button->parent; gtk_widget_destroy(button); button = picture_button2(win, text, xpm, dispstyle); gtk_box_pack_start(GTK_BOX(parent), button, dispstyle, dispstyle, 5); gtk_box_pack_end(GTK_BOX(parent), button, dispstyle, dispstyle, 0); void update_chat_button_pix() struct gaim_connection *g; g = (struct gaim_connection *)C->data; c = (struct conversation *)bcs->data; c->send = change_text(c->window, _("Send"), c->send, tmp_send_xpm, opt); change_text(c->window, _("Whisper"), c->whisper, tb_forward_xpm, opt); c->invite = change_text(c->window, _("Invite"), c->invite, join_xpm, opt); c->close = change_text(c->window, _("Close"), c->close, cancel_xpm, opt); gtk_object_set_user_data(GTK_OBJECT(c->close), c); gtk_signal_connect(GTK_OBJECT(c->close), "clicked", GTK_SIGNAL_FUNC(close_callback), c); gtk_signal_connect(GTK_OBJECT(c->send), "clicked", GTK_SIGNAL_FUNC(send_callback), c); gtk_signal_connect(GTK_OBJECT(c->invite), "clicked", GTK_SIGNAL_FUNC(invite_callback), c); gtk_signal_connect(GTK_OBJECT(c->whisper), "clicked", GTK_SIGNAL_FUNC(whisper_callback), c); update_buttons_by_protocol(c); void update_im_button_pix() GList *bcs = conversations; int dispstyle = set_dispstyle(0); c = (struct conversation *)bcs->data; parent = c->close->parent; c->close = change_text(c->window, _("Close"), c->close, cancel_xpm, opt); gtk_box_reorder_child(GTK_BOX(parent), c->close, 0); gtk_box_set_child_packing(GTK_BOX(parent), c->sep1, dispstyle, dispstyle, 0, if (find_buddy(c->gc, c->name) == NULL) c->add = change_text(c->window, _("Add"), c->add, gnome_add_xpm, opt); c->add = change_text(c->window, _("Remove"), c->add, gnome_remove_xpm, opt); gtk_box_reorder_child(GTK_BOX(parent), c->add, 2); c->block = change_text(c->window, _("Block"), c->block, block_xpm, opt); gtk_box_reorder_child(GTK_BOX(parent), c->block, 3); c->warn = change_text(c->window, _("Warn"), c->warn, warn_xpm, opt); gtk_box_reorder_child(GTK_BOX(parent), c->warn, 4); c->info = change_text(c->window, _("Info"), c->info, tb_search_xpm, opt); gtk_box_reorder_child(GTK_BOX(parent), c->info, 5); c->send = change_text(c->window, _("Send"), c->send, tmp_send_xpm, opt); gtk_box_set_child_packing(GTK_BOX(parent), c->sep2, dispstyle, dispstyle, 0, gtk_box_reorder_child(GTK_BOX(parent), c->send, 7); gtk_object_set_user_data(GTK_OBJECT(c->close), c); gtk_signal_connect(GTK_OBJECT(c->close), "clicked", GTK_SIGNAL_FUNC(close_callback), c); gtk_signal_connect(GTK_OBJECT(c->send), "clicked", GTK_SIGNAL_FUNC(send_callback), c); gtk_signal_connect(GTK_OBJECT(c->add), "clicked", GTK_SIGNAL_FUNC(add_callback), c); gtk_signal_connect(GTK_OBJECT(c->info), "clicked", GTK_SIGNAL_FUNC(info_callback), c); gtk_signal_connect(GTK_OBJECT(c->warn), "clicked", GTK_SIGNAL_FUNC(warn_callback), c); gtk_signal_connect(GTK_OBJECT(c->block), "clicked", GTK_SIGNAL_FUNC(block_callback), c); /* evil, evil i tell you! evil! */ if (chat_options & OPT_CHAT_ONE_WINDOW) { if ((convo_options & OPT_CONVO_COMBINE) && (im_options & OPT_IM_ONE_WINDOW)) { chat_notebook = convo_notebook; struct conversation *c = x->data; gtk_widget_destroy(c->text); gtk_widget_reparent(imhtml, c->sw); gtk_signal_disconnect_by_func(GTK_OBJECT(win), GTK_SIGNAL_FUNC(close_callback), c); gtk_entry_set_text(GTK_ENTRY(c->topic_text), c->topic); g_snprintf(tmp, sizeof(tmp), _("%d %s in room"), g_list_length(c->in_room), g_list_length(c->in_room) == 1 ? "person" : "people"); gtk_label_set_text(GTK_LABEL(c->count), tmp); add_chat_buddy_common(c, name, pos); struct conversation *c = x->data; gtk_widget_destroy(c->text); gtk_widget_reparent(imhtml, c->sw); gtk_entry_set_text(GTK_ENTRY(c->topic_text), c->topic); g_snprintf(tmp, sizeof(tmp), _("%d %s in room"), g_list_length(c->in_room), g_list_length(c->in_room) == 1 ? "person" : "people"); gtk_label_set_text(GTK_LABEL(c->count), tmp); add_chat_buddy_common(c, name, pos); if ((convo_options & OPT_CONVO_COMBINE) && (im_options & OPT_IM_ONE_WINDOW) && conversations) { gtk_notebook_remove_page(GTK_NOTEBOOK(chat_notebook), g_list_length(conversations)); gtk_widget_destroy(all_chats);