From: Eric W. <war...@us...> - 2001-09-28 12:15:57
|
Update of /cvsroot/gaim/gaim/src In directory usw-pr-cvs1:/tmp/cvs-serv4917/src Modified Files: buddy_chat.c conversation.c convo.h gaim.h prefs.c Log Message: Sean Egan's tab-completion patch. Index: buddy_chat.c =================================================================== RCS file: /cvsroot/gaim/gaim/src/buddy_chat.c,v retrieving revision 1.118 retrieving revision 1.119 diff -u -d -r1.118 -r1.119 --- buddy_chat.c 2001/09/28 09:33:38 1.118 +++ buddy_chat.c 2001/09/28 12:15:54 1.119 @@ -440,6 +440,163 @@ gtk_widget_show(invite); } +void tab_complete(struct conversation *c) +{ + int pos = GTK_EDITABLE(c->entry)->current_pos; + int start = pos; + int most_matched = -1; + char *entered, *partial = NULL; + char *text; + GList *matches = NULL; + GList *nicks = c->in_room; + + /* if there's nothing there just return */ + if (!start) + 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] == ':') + start -= 2; + + /* find the start of the word that we're tabbing */ + while (start > 0 && text[start - 1] != ' ') + start--; + + entered = text + start; + if (chat_options & OPT_CHAT_OLD_STYLE_TAB) { + if (strlen(entered) >= 2 && !strncmp(": ", entered + strlen(entered) - 2, 2)) + entered[strlen(entered) - 2] = 0; + } + + if (!strlen(entered)) { + g_free(text); + return; + } + + debug_printf("checking tab-completion for %s\n", entered); + + while (nicks) { + 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] != '@') { + nicks = nicks->next; + continue; + } + if (g_strncasecmp(nick + 1, entered, strlen(entered))) { + if (nick[0] != '@' && nick[1] != '+') { + nicks = nicks->next; + continue; + } + if (g_strncasecmp(nick + 2, entered, strlen(entered))) { + nicks = nicks->next; + continue; + } + else + nick += 2; + } else + nick++; + } + /* 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; + nick = nicks->data; + if (*nick == '@') + nick++; + if (*nick == '+') + nick++; + } + + if (start == 0) { + char *tmp = g_strdup_printf("%s: ", nick); + int t = start; + gtk_editable_insert_text(GTK_EDITABLE(c->entry), tmp, strlen(tmp), &start); + if (t == start) { + t = start + strlen(tmp); + gtk_editable_set_position(GTK_EDITABLE(c->entry), t); + } + g_free(tmp); + } else { + int t = start; + gtk_editable_insert_text(GTK_EDITABLE(c->entry), nick, strlen(nick), &start); + if (t == start) { + t = start + strlen(nick); + gtk_editable_set_position(GTK_EDITABLE(c->entry), t); + } + } + g_free(text); + return; + } + + /* 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)) + most_matched--; + partial[most_matched] = 0; + } + matches = g_list_append(matches, nick); + + nicks = nicks->next; + } + /* we're only here if we're doing new style */ + + /* if there weren't any matches, return */ + if (!matches) { + /* if matches isn't set partials won't be either */ + g_free(text); + return; + } + + gtk_editable_delete_text(GTK_EDITABLE(c->entry), start, pos); + if (!matches->next) { + /* there was only one match. fill it in. */ + if (start == 0) { + char *tmp = g_strdup_printf("%s: ", (char *)matches->data); + int t = start; + gtk_editable_insert_text(GTK_EDITABLE(c->entry), tmp, strlen(tmp), &start); + if (t == start) { + t = start + strlen(tmp); + gtk_editable_set_position(GTK_EDITABLE(c->entry), t); + } + g_free(tmp); + } else { + gtk_editable_insert_text(GTK_EDITABLE(c->entry), matches->data, strlen(matches->data), &start); + } + matches = g_list_remove(matches, matches->data); + } else { + /* there were lots of matches, fill in as much as possible and display all of them */ + char *addthis = g_malloc0(1); + int t = start; + while (matches) { + char *tmp = addthis; + addthis = g_strconcat(tmp, matches->data, " ", NULL); + g_free(tmp); + matches = g_list_remove(matches, matches->data); + } + write_to_conv(c, addthis, WFLAG_NOLOG, NULL, time(NULL)); + gtk_editable_insert_text(GTK_EDITABLE(c->entry), partial, strlen(partial), &start); + if (t == start) { + t = start + strlen(partial); + gtk_editable_set_position(GTK_EDITABLE(c->entry), t); + } + g_free(addthis); + } + + g_free(text); + g_free(partial); +} + gboolean meify(char *message) { /* read /me-ify : if the message (post-HTML) starts with /me, remove Index: conversation.c =================================================================== RCS file: /cvsroot/gaim/gaim/src/conversation.c,v retrieving revision 1.268 retrieving revision 1.269 diff -u -d -r1.268 -r1.269 --- conversation.c 2001/09/28 01:25:02 1.268 +++ conversation.c 2001/09/28 12:15:54 1.269 @@ -755,6 +755,9 @@ gtk_signal_emit_stop_by_name(GTK_OBJECT(entry), "key_press_event"); } } + } else if ((event->keyval == GDK_Tab) && c->is_chat && (chat_options & OPT_CHAT_TAB_COMPLETE)) { + tab_complete(c); + gtk_signal_emit_stop_by_name(GTK_OBJECT(entry), "key_press_event"); } else if (((!c->is_chat && (im_options & OPT_IM_ONE_WINDOW)) || (c->is_chat && (chat_options & OPT_CHAT_ONE_WINDOW))) && (event->state & GDK_MOD1_MASK) && isdigit(event->keyval) && (event->keyval > '0')) { @@ -1396,7 +1399,7 @@ c->history = g_string_append(c->history, "<BR>\n"); } - if ((logging_options & OPT_LOG_ALL) || find_log_info(c->name)) { + if (!(flags & WFLAG_NOLOG) && ((logging_options & OPT_LOG_ALL) || find_log_info(c->name))) { char *t1; char nm[256]; @@ -1422,7 +1425,9 @@ g_free(t1); } } - + } else if (flags & WFLAG_NOLOG) { + g_snprintf(buf, BUF_LONG, "<B><FONT COLOR=\"#777777\">%s</FONT></B><BR>", what); + gtk_imhtml_append_text(GTK_IMHTML(c->text), buf, 0); } else { if (flags & WFLAG_WHISPER) { /* if we're whispering, it's not an autoresponse */ @@ -1499,7 +1504,7 @@ g_free(t2); } - if ((logging_options & OPT_LOG_ALL) || find_log_info(c->name)) { + if (!(flags & WFLAG_NOLOG) && ((logging_options & OPT_LOG_ALL) || find_log_info(c->name))) { char *t1, *t2; char *nm = g_malloc(256); if (c->is_chat) Index: convo.h =================================================================== RCS file: /cvsroot/gaim/gaim/src/convo.h,v retrieving revision 1.10 retrieving revision 1.11 diff -u -d -r1.10 -r1.11 --- convo.h 2001/09/28 01:25:02 1.10 +++ convo.h 2001/09/28 12:15:54 1.11 @@ -41,6 +41,7 @@ extern void ignore_callback(GtkWidget *, struct conversation *); extern void whisper_callback(GtkWidget *, struct conversation *); extern void invite_callback(GtkWidget *, struct conversation *); +extern void tab_complete(struct conversation *c); /* now IM */ extern void warn_callback(GtkWidget *, struct conversation *); Index: gaim.h =================================================================== RCS file: /cvsroot/gaim/gaim/src/gaim.h,v retrieving revision 1.269 retrieving revision 1.270 diff -u -d -r1.269 -r1.270 --- gaim.h 2001/09/28 07:46:36 1.269 +++ gaim.h 2001/09/28 12:15:54 1.270 @@ -70,6 +70,7 @@ #define WFLAG_FILERECV 0x10 #define WFLAG_SYSTEM 0x20 #define WFLAG_NICK 0x40 +#define WFLAG_NOLOG 0x80 #define AUTO_RESPONSE "<AUTO-REPLY> : " @@ -528,6 +529,8 @@ #define OPT_CHAT_POPUP 0x00000010 #define OPT_CHAT_SIDE_TAB 0x00000020 #define OPT_CHAT_BR_TAB 0x00000040 +#define OPT_CHAT_TAB_COMPLETE 0x00000080 +#define OPT_CHAT_OLD_STYLE_TAB 0x00000100 extern guint font_options; #define OPT_FONT_BOLD 0x00000001 Index: prefs.c =================================================================== RCS file: /cvsroot/gaim/gaim/src/prefs.c,v retrieving revision 1.182 retrieving revision 1.183 diff -u -d -r1.182 -r1.183 --- prefs.c 2001/09/27 19:17:10 1.182 +++ prefs.c 2001/09/28 12:15:54 1.183 @@ -984,6 +984,8 @@ GtkWidget *button; GtkWidget *hbox2; GtkWidget *vbox3; + GtkWidget *tab; + GtkWidget *old; parent = prefdialog->parent; gtk_widget_destroy(prefdialog); @@ -1085,6 +1087,29 @@ gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(toggle_sensitive), opt); opt = tab_radio(_("Right"), OPT_CHAT_SIDE_TAB | OPT_CHAT_BR_TAB | 1, vbox3, opt); gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(toggle_sensitive), opt); + + frame = gtk_frame_new(_("Tab Completion")); + gtk_box_pack_start(GTK_BOX(box), frame, FALSE, FALSE, 5); + gtk_widget_show(frame); + + hbox = gtk_hbox_new(FALSE, 5); + gtk_container_add(GTK_CONTAINER(frame), hbox); + gtk_widget_show(hbox); + + vbox = gtk_vbox_new(FALSE, 5); + gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 5); + gtk_widget_show(vbox); + + tab = gaim_button(_("Tab-Complete Nicks"), &chat_options, OPT_CHAT_TAB_COMPLETE, vbox); + + vbox = gtk_vbox_new(FALSE, 5); + gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 5); + gtk_widget_show(vbox); + + old = gaim_button(_("Old-Style Tab Completion"), &chat_options, OPT_CHAT_OLD_STYLE_TAB, vbox); + if (!(chat_options & OPT_CHAT_TAB_COMPLETE)) + gtk_widget_set_sensitive(GTK_WIDGET(old), FALSE); + gtk_signal_connect(GTK_OBJECT(tab), "clicked", GTK_SIGNAL_FUNC(toggle_sensitive), old); gtk_widget_show(prefdialog); } |