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