textiter: fix bug in gtk_text_iter_backward_line()
authorNelson Benítez León <nbenitezl+gnome@gmail.com>
Fri, 10 Feb 2017 18:29:41 +0000 (23:29 +0500)
committerDaniel Boles <dboles@src.gnome.org>
Sat, 18 Feb 2017 20:00:32 +0000 (20:00 +0000)
gtk_text_iter_backward_line() checks the value of
real->line_char_offset without previously calling
ensure_char_offsets (real) to make sure the former
is up-to-date.

As a consequence of this, when gtk_text_iter_backward_line()
is called after a gtk_text_buffer_insert_range() in the
first line of buffer, the iter is not moved to the start of
the line, and the return value is wrong.

Fixed by adding the ensure_char_offsets() call.

A test case for this bug is added to the textiter gtk testsuite.

gtk/gtktextiter.c
testsuite/gtk/textiter.c

index 3e2e5f530092b75ae89f082f6d7b8ca193a772a3..cecee7286230c0faf42a0b22621d2b8228231a55 100644 (file)
@@ -2604,6 +2604,8 @@ gtk_text_iter_backward_line (GtkTextIter *iter)
   if (real == NULL)
     return FALSE;
 
+  ensure_char_offsets (real);
+
   check_invariants (iter);
 
   new_line = _gtk_text_line_previous (real->line);
index f022e92381fd68b70d13d7617d795cdc7a7ad37a..c68220c0f1d465c5a017de8c78352d486bd39151 100644 (file)
@@ -743,6 +743,42 @@ test_sentence_boundaries (void)
   check_backward_sentence_start (" Hi.", 0, 0, FALSE);
 }
 
+static void
+test_backward_line (void)
+{
+  GtkTextBuffer *buffer;
+  GtkTextIter iter, start, end;
+  gboolean ret;
+  gint offset;
+
+  buffer = gtk_text_buffer_new (NULL);
+  gtk_text_buffer_get_start_iter (buffer, &iter);
+  gtk_text_buffer_insert (buffer, &iter, "Hi line 1\nHi line 2", -1);
+
+  /* Go to middle of first line */
+  gtk_text_iter_backward_line (&iter);
+  gtk_text_iter_set_line_offset (&iter, 4);
+
+  /* Now insert some chars with gtk_text_buffer_insert_range() */
+  gtk_text_buffer_get_end_iter (buffer, &end);
+  start = end;
+  gtk_text_iter_backward_cursor_positions (&start, 5);
+  gtk_text_buffer_insert_range (buffer, &iter, &start, &end);
+
+  /* Check we are still at the first line */
+  g_assert_cmpint (gtk_text_iter_get_line (&iter), ==, 0);
+
+  /* Now a call to gtk_text_iter_backward_line() should return TRUE
+     and move &iter to start of the line, or return FALSE if &iter
+     was already at start of the line, so in both cases &iter should
+     be at the start of the line, so check that */
+  gtk_text_iter_backward_line (&iter);
+  offset = gtk_text_iter_get_line_offset (&iter);
+  g_assert_cmpint (offset, ==, 0);
+
+  g_object_unref (buffer);
+}
+
 int
 main (int argc, char** argv)
 {
@@ -759,6 +795,7 @@ main (int argc, char** argv)
   g_test_add_func ("/TextIter/Cursor Positions", test_cursor_positions);
   g_test_add_func ("/TextIter/Visible Cursor Positions", test_visible_cursor_positions);
   g_test_add_func ("/TextIter/Sentence Boundaries", test_sentence_boundaries);
+  g_test_add_func ("/TextIter/Backward line", test_backward_line);
 
   return g_test_run();
 }