summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHavoc Pennington <hp@pobox.com>2000-06-02 17:27:21 +0000
committerHavoc Pennington <hp@src.gnome.org>2000-06-02 17:27:21 +0000
commite86329d5d4640805dc46cbf07a920cb932bd54d4 (patch)
tree0d81a57ff3971f3a3f600e9a82ff2af1c63230e6
parentbb77f4e6b934e2ff9dbe99a73a0aad1fbdd921bc (diff)
downloadgtk+-e86329d5d4640805dc46cbf07a920cb932bd54d4.tar.gz
Test program to make sure GtkTextBuffer is in working order.
2000-06-02 Havoc Pennington <hp@pobox.com> * gtk/testtextbuffer.c: Test program to make sure GtkTextBuffer is in working order. * gtk/testtext.c: Change to reflect anonymous mark API * gtk/gtktextview.c: Convert from mark names to GtkTextMark*. * gtk/gtktexttag.h (struct _GtkTextTag): remove the affects_size field, which was unused. * gtk/gtktextmarkprivate.h (GTK_IS_TEXT_MARK): add this macro, saves some typing. * gtk/gtktextbuffer.c: Switch from mark names to GtkTextMark* * gtk/gtktextbtree.c (gtk_text_btree_new): set the not_deleteable flag on the insertion point and selection bound Throughout, use GtkTextMark instead of GtkTextLineSegment, and make mark-manipulation functions take a GtkTextMark* instead of a mark name. * gtk/gtktextmarkprivate.h: Add a "not_deleteable" flag to GtkTextMarkBody; will be used to detect attempts to delete the permanent marks (insert and selection bound)
-rw-r--r--ChangeLog30
-rw-r--r--ChangeLog.pre-2-030
-rw-r--r--ChangeLog.pre-2-1030
-rw-r--r--ChangeLog.pre-2-230
-rw-r--r--ChangeLog.pre-2-430
-rw-r--r--ChangeLog.pre-2-630
-rw-r--r--ChangeLog.pre-2-830
-rw-r--r--gtk/Makefile.am3
-rw-r--r--gtk/gtktextbtree.c100
-rw-r--r--gtk/gtktextbtree.h15
-rw-r--r--gtk/gtktextbuffer.c99
-rw-r--r--gtk/gtktextbuffer.h12
-rw-r--r--gtk/gtktextiter.c16
-rw-r--r--gtk/gtktextlayout.c4
-rw-r--r--gtk/gtktextmark.c1
-rw-r--r--gtk/gtktextmarkprivate.h11
-rw-r--r--gtk/gtktexttag.h5
-rw-r--r--gtk/gtktextview.c135
-rw-r--r--gtk/gtktextview.h4
-rw-r--r--gtk/testtext.c13
-rw-r--r--gtk/testtextbuffer.c393
-rw-r--r--tests/testtext.c13
-rw-r--r--tests/testtextbuffer.c393
23 files changed, 1264 insertions, 163 deletions
diff --git a/ChangeLog b/ChangeLog
index d33cfd8bca..4fd0965fc7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,33 @@
+2000-06-02 Havoc Pennington <hp@pobox.com>
+
+ * gtk/testtextbuffer.c: Test program to make sure GtkTextBuffer
+ is in working order.
+
+ * gtk/testtext.c: Change to reflect anonymous mark API
+
+ * gtk/gtktextview.c: Convert from mark names to GtkTextMark*.
+
+ * gtk/gtktexttag.h (struct _GtkTextTag): remove the affects_size
+ field, which was unused.
+
+ * gtk/gtktextmarkprivate.h (GTK_IS_TEXT_MARK): add this macro,
+ saves some typing.
+
+ * gtk/gtktextbuffer.c: Switch from mark names to GtkTextMark*
+
+ * gtk/gtktextbtree.c (gtk_text_btree_new): set the not_deleteable
+ flag on the insertion point and selection bound
+
+ Throughout, use GtkTextMark instead of GtkTextLineSegment, and
+ make mark-manipulation functions take a GtkTextMark* instead of a
+ mark name.
+
+ * gtk/gtktextmarkprivate.h: Add a "not_deleteable" flag to
+ GtkTextMarkBody; will be used to detect attempts to delete
+ the permanent marks (insert and selection bound)
+
+ * gtk/Makefile.am (noinst_PROGRAMS): add testtextbuffer
+
Fri Jun 2 12:56:01 2000 Owen Taylor <otaylor@redhat.com>
* gtk/gtkwidget.c (gtk_widget_init): Initialize DOUBLE_BUFFERED
diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0
index d33cfd8bca..4fd0965fc7 100644
--- a/ChangeLog.pre-2-0
+++ b/ChangeLog.pre-2-0
@@ -1,3 +1,33 @@
+2000-06-02 Havoc Pennington <hp@pobox.com>
+
+ * gtk/testtextbuffer.c: Test program to make sure GtkTextBuffer
+ is in working order.
+
+ * gtk/testtext.c: Change to reflect anonymous mark API
+
+ * gtk/gtktextview.c: Convert from mark names to GtkTextMark*.
+
+ * gtk/gtktexttag.h (struct _GtkTextTag): remove the affects_size
+ field, which was unused.
+
+ * gtk/gtktextmarkprivate.h (GTK_IS_TEXT_MARK): add this macro,
+ saves some typing.
+
+ * gtk/gtktextbuffer.c: Switch from mark names to GtkTextMark*
+
+ * gtk/gtktextbtree.c (gtk_text_btree_new): set the not_deleteable
+ flag on the insertion point and selection bound
+
+ Throughout, use GtkTextMark instead of GtkTextLineSegment, and
+ make mark-manipulation functions take a GtkTextMark* instead of a
+ mark name.
+
+ * gtk/gtktextmarkprivate.h: Add a "not_deleteable" flag to
+ GtkTextMarkBody; will be used to detect attempts to delete
+ the permanent marks (insert and selection bound)
+
+ * gtk/Makefile.am (noinst_PROGRAMS): add testtextbuffer
+
Fri Jun 2 12:56:01 2000 Owen Taylor <otaylor@redhat.com>
* gtk/gtkwidget.c (gtk_widget_init): Initialize DOUBLE_BUFFERED
diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10
index d33cfd8bca..4fd0965fc7 100644
--- a/ChangeLog.pre-2-10
+++ b/ChangeLog.pre-2-10
@@ -1,3 +1,33 @@
+2000-06-02 Havoc Pennington <hp@pobox.com>
+
+ * gtk/testtextbuffer.c: Test program to make sure GtkTextBuffer
+ is in working order.
+
+ * gtk/testtext.c: Change to reflect anonymous mark API
+
+ * gtk/gtktextview.c: Convert from mark names to GtkTextMark*.
+
+ * gtk/gtktexttag.h (struct _GtkTextTag): remove the affects_size
+ field, which was unused.
+
+ * gtk/gtktextmarkprivate.h (GTK_IS_TEXT_MARK): add this macro,
+ saves some typing.
+
+ * gtk/gtktextbuffer.c: Switch from mark names to GtkTextMark*
+
+ * gtk/gtktextbtree.c (gtk_text_btree_new): set the not_deleteable
+ flag on the insertion point and selection bound
+
+ Throughout, use GtkTextMark instead of GtkTextLineSegment, and
+ make mark-manipulation functions take a GtkTextMark* instead of a
+ mark name.
+
+ * gtk/gtktextmarkprivate.h: Add a "not_deleteable" flag to
+ GtkTextMarkBody; will be used to detect attempts to delete
+ the permanent marks (insert and selection bound)
+
+ * gtk/Makefile.am (noinst_PROGRAMS): add testtextbuffer
+
Fri Jun 2 12:56:01 2000 Owen Taylor <otaylor@redhat.com>
* gtk/gtkwidget.c (gtk_widget_init): Initialize DOUBLE_BUFFERED
diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2
index d33cfd8bca..4fd0965fc7 100644
--- a/ChangeLog.pre-2-2
+++ b/ChangeLog.pre-2-2
@@ -1,3 +1,33 @@
+2000-06-02 Havoc Pennington <hp@pobox.com>
+
+ * gtk/testtextbuffer.c: Test program to make sure GtkTextBuffer
+ is in working order.
+
+ * gtk/testtext.c: Change to reflect anonymous mark API
+
+ * gtk/gtktextview.c: Convert from mark names to GtkTextMark*.
+
+ * gtk/gtktexttag.h (struct _GtkTextTag): remove the affects_size
+ field, which was unused.
+
+ * gtk/gtktextmarkprivate.h (GTK_IS_TEXT_MARK): add this macro,
+ saves some typing.
+
+ * gtk/gtktextbuffer.c: Switch from mark names to GtkTextMark*
+
+ * gtk/gtktextbtree.c (gtk_text_btree_new): set the not_deleteable
+ flag on the insertion point and selection bound
+
+ Throughout, use GtkTextMark instead of GtkTextLineSegment, and
+ make mark-manipulation functions take a GtkTextMark* instead of a
+ mark name.
+
+ * gtk/gtktextmarkprivate.h: Add a "not_deleteable" flag to
+ GtkTextMarkBody; will be used to detect attempts to delete
+ the permanent marks (insert and selection bound)
+
+ * gtk/Makefile.am (noinst_PROGRAMS): add testtextbuffer
+
Fri Jun 2 12:56:01 2000 Owen Taylor <otaylor@redhat.com>
* gtk/gtkwidget.c (gtk_widget_init): Initialize DOUBLE_BUFFERED
diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4
index d33cfd8bca..4fd0965fc7 100644
--- a/ChangeLog.pre-2-4
+++ b/ChangeLog.pre-2-4
@@ -1,3 +1,33 @@
+2000-06-02 Havoc Pennington <hp@pobox.com>
+
+ * gtk/testtextbuffer.c: Test program to make sure GtkTextBuffer
+ is in working order.
+
+ * gtk/testtext.c: Change to reflect anonymous mark API
+
+ * gtk/gtktextview.c: Convert from mark names to GtkTextMark*.
+
+ * gtk/gtktexttag.h (struct _GtkTextTag): remove the affects_size
+ field, which was unused.
+
+ * gtk/gtktextmarkprivate.h (GTK_IS_TEXT_MARK): add this macro,
+ saves some typing.
+
+ * gtk/gtktextbuffer.c: Switch from mark names to GtkTextMark*
+
+ * gtk/gtktextbtree.c (gtk_text_btree_new): set the not_deleteable
+ flag on the insertion point and selection bound
+
+ Throughout, use GtkTextMark instead of GtkTextLineSegment, and
+ make mark-manipulation functions take a GtkTextMark* instead of a
+ mark name.
+
+ * gtk/gtktextmarkprivate.h: Add a "not_deleteable" flag to
+ GtkTextMarkBody; will be used to detect attempts to delete
+ the permanent marks (insert and selection bound)
+
+ * gtk/Makefile.am (noinst_PROGRAMS): add testtextbuffer
+
Fri Jun 2 12:56:01 2000 Owen Taylor <otaylor@redhat.com>
* gtk/gtkwidget.c (gtk_widget_init): Initialize DOUBLE_BUFFERED
diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6
index d33cfd8bca..4fd0965fc7 100644
--- a/ChangeLog.pre-2-6
+++ b/ChangeLog.pre-2-6
@@ -1,3 +1,33 @@
+2000-06-02 Havoc Pennington <hp@pobox.com>
+
+ * gtk/testtextbuffer.c: Test program to make sure GtkTextBuffer
+ is in working order.
+
+ * gtk/testtext.c: Change to reflect anonymous mark API
+
+ * gtk/gtktextview.c: Convert from mark names to GtkTextMark*.
+
+ * gtk/gtktexttag.h (struct _GtkTextTag): remove the affects_size
+ field, which was unused.
+
+ * gtk/gtktextmarkprivate.h (GTK_IS_TEXT_MARK): add this macro,
+ saves some typing.
+
+ * gtk/gtktextbuffer.c: Switch from mark names to GtkTextMark*
+
+ * gtk/gtktextbtree.c (gtk_text_btree_new): set the not_deleteable
+ flag on the insertion point and selection bound
+
+ Throughout, use GtkTextMark instead of GtkTextLineSegment, and
+ make mark-manipulation functions take a GtkTextMark* instead of a
+ mark name.
+
+ * gtk/gtktextmarkprivate.h: Add a "not_deleteable" flag to
+ GtkTextMarkBody; will be used to detect attempts to delete
+ the permanent marks (insert and selection bound)
+
+ * gtk/Makefile.am (noinst_PROGRAMS): add testtextbuffer
+
Fri Jun 2 12:56:01 2000 Owen Taylor <otaylor@redhat.com>
* gtk/gtkwidget.c (gtk_widget_init): Initialize DOUBLE_BUFFERED
diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8
index d33cfd8bca..4fd0965fc7 100644
--- a/ChangeLog.pre-2-8
+++ b/ChangeLog.pre-2-8
@@ -1,3 +1,33 @@
+2000-06-02 Havoc Pennington <hp@pobox.com>
+
+ * gtk/testtextbuffer.c: Test program to make sure GtkTextBuffer
+ is in working order.
+
+ * gtk/testtext.c: Change to reflect anonymous mark API
+
+ * gtk/gtktextview.c: Convert from mark names to GtkTextMark*.
+
+ * gtk/gtktexttag.h (struct _GtkTextTag): remove the affects_size
+ field, which was unused.
+
+ * gtk/gtktextmarkprivate.h (GTK_IS_TEXT_MARK): add this macro,
+ saves some typing.
+
+ * gtk/gtktextbuffer.c: Switch from mark names to GtkTextMark*
+
+ * gtk/gtktextbtree.c (gtk_text_btree_new): set the not_deleteable
+ flag on the insertion point and selection bound
+
+ Throughout, use GtkTextMark instead of GtkTextLineSegment, and
+ make mark-manipulation functions take a GtkTextMark* instead of a
+ mark name.
+
+ * gtk/gtktextmarkprivate.h: Add a "not_deleteable" flag to
+ GtkTextMarkBody; will be used to detect attempts to delete
+ the permanent marks (insert and selection bound)
+
+ * gtk/Makefile.am (noinst_PROGRAMS): add testtextbuffer
+
Fri Jun 2 12:56:01 2000 Owen Taylor <otaylor@redhat.com>
* gtk/gtkwidget.c (gtk_widget_init): Initialize DOUBLE_BUFFERED
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index c1c40aabd5..d265d1d0b0 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -487,7 +487,7 @@ uninstall-local:
#
# test programs, not to be installed
#
-noinst_PROGRAMS = testgtk testcalendar testinput testselection testrgb testdnd testtext simple # testthreads
+noinst_PROGRAMS = testgtk testcalendar testinput testselection testrgb testdnd testtext simple testtextbuffer # testthreads
DEPS = libgtk.la $(top_builddir)/gdk/libgdk.la
LDADDS = @STRIP_BEGIN@ \
libgtk.la \
@@ -514,6 +514,7 @@ testgtk_LDADD = $(LDADDS)
testinput_LDADD = $(LDADDS)
testselection_LDADD = $(LDADDS)
testtext_LDADD = $(LDADDS)
+testtextbuffer_LDADD = $(LDADDS)
testrgb_LDADD = $(LDADDS)
testdnd_LDADD = $(LDADDS)
simple_LDADD = $(LDADDS)
diff --git a/gtk/gtktextbtree.c b/gtk/gtktextbtree.c
index 412a41c3c4..ebbe0d92e8 100644
--- a/gtk/gtktextbtree.c
+++ b/gtk/gtktextbtree.c
@@ -63,6 +63,7 @@
#include "gtktextlayout.h"
#include "gtktextiterprivate.h"
#include "gtkdebug.h"
+#include "gtktextmarkprivate.h"
/*
* Types
@@ -417,19 +418,27 @@ gtk_text_btree_new (GtkTextTagTable *table,
gtk_text_btree_get_iter_at_line_char(tree, &start, 0, 0);
- tree->insert_mark = gtk_text_btree_set_mark(tree,
- "insert",
- FALSE,
- &start,
- FALSE);
-
+ tree->insert_mark =
+ (GtkTextLineSegment*) gtk_text_btree_set_mark(tree,
+ NULL,
+ "insert",
+ FALSE,
+ &start,
+ FALSE);
+
+ tree->insert_mark->body.mark.not_deleteable = TRUE;
+
tree->insert_mark->body.mark.visible = TRUE;
- tree->selection_bound_mark = gtk_text_btree_set_mark(tree,
- "selection_bound",
- FALSE,
- &start,
- FALSE);
+ tree->selection_bound_mark =
+ (GtkTextLineSegment*) gtk_text_btree_set_mark(tree,
+ NULL,
+ "selection_bound",
+ FALSE,
+ &start,
+ FALSE);
+
+ tree->selection_bound_mark->body.mark.not_deleteable = TRUE;
mark_segment_ref(tree->insert_mark);
mark_segment_ref(tree->selection_bound_mark);
@@ -2310,7 +2319,7 @@ redisplay_mark(GtkTextLineSegment *mark)
gtk_text_btree_get_iter_at_mark(mark->body.mark.tree,
&iter,
- mark);
+ (GtkTextMark*)mark);
end = iter;
gtk_text_iter_forward_char(&end);
@@ -2340,6 +2349,7 @@ ensure_not_off_end(GtkTextBTree *tree,
static GtkTextLineSegment*
real_set_mark(GtkTextBTree *tree,
+ GtkTextMark *existing_mark,
const gchar *name,
gboolean left_gravity,
const GtkTextIter *where,
@@ -2350,13 +2360,17 @@ real_set_mark(GtkTextBTree *tree,
GtkTextIter iter;
g_return_val_if_fail(tree != NULL, NULL);
- g_return_val_if_fail(name != NULL, NULL);
g_return_val_if_fail(where != NULL, NULL);
g_return_val_if_fail(gtk_text_iter_get_btree(where) == tree, NULL);
-
- mark = g_hash_table_lookup(tree->mark_table,
- name);
+ if (existing_mark)
+ mark = (GtkTextLineSegment*) existing_mark;
+ else if (name != NULL)
+ mark = g_hash_table_lookup(tree->mark_table,
+ name);
+ else
+ mark = NULL;
+
if (should_exist && mark == NULL)
{
g_warning("No mark `%s' exists!", name);
@@ -2376,7 +2390,7 @@ real_set_mark(GtkTextBTree *tree,
{
GtkTextIter old_pos;
- gtk_text_btree_get_iter_at_mark (tree, &old_pos, mark);
+ gtk_text_btree_get_iter_at_mark (tree, &old_pos, (GtkTextMark*)mark);
redisplay_region (tree, &old_pos, where);
}
@@ -2411,9 +2425,10 @@ real_set_mark(GtkTextBTree *tree,
mark->body.mark.line = gtk_text_iter_get_line(&iter);
- g_hash_table_insert(tree->mark_table,
- mark->body.mark.name,
- mark);
+ if (mark->body.mark.name)
+ g_hash_table_insert(tree->mark_table,
+ mark->body.mark.name,
+ mark);
}
/* Link mark into new location */
@@ -2432,15 +2447,17 @@ real_set_mark(GtkTextBTree *tree,
}
-GtkTextLineSegment*
+GtkTextMark*
gtk_text_btree_set_mark (GtkTextBTree *tree,
+ GtkTextMark *existing_mark,
const gchar *name,
gboolean left_gravity,
const GtkTextIter *iter,
gboolean should_exist)
{
- return real_set_mark(tree, name, left_gravity, iter, should_exist,
- TRUE);
+ return (GtkTextMark*)real_set_mark(tree, existing_mark,
+ name, left_gravity, iter, should_exist,
+ TRUE);
}
gboolean
@@ -2448,8 +2465,10 @@ gtk_text_btree_get_selection_bounds (GtkTextBTree *tree,
GtkTextIter *start,
GtkTextIter *end)
{
- gtk_text_btree_get_iter_at_mark (tree, start, tree->insert_mark);
- gtk_text_btree_get_iter_at_mark (tree, end, tree->selection_bound_mark);
+ gtk_text_btree_get_iter_at_mark (tree, start,
+ (GtkTextMark*)tree->insert_mark);
+ gtk_text_btree_get_iter_at_mark (tree, end,
+ (GtkTextMark*)tree->selection_bound_mark);
if (gtk_text_iter_equal(start, end))
return FALSE;
@@ -2470,15 +2489,17 @@ gtk_text_btree_place_cursor(GtkTextBTree *tree,
redisplay_region(tree, &start, &end);
/* Move insert AND selection_bound before we redisplay */
- real_set_mark(tree, "insert", FALSE, iter, TRUE, FALSE);
- real_set_mark(tree, "selection_bound", FALSE, iter, TRUE, FALSE);
+ real_set_mark(tree, (GtkTextMark*) tree->insert_mark,
+ "insert", FALSE, iter, TRUE, FALSE);
+ real_set_mark(tree, (GtkTextMark*) tree->selection_bound_mark,
+ "selection_bound", FALSE, iter, TRUE, FALSE);
}
void
gtk_text_btree_remove_mark_by_name (GtkTextBTree *tree,
const gchar *name)
{
- GtkTextLineSegment *mark;
+ GtkTextMark *mark;
g_return_if_fail(tree != NULL);
g_return_if_fail(name != NULL);
@@ -2491,35 +2512,44 @@ gtk_text_btree_remove_mark_by_name (GtkTextBTree *tree,
void
gtk_text_btree_remove_mark (GtkTextBTree *tree,
- GtkTextLineSegment *segment)
+ GtkTextMark *mark)
{
+ GtkTextLineSegment *segment = (GtkTextLineSegment*) mark;
+
g_return_if_fail(segment != NULL);
g_return_if_fail(segment != tree->selection_bound_mark);
g_return_if_fail(segment != tree->insert_mark);
g_return_if_fail(tree != NULL);
+
+ if (segment->body.mark.not_deleteable)
+ {
+ g_warning("Can't delete special mark `%s'", segment->body.mark.name);
+ return;
+ }
gtk_text_btree_unlink_segment(tree, segment, segment->body.mark.line);
/* FIXME should probably cleanup_line but Tk didn't */
- g_hash_table_remove(tree->mark_table, segment->body.mark.name);
+ if (segment->body.mark.name)
+ g_hash_table_remove(tree->mark_table, segment->body.mark.name);
mark_segment_unref(segment);
segments_changed(tree);
}
gboolean
gtk_text_btree_mark_is_insert (GtkTextBTree *tree,
- GtkTextLineSegment *segment)
+ GtkTextMark *segment)
{
- return segment == tree->insert_mark;
+ return segment == (GtkTextMark*) tree->insert_mark;
}
gboolean
gtk_text_btree_mark_is_selection_bound (GtkTextBTree *tree,
- GtkTextLineSegment *segment)
+ GtkTextMark *segment)
{
- return segment == tree->selection_bound_mark;
+ return segment == (GtkTextMark*) tree->selection_bound_mark;
}
-GtkTextLineSegment*
+GtkTextMark*
gtk_text_btree_get_mark_by_name (GtkTextBTree *tree,
const gchar *name)
{
diff --git a/gtk/gtktextbtree.h b/gtk/gtktextbtree.h
index 91b37af759..0c594c3c85 100644
--- a/gtk/gtktextbtree.h
+++ b/gtk/gtktextbtree.h
@@ -117,7 +117,7 @@ gboolean gtk_text_btree_get_iter_at_mark_name (GtkTextBTree *tree,
const gchar *mark_name);
void gtk_text_btree_get_iter_at_mark (GtkTextBTree *tree,
GtkTextIter *iter,
- GtkTextLineSegment *mark);
+ GtkTextMark *mark);
void gtk_text_btree_get_last_iter (GtkTextBTree *tree,
GtkTextIter *iter);
void gtk_text_btree_get_iter_at_line (GtkTextBTree *tree,
@@ -133,25 +133,26 @@ gboolean gtk_text_btree_get_iter_at_last_toggle (GtkTextBTree *tree,
/* Manipulate marks */
-GtkTextLineSegment *gtk_text_btree_set_mark (GtkTextBTree *tree,
+GtkTextMark *gtk_text_btree_set_mark (GtkTextBTree *tree,
+ GtkTextMark *existing_mark,
const gchar *name,
gboolean left_gravity,
const GtkTextIter *index,
- gboolean should_exist);
+ gboolean should_exist);
void gtk_text_btree_remove_mark_by_name (GtkTextBTree *tree,
const gchar *name);
void gtk_text_btree_remove_mark (GtkTextBTree *tree,
- GtkTextLineSegment *segment);
+ GtkTextMark *segment);
gboolean gtk_text_btree_get_selection_bounds (GtkTextBTree *tree,
GtkTextIter *start,
GtkTextIter *end);
void gtk_text_btree_place_cursor (GtkTextBTree *tree,
const GtkTextIter *where);
gboolean gtk_text_btree_mark_is_insert (GtkTextBTree *tree,
- GtkTextLineSegment *segment);
+ GtkTextMark *segment);
gboolean gtk_text_btree_mark_is_selection_bound (GtkTextBTree *tree,
- GtkTextLineSegment *segment);
-GtkTextLineSegment *gtk_text_btree_get_mark_by_name (GtkTextBTree *tree,
+ GtkTextMark *segment);
+GtkTextMark *gtk_text_btree_get_mark_by_name (GtkTextBTree *tree,
const gchar *name);
GtkTextLine * gtk_text_btree_first_could_contain_tag (GtkTextBTree *tree,
GtkTextTag *tag);
diff --git a/gtk/gtktextbuffer.c b/gtk/gtktextbuffer.c
index 8fe51fb13f..75af349bf3 100644
--- a/gtk/gtktextbuffer.c
+++ b/gtk/gtktextbuffer.c
@@ -377,7 +377,9 @@ gtk_text_buffer_insert_at_cursor (GtkTextBuffer *buffer,
g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
g_return_if_fail(text != NULL);
- gtk_text_buffer_get_iter_at_mark(buffer, &iter, "insert");
+ gtk_text_buffer_get_iter_at_mark(buffer, &iter,
+ gtk_text_buffer_get_mark (buffer,
+ "insert"));
gtk_text_buffer_insert(buffer, &iter, text, len);
}
@@ -700,7 +702,7 @@ gtk_text_buffer_insert_pixmap_at_char (GtkTextBuffer *buffer,
static void
gtk_text_buffer_mark_set (GtkTextBuffer *buffer,
const GtkTextIter *location,
- const char *mark_name)
+ GtkTextMark *mark)
{
/* IMO this should NOT work like insert_text and delete_text,
where the real action happens in the default handler.
@@ -714,7 +716,7 @@ gtk_text_buffer_mark_set (GtkTextBuffer *buffer,
gtk_signal_emit(GTK_OBJECT(buffer),
signals[MARK_SET],
&location,
- mark_name);
+ mark);
}
@@ -734,17 +736,19 @@ gtk_text_buffer_mark_set (GtkTextBuffer *buffer,
**/
static GtkTextMark*
gtk_text_buffer_set_mark(GtkTextBuffer *buffer,
+ GtkTextMark *existing_mark,
const gchar *mark_name,
const GtkTextIter *iter,
gboolean left_gravity,
gboolean should_exist)
{
GtkTextIter location;
- GtkTextLineSegment *mark;
+ GtkTextMark *mark;
g_return_val_if_fail(GTK_IS_TEXT_BUFFER(buffer), NULL);
mark = gtk_text_btree_set_mark(buffer->tree,
+ existing_mark,
mark_name,
left_gravity,
iter,
@@ -759,8 +763,8 @@ gtk_text_buffer_set_mark(GtkTextBuffer *buffer,
gtk_text_btree_get_iter_at_mark(buffer->tree,
&location,
mark);
-
- gtk_text_buffer_mark_set (buffer, &location, mark_name);
+
+ gtk_text_buffer_mark_set (buffer, &location, mark);
return (GtkTextMark*)mark;
}
@@ -771,64 +775,59 @@ gtk_text_buffer_create_mark(GtkTextBuffer *buffer,
const GtkTextIter *where,
gboolean left_gravity)
{
- return gtk_text_buffer_set_mark(buffer, mark_name, where,
+ return gtk_text_buffer_set_mark(buffer, NULL, mark_name, where,
left_gravity, FALSE);
}
void
gtk_text_buffer_move_mark(GtkTextBuffer *buffer,
- const gchar *mark_name,
+ GtkTextMark *mark,
const GtkTextIter *where)
{
- gtk_text_buffer_set_mark(buffer, mark_name, where, FALSE, TRUE);
+ g_return_if_fail (mark != NULL);
+
+ gtk_text_buffer_set_mark(buffer, mark, NULL, where, FALSE, TRUE);
}
-gboolean
+void
gtk_text_buffer_get_iter_at_mark(GtkTextBuffer *buffer,
GtkTextIter *iter,
- const gchar *name)
+ GtkTextMark *mark)
{
- g_return_val_if_fail(GTK_IS_TEXT_BUFFER(buffer), FALSE);
+ g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
- return gtk_text_btree_get_iter_at_mark_name(buffer->tree,
- iter,
- name);
+ gtk_text_btree_get_iter_at_mark(buffer->tree,
+ iter,
+ mark);
}
void
gtk_text_buffer_delete_mark(GtkTextBuffer *buffer,
- const gchar *name)
+ GtkTextMark *mark)
{
g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
- if (strcmp(name, "insert") == 0 ||
- strcmp(name, "selection_bound") == 0)
- {
- g_warning("Can't delete special mark `%s'", name);
- return;
- }
-
- gtk_text_btree_remove_mark_by_name(buffer->tree, name);
+ gtk_text_btree_remove_mark (buffer->tree, mark);
/* See rationale above for MARK_SET on why we emit this after
removing the mark, rather than removing the mark in a default
handler. */
gtk_signal_emit(GTK_OBJECT(buffer), signals[MARK_DELETED],
- name);
+ mark);
}
GtkTextMark*
gtk_text_buffer_get_mark (GtkTextBuffer *buffer,
const gchar *name)
{
- GtkTextLineSegment *seg;
+ GtkTextMark *mark;
g_return_val_if_fail(GTK_IS_TEXT_BUFFER(buffer), NULL);
g_return_val_if_fail(name != NULL, NULL);
- seg = gtk_text_btree_get_mark_by_name(buffer->tree, name);
+ mark = gtk_text_btree_get_mark_by_name(buffer->tree, name);
- return (GtkTextMark*)seg;
+ return mark;
}
void
@@ -838,8 +837,12 @@ gtk_text_buffer_place_cursor (GtkTextBuffer *buffer,
g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
gtk_text_btree_place_cursor(buffer->tree, where);
- gtk_text_buffer_mark_set (buffer, where, "insert");
- gtk_text_buffer_mark_set (buffer, where, "selection_bound");
+ gtk_text_buffer_mark_set (buffer, where,
+ gtk_text_buffer_get_mark (buffer,
+ "insert"));
+ gtk_text_buffer_mark_set (buffer, where,
+ gtk_text_buffer_get_mark (buffer,
+ "selection_bound"));
}
/*
@@ -1233,11 +1236,15 @@ selection_clear_event(GtkWidget *widget, GdkEventSelection *event,
GtkTextIter insert;
GtkTextIter selection_bound;
- gtk_text_buffer_get_iter_at_mark(buffer, &insert, "insert");
- gtk_text_buffer_get_iter_at_mark(buffer, &selection_bound, "selection_bound");
+ gtk_text_buffer_get_iter_at_mark(buffer, &insert,
+ gtk_text_buffer_get_mark (buffer, "insert"));
+ gtk_text_buffer_get_iter_at_mark(buffer, &selection_bound,
+ gtk_text_buffer_get_mark (buffer, "selection_bound"));
if (!gtk_text_iter_equal(&insert, &selection_bound))
- gtk_text_buffer_move_mark(buffer, "selection_bound", &insert);
+ gtk_text_buffer_move_mark(buffer,
+ gtk_text_buffer_get_mark (buffer, "selection_bound"),
+ &insert);
}
else if (event->selection == clipboard_atom)
{
@@ -1347,6 +1354,7 @@ selection_received (GtkWidget *widget,
GtkTextBuffer *buffer;
gboolean reselect;
GtkTextIter insert_point;
+ GtkTextMark *paste_point_override;
enum {INVALID, STRING, CTEXT, UTF8} type;
g_return_if_fail (widget != NULL);
@@ -1373,15 +1381,22 @@ selection_received (GtkWidget *widget,
return;
}
- if (gtk_text_buffer_get_iter_at_mark(buffer, &insert_point,
- "__paste_point_override"))
+ paste_point_override = gtk_text_buffer_get_mark (buffer,
+ "__paste_point_override");
+
+ if (paste_point_override != NULL)
{
- gtk_text_buffer_delete_mark(buffer, "__paste_point_override");
+ 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,
+ "__paste_point_override"));
}
else
{
gtk_text_buffer_get_iter_at_mark(buffer, &insert_point,
- "insert");
+ gtk_text_buffer_get_mark (buffer,
+ "insert"));
}
reselect = FALSE;
@@ -1594,11 +1609,15 @@ cut_or_copy(GtkTextBuffer *buffer,
if (!gtk_text_buffer_get_selection_bounds(buffer, &start, &end))
{
/* Let's try the anchor thing */
-
- if (!gtk_text_buffer_get_iter_at_mark(buffer, &end, "anchor"))
+ GtkTextMark * anchor = gtk_text_buffer_get_mark (buffer, "anchor");
+
+ if (anchor == NULL)
return;
else
- gtk_text_iter_reorder(&start, &end);
+ {
+ gtk_text_buffer_get_iter_at_mark(buffer, &end, anchor);
+ gtk_text_iter_reorder(&start, &end);
+ }
}
if (!gtk_text_iter_equal(&start, &end))
diff --git a/gtk/gtktextbuffer.h b/gtk/gtktextbuffer.h
index 66f770ab14..c57354b17b 100644
--- a/gtk/gtktextbuffer.h
+++ b/gtk/gtktextbuffer.h
@@ -68,10 +68,10 @@ struct _GtkTextBufferClass {
/* Mark moved or created */
void (* mark_set) (GtkTextBuffer *buffer,
const GtkTextIter *location,
- const gchar *mark_name);
+ GtkTextMark *mark);
void (* mark_deleted) (GtkTextBuffer *buffer,
- const gchar *mark_name);
+ GtkTextMark *mark);
void (* apply_tag) (GtkTextBuffer *buffer,
GtkTextTag *tag,
@@ -176,10 +176,10 @@ GtkTextMark *gtk_text_buffer_create_mark (GtkTextBuffer *buffer,
const GtkTextIter *where,
gboolean left_gravity);
void gtk_text_buffer_move_mark (GtkTextBuffer *buffer,
- const gchar *mark_name,
+ GtkTextMark *mark,
const GtkTextIter *where);
void gtk_text_buffer_delete_mark (GtkTextBuffer *buffer,
- const gchar *name);
+ GtkTextMark *mark);
GtkTextMark *gtk_text_buffer_get_mark (GtkTextBuffer *buffer,
const gchar *name);
@@ -233,9 +233,9 @@ void gtk_text_buffer_get_last_iter (GtkTextBuffer *buffer,
void gtk_text_buffer_get_bounds (GtkTextBuffer *buffer,
GtkTextIter *start,
GtkTextIter *end);
-gboolean gtk_text_buffer_get_iter_at_mark (GtkTextBuffer *buffer,
+void gtk_text_buffer_get_iter_at_mark (GtkTextBuffer *buffer,
GtkTextIter *iter,
- const gchar *name);
+ GtkTextMark *mark);
/* There's no get_first_iter because you just get the iter for
diff --git a/gtk/gtktextiter.c b/gtk/gtktextiter.c
index 41a16916c2..8cc5f783e2 100644
--- a/gtk/gtktextiter.c
+++ b/gtk/gtktextiter.c
@@ -952,7 +952,7 @@ forward_line_leaving_caches_unmodified(GtkTextRealIter *real)
g_assert(new_line != real->line);
if (new_line != NULL)
- {
+ {
real->line = new_line;
real->line_byte_offset = 0;
@@ -2153,7 +2153,7 @@ gtk_text_btree_get_iter_at_mark_name (GtkTextBTree *tree,
GtkTextIter *iter,
const gchar *mark_name)
{
- GtkTextLineSegment *mark;
+ GtkTextMark *mark;
g_return_val_if_fail(iter != NULL, FALSE);
g_return_val_if_fail(tree != NULL, FALSE);
@@ -2173,15 +2173,17 @@ gtk_text_btree_get_iter_at_mark_name (GtkTextBTree *tree,
void
gtk_text_btree_get_iter_at_mark (GtkTextBTree *tree,
GtkTextIter *iter,
- GtkTextLineSegment *mark)
+ GtkTextMark *mark)
{
+ GtkTextLineSegment *seg = (GtkTextLineSegment*) mark;
+
g_return_if_fail(iter != NULL);
g_return_if_fail(tree != NULL);
- g_return_if_fail(mark->type == &gtk_text_left_mark_type ||
- mark->type == &gtk_text_right_mark_type);
+ g_return_if_fail(GTK_IS_TEXT_MARK (mark));
- iter_init_from_segment(iter, tree, mark->body.mark.line, mark);
- g_assert(mark->body.mark.line == gtk_text_iter_get_line(iter));
+ iter_init_from_segment(iter, tree,
+ seg->body.mark.line, seg);
+ g_assert(seg->body.mark.line == gtk_text_iter_get_line(iter));
check_invariants(iter);
}
diff --git a/gtk/gtktextlayout.c b/gtk/gtktextlayout.c
index 6bf09515ff..a6bb822c6e 100644
--- a/gtk/gtktextlayout.c
+++ b/gtk/gtktextlayout.c
@@ -757,7 +757,7 @@ gtk_text_layout_real_get_log_attrs (GtkTextLayout *layout,
{
GtkTextLineDisplay *display;
- g_return_val_if_fail (GTK_IS_TEXT_LAYOUT (layout), NULL);
+ g_return_if_fail (GTK_IS_TEXT_LAYOUT (layout));
display = gtk_text_layout_get_line_display (layout, line, TRUE);
pango_layout_get_log_attrs (display->layout, attrs, n_attrs);
@@ -1116,7 +1116,7 @@ add_cursor (GtkTextLayout *layout,
/* Hide insertion cursor when we have a selection
*/
- if (gtk_text_btree_mark_is_insert (layout->buffer->tree, seg) &&
+ if (gtk_text_btree_mark_is_insert (layout->buffer->tree, (GtkTextMark*)seg) &&
gtk_text_buffer_get_selection_bounds (layout->buffer, &selection_start, &selection_end))
return;
diff --git a/gtk/gtktextmark.c b/gtk/gtktextmark.c
index 739504732b..72cb4f1bab 100644
--- a/gtk/gtktextmark.c
+++ b/gtk/gtktextmark.c
@@ -68,6 +68,7 @@ mark_segment_new(GtkTextBTree *tree,
mark->body.mark.refcount = 1;
mark->body.mark.visible = FALSE;
+ mark->body.mark.not_deleteable = FALSE;
return mark;
}
diff --git a/gtk/gtktextmarkprivate.h b/gtk/gtktextmarkprivate.h
index 20ed1d5b08..578e68036b 100644
--- a/gtk/gtktextmarkprivate.h
+++ b/gtk/gtktextmarkprivate.h
@@ -7,6 +7,10 @@ extern "C" {
#include <gtk/gtktexttypes.h>
+
+#define GTK_IS_TEXT_MARK(mark) (((GtkTextLineSegment*)mark)->type == &gtk_text_left_mark_type || \
+ ((GtkTextLineSegment*)mark)->type == &gtk_text_right_mark_type)
+
/*
* The data structure below defines line segments that represent
* marks. There is one of these for each mark in the text.
@@ -17,12 +21,13 @@ struct _GtkTextMarkBody {
gchar *name;
GtkTextBTree *tree;
GtkTextLine *line;
- gboolean visible;
+ guint visible : 1;
+ guint not_deleteable : 1;
};
GtkTextLineSegment *mark_segment_new (GtkTextBTree *tree,
- gboolean left_gravity,
- const gchar *name);
+ gboolean left_gravity,
+ const gchar *name);
void mark_segment_ref (GtkTextLineSegment *mark);
void mark_segment_unref (GtkTextLineSegment *mark);
diff --git a/gtk/gtktexttag.h b/gtk/gtktexttag.h
index c76b46fcc3..a21d42bcc1 100644
--- a/gtk/gtktexttag.h
+++ b/gtk/gtktexttag.h
@@ -52,10 +52,7 @@ struct _GtkTextTag {
* defaults if no tag specifies an override.
*/
- GtkTextStyleValues *values;
-
- /* tag contains appearance-related options */
- guint affects_size : 1;
+ GtkTextStyleValues *values;
/*
Flags for whether a given value is set; if a value is unset, then
diff --git a/gtk/gtktextview.c b/gtk/gtktextview.c
index 31bc165b2a..96318efc2c 100644
--- a/gtk/gtktextview.c
+++ b/gtk/gtktextview.c
@@ -725,7 +725,7 @@ set_adjustment_clamped (GtkAdjustment *adj, gfloat val)
gboolean
gtk_text_view_scroll_to_mark_adjusted (GtkTextView *text_view,
- const gchar *mark_name,
+ GtkTextMark *mark,
gint margin,
gfloat percentage)
{
@@ -741,7 +741,7 @@ gtk_text_view_scroll_to_mark_adjusted (GtkTextView *text_view,
gint current_x_scroll, current_y_scroll;
g_return_val_if_fail (GTK_IS_TEXT_VIEW (text_view), FALSE);
- g_return_val_if_fail (mark_name != NULL, FALSE);
+ g_return_val_if_fail (mark != NULL, FALSE);
widget = GTK_WIDGET (text_view);
@@ -750,12 +750,8 @@ gtk_text_view_scroll_to_mark_adjusted (GtkTextView *text_view,
g_warning ("FIXME need to implement scroll_to_mark for unmapped GtkTextView?");
return FALSE;
}
-
- if (!gtk_text_buffer_get_iter_at_mark (text_view->buffer, &iter, mark_name))
- {
- g_warning ("Mark %s does not exist! can't scroll to it.", mark_name);
- return FALSE;
- }
+
+ gtk_text_buffer_get_iter_at_mark (text_view->buffer, &iter, mark);
gtk_text_layout_get_iter_location (text_view->layout,
&iter,
@@ -852,12 +848,12 @@ gtk_text_view_scroll_to_mark_adjusted (GtkTextView *text_view,
gboolean
gtk_text_view_scroll_to_mark (GtkTextView *text_view,
- const gchar *mark_name,
- gint mark_within_margin)
+ GtkTextMark *mark,
+ gint mark_within_margin)
{
g_return_val_if_fail (mark_within_margin >= 0, FALSE);
- return gtk_text_view_scroll_to_mark_adjusted (text_view, mark_name,
+ return gtk_text_view_scroll_to_mark_adjusted (text_view, mark,
mark_within_margin, 1.0);
}
@@ -874,19 +870,18 @@ clamp_iter_onscreen (GtkTextView *text_view, GtkTextIter *iter)
gboolean
gtk_text_view_move_mark_onscreen (GtkTextView *text_view,
- const gchar *mark_name)
+ GtkTextMark *mark)
{
- GtkTextIter mark;
+ GtkTextIter iter;
g_return_val_if_fail (GTK_IS_TEXT_VIEW (text_view), FALSE);
- g_return_val_if_fail (mark_name != NULL, FALSE);
+ g_return_val_if_fail (mark != NULL, FALSE);
- if (!gtk_text_buffer_get_iter_at_mark (text_view->buffer, &mark, mark_name))
- return FALSE;
+ gtk_text_buffer_get_iter_at_mark (text_view->buffer, &iter, mark);
- if (clamp_iter_onscreen (text_view, &mark))
+ if (clamp_iter_onscreen (text_view, &iter))
{
- gtk_text_buffer_move_mark (text_view->buffer, mark_name, &mark);
+ gtk_text_buffer_move_mark (text_view->buffer, mark, &iter);
return TRUE;
}
else
@@ -948,7 +943,9 @@ gtk_text_view_place_cursor_onscreen (GtkTextView *text_view)
g_return_val_if_fail (GTK_IS_TEXT_VIEW (text_view), FALSE);
- gtk_text_buffer_get_iter_at_mark (text_view->buffer, &insert, "insert");
+ gtk_text_buffer_get_iter_at_mark (text_view->buffer, &insert,
+ gtk_text_buffer_get_mark (text_view->buffer,
+ "insert"));
if (clamp_iter_onscreen (text_view, &insert))
{
@@ -1148,9 +1145,8 @@ static void
gtk_text_view_get_first_para_iter (GtkTextView *text_view,
GtkTextIter *iter)
{
- gchar *mark_name = gtk_text_mark_get_name (text_view->first_para_mark);
- gtk_text_buffer_get_iter_at_mark (text_view->buffer, iter, mark_name);
- g_free (mark_name);
+ gtk_text_buffer_get_iter_at_mark (text_view->buffer, iter,
+ text_view->first_para_mark);
}
static void
@@ -1492,7 +1488,10 @@ gtk_text_view_key_press_event (GtkWidget *widget, GdkEventKey *event)
else if (event->keyval == GDK_Return)
{
gtk_text_buffer_insert_at_cursor (text_view->buffer, "\n", 1);
- gtk_text_view_scroll_to_mark (text_view, "insert", 0);
+ gtk_text_view_scroll_to_mark (text_view,
+ gtk_text_buffer_get_mark (text_view->buffer,
+ "insert"),
+ 0);
return TRUE;
}
else
@@ -1755,7 +1754,9 @@ gtk_text_view_move_insert (GtkTextView *text_view,
gint cursor_x_pos = 0;
- gtk_text_buffer_get_iter_at_mark (text_view->buffer, &insert, "insert");
+ gtk_text_buffer_get_iter_at_mark (text_view->buffer, &insert,
+ gtk_text_buffer_get_mark (text_view->buffer,
+ "insert"));
newplace = insert;
if (step == GTK_TEXT_MOVEMENT_LINE)
@@ -1810,11 +1811,16 @@ gtk_text_view_move_insert (GtkTextView *text_view,
if (!gtk_text_iter_equal (&insert, &newplace))
{
if (extend_selection)
- gtk_text_buffer_move_mark (text_view->buffer, "insert", &newplace);
+ gtk_text_buffer_move_mark (text_view->buffer,
+ gtk_text_buffer_get_mark (text_view->buffer,
+ "insert"),
+ &newplace);
else
gtk_text_buffer_place_cursor (text_view->buffer, &newplace);
- gtk_text_view_scroll_to_mark (text_view, "insert", 0);
+ gtk_text_view_scroll_to_mark (text_view,
+ gtk_text_buffer_get_mark (text_view->buffer,
+ "insert"), 0);
if (step == GTK_TEXT_MOVEMENT_LINE)
{
@@ -1828,7 +1834,9 @@ gtk_text_view_set_anchor (GtkTextView *text_view)
{
GtkTextIter insert;
- gtk_text_buffer_get_iter_at_mark (text_view->buffer, &insert, "insert");
+ gtk_text_buffer_get_iter_at_mark (text_view->buffer, &insert,
+ gtk_text_buffer_get_mark (text_view->buffer,
+ "insert"));
gtk_text_buffer_create_mark (text_view->buffer, "anchor", &insert, TRUE);
}
@@ -1917,7 +1925,10 @@ gtk_text_view_scroll_text (GtkTextView *text_view,
/* Adjust to have the cursor _entirely_ onscreen, move_mark_onscreen
* only guarantees 1 pixel onscreen.
*/
- gtk_text_view_scroll_to_mark (text_view, "insert", 0);
+ gtk_text_view_scroll_to_mark (text_view,
+ gtk_text_buffer_get_mark (text_view->buffer,
+ "insert"),
+ 0);
}
static gboolean
@@ -1966,7 +1977,8 @@ gtk_text_view_delete_text (GtkTextView *text_view,
gtk_text_buffer_get_iter_at_mark (text_view->buffer,
&insert,
- "insert");
+ gtk_text_buffer_get_mark (text_view->buffer,
+ "insert"));
start = insert;
end = insert;
@@ -2044,7 +2056,9 @@ gtk_text_view_delete_text (GtkTextView *text_view,
if (leave_one)
gtk_text_buffer_insert_at_cursor (text_view->buffer, " ", 1);
- gtk_text_view_scroll_to_mark (text_view, "insert", 0);
+ gtk_text_view_scroll_to_mark (text_view,
+ gtk_text_buffer_get_mark (text_view->buffer, "insert"),
+ 0);
}
}
@@ -2052,21 +2066,30 @@ static void
gtk_text_view_cut_text (GtkTextView *text_view)
{
gtk_text_buffer_cut (text_view->buffer, GDK_CURRENT_TIME);
- gtk_text_view_scroll_to_mark (text_view, "insert", 0);
+ gtk_text_view_scroll_to_mark (text_view,
+ gtk_text_buffer_get_mark (text_view->buffer,
+ "insert"),
+ 0);
}
static void
gtk_text_view_copy_text (GtkTextView *text_view)
{
gtk_text_buffer_copy (text_view->buffer, GDK_CURRENT_TIME);
- gtk_text_view_scroll_to_mark (text_view, "insert", 0);
+ gtk_text_view_scroll_to_mark (text_view,
+ gtk_text_buffer_get_mark (text_view->buffer,
+ "insert"),
+ 0);
}
static void
gtk_text_view_paste_text (GtkTextView *text_view)
{
gtk_text_buffer_paste_clipboard (text_view->buffer, GDK_CURRENT_TIME);
- gtk_text_view_scroll_to_mark (text_view, "insert", 0);
+ gtk_text_view_scroll_to_mark (text_view,
+ gtk_text_buffer_get_mark (text_view->buffer,
+ "insert"),
+ 0);
}
static void
@@ -2123,15 +2146,17 @@ move_insert_to_pointer_and_scroll (GtkTextView *text_view, gboolean partial_scro
{
gboolean scrolled = FALSE;
+ GtkTextMark *insert_mark =
+ gtk_text_buffer_get_mark (text_view->buffer, "insert");
gtk_text_buffer_move_mark (text_view->buffer,
- "insert",
+ insert_mark,
&newplace);
if (partial_scroll)
- scrolled = gtk_text_view_scroll_to_mark_adjusted (text_view, "insert", 0, 0.7);
+ scrolled = gtk_text_view_scroll_to_mark_adjusted (text_view, insert_mark, 0, 0.7);
else
- scrolled = gtk_text_view_scroll_to_mark_adjusted (text_view, "insert", 0, 1.0);
+ scrolled = gtk_text_view_scroll_to_mark_adjusted (text_view, insert_mark, 0, 1.0);
if (scrolled)
{
@@ -2588,7 +2613,8 @@ gtk_text_view_drag_motion (GtkWidget *widget,
}
gtk_text_buffer_move_mark (text_view->buffer,
- "__drag_target",
+ gtk_text_buffer_get_mark (text_view->buffer,
+ "__drag_target"),
&newplace);
{
@@ -2600,7 +2626,10 @@ gtk_text_view_drag_motion (GtkWidget *widget,
margin = MIN (widget->allocation.width, widget->allocation.height);
margin /= 5;
- gtk_text_view_scroll_to_mark_adjusted (text_view, "__drag_target", margin, 1.0);
+ gtk_text_view_scroll_to_mark_adjusted (text_view,
+ gtk_text_buffer_get_mark (text_view->buffer,
+ "__drag_target"),
+ margin, 1.0);
}
return TRUE;
@@ -2639,6 +2668,8 @@ gtk_text_view_drag_data_received (GtkWidget *widget,
{
GtkTextIter drop_point;
GtkTextView *text_view;
+ GtkTextMark *drag_target_mark;
+
enum {INVALID, STRING, CTEXT, UTF8} type;
text_view = GTK_TEXT_VIEW (widget);
@@ -2659,8 +2690,16 @@ gtk_text_view_drag_data_received (GtkWidget *widget,
return;
}
- if (!gtk_text_buffer_get_iter_at_mark (text_view->buffer, &drop_point, "__drag_target"))
+ drag_target_mark = gtk_text_buffer_get_mark (text_view->buffer,
+ "__drag_target");
+
+ if (drag_target_mark == NULL)
return;
+
+ gtk_text_buffer_get_iter_at_mark (text_view->buffer,
+ &drop_point,
+ drag_target_mark);
+
switch (type)
{
@@ -2780,7 +2819,6 @@ gtk_text_view_value_changed (GtkAdjustment *adj,
GtkTextView *text_view)
{
GtkTextIter iter;
- gchar *mark_name;
gint line_top;
gint dx = 0;
gint dy = 0;
@@ -2799,9 +2837,7 @@ gtk_text_view_value_changed (GtkAdjustment *adj,
{
gtk_text_layout_get_line_at_y (text_view->layout, &iter, adj->value, &line_top);
- mark_name = gtk_text_mark_get_name (text_view->first_para_mark);
- gtk_text_buffer_move_mark (text_view->buffer, mark_name, &iter);
- g_free (mark_name);
+ gtk_text_buffer_move_mark (text_view->buffer, text_view->first_para_mark, &iter);
text_view->first_para_pixels = adj->value - line_top;
}
@@ -2832,7 +2868,10 @@ gtk_text_view_commit_handler (GtkIMContext *context,
gtk_text_buffer_insert_at_cursor (text_view->buffer, str, strlen (str));
}
- gtk_text_view_scroll_to_mark (text_view, "insert", 0);
+ gtk_text_view_scroll_to_mark (text_view,
+ gtk_text_buffer_get_mark (text_view->buffer,
+ "insert"),
+ 0);
}
static void
@@ -2858,7 +2897,9 @@ gtk_text_view_get_virtual_cursor_pos (GtkTextView *text_view,
GdkRectangle strong_pos;
GtkTextIter insert;
- gtk_text_buffer_get_iter_at_mark (text_view->buffer, &insert, "insert");
+ gtk_text_buffer_get_iter_at_mark (text_view->buffer, &insert,
+ gtk_text_buffer_get_mark (text_view->buffer,
+ "insert"));
if ((x && text_view->virtual_cursor_x == -1) ||
(y && text_view->virtual_cursor_y == -1))
@@ -2889,7 +2930,9 @@ gtk_text_view_set_virtual_cursor_pos (GtkTextView *text_view,
GdkRectangle strong_pos;
GtkTextIter insert;
- gtk_text_buffer_get_iter_at_mark (text_view->buffer, &insert, "insert");
+ gtk_text_buffer_get_iter_at_mark (text_view->buffer, &insert,
+ gtk_text_buffer_get_mark (text_view->buffer,
+ "insert"));
if (x == -1 || y == -1)
gtk_text_layout_get_cursor_locations (text_view->layout, &insert, &strong_pos, NULL);
diff --git a/gtk/gtktextview.h b/gtk/gtktextview.h
index ba46ae6b47..002d3cd01f 100644
--- a/gtk/gtktextview.h
+++ b/gtk/gtktextview.h
@@ -132,10 +132,10 @@ void gtk_text_view_get_iter_at_pixel (GtkTextView *text_view,
gint x,
gint y);
gboolean gtk_text_view_scroll_to_mark (GtkTextView *text_view,
- const gchar *mark_name,
+ GtkTextMark *mark,
gint mark_within_margin);
gboolean gtk_text_view_move_mark_onscreen (GtkTextView *text_view,
- const gchar *mark_name);
+ GtkTextMark *mark);
gboolean gtk_text_view_place_cursor_onscreen (GtkTextView *text_view);
void gtk_text_view_get_visible_rect (GtkTextView *text_view,
diff --git a/gtk/testtext.c b/gtk/testtext.c
index 478a6dfb21..3393596cdf 100644
--- a/gtk/testtext.c
+++ b/gtk/testtext.c
@@ -502,6 +502,8 @@ fill_example_buffer (GtkTextBuffer *buffer)
i = 0;
while (i < 100)
{
+ GtkTextMark * temp_mark;
+
gtk_text_buffer_get_iter_at_char(buffer, &iter, 0);
gtk_text_buffer_insert_pixmap (buffer, &iter, pixmap, mask);
@@ -521,7 +523,8 @@ fill_example_buffer (GtkTextBuffer *buffer)
really know how to display it */
"German (Deutsch Süd) Grüß Gott Greek (Ελληνικά) Γειά σας Hebrew שלום Japanese (日本語)\n", -1);
- gtk_text_buffer_create_mark (buffer, "tmp_mark", &iter, TRUE);
+ temp_mark =
+ gtk_text_buffer_create_mark (buffer, "tmp_mark", &iter, TRUE);
#if 1
gtk_text_buffer_get_iter_at_line_char(buffer, &iter, 0, 6);
@@ -555,16 +558,16 @@ fill_example_buffer (GtkTextBuffer *buffer)
gtk_text_buffer_apply_tag(buffer, "fg_red", &iter, &iter2);
#endif
- gtk_text_buffer_get_iter_at_mark (buffer, &iter, "tmp_mark");
+ gtk_text_buffer_get_iter_at_mark (buffer, &iter, temp_mark);
gtk_text_buffer_insert (buffer, &iter, "Centered text!\n", -1);
- gtk_text_buffer_get_iter_at_mark (buffer, &iter2, "tmp_mark");
+ gtk_text_buffer_get_iter_at_mark (buffer, &iter2, temp_mark);
gtk_text_buffer_apply_tag (buffer, "centered", &iter2, &iter);
- gtk_text_buffer_move_mark (buffer, "tmp_mark", &iter);
+ gtk_text_buffer_move_mark (buffer, temp_mark, &iter);
gtk_text_buffer_insert (buffer, &iter, "Word wrapped, Right-to-left Quote\n", -1);
gtk_text_buffer_insert (buffer, &iter, "وقد بدأ ثلاث من أكثر المؤسسات تقدما في شبكة اكسيون برامجها كمنظمات لا تسعى للربح، ثم تحولت في السنوات الخمس الماضية إلى مؤسسات مالية منظمة، وباتت جزءا من النظام المالي في بلدانها، ولكنها تتخصص في خدمة قطاع المشروعات الصغيرة. وأحد أكثر هذه المؤسسات نجاحا هو »بانكوسول« في بوليفيا.\n", -1);
- gtk_text_buffer_get_iter_at_mark (buffer, &iter2, "tmp_mark");
+ gtk_text_buffer_get_iter_at_mark (buffer, &iter2, temp_mark);
gtk_text_buffer_apply_tag (buffer, "rtl_quote", &iter2, &iter);
++i;
diff --git a/gtk/testtextbuffer.c b/gtk/testtextbuffer.c
new file mode 100644
index 0000000000..dfd95bf0a4
--- /dev/null
+++ b/gtk/testtextbuffer.c
@@ -0,0 +1,393 @@
+/* Simplistic test suite */
+
+#include <stdio.h>
+
+#include <gtk/gtk.h>
+#include "gtktextbtree.h"
+
+static void fill_buffer(GtkTextBuffer *buffer);
+
+static void run_tests(GtkTextBuffer *buffer);
+
+int
+main(int argc, char** argv)
+{
+ GtkTextBuffer *buffer;
+ int n;
+ GtkTextUniChar ch;
+ GtkTextIter start, end;
+
+ gtk_init(&argc, &argv);
+
+ /* Check UTF8 unknown char thing */
+ g_assert(gtk_text_view_num_utf_chars(gtk_text_unknown_char_utf8, 3) == 1);
+ gtk_text_utf_to_unichar(gtk_text_unknown_char_utf8, &ch);
+ g_assert(ch == gtk_text_unknown_char);
+
+ /* First, we turn on btree debugging. */
+ gtk_debug_flags |= GTK_DEBUG_TEXT;
+
+ /* Create a buffer */
+ buffer = gtk_text_buffer_new(NULL);
+
+ /* Check that buffer starts with one empty line and zero chars */
+
+ n = gtk_text_buffer_get_line_count(buffer);
+ if (n != 1)
+ g_error("%d lines, expected 1", n);
+
+ n = gtk_text_buffer_get_char_count(buffer);
+ if (n != 1)
+ g_error("%d chars, expected 1", n);
+
+ /* Run gruesome alien test suite on buffer */
+ run_tests(buffer);
+
+ /* Put stuff in the buffer */
+
+ fill_buffer(buffer);
+
+ /* Subject stuff-bloated buffer to further torment */
+ run_tests(buffer);
+
+ /* Delete all stuff from the buffer */
+ gtk_text_buffer_get_bounds(buffer, &start, &end);
+ gtk_text_buffer_delete(buffer, &start, &end);
+
+ /* Check buffer for emptiness (note that a single
+ empty line always remains in the buffer) */
+ n = gtk_text_buffer_get_line_count(buffer);
+ if (n != 1)
+ g_error("%d lines, expected 1", n);
+
+ n = gtk_text_buffer_get_char_count(buffer);
+ if (n != 1)
+ g_error("%d chars, expected 1", n);
+
+ run_tests(buffer);
+
+ return 0;
+}
+
+static void
+run_tests(GtkTextBuffer *buffer)
+{
+ GtkTextIter iter;
+ GtkTextIter start;
+ GtkTextIter end;
+ GtkTextIter mark;
+ gint i, j;
+ gint num_chars;
+ GtkTextMark *bar_mark;
+
+ gtk_text_buffer_get_bounds(buffer, &start, &end);
+
+ /* Check that walking the tree via chars and via indexes produces
+ * the same number of indexable locations.
+ */
+ num_chars = gtk_text_buffer_get_char_count(buffer);
+ iter = start;
+ bar_mark = gtk_text_buffer_create_mark(buffer, "bar", &iter, FALSE);
+ i = 0;
+ while (i < num_chars)
+ {
+ GtkTextIter current;
+ GtkTextMark *foo_mark;
+
+ gtk_text_buffer_get_iter_at_char(buffer, &current, i);
+
+ if (!gtk_text_iter_equal(&iter, &current))
+ {
+ g_error("get_char_index didn't return current iter");
+ }
+
+ j = gtk_text_iter_get_char_index(&iter);
+
+ if (i != j)
+ {
+ g_error("iter converted to %d not %d", j, i);
+ }
+
+ /* get/set mark */
+ gtk_text_buffer_get_iter_at_mark(buffer, &mark, bar_mark);
+
+ if (!gtk_text_iter_equal(&iter, &mark))
+ {
+ gtk_text_iter_spew(&iter, "iter");
+ gtk_text_iter_spew(&mark, "mark");
+ g_error("Mark not moved to the right place.");
+ }
+
+ foo_mark = gtk_text_buffer_create_mark(buffer, "foo", &iter, FALSE);
+ gtk_text_buffer_get_iter_at_mark(buffer, &mark, foo_mark);
+ gtk_text_buffer_delete_mark(buffer, foo_mark);
+
+ if (!gtk_text_iter_equal(&iter, &mark))
+ {
+ gtk_text_iter_spew(&iter, "iter");
+ gtk_text_iter_spew(&mark, "mark");
+ g_error("Mark not created in the right place.");
+ }
+
+ if (!gtk_text_iter_forward_char(&iter))
+ g_error("iterators ran out before chars");
+
+ gtk_text_buffer_move_mark(buffer, bar_mark, &iter);
+
+ ++i;
+ }
+
+ if (!gtk_text_iter_equal(&iter, &end))
+ g_error("Iterating over all chars didn't end with the end iter");
+
+ /* Do the tree-walk backward
+ */
+ num_chars = gtk_text_buffer_get_char_count(buffer);
+ gtk_text_buffer_get_iter_at_char(buffer, &iter, -1);
+
+ gtk_text_buffer_move_mark(buffer, bar_mark, &iter);
+
+ i = num_chars;
+
+ if (!gtk_text_iter_equal(&iter, &end))
+ g_error("iter at char -1 is not equal to the end iterator");
+
+ while (i >= 0)
+ {
+ GtkTextIter current;
+ GtkTextMark *foo_mark;
+
+ gtk_text_buffer_get_iter_at_char(buffer, &current, i);
+
+ if (!gtk_text_iter_equal(&iter, &current))
+ {
+ g_error("get_char_index didn't return current iter while going backward");
+ }
+ j = gtk_text_iter_get_char_index(&iter);
+
+ if (i != j)
+ {
+ g_error("going backward, iter converted to %d not %d", j, i);
+ }
+
+ /* get/set mark */
+ gtk_text_buffer_get_iter_at_mark(buffer, &mark, bar_mark);
+
+ if (!gtk_text_iter_equal(&iter, &mark))
+ {
+ gtk_text_iter_spew(&iter, "iter");
+ gtk_text_iter_spew(&mark, "mark");
+ g_error("Mark not moved to the right place.");
+ }
+
+ foo_mark = gtk_text_buffer_create_mark(buffer, "foo", &iter, FALSE);
+ gtk_text_buffer_get_iter_at_mark(buffer, &mark, foo_mark);
+ gtk_text_buffer_delete_mark(buffer, foo_mark);
+
+ if (!gtk_text_iter_equal(&iter, &mark))
+ {
+ gtk_text_iter_spew(&iter, "iter");
+ gtk_text_iter_spew(&mark, "mark");
+ g_error("Mark not created in the right place.");
+ }
+
+ if (i > 0)
+ {
+ if (!gtk_text_iter_backward_char(&iter))
+ g_error("iterators ran out before char indexes");
+
+ gtk_text_buffer_move_mark(buffer, bar_mark, &iter);
+ }
+ else
+ {
+ if (gtk_text_iter_backward_char(&iter))
+ g_error("went backward from 0?");
+ }
+
+ --i;
+ }
+
+ if (!gtk_text_iter_equal(&iter, &start))
+ g_error("Iterating backward over all chars didn't end with the start iter");
+
+ /*
+ * Check that get_line_count returns the same number of lines
+ * as walking the tree by line
+ */
+ i = 1; /* include current (first) line */
+ gtk_text_buffer_get_iter_at_line(buffer, &iter, 0);
+ while (gtk_text_iter_forward_line(&iter))
+ ++i;
+
+ /* Add 1 to the line count, because 'i' counts the end-iterator line */
+ if (i != gtk_text_buffer_get_line_count(buffer) + 1)
+ g_error("Counted %d lines, buffer has %d", i,
+ gtk_text_buffer_get_line_count(buffer) + 1);
+}
+
+
+static char *book_closed_xpm[] = {
+"16 16 6 1",
+" c None s None",
+". c black",
+"X c red",
+"o c yellow",
+"O c #808080",
+"# c white",
+" ",
+" .. ",
+" ..XX. ",
+" ..XXXXX. ",
+" ..XXXXXXXX. ",
+".ooXXXXXXXXX. ",
+"..ooXXXXXXXXX. ",
+".X.ooXXXXXXXXX. ",
+".XX.ooXXXXXX.. ",
+" .XX.ooXXX..#O ",
+" .XX.oo..##OO. ",
+" .XX..##OO.. ",
+" .X.#OO.. ",
+" ..O.. ",
+" .. ",
+" "};
+
+static void
+fill_buffer(GtkTextBuffer *buffer)
+{
+ GtkTextTag *tag;
+ GdkColor color, color2;
+ GtkTextIter iter;
+ GtkTextIter iter2;
+ GdkPixmap *pixmap;
+ GdkBitmap *mask;
+ int i;
+
+ tag = gtk_text_buffer_create_tag(buffer, "fg_blue");
+
+ color.red = color.green = 0;
+ color.blue = 0xffff;
+ color2.red = 0xfff;
+ color2.blue = 0x0;
+ color2.green = 0;
+ gtk_object_set(GTK_OBJECT(tag),
+ "foreground_gdk", &color,
+ "background_gdk", &color2,
+ "font", "-*-courier-bold-r-*-*-30-*-*-*-*-*-*-*",
+ NULL);
+
+ tag = gtk_text_buffer_create_tag(buffer, "fg_red");
+
+ color.blue = color.green = 0;
+ color.red = 0xffff;
+ gtk_object_set(GTK_OBJECT(tag),
+ "offset", -4,
+ "foreground_gdk", &color,
+ NULL);
+
+ tag = gtk_text_buffer_create_tag(buffer, "bg_green");
+
+ color.blue = color.red = 0;
+ color.green = 0xffff;
+ gtk_object_set(GTK_OBJECT(tag),
+ "background_gdk", &color,
+ "font", "-*-courier-bold-r-*-*-10-*-*-*-*-*-*-*",
+ NULL);
+
+ pixmap = gdk_pixmap_colormap_create_from_xpm_d (NULL,
+ gtk_widget_get_default_colormap(),
+ &mask,
+ NULL, book_closed_xpm);
+
+ g_assert(pixmap != NULL);
+
+ i = 0;
+ while (i < 10)
+ {
+ gchar *str;
+
+ gtk_text_buffer_get_iter_at_char(buffer, &iter, 0);
+
+ gtk_text_buffer_insert_pixmap (buffer, &iter, pixmap, mask);
+
+ gtk_text_buffer_get_iter_at_char(buffer, &iter, 1);
+
+ gtk_text_buffer_insert_pixmap (buffer, &iter, pixmap, mask);
+
+ str = g_strdup_printf("%d Hello World!\nwoo woo woo woo woo woo woo woo\n",
+ i);
+
+ gtk_text_buffer_insert(buffer, &iter, str, -1);
+
+ g_free(str);
+
+ gtk_text_buffer_insert(buffer, &iter,
+ "(Hello World!)\nfoo foo Hello this is some text we are using to text word wrap. It has punctuation! gee; blah - hmm, great.\nnew line\n\n"
+ /* This is UTF8 stuff, Emacs doesn't
+ really know how to display it */
+ "Spanish (Español) ¡Hola! / French (Français) Bonjour, Salut / German (Deutsch Süd) Grüß Gott (testing Latin-1 chars encoded in UTF8)\nThai (we can't display this, just making sure we don't crash) (ภาษาไทย) สวัสดีครับ, สวัสดีค่ะ\n",
+ -1);
+
+ gtk_text_buffer_insert_pixmap (buffer, &iter, pixmap, mask);
+ gtk_text_buffer_insert_pixmap (buffer, &iter, pixmap, mask);
+
+ gtk_text_buffer_get_iter_at_char(buffer, &iter, 4);
+
+ gtk_text_buffer_insert_pixmap (buffer, &iter, pixmap, mask);
+
+ gtk_text_buffer_get_iter_at_char(buffer, &iter, 7);
+
+ gtk_text_buffer_insert_pixmap (buffer, &iter, pixmap, mask);
+
+ gtk_text_buffer_get_iter_at_char(buffer, &iter, 8);
+
+ gtk_text_buffer_insert_pixmap (buffer, &iter, pixmap, mask);
+
+ gtk_text_buffer_get_iter_at_line_char(buffer, &iter, 0, 8);
+ iter2 = iter;
+ gtk_text_iter_forward_chars(&iter2, 10);
+
+ gtk_text_buffer_apply_tag(buffer, "fg_blue", &iter, &iter2);
+
+ gtk_text_iter_forward_chars(&iter, 7);
+ gtk_text_iter_forward_chars(&iter2, 10);
+
+ gtk_text_buffer_apply_tag(buffer, "bg_green", &iter, &iter2);
+
+ gtk_text_iter_forward_chars(&iter, 12);
+ gtk_text_iter_forward_chars(&iter2, 10);
+
+ gtk_text_buffer_apply_tag(buffer, "bg_green", &iter, &iter2);
+
+ gtk_text_iter_forward_chars(&iter, 10);
+ gtk_text_iter_forward_chars(&iter2, 15);
+
+ gtk_text_buffer_apply_tag(buffer, "fg_red", &iter, &iter2);
+ gtk_text_buffer_apply_tag(buffer, "fg_blue", &iter, &iter2);
+
+ gtk_text_iter_forward_chars(&iter, 20);
+ gtk_text_iter_forward_chars(&iter2, 20);
+
+ gtk_text_buffer_apply_tag(buffer, "fg_red", &iter, &iter2);
+ gtk_text_buffer_apply_tag(buffer, "fg_blue", &iter, &iter2);
+
+ gtk_text_iter_backward_chars(&iter, 25);
+ gtk_text_iter_forward_chars(&iter2, 5);
+
+ gtk_text_buffer_apply_tag(buffer, "fg_red", &iter, &iter2);
+ gtk_text_buffer_apply_tag(buffer, "fg_blue", &iter, &iter2);
+
+ gtk_text_iter_forward_chars(&iter, 15);
+ gtk_text_iter_backward_chars(&iter2, 10);
+
+ gtk_text_buffer_remove_tag(buffer, "fg_red", &iter, &iter2);
+ gtk_text_buffer_remove_tag(buffer, "fg_blue", &iter, &iter2);
+
+ ++i;
+ }
+
+ gdk_pixmap_unref(pixmap);
+ if (mask)
+ gdk_bitmap_unref(mask);
+}
+
+
diff --git a/tests/testtext.c b/tests/testtext.c
index 478a6dfb21..3393596cdf 100644
--- a/tests/testtext.c
+++ b/tests/testtext.c
@@ -502,6 +502,8 @@ fill_example_buffer (GtkTextBuffer *buffer)
i = 0;
while (i < 100)
{
+ GtkTextMark * temp_mark;
+
gtk_text_buffer_get_iter_at_char(buffer, &iter, 0);
gtk_text_buffer_insert_pixmap (buffer, &iter, pixmap, mask);
@@ -521,7 +523,8 @@ fill_example_buffer (GtkTextBuffer *buffer)
really know how to display it */
"German (Deutsch Süd) Grüß Gott Greek (Ελληνικά) Γειά σας Hebrew שלום Japanese (日本語)\n", -1);
- gtk_text_buffer_create_mark (buffer, "tmp_mark", &iter, TRUE);
+ temp_mark =
+ gtk_text_buffer_create_mark (buffer, "tmp_mark", &iter, TRUE);
#if 1
gtk_text_buffer_get_iter_at_line_char(buffer, &iter, 0, 6);
@@ -555,16 +558,16 @@ fill_example_buffer (GtkTextBuffer *buffer)
gtk_text_buffer_apply_tag(buffer, "fg_red", &iter, &iter2);
#endif
- gtk_text_buffer_get_iter_at_mark (buffer, &iter, "tmp_mark");
+ gtk_text_buffer_get_iter_at_mark (buffer, &iter, temp_mark);
gtk_text_buffer_insert (buffer, &iter, "Centered text!\n", -1);
- gtk_text_buffer_get_iter_at_mark (buffer, &iter2, "tmp_mark");
+ gtk_text_buffer_get_iter_at_mark (buffer, &iter2, temp_mark);
gtk_text_buffer_apply_tag (buffer, "centered", &iter2, &iter);
- gtk_text_buffer_move_mark (buffer, "tmp_mark", &iter);
+ gtk_text_buffer_move_mark (buffer, temp_mark, &iter);
gtk_text_buffer_insert (buffer, &iter, "Word wrapped, Right-to-left Quote\n", -1);
gtk_text_buffer_insert (buffer, &iter, "وقد بدأ ثلاث من أكثر المؤسسات تقدما في شبكة اكسيون برامجها كمنظمات لا تسعى للربح، ثم تحولت في السنوات الخمس الماضية إلى مؤسسات مالية منظمة، وباتت جزءا من النظام المالي في بلدانها، ولكنها تتخصص في خدمة قطاع المشروعات الصغيرة. وأحد أكثر هذه المؤسسات نجاحا هو »بانكوسول« في بوليفيا.\n", -1);
- gtk_text_buffer_get_iter_at_mark (buffer, &iter2, "tmp_mark");
+ gtk_text_buffer_get_iter_at_mark (buffer, &iter2, temp_mark);
gtk_text_buffer_apply_tag (buffer, "rtl_quote", &iter2, &iter);
++i;
diff --git a/tests/testtextbuffer.c b/tests/testtextbuffer.c
new file mode 100644
index 0000000000..dfd95bf0a4
--- /dev/null
+++ b/tests/testtextbuffer.c
@@ -0,0 +1,393 @@
+/* Simplistic test suite */
+
+#include <stdio.h>
+
+#include <gtk/gtk.h>
+#include "gtktextbtree.h"
+
+static void fill_buffer(GtkTextBuffer *buffer);
+
+static void run_tests(GtkTextBuffer *buffer);
+
+int
+main(int argc, char** argv)
+{
+ GtkTextBuffer *buffer;
+ int n;
+ GtkTextUniChar ch;
+ GtkTextIter start, end;
+
+ gtk_init(&argc, &argv);
+
+ /* Check UTF8 unknown char thing */
+ g_assert(gtk_text_view_num_utf_chars(gtk_text_unknown_char_utf8, 3) == 1);
+ gtk_text_utf_to_unichar(gtk_text_unknown_char_utf8, &ch);
+ g_assert(ch == gtk_text_unknown_char);
+
+ /* First, we turn on btree debugging. */
+ gtk_debug_flags |= GTK_DEBUG_TEXT;
+
+ /* Create a buffer */
+ buffer = gtk_text_buffer_new(NULL);
+
+ /* Check that buffer starts with one empty line and zero chars */
+
+ n = gtk_text_buffer_get_line_count(buffer);
+ if (n != 1)
+ g_error("%d lines, expected 1", n);
+
+ n = gtk_text_buffer_get_char_count(buffer);
+ if (n != 1)
+ g_error("%d chars, expected 1", n);
+
+ /* Run gruesome alien test suite on buffer */
+ run_tests(buffer);
+
+ /* Put stuff in the buffer */
+
+ fill_buffer(buffer);
+
+ /* Subject stuff-bloated buffer to further torment */
+ run_tests(buffer);
+
+ /* Delete all stuff from the buffer */
+ gtk_text_buffer_get_bounds(buffer, &start, &end);
+ gtk_text_buffer_delete(buffer, &start, &end);
+
+ /* Check buffer for emptiness (note that a single
+ empty line always remains in the buffer) */
+ n = gtk_text_buffer_get_line_count(buffer);
+ if (n != 1)
+ g_error("%d lines, expected 1", n);
+
+ n = gtk_text_buffer_get_char_count(buffer);
+ if (n != 1)
+ g_error("%d chars, expected 1", n);
+
+ run_tests(buffer);
+
+ return 0;
+}
+
+static void
+run_tests(GtkTextBuffer *buffer)
+{
+ GtkTextIter iter;
+ GtkTextIter start;
+ GtkTextIter end;
+ GtkTextIter mark;
+ gint i, j;
+ gint num_chars;
+ GtkTextMark *bar_mark;
+
+ gtk_text_buffer_get_bounds(buffer, &start, &end);
+
+ /* Check that walking the tree via chars and via indexes produces
+ * the same number of indexable locations.
+ */
+ num_chars = gtk_text_buffer_get_char_count(buffer);
+ iter = start;
+ bar_mark = gtk_text_buffer_create_mark(buffer, "bar", &iter, FALSE);
+ i = 0;
+ while (i < num_chars)
+ {
+ GtkTextIter current;
+ GtkTextMark *foo_mark;
+
+ gtk_text_buffer_get_iter_at_char(buffer, &current, i);
+
+ if (!gtk_text_iter_equal(&iter, &current))
+ {
+ g_error("get_char_index didn't return current iter");
+ }
+
+ j = gtk_text_iter_get_char_index(&iter);
+
+ if (i != j)
+ {
+ g_error("iter converted to %d not %d", j, i);
+ }
+
+ /* get/set mark */
+ gtk_text_buffer_get_iter_at_mark(buffer, &mark, bar_mark);
+
+ if (!gtk_text_iter_equal(&iter, &mark))
+ {
+ gtk_text_iter_spew(&iter, "iter");
+ gtk_text_iter_spew(&mark, "mark");
+ g_error("Mark not moved to the right place.");
+ }
+
+ foo_mark = gtk_text_buffer_create_mark(buffer, "foo", &iter, FALSE);
+ gtk_text_buffer_get_iter_at_mark(buffer, &mark, foo_mark);
+ gtk_text_buffer_delete_mark(buffer, foo_mark);
+
+ if (!gtk_text_iter_equal(&iter, &mark))
+ {
+ gtk_text_iter_spew(&iter, "iter");
+ gtk_text_iter_spew(&mark, "mark");
+ g_error("Mark not created in the right place.");
+ }
+
+ if (!gtk_text_iter_forward_char(&iter))
+ g_error("iterators ran out before chars");
+
+ gtk_text_buffer_move_mark(buffer, bar_mark, &iter);
+
+ ++i;
+ }
+
+ if (!gtk_text_iter_equal(&iter, &end))
+ g_error("Iterating over all chars didn't end with the end iter");
+
+ /* Do the tree-walk backward
+ */
+ num_chars = gtk_text_buffer_get_char_count(buffer);
+ gtk_text_buffer_get_iter_at_char(buffer, &iter, -1);
+
+ gtk_text_buffer_move_mark(buffer, bar_mark, &iter);
+
+ i = num_chars;
+
+ if (!gtk_text_iter_equal(&iter, &end))
+ g_error("iter at char -1 is not equal to the end iterator");
+
+ while (i >= 0)
+ {
+ GtkTextIter current;
+ GtkTextMark *foo_mark;
+
+ gtk_text_buffer_get_iter_at_char(buffer, &current, i);
+
+ if (!gtk_text_iter_equal(&iter, &current))
+ {
+ g_error("get_char_index didn't return current iter while going backward");
+ }
+ j = gtk_text_iter_get_char_index(&iter);
+
+ if (i != j)
+ {
+ g_error("going backward, iter converted to %d not %d", j, i);
+ }
+
+ /* get/set mark */
+ gtk_text_buffer_get_iter_at_mark(buffer, &mark, bar_mark);
+
+ if (!gtk_text_iter_equal(&iter, &mark))
+ {
+ gtk_text_iter_spew(&iter, "iter");
+ gtk_text_iter_spew(&mark, "mark");
+ g_error("Mark not moved to the right place.");
+ }
+
+ foo_mark = gtk_text_buffer_create_mark(buffer, "foo", &iter, FALSE);
+ gtk_text_buffer_get_iter_at_mark(buffer, &mark, foo_mark);
+ gtk_text_buffer_delete_mark(buffer, foo_mark);
+
+ if (!gtk_text_iter_equal(&iter, &mark))
+ {
+ gtk_text_iter_spew(&iter, "iter");
+ gtk_text_iter_spew(&mark, "mark");
+ g_error("Mark not created in the right place.");
+ }
+
+ if (i > 0)
+ {
+ if (!gtk_text_iter_backward_char(&iter))
+ g_error("iterators ran out before char indexes");
+
+ gtk_text_buffer_move_mark(buffer, bar_mark, &iter);
+ }
+ else
+ {
+ if (gtk_text_iter_backward_char(&iter))
+ g_error("went backward from 0?");
+ }
+
+ --i;
+ }
+
+ if (!gtk_text_iter_equal(&iter, &start))
+ g_error("Iterating backward over all chars didn't end with the start iter");
+
+ /*
+ * Check that get_line_count returns the same number of lines
+ * as walking the tree by line
+ */
+ i = 1; /* include current (first) line */
+ gtk_text_buffer_get_iter_at_line(buffer, &iter, 0);
+ while (gtk_text_iter_forward_line(&iter))
+ ++i;
+
+ /* Add 1 to the line count, because 'i' counts the end-iterator line */
+ if (i != gtk_text_buffer_get_line_count(buffer) + 1)
+ g_error("Counted %d lines, buffer has %d", i,
+ gtk_text_buffer_get_line_count(buffer) + 1);
+}
+
+
+static char *book_closed_xpm[] = {
+"16 16 6 1",
+" c None s None",
+". c black",
+"X c red",
+"o c yellow",
+"O c #808080",
+"# c white",
+" ",
+" .. ",
+" ..XX. ",
+" ..XXXXX. ",
+" ..XXXXXXXX. ",
+".ooXXXXXXXXX. ",
+"..ooXXXXXXXXX. ",
+".X.ooXXXXXXXXX. ",
+".XX.ooXXXXXX.. ",
+" .XX.ooXXX..#O ",
+" .XX.oo..##OO. ",
+" .XX..##OO.. ",
+" .X.#OO.. ",
+" ..O.. ",
+" .. ",
+" "};
+
+static void
+fill_buffer(GtkTextBuffer *buffer)
+{
+ GtkTextTag *tag;
+ GdkColor color, color2;
+ GtkTextIter iter;
+ GtkTextIter iter2;
+ GdkPixmap *pixmap;
+ GdkBitmap *mask;
+ int i;
+
+ tag = gtk_text_buffer_create_tag(buffer, "fg_blue");
+
+ color.red = color.green = 0;
+ color.blue = 0xffff;
+ color2.red = 0xfff;
+ color2.blue = 0x0;
+ color2.green = 0;
+ gtk_object_set(GTK_OBJECT(tag),
+ "foreground_gdk", &color,
+ "background_gdk", &color2,
+ "font", "-*-courier-bold-r-*-*-30-*-*-*-*-*-*-*",
+ NULL);
+
+ tag = gtk_text_buffer_create_tag(buffer, "fg_red");
+
+ color.blue = color.green = 0;
+ color.red = 0xffff;
+ gtk_object_set(GTK_OBJECT(tag),
+ "offset", -4,
+ "foreground_gdk", &color,
+ NULL);
+
+ tag = gtk_text_buffer_create_tag(buffer, "bg_green");
+
+ color.blue = color.red = 0;
+ color.green = 0xffff;
+ gtk_object_set(GTK_OBJECT(tag),
+ "background_gdk", &color,
+ "font", "-*-courier-bold-r-*-*-10-*-*-*-*-*-*-*",
+ NULL);
+
+ pixmap = gdk_pixmap_colormap_create_from_xpm_d (NULL,
+ gtk_widget_get_default_colormap(),
+ &mask,
+ NULL, book_closed_xpm);
+
+ g_assert(pixmap != NULL);
+
+ i = 0;
+ while (i < 10)
+ {
+ gchar *str;
+
+ gtk_text_buffer_get_iter_at_char(buffer, &iter, 0);
+
+ gtk_text_buffer_insert_pixmap (buffer, &iter, pixmap, mask);
+
+ gtk_text_buffer_get_iter_at_char(buffer, &iter, 1);
+
+ gtk_text_buffer_insert_pixmap (buffer, &iter, pixmap, mask);
+
+ str = g_strdup_printf("%d Hello World!\nwoo woo woo woo woo woo woo woo\n",
+ i);
+
+ gtk_text_buffer_insert(buffer, &iter, str, -1);
+
+ g_free(str);
+
+ gtk_text_buffer_insert(buffer, &iter,
+ "(Hello World!)\nfoo foo Hello this is some text we are using to text word wrap. It has punctuation! gee; blah - hmm, great.\nnew line\n\n"
+ /* This is UTF8 stuff, Emacs doesn't
+ really know how to display it */
+ "Spanish (Español) ¡Hola! / French (Français) Bonjour, Salut / German (Deutsch Süd) Grüß Gott (testing Latin-1 chars encoded in UTF8)\nThai (we can't display this, just making sure we don't crash) (ภาษาไทย) สวัสดีครับ, สวัสดีค่ะ\n",
+ -1);
+
+ gtk_text_buffer_insert_pixmap (buffer, &iter, pixmap, mask);
+ gtk_text_buffer_insert_pixmap (buffer, &iter, pixmap, mask);
+
+ gtk_text_buffer_get_iter_at_char(buffer, &iter, 4);
+
+ gtk_text_buffer_insert_pixmap (buffer, &iter, pixmap, mask);
+
+ gtk_text_buffer_get_iter_at_char(buffer, &iter, 7);
+
+ gtk_text_buffer_insert_pixmap (buffer, &iter, pixmap, mask);
+
+ gtk_text_buffer_get_iter_at_char(buffer, &iter, 8);
+
+ gtk_text_buffer_insert_pixmap (buffer, &iter, pixmap, mask);
+
+ gtk_text_buffer_get_iter_at_line_char(buffer, &iter, 0, 8);
+ iter2 = iter;
+ gtk_text_iter_forward_chars(&iter2, 10);
+
+ gtk_text_buffer_apply_tag(buffer, "fg_blue", &iter, &iter2);
+
+ gtk_text_iter_forward_chars(&iter, 7);
+ gtk_text_iter_forward_chars(&iter2, 10);
+
+ gtk_text_buffer_apply_tag(buffer, "bg_green", &iter, &iter2);
+
+ gtk_text_iter_forward_chars(&iter, 12);
+ gtk_text_iter_forward_chars(&iter2, 10);
+
+ gtk_text_buffer_apply_tag(buffer, "bg_green", &iter, &iter2);
+
+ gtk_text_iter_forward_chars(&iter, 10);
+ gtk_text_iter_forward_chars(&iter2, 15);
+
+ gtk_text_buffer_apply_tag(buffer, "fg_red", &iter, &iter2);
+ gtk_text_buffer_apply_tag(buffer, "fg_blue", &iter, &iter2);
+
+ gtk_text_iter_forward_chars(&iter, 20);
+ gtk_text_iter_forward_chars(&iter2, 20);
+
+ gtk_text_buffer_apply_tag(buffer, "fg_red", &iter, &iter2);
+ gtk_text_buffer_apply_tag(buffer, "fg_blue", &iter, &iter2);
+
+ gtk_text_iter_backward_chars(&iter, 25);
+ gtk_text_iter_forward_chars(&iter2, 5);
+
+ gtk_text_buffer_apply_tag(buffer, "fg_red", &iter, &iter2);
+ gtk_text_buffer_apply_tag(buffer, "fg_blue", &iter, &iter2);
+
+ gtk_text_iter_forward_chars(&iter, 15);
+ gtk_text_iter_backward_chars(&iter2, 10);
+
+ gtk_text_buffer_remove_tag(buffer, "fg_red", &iter, &iter2);
+ gtk_text_buffer_remove_tag(buffer, "fg_blue", &iter, &iter2);
+
+ ++i;
+ }
+
+ gdk_pixmap_unref(pixmap);
+ if (mask)
+ gdk_bitmap_unref(mask);
+}
+
+