From: Matthias Clasen Date: Tue, 14 Jan 2003 01:07:58 +0000 (+0000) Subject: Skip invisible chars for GTK_MOVEMENT_LOGICAL_POSITIONS and X-Git-Url: http://pileus.org/git/?a=commitdiff_plain;h=740f871a15b5bf0282bd6bbf1f4fc3423d04ce1b;p=~andy%2Fgtk Skip invisible chars for GTK_MOVEMENT_LOGICAL_POSITIONS and * gtk/gtktextview.c (gtk_text_view_move_cursor_internal): Skip invisible chars for GTK_MOVEMENT_LOGICAL_POSITIONS and GTK_MOVEMENT_WORDS. * gtk/gtktextiter.c, gtk/gtktextiter.h: Add some variant movement functions which skip invisible chars, and do some cleanups. * gtk/gtk-sections.txt: Add new GtkTextIter functions. --- diff --git a/ChangeLog b/ChangeLog index ebe3153e2..22d446119 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2003-01-14 Matthias Clasen + + * gtk/gtktextview.c (gtk_text_view_move_cursor_internal): Skip + invisible chars for GTK_MOVEMENT_LOGICAL_POSITIONS and + GTK_MOVEMENT_WORDS. + + * gtk/gtktextiter.c, + gtk/gtktextiter.h: Add some variant movement functions which + skip invisible chars, and do some cleanups. + 2003-01-12 Tor Lillqvist Merge from stable: diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index ebe3153e2..22d446119 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,13 @@ +2003-01-14 Matthias Clasen + + * gtk/gtktextview.c (gtk_text_view_move_cursor_internal): Skip + invisible chars for GTK_MOVEMENT_LOGICAL_POSITIONS and + GTK_MOVEMENT_WORDS. + + * gtk/gtktextiter.c, + gtk/gtktextiter.h: Add some variant movement functions which + skip invisible chars, and do some cleanups. + 2003-01-12 Tor Lillqvist Merge from stable: diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index ebe3153e2..22d446119 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,13 @@ +2003-01-14 Matthias Clasen + + * gtk/gtktextview.c (gtk_text_view_move_cursor_internal): Skip + invisible chars for GTK_MOVEMENT_LOGICAL_POSITIONS and + GTK_MOVEMENT_WORDS. + + * gtk/gtktextiter.c, + gtk/gtktextiter.h: Add some variant movement functions which + skip invisible chars, and do some cleanups. + 2003-01-12 Tor Lillqvist Merge from stable: diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index ebe3153e2..22d446119 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,13 @@ +2003-01-14 Matthias Clasen + + * gtk/gtktextview.c (gtk_text_view_move_cursor_internal): Skip + invisible chars for GTK_MOVEMENT_LOGICAL_POSITIONS and + GTK_MOVEMENT_WORDS. + + * gtk/gtktextiter.c, + gtk/gtktextiter.h: Add some variant movement functions which + skip invisible chars, and do some cleanups. + 2003-01-12 Tor Lillqvist Merge from stable: diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index ebe3153e2..22d446119 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,13 @@ +2003-01-14 Matthias Clasen + + * gtk/gtktextview.c (gtk_text_view_move_cursor_internal): Skip + invisible chars for GTK_MOVEMENT_LOGICAL_POSITIONS and + GTK_MOVEMENT_WORDS. + + * gtk/gtktextiter.c, + gtk/gtktextiter.h: Add some variant movement functions which + skip invisible chars, and do some cleanups. + 2003-01-12 Tor Lillqvist Merge from stable: diff --git a/docs/reference/ChangeLog b/docs/reference/ChangeLog index 6022e479c..0fec5cfd0 100644 --- a/docs/reference/ChangeLog +++ b/docs/reference/ChangeLog @@ -1,9 +1,13 @@ +2003-01-14 Matthias Clasen + + * gtk/gtk-sections.txt: Add new GtkTextIter functions. + 2003-01-13 Matthias Clasen * gdk-pixbuf/tmpl/gdk-pixbuf.sgml: * gdk-pixbuf/tmpl/animation.sgml: Remove ids which are now generated by gtk-doc. - + 2003-01-03 Matthias Clasen * gtk/tmpl/gtkrc.sgml: Update description of priorities for styles diff --git a/docs/reference/gtk/gtk-sections.txt b/docs/reference/gtk/gtk-sections.txt index 6d5053c75..8f7f9aae2 100644 --- a/docs/reference/gtk/gtk-sections.txt +++ b/docs/reference/gtk/gtk-sections.txt @@ -2463,6 +2463,14 @@ gtk_text_iter_backward_sentence_start gtk_text_iter_backward_sentence_starts gtk_text_iter_forward_sentence_end gtk_text_iter_forward_sentence_ends +gtk_text_iter_forward_visible_word_ends +gtk_text_iter_backward_visible_word_starts +gtk_text_iter_forward_visible_word_end +gtk_text_iter_backward_visible_word_start +gtk_text_iter_forward_visible_cursor_position +gtk_text_iter_backward_visible_cursor_position +gtk_text_iter_forward_visible_cursor_positions +gtk_text_iter_backward_visible_cursor_positions gtk_text_iter_set_offset gtk_text_iter_set_line gtk_text_iter_set_line_offset diff --git a/gtk/gtktextiter.c b/gtk/gtktextiter.c index d49ceeeb0..ecc2b4076 100644 --- a/gtk/gtktextiter.c +++ b/gtk/gtktextiter.c @@ -2995,6 +2995,64 @@ find_by_log_attrs (GtkTextIter *iter, } } +static gboolean +find_visible_by_log_attrs (GtkTextIter *iter, + FindLogAttrFunc func, + gboolean forward, + gboolean already_moved_initially) +{ + GtkTextIter pos; + + g_return_val_if_fail (iter != NULL, FALSE); + + pos = *iter; + + while (find_by_log_attrs (&pos, func, forward, already_moved_initially)) + { + if (!_gtk_text_btree_char_is_invisible (&pos)) + { + *iter = pos; + return TRUE; + } + } + + return FALSE; +} + +typedef gboolean (* OneStepFunc) (GtkTextIter *iter); +typedef gboolean (* MultipleStepFunc) (GtkTextIter *iter, gint count); + +static gboolean +move_multiple_steps (GtkTextIter *iter, + gint count, + OneStepFunc step_forward, + MultipleStepFunc n_steps_backward) +{ + g_return_val_if_fail (iter != NULL, FALSE); + + FIX_OVERFLOWS (count); + + if (count == 0) + return FALSE; + + if (count < 0) + return n_steps_backward (iter, -count); + + if (!step_forward (iter)) + return FALSE; + --count; + + while (count > 0) + { + if (!step_forward (iter)) + break; + --count; + } + + return !gtk_text_iter_is_end (iter); +} + + /** * gtk_text_iter_forward_word_end: * @iter: a #GtkTextIter @@ -3048,28 +3106,9 @@ gboolean gtk_text_iter_forward_word_ends (GtkTextIter *iter, gint count) { - g_return_val_if_fail (iter != NULL, FALSE); - - FIX_OVERFLOWS (count); - - if (count == 0) - return FALSE; - - if (count < 0) - return gtk_text_iter_backward_word_starts (iter, -count); - - if (!gtk_text_iter_forward_word_end (iter)) - return FALSE; - --count; - - while (count > 0) - { - if (!gtk_text_iter_forward_word_end (iter)) - break; - --count; - } - - return !gtk_text_iter_is_end (iter); + return move_multiple_steps (iter, count, + gtk_text_iter_forward_word_end, + gtk_text_iter_backward_word_starts); } /** @@ -3085,25 +3124,89 @@ gboolean gtk_text_iter_backward_word_starts (GtkTextIter *iter, gint count) { - g_return_val_if_fail (iter != NULL, FALSE); + return move_multiple_steps (iter, count, + gtk_text_iter_backward_word_start, + gtk_text_iter_forward_word_ends); +} - FIX_OVERFLOWS (count); - - if (count < 0) - return gtk_text_iter_forward_word_ends (iter, -count); +/** + * gtk_text_iter_forward_visible_word_end: + * @iter: a #GtkTextIter + * + * Moves forward to the next visible word end. (If @iter is currently on a + * word end, moves forward to the next one after that.) Word breaks + * are determined by Pango and should be correct for nearly any + * language (if not, the correct fix would be to the Pango word break + * algorithms). + * + * Return value: %TRUE if @iter moved and is not the end iterator + * + * Since: 2.4 + **/ +gboolean +gtk_text_iter_forward_visible_word_end (GtkTextIter *iter) +{ + return find_visible_by_log_attrs (iter, find_word_end_func, TRUE, FALSE); +} - if (!gtk_text_iter_backward_word_start (iter)) - return FALSE; - --count; +/** + * gtk_text_iter_backward_visible_word_start: + * @iter: a #GtkTextIter + * + * Moves backward to the previous visible word start. (If @iter is currently + * on a word start, moves backward to the next one after that.) Word breaks + * are determined by Pango and should be correct for nearly any + * language (if not, the correct fix would be to the Pango word break + * algorithms). + * + * Return value: %TRUE if @iter moved and is not the end iterator + * + * Since: 2.4 + **/ +gboolean +gtk_text_iter_backward_visible_word_start (GtkTextIter *iter) +{ + return find_visible_by_log_attrs (iter, find_word_start_func, FALSE, FALSE); +} - while (count > 0) - { - if (!gtk_text_iter_backward_word_start (iter)) - break; - --count; - } +/** + * gtk_text_iter_forward_visible_word_ends: + * @iter: a #GtkTextIter + * @count: number of times to move + * + * Calls gtk_text_iter_forward_visible_word_end() up to @count times. + * + * Return value: %TRUE if @iter moved and is not the end iterator + * + * Since: 2.4 + **/ +gboolean +gtk_text_iter_forward_visible_word_ends (GtkTextIter *iter, + gint count) +{ + return move_multiple_steps (iter, count, + gtk_text_iter_forward_visible_word_end, + gtk_text_iter_backward_visible_word_starts); +} - return !gtk_text_iter_is_end (iter); +/** + * gtk_text_iter_backward_visible_word_starts + * @iter: a #GtkTextIter + * @count: number of times to move + * + * Calls gtk_text_iter_backward_visible_word_start() up to @count times. + * + * Return value: %TRUE if @iter moved and is not the end iterator + * + * Since: 2.4 + **/ +gboolean +gtk_text_iter_backward_visible_word_starts (GtkTextIter *iter, + gint count) +{ + return move_multiple_steps (iter, count, + gtk_text_iter_backward_visible_word_start, + gtk_text_iter_forward_visible_word_ends); } /** @@ -3263,26 +3366,9 @@ gboolean gtk_text_iter_forward_sentence_ends (GtkTextIter *iter, gint count) { - g_return_val_if_fail (iter != NULL, FALSE); - - if (count == 0) - return FALSE; - - if (count < 0) - return gtk_text_iter_backward_sentence_starts (iter, -count); - - if (!gtk_text_iter_forward_sentence_end (iter)) - return FALSE; - --count; - - while (count > 0) - { - if (!gtk_text_iter_forward_sentence_end (iter)) - break; - --count; - } - - return !gtk_text_iter_is_end (iter); + return move_multiple_steps (iter, count, + gtk_text_iter_forward_sentence_end, + gtk_text_iter_backward_sentence_starts); } /** @@ -3300,26 +3386,9 @@ gboolean gtk_text_iter_backward_sentence_starts (GtkTextIter *iter, gint count) { - g_return_val_if_fail (iter != NULL, FALSE); - - if (count == 0) - return FALSE; - - if (count < 0) - return gtk_text_iter_forward_sentence_ends (iter, -count); - - if (!gtk_text_iter_backward_sentence_start (iter)) - return FALSE; - --count; - - while (count > 0) - { - if (!gtk_text_iter_backward_sentence_start (iter)) - break; - --count; - } - - return !gtk_text_iter_is_end (iter); + return move_multiple_steps (iter, count, + gtk_text_iter_backward_sentence_start, + gtk_text_iter_forward_sentence_ends); } static gboolean @@ -3422,28 +3491,9 @@ gboolean gtk_text_iter_forward_cursor_positions (GtkTextIter *iter, gint count) { - g_return_val_if_fail (iter != NULL, FALSE); - - FIX_OVERFLOWS (count); - - if (count == 0) - return FALSE; - - if (count < 0) - return gtk_text_iter_backward_cursor_positions (iter, -count); - - if (!gtk_text_iter_forward_cursor_position (iter)) - return FALSE; - --count; - - while (count > 0) - { - if (!gtk_text_iter_forward_cursor_position (iter)) - break; - --count; - } - - return !gtk_text_iter_is_end (iter); + return move_multiple_steps (iter, count, + gtk_text_iter_forward_cursor_position, + gtk_text_iter_backward_cursor_positions); } /** @@ -3460,28 +3510,85 @@ gboolean gtk_text_iter_backward_cursor_positions (GtkTextIter *iter, gint count) { - g_return_val_if_fail (iter != NULL, FALSE); + return move_multiple_steps (iter, count, + gtk_text_iter_backward_cursor_position, + gtk_text_iter_forward_cursor_positions); +} - FIX_OVERFLOWS (count); - - if (count == 0) - return FALSE; +/** + * gtk_text_iter_forward_visible_cursor_position: + * @iter: a #GtkTextIter + * + * Moves @iter forward to the next visible cursor position. See + * gtk_text_iter_forward_cursor_position() for details. + * + * Return value: %TRUE if we moved and the new position is dereferenceable + * + * Since: 2.4 + **/ +gboolean +gtk_text_iter_forward_visible_cursor_position (GtkTextIter *iter) +{ + return find_visible_by_log_attrs (iter, find_forward_cursor_pos_func, TRUE, FALSE); +} - if (count < 0) - return gtk_text_iter_forward_cursor_positions (iter, -count); - - if (!gtk_text_iter_backward_cursor_position (iter)) - return FALSE; - --count; +/** + * gtk_text_iter_backward_visible_cursor_position: + * @iter: a #GtkTextIter + * + * Moves @iter forward to the previous visible cursor position. See + * gtk_text_iter_backward_cursor_position() for details. + * + * Return value: %TRUE if we moved and the new position is dereferenceable + * + * Since: 2.4 + **/ +gboolean +gtk_text_iter_backward_visible_cursor_position (GtkTextIter *iter) +{ + return find_visible_by_log_attrs (iter, find_backward_cursor_pos_func, FALSE, FALSE); +} - while (count > 0) - { - if (!gtk_text_iter_backward_cursor_position (iter)) - break; - --count; - } +/** + * gtk_text_iter_forward_visible_cursor_positions: + * @iter: a #GtkTextIter + * @count: number of positions to move + * + * Moves up to @count visible cursor positions. See + * gtk_text_iter_forward_cursor_position() for details. + * + * Return value: %TRUE if we moved and the new position is dereferenceable + * + * Since: 2.4 + **/ +gboolean +gtk_text_iter_forward_visible_cursor_positions (GtkTextIter *iter, + gint count) +{ + return move_multiple_steps (iter, count, + gtk_text_iter_forward_visible_cursor_position, + gtk_text_iter_backward_visible_cursor_positions); +} - return !gtk_text_iter_is_end (iter); +/** + * gtk_text_iter_backward_visible_cursor_positions: + * @iter: a #GtkTextIter + * @count: number of positions to move + * + * Moves up to @count visible cursor positions. See + * gtk_text_iter_forward_cursor_position() for details. + * + * Return value: %TRUE if we moved and the new position is dereferenceable + * + * Since: 2.4 + **/ +gboolean +gtk_text_iter_backward_visible_cursor_positions (GtkTextIter *iter, + gint count) +{ + return move_multiple_steps (iter, count, + gtk_text_iter_backward_visible_cursor_position, + gtk_text_iter_forward_visible_cursor_positions); } /** @@ -3646,6 +3753,7 @@ gtk_text_iter_set_visible_line_index (GtkTextIter *iter, gint byte_on_line) { gint bytes_seen = 0; + gint skipped = 0; GtkTextIter pos; g_return_if_fail (iter != NULL); @@ -3657,6 +3765,7 @@ gtk_text_iter_set_visible_line_index (GtkTextIter *iter, { if (!_gtk_text_btree_char_is_invisible (&pos)) bytes_seen += bytes_in_char (&pos); + else skipped++; if (!gtk_text_iter_forward_char (&pos)) break; @@ -4618,43 +4727,6 @@ lines_window_free (LinesWindow *win) g_strfreev (win->lines); } -static gchar* -my_strrstr (const gchar *haystack, - const gchar *needle) -{ - /* FIXME GLib should have a nice implementation in it, this - * is slow-ass crap. - */ - - gint haystack_len = strlen (haystack); - gint needle_len = strlen (needle); - const gchar *needle_end = needle + needle_len; - const gchar *haystack_rend = haystack - 1; - const gchar *needle_rend = needle - 1; - const gchar *p; - - p = haystack + haystack_len; - while (p != haystack) - { - const gchar *n = needle_end - 1; - const gchar *s = p - 1; - while (s != haystack_rend && - n != needle_rend && - *s == *n) - { - --n; - --s; - } - - if (n == needle_rend) - return (gchar*)++s; - - --p; - } - - return NULL; -} - /** * gtk_text_iter_backward_search: * @iter: a #GtkTextIter where the search begins @@ -4750,7 +4822,7 @@ gtk_text_iter_backward_search (const GtkTextIter *iter, * end in '\n', so this will only match at the * end of the first line, which is correct. */ - first_line_match = my_strrstr (*win.lines, *lines); + first_line_match = g_strrstr (*win.lines, *lines); if (first_line_match && vectors_equal_ignoring_trailing (lines + 1, win.lines + 1)) diff --git a/gtk/gtktextiter.h b/gtk/gtktextiter.h index 0c8c56cc9..0b6f24517 100644 --- a/gtk/gtktextiter.h +++ b/gtk/gtktextiter.h @@ -191,6 +191,13 @@ gboolean gtk_text_iter_forward_word_ends (GtkTextIter *iter, gboolean gtk_text_iter_backward_word_starts (GtkTextIter *iter, gint count); +gboolean gtk_text_iter_forward_visible_word_end (GtkTextIter *iter); +gboolean gtk_text_iter_backward_visible_word_start (GtkTextIter *iter); +gboolean gtk_text_iter_forward_visible_word_ends (GtkTextIter *iter, + gint count); +gboolean gtk_text_iter_backward_visible_word_starts (GtkTextIter *iter, + gint count); + gboolean gtk_text_iter_forward_sentence_end (GtkTextIter *iter); gboolean gtk_text_iter_backward_sentence_start (GtkTextIter *iter); gboolean gtk_text_iter_forward_sentence_ends (GtkTextIter *iter, @@ -209,6 +216,13 @@ gboolean gtk_text_iter_forward_cursor_positions (GtkTextIter *iter, gboolean gtk_text_iter_backward_cursor_positions (GtkTextIter *iter, gint count); +gboolean gtk_text_iter_forward_visible_cursor_position (GtkTextIter *iter); +gboolean gtk_text_iter_backward_visible_cursor_position (GtkTextIter *iter); +gboolean gtk_text_iter_forward_visible_cursor_positions (GtkTextIter *iter, + gint count); +gboolean gtk_text_iter_backward_visible_cursor_positions (GtkTextIter *iter, + gint count); + void gtk_text_iter_set_offset (GtkTextIter *iter, gint char_offset); diff --git a/gtk/gtktextview.c b/gtk/gtktextview.c index e7b3c11fc..352309ee7 100644 --- a/gtk/gtktextview.c +++ b/gtk/gtktextview.c @@ -4524,7 +4524,7 @@ gtk_text_view_move_cursor_internal (GtkTextView *text_view, switch (step) { case GTK_MOVEMENT_LOGICAL_POSITIONS: - gtk_text_iter_forward_cursor_positions (&newplace, count); + gtk_text_iter_forward_visible_cursor_positions (&newplace, count); break; case GTK_MOVEMENT_VISUAL_POSITIONS: @@ -4534,9 +4534,9 @@ gtk_text_view_move_cursor_internal (GtkTextView *text_view, case GTK_MOVEMENT_WORDS: if (count < 0) - gtk_text_iter_backward_word_starts (&newplace, -count); + gtk_text_iter_backward_visible_word_starts (&newplace, -count); else if (count > 0) - gtk_text_iter_forward_word_ends (&newplace, count); + gtk_text_iter_forward_visible_word_ends (&newplace, count); break; case GTK_MOVEMENT_DISPLAY_LINES: @@ -5162,10 +5162,10 @@ extend_selection (GtkTextView *text_view, if (gtk_text_iter_inside_word (start)) { if (!gtk_text_iter_starts_word (start)) - gtk_text_iter_backward_word_start (start); + gtk_text_iter_backward_visible_word_start (start); if (!gtk_text_iter_ends_word (end)) - gtk_text_iter_forward_word_end (end); + gtk_text_iter_forward_visible_word_end (end); } else extend = FALSE;