X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtkcelllayout.c;h=f9e0ce8d061d7f402d6974bb58dee2ce7c5cdea0;hb=320613c439c6c7eeb5bc64685522195e0a6adc4e;hp=d56747c1c49b632d03ef8d9a638c83e45ba9eba5;hpb=920e8b434367f9aa8aab306721cc024e66892e2e;p=~andy%2Fgtk diff --git a/gtk/gtkcelllayout.c b/gtk/gtkcelllayout.c index d56747c1c..f9e0ce8d0 100644 --- a/gtk/gtkcelllayout.c +++ b/gtk/gtkcelllayout.c @@ -12,9 +12,7 @@ * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * License along with this library. If not, see . */ /** @@ -23,7 +21,7 @@ * @Title: GtkCellLayout * * #GtkCellLayout is an interface to be implemented by all objects which - * want to provide a #GtkTreeViewColumn-like API for packing cells, setting + * want to provide a #GtkTreeViewColumn-like API for packing cells, setting * attributes and data funcs. * * One of the notable features provided by implementations of GtkCellLayout @@ -40,7 +38,7 @@ * GtkCellLayouts as GtkBuildable * * Implementations of GtkCellLayout which also implement the GtkBuildable - * interface (#GtkCellView, #GtkIconView, #GtkComboBox, #GtkComboBoxEntry, + * interface (#GtkCellView, #GtkIconView, #GtkComboBox, * #GtkEntryCompletion, #GtkTreeViewColumn) accept GtkCellRenderer objects * as <child> elements in UI definitions. They support a custom * <attributes> element for their children, which can contain @@ -83,6 +81,55 @@ * * * + * + * + * Subclassing GtkCellLayout implementations + * + * When subclassing a widget that implements #GtkCellLayout like + * #GtkIconView or #GtkComboBox, there are some considerations related + * to the fact that these widgets internally use a #GtkCellArea. + * The cell area is exposed as a construct-only property by these + * widgets. This means that it is possible to e.g. do + * + * combo = g_object_new (GTK_TYPE_COMBO_BOX, "cell-area", my_cell_area, NULL); + * + * to use a custom cell area with a combo box. But construct properties + * are only initialized after instance init() + * functions have run, which means that using functions which rely on + * the existence of the cell area in your subclass' init() function will + * cause the default cell area to be instantiated. In this case, a provided + * construct property value will be ignored (with a warning, to alert + * you to the problem). + * + * static void + * my_combo_box_init (MyComboBox *b) + * { + * GtkCellRenderer *cell; + * + * cell = gtk_cell_renderer_pixbuf_new (); + * /* The following call causes the default cell area for combo boxes, + * * a GtkCellAreaBox, to be instantiated + * */ + * gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (b), cell, FALSE); + * ... + * } + * + * GtkWidget * + * my_combo_box_new (GtkCellArea *area) + * { + * /* This call is going to cause a warning + * * about area being ignored + * */ + * return g_object_new (MY_TYPE_COMBO_BOX, "cell-area", area, NULL); + * } + * + * If supporting alternative cell areas with your derived widget is + * not important, then this does not have to concern you. If you want + * to support alternative cell areas, you can do so by moving the + * problematic calls out of init() and into a constructor() + * for your class. + * + * */ #include "config.h" @@ -400,7 +447,7 @@ gtk_cell_layout_set_attributesv (GtkCellLayout *cell_layout, * gtk_cell_layout_set_attributes: * @cell_layout: a #GtkCellLayout * @cell: a #GtkCellRenderer - * @Varargs: a %NULL-terminated list of attributes + * @...: a %NULL-terminated list of attributes * * Sets the attributes in list as the attributes of @cell_layout. * @@ -662,7 +709,7 @@ gtk_cell_layout_buildable_set_cell_property (GtkCellArea *area, const gchar *value) { GParamSpec *pspec; - GValue gvalue = { 0, }; + GValue gvalue = G_VALUE_INIT; GError *error = NULL; pspec = gtk_cell_area_class_find_cell_property (GTK_CELL_AREA_GET_CLASS (area), name); @@ -693,6 +740,7 @@ typedef struct { GtkBuilder *builder; GtkCellLayout *cell_layout; GtkCellRenderer *renderer; + GString *string; gchar *cell_prop_name; gchar *context; gboolean translatable; @@ -743,53 +791,63 @@ cell_packing_text_element (GMarkupParseContext *context, GError **error) { CellPackingSubParserData *parser_data = (CellPackingSubParserData*)user_data; - GtkCellArea *area; - gchar* value; - - if (!parser_data->cell_prop_name) - return; - if (parser_data->translatable && text_len) - { - const gchar* domain; - domain = gtk_builder_get_translation_domain (parser_data->builder); + if (parser_data->cell_prop_name) + g_string_append_len (parser_data->string, text, text_len); +} - value = _gtk_builder_parser_translate (domain, - parser_data->context, - text); - } - else - { - value = g_strdup (text); - } +static void +cell_packing_end_element (GMarkupParseContext *context, + const gchar *element_name, + gpointer user_data, + GError **error) +{ + CellPackingSubParserData *parser_data = (CellPackingSubParserData*)user_data; + GtkCellArea *area; area = gtk_cell_layout_get_area (parser_data->cell_layout); - if (!area) + if (area) { - g_warning ("%s does not have an internal GtkCellArea class and cannot apply child cell properties", - g_type_name (G_OBJECT_TYPE (parser_data->cell_layout))); - return; + /* translate the string */ + if (parser_data->string->len && parser_data->translatable) + { + gchar *translated; + const gchar* domain; + + domain = gtk_builder_get_translation_domain (parser_data->builder); + + translated = _gtk_builder_parser_translate (domain, + parser_data->context, + parser_data->string->str); + g_string_set_size (parser_data->string, 0); + g_string_append (parser_data->string, translated); + } + + if (parser_data->cell_prop_name) + gtk_cell_layout_buildable_set_cell_property (area, + parser_data->builder, + parser_data->renderer, + parser_data->cell_prop_name, + parser_data->string->str); } + else + g_warning ("%s does not have an internal GtkCellArea class and cannot apply child cell properties", + g_type_name (G_OBJECT_TYPE (parser_data->cell_layout))); - gtk_cell_layout_buildable_set_cell_property (area, - parser_data->builder, - parser_data->renderer, - parser_data->cell_prop_name, - value); - + g_string_set_size (parser_data->string, 0); g_free (parser_data->cell_prop_name); g_free (parser_data->context); - g_free (value); parser_data->cell_prop_name = NULL; parser_data->context = NULL; parser_data->translatable = FALSE; } + static const GMarkupParser cell_packing_parser = { cell_packing_start_element, - NULL, + cell_packing_end_element, cell_packing_text_element, }; @@ -821,6 +879,7 @@ _gtk_cell_layout_buildable_custom_tag_start (GtkBuildable *buildable, else if (strcmp (tagname, "cell-packing") == 0) { packing_data = g_slice_new0 (CellPackingSubParserData); + packing_data->string = g_string_new (""); packing_data->builder = builder; packing_data->cell_layout = GTK_CELL_LAYOUT (buildable); packing_data->renderer = GTK_CELL_RENDERER (child); @@ -841,6 +900,7 @@ _gtk_cell_layout_buildable_custom_tag_end (GtkBuildable *buildable, gpointer *data) { AttributesSubParserData *attr_data; + CellPackingSubParserData *packing_data; if (strcmp (tagname, "attributes") == 0) { @@ -851,7 +911,9 @@ _gtk_cell_layout_buildable_custom_tag_end (GtkBuildable *buildable, } else if (strcmp (tagname, "cell-packing") == 0) { - g_slice_free (CellPackingSubParserData, (gpointer)data); + packing_data = (CellPackingSubParserData *)data; + g_string_free (packing_data->string, TRUE); + g_slice_free (CellPackingSubParserData, packing_data); return TRUE; } return FALSE;