Commit 7a958797 authored by Havoc Pennington's avatar Havoc Pennington Committed by Havoc Pennington

Rearrange all the scroll-while-dragging-or-selecting code to be different,

2000-12-31  Havoc Pennington  <hp@pobox.com>

* gtk/gtktextview.c: Rearrange all the
scroll-while-dragging-or-selecting code to be different, not
necessarily better. ;-)
(gtk_text_view_scroll_to_mark): Change this
function to take within_margin as a fraction instead of a pixel
value, and to take alignment arguments (indicating where to align
the mark inside the visible area)

* gtk/testtextbuffer.c (fill_buffer): fix bad cast of GtkTextTag
to GtkObject

* gtk/gtktextiter.c (gtk_text_iter_set_line_offset): change
behavior so that offsets past the end of the line are not
allowed, and an offset equal to the line length moves the iterator
to the next line
(gtk_text_iter_set_line_index): make parallel change
(gtk_text_iter_get_bytes_in_line): add this function

* gtk/gtktextbtree.c (_gtk_text_line_byte_locate): change handling
of byte indexes off the end of the line; byte index at the end of
the line now returns FALSE and doesn't fill in the requested
values, byte index past the end of the line is an error.  Also,
don't allow -1 offset anymore, since its meaning is unclear.

This change exposes some bug in visual cursor motion, where we
end up with a huge invalid byte index; needs fixing. Symptom of
bug is a crash when you hit up arrow.

(_gtk_text_line_char_locate): match the change to byte_locate

* gtk/gtktextiter.c (find_by_log_attrs): Handle iteration backward
from start of line properly. fixes bug reported by Mikael
Hermansson where backspace would delete all text before the
cursor.
parent 72cdcb63
2000-12-31 Havoc Pennington <hp@pobox.com>
* gtk/gtktextview.c: Rearrange all the
scroll-while-dragging-or-selecting code to be different, not
necessarily better. ;-)
(gtk_text_view_scroll_to_mark): Change this
function to take within_margin as a fraction instead of a pixel
value, and to take alignment arguments (indicating where to align
the mark inside the visible area)
* gtk/testtextbuffer.c (fill_buffer): fix bad cast of GtkTextTag
to GtkObject
* gtk/gtktextiter.c (gtk_text_iter_set_line_offset): change
behavior so that offsets past the end of the line are not
allowed, and an offset equal to the line length moves the iterator
to the next line
(gtk_text_iter_set_line_index): make parallel change
(gtk_text_iter_get_bytes_in_line): add this function
* gtk/gtktextbtree.c (_gtk_text_line_byte_locate): change handling
of byte indexes off the end of the line; byte index at the end of
the line now returns FALSE and doesn't fill in the requested
values, byte index past the end of the line is an error. Also,
don't allow -1 offset anymore, since its meaning is unclear.
This change exposes some bug in visual cursor motion, where we
end up with a huge invalid byte index; needs fixing. Symptom of
bug is a crash when you hit up arrow.
(_gtk_text_line_char_locate): match the change to byte_locate
* gtk/gtktextiter.c (find_by_log_attrs): Handle iteration backward
from start of line properly. fixes bug reported by Mikael
Hermansson where backspace would delete all text before the
cursor.
2000-12-30 Tor Lillqvist <tml@iki.fi>
* gdk/win32/gdkwindow-win32.c
......
2000-12-31 Havoc Pennington <hp@pobox.com>
* gtk/gtktextview.c: Rearrange all the
scroll-while-dragging-or-selecting code to be different, not
necessarily better. ;-)
(gtk_text_view_scroll_to_mark): Change this
function to take within_margin as a fraction instead of a pixel
value, and to take alignment arguments (indicating where to align
the mark inside the visible area)
* gtk/testtextbuffer.c (fill_buffer): fix bad cast of GtkTextTag
to GtkObject
* gtk/gtktextiter.c (gtk_text_iter_set_line_offset): change
behavior so that offsets past the end of the line are not
allowed, and an offset equal to the line length moves the iterator
to the next line
(gtk_text_iter_set_line_index): make parallel change
(gtk_text_iter_get_bytes_in_line): add this function
* gtk/gtktextbtree.c (_gtk_text_line_byte_locate): change handling
of byte indexes off the end of the line; byte index at the end of
the line now returns FALSE and doesn't fill in the requested
values, byte index past the end of the line is an error. Also,
don't allow -1 offset anymore, since its meaning is unclear.
This change exposes some bug in visual cursor motion, where we
end up with a huge invalid byte index; needs fixing. Symptom of
bug is a crash when you hit up arrow.
(_gtk_text_line_char_locate): match the change to byte_locate
* gtk/gtktextiter.c (find_by_log_attrs): Handle iteration backward
from start of line properly. fixes bug reported by Mikael
Hermansson where backspace would delete all text before the
cursor.
2000-12-30 Tor Lillqvist <tml@iki.fi>
* gdk/win32/gdkwindow-win32.c
......
2000-12-31 Havoc Pennington <hp@pobox.com>
* gtk/gtktextview.c: Rearrange all the
scroll-while-dragging-or-selecting code to be different, not
necessarily better. ;-)
(gtk_text_view_scroll_to_mark): Change this
function to take within_margin as a fraction instead of a pixel
value, and to take alignment arguments (indicating where to align
the mark inside the visible area)
* gtk/testtextbuffer.c (fill_buffer): fix bad cast of GtkTextTag
to GtkObject
* gtk/gtktextiter.c (gtk_text_iter_set_line_offset): change
behavior so that offsets past the end of the line are not
allowed, and an offset equal to the line length moves the iterator
to the next line
(gtk_text_iter_set_line_index): make parallel change
(gtk_text_iter_get_bytes_in_line): add this function
* gtk/gtktextbtree.c (_gtk_text_line_byte_locate): change handling
of byte indexes off the end of the line; byte index at the end of
the line now returns FALSE and doesn't fill in the requested
values, byte index past the end of the line is an error. Also,
don't allow -1 offset anymore, since its meaning is unclear.
This change exposes some bug in visual cursor motion, where we
end up with a huge invalid byte index; needs fixing. Symptom of
bug is a crash when you hit up arrow.
(_gtk_text_line_char_locate): match the change to byte_locate
* gtk/gtktextiter.c (find_by_log_attrs): Handle iteration backward
from start of line properly. fixes bug reported by Mikael
Hermansson where backspace would delete all text before the
cursor.
2000-12-30 Tor Lillqvist <tml@iki.fi>
* gdk/win32/gdkwindow-win32.c
......
2000-12-31 Havoc Pennington <hp@pobox.com>
* gtk/gtktextview.c: Rearrange all the
scroll-while-dragging-or-selecting code to be different, not
necessarily better. ;-)
(gtk_text_view_scroll_to_mark): Change this
function to take within_margin as a fraction instead of a pixel
value, and to take alignment arguments (indicating where to align
the mark inside the visible area)
* gtk/testtextbuffer.c (fill_buffer): fix bad cast of GtkTextTag
to GtkObject
* gtk/gtktextiter.c (gtk_text_iter_set_line_offset): change
behavior so that offsets past the end of the line are not
allowed, and an offset equal to the line length moves the iterator
to the next line
(gtk_text_iter_set_line_index): make parallel change
(gtk_text_iter_get_bytes_in_line): add this function
* gtk/gtktextbtree.c (_gtk_text_line_byte_locate): change handling
of byte indexes off the end of the line; byte index at the end of
the line now returns FALSE and doesn't fill in the requested
values, byte index past the end of the line is an error. Also,
don't allow -1 offset anymore, since its meaning is unclear.
This change exposes some bug in visual cursor motion, where we
end up with a huge invalid byte index; needs fixing. Symptom of
bug is a crash when you hit up arrow.
(_gtk_text_line_char_locate): match the change to byte_locate
* gtk/gtktextiter.c (find_by_log_attrs): Handle iteration backward
from start of line properly. fixes bug reported by Mikael
Hermansson where backspace would delete all text before the
cursor.
2000-12-30 Tor Lillqvist <tml@iki.fi>
* gdk/win32/gdkwindow-win32.c
......
2000-12-31 Havoc Pennington <hp@pobox.com>
* gtk/gtktextview.c: Rearrange all the
scroll-while-dragging-or-selecting code to be different, not
necessarily better. ;-)
(gtk_text_view_scroll_to_mark): Change this
function to take within_margin as a fraction instead of a pixel
value, and to take alignment arguments (indicating where to align
the mark inside the visible area)
* gtk/testtextbuffer.c (fill_buffer): fix bad cast of GtkTextTag
to GtkObject
* gtk/gtktextiter.c (gtk_text_iter_set_line_offset): change
behavior so that offsets past the end of the line are not
allowed, and an offset equal to the line length moves the iterator
to the next line
(gtk_text_iter_set_line_index): make parallel change
(gtk_text_iter_get_bytes_in_line): add this function
* gtk/gtktextbtree.c (_gtk_text_line_byte_locate): change handling
of byte indexes off the end of the line; byte index at the end of
the line now returns FALSE and doesn't fill in the requested
values, byte index past the end of the line is an error. Also,
don't allow -1 offset anymore, since its meaning is unclear.
This change exposes some bug in visual cursor motion, where we
end up with a huge invalid byte index; needs fixing. Symptom of
bug is a crash when you hit up arrow.
(_gtk_text_line_char_locate): match the change to byte_locate
* gtk/gtktextiter.c (find_by_log_attrs): Handle iteration backward
from start of line properly. fixes bug reported by Mikael
Hermansson where backspace would delete all text before the
cursor.
2000-12-30 Tor Lillqvist <tml@iki.fi>
* gdk/win32/gdkwindow-win32.c
......
2000-12-31 Havoc Pennington <hp@pobox.com>
* gtk/gtktextview.c: Rearrange all the
scroll-while-dragging-or-selecting code to be different, not
necessarily better. ;-)
(gtk_text_view_scroll_to_mark): Change this
function to take within_margin as a fraction instead of a pixel
value, and to take alignment arguments (indicating where to align
the mark inside the visible area)
* gtk/testtextbuffer.c (fill_buffer): fix bad cast of GtkTextTag
to GtkObject
* gtk/gtktextiter.c (gtk_text_iter_set_line_offset): change
behavior so that offsets past the end of the line are not
allowed, and an offset equal to the line length moves the iterator
to the next line
(gtk_text_iter_set_line_index): make parallel change
(gtk_text_iter_get_bytes_in_line): add this function
* gtk/gtktextbtree.c (_gtk_text_line_byte_locate): change handling
of byte indexes off the end of the line; byte index at the end of
the line now returns FALSE and doesn't fill in the requested
values, byte index past the end of the line is an error. Also,
don't allow -1 offset anymore, since its meaning is unclear.
This change exposes some bug in visual cursor motion, where we
end up with a huge invalid byte index; needs fixing. Symptom of
bug is a crash when you hit up arrow.
(_gtk_text_line_char_locate): match the change to byte_locate
* gtk/gtktextiter.c (find_by_log_attrs): Handle iteration backward
from start of line properly. fixes bug reported by Mikael
Hermansson where backspace would delete all text before the
cursor.
2000-12-30 Tor Lillqvist <tml@iki.fi>
* gdk/win32/gdkwindow-win32.c
......
2000-12-31 Havoc Pennington <hp@pobox.com>
* gtk/gtktextview.c: Rearrange all the
scroll-while-dragging-or-selecting code to be different, not
necessarily better. ;-)
(gtk_text_view_scroll_to_mark): Change this
function to take within_margin as a fraction instead of a pixel
value, and to take alignment arguments (indicating where to align
the mark inside the visible area)
* gtk/testtextbuffer.c (fill_buffer): fix bad cast of GtkTextTag
to GtkObject
* gtk/gtktextiter.c (gtk_text_iter_set_line_offset): change
behavior so that offsets past the end of the line are not
allowed, and an offset equal to the line length moves the iterator
to the next line
(gtk_text_iter_set_line_index): make parallel change
(gtk_text_iter_get_bytes_in_line): add this function
* gtk/gtktextbtree.c (_gtk_text_line_byte_locate): change handling
of byte indexes off the end of the line; byte index at the end of
the line now returns FALSE and doesn't fill in the requested
values, byte index past the end of the line is an error. Also,
don't allow -1 offset anymore, since its meaning is unclear.
This change exposes some bug in visual cursor motion, where we
end up with a huge invalid byte index; needs fixing. Symptom of
bug is a crash when you hit up arrow.
(_gtk_text_line_char_locate): match the change to byte_locate
* gtk/gtktextiter.c (find_by_log_attrs): Handle iteration backward
from start of line properly. fixes bug reported by Mikael
Hermansson where backspace would delete all text before the
cursor.
2000-12-30 Tor Lillqvist <tml@iki.fi>
* gdk/win32/gdkwindow-win32.c
......
......@@ -1053,9 +1053,9 @@ _gtk_text_btree_insert (GtkTextIter *iter,
_gtk_text_btree_get_iter_at_line (tree,
&start,
start_line,
start_byte_index);
&start,
start_line,
start_byte_index);
end = start;
/* We could almost certainly be more efficient here
......@@ -3545,13 +3545,13 @@ _gtk_text_line_char_to_byte (GtkTextLine *line,
/* FIXME sync with char_locate (or figure out a clean
way to merge the two functions) */
void
gboolean
_gtk_text_line_byte_locate (GtkTextLine *line,
gint byte_offset,
GtkTextLineSegment **segment,
GtkTextLineSegment **any_segment,
gint *seg_byte_offset,
gint *line_byte_offset)
gint byte_offset,
GtkTextLineSegment **segment,
GtkTextLineSegment **any_segment,
gint *seg_byte_offset,
gint *line_byte_offset)
{
GtkTextLineSegment *seg;
GtkTextLineSegment *after_prev_indexable;
......@@ -3560,16 +3560,8 @@ _gtk_text_line_byte_locate (GtkTextLine *line,
gint offset;
gint bytes_in_line;
g_return_if_fail (line != NULL);
if (byte_offset < 0)
{
/* -1 means end of line; we here assume no line is
longer than 1 bazillion bytes, of course we assumed
that anyway since we'd wrap around... */
byte_offset = G_MAXINT;
}
g_return_val_if_fail (line != NULL, FALSE);
g_return_val_if_fail (byte_offset >= 0, FALSE);
*segment = NULL;
*any_segment = NULL;
......@@ -3602,11 +3594,10 @@ _gtk_text_line_byte_locate (GtkTextLine *line,
if (seg == NULL)
{
/* We went off the end of the line */
*segment = last_indexable;
*any_segment = after_prev_indexable;
/* subtracting 1 is OK, we know it's a newline at the end. */
offset = (*segment)->byte_count - 1;
bytes_in_line -= (*segment)->byte_count;
if (offset != 0)
g_warning ("%s: byte index off the end of the line", G_STRLOC);
return FALSE;
}
else
{
......@@ -3628,17 +3619,19 @@ _gtk_text_line_byte_locate (GtkTextLine *line,
g_assert (*seg_byte_offset < (*segment)->byte_count);
*line_byte_offset = bytes_in_line + *seg_byte_offset;
return TRUE;
}
/* FIXME sync with byte_locate (or figure out a clean
way to merge the two functions) */
void
gboolean
_gtk_text_line_char_locate (GtkTextLine *line,
gint char_offset,
GtkTextLineSegment **segment,
GtkTextLineSegment **any_segment,
gint *seg_char_offset,
gint *line_char_offset)
gint char_offset,
GtkTextLineSegment **segment,
GtkTextLineSegment **any_segment,
gint *seg_char_offset,
gint *line_char_offset)
{
GtkTextLineSegment *seg;
GtkTextLineSegment *after_prev_indexable;
......@@ -3647,17 +3640,9 @@ _gtk_text_line_char_locate (GtkTextLine *line,
gint offset;
gint chars_in_line;
g_return_if_fail (line != NULL);
if (char_offset < 0)
{
/* -1 means end of line; we here assume no line is
longer than 1 bazillion chars, of course we assumed
that anyway since we'd wrap around... */
char_offset = G_MAXINT;
}
g_return_val_if_fail (line != NULL, FALSE);
g_return_val_if_fail (char_offset >= 0, FALSE);
*segment = NULL;
*any_segment = NULL;
chars_in_line = 0;
......@@ -3688,12 +3673,11 @@ _gtk_text_line_char_locate (GtkTextLine *line,
if (seg == NULL)
{
/* We went off the end of the line */
*segment = last_indexable;
*any_segment = after_prev_indexable;
/* subtracting 1 is OK, we know it's a newline at the end. */
offset = (*segment)->char_count - 1;
chars_in_line -= (*segment)->char_count;
/* end of the line */
if (offset != 0)
g_warning ("%s: char offset off the end of the line", G_STRLOC);
return FALSE;
}
else
{
......@@ -3715,6 +3699,8 @@ _gtk_text_line_char_locate (GtkTextLine *line,
g_assert (*seg_char_offset < (*segment)->char_count);
*line_char_offset = chars_in_line + *seg_char_offset;
return TRUE;
}
void
......
......@@ -225,13 +225,13 @@ GtkTextLineSegment *_gtk_text_line_byte_to_segment (GtkTextLine
GtkTextLineSegment *_gtk_text_line_char_to_segment (GtkTextLine *line,
gint char_offset,
gint *seg_offset);
void _gtk_text_line_byte_locate (GtkTextLine *line,
gboolean _gtk_text_line_byte_locate (GtkTextLine *line,
gint byte_offset,
GtkTextLineSegment **segment,
GtkTextLineSegment **any_segment,
gint *seg_byte_offset,
gint *line_byte_offset);
void _gtk_text_line_char_locate (GtkTextLine *line,
gboolean _gtk_text_line_char_locate (GtkTextLine *line,
gint char_offset,
GtkTextLineSegment **segment,
GtkTextLineSegment **any_segment,
......
......@@ -93,12 +93,11 @@ iter_set_from_byte_offset (GtkTextRealIter *iter,
iter_set_common (iter, line);
_gtk_text_line_byte_locate (iter->line,
byte_offset,
&iter->segment,
&iter->any_segment,
&iter->segment_byte_offset,
&iter->line_byte_offset);
byte_offset,
&iter->segment,
&iter->any_segment,
&iter->segment_byte_offset,
&iter->line_byte_offset);
}
static void
......@@ -109,11 +108,11 @@ iter_set_from_char_offset (GtkTextRealIter *iter,
iter_set_common (iter, line);
_gtk_text_line_char_locate (iter->line,
char_offset,
&iter->segment,
&iter->any_segment,
&iter->segment_char_offset,
&iter->line_char_offset);
char_offset,
&iter->segment,
&iter->any_segment,
&iter->segment_char_offset,
&iter->line_char_offset);
}
static void
......@@ -1289,8 +1288,8 @@ gtk_text_iter_get_language (const GtkTextIter *iter)
* gtk_text_iter_starts_line:
* @iter: an iterator
*
* Returns TRUE if @iter begins a newline-terminated line,
* i.e. gtk_text_iter_get_line_offset () would return 0.
* Returns TRUE if @iter begins a paragraph,
* i.e. if gtk_text_iter_get_line_offset () would return 0.
* However this function is potentially more efficient than
* gtk_text_iter_get_line_offset () because it doesn't have to compute
* the offset, it just has to see whether it's 0.
......@@ -1419,7 +1418,7 @@ gtk_text_iter_is_first (const GtkTextIter *iter)
* @iter: an iterator
*
* Returns the number of characters in the line containing @iter,
* including the terminating newline.
* including the paragraph delimiters.
*
* Return value: number of characters in the line
**/
......@@ -1463,6 +1462,54 @@ gtk_text_iter_get_chars_in_line (const GtkTextIter *iter)
return count;
}
/**
* gtk_text_iter_get_bytes_in_line:
* @iter: an iterator
*
* Returns the number of bytes in the line containing @iter,
* including the paragraph delimiters.
*
* Return value: number of bytes in the line
**/
gint
gtk_text_iter_get_bytes_in_line (const GtkTextIter *iter)
{
GtkTextRealIter *real;
gint count;
GtkTextLineSegment *seg;
g_return_val_if_fail (iter != NULL, FALSE);
real = gtk_text_iter_make_surreal (iter);
if (real == NULL)
return 0;
check_invariants (iter);
if (real->line_byte_offset >= 0)
{
/* We can start at the segments we've already found. */
count = real->line_byte_offset - real->segment_byte_offset;
seg = gtk_text_iter_get_indexable_segment (iter);
}
else
{
/* count whole line. */
seg = real->line->segments;
count = 0;
}
while (seg != NULL)
{
count += seg->byte_count;
seg = seg->next;
}
return count;
}
/**
* gtk_text_iter_get_attributes:
* @iter: an iterator
......@@ -2388,7 +2435,8 @@ typedef gboolean (* FindLogAttrFunc) (const PangoLogAttr *attrs,
gint offset,
gint min_offset,
gint len,
gint *found_offset);
gint *found_offset,
gboolean already_moved_initially);
typedef gboolean (* TestLogAttrFunc) (const PangoLogAttr *attrs,
gint offset,
......@@ -2400,9 +2448,11 @@ find_word_end_func (const PangoLogAttr *attrs,
gint offset,
gint min_offset,
gint len,
gint *found_offset)
gint *found_offset,
gboolean already_moved_initially)
{
++offset; /* We always go to the NEXT word end */
if (!already_moved_initially)
++offset;
/* Find end of next word */
while (offset < min_offset + len &&
......@@ -2428,9 +2478,11 @@ find_word_start_func (const PangoLogAttr *attrs,
gint offset,
gint min_offset,
gint len,
gint *found_offset)
gint *found_offset,
gboolean already_moved_initially)
{
--offset; /* We always go to the NEXT word start */
if (!already_moved_initially)
--offset;
/* Find start of prev word */
while (offset >= min_offset &&
......@@ -2469,7 +2521,6 @@ static gboolean
test_log_attrs (const GtkTextIter *iter,
TestLogAttrFunc func)
{
gchar *paragraph;
gint char_len;
const PangoLogAttr *attrs;
int offset;
......@@ -2493,25 +2544,26 @@ test_log_attrs (const GtkTextIter *iter,
static gboolean
find_line_log_attrs (const GtkTextIter *iter,
FindLogAttrFunc func,
gint *found_offset)
gint *found_offset,
gboolean already_moved_initially)
{
gchar *paragraph;
gint char_len;
const PangoLogAttr *attrs;
int offset;
gboolean result = FALSE;
g_return_val_if_fail (iter != NULL, FALSE);
attrs = _gtk_text_buffer_get_line_log_attrs (gtk_text_iter_get_buffer (iter),
iter, &char_len);
iter, &char_len);
offset = gtk_text_iter_get_line_offset (iter);
g_assert (char_len > 0);
if (offset < char_len)
result = (* func) (attrs, offset, 0, char_len, found_offset);
result = (* func) (attrs, offset, 0, char_len, found_offset,
already_moved_initially);
return result;
}
......@@ -2520,7 +2572,8 @@ find_line_log_attrs (const GtkTextIter *iter,
static gboolean
find_by_log_attrs (GtkTextIter *iter,
FindLogAttrFunc func,
gboolean forward)
gboolean forward,
gboolean already_moved_initially)
{
GtkTextIter orig;
gint offset = 0;
......@@ -2529,22 +2582,27 @@ find_by_log_attrs (GtkTextIter *iter,
g_return_val_if_fail (iter != NULL, FALSE);
orig = *iter;
found = find_line_log_attrs (iter, func, &offset);
found = find_line_log_attrs (iter, func, &offset, already_moved_initially);
if (!found)
{
if (forward)
{
if (gtk_text_iter_forward_line (iter))
return find_by_log_attrs (iter, func, forward);
return find_by_log_attrs (iter, func, forward,
TRUE);
else
return FALSE;
}
else
{
if (gtk_text_iter_backward_line (iter))
return find_by_log_attrs (iter, func, forward);
{
/* go to end of previous line */
gtk_text_iter_set_line_offset (iter, 0);
if (gtk_text_iter_backward_char (iter))
return find_by_log_attrs (iter, func, forward,