Mercurial > pidgin
comparison pidgin/gtkconv.c @ 22805:e1052f4b0254
Modified patch from Andrei Mozzhuhin to fix tab-completion when non-ascii
characters are involved. Closes #5653.
author | Sadrul Habib Chowdhury <imadil@gmail.com> |
---|---|
date | Thu, 01 May 2008 22:42:21 +0000 |
parents | 4040c4ee1f44 |
children | 6079335eb01c fdf60a5c2f66 |
comparison
equal
deleted
inserted
replaced
22804:1de2fa8be76b | 22805:e1052f4b0254 |
---|---|
3978 g_object_unref(pixbuf); | 3978 g_object_unref(pixbuf); |
3979 g_free(alias_key); | 3979 g_free(alias_key); |
3980 } | 3980 } |
3981 | 3981 |
3982 static void | 3982 static void |
3983 tab_complete_process_item(int *most_matched, char *entered, char **partial, char *nick_partial, | 3983 tab_complete_process_item(int *most_matched, char *entered, gsize entered_bytes, char **partial, char *nick_partial, |
3984 GList **matches, gboolean command, char *name) | 3984 GList **matches, gboolean command, char *name) |
3985 { | 3985 { |
3986 strncpy(nick_partial, name, strlen(entered)); | 3986 memcpy(nick_partial, name, entered_bytes); |
3987 nick_partial[strlen(entered)] = '\0'; | |
3988 if (purple_utf8_strcasecmp(nick_partial, entered)) | 3987 if (purple_utf8_strcasecmp(nick_partial, entered)) |
3989 return; | 3988 return; |
3990 | 3989 |
3991 /* if we're here, it's a possible completion */ | 3990 /* if we're here, it's a possible completion */ |
3992 | 3991 |
4027 char *text; | 4026 char *text; |
4028 char *nick_partial; | 4027 char *nick_partial; |
4029 const char *prefix; | 4028 const char *prefix; |
4030 GList *matches = NULL; | 4029 GList *matches = NULL; |
4031 gboolean command = FALSE; | 4030 gboolean command = FALSE; |
4031 gsize entered_bytes = 0; | |
4032 | 4032 |
4033 gtkconv = PIDGIN_CONVERSATION(conv); | 4033 gtkconv = PIDGIN_CONVERSATION(conv); |
4034 | 4034 |
4035 gtk_text_buffer_get_start_iter(gtkconv->entry_buffer, &start_buffer); | 4035 gtk_text_buffer_get_start_iter(gtkconv->entry_buffer, &start_buffer); |
4036 gtk_text_buffer_get_iter_at_mark(gtkconv->entry_buffer, &cursor, | 4036 gtk_text_buffer_get_iter_at_mark(gtkconv->entry_buffer, &cursor, |
4046 &cursor, FALSE); | 4046 &cursor, FALSE); |
4047 | 4047 |
4048 /* if we're at the end of ": " we need to move back 2 spaces */ | 4048 /* if we're at the end of ": " we need to move back 2 spaces */ |
4049 start = strlen(text) - 1; | 4049 start = strlen(text) - 1; |
4050 | 4050 |
4051 if (strlen(text) >= 2 && !strncmp(&text[start-1], ": ", 2)) { | 4051 if (start >= 1 && !strncmp(&text[start-1], ": ", 2)) { |
4052 gtk_text_iter_backward_chars(&word_start, 2); | 4052 gtk_text_iter_backward_chars(&word_start, 2); |
4053 start-=2; | 4053 } |
4054 } | 4054 |
4055 | 4055 /* find the start of the word that we're tabbing. |
4056 /* find the start of the word that we're tabbing */ | 4056 * Using gtk_text_iter_backward_word_start won't work, because a nick can contain |
4057 while (start >= 0 && text[start] != ' ') { | 4057 * characters (e.g. '.', '/' etc.) that Pango may think are word separators. */ |
4058 gtk_text_iter_backward_char(&word_start); | 4058 while (gtk_text_iter_backward_char(&word_start)) { |
4059 start--; | 4059 if (gtk_text_iter_get_char(&word_start) == ' ') { |
4060 /* Reached the whitespace before the start of the word. Move forward once */ | |
4061 gtk_text_iter_forward_char(&word_start); | |
4062 break; | |
4063 } | |
4060 } | 4064 } |
4061 | 4065 |
4062 prefix = pidgin_get_cmd_prefix(); | 4066 prefix = pidgin_get_cmd_prefix(); |
4063 if (start == -1 && (strlen(text) >= strlen(prefix)) && !strncmp(text, prefix, strlen(prefix))) { | 4067 if (gtk_text_iter_get_offset(&word_start) == 0 && |
4068 (strlen(text) >= strlen(prefix)) && !strncmp(text, prefix, strlen(prefix))) { | |
4064 command = TRUE; | 4069 command = TRUE; |
4065 gtk_text_iter_forward_chars(&word_start, strlen(prefix)); | 4070 gtk_text_iter_forward_chars(&word_start, strlen(prefix)); |
4066 } | 4071 } |
4067 | 4072 |
4068 g_free(text); | 4073 g_free(text); |
4069 | 4074 |
4070 entered = gtk_text_buffer_get_text(gtkconv->entry_buffer, &word_start, | 4075 entered = gtk_text_buffer_get_text(gtkconv->entry_buffer, &word_start, |
4071 &cursor, FALSE); | 4076 &cursor, FALSE); |
4077 entered_bytes = strlen(entered); | |
4072 | 4078 |
4073 if (!g_utf8_strlen(entered, -1)) { | 4079 if (!g_utf8_strlen(entered, -1)) { |
4074 g_free(entered); | 4080 g_free(entered); |
4075 return (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) ? TRUE : FALSE; | 4081 return (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) ? TRUE : FALSE; |
4076 } | 4082 } |
4077 | 4083 |
4078 nick_partial = g_malloc(strlen(entered)+1); | 4084 nick_partial = g_malloc0(entered_bytes + 1); |
4079 | 4085 |
4080 if (command) { | 4086 if (command) { |
4081 GList *list = purple_cmd_list(conv); | 4087 GList *list = purple_cmd_list(conv); |
4082 GList *l; | 4088 GList *l; |
4083 | 4089 |
4084 /* Commands */ | 4090 /* Commands */ |
4085 for (l = list; l != NULL; l = l->next) { | 4091 for (l = list; l != NULL; l = l->next) { |
4086 tab_complete_process_item(&most_matched, entered, &partial, nick_partial, | 4092 tab_complete_process_item(&most_matched, entered, entered_bytes, &partial, nick_partial, |
4087 &matches, TRUE, l->data); | 4093 &matches, TRUE, l->data); |
4088 } | 4094 } |
4089 g_list_free(list); | 4095 g_list_free(list); |
4090 } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { | 4096 } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { |
4091 PurpleConvChat *chat = PURPLE_CONV_CHAT(conv); | 4097 PurpleConvChat *chat = PURPLE_CONV_CHAT(conv); |
4094 GtkTreeIter iter; | 4100 GtkTreeIter iter; |
4095 int f; | 4101 int f; |
4096 | 4102 |
4097 /* Users */ | 4103 /* Users */ |
4098 for (; l != NULL; l = l->next) { | 4104 for (; l != NULL; l = l->next) { |
4099 tab_complete_process_item(&most_matched, entered, &partial, nick_partial, | 4105 tab_complete_process_item(&most_matched, entered, entered_bytes, &partial, nick_partial, |
4100 &matches, TRUE, ((PurpleConvChatBuddy *)l->data)->name); | 4106 &matches, TRUE, ((PurpleConvChatBuddy *)l->data)->name); |
4101 } | 4107 } |
4102 | 4108 |
4103 | 4109 |
4104 /* Aliases */ | 4110 /* Aliases */ |
4112 CHAT_USERS_NAME_COLUMN, &name, | 4118 CHAT_USERS_NAME_COLUMN, &name, |
4113 CHAT_USERS_ALIAS_COLUMN, &alias, | 4119 CHAT_USERS_ALIAS_COLUMN, &alias, |
4114 -1); | 4120 -1); |
4115 | 4121 |
4116 if (name && alias && strcmp(name, alias)) | 4122 if (name && alias && strcmp(name, alias)) |
4117 tab_complete_process_item(&most_matched, entered, &partial, nick_partial, | 4123 tab_complete_process_item(&most_matched, entered, entered_bytes, &partial, nick_partial, |
4118 &matches, FALSE, alias); | 4124 &matches, FALSE, alias); |
4119 g_free(name); | 4125 g_free(name); |
4120 g_free(alias); | 4126 g_free(alias); |
4121 | 4127 |
4122 f = gtk_tree_model_iter_next(model, &iter); | 4128 f = gtk_tree_model_iter_next(model, &iter); |