[gtksourceview] Add API to change text case



commit 45d8fde16a7cb0c705d9135a135dc19764a9fc53
Author: Paolo Borelli <pborelli gnome org>
Date:   Sun Nov 24 13:52:57 2013 +0100

    Add API to change text case
    
    Add API to change text to lowercase, uppercase, title case and to
    toggle text case. These were living in gedit for a long time but
    they should be here to be easily shared in all users of gtksourceview.

 docs/reference/gtksourceview-3.0-sections.txt |    2 +
 gtksourceview/gtksourcebuffer.c               |  136 +++++++++++++++++++++++++
 gtksourceview/gtksourcebuffer.h               |   20 ++++
 tests/test-buffer.c                           |   34 ++++++
 4 files changed, 192 insertions(+), 0 deletions(-)
---
diff --git a/docs/reference/gtksourceview-3.0-sections.txt b/docs/reference/gtksourceview-3.0-sections.txt
index 3b3bd10..0618e46 100644
--- a/docs/reference/gtksourceview-3.0-sections.txt
+++ b/docs/reference/gtksourceview-3.0-sections.txt
@@ -5,6 +5,7 @@
 <TITLE>GtkSourceBuffer</TITLE>
 GtkSourceBuffer
 GtkSourceBracketMatchType
+GtkSourceChangeCaseType
 gtk_source_buffer_new
 gtk_source_buffer_new_with_language
 gtk_source_buffer_set_highlight_syntax
@@ -26,6 +27,7 @@ gtk_source_buffer_iter_has_context_class
 gtk_source_buffer_get_context_classes_at_iter
 gtk_source_buffer_iter_forward_to_context_class_toggle
 gtk_source_buffer_iter_backward_to_context_class_toggle
+gtk_source_buffer_change_case
 <SUBSECTION>
 gtk_source_buffer_get_max_undo_levels
 gtk_source_buffer_set_max_undo_levels
diff --git a/gtksourceview/gtksourcebuffer.c b/gtksourceview/gtksourcebuffer.c
index 936f30c..4f86c92 100644
--- a/gtksourceview/gtksourcebuffer.c
+++ b/gtksourceview/gtksourcebuffer.c
@@ -2295,6 +2295,142 @@ gtk_source_buffer_iter_backward_to_context_class_toggle (GtkSourceBuffer *buffer
        }
 }
 
+static void
+do_lower_case (GtkTextBuffer *buffer,
+               GtkTextIter   *start,
+               GtkTextIter   *end,
+               GString       *str)
+{
+       while (!gtk_text_iter_is_end (start) &&
+              !gtk_text_iter_equal (start, end))
+       {
+               gunichar c, nc;
+
+               c = gtk_text_iter_get_char (start);
+               nc = g_unichar_tolower (c);
+               g_string_append_unichar (str, nc);
+
+               gtk_text_iter_forward_char (start);
+       }
+}
+
+static void
+do_upper_case (GtkTextBuffer *buffer,
+               GtkTextIter   *start,
+               GtkTextIter   *end,
+               GString       *str)
+{
+       while (!gtk_text_iter_is_end (start) &&
+              !gtk_text_iter_equal (start, end))
+       {
+               gunichar c, nc;
+
+               c = gtk_text_iter_get_char (start);
+               nc = g_unichar_toupper (c);
+               g_string_append_unichar (str, nc);
+
+               gtk_text_iter_forward_char (start);
+       }
+}
+
+static void
+do_toggle_case (GtkTextBuffer *buffer,
+                GtkTextIter   *start,
+                GtkTextIter   *end,
+                GString       *str)
+{
+       while (!gtk_text_iter_is_end (start) &&
+              !gtk_text_iter_equal (start, end))
+       {
+               gunichar c, nc;
+
+               c = gtk_text_iter_get_char (start);
+               if (g_unichar_islower (c))
+                       nc = g_unichar_toupper (c);
+               else
+                       nc = g_unichar_tolower (c);
+               g_string_append_unichar (str, nc);
+
+               gtk_text_iter_forward_char (start);
+       }
+}
+
+static void
+do_title_case (GtkTextBuffer *buffer,
+               GtkTextIter   *start,
+               GtkTextIter   *end,
+               GString       *str)
+{
+
+       while (!gtk_text_iter_is_end (start) &&
+              !gtk_text_iter_equal (start, end))
+       {
+               gunichar c, nc;
+
+               c = gtk_text_iter_get_char (start);
+               if (gtk_text_iter_starts_word (start))
+                       nc = g_unichar_totitle (c);
+               else
+                       nc = g_unichar_tolower (c);
+               g_string_append_unichar (str, nc);
+
+               gtk_text_iter_forward_char (start);
+       }
+}
+
+/**
+ * gtk_source_buffer_change_case:
+ * @buffer: a #GtkSourceBuffer.
+ * @case_type: how to change the case.
+ * @start: a #GtkTextIter.
+ * @end: a #GtkTextI
+ *
+ * Changes the case of the text between the specified iterators.
+ *
+ * Since: 3.12
+ **/
+void
+gtk_source_buffer_change_case (GtkSourceBuffer         *buffer,
+                               GtkSourceChangeCaseType  case_type,
+                               GtkTextIter             *start,
+                               GtkTextIter             *end)
+{
+       GtkTextIter i;
+       GString *s;
+
+       g_return_if_fail (GTK_SOURCE_IS_BUFFER (buffer));
+       g_return_if_fail (start != NULL);
+       g_return_if_fail (end != NULL);
+
+       i = *start;
+       s = g_string_new (NULL);
+
+       switch (case_type)
+       {
+       case GTK_SOURCE_CHANGE_CASE_UPPER:
+               do_upper_case (GTK_TEXT_BUFFER (buffer), &i, end, s);
+               break;
+       case GTK_SOURCE_CHANGE_CASE_LOWER:
+               do_lower_case (GTK_TEXT_BUFFER (buffer), &i, end, s);
+               break;
+       case GTK_SOURCE_CHANGE_CASE_TOGGLE:
+               do_toggle_case (GTK_TEXT_BUFFER (buffer), &i, end, s);
+               break;
+       case GTK_SOURCE_CHANGE_CASE_TITLE:
+               do_title_case (GTK_TEXT_BUFFER (buffer), &i, end, s);
+               break;
+       default:
+               g_return_if_reached ();
+       }
+
+       gtk_text_buffer_begin_user_action (GTK_TEXT_BUFFER (buffer));
+       gtk_text_buffer_delete_interactive (GTK_TEXT_BUFFER (buffer), start, end, TRUE);
+       gtk_text_buffer_insert_interactive (GTK_TEXT_BUFFER (buffer), start, s->str, s->len, TRUE);
+       gtk_text_buffer_end_user_action (GTK_TEXT_BUFFER (buffer));
+
+       g_string_free (s, TRUE);
+}
+
 /**
  * gtk_source_buffer_set_undo_manager:
  * @buffer: a #GtkSourceBuffer.
diff --git a/gtksourceview/gtksourcebuffer.h b/gtksourceview/gtksourcebuffer.h
index 9026ca2..167c692 100644
--- a/gtksourceview/gtksourcebuffer.h
+++ b/gtksourceview/gtksourcebuffer.h
@@ -56,6 +56,21 @@ typedef enum
        GTK_SOURCE_BRACKET_MATCH_FOUND
 } GtkSourceBracketMatchType;
 
+/**
+ * GtkSourceChangeCaseType:
+ * @GTK_SOURCE_CHANGE_CASE_LOWER: change case to lowercase.
+ * @GTK_SOURCE_CHANGE_CASE_UPPER: change case to uppercase.
+ * @GTK_SOURCE_CHANGE_CASE_TOGGLE: toggle case of each character.
+ * @GTK_SOURCE_CHANGE_CASE_TITLE: capitalize each word.
+ */
+typedef enum
+{
+       GTK_SOURCE_CHANGE_CASE_LOWER,
+       GTK_SOURCE_CHANGE_CASE_UPPER,
+       GTK_SOURCE_CHANGE_CASE_TOGGLE,
+       GTK_SOURCE_CHANGE_CASE_TITLE
+} GtkSourceChangeCaseType;
+
 struct _GtkSourceBuffer
 {
        GtkTextBuffer parent_instance;
@@ -175,6 +190,11 @@ gboolean            gtk_source_buffer_iter_backward_to_context_class_toggle
                                                                                 GtkTextIter            *iter,
                                                                                 const gchar            
*context_class);
 
+void                    gtk_source_buffer_change_case                          (GtkSourceBuffer        
*buffer,
+                                                                                GtkSourceChangeCaseType 
case_type,
+                                                                                GtkTextIter            
*start,
+                                                                                GtkTextIter            *end);
+
 GtkSourceUndoManager   *gtk_source_buffer_get_undo_manager                     (GtkSourceBuffer        
*buffer);
 
 void                    gtk_source_buffer_set_undo_manager                     (GtkSourceBuffer        
*buffer,
diff --git a/tests/test-buffer.c b/tests/test-buffer.c
index f4dd764..8084ec6 100644
--- a/tests/test-buffer.c
+++ b/tests/test-buffer.c
@@ -1,3 +1,5 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; coding: utf-8 -*- */
+
 #include <stdlib.h>
 #include <gtk/gtk.h>
 #include <gtksourceview/gtksource.h>
@@ -27,12 +29,44 @@ test_get_buffer (void)
        g_object_unref (view);
 }
 
+static void
+do_test_change_case (GtkSourceBuffer         *buffer,
+                     GtkSourceChangeCaseType  case_type,
+                     const char              *text,
+                     const char              *expected)
+{
+       GtkTextIter start, end;
+       char *changed;
+
+       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);
+       g_free (changed);
+}
+
+static void
+test_change_case (void)
+{
+       GtkSourceBuffer* buffer;
+
+       buffer = gtk_source_buffer_new (NULL);
+
+       do_test_change_case (buffer, GTK_SOURCE_CHANGE_CASE_LOWER, "some TEXT", "some text");
+       do_test_change_case (buffer, GTK_SOURCE_CHANGE_CASE_UPPER, "some TEXT", "SOME TEXT");
+       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");
+}
+
 int
 main (int argc, char** argv)
 {
        gtk_test_init (&argc, &argv);
 
        g_test_add_func ("/Buffer/bug-634510", test_get_buffer);
+       g_test_add_func ("/Buffer/change-case", test_change_case);
 
        return g_test_run();
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]