make it a static function

2000-10-24  Havoc Pennington  <hp@redhat.com>

	* gtk/gtktextview.c (gtk_text_view_scroll_to_mark_adjusted): make
	it a static function

	* gtk/gtktextbtree.c (gtk_text_btree_tag): Gee, maybe we should
	redraw text when a tag is applied to it.

	* gtk/gtktexttag.c (gtk_text_tag_affects_size)
	(gtk_text_tag_affects_nonsize_appearance): private functions to
	see if a tag requires various kinds of redraw/layout to be queued
	up.

	* gtk/gtktexttag.h (struct _GtkTextTag): Remove relief crackrock

	* gtk/testtext.c (fill_example_buffer): Put the cursor
	at the start of the buffer, so search works by default

	* gtk/gtktextiter.c (lines_match): init match_start always

	* gtk/gtktextbuffer.c (gtk_text_buffer_get_iter_at_line_index): New
	function, get iter at a line + a byte index

	* gtk/gtktextiter.c (gtk_text_iter_set_line_index): New function,
	to set byte position within a line
	(gtk_text_iter_check): remove leftover G_BREAKPOINT thing
This commit is contained in:
Havoc Pennington 2000-10-24 22:44:14 +00:00 committed by Havoc Pennington
parent 873b316f23
commit 2fab0eb1fa
23 changed files with 623 additions and 212 deletions

View File

@ -1,3 +1,30 @@
2000-10-24 Havoc Pennington <hp@redhat.com>
* gtk/gtktextview.c (gtk_text_view_scroll_to_mark_adjusted): make
it a static function
* gtk/gtktextbtree.c (gtk_text_btree_tag): Gee, maybe we should
redraw text when a tag is applied to it.
* gtk/gtktexttag.c (gtk_text_tag_affects_size)
(gtk_text_tag_affects_nonsize_appearance): private functions to
see if a tag requires various kinds of redraw/layout to be queued
up.
* gtk/gtktexttag.h (struct _GtkTextTag): Remove relief crackrock
* gtk/testtext.c (fill_example_buffer): Put the cursor
at the start of the buffer, so search works by default
* gtk/gtktextiter.c (lines_match): init match_start always
* gtk/gtktextbuffer.c (gtk_text_buffer_get_iter_at_line_index): New
function, get iter at a line + a byte index
* gtk/gtktextiter.c (gtk_text_iter_set_line_index): New function,
to set byte position within a line
(gtk_text_iter_check): remove leftover G_BREAKPOINT thing
2000-10-23 Havoc Pennington <hp@redhat.com>
* gtk/testtext.c: Re-enable the "find" dialog

View File

@ -1,3 +1,30 @@
2000-10-24 Havoc Pennington <hp@redhat.com>
* gtk/gtktextview.c (gtk_text_view_scroll_to_mark_adjusted): make
it a static function
* gtk/gtktextbtree.c (gtk_text_btree_tag): Gee, maybe we should
redraw text when a tag is applied to it.
* gtk/gtktexttag.c (gtk_text_tag_affects_size)
(gtk_text_tag_affects_nonsize_appearance): private functions to
see if a tag requires various kinds of redraw/layout to be queued
up.
* gtk/gtktexttag.h (struct _GtkTextTag): Remove relief crackrock
* gtk/testtext.c (fill_example_buffer): Put the cursor
at the start of the buffer, so search works by default
* gtk/gtktextiter.c (lines_match): init match_start always
* gtk/gtktextbuffer.c (gtk_text_buffer_get_iter_at_line_index): New
function, get iter at a line + a byte index
* gtk/gtktextiter.c (gtk_text_iter_set_line_index): New function,
to set byte position within a line
(gtk_text_iter_check): remove leftover G_BREAKPOINT thing
2000-10-23 Havoc Pennington <hp@redhat.com>
* gtk/testtext.c: Re-enable the "find" dialog

View File

@ -1,3 +1,30 @@
2000-10-24 Havoc Pennington <hp@redhat.com>
* gtk/gtktextview.c (gtk_text_view_scroll_to_mark_adjusted): make
it a static function
* gtk/gtktextbtree.c (gtk_text_btree_tag): Gee, maybe we should
redraw text when a tag is applied to it.
* gtk/gtktexttag.c (gtk_text_tag_affects_size)
(gtk_text_tag_affects_nonsize_appearance): private functions to
see if a tag requires various kinds of redraw/layout to be queued
up.
* gtk/gtktexttag.h (struct _GtkTextTag): Remove relief crackrock
* gtk/testtext.c (fill_example_buffer): Put the cursor
at the start of the buffer, so search works by default
* gtk/gtktextiter.c (lines_match): init match_start always
* gtk/gtktextbuffer.c (gtk_text_buffer_get_iter_at_line_index): New
function, get iter at a line + a byte index
* gtk/gtktextiter.c (gtk_text_iter_set_line_index): New function,
to set byte position within a line
(gtk_text_iter_check): remove leftover G_BREAKPOINT thing
2000-10-23 Havoc Pennington <hp@redhat.com>
* gtk/testtext.c: Re-enable the "find" dialog

View File

@ -1,3 +1,30 @@
2000-10-24 Havoc Pennington <hp@redhat.com>
* gtk/gtktextview.c (gtk_text_view_scroll_to_mark_adjusted): make
it a static function
* gtk/gtktextbtree.c (gtk_text_btree_tag): Gee, maybe we should
redraw text when a tag is applied to it.
* gtk/gtktexttag.c (gtk_text_tag_affects_size)
(gtk_text_tag_affects_nonsize_appearance): private functions to
see if a tag requires various kinds of redraw/layout to be queued
up.
* gtk/gtktexttag.h (struct _GtkTextTag): Remove relief crackrock
* gtk/testtext.c (fill_example_buffer): Put the cursor
at the start of the buffer, so search works by default
* gtk/gtktextiter.c (lines_match): init match_start always
* gtk/gtktextbuffer.c (gtk_text_buffer_get_iter_at_line_index): New
function, get iter at a line + a byte index
* gtk/gtktextiter.c (gtk_text_iter_set_line_index): New function,
to set byte position within a line
(gtk_text_iter_check): remove leftover G_BREAKPOINT thing
2000-10-23 Havoc Pennington <hp@redhat.com>
* gtk/testtext.c: Re-enable the "find" dialog

View File

@ -1,3 +1,30 @@
2000-10-24 Havoc Pennington <hp@redhat.com>
* gtk/gtktextview.c (gtk_text_view_scroll_to_mark_adjusted): make
it a static function
* gtk/gtktextbtree.c (gtk_text_btree_tag): Gee, maybe we should
redraw text when a tag is applied to it.
* gtk/gtktexttag.c (gtk_text_tag_affects_size)
(gtk_text_tag_affects_nonsize_appearance): private functions to
see if a tag requires various kinds of redraw/layout to be queued
up.
* gtk/gtktexttag.h (struct _GtkTextTag): Remove relief crackrock
* gtk/testtext.c (fill_example_buffer): Put the cursor
at the start of the buffer, so search works by default
* gtk/gtktextiter.c (lines_match): init match_start always
* gtk/gtktextbuffer.c (gtk_text_buffer_get_iter_at_line_index): New
function, get iter at a line + a byte index
* gtk/gtktextiter.c (gtk_text_iter_set_line_index): New function,
to set byte position within a line
(gtk_text_iter_check): remove leftover G_BREAKPOINT thing
2000-10-23 Havoc Pennington <hp@redhat.com>
* gtk/testtext.c: Re-enable the "find" dialog

View File

@ -1,3 +1,30 @@
2000-10-24 Havoc Pennington <hp@redhat.com>
* gtk/gtktextview.c (gtk_text_view_scroll_to_mark_adjusted): make
it a static function
* gtk/gtktextbtree.c (gtk_text_btree_tag): Gee, maybe we should
redraw text when a tag is applied to it.
* gtk/gtktexttag.c (gtk_text_tag_affects_size)
(gtk_text_tag_affects_nonsize_appearance): private functions to
see if a tag requires various kinds of redraw/layout to be queued
up.
* gtk/gtktexttag.h (struct _GtkTextTag): Remove relief crackrock
* gtk/testtext.c (fill_example_buffer): Put the cursor
at the start of the buffer, so search works by default
* gtk/gtktextiter.c (lines_match): init match_start always
* gtk/gtktextbuffer.c (gtk_text_buffer_get_iter_at_line_index): New
function, get iter at a line + a byte index
* gtk/gtktextiter.c (gtk_text_iter_set_line_index): New function,
to set byte position within a line
(gtk_text_iter_check): remove leftover G_BREAKPOINT thing
2000-10-23 Havoc Pennington <hp@redhat.com>
* gtk/testtext.c: Re-enable the "find" dialog

View File

@ -1,3 +1,30 @@
2000-10-24 Havoc Pennington <hp@redhat.com>
* gtk/gtktextview.c (gtk_text_view_scroll_to_mark_adjusted): make
it a static function
* gtk/gtktextbtree.c (gtk_text_btree_tag): Gee, maybe we should
redraw text when a tag is applied to it.
* gtk/gtktexttag.c (gtk_text_tag_affects_size)
(gtk_text_tag_affects_nonsize_appearance): private functions to
see if a tag requires various kinds of redraw/layout to be queued
up.
* gtk/gtktexttag.h (struct _GtkTextTag): Remove relief crackrock
* gtk/testtext.c (fill_example_buffer): Put the cursor
at the start of the buffer, so search works by default
* gtk/gtktextiter.c (lines_match): init match_start always
* gtk/gtktextbuffer.c (gtk_text_buffer_get_iter_at_line_index): New
function, get iter at a line + a byte index
* gtk/gtktextiter.c (gtk_text_iter_set_line_index): New function,
to set byte position within a line
(gtk_text_iter_check): remove leftover G_BREAKPOINT thing
2000-10-23 Havoc Pennington <hp@redhat.com>
* gtk/testtext.c: Re-enable the "find" dialog

View File

@ -1,3 +1,7 @@
2000-10-24 Havoc Pennington <hp@redhat.com>
* gtk/text_widget.sgml: add note about UTF-8
2000-10-23 Havoc Pennington <hp@redhat.com>
* gtk/gtk-sections.txt: remove GtkTextBTree

View File

@ -21,6 +21,16 @@ display a <link linkend="GtkTextBuffer">GtkTextBuffer</link>. Each buffer can be
displayed by any number of views.
</para>
<para>
One of the important things to remember about text in GTK+ is that it's in the
UTF-8 encoding. This means that one character can be encoded as multiple
bytes. Character counts are usually referred to as
<firstterm>offsets</firstterm>, while byte counts are called
<firstterm>indexes</firstterm>. If you confuse these two, things will work fine
with ASCII, but as soon as your buffer contains multibyte characters, bad things
will happen.
</para>
<para>
Text in a buffer can be marked with <firstterm>tags</firstterm>. A tag is an
attribute that can be applied to some range of text. For example, a tag might be

View File

@ -172,8 +172,8 @@ struct _GtkTextBTree {
GtkTextTagTable *table;
GHashTable *mark_table;
guint refcount;
GtkTextLineSegment *insert_mark;
GtkTextLineSegment *selection_bound_mark;
GtkTextMark *insert_mark;
GtkTextMark *selection_bound_mark;
GtkTextBuffer *buffer;
BTreeView *views;
GSList *tag_infos;
@ -321,6 +321,9 @@ static GtkTextTagInfo *gtk_text_btree_get_existing_tag_info (GtkTextBTree *tre
static void gtk_text_btree_remove_tag_info (GtkTextBTree *tree,
GtkTextTag *tag);
static void redisplay_region (GtkTextBTree *tree,
const GtkTextIter *start,
const GtkTextIter *end);
/* Inline thingies */
@ -421,33 +424,36 @@ gtk_text_btree_new (GtkTextTagTable *table,
{
GtkTextIter start;
GtkTextLineSegment *seg;
gtk_text_btree_get_iter_at_line_char(tree, &start, 0, 0);
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 =
(GtkTextLineSegment*) gtk_text_btree_set_mark(tree,
NULL,
"selection_bound",
FALSE,
&start,
FALSE);
tree->insert_mark = gtk_text_btree_set_mark (tree,
NULL,
"insert",
FALSE,
&start,
FALSE);
tree->selection_bound_mark->body.mark.not_deleteable = TRUE;
seg = tree->insert_mark->segment;
_mark_segment_ref(tree->insert_mark);
_mark_segment_ref(tree->selection_bound_mark);
seg->body.mark.not_deleteable = TRUE;
seg->body.mark.visible = TRUE;
tree->selection_bound_mark = gtk_text_btree_set_mark (tree,
NULL,
"selection_bound",
FALSE,
&start,
FALSE);
seg = tree->selection_bound_mark->segment;
seg->body.mark.not_deleteable = TRUE;
g_object_ref (G_OBJECT (tree->insert_mark));
g_object_ref (G_OBJECT (tree->selection_bound_mark));
}
tree->refcount = 1;
@ -467,7 +473,11 @@ gtk_text_btree_ref (GtkTextBTree *tree)
static void
mark_destroy_foreach (gpointer key, gpointer value, gpointer user_data)
{
_mark_segment_unref (value);
GtkTextLineSegment *seg = value;
g_return_if_fail (seg->body.mark.tree == NULL);
g_object_unref (G_OBJECT (seg->body.mark.obj));
}
void
@ -479,26 +489,26 @@ gtk_text_btree_unref (GtkTextBTree *tree)
tree->refcount -= 1;
if (tree->refcount == 0)
{
gtk_text_btree_node_destroy(tree, tree->root_node);
{
gtk_text_btree_node_destroy (tree, tree->root_node);
g_hash_table_foreach(tree->mark_table,
mark_destroy_foreach,
NULL);
g_hash_table_destroy(tree->mark_table);
g_hash_table_foreach (tree->mark_table,
mark_destroy_foreach,
NULL);
g_hash_table_destroy (tree->mark_table);
_mark_segment_unref(tree->insert_mark);
_mark_segment_unref(tree->selection_bound_mark);
g_object_unref (G_OBJECT (tree->insert_mark));
g_object_unref (G_OBJECT (tree->selection_bound_mark));
gtk_signal_disconnect(GTK_OBJECT(tree->table),
tree->tag_changed_handler);
gtk_signal_disconnect (GTK_OBJECT(tree->table),
tree->tag_changed_handler);
gtk_signal_disconnect(GTK_OBJECT(tree->table),
tree->tag_removed_handler);
gtk_signal_disconnect (GTK_OBJECT(tree->table),
tree->tag_removed_handler);
gtk_object_unref(GTK_OBJECT(tree->table));
gtk_object_unref (GTK_OBJECT(tree->table));
g_free(tree);
g_free (tree);
}
}
@ -1382,8 +1392,8 @@ gtk_text_btree_get_view_size (GtkTextBTree *tree,
g_return_if_fail(tree != NULL);
g_return_if_fail(view_id != NULL);
gtk_text_btree_node_get_size(tree->root_node, view_id,
width, height);
gtk_text_btree_node_get_size (tree->root_node, view_id,
width, height);
}
/*
@ -1461,6 +1471,26 @@ iter_stack_invert(IterStack *stack)
}
}
static void
queue_tag_redisplay (GtkTextBTree *tree,
GtkTextTag *tag,
const GtkTextIter *start,
const GtkTextIter *end)
{
if (gtk_text_tag_affects_size (tag))
{
gtk_text_btree_invalidate_region (tree, start, end);
}
else if (gtk_text_tag_affects_nonsize_appearance (tag))
{
/* We only need to queue a redraw, not a relayout */
redisplay_region (tree, start, end);
}
/* We don't need to do anything if the tag doesn't affect display */
}
void
gtk_text_btree_tag (const GtkTextIter *start_orig,
const GtkTextIter *end_orig,
@ -1502,6 +1532,8 @@ gtk_text_btree_tag (const GtkTextIter *start_orig,
tree = gtk_text_iter_get_btree(&start);
queue_tag_redisplay (tree, tag, &start, &end);
info = gtk_text_btree_get_tag_info(tree, tag);
start_line = gtk_text_iter_get_text_line(&start);
@ -2311,21 +2343,23 @@ redisplay_region (GtkTextBTree *tree,
if (ld)
end_y += ld->height;
gtk_text_layout_changed (view->layout, start_y, end_y - start_y, end_y - start_y);
gtk_text_layout_changed (view->layout, start_y,
end_y - start_y,
end_y - start_y);
view = view->next;
}
}
static void
redisplay_mark(GtkTextLineSegment *mark)
redisplay_mark (GtkTextLineSegment *mark)
{
GtkTextIter iter;
GtkTextIter end;
gtk_text_btree_get_iter_at_mark(mark->body.mark.tree,
&iter,
(GtkTextMark*)mark);
mark->body.mark.obj);
end = iter;
gtk_text_iter_next_char(&end);
@ -2370,10 +2404,10 @@ real_set_mark(GtkTextBTree *tree,
g_return_val_if_fail(gtk_text_iter_get_btree(where) == tree, NULL);
if (existing_mark)
mark = (GtkTextLineSegment*) existing_mark;
mark = existing_mark->segment;
else if (name != NULL)
mark = g_hash_table_lookup(tree->mark_table,
name);
mark = g_hash_table_lookup (tree->mark_table,
name);
else
mark = NULL;
@ -2391,12 +2425,13 @@ real_set_mark(GtkTextBTree *tree,
if (mark != NULL)
{
if (redraw_selections &&
(mark == tree->insert_mark ||
mark == tree->selection_bound_mark))
(mark == tree->insert_mark->segment ||
mark == tree->selection_bound_mark->segment))
{
GtkTextIter old_pos;
gtk_text_btree_get_iter_at_mark (tree, &old_pos, (GtkTextMark*)mark);
gtk_text_btree_get_iter_at_mark (tree, &old_pos,
mark->body.mark.obj);
redisplay_region (tree, &old_pos, where);
}
@ -2411,7 +2446,7 @@ real_set_mark(GtkTextBTree *tree,
}
/* Redraw the mark's old location. */
redisplay_mark_if_visible(mark);
redisplay_mark_if_visible (mark);
/* Unlink mark from its current location.
This could hose our iterator... */
@ -2432,22 +2467,22 @@ real_set_mark(GtkTextBTree *tree,
mark->body.mark.line = gtk_text_iter_get_text_line(&iter);
if (mark->body.mark.name)
g_hash_table_insert(tree->mark_table,
mark->body.mark.name,
mark);
g_hash_table_insert (tree->mark_table,
mark->body.mark.name,
mark);
}
/* Link mark into new location */
gtk_text_btree_link_segment(mark, &iter);
gtk_text_btree_link_segment (mark, &iter);
/* Invalidate some iterators. */
segments_changed(tree);
segments_changed (tree);
/*
* update the screen at the mark's new location.
*/
redisplay_mark_if_visible(mark);
redisplay_mark_if_visible (mark);
return mark;
}
@ -2461,9 +2496,13 @@ gtk_text_btree_set_mark (GtkTextBTree *tree,
const GtkTextIter *iter,
gboolean should_exist)
{
return (GtkTextMark*)real_set_mark(tree, existing_mark,
name, left_gravity, iter, should_exist,
TRUE);
GtkTextLineSegment *seg;
seg = real_set_mark(tree, existing_mark,
name, left_gravity, iter, should_exist,
TRUE);
return seg ? seg->body.mark.obj : NULL;
}
gboolean
@ -2474,9 +2513,9 @@ gtk_text_btree_get_selection_bounds (GtkTextBTree *tree,
GtkTextIter tmp_start, tmp_end;
gtk_text_btree_get_iter_at_mark (tree, &tmp_start,
(GtkTextMark*)tree->insert_mark);
tree->insert_mark);
gtk_text_btree_get_iter_at_mark (tree, &tmp_end,
(GtkTextMark*)tree->selection_bound_mark);
tree->selection_bound_mark);
if (gtk_text_iter_equal(&tmp_start, &tmp_end))
{
@ -2512,10 +2551,10 @@ gtk_text_btree_place_cursor(GtkTextBTree *tree,
redisplay_region(tree, &start, &end);
/* Move insert AND selection_bound before we redisplay */
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);
real_set_mark (tree, tree->insert_mark,
"insert", FALSE, iter, TRUE, FALSE);
real_set_mark (tree, tree->selection_bound_mark,
"selection_bound", FALSE, iter, TRUE, FALSE);
}
void
@ -2537,11 +2576,13 @@ void
gtk_text_btree_remove_mark (GtkTextBTree *tree,
GtkTextMark *mark)
{
GtkTextLineSegment *segment = (GtkTextLineSegment*) mark;
GtkTextLineSegment *segment;
g_return_if_fail (segment != NULL);
g_return_if_fail (mark != NULL);
g_return_if_fail (tree != NULL);
segment = mark->segment;
if (segment->body.mark.not_deleteable)
{
g_warning("Can't delete special mark `%s'", segment->body.mark.name);
@ -2553,8 +2594,9 @@ gtk_text_btree_remove_mark (GtkTextBTree *tree,
if (segment->body.mark.name)
g_hash_table_remove (tree->mark_table, segment->body.mark.name);
_mark_segment_unref (segment);
/* Remove the ref on the mark that belonged to the segment. */
g_object_unref (G_OBJECT (mark));
segment->body.mark.tree = NULL;
segment->body.mark.line = NULL;
@ -2564,24 +2606,28 @@ gboolean
gtk_text_btree_mark_is_insert (GtkTextBTree *tree,
GtkTextMark *segment)
{
return segment == (GtkTextMark*) tree->insert_mark;
return segment == tree->insert_mark;
}
gboolean
gtk_text_btree_mark_is_selection_bound (GtkTextBTree *tree,
GtkTextMark *segment)
{
return segment == (GtkTextMark*) tree->selection_bound_mark;
return segment == tree->selection_bound_mark;
}
GtkTextMark*
gtk_text_btree_get_mark_by_name (GtkTextBTree *tree,
const gchar *name)
{
GtkTextLineSegment *seg;
g_return_val_if_fail(tree != NULL, NULL);
g_return_val_if_fail(name != NULL, NULL);
return g_hash_table_lookup(tree->mark_table, name);
seg = g_hash_table_lookup (tree->mark_table, name);
return seg ? seg->body.mark.obj : NULL;
}
void
@ -2592,7 +2638,7 @@ gtk_text_mark_set_visible (GtkTextMark *mark,
g_return_if_fail(mark != NULL);
seg = (GtkTextLineSegment*)mark;
seg = mark->segment;
if (seg->body.mark.visible == setting)
return;
@ -4964,7 +5010,15 @@ gtk_text_btree_node_destroy(GtkTextBTree *tree, GtkTextBTreeNode *node)
{
seg = line->segments;
line->segments = seg->next;
(*seg->type->deleteFunc)(seg, line, 1);
if (GTK_IS_TEXT_MARK_SEGMENT (seg))
{
/* Set the mark as deleted */
seg->body.mark.tree = NULL;
seg->body.mark.line = NULL;
}
(*seg->type->deleteFunc) (seg, line, 1);
}
gtk_text_line_destroy(tree, line);
}
@ -4977,12 +5031,13 @@ gtk_text_btree_node_destroy(GtkTextBTree *tree, GtkTextBTreeNode *node)
{
childPtr = node->children.node;
node->children.node = childPtr->next;
gtk_text_btree_node_destroy(tree, childPtr);
gtk_text_btree_node_destroy (tree, childPtr);
}
}
summary_list_destroy(node->summary);
node_data_list_destroy(node->node_data);
g_free(node);
summary_list_destroy (node->summary);
node_data_list_destroy (node->node_data);
g_free (node);
}
static NodeData*
@ -5111,15 +5166,16 @@ get_tree_bounds(GtkTextBTree *tree,
}
static void
tag_changed_cb(GtkTextTagTable *table,
GtkTextTag *tag,
gboolean size_changed,
GtkTextBTree *tree)
tag_changed_cb (GtkTextTagTable *table,
GtkTextTag *tag,
gboolean size_changed,
GtkTextBTree *tree)
{
if (size_changed)
{
/* We need to queue a redisplay on all regions that are tagged with
this tag. */
/* We need to queue a relayout on all regions that are tagged with
* this tag.
*/
GtkTextIter start;
GtkTextIter end;
@ -5127,14 +5183,15 @@ tag_changed_cb(GtkTextTagTable *table,
if (gtk_text_btree_get_iter_at_first_toggle(tree, &start, tag))
{
/* Must be a last toggle if there was a first one. */
gtk_text_btree_get_iter_at_last_toggle(tree, &end, tag);
gtk_text_btree_invalidate_region(tree,
&start, &end);
gtk_text_btree_get_iter_at_last_toggle (tree, &end, tag);
gtk_text_btree_invalidate_region (tree,
&start, &end);
}
}
else
{
/* We only need to queue a redraw, not a relayout */
BTreeView *view;
view = tree->views;

View File

@ -1072,14 +1072,14 @@ gtk_text_buffer_mark_set (GtkTextBuffer *buffer,
this signal is purely for notification, and not to allow users
to modify the default behavior. */
gtk_text_mark_ref (mark);
g_object_ref (G_OBJECT (mark));
gtk_signal_emit(GTK_OBJECT(buffer),
signals[MARK_SET],
location,
mark);
gtk_text_mark_unref (mark);
g_object_unref (G_OBJECT (mark));
}
/**
@ -1107,12 +1107,12 @@ gtk_text_buffer_set_mark (GtkTextBuffer *buffer,
GtkTextIter location;
GtkTextMark *mark;
mark = gtk_text_btree_set_mark(get_btree (buffer),
existing_mark,
mark_name,
left_gravity,
iter,
should_exist);
mark = gtk_text_btree_set_mark (get_btree (buffer),
existing_mark,
mark_name,
left_gravity,
iter,
should_exist);
if (gtk_text_btree_mark_is_insert(get_btree (buffer), mark) ||
gtk_text_btree_mark_is_selection_bound (get_btree (buffer), mark))
@ -1126,7 +1126,7 @@ gtk_text_buffer_set_mark (GtkTextBuffer *buffer,
gtk_text_buffer_mark_set (buffer, &location, mark);
return (GtkTextMark*)mark;
return mark;
}
/**
@ -1182,7 +1182,7 @@ gtk_text_buffer_move_mark (GtkTextBuffer *buffer,
GtkTextMark *mark,
const GtkTextIter *where)
{
g_return_if_fail (mark != NULL);
g_return_if_fail (GTK_IS_TEXT_MARK (mark));
g_return_if_fail (!gtk_text_mark_get_deleted (mark));
g_return_if_fail (GTK_IS_TEXT_BUFFER(buffer));
@ -1202,7 +1202,7 @@ gtk_text_buffer_get_iter_at_mark (GtkTextBuffer *buffer,
GtkTextIter *iter,
GtkTextMark *mark)
{
g_return_if_fail (mark != NULL);
g_return_if_fail (GTK_IS_TEXT_MARK (mark));
g_return_if_fail (!gtk_text_mark_get_deleted (mark));
g_return_if_fail (GTK_IS_TEXT_BUFFER(buffer));
@ -1218,7 +1218,7 @@ gtk_text_buffer_get_iter_at_mark (GtkTextBuffer *buffer,
*
* Deletes @mark, so that it's no longer located anywhere in the
* buffer. Removes the reference the buffer holds to the mark, so if
* you haven't called gtk_text_mark_ref() the mark will be freed. Even
* you haven't called g_object_ref() on the mark, it will be freed. Even
* if the mark isn't freed, most operations on @mark become
* invalid. There is no way to undelete a
* mark. gtk_text_mark_get_deleted() will return TRUE after this
@ -1230,11 +1230,11 @@ void
gtk_text_buffer_delete_mark(GtkTextBuffer *buffer,
GtkTextMark *mark)
{
g_return_if_fail (mark != NULL);
g_return_if_fail (GTK_IS_TEXT_MARK (mark));
g_return_if_fail (!gtk_text_mark_get_deleted (mark));
g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
gtk_text_mark_ref (mark);
g_object_ref (G_OBJECT (mark));
gtk_text_btree_remove_mark (get_btree (buffer), mark);
@ -1245,7 +1245,7 @@ gtk_text_buffer_delete_mark(GtkTextBuffer *buffer,
gtk_signal_emit (GTK_OBJECT(buffer), signals[MARK_DELETED],
mark);
gtk_text_mark_unref (mark);
g_object_unref (G_OBJECT (mark));
}
/**
@ -1616,11 +1616,24 @@ gtk_text_buffer_get_iter_at_line_offset (GtkTextBuffer *buffer,
gint line_number,
gint char_offset)
{
g_return_if_fail(iter != NULL);
g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
g_return_if_fail (iter != NULL);
g_return_if_fail (GTK_IS_TEXT_BUFFER(buffer));
gtk_text_btree_get_iter_at_line_char(get_btree (buffer),
iter, line_number, char_offset);
gtk_text_btree_get_iter_at_line_char (get_btree (buffer),
iter, line_number, char_offset);
}
void
gtk_text_buffer_get_iter_at_line_index (GtkTextBuffer *buffer,
GtkTextIter *iter,
gint line_number,
gint byte_index)
{
g_return_if_fail (iter != NULL);
g_return_if_fail (GTK_IS_TEXT_BUFFER(buffer));
gtk_text_btree_get_iter_at_line_byte (get_btree (buffer),
iter, line_number, byte_index);
}
void

View File

@ -263,6 +263,10 @@ void gtk_text_buffer_get_iter_at_line_offset (GtkTextBuffer *buffer,
GtkTextIter *iter,
gint line_number,
gint char_offset);
void gtk_text_buffer_get_iter_at_line_index (GtkTextBuffer *buffer,
GtkTextIter *iter,
gint line_number,
gint byte_index);
void gtk_text_buffer_get_iter_at_offset (GtkTextBuffer *buffer,
GtkTextIter *iter,
gint char_offset);

View File

@ -134,7 +134,7 @@ iter_set_from_segment(GtkTextRealIter *iter,
seg = seg->next;
}
iter_set_from_byte_offset(iter, line, byte_offset);
iter_set_from_byte_offset (iter, line, byte_offset);
}
/* This function ensures that the segment-dependent information is
@ -667,7 +667,7 @@ gtk_text_iter_get_line_offset(const GtkTextIter *iter)
* Return value: distance from start of line, in bytes
**/
gint
gtk_text_iter_get_line_index(const GtkTextIter *iter)
gtk_text_iter_get_line_index (const GtkTextIter *iter)
{
GtkTextRealIter *real;
@ -898,7 +898,7 @@ gtk_text_iter_get_marks (const GtkTextIter *iter)
{
if (seg->type == &gtk_text_left_mark_type ||
seg->type == &gtk_text_right_mark_type)
retval = g_slist_prepend(retval, (GtkTextMark*)seg);
retval = g_slist_prepend (retval, seg->body.mark.obj);
seg = seg->next;
}
@ -2477,7 +2477,35 @@ gtk_text_iter_set_line_offset(GtkTextIter *iter,
}
void
gtk_text_iter_set_line(GtkTextIter *iter, gint line_number)
gtk_text_iter_set_line_index (GtkTextIter *iter,
gint byte_on_line)
{
GtkTextRealIter *real;
g_return_if_fail (iter != NULL);
real = gtk_text_iter_make_surreal (iter);
if (real == NULL)
return;
check_invariants (iter);
iter_set_from_byte_offset (real, real->line, byte_on_line);
if (real->segment->type == &gtk_text_char_type &&
(real->segment->body.chars[real->segment_byte_offset] & 0xc0) == 0x80)
g_warning ("%s: Incorrect byte offset %d falls in the middle of a UTF-8 "
"character; this will crash the text buffer. "
"Byte indexes must refer to the start of a character.",
G_STRLOC, byte_on_line);
check_invariants (iter);
}
void
gtk_text_iter_set_line (GtkTextIter *iter,
gint line_number)
{
GtkTextLine *line;
gint real_line;
@ -2861,6 +2889,9 @@ lines_match (const GtkTextIter *start,
if (*lines == NULL || **lines == '\0')
{
if (match_start)
*match_start = *start;
if (match_end)
*match_end = *start;
return TRUE;
@ -2904,7 +2935,7 @@ lines_match (const GtkTextIter *start,
}
if (found == NULL)
{
{
g_free (line_text);
return FALSE;
}
@ -2924,7 +2955,7 @@ lines_match (const GtkTextIter *start,
forward_chars_with_skipping (match_start, offset,
visible_only, !slice);
}
/* Go to end of search string */
offset += g_utf8_strlen (*lines, -1);
@ -3234,9 +3265,9 @@ gtk_text_btree_get_iter_at_line_char (GtkTextBTree *tree,
void
gtk_text_btree_get_iter_at_line_byte (GtkTextBTree *tree,
GtkTextIter *iter,
gint line_number,
gint byte_index)
GtkTextIter *iter,
gint line_number,
gint byte_index)
{
GtkTextRealIter *real = (GtkTextRealIter*)iter;
GtkTextLine *line;
@ -3252,6 +3283,13 @@ gtk_text_btree_get_iter_at_line_byte (GtkTextBTree *tree,
/* We might as well cache this, since we know it. */
real->cached_line_number = real_line;
if (real->segment->type == &gtk_text_char_type &&
(real->segment->body.chars[real->segment_byte_offset] & 0xc0) == 0x80)
g_warning ("%s: Incorrect byte offset %d falls in the middle of a UTF-8 "
"character; this will crash the text buffer. "
"Byte indexes must refer to the start of a character.",
G_STRLOC, byte_index);
check_invariants(iter);
}
@ -3336,32 +3374,34 @@ gtk_text_btree_get_iter_at_mark_name (GtkTextBTree *tree,
g_return_val_if_fail(iter != NULL, FALSE);
g_return_val_if_fail(tree != NULL, FALSE);
mark = gtk_text_btree_get_mark_by_name(tree, mark_name);
mark = gtk_text_btree_get_mark_by_name (tree, mark_name);
if (mark == NULL)
return FALSE;
else
{
gtk_text_btree_get_iter_at_mark(tree, iter, mark);
check_invariants(iter);
gtk_text_btree_get_iter_at_mark (tree, iter, mark);
check_invariants (iter);
return TRUE;
}
}
void
gtk_text_btree_get_iter_at_mark (GtkTextBTree *tree,
GtkTextIter *iter,
GtkTextMark *mark)
GtkTextIter *iter,
GtkTextMark *mark)
{
GtkTextLineSegment *seg = (GtkTextLineSegment*) mark;
GtkTextLineSegment *seg;
g_return_if_fail(iter != NULL);
g_return_if_fail(tree != NULL);
g_return_if_fail(GTK_IS_TEXT_MARK (mark));
g_return_if_fail (iter != NULL);
g_return_if_fail (tree != NULL);
g_return_if_fail (GTK_IS_TEXT_MARK (mark));
seg = mark->segment;
iter_init_from_segment(iter, tree,
seg->body.mark.line, seg);
g_assert(seg->body.mark.line == gtk_text_iter_get_text_line(iter));
iter_init_from_segment (iter, tree,
seg->body.mark.line, seg);
g_assert (seg->body.mark.line == gtk_text_iter_get_text_line(iter));
check_invariants(iter);
}
@ -3431,10 +3471,6 @@ gtk_text_iter_check (const GtkTextIter *iter)
real->line_byte_offset,
real->line_char_offset);
#endif
if (real->line_byte_offset == 97 &&
real->line_char_offset == 95)
G_BREAKPOINT();
if (segments_updated)
{

View File

@ -160,6 +160,8 @@ void gtk_text_iter_set_line (GtkTextIter *iter,
gint line_number);
void gtk_text_iter_set_line_offset (GtkTextIter *iter,
gint char_on_line);
void gtk_text_iter_set_line_index (GtkTextIter *iter,
gint byte_on_line);
void gtk_text_iter_forward_to_end (GtkTextIter *iter);
gboolean gtk_text_iter_forward_to_newline (GtkTextIter *iter);

View File

@ -1211,7 +1211,7 @@ add_cursor (GtkTextLayout *layout,
* user has hidden the cursor.
*/
if (gtk_text_btree_mark_is_insert (_gtk_text_buffer_get_btree (layout->buffer),
(GtkTextMark*)seg) &&
seg->body.mark.obj) &&
(!layout->cursor_visible ||
gtk_text_buffer_get_selection_bounds (layout->buffer, NULL, NULL)))
return;

View File

@ -50,12 +50,89 @@
#include "gtktextbtree.h"
static void gtk_text_mark_init (GtkTextMark *mark);
static void gtk_text_mark_class_init (GtkTextMarkClass *klass);
static void gtk_text_mark_finalize (GObject *obj);
static gpointer parent_class = NULL;
GType
gtk_text_mark_get_type (void)
{
static GType object_type = 0;
if (!object_type)
{
static const GTypeInfo object_info =
{
sizeof (GtkTextMarkClass),
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
(GClassInitFunc) gtk_text_mark_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (GtkTextMark),
0, /* n_preallocs */
(GInstanceInitFunc) gtk_text_mark_init,
};
object_type = g_type_register_static (G_TYPE_OBJECT,
"GtkTextMark",
&object_info);
}
return object_type;
}
static void
gtk_text_mark_init (GtkTextMark *mark)
{
mark->segment = NULL;
}
static void
gtk_text_mark_class_init (GtkTextMarkClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
object_class->finalize = gtk_text_mark_finalize;
}
static void
gtk_text_mark_finalize (GObject *obj)
{
GtkTextMark *mark;
GtkTextLineSegment *seg;
mark = GTK_TEXT_MARK (obj);
seg = mark->segment;
if (seg)
{
g_return_if_fail (seg->body.mark.tree == NULL);
if (seg->body.mark.tree != NULL)
g_warning ("GtkTextMark being finalized while still in the buffer; "
"someone removed a reference they didn't own! Crash "
"impending");
g_free (seg->body.mark.name);
g_free (seg);
mark->segment = NULL;
}
}
gboolean
gtk_text_mark_is_visible(GtkTextMark *mark)
{
GtkTextLineSegment *seg;
seg = (GtkTextLineSegment*)mark;
seg = mark->segment;
return seg->body.mark.visible;
}
@ -65,34 +142,11 @@ gtk_text_mark_get_name (GtkTextMark *mark)
{
GtkTextLineSegment *seg;
seg = (GtkTextLineSegment*)mark;
seg = mark->segment;
return seg->body.mark.name;
}
GtkTextMark *
gtk_text_mark_ref (GtkTextMark *mark)
{
GtkTextLineSegment *seg;
seg = (GtkTextLineSegment*)mark;
_mark_segment_ref (seg);
return mark;
}
void
gtk_text_mark_unref (GtkTextMark *mark)
{
GtkTextLineSegment *seg;
seg = (GtkTextLineSegment*)mark;
_mark_segment_unref (seg);
}
gboolean
gtk_text_mark_get_deleted (GtkTextMark *mark)
{
@ -100,7 +154,10 @@ gtk_text_mark_get_deleted (GtkTextMark *mark)
g_return_val_if_fail (mark != NULL, FALSE);
seg = (GtkTextLineSegment*)mark;
seg = mark->segment;
if (seg == NULL)
return TRUE;
return seg->body.mark.tree == NULL;
}
@ -127,52 +184,23 @@ _mark_segment_new (GtkTextBTree *tree,
mark->type = &gtk_text_left_mark_type;
else
mark->type = &gtk_text_right_mark_type;
mark->byte_count = 0;
mark->char_count = 0;
mark->body.mark.obj = g_object_new (GTK_TYPE_TEXT_MARK, NULL);
mark->body.mark.obj->segment = mark;
mark->body.mark.tree = tree;
mark->body.mark.line = NULL;
mark->next = NULL;
mark->body.mark.refcount = 1;
mark->body.mark.visible = FALSE;
mark->body.mark.not_deleteable = FALSE;
return mark;
}
void
_mark_segment_ref (GtkTextLineSegment *mark)
{
g_return_if_fail (mark != NULL);
g_return_if_fail (mark->type == &gtk_text_right_mark_type ||
mark->type == &gtk_text_left_mark_type);
g_return_if_fail (mark->body.mark.refcount > 0);
mark->body.mark.refcount += 1;
}
void
_mark_segment_unref (GtkTextLineSegment *mark)
{
g_return_if_fail (mark != NULL);
g_return_if_fail (mark->type == &gtk_text_right_mark_type ||
mark->type == &gtk_text_left_mark_type);
g_return_if_fail (mark->body.mark.refcount > 0);
mark->body.mark.refcount -= 1;
if (mark->body.mark.refcount == 0)
{
g_free(mark->body.mark.name);
g_free(mark);
}
}
static int mark_segment_delete_func (GtkTextLineSegment *segPtr,
GtkTextLine *line,
int treeGone);

View File

@ -56,15 +56,36 @@ extern "C" {
/* The GtkTextMark data type */
typedef struct _GtkTextMark GtkTextMark;
typedef struct _GtkTextMark GtkTextMark;
typedef struct _GtkTextMarkClass GtkTextMarkClass;
#define GTK_TYPE_TEXT_MARK (gtk_text_mark_get_type ())
#define GTK_TEXT_MARK(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GTK_TYPE_TEXT_MARK, GtkTextMark))
#define GTK_TEXT_MARK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_TEXT_MARK, GtkTextMarkClass))
#define GTK_IS_TEXT_MARK(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GTK_TYPE_TEXT_MARK))
#define GTK_IS_TEXT_MARK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_TEXT_MARK))
#define GTK_TEXT_MARK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_TEXT_MARK, GtkTextMarkClass))
struct _GtkTextMark
{
GObject parent_instance;
gpointer segment;
};
struct _GtkTextMarkClass
{
GObjectClass parent_class;
};
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);
/* FIXME gconst */
const char * gtk_text_mark_get_name (GtkTextMark *mark);
GtkTextMark *gtk_text_mark_ref (GtkTextMark *mark);
void gtk_text_mark_unref (GtkTextMark *mark);
const char *gtk_text_mark_get_name (GtkTextMark *mark);
gboolean gtk_text_mark_get_deleted (GtkTextMark *mark);

View File

@ -8,7 +8,7 @@ extern "C" {
#include <gtk/gtktexttypes.h>
#include <gtk/gtktextlayout.h>
#define GTK_IS_TEXT_MARK(mark) (((GtkTextLineSegment*)mark)->type == &gtk_text_left_mark_type || \
#define GTK_IS_TEXT_MARK_SEGMENT(mark) (((GtkTextLineSegment*)mark)->type == &gtk_text_left_mark_type || \
((GtkTextLineSegment*)mark)->type == &gtk_text_right_mark_type)
/*
@ -17,7 +17,7 @@ extern "C" {
*/
struct _GtkTextMarkBody {
guint refcount;
GtkTextMark *obj;
gchar *name;
GtkTextBTree *tree;
GtkTextLine *line;
@ -28,9 +28,6 @@ struct _GtkTextMarkBody {
GtkTextLineSegment *_mark_segment_new (GtkTextBTree *tree,
gboolean left_gravity,
const gchar *name);
void _mark_segment_ref (GtkTextLineSegment *mark);
void _mark_segment_unref (GtkTextLineSegment *mark);
#ifdef __cplusplus
}

View File

@ -1233,10 +1233,7 @@ gtk_text_attributes_fill_from_tags(GtkTextAttributes *dest,
dest->appearance.bg_color = vals->appearance.bg_color;
dest->appearance.draw_bg = TRUE;
}
if (tag->relief_set)
dest->relief = vals->relief;
}
if (tag->bg_stipple_set)
{
@ -1327,3 +1324,38 @@ gtk_text_attributes_fill_from_tags(GtkTextAttributes *dest,
++n;
}
}
gboolean
gtk_text_tag_affects_size (GtkTextTag *tag)
{
g_return_val_if_fail (GTK_IS_TEXT_TAG (tag), FALSE);
return
tag->font_set ||
tag->justify_set ||
tag->left_margin_set ||
tag->left_wrapped_line_margin_set ||
tag->offset_set ||
tag->right_margin_set ||
tag->pixels_above_lines_set ||
tag->pixels_below_lines_set ||
tag->pixels_inside_wrap_set ||
tag->tabs_set ||
tag->underline_set ||
tag->wrap_mode_set ||
tag->invisible_set;
}
gboolean
gtk_text_tag_affects_nonsize_appearance (GtkTextTag *tag)
{
g_return_val_if_fail (GTK_IS_TEXT_TAG (tag), FALSE);
return
tag->bg_color_set ||
tag->bg_stipple_set ||
tag->fg_color_set ||
tag->fg_stipple_set ||
tag->strikethrough_set ||
tag->bg_full_height_set;
}

View File

@ -31,7 +31,8 @@ typedef struct _GtkTextAttributes GtkTextAttributes;
typedef struct _GtkTextTag GtkTextTag;
typedef struct _GtkTextTagClass GtkTextTagClass;
struct _GtkTextTag {
struct _GtkTextTag
{
GtkObject parent_instance;
GtkTextTagTable *table;
@ -58,7 +59,6 @@ struct _GtkTextTag {
* this tag does not affect it.
*/
guint bg_color_set : 1;
guint relief_set : 1;
guint bg_stipple_set : 1;
guint fg_color_set : 1;
guint font_set : 1;
@ -139,7 +139,6 @@ struct _GtkTextAttributes
GtkTextAppearance appearance;
GtkShadowType relief;
GtkJustification justify;
GtkTextDirection direction;

View File

@ -23,4 +23,7 @@ void gtk_text_attributes_unrealize (GtkTextAttributes *values,
GdkColormap *cmap,
GdkVisual *visual);
gboolean gtk_text_tag_affects_size (GtkTextTag *tag);
gboolean gtk_text_tag_affects_nonsize_appearance (GtkTextTag *tag);
#endif

View File

@ -421,6 +421,10 @@ fill_example_buffer (GtkTextBuffer *buffer)
GdkPixbuf *pixbuf;
int i;
char *str;
/* FIXME this is broken if called twice on a buffer, since
* we try to create tags a second time.
*/
tag = gtk_text_buffer_create_tag (buffer, "fg_blue");
@ -581,9 +585,13 @@ fill_example_buffer (GtkTextBuffer *buffer)
g_object_unref (G_OBJECT (pixbuf));
printf ("%d lines %d chars\n",
gtk_text_buffer_get_line_count (buffer),
gtk_text_buffer_get_char_count (buffer));
gtk_text_buffer_get_line_count (buffer),
gtk_text_buffer_get_char_count (buffer));
/* Move cursor to start */
gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
gtk_text_buffer_place_cursor (buffer, &iter);
gtk_text_buffer_set_modified (buffer, FALSE);
}

View File

@ -421,6 +421,10 @@ fill_example_buffer (GtkTextBuffer *buffer)
GdkPixbuf *pixbuf;
int i;
char *str;
/* FIXME this is broken if called twice on a buffer, since
* we try to create tags a second time.
*/
tag = gtk_text_buffer_create_tag (buffer, "fg_blue");
@ -581,9 +585,13 @@ fill_example_buffer (GtkTextBuffer *buffer)
g_object_unref (G_OBJECT (pixbuf));
printf ("%d lines %d chars\n",
gtk_text_buffer_get_line_count (buffer),
gtk_text_buffer_get_char_count (buffer));
gtk_text_buffer_get_line_count (buffer),
gtk_text_buffer_get_char_count (buffer));
/* Move cursor to start */
gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
gtk_text_buffer_place_cursor (buffer, &iter);
gtk_text_buffer_set_modified (buffer, FALSE);
}