tons of fixes

This commit is contained in:
Havoc Pennington
2000-07-06 23:33:15 +00:00
parent 452f2ab948
commit 7cbdbc2b39
17 changed files with 965 additions and 238 deletions

View File

@@ -252,7 +252,7 @@ connect_action_widget (GtkDialog *dialog, GtkWidget *child)
if (GTK_WIDGET_GET_CLASS (child)->activate_signal != 0)
{
const gchar* name =
gtk_signal_name (GTK_WIDGET_GET_CLASS (child)->activate_signal != 0);
gtk_signal_name (GTK_WIDGET_GET_CLASS (child)->activate_signal);
gtk_signal_connect_while_alive (GTK_OBJECT (child),
name,
@@ -279,7 +279,7 @@ gtk_dialog_add_action_widget (GtkDialog *dialog,
ad->response_id = response_id;
connect_action_widget (dialog, widget);
gtk_box_pack_end (GTK_BOX (dialog->action_area),
widget,
FALSE, TRUE, 5);

View File

@@ -2085,18 +2085,17 @@ gtk_text_btree_get_text (const GtkTextIter *start_orig,
iter = start;
seg = gtk_text_iter_get_indexable_segment(&iter);
while (seg != end_seg)
{
{
copy_segment(retval, include_hidden, include_nonchars,
&iter, &end);
if (!gtk_text_iter_forward_indexable_segment(&iter))
g_assert_not_reached(); /* must be able to go forward to
end_seg, if end_seg still exists
and was in front. */
gtk_text_iter_forward_indexable_segment(&iter);
seg = gtk_text_iter_get_indexable_segment(&iter);
}
copy_segment(retval, include_hidden, include_nonchars, &iter, &end);
str = retval->str;
g_string_free(retval, FALSE);
return str;
@@ -2937,6 +2936,23 @@ gtk_text_line_byte_has_tag (GtkTextLine *line,
return find_toggle_outside_current_line(line, tree, tag);
}
gboolean
gtk_text_line_is_last (GtkTextLine *line)
{
GtkTextBTreeNode *node;
if (line->next != NULL)
return FALSE;
else
{
node = line->parent;
while (node != NULL && node->next == NULL)
node = node->parent;
return node == NULL;
}
}
GtkTextLine*
gtk_text_line_next (GtkTextLine *line)
{

View File

@@ -201,6 +201,7 @@ gboolean gtk_text_line_byte_has_tag (GtkTextLine
GtkTextBTree *tree,
gint byte_in_line,
GtkTextTag *tag);
gboolean gtk_text_line_is_last (GtkTextLine *line);
GtkTextLine * gtk_text_line_next (GtkTextLine *line);
GtkTextLine * gtk_text_line_previous (GtkTextLine *line);
void gtk_text_line_add_data (GtkTextLine *line,

View File

@@ -59,6 +59,7 @@ static void gtk_text_buffer_real_remove_tag (GtkTextBuffer *buffe
const GtkTextIter *start_char,
const GtkTextIter *end_char);
static GtkTextBTree* get_btree (GtkTextBuffer *buffer);
void gtk_marshal_NONE__INT_POINTER_INT (GtkObject *object,
GtkSignalFunc func,
@@ -265,23 +266,16 @@ GtkTextBuffer*
gtk_text_buffer_new (GtkTextTagTable *table)
{
GtkTextBuffer *text_buffer;
/* This is broken, need construct_only argument for the tag table
so language bindings can set it.
*/
text_buffer = GTK_TEXT_BUFFER (gtk_type_new (gtk_text_buffer_get_type ()));
if (table)
text_buffer->tag_table = table;
else
text_buffer->tag_table = gtk_text_tag_table_new();
gtk_object_ref (GTK_OBJECT(text_buffer->tag_table));
gtk_object_sink (GTK_OBJECT(text_buffer->tag_table));
text_buffer->tree = gtk_text_btree_new(text_buffer->tag_table,
text_buffer);
{
text_buffer->tag_table = table;
gtk_object_ref (GTK_OBJECT(text_buffer->tag_table));
gtk_object_sink (GTK_OBJECT(text_buffer->tag_table));
}
return text_buffer;
}
@@ -296,11 +290,17 @@ gtk_text_buffer_destroy (GtkObject *object)
gtk_widget_destroy(buffer->selection_widget);
buffer->selection_widget = NULL;
gtk_object_unref(GTK_OBJECT(buffer->tag_table));
buffer->tag_table = NULL;
gtk_text_btree_unref(buffer->tree);
buffer->tree = NULL;
if (buffer->tag_table)
{
gtk_object_unref(GTK_OBJECT(buffer->tag_table));
buffer->tag_table = NULL;
}
if (buffer->btree)
{
gtk_text_btree_unref(buffer->btree);
buffer->btree = NULL;
}
(* parent_class->destroy) (object);
}
@@ -315,6 +315,44 @@ gtk_text_buffer_finalize (GObject *object)
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static GtkTextTagTable*
get_table (GtkTextBuffer *buffer)
{
if (buffer->tag_table == NULL)
{
buffer->tag_table = gtk_text_tag_table_new ();
gtk_object_ref (GTK_OBJECT(buffer->tag_table));
gtk_object_sink (GTK_OBJECT(buffer->tag_table));
}
return buffer->tag_table;
}
static GtkTextBTree*
get_btree (GtkTextBuffer *buffer)
{
if (buffer->btree == NULL)
buffer->btree = gtk_text_btree_new(gtk_text_buffer_get_tag_table (buffer),
buffer);
return buffer->btree;
}
GtkTextBTree*
_gtk_text_buffer_get_btree (GtkTextBuffer *buffer)
{
return get_btree (buffer);
}
GtkTextTagTable*
gtk_text_buffer_get_tag_table (GtkTextBuffer *buffer)
{
g_return_val_if_fail(GTK_IS_TEXT_BUFFER(buffer), NULL);
return get_table (buffer);
}
/*
* Insertion
*/
@@ -505,12 +543,14 @@ gtk_text_buffer_delete_interactive (GtkTextBuffer *buffer,
current_state = gtk_text_iter_editable (&iter, default_editable);
while (gtk_text_iter_forward_find_tag_toggle (&iter, NULL))
while (TRUE)
{
gboolean new_state;
gboolean done = FALSE;
GtkTextIter end;
gtk_text_iter_forward_find_tag_toggle (&iter, NULL);
gtk_text_buffer_get_iter_at_mark (buffer, &end, end_mark);
if (gtk_text_iter_compare (&iter, &end) >= 0)
@@ -529,11 +569,11 @@ gtk_text_buffer_delete_interactive (GtkTextBuffer *buffer,
{
/* We're ending an editable region. Delete said region. */
GtkTextIter start;
gtk_text_buffer_get_iter_at_mark (buffer, &start, start_mark);
gtk_text_buffer_delete (buffer, &start, &iter);
deleted_stuff = TRUE;
}
@@ -574,6 +614,7 @@ gtk_text_buffer_delete_interactive (GtkTextBuffer *buffer,
break;
}
gtk_text_buffer_delete_mark (buffer, start_mark);
gtk_text_buffer_delete_mark (buffer, end_mark);
@@ -689,20 +730,20 @@ gtk_text_buffer_set_mark(GtkTextBuffer *buffer,
GtkTextIter location;
GtkTextMark *mark;
mark = gtk_text_btree_set_mark(buffer->tree,
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(buffer->tree, mark) ||
gtk_text_btree_mark_is_selection_bound(buffer->tree, mark))
if (gtk_text_btree_mark_is_insert(get_btree (buffer), mark) ||
gtk_text_btree_mark_is_selection_bound(get_btree (buffer), mark))
{
gtk_text_buffer_update_primary_selection(buffer);
}
gtk_text_btree_get_iter_at_mark(buffer->tree,
gtk_text_btree_get_iter_at_mark(get_btree (buffer),
&location,
mark);
@@ -744,7 +785,7 @@ gtk_text_buffer_get_iter_at_mark(GtkTextBuffer *buffer,
g_return_if_fail (!gtk_text_mark_deleted (mark));
g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
gtk_text_btree_get_iter_at_mark(buffer->tree,
gtk_text_btree_get_iter_at_mark(get_btree (buffer),
iter,
mark);
}
@@ -757,7 +798,7 @@ gtk_text_buffer_delete_mark(GtkTextBuffer *buffer,
g_return_if_fail (!gtk_text_mark_deleted (mark));
g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
gtk_text_btree_remove_mark (buffer->tree, mark);
gtk_text_btree_remove_mark (get_btree (buffer), mark);
/* See rationale above for MARK_SET on why we emit this after
removing the mark, rather than removing the mark in a default
@@ -775,7 +816,7 @@ gtk_text_buffer_get_mark (GtkTextBuffer *buffer,
g_return_val_if_fail(GTK_IS_TEXT_BUFFER(buffer), NULL);
g_return_val_if_fail(name != NULL, NULL);
mark = gtk_text_btree_get_mark_by_name(buffer->tree, name);
mark = gtk_text_btree_get_mark_by_name(get_btree (buffer), name);
return mark;
}
@@ -784,13 +825,20 @@ void
gtk_text_buffer_place_cursor (GtkTextBuffer *buffer,
const GtkTextIter *where)
{
g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
GtkTextIter real;
gtk_text_btree_place_cursor(buffer->tree, where);
gtk_text_buffer_mark_set (buffer, where,
g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
real = *where;
if (gtk_text_iter_is_last (&real))
gtk_text_iter_prev_char (&real);
gtk_text_btree_place_cursor(get_btree (buffer), &real);
gtk_text_buffer_mark_set (buffer, &real,
gtk_text_buffer_get_mark (buffer,
"insert"));
gtk_text_buffer_mark_set (buffer, where,
gtk_text_buffer_mark_set (buffer, &real,
gtk_text_buffer_get_mark (buffer,
"selection_bound"));
}
@@ -809,7 +857,7 @@ gtk_text_buffer_create_tag(GtkTextBuffer *buffer,
tag = gtk_text_tag_new(tag_name);
gtk_text_tag_table_add(buffer->tag_table, tag);
gtk_text_tag_table_add(get_table (buffer), tag);
return tag;
}
@@ -894,7 +942,7 @@ gtk_text_buffer_apply_tag_by_name (GtkTextBuffer *buffer,
g_return_if_fail(start != NULL);
g_return_if_fail(end != NULL);
tag = gtk_text_tag_table_lookup(buffer->tag_table,
tag = gtk_text_tag_table_lookup(get_table (buffer),
name);
if (tag == NULL)
@@ -919,7 +967,7 @@ gtk_text_buffer_remove_tag_by_name (GtkTextBuffer *buffer,
g_return_if_fail(start != NULL);
g_return_if_fail(end != NULL);
tag = gtk_text_tag_table_lookup(buffer->tag_table,
tag = gtk_text_tag_table_lookup(get_table (buffer),
name);
if (tag == NULL)
@@ -945,7 +993,7 @@ gtk_text_buffer_get_iter_at_line_offset (GtkTextBuffer *buffer,
g_return_if_fail(iter != NULL);
g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
gtk_text_btree_get_iter_at_line_char(buffer->tree,
gtk_text_btree_get_iter_at_line_char(get_btree (buffer),
iter, line_number, char_offset);
}
@@ -968,7 +1016,7 @@ gtk_text_buffer_get_iter_at_offset (GtkTextBuffer *buffer,
g_return_if_fail(iter != NULL);
g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
gtk_text_btree_get_iter_at_char(buffer->tree, iter, char_offset);
gtk_text_btree_get_iter_at_char(get_btree (buffer), iter, char_offset);
}
void
@@ -978,7 +1026,7 @@ gtk_text_buffer_get_last_iter (GtkTextBuffer *buffer,
g_return_if_fail(iter != NULL);
g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
gtk_text_btree_get_last_iter(buffer->tree, iter);
gtk_text_btree_get_last_iter(get_btree (buffer), iter);
}
void
@@ -990,8 +1038,8 @@ gtk_text_buffer_get_bounds (GtkTextBuffer *buffer,
g_return_if_fail(end != NULL);
g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
gtk_text_btree_get_iter_at_char(buffer->tree, start, 0);
gtk_text_btree_get_last_iter(buffer->tree, end);
gtk_text_btree_get_iter_at_char(get_btree (buffer), start, 0);
gtk_text_btree_get_last_iter(get_btree (buffer), end);
}
/*
@@ -1070,7 +1118,7 @@ gtk_text_buffer_get_line_count(GtkTextBuffer *buffer)
{
g_return_val_if_fail(GTK_IS_TEXT_BUFFER(buffer), 0);
return gtk_text_btree_line_count(buffer->tree);
return gtk_text_btree_line_count(get_btree (buffer));
}
gint
@@ -1078,7 +1126,7 @@ gtk_text_buffer_get_char_count(GtkTextBuffer *buffer)
{
g_return_val_if_fail(GTK_IS_TEXT_BUFFER(buffer), 0);
return gtk_text_btree_char_count(buffer->tree);
return gtk_text_btree_char_count(get_btree (buffer));
}
GSList*
@@ -1655,7 +1703,7 @@ gtk_text_buffer_get_selection_bounds (GtkTextBuffer *buffer,
g_return_val_if_fail (buffer != NULL, FALSE);
g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
return gtk_text_btree_get_selection_bounds (buffer->tree, start, end);
return gtk_text_btree_get_selection_bounds (get_btree (buffer), start, end);
}
@@ -1666,5 +1714,6 @@ gtk_text_buffer_get_selection_bounds (GtkTextBuffer *buffer,
void
gtk_text_buffer_spew(GtkTextBuffer *buffer)
{
gtk_text_btree_spew(buffer->tree);
gtk_text_btree_spew(get_btree (buffer));
}

View File

@@ -30,7 +30,7 @@ struct _GtkTextBuffer {
GtkObject parent_instance;
GtkTextTagTable *tag_table;
GtkTextBTree *tree;
GtkTextBTree *btree;
/* Text currently pasted to the clipboard */
gchar *clipboard_text;
@@ -97,6 +97,7 @@ gint gtk_text_buffer_get_line_count (GtkTextBuffer *buffer);
gint gtk_text_buffer_get_char_count (GtkTextBuffer *buffer);
GtkTextTagTable* gtk_text_buffer_get_tag_table (GtkTextBuffer *buffer);
/* Insert into the buffer */
void gtk_text_buffer_insert (GtkTextBuffer *buffer,
@@ -278,6 +279,8 @@ gboolean gtk_text_buffer_find_regexp(GtkTextBuffer *buffer,
/* INTERNAL private stuff */
void gtk_text_buffer_spew (GtkTextBuffer *buffer);
GtkTextBTree* _gtk_text_buffer_get_btree (GtkTextBuffer *buffer);
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@@ -547,9 +547,11 @@ gtk_text_layout_draw (GtkTextLayout *layout,
GtkTextIter line_start, line_end;
gint byte_count = gtk_text_line_byte_count (line);
gtk_text_btree_get_iter_at_line (layout->buffer->tree, &line_start,
gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
&line_start,
line, 0);
gtk_text_btree_get_iter_at_line (layout->buffer->tree, &line_end,
gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
&line_end,
line, byte_count - 1);
if (gtk_text_iter_compare (&selection_start, &line_end) < 0 &&

View File

@@ -2,6 +2,7 @@
#include "gtktextbtree.h"
#include "gtktextiterprivate.h"
#include "gtkdebug.h"
#include <string.h>
#include <ctype.h>
typedef struct _GtkTextRealIter GtkTextRealIter;
@@ -34,9 +35,9 @@ struct _GtkTextRealIter {
and ditto for char offsets. */
gint segment_byte_offset;
gint segment_char_offset;
/* These are here for binary-compatible expansion space. */
/* Pads are here for binary-compatible expansion space. */
gpointer pad1;
gint pad2;
guint pad2;
};
/* These "set" functions should not assume any fields
@@ -114,7 +115,8 @@ iter_set_from_segment(GtkTextRealIter *iter,
/* This function ensures that the segment-dependent information is
truly computed lazily; often we don't need to do the full make_real
work. */
work. This ensures the btree and line are valid, but doesn't
update the segments. */
static GtkTextRealIter*
gtk_text_iter_make_surreal(const GtkTextIter *_iter)
{
@@ -308,9 +310,9 @@ ensure_char_offsets(GtkTextRealIter *iter)
g_assert(iter->line_byte_offset >= 0);
gtk_text_line_byte_to_char_offsets(iter->line,
iter->line_byte_offset,
&iter->line_char_offset,
&iter->segment_char_offset);
iter->line_byte_offset,
&iter->line_char_offset,
&iter->segment_char_offset);
}
}
@@ -322,9 +324,9 @@ ensure_byte_offsets(GtkTextRealIter *iter)
g_assert(iter->line_char_offset >= 0);
gtk_text_line_char_to_byte_offsets(iter->line,
iter->line_char_offset,
&iter->line_byte_offset,
&iter->segment_byte_offset);
iter->line_char_offset,
&iter->line_byte_offset,
&iter->segment_byte_offset);
}
}
@@ -487,7 +489,7 @@ gtk_text_iter_get_btree(const GtkTextIter *iter)
*/
gint
gtk_text_buffer_get_offset(const GtkTextIter *iter)
gtk_text_iter_get_offset(const GtkTextIter *iter)
{
GtkTextRealIter *real;
@@ -690,6 +692,38 @@ gtk_text_iter_get_pixmap (const GtkTextIter *iter,
}
}
GSList*
gtk_text_iter_get_marks (const GtkTextIter *iter)
{
GtkTextRealIter *real;
GtkTextLineSegment *seg;
GSList *retval;
g_return_val_if_fail(iter != NULL, NULL);
real = gtk_text_iter_make_real(iter);
if (real == NULL)
return NULL;
check_invariants(iter);
retval = NULL;
seg = real->any_segment;
while (seg != real->segment)
{
if (seg->type == &gtk_text_left_mark_type ||
seg->type == &gtk_text_right_mark_type)
retval = g_slist_prepend(retval, (GtkTextMark*)seg);
seg = seg->next;
}
/* The returned list isn't guaranteed to be in any special order,
and it isn't. */
return retval;
}
GSList*
gtk_text_iter_get_toggled_tags (const GtkTextIter *iter,
gboolean toggled_on)
@@ -878,6 +912,23 @@ gtk_text_iter_editable (const GtkTextIter *iter,
return retval;
}
static gchar*
gtk_text_iter_get_language (const GtkTextIter *iter)
{
GtkTextStyleValues *values;
gchar *retval;
values = gtk_text_style_values_new ();
gtk_text_iter_get_style_values (iter, values);
retval = g_strdup (values->language);
gtk_text_style_values_unref (values);
return retval;
}
gboolean
gtk_text_iter_starts_line (const GtkTextIter *iter)
{
@@ -913,6 +964,29 @@ gtk_text_iter_ends_line (const GtkTextIter *iter)
return gtk_text_iter_get_char(iter) == '\n';
}
gboolean
gtk_text_iter_is_last (const GtkTextIter *iter)
{
GtkTextRealIter *real;
g_return_val_if_fail(iter != NULL, FALSE);
real = gtk_text_iter_make_surreal(iter);
if (real == NULL)
return FALSE;
check_invariants(iter);
return gtk_text_line_is_last(real->line);
}
gboolean
gtk_text_iter_is_first (const GtkTextIter *iter)
{
return gtk_text_iter_get_offset (iter) == 0;
}
gint
gtk_text_iter_get_chars_in_line (const GtkTextIter *iter)
{
@@ -988,6 +1062,10 @@ gtk_text_iter_get_style_values (const GtkTextIter *iter,
* Increments/decrements
*/
/* The return value of this indicates WHETHER WE MOVED.
* The return value of public functions indicates
* (MOVEMENT OCCURRED && NEW ITER IS DEREFERENCEABLE)
*/
static gboolean
forward_line_leaving_caches_unmodified(GtkTextRealIter *real)
{
@@ -1012,7 +1090,7 @@ forward_line_leaving_caches_unmodified(GtkTextRealIter *real)
real->segment = real->any_segment;
while (real->segment->char_count == 0)
real->segment = real->segment->next;
return TRUE;
}
else
@@ -1177,8 +1255,11 @@ gtk_text_iter_forward_indexable_segment(GtkTextIter *iter)
g_assert(gtk_text_iter_starts_line(iter));
check_invariants(iter);
return TRUE;
if (gtk_text_iter_is_last (iter))
return FALSE;
else
return TRUE;
}
else
{
@@ -1196,6 +1277,8 @@ gtk_text_iter_backward_indexable_segment(GtkTextIter *iter)
{
g_warning("FIXME");
return FALSE;
}
gboolean
@@ -1275,7 +1358,7 @@ gtk_text_iter_forward_chars(GtkTextIter *iter, gint count)
check_invariants(iter);
current_char_index = gtk_text_buffer_get_offset(iter);
current_char_index = gtk_text_iter_get_offset(iter);
if (current_char_index == gtk_text_btree_char_count(real->tree))
return FALSE; /* can't move forward */
@@ -1285,7 +1368,13 @@ gtk_text_iter_forward_chars(GtkTextIter *iter, gint count)
check_invariants(iter);
return TRUE;
/* Return FALSE if we're on the non-dereferenceable end
* iterator.
*/
if (gtk_text_iter_is_last (iter))
return FALSE;
else
return TRUE;
}
}
@@ -1351,7 +1440,7 @@ gtk_text_iter_backward_chars(GtkTextIter *iter, gint count)
gint current_char_index;
gint new_char_index;
current_char_index = gtk_text_buffer_get_offset(iter);
current_char_index = gtk_text_iter_get_offset(iter);
if (current_char_index == 0)
return FALSE; /* can't move backward */
@@ -1387,8 +1476,11 @@ gtk_text_iter_forward_line(GtkTextIter *iter)
adjust_line_number(real, 1);
check_invariants(iter);
return TRUE;
if (gtk_text_iter_is_last (iter))
return FALSE;
else
return TRUE;
}
else
{
@@ -1507,85 +1599,153 @@ gtk_text_iter_backward_lines(GtkTextIter *iter, gint count)
}
}
typedef gboolean (* FindLogAttrFunc) (PangoLogAttr *attrs,
gint offset,
gint min_offset,
gint len,
gint *found_offset);
static gboolean
is_word_char(gunichar ch, gpointer user_data)
find_word_end_func (PangoLogAttr *attrs,
gint offset,
gint min_offset,
gint len,
gint *found_offset)
{
/* will likely need some i18n help FIXME */
return isalpha(ch);
++offset; /* We always go to the NEXT word end */
/* Find start of next word */
while (offset < min_offset + len &&
!attrs[offset].is_word_stop)
++offset;
/* Find end */
while (offset < min_offset + len &&
!attrs[offset].is_white)
++offset;
*found_offset = offset;
return offset < min_offset + len;
}
static gboolean
is_not_word_char(gunichar ch, gpointer user_data)
find_word_start_func (PangoLogAttr *attrs,
gint offset,
gint min_offset,
gint len,
gint *found_offset)
{
return !is_word_char(ch, user_data);
--offset; /* We always go to the NEXT word start */
/* Find end of prev word */
while (offset >= min_offset &&
attrs[offset].is_white)
--offset;
/* Find start */
while (offset >= min_offset &&
!attrs[offset].is_word_stop)
--offset;
*found_offset = offset;
return offset >= min_offset;
}
/* FIXME this function is very, very gratuitously slow */
static gboolean
gtk_text_iter_is_in_word(const GtkTextIter *iter)
find_by_log_attrs (GtkTextIter *iter,
FindLogAttrFunc func,
gboolean forward)
{
gint ch;
ch = gtk_text_iter_get_char(iter);
return is_word_char(ch, NULL);
}
gboolean
gtk_text_iter_forward_word_end(GtkTextIter *iter)
{
gboolean in_word;
GtkTextIter orig;
GtkTextIter start;
GtkTextIter end;
gchar *paragraph;
gint char_len, byte_len;
PangoLogAttr *attrs;
int offset;
gboolean found = FALSE;
g_return_val_if_fail(iter != NULL, FALSE);
orig = *iter;
start = *iter;
in_word = gtk_text_iter_is_in_word(iter);
end = *iter;
if (!in_word)
gtk_text_iter_set_line_offset (&start, 0);
gtk_text_iter_forward_to_newline (&end);
paragraph = gtk_text_iter_get_text (&start, &end);
char_len = g_utf8_strlen (paragraph, -1);
byte_len = strlen (paragraph);
offset = gtk_text_iter_get_line_offset (iter);
if (char_len > 0 && offset < char_len)
{
if (!gtk_text_iter_forward_find_char(iter, is_word_char, NULL))
return !gtk_text_iter_equal(iter, &start);
else
in_word = TRUE;
gchar *lang;
attrs = g_new (PangoLogAttr, char_len);
lang = gtk_text_iter_get_language (iter);
pango_get_log_attrs (paragraph, byte_len, -1,
lang,
attrs);
g_free (lang);
found = (* func) (attrs, offset, 0, char_len, &offset);
g_free (attrs);
}
g_assert(in_word);
gtk_text_iter_forward_find_char(iter, is_not_word_char, NULL);
g_free (paragraph);
if (!found)
{
if (forward)
{
if (gtk_text_iter_forward_line (iter))
return find_by_log_attrs (iter, func, forward);
else
return FALSE;
}
else
{
if (gtk_text_iter_backward_line (iter))
return find_by_log_attrs (iter, func, forward);
else
return FALSE;
}
}
else
{
gtk_text_iter_set_line_offset (iter, offset);
return
!gtk_text_iter_equal(iter, &orig) &&
!gtk_text_iter_is_last (iter);
}
}
return !gtk_text_iter_equal(iter, &start);
gboolean
gtk_text_iter_forward_word_end(GtkTextIter *iter)
{
return find_by_log_attrs (iter, find_word_end_func, TRUE);
}
gboolean
gtk_text_iter_backward_word_start(GtkTextIter *iter)
{
gboolean in_word;
GtkTextIter start;
g_return_val_if_fail(iter != NULL, FALSE);
start = *iter;
in_word = gtk_text_iter_is_in_word(iter);
if (!in_word)
{
if (!gtk_text_iter_backward_find_char(iter, is_word_char, NULL))
return !gtk_text_iter_equal(iter, &start);
else
in_word = TRUE;
}
g_assert(in_word);
gtk_text_iter_backward_find_char(iter, is_not_word_char, NULL);
gtk_text_iter_next_char(iter); /* point to first char of word,
not first non-word char. */
return !gtk_text_iter_equal(iter, &start);
return find_by_log_attrs (iter, find_word_start_func, FALSE);
}
/* FIXME a loop around a truly slow function means
* a truly spectacularly slow function.
*/
gboolean
gtk_text_iter_forward_word_ends(GtkTextIter *iter,
gint count)
@@ -1808,6 +1968,15 @@ gtk_text_iter_forward_find_tag_toggle (GtkTextIter *iter,
}
}
/* Check end iterator for tags */
if (gtk_text_iter_toggles_tag(iter, tag))
{
/* If there's a toggle here, it isn't indexable so
any_segment can't be the indexable segment. */
g_assert(real->any_segment != real->segment);
return TRUE;
}
/* Reached end of buffer */
return FALSE;
}
@@ -1866,6 +2035,167 @@ gtk_text_iter_backward_find_char (GtkTextIter *iter,
return FALSE;
}
static gboolean
lines_match (const GtkTextIter *start,
const gchar **lines,
gboolean visible_only,
GtkTextIter *match_start)
{
GtkTextIter next;
gchar *line_text;
const gchar *found;
gint offset;
if (*lines == NULL || **lines == '\0')
return TRUE;
next = *start;
gtk_text_iter_forward_line (&next);
/* No more text in buffer, but *lines is nonempty */
if (gtk_text_iter_equal (start, &next))
return FALSE;
if (visible_only)
line_text = gtk_text_iter_get_visible_text (start, &next);
else
line_text = gtk_text_iter_get_text (start, &next);
if (match_start) /* if this is the first line we're matching */
found = strstr (line_text, *lines);
else
{
/* If it's not the first line, we have to match from the
* start of the line.
*/
if (strncmp (line_text, *lines, strlen (*lines)) == 0)
found = line_text;
else
found = NULL;
}
if (found == NULL)
{
g_free (line_text);
return FALSE;
}
/* Get offset to start of search string */
offset = g_utf8_strlen (line_text, found - line_text);
next = *start;
/* If match start needs to be returned, set it to the
* start of the search string.
*/
if (match_start)
{
*match_start = next;
gtk_text_iter_forward_chars (match_start, offset);
}
/* Go to end of search string */
offset += g_utf8_strlen (*lines, -1);
gtk_text_iter_forward_chars (&next, offset);
g_free (line_text);
++lines;
/* pass NULL for match_start, since we don't need to find the
* start again.
*/
return lines_match (&next, lines, visible_only, NULL);
}
gboolean
gtk_text_iter_forward_search (GtkTextIter *iter,
const char *str,
gboolean visible_only)
{
const gchar **lines = NULL;
const gchar *newline;
int line_num = 0;
int allocated = 2;
GtkTextIter match;
gboolean retval = FALSE;
GtkTextIter search;
g_return_val_if_fail (iter != NULL, FALSE);
g_return_val_if_fail (str != NULL, FALSE);
if (*str == '\0')
return TRUE; /* we found the empty string */
/* locate all lines */
lines = g_new (const gchar*, allocated);
lines[line_num] = str;
newline = str;
while (*newline)
{
/* Note that we can have empty lines */
if (*newline == '\n')
{
++newline;
++line_num;
if (line_num == allocated)
{
allocated *= 2;
lines = g_realloc (lines, allocated + 1); /* alloc 1 for nul */
}
g_assert (line_num < allocated);
lines[line_num] = newline;
}
else
++newline;
}
++line_num;
lines[line_num] = NULL;
search = *iter;
do
{
/* This loop has an inefficient worst-case, where
* gtk_text_iter_get_text() is called repeatedly on
* a single line.
*/
if (lines_match (&search, lines, visible_only, &match))
{
retval = TRUE;
*iter = match;
break;
}
}
while (gtk_text_iter_forward_line (&search));
g_free (lines);
return retval;
}
gboolean
gtk_text_iter_backward_search (GtkTextIter *iter,
const char *str,
gboolean visible_only)
{
g_return_val_if_fail (iter != NULL, FALSE);
g_return_val_if_fail (str != NULL, FALSE);
}
/*
* Comparisons
*/
@@ -2192,7 +2522,7 @@ gtk_text_iter_spew (const GtkTextIter *iter, const gchar *desc)
g_print(" %20s: line %d / char %d / line char %d / line byte %d\n",
desc,
gtk_text_iter_get_line(iter),
gtk_text_buffer_get_offset(iter),
gtk_text_iter_get_offset(iter),
gtk_text_iter_get_line_offset(iter),
gtk_text_iter_get_line_index(iter));
check_invariants(iter);

View File

@@ -28,7 +28,7 @@ struct _GtkTextIter {
gpointer dummy8;
gint dummy9;
gpointer pad1;
gint pad2;
guint pad2;
};
@@ -47,7 +47,7 @@ void gtk_text_iter_free (GtkTextIter *iter);
* Convert to different kinds of index
*/
gint gtk_text_buffer_get_offset (const GtkTextIter *iter);
gint gtk_text_iter_get_offset (const GtkTextIter *iter);
gint gtk_text_iter_get_line (const GtkTextIter *iter);
gint gtk_text_iter_get_line_offset (const GtkTextIter *iter);
gint gtk_text_iter_get_line_index (const GtkTextIter *iter);
@@ -77,6 +77,8 @@ gboolean gtk_text_iter_get_pixmap (const GtkTextIter *iter,
GdkPixmap **pixmap,
GdkBitmap **mask);
GSList *gtk_text_iter_get_marks (const GtkTextIter *iter);
/* Return list of tags toggled at this point (toggled_on determines
whether the list is of on-toggles or off-toggles) */
GSList *gtk_text_iter_get_toggled_tags (const GtkTextIter *iter,
@@ -105,6 +107,9 @@ gint gtk_text_iter_get_chars_in_line (const GtkTextIter *iter);
gboolean gtk_text_iter_get_style_values (const GtkTextIter *iter,
GtkTextStyleValues *values);
gboolean gtk_text_iter_is_last (const GtkTextIter *iter);
gboolean gtk_text_iter_is_first (const GtkTextIter *iter);
/*
* Moving around the buffer
*/
@@ -129,7 +134,7 @@ gboolean gtk_text_iter_forward_word_end (GtkTextIter *iter);
gboolean gtk_text_iter_backward_word_start (GtkTextIter *iter);
void gtk_text_iter_set_offset (GtkTextIter *iter,
gint char_index);
gint char_offset);
void gtk_text_iter_set_line (GtkTextIter *iter,
gint line_number);
void gtk_text_iter_set_line_offset (GtkTextIter *iter,
@@ -157,16 +162,24 @@ gboolean gtk_text_iter_backward_find_char (GtkTextIter *iter,
GtkTextCharPredicate pred,
gpointer user_data);
gboolean gtk_text_iter_forward_search (GtkTextIter *iter,
const char *str,
gboolean visible_only);
gboolean gtk_text_iter_backward_search (GtkTextIter *iter,
const char *str,
gboolean visible_only);
/*
* Comparisons
*/
gboolean gtk_text_iter_equal (const GtkTextIter *lhs,
const GtkTextIter *rhs);
const GtkTextIter *rhs);
gint gtk_text_iter_compare (const GtkTextIter *lhs,
const GtkTextIter *rhs);
const GtkTextIter *rhs);
gboolean gtk_text_iter_in_region (const GtkTextIter *iter,
const GtkTextIter *start,
const GtkTextIter *end);
const GtkTextIter *start,
const GtkTextIter *end);
/* Put these two in ascending order */
void gtk_text_iter_reorder (GtkTextIter *first,

View File

@@ -246,7 +246,8 @@ gtk_text_layout_set_buffer (GtkTextLayout *layout,
if (layout->buffer)
{
gtk_text_btree_remove_view (layout->buffer->tree, layout);
gtk_text_btree_remove_view (_gtk_text_buffer_get_btree (layout->buffer),
layout);
gtk_object_unref (GTK_OBJECT (layout->buffer));
layout->buffer = NULL;
@@ -259,7 +260,7 @@ gtk_text_layout_set_buffer (GtkTextLayout *layout,
gtk_object_sink (GTK_OBJECT (buffer));
gtk_object_ref (GTK_OBJECT (buffer));
gtk_text_btree_add_view (buffer->tree, layout);
gtk_text_btree_add_view (_gtk_text_buffer_get_btree (buffer), layout);
}
}
@@ -337,7 +338,8 @@ gtk_text_layout_get_size (GtkTextLayout *layout,
g_return_if_fail (GTK_IS_TEXT_LAYOUT (layout));
gtk_text_btree_get_view_size (layout->buffer->tree, layout,
gtk_text_btree_get_view_size (_gtk_text_buffer_get_btree (layout->buffer),
layout,
&w, &h);
layout->width = w;
@@ -419,7 +421,9 @@ gtk_text_layout_get_lines (GtkTextLayout *layout,
retval = NULL;
first_btree_line = gtk_text_btree_find_line_by_y (layout->buffer->tree, layout, top_y, first_line_y);
first_btree_line =
gtk_text_btree_find_line_by_y (_gtk_text_buffer_get_btree (layout->buffer),
layout, top_y, first_line_y);
if (first_btree_line == NULL)
{
g_assert (top_y > 0);
@@ -428,11 +432,15 @@ gtk_text_layout_get_lines (GtkTextLayout *layout,
}
/* -1 since bottom_y is one past */
last_btree_line = gtk_text_btree_find_line_by_y (layout->buffer->tree, layout, bottom_y - 1, NULL);
last_btree_line =
gtk_text_btree_find_line_by_y (_gtk_text_buffer_get_btree (layout->buffer),
layout, bottom_y - 1, NULL);
if (!last_btree_line)
last_btree_line = gtk_text_btree_get_line (layout->buffer->tree,
gtk_text_btree_line_count (layout->buffer->tree) - 1, NULL);
last_btree_line =
gtk_text_btree_get_line (_gtk_text_buffer_get_btree (layout->buffer),
gtk_text_btree_line_count (_gtk_text_buffer_get_btree (layout->buffer)) - 1,
NULL);
{
GtkTextLineData *ld = gtk_text_line_get_data (last_btree_line, layout);
@@ -588,7 +596,8 @@ gtk_text_layout_is_valid (GtkTextLayout *layout)
g_return_val_if_fail (layout != NULL, FALSE);
g_return_val_if_fail (GTK_IS_TEXT_LAYOUT (layout), FALSE);
return gtk_text_btree_is_valid (layout->buffer->tree, layout);
return gtk_text_btree_is_valid (_gtk_text_buffer_get_btree (layout->buffer),
layout);
}
/**
@@ -639,7 +648,8 @@ gtk_text_layout_validate_yrange (GtkTextLayout *layout,
{
gint old_height = line_data ? line_data->height : 0;
gtk_text_btree_validate_line (layout->buffer->tree, line, layout);
gtk_text_btree_validate_line (_gtk_text_buffer_get_btree (layout->buffer),
line, layout);
line_data = gtk_text_line_get_data (line, layout);
delta_height += line_data->height - old_height;
@@ -667,7 +677,8 @@ gtk_text_layout_validate_yrange (GtkTextLayout *layout,
{
gint old_height = line_data ? line_data->height : 0;
gtk_text_btree_validate_line (layout->buffer->tree, line, layout);
gtk_text_btree_validate_line (_gtk_text_buffer_get_btree (layout->buffer),
line, layout);
line_data = gtk_text_line_get_data (line, layout);
delta_height += line_data->height - old_height;
@@ -689,7 +700,9 @@ gtk_text_layout_validate_yrange (GtkTextLayout *layout,
*/
if (first_line)
{
gint line_top = gtk_text_btree_find_line_top (layout->buffer->tree, first_line, layout);
gint line_top =
gtk_text_btree_find_line_top (_gtk_text_buffer_get_btree (layout->buffer),
first_line, layout);
gtk_text_layout_changed (layout,
line_top,
@@ -717,7 +730,8 @@ gtk_text_layout_validate (GtkTextLayout *layout,
g_return_if_fail (GTK_IS_TEXT_LAYOUT (layout));
while (max_pixels > 0 &&
gtk_text_btree_validate (layout->buffer->tree, layout, max_pixels,
gtk_text_btree_validate (_gtk_text_buffer_get_btree (layout->buffer),
layout, max_pixels,
&y, &old_height, &new_height))
{
max_pixels -= new_height;
@@ -869,7 +883,8 @@ totally_invisible_line (GtkTextLayout *layout,
function can use the whole btree to get it right. */
else
{
gtk_text_btree_get_iter_at_line(layout->buffer->tree, iter, line, 0);
gtk_text_btree_get_iter_at_line(_gtk_text_buffer_get_btree (layout->buffer),
iter, line, 0);
if (!gtk_text_btree_char_is_invisible (iter))
return FALSE;
@@ -1117,7 +1132,8 @@ add_cursor (GtkTextLayout *layout,
/* Hide insertion cursor when we have a selection
*/
if (gtk_text_btree_mark_is_insert (layout->buffer->tree, (GtkTextMark*)seg) &&
if (gtk_text_btree_mark_is_insert (_gtk_text_buffer_get_btree (layout->buffer),
(GtkTextMark*)seg) &&
gtk_text_buffer_get_selection_bounds (layout->buffer, &selection_start, &selection_end))
return;
@@ -1187,7 +1203,8 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
display->size_only = size_only;
display->line = line;
gtk_text_btree_get_iter_at_line (layout->buffer->tree, &iter, line, 0);
gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
&iter, line, 0);
/* Special-case optimization for completely
* invisible lines; makes it faster to deal
@@ -1212,7 +1229,7 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
if (seg->type == &gtk_text_char_type ||
seg->type == &gtk_text_pixmap_type)
{
gtk_text_btree_get_iter_at_line (layout->buffer->tree,
gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
&iter, line,
byte_offset);
style = get_style (layout, &iter);
@@ -1401,13 +1418,16 @@ get_line_at_y (GtkTextLayout *layout,
if (y > layout->height)
y = layout->height;
*line = gtk_text_btree_find_line_by_y (layout->buffer->tree, layout, y, line_top);
*line = gtk_text_btree_find_line_by_y (_gtk_text_buffer_get_btree (layout->buffer),
layout, y, line_top);
if (*line == NULL)
{
*line = gtk_text_btree_get_line (layout->buffer->tree,
gtk_text_btree_line_count (layout->buffer->tree) - 1, NULL);
*line = gtk_text_btree_get_line (_gtk_text_buffer_get_btree (layout->buffer),
gtk_text_btree_line_count (_gtk_text_buffer_get_btree (layout->buffer)) - 1, NULL);
if (line_top)
*line_top = gtk_text_btree_find_line_top (layout->buffer->tree, *line, layout);
*line_top =
gtk_text_btree_find_line_top (_gtk_text_buffer_get_btree (layout->buffer),
*line, layout);
}
}
@@ -1434,7 +1454,8 @@ gtk_text_layout_get_line_at_y (GtkTextLayout *layout,
g_return_if_fail (target_iter != NULL);
get_line_at_y (layout, y, &line, line_top);
gtk_text_btree_get_iter_at_line (layout->buffer->tree, target_iter, line, 0);
gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
target_iter, line, 0);
}
void
@@ -1477,7 +1498,7 @@ gtk_text_layout_get_iter_at_pixel (GtkTextLayout *layout,
trailing = 0;
}
gtk_text_btree_get_iter_at_line (layout->buffer->tree,
gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
target_iter,
line, byte_index);
@@ -1520,7 +1541,8 @@ gtk_text_layout_get_cursor_locations (GtkTextLayout *layout,
g_return_if_fail (iter != NULL);
line = gtk_text_iter_get_text_line (iter);
line_top = gtk_text_btree_find_line_top (layout->buffer->tree, line, layout);
line_top = gtk_text_btree_find_line_top (_gtk_text_buffer_get_btree (layout->buffer),
line, layout);
display = gtk_text_layout_get_line_display (layout, line, TRUE);
@@ -1564,10 +1586,11 @@ gtk_text_layout_get_line_y (GtkTextLayout *layout,
GtkTextLine *line;
g_return_val_if_fail (GTK_IS_TEXT_LAYOUT (layout), 0);
g_return_val_if_fail (gtk_text_iter_get_btree (iter) == layout->buffer->tree, 0);
g_return_val_if_fail (gtk_text_iter_get_btree (iter) == _gtk_text_buffer_get_btree (layout->buffer), 0);
line = gtk_text_iter_get_text_line (iter);
return gtk_text_btree_find_line_top (layout->buffer->tree, line, layout);
return gtk_text_btree_find_line_top (_gtk_text_buffer_get_btree (layout->buffer),
line, layout);
}
void
@@ -1582,7 +1605,7 @@ gtk_text_layout_get_iter_location (GtkTextLayout *layout,
gint byte_index;
g_return_if_fail (GTK_IS_TEXT_LAYOUT (layout));
g_return_if_fail (gtk_text_iter_get_btree (iter) == layout->buffer->tree);
g_return_if_fail (gtk_text_iter_get_btree (iter) == _gtk_text_buffer_get_btree (layout->buffer));
g_return_if_fail (rect != NULL);
tree = gtk_text_iter_get_btree (iter);
@@ -1592,32 +1615,14 @@ gtk_text_layout_get_iter_location (GtkTextLayout *layout,
rect->y = gtk_text_btree_find_line_top (tree, line, layout);
/* pango_layout_index_to_pos() expects the index of a character within the layout,
* so we have to special case the last character. FIXME: This should be moved
* to Pango.
*/
if (gtk_text_iter_ends_line (iter))
{
PangoLayoutLine *last_line = g_slist_last (pango_layout_get_lines (display->layout))->data;
pango_layout_line_get_extents (last_line, NULL, &pango_rect);
rect->x = display->x_offset + (pango_rect.x + pango_rect.width) / PANGO_SCALE;
rect->y += display->top_margin;
rect->width = 0;
rect->height = pango_rect.height / PANGO_SCALE;
}
else
{
byte_index = gtk_text_iter_get_line_index (iter);
byte_index = gtk_text_iter_get_line_index (iter);
pango_layout_index_to_pos (display->layout, byte_index, &pango_rect);
rect->x = display->x_offset + pango_rect.x / PANGO_SCALE;
rect->y += display->top_margin;
rect->width = pango_rect.width / PANGO_SCALE;
rect->height = pango_rect.height / PANGO_SCALE;
}
pango_layout_index_to_pos (display->layout, byte_index, &pango_rect);
rect->x = display->x_offset + pango_rect.x / PANGO_SCALE;
rect->y += display->top_margin + pango_rect.y / PANGO_SCALE;
rect->width = pango_rect.width / PANGO_SCALE;
rect->height = pango_rect.height / PANGO_SCALE;
gtk_text_layout_free_line_display (layout, display);
}
@@ -1636,12 +1641,17 @@ find_display_line_below (GtkTextLayout *layout,
gint line_top;
gint found_byte = 0;
line = gtk_text_btree_find_line_by_y (layout->buffer->tree, layout, y, &line_top);
line = gtk_text_btree_find_line_by_y (_gtk_text_buffer_get_btree (layout->buffer),
layout, y, &line_top);
if (!line)
{
line = gtk_text_btree_get_line (layout->buffer->tree,
gtk_text_btree_line_count (layout->buffer->tree) - 1, NULL);
line_top = gtk_text_btree_find_line_top (layout->buffer->tree, line, layout);
line =
gtk_text_btree_get_line (_gtk_text_buffer_get_btree (layout->buffer),
gtk_text_btree_line_count (_gtk_text_buffer_get_btree (layout->buffer)) - 1,
NULL);
line_top =
gtk_text_btree_find_line_top (_gtk_text_buffer_get_btree (layout->buffer),
line, layout);
}
while (line && !found_line)
@@ -1681,7 +1691,8 @@ find_display_line_below (GtkTextLayout *layout,
line = next;
}
gtk_text_btree_get_iter_at_line (layout->buffer->tree, iter, found_line, found_byte);
gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
iter, found_line, found_byte);
}
/* Find the iter for the logical beginning of the last display line whose
@@ -1698,12 +1709,12 @@ find_display_line_above (GtkTextLayout *layout,
gint line_top;
gint found_byte = 0;
line = gtk_text_btree_find_line_by_y (layout->buffer->tree, layout, y, &line_top);
line = gtk_text_btree_find_line_by_y (_gtk_text_buffer_get_btree (layout->buffer), layout, y, &line_top);
if (!line)
{
line = gtk_text_btree_get_line (layout->buffer->tree,
gtk_text_btree_line_count (layout->buffer->tree) - 1, NULL);
line_top = gtk_text_btree_find_line_top (layout->buffer->tree, line, layout);
line = gtk_text_btree_get_line (_gtk_text_buffer_get_btree (layout->buffer),
gtk_text_btree_line_count (_gtk_text_buffer_get_btree (layout->buffer)) - 1, NULL);
line_top = gtk_text_btree_find_line_top (_gtk_text_buffer_get_btree (layout->buffer), line, layout);
}
while (line && !found_line)
@@ -1747,7 +1758,8 @@ find_display_line_above (GtkTextLayout *layout,
}
if (found_line)
gtk_text_btree_get_iter_at_line (layout->buffer->tree, iter, found_line, found_byte);
gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
iter, found_line, found_byte);
else
gtk_text_buffer_get_iter_at_offset (layout->buffer, iter, 0);
}
@@ -1821,7 +1833,7 @@ gtk_text_layout_move_iter_to_previous_line (GtkTextLayout *layout,
g_return_if_fail (iter != NULL);
line = gtk_text_iter_get_text_line (iter);
line_byte = gtk_text_iter_get_line_offset (iter);
line_byte = gtk_text_iter_get_line_index (iter);
display = gtk_text_layout_get_line_display (layout, line, TRUE);
@@ -1849,11 +1861,11 @@ gtk_text_layout_move_iter_to_previous_line (GtkTextLayout *layout,
byte_offset += layout_line->length;
}
gtk_text_btree_get_iter_at_line (layout->buffer->tree,
gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
iter, prev_line, byte_offset);
}
else
gtk_text_btree_get_iter_at_line (layout->buffer->tree,
gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
iter, line, 0);
}
else
@@ -1868,7 +1880,7 @@ gtk_text_layout_move_iter_to_previous_line (GtkTextLayout *layout,
if (line_byte < byte_offset + layout_line->length || !tmp_list->next)
{
gtk_text_btree_get_iter_at_line (layout->buffer->tree,
gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
iter, line, prev_offset);
break;
}
@@ -1907,7 +1919,7 @@ gtk_text_layout_move_iter_to_next_line (GtkTextLayout *layout,
g_return_if_fail (iter != NULL);
line = gtk_text_iter_get_text_line (iter);
line_byte = gtk_text_iter_get_line_offset (iter);
line_byte = gtk_text_iter_get_line_index (iter);
while (line && !found_after)
{
@@ -1923,7 +1935,7 @@ gtk_text_layout_move_iter_to_next_line (GtkTextLayout *layout,
if (found)
{
gtk_text_btree_get_iter_at_line (layout->buffer->tree,
gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
iter, line,
byte_offset);
found_after = TRUE;
@@ -2005,7 +2017,7 @@ gtk_text_layout_move_iter_to_x (GtkTextLayout *layout,
x * PANGO_SCALE - x_offset,
&byte_index, &trailing);
gtk_text_btree_get_iter_at_line (layout->buffer->tree,
gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
iter,
line, byte_index);
@@ -2090,7 +2102,7 @@ gtk_text_layout_move_iter_visually (GtkTextLayout *layout,
new_index = 0;
}
gtk_text_btree_get_iter_at_line (layout->buffer->tree,
gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
iter,
line, new_index);
while (new_trailing--)

View File

@@ -923,6 +923,14 @@ delta_priority_foreach(GtkTextTag *tag, gpointer user_data)
tag->priority += dd->delta;
}
gint
gtk_text_tag_get_priority (GtkTextTag *tag)
{
g_return_val_if_fail(GTK_IS_TEXT_TAG(tag), 0);
return tag->priority;
}
void
gtk_text_tag_set_priority(GtkTextTag *tag,
gint priority)

View File

@@ -96,6 +96,7 @@ struct _GtkTextTagClass {
GtkType gtk_text_tag_get_type (void);
GtkTextTag *gtk_text_tag_new (const gchar *name);
gint gtk_text_tag_get_priority (GtkTextTag *tag);
void gtk_text_tag_set_priority (GtkTextTag *tag,
gint priority);
gint gtk_text_tag_event (GtkTextTag *tag,

View File

@@ -216,6 +216,9 @@ static void gtk_text_view_set_virtual_cursor_pos (GtkTextView *text_view,
gint x,
gint y);
static GtkAdjustment* get_hadjustment (GtkTextView *text_view);
static GtkAdjustment* get_vadjustment (GtkTextView *text_view);
enum {
TARGET_STRING,
TARGET_TEXT,
@@ -826,7 +829,7 @@ gtk_text_view_scroll_to_mark_adjusted (GtkTextView *text_view,
if (scroll_inc != 0)
{
set_adjustment_clamped (text_view->vadjustment,
set_adjustment_clamped (get_vadjustment (text_view),
current_y_scroll + scroll_inc);
retval = TRUE;
}
@@ -847,7 +850,7 @@ gtk_text_view_scroll_to_mark_adjusted (GtkTextView *text_view,
if (scroll_inc != 0)
{
set_adjustment_clamped (text_view->hadjustment,
set_adjustment_clamped (get_hadjustment (text_view),
current_x_scroll + scroll_inc);
retval = TRUE;
}
@@ -1041,8 +1044,11 @@ gtk_text_view_finalize (GObject *object)
text_view = GTK_TEXT_VIEW (object);
gtk_object_unref (GTK_OBJECT (text_view->hadjustment));
gtk_object_unref (GTK_OBJECT (text_view->vadjustment));
if (text_view->hadjustment)
gtk_object_unref (GTK_OBJECT (text_view->hadjustment));
if (text_view->vadjustment)
gtk_object_unref (GTK_OBJECT (text_view->vadjustment));
gtk_object_unref (GTK_OBJECT (text_view->im_context));
(* G_OBJECT_CLASS (parent_class)->finalize) (object);
@@ -1127,8 +1133,8 @@ gtk_text_view_size_request (GtkWidget *widget,
GtkTextView *text_view = GTK_TEXT_VIEW (widget);
/* Hrm */
requisition->width = 1;
requisition->height = 1;
requisition->width = 200;
requisition->height = 200;
/* Check to see if the widget direction has changed */
@@ -1180,6 +1186,10 @@ gtk_text_view_size_allocate (GtkWidget *widget,
gtk_text_view_get_first_para_iter (text_view, &first_para);
y = gtk_text_layout_get_line_y (text_view->layout, &first_para) + text_view->first_para_pixels;
/* Ensure h/v adj exist */
get_hadjustment (text_view);
get_vadjustment (text_view);
vadj = text_view->vadjustment;
if (y > vadj->upper - vadj->page_size)
y = MAX (0, vadj->upper - vadj->page_size);
@@ -1189,7 +1199,7 @@ gtk_text_view_size_allocate (GtkWidget *widget,
vadj->value = text_view->yoffset = y;
yoffset_changed = TRUE;
}
text_view->hadjustment->page_size = allocation->width;
text_view->hadjustment->page_increment = allocation->width / 2;
text_view->hadjustment->lower = 0;
@@ -1308,15 +1318,14 @@ changed_handler (GtkTextLayout *layout,
if (start_y + old_height <= text_view->yoffset - text_view->first_para_pixels)
{
text_view->yoffset += new_height - old_height;
text_view->vadjustment->value = text_view->yoffset;
get_vadjustment (text_view)->value = text_view->yoffset;
yoffset_changed = TRUE;
}
gtk_text_view_scroll_calc_now (text_view);
if (yoffset_changed)
gtk_adjustment_value_changed (text_view->vadjustment);
gtk_adjustment_value_changed (get_vadjustment (text_view));
}
}
@@ -2428,11 +2437,13 @@ gtk_text_view_scroll_calc_now (GtkTextView *text_view)
text_view->width = width;
text_view->height = height;
gtk_text_view_set_adjustment_upper (text_view->hadjustment,
gtk_text_view_set_adjustment_upper (get_hadjustment (text_view),
MAX (widget->allocation.width, width));
gtk_text_view_set_adjustment_upper (text_view->vadjustment,
gtk_text_view_set_adjustment_upper (get_vadjustment (text_view),
MAX (widget->allocation.height, height));
/* hadj/vadj exist since we called get_hadjustment/get_vadjustment above */
/* Set up the step sizes; we'll say that a page is
our allocation minus one step, and a step is
1/10 of our allocation. */
@@ -2871,6 +2882,33 @@ gtk_text_view_drag_data_received (GtkWidget *widget,
}
}
static GtkAdjustment*
get_hadjustment (GtkTextView *text_view)
{
if (text_view->hadjustment == NULL)
gtk_text_view_set_scroll_adjustments (text_view,
(GtkAdjustment*)
gtk_adjustment_new (0.0, 0.0, 0.0,
0.0, 0.0, 0.0),
text_view->vadjustment);
return text_view->hadjustment;
}
static GtkAdjustment*
get_vadjustment (GtkTextView *text_view)
{
if (text_view->vadjustment == NULL)
gtk_text_view_set_scroll_adjustments (text_view,
text_view->hadjustment,
(GtkAdjustment*)
gtk_adjustment_new (0.0, 0.0, 0.0,
0.0, 0.0, 0.0));
return text_view->vadjustment;
}
static void
gtk_text_view_set_scroll_adjustments (GtkTextView *text_view,
GtkAdjustment *hadj,

View File

@@ -1586,10 +1586,8 @@ static void
gtk_window_real_set_transient_for (GtkWindow *window,
GtkWindow *parent)
{
g_return_if_fail (window != NULL);
g_return_if_fail (parent != NULL);
g_return_if_fail (GTK_IS_WINDOW (window));
g_return_if_fail (GTK_IS_WINDOW (parent));
g_return_if_fail (parent == NULL || GTK_IS_WINDOW (parent));
g_return_if_fail (window != parent);
if (window->transient_parent)

View File

@@ -21,6 +21,7 @@ struct _Buffer
char *filename;
gint untitled_serial;
GtkTextTag *not_editable_tag;
GtkTextTag *found_text_tag;
};
struct _View
@@ -42,6 +43,9 @@ static gboolean save_buffer (Buffer *buffer);
static gboolean save_as_buffer (Buffer *buffer);
static char * buffer_pretty_name (Buffer *buffer);
static void buffer_filename_set (Buffer *buffer);
static void buffer_search_forward (Buffer *buffer,
const char *str,
View *view);
static View *view_from_widget (GtkWidget *widget);
@@ -313,7 +317,7 @@ tag_event_handler (GtkTextTag *tag, GtkWidget *widget, GdkEvent *event,
{
gint char_index;
char_index = gtk_text_buffer_get_offset (iter);
char_index = gtk_text_iter_get_offset (iter);
switch (event->type)
{
@@ -891,6 +895,71 @@ do_apply_editable (gpointer callback_data,
}
}
static void
dialog_response_callback (GtkWidget *dialog, gint response_id, gpointer data)
{
GtkTextBuffer *buffer;
View *view = data;
GtkTextIter start, end;
gchar *search_string;
buffer = gtk_object_get_data (GTK_OBJECT (dialog), "buffer");
gtk_text_buffer_get_bounds (buffer, &start, &end);
/* Remove trailing newline */
gtk_text_iter_prev_char (&end);
search_string = gtk_text_iter_get_text (&start, &end);
printf ("Searching for `%s'\n", search_string);
buffer_search_forward (view->buffer, search_string, view);
g_free (search_string);
gtk_widget_destroy (dialog);
}
static void
do_search (gpointer callback_data,
guint callback_action,
GtkWidget *widget)
{
View *view = view_from_widget (widget);
GtkWidget *dialog;
GtkWidget *search_text;
GtkTextBuffer *buffer;
dialog = gtk_dialog_new_with_buttons ("Search",
GTK_WINDOW (view->window),
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_STOCK_BUTTON_OK,
0, NULL);
buffer = gtk_text_buffer_new (NULL);
/* FIXME memory leak once buffer is a GObject */
search_text = gtk_text_view_new_with_buffer (buffer);
gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->vbox),
search_text,
TRUE, TRUE, 0);
gtk_object_set_data (GTK_OBJECT (dialog), "buffer", buffer);
gtk_signal_connect (GTK_OBJECT (dialog),
"response",
GTK_SIGNAL_FUNC (dialog_response_callback),
view);
gtk_widget_show (search_text);
gtk_widget_grab_focus (search_text);
gtk_widget_show_all (dialog);
}
static void
view_init_menus (View *view)
{
@@ -941,6 +1010,9 @@ static GtkItemFactoryEntry menu_items[] =
{ "/File/_Close", "<control>W" , do_close, 0, NULL },
{ "/File/E_xit", "<control>Q" , do_exit, 0, NULL },
{ "/_Edit", NULL, 0, 0, "<Branch>" },
{ "/Edit/Find...", NULL, do_search, 0, NULL },
{ "/_Settings", NULL, 0, 0, "<Branch>" },
{ "/Settings/Wrap _Off", NULL, do_wrap_changed, GTK_WRAPMODE_NONE, "<RadioItem>" },
{ "/Settings/Wrap _Words", NULL, do_wrap_changed, GTK_WRAPMODE_WORD, "/Settings/Wrap Off" },
@@ -1127,6 +1199,10 @@ create_buffer (void)
gtk_object_set (GTK_OBJECT (buffer->not_editable_tag),
"editable", FALSE,
"foreground", "purple", NULL);
buffer->found_text_tag = gtk_text_buffer_create_tag (buffer->buffer, NULL);
gtk_object_set (GTK_OBJECT (buffer->found_text_tag),
"foreground", "red", NULL);
buffers = g_slist_prepend (buffers, buffer);
@@ -1174,6 +1250,55 @@ buffer_filename_set (Buffer *buffer)
}
}
static void
buffer_search_forward (Buffer *buffer, const char *str,
View *view)
{
GtkTextIter iter;
GtkTextIter start, end;
gint char_len;
int i = 0;
GtkWidget *dialog;
/* remove tag from whole buffer */
gtk_text_buffer_get_bounds (buffer->buffer, &start, &end);
gtk_text_buffer_remove_tag (buffer->buffer, buffer->found_text_tag,
&start, &end );
gtk_text_buffer_get_iter_at_mark (buffer->buffer, &iter,
gtk_text_buffer_get_mark (buffer->buffer,
"insert"));
char_len = g_utf8_strlen (str, -1);
while (gtk_text_iter_forward_search (&iter, str, TRUE))
{
GtkTextIter end = iter;
gtk_text_iter_forward_chars (&end, char_len);
gtk_text_buffer_apply_tag (buffer->buffer, buffer->found_text_tag,
&iter, &end);
++i;
}
dialog = gtk_message_dialog_new (GTK_WINDOW (view->window),
GTK_MESSAGE_INFO,
GTK_BUTTONS_OK,
GTK_DIALOG_DESTROY_WITH_PARENT,
"%d strings found and marked in red",
i);
gtk_signal_connect_object (GTK_OBJECT (dialog),
"response",
GTK_SIGNAL_FUNC (gtk_widget_destroy),
GTK_OBJECT (dialog));
gtk_widget_show (dialog);
}
static void
buffer_ref (Buffer *buffer)
{
@@ -1292,7 +1417,8 @@ main (int argc, char** argv)
int i;
gtk_init (&argc, &argv);
gdk_rgb_init (); /* FIXME remove this */
buffer = create_buffer ();
view = create_view (buffer);
buffer_unref (buffer);

View File

@@ -101,7 +101,7 @@ run_tests (GtkTextBuffer *buffer)
g_error ("get_char_index didn't return current iter");
}
j = gtk_text_buffer_get_offset (&iter);
j = gtk_text_iter_get_offset (&iter);
if (i != j)
{
@@ -128,9 +128,12 @@ run_tests (GtkTextBuffer *buffer)
gtk_text_iter_spew (&mark, "mark");
g_error ("Mark not created in the right place.");
}
if (gtk_text_iter_is_last (&iter))
g_error ("iterators ran out before chars (offset %d of %d)",
i, num_chars);
if (!gtk_text_iter_next_char (&iter))
g_error ("iterators ran out before chars");
gtk_text_iter_next_char (&iter);
gtk_text_buffer_move_mark (buffer, bar_mark, &iter);
@@ -163,7 +166,7 @@ run_tests (GtkTextBuffer *buffer)
{
g_error ("get_char_index didn't return current iter while going backward");
}
j = gtk_text_buffer_get_offset (&iter);
j = gtk_text_iter_get_offset (&iter);
if (i != j)
{
@@ -218,11 +221,10 @@ run_tests (GtkTextBuffer *buffer)
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)
if (i != gtk_text_buffer_get_line_count (buffer))
g_error ("Counted %d lines, buffer has %d", i,
gtk_text_buffer_get_line_count (buffer) + 1);
gtk_text_buffer_get_line_count (buffer));
}

View File

@@ -21,6 +21,7 @@ struct _Buffer
char *filename;
gint untitled_serial;
GtkTextTag *not_editable_tag;
GtkTextTag *found_text_tag;
};
struct _View
@@ -42,6 +43,9 @@ static gboolean save_buffer (Buffer *buffer);
static gboolean save_as_buffer (Buffer *buffer);
static char * buffer_pretty_name (Buffer *buffer);
static void buffer_filename_set (Buffer *buffer);
static void buffer_search_forward (Buffer *buffer,
const char *str,
View *view);
static View *view_from_widget (GtkWidget *widget);
@@ -313,7 +317,7 @@ tag_event_handler (GtkTextTag *tag, GtkWidget *widget, GdkEvent *event,
{
gint char_index;
char_index = gtk_text_buffer_get_offset (iter);
char_index = gtk_text_iter_get_offset (iter);
switch (event->type)
{
@@ -891,6 +895,71 @@ do_apply_editable (gpointer callback_data,
}
}
static void
dialog_response_callback (GtkWidget *dialog, gint response_id, gpointer data)
{
GtkTextBuffer *buffer;
View *view = data;
GtkTextIter start, end;
gchar *search_string;
buffer = gtk_object_get_data (GTK_OBJECT (dialog), "buffer");
gtk_text_buffer_get_bounds (buffer, &start, &end);
/* Remove trailing newline */
gtk_text_iter_prev_char (&end);
search_string = gtk_text_iter_get_text (&start, &end);
printf ("Searching for `%s'\n", search_string);
buffer_search_forward (view->buffer, search_string, view);
g_free (search_string);
gtk_widget_destroy (dialog);
}
static void
do_search (gpointer callback_data,
guint callback_action,
GtkWidget *widget)
{
View *view = view_from_widget (widget);
GtkWidget *dialog;
GtkWidget *search_text;
GtkTextBuffer *buffer;
dialog = gtk_dialog_new_with_buttons ("Search",
GTK_WINDOW (view->window),
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_STOCK_BUTTON_OK,
0, NULL);
buffer = gtk_text_buffer_new (NULL);
/* FIXME memory leak once buffer is a GObject */
search_text = gtk_text_view_new_with_buffer (buffer);
gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->vbox),
search_text,
TRUE, TRUE, 0);
gtk_object_set_data (GTK_OBJECT (dialog), "buffer", buffer);
gtk_signal_connect (GTK_OBJECT (dialog),
"response",
GTK_SIGNAL_FUNC (dialog_response_callback),
view);
gtk_widget_show (search_text);
gtk_widget_grab_focus (search_text);
gtk_widget_show_all (dialog);
}
static void
view_init_menus (View *view)
{
@@ -941,6 +1010,9 @@ static GtkItemFactoryEntry menu_items[] =
{ "/File/_Close", "<control>W" , do_close, 0, NULL },
{ "/File/E_xit", "<control>Q" , do_exit, 0, NULL },
{ "/_Edit", NULL, 0, 0, "<Branch>" },
{ "/Edit/Find...", NULL, do_search, 0, NULL },
{ "/_Settings", NULL, 0, 0, "<Branch>" },
{ "/Settings/Wrap _Off", NULL, do_wrap_changed, GTK_WRAPMODE_NONE, "<RadioItem>" },
{ "/Settings/Wrap _Words", NULL, do_wrap_changed, GTK_WRAPMODE_WORD, "/Settings/Wrap Off" },
@@ -1127,6 +1199,10 @@ create_buffer (void)
gtk_object_set (GTK_OBJECT (buffer->not_editable_tag),
"editable", FALSE,
"foreground", "purple", NULL);
buffer->found_text_tag = gtk_text_buffer_create_tag (buffer->buffer, NULL);
gtk_object_set (GTK_OBJECT (buffer->found_text_tag),
"foreground", "red", NULL);
buffers = g_slist_prepend (buffers, buffer);
@@ -1174,6 +1250,55 @@ buffer_filename_set (Buffer *buffer)
}
}
static void
buffer_search_forward (Buffer *buffer, const char *str,
View *view)
{
GtkTextIter iter;
GtkTextIter start, end;
gint char_len;
int i = 0;
GtkWidget *dialog;
/* remove tag from whole buffer */
gtk_text_buffer_get_bounds (buffer->buffer, &start, &end);
gtk_text_buffer_remove_tag (buffer->buffer, buffer->found_text_tag,
&start, &end );
gtk_text_buffer_get_iter_at_mark (buffer->buffer, &iter,
gtk_text_buffer_get_mark (buffer->buffer,
"insert"));
char_len = g_utf8_strlen (str, -1);
while (gtk_text_iter_forward_search (&iter, str, TRUE))
{
GtkTextIter end = iter;
gtk_text_iter_forward_chars (&end, char_len);
gtk_text_buffer_apply_tag (buffer->buffer, buffer->found_text_tag,
&iter, &end);
++i;
}
dialog = gtk_message_dialog_new (GTK_WINDOW (view->window),
GTK_MESSAGE_INFO,
GTK_BUTTONS_OK,
GTK_DIALOG_DESTROY_WITH_PARENT,
"%d strings found and marked in red",
i);
gtk_signal_connect_object (GTK_OBJECT (dialog),
"response",
GTK_SIGNAL_FUNC (gtk_widget_destroy),
GTK_OBJECT (dialog));
gtk_widget_show (dialog);
}
static void
buffer_ref (Buffer *buffer)
{
@@ -1292,7 +1417,8 @@ main (int argc, char** argv)
int i;
gtk_init (&argc, &argv);
gdk_rgb_init (); /* FIXME remove this */
buffer = create_buffer ();
view = create_view (buffer);
buffer_unref (buffer);

View File

@@ -101,7 +101,7 @@ run_tests (GtkTextBuffer *buffer)
g_error ("get_char_index didn't return current iter");
}
j = gtk_text_buffer_get_offset (&iter);
j = gtk_text_iter_get_offset (&iter);
if (i != j)
{
@@ -128,9 +128,12 @@ run_tests (GtkTextBuffer *buffer)
gtk_text_iter_spew (&mark, "mark");
g_error ("Mark not created in the right place.");
}
if (gtk_text_iter_is_last (&iter))
g_error ("iterators ran out before chars (offset %d of %d)",
i, num_chars);
if (!gtk_text_iter_next_char (&iter))
g_error ("iterators ran out before chars");
gtk_text_iter_next_char (&iter);
gtk_text_buffer_move_mark (buffer, bar_mark, &iter);
@@ -163,7 +166,7 @@ run_tests (GtkTextBuffer *buffer)
{
g_error ("get_char_index didn't return current iter while going backward");
}
j = gtk_text_buffer_get_offset (&iter);
j = gtk_text_iter_get_offset (&iter);
if (i != j)
{
@@ -218,11 +221,10 @@ run_tests (GtkTextBuffer *buffer)
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)
if (i != gtk_text_buffer_get_line_count (buffer))
g_error ("Counted %d lines, buffer has %d", i,
gtk_text_buffer_get_line_count (buffer) + 1);
gtk_text_buffer_get_line_count (buffer));
}