summaryrefslogtreecommitdiff
path: root/gtk
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2000-10-24 22:44:14 +0000
committerHavoc Pennington <hp@src.gnome.org>2000-10-24 22:44:14 +0000
commit2fab0eb1fa92964cca24d55e51203c5af5113c8e (patch)
tree6198960908bd87ef72de178dd3ad0452d825832a /gtk
parent873b316f2346ad4cc928b798337d35f46a0ec716 (diff)
downloadgtk+-2fab0eb1fa92964cca24d55e51203c5af5113c8e.tar.gz
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
Diffstat (limited to 'gtk')
-rw-r--r--gtk/gtktextbtree.c231
-rw-r--r--gtk/gtktextbuffer.c51
-rw-r--r--gtk/gtktextbuffer.h4
-rw-r--r--gtk/gtktextiter.c86
-rw-r--r--gtk/gtktextiter.h2
-rw-r--r--gtk/gtktextlayout.c2
-rw-r--r--gtk/gtktextmark.c138
-rw-r--r--gtk/gtktextmark.h29
-rw-r--r--gtk/gtktextmarkprivate.h7
-rw-r--r--gtk/gtktexttag.c40
-rw-r--r--gtk/gtktexttag.h5
-rw-r--r--gtk/gtktexttagprivate.h3
-rw-r--r--gtk/testtext.c12
13 files changed, 405 insertions, 205 deletions
diff --git a/gtk/gtktextbtree.c b/gtk/gtktextbtree.c
index dcb5693606..5b1f98430b 100644
--- a/gtk/gtktextbtree.c
+++ b/gtk/gtktextbtree.c
@@ -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 = gtk_text_btree_set_mark (tree,
+ NULL,
+ "insert",
+ FALSE,
+ &start,
+ FALSE);
+
+ seg = tree->insert_mark->segment;
- tree->insert_mark->body.mark.not_deleteable = TRUE;
- tree->insert_mark->body.mark.visible = TRUE;
+ seg->body.mark.not_deleteable = TRUE;
+ seg->body.mark.visible = TRUE;
- 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;
+ tree->selection_bound_mark = gtk_text_btree_set_mark (tree,
+ NULL,
+ "selection_bound",
+ FALSE,
+ &start,
+ FALSE);
+
+ seg = tree->selection_bound_mark->segment;
- _mark_segment_ref(tree->insert_mark);
- _mark_segment_ref(tree->selection_bound_mark);
+ 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;
diff --git a/gtk/gtktextbuffer.c b/gtk/gtktextbuffer.c
index a686a4531f..557bd6bf5c 100644
--- a/gtk/gtktextbuffer.c
+++ b/gtk/gtktextbuffer.c
@@ -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);
+}
+
+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_char(get_btree (buffer),
- iter, line_number, char_offset);
+ gtk_text_btree_get_iter_at_line_byte (get_btree (buffer),
+ iter, line_number, byte_index);
}
void
diff --git a/gtk/gtktextbuffer.h b/gtk/gtktextbuffer.h
index d35eb9a4f7..920d09d2e9 100644
--- a/gtk/gtktextbuffer.h
+++ b/gtk/gtktextbuffer.h
@@ -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);
diff --git a/gtk/gtktextiter.c b/gtk/gtktextiter.c
index 70ac5f19e8..32f85be9a2 100644
--- a/gtk/gtktextiter.c
+++ b/gtk/gtktextiter.c
@@ -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)
{
diff --git a/gtk/gtktextiter.h b/gtk/gtktextiter.h
index 8e6eeaecdd..9a49dfbfab 100644
--- a/gtk/gtktextiter.h
+++ b/gtk/gtktextiter.h
@@ -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);
diff --git a/gtk/gtktextlayout.c b/gtk/gtktextlayout.c
index d4b57f973a..99e3c39c40 100644
--- a/gtk/gtktextlayout.c
+++ b/gtk/gtktextlayout.c
@@ -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;
diff --git a/gtk/gtktextmark.c b/gtk/gtktextmark.c
index a1a4c6f65f..c66af21e2f 100644
--- a/gtk/gtktextmark.c
+++ b/gtk/gtktextmark.c
@@ -50,47 +50,101 @@
#include "gtktextbtree.h"
-gboolean
-gtk_text_mark_is_visible(GtkTextMark *mark)
+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)
{
- GtkTextLineSegment *seg;
+ static GType object_type = 0;
- seg = (GtkTextLineSegment*)mark;
+ 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;
+}
- return seg->body.mark.visible;
+static void
+gtk_text_mark_init (GtkTextMark *mark)
+{
+ mark->segment = NULL;
}
-const char *
-gtk_text_mark_get_name (GtkTextMark *mark)
+static void
+gtk_text_mark_class_init (GtkTextMarkClass *klass)
{
- GtkTextLineSegment *seg;
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
- seg = (GtkTextLineSegment*)mark;
+ parent_class = g_type_class_peek_parent (klass);
- return seg->body.mark.name;
+ object_class->finalize = gtk_text_mark_finalize;
}
-
-GtkTextMark *
-gtk_text_mark_ref (GtkTextMark *mark)
+static void
+gtk_text_mark_finalize (GObject *obj)
{
+ GtkTextMark *mark;
GtkTextLineSegment *seg;
- seg = (GtkTextLineSegment*)mark;
+ mark = GTK_TEXT_MARK (obj);
- _mark_segment_ref (seg);
+ seg = mark->segment;
- return mark;
+ 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;
+ }
}
-void
-gtk_text_mark_unref (GtkTextMark *mark)
+gboolean
+gtk_text_mark_is_visible(GtkTextMark *mark)
{
GtkTextLineSegment *seg;
- seg = (GtkTextLineSegment*)mark;
-
- _mark_segment_unref (seg);
+ seg = mark->segment;
+
+ return seg->body.mark.visible;
+}
+
+const char *
+gtk_text_mark_get_name (GtkTextMark *mark)
+{
+ GtkTextLineSegment *seg;
+
+ seg = mark->segment;
+
+ return seg->body.mark.name;
}
gboolean
@@ -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);
diff --git a/gtk/gtktextmark.h b/gtk/gtktextmark.h
index 0ee0180639..45255f4459 100644
--- a/gtk/gtktextmark.h
+++ b/gtk/gtktextmark.h
@@ -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);
diff --git a/gtk/gtktextmarkprivate.h b/gtk/gtktextmarkprivate.h
index 87e862c289..4776ca6b10 100644
--- a/gtk/gtktextmarkprivate.h
+++ b/gtk/gtktextmarkprivate.h
@@ -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
}
diff --git a/gtk/gtktexttag.c b/gtk/gtktexttag.c
index 54d91d0bf2..d769aa3dec 100644
--- a/gtk/gtktexttag.c
+++ b/gtk/gtktexttag.c
@@ -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;
+}
diff --git a/gtk/gtktexttag.h b/gtk/gtktexttag.h
index 91a0591f30..0465fb9a39 100644
--- a/gtk/gtktexttag.h
+++ b/gtk/gtktexttag.h
@@ -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;
diff --git a/gtk/gtktexttagprivate.h b/gtk/gtktexttagprivate.h
index 200864503b..3e95017af9 100644
--- a/gtk/gtktexttagprivate.h
+++ b/gtk/gtktexttagprivate.h
@@ -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
diff --git a/gtk/testtext.c b/gtk/testtext.c
index d813d6fed4..dcc363b6fe 100644
--- a/gtk/testtext.c
+++ b/gtk/testtext.c
@@ -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);
}