]> Pileus Git - ~andy/gtk/blob - gtk/gtktoolitem.c
Use accessor functions to acces GtkContainer
[~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_get_border_width (GTK_CONTAINER (widget));
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   guint border_width;
493
494   if (child && gtk_widget_get_visible (child))
495     {
496       gtk_widget_size_request (child, requisition);
497     }
498   else
499     {
500       requisition->height = 0;
501       requisition->width = 0;
502     }
503
504   border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
505   requisition->width += border_width * 2;
506   requisition->height += border_width * 2;
507 }
508
509 static void
510 gtk_tool_item_size_allocate (GtkWidget     *widget,
511                              GtkAllocation *allocation)
512 {
513   GtkToolItem *toolitem = GTK_TOOL_ITEM (widget);
514   GtkAllocation child_allocation;
515   gint border_width;
516   GtkWidget *child = GTK_BIN (widget)->child;
517
518   widget->allocation = *allocation;
519   border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
520
521   if (toolitem->priv->drag_window)
522     gdk_window_move_resize (toolitem->priv->drag_window,
523                             widget->allocation.x + border_width,
524                             widget->allocation.y + border_width,
525                             widget->allocation.width - border_width * 2,
526                             widget->allocation.height - border_width * 2);
527   
528   if (child && gtk_widget_get_visible (child))
529     {
530       child_allocation.x = allocation->x + border_width;
531       child_allocation.y = allocation->y + border_width;
532       child_allocation.width = allocation->width - 2 * border_width;
533       child_allocation.height = allocation->height - 2 * border_width;
534       
535       gtk_widget_size_allocate (child, &child_allocation);
536     }
537 }
538
539 gboolean
540 _gtk_tool_item_create_menu_proxy (GtkToolItem *item)
541 {
542   GtkWidget *menu_item;
543   gboolean visible_overflown;
544
545   if (item->priv->action)
546     {
547       g_object_get (item->priv->action, "visible-overflown", &visible_overflown, NULL);
548     
549       if (visible_overflown)
550         {
551           menu_item = gtk_action_create_menu_item (item->priv->action);
552
553           g_object_ref_sink (menu_item);
554           gtk_tool_item_set_proxy_menu_item (item, "gtk-action-menu-item", menu_item);
555           g_object_unref (menu_item);
556         }
557       else
558         gtk_tool_item_set_proxy_menu_item (item, "gtk-action-menu-item", NULL);
559
560       return TRUE;
561     }
562
563   return FALSE;
564 }
565
566 static void
567 gtk_tool_item_activatable_interface_init (GtkActivatableIface *iface)
568 {
569   iface->update = gtk_tool_item_update;
570   iface->sync_action_properties = gtk_tool_item_sync_action_properties;
571 }
572
573 static void
574 gtk_tool_item_update (GtkActivatable *activatable,
575                       GtkAction      *action,
576                       const gchar    *property_name)
577 {
578   if (strcmp (property_name, "visible") == 0)
579     {
580       if (gtk_action_is_visible (action))
581         gtk_widget_show (GTK_WIDGET (activatable));
582       else
583         gtk_widget_hide (GTK_WIDGET (activatable));
584     }
585   else if (strcmp (property_name, "sensitive") == 0)
586     gtk_widget_set_sensitive (GTK_WIDGET (activatable), gtk_action_is_sensitive (action));
587   else if (strcmp (property_name, "tooltip") == 0)
588     gtk_tool_item_set_tooltip_text (GTK_TOOL_ITEM (activatable),
589                                     gtk_action_get_tooltip (action));
590   else if (strcmp (property_name, "visible-horizontal") == 0)
591     gtk_tool_item_set_visible_horizontal (GTK_TOOL_ITEM (activatable),
592                                           gtk_action_get_visible_horizontal (action));
593   else if (strcmp (property_name, "visible-vertical") == 0)
594     gtk_tool_item_set_visible_vertical (GTK_TOOL_ITEM (activatable),
595                                         gtk_action_get_visible_vertical (action));
596   else if (strcmp (property_name, "is-important") == 0)
597     gtk_tool_item_set_is_important (GTK_TOOL_ITEM (activatable),
598                                     gtk_action_get_is_important (action));
599 }
600
601 static void
602 gtk_tool_item_sync_action_properties (GtkActivatable *activatable,
603                                       GtkAction      *action)
604 {
605   if (!action)
606     return;
607
608   if (gtk_action_is_visible (action))
609     gtk_widget_show (GTK_WIDGET (activatable));
610   else
611     gtk_widget_hide (GTK_WIDGET (activatable));
612   
613   gtk_widget_set_sensitive (GTK_WIDGET (activatable), gtk_action_is_sensitive (action));
614   
615   gtk_tool_item_set_tooltip_text (GTK_TOOL_ITEM (activatable),
616                                   gtk_action_get_tooltip (action));
617   gtk_tool_item_set_visible_horizontal (GTK_TOOL_ITEM (activatable),
618                                         gtk_action_get_visible_horizontal (action));
619   gtk_tool_item_set_visible_vertical (GTK_TOOL_ITEM (activatable),
620                                       gtk_action_get_visible_vertical (action));
621   gtk_tool_item_set_is_important (GTK_TOOL_ITEM (activatable),
622                                   gtk_action_get_is_important (action));
623 }
624
625 static void
626 gtk_tool_item_set_related_action (GtkToolItem *item, 
627                                   GtkAction   *action)
628 {
629   if (item->priv->action == action)
630     return;
631
632   gtk_activatable_do_set_related_action (GTK_ACTIVATABLE (item), action);
633
634   item->priv->action = action;
635
636   if (action)
637     {
638       gtk_tool_item_rebuild_menu (item);
639     }
640 }
641
642 static void
643 gtk_tool_item_set_use_action_appearance (GtkToolItem *item,
644                                          gboolean     use_appearance)
645 {
646   if (item->priv->use_action_appearance != use_appearance)
647     {
648       item->priv->use_action_appearance = use_appearance;
649
650       gtk_activatable_sync_action_properties (GTK_ACTIVATABLE (item), item->priv->action);
651     }
652 }
653
654
655 /**
656  * gtk_tool_item_new:
657  * 
658  * Creates a new #GtkToolItem
659  * 
660  * Return value: the new #GtkToolItem
661  * 
662  * Since: 2.4
663  **/
664 GtkToolItem *
665 gtk_tool_item_new (void)
666 {
667   GtkToolItem *item;
668
669   item = g_object_new (GTK_TYPE_TOOL_ITEM, NULL);
670
671   return item;
672 }
673
674 /**
675  * gtk_tool_item_get_ellipsize_mode:
676  * @tool_item: a #GtkToolItem
677  *
678  * Returns the ellipsize mode used for @tool_item. Custom subclasses of
679  * #GtkToolItem should call this function to find out how text should
680  * be ellipsized.
681  *
682  * Return value: a #PangoEllipsizeMode indicating how text in @tool_item
683  * should be ellipsized.
684  *
685  * Since: 2.20
686  **/
687 PangoEllipsizeMode
688 gtk_tool_item_get_ellipsize_mode (GtkToolItem *tool_item)
689 {
690   GtkWidget *parent;
691   
692   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), GTK_ORIENTATION_HORIZONTAL);
693
694   parent = GTK_WIDGET (tool_item)->parent;
695   if (!parent || !GTK_IS_TOOL_SHELL (parent))
696     return PANGO_ELLIPSIZE_NONE;
697
698   return gtk_tool_shell_get_ellipsize_mode (GTK_TOOL_SHELL (parent));
699 }
700
701 /**
702  * gtk_tool_item_get_icon_size:
703  * @tool_item: a #GtkToolItem
704  * 
705  * Returns the icon size used for @tool_item. Custom subclasses of
706  * #GtkToolItem should call this function to find out what size icons
707  * they should use.
708  * 
709  * Return value: (type int): a #GtkIconSize indicating the icon size
710  * used for @tool_item
711  * 
712  * Since: 2.4
713  **/
714 GtkIconSize
715 gtk_tool_item_get_icon_size (GtkToolItem *tool_item)
716 {
717   GtkWidget *parent;
718
719   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), GTK_ICON_SIZE_LARGE_TOOLBAR);
720
721   parent = GTK_WIDGET (tool_item)->parent;
722   if (!parent || !GTK_IS_TOOL_SHELL (parent))
723     return GTK_ICON_SIZE_LARGE_TOOLBAR;
724
725   return gtk_tool_shell_get_icon_size (GTK_TOOL_SHELL (parent));
726 }
727
728 /**
729  * gtk_tool_item_get_orientation:
730  * @tool_item: a #GtkToolItem 
731  * 
732  * Returns the orientation used for @tool_item. Custom subclasses of
733  * #GtkToolItem should call this function to find out what size icons
734  * they should use.
735  * 
736  * Return value: a #GtkOrientation indicating the orientation
737  * used for @tool_item
738  * 
739  * Since: 2.4
740  **/
741 GtkOrientation
742 gtk_tool_item_get_orientation (GtkToolItem *tool_item)
743 {
744   GtkWidget *parent;
745   
746   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), GTK_ORIENTATION_HORIZONTAL);
747
748   parent = GTK_WIDGET (tool_item)->parent;
749   if (!parent || !GTK_IS_TOOL_SHELL (parent))
750     return GTK_ORIENTATION_HORIZONTAL;
751
752   return gtk_tool_shell_get_orientation (GTK_TOOL_SHELL (parent));
753 }
754
755 /**
756  * gtk_tool_item_get_toolbar_style:
757  * @tool_item: a #GtkToolItem 
758  * 
759  * Returns the toolbar style used for @tool_item. Custom subclasses of
760  * #GtkToolItem should call this function in the handler of the
761  * GtkToolItem::toolbar_reconfigured signal to find out in what style
762  * the toolbar is displayed and change themselves accordingly 
763  *
764  * Possibilities are:
765  * <itemizedlist>
766  * <listitem> GTK_TOOLBAR_BOTH, meaning the tool item should show
767  * both an icon and a label, stacked vertically </listitem>
768  * <listitem> GTK_TOOLBAR_ICONS, meaning the toolbar shows
769  * only icons </listitem>
770  * <listitem> GTK_TOOLBAR_TEXT, meaning the tool item should only
771  * show text</listitem>
772  * <listitem> GTK_TOOLBAR_BOTH_HORIZ, meaning the tool item should show
773  * both an icon and a label, arranged horizontally (however, note the 
774  * #GtkToolButton::has_text_horizontally that makes tool buttons not
775  * show labels when the toolbar style is GTK_TOOLBAR_BOTH_HORIZ.
776  * </listitem>
777  * </itemizedlist>
778  * 
779  * Return value: A #GtkToolbarStyle indicating the toolbar style used
780  * for @tool_item.
781  * 
782  * Since: 2.4
783  **/
784 GtkToolbarStyle
785 gtk_tool_item_get_toolbar_style (GtkToolItem *tool_item)
786 {
787   GtkWidget *parent;
788   
789   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), GTK_TOOLBAR_ICONS);
790
791   parent = GTK_WIDGET (tool_item)->parent;
792   if (!parent || !GTK_IS_TOOL_SHELL (parent))
793     return GTK_TOOLBAR_ICONS;
794
795   return gtk_tool_shell_get_style (GTK_TOOL_SHELL (parent));
796 }
797
798 /**
799  * gtk_tool_item_get_relief_style:
800  * @tool_item: a #GtkToolItem 
801  * 
802  * Returns the relief style of @tool_item. See gtk_button_set_relief_style().
803  * Custom subclasses of #GtkToolItem should call this function in the handler
804  * of the #GtkToolItem::toolbar_reconfigured signal to find out the
805  * relief style of buttons.
806  * 
807  * Return value: a #GtkReliefStyle indicating the relief style used
808  * for @tool_item.
809  * 
810  * Since: 2.4
811  **/
812 GtkReliefStyle 
813 gtk_tool_item_get_relief_style (GtkToolItem *tool_item)
814 {
815   GtkWidget *parent;
816   
817   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), GTK_RELIEF_NONE);
818
819   parent = GTK_WIDGET (tool_item)->parent;
820   if (!parent || !GTK_IS_TOOL_SHELL (parent))
821     return GTK_RELIEF_NONE;
822
823   return gtk_tool_shell_get_relief_style (GTK_TOOL_SHELL (parent));
824 }
825
826 /**
827  * gtk_tool_item_get_text_alignment:
828  * @tool_item: a #GtkToolItem: 
829  * 
830  * Returns the text alignment used for @tool_item. Custom subclasses of
831  * #GtkToolItem should call this function to find out how text should
832  * be aligned.
833  * 
834  * Return value: a #gfloat indicating the horizontal text alignment
835  * used for @tool_item
836  * 
837  * Since: 2.20
838  **/
839 gfloat
840 gtk_tool_item_get_text_alignment (GtkToolItem *tool_item)
841 {
842   GtkWidget *parent;
843   
844   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), GTK_ORIENTATION_HORIZONTAL);
845
846   parent = GTK_WIDGET (tool_item)->parent;
847   if (!parent || !GTK_IS_TOOL_SHELL (parent))
848     return 0.5;
849
850   return gtk_tool_shell_get_text_alignment (GTK_TOOL_SHELL (parent));
851 }
852
853 /**
854  * gtk_tool_item_get_text_orientation:
855  * @tool_item: a #GtkToolItem
856  *
857  * Returns the text orientation used for @tool_item. Custom subclasses of
858  * #GtkToolItem should call this function to find out how text should
859  * be orientated.
860  *
861  * Return value: a #GtkOrientation indicating the text orientation
862  * used for @tool_item
863  *
864  * Since: 2.20
865  */
866 GtkOrientation
867 gtk_tool_item_get_text_orientation (GtkToolItem *tool_item)
868 {
869   GtkWidget *parent;
870   
871   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), GTK_ORIENTATION_HORIZONTAL);
872
873   parent = GTK_WIDGET (tool_item)->parent;
874   if (!parent || !GTK_IS_TOOL_SHELL (parent))
875     return GTK_ORIENTATION_HORIZONTAL;
876
877   return gtk_tool_shell_get_text_orientation (GTK_TOOL_SHELL (parent));
878 }
879
880 /**
881  * gtk_tool_item_get_text_size_group:
882  * @tool_item: a #GtkToolItem
883  *
884  * Returns the size group used for labels in @tool_item. Custom subclasses of
885  * #GtkToolItem should call this function and use the size group for labels.
886  *
887  * Return value: a #GtkSizeGroup
888  *
889  * Since: 2.20
890  */
891 GtkSizeGroup *
892 gtk_tool_item_get_text_size_group (GtkToolItem *tool_item)
893 {
894   GtkWidget *parent;
895   
896   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), NULL);
897
898   parent = GTK_WIDGET (tool_item)->parent;
899   if (!parent || !GTK_IS_TOOL_SHELL (parent))
900     return NULL;
901
902   return gtk_tool_shell_get_text_size_group (GTK_TOOL_SHELL (parent));
903 }
904
905 /**
906  * gtk_tool_item_set_expand:
907  * @tool_item: a #GtkToolItem
908  * @expand: Whether @tool_item is allocated extra space
909  *
910  * Sets whether @tool_item is allocated extra space when there
911  * is more room on the toolbar then needed for the items. The
912  * effect is that the item gets bigger when the toolbar gets bigger
913  * and smaller when the toolbar gets smaller.
914  *
915  * Since: 2.4
916  */
917 void
918 gtk_tool_item_set_expand (GtkToolItem *tool_item,
919                           gboolean     expand)
920 {
921   g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
922     
923   expand = expand != FALSE;
924
925   if (tool_item->priv->expand != expand)
926     {
927       tool_item->priv->expand = expand;
928       gtk_widget_child_notify (GTK_WIDGET (tool_item), "expand");
929       gtk_widget_queue_resize (GTK_WIDGET (tool_item));
930     }
931 }
932
933 /**
934  * gtk_tool_item_get_expand:
935  * @tool_item: a #GtkToolItem 
936  * 
937  * Returns whether @tool_item is allocated extra space.
938  * See gtk_tool_item_set_expand().
939  * 
940  * Return value: %TRUE if @tool_item is allocated extra space.
941  * 
942  * Since: 2.4
943  **/
944 gboolean
945 gtk_tool_item_get_expand (GtkToolItem *tool_item)
946 {
947   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), FALSE);
948
949   return tool_item->priv->expand;
950 }
951
952 /**
953  * gtk_tool_item_set_homogeneous:
954  * @tool_item: a #GtkToolItem 
955  * @homogeneous: whether @tool_item is the same size as other homogeneous items
956  * 
957  * Sets whether @tool_item is to be allocated the same size as other
958  * homogeneous items. The effect is that all homogeneous items will have
959  * the same width as the widest of the items.
960  * 
961  * Since: 2.4
962  **/
963 void
964 gtk_tool_item_set_homogeneous (GtkToolItem *tool_item,
965                                gboolean     homogeneous)
966 {
967   g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
968     
969   homogeneous = homogeneous != FALSE;
970
971   if (tool_item->priv->homogeneous != homogeneous)
972     {
973       tool_item->priv->homogeneous = homogeneous;
974       gtk_widget_child_notify (GTK_WIDGET (tool_item), "homogeneous");
975       gtk_widget_queue_resize (GTK_WIDGET (tool_item));
976     }
977 }
978
979 /**
980  * gtk_tool_item_get_homogeneous:
981  * @tool_item: a #GtkToolItem 
982  * 
983  * Returns whether @tool_item is the same size as other homogeneous
984  * items. See gtk_tool_item_set_homogeneous().
985  * 
986  * Return value: %TRUE if the item is the same size as other homogeneous
987  * items.
988  * 
989  * Since: 2.4
990  **/
991 gboolean
992 gtk_tool_item_get_homogeneous (GtkToolItem *tool_item)
993 {
994   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), FALSE);
995
996   return tool_item->priv->homogeneous;
997 }
998
999 /**
1000  * gtk_tool_item_get_is_important:
1001  * @tool_item: a #GtkToolItem
1002  * 
1003  * Returns whether @tool_item is considered important. See
1004  * gtk_tool_item_set_is_important()
1005  * 
1006  * Return value: %TRUE if @tool_item is considered important.
1007  * 
1008  * Since: 2.4
1009  **/
1010 gboolean
1011 gtk_tool_item_get_is_important (GtkToolItem *tool_item)
1012 {
1013   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), FALSE);
1014
1015   return tool_item->priv->is_important;
1016 }
1017
1018 /**
1019  * gtk_tool_item_set_is_important:
1020  * @tool_item: a #GtkToolItem
1021  * @is_important: whether the tool item should be considered important
1022  * 
1023  * Sets whether @tool_item should be considered important. The #GtkToolButton
1024  * class uses this property to determine whether to show or hide its label
1025  * when the toolbar style is %GTK_TOOLBAR_BOTH_HORIZ. The result is that
1026  * only tool buttons with the "is_important" property set have labels, an
1027  * effect known as "priority text"
1028  * 
1029  * Since: 2.4
1030  **/
1031 void
1032 gtk_tool_item_set_is_important (GtkToolItem *tool_item, gboolean is_important)
1033 {
1034   g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
1035
1036   is_important = is_important != FALSE;
1037
1038   if (is_important != tool_item->priv->is_important)
1039     {
1040       tool_item->priv->is_important = is_important;
1041
1042       gtk_widget_queue_resize (GTK_WIDGET (tool_item));
1043
1044       g_object_notify (G_OBJECT (tool_item), "is-important");
1045     }
1046 }
1047
1048 /**
1049  * gtk_tool_item_set_tooltip_text:
1050  * @tool_item: a #GtkToolItem 
1051  * @text: text to be used as tooltip for @tool_item
1052  *
1053  * Sets the text to be displayed as tooltip on the item.
1054  * See gtk_widget_set_tooltip_text().
1055  *
1056  * Since: 2.12
1057  **/
1058 void
1059 gtk_tool_item_set_tooltip_text (GtkToolItem *tool_item,
1060                                 const gchar *text)
1061 {
1062   GtkWidget *child;
1063
1064   g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
1065
1066   child = GTK_BIN (tool_item)->child;
1067
1068   if (child)
1069     gtk_widget_set_tooltip_text (child, text);
1070 }
1071
1072 /**
1073  * gtk_tool_item_set_tooltip_markup:
1074  * @tool_item: a #GtkToolItem 
1075  * @markup: markup text to be used as tooltip for @tool_item
1076  *
1077  * Sets the markup text to be displayed as tooltip on the item.
1078  * See gtk_widget_set_tooltip_markup().
1079  *
1080  * Since: 2.12
1081  **/
1082 void
1083 gtk_tool_item_set_tooltip_markup (GtkToolItem *tool_item,
1084                                   const gchar *markup)
1085 {
1086   GtkWidget *child;
1087
1088   g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
1089
1090   child = GTK_BIN (tool_item)->child;
1091
1092   if (child)
1093     gtk_widget_set_tooltip_markup (child, markup);
1094 }
1095
1096 /**
1097  * gtk_tool_item_set_use_drag_window:
1098  * @tool_item: a #GtkToolItem 
1099  * @use_drag_window: Whether @tool_item has a drag window.
1100  * 
1101  * Sets whether @tool_item has a drag window. When %TRUE the
1102  * toolitem can be used as a drag source through gtk_drag_source_set().
1103  * When @tool_item has a drag window it will intercept all events,
1104  * even those that would otherwise be sent to a child of @tool_item.
1105  * 
1106  * Since: 2.4
1107  **/
1108 void
1109 gtk_tool_item_set_use_drag_window (GtkToolItem *toolitem,
1110                                    gboolean     use_drag_window)
1111 {
1112   g_return_if_fail (GTK_IS_TOOL_ITEM (toolitem));
1113
1114   use_drag_window = use_drag_window != FALSE;
1115
1116   if (toolitem->priv->use_drag_window != use_drag_window)
1117     {
1118       toolitem->priv->use_drag_window = use_drag_window;
1119       
1120       if (use_drag_window)
1121         {
1122           if (!toolitem->priv->drag_window &&
1123               gtk_widget_get_realized (GTK_WIDGET (toolitem)))
1124             {
1125               create_drag_window(toolitem);
1126               if (gtk_widget_get_mapped (GTK_WIDGET (toolitem)))
1127                 gdk_window_show (toolitem->priv->drag_window);
1128             }
1129         }
1130       else
1131         {
1132           destroy_drag_window (toolitem);
1133         }
1134     }
1135 }
1136
1137 /**
1138  * gtk_tool_item_get_use_drag_window:
1139  * @tool_item: a #GtkToolItem 
1140  * 
1141  * Returns whether @tool_item has a drag window. See
1142  * gtk_tool_item_set_use_drag_window().
1143  * 
1144  * Return value: %TRUE if @tool_item uses a drag window.
1145  * 
1146  * Since: 2.4
1147  **/
1148 gboolean
1149 gtk_tool_item_get_use_drag_window (GtkToolItem *toolitem)
1150 {
1151   g_return_val_if_fail (GTK_IS_TOOL_ITEM (toolitem), FALSE);
1152
1153   return toolitem->priv->use_drag_window;
1154 }
1155
1156 /**
1157  * gtk_tool_item_set_visible_horizontal:
1158  * @tool_item: a #GtkToolItem
1159  * @visible_horizontal: Whether @tool_item is visible when in horizontal mode
1160  * 
1161  * Sets whether @tool_item is visible when the toolbar is docked horizontally.
1162  * 
1163  * Since: 2.4
1164  **/
1165 void
1166 gtk_tool_item_set_visible_horizontal (GtkToolItem *toolitem,
1167                                       gboolean     visible_horizontal)
1168 {
1169   g_return_if_fail (GTK_IS_TOOL_ITEM (toolitem));
1170
1171   visible_horizontal = visible_horizontal != FALSE;
1172
1173   if (toolitem->priv->visible_horizontal != visible_horizontal)
1174     {
1175       toolitem->priv->visible_horizontal = visible_horizontal;
1176
1177       g_object_notify (G_OBJECT (toolitem), "visible-horizontal");
1178
1179       gtk_widget_queue_resize (GTK_WIDGET (toolitem));
1180     }
1181 }
1182
1183 /**
1184  * gtk_tool_item_get_visible_horizontal:
1185  * @tool_item: a #GtkToolItem 
1186  * 
1187  * Returns whether the @tool_item is visible on toolbars that are
1188  * docked horizontally.
1189  * 
1190  * Return value: %TRUE if @tool_item is visible on toolbars that are
1191  * docked horizontally.
1192  * 
1193  * Since: 2.4
1194  **/
1195 gboolean
1196 gtk_tool_item_get_visible_horizontal (GtkToolItem *toolitem)
1197 {
1198   g_return_val_if_fail (GTK_IS_TOOL_ITEM (toolitem), FALSE);
1199
1200   return toolitem->priv->visible_horizontal;
1201 }
1202
1203 /**
1204  * gtk_tool_item_set_visible_vertical:
1205  * @tool_item: a #GtkToolItem 
1206  * @visible_vertical: whether @tool_item is visible when the toolbar
1207  * is in vertical mode
1208  *
1209  * Sets whether @tool_item is visible when the toolbar is docked
1210  * vertically. Some tool items, such as text entries, are too wide to be
1211  * useful on a vertically docked toolbar. If @visible_vertical is %FALSE
1212  * @tool_item will not appear on toolbars that are docked vertically.
1213  * 
1214  * Since: 2.4
1215  **/
1216 void
1217 gtk_tool_item_set_visible_vertical (GtkToolItem *toolitem,
1218                                     gboolean     visible_vertical)
1219 {
1220   g_return_if_fail (GTK_IS_TOOL_ITEM (toolitem));
1221
1222   visible_vertical = visible_vertical != FALSE;
1223
1224   if (toolitem->priv->visible_vertical != visible_vertical)
1225     {
1226       toolitem->priv->visible_vertical = visible_vertical;
1227
1228       g_object_notify (G_OBJECT (toolitem), "visible-vertical");
1229
1230       gtk_widget_queue_resize (GTK_WIDGET (toolitem));
1231     }
1232 }
1233
1234 /**
1235  * gtk_tool_item_get_visible_vertical:
1236  * @tool_item: a #GtkToolItem 
1237  * 
1238  * Returns whether @tool_item is visible when the toolbar is docked vertically.
1239  * See gtk_tool_item_set_visible_vertical().
1240  * 
1241  * Return value: Whether @tool_item is visible when the toolbar is docked vertically
1242  * 
1243  * Since: 2.4
1244  **/
1245 gboolean
1246 gtk_tool_item_get_visible_vertical (GtkToolItem *toolitem)
1247 {
1248   g_return_val_if_fail (GTK_IS_TOOL_ITEM (toolitem), FALSE);
1249
1250   return toolitem->priv->visible_vertical;
1251 }
1252
1253 /**
1254  * gtk_tool_item_retrieve_proxy_menu_item:
1255  * @tool_item: a #GtkToolItem 
1256  * 
1257  * Returns the #GtkMenuItem that was last set by
1258  * gtk_tool_item_set_proxy_menu_item(), ie. the #GtkMenuItem
1259  * that is going to appear in the overflow menu.
1260  *
1261  * Return value: (transfer none): The #GtkMenuItem that is going to appear in the
1262  * overflow menu for @tool_item.
1263  *
1264  * Since: 2.4
1265  **/
1266 GtkWidget *
1267 gtk_tool_item_retrieve_proxy_menu_item (GtkToolItem *tool_item)
1268 {
1269   gboolean retval;
1270   
1271   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), NULL);
1272
1273   g_signal_emit (tool_item, toolitem_signals[CREATE_MENU_PROXY], 0,
1274                  &retval);
1275   
1276   return tool_item->priv->menu_item;
1277 }
1278
1279 /**
1280  * gtk_tool_item_get_proxy_menu_item:
1281  * @tool_item: a #GtkToolItem 
1282  * @menu_item_id: a string used to identify the menu item
1283  * 
1284  * If @menu_item_id matches the string passed to
1285  * gtk_tool_item_set_proxy_menu_item() return the corresponding #GtkMenuItem.
1286  *
1287  * Custom subclasses of #GtkToolItem should use this function to update
1288  * their menu item when the #GtkToolItem changes. That the
1289  * @menu_item_id<!-- -->s must match ensures that a #GtkToolItem will not
1290  * inadvertently change a menu item that they did not create.
1291  * 
1292  * Return value: The #GtkMenuItem passed to
1293  * gtk_tool_item_set_proxy_menu_item(), if the @menu_item_id<!-- -->s match.
1294  * 
1295  * Since: 2.4
1296  **/
1297 GtkWidget *
1298 gtk_tool_item_get_proxy_menu_item (GtkToolItem *tool_item,
1299                                    const gchar *menu_item_id)
1300 {
1301   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), NULL);
1302   g_return_val_if_fail (menu_item_id != NULL, NULL);
1303
1304   if (tool_item->priv->menu_item_id && strcmp (tool_item->priv->menu_item_id, menu_item_id) == 0)
1305     return tool_item->priv->menu_item;
1306
1307   return NULL;
1308 }
1309
1310 /**
1311  * gtk_tool_item_rebuild_menu:
1312  * @tool_item: a #GtkToolItem
1313  *
1314  * Calling this function signals to the toolbar that the
1315  * overflow menu item for @tool_item has changed. If the
1316  * overflow menu is visible when this function it called,
1317  * the menu will be rebuilt.
1318  *
1319  * The function must be called when the tool item changes what it
1320  * will do in response to the #GtkToolItem::create-menu-proxy signal.
1321  *
1322  * Since: 2.6
1323  */
1324 void
1325 gtk_tool_item_rebuild_menu (GtkToolItem *tool_item)
1326 {
1327   GtkWidget *widget;
1328   
1329   g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
1330
1331   widget = GTK_WIDGET (tool_item);
1332
1333   if (GTK_IS_TOOL_SHELL (widget->parent))
1334     gtk_tool_shell_rebuild_menu (GTK_TOOL_SHELL (widget->parent));
1335 }
1336
1337 /**
1338  * gtk_tool_item_set_proxy_menu_item:
1339  * @tool_item: a #GtkToolItem
1340  * @menu_item_id: a string used to identify @menu_item
1341  * @menu_item: a #GtkMenuItem to be used in the overflow menu
1342  * 
1343  * Sets the #GtkMenuItem used in the toolbar overflow menu. The
1344  * @menu_item_id is used to identify the caller of this function and
1345  * should also be used with gtk_tool_item_get_proxy_menu_item().
1346  * 
1347  * Since: 2.4
1348  **/
1349 void
1350 gtk_tool_item_set_proxy_menu_item (GtkToolItem *tool_item,
1351                                    const gchar *menu_item_id,
1352                                    GtkWidget   *menu_item)
1353 {
1354   g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
1355   g_return_if_fail (menu_item == NULL || GTK_IS_MENU_ITEM (menu_item));
1356   g_return_if_fail (menu_item_id != NULL);
1357
1358   g_free (tool_item->priv->menu_item_id);
1359       
1360   tool_item->priv->menu_item_id = g_strdup (menu_item_id);
1361
1362   if (tool_item->priv->menu_item != menu_item)
1363     {
1364       if (tool_item->priv->menu_item)
1365         g_object_unref (tool_item->priv->menu_item);
1366       
1367       if (menu_item)
1368         {
1369           g_object_ref_sink (menu_item);
1370
1371           gtk_widget_set_sensitive (menu_item,
1372                                     gtk_widget_get_sensitive (GTK_WIDGET (tool_item)));
1373         }
1374       
1375       tool_item->priv->menu_item = menu_item;
1376     }
1377 }
1378
1379 /**
1380  * gtk_tool_item_toolbar_reconfigured:
1381  * @tool_item: a #GtkToolItem
1382  *
1383  * Emits the signal #GtkToolItem::toolbar_reconfigured on @tool_item.
1384  * #GtkToolbar and other #GtkToolShell implementations use this function
1385  * to notify children, when some aspect of their configuration changes.
1386  *
1387  * Since: 2.14
1388  **/
1389 void
1390 gtk_tool_item_toolbar_reconfigured (GtkToolItem *tool_item)
1391 {
1392   /* The slightely inaccurate name "gtk_tool_item_toolbar_reconfigured" was
1393    * choosen over "gtk_tool_item_tool_shell_reconfigured", since the function
1394    * emits the "toolbar-reconfigured" signal, not "tool-shell-reconfigured".
1395    * Its not possible to rename the signal, and emitting another name than
1396    * indicated by the function name would be quite confusing. That's the
1397    * price of providing stable APIs.
1398    */
1399   g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
1400
1401   g_signal_emit (tool_item, toolitem_signals[TOOLBAR_RECONFIGURED], 0);
1402   
1403   if (tool_item->priv->drag_window)
1404     gdk_window_raise (tool_item->priv->drag_window);
1405
1406   gtk_widget_queue_resize (GTK_WIDGET (tool_item));
1407 }