+2001-09-25 Havoc Pennington <hp@redhat.com>
+
+ * gtk/gtktextview.c (gtk_text_view_key_press_event): use
+ gtk_text_iter_can_insert
+
+ * gtk/gtktextbuffer.c: use gtk_text_iter_can_insert
+
+ * gtk/gtktextiter.c (find_line_log_attrs): fixes, #57611, #57613
+ (gtk_text_iter_can_insert): new function to fix #60282, should
+ also fix msw's "can paste into empty buffer" bug.
+
+ * gtk/gtktexttag.c (gtk_text_tag_event): change type check for
+ "event object," #59091
+
+ * gtk/gtktextbtree.c: indentation fixes
+
+ * gtk/gtktextiter.c (find_by_log_attrs): fixes
+
Tue Sep 25 12:41:17 2001 Owen Taylor <otaylor@redhat.com>
* configure.in: Version 1.3.9, interface age 0, binary age 0.
+2001-09-25 Havoc Pennington <hp@redhat.com>
+
+ * gtk/gtktextview.c (gtk_text_view_key_press_event): use
+ gtk_text_iter_can_insert
+
+ * gtk/gtktextbuffer.c: use gtk_text_iter_can_insert
+
+ * gtk/gtktextiter.c (find_line_log_attrs): fixes, #57611, #57613
+ (gtk_text_iter_can_insert): new function to fix #60282, should
+ also fix msw's "can paste into empty buffer" bug.
+
+ * gtk/gtktexttag.c (gtk_text_tag_event): change type check for
+ "event object," #59091
+
+ * gtk/gtktextbtree.c: indentation fixes
+
+ * gtk/gtktextiter.c (find_by_log_attrs): fixes
+
Tue Sep 25 12:41:17 2001 Owen Taylor <otaylor@redhat.com>
* configure.in: Version 1.3.9, interface age 0, binary age 0.
+2001-09-25 Havoc Pennington <hp@redhat.com>
+
+ * gtk/gtktextview.c (gtk_text_view_key_press_event): use
+ gtk_text_iter_can_insert
+
+ * gtk/gtktextbuffer.c: use gtk_text_iter_can_insert
+
+ * gtk/gtktextiter.c (find_line_log_attrs): fixes, #57611, #57613
+ (gtk_text_iter_can_insert): new function to fix #60282, should
+ also fix msw's "can paste into empty buffer" bug.
+
+ * gtk/gtktexttag.c (gtk_text_tag_event): change type check for
+ "event object," #59091
+
+ * gtk/gtktextbtree.c: indentation fixes
+
+ * gtk/gtktextiter.c (find_by_log_attrs): fixes
+
Tue Sep 25 12:41:17 2001 Owen Taylor <otaylor@redhat.com>
* configure.in: Version 1.3.9, interface age 0, binary age 0.
+2001-09-25 Havoc Pennington <hp@redhat.com>
+
+ * gtk/gtktextview.c (gtk_text_view_key_press_event): use
+ gtk_text_iter_can_insert
+
+ * gtk/gtktextbuffer.c: use gtk_text_iter_can_insert
+
+ * gtk/gtktextiter.c (find_line_log_attrs): fixes, #57611, #57613
+ (gtk_text_iter_can_insert): new function to fix #60282, should
+ also fix msw's "can paste into empty buffer" bug.
+
+ * gtk/gtktexttag.c (gtk_text_tag_event): change type check for
+ "event object," #59091
+
+ * gtk/gtktextbtree.c: indentation fixes
+
+ * gtk/gtktextiter.c (find_by_log_attrs): fixes
+
Tue Sep 25 12:41:17 2001 Owen Taylor <otaylor@redhat.com>
* configure.in: Version 1.3.9, interface age 0, binary age 0.
+2001-09-25 Havoc Pennington <hp@redhat.com>
+
+ * gtk/gtktextview.c (gtk_text_view_key_press_event): use
+ gtk_text_iter_can_insert
+
+ * gtk/gtktextbuffer.c: use gtk_text_iter_can_insert
+
+ * gtk/gtktextiter.c (find_line_log_attrs): fixes, #57611, #57613
+ (gtk_text_iter_can_insert): new function to fix #60282, should
+ also fix msw's "can paste into empty buffer" bug.
+
+ * gtk/gtktexttag.c (gtk_text_tag_event): change type check for
+ "event object," #59091
+
+ * gtk/gtktextbtree.c: indentation fixes
+
+ * gtk/gtktextiter.c (find_by_log_attrs): fixes
+
Tue Sep 25 12:41:17 2001 Owen Taylor <otaylor@redhat.com>
* configure.in: Version 1.3.9, interface age 0, binary age 0.
+2001-09-25 Havoc Pennington <hp@redhat.com>
+
+ * gtk/gtktextview.c (gtk_text_view_key_press_event): use
+ gtk_text_iter_can_insert
+
+ * gtk/gtktextbuffer.c: use gtk_text_iter_can_insert
+
+ * gtk/gtktextiter.c (find_line_log_attrs): fixes, #57611, #57613
+ (gtk_text_iter_can_insert): new function to fix #60282, should
+ also fix msw's "can paste into empty buffer" bug.
+
+ * gtk/gtktexttag.c (gtk_text_tag_event): change type check for
+ "event object," #59091
+
+ * gtk/gtktextbtree.c: indentation fixes
+
+ * gtk/gtktextiter.c (find_by_log_attrs): fixes
+
Tue Sep 25 12:41:17 2001 Owen Taylor <otaylor@redhat.com>
* configure.in: Version 1.3.9, interface age 0, binary age 0.
+2001-09-25 Havoc Pennington <hp@redhat.com>
+
+ * gtk/gtktextview.c (gtk_text_view_key_press_event): use
+ gtk_text_iter_can_insert
+
+ * gtk/gtktextbuffer.c: use gtk_text_iter_can_insert
+
+ * gtk/gtktextiter.c (find_line_log_attrs): fixes, #57611, #57613
+ (gtk_text_iter_can_insert): new function to fix #60282, should
+ also fix msw's "can paste into empty buffer" bug.
+
+ * gtk/gtktexttag.c (gtk_text_tag_event): change type check for
+ "event object," #59091
+
+ * gtk/gtktextbtree.c: indentation fixes
+
+ * gtk/gtktextiter.c (find_by_log_attrs): fixes
+
Tue Sep 25 12:41:17 2001 Owen Taylor <otaylor@redhat.com>
* configure.in: Version 1.3.9, interface age 0, binary age 0.
@tree_model:
@iter:
+<!-- ##### FUNCTION gtk_tree_view_column_set_cell_renderer ##### -->
+<para>
+
+</para>
+
+@tree_column:
+@cell:
+
<!-- ##### FUNCTION gtk_tree_view_column_set_width ##### -->
<para>
Adds a new #GtkMenuItem to the end of the menu's item list.
</para>
+<!-- # Unused Parameters # -->
@menu: a #GtkMenu.
@child: The #GtkMenuItem to add.
-<!-- # Unused Parameters # -->
@m:
@c:
Adds a new #GtkMenuItem to the beginning of the menu's item list.
</para>
+<!-- # Unused Parameters # -->
@menu: a #GtkMenu.
@child: The #GtkMenuItem to add.
-<!-- # Unused Parameters # -->
@menu_child:
@m:
@c:
indicated by @position.
</para>
+<!-- # Unused Parameters # -->
@menu: a #GtkMenu.
@child: The #GtkMenuItem to add.
@pos:
-<!-- # Unused Parameters # -->
@position: The position in the item list where @child is added.
Positions are numbered from 0 to n-1.
@Returns:
-<!-- ##### FUNCTION gtk_tree_view_column_set_cell_renderer ##### -->
-<para>
-
-</para>
-
-@tree_column:
-@cell:
-
-
<!-- ##### FUNCTION gtk_tree_view_column_add_attribute ##### -->
<para>
/* FIXME this function is far too slow, for no good reason. */
gboolean
_gtk_text_line_char_has_tag (GtkTextLine *line,
- GtkTextBTree *tree,
- gint char_in_line,
- GtkTextTag *tag)
+ GtkTextBTree *tree,
+ gint char_in_line,
+ GtkTextTag *tag)
{
GtkTextLineSegment *toggle_seg;
gboolean
_gtk_text_line_byte_has_tag (GtkTextLine *line,
- GtkTextBTree *tree,
- gint byte_in_line,
- GtkTextTag *tag)
+ GtkTextBTree *tree,
+ gint byte_in_line,
+ GtkTextTag *tag)
{
GtkTextLineSegment *toggle_seg;
gboolean
_gtk_text_line_is_last (GtkTextLine *line,
- GtkTextBTree *tree)
+ GtkTextBTree *tree)
{
return line == get_last_line (tree);
}
g_return_val_if_fail (text != NULL, FALSE);
g_return_val_if_fail (gtk_text_iter_get_buffer (iter) == buffer, FALSE);
- if (gtk_text_iter_editable (iter, default_editable))
+ if (gtk_text_iter_can_insert (iter, default_editable))
{
gtk_text_buffer_begin_user_action (buffer);
gtk_text_buffer_emit_insert (buffer, iter, text, len);
buffer->tag_table, FALSE);
- if (gtk_text_iter_editable (iter, default_editable))
+ if (gtk_text_iter_can_insert (iter, default_editable))
{
gtk_text_buffer_real_insert_range (buffer, iter, start, end, TRUE);
return TRUE;
* Return value: whether @tag is toggled on or off at @iter
**/
gboolean
-gtk_text_iter_toggles_tag (const GtkTextIter *iter,
- GtkTextTag *tag)
+gtk_text_iter_toggles_tag (const GtkTextIter *iter,
+ GtkTextTag *tag)
{
GtkTextRealIter *real;
GtkTextLineSegment *seg;
* Return value: whether @iter is tagged with @tag
**/
gboolean
-gtk_text_iter_has_tag (const GtkTextIter *iter,
- GtkTextTag *tag)
+gtk_text_iter_has_tag (const GtkTextIter *iter,
+ GtkTextTag *tag)
{
GtkTextRealIter *real;
if (real->line_byte_offset >= 0)
{
return _gtk_text_line_byte_has_tag (real->line, real->tree,
- real->line_byte_offset, tag);
+ real->line_byte_offset, tag);
}
else
{
g_assert (real->line_char_offset >= 0);
return _gtk_text_line_char_has_tag (real->line, real->tree,
- real->line_char_offset, tag);
+ real->line_char_offset, tag);
}
}
/**
* gtk_text_iter_editable:
* @iter: an iterator
- * @default_setting: TRUE if text is editable by default
+ * @default_setting: %TRUE if text is editable by default
*
- * Returns whether @iter is within an editable region of text.
- * Non-editable text is "locked" and can't be changed by the user via
- * #GtkTextView. This function is simply a convenience wrapper around
- * gtk_text_iter_get_attributes (). If no tags applied to this text
- * affect editability, @default_setting will be returned.
+ * Returns whether the character at @iter is within an editable region
+ * of text. Non-editable text is "locked" and can't be changed by the
+ * user via #GtkTextView. This function is simply a convenience
+ * wrapper around gtk_text_iter_get_attributes (). If no tags applied
+ * to this text affect editability, @default_setting will be returned.
*
+ * You don't want to use this function to decide whether text can be
+ * inserted at @iter, because for insertion you don't want to know
+ * whether the char at @iter is inside an editable range, you want to
+ * know whether a new character inserted at @iter would be inside an
+ * editable range. Use gtk_text_iter_can_insert() to handle this
+ * case.
+ *
* Return value: whether @iter is inside an editable range
**/
gboolean
GtkTextAttributes *values;
gboolean retval;
+ g_return_val_if_fail (iter != NULL, FALSE);
+
values = gtk_text_attributes_new ();
values->editable = default_setting;
return retval;
}
+/**
+ * gtk_text_iter_can_insert:
+ * @iter: an iterator
+ * @default_editability: %TRUE if text is editable by default
+ *
+ * Considering the default editability of the buffer, and tags that
+ * affect editability, determines whether text inserted at @iter would
+ * be editable. If text inserted at @iter would be editable then the
+ * user should be allowed to insert text at @iter.
+ * gtk_text_buffer_insert_interactive() uses this function to decide
+ * whether insertions are allowed at a given position.
+ *
+ * Return value: whether text inserted at @iter would be editable
+ **/
+gboolean
+gtk_text_iter_can_insert (const GtkTextIter *iter,
+ gboolean default_editability)
+{
+ g_return_val_if_fail (iter != NULL, FALSE);
+
+ if (gtk_text_iter_editable (iter, default_editability))
+ return TRUE;
+ /* If at start/end of buffer, default editability is used */
+ else if ((gtk_text_iter_is_start (iter) ||
+ gtk_text_iter_is_end (iter)) &&
+ default_editability)
+ return TRUE;
+ else
+ {
+ /* if iter isn't editable, and the char before iter is,
+ * then iter is the first char in an editable region
+ * and thus insertion at iter results in editable text.
+ */
+ GtkTextIter prev = *iter;
+ gtk_text_iter_backward_char (&prev);
+ return gtk_text_iter_editable (&prev, default_editability);
+ }
+}
+
+
/**
* gtk_text_iter_get_language:
* @iter: an iterator
**/
gboolean
gtk_text_iter_get_attributes (const GtkTextIter *iter,
- GtkTextAttributes *values)
+ GtkTextAttributes *values)
{
GtkTextTag** tags;
gint tag_count = 0;
iter, &char_len);
offset = gtk_text_iter_get_line_offset (iter);
-
+
/* char_len may be 0 and attrs will be NULL if so, if
* iter is the end iter and the last line is empty
*/
- if (offset < char_len)
+ if (attrs)
result = (* func) (attrs, offset, 0, char_len, found_offset,
already_moved_initially);
}
else
{
- /* go to end of previous line */
- gtk_text_iter_set_line_offset (iter, 0);
-
- if (gtk_text_iter_backward_char (iter))
- return find_by_log_attrs (iter, func, forward,
- TRUE);
+ /* go to end of previous line. need to check that
+ * line is > 0 because backward_line snaps to start of
+ * line 0 if it's on line 0
+ */
+ if (gtk_text_iter_get_line (iter) > 0 &&
+ gtk_text_iter_backward_line (iter))
+ {
+ if (!gtk_text_iter_ends_line (iter))
+ gtk_text_iter_forward_to_line_end (iter);
+
+ return find_by_log_attrs (iter, func, forward,
+ TRUE);
+ }
else
return FALSE;
}
}
else
- {
+ {
gtk_text_iter_set_line_offset (iter, offset);
return
- !gtk_text_iter_equal (iter, &orig) &&
+ (already_moved_initially || !gtk_text_iter_equal (iter, &orig)) &&
!gtk_text_iter_is_end (iter);
}
}
gint len,
gint *found_offset,
gboolean already_moved_initially)
-{
+{
if (!already_moved_initially)
--offset;
gboolean gtk_text_iter_editable (const GtkTextIter *iter,
gboolean default_setting);
+gboolean gtk_text_iter_can_insert (const GtkTextIter *iter,
+ gboolean default_editability);
gboolean gtk_text_iter_starts_word (const GtkTextIter *iter);
gboolean gtk_text_iter_ends_word (const GtkTextIter *iter);
gboolean retval = FALSE;
g_return_val_if_fail (GTK_IS_TEXT_TAG (tag), FALSE);
- g_return_val_if_fail (GTK_IS_OBJECT (event_object), FALSE);
+ g_return_val_if_fail (G_IS_OBJECT (event_object), FALSE);
g_return_val_if_fail (event != NULL, FALSE);
g_signal_emit (G_OBJECT (tag),
insert = gtk_text_buffer_get_insert (get_buffer (text_view));
gtk_text_buffer_get_iter_at_mark (get_buffer (text_view), &iter, insert);
- if (gtk_text_iter_editable (&iter, text_view->editable) &&
+ if (gtk_text_iter_can_insert (&iter, text_view->editable) &&
gtk_im_context_filter_keypress (text_view->im_context, event))
{
text_view->need_im_reset = TRUE;
}
else
{
- if (gtk_text_iter_editable (&newplace, text_view->editable))
+ if (gtk_text_iter_can_insert (&newplace, text_view->editable))
{
GtkWidget *source_widget;
&iter,
gtk_text_buffer_get_insert (get_buffer (text_view)));
- can_insert = gtk_text_iter_editable (&iter, text_view->editable);
+ can_insert = gtk_text_iter_can_insert (&iter, text_view->editable);
append_action_signal (text_view, text_view->popup_menu, _("Cut"), "cut_clipboard",
have_selection);
static void line_separator_tests (void);
+static void logical_motion_tests (void);
+
int
main (int argc, char** argv)
{
/* Check some line separator stuff */
line_separator_tests ();
+
+ /* Check log attr motion */
+ logical_motion_tests ();
/* Create a buffer */
buffer = gtk_text_buffer_new (NULL);
str = g_strdup_printf ("line%sqw", buf);
test_line_separation (str, TRUE, FALSE, 2, 4, 5);
g_free (str);
+
+ g_print ("Line separator tests passed\n");
+}
+
+static void
+logical_motion_tests (void)
+{
+ char *str;
+ char buf1[7] = { '\0', };
+ char buf2[7] = { '\0', };
+ char buf3[7] = { '\0', };
+ int expected[30];
+ int expected_steps;
+ int i;
+ GtkTextBuffer *buffer;
+ GtkTextIter iter;
+
+ buffer = gtk_text_buffer_new (NULL);
+
+#define LEADING_JAMO 0x1111
+#define VOWEL_JAMO 0x1167
+#define TRAILING_JAMO 0x11B9
+
+ g_unichar_to_utf8 (LEADING_JAMO, buf1);
+ g_unichar_to_utf8 (VOWEL_JAMO, buf2);
+ g_unichar_to_utf8 (TRAILING_JAMO, buf3);
+
+ /* Build the string "abc<leading><vowel><trailing>def\r\nxyz" */
+ str = g_strconcat ("abc", buf1, buf2, buf3, "def\r\nxyz", NULL);
+ gtk_text_buffer_set_text (buffer, str, -1);
+ g_free (str);
+
+ /* Check cursor positions */
+ memset (expected, 0, sizeof (expected));
+ expected[0] = 0; /* before 'a' */
+ expected[1] = 1; /* before 'b' */
+ expected[2] = 2; /* before 'c' */
+ expected[3] = 3; /* before jamo */
+ expected[4] = 6; /* before 'd' */
+ expected[5] = 7; /* before 'e' */
+ expected[6] = 8; /* before 'f' */
+ expected[7] = 9; /* before '\r' */
+ expected[8] = 11; /* before 'x' */
+ expected[9] = 12; /* before 'y' */
+ expected[10] = 13; /* before 'z' */
+ expected[11] = 14; /* after 'z' */
+ expected_steps = 11;
+
+ gtk_text_buffer_get_start_iter (buffer, &iter);
+ i = 0;
+ do
+ {
+ int pos;
+
+ pos = gtk_text_iter_get_offset (&iter);
+
+ if (pos != expected[i])
+ {
+ g_error ("Cursor position %d, expected %d",
+ pos, expected[i]);
+ }
+
+ /* g_print ("%d = %d\n", pos, expected[i]); */
+
+ ++i;
+ }
+ while (gtk_text_iter_forward_cursor_position (&iter));
+
+ if (i != expected_steps)
+ g_error ("Expected %d steps, there were actually %d\n", expected_steps, i);
+
+ if (!gtk_text_iter_is_end (&iter))
+ g_error ("Expected to stop at the end iterator\n");
+
+ i = expected_steps;
+ do
+ {
+ int pos;
+
+ pos = gtk_text_iter_get_offset (&iter);
+
+ if (pos != expected[i])
+ {
+ g_error ("Moving backward, cursor position %d, expected %d",
+ pos, expected[i]);
+ }
+
+ /* g_print ("%d = %d\n", pos, expected[i]); */
+
+ --i;
+ }
+ while (gtk_text_iter_backward_cursor_position (&iter));
+
+ if (i != -1)
+ g_error ("Expected %d steps, there were actually %d\n", expected_steps - i, i);
+
+ if (!gtk_text_iter_is_start (&iter))
+ g_error ("Expected to stop at the start iterator\n");
+
+ g_print ("Logical motion tests passed\n");
+
+ g_object_unref (G_OBJECT (buffer));
}