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