summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog24
-rw-r--r--ChangeLog.pre-2-024
-rw-r--r--ChangeLog.pre-2-1024
-rw-r--r--ChangeLog.pre-2-224
-rw-r--r--ChangeLog.pre-2-424
-rw-r--r--ChangeLog.pre-2-624
-rw-r--r--ChangeLog.pre-2-824
-rw-r--r--docs/reference/gtk/tmpl/gtkrc.sgml1
-rw-r--r--gtk/gtkdialog.c74
-rw-r--r--gtk/gtkmessagedialog.c52
-rw-r--r--gtk/gtktextbuffer.h3
-rw-r--r--gtk/gtktextdisplay.c99
-rw-r--r--gtk/gtktextiter.c196
-rw-r--r--gtk/gtktextiter.h7
-rw-r--r--gtk/gtktextlayout.c86
-rw-r--r--tests/testtext.c2
16 files changed, 584 insertions, 104 deletions
diff --git a/ChangeLog b/ChangeLog
index 0b32b0f69a..2759990064 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,27 @@
+2001-04-21 Havoc Pennington <hp@pobox.com>
+
+ * gtk/gtktextdisplay.c (gtk_text_layout_draw): handle 0-height
+ empty/invisible lines.
+
+ * gtk/gtktextiter.c (gtk_text_iter_set_visible_line_offset)
+ (gtk_text_iter_set_visible_line_index): new functions to set
+ indexes excluding invisible text
+
+ * gtk/gtktextlayout.c (line_display_iter_to_index): get visible
+ index
+
+ * gtk/gtktextiter.c (gtk_text_iter_get_visible_line_index)
+ (gtk_text_iter_get_visible_line_offset): new functions to
+ get indexes excluding invisible text
+
+ * gtk/gtkmessagedialog.c (gtk_message_dialog_init): strip out a
+ bunch of extra padding that served no purpose
+
+ * gtk/gtkdialog.c: Make all the spacings configurable via style
+ properties, for chubbiness configuration in themes
+
+ * tests/testtext.c: fix path to the immodules.
+
Mon Apr 23 18:57:03 2001 Jonathan Blandford <jrb@redhat.com>
* gtk/gtksocket.c (gtk_socket_filter_func): add missing '}' that
diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0
index 0b32b0f69a..2759990064 100644
--- a/ChangeLog.pre-2-0
+++ b/ChangeLog.pre-2-0
@@ -1,3 +1,27 @@
+2001-04-21 Havoc Pennington <hp@pobox.com>
+
+ * gtk/gtktextdisplay.c (gtk_text_layout_draw): handle 0-height
+ empty/invisible lines.
+
+ * gtk/gtktextiter.c (gtk_text_iter_set_visible_line_offset)
+ (gtk_text_iter_set_visible_line_index): new functions to set
+ indexes excluding invisible text
+
+ * gtk/gtktextlayout.c (line_display_iter_to_index): get visible
+ index
+
+ * gtk/gtktextiter.c (gtk_text_iter_get_visible_line_index)
+ (gtk_text_iter_get_visible_line_offset): new functions to
+ get indexes excluding invisible text
+
+ * gtk/gtkmessagedialog.c (gtk_message_dialog_init): strip out a
+ bunch of extra padding that served no purpose
+
+ * gtk/gtkdialog.c: Make all the spacings configurable via style
+ properties, for chubbiness configuration in themes
+
+ * tests/testtext.c: fix path to the immodules.
+
Mon Apr 23 18:57:03 2001 Jonathan Blandford <jrb@redhat.com>
* gtk/gtksocket.c (gtk_socket_filter_func): add missing '}' that
diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10
index 0b32b0f69a..2759990064 100644
--- a/ChangeLog.pre-2-10
+++ b/ChangeLog.pre-2-10
@@ -1,3 +1,27 @@
+2001-04-21 Havoc Pennington <hp@pobox.com>
+
+ * gtk/gtktextdisplay.c (gtk_text_layout_draw): handle 0-height
+ empty/invisible lines.
+
+ * gtk/gtktextiter.c (gtk_text_iter_set_visible_line_offset)
+ (gtk_text_iter_set_visible_line_index): new functions to set
+ indexes excluding invisible text
+
+ * gtk/gtktextlayout.c (line_display_iter_to_index): get visible
+ index
+
+ * gtk/gtktextiter.c (gtk_text_iter_get_visible_line_index)
+ (gtk_text_iter_get_visible_line_offset): new functions to
+ get indexes excluding invisible text
+
+ * gtk/gtkmessagedialog.c (gtk_message_dialog_init): strip out a
+ bunch of extra padding that served no purpose
+
+ * gtk/gtkdialog.c: Make all the spacings configurable via style
+ properties, for chubbiness configuration in themes
+
+ * tests/testtext.c: fix path to the immodules.
+
Mon Apr 23 18:57:03 2001 Jonathan Blandford <jrb@redhat.com>
* gtk/gtksocket.c (gtk_socket_filter_func): add missing '}' that
diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2
index 0b32b0f69a..2759990064 100644
--- a/ChangeLog.pre-2-2
+++ b/ChangeLog.pre-2-2
@@ -1,3 +1,27 @@
+2001-04-21 Havoc Pennington <hp@pobox.com>
+
+ * gtk/gtktextdisplay.c (gtk_text_layout_draw): handle 0-height
+ empty/invisible lines.
+
+ * gtk/gtktextiter.c (gtk_text_iter_set_visible_line_offset)
+ (gtk_text_iter_set_visible_line_index): new functions to set
+ indexes excluding invisible text
+
+ * gtk/gtktextlayout.c (line_display_iter_to_index): get visible
+ index
+
+ * gtk/gtktextiter.c (gtk_text_iter_get_visible_line_index)
+ (gtk_text_iter_get_visible_line_offset): new functions to
+ get indexes excluding invisible text
+
+ * gtk/gtkmessagedialog.c (gtk_message_dialog_init): strip out a
+ bunch of extra padding that served no purpose
+
+ * gtk/gtkdialog.c: Make all the spacings configurable via style
+ properties, for chubbiness configuration in themes
+
+ * tests/testtext.c: fix path to the immodules.
+
Mon Apr 23 18:57:03 2001 Jonathan Blandford <jrb@redhat.com>
* gtk/gtksocket.c (gtk_socket_filter_func): add missing '}' that
diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4
index 0b32b0f69a..2759990064 100644
--- a/ChangeLog.pre-2-4
+++ b/ChangeLog.pre-2-4
@@ -1,3 +1,27 @@
+2001-04-21 Havoc Pennington <hp@pobox.com>
+
+ * gtk/gtktextdisplay.c (gtk_text_layout_draw): handle 0-height
+ empty/invisible lines.
+
+ * gtk/gtktextiter.c (gtk_text_iter_set_visible_line_offset)
+ (gtk_text_iter_set_visible_line_index): new functions to set
+ indexes excluding invisible text
+
+ * gtk/gtktextlayout.c (line_display_iter_to_index): get visible
+ index
+
+ * gtk/gtktextiter.c (gtk_text_iter_get_visible_line_index)
+ (gtk_text_iter_get_visible_line_offset): new functions to
+ get indexes excluding invisible text
+
+ * gtk/gtkmessagedialog.c (gtk_message_dialog_init): strip out a
+ bunch of extra padding that served no purpose
+
+ * gtk/gtkdialog.c: Make all the spacings configurable via style
+ properties, for chubbiness configuration in themes
+
+ * tests/testtext.c: fix path to the immodules.
+
Mon Apr 23 18:57:03 2001 Jonathan Blandford <jrb@redhat.com>
* gtk/gtksocket.c (gtk_socket_filter_func): add missing '}' that
diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6
index 0b32b0f69a..2759990064 100644
--- a/ChangeLog.pre-2-6
+++ b/ChangeLog.pre-2-6
@@ -1,3 +1,27 @@
+2001-04-21 Havoc Pennington <hp@pobox.com>
+
+ * gtk/gtktextdisplay.c (gtk_text_layout_draw): handle 0-height
+ empty/invisible lines.
+
+ * gtk/gtktextiter.c (gtk_text_iter_set_visible_line_offset)
+ (gtk_text_iter_set_visible_line_index): new functions to set
+ indexes excluding invisible text
+
+ * gtk/gtktextlayout.c (line_display_iter_to_index): get visible
+ index
+
+ * gtk/gtktextiter.c (gtk_text_iter_get_visible_line_index)
+ (gtk_text_iter_get_visible_line_offset): new functions to
+ get indexes excluding invisible text
+
+ * gtk/gtkmessagedialog.c (gtk_message_dialog_init): strip out a
+ bunch of extra padding that served no purpose
+
+ * gtk/gtkdialog.c: Make all the spacings configurable via style
+ properties, for chubbiness configuration in themes
+
+ * tests/testtext.c: fix path to the immodules.
+
Mon Apr 23 18:57:03 2001 Jonathan Blandford <jrb@redhat.com>
* gtk/gtksocket.c (gtk_socket_filter_func): add missing '}' that
diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8
index 0b32b0f69a..2759990064 100644
--- a/ChangeLog.pre-2-8
+++ b/ChangeLog.pre-2-8
@@ -1,3 +1,27 @@
+2001-04-21 Havoc Pennington <hp@pobox.com>
+
+ * gtk/gtktextdisplay.c (gtk_text_layout_draw): handle 0-height
+ empty/invisible lines.
+
+ * gtk/gtktextiter.c (gtk_text_iter_set_visible_line_offset)
+ (gtk_text_iter_set_visible_line_index): new functions to set
+ indexes excluding invisible text
+
+ * gtk/gtktextlayout.c (line_display_iter_to_index): get visible
+ index
+
+ * gtk/gtktextiter.c (gtk_text_iter_get_visible_line_index)
+ (gtk_text_iter_get_visible_line_offset): new functions to
+ get indexes excluding invisible text
+
+ * gtk/gtkmessagedialog.c (gtk_message_dialog_init): strip out a
+ bunch of extra padding that served no purpose
+
+ * gtk/gtkdialog.c: Make all the spacings configurable via style
+ properties, for chubbiness configuration in themes
+
+ * tests/testtext.c: fix path to the immodules.
+
Mon Apr 23 18:57:03 2001 Jonathan Blandford <jrb@redhat.com>
* gtk/gtksocket.c (gtk_socket_filter_func): add missing '}' that
diff --git a/docs/reference/gtk/tmpl/gtkrc.sgml b/docs/reference/gtk/tmpl/gtkrc.sgml
index 178b403922..4c81682d17 100644
--- a/docs/reference/gtk/tmpl/gtkrc.sgml
+++ b/docs/reference/gtk/tmpl/gtkrc.sgml
@@ -496,6 +496,7 @@ This can later be composited together with other
#GtkRcStyle structures to form a #GtkStyle.
</para>
+@parent_instance:
@name:
@bg_pixmap_name:
@font_desc:
diff --git a/gtk/gtkdialog.c b/gtk/gtkdialog.c
index b4af6a7a26..324f781d15 100644
--- a/gtk/gtkdialog.c
+++ b/gtk/gtkdialog.c
@@ -55,6 +55,8 @@ static void gtk_dialog_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec);
+static void gtk_dialog_style_set (GtkWidget *widget,
+ GtkStyle *prev_style);
enum {
PROP_0,
@@ -111,7 +113,8 @@ gtk_dialog_class_init (GtkDialogClass *class)
gobject_class->get_property = gtk_dialog_get_property;
widget_class->key_press_event = gtk_dialog_key_press;
-
+ widget_class->style_set = gtk_dialog_style_set;
+
g_object_class_install_property (gobject_class,
PROP_HAS_SEPARATOR,
g_param_spec_boolean ("has_separator",
@@ -128,6 +131,59 @@ gtk_dialog_class_init (GtkDialogClass *class)
gtk_marshal_NONE__INT,
GTK_TYPE_NONE, 1,
GTK_TYPE_INT);
+
+ gtk_widget_class_install_style_property (widget_class,
+ g_param_spec_int ("content_area_border",
+ _("Content area border"),
+ _("Width of border around the main dialog area"),
+ 0,
+ G_MAXINT,
+ 2,
+ G_PARAM_READABLE));
+ gtk_widget_class_install_style_property (widget_class,
+ g_param_spec_int ("button_spacing",
+ _("Button spacing"),
+ _("Spacing between buttons"),
+ 0,
+ G_MAXINT,
+ 1,
+ G_PARAM_READABLE));
+
+ gtk_widget_class_install_style_property (widget_class,
+ g_param_spec_int ("action_area_border",
+ _("Action area border"),
+ _("Width of border around the button area at the bottom of the dialog"),
+ 0,
+ G_MAXINT,
+ 0,
+ G_PARAM_READABLE));
+}
+
+static void
+update_spacings (GtkDialog *dialog)
+{
+ GtkWidget *widget;
+ gint content_area_border;
+ gint button_spacing;
+ gint action_area_border;
+
+ widget = GTK_WIDGET (dialog);
+
+ gtk_widget_style_get (widget,
+ "content_area_border",
+ &content_area_border,
+ "button_spacing",
+ &button_spacing,
+ "action_area_border",
+ &action_area_border,
+ NULL);
+
+ gtk_container_set_border_width (GTK_CONTAINER (dialog->vbox),
+ content_area_border);
+ gtk_box_set_spacing (GTK_BOX (dialog->action_area),
+ button_spacing);
+ gtk_container_set_border_width (GTK_CONTAINER (dialog->action_area),
+ action_area_border);
}
static void
@@ -143,8 +199,6 @@ gtk_dialog_init (GtkDialog *dialog)
NULL);
dialog->vbox = gtk_vbox_new (FALSE, 0);
-
- gtk_container_set_border_width (GTK_CONTAINER (dialog->vbox), 2);
gtk_container_add (GTK_CONTAINER (dialog), dialog->vbox);
gtk_widget_show (dialog->vbox);
@@ -152,11 +206,8 @@ gtk_dialog_init (GtkDialog *dialog)
dialog->action_area = gtk_hbutton_box_new ();
gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog->action_area),
- GTK_BUTTONBOX_END);
+ GTK_BUTTONBOX_END);
- gtk_box_set_spacing (GTK_BOX (dialog->action_area), 5);
-
- gtk_container_set_border_width (GTK_CONTAINER (dialog->action_area), 5);
gtk_box_pack_end (GTK_BOX (dialog->vbox), dialog->action_area,
FALSE, TRUE, 0);
gtk_widget_show (dialog->action_area);
@@ -252,6 +303,13 @@ gtk_dialog_key_press (GtkWidget *widget,
return TRUE;
}
+static void
+gtk_dialog_style_set (GtkWidget *widget,
+ GtkStyle *prev_style)
+{
+ update_spacings (GTK_DIALOG (widget));
+}
+
GtkWidget*
gtk_dialog_new (void)
{
@@ -444,7 +502,7 @@ gtk_dialog_add_action_widget (GtkDialog *dialog,
gtk_box_pack_end (GTK_BOX (dialog->action_area),
child,
- FALSE, TRUE, 5);
+ FALSE, TRUE, 0);
}
/**
diff --git a/gtk/gtkmessagedialog.c b/gtk/gtkmessagedialog.c
index 6a74193cf2..c6a0145a93 100644
--- a/gtk/gtkmessagedialog.c
+++ b/gtk/gtkmessagedialog.c
@@ -30,10 +30,14 @@
#include "gtkimage.h"
#include "gtkstock.h"
#include "gtkiconfactory.h"
+#include "gtkintl.h"
static void gtk_message_dialog_class_init (GtkMessageDialogClass *klass);
static void gtk_message_dialog_init (GtkMessageDialog *dialog);
+static void gtk_message_dialog_style_set (GtkWidget *widget,
+ GtkStyle *prev_style);
+static gpointer parent_class;
GtkType
gtk_message_dialog_get_type (void)
@@ -63,6 +67,22 @@ gtk_message_dialog_get_type (void)
static void
gtk_message_dialog_class_init (GtkMessageDialogClass *class)
{
+ GtkWidgetClass *widget_class;
+
+ widget_class = GTK_WIDGET_CLASS (class);
+
+ parent_class = g_type_class_peek_parent (class);
+
+ widget_class->style_set = gtk_message_dialog_style_set;
+
+ gtk_widget_class_install_style_property (widget_class,
+ g_param_spec_int ("message_border",
+ _("Image/label border"),
+ _("Width of border around the label and image in the message dialog"),
+ 0,
+ G_MAXINT,
+ 8,
+ G_PARAM_READABLE));
}
static void
@@ -75,19 +95,17 @@ gtk_message_dialog_init (GtkMessageDialog *dialog)
gtk_label_set_line_wrap (GTK_LABEL (dialog->label), TRUE);
- hbox = gtk_hbox_new (FALSE, 10);
+ hbox = gtk_hbox_new (FALSE, 6);
- gtk_container_set_border_width (GTK_CONTAINER (hbox), 10);
-
gtk_box_pack_start (GTK_BOX (hbox), dialog->image,
- FALSE, FALSE, 2);
+ FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (hbox), dialog->label,
- TRUE, TRUE, 2);
+ TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
hbox,
- FALSE, FALSE, 10);
+ FALSE, FALSE, 0);
gtk_widget_show_all (hbox);
}
@@ -247,3 +265,25 @@ gtk_message_dialog_new (GtkWindow *parent,
return widget;
}
+
+static void
+gtk_message_dialog_style_set (GtkWidget *widget,
+ GtkStyle *prev_style)
+{
+ GtkWidget *parent;
+ gint border_width = 0;
+
+ parent = GTK_WIDGET (GTK_MESSAGE_DIALOG (widget)->image->parent);
+
+ if (parent)
+ {
+ gtk_widget_style_get (widget, "message_border",
+ &border_width, NULL);
+
+ gtk_container_set_border_width (GTK_CONTAINER (parent),
+ border_width);
+ }
+
+ if (GTK_WIDGET_CLASS (parent_class)->style_set)
+ (GTK_WIDGET_CLASS (parent_class)->style_set) (widget, prev_style);
+}
diff --git a/gtk/gtktextbuffer.h b/gtk/gtktextbuffer.h
index 54f245e8aa..b6f801f119 100644
--- a/gtk/gtktextbuffer.h
+++ b/gtk/gtktextbuffer.h
@@ -277,7 +277,8 @@ GtkTextTag *gtk_text_buffer_create_tag (GtkTextBuffer *buffer,
...);
/* Obtain iterators pointed at various places, then you can move the
- iterator around using the GtkTextIter operators */
+ * iterator around using the GtkTextIter operators
+ */
void gtk_text_buffer_get_iter_at_line_offset (GtkTextBuffer *buffer,
GtkTextIter *iter,
gint line_number,
diff --git a/gtk/gtktextdisplay.c b/gtk/gtktextdisplay.c
index 17e3f5b560..0b2c3f7872 100644
--- a/gtk/gtktextdisplay.c
+++ b/gtk/gtktextdisplay.c
@@ -739,66 +739,71 @@ gtk_text_layout_draw (GtkTextLayout *layout,
GtkTextLine *line = tmp_list->data;
line_display = gtk_text_layout_get_line_display (layout, line, FALSE);
-
- if (have_selection)
- {
- GtkTextIter line_start, line_end;
- gint byte_count;
- gtk_text_layout_get_iter_at_line (layout,
- &line_start,
- line, 0);
- byte_count = gtk_text_iter_get_bytes_in_line (&line_start);
+ if (line_display->height > 0)
+ {
+ g_assert (line_display->layout != NULL);
- /* FIXME the -1 assumes a newline I think */
- gtk_text_layout_get_iter_at_line (layout,
- &line_end,
- line, byte_count - 1);
-
- if (gtk_text_iter_compare (&selection_start, &line_end) < 0 &&
- gtk_text_iter_compare (&selection_end, &line_start) > 0)
+ if (have_selection)
{
- if (gtk_text_iter_compare (&selection_start, &line_start) >= 0)
- selection_start_index = gtk_text_iter_get_line_index (&selection_start);
- else
- selection_start_index = -1;
+ GtkTextIter line_start, line_end;
+ gint byte_count;
- if (gtk_text_iter_compare (&selection_end, &line_end) <= 0)
- selection_end_index = gtk_text_iter_get_line_index (&selection_end);
- else
- selection_end_index = byte_count;
+ gtk_text_layout_get_iter_at_line (layout,
+ &line_start,
+ line, 0);
+ byte_count = gtk_text_iter_get_bytes_in_line (&line_start);
+
+ /* FIXME the -1 assumes a newline I think */
+ gtk_text_layout_get_iter_at_line (layout,
+ &line_end,
+ line, byte_count - 1);
+
+ if (gtk_text_iter_compare (&selection_start, &line_end) < 0 &&
+ gtk_text_iter_compare (&selection_end, &line_start) > 0)
+ {
+ if (gtk_text_iter_compare (&selection_start, &line_start) >= 0)
+ selection_start_index = gtk_text_iter_get_line_index (&selection_start);
+ else
+ selection_start_index = -1;
+
+ if (gtk_text_iter_compare (&selection_end, &line_end) <= 0)
+ selection_end_index = gtk_text_iter_get_line_index (&selection_end);
+ else
+ selection_end_index = byte_count;
+ }
}
- }
- render_para (drawable, render_state, line_display,
- - x_offset,
- current_y,
- selection_start_index, selection_end_index);
+ render_para (drawable, render_state, line_display,
+ - x_offset,
+ current_y,
+ selection_start_index, selection_end_index);
- /* We paint the cursors last, because they overlap another chunk
+ /* We paint the cursors last, because they overlap another chunk
and need to appear on top. */
- cursor_list = line_display->cursors;
- while (cursor_list)
- {
- GtkTextCursorDisplay *cursor = cursor_list->data;
- GdkGC *gc;
-
- if (cursor->is_strong)
- gc = widget->style->base_gc[GTK_STATE_SELECTED];
- else
- gc = widget->style->text_gc[GTK_STATE_NORMAL];
+ cursor_list = line_display->cursors;
+ while (cursor_list)
+ {
+ GtkTextCursorDisplay *cursor = cursor_list->data;
+ GdkGC *gc;
- gdk_draw_line (drawable, gc,
- line_display->x_offset + cursor->x - x_offset,
- current_y + line_display->top_margin + cursor->y,
- line_display->x_offset + cursor->x - x_offset,
- current_y + line_display->top_margin + cursor->y + cursor->height - 1);
+ if (cursor->is_strong)
+ gc = widget->style->base_gc[GTK_STATE_SELECTED];
+ else
+ gc = widget->style->text_gc[GTK_STATE_NORMAL];
- cursor_list = cursor_list->next;
- }
+ gdk_draw_line (drawable, gc,
+ line_display->x_offset + cursor->x - x_offset,
+ current_y + line_display->top_margin + cursor->y,
+ line_display->x_offset + cursor->x - x_offset,
+ current_y + line_display->top_margin + cursor->y + cursor->height - 1);
+ cursor_list = cursor_list->next;
+ }
+ } /* line_display->height > 0 */
+
current_y += line_display->height;
gtk_text_layout_free_line_display (layout, line_display);
render_state->last_appearance = NULL;
diff --git a/gtk/gtktextiter.c b/gtk/gtktextiter.c
index 73a51ed368..241529d389 100644
--- a/gtk/gtktextiter.c
+++ b/gtk/gtktextiter.c
@@ -650,7 +650,6 @@ gtk_text_iter_get_line (const GtkTextIter *iter)
gint
gtk_text_iter_get_line_offset (const GtkTextIter *iter)
{
-
GtkTextRealIter *real;
g_return_val_if_fail (iter != NULL, 0);
@@ -683,7 +682,7 @@ gint
gtk_text_iter_get_line_index (const GtkTextIter *iter)
{
GtkTextRealIter *real;
-
+
g_return_val_if_fail (iter != NULL, 0);
real = gtk_text_iter_make_surreal (iter);
@@ -698,6 +697,108 @@ gtk_text_iter_get_line_index (const GtkTextIter *iter)
return real->line_byte_offset;
}
+gint
+gtk_text_iter_get_visible_line_offset (const GtkTextIter *iter)
+{
+ GtkTextRealIter *real;
+ gint vis_offset;
+ GtkTextLineSegment *seg;
+ GtkTextIter pos;
+
+ g_return_val_if_fail (iter != NULL, 0);
+
+ real = gtk_text_iter_make_real (iter);
+
+ if (real == NULL)
+ return 0;
+
+ ensure_char_offsets (real);
+
+ check_invariants (iter);
+
+ vis_offset = real->line_char_offset;
+
+ _gtk_text_btree_get_iter_at_line (real->tree,
+ &pos,
+ real->line,
+ 0);
+
+ seg = _gtk_text_iter_get_indexable_segment (&pos);
+
+ while (seg != real->segment)
+ {
+ /* This is a pretty expensive call, making the
+ * whole function pretty lame; we could keep track
+ * of current invisibility state by looking at toggle
+ * segments as we loop, and then call this function
+ * only once per line, in order to speed up the loop
+ * quite a lot.
+ */
+ if (_gtk_text_btree_char_is_invisible (&pos))
+ vis_offset -= seg->char_count;
+
+ _gtk_text_iter_forward_indexable_segment (&pos);
+
+ seg = _gtk_text_iter_get_indexable_segment (&pos);
+ }
+
+ if (_gtk_text_btree_char_is_invisible (&pos))
+ vis_offset -= real->segment_char_offset;
+
+ return vis_offset;
+}
+
+gint
+gtk_text_iter_get_visible_line_index (const GtkTextIter *iter)
+{
+ GtkTextRealIter *real;
+ gint vis_offset;
+ GtkTextLineSegment *seg;
+ GtkTextIter pos;
+
+ g_return_val_if_fail (iter != NULL, 0);
+
+ real = gtk_text_iter_make_real (iter);
+
+ if (real == NULL)
+ return 0;
+
+ ensure_char_offsets (real);
+
+ check_invariants (iter);
+
+ vis_offset = real->line_byte_offset;
+
+ _gtk_text_btree_get_iter_at_line (real->tree,
+ &pos,
+ real->line,
+ 0);
+
+ seg = _gtk_text_iter_get_indexable_segment (&pos);
+
+ while (seg != real->segment)
+ {
+ /* This is a pretty expensive call, making the
+ * whole function pretty lame; we could keep track
+ * of current invisibility state by looking at toggle
+ * segments as we loop, and then call this function
+ * only once per line, in order to speed up the loop
+ * quite a lot.
+ */
+ if (_gtk_text_btree_char_is_invisible (&pos))
+ vis_offset -= seg->byte_count;
+
+ _gtk_text_iter_forward_indexable_segment (&pos);
+
+ seg = _gtk_text_iter_get_indexable_segment (&pos);
+ }
+
+ if (_gtk_text_btree_char_is_invisible (&pos))
+ vis_offset -= real->segment_byte_offset;
+
+ return vis_offset;
+}
+
/*
* Dereferencing
*/
@@ -3276,6 +3377,97 @@ gtk_text_iter_set_line_index (GtkTextIter *iter,
check_invariants (iter);
}
+
+/**
+ * gtk_text_iter_set_visible_line_offset:
+ * @iter: a #GtkTextIter
+ * @char_on_line: a character offset
+ *
+ * Like gtk_text_iter_set_line_offset(), but the offset is in visible
+ * characters, i.e. text with a tag making it invisible is not
+ * counted in the offset.
+ **/
+void
+gtk_text_iter_set_visible_line_offset (GtkTextIter *iter,
+ gint char_on_line)
+{
+ gint chars_seen = 0;
+ GtkTextIter pos;
+
+ g_return_if_fail (iter != NULL);
+
+ pos = *iter;
+
+ /* For now we use a ludicrously slow implementation */
+ while (chars_seen < char_on_line)
+ {
+ if (!_gtk_text_btree_char_is_invisible (&pos))
+ ++chars_seen;
+
+ if (!gtk_text_iter_forward_char (&pos))
+ break;
+
+ if (chars_seen == char_on_line)
+ break;
+ }
+
+ if (_gtk_text_iter_get_text_line (&pos) == _gtk_text_iter_get_text_line (iter))
+ *iter = pos;
+ else
+ gtk_text_iter_forward_line (iter);
+}
+
+static gint
+bytes_in_char (GtkTextIter *iter)
+{
+ return g_unichar_to_utf8 (gtk_text_iter_get_char (iter), NULL);
+}
+
+/**
+ * gtk_text_iter_set_visible_line_index:
+ * @iter: a #GtkTextIter
+ * @byte_on_line: a byte index
+ *
+ * Like gtk_text_iter_set_line_index(), but the index is in visible
+ * bytes, i.e. text with a tag making it invisible is not counted
+ * in the index.
+ **/
+void
+gtk_text_iter_set_visible_line_index (GtkTextIter *iter,
+ gint byte_on_line)
+{
+ gint bytes_seen = 0;
+ GtkTextIter pos;
+
+ g_return_if_fail (iter != NULL);
+
+ pos = *iter;
+
+ /* For now we use a ludicrously slow implementation */
+ while (bytes_seen < byte_on_line)
+ {
+ if (!_gtk_text_btree_char_is_invisible (&pos))
+ bytes_seen += bytes_in_char (&pos);
+
+ if (!gtk_text_iter_forward_char (&pos))
+ break;
+
+ if (bytes_seen >= byte_on_line)
+ break;
+ }
+
+ if (bytes_seen > byte_on_line)
+ g_warning ("%s: Incorrect visible byte index %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);
+
+ if (_gtk_text_iter_get_text_line (&pos) == _gtk_text_iter_get_text_line (iter))
+ *iter = pos;
+ else
+ gtk_text_iter_forward_line (iter);
+}
+
/**
* gtk_text_iter_set_line:
* @iter: a #GtkTextIter
diff --git a/gtk/gtktextiter.h b/gtk/gtktextiter.h
index 9b25a8be49..00285e287b 100644
--- a/gtk/gtktextiter.h
+++ b/gtk/gtktextiter.h
@@ -78,6 +78,9 @@ 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);
+gint gtk_text_iter_get_visible_line_offset (const GtkTextIter *iter);
+gint gtk_text_iter_get_visible_line_index (const GtkTextIter *iter);
+
/*
* "Dereference" operators
@@ -197,6 +200,10 @@ void gtk_text_iter_set_line_index (GtkTextIter *iter,
void gtk_text_iter_forward_to_end (GtkTextIter *iter);
gboolean gtk_text_iter_forward_to_line_end (GtkTextIter *iter);
+void gtk_text_iter_set_visible_line_offset (GtkTextIter *iter,
+ gint char_on_line);
+void gtk_text_iter_set_visible_line_index (GtkTextIter *iter,
+ gint byte_on_line);
/* returns TRUE if a toggle was found; NULL for the tag pointer
* means "any tag toggle", otherwise the next toggle of the
diff --git a/gtk/gtktextlayout.c b/gtk/gtktextlayout.c
index dad06d319d..ec61bb250a 100644
--- a/gtk/gtktextlayout.c
+++ b/gtk/gtktextlayout.c
@@ -994,14 +994,16 @@ totally_invisible_line (GtkTextLayout *layout,
int bytes = 0;
/* If we have a cached style, then we know it does actually apply
- and we can just see if it is invisible. */
+ * and we can just see if it is invisible.
+ */
if (layout->one_style_cache &&
!layout->one_style_cache->invisible)
return FALSE;
/* Without the cache, we check if the first char is visible, if so
- we are partially visible. Note that we have to check this since
- we don't know the current invisible/noninvisible toggle state; this
- function can use the whole btree to get it right. */
+ * we are partially visible. Note that we have to check this since
+ * we don't know the current invisible/noninvisible toggle state; this
+ * function can use the whole btree to get it right.
+ */
else
{
_gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
@@ -1020,10 +1022,11 @@ totally_invisible_line (GtkTextLayout *layout,
bytes += seg->byte_count;
/* Note that these two tests can cause us to bail out
- when we shouldn't, because a higher-priority tag
- may override these settings. However the important
- thing is to only invisible really-invisible lines, rather
- than to invisible all really-invisible lines. */
+ * when we shouldn't, because a higher-priority tag
+ * may override these settings. However the important
+ * thing is to only invisible really-invisible lines, rather
+ * than to invisible all really-invisible lines.
+ */
else if (seg->type == &gtk_text_toggle_on_type)
{
@@ -1478,8 +1481,6 @@ allocate_child_widgets (GtkTextLayout *text_layout,
pango_layout_iter_get_run_extents (iter,
NULL,
&extents);
-
- g_print ("extents at %d,%d\n", extents.x, extents.y);
g_signal_emit (G_OBJECT (text_layout),
signals[ALLOCATE_CHILD],
@@ -1593,7 +1594,7 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
GtkTextAttributes *style;
gchar *text;
PangoAttrList *attrs;
- gint byte_count, layout_byte_offset, layout_only_bytes;
+ gint text_allocated, layout_byte_offset, buffer_byte_offset;
gdouble align;
PangoRectangle extents;
gboolean para_values_set = FALSE;
@@ -1635,14 +1636,14 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
/* Allocate space for flat text for buffer
*/
- byte_count = _gtk_text_line_byte_count (line);
- text = g_malloc (byte_count);
+ text_allocated = _gtk_text_line_byte_count (line);
+ text = g_malloc (text_allocated);
attrs = pango_attr_list_new ();
/* Iterate over segments, creating display chunks for them. */
- layout_byte_offset = 0; /* current length of layout text (includes preedit) */
- layout_only_bytes = 0; /* bytes in layout_byte_offset not in buffer */
+ layout_byte_offset = 0; /* current length of layout text (includes preedit, does not include invisible text) */
+ buffer_byte_offset = 0; /* position in the buffer line */
seg = _gtk_text_iter_get_any_segment (&iter);
while (seg != NULL)
{
@@ -1653,7 +1654,7 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
{
_gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
&iter, line,
- layout_byte_offset - layout_only_bytes);
+ buffer_byte_offset);
style = get_style (layout, &iter);
/* We have to delay setting the paragraph values until we
@@ -1692,6 +1693,7 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
{
memcpy (text + layout_byte_offset, seg->body.chars, seg->byte_count);
layout_byte_offset += seg->byte_count;
+ buffer_byte_offset += seg->byte_count;
bytes += seg->byte_count;
}
else if (seg->type == &gtk_text_right_mark_type ||
@@ -1739,6 +1741,7 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
memcpy (text + layout_byte_offset, gtk_text_unknown_char_utf8,
seg->byte_count);
layout_byte_offset += seg->byte_count;
+ buffer_byte_offset += seg->byte_count;
}
else if (seg->type == &gtk_text_child_type)
{
@@ -1753,11 +1756,19 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
memcpy (text + layout_byte_offset, gtk_text_unknown_char_utf8,
seg->byte_count);
layout_byte_offset += seg->byte_count;
+ buffer_byte_offset += seg->byte_count;
}
else
{
+ /* We don't know this segment type */
g_assert_not_reached ();
}
+
+ } /* if (segment was visible) */
+ else
+ {
+ /* Invisible segment */
+ buffer_byte_offset += seg->byte_count;
}
release_style (layout, style);
@@ -1787,8 +1798,8 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
if (layout->preedit_len > 0)
{
- byte_count += layout->preedit_len;
- text = g_realloc (text, byte_count);
+ text_allocated += layout->preedit_len;
+ text = g_realloc (text, text_allocated);
style = get_style (layout, &iter);
add_preedit_attrs (layout, style, attrs, layout_byte_offset, size_only);
@@ -1796,7 +1807,7 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
memcpy (text + layout_byte_offset, layout->preedit_string, layout->preedit_len);
layout_byte_offset += layout->preedit_len;
- layout_only_bytes += layout->preedit_len;
+ /* DO NOT increment the buffer byte offset for preedit */
cursor_offset = layout->preedit_cursor - layout->preedit_len;
}
@@ -1825,8 +1836,6 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
set_para_values (layout, style, display, &align);
release_style (layout, style);
}
-
- g_assert (layout_byte_offset == byte_count);
/* Pango doesn't want the trailing paragraph delimiters */
@@ -1897,7 +1906,8 @@ gtk_text_layout_free_line_display (GtkTextLayout *layout,
{
if (display != layout->one_display_cache)
{
- g_object_unref (G_OBJECT (display->layout));
+ if (display->layout)
+ g_object_unref (G_OBJECT (display->layout));
if (display->cursors)
{
@@ -1911,7 +1921,7 @@ gtk_text_layout_free_line_display (GtkTextLayout *layout,
}
/* Functions to convert iter <=> index for the line of a GtkTextLineDisplay
- * taking into account the preedit string, if necessary.
+ * taking into account the preedit string and invisible text if necessary.
*/
static gint
line_display_iter_to_index (GtkTextLayout *layout,
@@ -1922,8 +1932,8 @@ line_display_iter_to_index (GtkTextLayout *layout,
g_return_val_if_fail (_gtk_text_iter_get_text_line (iter) == display->line, 0);
- index = gtk_text_iter_get_line_index (iter);
-
+ index = gtk_text_iter_get_visible_line_index (iter);
+
if (index >= display->insert_index)
index += layout->preedit_len;
@@ -1937,8 +1947,6 @@ line_display_index_to_iter (GtkTextLayout *layout,
gint index,
gint trailing)
{
- gint line_len;
-
if (index >= display->insert_index + layout->preedit_len)
index -= layout->preedit_len;
else if (index > display->insert_index)
@@ -1946,27 +1954,24 @@ line_display_index_to_iter (GtkTextLayout *layout,
index = display->insert_index;
trailing = 0;
}
-
- line_len = _gtk_text_line_byte_count (display->line);
- g_assert (index <= line_len);
- if (index < line_len)
- _gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
- iter, display->line, index);
- else
+ _gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
+ iter, display->line, 0);
+
+ gtk_text_iter_set_visible_line_index (iter, index);
+
+ if (_gtk_text_iter_get_text_line (iter) != display->line)
{
/* Clamp to end of line - really this clamping should have been done
* before here, maybe in Pango, this is a broken band-aid I think
*/
- g_assert (index == line_len);
-
_gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
iter, display->line, 0);
if (!gtk_text_iter_ends_line (iter))
gtk_text_iter_forward_to_line_end (iter);
}
-
+
/* FIXME should this be cursor positions? */
gtk_text_iter_forward_chars (iter, trailing);
}
@@ -2414,7 +2419,7 @@ gtk_text_layout_clamp_iter_to_vrange (GtkTextLayout *layout,
}
/**
- * gtk_text_layout_move_iter_to_next_line:
+ * gtk_text_layout_move_iter_to_previous_line:
* @layout: a #GtkLayout
* @iter: a #GtkTextIter
*
@@ -2439,9 +2444,10 @@ gtk_text_layout_move_iter_to_previous_line (GtkTextLayout *layout,
orig = *iter;
line = _gtk_text_iter_get_text_line (iter);
- display = gtk_text_layout_get_line_display (layout, line, FALSE);
+ display = gtk_text_layout_get_line_display (layout, line, FALSE);
line_byte = line_display_iter_to_index (layout, display, iter);
+ /* FIXME can't use layout until we check display->height > 0) */
tmp_list = pango_layout_get_lines (display->layout);
layout_line = tmp_list->data;
@@ -2449,6 +2455,8 @@ gtk_text_layout_move_iter_to_previous_line (GtkTextLayout *layout,
{
GtkTextLine *prev_line = _gtk_text_line_previous (line);
+ /* FIXME keep going back while display->height == 0 */
+
if (prev_line)
{
gtk_text_layout_free_line_display (layout, display);
diff --git a/tests/testtext.c b/tests/testtext.c
index badbaf17a7..73c7231f64 100644
--- a/tests/testtext.c
+++ b/tests/testtext.c
@@ -2236,7 +2236,7 @@ test_init ()
if (file_exists ("../gdk-pixbuf/.libs/libpixbufloader-pnm.so"))
{
putenv ("GDK_PIXBUF_MODULEDIR=../gdk-pixbuf/.libs");
- putenv ("GTK_IM_MODULE_FILE=./gtk.immodules");
+ putenv ("GTK_IM_MODULE_FILE=../gtk/gtk.immodules");
}
}