[gtksourceview] changecase: better character conversions
- From: Sébastien Wilmet <swilmet src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtksourceview] changecase: better character conversions
- Date: Thu, 25 Sep 2014 17:01:44 +0000 (UTC)
commit fd545bd9e501df65e9c67c5d679d2b0c5fc5344f
Author: Sébastien Wilmet <swilmet gnome org>
Date: Thu Sep 25 17:20:22 2014 +0200
changecase: better character conversions
Moving by cursor positions gives better results, since between two
cursor positions there may be several characters, like a letter+accent
mark.
https://bugzilla.gnome.org/show_bug.cgi?id=416390
gtksourceview/gtksourcebuffer.c | 187 +++++++++++++++++++++++++--------------
tests/test-buffer.c | 46 ++++++++--
2 files changed, 160 insertions(+), 73 deletions(-)
---
diff --git a/gtksourceview/gtksourcebuffer.c b/gtksourceview/gtksourcebuffer.c
index d1d0385..61b0b54 100644
--- a/gtksourceview/gtksourcebuffer.c
+++ b/gtksourceview/gtksourcebuffer.c
@@ -2298,102 +2298,158 @@ gtk_source_buffer_iter_backward_to_context_class_toggle (GtkSourceBuffer *buffer
}
}
-static void
+static gchar *
do_lower_case (GtkTextBuffer *buffer,
const GtkTextIter *start,
- const GtkTextIter *end,
- GString *str)
+ const GtkTextIter *end)
{
- GtkTextIter iter = *start;
-
- while (!gtk_text_iter_is_end (&iter) &&
- !gtk_text_iter_equal (&iter, end))
- {
- gunichar c, nc;
+ gchar *text;
+ gchar *new_text;
- c = gtk_text_iter_get_char (&iter);
- nc = g_unichar_tolower (c);
- g_string_append_unichar (str, nc);
+ text = gtk_text_buffer_get_text (buffer, start, end, TRUE);
+ new_text = g_utf8_strdown (text, -1);
- gtk_text_iter_forward_char (&iter);
- }
+ g_free (text);
+ return new_text;
}
-static void
+static gchar *
do_upper_case (GtkTextBuffer *buffer,
const GtkTextIter *start,
- const GtkTextIter *end,
- GString *str)
+ const GtkTextIter *end)
{
- GtkTextIter iter = *start;
-
- while (!gtk_text_iter_is_end (&iter) &&
- !gtk_text_iter_equal (&iter, end))
- {
- gunichar c, nc;
+ gchar *text;
+ gchar *new_text;
- c = gtk_text_iter_get_char (&iter);
- nc = g_unichar_toupper (c);
- g_string_append_unichar (str, nc);
+ text = gtk_text_buffer_get_text (buffer, start, end, TRUE);
+ new_text = g_utf8_strup (text, -1);
- gtk_text_iter_forward_char (&iter);
- }
+ g_free (text);
+ return new_text;
}
-static void
+static gchar *
do_toggle_case (GtkTextBuffer *buffer,
const GtkTextIter *start,
- const GtkTextIter *end,
- GString *str)
+ const GtkTextIter *end)
{
- GtkTextIter iter = *start;
+ GString *str;
+ GtkTextIter iter_start;
- while (!gtk_text_iter_is_end (&iter) &&
- !gtk_text_iter_equal (&iter, end))
+ str = g_string_new (NULL);
+ iter_start = *start;
+
+ while (!gtk_text_iter_is_end (&iter_start))
{
- gunichar c, nc;
+ GtkTextIter iter_end;
+ gchar *text;
+ gchar *text_down;
+ gchar *text_up;
+
+ iter_end = iter_start;
+ gtk_text_iter_forward_cursor_position (&iter_end);
+
+ if (gtk_text_iter_compare (end, &iter_end) < 0)
+ {
+ break;
+ }
+
+ text = gtk_text_buffer_get_text (buffer, &iter_start, &iter_end, TRUE);
+ text_down = g_utf8_strdown (text, -1);
+ text_up = g_utf8_strup (text, -1);
- c = gtk_text_iter_get_char (&iter);
- if (g_unichar_islower (c))
+ if (g_strcmp0 (text, text_down) == 0)
{
- nc = g_unichar_toupper (c);
+ g_string_append (str, text_up);
+ }
+ else if (g_strcmp0 (text, text_up) == 0)
+ {
+ g_string_append (str, text_down);
}
else
{
- nc = g_unichar_tolower (c);
+ g_string_append (str, text);
}
- g_string_append_unichar (str, nc);
- gtk_text_iter_forward_char (&iter);
+ g_free (text);
+ g_free (text_down);
+ g_free (text_up);
+
+ iter_start = iter_end;
}
+
+ return g_string_free (str, FALSE);
}
-static void
+static gchar *
do_title_case (GtkTextBuffer *buffer,
const GtkTextIter *start,
- const GtkTextIter *end,
- GString *str)
+ const GtkTextIter *end)
{
- GtkTextIter iter = *start;
+ GString *str;
+ GtkTextIter iter_start;
- while (!gtk_text_iter_is_end (&iter) &&
- !gtk_text_iter_equal (&iter, end))
+ str = g_string_new (NULL);
+ iter_start = *start;
+
+ while (!gtk_text_iter_is_end (&iter_start))
{
- gunichar c, nc;
+ GtkTextIter iter_end;
+ gchar *text;
+
+ iter_end = iter_start;
+ gtk_text_iter_forward_cursor_position (&iter_end);
- c = gtk_text_iter_get_char (&iter);
- if (gtk_text_iter_starts_word (&iter))
+ if (gtk_text_iter_compare (end, &iter_end) < 0)
{
- nc = g_unichar_totitle (c);
+ break;
+ }
+
+ text = gtk_text_buffer_get_text (buffer, &iter_start, &iter_end, TRUE);
+
+ if (gtk_text_iter_starts_word (&iter_start))
+ {
+ gchar *text_normalized;
+
+ text_normalized = g_utf8_normalize (text, -1, G_NORMALIZE_DEFAULT);
+
+ if (g_utf8_strlen (text_normalized, -1) == 1)
+ {
+ gunichar c;
+ gunichar new_c;
+
+ c = gtk_text_iter_get_char (&iter_start);
+ new_c = g_unichar_totitle (c);
+
+ g_string_append_unichar (str, new_c);
+ }
+ else
+ {
+ gchar *text_up;
+
+ text_up = g_utf8_strup (text, -1);
+ g_string_append (str, text_up);
+
+ g_free (text_up);
+ }
+
+ g_free (text_normalized);
}
else
{
- nc = g_unichar_tolower (c);
+ gchar *text_down;
+
+ text_down = g_utf8_strdown (text, -1);
+ g_string_append (str, text_down);
+
+ g_free (text_down);
}
- g_string_append_unichar (str, nc);
- gtk_text_iter_forward_char (&iter);
+ g_free (text);
+ iter_start = iter_end;
}
+
+ return g_string_free (str, FALSE);
}
/**
@@ -2414,31 +2470,32 @@ gtk_source_buffer_change_case (GtkSourceBuffer *buffer,
GtkTextIter *end)
{
GtkTextBuffer *text_buffer;
- GString *str;
+ gchar *new_text;
g_return_if_fail (GTK_SOURCE_IS_BUFFER (buffer));
g_return_if_fail (start != NULL);
g_return_if_fail (end != NULL);
+ gtk_text_iter_order (start, end);
+
text_buffer = GTK_TEXT_BUFFER (buffer);
- str = g_string_new (NULL);
switch (case_type)
{
- case GTK_SOURCE_CHANGE_CASE_UPPER:
- do_upper_case (text_buffer, start, end, str);
+ case GTK_SOURCE_CHANGE_CASE_LOWER:
+ new_text = do_lower_case (text_buffer, start, end);
break;
- case GTK_SOURCE_CHANGE_CASE_LOWER:
- do_lower_case (text_buffer, start, end, str);
+ case GTK_SOURCE_CHANGE_CASE_UPPER:
+ new_text = do_upper_case (text_buffer, start, end);
break;
case GTK_SOURCE_CHANGE_CASE_TOGGLE:
- do_toggle_case (text_buffer, start, end, str);
+ new_text = do_toggle_case (text_buffer, start, end);
break;
case GTK_SOURCE_CHANGE_CASE_TITLE:
- do_title_case (text_buffer, start, end, str);
+ new_text = do_title_case (text_buffer, start, end);
break;
default:
@@ -2446,11 +2503,11 @@ gtk_source_buffer_change_case (GtkSourceBuffer *buffer,
}
gtk_text_buffer_begin_user_action (text_buffer);
- gtk_text_buffer_delete_interactive (text_buffer, start, end, TRUE);
- gtk_text_buffer_insert_interactive (text_buffer, start, str->str, str->len, TRUE);
+ gtk_text_buffer_delete (text_buffer, start, end);
+ gtk_text_buffer_insert (text_buffer, start, new_text, -1);
gtk_text_buffer_end_user_action (text_buffer);
- g_string_free (str, TRUE);
+ g_free (new_text);
}
/**
diff --git a/tests/test-buffer.c b/tests/test-buffer.c
index b2d34fc..cba7065 100644
--- a/tests/test-buffer.c
+++ b/tests/test-buffer.c
@@ -43,8 +43,8 @@ init_default_manager (void)
static void
test_get_buffer (void)
{
- GtkWidget* view;
- GtkSourceBuffer* buffer;
+ GtkWidget *view;
+ GtkSourceBuffer *buffer;
view = gtk_source_view_new ();
@@ -113,20 +113,32 @@ test_get_context_classes (void)
static void
do_test_change_case (GtkSourceBuffer *buffer,
- GtkSourceChangeCaseType case_type,
- const char *text,
- const char *expected)
+ GtkSourceChangeCaseType case_type,
+ const gchar *text,
+ const gchar *expected)
{
- GtkTextIter start, end;
- char *changed;
+ GtkTextIter start;
+ GtkTextIter end;
+ gchar *changed;
+ gchar *changed_normalized;
+ gchar *expected_normalized;
gtk_text_buffer_set_text (GTK_TEXT_BUFFER (buffer), text, -1);
+
gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (buffer), &start, &end);
gtk_source_buffer_change_case (buffer, case_type, &start, &end);
+
gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (buffer), &start, &end);
changed = gtk_text_buffer_get_text (GTK_TEXT_BUFFER (buffer), &start, &end, TRUE);
- g_assert_cmpstr (changed, ==, expected);
+
+ changed_normalized = g_utf8_normalize (changed, -1, G_NORMALIZE_DEFAULT);
+ expected_normalized = g_utf8_normalize (expected, -1, G_NORMALIZE_DEFAULT);
+
+ g_assert_cmpstr (changed_normalized, ==, expected_normalized);
+
g_free (changed);
+ g_free (changed_normalized);
+ g_free (expected_normalized);
}
static void
@@ -141,6 +153,24 @@ test_change_case (void)
do_test_change_case (buffer, GTK_SOURCE_CHANGE_CASE_TOGGLE, "some TEXT", "SOME text");
do_test_change_case (buffer, GTK_SOURCE_CHANGE_CASE_TITLE, "some TEXT", "Some Text");
+ /* https://bugzilla.gnome.org/show_bug.cgi?id=416390 */
+ do_test_change_case (buffer, GTK_SOURCE_CHANGE_CASE_LOWER, "T̈OME", "ẗome");
+ do_test_change_case (buffer, GTK_SOURCE_CHANGE_CASE_UPPER, "ẗome", "T̈OME");
+ do_test_change_case (buffer, GTK_SOURCE_CHANGE_CASE_TOGGLE, "ẗome", "T̈OME");
+ do_test_change_case (buffer, GTK_SOURCE_CHANGE_CASE_TOGGLE, "T̈OME", "ẗome");
+ do_test_change_case (buffer, GTK_SOURCE_CHANGE_CASE_TITLE, "ẗome", "T̈ome");
+
+ /* test g_unichar_totitle */
+ do_test_change_case (buffer, GTK_SOURCE_CHANGE_CASE_LOWER, "\307\261adzíki", "\307\263adzíki");
+ do_test_change_case (buffer, GTK_SOURCE_CHANGE_CASE_LOWER, "\307\262adzíki", "\307\263adzíki");
+ do_test_change_case (buffer, GTK_SOURCE_CHANGE_CASE_LOWER, "\307\263adzíki", "\307\263adzíki");
+ do_test_change_case (buffer, GTK_SOURCE_CHANGE_CASE_UPPER, "\307\263adzíki", "\307\261ADZÍKI");
+ do_test_change_case (buffer, GTK_SOURCE_CHANGE_CASE_UPPER, "\307\262adzíki", "\307\261ADZÍKI");
+ do_test_change_case (buffer, GTK_SOURCE_CHANGE_CASE_TOGGLE, "\307\263adzíki", "\307\261ADZÍKI");
+ do_test_change_case (buffer, GTK_SOURCE_CHANGE_CASE_TITLE, "\307\263adzíki", "\307\262adzíki");
+ do_test_change_case (buffer, GTK_SOURCE_CHANGE_CASE_TITLE, "\307\261ADZÍKI", "\307\262adzíki");
+ do_test_change_case (buffer, GTK_SOURCE_CHANGE_CASE_TITLE, "\307\262ADZÍKI", "\307\262adzíki");
+
g_object_unref (buffer);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]