summaryrefslogtreecommitdiff
path: root/gtk
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2000-11-07 21:01:02 +0000
committerHavoc Pennington <hp@src.gnome.org>2000-11-07 21:01:02 +0000
commitf1de9df0511db6e82ee12c8e7f78d68d7a31cbbe (patch)
treee7c7ec7be138908bef2c5395d50ab6710f86f6d9 /gtk
parent163dc54dea828d41fe12eb762c730e57444d63f3 (diff)
downloadgtk+-f1de9df0511db6e82ee12c8e7f78d68d7a31cbbe.tar.gz
rename to gtk_text_mark_get_visible
2000-11-07 Havoc Pennington <hp@redhat.com> * gtk/gtktextmark.c (gtk_text_mark_is_visible): rename to gtk_text_mark_get_visible * gtk/gtktextlayout.c (gtk_text_layout_move_iter_to_line_end): fix bug that was generating an invalid iterator * gtk/gtktextiter.c (gtk_text_iter_get_offset): move call to ensure_char_offsets() in front of code placing the iter in an invalid state. * gtk/gtktextbuffer.c (gtk_text_buffer_paste_primary): make override_location arg const (paste): Replace the selection if we paste into the current selection * gtk/gtkselection.h: Remove "GtkSelectioData" (struct _GtkSelectionData): move the definition here. * gtk/gtktextbuffer.c (gtk_text_buffer_update_primary_selection): Export the GTK_TEXT_BUFFER_CONTENTS target for in-process copies * gtk/gtktextiter.c (gtk_text_iter_get_tags): New function * gtk/gtktextbuffer.c (gtk_text_buffer_insert_range): implement (gtk_text_buffer_insert_range_interactive): implement (gtk_text_buffer_get_tags): Remove, replaced by gtk_text_iter_get_tags() * gtk/gtktextiter.c (gtk_text_iter_forward_search): Add a search limit parameter, to avoid infinite linear scan. (gtk_text_iter_backward_search): Add search limit (gtk_text_iter_forward_find_char): Add search limit (gtk_text_iter_backward_find_char): Add search limit
Diffstat (limited to 'gtk')
-rw-r--r--gtk/gtkselection.c2
-rw-r--r--gtk/gtkselection.h26
-rw-r--r--gtk/gtktextbtree.c32
-rw-r--r--gtk/gtktextbuffer.c621
-rw-r--r--gtk/gtktextbuffer.h10
-rw-r--r--gtk/gtktextiter.c249
-rw-r--r--gtk/gtktextiter.h29
-rw-r--r--gtk/gtktextlayout.c2
-rw-r--r--gtk/gtktextmark.c4
-rw-r--r--gtk/gtktextmark.h2
-rw-r--r--gtk/gtktextsegment.c3
-rw-r--r--gtk/gtktextview.c8
-rw-r--r--gtk/gtkwidget.h19
-rw-r--r--gtk/testtext.c6
14 files changed, 803 insertions, 210 deletions
diff --git a/gtk/gtkselection.c b/gtk/gtkselection.c
index e09da3d65e..fdfb1aa157 100644
--- a/gtk/gtkselection.c
+++ b/gtk/gtkselection.c
@@ -1720,7 +1720,7 @@ gtk_selection_default_handler (GtkWidget *widget,
}
-GtkSelectioData*
+GtkSelectionData*
gtk_selection_data_copy (GtkSelectionData *selection_data)
{
GtkSelectionData *new_data;
diff --git a/gtk/gtkselection.h b/gtk/gtkselection.h
index 668fec4b3a..4c109d5531 100644
--- a/gtk/gtkselection.h
+++ b/gtk/gtkselection.h
@@ -36,10 +36,30 @@
extern "C" {
#endif /* __cplusplus */
-typedef struct _GtkSelectionData GtkSelectioData;
typedef struct _GtkTargetList GtkTargetList;
typedef struct _GtkTargetEntry GtkTargetEntry;
+/* The contents of a selection are returned in a GtkSelectionData
+ * structure. selection/target identify the request. type specifies
+ * the type of the return; if length < 0, and the data should be
+ * ignored. This structure has object semantics - no fields should be
+ * modified directly, they should not be created directly, and
+ * pointers to them should not be stored beyond the duration of a
+ * callback. (If the last is changed, we'll need to add reference
+ * counting.) The time field gives the timestamp at which the data was
+ * sent.
+ */
+
+struct _GtkSelectionData
+{
+ GdkAtom selection;
+ GdkAtom target;
+ GdkAtom type;
+ gint format;
+ guchar *data;
+ gint length;
+};
+
struct _GtkTargetEntry {
gchar *target;
guint flags;
@@ -125,8 +145,8 @@ gint gtk_selection_notify (GtkWidget *widget,
GdkEventSelection *event);
gint gtk_selection_property_notify (GtkWidget *widget,
GdkEventProperty *event);
-GtkSelectioData *gtk_selection_data_copy (GtkSelectionData *data);
-void gtk_selection_data_free (GtkSelectionData *data);
+GtkSelectionData *gtk_selection_data_copy (GtkSelectionData *data);
+void gtk_selection_data_free (GtkSelectionData *data);
diff --git a/gtk/gtktextbtree.c b/gtk/gtktextbtree.c
index b73ba456c6..8654c29235 100644
--- a/gtk/gtktextbtree.c
+++ b/gtk/gtktextbtree.c
@@ -2435,13 +2435,13 @@ ensure_not_off_end (GtkTextBTree *tree,
}
static GtkTextLineSegment*
-real_set_mark (GtkTextBTree *tree,
- GtkTextMark *existing_mark,
- const gchar *name,
- gboolean left_gravity,
+real_set_mark (GtkTextBTree *tree,
+ GtkTextMark *existing_mark,
+ const gchar *name,
+ gboolean left_gravity,
const GtkTextIter *where,
- gboolean should_exist,
- gboolean redraw_selections)
+ gboolean should_exist,
+ gboolean redraw_selections)
{
GtkTextLineSegment *mark;
GtkTextIter iter;
@@ -2465,10 +2465,14 @@ real_set_mark (GtkTextBTree *tree,
}
/* OK if !should_exist and it does already exist, in that case
- we just move it. */
-
+ * we just move it.
+ */
+
iter = *where;
+ if (gtk_debug_flags & GTK_DEBUG_TEXT)
+ gtk_text_iter_check (&iter);
+
if (mark != NULL)
{
if (redraw_selections &&
@@ -2519,6 +2523,9 @@ real_set_mark (GtkTextBTree *tree,
mark);
}
+ if (gtk_debug_flags & GTK_DEBUG_TEXT)
+ gtk_text_iter_check (&iter);
+
/* Link mark into new location */
gtk_text_btree_link_segment (mark, &iter);
@@ -2531,6 +2538,12 @@ real_set_mark (GtkTextBTree *tree,
redisplay_mark_if_visible (mark);
+ if (gtk_debug_flags & GTK_DEBUG_TEXT)
+ gtk_text_iter_check (&iter);
+
+ if (gtk_debug_flags & GTK_DEBUG_TEXT)
+ gtk_text_btree_check (tree);
+
return mark;
}
@@ -3716,7 +3729,8 @@ gtk_text_line_byte_to_char_offsets (GtkTextLine *line,
g_assert (seg->char_count > 0); /* indexable. */
/* offset is now the number of bytes into the current segment we
- want to go. Count chars into the current segment. */
+ * want to go. Count chars into the current segment.
+ */
if (seg->type == &gtk_text_char_type)
{
diff --git a/gtk/gtktextbuffer.c b/gtk/gtktextbuffer.c
index c3fcf25e17..b48629e667 100644
--- a/gtk/gtktextbuffer.c
+++ b/gtk/gtktextbuffer.c
@@ -43,6 +43,7 @@ struct _ClipboardRequest
gboolean interactive;
gboolean default_editable;
gboolean is_clipboard;
+ gboolean replace_selection;
};
enum {
@@ -66,7 +67,8 @@ enum {
TARGET_STRING,
TARGET_TEXT,
TARGET_COMPOUND_TEXT,
- TARGET_UTF8_STRING
+ TARGET_UTF8_STRING,
+ TARGET_TEXT_BUFFER_CONTENTS
};
static void gtk_text_buffer_init (GtkTextBuffer *tkxt_buffer);
@@ -494,6 +496,10 @@ gtk_text_buffer_insert_at_cursor (GtkTextBuffer *buffer,
* want to prevent insertions at ineditable locations if the insertion
* results from a user action (is interactive).
*
+ * @default_editable indicates the editability of text that doesn't
+ * have a tag affecting editability applied to it. Typically the
+ * result of gtk_text_view_get_editable() is appropriate here.
+ *
* Return value: whether text was actually inserted
**/
gboolean
@@ -525,6 +531,10 @@ gtk_text_buffer_insert_interactive (GtkTextBuffer *buffer,
* Calls gtk_text_buffer_insert_interactive () at the cursor
* position.
*
+ * @default_editable indicates the editability of text that doesn't
+ * have a tag affecting editability applied to it. Typically the
+ * result of gtk_text_view_get_editable() is appropriate here.
+ *
* Return value: whether text was actually inserted
**/
gboolean
@@ -546,6 +556,301 @@ gtk_text_buffer_insert_interactive_at_cursor (GtkTextBuffer *buffer,
default_editable);
}
+static gboolean
+possibly_not_text (gunichar ch,
+ gpointer user_data)
+{
+ return ch == 0xFFFD;
+}
+
+static void
+insert_text_range (GtkTextBuffer *buffer,
+ GtkTextIter *iter,
+ const GtkTextIter *orig_start,
+ const GtkTextIter *orig_end,
+ gboolean interactive)
+{
+ gchar *text;
+
+ text = gtk_text_iter_get_text (orig_start, orig_end);
+
+ gtk_text_buffer_emit_insert (buffer, iter, text, -1, interactive);
+
+ g_free (text);
+}
+
+typedef struct _Range Range;
+struct _Range
+{
+ GtkTextBuffer *buffer;
+ GtkTextMark *start_mark;
+ GtkTextMark *end_mark;
+ GtkTextMark *whole_end_mark;
+ GtkTextIter *range_start;
+ GtkTextIter *range_end;
+ GtkTextIter *whole_end;
+};
+
+static Range*
+save_range (GtkTextIter *range_start,
+ GtkTextIter *range_end,
+ GtkTextIter *whole_end)
+{
+ Range *r;
+
+ r = g_new (Range, 1);
+
+ r->buffer = gtk_text_iter_get_buffer (range_start);
+ g_object_ref (G_OBJECT (r->buffer));
+
+ r->start_mark =
+ gtk_text_buffer_create_mark (gtk_text_iter_get_buffer (range_start),
+ NULL,
+ range_start,
+ TRUE);
+ r->end_mark =
+ gtk_text_buffer_create_mark (gtk_text_iter_get_buffer (range_start),
+ NULL,
+ range_end,
+ FALSE);
+
+ r->whole_end_mark =
+ gtk_text_buffer_create_mark (gtk_text_iter_get_buffer (range_start),
+ NULL,
+ whole_end,
+ FALSE);
+
+ r->range_start = range_start;
+ r->range_end = range_end;
+ r->whole_end = whole_end;
+
+ return r;
+}
+
+static void
+restore_range (Range *r)
+{
+ gtk_text_buffer_get_iter_at_mark (r->buffer,
+ r->range_start,
+ r->start_mark);
+
+ gtk_text_buffer_get_iter_at_mark (r->buffer,
+ r->range_end,
+ r->end_mark);
+
+ gtk_text_buffer_get_iter_at_mark (r->buffer,
+ r->whole_end,
+ r->whole_end_mark);
+
+ gtk_text_buffer_delete_mark (r->buffer, r->start_mark);
+ gtk_text_buffer_delete_mark (r->buffer, r->end_mark);
+ gtk_text_buffer_delete_mark (r->buffer, r->whole_end_mark);
+
+ g_object_unref (G_OBJECT (r->buffer));
+ g_free (r);
+}
+
+static void
+insert_range_untagged (GtkTextBuffer *buffer,
+ GtkTextIter *iter,
+ const GtkTextIter *orig_start,
+ const GtkTextIter *orig_end,
+ gboolean interactive)
+{
+ GtkTextIter range_start;
+ GtkTextIter range_end;
+ GtkTextIter start, end;
+ GtkTextBuffer *src_buffer;
+ Range *r;
+
+ if (gtk_text_iter_equal (orig_start, orig_end))
+ return;
+
+ start = *orig_start;
+ end = *orig_end;
+
+ src_buffer = gtk_text_iter_get_buffer (&start);
+
+ range_start = start;
+ range_end = start;
+
+ while (TRUE)
+ {
+ if (gtk_text_iter_equal (&range_start, &range_end))
+ {
+ /* Figure out how to move forward */
+
+ g_assert (gtk_text_iter_compare (&range_end, &end) <= 0);
+
+ if (gtk_text_iter_equal (&range_end, &end))
+ {
+ /* nothing left to do */
+ break;
+ }
+ else if (gtk_text_iter_get_char (&range_end) == 0xFFFD)
+ {
+ GdkPixbuf *pixbuf = NULL;
+ GtkTextChildAnchor *anchor = NULL;
+ pixbuf = gtk_text_iter_get_pixbuf (&range_end);
+ anchor = gtk_text_iter_get_child_anchor (&range_end);
+
+ if (pixbuf)
+ {
+ r = save_range (&range_start,
+ &range_end,
+ &end);
+
+ gtk_text_buffer_insert_pixbuf (buffer,
+ iter,
+ pixbuf);
+
+ restore_range (r);
+ r = NULL;
+
+ gtk_text_iter_next_char (&range_end);
+
+ range_start = range_end;
+ }
+ else if (anchor)
+ {
+ /* Just skip anchors */
+
+ gtk_text_iter_next_char (&range_end);
+ range_start = range_end;
+ }
+ else
+ {
+ /* The 0xFFFD was in a text segment, so
+ * keep going.
+ */
+ gtk_text_iter_forward_find_char (&range_end,
+ possibly_not_text, NULL,
+ &end);
+
+ g_assert (gtk_text_iter_compare (&range_end, &end) <= 0);
+ }
+ }
+ else
+ {
+ /* Text segment starts here, so forward search to
+ * find its possible endpoint
+ */
+ gtk_text_iter_forward_find_char (&range_end,
+ possibly_not_text, NULL,
+ &end);
+
+ g_assert (gtk_text_iter_compare (&range_end, &end) <= 0);
+ }
+ }
+ else
+ {
+ r = save_range (&range_start,
+ &range_end,
+ &end);
+
+ insert_text_range (buffer,
+ iter,
+ &range_start,
+ &range_end,
+ interactive);
+
+ restore_range (r);
+ r = NULL;
+
+ range_start = range_end;
+ }
+ }
+}
+
+static void
+gtk_text_buffer_real_insert_range (GtkTextBuffer *buffer,
+ GtkTextIter *iter,
+ const GtkTextIter *orig_start,
+ const GtkTextIter *orig_end,
+ gboolean interactive)
+{
+ /* Find each range of uniformly-tagged text, insert it,
+ * then apply the tags.
+ */
+ GtkTextIter start = *orig_start;
+ GtkTextIter end = *orig_end;
+ GtkTextIter range_start;
+ GtkTextIter range_end;
+ GtkTextBuffer *src_buffer;
+ Range *r;
+
+ if (gtk_text_iter_equal (orig_start, orig_end))
+ return;
+
+ src_buffer = gtk_text_iter_get_buffer (orig_start);
+
+ gtk_text_iter_reorder (&start, &end);
+
+ range_start = start;
+ range_end = start;
+
+ while (TRUE)
+ {
+ gint start_offset;
+ GtkTextIter start_iter;
+ GSList *tags;
+ GSList *tmp_list;
+
+ gtk_text_iter_spew (&range_start, "range_start");
+ gtk_text_iter_spew (&range_end, "range_end");
+ gtk_text_iter_spew (&end, "end");
+
+ if (gtk_text_iter_equal (&range_start, &end))
+ break; /* All done */
+
+ g_assert (gtk_text_iter_compare (&range_start, &end) < 0);
+
+ gtk_text_iter_forward_to_tag_toggle (&range_end, NULL);
+
+ g_assert (!gtk_text_iter_equal (&range_start, &range_end));
+
+ /* Clamp to the end iterator */
+ if (gtk_text_iter_compare (&range_end, &end) > 0)
+ range_end = end;
+
+ /* We have a range with unique tags; insert it, and
+ * apply all tags.
+ */
+ start_offset = gtk_text_iter_get_offset (iter);
+
+ r = save_range (&range_start, &range_end, &end);
+
+ printf ("Source range is %d to %d\n",
+ gtk_text_iter_get_offset (&range_start),
+ gtk_text_iter_get_offset (&range_end));
+
+ insert_range_untagged (buffer, iter, &range_start, &range_end, interactive);
+
+ restore_range (r);
+ r = NULL;
+
+ gtk_text_buffer_get_iter_at_offset (buffer, &start_iter, start_offset);
+
+ printf ("Dest range is %d to %d\n",
+ gtk_text_iter_get_offset (&start_iter),
+ gtk_text_iter_get_offset (iter));
+
+ tags = gtk_text_iter_get_tags (&range_start);
+ tmp_list = tags;
+ while (tmp_list != NULL)
+ {
+ gtk_text_buffer_apply_tag (buffer,
+ tmp_list->data,
+ &start_iter,
+ iter);
+
+ tmp_list = g_slist_next (tmp_list);
+ }
+ g_slist_free (tags);
+
+ range_start = range_end;
+ }
+}
/**
* gtk_text_buffer_insert_range:
@@ -576,11 +881,27 @@ gtk_text_buffer_insert_range (GtkTextBuffer *buffer,
g_return_if_fail (gtk_text_iter_get_buffer (start) !=
gtk_text_iter_get_buffer (end));
g_return_if_fail (gtk_text_iter_get_buffer (start)->tag_table !=
- buffer->tag_table);
+ buffer->tag_table);
- /* FIXME */
+ gtk_text_buffer_real_insert_range (buffer, iter, start, end, FALSE);
}
+/**
+ * gtk_text_buffer_insert_range_interactive:
+ * @buffer: a #GtkTextBuffer
+ * @iter: a position in @buffer
+ * @start: a position in a #GtkTextBuffer
+ * @end: another position in the same buffer as @start
+ * @default_editable: default editability of the buffer
+ *
+ * Same as gtk_text_buffer_insert_range(), but does nothing if the
+ * insertion point isn't editable. The @default_editable parameter
+ * indicates whether the text is editable at @iter if no tags
+ * enclosing @iter affect editability. Typically the result of
+ * gtk_text_view_get_editable() is appropriate here.
+ *
+ * Returns: whether an insertion was possible at @iter
+ **/
gboolean
gtk_text_buffer_insert_range_interactive (GtkTextBuffer *buffer,
GtkTextIter *iter,
@@ -598,9 +919,13 @@ gtk_text_buffer_insert_range_interactive (GtkTextBuffer *buffer,
buffer->tag_table, FALSE);
- /* FIXME */
-
- return FALSE;
+ if (gtk_text_iter_editable (iter, default_editable))
+ {
+ gtk_text_buffer_real_insert_range (buffer, iter, start, end, TRUE);
+ return TRUE;
+ }
+ else
+ return FALSE;
}
/**
@@ -981,7 +1306,9 @@ gtk_text_buffer_get_text (GtkTextBuffer *buffer,
* embedded images, so byte and character indexes into
* the returned string <emphasis>do</emphasis> correspond to byte
* and character indexes into the buffer. Contrast with
- * gtk_text_buffer_get_text ().
+ * gtk_text_buffer_get_text (). Note that 0xFFFD can occur in normal
+ * text as well, so it is not a reliable indicator that a pixbuf or
+ * widget is in the buffer.
*
* Return value: an allocated UTF-8 string
**/
@@ -1707,38 +2034,6 @@ gtk_text_buffer_get_char_count (GtkTextBuffer *buffer)
return gtk_text_btree_char_count (get_btree (buffer));
}
-GSList*
-gtk_text_buffer_get_tags (GtkTextBuffer *buffer,
- const GtkTextIter *iter)
-{
- GSList *retval = NULL;
- GtkTextTag** tags;
- gint count = 0;
-
- tags = gtk_text_btree_get_tags (iter, &count);
-
- if (count > 0)
- {
- gint i;
-
- gtk_text_tag_array_sort (tags, count);
-
- i = 0;
- while (i < count)
- {
- retval = g_slist_prepend (retval, tags[i]);
- ++i;
- }
-
- retval = g_slist_reverse (retval);
- }
-
- if (tags)
- g_free (tags);
-
- return retval;
-}
-
/* Called when we lose the primary selection.
*/
static void
@@ -1771,89 +2066,110 @@ clipboard_get_cb (GtkClipboard *clipboard,
gpointer data)
{
GtkTextBuffer *buffer = GTK_TEXT_BUFFER (data);
- gchar *str;
GtkTextIter start, end;
if (gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
{
- /* Extract the selected text */
- str = gtk_text_iter_get_visible_text (&start, &end);
- gtk_selection_data_set_text (selection_data, str);
- g_free (str);
+ if (selection_data->target ==
+ gdk_atom_intern ("GTK_TEXT_BUFFER_CONTENTS", FALSE))
+ {
+ /* Provide the address of the buffer; this will only be
+ * used within-process
+ */
+ gtk_selection_data_set (selection_data,
+ gdk_atom_intern ("GTK_TEXT_BUFFER_CONTENTS", FALSE),
+ 8, /* bytes */
+ (void*)&buffer,
+ sizeof (buffer));
+ }
+ else
+ {
+ gchar *str;
+
+ str = gtk_text_iter_get_visible_text (&start, &end);
+ gtk_selection_data_set_text (selection_data, str);
+ g_free (str);
+ }
}
}
-/* Called when we request a paste and receive the data
- */
static void
-clipboard_received (GtkClipboard *clipboard,
- const gchar *str,
- gpointer data)
+get_paste_point (GtkTextBuffer *buffer,
+ GtkTextIter *iter,
+ gboolean clear_afterward)
{
- ClipboardRequest *request_data = data;
- GtkTextBuffer *buffer = request_data->buffer;
+ GtkTextIter insert_point;
+ GtkTextMark *paste_point_override;
- if (str)
- {
- gboolean reselect;
- GtkTextIter insert_point;
- GtkTextMark *paste_point_override;
+ paste_point_override = gtk_text_buffer_get_mark (buffer,
+ "gtk_paste_point_override");
- paste_point_override = gtk_text_buffer_get_mark (buffer,
- "gtk_paste_point_override");
+ if (paste_point_override != NULL)
+ {
+ gtk_text_buffer_get_iter_at_mark (buffer, &insert_point,
+ paste_point_override);
+ if (clear_afterward)
+ gtk_text_buffer_delete_mark (buffer,
+ gtk_text_buffer_get_mark (buffer,
+ "gtk_paste_point_override"));
+ }
+ else
+ {
+ gtk_text_buffer_get_iter_at_mark (buffer, &insert_point,
+ gtk_text_buffer_get_mark (buffer,
+ "insert"));
+ }
- if (paste_point_override != NULL)
- {
- gtk_text_buffer_get_iter_at_mark (buffer, &insert_point,
- paste_point_override);
- gtk_text_buffer_delete_mark (buffer,
- gtk_text_buffer_get_mark (buffer,
- "gtk_paste_point_override"));
- }
- else
- {
- gtk_text_buffer_get_iter_at_mark (buffer, &insert_point,
- gtk_text_buffer_get_mark (buffer,
- "insert"));
- }
+ *iter = insert_point;
+}
- reselect = FALSE;
+static void
+pre_paste_prep (ClipboardRequest *request_data,
+ GtkTextIter *insert_point)
+{
+ GtkTextBuffer *buffer = request_data->buffer;
- /* FIXME ALL OF THIS - I think that the "best method" is that when pasting
- * with the cursor inside the selection area, you 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.
- *
- * This probably is best implemented as a "replace_selection" flag in
- * ClipboardRequest.
- */
-#if 0
- if ((TRUE/* Text is selected FIXME */) &&
- (!buffer->have_selection || request_data->is_clipboard))
+ if (request_data->replace_selection)
+ {
+ GtkTextIter start, end;
+
+ if (gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
{
- reselect = TRUE;
-
- if (buffer->have_selection)
- {
- /* FIXME Delete currently-selected chars but don't give up X
- selection since we'll use the newly-pasted stuff as
- a new X selection */
-
- }
+ if (request_data->interactive)
+ gtk_text_buffer_delete_interactive (buffer,
+ &start,
+ &end,
+ request_data->default_editable);
else
- ; /* FIXME Delete selected chars and give up X selection */
+ gtk_text_buffer_delete (buffer, &start, &end);
}
-#endif
+ }
+
+ get_paste_point (buffer, insert_point, TRUE);
+}
+
+/* Called when we request a paste and receive the text data
+ */
+static void
+clipboard_text_received (GtkClipboard *clipboard,
+ const gchar *str,
+ gpointer data)
+{
+ ClipboardRequest *request_data = data;
+ GtkTextBuffer *buffer = request_data->buffer;
+ if (str)
+ {
+ GtkTextIter insert_point;
+
+ pre_paste_prep (request_data, &insert_point);
+
if (request_data->interactive)
gtk_text_buffer_insert_interactive (buffer, &insert_point,
str, -1, request_data->default_editable);
else
gtk_text_buffer_insert (buffer, &insert_point,
str, -1);
-
- if (reselect)
- ; /* FIXME Select the region of text we just inserted */
}
g_object_unref (G_OBJECT (buffer));
@@ -1861,13 +2177,74 @@ clipboard_received (GtkClipboard *clipboard,
}
static void
+clipboard_buffer_received (GtkClipboard *clipboard,
+ GtkSelectionData *selection_data,
+ gpointer data)
+{
+ ClipboardRequest *request_data = data;
+ GtkTextBuffer *buffer = request_data->buffer;
+ GdkWindow *owner;
+ GtkTextBuffer *src_buffer = NULL;
+ GtkTextIter src_start, src_end;
+ GtkTextIter insert_point;
+
+ /* If we can get the owner, the selection is in-process */
+ owner = gdk_selection_owner_get (selection_data->selection);
+
+ if (owner == NULL)
+ goto try_another_target;
+
+ if (selection_data->type != gdk_atom_intern ("GTK_TEXT_BUFFER_CONTENTS", FALSE))
+ goto try_another_target;
+
+ if (selection_data->length != sizeof (src_buffer))
+ return;
+
+ memcpy (&src_buffer, selection_data->data, sizeof (src_buffer));
+
+ g_return_if_fail (GTK_IS_TEXT_BUFFER (src_buffer));
+
+ if (gtk_text_buffer_get_tag_table (src_buffer) !=
+ gtk_text_buffer_get_tag_table (buffer))
+ goto try_another_target;
+
+ /* We're about to emit a bunch of signals, so be safe */
+ g_object_ref (G_OBJECT (src_buffer));
+
+ pre_paste_prep (request_data, &insert_point);
+
+ if (gtk_text_buffer_get_selection_bounds (src_buffer,
+ &src_start,
+ &src_end))
+ {
+ gtk_text_buffer_real_insert_range (buffer,
+ &insert_point,
+ &src_start,
+ &src_end,
+ request_data->interactive);
+ }
+
+ g_object_unref (G_OBJECT (src_buffer));
+
+ return;
+
+ try_another_target:
+
+ /* Request the text selection instead */
+ gtk_clipboard_request_text (clipboard,
+ clipboard_text_received,
+ data);
+}
+
+static void
gtk_text_buffer_update_primary_selection (GtkTextBuffer *buffer)
{
static const GtkTargetEntry targets[] = {
{ "STRING", 0, TARGET_STRING },
{ "TEXT", 0, TARGET_TEXT },
{ "COMPOUND_TEXT", 0, TARGET_COMPOUND_TEXT },
- { "UTF8_STRING", 0, TARGET_UTF8_STRING }
+ { "UTF8_STRING", 0, TARGET_UTF8_STRING },
+ { "GTK_TEXT_BUFFER_CONTENTS", 0, TARGET_TEXT_BUFFER_CONTENTS }
};
GtkTextIter start;
@@ -1897,25 +2274,42 @@ gtk_text_buffer_update_primary_selection (GtkTextBuffer *buffer)
static void
paste (GtkTextBuffer *buffer,
- gboolean is_clipboard,
- gboolean interactive,
- gboolean default_editable)
+ gboolean is_clipboard,
+ gboolean interactive,
+ gboolean default_editable)
{
ClipboardRequest *data = g_new (ClipboardRequest, 1);
-
+ GtkTextIter paste_point;
+ GtkTextIter start, end;
+
data->buffer = buffer;
g_object_ref (G_OBJECT (buffer));
data->interactive = interactive;
data->default_editable = default_editable;
- gtk_clipboard_request_text (gtk_clipboard_get (is_clipboard ? GDK_NONE : GDK_SELECTION_PRIMARY),
- clipboard_received, data);
+ /* When pasting with the cursor inside the selection area, you
+ * 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.
+ */
+ 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))
+ data->replace_selection = TRUE;
+
+ gtk_clipboard_request_contents (gtk_clipboard_get (is_clipboard ? GDK_NONE : GDK_SELECTION_PRIMARY),
+
+ gdk_atom_intern ("GTK_TEXT_BUFFER_CONTENTS", FALSE),
+ clipboard_buffer_received, data);
}
void
-gtk_text_buffer_paste_primary (GtkTextBuffer *buffer,
- GtkTextIter *override_location,
- gboolean default_editable)
+gtk_text_buffer_paste_primary (GtkTextBuffer *buffer,
+ const GtkTextIter *override_location,
+ gboolean default_editable)
{
if (override_location != NULL)
gtk_text_buffer_create_mark (buffer,
@@ -1962,11 +2356,12 @@ cut_or_copy (GtkTextBuffer *buffer,
gboolean default_editable)
{
/* We prefer to cut the selected region between selection_bound and
- insertion point. If that region is empty, then we cut the region
- between the "anchor" and the insertion point (this is for C-space
- and M-w and other Emacs-style copy/yank keys). Note that insert
- and selection_bound are guaranteed to exist, but the anchor only
- exists sometimes. */
+ * insertion point. If that region is empty, then we cut the region
+ * between the "anchor" and the insertion point (this is for
+ * C-space and M-w and other Emacs-style copy/yank keys). Note that
+ * insert and selection_bound are guaranteed to exist, but the
+ * anchor only exists sometimes.
+ */
GtkTextIter start;
GtkTextIter end;
diff --git a/gtk/gtktextbuffer.h b/gtk/gtktextbuffer.h
index c1b5fcdd58..54844e1465 100644
--- a/gtk/gtktextbuffer.h
+++ b/gtk/gtktextbuffer.h
@@ -283,10 +283,6 @@ void gtk_text_buffer_get_iter_at_child_anchor (GtkTextBuffer *buffer,
/* There's no get_first_iter because you just get the iter for
line or char 0 */
-GSList *gtk_text_buffer_get_tags (GtkTextBuffer *buffer,
- const GtkTextIter *iter);
-
-
/* Used to keep track of whether the buffer needs saving; anytime the
buffer contents change, the modified flag is turned on. Whenever
you save, turn it off. Tags and marks do not affect the modified
@@ -297,9 +293,9 @@ gboolean gtk_text_buffer_modified (GtkTextBuffer *buffer);
void gtk_text_buffer_set_modified (GtkTextBuffer *buffer,
gboolean setting);
-void gtk_text_buffer_paste_primary (GtkTextBuffer *buffer,
- GtkTextIter *override_location,
- gboolean default_editable);
+void gtk_text_buffer_paste_primary (GtkTextBuffer *buffer,
+ const GtkTextIter *override_location,
+ gboolean default_editable);
void gtk_text_buffer_cut_clipboard (GtkTextBuffer *buffer,
gboolean default_editable);
void gtk_text_buffer_copy_clipboard (GtkTextBuffer *buffer);
diff --git a/gtk/gtktextiter.c b/gtk/gtktextiter.c
index e57855551a..f7713d3099 100644
--- a/gtk/gtktextiter.c
+++ b/gtk/gtktextiter.c
@@ -580,11 +580,14 @@ gtk_text_iter_get_offset (const GtkTextIter *iter)
if (real == NULL)
return 0;
+ check_invariants (iter);
+
if (real->cached_char_index < 0)
{
+ ensure_char_offsets (real);
+
real->cached_char_index =
gtk_text_line_char_index (real->line);
- ensure_char_offsets (real);
real->cached_char_index += real->line_char_offset;
}
@@ -722,7 +725,7 @@ gtk_text_iter_get_char (const GtkTextIter *iter)
else if (real->segment->type == &gtk_text_char_type)
{
ensure_byte_offsets (real);
-
+
return g_utf8_get_char (real->segment->body.chars +
real->segment_byte_offset);
}
@@ -743,7 +746,9 @@ gtk_text_iter_get_char (const GtkTextIter *iter)
* character 0xFFFD for iterable non-character elements in the buffer,
* such as images. Because images are encoded in the slice, byte and
* character offsets in the returned array will correspond to byte
- * offsets in the text buffer.
+ * offsets in the text buffer. Note that 0xFFFD can occur in normal
+ * text as well, so it is not a reliable indicator that a pixbuf or
+ * widget is in the buffer.
*
* Return value: slice of text from the buffer
**/
@@ -1170,6 +1175,56 @@ gtk_text_iter_has_tag (const GtkTextIter *iter,
}
/**
+ * gtk_text_iter_get_tags:
+ * @iter: a #GtkTextIter
+ *
+ * Returns a list of tags that apply to @iter, in ascending order of
+ * priority (highest-priority tags are last). The #GtkTextTag in the
+ * list don't have a reference added, but you have to free the list
+ * itself.
+ *
+ * Return value: list of #GtkTextTag
+ **/
+GSList*
+gtk_text_iter_get_tags (const GtkTextIter *iter)
+{
+ GtkTextTag** tags;
+ gint tag_count = 0;
+ gint i;
+ GSList *retval;
+
+ g_return_val_if_fail (iter != NULL, NULL);
+
+ /* Get the tags at this spot */
+ tags = gtk_text_btree_get_tags (iter, &tag_count);
+
+ /* No tags, use default style */
+ if (tags == NULL || tag_count == 0)
+ {
+ if (tags)
+ g_free (tags);
+
+ return NULL;
+ }
+
+ /* Sort tags in ascending order of priority */
+ gtk_text_tag_array_sort (tags, tag_count);
+
+ retval = NULL;
+ i = 0;
+ while (i < tag_count)
+ {
+ retval = g_slist_prepend (retval, tags[i]);
+ ++i;
+ }
+
+ g_free (tags);
+
+ /* Return tags in ascending order of priority */
+ return g_slist_reverse (retval);
+}
+
+/**
* gtk_text_iter_editable:
* @iter: an iterator
* @default_setting: TRUE if text is editable by default
@@ -2654,7 +2709,9 @@ gtk_text_iter_forward_to_newline (GtkTextIter *iter)
* #GtkTextTag @tag, or to the next toggle of any tag if
* @tag is NULL. If no matching tag toggles are found,
* returns FALSE, otherwise TRUE. Does not return toggles
- * located at @iter, only toggles after @iter.
+ * located at @iter, only toggles after @iter. Sets @iter to
+ * the location of the toggle, or to the end of the buffer
+ * if no toggle is found.
*
* Return value: whether we found a tag toggle after @iter
**/
@@ -2734,7 +2791,9 @@ gtk_text_iter_forward_to_tag_toggle (GtkTextIter *iter,
* #GtkTextTag @tag, or to the next toggle of any tag if
* @tag is NULL. If no matching tag toggles are found,
* returns FALSE, otherwise TRUE. Does not return toggles
- * located at @iter, only toggles before @iter.
+ * located at @iter, only toggles before @iter. Sets @iter
+ * to the location of the toggle, or the start of the buffer
+ * if no toggle is found.
*
* Return value: whether we found a tag toggle before @iter
**/
@@ -2836,16 +2895,37 @@ matches_pred (GtkTextIter *iter,
return (*pred) (ch, user_data);
}
+/**
+ * gtk_text_iter_forward_find_char:
+ * @iter: a #GtkTextIter
+ * @pred: a function to be called on each character
+ * @user_data: user data for @pred
+ * @limit: search limit, or %NULL for none
+ *
+ * Advances @iter, calling @pred on each character. If
+ * @pred returns %TRUE, returns %TRUE and stops scanning.
+ * If @pred never returns %TRUE, @iter is set to @limit if
+ * @limit is non-%NULL, otherwise to the end iterator.
+ *
+ * Return value: whether a match was found
+ **/
gboolean
-gtk_text_iter_forward_find_char (GtkTextIter *iter,
+gtk_text_iter_forward_find_char (GtkTextIter *iter,
GtkTextCharPredicate pred,
- gpointer user_data)
+ gpointer user_data,
+ const GtkTextIter *limit)
{
g_return_val_if_fail (iter != NULL, FALSE);
g_return_val_if_fail (pred != NULL, FALSE);
- while (gtk_text_iter_next_char (iter))
- {
+ if (limit &&
+ gtk_text_iter_compare (iter, limit) >= 0)
+ return FALSE;
+
+ while ((limit == NULL ||
+ !gtk_text_iter_equal (limit, iter)) &&
+ gtk_text_iter_next_char (iter))
+ {
if (matches_pred (iter, pred, user_data))
return TRUE;
}
@@ -2854,14 +2934,21 @@ gtk_text_iter_forward_find_char (GtkTextIter *iter,
}
gboolean
-gtk_text_iter_backward_find_char (GtkTextIter *iter,
+gtk_text_iter_backward_find_char (GtkTextIter *iter,
GtkTextCharPredicate pred,
- gpointer user_data)
+ gpointer user_data,
+ const GtkTextIter *limit)
{
g_return_val_if_fail (iter != NULL, FALSE);
g_return_val_if_fail (pred != NULL, FALSE);
- while (gtk_text_iter_prev_char (iter))
+ if (limit &&
+ gtk_text_iter_compare (iter, limit) <= 0)
+ return FALSE;
+
+ while ((limit == NULL ||
+ !gtk_text_iter_equal (limit, iter)) &&
+ gtk_text_iter_prev_char (iter))
{
if (matches_pred (iter, pred, user_data))
return TRUE;
@@ -3060,13 +3147,28 @@ strbreakup (const char *string,
return str_array;
}
+/**
+ * gtk_text_iter_forward_search:
+ * @iter: start of search
+ * @str: a search string
+ * @visible_only: if %TRUE, search only visible text
+ * @slice: if %TRUE, @str contains 0xFFFD when we want to match widgets, pixbufs
+ * @match_start: return location for start of match, or %NULL
+ * @match_end: return location for end of match, or %NULL
+ * @limit: bound for the search, or %NULL for the end of the buffer
+ *
+ *
+ *
+ * Return value: whether a match was found
+ **/
gboolean
gtk_text_iter_forward_search (const GtkTextIter *iter,
const gchar *str,
gboolean visible_only,
gboolean slice,
GtkTextIter *match_start,
- GtkTextIter *match_end)
+ GtkTextIter *match_end,
+ const GtkTextIter *limit)
{
gchar **lines = NULL;
GtkTextIter match;
@@ -3076,12 +3178,21 @@ gtk_text_iter_forward_search (const GtkTextIter *iter,
g_return_val_if_fail (iter != NULL, FALSE);
g_return_val_if_fail (str != NULL, FALSE);
+ if (limit &&
+ gtk_text_iter_compare (iter, limit) >= 0)
+ return FALSE;
+
if (*str == '\0')
{
/* If we can move one char, return the empty string there */
match = *iter;
+
if (gtk_text_iter_next_char (&match))
{
+ if (limit &&
+ gtk_text_iter_equal (&match, limit))
+ return FALSE;
+
if (match_start)
*match_start = match;
if (match_end)
@@ -3106,17 +3217,26 @@ gtk_text_iter_forward_search (const GtkTextIter *iter,
*/
GtkTextIter end;
+ if (limit &&
+ gtk_text_iter_compare (&search, limit) >= 0)
+ break;
+
if (lines_match (&search, (const gchar**)lines,
visible_only, slice, &match, &end))
{
- retval = TRUE;
-
- if (match_start)
- *match_start = match;
-
- if (match_end)
- *match_end = end;
-
+ if (limit == NULL ||
+ (limit &&
+ gtk_text_iter_compare (&end, limit) < 0))
+ {
+ retval = TRUE;
+
+ if (match_start)
+ *match_start = match;
+
+ if (match_end)
+ *match_end = end;
+ }
+
break;
}
}
@@ -3345,13 +3465,28 @@ my_strrstr (const gchar *haystack,
return NULL;
}
+/**
+ * gtk_text_iter_backward_search:
+ * @iter: a #GtkTextIter where the search begins
+ * @str: search string
+ * @visible_only: if %TRUE search only visible text
+ * @slice: if %TRUE the search string contains 0xFFFD to match pixbufs, widgets
+ * @match_start: return location for start of match, or %NULL
+ * @match_end: return location for end of match, or %NULL
+ * @limit: location of last possible @match_start, or %NULL for start of buffer
+ *
+ *
+ *
+ * Return value: whether a match was found
+ **/
gboolean
gtk_text_iter_backward_search (const GtkTextIter *iter,
const gchar *str,
gboolean visible_only,
gboolean slice,
GtkTextIter *match_start,
- GtkTextIter *match_end)
+ GtkTextIter *match_end,
+ const GtkTextIter *limit)
{
gchar **lines = NULL;
gchar **l;
@@ -3362,11 +3497,18 @@ gtk_text_iter_backward_search (const GtkTextIter *iter,
g_return_val_if_fail (iter != NULL, FALSE);
g_return_val_if_fail (str != NULL, FALSE);
+ if (limit &&
+ gtk_text_iter_compare (limit, iter) > 0)
+ return FALSE;
+
if (*str == '\0')
{
/* If we can move one char, return the empty string there */
GtkTextIter match = *iter;
+ if (limit && gtk_text_iter_equal (limit, &match))
+ return FALSE;
+
if (gtk_text_iter_prev_char (&match))
{
if (match_start)
@@ -3404,6 +3546,13 @@ gtk_text_iter_backward_search (const GtkTextIter *iter,
{
gchar *first_line_match;
+ if (limit &&
+ gtk_text_iter_compare (limit, &win.first_line_end) > 0)
+ {
+ /* We're now before the search limit, abort. */
+ goto out;
+ }
+
/* If there are multiple lines, the first line will
* end in '\n', so this will only match at the
* end of the first line, which is correct.
@@ -3416,17 +3565,22 @@ gtk_text_iter_backward_search (const GtkTextIter *iter,
/* Match! */
gint offset;
GtkTextIter next;
-
+ GtkTextIter start_tmp;
+
/* Offset to start of search string */
offset = g_utf8_strlen (*win.lines, first_line_match - *win.lines);
next = win.first_line_start;
+ start_tmp = next;
+ forward_chars_with_skipping (&start_tmp, offset,
+ visible_only, !slice);
+
+ if (limit &&
+ gtk_text_iter_compare (limit, &start_tmp) > 0)
+ goto out; /* match was bogus */
+
if (match_start)
- {
- *match_start = next;
- forward_chars_with_skipping (match_start, offset,
- visible_only, !slice);
- }
+ *match_start = start_tmp;
/* Go to end of search string */
l = lines;
@@ -3451,7 +3605,7 @@ gtk_text_iter_backward_search (const GtkTextIter *iter,
out:
lines_window_free (&win);
g_strfreev (lines);
-
+
return retval;
}
@@ -3655,7 +3809,7 @@ void
gtk_text_btree_get_iter_at_line (GtkTextBTree *tree,
GtkTextIter *iter,
GtkTextLine *line,
- gint byte_offset)
+ gint byte_offset)
{
g_return_if_fail (iter != NULL);
g_return_if_fail (tree != NULL);
@@ -3822,13 +3976,13 @@ gtk_text_iter_check (const GtkTextIter *iter)
{
const GtkTextRealIter *real = (const GtkTextRealIter*)iter;
gint line_char_offset, line_byte_offset, seg_char_offset, seg_byte_offset;
- GtkTextLineSegment *byte_segment;
- GtkTextLineSegment *byte_any_segment;
- GtkTextLineSegment *char_segment;
- GtkTextLineSegment *char_any_segment;
+ GtkTextLineSegment *byte_segment = NULL;
+ GtkTextLineSegment *byte_any_segment = NULL;
+ GtkTextLineSegment *char_segment = NULL;
+ GtkTextLineSegment *char_any_segment = NULL;
gboolean segments_updated;
- /* We are going to check our class invariants for the Iter class. */
+ /* This function checks our class invariants for the Iter class. */
g_assert (sizeof (GtkTextIter) == sizeof (GtkTextRealIter));
@@ -3891,6 +4045,15 @@ gtk_text_iter_check (const GtkTextIter *iter)
if (seg_byte_offset != real->segment_byte_offset)
g_error ("wrong segment byte offset was stored in iterator");
+
+ if (byte_segment->type == &gtk_text_char_type)
+ {
+ const gchar *p;
+ p = byte_segment->body.chars + seg_byte_offset;
+
+ if (!gtk_text_byte_begins_utf8_char (p))
+ g_error ("broken iterator byte index pointed into the middle of a character");
+ }
}
}
@@ -3904,7 +4067,7 @@ gtk_text_iter_check (const GtkTextIter *iter)
g_error ("wrong char offset was stored in iterator");
if (segments_updated)
- {
+ {
if (real->segment != char_segment)
g_error ("wrong segment was stored in iterator");
@@ -3913,6 +4076,17 @@ gtk_text_iter_check (const GtkTextIter *iter)
if (seg_char_offset != real->segment_char_offset)
g_error ("wrong segment char offset was stored in iterator");
+
+ if (char_segment->type == &gtk_text_char_type)
+ {
+ const gchar *p;
+ p = g_utf8_offset_to_pointer (char_segment->body.chars,
+ seg_char_offset);
+
+ /* hmm, not likely to happen eh */
+ if (!gtk_text_byte_begins_utf8_char (p))
+ g_error ("broken iterator char offset pointed into the middle of a character");
+ }
}
}
@@ -3945,6 +4119,9 @@ gtk_text_iter_check (const GtkTextIter *iter)
if (char_offset != seg_char_offset)
g_error ("char offset did not correspond to byte offset");
+
+ if (!gtk_text_byte_begins_utf8_char (char_segment->body.chars + seg_byte_offset))
+ g_error ("byte index for iterator does not index the start of a character");
}
}
diff --git a/gtk/gtktextiter.h b/gtk/gtktextiter.h
index 3e649d0b40..caadecb2a2 100644
--- a/gtk/gtktextiter.h
+++ b/gtk/gtktextiter.h
@@ -119,6 +119,7 @@ gboolean gtk_text_iter_toggles_tag (const GtkTextIter *iter,
gboolean gtk_text_iter_has_tag (const GtkTextIter *iter,
GtkTextTag *tag);
+GSList *gtk_text_iter_get_tags (const GtkTextIter *iter);
gboolean gtk_text_iter_editable (const GtkTextIter *iter,
gboolean default_setting);
@@ -170,8 +171,9 @@ gboolean gtk_text_iter_forward_to_newline (GtkTextIter *iter);
/* returns TRUE if a toggle was found; NULL for the tag pointer
- means "any tag toggle", otherwise the next toggle of the
- specified tag is located. */
+ * means "any tag toggle", otherwise the next toggle of the
+ * specified tag is located.
+ */
gboolean gtk_text_iter_forward_to_tag_toggle (GtkTextIter *iter,
GtkTextTag *tag);
@@ -180,27 +182,30 @@ gboolean gtk_text_iter_backward_to_tag_toggle (GtkTextIter *iter,
typedef gboolean (* GtkTextCharPredicate) (gunichar ch, gpointer user_data);
-gboolean gtk_text_iter_forward_find_char (GtkTextIter *iter,
- GtkTextCharPredicate pred,
- gpointer user_data);
-
-gboolean gtk_text_iter_backward_find_char (GtkTextIter *iter,
- GtkTextCharPredicate pred,
- gpointer user_data);
+gboolean gtk_text_iter_forward_find_char (GtkTextIter *iter,
+ GtkTextCharPredicate pred,
+ gpointer user_data,
+ const GtkTextIter *limit);
+gboolean gtk_text_iter_backward_find_char (GtkTextIter *iter,
+ GtkTextCharPredicate pred,
+ gpointer user_data,
+ const GtkTextIter *limit);
gboolean gtk_text_iter_forward_search (const GtkTextIter *iter,
const gchar *str,
gboolean visible_only,
gboolean slice,
GtkTextIter *match_start,
- GtkTextIter *match_end);
+ GtkTextIter *match_end,
+ const GtkTextIter *limit);
+
gboolean gtk_text_iter_backward_search (const GtkTextIter *iter,
const gchar *str,
gboolean visible_only,
gboolean slice,
GtkTextIter *match_start,
- GtkTextIter *match_end);
-
+ GtkTextIter *match_end,
+ const GtkTextIter *limit);
/*
diff --git a/gtk/gtktextlayout.c b/gtk/gtktextlayout.c
index cba5557b31..9f84c001ef 100644
--- a/gtk/gtktextlayout.c
+++ b/gtk/gtktextlayout.c
@@ -2235,7 +2235,7 @@ gtk_text_layout_move_iter_to_line_end (GtkTextLayout *layout,
{
gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
iter, line,
- direction < 0 ? byte_offset : layout_line->length);
+ direction < 0 ? byte_offset : byte_offset + layout_line->length);
/* FIXME: Move back one position to avoid going to next line
*/
diff --git a/gtk/gtktextmark.c b/gtk/gtktextmark.c
index 13587007bc..4e20eb300c 100644
--- a/gtk/gtktextmark.c
+++ b/gtk/gtktextmark.c
@@ -128,7 +128,7 @@ gtk_text_mark_finalize (GObject *obj)
}
/**
- * gtk_text_mark_is_visible:
+ * gtk_text_mark_get_visible:
* @mark: a #GtkTextMark
*
* Returns %TRUE if the mark is visible (i.e. a cursor is displayed
@@ -137,7 +137,7 @@ gtk_text_mark_finalize (GObject *obj)
* Return value: %TRUE if visible
**/
gboolean
-gtk_text_mark_is_visible (GtkTextMark *mark)
+gtk_text_mark_get_visible (GtkTextMark *mark)
{
GtkTextLineSegment *seg;
diff --git a/gtk/gtktextmark.h b/gtk/gtktextmark.h
index cdcaeab4bc..e2130c5acd 100644
--- a/gtk/gtktextmark.h
+++ b/gtk/gtktextmark.h
@@ -83,7 +83,7 @@ GType gtk_text_mark_get_type (void) G_GNUC_CONST;
void gtk_text_mark_set_visible (GtkTextMark *mark,
gboolean setting);
-gboolean gtk_text_mark_is_visible (GtkTextMark *mark);
+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);
diff --git a/gtk/gtktextsegment.c b/gtk/gtktextsegment.c
index 66f0a672b9..33d1083317 100644
--- a/gtk/gtktextsegment.c
+++ b/gtk/gtktextsegment.c
@@ -102,6 +102,9 @@ gtk_text_line_segment_split (const GtkTextIter *iter)
count = gtk_text_iter_get_line_index (iter);
+ if (gtk_debug_flags & GTK_DEBUG_TEXT)
+ gtk_text_iter_check (iter);
+
prev = NULL;
seg = line->segments;
diff --git a/gtk/gtktextview.c b/gtk/gtktextview.c
index bc054fb173..1dedcaf068 100644
--- a/gtk/gtktextview.c
+++ b/gtk/gtktextview.c
@@ -2040,14 +2040,14 @@ emit_event_on_tags (GtkWidget *widget,
text_view = GTK_TEXT_VIEW (widget);
- tags = gtk_text_buffer_get_tags (get_buffer (text_view), iter);
+ tags = gtk_text_iter_get_tags (iter);
tmp = tags;
while (tmp != NULL)
{
GtkTextTag *tag = tmp->data;
- if (gtk_text_tag_event (tag, GTK_OBJECT (widget), event, iter))
+ if (gtk_text_tag_event (tag, G_OBJECT (widget), event, iter))
{
retval = TRUE;
break;
@@ -2818,10 +2818,10 @@ find_whitepace_region (const GtkTextIter *center,
*start = *center;
*end = *center;
- if (gtk_text_iter_backward_find_char (start, not_whitespace, NULL))
+ if (gtk_text_iter_backward_find_char (start, not_whitespace, NULL, NULL))
gtk_text_iter_next_char (start); /* we want the first whitespace... */
if (whitespace (gtk_text_iter_get_char (end), NULL))
- gtk_text_iter_forward_find_char (end, not_whitespace, NULL);
+ gtk_text_iter_forward_find_char (end, not_whitespace, NULL, NULL);
return !gtk_text_iter_equal (start, end);
}
diff --git a/gtk/gtkwidget.h b/gtk/gtkwidget.h
index b55a2a1b99..e89c3857ec 100644
--- a/gtk/gtkwidget.h
+++ b/gtk/gtkwidget.h
@@ -141,25 +141,6 @@ struct _GtkRequisition
gint height;
};
-/* The contents of a selection are returned in a GtkSelectionData
- structure. selection/target identify the request.
- type specifies the type of the return; if length < 0, and
- the data should be ignored. This structure has object semantics -
- no fields should be modified directly, they should not be created
- directly, and pointers to them should not be stored beyond the duration of
- a callback. (If the last is changed, we'll need to add reference
- counting.) The time field gives the timestamp at which the data was sent. */
-
-struct _GtkSelectionData
-{
- GdkAtom selection;
- GdkAtom target;
- GdkAtom type;
- gint format;
- guchar *data;
- gint length;
-};
-
/* The widget is the base of the tree for displayable objects.
* (A displayable object is one which takes up some amount
* of screen real estate). It provides a common base and interface
diff --git a/gtk/testtext.c b/gtk/testtext.c
index d62545f7ae..12cfcd0899 100644
--- a/gtk/testtext.c
+++ b/gtk/testtext.c
@@ -1351,7 +1351,8 @@ buffer_search (Buffer *buffer,
if (forward)
{
while (gtk_text_iter_forward_search (&iter, str, TRUE, FALSE,
- &match_start, &match_end))
+ &match_start, &match_end,
+ NULL))
{
++i;
gtk_text_buffer_apply_tag (buffer->buffer, buffer->found_text_tag,
@@ -1363,7 +1364,8 @@ buffer_search (Buffer *buffer,
else
{
while (gtk_text_iter_backward_search (&iter, str, TRUE, FALSE,
- &match_start, &match_end))
+ &match_start, &match_end,
+ NULL))
{
++i;
gtk_text_buffer_apply_tag (buffer->buffer, buffer->found_text_tag,