]> Pileus Git - ~andy/gtk/blob - gtk/gtktoolitem.c
Updated Russian translation
[~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
405 static void
406 create_drag_window (GtkToolItem *toolitem)
407 {
408   GtkAllocation allocation;
409   GtkWidget *widget;
410   GdkWindowAttr attributes;
411   gint attributes_mask;
412
413   g_return_if_fail (toolitem->priv->use_drag_window == TRUE);
414
415   widget = GTK_WIDGET (toolitem);
416
417   gtk_widget_get_allocation (widget, &allocation);
418
419   attributes.window_type = GDK_WINDOW_CHILD;
420   attributes.x = allocation.x;
421   attributes.y = allocation.y;
422   attributes.width = allocation.width;
423   attributes.height = allocation.height;
424   attributes.wclass = GDK_INPUT_ONLY;
425   attributes.event_mask = gtk_widget_get_events (widget);
426   attributes.event_mask |= (GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
427
428   attributes_mask = GDK_WA_X | GDK_WA_Y;
429
430   toolitem->priv->drag_window = gdk_window_new (gtk_widget_get_parent_window (widget),
431                                           &attributes, attributes_mask);
432   gdk_window_set_user_data (toolitem->priv->drag_window, toolitem);
433 }
434
435 static void
436 gtk_tool_item_realize (GtkWidget *widget)
437 {
438   GtkToolItem *toolitem;
439   GdkWindow *window;
440
441   toolitem = GTK_TOOL_ITEM (widget);
442   gtk_widget_set_realized (widget, TRUE);
443
444   window = gtk_widget_get_parent_window (widget);
445   gtk_widget_set_window (widget, window);
446   g_object_ref (window);
447
448   if (toolitem->priv->use_drag_window)
449     create_drag_window(toolitem);
450 }
451
452 static void
453 destroy_drag_window (GtkToolItem *toolitem)
454 {
455   if (toolitem->priv->drag_window)
456     {
457       gdk_window_set_user_data (toolitem->priv->drag_window, NULL);
458       gdk_window_destroy (toolitem->priv->drag_window);
459       toolitem->priv->drag_window = NULL;
460     }
461 }
462
463 static void
464 gtk_tool_item_unrealize (GtkWidget *widget)
465 {
466   GtkToolItem *toolitem;
467
468   toolitem = GTK_TOOL_ITEM (widget);
469
470   destroy_drag_window (toolitem);
471   
472   GTK_WIDGET_CLASS (gtk_tool_item_parent_class)->unrealize (widget);
473 }
474
475 static void
476 gtk_tool_item_map (GtkWidget *widget)
477 {
478   GtkToolItem *toolitem;
479
480   toolitem = GTK_TOOL_ITEM (widget);
481   GTK_WIDGET_CLASS (gtk_tool_item_parent_class)->map (widget);
482   if (toolitem->priv->drag_window)
483     gdk_window_show (toolitem->priv->drag_window);
484 }
485
486 static void
487 gtk_tool_item_unmap (GtkWidget *widget)
488 {
489   GtkToolItem *toolitem;
490
491   toolitem = GTK_TOOL_ITEM (widget);
492   if (toolitem->priv->drag_window)
493     gdk_window_hide (toolitem->priv->drag_window);
494   GTK_WIDGET_CLASS (gtk_tool_item_parent_class)->unmap (widget);
495 }
496
497 static void
498 gtk_tool_item_get_preferred_width (GtkWidget *widget,
499                                    gint      *minimum,
500                                    gint      *natural)
501 {
502   GtkWidget *child;
503
504   *minimum = *natural = 0;
505
506   child = gtk_bin_get_child (GTK_BIN (widget));
507   if (child && gtk_widget_get_visible (child))
508     gtk_widget_get_preferred_width (child, minimum, natural);
509 }
510
511 static void
512 gtk_tool_item_get_preferred_height (GtkWidget *widget,
513                                     gint      *minimum,
514                                     gint      *natural)
515 {
516   GtkWidget *child;
517
518   *minimum = *natural = 0;
519
520   child = gtk_bin_get_child (GTK_BIN (widget));
521   if (child && gtk_widget_get_visible (child))
522     gtk_widget_get_preferred_height (child, minimum, natural);
523 }
524
525 static void
526 gtk_tool_item_size_allocate (GtkWidget     *widget,
527                              GtkAllocation *allocation)
528 {
529   GtkToolItem *toolitem = GTK_TOOL_ITEM (widget);
530   GtkAllocation child_allocation;
531   GtkWidget *child;
532
533   gtk_widget_set_allocation (widget, allocation);
534
535   if (toolitem->priv->drag_window)
536     gdk_window_move_resize (toolitem->priv->drag_window,
537                             allocation->x,
538                             allocation->y,
539                             allocation->width,
540                             allocation->height);
541
542   child = gtk_bin_get_child (GTK_BIN (widget));
543   if (child && gtk_widget_get_visible (child))
544     {
545       child_allocation.x = allocation->x;
546       child_allocation.y = allocation->y;
547       child_allocation.width = allocation->width;
548       child_allocation.height = allocation->height;
549       
550       gtk_widget_size_allocate (child, &child_allocation);
551     }
552 }
553
554 gboolean
555 _gtk_tool_item_create_menu_proxy (GtkToolItem *item)
556 {
557   GtkWidget *menu_item;
558   gboolean visible_overflown;
559
560   if (item->priv->action)
561     {
562       g_object_get (item->priv->action, "visible-overflown", &visible_overflown, NULL);
563     
564       if (visible_overflown)
565         {
566           menu_item = gtk_action_create_menu_item (item->priv->action);
567
568           g_object_ref_sink (menu_item);
569           gtk_tool_item_set_proxy_menu_item (item, "gtk-action-menu-item", menu_item);
570           g_object_unref (menu_item);
571         }
572       else
573         gtk_tool_item_set_proxy_menu_item (item, "gtk-action-menu-item", NULL);
574
575       return TRUE;
576     }
577
578   return FALSE;
579 }
580
581 static void
582 gtk_tool_item_activatable_interface_init (GtkActivatableIface *iface)
583 {
584   iface->update = gtk_tool_item_update;
585   iface->sync_action_properties = gtk_tool_item_sync_action_properties;
586 }
587
588 static void
589 gtk_tool_item_update (GtkActivatable *activatable,
590                       GtkAction      *action,
591                       const gchar    *property_name)
592 {
593   if (strcmp (property_name, "visible") == 0)
594     {
595       if (gtk_action_is_visible (action))
596         gtk_widget_show (GTK_WIDGET (activatable));
597       else
598         gtk_widget_hide (GTK_WIDGET (activatable));
599     }
600   else if (strcmp (property_name, "sensitive") == 0)
601     gtk_widget_set_sensitive (GTK_WIDGET (activatable), gtk_action_is_sensitive (action));
602   else if (strcmp (property_name, "tooltip") == 0)
603     gtk_tool_item_set_tooltip_text (GTK_TOOL_ITEM (activatable),
604                                     gtk_action_get_tooltip (action));
605   else if (strcmp (property_name, "visible-horizontal") == 0)
606     gtk_tool_item_set_visible_horizontal (GTK_TOOL_ITEM (activatable),
607                                           gtk_action_get_visible_horizontal (action));
608   else if (strcmp (property_name, "visible-vertical") == 0)
609     gtk_tool_item_set_visible_vertical (GTK_TOOL_ITEM (activatable),
610                                         gtk_action_get_visible_vertical (action));
611   else if (strcmp (property_name, "is-important") == 0)
612     gtk_tool_item_set_is_important (GTK_TOOL_ITEM (activatable),
613                                     gtk_action_get_is_important (action));
614 }
615
616 static void
617 gtk_tool_item_sync_action_properties (GtkActivatable *activatable,
618                                       GtkAction      *action)
619 {
620   if (!action)
621     return;
622
623   if (gtk_action_is_visible (action))
624     gtk_widget_show (GTK_WIDGET (activatable));
625   else
626     gtk_widget_hide (GTK_WIDGET (activatable));
627   
628   gtk_widget_set_sensitive (GTK_WIDGET (activatable), gtk_action_is_sensitive (action));
629   
630   gtk_tool_item_set_tooltip_text (GTK_TOOL_ITEM (activatable),
631                                   gtk_action_get_tooltip (action));
632   gtk_tool_item_set_visible_horizontal (GTK_TOOL_ITEM (activatable),
633                                         gtk_action_get_visible_horizontal (action));
634   gtk_tool_item_set_visible_vertical (GTK_TOOL_ITEM (activatable),
635                                       gtk_action_get_visible_vertical (action));
636   gtk_tool_item_set_is_important (GTK_TOOL_ITEM (activatable),
637                                   gtk_action_get_is_important (action));
638 }
639
640 static void
641 gtk_tool_item_set_related_action (GtkToolItem *item, 
642                                   GtkAction   *action)
643 {
644   if (item->priv->action == action)
645     return;
646
647   gtk_activatable_do_set_related_action (GTK_ACTIVATABLE (item), action);
648
649   item->priv->action = action;
650
651   if (action)
652     {
653       gtk_tool_item_rebuild_menu (item);
654     }
655 }
656
657 static void
658 gtk_tool_item_set_use_action_appearance (GtkToolItem *item,
659                                          gboolean     use_appearance)
660 {
661   if (item->priv->use_action_appearance != use_appearance)
662     {
663       item->priv->use_action_appearance = use_appearance;
664
665       gtk_activatable_sync_action_properties (GTK_ACTIVATABLE (item), item->priv->action);
666     }
667 }
668
669
670 /**
671  * gtk_tool_item_new:
672  * 
673  * Creates a new #GtkToolItem
674  * 
675  * Return value: the new #GtkToolItem
676  * 
677  * Since: 2.4
678  **/
679 GtkToolItem *
680 gtk_tool_item_new (void)
681 {
682   GtkToolItem *item;
683
684   item = g_object_new (GTK_TYPE_TOOL_ITEM, NULL);
685
686   return item;
687 }
688
689 /**
690  * gtk_tool_item_get_ellipsize_mode:
691  * @tool_item: a #GtkToolItem
692  *
693  * Returns the ellipsize mode used for @tool_item. Custom subclasses of
694  * #GtkToolItem should call this function to find out how text should
695  * be ellipsized.
696  *
697  * Return value: a #PangoEllipsizeMode indicating how text in @tool_item
698  * should be ellipsized.
699  *
700  * Since: 2.20
701  **/
702 PangoEllipsizeMode
703 gtk_tool_item_get_ellipsize_mode (GtkToolItem *tool_item)
704 {
705   GtkWidget *parent;
706   
707   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), GTK_ORIENTATION_HORIZONTAL);
708
709   parent = gtk_widget_get_parent (GTK_WIDGET (tool_item));
710   if (!parent || !GTK_IS_TOOL_SHELL (parent))
711     return PANGO_ELLIPSIZE_NONE;
712
713   return gtk_tool_shell_get_ellipsize_mode (GTK_TOOL_SHELL (parent));
714 }
715
716 /**
717  * gtk_tool_item_get_icon_size:
718  * @tool_item: a #GtkToolItem
719  * 
720  * Returns the icon size used for @tool_item. Custom subclasses of
721  * #GtkToolItem should call this function to find out what size icons
722  * they should use.
723  * 
724  * Return value: (type int): a #GtkIconSize indicating the icon size
725  * used for @tool_item
726  * 
727  * Since: 2.4
728  **/
729 GtkIconSize
730 gtk_tool_item_get_icon_size (GtkToolItem *tool_item)
731 {
732   GtkWidget *parent;
733
734   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), GTK_ICON_SIZE_LARGE_TOOLBAR);
735
736   parent = gtk_widget_get_parent (GTK_WIDGET (tool_item));
737   if (!parent || !GTK_IS_TOOL_SHELL (parent))
738     return GTK_ICON_SIZE_LARGE_TOOLBAR;
739
740   return gtk_tool_shell_get_icon_size (GTK_TOOL_SHELL (parent));
741 }
742
743 /**
744  * gtk_tool_item_get_orientation:
745  * @tool_item: a #GtkToolItem 
746  * 
747  * Returns the orientation used for @tool_item. Custom subclasses of
748  * #GtkToolItem should call this function to find out what size icons
749  * they should use.
750  * 
751  * Return value: a #GtkOrientation indicating the orientation
752  * used for @tool_item
753  * 
754  * Since: 2.4
755  **/
756 GtkOrientation
757 gtk_tool_item_get_orientation (GtkToolItem *tool_item)
758 {
759   GtkWidget *parent;
760   
761   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), GTK_ORIENTATION_HORIZONTAL);
762
763   parent = gtk_widget_get_parent (GTK_WIDGET (tool_item));
764   if (!parent || !GTK_IS_TOOL_SHELL (parent))
765     return GTK_ORIENTATION_HORIZONTAL;
766
767   return gtk_tool_shell_get_orientation (GTK_TOOL_SHELL (parent));
768 }
769
770 /**
771  * gtk_tool_item_get_toolbar_style:
772  * @tool_item: a #GtkToolItem 
773  * 
774  * Returns the toolbar style used for @tool_item. Custom subclasses of
775  * #GtkToolItem should call this function in the handler of the
776  * GtkToolItem::toolbar_reconfigured signal to find out in what style
777  * the toolbar is displayed and change themselves accordingly 
778  *
779  * Possibilities are:
780  * <itemizedlist>
781  * <listitem> GTK_TOOLBAR_BOTH, meaning the tool item should show
782  * both an icon and a label, stacked vertically </listitem>
783  * <listitem> GTK_TOOLBAR_ICONS, meaning the toolbar shows
784  * only icons </listitem>
785  * <listitem> GTK_TOOLBAR_TEXT, meaning the tool item should only
786  * show text</listitem>
787  * <listitem> GTK_TOOLBAR_BOTH_HORIZ, meaning the tool item should show
788  * both an icon and a label, arranged horizontally (however, note the 
789  * #GtkToolButton:has_text_horizontally property that makes tool buttons not
790  * show labels when the toolbar style is GTK_TOOLBAR_BOTH_HORIZ.
791  * </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_style().
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    * Its 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 }