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