diff options
Diffstat (limited to 'addressbook')
-rw-r--r-- | addressbook/ChangeLog | 19 | ||||
-rw-r--r-- | addressbook/gui/component/select-names/e-select-names-model.c | 13 | ||||
-rw-r--r-- | addressbook/gui/component/select-names/e-select-names-text-model.c | 93 |
3 files changed, 94 insertions, 31 deletions
diff --git a/addressbook/ChangeLog b/addressbook/ChangeLog index fb355f6ac1..f21d687ee7 100644 --- a/addressbook/ChangeLog +++ b/addressbook/ChangeLog @@ -1,5 +1,24 @@ 2003-05-13 Chris Toshok <toshok@ximian.com> + * gui/component/select-names/e-select-names-text-model.c + (e_select_names_text_model_set_separator): strlen -> + g_utf8_strlen. + (e_select_names_text_model_insert): same. + (e_select_names_text_model_insert_length): big change, make this + work with multibyte utf8. + (e_select_names_text_model_delete): same. this could possibly use + a tighter loop + a memmove, but this works. + + * gui/component/select-names/e-select-names-model.c + (e_select_names_model_get_textification): make sure our truncation + to MAX_LENGTH characters uses utf8 characters, not bytes. + (e_select_names_model_name_pos): track e-text-model change. + pos/length are now in utf8 character terms, so use g_utf8_strlen + instead of strlen. + (e_select_names_model_text_pos): same. + +2003-05-13 Chris Toshok <toshok@ximian.com> + * gui/widgets/e-addressbook-table-adapter.c (addressbook_dispose): rename addressbook_destroy to this, and guard against multiple calls. diff --git a/addressbook/gui/component/select-names/e-select-names-model.c b/addressbook/gui/component/select-names/e-select-names-model.c index 595b4a257e..6c3cb0f9c6 100644 --- a/addressbook/gui/component/select-names/e-select-names-model.c +++ b/addressbook/gui/component/select-names/e-select-names-model.c @@ -219,10 +219,11 @@ e_select_names_model_get_textification (ESelectNamesModel *model, const char *se } text = g_strjoinv (separator, strv); - - if (strlen(text) > MAX_LENGTH) { - text[MAX_LENGTH] = '\0'; - text = g_realloc (text, MAX_LENGTH + 1); + + if (g_utf8_strlen(text, -1) > MAX_LENGTH) { + char *p = g_utf8_offset_to_pointer (text, MAX_LENGTH); + *p = '\0'; + text = g_realloc (text, p - text + 1); } g_free (strv); @@ -650,7 +651,7 @@ e_select_names_model_name_pos (ESelectNamesModel *model, gint seplen, gint index while (iter && i <= index) { rp += len + (i > 0 ? seplen : 0); str = e_destination_get_textrep (E_DESTINATION (iter->data), FALSE); - len = str ? strlen (str) : 0; + len = str ? g_utf8_strlen (str, -1) : 0; ++i; iter = g_list_next (iter); } @@ -680,7 +681,7 @@ e_select_names_model_text_pos (ESelectNamesModel *model, gint seplen, gint pos, while (iter != NULL) { str = e_destination_get_textrep (E_DESTINATION (iter->data), FALSE); - len = str ? strlen (str) : 0; + len = str ? g_utf8_strlen (str, -1) : 0; if (sp <= pos && pos <= sp + len + adj) { break; diff --git a/addressbook/gui/component/select-names/e-select-names-text-model.c b/addressbook/gui/component/select-names/e-select-names-text-model.c index 269e0599a3..c2ddfcf96c 100644 --- a/addressbook/gui/component/select-names/e-select-names-text-model.c +++ b/addressbook/gui/component/select-names/e-select-names-text-model.c @@ -297,7 +297,7 @@ e_select_names_text_model_set_separator (ESelectNamesTextModel *model, const cha g_free (model->sep); model->sep = g_strdup (sep); - model->seplen = strlen (sep); + model->seplen = g_utf8_strlen (sep, -1); } static const gchar * @@ -325,7 +325,7 @@ e_select_names_text_model_set_text (ETextModel *model, const gchar *text) static void e_select_names_text_model_insert (ETextModel *model, gint position, const gchar *text) { - e_select_names_text_model_insert_length (model, position, text, strlen (text)); + e_select_names_text_model_insert_length (model, position, text, g_utf8_strlen (text, -1)); } static void @@ -333,8 +333,7 @@ e_select_names_text_model_insert_length (ETextModel *model, gint pos, const gcha { ESelectNamesTextModel *text_model = E_SELECT_NAMES_TEXT_MODEL (model); ESelectNamesModel *source = text_model->source; - - gint i; + const char *t; if (out) { gchar *tmp = g_strndup (text, length); @@ -342,7 +341,7 @@ e_select_names_text_model_insert_length (ETextModel *model, gint pos, const gcha g_free (tmp); } - pos = CLAMP (pos, 0, strlen (e_select_names_model_get_textification (source, text_model->sep))); + pos = CLAMP (pos, 0, g_utf8_strlen (e_select_names_model_get_textification (source, text_model->sep), -1)); /* We want to control all cursor motions ourselves, rather than taking hints from the ESelectNamesModel. */ @@ -350,40 +349,49 @@ e_select_names_text_model_insert_length (ETextModel *model, gint pos, const gcha /* We handle this one character at a time. */ - for (i = 0; i < length && text[i]; ++i) { + for (t = text; length >= 0; t = g_utf8_next_char (t), length--) { gint index, start_pos, text_len; gboolean inside_quote = FALSE; + gunichar ut = g_utf8_get_char (t); + + if (ut == 0) + break; text_model->last_magic_comma_pos = -1; if (out) - fprintf (out, "processing [%c]\n", text[i]); + fprintf (out, "processing [%d]\n", ut); e_select_names_model_text_pos (source, text_model->seplen, pos, &index, &start_pos, &text_len); if (out) fprintf (out, "index=%d start_pos=%d text_len=%d\n", index, start_pos, text_len); - if (text[i] == *text_model->sep && index >= 0) { /* Is this a quoted or an unquoted separator we are dealing with? */ + /* Is this a quoted or an unquoted separator we are dealing with? */ + if (ut == g_utf8_get_char(text_model->sep) && index >= 0) { const EDestination *dest = e_select_names_model_get_destination (source, index); if (dest) { const gchar *str = e_destination_get_textrep (dest, FALSE); - gint j; + int j; + const char *jp; + if (out) fprintf (out, "str=%s pos=%d\n", str, pos); - for (j=0; j<pos-start_pos && str[j]; ++j) - if (str[j] == '"') { + + for (jp = str, j = 0; j<pos-start_pos && *jp; jp = g_utf8_next_char (jp), ++j) { + if (*jp == '"') { inside_quote = !inside_quote; if (out) fprintf (out, "flip to %d at %d\n", start_pos+j, inside_quote); } + } } if (out) fprintf (out, inside_quote ? "inside quote\n" : "not inside quote\n"); } - if (text[i] == *text_model->sep && !inside_quote) { + if (ut == g_utf8_get_char (text_model->sep) && !inside_quote) { /* This is the case of hitting , first thing in an empty entry */ if (index == -1) { @@ -449,9 +457,9 @@ e_select_names_text_model_insert_length (ETextModel *model, gint pos, const gcha EReposInsertShift repos; gint offset = MAX (pos - start_pos, 0); const gchar *str; - gchar *new_str = NULL; + GString *new_str = g_string_new (NULL); gint this_length = 1; - gboolean whitespace = isspace ((gint) text[i]); + gboolean whitespace = g_unichar_isspace (ut); str = index >= 0 ? e_select_names_model_get_string (source, index) : NULL; if (str && *str) { @@ -462,27 +470,34 @@ e_select_names_text_model_insert_length (ETextModel *model, gint pos, const gcha } else { /* Adjust for our "magic white space" */ /* FIXME: This code does the wrong thing if seplen > 2 */ - new_str = g_strdup_printf("%c%s%s", text[i], pos < start_pos ? " " : "", str); + g_string_append_unichar (new_str, ut); + g_string_append (new_str, pos < start_pos ? " " : ""); + g_string_append (new_str, str); if (pos < start_pos) ++this_length; } } else { - new_str = g_strdup_printf ("%.*s%c%s", offset, str, text[i], str + offset); + const char *u; + int n; + for (u = str, n = 0; n < offset; u = g_utf8_next_char (u), n++) + g_string_append_unichar (new_str, g_utf8_get_char (u)); + g_string_append_unichar (new_str, ut); + g_string_append (new_str, u); } } else { if (whitespace) { /* swallow leading whitespace */ this_length = 0; } else { - new_str = g_strdup_printf ("%c", text[i]); + g_string_append_unichar (new_str, ut); } } - if (new_str) { + if (new_str->len) { EDestination *dest; dest = index >= 0 ? e_destination_copy (e_select_names_model_get_destination (source, index)) : e_destination_new (); - e_destination_set_raw (dest, new_str); + e_destination_set_raw (dest, new_str->str); e_select_names_model_replace (source, index, dest); /* e_select_names_model_replace (source, index, dest); */ @@ -495,9 +510,8 @@ e_select_names_text_model_insert_length (ETextModel *model, gint pos, const gcha pos += this_length; } - - g_free (new_str); } + g_string_free (new_str, TRUE); } } @@ -666,12 +680,41 @@ e_select_names_text_model_delete (ETextModel *model, gint pos, gint length) offset = pos - start_pos; str = e_select_names_model_get_string (source, index); - new_str = str ? g_strdup_printf ("%.*s%s", offset, str, str + offset + length) : NULL; - - if (new_str) { + + if (str) { + const char *p; + char *np; + int i; EReposDeleteShift repos; EDestination *dest; + new_str = g_new0 (char, strlen (str) * 6 + 1); /* worse case it can't be any longer than this */ + + /* copy the region before the deletion */ + for (p = str, i = 0, np = new_str; i < offset; i++) { + gunichar ch; + + ch = g_utf8_get_char (p); + g_unichar_to_utf8 (ch, np); + + np = g_utf8_next_char (np); + p = g_utf8_next_char (p); + } + + /* skip the deleted segment */ + for (i = 0; i < length; i++) + p = g_utf8_next_char (p); + + /* copy the region after the deletion */ + for (; *p; p = g_utf8_next_char (p)) { + gunichar ch; + + ch = g_utf8_get_char (p); + g_unichar_to_utf8 (ch, np); + + np = g_utf8_next_char (np); + } + dest = index >= 0 ? e_destination_copy (e_select_names_model_get_destination (source, index)) : e_destination_new (); e_destination_set_raw (dest, new_str); e_select_names_model_replace (source, index, dest); @@ -768,7 +811,7 @@ e_select_names_text_model_get_nth_obj (ETextModel *model, gint n, gint *len) if (text_model->text == NULL) text_model->text = e_select_names_model_get_textification (source, text_model->sep); - return text_model->text + pos; + return g_utf8_offset_to_pointer (text_model->text, pos); } static void |