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