mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-23 20:30:15 +00:00
don't create dangling pointers to the appearance attributes from the line
2000-11-30 Havoc Pennington <hp@pobox.com> * gtk/gtktextdisplay.c (gtk_text_layout_draw): don't create dangling pointers to the appearance attributes from the line display * gdk/gdkdraw.c (gdk_drawable_get_image): allow negative width/height to mean "full width/height of drawable" * gtk/gtktextview.h, gtk/gtktextview.c: Implement double/triple click to select word/line * gtk/gtktextiter.c (test_log_attrs): include paragraph delimiters when getting log attrs. Get a slice, so that pixmaps and stuff are properly handled. * gtk/gtktextbuffer.c (paste): Fix pasting to work properly if you paste into the selection (replaces selection now, previously crashed or added to selection). Reveals longstanding btree bug - select multiple lines, middle-click on the selection, boom. This isn't related to my changes though. * gtk/gtkentry.c (gtk_entry_move_forward_word): Update to reflect PangoLogAttrs changes (gtk_entry_move_backward_word): ditto * gtk/gtktextlayout.h, gtk/gtktextlayout.c: Make the iter motion functions return bool whether the iter moved onto a dereferenceable position. * gtk/gtktextview.h, gtk/gtktextview.c: Add a bunch of public functions for motion in terms of display lines. * gtk/gtktextmark.c (gtk_text_mark_get_buffer): Add function to get the buffer a mark is inside
This commit is contained in:
parent
fb14d1299e
commit
35876710dc
38
ChangeLog
38
ChangeLog
@ -1,4 +1,40 @@
|
||||
2000-12-01 <alexl@redhat.com>
|
||||
2000-11-30 Havoc Pennington <hp@pobox.com>
|
||||
|
||||
* gtk/gtktextdisplay.c (gtk_text_layout_draw): don't create
|
||||
dangling pointers to the appearance attributes from the
|
||||
line display
|
||||
|
||||
* gdk/gdkdraw.c (gdk_drawable_get_image): allow negative
|
||||
width/height to mean "full width/height of drawable"
|
||||
|
||||
* gtk/gtktextview.h, gtk/gtktextview.c: Implement double/triple
|
||||
click to select word/line
|
||||
|
||||
* gtk/gtktextiter.c (test_log_attrs): include paragraph delimiters
|
||||
when getting log attrs. Get a slice, so that pixmaps and stuff
|
||||
are properly handled.
|
||||
|
||||
* gtk/gtktextbuffer.c (paste): Fix pasting to work properly if you
|
||||
paste into the selection (replaces selection now, previously
|
||||
crashed or added to selection). Reveals longstanding btree bug -
|
||||
select multiple lines, middle-click on the selection, boom. This
|
||||
isn't related to my changes though.
|
||||
|
||||
* gtk/gtkentry.c (gtk_entry_move_forward_word): Update to reflect
|
||||
PangoLogAttrs changes
|
||||
(gtk_entry_move_backward_word): ditto
|
||||
|
||||
* gtk/gtktextlayout.h, gtk/gtktextlayout.c: Make the iter motion
|
||||
functions return bool whether the iter moved onto a
|
||||
dereferenceable position.
|
||||
|
||||
* gtk/gtktextview.h, gtk/gtktextview.c: Add a bunch of public
|
||||
functions for motion in terms of display lines.
|
||||
|
||||
* gtk/gtktextmark.c (gtk_text_mark_get_buffer): Add function to
|
||||
get the buffer a mark is inside
|
||||
|
||||
2000-12-01 Alexander Larsson <alexl@redhat.com>
|
||||
|
||||
* gdk/linux-fb/Makefile.am:
|
||||
* modules/linux-fb/Makefile.am:
|
||||
|
@ -1,4 +1,40 @@
|
||||
2000-12-01 <alexl@redhat.com>
|
||||
2000-11-30 Havoc Pennington <hp@pobox.com>
|
||||
|
||||
* gtk/gtktextdisplay.c (gtk_text_layout_draw): don't create
|
||||
dangling pointers to the appearance attributes from the
|
||||
line display
|
||||
|
||||
* gdk/gdkdraw.c (gdk_drawable_get_image): allow negative
|
||||
width/height to mean "full width/height of drawable"
|
||||
|
||||
* gtk/gtktextview.h, gtk/gtktextview.c: Implement double/triple
|
||||
click to select word/line
|
||||
|
||||
* gtk/gtktextiter.c (test_log_attrs): include paragraph delimiters
|
||||
when getting log attrs. Get a slice, so that pixmaps and stuff
|
||||
are properly handled.
|
||||
|
||||
* gtk/gtktextbuffer.c (paste): Fix pasting to work properly if you
|
||||
paste into the selection (replaces selection now, previously
|
||||
crashed or added to selection). Reveals longstanding btree bug -
|
||||
select multiple lines, middle-click on the selection, boom. This
|
||||
isn't related to my changes though.
|
||||
|
||||
* gtk/gtkentry.c (gtk_entry_move_forward_word): Update to reflect
|
||||
PangoLogAttrs changes
|
||||
(gtk_entry_move_backward_word): ditto
|
||||
|
||||
* gtk/gtktextlayout.h, gtk/gtktextlayout.c: Make the iter motion
|
||||
functions return bool whether the iter moved onto a
|
||||
dereferenceable position.
|
||||
|
||||
* gtk/gtktextview.h, gtk/gtktextview.c: Add a bunch of public
|
||||
functions for motion in terms of display lines.
|
||||
|
||||
* gtk/gtktextmark.c (gtk_text_mark_get_buffer): Add function to
|
||||
get the buffer a mark is inside
|
||||
|
||||
2000-12-01 Alexander Larsson <alexl@redhat.com>
|
||||
|
||||
* gdk/linux-fb/Makefile.am:
|
||||
* modules/linux-fb/Makefile.am:
|
||||
|
@ -1,4 +1,40 @@
|
||||
2000-12-01 <alexl@redhat.com>
|
||||
2000-11-30 Havoc Pennington <hp@pobox.com>
|
||||
|
||||
* gtk/gtktextdisplay.c (gtk_text_layout_draw): don't create
|
||||
dangling pointers to the appearance attributes from the
|
||||
line display
|
||||
|
||||
* gdk/gdkdraw.c (gdk_drawable_get_image): allow negative
|
||||
width/height to mean "full width/height of drawable"
|
||||
|
||||
* gtk/gtktextview.h, gtk/gtktextview.c: Implement double/triple
|
||||
click to select word/line
|
||||
|
||||
* gtk/gtktextiter.c (test_log_attrs): include paragraph delimiters
|
||||
when getting log attrs. Get a slice, so that pixmaps and stuff
|
||||
are properly handled.
|
||||
|
||||
* gtk/gtktextbuffer.c (paste): Fix pasting to work properly if you
|
||||
paste into the selection (replaces selection now, previously
|
||||
crashed or added to selection). Reveals longstanding btree bug -
|
||||
select multiple lines, middle-click on the selection, boom. This
|
||||
isn't related to my changes though.
|
||||
|
||||
* gtk/gtkentry.c (gtk_entry_move_forward_word): Update to reflect
|
||||
PangoLogAttrs changes
|
||||
(gtk_entry_move_backward_word): ditto
|
||||
|
||||
* gtk/gtktextlayout.h, gtk/gtktextlayout.c: Make the iter motion
|
||||
functions return bool whether the iter moved onto a
|
||||
dereferenceable position.
|
||||
|
||||
* gtk/gtktextview.h, gtk/gtktextview.c: Add a bunch of public
|
||||
functions for motion in terms of display lines.
|
||||
|
||||
* gtk/gtktextmark.c (gtk_text_mark_get_buffer): Add function to
|
||||
get the buffer a mark is inside
|
||||
|
||||
2000-12-01 Alexander Larsson <alexl@redhat.com>
|
||||
|
||||
* gdk/linux-fb/Makefile.am:
|
||||
* modules/linux-fb/Makefile.am:
|
||||
|
@ -1,4 +1,40 @@
|
||||
2000-12-01 <alexl@redhat.com>
|
||||
2000-11-30 Havoc Pennington <hp@pobox.com>
|
||||
|
||||
* gtk/gtktextdisplay.c (gtk_text_layout_draw): don't create
|
||||
dangling pointers to the appearance attributes from the
|
||||
line display
|
||||
|
||||
* gdk/gdkdraw.c (gdk_drawable_get_image): allow negative
|
||||
width/height to mean "full width/height of drawable"
|
||||
|
||||
* gtk/gtktextview.h, gtk/gtktextview.c: Implement double/triple
|
||||
click to select word/line
|
||||
|
||||
* gtk/gtktextiter.c (test_log_attrs): include paragraph delimiters
|
||||
when getting log attrs. Get a slice, so that pixmaps and stuff
|
||||
are properly handled.
|
||||
|
||||
* gtk/gtktextbuffer.c (paste): Fix pasting to work properly if you
|
||||
paste into the selection (replaces selection now, previously
|
||||
crashed or added to selection). Reveals longstanding btree bug -
|
||||
select multiple lines, middle-click on the selection, boom. This
|
||||
isn't related to my changes though.
|
||||
|
||||
* gtk/gtkentry.c (gtk_entry_move_forward_word): Update to reflect
|
||||
PangoLogAttrs changes
|
||||
(gtk_entry_move_backward_word): ditto
|
||||
|
||||
* gtk/gtktextlayout.h, gtk/gtktextlayout.c: Make the iter motion
|
||||
functions return bool whether the iter moved onto a
|
||||
dereferenceable position.
|
||||
|
||||
* gtk/gtktextview.h, gtk/gtktextview.c: Add a bunch of public
|
||||
functions for motion in terms of display lines.
|
||||
|
||||
* gtk/gtktextmark.c (gtk_text_mark_get_buffer): Add function to
|
||||
get the buffer a mark is inside
|
||||
|
||||
2000-12-01 Alexander Larsson <alexl@redhat.com>
|
||||
|
||||
* gdk/linux-fb/Makefile.am:
|
||||
* modules/linux-fb/Makefile.am:
|
||||
|
@ -1,4 +1,40 @@
|
||||
2000-12-01 <alexl@redhat.com>
|
||||
2000-11-30 Havoc Pennington <hp@pobox.com>
|
||||
|
||||
* gtk/gtktextdisplay.c (gtk_text_layout_draw): don't create
|
||||
dangling pointers to the appearance attributes from the
|
||||
line display
|
||||
|
||||
* gdk/gdkdraw.c (gdk_drawable_get_image): allow negative
|
||||
width/height to mean "full width/height of drawable"
|
||||
|
||||
* gtk/gtktextview.h, gtk/gtktextview.c: Implement double/triple
|
||||
click to select word/line
|
||||
|
||||
* gtk/gtktextiter.c (test_log_attrs): include paragraph delimiters
|
||||
when getting log attrs. Get a slice, so that pixmaps and stuff
|
||||
are properly handled.
|
||||
|
||||
* gtk/gtktextbuffer.c (paste): Fix pasting to work properly if you
|
||||
paste into the selection (replaces selection now, previously
|
||||
crashed or added to selection). Reveals longstanding btree bug -
|
||||
select multiple lines, middle-click on the selection, boom. This
|
||||
isn't related to my changes though.
|
||||
|
||||
* gtk/gtkentry.c (gtk_entry_move_forward_word): Update to reflect
|
||||
PangoLogAttrs changes
|
||||
(gtk_entry_move_backward_word): ditto
|
||||
|
||||
* gtk/gtktextlayout.h, gtk/gtktextlayout.c: Make the iter motion
|
||||
functions return bool whether the iter moved onto a
|
||||
dereferenceable position.
|
||||
|
||||
* gtk/gtktextview.h, gtk/gtktextview.c: Add a bunch of public
|
||||
functions for motion in terms of display lines.
|
||||
|
||||
* gtk/gtktextmark.c (gtk_text_mark_get_buffer): Add function to
|
||||
get the buffer a mark is inside
|
||||
|
||||
2000-12-01 Alexander Larsson <alexl@redhat.com>
|
||||
|
||||
* gdk/linux-fb/Makefile.am:
|
||||
* modules/linux-fb/Makefile.am:
|
||||
|
@ -1,4 +1,40 @@
|
||||
2000-12-01 <alexl@redhat.com>
|
||||
2000-11-30 Havoc Pennington <hp@pobox.com>
|
||||
|
||||
* gtk/gtktextdisplay.c (gtk_text_layout_draw): don't create
|
||||
dangling pointers to the appearance attributes from the
|
||||
line display
|
||||
|
||||
* gdk/gdkdraw.c (gdk_drawable_get_image): allow negative
|
||||
width/height to mean "full width/height of drawable"
|
||||
|
||||
* gtk/gtktextview.h, gtk/gtktextview.c: Implement double/triple
|
||||
click to select word/line
|
||||
|
||||
* gtk/gtktextiter.c (test_log_attrs): include paragraph delimiters
|
||||
when getting log attrs. Get a slice, so that pixmaps and stuff
|
||||
are properly handled.
|
||||
|
||||
* gtk/gtktextbuffer.c (paste): Fix pasting to work properly if you
|
||||
paste into the selection (replaces selection now, previously
|
||||
crashed or added to selection). Reveals longstanding btree bug -
|
||||
select multiple lines, middle-click on the selection, boom. This
|
||||
isn't related to my changes though.
|
||||
|
||||
* gtk/gtkentry.c (gtk_entry_move_forward_word): Update to reflect
|
||||
PangoLogAttrs changes
|
||||
(gtk_entry_move_backward_word): ditto
|
||||
|
||||
* gtk/gtktextlayout.h, gtk/gtktextlayout.c: Make the iter motion
|
||||
functions return bool whether the iter moved onto a
|
||||
dereferenceable position.
|
||||
|
||||
* gtk/gtktextview.h, gtk/gtktextview.c: Add a bunch of public
|
||||
functions for motion in terms of display lines.
|
||||
|
||||
* gtk/gtktextmark.c (gtk_text_mark_get_buffer): Add function to
|
||||
get the buffer a mark is inside
|
||||
|
||||
2000-12-01 Alexander Larsson <alexl@redhat.com>
|
||||
|
||||
* gdk/linux-fb/Makefile.am:
|
||||
* modules/linux-fb/Makefile.am:
|
||||
|
@ -1,4 +1,40 @@
|
||||
2000-12-01 <alexl@redhat.com>
|
||||
2000-11-30 Havoc Pennington <hp@pobox.com>
|
||||
|
||||
* gtk/gtktextdisplay.c (gtk_text_layout_draw): don't create
|
||||
dangling pointers to the appearance attributes from the
|
||||
line display
|
||||
|
||||
* gdk/gdkdraw.c (gdk_drawable_get_image): allow negative
|
||||
width/height to mean "full width/height of drawable"
|
||||
|
||||
* gtk/gtktextview.h, gtk/gtktextview.c: Implement double/triple
|
||||
click to select word/line
|
||||
|
||||
* gtk/gtktextiter.c (test_log_attrs): include paragraph delimiters
|
||||
when getting log attrs. Get a slice, so that pixmaps and stuff
|
||||
are properly handled.
|
||||
|
||||
* gtk/gtktextbuffer.c (paste): Fix pasting to work properly if you
|
||||
paste into the selection (replaces selection now, previously
|
||||
crashed or added to selection). Reveals longstanding btree bug -
|
||||
select multiple lines, middle-click on the selection, boom. This
|
||||
isn't related to my changes though.
|
||||
|
||||
* gtk/gtkentry.c (gtk_entry_move_forward_word): Update to reflect
|
||||
PangoLogAttrs changes
|
||||
(gtk_entry_move_backward_word): ditto
|
||||
|
||||
* gtk/gtktextlayout.h, gtk/gtktextlayout.c: Make the iter motion
|
||||
functions return bool whether the iter moved onto a
|
||||
dereferenceable position.
|
||||
|
||||
* gtk/gtktextview.h, gtk/gtktextview.c: Add a bunch of public
|
||||
functions for motion in terms of display lines.
|
||||
|
||||
* gtk/gtktextmark.c (gtk_text_mark_get_buffer): Add function to
|
||||
get the buffer a mark is inside
|
||||
|
||||
2000-12-01 Alexander Larsson <alexl@redhat.com>
|
||||
|
||||
* gdk/linux-fb/Makefile.am:
|
||||
* modules/linux-fb/Makefile.am:
|
||||
|
@ -486,9 +486,12 @@ gdk_drawable_get_image (GdkDrawable *drawable,
|
||||
g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
|
||||
g_return_val_if_fail (x >= 0, NULL);
|
||||
g_return_val_if_fail (y >= 0, NULL);
|
||||
g_return_val_if_fail (width >= 0, NULL);
|
||||
g_return_val_if_fail (height >= 0, NULL);
|
||||
|
||||
if (width < 0 || height < 0)
|
||||
gdk_drawable_get_size (drawable,
|
||||
width < 0 ? &width : NULL,
|
||||
height < 0 ? &height : NULL);
|
||||
|
||||
composite =
|
||||
GDK_DRAWABLE_GET_CLASS (drawable)->get_composite_drawable (drawable,
|
||||
x, y,
|
||||
|
@ -2111,20 +2111,12 @@ gtk_entry_move_forward_word (GtkEntry *entry,
|
||||
gint n_attrs;
|
||||
|
||||
pango_layout_get_log_attrs (layout, &log_attrs, &n_attrs);
|
||||
|
||||
/* Advance over white space */
|
||||
while (new_pos < n_attrs && log_attrs[new_pos].is_white)
|
||||
new_pos++;
|
||||
|
||||
/* Find the next word beginning */
|
||||
/* Find the next word end */
|
||||
new_pos++;
|
||||
while (new_pos < n_attrs && !log_attrs[new_pos].is_word_stop)
|
||||
while (new_pos < n_attrs && !log_attrs[new_pos].is_word_end)
|
||||
new_pos++;
|
||||
|
||||
/* Back up over white space */
|
||||
while (new_pos > 0 && log_attrs[new_pos - 1].is_white)
|
||||
new_pos--;
|
||||
|
||||
g_free (log_attrs);
|
||||
g_object_unref (G_OBJECT (layout));
|
||||
}
|
||||
@ -2155,7 +2147,7 @@ gtk_entry_move_backward_word (GtkEntry *entry,
|
||||
new_pos = start - 1;
|
||||
|
||||
/* Find the previous word beginning */
|
||||
while (new_pos > 0 && !log_attrs[new_pos].is_word_stop)
|
||||
while (new_pos > 0 && !log_attrs[new_pos].is_word_start)
|
||||
new_pos--;
|
||||
|
||||
g_free (log_attrs);
|
||||
|
@ -2172,24 +2172,40 @@ pre_paste_prep (ClipboardRequest *request_data,
|
||||
GtkTextIter *insert_point)
|
||||
{
|
||||
GtkTextBuffer *buffer = request_data->buffer;
|
||||
|
||||
get_paste_point (buffer, insert_point, TRUE);
|
||||
|
||||
/* If we're going to replace the selection, we insert before it to
|
||||
* avoid messing it up, then we delete the selection after inserting.
|
||||
*/
|
||||
if (request_data->replace_selection)
|
||||
{
|
||||
GtkTextIter start, end;
|
||||
|
||||
if (gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
|
||||
*insert_point = start;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
post_paste_cleanup (ClipboardRequest *request_data)
|
||||
{
|
||||
if (request_data->replace_selection)
|
||||
{
|
||||
GtkTextIter start, end;
|
||||
|
||||
if (gtk_text_buffer_get_selection_bounds (request_data->buffer,
|
||||
&start, &end))
|
||||
{
|
||||
if (request_data->interactive)
|
||||
gtk_text_buffer_delete_interactive (buffer,
|
||||
gtk_text_buffer_delete_interactive (request_data->buffer,
|
||||
&start,
|
||||
&end,
|
||||
request_data->default_editable);
|
||||
else
|
||||
gtk_text_buffer_delete (buffer, &start, &end);
|
||||
gtk_text_buffer_delete (request_data->buffer, &start, &end);
|
||||
}
|
||||
}
|
||||
|
||||
get_paste_point (buffer, insert_point, TRUE);
|
||||
}
|
||||
|
||||
/* Called when we request a paste and receive the text data
|
||||
@ -2214,6 +2230,8 @@ clipboard_text_received (GtkClipboard *clipboard,
|
||||
else
|
||||
gtk_text_buffer_insert (buffer, &insert_point,
|
||||
str, -1);
|
||||
|
||||
post_paste_cleanup (request_data);
|
||||
}
|
||||
|
||||
g_object_unref (G_OBJECT (buffer));
|
||||
@ -2253,6 +2271,33 @@ selection_data_get_buffer (GtkSelectionData *selection_data,
|
||||
return src_buffer;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* These are pretty handy functions; maybe something like them
|
||||
* should be in the public API. Also, there are other places in this
|
||||
* file where they could be used.
|
||||
*/
|
||||
static gpointer
|
||||
save_iter (const GtkTextIter *iter,
|
||||
gboolean left_gravity)
|
||||
{
|
||||
return gtk_text_buffer_create_mark (gtk_text_iter_get_buffer (iter),
|
||||
NULL,
|
||||
iter,
|
||||
TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
restore_iter (const GtkTextIter *iter,
|
||||
gpointer save_id)
|
||||
{
|
||||
gtk_text_buffer_get_iter_at_mark (gtk_text_mark_get_buffer (save_id),
|
||||
(GtkTextIter*) iter,
|
||||
save_id);
|
||||
gtk_text_buffer_delete_mark (gtk_text_mark_get_buffer (save_id),
|
||||
save_id);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
paste_from_buffer (ClipboardRequest *request_data,
|
||||
GtkTextBuffer *src_buffer,
|
||||
@ -2274,6 +2319,8 @@ paste_from_buffer (ClipboardRequest *request_data,
|
||||
end,
|
||||
request_data->interactive);
|
||||
}
|
||||
|
||||
post_paste_cleanup (request_data);
|
||||
|
||||
g_object_unref (G_OBJECT (src_buffer));
|
||||
}
|
||||
@ -2392,13 +2439,14 @@ paste (GtkTextBuffer *buffer,
|
||||
* replace the selection with the new text, otherwise, you
|
||||
* simply insert the new text at the point where the click
|
||||
* occured, unselecting any selected text. The replace_selection
|
||||
* flag toggles this behavior. FIXME set the flag based on something.
|
||||
* flag toggles this behavior.
|
||||
*/
|
||||
data->replace_selection = FALSE;
|
||||
|
||||
get_paste_point (buffer, &paste_point, FALSE);
|
||||
if (gtk_text_buffer_get_selection_bounds (buffer, &start, &end) &&
|
||||
gtk_text_iter_in_range (&paste_point, &start, &end))
|
||||
(gtk_text_iter_in_range (&paste_point, &start, &end) ||
|
||||
gtk_text_iter_equal (&paste_point, &end)))
|
||||
data->replace_selection = TRUE;
|
||||
|
||||
if (is_clipboard)
|
||||
|
@ -796,7 +796,9 @@ gtk_text_layout_draw (GtkTextLayout *layout,
|
||||
|
||||
current_y += line_display->height;
|
||||
gtk_text_layout_free_line_display (layout, line_display);
|
||||
|
||||
render_state->last_appearance = NULL;
|
||||
render_state->last_bg_appearance = NULL;
|
||||
|
||||
tmp_list = g_slist_next (tmp_list);
|
||||
}
|
||||
|
||||
|
@ -2368,14 +2368,9 @@ find_word_end_func (PangoLogAttr *attrs,
|
||||
{
|
||||
++offset; /* We always go to the NEXT word end */
|
||||
|
||||
/* Find start of next word */
|
||||
/* Find end of next word */
|
||||
while (offset < min_offset + len &&
|
||||
!attrs[offset].is_word_stop)
|
||||
++offset;
|
||||
|
||||
/* Find end */
|
||||
while (offset < min_offset + len &&
|
||||
!attrs[offset].is_white)
|
||||
!attrs[offset].is_word_end)
|
||||
++offset;
|
||||
|
||||
*found_offset = offset;
|
||||
@ -2383,6 +2378,16 @@ find_word_end_func (PangoLogAttr *attrs,
|
||||
return offset < min_offset + len;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_word_end_func (PangoLogAttr *attrs,
|
||||
gint offset,
|
||||
gint min_offset,
|
||||
gint len,
|
||||
gint *found_offset)
|
||||
{
|
||||
return attrs[offset].is_word_end;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
find_word_start_func (PangoLogAttr *attrs,
|
||||
gint offset,
|
||||
@ -2392,14 +2397,9 @@ find_word_start_func (PangoLogAttr *attrs,
|
||||
{
|
||||
--offset; /* We always go to the NEXT word start */
|
||||
|
||||
/* Find end of prev word */
|
||||
/* Find start of prev word */
|
||||
while (offset >= min_offset &&
|
||||
attrs[offset].is_white)
|
||||
--offset;
|
||||
|
||||
/* Find start */
|
||||
while (offset >= min_offset &&
|
||||
!attrs[offset].is_word_stop)
|
||||
!attrs[offset].is_word_start)
|
||||
--offset;
|
||||
|
||||
*found_offset = offset;
|
||||
@ -2407,31 +2407,53 @@ find_word_start_func (PangoLogAttr *attrs,
|
||||
return offset >= min_offset;
|
||||
}
|
||||
|
||||
/* FIXME this function is very, very gratuitously slow */
|
||||
static gboolean
|
||||
find_by_log_attrs (GtkTextIter *iter,
|
||||
FindLogAttrFunc func,
|
||||
gboolean forward)
|
||||
is_word_start_func (PangoLogAttr *attrs,
|
||||
gint offset,
|
||||
gint min_offset,
|
||||
gint len,
|
||||
gint *found_offset)
|
||||
{
|
||||
return attrs[offset].is_word_start;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
inside_word_func (PangoLogAttr *attrs,
|
||||
gint offset,
|
||||
gint min_offset,
|
||||
gint len,
|
||||
gint *found_offset)
|
||||
{
|
||||
/* Find next word start or end */
|
||||
while (offset >= min_offset &&
|
||||
!(attrs[offset].is_word_start || attrs[offset].is_word_end))
|
||||
--offset;
|
||||
|
||||
return attrs[offset].is_word_start;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
test_log_attrs (GtkTextIter *iter,
|
||||
FindLogAttrFunc func,
|
||||
gint *found_offset)
|
||||
{
|
||||
GtkTextIter orig;
|
||||
GtkTextIter start;
|
||||
GtkTextIter end;
|
||||
gchar *paragraph;
|
||||
gint char_len, byte_len;
|
||||
PangoLogAttr *attrs;
|
||||
int offset;
|
||||
gboolean found = FALSE;
|
||||
gboolean result = FALSE;
|
||||
|
||||
g_return_val_if_fail (iter != NULL, FALSE);
|
||||
|
||||
orig = *iter;
|
||||
start = *iter;
|
||||
end = *iter;
|
||||
|
||||
gtk_text_iter_set_line_offset (&start, 0);
|
||||
gtk_text_iter_forward_to_newline (&end);
|
||||
gtk_text_iter_forward_line (&end);
|
||||
|
||||
paragraph = gtk_text_iter_get_text (&start, &end);
|
||||
paragraph = gtk_text_iter_get_slice (&start, &end);
|
||||
char_len = g_utf8_strlen (paragraph, -1);
|
||||
byte_len = strlen (paragraph);
|
||||
|
||||
@ -2451,13 +2473,32 @@ find_by_log_attrs (GtkTextIter *iter,
|
||||
|
||||
g_free (lang);
|
||||
|
||||
found = (* func) (attrs, offset, 0, char_len, &offset);
|
||||
result = (* func) (attrs, offset, 0, char_len, found_offset);
|
||||
|
||||
g_free (attrs);
|
||||
}
|
||||
|
||||
g_free (paragraph);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* FIXME this function is very, very gratuitously slow */
|
||||
static gboolean
|
||||
find_by_log_attrs (GtkTextIter *iter,
|
||||
FindLogAttrFunc func,
|
||||
gboolean forward)
|
||||
{
|
||||
GtkTextIter orig;
|
||||
gint offset = 0;
|
||||
gboolean found = FALSE;
|
||||
|
||||
g_return_val_if_fail (iter != NULL, FALSE);
|
||||
|
||||
orig = *iter;
|
||||
|
||||
found = test_log_attrs (iter, func, &offset);
|
||||
|
||||
if (!found)
|
||||
{
|
||||
if (forward)
|
||||
@ -2502,7 +2543,7 @@ gtk_text_iter_backward_word_start (GtkTextIter *iter)
|
||||
*/
|
||||
gboolean
|
||||
gtk_text_iter_forward_word_ends (GtkTextIter *iter,
|
||||
gint count)
|
||||
gint count)
|
||||
{
|
||||
g_return_val_if_fail (iter != NULL, FALSE);
|
||||
g_return_val_if_fail (count > 0, FALSE);
|
||||
@ -2540,6 +2581,25 @@ gtk_text_iter_backward_word_starts (GtkTextIter *iter,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
gboolean
|
||||
gtk_text_iter_starts_word (const GtkTextIter *iter)
|
||||
{
|
||||
return test_log_attrs (iter, is_word_start_func, NULL);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_text_iter_ends_word (const GtkTextIter *iter)
|
||||
{
|
||||
return test_log_attrs (iter, is_word_end_func, NULL);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_text_iter_inside_word (const GtkTextIter *iter)
|
||||
{
|
||||
return test_log_attrs (iter, inside_word_func, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_text_iter_set_line_offset (GtkTextIter *iter,
|
||||
gint char_on_line)
|
||||
|
@ -124,6 +124,9 @@ GSList *gtk_text_iter_get_tags (const GtkTextIter *iter);
|
||||
gboolean gtk_text_iter_editable (const GtkTextIter *iter,
|
||||
gboolean default_setting);
|
||||
|
||||
gboolean gtk_text_iter_starts_word (const GtkTextIter *iter);
|
||||
gboolean gtk_text_iter_ends_word (const GtkTextIter *iter);
|
||||
gboolean gtk_text_iter_inside_word (const GtkTextIter *iter);
|
||||
gboolean gtk_text_iter_starts_line (const GtkTextIter *iter);
|
||||
gboolean gtk_text_iter_ends_line (const GtkTextIter *iter);
|
||||
|
||||
|
@ -2209,7 +2209,6 @@ find_display_line_below (GtkTextLayout *layout,
|
||||
while (line && !found_line)
|
||||
{
|
||||
GtkTextLineDisplay *display = gtk_text_layout_get_line_display (layout, line, FALSE);
|
||||
gint byte_index = 0;
|
||||
PangoLayoutIter *layout_iter;
|
||||
|
||||
layout_iter = pango_layout_get_iter (display->layout);
|
||||
@ -2221,7 +2220,7 @@ find_display_line_below (GtkTextLayout *layout,
|
||||
gint first_y, last_y;
|
||||
PangoLayoutLine *layout_line = pango_layout_iter_get_line (layout_iter);
|
||||
|
||||
found_byte = byte_index;
|
||||
found_byte = layout_line->start_index;
|
||||
|
||||
if (line_top >= y)
|
||||
{
|
||||
@ -2231,8 +2230,6 @@ find_display_line_below (GtkTextLayout *layout,
|
||||
|
||||
pango_layout_iter_get_line_yrange (layout_iter, &first_y, &last_y);
|
||||
line_top += (last_y - first_y) / PANGO_SCALE;
|
||||
|
||||
byte_index += layout_line->length;
|
||||
}
|
||||
while (pango_layout_iter_next_line (layout_iter));
|
||||
|
||||
@ -2278,8 +2275,6 @@ find_display_line_above (GtkTextLayout *layout,
|
||||
{
|
||||
GtkTextLineDisplay *display = gtk_text_layout_get_line_display (layout, line, FALSE);
|
||||
PangoRectangle logical_rect;
|
||||
|
||||
gint byte_index = 0;
|
||||
PangoLayoutIter *layout_iter;
|
||||
gint tmp_top;
|
||||
|
||||
@ -2296,7 +2291,7 @@ find_display_line_above (GtkTextLayout *layout,
|
||||
gint first_y, last_y;
|
||||
PangoLayoutLine *layout_line = pango_layout_iter_get_line (layout_iter);
|
||||
|
||||
found_byte = byte_index;
|
||||
found_byte = layout_line->start_index;
|
||||
|
||||
pango_layout_iter_get_line_yrange (layout_iter, &first_y, &last_y);
|
||||
|
||||
@ -2305,11 +2300,8 @@ find_display_line_above (GtkTextLayout *layout,
|
||||
if (tmp_top < y)
|
||||
{
|
||||
found_line = line;
|
||||
found_byte = byte_index;
|
||||
goto done;
|
||||
}
|
||||
|
||||
byte_index += layout_line->length;
|
||||
}
|
||||
while (pango_layout_iter_next_line (layout_iter));
|
||||
|
||||
@ -2383,7 +2375,7 @@ gtk_text_layout_clamp_iter_to_vrange (GtkTextLayout *layout,
|
||||
* Move the iterator to the beginning of the previous line. The lines
|
||||
* of a wrapped paragraph are treated as distinct for this operation.
|
||||
**/
|
||||
void
|
||||
gboolean
|
||||
gtk_text_layout_move_iter_to_previous_line (GtkTextLayout *layout,
|
||||
GtkTextIter *iter)
|
||||
{
|
||||
@ -2392,11 +2384,14 @@ gtk_text_layout_move_iter_to_previous_line (GtkTextLayout *layout,
|
||||
gint line_byte;
|
||||
GSList *tmp_list;
|
||||
PangoLayoutLine *layout_line;
|
||||
GtkTextIter orig;
|
||||
|
||||
g_return_val_if_fail (layout != NULL, FALSE);
|
||||
g_return_val_if_fail (GTK_IS_TEXT_LAYOUT (layout), FALSE);
|
||||
g_return_val_if_fail (iter != NULL, FALSE);
|
||||
|
||||
g_return_if_fail (layout != NULL);
|
||||
g_return_if_fail (GTK_IS_TEXT_LAYOUT (layout));
|
||||
g_return_if_fail (iter != NULL);
|
||||
|
||||
orig = *iter;
|
||||
|
||||
line = gtk_text_iter_get_text_line (iter);
|
||||
display = gtk_text_layout_get_line_display (layout, line, FALSE);
|
||||
line_byte = line_display_iter_to_index (layout, display, iter);
|
||||
@ -2410,49 +2405,49 @@ gtk_text_layout_move_iter_to_previous_line (GtkTextLayout *layout,
|
||||
|
||||
if (prev_line)
|
||||
{
|
||||
gint byte_offset = 0;
|
||||
|
||||
gtk_text_layout_free_line_display (layout, display);
|
||||
display = gtk_text_layout_get_line_display (layout, prev_line, FALSE);
|
||||
|
||||
tmp_list = pango_layout_get_lines (display->layout);
|
||||
|
||||
tmp_list = pango_layout_get_lines (display->layout);
|
||||
|
||||
while (tmp_list->next)
|
||||
{
|
||||
layout_line = tmp_list->data;
|
||||
tmp_list = tmp_list->next;
|
||||
|
||||
byte_offset += layout_line->length;
|
||||
}
|
||||
|
||||
line_display_index_to_iter (layout, display, iter, byte_offset, 0);
|
||||
line_display_index_to_iter (layout, display, iter,
|
||||
layout_line->start_index + layout_line->length, 0);
|
||||
}
|
||||
else
|
||||
line_display_index_to_iter (layout, display, iter, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
gint prev_offset = 0;
|
||||
gint byte_offset = layout_line->length;
|
||||
gint prev_offset = layout_line->start_index;
|
||||
|
||||
tmp_list = tmp_list->next;
|
||||
while (tmp_list)
|
||||
{
|
||||
layout_line = tmp_list->data;
|
||||
|
||||
if (line_byte < byte_offset + layout_line->length || !tmp_list->next)
|
||||
if (line_byte < layout_line->start_index + layout_line->length ||
|
||||
!tmp_list->next)
|
||||
{
|
||||
line_display_index_to_iter (layout, display, iter, prev_offset, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
prev_offset = byte_offset;
|
||||
byte_offset += layout_line->length;
|
||||
prev_offset = layout_line->start_index;
|
||||
tmp_list = tmp_list->next;
|
||||
}
|
||||
}
|
||||
|
||||
gtk_text_layout_free_line_display (layout, display);
|
||||
|
||||
return
|
||||
!gtk_text_iter_equal (iter, &orig) &&
|
||||
!gtk_text_iter_is_last (iter);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2464,27 +2459,28 @@ gtk_text_layout_move_iter_to_previous_line (GtkTextLayout *layout,
|
||||
* lines of a wrapped paragraph are treated as distinct for
|
||||
* this operation.
|
||||
**/
|
||||
void
|
||||
gboolean
|
||||
gtk_text_layout_move_iter_to_next_line (GtkTextLayout *layout,
|
||||
GtkTextIter *iter)
|
||||
{
|
||||
GtkTextLine *line;
|
||||
GtkTextLineDisplay *display;
|
||||
gint line_byte;
|
||||
|
||||
GtkTextIter orig;
|
||||
gboolean found = FALSE;
|
||||
gboolean found_after = FALSE;
|
||||
gboolean first = TRUE;
|
||||
|
||||
g_return_if_fail (layout != NULL);
|
||||
g_return_if_fail (GTK_IS_TEXT_LAYOUT (layout));
|
||||
g_return_if_fail (iter != NULL);
|
||||
g_return_val_if_fail (layout != NULL, FALSE);
|
||||
g_return_val_if_fail (GTK_IS_TEXT_LAYOUT (layout), FALSE);
|
||||
g_return_val_if_fail (iter != NULL, FALSE);
|
||||
|
||||
orig = *iter;
|
||||
|
||||
line = gtk_text_iter_get_text_line (iter);
|
||||
|
||||
while (line && !found_after)
|
||||
{
|
||||
gint byte_offset = 0;
|
||||
GSList *tmp_list;
|
||||
|
||||
display = gtk_text_layout_get_line_display (layout, line, FALSE);
|
||||
@ -2504,13 +2500,13 @@ gtk_text_layout_move_iter_to_next_line (GtkTextLayout *layout,
|
||||
|
||||
if (found)
|
||||
{
|
||||
line_display_index_to_iter (layout, display, iter, byte_offset, 0);
|
||||
line_display_index_to_iter (layout, display, iter,
|
||||
layout_line->start_index, 0);
|
||||
found_after = TRUE;
|
||||
}
|
||||
else if (line_byte < byte_offset + layout_line->length || !tmp_list->next)
|
||||
else if (line_byte < layout_line->start_index + layout_line->length || !tmp_list->next)
|
||||
found = TRUE;
|
||||
|
||||
byte_offset += layout_line->length;
|
||||
|
||||
tmp_list = tmp_list->next;
|
||||
}
|
||||
|
||||
@ -2518,6 +2514,10 @@ gtk_text_layout_move_iter_to_next_line (GtkTextLayout *layout,
|
||||
|
||||
line = gtk_text_line_next (line);
|
||||
}
|
||||
|
||||
return
|
||||
!gtk_text_iter_equal (iter, &orig) &&
|
||||
!gtk_text_iter_is_last (iter);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2528,7 +2528,7 @@ gtk_text_layout_move_iter_to_next_line (GtkTextLayout *layout,
|
||||
*
|
||||
* Move to the beginning or end of a display line.
|
||||
**/
|
||||
void
|
||||
gboolean
|
||||
gtk_text_layout_move_iter_to_line_end (GtkTextLayout *layout,
|
||||
GtkTextIter *iter,
|
||||
gint direction)
|
||||
@ -2536,13 +2536,15 @@ gtk_text_layout_move_iter_to_line_end (GtkTextLayout *layout,
|
||||
GtkTextLine *line;
|
||||
GtkTextLineDisplay *display;
|
||||
gint line_byte;
|
||||
gint byte_offset = 0;
|
||||
GSList *tmp_list;
|
||||
GtkTextIter orig;
|
||||
|
||||
g_return_val_if_fail (layout != NULL, FALSE);
|
||||
g_return_val_if_fail (GTK_IS_TEXT_LAYOUT (layout), FALSE);
|
||||
g_return_val_if_fail (iter != NULL, FALSE);
|
||||
|
||||
g_return_if_fail (layout != NULL);
|
||||
g_return_if_fail (GTK_IS_TEXT_LAYOUT (layout));
|
||||
g_return_if_fail (iter != NULL);
|
||||
|
||||
orig = *iter;
|
||||
|
||||
line = gtk_text_iter_get_text_line (iter);
|
||||
display = gtk_text_layout_get_line_display (layout, line, FALSE);
|
||||
line_byte = line_display_iter_to_index (layout, display, iter);
|
||||
@ -2552,10 +2554,10 @@ gtk_text_layout_move_iter_to_line_end (GtkTextLayout *layout,
|
||||
{
|
||||
PangoLayoutLine *layout_line = tmp_list->data;
|
||||
|
||||
if (line_byte < byte_offset + layout_line->length || !tmp_list->next)
|
||||
if (line_byte < layout_line->start_index + layout_line->length || !tmp_list->next)
|
||||
{
|
||||
line_display_index_to_iter (layout, display, iter,
|
||||
direction < 0 ? byte_offset : byte_offset + layout_line->length,
|
||||
direction < 0 ? layout_line->start_index : layout_line->start_index + layout_line->length,
|
||||
0);
|
||||
|
||||
/* FIXME: As a bad hack, we move back one position when we
|
||||
@ -2567,12 +2569,66 @@ gtk_text_layout_move_iter_to_line_end (GtkTextLayout *layout,
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
byte_offset += layout_line->length;
|
||||
|
||||
tmp_list = tmp_list->next;
|
||||
}
|
||||
|
||||
gtk_text_layout_free_line_display (layout, display);
|
||||
|
||||
return
|
||||
!gtk_text_iter_equal (iter, &orig) &&
|
||||
!gtk_text_iter_is_last (iter);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gtk_text_layout_iter_starts_line:
|
||||
* @layout: a #GtkTextLayout
|
||||
* @iter: iterator to test
|
||||
*
|
||||
* Tests whether an iterator is at the start of a display line.
|
||||
**/
|
||||
gboolean
|
||||
gtk_text_layout_iter_starts_line (GtkTextLayout *layout,
|
||||
const GtkTextIter *iter)
|
||||
{
|
||||
GtkTextLine *line;
|
||||
GtkTextLineDisplay *display;
|
||||
gint line_byte;
|
||||
GSList *tmp_list;
|
||||
|
||||
g_return_val_if_fail (layout != NULL, FALSE);
|
||||
g_return_val_if_fail (GTK_IS_TEXT_LAYOUT (layout), FALSE);
|
||||
g_return_val_if_fail (iter != NULL, FALSE);
|
||||
|
||||
line = gtk_text_iter_get_text_line (iter);
|
||||
display = gtk_text_layout_get_line_display (layout, line, FALSE);
|
||||
line_byte = line_display_iter_to_index (layout, display, iter);
|
||||
|
||||
tmp_list = pango_layout_get_lines (display->layout);
|
||||
while (tmp_list)
|
||||
{
|
||||
PangoLayoutLine *layout_line = tmp_list->data;
|
||||
|
||||
if (line_byte < layout_line->start_index + layout_line->length ||
|
||||
!tmp_list->next)
|
||||
{
|
||||
/* We're located on this line of the para delimiters before
|
||||
* it
|
||||
*/
|
||||
gtk_text_layout_free_line_display (layout, display);
|
||||
|
||||
if (line_byte == layout_line->start_index)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
tmp_list = tmp_list->next;
|
||||
}
|
||||
|
||||
g_assert_not_reached ();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2593,7 +2649,6 @@ gtk_text_layout_move_iter_to_x (GtkTextLayout *layout,
|
||||
GtkTextLine *line;
|
||||
GtkTextLineDisplay *display;
|
||||
gint line_byte;
|
||||
gint byte_offset = 0;
|
||||
PangoLayoutIter *layout_iter;
|
||||
|
||||
g_return_if_fail (layout != NULL);
|
||||
@ -2611,7 +2666,7 @@ gtk_text_layout_move_iter_to_x (GtkTextLayout *layout,
|
||||
{
|
||||
PangoLayoutLine *layout_line = pango_layout_iter_get_line (layout_iter);
|
||||
|
||||
if (line_byte < byte_offset + layout_line->length ||
|
||||
if (line_byte < layout_line->start_index + layout_line->length ||
|
||||
pango_layout_iter_at_last_line (layout_iter))
|
||||
{
|
||||
PangoRectangle logical_rect;
|
||||
@ -2628,8 +2683,6 @@ gtk_text_layout_move_iter_to_x (GtkTextLayout *layout,
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
byte_offset += layout_line->length;
|
||||
}
|
||||
while (pango_layout_iter_next_line (layout_iter));
|
||||
|
||||
@ -2657,16 +2710,19 @@ gtk_text_layout_move_iter_to_x (GtkTextLayout *layout,
|
||||
* is moved off of the end of a run.
|
||||
**/
|
||||
|
||||
void
|
||||
gboolean
|
||||
gtk_text_layout_move_iter_visually (GtkTextLayout *layout,
|
||||
GtkTextIter *iter,
|
||||
gint count)
|
||||
{
|
||||
GtkTextLineDisplay *display = NULL;
|
||||
GtkTextIter orig;
|
||||
|
||||
g_return_val_if_fail (layout != NULL, FALSE);
|
||||
g_return_val_if_fail (iter != NULL, FALSE);
|
||||
|
||||
g_return_if_fail (layout != NULL);
|
||||
g_return_if_fail (iter != NULL);
|
||||
|
||||
orig = *iter;
|
||||
|
||||
while (count != 0)
|
||||
{
|
||||
GtkTextLine *line = gtk_text_iter_get_text_line (iter);
|
||||
@ -2715,8 +2771,8 @@ gtk_text_layout_move_iter_visually (GtkTextLayout *layout,
|
||||
line = gtk_text_line_previous (line);
|
||||
|
||||
if (!line)
|
||||
return;
|
||||
|
||||
goto done;
|
||||
|
||||
gtk_text_layout_free_line_display (layout, display);
|
||||
display = gtk_text_layout_get_line_display (layout, line, FALSE);
|
||||
new_index = gtk_text_line_byte_count (line);
|
||||
@ -2725,7 +2781,7 @@ gtk_text_layout_move_iter_visually (GtkTextLayout *layout,
|
||||
{
|
||||
line = gtk_text_line_next (line);
|
||||
if (!line)
|
||||
return;
|
||||
goto done;
|
||||
|
||||
gtk_text_layout_free_line_display (layout, display);
|
||||
display = gtk_text_layout_get_line_display (layout, line, FALSE);
|
||||
@ -2738,6 +2794,12 @@ gtk_text_layout_move_iter_visually (GtkTextLayout *layout,
|
||||
}
|
||||
|
||||
gtk_text_layout_free_line_display (layout, display);
|
||||
|
||||
done:
|
||||
|
||||
return
|
||||
!gtk_text_iter_equal (iter, &orig) &&
|
||||
!gtk_text_iter_is_last (iter);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -339,20 +339,22 @@ gboolean gtk_text_layout_clamp_iter_to_vrange (GtkTextLayout *layout,
|
||||
gint top,
|
||||
gint bottom);
|
||||
|
||||
void gtk_text_layout_move_iter_to_line_end (GtkTextLayout *layout,
|
||||
GtkTextIter *iter,
|
||||
gint direction);
|
||||
void gtk_text_layout_move_iter_to_previous_line (GtkTextLayout *layout,
|
||||
GtkTextIter *iter);
|
||||
void gtk_text_layout_move_iter_to_next_line (GtkTextLayout *layout,
|
||||
GtkTextIter *iter);
|
||||
void gtk_text_layout_move_iter_to_x (GtkTextLayout *layout,
|
||||
GtkTextIter *iter,
|
||||
gint x);
|
||||
void gtk_text_layout_move_iter_visually (GtkTextLayout *layout,
|
||||
GtkTextIter *iter,
|
||||
gint count);
|
||||
gboolean gtk_text_layout_move_iter_to_line_end (GtkTextLayout *layout,
|
||||
GtkTextIter *iter,
|
||||
gint direction);
|
||||
gboolean gtk_text_layout_move_iter_to_previous_line (GtkTextLayout *layout,
|
||||
GtkTextIter *iter);
|
||||
gboolean gtk_text_layout_move_iter_to_next_line (GtkTextLayout *layout,
|
||||
GtkTextIter *iter);
|
||||
void gtk_text_layout_move_iter_to_x (GtkTextLayout *layout,
|
||||
GtkTextIter *iter,
|
||||
gint x);
|
||||
gboolean gtk_text_layout_move_iter_visually (GtkTextLayout *layout,
|
||||
GtkTextIter *iter,
|
||||
gint count);
|
||||
|
||||
gboolean gtk_text_layout_iter_starts_line (GtkTextLayout *layout,
|
||||
const GtkTextIter *iter);
|
||||
|
||||
/* Don't use these. Use gtk_text_view_add_child_at_anchor().
|
||||
* These functions are defined in gtktextchild.c, but here
|
||||
|
@ -179,7 +179,7 @@ gtk_text_mark_get_deleted (GtkTextMark *mark)
|
||||
{
|
||||
GtkTextLineSegment *seg;
|
||||
|
||||
g_return_val_if_fail (mark != NULL, FALSE);
|
||||
g_return_val_if_fail (GTK_IS_TEXT_MARK (mark), FALSE);
|
||||
|
||||
seg = mark->segment;
|
||||
|
||||
@ -189,6 +189,30 @@ gtk_text_mark_get_deleted (GtkTextMark *mark)
|
||||
return seg->body.mark.tree == NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_text_mark_get_buffer:
|
||||
* @mark: a #GtkTextMark
|
||||
*
|
||||
* Gets the buffer this mark is located inside,
|
||||
* or NULL if the mark is deleted.
|
||||
*
|
||||
* Return value: the mark's #GtkTextBuffer
|
||||
**/
|
||||
GtkTextBuffer*
|
||||
gtk_text_mark_get_buffer (GtkTextMark *mark)
|
||||
{
|
||||
GtkTextLineSegment *seg;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_TEXT_MARK (mark), FALSE);
|
||||
|
||||
seg = mark->segment;
|
||||
|
||||
if (seg->body.mark.tree == NULL)
|
||||
return NULL;
|
||||
else
|
||||
return gtk_text_btree_get_buffer (seg->body.mark.tree);
|
||||
}
|
||||
|
||||
/*
|
||||
* Macro that determines the size of a mark segment:
|
||||
*/
|
||||
|
@ -81,12 +81,14 @@ struct _GtkTextMarkClass
|
||||
|
||||
GType gtk_text_mark_get_type (void) G_GNUC_CONST;
|
||||
|
||||
void gtk_text_mark_set_visible (GtkTextMark *mark,
|
||||
gboolean setting);
|
||||
gboolean gtk_text_mark_get_visible (GtkTextMark *mark);
|
||||
void gtk_text_mark_set_visible (GtkTextMark *mark,
|
||||
gboolean setting);
|
||||
gboolean gtk_text_mark_get_visible (GtkTextMark *mark);
|
||||
|
||||
/* FIXME gconst */
|
||||
const char *gtk_text_mark_get_name (GtkTextMark *mark);
|
||||
gboolean gtk_text_mark_get_deleted (GtkTextMark *mark);
|
||||
const char * gtk_text_mark_get_name (GtkTextMark *mark);
|
||||
gboolean gtk_text_mark_get_deleted (GtkTextMark *mark);
|
||||
GtkTextBuffer* gtk_text_mark_get_buffer (GtkTextMark *mark);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -2637,7 +2637,69 @@ gtk_text_view_button_press_event (GtkWidget *widget, GdkEventButton *event)
|
||||
gtk_text_view_popup_menu (text_view, event);
|
||||
}
|
||||
}
|
||||
else if ((event->type == GDK_2BUTTON_PRESS ||
|
||||
event->type == GDK_3BUTTON_PRESS) &&
|
||||
event->button == 1)
|
||||
{
|
||||
GtkTextIter start, end;
|
||||
|
||||
/* End the selection drag, otherwise we'd clear the new
|
||||
* word/line selection on button release
|
||||
*/
|
||||
gtk_text_view_end_selection_drag (text_view, event);
|
||||
|
||||
gtk_text_layout_get_iter_at_pixel (text_view->layout,
|
||||
&start,
|
||||
event->x + text_view->xoffset,
|
||||
event->y + text_view->yoffset);
|
||||
|
||||
end = start;
|
||||
|
||||
if (event->type == GDK_2BUTTON_PRESS)
|
||||
{
|
||||
if (gtk_text_iter_inside_word (&start))
|
||||
{
|
||||
if (!gtk_text_iter_starts_word (&start))
|
||||
gtk_text_iter_backward_word_start (&start);
|
||||
|
||||
if (!gtk_text_iter_ends_word (&end))
|
||||
gtk_text_iter_forward_word_end (&end);
|
||||
}
|
||||
}
|
||||
else if (event->type == GDK_3BUTTON_PRESS)
|
||||
{
|
||||
if (gtk_text_view_starts_display_line (text_view, &start))
|
||||
{
|
||||
/* If on a display line boundary, we assume the user
|
||||
* clicked off the end of a line and we therefore select
|
||||
* the line before the boundary.
|
||||
*/
|
||||
gtk_text_view_backward_display_line_start (text_view, &start);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* start isn't on the start of a line, so we move it to the
|
||||
* start, and move end to the end unless it's already there.
|
||||
*/
|
||||
gtk_text_view_backward_display_line_start (text_view, &start);
|
||||
|
||||
if (!gtk_text_view_starts_display_line (text_view, &end))
|
||||
gtk_text_view_forward_display_line_end (text_view, &end);
|
||||
}
|
||||
}
|
||||
|
||||
gtk_text_buffer_move_mark (get_buffer (text_view),
|
||||
gtk_text_buffer_get_selection_bound (get_buffer (text_view)),
|
||||
&start);
|
||||
gtk_text_buffer_move_mark (get_buffer (text_view),
|
||||
gtk_text_buffer_get_insert (get_buffer (text_view)),
|
||||
&end);
|
||||
|
||||
text_view->just_selected_element = TRUE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -2661,6 +2723,11 @@ gtk_text_view_button_release_event (GtkWidget *widget, GdkEventButton *event)
|
||||
|
||||
if (gtk_text_view_end_selection_drag (GTK_TEXT_VIEW (widget), event))
|
||||
return TRUE;
|
||||
else if (text_view->just_selected_element)
|
||||
{
|
||||
text_view->just_selected_element = FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Unselect everything; probably we were dragging, or clicked
|
||||
@ -5457,3 +5524,80 @@ gtk_text_view_move_child (GtkTextView *text_view,
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Iterator operations */
|
||||
|
||||
gboolean
|
||||
gtk_text_view_forward_display_line (GtkTextView *text_view,
|
||||
GtkTextIter *iter)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_TEXT_VIEW (text_view), FALSE);
|
||||
g_return_val_if_fail (iter != NULL, FALSE);
|
||||
|
||||
gtk_text_view_ensure_layout (text_view);
|
||||
|
||||
return gtk_text_layout_move_iter_to_next_line (text_view->layout, iter);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_text_view_backward_display_line (GtkTextView *text_view,
|
||||
GtkTextIter *iter)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_TEXT_VIEW (text_view), FALSE);
|
||||
g_return_val_if_fail (iter != NULL, FALSE);
|
||||
|
||||
gtk_text_view_ensure_layout (text_view);
|
||||
|
||||
return gtk_text_layout_move_iter_to_previous_line (text_view->layout, iter);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_text_view_forward_display_line_end (GtkTextView *text_view,
|
||||
GtkTextIter *iter)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_TEXT_VIEW (text_view), FALSE);
|
||||
g_return_val_if_fail (iter != NULL, FALSE);
|
||||
|
||||
gtk_text_view_ensure_layout (text_view);
|
||||
|
||||
return gtk_text_layout_move_iter_to_line_end (text_view->layout, iter, 1);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_text_view_backward_display_line_start (GtkTextView *text_view,
|
||||
GtkTextIter *iter)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_TEXT_VIEW (text_view), FALSE);
|
||||
g_return_val_if_fail (iter != NULL, FALSE);
|
||||
|
||||
gtk_text_view_ensure_layout (text_view);
|
||||
|
||||
return gtk_text_layout_move_iter_to_line_end (text_view->layout, iter, -1);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_text_view_starts_display_line (GtkTextView *text_view,
|
||||
const GtkTextIter *iter)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_TEXT_VIEW (text_view), FALSE);
|
||||
g_return_val_if_fail (iter != NULL, FALSE);
|
||||
|
||||
gtk_text_view_ensure_layout (text_view);
|
||||
|
||||
return gtk_text_layout_iter_starts_line (text_view->layout, iter);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_text_view_move_visually (GtkTextView *text_view,
|
||||
GtkTextIter *iter,
|
||||
gint count)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_TEXT_VIEW (text_view), FALSE);
|
||||
g_return_val_if_fail (iter != NULL, FALSE);
|
||||
|
||||
gtk_text_view_ensure_layout (text_view);
|
||||
|
||||
return gtk_text_layout_move_iter_visually (text_view->layout, iter, count);
|
||||
}
|
||||
|
||||
|
||||
|
@ -87,7 +87,9 @@ struct _GtkTextView
|
||||
guint overwrite_mode : 1;
|
||||
guint cursor_visible : 1;
|
||||
guint need_im_reset : 1; /* If we have reset the IM since the last character entered */
|
||||
|
||||
/* just selected a word or line via double/triple click */
|
||||
guint just_selected_element : 1;
|
||||
|
||||
GtkTextWindow *text_window;
|
||||
GtkTextWindow *left_window;
|
||||
GtkTextWindow *right_window;
|
||||
@ -226,6 +228,19 @@ void gtk_text_view_set_text_window_size (GtkTextView *text_view,
|
||||
gint width,
|
||||
gint height);
|
||||
|
||||
gboolean gtk_text_view_forward_display_line (GtkTextView *text_view,
|
||||
GtkTextIter *iter);
|
||||
gboolean gtk_text_view_backward_display_line (GtkTextView *text_view,
|
||||
GtkTextIter *iter);
|
||||
gboolean gtk_text_view_forward_display_line_end (GtkTextView *text_view,
|
||||
GtkTextIter *iter);
|
||||
gboolean gtk_text_view_backward_display_line_start (GtkTextView *text_view,
|
||||
GtkTextIter *iter);
|
||||
gboolean gtk_text_view_starts_display_line (GtkTextView *text_view,
|
||||
const GtkTextIter *iter);
|
||||
gboolean gtk_text_view_move_visually (GtkTextView *text_view,
|
||||
GtkTextIter *iter,
|
||||
gint count);
|
||||
|
||||
/* Adding child widgets */
|
||||
void gtk_text_view_add_child_at_anchor (GtkTextView *text_view,
|
||||
|
Loading…
Reference in New Issue
Block a user