aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMilan Crha <mcrha@redhat.com>2013-01-12 00:07:05 +0800
committerMilan Crha <mcrha@redhat.com>2013-01-12 00:09:02 +0800
commitadc0ad91c4e187d814d41edd69a6c53c6405f235 (patch)
tree5d511f09f581bf5bd8caac5da29608ba10b1017c
parent57b3e6c760e8bdcdb59d1e28108abdf92999c087 (diff)
downloadgsoc2013-evolution-adc0ad91c4e187d814d41edd69a6c53c6405f235.tar
gsoc2013-evolution-adc0ad91c4e187d814d41edd69a6c53c6405f235.tar.gz
gsoc2013-evolution-adc0ad91c4e187d814d41edd69a6c53c6405f235.tar.bz2
gsoc2013-evolution-adc0ad91c4e187d814d41edd69a6c53c6405f235.tar.lz
gsoc2013-evolution-adc0ad91c4e187d814d41edd69a6c53c6405f235.tar.xz
gsoc2013-evolution-adc0ad91c4e187d814d41edd69a6c53c6405f235.tar.zst
gsoc2013-evolution-adc0ad91c4e187d814d41edd69a6c53c6405f235.zip
Bug #691470 - ENameSelectorEntry: Copy to clipboard issue with multi-byte characters
-rw-r--r--e-util/e-name-selector-entry.c43
1 files changed, 32 insertions, 11 deletions
diff --git a/e-util/e-name-selector-entry.c b/e-util/e-name-selector-entry.c
index ea7e2ef383..45038c0fee 100644
--- a/e-util/e-name-selector-entry.c
+++ b/e-util/e-name-selector-entry.c
@@ -3062,6 +3062,13 @@ populate_popup (ENameSelectorEntry *name_selector_entry,
deep_free_list (email_list);
}
+static gint
+compare_gint_ptr_cb (gconstpointer a,
+ gconstpointer b)
+{
+ return GPOINTER_TO_INT (a) - GPOINTER_TO_INT (b);
+}
+
static void
copy_or_cut_clipboard (ENameSelectorEntry *name_selector_entry,
gboolean is_cut)
@@ -3072,8 +3079,9 @@ copy_or_cut_clipboard (ENameSelectorEntry *name_selector_entry,
GHashTable *hash;
GHashTableIter iter;
gpointer key, value;
+ GSList *sorted, *siter;
GString *addresses;
- gint ii, start, end;
+ gint ii, start, end, ostart, oend;
gunichar uc;
editable = GTK_EDITABLE (name_selector_entry);
@@ -3086,6 +3094,10 @@ copy_or_cut_clipboard (ENameSelectorEntry *name_selector_entry,
hash = g_hash_table_new (g_direct_hash, g_direct_equal);
+ /* convert from character indexes to pointer indexes */
+ ostart = g_utf8_offset_to_pointer (text, start) - text;
+ oend = g_utf8_offset_to_pointer (text, end) - text;
+
ii = end;
cp = g_utf8_offset_to_pointer (text, end);
uc = g_utf8_get_char (cp);
@@ -3103,27 +3115,37 @@ copy_or_cut_clipboard (ENameSelectorEntry *name_selector_entry,
g_hash_table_insert (hash, GINT_TO_POINTER (index), NULL);
}
- addresses = g_string_new ("");
-
+ sorted = NULL;
g_hash_table_iter_init (&iter, hash);
while (g_hash_table_iter_next (&iter, &key, &value)) {
- gint index = GPOINTER_TO_INT (key);
+ sorted = g_slist_prepend (sorted, key);
+ }
+
+ sorted = g_slist_sort (sorted, compare_gint_ptr_cb);
+ addresses = g_string_new ("");
+
+ for (siter = sorted; siter != NULL; siter = g_slist_next (siter)) {
+ gint index = GPOINTER_TO_INT (siter->data);
EDestination *dest;
gint rstart, rend;
if (!get_range_by_index (text, index, &rstart, &rend))
continue;
- if (rstart < start) {
+ /* convert from character indexes to pointer indexes */
+ rstart = g_utf8_offset_to_pointer (text, rstart) - text;
+ rend = g_utf8_offset_to_pointer (text, rend) - text;
+
+ if (rstart < ostart) {
if (addresses->str && *addresses->str)
g_string_append (addresses, ", ");
- g_string_append_len (addresses, text + start, rend - start);
- } else if (rend > end) {
+ g_string_append_len (addresses, text + ostart, MIN (oend - ostart, rend - ostart));
+ } else if (rend > oend) {
if (addresses->str && *addresses->str)
g_string_append (addresses, ", ");
- g_string_append_len (addresses, text + rstart, end - rstart);
+ g_string_append_len (addresses, text + rstart, oend - rstart);
} else {
/* the contact is whole selected */
dest = find_destination_by_index (name_selector_entry, index);
@@ -3132,14 +3154,13 @@ copy_or_cut_clipboard (ENameSelectorEntry *name_selector_entry,
g_string_append (addresses, ", ");
g_string_append (addresses, e_destination_get_textrep (dest, TRUE));
-
- /* store the 'dest' as a value for the index */
- g_hash_table_insert (hash, GINT_TO_POINTER (index), dest);
} else
g_string_append_len (addresses, text + rstart, rend - rstart);
}
}
+ g_slist_free (sorted);
+
if (is_cut)
gtk_editable_delete_text (editable, start, end);