X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtktextchild.c;h=dd7d3a49061766733c874e156479ab1716926da0;hb=9f41970832b60f3cf6644dfbd154df7ec24f26ce;hp=db93231e6c3919acd9d5649fb42659fae0874c9a;hpb=565074f9a3eaaf3f88c71051624ee28836506ff1;p=~andy%2Fgtk diff --git a/gtk/gtktextchild.c b/gtk/gtktextchild.c index db93231e6..dd7d3a490 100644 --- a/gtk/gtktextchild.c +++ b/gtk/gtktextchild.c @@ -47,9 +47,31 @@ * */ +#define GTK_TEXT_USE_INTERNAL_UNSUPPORTED_API +#include "config.h" #include "gtktextchild.h" #include "gtktextbtree.h" #include "gtktextlayout.h" +#include "gtkintl.h" + +#define CHECK_IN_BUFFER(anchor) \ + G_STMT_START { \ + if ((anchor)->segment == NULL) \ + { \ + g_warning ("%s: GtkTextChildAnchor hasn't been in a buffer yet",\ + G_STRFUNC); \ + } \ + } G_STMT_END + +#define CHECK_IN_BUFFER_RETURN(anchor, val) \ + G_STMT_START { \ + if ((anchor)->segment == NULL) \ + { \ + g_warning ("%s: GtkTextChildAnchor hasn't been in a buffer yet",\ + G_STRFUNC); \ + return (val); \ + } \ + } G_STMT_END static GtkTextLineSegment * pixbuf_segment_cleanup_func (GtkTextLineSegment *seg, @@ -65,7 +87,7 @@ pixbuf_segment_delete_func (GtkTextLineSegment *seg, gboolean tree_gone) { if (seg->body.pixbuf.pixbuf) - g_object_unref (G_OBJECT (seg->body.pixbuf.pixbuf)); + g_object_unref (seg->body.pixbuf.pixbuf); g_free (seg); @@ -87,7 +109,7 @@ pixbuf_segment_check_func (GtkTextLineSegment *seg, } -GtkTextLineSegmentClass gtk_text_pixbuf_type = { +const GtkTextLineSegmentClass gtk_text_pixbuf_type = { "pixbuf", /* name */ FALSE, /* leftGravity */ NULL, /* splitFunc */ @@ -112,14 +134,15 @@ _gtk_pixbuf_segment_new (GdkPixbuf *pixbuf) seg->next = NULL; - seg->byte_count = 3; /* We convert to the 0xFFFC "unknown character", - * a 3-byte sequence in UTF-8 - */ + /* We convert to the 0xFFFC "unknown character", + * a 3-byte sequence in UTF-8. + */ + seg->byte_count = GTK_TEXT_UNKNOWN_CHAR_UTF8_LEN; seg->char_count = 1; seg->body.pixbuf.pixbuf = pixbuf; - g_object_ref (G_OBJECT (pixbuf)); + g_object_ref (pixbuf); return seg; } @@ -142,7 +165,7 @@ child_segment_delete_func (GtkTextLineSegment *seg, GSList *tmp_list; GSList *copy; - gtk_text_btree_unregister_child_anchor (seg->body.child.obj); + _gtk_text_btree_unregister_child_anchor (seg->body.child.obj); seg->body.child.tree = NULL; seg->body.child.line = NULL; @@ -185,7 +208,7 @@ child_segment_check_func (GtkTextLineSegment *seg, g_error ("child segment has char count of %d", seg->char_count); } -GtkTextLineSegmentClass gtk_text_child_type = { +const GtkTextLineSegmentClass gtk_text_child_type = { "child-widget", /* name */ FALSE, /* leftGravity */ NULL, /* splitFunc */ @@ -199,7 +222,7 @@ GtkTextLineSegmentClass gtk_text_child_type = { + sizeof (GtkTextChildBody))) GtkTextLineSegment * -_gtk_widget_segment_new (void) +_gtk_widget_segment_new (GtkTextChildAnchor *anchor) { GtkTextLineSegment *seg; @@ -214,12 +237,14 @@ _gtk_widget_segment_new (void) */ seg->char_count = 1; - seg->body.child.obj = g_object_new (GTK_TYPE_TEXT_CHILD_ANCHOR, NULL); + seg->body.child.obj = anchor; seg->body.child.obj->segment = seg; seg->body.child.widgets = NULL; seg->body.child.tree = NULL; seg->body.child.line = NULL; + g_object_ref (anchor); + return seg; } @@ -227,10 +252,10 @@ void _gtk_widget_segment_add (GtkTextLineSegment *widget_segment, GtkWidget *child) { - g_return_if_fail (widget_segment->type = >k_text_child_type); + g_return_if_fail (widget_segment->type == >k_text_child_type); g_return_if_fail (widget_segment->body.child.tree != NULL); - g_object_ref (G_OBJECT (child)); + g_object_ref (child); widget_segment->body.child.widgets = g_slist_prepend (widget_segment->body.child.widgets, @@ -241,79 +266,49 @@ void _gtk_widget_segment_remove (GtkTextLineSegment *widget_segment, GtkWidget *child) { - g_return_if_fail (widget_segment->type = >k_text_child_type); + g_return_if_fail (widget_segment->type == >k_text_child_type); widget_segment->body.child.widgets = g_slist_remove (widget_segment->body.child.widgets, child); - g_object_unref (G_OBJECT (child)); + g_object_unref (child); } void _gtk_widget_segment_ref (GtkTextLineSegment *widget_segment) { - g_assert (widget_segment->type = >k_text_child_type); + g_assert (widget_segment->type == >k_text_child_type); - g_object_ref (G_OBJECT (widget_segment->body.child.obj)); + g_object_ref (widget_segment->body.child.obj); } void _gtk_widget_segment_unref (GtkTextLineSegment *widget_segment) { - g_assert (widget_segment->type = >k_text_child_type); + g_assert (widget_segment->type == >k_text_child_type); - g_object_unref (G_OBJECT (widget_segment->body.child.obj)); + g_object_unref (widget_segment->body.child.obj); } GtkTextLayout* _gtk_anchored_child_get_layout (GtkWidget *child) { - return gtk_object_get_data (GTK_OBJECT (child), "gtk-text-child-anchor-layout"); + return g_object_get_data (G_OBJECT (child), "gtk-text-child-anchor-layout"); } static void _gtk_anchored_child_set_layout (GtkWidget *child, GtkTextLayout *layout) { - gtk_object_set_data (GTK_OBJECT (child), - "gtk-text-child-anchor-layout", - layout); + g_object_set_data (G_OBJECT (child), + I_("gtk-text-child-anchor-layout"), + layout); } -static void gtk_text_child_anchor_init (GtkTextChildAnchor *child_anchor); -static void gtk_text_child_anchor_class_init (GtkTextChildAnchorClass *klass); -static void gtk_text_child_anchor_finalize (GObject *obj); +static void gtk_text_child_anchor_finalize (GObject *obj); -static gpointer parent_class = NULL; - -GType -gtk_text_child_anchor_get_type (void) -{ - static GType object_type = 0; - - if (!object_type) - { - static const GTypeInfo object_info = - { - sizeof (GtkTextChildAnchorClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) gtk_text_child_anchor_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (GtkTextChildAnchor), - 0, /* n_preallocs */ - (GInstanceInitFunc) gtk_text_child_anchor_init, - }; - - object_type = g_type_register_static (G_TYPE_OBJECT, - "GtkTextChildAnchor", - &object_info, 0); - } - - return object_type; -} +G_DEFINE_TYPE (GtkTextChildAnchor, gtk_text_child_anchor, G_TYPE_OBJECT) static void gtk_text_child_anchor_init (GtkTextChildAnchor *child_anchor) @@ -326,11 +321,25 @@ gtk_text_child_anchor_class_init (GtkTextChildAnchorClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); - parent_class = g_type_class_peek_parent (klass); - object_class->finalize = gtk_text_child_anchor_finalize; } +/** + * gtk_text_child_anchor_new: + * + * Creates a new #GtkTextChildAnchor. Usually you would then insert + * it into a #GtkTextBuffer with gtk_text_buffer_insert_child_anchor(). + * To perform the creation and insertion in one step, use the + * convenience function gtk_text_buffer_create_child_anchor(). + * + * Return value: a new #GtkTextChildAnchor + **/ +GtkTextChildAnchor* +gtk_text_child_anchor_new (void) +{ + return g_object_new (GTK_TYPE_TEXT_CHILD_ANCHOR, NULL); +} + static void gtk_text_child_anchor_finalize (GObject *obj) { @@ -342,29 +351,43 @@ gtk_text_child_anchor_finalize (GObject *obj) seg = anchor->segment; - if (seg->body.child.tree != NULL) + if (seg) { - g_warning ("Someone removed a reference to a GtkTextChildAnchor " - "they didn't own; the anchor is still in the text buffer " - "and the refcount is 0."); - return; - } + if (seg->body.child.tree != NULL) + { + g_warning ("Someone removed a reference to a GtkTextChildAnchor " + "they didn't own; the anchor is still in the text buffer " + "and the refcount is 0."); + return; + } - tmp_list = seg->body.child.widgets; - while (tmp_list) - { - g_object_unref (G_OBJECT (tmp_list->data)); - - tmp_list = g_slist_next (tmp_list); - } + tmp_list = seg->body.child.widgets; + while (tmp_list) + { + g_object_unref (tmp_list->data); + tmp_list = g_slist_next (tmp_list); + } - g_slist_free (seg->body.child.widgets); + g_slist_free (seg->body.child.widgets); - g_free (seg); + g_free (seg); + } anchor->segment = NULL; + + G_OBJECT_CLASS (gtk_text_child_anchor_parent_class)->finalize (obj); } +/** + * gtk_text_child_anchor_get_widgets: + * @anchor: a #GtkTextChildAnchor + * + * Gets a list of all widgets anchored at this child anchor. + * The returned list should be freed with g_list_free(). + * + * + * Return value: (element-type GtkWidget) (transfer container): list of widgets anchored at @anchor + **/ GList* gtk_text_child_anchor_get_widgets (GtkTextChildAnchor *anchor) { @@ -372,7 +395,9 @@ gtk_text_child_anchor_get_widgets (GtkTextChildAnchor *anchor) GList *list = NULL; GSList *iter; - g_return_val_if_fail (seg->type = >k_text_child_type, NULL); + CHECK_IN_BUFFER_RETURN (anchor, NULL); + + g_return_val_if_fail (seg->type == >k_text_child_type, NULL); iter = seg->body.child.widgets; while (iter != NULL) @@ -388,12 +413,27 @@ gtk_text_child_anchor_get_widgets (GtkTextChildAnchor *anchor) return list; } +/** + * gtk_text_child_anchor_get_deleted: + * @anchor: a #GtkTextChildAnchor + * + * Determines whether a child anchor has been deleted from + * the buffer. Keep in mind that the child anchor will be + * unreferenced when removed from the buffer, so you need to + * hold your own reference (with g_object_ref()) if you plan + * to use this function — otherwise all deleted child anchors + * will also be finalized. + * + * Return value: %TRUE if the child anchor has been deleted from its buffer + **/ gboolean gtk_text_child_anchor_get_deleted (GtkTextChildAnchor *anchor) { GtkTextLineSegment *seg = anchor->segment; - g_return_val_if_fail (seg->type = >k_text_child_type, TRUE); + CHECK_IN_BUFFER_RETURN (anchor, TRUE); + + g_return_val_if_fail (seg->type == >k_text_child_type, TRUE); return seg->body.child.tree == NULL; } @@ -406,6 +446,8 @@ gtk_text_child_anchor_register_child (GtkTextChildAnchor *anchor, g_return_if_fail (GTK_IS_TEXT_CHILD_ANCHOR (anchor)); g_return_if_fail (GTK_IS_WIDGET (child)); + CHECK_IN_BUFFER (anchor); + _gtk_anchored_child_set_layout (child, layout); _gtk_widget_segment_add (anchor->segment, child); @@ -420,6 +462,8 @@ gtk_text_child_anchor_unregister_child (GtkTextChildAnchor *anchor, g_return_if_fail (GTK_IS_TEXT_CHILD_ANCHOR (anchor)); g_return_if_fail (GTK_IS_WIDGET (child)); + CHECK_IN_BUFFER (anchor); + if (_gtk_anchored_child_get_layout (child)) { gtk_text_child_anchor_queue_resize (anchor, @@ -441,6 +485,8 @@ gtk_text_child_anchor_queue_resize (GtkTextChildAnchor *anchor, g_return_if_fail (GTK_IS_TEXT_CHILD_ANCHOR (anchor)); g_return_if_fail (GTK_IS_TEXT_LAYOUT (layout)); + + CHECK_IN_BUFFER (anchor); seg = anchor->segment; @@ -450,7 +496,7 @@ gtk_text_child_anchor_queue_resize (GtkTextChildAnchor *anchor, gtk_text_buffer_get_iter_at_child_anchor (layout->buffer, &start, anchor); end = start; - gtk_text_iter_next_char (&end); + gtk_text_iter_forward_char (&end); gtk_text_layout_invalidate (layout, &start, &end); } @@ -464,5 +510,3 @@ gtk_text_anchored_child_set_layout (GtkWidget *child, _gtk_anchored_child_set_layout (child, layout); } - -