]> Pileus Git - ~andy/gtk/blob - gtk/gtktoolitem.c
stylecontext: Do invalidation on first resize container
[~andy/gtk] / gtk / gtktoolitem.c
1 /* gtktoolitem.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, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include "config.h"
22
23 #include "gtktoolitem.h"
24
25 #include <string.h>
26
27 #include "gtkmarshalers.h"
28 #include "gtktoolshell.h"
29 #include "gtkseparatormenuitem.h"
30 #include "gtksizerequest.h"
31 #include "gtkactivatable.h"
32 #include "gtkintl.h"
33 #include "gtkprivate.h"
34
35
36 /**
37  * SECTION:gtktoolitem
38  * @short_description: The base class of widgets that can be added to GtkToolShell
39  * @Title: GtkToolItem
40  * @see_also: <variablelist>
41  *   <varlistentry>
42  *     <term>#GtkToolbar</term>
43  *     <listitem><para>The toolbar widget</para></listitem>
44  *   </varlistentry>
45  *   <varlistentry>
46  *     <term>#GtkToolButton</term>
47  *     <listitem><para>A subclass of #GtkToolItem that displays buttons on
48  *         the toolbar</para></listitem>
49  *   </varlistentry>
50  *   <varlistentry>
51  *     <term>#GtkSeparatorToolItem</term>
52  *     <listitem><para>A subclass of #GtkToolItem that separates groups of
53  *         items on a toolbar</para></listitem>
54  *   </varlistentry>
55  * </variablelist>
56  *
57  * #GtkToolItem<!-- -->s are widgets that can appear on a toolbar. To
58  * create a toolbar item that contain something else than a button, use
59  * gtk_tool_item_new(). Use gtk_container_add() to add a child
60  * widget to the tool item.
61  *
62  * For toolbar items that contain buttons, see the #GtkToolButton,
63  * #GtkToggleToolButton and #GtkRadioToolButton classes.
64  *
65  * See the #GtkToolbar class for a description of the toolbar widget, and
66  * #GtkToolShell for a description of the tool shell interface.
67  */
68
69 /**
70  * GtkToolItem:
71  *
72  * The GtkToolItem struct contains only private data.
73  * It should only be accessed through the functions described below.
74  */
75
76 enum {
77   CREATE_MENU_PROXY,
78   TOOLBAR_RECONFIGURED,
79   LAST_SIGNAL
80 };
81
82 enum {
83   PROP_0,
84   PROP_VISIBLE_HORIZONTAL,
85   PROP_VISIBLE_VERTICAL,
86   PROP_IS_IMPORTANT,
87
88   /* activatable properties */
89   PROP_ACTIVATABLE_RELATED_ACTION,
90   PROP_ACTIVATABLE_USE_ACTION_APPEARANCE
91 };
92
93
94 struct _GtkToolItemPrivate
95 {
96   gchar *tip_text;
97   gchar *tip_private;
98
99   guint visible_horizontal    : 1;
100   guint visible_vertical      : 1;
101   guint homogeneous           : 1;
102   guint expand                : 1;
103   guint use_drag_window       : 1;
104   guint is_important          : 1;
105   guint use_action_appearance : 1;
106
107   GdkWindow *drag_window;
108   gchar *menu_item_id;
109   GtkWidget *menu_item;
110
111   GtkAction *action;
112 };
113
114 static void gtk_tool_item_finalize     (GObject         *object);
115 static void gtk_tool_item_dispose      (GObject         *object);
116 static void gtk_tool_item_parent_set   (GtkWidget       *toolitem,
117                                         GtkWidget       *parent);
118 static void gtk_tool_item_set_property (GObject         *object,
119                                         guint            prop_id,
120                                         const GValue    *value,
121                                         GParamSpec      *pspec);
122 static void gtk_tool_item_get_property (GObject         *object,
123                                         guint            prop_id,
124                                         GValue          *value,
125                                         GParamSpec      *pspec);
126 static void gtk_tool_item_property_notify (GObject      *object,
127                                            GParamSpec   *pspec);
128 static void gtk_tool_item_realize       (GtkWidget      *widget);
129 static void gtk_tool_item_unrealize     (GtkWidget      *widget);
130 static void gtk_tool_item_map           (GtkWidget      *widget);
131 static void gtk_tool_item_unmap         (GtkWidget      *widget);
132 static void gtk_tool_item_get_preferred_width
133                                         (GtkWidget      *widget,
134                                          gint           *minimum,
135                                          gint           *natural);
136 static void gtk_tool_item_get_preferred_height
137                                         (GtkWidget      *widget,
138                                          gint           *minimum,
139                                          gint           *natural);
140 static void gtk_tool_item_size_allocate (GtkWidget      *widget,
141                                          GtkAllocation  *allocation);
142
143 static void gtk_tool_item_activatable_interface_init (GtkActivatableIface  *iface);
144 static void gtk_tool_item_update                     (GtkActivatable       *activatable,
145                                                       GtkAction            *action,
146                                                       const gchar          *property_name);
147 static void gtk_tool_item_sync_action_properties     (GtkActivatable       *activatable,
148                                                       GtkAction            *action);
149 static void gtk_tool_item_set_related_action         (GtkToolItem          *item, 
150                                                       GtkAction            *action);
151 static void gtk_tool_item_set_use_action_appearance  (GtkToolItem          *item, 
152                                                       gboolean              use_appearance);
153
154 static guint toolitem_signals[LAST_SIGNAL] = { 0 };
155
156 G_DEFINE_TYPE_WITH_CODE (GtkToolItem, gtk_tool_item, GTK_TYPE_BIN,
157                          G_IMPLEMENT_INTERFACE (GTK_TYPE_ACTIVATABLE,
158                                                 gtk_tool_item_activatable_interface_init))
159
160 static void
161 gtk_tool_item_class_init (GtkToolItemClass *klass)
162 {
163   GObjectClass *object_class;
164   GtkWidgetClass *widget_class;
165   
166   object_class = (GObjectClass *)klass;
167   widget_class = (GtkWidgetClass *)klass;
168
169   object_class->set_property = gtk_tool_item_set_property;
170   object_class->get_property = gtk_tool_item_get_property;
171   object_class->finalize     = gtk_tool_item_finalize;
172   object_class->dispose      = gtk_tool_item_dispose;
173   object_class->notify       = gtk_tool_item_property_notify;
174
175   widget_class->realize       = gtk_tool_item_realize;
176   widget_class->unrealize     = gtk_tool_item_unrealize;
177   widget_class->map           = gtk_tool_item_map;
178   widget_class->unmap         = gtk_tool_item_unmap;
179   widget_class->get_preferred_width = gtk_tool_item_get_preferred_width;
180   widget_class->get_preferred_height = gtk_tool_item_get_preferred_height;
181   widget_class->size_allocate = gtk_tool_item_size_allocate;
182   widget_class->parent_set    = gtk_tool_item_parent_set;
183
184   gtk_container_class_handle_border_width (GTK_CONTAINER_CLASS (klass));
185
186   klass->create_menu_proxy = _gtk_tool_item_create_menu_proxy;
187   
188   g_object_class_install_property (object_class,
189                                    PROP_VISIBLE_HORIZONTAL,
190                                    g_param_spec_boolean ("visible-horizontal",
191                                                          P_("Visible when horizontal"),
192                                                          P_("Whether the toolbar item is visible when the toolbar is in a horizontal orientation."),
193                                                          TRUE,
194                                                          GTK_PARAM_READWRITE));
195   g_object_class_install_property (object_class,
196                                    PROP_VISIBLE_VERTICAL,
197                                    g_param_spec_boolean ("visible-vertical",
198                                                          P_("Visible when vertical"),
199                                                          P_("Whether the toolbar item is visible when the toolbar is in a vertical orientation."),
200                                                          TRUE,
201                                                          GTK_PARAM_READWRITE));
202   g_object_class_install_property (object_class,
203                                    PROP_IS_IMPORTANT,
204                                    g_param_spec_boolean ("is-important",
205                                                          P_("Is important"),
206                                                          P_("Whether the toolbar item is considered important. When TRUE, toolbar buttons show text in GTK_TOOLBAR_BOTH_HORIZ mode"),
207                                                          FALSE,
208                                                          GTK_PARAM_READWRITE));
209
210   g_object_class_override_property (object_class, PROP_ACTIVATABLE_RELATED_ACTION, "related-action");
211   g_object_class_override_property (object_class, PROP_ACTIVATABLE_USE_ACTION_APPEARANCE, "use-action-appearance");
212
213
214 /**
215  * GtkToolItem::create-menu-proxy:
216  * @tool_item: the object the signal was emitted on
217  *
218  * This signal is emitted when the toolbar needs information from @tool_item
219  * about whether the item should appear in the toolbar overflow menu. In
220  * response the tool item should either
221  * <itemizedlist>
222  * <listitem>call gtk_tool_item_set_proxy_menu_item() with a %NULL
223  * pointer and return %TRUE to indicate that the item should not appear
224  * in the overflow menu
225  * </listitem>
226  * <listitem> call gtk_tool_item_set_proxy_menu_item() with a new menu
227  * item and return %TRUE, or 
228  * </listitem>
229  * <listitem> return %FALSE to indicate that the signal was not
230  * handled by the item. This means that
231  * the item will not appear in the overflow menu unless a later handler
232  * installs a menu item.
233  * </listitem>
234  * </itemizedlist>
235  *
236  * The toolbar may cache the result of this signal. When the tool item changes
237  * how it will respond to this signal it must call gtk_tool_item_rebuild_menu()
238  * to invalidate the cache and ensure that the toolbar rebuilds its overflow
239  * menu.
240  *
241  * Return value: %TRUE if the signal was handled, %FALSE if not
242  **/
243   toolitem_signals[CREATE_MENU_PROXY] =
244     g_signal_new (I_("create-menu-proxy"),
245                   G_OBJECT_CLASS_TYPE (klass),
246                   G_SIGNAL_RUN_LAST,
247                   G_STRUCT_OFFSET (GtkToolItemClass, create_menu_proxy),
248                   _gtk_boolean_handled_accumulator, NULL,
249                   _gtk_marshal_BOOLEAN__VOID,
250                   G_TYPE_BOOLEAN, 0);
251
252 /**
253  * GtkToolItem::toolbar-reconfigured:
254  * @tool_item: the object the signal was emitted on
255  *
256  * This signal is emitted when some property of the toolbar that the
257  * item is a child of changes. For custom subclasses of #GtkToolItem,
258  * the default handler of this signal use the functions
259  * <itemizedlist>
260  * <listitem>gtk_tool_shell_get_orientation()</listitem>
261  * <listitem>gtk_tool_shell_get_style()</listitem>
262  * <listitem>gtk_tool_shell_get_icon_size()</listitem>
263  * <listitem>gtk_tool_shell_get_relief_style()</listitem>
264  * </itemizedlist>
265  * to find out what the toolbar should look like and change
266  * themselves accordingly.
267  **/
268   toolitem_signals[TOOLBAR_RECONFIGURED] =
269     g_signal_new (I_("toolbar-reconfigured"),
270                   G_OBJECT_CLASS_TYPE (klass),
271                   G_SIGNAL_RUN_LAST,
272                   G_STRUCT_OFFSET (GtkToolItemClass, toolbar_reconfigured),
273                   NULL, NULL,
274                   _gtk_marshal_VOID__VOID,
275                   G_TYPE_NONE, 0);
276
277   g_type_class_add_private (object_class, sizeof (GtkToolItemPrivate));
278 }
279
280 static void
281 gtk_tool_item_init (GtkToolItem *toolitem)
282 {
283   gtk_widget_set_can_focus (GTK_WIDGET (toolitem), FALSE);
284
285   toolitem->priv = G_TYPE_INSTANCE_GET_PRIVATE (toolitem,
286                                                 GTK_TYPE_TOOL_ITEM,
287                                                 GtkToolItemPrivate);
288
289   toolitem->priv->visible_horizontal = TRUE;
290   toolitem->priv->visible_vertical = TRUE;
291   toolitem->priv->homogeneous = FALSE;
292   toolitem->priv->expand = FALSE;
293
294   toolitem->priv->use_action_appearance = TRUE;
295 }
296
297 static void
298 gtk_tool_item_finalize (GObject *object)
299 {
300   GtkToolItem *item = GTK_TOOL_ITEM (object);
301
302   g_free (item->priv->menu_item_id);
303
304   if (item->priv->menu_item)
305     g_object_unref (item->priv->menu_item);
306
307   G_OBJECT_CLASS (gtk_tool_item_parent_class)->finalize (object);
308 }
309
310 static void
311 gtk_tool_item_dispose (GObject *object)
312 {
313   GtkToolItem *item = GTK_TOOL_ITEM (object);
314
315   if (item->priv->action)
316     {
317       gtk_activatable_do_set_related_action (GTK_ACTIVATABLE (item), NULL);      
318       item->priv->action = NULL;
319     }
320   G_OBJECT_CLASS (gtk_tool_item_parent_class)->dispose (object);
321 }
322
323
324 static void
325 gtk_tool_item_parent_set (GtkWidget   *toolitem,
326                           GtkWidget   *prev_parent)
327 {
328   if (gtk_widget_get_parent (GTK_WIDGET (toolitem)) != NULL)
329     gtk_tool_item_toolbar_reconfigured (GTK_TOOL_ITEM (toolitem));
330 }
331
332 static void
333 gtk_tool_item_set_property (GObject      *object,
334                             guint         prop_id,
335                             const GValue *value,
336                             GParamSpec   *pspec)
337 {
338   GtkToolItem *toolitem = GTK_TOOL_ITEM (object);
339
340   switch (prop_id)
341     {
342     case PROP_VISIBLE_HORIZONTAL:
343       gtk_tool_item_set_visible_horizontal (toolitem, g_value_get_boolean (value));
344       break;
345     case PROP_VISIBLE_VERTICAL:
346       gtk_tool_item_set_visible_vertical (toolitem, g_value_get_boolean (value));
347       break;
348     case PROP_IS_IMPORTANT:
349       gtk_tool_item_set_is_important (toolitem, g_value_get_boolean (value));
350       break;
351     case PROP_ACTIVATABLE_RELATED_ACTION:
352       gtk_tool_item_set_related_action (toolitem, g_value_get_object (value));
353       break;
354     case PROP_ACTIVATABLE_USE_ACTION_APPEARANCE:
355       gtk_tool_item_set_use_action_appearance (toolitem, g_value_get_boolean (value));
356       break;
357     default:
358       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
359       break;
360     }
361 }
362
363 static void
364 gtk_tool_item_get_property (GObject    *object,
365                             guint       prop_id,
366                             GValue     *value,
367                             GParamSpec *pspec)
368 {
369   GtkToolItem *toolitem = GTK_TOOL_ITEM (object);
370
371   switch (prop_id)
372     {
373     case PROP_VISIBLE_HORIZONTAL:
374       g_value_set_boolean (value, toolitem->priv->visible_horizontal);
375       break;
376     case PROP_VISIBLE_VERTICAL:
377       g_value_set_boolean (value, toolitem->priv->visible_vertical);
378       break;
379     case PROP_IS_IMPORTANT:
380       g_value_set_boolean (value, toolitem->priv->is_important);
381       break;
382     case PROP_ACTIVATABLE_RELATED_ACTION:
383       g_value_set_object (value, toolitem->priv->action);
384       break;
385     case PROP_ACTIVATABLE_USE_ACTION_APPEARANCE:
386       g_value_set_boolean (value, toolitem->priv->use_action_appearance);
387       break;
388     default:
389       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
390       break;
391     }
392 }
393
394 static void
395 gtk_tool_item_property_notify (GObject    *object,
396                                GParamSpec *pspec)
397 {
398   GtkToolItem *tool_item = GTK_TOOL_ITEM (object);
399
400   if (tool_item->priv->menu_item && strcmp (pspec->name, "sensitive") == 0)
401     gtk_widget_set_sensitive (tool_item->priv->menu_item,
402                               gtk_widget_get_sensitive (GTK_WIDGET (tool_item)));
403
404   if (G_OBJECT_CLASS (gtk_tool_item_parent_class)->notify)
405     G_OBJECT_CLASS (gtk_tool_item_parent_class)->notify (object, pspec);
406 }
407
408 static void
409 create_drag_window (GtkToolItem *toolitem)
410 {
411   GtkAllocation allocation;
412   GtkWidget *widget;
413   GdkWindowAttr attributes;
414   gint attributes_mask;
415
416   g_return_if_fail (toolitem->priv->use_drag_window == TRUE);
417
418   widget = GTK_WIDGET (toolitem);
419
420   gtk_widget_get_allocation (widget, &allocation);
421
422   attributes.window_type = GDK_WINDOW_CHILD;
423   attributes.x = allocation.x;
424   attributes.y = allocation.y;
425   attributes.width = allocation.width;
426   attributes.height = allocation.height;
427   attributes.wclass = GDK_INPUT_ONLY;
428   attributes.event_mask = gtk_widget_get_events (widget);
429   attributes.event_mask |= (GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
430
431   attributes_mask = GDK_WA_X | GDK_WA_Y;
432
433   toolitem->priv->drag_window = gdk_window_new (gtk_widget_get_parent_window (widget),
434                                           &attributes, attributes_mask);
435   gtk_widget_register_window (widget, toolitem->priv->drag_window);
436 }
437
438 static void
439 gtk_tool_item_realize (GtkWidget *widget)
440 {
441   GtkToolItem *toolitem;
442   GdkWindow *window;
443
444   toolitem = GTK_TOOL_ITEM (widget);
445   gtk_widget_set_realized (widget, TRUE);
446
447   window = gtk_widget_get_parent_window (widget);
448   gtk_widget_set_window (widget, window);
449   g_object_ref (window);
450
451   if (toolitem->priv->use_drag_window)
452     create_drag_window(toolitem);
453 }
454
455 static void
456 destroy_drag_window (GtkToolItem *toolitem)
457 {
458   if (toolitem->priv->drag_window)
459     {
460       gtk_widget_unregister_window (GTK_WIDGET (toolitem), toolitem->priv->drag_window);
461       gdk_window_destroy (toolitem->priv->drag_window);
462       toolitem->priv->drag_window = NULL;
463     }
464 }
465
466 static void
467 gtk_tool_item_unrealize (GtkWidget *widget)
468 {
469   GtkToolItem *toolitem;
470
471   toolitem = GTK_TOOL_ITEM (widget);
472
473   destroy_drag_window (toolitem);
474   
475   GTK_WIDGET_CLASS (gtk_tool_item_parent_class)->unrealize (widget);
476 }
477
478 static void
479 gtk_tool_item_map (GtkWidget *widget)
480 {
481   GtkToolItem *toolitem;
482
483   toolitem = GTK_TOOL_ITEM (widget);
484   GTK_WIDGET_CLASS (gtk_tool_item_parent_class)->map (widget);
485   if (toolitem->priv->drag_window)
486     gdk_window_show (toolitem->priv->drag_window);
487 }
488
489 static void
490 gtk_tool_item_unmap (GtkWidget *widget)
491 {
492   GtkToolItem *toolitem;
493
494   toolitem = GTK_TOOL_ITEM (widget);
495   if (toolitem->priv->drag_window)
496     gdk_window_hide (toolitem->priv->drag_window);
497   GTK_WIDGET_CLASS (gtk_tool_item_parent_class)->unmap (widget);
498 }
499
500 static void
501 gtk_tool_item_get_preferred_width (GtkWidget *widget,
502                                    gint      *minimum,
503                                    gint      *natural)
504 {
505   GtkWidget *child;
506
507   *minimum = *natural = 0;
508
509   child = gtk_bin_get_child (GTK_BIN (widget));
510   if (child && gtk_widget_get_visible (child))
511     gtk_widget_get_preferred_width (child, minimum, natural);
512 }
513
514 static void
515 gtk_tool_item_get_preferred_height (GtkWidget *widget,
516                                     gint      *minimum,
517                                     gint      *natural)
518 {
519   GtkWidget *child;
520
521   *minimum = *natural = 0;
522
523   child = gtk_bin_get_child (GTK_BIN (widget));
524   if (child && gtk_widget_get_visible (child))
525     gtk_widget_get_preferred_height (child, minimum, natural);
526 }
527
528 static void
529 gtk_tool_item_size_allocate (GtkWidget     *widget,
530                              GtkAllocation *allocation)
531 {
532   GtkToolItem *toolitem = GTK_TOOL_ITEM (widget);
533   GtkAllocation child_allocation;
534   GtkWidget *child;
535
536   gtk_widget_set_allocation (widget, allocation);
537
538   if (toolitem->priv->drag_window)
539     gdk_window_move_resize (toolitem->priv->drag_window,
540                             allocation->x,
541                             allocation->y,
542                             allocation->width,
543                             allocation->height);
544
545   child = gtk_bin_get_child (GTK_BIN (widget));
546   if (child && gtk_widget_get_visible (child))
547     {
548       child_allocation.x = allocation->x;
549       child_allocation.y = allocation->y;
550       child_allocation.width = allocation->width;
551       child_allocation.height = allocation->height;
552       
553       gtk_widget_size_allocate (child, &child_allocation);
554     }
555 }
556
557 gboolean
558 _gtk_tool_item_create_menu_proxy (GtkToolItem *item)
559 {
560   GtkWidget *menu_item;
561   gboolean visible_overflown;
562
563   if (item->priv->action)
564     {
565       g_object_get (item->priv->action, "visible-overflown", &visible_overflown, NULL);
566     
567       if (visible_overflown)
568         {
569           menu_item = gtk_action_create_menu_item (item->priv->action);
570
571           g_object_ref_sink (menu_item);
572           gtk_tool_item_set_proxy_menu_item (item, "gtk-action-menu-item", menu_item);
573           g_object_unref (menu_item);
574         }
575       else
576         gtk_tool_item_set_proxy_menu_item (item, "gtk-action-menu-item", NULL);
577
578       return TRUE;
579     }
580
581   return FALSE;
582 }
583
584 static void
585 gtk_tool_item_activatable_interface_init (GtkActivatableIface *iface)
586 {
587   iface->update = gtk_tool_item_update;
588   iface->sync_action_properties = gtk_tool_item_sync_action_properties;
589 }
590
591 static void
592 gtk_tool_item_update (GtkActivatable *activatable,
593                       GtkAction      *action,
594                       const gchar    *property_name)
595 {
596   if (strcmp (property_name, "visible") == 0)
597     {
598       if (gtk_action_is_visible (action))
599         gtk_widget_show (GTK_WIDGET (activatable));
600       else
601         gtk_widget_hide (GTK_WIDGET (activatable));
602     }
603   else if (strcmp (property_name, "sensitive") == 0)
604     gtk_widget_set_sensitive (GTK_WIDGET (activatable), gtk_action_is_sensitive (action));
605   else if (strcmp (property_name, "tooltip") == 0)
606     gtk_tool_item_set_tooltip_text (GTK_TOOL_ITEM (activatable),
607                                     gtk_action_get_tooltip (action));
608   else if (strcmp (property_name, "visible-horizontal") == 0)
609     gtk_tool_item_set_visible_horizontal (GTK_TOOL_ITEM (activatable),
610                                           gtk_action_get_visible_horizontal (action));
611   else if (strcmp (property_name, "visible-vertical") == 0)
612     gtk_tool_item_set_visible_vertical (GTK_TOOL_ITEM (activatable),
613                                         gtk_action_get_visible_vertical (action));
614   else if (strcmp (property_name, "is-important") == 0)
615     gtk_tool_item_set_is_important (GTK_TOOL_ITEM (activatable),
616                                     gtk_action_get_is_important (action));
617 }
618
619 static void
620 gtk_tool_item_sync_action_properties (GtkActivatable *activatable,
621                                       GtkAction      *action)
622 {
623   if (!action)
624     return;
625
626   if (gtk_action_is_visible (action))
627     gtk_widget_show (GTK_WIDGET (activatable));
628   else
629     gtk_widget_hide (GTK_WIDGET (activatable));
630   
631   gtk_widget_set_sensitive (GTK_WIDGET (activatable), gtk_action_is_sensitive (action));
632   
633   gtk_tool_item_set_tooltip_text (GTK_TOOL_ITEM (activatable),
634                                   gtk_action_get_tooltip (action));
635   gtk_tool_item_set_visible_horizontal (GTK_TOOL_ITEM (activatable),
636                                         gtk_action_get_visible_horizontal (action));
637   gtk_tool_item_set_visible_vertical (GTK_TOOL_ITEM (activatable),
638                                       gtk_action_get_visible_vertical (action));
639   gtk_tool_item_set_is_important (GTK_TOOL_ITEM (activatable),
640                                   gtk_action_get_is_important (action));
641 }
642
643 static void
644 gtk_tool_item_set_related_action (GtkToolItem *item, 
645                                   GtkAction   *action)
646 {
647   if (item->priv->action == action)
648     return;
649
650   gtk_activatable_do_set_related_action (GTK_ACTIVATABLE (item), action);
651
652   item->priv->action = action;
653
654   if (action)
655     {
656       gtk_tool_item_rebuild_menu (item);
657     }
658 }
659
660 static void
661 gtk_tool_item_set_use_action_appearance (GtkToolItem *item,
662                                          gboolean     use_appearance)
663 {
664   if (item->priv->use_action_appearance != use_appearance)
665     {
666       item->priv->use_action_appearance = use_appearance;
667
668       gtk_activatable_sync_action_properties (GTK_ACTIVATABLE (item), item->priv->action);
669     }
670 }
671
672
673 /**
674  * gtk_tool_item_new:
675  * 
676  * Creates a new #GtkToolItem
677  * 
678  * Return value: the new #GtkToolItem
679  * 
680  * Since: 2.4
681  **/
682 GtkToolItem *
683 gtk_tool_item_new (void)
684 {
685   GtkToolItem *item;
686
687   item = g_object_new (GTK_TYPE_TOOL_ITEM, NULL);
688
689   return item;
690 }
691
692 /**
693  * gtk_tool_item_get_ellipsize_mode:
694  * @tool_item: a #GtkToolItem
695  *
696  * Returns the ellipsize mode used for @tool_item. Custom subclasses of
697  * #GtkToolItem should call this function to find out how text should
698  * be ellipsized.
699  *
700  * Return value: a #PangoEllipsizeMode indicating how text in @tool_item
701  * should be ellipsized.
702  *
703  * Since: 2.20
704  **/
705 PangoEllipsizeMode
706 gtk_tool_item_get_ellipsize_mode (GtkToolItem *tool_item)
707 {
708   GtkWidget *parent;
709   
710   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), GTK_ORIENTATION_HORIZONTAL);
711
712   parent = gtk_widget_get_parent (GTK_WIDGET (tool_item));
713   if (!parent || !GTK_IS_TOOL_SHELL (parent))
714     return PANGO_ELLIPSIZE_NONE;
715
716   return gtk_tool_shell_get_ellipsize_mode (GTK_TOOL_SHELL (parent));
717 }
718
719 /**
720  * gtk_tool_item_get_icon_size:
721  * @tool_item: a #GtkToolItem
722  * 
723  * Returns the icon size used for @tool_item. Custom subclasses of
724  * #GtkToolItem should call this function to find out what size icons
725  * they should use.
726  * 
727  * Return value: (type int): a #GtkIconSize indicating the icon size
728  * used for @tool_item
729  * 
730  * Since: 2.4
731  **/
732 GtkIconSize
733 gtk_tool_item_get_icon_size (GtkToolItem *tool_item)
734 {
735   GtkWidget *parent;
736
737   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), GTK_ICON_SIZE_LARGE_TOOLBAR);
738
739   parent = gtk_widget_get_parent (GTK_WIDGET (tool_item));
740   if (!parent || !GTK_IS_TOOL_SHELL (parent))
741     return GTK_ICON_SIZE_LARGE_TOOLBAR;
742
743   return gtk_tool_shell_get_icon_size (GTK_TOOL_SHELL (parent));
744 }
745
746 /**
747  * gtk_tool_item_get_orientation:
748  * @tool_item: a #GtkToolItem 
749  * 
750  * Returns the orientation used for @tool_item. Custom subclasses of
751  * #GtkToolItem should call this function to find out what size icons
752  * they should use.
753  * 
754  * Return value: a #GtkOrientation indicating the orientation
755  * used for @tool_item
756  * 
757  * Since: 2.4
758  **/
759 GtkOrientation
760 gtk_tool_item_get_orientation (GtkToolItem *tool_item)
761 {
762   GtkWidget *parent;
763   
764   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), GTK_ORIENTATION_HORIZONTAL);
765
766   parent = gtk_widget_get_parent (GTK_WIDGET (tool_item));
767   if (!parent || !GTK_IS_TOOL_SHELL (parent))
768     return GTK_ORIENTATION_HORIZONTAL;
769
770   return gtk_tool_shell_get_orientation (GTK_TOOL_SHELL (parent));
771 }
772
773 /**
774  * gtk_tool_item_get_toolbar_style:
775  * @tool_item: a #GtkToolItem 
776  * 
777  * Returns the toolbar style used for @tool_item. Custom subclasses of
778  * #GtkToolItem should call this function in the handler of the
779  * GtkToolItem::toolbar_reconfigured signal to find out in what style
780  * the toolbar is displayed and change themselves accordingly 
781  *
782  * Possibilities are:
783  * <itemizedlist>
784  * <listitem> GTK_TOOLBAR_BOTH, meaning the tool item should show
785  * both an icon and a label, stacked vertically </listitem>
786  * <listitem> GTK_TOOLBAR_ICONS, meaning the toolbar shows
787  * only icons </listitem>
788  * <listitem> GTK_TOOLBAR_TEXT, meaning the tool item should only
789  * show text</listitem>
790  * <listitem> GTK_TOOLBAR_BOTH_HORIZ, meaning the tool item should show
791  * both an icon and a label, arranged horizontally</listitem>
792  * </itemizedlist>
793  * 
794  * Return value: A #GtkToolbarStyle indicating the toolbar style used
795  * for @tool_item.
796  * 
797  * Since: 2.4
798  **/
799 GtkToolbarStyle
800 gtk_tool_item_get_toolbar_style (GtkToolItem *tool_item)
801 {
802   GtkWidget *parent;
803   
804   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), GTK_TOOLBAR_ICONS);
805
806   parent = gtk_widget_get_parent (GTK_WIDGET (tool_item));
807   if (!parent || !GTK_IS_TOOL_SHELL (parent))
808     return GTK_TOOLBAR_ICONS;
809
810   return gtk_tool_shell_get_style (GTK_TOOL_SHELL (parent));
811 }
812
813 /**
814  * gtk_tool_item_get_relief_style:
815  * @tool_item: a #GtkToolItem 
816  * 
817  * Returns the relief style of @tool_item. See gtk_button_set_relief().
818  * Custom subclasses of #GtkToolItem should call this function in the handler
819  * of the #GtkToolItem::toolbar_reconfigured signal to find out the
820  * relief style of buttons.
821  * 
822  * Return value: a #GtkReliefStyle indicating the relief style used
823  * for @tool_item.
824  * 
825  * Since: 2.4
826  **/
827 GtkReliefStyle 
828 gtk_tool_item_get_relief_style (GtkToolItem *tool_item)
829 {
830   GtkWidget *parent;
831   
832   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), GTK_RELIEF_NONE);
833
834   parent = gtk_widget_get_parent (GTK_WIDGET (tool_item));
835   if (!parent || !GTK_IS_TOOL_SHELL (parent))
836     return GTK_RELIEF_NONE;
837
838   return gtk_tool_shell_get_relief_style (GTK_TOOL_SHELL (parent));
839 }
840
841 /**
842  * gtk_tool_item_get_text_alignment:
843  * @tool_item: a #GtkToolItem: 
844  * 
845  * Returns the text alignment used for @tool_item. Custom subclasses of
846  * #GtkToolItem should call this function to find out how text should
847  * be aligned.
848  * 
849  * Return value: a #gfloat indicating the horizontal text alignment
850  * used for @tool_item
851  * 
852  * Since: 2.20
853  **/
854 gfloat
855 gtk_tool_item_get_text_alignment (GtkToolItem *tool_item)
856 {
857   GtkWidget *parent;
858   
859   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), GTK_ORIENTATION_HORIZONTAL);
860
861   parent = gtk_widget_get_parent (GTK_WIDGET (tool_item));
862   if (!parent || !GTK_IS_TOOL_SHELL (parent))
863     return 0.5;
864
865   return gtk_tool_shell_get_text_alignment (GTK_TOOL_SHELL (parent));
866 }
867
868 /**
869  * gtk_tool_item_get_text_orientation:
870  * @tool_item: a #GtkToolItem
871  *
872  * Returns the text orientation used for @tool_item. Custom subclasses of
873  * #GtkToolItem should call this function to find out how text should
874  * be orientated.
875  *
876  * Return value: a #GtkOrientation indicating the text orientation
877  * used for @tool_item
878  *
879  * Since: 2.20
880  */
881 GtkOrientation
882 gtk_tool_item_get_text_orientation (GtkToolItem *tool_item)
883 {
884   GtkWidget *parent;
885   
886   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), GTK_ORIENTATION_HORIZONTAL);
887
888   parent = gtk_widget_get_parent (GTK_WIDGET (tool_item));
889   if (!parent || !GTK_IS_TOOL_SHELL (parent))
890     return GTK_ORIENTATION_HORIZONTAL;
891
892   return gtk_tool_shell_get_text_orientation (GTK_TOOL_SHELL (parent));
893 }
894
895 /**
896  * gtk_tool_item_get_text_size_group:
897  * @tool_item: a #GtkToolItem
898  *
899  * Returns the size group used for labels in @tool_item.
900  * Custom subclasses of #GtkToolItem should call this function
901  * and use the size group for labels.
902  *
903  * Return value: (transfer none): a #GtkSizeGroup
904  *
905  * Since: 2.20
906  */
907 GtkSizeGroup *
908 gtk_tool_item_get_text_size_group (GtkToolItem *tool_item)
909 {
910   GtkWidget *parent;
911   
912   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), NULL);
913
914   parent = gtk_widget_get_parent (GTK_WIDGET (tool_item));
915   if (!parent || !GTK_IS_TOOL_SHELL (parent))
916     return NULL;
917
918   return gtk_tool_shell_get_text_size_group (GTK_TOOL_SHELL (parent));
919 }
920
921 /**
922  * gtk_tool_item_set_expand:
923  * @tool_item: a #GtkToolItem
924  * @expand: Whether @tool_item is allocated extra space
925  *
926  * Sets whether @tool_item is allocated extra space when there
927  * is more room on the toolbar then needed for the items. The
928  * effect is that the item gets bigger when the toolbar gets bigger
929  * and smaller when the toolbar gets smaller.
930  *
931  * Since: 2.4
932  */
933 void
934 gtk_tool_item_set_expand (GtkToolItem *tool_item,
935                           gboolean     expand)
936 {
937   g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
938     
939   expand = expand != FALSE;
940
941   if (tool_item->priv->expand != expand)
942     {
943       tool_item->priv->expand = expand;
944       gtk_widget_child_notify (GTK_WIDGET (tool_item), "expand");
945       gtk_widget_queue_resize (GTK_WIDGET (tool_item));
946     }
947 }
948
949 /**
950  * gtk_tool_item_get_expand:
951  * @tool_item: a #GtkToolItem 
952  * 
953  * Returns whether @tool_item is allocated extra space.
954  * See gtk_tool_item_set_expand().
955  * 
956  * Return value: %TRUE if @tool_item is allocated extra space.
957  * 
958  * Since: 2.4
959  **/
960 gboolean
961 gtk_tool_item_get_expand (GtkToolItem *tool_item)
962 {
963   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), FALSE);
964
965   return tool_item->priv->expand;
966 }
967
968 /**
969  * gtk_tool_item_set_homogeneous:
970  * @tool_item: a #GtkToolItem 
971  * @homogeneous: whether @tool_item is the same size as other homogeneous items
972  * 
973  * Sets whether @tool_item is to be allocated the same size as other
974  * homogeneous items. The effect is that all homogeneous items will have
975  * the same width as the widest of the items.
976  * 
977  * Since: 2.4
978  **/
979 void
980 gtk_tool_item_set_homogeneous (GtkToolItem *tool_item,
981                                gboolean     homogeneous)
982 {
983   g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
984     
985   homogeneous = homogeneous != FALSE;
986
987   if (tool_item->priv->homogeneous != homogeneous)
988     {
989       tool_item->priv->homogeneous = homogeneous;
990       gtk_widget_child_notify (GTK_WIDGET (tool_item), "homogeneous");
991       gtk_widget_queue_resize (GTK_WIDGET (tool_item));
992     }
993 }
994
995 /**
996  * gtk_tool_item_get_homogeneous:
997  * @tool_item: a #GtkToolItem 
998  * 
999  * Returns whether @tool_item is the same size as other homogeneous
1000  * items. See gtk_tool_item_set_homogeneous().
1001  * 
1002  * Return value: %TRUE if the item is the same size as other homogeneous
1003  * items.
1004  * 
1005  * Since: 2.4
1006  **/
1007 gboolean
1008 gtk_tool_item_get_homogeneous (GtkToolItem *tool_item)
1009 {
1010   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), FALSE);
1011
1012   return tool_item->priv->homogeneous;
1013 }
1014
1015 /**
1016  * gtk_tool_item_get_is_important:
1017  * @tool_item: a #GtkToolItem
1018  * 
1019  * Returns whether @tool_item is considered important. See
1020  * gtk_tool_item_set_is_important()
1021  * 
1022  * Return value: %TRUE if @tool_item is considered important.
1023  * 
1024  * Since: 2.4
1025  **/
1026 gboolean
1027 gtk_tool_item_get_is_important (GtkToolItem *tool_item)
1028 {
1029   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), FALSE);
1030
1031   return tool_item->priv->is_important;
1032 }
1033
1034 /**
1035  * gtk_tool_item_set_is_important:
1036  * @tool_item: a #GtkToolItem
1037  * @is_important: whether the tool item should be considered important
1038  * 
1039  * Sets whether @tool_item should be considered important. The #GtkToolButton
1040  * class uses this property to determine whether to show or hide its label
1041  * when the toolbar style is %GTK_TOOLBAR_BOTH_HORIZ. The result is that
1042  * only tool buttons with the "is_important" property set have labels, an
1043  * effect known as "priority text"
1044  * 
1045  * Since: 2.4
1046  **/
1047 void
1048 gtk_tool_item_set_is_important (GtkToolItem *tool_item, gboolean is_important)
1049 {
1050   g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
1051
1052   is_important = is_important != FALSE;
1053
1054   if (is_important != tool_item->priv->is_important)
1055     {
1056       tool_item->priv->is_important = is_important;
1057
1058       gtk_widget_queue_resize (GTK_WIDGET (tool_item));
1059
1060       g_object_notify (G_OBJECT (tool_item), "is-important");
1061     }
1062 }
1063
1064 /**
1065  * gtk_tool_item_set_tooltip_text:
1066  * @tool_item: a #GtkToolItem 
1067  * @text: text to be used as tooltip for @tool_item
1068  *
1069  * Sets the text to be displayed as tooltip on the item.
1070  * See gtk_widget_set_tooltip_text().
1071  *
1072  * Since: 2.12
1073  **/
1074 void
1075 gtk_tool_item_set_tooltip_text (GtkToolItem *tool_item,
1076                                 const gchar *text)
1077 {
1078   GtkWidget *child;
1079
1080   g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
1081
1082   child = gtk_bin_get_child (GTK_BIN (tool_item));
1083   if (child)
1084     gtk_widget_set_tooltip_text (child, text);
1085 }
1086
1087 /**
1088  * gtk_tool_item_set_tooltip_markup:
1089  * @tool_item: a #GtkToolItem 
1090  * @markup: markup text to be used as tooltip for @tool_item
1091  *
1092  * Sets the markup text to be displayed as tooltip on the item.
1093  * See gtk_widget_set_tooltip_markup().
1094  *
1095  * Since: 2.12
1096  **/
1097 void
1098 gtk_tool_item_set_tooltip_markup (GtkToolItem *tool_item,
1099                                   const gchar *markup)
1100 {
1101   GtkWidget *child;
1102
1103   g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
1104
1105   child = gtk_bin_get_child (GTK_BIN (tool_item));
1106   if (child)
1107     gtk_widget_set_tooltip_markup (child, markup);
1108 }
1109
1110 /**
1111  * gtk_tool_item_set_use_drag_window:
1112  * @tool_item: a #GtkToolItem 
1113  * @use_drag_window: Whether @tool_item has a drag window.
1114  * 
1115  * Sets whether @tool_item has a drag window. When %TRUE the
1116  * toolitem can be used as a drag source through gtk_drag_source_set().
1117  * When @tool_item has a drag window it will intercept all events,
1118  * even those that would otherwise be sent to a child of @tool_item.
1119  * 
1120  * Since: 2.4
1121  **/
1122 void
1123 gtk_tool_item_set_use_drag_window (GtkToolItem *toolitem,
1124                                    gboolean     use_drag_window)
1125 {
1126   g_return_if_fail (GTK_IS_TOOL_ITEM (toolitem));
1127
1128   use_drag_window = use_drag_window != FALSE;
1129
1130   if (toolitem->priv->use_drag_window != use_drag_window)
1131     {
1132       toolitem->priv->use_drag_window = use_drag_window;
1133       
1134       if (use_drag_window)
1135         {
1136           if (!toolitem->priv->drag_window &&
1137               gtk_widget_get_realized (GTK_WIDGET (toolitem)))
1138             {
1139               create_drag_window(toolitem);
1140               if (gtk_widget_get_mapped (GTK_WIDGET (toolitem)))
1141                 gdk_window_show (toolitem->priv->drag_window);
1142             }
1143         }
1144       else
1145         {
1146           destroy_drag_window (toolitem);
1147         }
1148     }
1149 }
1150
1151 /**
1152  * gtk_tool_item_get_use_drag_window:
1153  * @tool_item: a #GtkToolItem 
1154  * 
1155  * Returns whether @tool_item has a drag window. See
1156  * gtk_tool_item_set_use_drag_window().
1157  * 
1158  * Return value: %TRUE if @tool_item uses a drag window.
1159  * 
1160  * Since: 2.4
1161  **/
1162 gboolean
1163 gtk_tool_item_get_use_drag_window (GtkToolItem *toolitem)
1164 {
1165   g_return_val_if_fail (GTK_IS_TOOL_ITEM (toolitem), FALSE);
1166
1167   return toolitem->priv->use_drag_window;
1168 }
1169
1170 /**
1171  * gtk_tool_item_set_visible_horizontal:
1172  * @tool_item: a #GtkToolItem
1173  * @visible_horizontal: Whether @tool_item is visible when in horizontal mode
1174  * 
1175  * Sets whether @tool_item is visible when the toolbar is docked horizontally.
1176  * 
1177  * Since: 2.4
1178  **/
1179 void
1180 gtk_tool_item_set_visible_horizontal (GtkToolItem *toolitem,
1181                                       gboolean     visible_horizontal)
1182 {
1183   g_return_if_fail (GTK_IS_TOOL_ITEM (toolitem));
1184
1185   visible_horizontal = visible_horizontal != FALSE;
1186
1187   if (toolitem->priv->visible_horizontal != visible_horizontal)
1188     {
1189       toolitem->priv->visible_horizontal = visible_horizontal;
1190
1191       g_object_notify (G_OBJECT (toolitem), "visible-horizontal");
1192
1193       gtk_widget_queue_resize (GTK_WIDGET (toolitem));
1194     }
1195 }
1196
1197 /**
1198  * gtk_tool_item_get_visible_horizontal:
1199  * @tool_item: a #GtkToolItem 
1200  * 
1201  * Returns whether the @tool_item is visible on toolbars that are
1202  * docked horizontally.
1203  * 
1204  * Return value: %TRUE if @tool_item is visible on toolbars that are
1205  * docked horizontally.
1206  * 
1207  * Since: 2.4
1208  **/
1209 gboolean
1210 gtk_tool_item_get_visible_horizontal (GtkToolItem *toolitem)
1211 {
1212   g_return_val_if_fail (GTK_IS_TOOL_ITEM (toolitem), FALSE);
1213
1214   return toolitem->priv->visible_horizontal;
1215 }
1216
1217 /**
1218  * gtk_tool_item_set_visible_vertical:
1219  * @tool_item: a #GtkToolItem 
1220  * @visible_vertical: whether @tool_item is visible when the toolbar
1221  * is in vertical mode
1222  *
1223  * Sets whether @tool_item is visible when the toolbar is docked
1224  * vertically. Some tool items, such as text entries, are too wide to be
1225  * useful on a vertically docked toolbar. If @visible_vertical is %FALSE
1226  * @tool_item will not appear on toolbars that are docked vertically.
1227  * 
1228  * Since: 2.4
1229  **/
1230 void
1231 gtk_tool_item_set_visible_vertical (GtkToolItem *toolitem,
1232                                     gboolean     visible_vertical)
1233 {
1234   g_return_if_fail (GTK_IS_TOOL_ITEM (toolitem));
1235
1236   visible_vertical = visible_vertical != FALSE;
1237
1238   if (toolitem->priv->visible_vertical != visible_vertical)
1239     {
1240       toolitem->priv->visible_vertical = visible_vertical;
1241
1242       g_object_notify (G_OBJECT (toolitem), "visible-vertical");
1243
1244       gtk_widget_queue_resize (GTK_WIDGET (toolitem));
1245     }
1246 }
1247
1248 /**
1249  * gtk_tool_item_get_visible_vertical:
1250  * @tool_item: a #GtkToolItem 
1251  * 
1252  * Returns whether @tool_item is visible when the toolbar is docked vertically.
1253  * See gtk_tool_item_set_visible_vertical().
1254  * 
1255  * Return value: Whether @tool_item is visible when the toolbar is docked vertically
1256  * 
1257  * Since: 2.4
1258  **/
1259 gboolean
1260 gtk_tool_item_get_visible_vertical (GtkToolItem *toolitem)
1261 {
1262   g_return_val_if_fail (GTK_IS_TOOL_ITEM (toolitem), FALSE);
1263
1264   return toolitem->priv->visible_vertical;
1265 }
1266
1267 /**
1268  * gtk_tool_item_retrieve_proxy_menu_item:
1269  * @tool_item: a #GtkToolItem 
1270  * 
1271  * Returns the #GtkMenuItem that was last set by
1272  * gtk_tool_item_set_proxy_menu_item(), ie. the #GtkMenuItem
1273  * that is going to appear in the overflow menu.
1274  *
1275  * Return value: (transfer none): The #GtkMenuItem that is going to appear in the
1276  * overflow menu for @tool_item.
1277  *
1278  * Since: 2.4
1279  **/
1280 GtkWidget *
1281 gtk_tool_item_retrieve_proxy_menu_item (GtkToolItem *tool_item)
1282 {
1283   gboolean retval;
1284   
1285   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), NULL);
1286
1287   g_signal_emit (tool_item, toolitem_signals[CREATE_MENU_PROXY], 0,
1288                  &retval);
1289   
1290   return tool_item->priv->menu_item;
1291 }
1292
1293 /**
1294  * gtk_tool_item_get_proxy_menu_item:
1295  * @tool_item: a #GtkToolItem
1296  * @menu_item_id: a string used to identify the menu item
1297  *
1298  * If @menu_item_id matches the string passed to
1299  * gtk_tool_item_set_proxy_menu_item() return the corresponding #GtkMenuItem.
1300  *
1301  * Custom subclasses of #GtkToolItem should use this function to
1302  * update their menu item when the #GtkToolItem changes. That the
1303  * @menu_item_id<!-- -->s must match ensures that a #GtkToolItem
1304  * will not inadvertently change a menu item that they did not create.
1305  *
1306  * Return value: (transfer none): The #GtkMenuItem passed to
1307  *     gtk_tool_item_set_proxy_menu_item(), if the @menu_item_id<!-- -->s
1308  *     match.
1309  *
1310  * Since: 2.4
1311  **/
1312 GtkWidget *
1313 gtk_tool_item_get_proxy_menu_item (GtkToolItem *tool_item,
1314                                    const gchar *menu_item_id)
1315 {
1316   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), NULL);
1317   g_return_val_if_fail (menu_item_id != NULL, NULL);
1318
1319   if (tool_item->priv->menu_item_id && strcmp (tool_item->priv->menu_item_id, menu_item_id) == 0)
1320     return tool_item->priv->menu_item;
1321
1322   return NULL;
1323 }
1324
1325 /**
1326  * gtk_tool_item_rebuild_menu:
1327  * @tool_item: a #GtkToolItem
1328  *
1329  * Calling this function signals to the toolbar that the
1330  * overflow menu item for @tool_item has changed. If the
1331  * overflow menu is visible when this function it called,
1332  * the menu will be rebuilt.
1333  *
1334  * The function must be called when the tool item changes what it
1335  * will do in response to the #GtkToolItem::create-menu-proxy signal.
1336  *
1337  * Since: 2.6
1338  */
1339 void
1340 gtk_tool_item_rebuild_menu (GtkToolItem *tool_item)
1341 {
1342   GtkWidget *parent;
1343   GtkWidget *widget;
1344
1345   g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
1346
1347   widget = GTK_WIDGET (tool_item);
1348
1349   parent = gtk_widget_get_parent (widget);
1350   if (GTK_IS_TOOL_SHELL (parent))
1351     gtk_tool_shell_rebuild_menu (GTK_TOOL_SHELL (parent));
1352 }
1353
1354 /**
1355  * gtk_tool_item_set_proxy_menu_item:
1356  * @tool_item: a #GtkToolItem
1357  * @menu_item_id: a string used to identify @menu_item
1358  * @menu_item: a #GtkMenuItem to be used in the overflow menu
1359  * 
1360  * Sets the #GtkMenuItem used in the toolbar overflow menu. The
1361  * @menu_item_id is used to identify the caller of this function and
1362  * should also be used with gtk_tool_item_get_proxy_menu_item().
1363  * 
1364  * Since: 2.4
1365  **/
1366 void
1367 gtk_tool_item_set_proxy_menu_item (GtkToolItem *tool_item,
1368                                    const gchar *menu_item_id,
1369                                    GtkWidget   *menu_item)
1370 {
1371   g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
1372   g_return_if_fail (menu_item == NULL || GTK_IS_MENU_ITEM (menu_item));
1373   g_return_if_fail (menu_item_id != NULL);
1374
1375   g_free (tool_item->priv->menu_item_id);
1376       
1377   tool_item->priv->menu_item_id = g_strdup (menu_item_id);
1378
1379   if (tool_item->priv->menu_item != menu_item)
1380     {
1381       if (tool_item->priv->menu_item)
1382         g_object_unref (tool_item->priv->menu_item);
1383       
1384       if (menu_item)
1385         {
1386           g_object_ref_sink (menu_item);
1387
1388           gtk_widget_set_sensitive (menu_item,
1389                                     gtk_widget_get_sensitive (GTK_WIDGET (tool_item)));
1390         }
1391       
1392       tool_item->priv->menu_item = menu_item;
1393     }
1394 }
1395
1396 /**
1397  * gtk_tool_item_toolbar_reconfigured:
1398  * @tool_item: a #GtkToolItem
1399  *
1400  * Emits the signal #GtkToolItem::toolbar_reconfigured on @tool_item.
1401  * #GtkToolbar and other #GtkToolShell implementations use this function
1402  * to notify children, when some aspect of their configuration changes.
1403  *
1404  * Since: 2.14
1405  **/
1406 void
1407 gtk_tool_item_toolbar_reconfigured (GtkToolItem *tool_item)
1408 {
1409   /* The slightely inaccurate name "gtk_tool_item_toolbar_reconfigured" was
1410    * choosen over "gtk_tool_item_tool_shell_reconfigured", since the function
1411    * emits the "toolbar-reconfigured" signal, not "tool-shell-reconfigured".
1412    * It's not possible to rename the signal, and emitting another name than
1413    * indicated by the function name would be quite confusing. That's the
1414    * price of providing stable APIs.
1415    */
1416   g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
1417
1418   g_signal_emit (tool_item, toolitem_signals[TOOLBAR_RECONFIGURED], 0);
1419   
1420   if (tool_item->priv->drag_window)
1421     gdk_window_raise (tool_item->priv->drag_window);
1422
1423   gtk_widget_queue_resize (GTK_WIDGET (tool_item));
1424 }