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