]> Pileus Git - ~andy/gtk/blob - gtk/gtktoolbutton.c
remove strange #define fix cut'n'paste error use instance private data use
[~andy/gtk] / gtk / gtktoolbutton.c
1 /* gtktoolbutton.c
2  *
3  * Copyright (C) 2002 Anders Carlsson <andersca@codefactory.se>
4  * Copyright (C) 2002 James Henstridge <james@daa.com.au>
5  * Copyright (C) 2003 Soeren Sandmann <sandmann@daimi.au.dk>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 #include "gtktoolbutton.h"
24 #include "gtkbutton.h"
25 #include "gtkhbox.h"
26 #include "gtkiconfactory.h"
27 #include "gtkimage.h"
28 #include "gtkimagemenuitem.h"
29 #include "gtklabel.h"
30 #include "gtkstock.h"
31 #include "gtkvbox.h"
32 #include "gtkintl.h"
33 #include "gtktoolbar.h"
34 #include "gtkiconfactory.h"
35
36 #include <string.h>
37
38 #define MENU_ID "gtk-tool-button-menu-id"
39
40 enum {
41   CLICKED,
42   LAST_SIGNAL
43 };
44
45 enum {
46   PROP_0,
47   PROP_LABEL,
48   PROP_USE_UNDERLINE,
49   PROP_LABEL_WIDGET,
50   PROP_STOCK_ID,
51   PROP_ICON_WIDGET,
52 };
53
54 static void gtk_tool_button_init          (GtkToolButton      *button,
55                                            GtkToolButtonClass *klass);
56 static void gtk_tool_button_class_init    (GtkToolButtonClass *klass);
57 static void gtk_tool_button_size_request  (GtkWidget          *widget,
58                                            GtkRequisition     *requisition);
59 static void gtk_tool_button_size_allocate (GtkWidget          *widget,
60                                            GtkAllocation      *allocation);
61 static void gtk_tool_button_set_property  (GObject            *object,
62                                            guint               prop_id,
63                                            const GValue       *value,
64                                            GParamSpec         *pspec);
65 static void gtk_tool_button_get_property  (GObject            *object,
66                                            guint               prop_id,
67                                            GValue             *value,
68                                            GParamSpec         *pspec);
69 static void gtk_tool_button_finalize      (GObject            *object);
70
71 static void gtk_tool_button_toolbar_reconfigured (GtkToolItem *tool_item);
72 static gboolean   gtk_tool_button_create_menu_proxy (GtkToolItem     *item);
73 static void       button_clicked                    (GtkWidget       *widget,
74                                                      GtkToolButton   *button);
75
76 static void gtk_tool_button_construct_contents (GtkToolItem *tool_item);
77       
78 static GObjectClass *parent_class = NULL;
79 static guint         toolbutton_signals[LAST_SIGNAL] = { 0 };
80
81 struct _GtkToolButtonPrivate
82 {
83   GtkWidget *button;
84
85   gchar *stock_id;
86   gchar *label_text;
87   GtkWidget *label_widget;
88   GtkWidget *icon_widget;
89   
90   guint use_underline : 1;
91 };
92
93 GType
94 gtk_tool_button_get_type (void)
95 {
96   static GtkType type = 0;
97
98   if (!type)
99     {
100       static const GTypeInfo type_info =
101         {
102           sizeof (GtkToolButtonClass),
103           (GBaseInitFunc) NULL,
104           (GBaseFinalizeFunc) NULL,
105           (GClassInitFunc) gtk_tool_button_class_init,
106           (GClassFinalizeFunc) NULL,
107           NULL,
108           sizeof (GtkToolButton),
109           0, /* n_preallocs */
110           (GInstanceInitFunc) gtk_tool_button_init,
111         };
112
113       type = g_type_register_static (GTK_TYPE_TOOL_ITEM,
114                                      "GtkToolButton",
115                                      &type_info, 0);
116     }
117   return type;
118 }
119
120 static void
121 gtk_tool_button_class_init (GtkToolButtonClass *klass)
122 {
123   GObjectClass *object_class;
124   GtkWidgetClass *widget_class;
125   GtkToolItemClass *tool_item_class;
126   
127   parent_class = g_type_class_peek_parent (klass);
128   
129   object_class = (GObjectClass *)klass;
130   widget_class = (GtkWidgetClass *)klass;
131   tool_item_class = (GtkToolItemClass *)klass;
132   
133   object_class->set_property = gtk_tool_button_set_property;
134   object_class->get_property = gtk_tool_button_get_property;
135   object_class->finalize = gtk_tool_button_finalize;
136
137   widget_class->size_request = gtk_tool_button_size_request;
138   widget_class->size_allocate = gtk_tool_button_size_allocate;
139
140   tool_item_class->create_menu_proxy = gtk_tool_button_create_menu_proxy;
141   tool_item_class->toolbar_reconfigured = gtk_tool_button_toolbar_reconfigured;
142   
143   klass->button_type = GTK_TYPE_BUTTON;
144
145   /* Properties are interpreted like this:
146    *
147    *          - if the tool button has an icon_widget, then that widget
148    *            will be used as the icon. Otherwise, if the tool button
149    *            has a stock id, the corresponding stock icon will be
150    *            used. Otherwise, the tool button will not have an icon.
151    *
152    *          - if the tool button has a label_widget then that widget
153    *            will be used as the label. Otherwise, if the tool button
154    *            has a label text, that text will be used as label. Otherwise,
155    *            if the toolbutton has a stock id, the corresponding text
156    *            will be used as label. Otherwise, the toolbutton will
157    *            have an empty label.
158    *
159    *          - The use_underline property only has an effect when the label
160    *            on the toolbutton comes from the label property (ie. not from
161    *            label_widget or from stock_id).
162    *
163    *            In that case, if use_underline is set,
164    *
165    *                    - underscores are removed from the label text before
166    *                      the label is shown on the toolbutton unless the
167    *                      underscore is followed by another underscore
168    *
169    *                    - an underscore indicates that the next character when
170    *                      used in the overflow menu should be used as a mnemonic.
171    *
172    *            In short: use_underline = TRUE means that the label text has
173    *            the form "_Open" and the toolbar should take appropriate action.
174    */
175
176   g_object_class_install_property (object_class,
177                                    PROP_LABEL,
178                                    g_param_spec_string ("label",
179                                                         _("Label"),
180                                                         _("Text to show in the item."),
181                                                         NULL,
182                                                         G_PARAM_READWRITE));
183   g_object_class_install_property (object_class,
184                                    PROP_USE_UNDERLINE,
185                                    g_param_spec_boolean ("use_underline",
186                                                          _("Use underline"),
187                                                          _("If set, an underline in the label property indicates that the next character should be used for the mnemonic accelerator key in the overflow menu"),
188                                                          FALSE,
189                                                          G_PARAM_READWRITE));
190   g_object_class_install_property (object_class,
191                                    PROP_LABEL_WIDGET,
192                                    g_param_spec_object ("label_widget",
193                                                         _("Label widget"),
194                                                         _("Widget to use as the item label"),
195                                                         GTK_TYPE_WIDGET,
196                                                         G_PARAM_READWRITE));
197   g_object_class_install_property (object_class,
198                                    PROP_STOCK_ID,
199                                    g_param_spec_string ("stock_id",
200                                                         _("Stock Id"),
201                                                         _("The stock icon displayed on the item"),
202                                                         NULL,
203                                                         G_PARAM_READWRITE));
204   g_object_class_install_property (object_class,
205                                    PROP_ICON_WIDGET,
206                                    g_param_spec_object ("icon_widget",
207                                                         _("Icon widget"),
208                                                         _("Icon widget to display in the item"),
209                                                         GTK_TYPE_WIDGET,
210                                                         G_PARAM_READWRITE));
211
212   toolbutton_signals[CLICKED] =
213     g_signal_new ("clicked",
214                   G_OBJECT_CLASS_TYPE (klass),
215                   G_SIGNAL_RUN_FIRST,
216                   G_STRUCT_OFFSET (GtkToolButtonClass, clicked),
217                   NULL, NULL,
218                   g_cclosure_marshal_VOID__VOID,
219                   G_TYPE_NONE, 0);
220   
221   g_type_class_add_private (object_class, sizeof (GtkToolButtonPrivate));
222 }
223
224 static void
225 gtk_tool_button_init (GtkToolButton      *button,
226                       GtkToolButtonClass *klass)
227 {
228   GtkToolItem *toolitem = GTK_TOOL_ITEM (button);
229   
230   button->priv = GTK_TOOL_BUTTON_GET_PRIVATE (button);
231
232   gtk_tool_item_set_homogeneous (toolitem, TRUE);
233
234   /* create button */
235   button->priv->button = g_object_new (klass->button_type, NULL);
236   gtk_button_set_focus_on_click (GTK_BUTTON (button->priv->button), FALSE);
237   g_signal_connect_object (button->priv->button, "clicked",
238                            G_CALLBACK (button_clicked), button, 0);
239
240   gtk_container_add (GTK_CONTAINER (button), button->priv->button);
241   gtk_widget_show (button->priv->button);
242 }
243
244 static void
245 gtk_tool_button_size_request (GtkWidget      *widget,
246                               GtkRequisition *requisition)
247 {
248   GtkWidget *child = GTK_BIN (widget)->child;
249
250   if (child && GTK_WIDGET_VISIBLE (child))
251     {
252       gtk_widget_size_request (child, requisition);
253     }
254   else
255     {
256       requisition->width = 0;
257       requisition->height = 0;
258     }
259   
260   requisition->width += GTK_CONTAINER (widget)->border_width * 2;
261   requisition->height += GTK_CONTAINER (widget)->border_width * 2;  
262 }
263
264 static void
265 gtk_tool_button_size_allocate (GtkWidget     *widget,
266                                GtkAllocation *allocation)
267 {
268   GtkToolItem *toolitem = GTK_TOOL_ITEM (widget);
269   GtkAllocation child_allocation;
270   gint border_width;
271   GtkWidget *child = GTK_BIN (widget)->child;
272
273   widget->allocation = *allocation;
274   border_width = GTK_CONTAINER (widget)->border_width;
275
276   if (gtk_tool_item_get_use_drag_window (toolitem) && GTK_WIDGET_REALIZED (widget))
277     gdk_window_move_resize (_gtk_tool_item_get_drag_window (toolitem),
278                             widget->allocation.x + border_width,
279                             widget->allocation.y + border_width,
280                             widget->allocation.width - border_width * 2,
281                             widget->allocation.height - border_width * 2);
282   
283   if (child && GTK_WIDGET_VISIBLE (child))
284     {
285       child_allocation.x = allocation->x + border_width;
286       child_allocation.y = allocation->y + border_width;
287       child_allocation.width = allocation->width - 2 * border_width;
288       child_allocation.height = allocation->height - 2 * border_width;
289       
290       gtk_widget_size_allocate (child, &child_allocation);
291     }
292 }
293
294 static void
295 gtk_tool_button_construct_contents (GtkToolItem *tool_item)
296 {
297   GtkToolButton *button = GTK_TOOL_BUTTON (tool_item);
298   GtkWidget *label = NULL;
299   GtkWidget *icon = NULL;
300   GtkToolbarStyle style;
301   gboolean need_label = FALSE;
302   gboolean need_icon = FALSE;
303   GtkIconSize icon_size;
304   GtkWidget *box = NULL;
305
306   if (gtk_tool_item_get_proxy_menu_item (tool_item, MENU_ID))
307     {
308       /* Remove item, so it will be recreated on the next
309        * create_proxy_menu_item()
310        */
311       gtk_tool_item_set_proxy_menu_item (tool_item, MENU_ID, NULL);
312     }
313   
314   if (button->priv->icon_widget && button->priv->icon_widget->parent)
315     {
316       gtk_container_remove (GTK_CONTAINER (button->priv->icon_widget->parent),
317                             button->priv->icon_widget);
318     }
319
320   if (button->priv->label_widget && button->priv->label_widget->parent)
321     {
322       gtk_container_remove (GTK_CONTAINER (button->priv->label_widget->parent),
323                             button->priv->label_widget);
324     }
325
326   if (GTK_BIN (button->priv->button)->child)
327     {
328       /* Note: we are not destroying the label_widget or icon_widget
329        * here because they were removed from their containers above
330        */
331       gtk_widget_destroy (GTK_BIN (button->priv->button)->child);
332     }
333
334   style = gtk_tool_item_get_toolbar_style (GTK_TOOL_ITEM (button));
335   
336   if (style != GTK_TOOLBAR_TEXT)
337     need_icon = TRUE;
338
339   if (style != GTK_TOOLBAR_ICONS)
340     need_label = TRUE;
341
342   if (need_label)
343     {
344       if (button->priv->label_widget)
345         {
346           label = button->priv->label_widget;
347         }
348       else
349         {
350           GtkStockItem stock_item;
351           gboolean elide;
352           gchar *label_text;
353
354           if (button->priv->label_text)
355             {
356               label_text = button->priv->label_text;
357               elide = button->priv->use_underline;
358             }
359           else if (button->priv->stock_id && gtk_stock_lookup (button->priv->stock_id, &stock_item))
360             {
361               label_text = stock_item.label;
362               elide = TRUE;
363             }
364           else
365             {
366               label_text = "";
367               elide = FALSE;
368             }
369
370           if (elide)
371             label_text = _gtk_toolbar_elide_underscores (label_text);
372           else
373             label_text = g_strdup (label_text);
374
375           label = gtk_label_new (label_text);
376
377           g_free (label_text);
378           
379           gtk_widget_show (label);
380         }
381     }
382
383   icon_size = gtk_tool_item_get_icon_size (GTK_TOOL_ITEM (button));
384   if (need_icon)
385     {
386       if (button->priv->icon_widget)
387         {
388           icon = button->priv->icon_widget;
389           
390           if (GTK_IS_IMAGE (icon))
391             {
392               g_object_set (G_OBJECT (button->priv->icon_widget),
393                             "icon-size", icon_size,
394                             NULL);
395             }
396         }
397       else if (button->priv->stock_id)
398         {
399           icon = gtk_image_new_from_stock (button->priv->stock_id, icon_size);
400           gtk_widget_show (icon);
401         }
402     }
403
404   switch (style)
405     {
406     case GTK_TOOLBAR_ICONS:
407       if (icon)
408         gtk_container_add (GTK_CONTAINER (button->priv->button), icon);
409       break;
410
411     case GTK_TOOLBAR_BOTH:
412       box = gtk_vbox_new (FALSE, 0);
413       gtk_box_pack_start (GTK_BOX (box), icon, TRUE, TRUE, 0);
414       gtk_box_pack_start (GTK_BOX (box), label, FALSE, TRUE, 0);
415       gtk_container_add (GTK_CONTAINER (button->priv->button), box);
416       break;
417
418     case GTK_TOOLBAR_BOTH_HORIZ:
419       box = gtk_hbox_new (FALSE, 0);
420       gtk_box_pack_start (GTK_BOX (box), icon, FALSE, TRUE, 0);
421       gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 0);
422       gtk_container_add (GTK_CONTAINER (button->priv->button), box);
423       break;
424
425     case GTK_TOOLBAR_TEXT:
426       gtk_container_add (GTK_CONTAINER (button->priv->button), label);
427       break;
428     }
429
430   if (box)
431     gtk_widget_show (box);
432
433   gtk_button_set_relief (GTK_BUTTON (button->priv->button),
434                          gtk_tool_item_get_relief_style (GTK_TOOL_ITEM (button)));
435
436   gtk_widget_queue_resize (GTK_WIDGET (button));
437 }
438
439 static void
440 gtk_tool_button_set_property (GObject         *object,
441                               guint            prop_id,
442                               const GValue    *value,
443                               GParamSpec      *pspec)
444 {
445   GtkToolButton *button = GTK_TOOL_BUTTON (object);
446   
447   switch (prop_id)
448     {
449     case PROP_LABEL:
450       gtk_tool_button_set_label (button, g_value_get_string (value));
451       break;
452     case PROP_USE_UNDERLINE:
453       gtk_tool_button_set_use_underline (button, g_value_get_boolean (value));
454       break;
455     case PROP_LABEL_WIDGET:
456       gtk_tool_button_set_label_widget (button, g_value_get_object (value));
457       break;
458     case PROP_STOCK_ID:
459       gtk_tool_button_set_stock_id (button, g_value_get_string (value));
460       break;
461     case PROP_ICON_WIDGET:
462       gtk_tool_button_set_icon_widget (button, g_value_get_object (value));
463       break;
464     default:
465       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
466     }
467 }
468
469 static void
470 gtk_tool_button_get_property (GObject         *object,
471                               guint            prop_id,
472                               GValue          *value,
473                               GParamSpec      *pspec)
474 {
475   GtkToolButton *button = GTK_TOOL_BUTTON (object);
476
477   switch (prop_id)
478     {
479     case PROP_LABEL:
480       g_value_set_string (value, gtk_tool_button_get_label (button));
481       break;
482     case PROP_LABEL_WIDGET:
483       g_value_set_object (value, gtk_tool_button_get_label_widget (button));
484       break;
485     case PROP_USE_UNDERLINE:
486       g_value_set_boolean (value, gtk_tool_button_get_use_underline (button));
487       break;
488     case PROP_STOCK_ID:
489       g_value_set_string (value, button->priv->stock_id);
490       break;
491     case PROP_ICON_WIDGET:
492       g_value_set_object (value, button->priv->icon_widget);
493       break;
494     default:
495       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
496     }
497 }
498
499 static void
500 gtk_tool_button_finalize (GObject *object)
501 {
502   GtkToolButton *button = GTK_TOOL_BUTTON (object);
503
504   g_free (button->priv->stock_id);
505   button->priv->stock_id = NULL;
506
507   parent_class->finalize (object);
508 }
509
510 static GtkWidget *
511 clone_image_menu_size (GtkImage *image, GtkSettings *settings)
512 {
513   GtkImageType storage_type = gtk_image_get_storage_type (image);
514
515   if (storage_type == GTK_IMAGE_STOCK)
516     {
517       gchar *stock_id;
518       gtk_image_get_stock (image, &stock_id, NULL);
519       return gtk_image_new_from_stock (stock_id, GTK_ICON_SIZE_MENU);
520     }
521   else if (storage_type == GTK_IMAGE_ICON_SET)
522     {
523       GtkIconSet *icon_set;
524       gtk_image_get_icon_set (image, &icon_set, NULL);
525       return gtk_image_new_from_icon_set (icon_set, GTK_ICON_SIZE_MENU);
526     }
527   else if (storage_type == GTK_IMAGE_PIXBUF)
528     {
529       gint width, height;
530       
531       if (settings &&
532           gtk_icon_size_lookup_for_settings (settings, GTK_ICON_SIZE_MENU,
533                                              &width, &height))
534         {
535           GdkPixbuf *src_pixbuf, *dest_pixbuf;
536
537           src_pixbuf = gtk_image_get_pixbuf (image);
538           dest_pixbuf = gdk_pixbuf_scale_simple (src_pixbuf, width, height,
539                                                  GDK_INTERP_BILINEAR);
540
541           return gtk_image_new_from_pixbuf (dest_pixbuf);
542         }
543     }
544
545   return NULL;
546 }
547       
548 static gboolean
549 gtk_tool_button_create_menu_proxy (GtkToolItem *item)
550 {
551   GtkToolButton *button = GTK_TOOL_BUTTON (item);
552   GtkWidget *menu_item;
553   GtkWidget *menu_image = NULL;
554   GtkStockItem stock_item;
555   gboolean use_mnemonic = TRUE;
556   const char *label;
557
558   if (button->priv->label_widget && GTK_IS_LABEL (button->priv->label_widget))
559     {
560       label = gtk_label_get_label (GTK_LABEL (button->priv->label_widget));
561       use_mnemonic = gtk_label_get_use_underline (GTK_LABEL (button->priv->label_widget));
562     }
563   else if (button->priv->label_text)
564     {
565       label = button->priv->label_text;
566       use_mnemonic = button->priv->use_underline;
567     }
568   else if (button->priv->stock_id && gtk_stock_lookup (button->priv->stock_id, &stock_item))
569     {
570       label = stock_item.label;
571       use_mnemonic = FALSE;
572     }
573   else
574     {
575       label = "";
576       use_mnemonic = FALSE;
577     }
578   
579   if (use_mnemonic)
580     menu_item = gtk_image_menu_item_new_with_mnemonic (label);
581   else
582     menu_item = gtk_image_menu_item_new_with_label (label);
583
584   if (button->priv->icon_widget && GTK_IS_IMAGE (button->priv->icon_widget))
585     {
586       menu_image = clone_image_menu_size (GTK_IMAGE (button->priv->icon_widget),
587                                           gtk_widget_get_settings (GTK_WIDGET (button)));
588     }
589   else if (button->priv->stock_id)
590     {
591       menu_image = gtk_image_new_from_stock (button->priv->stock_id, GTK_ICON_SIZE_MENU);
592     }
593
594   if (menu_image)
595     gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item), menu_image);
596
597   g_signal_connect_closure_by_id (menu_item,
598                                   g_signal_lookup ("activate", G_OBJECT_TYPE (menu_item)), 0,
599                                   g_cclosure_new_object_swap (G_CALLBACK (gtk_button_clicked),
600                                                               G_OBJECT (GTK_TOOL_BUTTON (button)->priv->button)),
601                                   FALSE);
602
603   gtk_tool_item_set_proxy_menu_item (GTK_TOOL_ITEM (button), MENU_ID, menu_item);
604   
605   return TRUE;
606 }
607
608 static void
609 button_clicked (GtkWidget     *widget,
610                 GtkToolButton *button)
611 {
612   g_signal_emit_by_name (button, "clicked");
613 }
614
615 static void
616 gtk_tool_button_toolbar_reconfigured (GtkToolItem *tool_item)
617 {
618   gtk_tool_button_construct_contents (tool_item);
619 }
620
621 GtkToolItem *
622 gtk_tool_button_new_from_stock (const gchar *stock_id)
623 {
624   GtkToolButton *button;
625
626   g_return_val_if_fail (stock_id != NULL, NULL);
627     
628   button = g_object_new (GTK_TYPE_TOOL_BUTTON,
629                          "stock_id", stock_id,
630                          NULL);
631
632   return GTK_TOOL_ITEM (button);
633 }
634
635 GtkToolItem *
636 gtk_tool_button_new (const gchar *label,
637                      GtkWidget   *icon_widget)
638 {
639   GtkToolButton *button;
640
641   button = g_object_new (GTK_TYPE_TOOL_BUTTON,
642                          NULL);
643   
644   if (label)
645     gtk_tool_button_set_label (button, label);
646
647   if (icon_widget)
648     gtk_tool_button_set_icon_widget (button, icon_widget);
649
650   return GTK_TOOL_ITEM (button);  
651 }
652
653 void
654 gtk_tool_button_set_label (GtkToolButton *button,
655                            const gchar   *label)
656 {
657   gchar *old_label;
658   
659   g_return_if_fail (GTK_IS_TOOL_BUTTON (button));
660
661   old_label = button->priv->label_text;
662
663   button->priv->label_text = g_strdup (label);
664   gtk_tool_button_construct_contents (GTK_TOOL_ITEM (button));
665       
666   g_object_notify (G_OBJECT (button), "label");
667
668   if (old_label)
669     g_free (old_label);
670 }
671
672 G_CONST_RETURN gchar *
673 gtk_tool_button_get_label (GtkToolButton *button)
674 {
675   g_return_val_if_fail (GTK_IS_TOOL_BUTTON (button), NULL);
676
677   return button->priv->label_text;
678 }
679
680 void
681 gtk_tool_button_set_use_underline (GtkToolButton *button,
682                                    gboolean       use_underline)
683 {
684   g_return_if_fail (GTK_IS_TOOL_BUTTON (button));
685
686   use_underline = use_underline != FALSE;
687
688   if (use_underline != button->priv->use_underline)
689     {
690       button->priv->use_underline = use_underline;
691
692       gtk_tool_button_construct_contents (GTK_TOOL_ITEM (button));
693
694       g_object_notify (G_OBJECT (button), "use_underline");
695     }
696 }
697
698 gboolean
699 gtk_tool_button_get_use_underline (GtkToolButton *button)
700 {
701   g_return_val_if_fail (GTK_IS_TOOL_BUTTON (button), FALSE);
702
703   return button->priv->use_underline;
704 }
705
706 void
707 gtk_tool_button_set_stock_id (GtkToolButton *button,
708                               const gchar   *stock_id)
709 {
710   gchar *old_stock_id;
711   
712   g_return_if_fail (GTK_IS_TOOL_BUTTON (button));
713
714   old_stock_id = button->priv->stock_id;
715
716   button->priv->stock_id = g_strdup (stock_id);
717   gtk_tool_button_construct_contents (GTK_TOOL_ITEM (button));
718   
719   g_object_notify (G_OBJECT (button), "stock_id");
720
721   g_free (old_stock_id);
722 }
723
724 G_CONST_RETURN gchar *
725 gtk_tool_button_get_stock_id (GtkToolButton *button)
726 {
727   g_return_val_if_fail (GTK_IS_TOOL_BUTTON (button), NULL);
728
729   return button->priv->stock_id;
730 }
731
732 void
733 gtk_tool_button_set_icon_widget (GtkToolButton *button,
734                                  GtkWidget     *icon)
735 {
736   g_return_if_fail (GTK_IS_TOOL_BUTTON (button));
737   g_return_if_fail (icon == NULL || GTK_IS_WIDGET (icon));
738
739   if (icon != button->priv->icon_widget)
740     {
741       if (button->priv->icon_widget)
742         g_object_unref (G_OBJECT (button->priv->icon_widget));
743
744       if (icon)
745         {
746           g_object_ref (icon);
747           gtk_object_sink (GTK_OBJECT (icon));
748         }
749
750       button->priv->icon_widget = icon;
751
752       gtk_tool_button_construct_contents (GTK_TOOL_ITEM (button));
753       
754       g_object_notify (G_OBJECT (button), "icon_widget");
755     }
756 }
757
758 void
759 gtk_tool_button_set_label_widget (GtkToolButton *button,
760                                   GtkWidget     *label_widget)
761 {
762   g_return_if_fail (GTK_IS_TOOL_BUTTON (button));
763   g_return_if_fail (label_widget == NULL || GTK_IS_WIDGET (label_widget));
764
765   if (label_widget != button->priv->label_widget)
766     {
767       if (button->priv->label_widget)
768         g_object_unref (button->priv->label_widget);
769
770       if (label_widget)
771         {
772           g_object_ref (label_widget);
773           gtk_object_sink (GTK_OBJECT (label_widget));
774         }
775
776       button->priv->label_widget = label_widget;
777
778       gtk_tool_button_construct_contents (GTK_TOOL_ITEM (button));
779       
780       g_object_notify (G_OBJECT (button), "label_widget");
781     }
782 }
783
784 GtkWidget *
785 gtk_tool_button_get_label_widget (GtkToolButton *button)
786 {
787   g_return_val_if_fail (GTK_IS_TOOL_BUTTON (button), NULL);
788
789   return button->priv->label_widget;
790 }
791
792 GtkWidget *
793 gtk_tool_button_get_icon_widget (GtkToolButton *button)
794 {
795   g_return_val_if_fail (GTK_IS_TOOL_BUTTON (button), NULL);
796
797   return button->priv->icon_widget;
798 }
799
800 GtkWidget *
801 _gtk_tool_button_get_button (GtkToolButton *button)
802 {
803   g_return_val_if_fail (GTK_IS_TOOL_BUTTON (button), NULL);
804
805   return button->priv->button;
806 }