diff --git a/ChangeLog b/ChangeLog index 580a541a23d035fb1cd97f9ab4a9969dc4d7947c..caa2286b0371cdaae774550c4aaeb0a0566d196f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2005-06-13 Matthias Clasen + + Make invisible text work a bit better (#66194, patch by + Jeroen Zwartepoorte) + + * gtk/gtk.symbols: + * gtk/gtktextiter.[hc]: Add function to move by + visible lines. + + * gtk/gtktextview.c (gtk_text_view_move_cursor_internal): + Skip invisible text when moving by paragraphs. + + * gtk/gtktextlayout.c (gtk_text_layout_move_iter_visually): + Skip invisible lines here too. + 2005-06-12 Matthias Clasen * gtk/gtkselection.c (gtk_target_list_add_image_targets): diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 580a541a23d035fb1cd97f9ab4a9969dc4d7947c..caa2286b0371cdaae774550c4aaeb0a0566d196f 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,18 @@ +2005-06-13 Matthias Clasen + + Make invisible text work a bit better (#66194, patch by + Jeroen Zwartepoorte) + + * gtk/gtk.symbols: + * gtk/gtktextiter.[hc]: Add function to move by + visible lines. + + * gtk/gtktextview.c (gtk_text_view_move_cursor_internal): + Skip invisible text when moving by paragraphs. + + * gtk/gtktextlayout.c (gtk_text_layout_move_iter_visually): + Skip invisible lines here too. + 2005-06-12 Matthias Clasen * gtk/gtkselection.c (gtk_target_list_add_image_targets): diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 580a541a23d035fb1cd97f9ab4a9969dc4d7947c..caa2286b0371cdaae774550c4aaeb0a0566d196f 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,18 @@ +2005-06-13 Matthias Clasen + + Make invisible text work a bit better (#66194, patch by + Jeroen Zwartepoorte) + + * gtk/gtk.symbols: + * gtk/gtktextiter.[hc]: Add function to move by + visible lines. + + * gtk/gtktextview.c (gtk_text_view_move_cursor_internal): + Skip invisible text when moving by paragraphs. + + * gtk/gtktextlayout.c (gtk_text_layout_move_iter_visually): + Skip invisible lines here too. + 2005-06-12 Matthias Clasen * gtk/gtkselection.c (gtk_target_list_add_image_targets): diff --git a/gtk/gtk.symbols b/gtk/gtk.symbols index 3399ab4a2976a4eebe478bf1b13d67d26824ac6e..3a468e28e27d41365231fde107eb02d8683be198 100644 --- a/gtk/gtk.symbols +++ b/gtk/gtk.symbols @@ -2890,6 +2890,8 @@ gtk_text_iter_backward_sentence_starts gtk_text_iter_backward_to_tag_toggle gtk_text_iter_backward_visible_cursor_position gtk_text_iter_backward_visible_cursor_positions +gtk_text_iter_backward_visible_line +gtk_text_iter_backward_visible_lines gtk_text_iter_backward_visible_word_start gtk_text_iter_backward_visible_word_starts gtk_text_iter_backward_word_start @@ -2919,6 +2921,8 @@ gtk_text_iter_forward_to_line_end gtk_text_iter_forward_to_tag_toggle gtk_text_iter_forward_visible_cursor_position gtk_text_iter_forward_visible_cursor_positions +gtk_text_iter_forward_visible_line +gtk_text_iter_forward_visible_lines gtk_text_iter_forward_visible_word_end gtk_text_iter_forward_visible_word_ends gtk_text_iter_forward_word_end diff --git a/gtk/gtktextiter.c b/gtk/gtktextiter.c index d0198b31ae746fee5b5fcc9a200ea7574b6c29ff..ffebb29688b548aef2084c3fab216b76656a1d99 100644 --- a/gtk/gtktextiter.c +++ b/gtk/gtktextiter.c @@ -2719,6 +2719,162 @@ gtk_text_iter_backward_lines (GtkTextIter *iter, gint count) } } +/** + * gtk_text_iter_forward_visible_line: + * @iter: an iterator + * + * Moves @iter to the start of the next visible line. Returns %TRUE if there + * was a next line to move to, and %FALSE if @iter was simply moved to + * the end of the buffer and is now not dereferenceable, or if @iter was + * already at the end of the buffer. + * + * Return value: whether @iter can be dereferenced + * + * Since: 2.8 + **/ +gboolean +gtk_text_iter_forward_visible_line (GtkTextIter *iter) +{ + while (gtk_text_iter_forward_line (iter)) + { + if (!_gtk_text_btree_char_is_invisible (iter)) + return TRUE; + else + { + do + { + if (!gtk_text_iter_forward_char (iter)) + return FALSE; + + if (!_gtk_text_btree_char_is_invisible (iter)) + return TRUE; + } + while (!gtk_text_iter_ends_line (iter)); + } + } + + return FALSE; +} + +/** + * gtk_text_iter_backward_visible_line: + * @iter: an iterator + * + * Moves @iter to the start of the previous visible line. Returns %TRUE if + * @iter could be moved; i.e. if @iter was at character offset 0, this + * function returns %FALSE. Therefore if @iter was already on line 0, + * but not at the start of the line, @iter is snapped to the start of + * the line and the function returns %TRUE. (Note that this implies that + * in a loop calling this function, the line number may not change on + * every iteration, if your first iteration is on line 0.) + * + * Return value: whether @iter moved + * + * Since: 2.8 + **/ +gboolean +gtk_text_iter_backward_visible_line (GtkTextIter *iter) +{ + while (gtk_text_iter_backward_line (iter)) + { + if (!_gtk_text_btree_char_is_invisible (iter)) + return TRUE; + else + { + do + { + if (!gtk_text_iter_backward_char (iter)) + return FALSE; + + if (!_gtk_text_btree_char_is_invisible (iter)) + return TRUE; + } + while (!gtk_text_iter_starts_line (iter)); + } + } + + return FALSE; +} + +/** + * gtk_text_iter_forward_visible_lines: + * @iter: a #GtkTextIter + * @count: number of lines to move forward + * + * Moves @count visible lines forward, if possible (if @count would move + * past the start or end of the buffer, moves to the start or end of + * the buffer). The return value indicates whether the iterator moved + * onto a dereferenceable position; if the iterator didn't move, or + * moved onto the end iterator, then %FALSE is returned. If @count is 0, + * the function does nothing and returns %FALSE. If @count is negative, + * moves backward by 0 - @count lines. + * + * Return value: whether @iter moved and is dereferenceable + * + * Since: 2.8 + **/ +gboolean +gtk_text_iter_forward_visible_lines (GtkTextIter *iter, + gint count) +{ + FIX_OVERFLOWS (count); + + if (count < 0) + return gtk_text_iter_backward_visible_lines (iter, 0 - count); + else if (count == 0) + return FALSE; + else if (count == 1) + { + check_invariants (iter); + return gtk_text_iter_forward_visible_line (iter); + } + else + { + while (gtk_text_iter_forward_visible_line (iter) && count > 0) + count--; + return count == 0; + } +} + +/** + * gtk_text_iter_backward_visible_lines: + * @iter: a #GtkTextIter + * @count: number of lines to move backward + * + * Moves @count visible lines backward, if possible (if @count would move + * past the start or end of the buffer, moves to the start or end of + * the buffer). The return value indicates whether the iterator moved + * onto a dereferenceable position; if the iterator didn't move, or + * moved onto the end iterator, then %FALSE is returned. If @count is 0, + * the function does nothing and returns %FALSE. If @count is negative, + * moves forward by 0 - @count lines. + * + * Return value: whether @iter moved and is dereferenceable + * + * Since: 2.8 + **/ +gboolean +gtk_text_iter_backward_visible_lines (GtkTextIter *iter, + gint count) +{ + FIX_OVERFLOWS (count); + + if (count < 0) + return gtk_text_iter_forward_visible_lines (iter, 0 - count); + else if (count == 0) + return FALSE; + else if (count == 1) + { + return gtk_text_iter_backward_visible_line (iter); + } + else + { + while (gtk_text_iter_backward_visible_line (iter) && count > 0) + count--; + return count == 0; + } +} + typedef gboolean (* FindLogAttrFunc) (const PangoLogAttr *attrs, gint offset, gint min_offset, diff --git a/gtk/gtktextiter.h b/gtk/gtktextiter.h index 6816cc222addc1d3efe7e816e1f11b7a8849a41f..f788397f558a2a36fcde137e138fc5552ecd1ed2 100644 --- a/gtk/gtktextiter.h +++ b/gtk/gtktextiter.h @@ -188,6 +188,13 @@ gboolean gtk_text_iter_forward_word_ends (GtkTextIter *iter, gint count); gboolean gtk_text_iter_backward_word_starts (GtkTextIter *iter, gint count); + +gboolean gtk_text_iter_forward_visible_line (GtkTextIter *iter); +gboolean gtk_text_iter_backward_visible_line (GtkTextIter *iter); +gboolean gtk_text_iter_forward_visible_lines (GtkTextIter *iter, + gint count); +gboolean gtk_text_iter_backward_visible_lines (GtkTextIter *iter, + gint count); gboolean gtk_text_iter_forward_visible_word_end (GtkTextIter *iter); gboolean gtk_text_iter_backward_visible_word_start (GtkTextIter *iter); diff --git a/gtk/gtktextlayout.c b/gtk/gtktextlayout.c index be77af2971b528d92695b010321891ea809a95d9..a44bf785bedb6e18bfa5b126f742f7263e288b38 100644 --- a/gtk/gtktextlayout.c +++ b/gtk/gtktextlayout.c @@ -2390,8 +2390,8 @@ gtk_text_layout_get_cursor_locations (GtkTextLayout *layout, index += layout->preedit_cursor - layout->preedit_len; pango_layout_get_cursor_pos (display->layout, index, - strong_pos ? &pango_strong_pos : NULL, - weak_pos ? &pango_weak_pos : NULL); + strong_pos ? &pango_strong_pos : NULL, + weak_pos ? &pango_weak_pos : NULL); if (strong_pos) { @@ -3117,6 +3117,7 @@ gtk_text_layout_move_iter_visually (GtkTextLayout *layout, { GtkTextLineDisplay *display = NULL; GtkTextIter orig; + GtkTextIter lineiter; g_return_val_if_fail (layout != NULL, FALSE); g_return_val_if_fail (iter != NULL, FALSE); @@ -3174,10 +3175,17 @@ gtk_text_layout_move_iter_visually (GtkTextLayout *layout, if (new_index < 0 || (new_index == 0 && extra_back)) { - line = _gtk_text_line_previous (line); + do + { + line = _gtk_text_line_previous (line); - if (!line) - goto done; + if (!line) + goto done; + + _gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer), + &lineiter, line, 0); + } + while (totally_invisible_line (layout, line, &lineiter)); gtk_text_layout_free_line_display (layout, display); display = gtk_text_layout_get_line_display (layout, line, FALSE); @@ -3185,10 +3193,17 @@ gtk_text_layout_move_iter_visually (GtkTextLayout *layout, } else if (new_index > byte_count) { - line = _gtk_text_line_next_excluding_last (line); - if (!line) - goto done; + do + { + line = _gtk_text_line_next_excluding_last (line); + if (!line) + goto done; + _gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer), + &lineiter, line, 0); + } + while (totally_invisible_line (layout, line, &lineiter)); + gtk_text_layout_free_line_display (layout, display); display = gtk_text_layout_get_line_display (layout, line, FALSE); new_index = 0; diff --git a/gtk/gtktextview.c b/gtk/gtktextview.c index 3ea6f1ebe2ba377f60b7cc4d0a523255e1b59f26..9a7fe68334b8640bd7897f346b3367c125fbf02f 100644 --- a/gtk/gtktextview.c +++ b/gtk/gtktextview.c @@ -4759,7 +4759,7 @@ gtk_text_view_move_cursor_internal (GtkTextView *text_view, gtk_text_iter_forward_to_line_end (&newplace); --count; } - gtk_text_iter_forward_lines (&newplace, count); + gtk_text_iter_forward_visible_lines (&newplace, count); gtk_text_iter_forward_to_line_end (&newplace); } else if (count < 0) @@ -4769,7 +4769,7 @@ gtk_text_view_move_cursor_internal (GtkTextView *text_view, gtk_text_iter_set_line_offset (&newplace, 0); ++count; } - gtk_text_iter_forward_lines (&newplace, count); + gtk_text_iter_forward_visible_lines (&newplace, count); gtk_text_iter_set_line_offset (&newplace, 0); } break;