]> Pileus Git - ~andy/gtk/blob - gtk/gtktoolbutton.c
959104087c9eab3b032a956aab14eef024226810
[~andy/gtk] / gtk / gtktoolbutton.c
1 /* gtktoolbutton.c
2  *
3  * Copyright (C) 2002 Anders Carlsson <andersca@gnome.org>
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 <config.h>
24 #include "gtktoolbutton.h"
25 #include "gtkbutton.h"
26 #include "gtkhbox.h"
27 #include "gtkiconfactory.h"
28 #include "gtkimage.h"
29 #include "gtkimagemenuitem.h"
30 #include "gtklabel.h"
31 #include "gtkstock.h"
32 #include "gtkvbox.h"
33 #include "gtkintl.h"
34 #include "gtktoolbar.h"
35 #include "gtkiconfactory.h"
36 #include "gtkprivate.h"
37 #include "gtkalias.h"
38
39 #include <string.h>
40
41 #define MENU_ID "gtk-tool-button-menu-id"
42
43 enum {
44   CLICKED,
45   LAST_SIGNAL
46 };
47
48 enum {
49   PROP_0,
50   PROP_LABEL,
51   PROP_USE_UNDERLINE,
52   PROP_LABEL_WIDGET,
53   PROP_STOCK_ID,
54   PROP_ICON_NAME,
55   PROP_ICON_WIDGET
56 };
57
58 static void gtk_tool_button_init          (GtkToolButton      *button,
59                                            GtkToolButtonClass *klass);
60 static void gtk_tool_button_class_init    (GtkToolButtonClass *klass);
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_property_notify (GObject          *object,
70                                              GParamSpec       *pspec);
71 static void gtk_tool_button_finalize      (GObject            *object);
72
73 static void gtk_tool_button_toolbar_reconfigured (GtkToolItem *tool_item);
74 static gboolean   gtk_tool_button_create_menu_proxy (GtkToolItem     *item);
75 static void       button_clicked                    (GtkWidget       *widget,
76                                                      GtkToolButton   *button);
77
78 static void gtk_tool_button_construct_contents (GtkToolItem *tool_item);
79       
80 static GObjectClass *parent_class = NULL;
81 static guint         toolbutton_signals[LAST_SIGNAL] = { 0 };
82
83 #define GTK_TOOL_BUTTON_GET_PRIVATE(obj)(G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_TOOL_BUTTON, GtkToolButtonPrivate))
84
85 struct _GtkToolButtonPrivate
86 {
87   GtkWidget *button;
88
89   gchar *stock_id;
90   gchar *icon_name;
91   gchar *label_text;
92   GtkWidget *label_widget;
93   GtkWidget *icon_widget;
94   
95   guint use_underline : 1;
96 };
97
98 GType
99 gtk_tool_button_get_type (void)
100 {
101   static GtkType type = 0;
102
103   if (!type)
104     {
105       static const GTypeInfo type_info =
106         {
107           sizeof (GtkToolButtonClass),
108           (GBaseInitFunc) NULL,
109           (GBaseFinalizeFunc) NULL,
110           (GClassInitFunc) gtk_tool_button_class_init,
111           (GClassFinalizeFunc) NULL,
112           NULL,
113           sizeof (GtkToolButton),
114           0, /* n_preallocs */
115           (GInstanceInitFunc) gtk_tool_button_init,
116         };
117
118       type = g_type_register_static (GTK_TYPE_TOOL_ITEM,
119                                      I_("GtkToolButton"),
120                                      &type_info, 0);
121     }
122   return type;
123 }
124
125 static void
126 gtk_tool_button_class_init (GtkToolButtonClass *klass)
127 {
128   GObjectClass *object_class;
129   GtkToolItemClass *tool_item_class;
130   
131   parent_class = g_type_class_peek_parent (klass);
132   
133   object_class = (GObjectClass *)klass;
134   tool_item_class = (GtkToolItemClass *)klass;
135   
136   object_class->set_property = gtk_tool_button_set_property;
137   object_class->get_property = gtk_tool_button_get_property;
138   object_class->notify = gtk_tool_button_property_notify;
139   object_class->finalize = gtk_tool_button_finalize;
140
141   tool_item_class->create_menu_proxy = gtk_tool_button_create_menu_proxy;
142   tool_item_class->toolbar_reconfigured = gtk_tool_button_toolbar_reconfigured;
143   
144   klass->button_type = GTK_TYPE_BUTTON;
145
146   /* Properties are interpreted like this:
147    *
148    *          - if the tool button has an icon_widget, then that widget
149    *            will be used as the icon. Otherwise, if the tool button
150    *            has a stock id, the corresponding stock icon will be
151    *            used. Otherwise, if the tool button has an icon name,
152    *            the corresponding icon from the theme will be used.
153    *            Otherwise, the tool button will not have an icon.
154    *
155    *          - if the tool button has a label_widget then that widget
156    *            will be used as the label. Otherwise, if the tool button
157    *            has a label text, that text will be used as label. Otherwise,
158    *            if the toolbutton has a stock id, the corresponding text
159    *            will be used as label. Otherwise, if the tool button has
160    *            an icon name, the corresponding icon name from the theme will
161    *            be used. Otherwise, the toolbutton will have an empty label.
162    *
163    *          - The use_underline property only has an effect when the label
164    *            on the toolbutton comes from the label property (ie. not from
165    *            label_widget or from stock_id).
166    *
167    *            In that case, if use_underline is set,
168    *
169    *                    - underscores are removed from the label text before
170    *                      the label is shown on the toolbutton unless the
171    *                      underscore is followed by another underscore
172    *
173    *                    - an underscore indicates that the next character when
174    *                      used in the overflow menu should be used as a
175    *                      mnemonic.
176    *
177    *            In short: use_underline = TRUE means that the label text has
178    *            the form "_Open" and the toolbar should take appropriate
179    *            action.
180    */
181
182   g_object_class_install_property (object_class,
183                                    PROP_LABEL,
184                                    g_param_spec_string ("label",
185                                                         P_("Label"),
186                                                         P_("Text to show in the item."),
187                                                         NULL,
188                                                         GTK_PARAM_READWRITE));
189   g_object_class_install_property (object_class,
190                                    PROP_USE_UNDERLINE,
191                                    g_param_spec_boolean ("use-underline",
192                                                          P_("Use underline"),
193                                                          P_("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"),
194                                                          FALSE,
195                                                          GTK_PARAM_READWRITE));
196   g_object_class_install_property (object_class,
197                                    PROP_LABEL_WIDGET,
198                                    g_param_spec_object ("label-widget",
199                                                         P_("Label widget"),
200                                                         P_("Widget to use as the item label"),
201                                                         GTK_TYPE_WIDGET,
202                                                         GTK_PARAM_READWRITE));
203   g_object_class_install_property (object_class,
204                                    PROP_STOCK_ID,
205                                    g_param_spec_string ("stock-id",
206                                                         P_("Stock Id"),
207                                                         P_("The stock icon displayed on the item"),
208                                                         NULL,
209                                                         GTK_PARAM_READWRITE));
210
211   /**
212    * GtkToolButton:icon-name:
213    * 
214    * The name of the themed icon displayed on the item.
215    * This property only has an effect if not overridden by "label", 
216    * "icon_widget" or "stock_id" properties.
217    *
218    * Since: 2.8 
219    */
220   g_object_class_install_property (object_class,
221                                    PROP_ICON_NAME,
222                                    g_param_spec_string ("icon-name",
223                                                         P_("Icon name"),
224                                                         P_("The name of the themed icon displayed on the item"),
225                                                         NULL,
226                                                         GTK_PARAM_READWRITE));
227   g_object_class_install_property (object_class,
228                                    PROP_ICON_WIDGET,
229                                    g_param_spec_object ("icon-widget",
230                                                         P_("Icon widget"),
231                                                         P_("Icon widget to display in the item"),
232                                                         GTK_TYPE_WIDGET,
233                                                         GTK_PARAM_READWRITE));
234
235 /**
236  * GtkToolButton::clicked:
237  * @toolbutton: the object that emitted the signal
238  *
239  * This signal is emitted when the tool button is clicked with the mouse
240  * or activated with the keyboard.
241  **/
242   toolbutton_signals[CLICKED] =
243     g_signal_new (I_("clicked"),
244                   G_OBJECT_CLASS_TYPE (klass),
245                   G_SIGNAL_RUN_FIRST,
246                   G_STRUCT_OFFSET (GtkToolButtonClass, clicked),
247                   NULL, NULL,
248                   g_cclosure_marshal_VOID__VOID,
249                   G_TYPE_NONE, 0);
250   
251   g_type_class_add_private (object_class, sizeof (GtkToolButtonPrivate));
252 }
253
254 static void
255 gtk_tool_button_init (GtkToolButton      *button,
256                       GtkToolButtonClass *klass)
257 {
258   GtkToolItem *toolitem = GTK_TOOL_ITEM (button);
259   
260   button->priv = GTK_TOOL_BUTTON_GET_PRIVATE (button);
261
262   gtk_tool_item_set_homogeneous (toolitem, TRUE);
263
264   /* create button */
265   button->priv->button = g_object_new (klass->button_type, NULL);
266   gtk_button_set_focus_on_click (GTK_BUTTON (button->priv->button), FALSE);
267   g_signal_connect_object (button->priv->button, "clicked",
268                            G_CALLBACK (button_clicked), button, 0);
269
270   gtk_container_add (GTK_CONTAINER (button), button->priv->button);
271   gtk_widget_show (button->priv->button);
272 }
273
274 static void
275 gtk_tool_button_construct_contents (GtkToolItem *tool_item)
276 {
277   GtkToolButton *button = GTK_TOOL_BUTTON (tool_item);
278   GtkWidget *label = NULL;
279   GtkWidget *icon = NULL;
280   GtkToolbarStyle style;
281   gboolean need_label = FALSE;
282   gboolean need_icon = FALSE;
283   GtkIconSize icon_size;
284   GtkWidget *box = NULL;
285
286   if (button->priv->icon_widget && button->priv->icon_widget->parent)
287     {
288       gtk_container_remove (GTK_CONTAINER (button->priv->icon_widget->parent),
289                             button->priv->icon_widget);
290     }
291
292   if (button->priv->label_widget && button->priv->label_widget->parent)
293     {
294       gtk_container_remove (GTK_CONTAINER (button->priv->label_widget->parent),
295                             button->priv->label_widget);
296     }
297
298   if (GTK_BIN (button->priv->button)->child)
299     {
300       /* Note: we are not destroying the label_widget or icon_widget
301        * here because they were removed from their containers above
302        */
303       gtk_widget_destroy (GTK_BIN (button->priv->button)->child);
304     }
305
306   style = gtk_tool_item_get_toolbar_style (GTK_TOOL_ITEM (button));
307   
308   if (style != GTK_TOOLBAR_TEXT)
309     need_icon = TRUE;
310
311   if (style != GTK_TOOLBAR_ICONS && style != GTK_TOOLBAR_BOTH_HORIZ)
312     need_label = TRUE;
313
314   if (style == GTK_TOOLBAR_BOTH_HORIZ &&
315       (gtk_tool_item_get_is_important (GTK_TOOL_ITEM (button)) ||
316        gtk_tool_item_get_orientation (GTK_TOOL_ITEM (button)) == GTK_ORIENTATION_VERTICAL))
317     {
318       need_label = TRUE;
319     }
320
321   if (need_label)
322     {
323       if (button->priv->label_widget)
324         {
325           label = button->priv->label_widget;
326         }
327       else
328         {
329           GtkStockItem stock_item;
330           gboolean elide;
331           gchar *label_text;
332
333           if (button->priv->label_text)
334             {
335               label_text = button->priv->label_text;
336               elide = button->priv->use_underline;
337             }
338           else if (button->priv->stock_id && gtk_stock_lookup (button->priv->stock_id, &stock_item))
339             {
340               label_text = stock_item.label;
341               elide = TRUE;
342             }
343           else
344             {
345               label_text = "";
346               elide = FALSE;
347             }
348
349           if (elide)
350             label_text = _gtk_toolbar_elide_underscores (label_text);
351           else
352             label_text = g_strdup (label_text);
353
354           label = gtk_label_new (label_text);
355
356           g_free (label_text);
357           
358           gtk_widget_show (label);
359         }
360     }
361
362   icon_size = gtk_tool_item_get_icon_size (GTK_TOOL_ITEM (button));
363   if (need_icon)
364     {
365       if (button->priv->icon_widget)
366         {
367           icon = button->priv->icon_widget;
368           
369           if (GTK_IS_IMAGE (icon))
370             {
371               g_object_set (button->priv->icon_widget,
372                             "icon-size", icon_size,
373                             NULL);
374             }
375         }
376       else if (button->priv->stock_id)
377         {
378           icon = gtk_image_new_from_stock (button->priv->stock_id, icon_size);
379           gtk_widget_show (icon);
380         }
381       else if (button->priv->icon_name)
382         {
383           icon = gtk_image_new_from_icon_name (button->priv->icon_name, icon_size);
384           gtk_widget_show (icon);
385         }
386     }
387
388   switch (style)
389     {
390     case GTK_TOOLBAR_ICONS:
391       if (icon)
392         gtk_container_add (GTK_CONTAINER (button->priv->button), icon);
393       break;
394
395     case GTK_TOOLBAR_BOTH:
396       box = gtk_vbox_new (FALSE, 0);
397       if (icon)
398         gtk_box_pack_start (GTK_BOX (box), icon, TRUE, TRUE, 0);
399       gtk_box_pack_start (GTK_BOX (box), label, FALSE, TRUE, 0);
400       gtk_container_add (GTK_CONTAINER (button->priv->button), box);
401       break;
402
403     case GTK_TOOLBAR_BOTH_HORIZ:
404       box = gtk_hbox_new (FALSE, 0);
405       if (icon)
406         gtk_box_pack_start (GTK_BOX (box), icon, label? FALSE : TRUE, TRUE, 0);
407       if (label)
408         gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 0);
409       gtk_container_add (GTK_CONTAINER (button->priv->button), box);
410       break;
411
412     case GTK_TOOLBAR_TEXT:
413       gtk_container_add (GTK_CONTAINER (button->priv->button), label);
414       break;
415     }
416
417   if (box)
418     gtk_widget_show (box);
419
420   gtk_button_set_relief (GTK_BUTTON (button->priv->button),
421                          gtk_tool_item_get_relief_style (GTK_TOOL_ITEM (button)));
422
423   gtk_tool_item_rebuild_menu (tool_item);
424   
425   gtk_widget_queue_resize (GTK_WIDGET (button));
426 }
427
428 static void
429 gtk_tool_button_set_property (GObject         *object,
430                               guint            prop_id,
431                               const GValue    *value,
432                               GParamSpec      *pspec)
433 {
434   GtkToolButton *button = GTK_TOOL_BUTTON (object);
435   
436   switch (prop_id)
437     {
438     case PROP_LABEL:
439       gtk_tool_button_set_label (button, g_value_get_string (value));
440       break;
441     case PROP_USE_UNDERLINE:
442       gtk_tool_button_set_use_underline (button, g_value_get_boolean (value));
443       break;
444     case PROP_LABEL_WIDGET:
445       gtk_tool_button_set_label_widget (button, g_value_get_object (value));
446       break;
447     case PROP_STOCK_ID:
448       gtk_tool_button_set_stock_id (button, g_value_get_string (value));
449       break;
450     case PROP_ICON_NAME:
451       gtk_tool_button_set_icon_name (button, g_value_get_string (value));
452       break;
453     case PROP_ICON_WIDGET:
454       gtk_tool_button_set_icon_widget (button, g_value_get_object (value));
455       break;
456     default:
457       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
458     }
459 }
460
461 static void
462 gtk_tool_button_property_notify (GObject          *object,
463                                  GParamSpec       *pspec)
464 {
465   if (strcmp (pspec->name, "is-important") == 0)
466     gtk_tool_button_construct_contents (GTK_TOOL_ITEM (object));
467
468   if (parent_class->notify)
469     parent_class->notify (object, pspec);
470 }
471
472 static void
473 gtk_tool_button_get_property (GObject         *object,
474                               guint            prop_id,
475                               GValue          *value,
476                               GParamSpec      *pspec)
477 {
478   GtkToolButton *button = GTK_TOOL_BUTTON (object);
479
480   switch (prop_id)
481     {
482     case PROP_LABEL:
483       g_value_set_string (value, gtk_tool_button_get_label (button));
484       break;
485     case PROP_LABEL_WIDGET:
486       g_value_set_object (value, gtk_tool_button_get_label_widget (button));
487       break;
488     case PROP_USE_UNDERLINE:
489       g_value_set_boolean (value, gtk_tool_button_get_use_underline (button));
490       break;
491     case PROP_STOCK_ID:
492       g_value_set_string (value, button->priv->stock_id);
493       break;
494     case PROP_ICON_NAME:
495       g_value_set_string (value, button->priv->icon_name);
496       break;
497     case PROP_ICON_WIDGET:
498       g_value_set_object (value, button->priv->icon_widget);
499       break;
500     default:
501       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
502     }
503 }
504
505 static void
506 gtk_tool_button_finalize (GObject *object)
507 {
508   GtkToolButton *button = GTK_TOOL_BUTTON (object);
509
510   g_free (button->priv->stock_id);
511   g_free (button->priv->icon_name);
512   g_free (button->priv->label_text);
513
514   if (button->priv->label_widget)
515     g_object_unref (button->priv->label_widget);
516
517   if (button->priv->icon_widget)
518     g_object_unref (button->priv->icon_widget);
519   
520   parent_class->finalize (object);
521 }
522
523 static GtkWidget *
524 clone_image_menu_size (GtkImage *image, GtkSettings *settings)
525 {
526   GtkImageType storage_type = gtk_image_get_storage_type (image);
527
528   if (storage_type == GTK_IMAGE_STOCK)
529     {
530       gchar *stock_id;
531       gtk_image_get_stock (image, &stock_id, NULL);
532       return gtk_image_new_from_stock (stock_id, GTK_ICON_SIZE_MENU);
533     }
534   else if (storage_type == GTK_IMAGE_ICON_SET)
535     {
536       GtkIconSet *icon_set;
537       gtk_image_get_icon_set (image, &icon_set, NULL);
538       return gtk_image_new_from_icon_set (icon_set, GTK_ICON_SIZE_MENU);
539     }
540   else if (storage_type == GTK_IMAGE_PIXBUF)
541     {
542       gint width, height;
543       
544       if (settings &&
545           gtk_icon_size_lookup_for_settings (settings, GTK_ICON_SIZE_MENU,
546                                              &width, &height))
547         {
548           GdkPixbuf *src_pixbuf, *dest_pixbuf;
549
550           src_pixbuf = gtk_image_get_pixbuf (image);
551           dest_pixbuf = gdk_pixbuf_scale_simple (src_pixbuf, width, height,
552                                                  GDK_INTERP_BILINEAR);
553
554           return gtk_image_new_from_pixbuf (dest_pixbuf);
555         }
556     }
557
558   return NULL;
559 }
560       
561 static gboolean
562 gtk_tool_button_create_menu_proxy (GtkToolItem *item)
563 {
564   GtkToolButton *button = GTK_TOOL_BUTTON (item);
565   GtkWidget *menu_item;
566   GtkWidget *menu_image = NULL;
567   GtkStockItem stock_item;
568   gboolean use_mnemonic = TRUE;
569   const char *label;
570
571   if (button->priv->label_widget && GTK_IS_LABEL (button->priv->label_widget))
572     {
573       label = gtk_label_get_label (GTK_LABEL (button->priv->label_widget));
574       use_mnemonic = gtk_label_get_use_underline (GTK_LABEL (button->priv->label_widget));
575     }
576   else if (button->priv->label_text)
577     {
578       label = button->priv->label_text;
579       use_mnemonic = button->priv->use_underline;
580     }
581   else if (button->priv->stock_id && gtk_stock_lookup (button->priv->stock_id, &stock_item))
582     {
583       label = stock_item.label;
584     }
585   else
586     {
587       label = "";
588     }
589   
590   if (use_mnemonic)
591     menu_item = gtk_image_menu_item_new_with_mnemonic (label);
592   else
593     menu_item = gtk_image_menu_item_new_with_label (label);
594
595   if (button->priv->icon_widget && GTK_IS_IMAGE (button->priv->icon_widget))
596     {
597       menu_image = clone_image_menu_size (GTK_IMAGE (button->priv->icon_widget),
598                                           gtk_widget_get_settings (GTK_WIDGET (button)));
599     }
600   else if (button->priv->stock_id)
601     {
602       menu_image = gtk_image_new_from_stock (button->priv->stock_id, GTK_ICON_SIZE_MENU);
603     }
604
605   if (menu_image)
606     gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item), menu_image);
607
608   g_signal_connect_closure_by_id (menu_item,
609                                   g_signal_lookup ("activate", G_OBJECT_TYPE (menu_item)), 0,
610                                   g_cclosure_new_object_swap (G_CALLBACK (gtk_button_clicked),
611                                                               G_OBJECT (GTK_TOOL_BUTTON (button)->priv->button)),
612                                   FALSE);
613
614   gtk_tool_item_set_proxy_menu_item (GTK_TOOL_ITEM (button), MENU_ID, menu_item);
615   
616   return TRUE;
617 }
618
619 static void
620 button_clicked (GtkWidget     *widget,
621                 GtkToolButton *button)
622 {
623   g_signal_emit_by_name (button, "clicked");
624 }
625
626 static void
627 gtk_tool_button_toolbar_reconfigured (GtkToolItem *tool_item)
628 {
629   gtk_tool_button_construct_contents (tool_item);
630 }
631
632 /**
633  * gtk_tool_button_new_from_stock:
634  * @stock_id: the name of the stock item 
635  *
636  * Creates a new #GtkToolButton containing the image and text from a
637  * stock item. Some stock ids have preprocessor macros like #GTK_STOCK_OK
638  * and #GTK_STOCK_APPLY.
639  *
640  * It is an error if @stock_id is not a name of a stock item.
641  * 
642  * Return value: A new #GtkToolButton
643  * 
644  * Since: 2.4
645  **/
646 GtkToolItem *
647 gtk_tool_button_new_from_stock (const gchar *stock_id)
648 {
649   GtkToolButton *button;
650
651   g_return_val_if_fail (stock_id != NULL, NULL);
652     
653   button = g_object_new (GTK_TYPE_TOOL_BUTTON,
654                          "stock-id", stock_id,
655                          NULL);
656
657   return GTK_TOOL_ITEM (button);
658 }
659
660 /**
661  * gtk_tool_button_new:
662  * @label: a string that will be used as label, or %NULL
663  * @icon_widget: a widget that will be used as icon widget, or %NULL
664  * 
665  * Creates a new %GtkToolButton using @icon_widget as icon and @label as
666  * label.
667  * 
668  * Return value: A new #GtkToolButton
669  * 
670  * Since: 2.4
671  **/
672 GtkToolItem *
673 gtk_tool_button_new (GtkWidget   *icon_widget,
674                      const gchar *label)
675 {
676   GtkToolButton *button;
677
678   button = g_object_new (GTK_TYPE_TOOL_BUTTON,
679                          NULL);
680   
681   if (label)
682     gtk_tool_button_set_label (button, label);
683
684   if (icon_widget)
685     gtk_tool_button_set_icon_widget (button, icon_widget);
686
687   return GTK_TOOL_ITEM (button);  
688 }
689
690 /**
691  * gtk_tool_button_set_label:
692  * @button: a #GtkToolButton
693  * @label: a string that will be used as label, or %NULL.
694  * 
695  * Sets @label as the label used for the tool button. The "label" property
696  * only has an effect if not overridden by a non-%NULL "label_widget" property.
697  * If both the "label_widget" and "label" properties are %NULL, the label
698  * is determined by the "stock_id" property. If the "stock_id" property is also
699  * %NULL, @button will not have a label.
700  * 
701  * Since: 2.4
702  **/
703 void
704 gtk_tool_button_set_label (GtkToolButton *button,
705                            const gchar   *label)
706 {
707   gchar *old_label;
708   
709   g_return_if_fail (GTK_IS_TOOL_BUTTON (button));
710
711   old_label = button->priv->label_text;
712
713   button->priv->label_text = g_strdup (label);
714   gtk_tool_button_construct_contents (GTK_TOOL_ITEM (button));
715       
716   g_object_notify (G_OBJECT (button), "label");
717
718   if (old_label)
719     g_free (old_label);
720 }
721
722 /**
723  * gtk_tool_button_get_label:
724  * @button: a #GtkToolButton
725  * 
726  * Returns the label used by the tool button, or %NULL if the tool button
727  * doesn't have a label. or uses a the label from a stock item. The returned
728  * string is owned by GTK+, and must not be modified or freed.
729  * 
730  * Return value: The label, or %NULL
731  * 
732  * Since: 2.4
733  **/
734 G_CONST_RETURN gchar *
735 gtk_tool_button_get_label (GtkToolButton *button)
736 {
737   g_return_val_if_fail (GTK_IS_TOOL_BUTTON (button), NULL);
738
739   return button->priv->label_text;
740 }
741
742 /**
743  * gtk_tool_button_set_use_underline:
744  * @button: a #GtkToolButton
745  * @use_underline: whether the button label has the form "_Open"
746  *
747  * If set, an underline in the label property indicates that the next character
748  * should be used for the mnemonic accelerator key in the overflow menu. For
749  * example, if the label property is "_Open" and @use_underline is %TRUE,
750  * the label on the tool button will be "Open" and the item on the overflow
751  * menu will have an underlined 'O'.
752  * 
753  * Labels shown on tool buttons never have mnemonics on them; this property
754  * only affects the menu item on the overflow menu.
755  * 
756  * Since: 2.4
757  **/
758 void
759 gtk_tool_button_set_use_underline (GtkToolButton *button,
760                                    gboolean       use_underline)
761 {
762   g_return_if_fail (GTK_IS_TOOL_BUTTON (button));
763
764   use_underline = use_underline != FALSE;
765
766   if (use_underline != button->priv->use_underline)
767     {
768       button->priv->use_underline = use_underline;
769
770       gtk_tool_button_construct_contents (GTK_TOOL_ITEM (button));
771
772       g_object_notify (G_OBJECT (button), "use-underline");
773     }
774 }
775
776 /**
777  * gtk_tool_button_get_use_underline:
778  * @button: a #GtkToolButton
779  * 
780  * Returns whether underscores in the label property are used as mnemonics
781  * on menu items on the overflow menu. See gtk_tool_button_set_use_underline().
782  * 
783  * Return value: %TRUE if underscores in the label property are used as
784  * mnemonics on menu items on the overflow menu.
785  * 
786  * Since: 2.4
787  **/
788 gboolean
789 gtk_tool_button_get_use_underline (GtkToolButton *button)
790 {
791   g_return_val_if_fail (GTK_IS_TOOL_BUTTON (button), FALSE);
792
793   return button->priv->use_underline;
794 }
795
796 /**
797  * gtk_tool_button_set_stock_id:
798  * @button: a #GtkToolButton
799  * @stock_id: a name of a stock item, or %NULL
800  * 
801  * Sets the name of the stock item. See gtk_tool_button_new_from_stock().
802  * The stock_id property only has an effect if not
803  * overridden by non-%NULL "label" and "icon_widget" properties.
804  * 
805  * Since: 2.4
806  **/
807 void
808 gtk_tool_button_set_stock_id (GtkToolButton *button,
809                               const gchar   *stock_id)
810 {
811   gchar *old_stock_id;
812   
813   g_return_if_fail (GTK_IS_TOOL_BUTTON (button));
814
815   old_stock_id = button->priv->stock_id;
816
817   button->priv->stock_id = g_strdup (stock_id);
818   gtk_tool_button_construct_contents (GTK_TOOL_ITEM (button));
819   
820   g_object_notify (G_OBJECT (button), "stock-id");
821
822   g_free (old_stock_id);
823 }
824
825 /**
826  * gtk_tool_button_get_stock_id:
827  * @button: a #GtkToolButton
828  * 
829  * Returns the name of the stock item. See gtk_tool_button_set_stock_id().
830  * The returned string is owned by GTK+ and must not be freed or modifed.
831  * 
832  * Return value: the name of the stock item for @button.
833  * 
834  * Since: 2.4
835  **/
836 G_CONST_RETURN gchar *
837 gtk_tool_button_get_stock_id (GtkToolButton *button)
838 {
839   g_return_val_if_fail (GTK_IS_TOOL_BUTTON (button), NULL);
840
841   return button->priv->stock_id;
842 }
843
844 /**
845  * gtk_tool_button_set_icon_name
846  * @button: a #GtkToolButton
847  * @icon_name: the name of the themed icon
848  * 
849  * Sets the icon for the tool button from a named themed icon.
850  * See the docs for #GtkIconTheme for more details.
851  * The "icon_name" property only has an effect if not
852  * overridden by non-%NULL "label", "icon_widget" and "stock_id"
853  * properties.
854  * 
855  * Since: 2.8
856  **/
857 void
858 gtk_tool_button_set_icon_name (GtkToolButton *button,
859                                const gchar   *icon_name)
860 {
861   gchar *old_icon_name;
862
863   g_return_if_fail (GTK_IS_TOOL_BUTTON (button));
864
865   old_icon_name = button->priv->icon_name;
866
867   button->priv->icon_name = g_strdup (icon_name);
868   gtk_tool_button_construct_contents (GTK_TOOL_ITEM (button));
869
870   g_object_notify (G_OBJECT (button), "icon-name");
871
872   g_free (old_icon_name);
873 }
874
875 /**
876  * gtk_tool_button_get_icon_name
877  * @button: a #GtkToolButton
878  * 
879  * Returns the name of the themed icon for the tool button,
880  * see gtk_tool_button_set_icon_name().
881  *
882  * Returns: the icon name or %NULL if the tool button has
883  * no themed icon
884  * 
885  * Since: 2.8
886  **/
887 G_CONST_RETURN gchar*
888 gtk_tool_button_get_icon_name (GtkToolButton *button)
889 {
890   g_return_val_if_fail (GTK_IS_TOOL_BUTTON (button), NULL);
891
892   return button->priv->icon_name;
893 }
894
895 /**
896  * gtk_tool_button_set_icon_widget:
897  * @button: a #GtkToolButton
898  * @icon_widget: the widget used as icon, or %NULL
899  * 
900  * Sets @icon as the widget used as icon on @button. If @icon_widget is
901  * %NULL the icon is determined by the "stock_id" property. If the
902  * "stock_id" property is also %NULL, @button will not have an icon.
903  * 
904  * Since: 2.4
905  **/
906 void
907 gtk_tool_button_set_icon_widget (GtkToolButton *button,
908                                  GtkWidget     *icon_widget)
909 {
910   g_return_if_fail (GTK_IS_TOOL_BUTTON (button));
911   g_return_if_fail (icon_widget == NULL || GTK_IS_WIDGET (icon_widget));
912
913   if (icon_widget != button->priv->icon_widget)
914     {
915       if (button->priv->icon_widget)
916         {
917           if (button->priv->icon_widget->parent)
918             {
919               gtk_container_remove (GTK_CONTAINER (button->priv->icon_widget->parent),
920                                     button->priv->icon_widget);
921             }
922
923           g_object_unref (button->priv->icon_widget);
924         }
925       
926       if (icon_widget)
927         {
928           g_object_ref (icon_widget);
929           gtk_object_sink (GTK_OBJECT (icon_widget));
930         }
931
932       button->priv->icon_widget = icon_widget;
933
934       gtk_tool_button_construct_contents (GTK_TOOL_ITEM (button));
935       
936       g_object_notify (G_OBJECT (button), "icon-widget");
937     }
938 }
939
940 /**
941  * gtk_tool_button_set_label_widget:
942  * @button: a #GtkToolButton
943  * @label_widget: the widget used as label, or %NULL
944  * 
945  * Sets @label_widget as the widget that will be used as the label
946  * for @button. If @label_widget is %NULL the "label" property is used
947  * as label. If "label" is also %NULL, the label in the stock item
948  * determined by the "stock_id" property is used as label. If
949  * "stock_id" is also %NULL, @button does not have a label.
950  * 
951  * Since: 2.4
952  **/
953 void
954 gtk_tool_button_set_label_widget (GtkToolButton *button,
955                                   GtkWidget     *label_widget)
956 {
957   g_return_if_fail (GTK_IS_TOOL_BUTTON (button));
958   g_return_if_fail (label_widget == NULL || GTK_IS_WIDGET (label_widget));
959
960   if (label_widget != button->priv->label_widget)
961     {
962       if (button->priv->label_widget)
963         {
964           if (button->priv->label_widget->parent)
965             {
966               gtk_container_remove (GTK_CONTAINER (button->priv->label_widget->parent),
967                                     button->priv->label_widget);
968             }
969           
970           g_object_unref (button->priv->label_widget);
971         }
972       
973       if (label_widget)
974         {
975           g_object_ref (label_widget);
976           gtk_object_sink (GTK_OBJECT (label_widget));
977         }
978
979       button->priv->label_widget = label_widget;
980
981       gtk_tool_button_construct_contents (GTK_TOOL_ITEM (button));
982       
983       g_object_notify (G_OBJECT (button), "label-widget");
984     }
985 }
986
987 /**
988  * gtk_tool_button_get_label_widget:
989  * @button: a #GtkToolButton
990  * 
991  * Returns the widget used as label on @button. See
992  * gtk_tool_button_set_label_widget().
993  * 
994  * Return value: The widget used as label on @button, or %NULL.
995  * 
996  * Since: 2.4
997  **/
998 GtkWidget *
999 gtk_tool_button_get_label_widget (GtkToolButton *button)
1000 {
1001   g_return_val_if_fail (GTK_IS_TOOL_BUTTON (button), NULL);
1002
1003   return button->priv->label_widget;
1004 }
1005
1006 /**
1007  * gtk_tool_button_get_icon_widget:
1008  * @button: a #GtkToolButton
1009  * 
1010  * Return the widget used as icon widget on @button. See
1011  * gtk_tool_button_set_icon_widget().
1012  * 
1013  * Return value: The widget used as icon on @button, or %NULL.
1014  * 
1015  * Since: 2.4
1016  **/
1017 GtkWidget *
1018 gtk_tool_button_get_icon_widget (GtkToolButton *button)
1019 {
1020   g_return_val_if_fail (GTK_IS_TOOL_BUTTON (button), NULL);
1021
1022   return button->priv->icon_widget;
1023 }
1024
1025 GtkWidget *
1026 _gtk_tool_button_get_button (GtkToolButton *button)
1027 {
1028   g_return_val_if_fail (GTK_IS_TOOL_BUTTON (button), NULL);
1029
1030   return button->priv->button;
1031 }
1032
1033 #define __GTK_TOOL_BUTTON_C__
1034 #include "gtkaliasdef.c"