]> Pileus Git - ~andy/gtk/blob - gtk/gtktoolitem.c
Commit a patch by Behdad to fix typos, omissions and other errors in the
[~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 #include "gtktoolitem.h"
25 #include "gtkmarshalers.h"
26 #include "gtktoolbar.h"
27 #include "gtkseparatormenuitem.h"
28 #include "gtkintl.h"
29 #include "gtkmain.h"
30 #include "gtkprivate.h"
31 #include "gtkalias.h"
32
33 #include <string.h>
34
35 enum {
36   CREATE_MENU_PROXY,
37   TOOLBAR_RECONFIGURED,
38   SET_TOOLTIP,
39   LAST_SIGNAL
40 };
41
42 enum {
43   PROP_0,
44   PROP_VISIBLE_HORIZONTAL,
45   PROP_VISIBLE_VERTICAL,
46   PROP_IS_IMPORTANT
47 };
48
49 #define GTK_TOOL_ITEM_GET_PRIVATE(o)  (G_TYPE_INSTANCE_GET_PRIVATE ((o), GTK_TYPE_TOOL_ITEM, GtkToolItemPrivate))
50
51 struct _GtkToolItemPrivate
52 {
53   gchar *tip_text;
54   gchar *tip_private;
55
56   guint visible_horizontal : 1;
57   guint visible_vertical : 1;
58   guint homogeneous : 1;
59   guint expand : 1;
60   guint use_drag_window : 1;
61   guint is_important : 1;
62
63   GdkWindow *drag_window;
64   
65   gchar *menu_item_id;
66   GtkWidget *menu_item;
67 };
68   
69 static void gtk_tool_item_finalize    (GObject *object);
70 static void gtk_tool_item_parent_set   (GtkWidget   *toolitem,
71                                         GtkWidget   *parent);
72 static void gtk_tool_item_set_property (GObject         *object,
73                                         guint            prop_id,
74                                         const GValue    *value,
75                                         GParamSpec      *pspec);
76 static void gtk_tool_item_get_property (GObject         *object,
77                                         guint            prop_id,
78                                         GValue          *value,
79                                         GParamSpec      *pspec);
80 static void gtk_tool_item_property_notify (GObject      *object,
81                                            GParamSpec   *pspec);
82 static void gtk_tool_item_realize       (GtkWidget      *widget);
83 static void gtk_tool_item_unrealize     (GtkWidget      *widget);
84 static void gtk_tool_item_map           (GtkWidget      *widget);
85 static void gtk_tool_item_unmap         (GtkWidget      *widget);
86 static void gtk_tool_item_size_request  (GtkWidget      *widget,
87                                          GtkRequisition *requisition);
88 static void gtk_tool_item_size_allocate (GtkWidget      *widget,
89                                          GtkAllocation  *allocation);
90 static gboolean gtk_tool_item_real_set_tooltip (GtkToolItem *tool_item,
91                                                 GtkTooltips *tooltips,
92                                                 const gchar *tip_text,
93                                                 const gchar *tip_private);
94
95 static gboolean gtk_tool_item_create_menu_proxy (GtkToolItem *item);
96
97
98 static guint toolitem_signals[LAST_SIGNAL] = { 0 };
99
100 G_DEFINE_TYPE (GtkToolItem, gtk_tool_item, GTK_TYPE_BIN)
101
102 static void
103 gtk_tool_item_class_init (GtkToolItemClass *klass)
104 {
105   GObjectClass *object_class;
106   GtkWidgetClass *widget_class;
107   
108   object_class = (GObjectClass *)klass;
109   widget_class = (GtkWidgetClass *)klass;
110   
111   object_class->set_property = gtk_tool_item_set_property;
112   object_class->get_property = gtk_tool_item_get_property;
113   object_class->finalize = gtk_tool_item_finalize;
114   object_class->notify = gtk_tool_item_property_notify;
115
116   widget_class->realize       = gtk_tool_item_realize;
117   widget_class->unrealize     = gtk_tool_item_unrealize;
118   widget_class->map           = gtk_tool_item_map;
119   widget_class->unmap         = gtk_tool_item_unmap;
120   widget_class->size_request  = gtk_tool_item_size_request;
121   widget_class->size_allocate = gtk_tool_item_size_allocate;
122   widget_class->parent_set    = gtk_tool_item_parent_set;
123
124   klass->create_menu_proxy = gtk_tool_item_create_menu_proxy;
125   klass->set_tooltip       = gtk_tool_item_real_set_tooltip;
126   
127   g_object_class_install_property (object_class,
128                                    PROP_VISIBLE_HORIZONTAL,
129                                    g_param_spec_boolean ("visible-horizontal",
130                                                          P_("Visible when horizontal"),
131                                                          P_("Whether the toolbar item is visible when the toolbar is in a horizontal orientation."),
132                                                          TRUE,
133                                                          GTK_PARAM_READWRITE));
134   g_object_class_install_property (object_class,
135                                    PROP_VISIBLE_VERTICAL,
136                                    g_param_spec_boolean ("visible-vertical",
137                                                          P_("Visible when vertical"),
138                                                          P_("Whether the toolbar item is visible when the toolbar is in a vertical orientation."),
139                                                          TRUE,
140                                                          GTK_PARAM_READWRITE));
141   g_object_class_install_property (object_class,
142                                    PROP_IS_IMPORTANT,
143                                    g_param_spec_boolean ("is-important",
144                                                          P_("Is important"),
145                                                          P_("Whether the toolbar item is considered important. When TRUE, toolbar buttons show text in GTK_TOOLBAR_BOTH_HORIZ mode"),
146                                                          FALSE,
147                                                          GTK_PARAM_READWRITE));
148
149 /**
150  * GtkToolItem::create-menu-proxy:
151  * @toolitem: the object the signal was emitted on
152  *
153  * This signal is emitted when the toolbar needs information from @tool_item
154  * about whether the item should appear in the toolbar overflow menu. In
155  * response the tool item should either
156  * <itemizedlist>
157  * <listitem> call gtk_tool_item_set_proxy_menu_item() with a %NULL
158  * pointer and return %TRUE to indicate that the item should not appear
159  * in the overflow menu
160  * </listitem>
161  * <listitem> call gtk_tool_item_set_proxy_menu_item() with a new menu
162  * item and return %TRUE, or 
163  * </listitem>
164  * <listitem> return %FALSE to indicate that the signal was not
165  * handled by the item. This means that
166  * the item will not appear in the overflow menu unless a later handler
167  * installs a menu item.
168  * </listitem>
169  * </itemizedlist>
170  *
171  * The toolbar may cache the result of this signal. When the tool item changes
172  * how it will respond to this signal it must call gtk_tool_item_rebuild_menu()
173  * to invalidate the cache and ensure that the toolbar rebuilds its overflow
174  * menu.
175  *
176  * Return value: %TRUE if the signal was handled, %FALSE if not
177  **/
178   toolitem_signals[CREATE_MENU_PROXY] =
179     g_signal_new (I_("create_menu_proxy"),
180                   G_OBJECT_CLASS_TYPE (klass),
181                   G_SIGNAL_RUN_LAST,
182                   G_STRUCT_OFFSET (GtkToolItemClass, create_menu_proxy),
183                   _gtk_boolean_handled_accumulator, NULL,
184                   _gtk_marshal_BOOLEAN__VOID,
185                   G_TYPE_BOOLEAN, 0);
186
187 /**
188  * GtkToolItem::toolbar-reconfigured:
189  * @toolitem: the object the signal was emitted on
190  *
191  * This signal is emitted when some property of the toolbar that the
192  * item is a child of changes. For custom subclasses of #GtkToolItem,
193  * the default handler of this signal use the functions
194  * <itemizedlist>
195  * <listitem>gtk_toolbar_get_orientation()</listitem>
196  * <listitem>gtk_toolbar_get_style()</listitem>
197  * <listitem>gtk_toolbar_get_icon_size()</listitem>
198  * <listitem>gtk_toolbar_get_relief_style()</listitem>
199  * </itemizedlist>
200  * to find out what the toolbar should look like and change
201  * themselves accordingly.
202  **/
203   toolitem_signals[TOOLBAR_RECONFIGURED] =
204     g_signal_new (I_("toolbar_reconfigured"),
205                   G_OBJECT_CLASS_TYPE (klass),
206                   G_SIGNAL_RUN_LAST,
207                   G_STRUCT_OFFSET (GtkToolItemClass, toolbar_reconfigured),
208                   NULL, NULL,
209                   _gtk_marshal_VOID__VOID,
210                   G_TYPE_NONE, 0);
211 /**
212  * GtkToolItem::set-tooltip:
213  * @toolitem: the object the signal was emitted on
214  * @tooltips: the #GtkTooltips
215  * @tip_text: the tooltip text
216  * @tip_private: the tooltip private text
217  *
218  * This signal is emitted when the toolitem's tooltip changes.
219  * Application developers can use gtk_tool_item_set_tooltip() to
220  * set the item's tooltip.
221  *
222  * Return value: %TRUE if the signal was handled, %FALSE if not
223  **/
224   toolitem_signals[SET_TOOLTIP] =
225     g_signal_new (I_("set_tooltip"),
226                   G_OBJECT_CLASS_TYPE (klass),
227                   G_SIGNAL_RUN_LAST,
228                   G_STRUCT_OFFSET (GtkToolItemClass, set_tooltip),
229                   _gtk_boolean_handled_accumulator, NULL,
230                   _gtk_marshal_BOOLEAN__OBJECT_STRING_STRING,
231                   G_TYPE_BOOLEAN, 3,
232                   GTK_TYPE_TOOLTIPS,
233                   G_TYPE_STRING,
234                   G_TYPE_STRING);                 
235
236   g_type_class_add_private (object_class, sizeof (GtkToolItemPrivate));
237 }
238
239 static void
240 gtk_tool_item_init (GtkToolItem *toolitem)
241 {
242   GTK_WIDGET_UNSET_FLAGS (toolitem, GTK_CAN_FOCUS);  
243
244   toolitem->priv = GTK_TOOL_ITEM_GET_PRIVATE (toolitem);
245
246   toolitem->priv->visible_horizontal = TRUE;
247   toolitem->priv->visible_vertical = TRUE;
248   toolitem->priv->homogeneous = FALSE;
249   toolitem->priv->expand = FALSE;
250 }
251
252 static void
253 gtk_tool_item_finalize (GObject *object)
254 {
255   GtkToolItem *item = GTK_TOOL_ITEM (object);
256
257   if (item->priv->menu_item_id)
258     g_free (item->priv->menu_item_id);
259   
260   if (item->priv->menu_item)
261     g_object_unref (item->priv->menu_item);
262   
263   if (G_OBJECT_CLASS (gtk_tool_item_parent_class)->finalize)
264     G_OBJECT_CLASS (gtk_tool_item_parent_class)->finalize (object);
265 }
266
267 static void
268 gtk_tool_item_parent_set   (GtkWidget   *toolitem,
269                             GtkWidget   *prev_parent)
270 {
271   _gtk_tool_item_toolbar_reconfigured (GTK_TOOL_ITEM (toolitem));
272 }
273
274 static void
275 gtk_tool_item_set_property (GObject      *object,
276                             guint         prop_id,
277                             const GValue *value,
278                             GParamSpec   *pspec)
279 {
280   GtkToolItem *toolitem = GTK_TOOL_ITEM (object);
281
282   switch (prop_id)
283     {
284     case PROP_VISIBLE_HORIZONTAL:
285       gtk_tool_item_set_visible_horizontal (toolitem, g_value_get_boolean (value));
286       break;
287     case PROP_VISIBLE_VERTICAL:
288       gtk_tool_item_set_visible_vertical (toolitem, g_value_get_boolean (value));
289       break;
290     case PROP_IS_IMPORTANT:
291       gtk_tool_item_set_is_important (toolitem, g_value_get_boolean (value));
292       break;
293     default:
294       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
295     }
296 }
297
298 static void
299 gtk_tool_item_get_property (GObject    *object,
300                             guint       prop_id,
301                             GValue     *value,
302                             GParamSpec *pspec)
303 {
304   GtkToolItem *toolitem = GTK_TOOL_ITEM (object);
305
306   switch (prop_id)
307     {
308     case PROP_VISIBLE_HORIZONTAL:
309       g_value_set_boolean (value, toolitem->priv->visible_horizontal);
310       break;
311     case PROP_VISIBLE_VERTICAL:
312       g_value_set_boolean (value, toolitem->priv->visible_vertical);
313       break;
314     case PROP_IS_IMPORTANT:
315       g_value_set_boolean (value, toolitem->priv->is_important);
316       break;
317     default:
318       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
319     }
320 }
321
322 static void
323 gtk_tool_item_property_notify (GObject    *object,
324                                GParamSpec *pspec)
325 {
326   GtkToolItem *tool_item = GTK_TOOL_ITEM (object);
327
328   if (tool_item->priv->menu_item && strcmp (pspec->name, "sensitive") == 0)
329     gtk_widget_set_sensitive (tool_item->priv->menu_item,
330                               GTK_WIDGET_SENSITIVE (tool_item));
331 }
332
333 static void
334 create_drag_window (GtkToolItem *toolitem)
335 {
336   GtkWidget *widget;
337   GdkWindowAttr attributes;
338   gint attributes_mask, border_width;
339
340   g_return_if_fail (toolitem->priv->use_drag_window == TRUE);
341
342   widget = GTK_WIDGET (toolitem);
343   border_width = GTK_CONTAINER (toolitem)->border_width;
344
345   attributes.window_type = GDK_WINDOW_CHILD;
346   attributes.x = widget->allocation.x + border_width;
347   attributes.y = widget->allocation.y + border_width;
348   attributes.width = widget->allocation.width - border_width * 2;
349   attributes.height = widget->allocation.height - border_width * 2;
350   attributes.wclass = GDK_INPUT_ONLY;
351   attributes.event_mask = gtk_widget_get_events (widget);
352   attributes.event_mask |= (GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
353
354   attributes_mask = GDK_WA_X | GDK_WA_Y;
355
356   toolitem->priv->drag_window = gdk_window_new (gtk_widget_get_parent_window (widget),
357                                           &attributes, attributes_mask);
358   gdk_window_set_user_data (toolitem->priv->drag_window, toolitem);
359 }
360
361 static void
362 gtk_tool_item_realize (GtkWidget *widget)
363 {
364   GtkToolItem *toolitem;
365
366   toolitem = GTK_TOOL_ITEM (widget);
367   GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
368
369   widget->window = gtk_widget_get_parent_window (widget);
370   g_object_ref (widget->window);
371
372   if (toolitem->priv->use_drag_window)
373     create_drag_window(toolitem);
374
375   widget->style = gtk_style_attach (widget->style, widget->window);
376 }
377
378 static void
379 destroy_drag_window (GtkToolItem *toolitem)
380 {
381   if (toolitem->priv->drag_window)
382     {
383       gdk_window_set_user_data (toolitem->priv->drag_window, NULL);
384       gdk_window_destroy (toolitem->priv->drag_window);
385       toolitem->priv->drag_window = NULL;
386     }
387 }
388
389 static void
390 gtk_tool_item_unrealize (GtkWidget *widget)
391 {
392   GtkToolItem *toolitem;
393
394   toolitem = GTK_TOOL_ITEM (widget);
395
396   destroy_drag_window (toolitem);
397   
398   GTK_WIDGET_CLASS (gtk_tool_item_parent_class)->unrealize (widget);
399 }
400
401 static void
402 gtk_tool_item_map (GtkWidget *widget)
403 {
404   GtkToolItem *toolitem;
405
406   toolitem = GTK_TOOL_ITEM (widget);
407   GTK_WIDGET_CLASS (gtk_tool_item_parent_class)->map (widget);
408   if (toolitem->priv->drag_window)
409     gdk_window_show (toolitem->priv->drag_window);
410 }
411
412 static void
413 gtk_tool_item_unmap (GtkWidget *widget)
414 {
415   GtkToolItem *toolitem;
416
417   toolitem = GTK_TOOL_ITEM (widget);
418   if (toolitem->priv->drag_window)
419     gdk_window_hide (toolitem->priv->drag_window);
420   GTK_WIDGET_CLASS (gtk_tool_item_parent_class)->unmap (widget);
421 }
422
423 static void
424 gtk_tool_item_size_request (GtkWidget      *widget,
425                             GtkRequisition *requisition)
426 {
427   GtkWidget *child = GTK_BIN (widget)->child;
428
429   if (child && GTK_WIDGET_VISIBLE (child))
430     {
431       gtk_widget_size_request (child, requisition);
432     }
433   else
434     {
435       requisition->height = 0;
436       requisition->width = 0;
437     }
438   
439   requisition->width += (GTK_CONTAINER (widget)->border_width) * 2;
440   requisition->height += (GTK_CONTAINER (widget)->border_width) * 2;
441 }
442
443 static void
444 gtk_tool_item_size_allocate (GtkWidget     *widget,
445                              GtkAllocation *allocation)
446 {
447   GtkToolItem *toolitem = GTK_TOOL_ITEM (widget);
448   GtkAllocation child_allocation;
449   gint border_width;
450   GtkWidget *child = GTK_BIN (widget)->child;
451
452   widget->allocation = *allocation;
453   border_width = GTK_CONTAINER (widget)->border_width;
454
455   if (toolitem->priv->drag_window)
456     gdk_window_move_resize (toolitem->priv->drag_window,
457                             widget->allocation.x + border_width,
458                             widget->allocation.y + border_width,
459                             widget->allocation.width - border_width * 2,
460                             widget->allocation.height - border_width * 2);
461   
462   if (child && GTK_WIDGET_VISIBLE (child))
463     {
464       child_allocation.x = allocation->x + border_width;
465       child_allocation.y = allocation->y + border_width;
466       child_allocation.width = allocation->width - 2 * border_width;
467       child_allocation.height = allocation->height - 2 * border_width;
468       
469       gtk_widget_size_allocate (child, &child_allocation);
470     }
471 }
472
473 static gboolean
474 gtk_tool_item_create_menu_proxy (GtkToolItem *item)
475 {
476   return FALSE;
477 }
478
479 /**
480  * gtk_tool_item_new:
481  * 
482  * Creates a new #GtkToolItem
483  * 
484  * Return value: the new #GtkToolItem
485  * 
486  * Since: 2.4
487  **/
488 GtkToolItem *
489 gtk_tool_item_new (void)
490 {
491   GtkToolItem *item;
492
493   item = g_object_new (GTK_TYPE_TOOL_ITEM, NULL);
494
495   return item;
496 }
497
498 /**
499  * gtk_tool_item_get_icon_size:
500  * @tool_item: a #GtkToolItem:
501  * 
502  * Returns the icon size used for @tool_item. Custom subclasses of
503  * #GtkToolItem should call this function to find out what size icons
504  * they should use.
505  * 
506  * Return value: a #GtkIconSize indicating the icon size used for @tool_item
507  * 
508  * Since: 2.4
509  **/
510 GtkIconSize
511 gtk_tool_item_get_icon_size (GtkToolItem *tool_item)
512 {
513   GtkWidget *parent;
514
515   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), GTK_ICON_SIZE_LARGE_TOOLBAR);
516
517   parent = GTK_WIDGET (tool_item)->parent;
518   if (!parent || !GTK_IS_TOOLBAR (parent))
519     return GTK_ICON_SIZE_LARGE_TOOLBAR;
520
521   return gtk_toolbar_get_icon_size (GTK_TOOLBAR (parent));
522 }
523
524 /**
525  * gtk_tool_item_get_orientation:
526  * @tool_item: a #GtkToolItem: 
527  * 
528  * Returns the orientation used for @tool_item. Custom subclasses of
529  * #GtkToolItem should call this function to find out what size icons
530  * they should use.
531  * 
532  * Return value: a #GtkOrientation indicating the orientation
533  * used for @tool_item
534  * 
535  * Since: 2.4
536  **/
537 GtkOrientation
538 gtk_tool_item_get_orientation (GtkToolItem *tool_item)
539 {
540   GtkWidget *parent;
541   
542   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), GTK_ORIENTATION_HORIZONTAL);
543
544   parent = GTK_WIDGET (tool_item)->parent;
545   if (!parent || !GTK_IS_TOOLBAR (parent))
546     return GTK_ORIENTATION_HORIZONTAL;
547
548   return gtk_toolbar_get_orientation (GTK_TOOLBAR (parent));
549 }
550
551 /**
552  * gtk_tool_item_get_toolbar_style:
553  * @tool_item: a #GtkToolItem: 
554  * 
555  * Returns the toolbar style used for @tool_item. Custom subclasses of
556  * #GtkToolItem should call this function in the handler of the
557  * GtkToolItem::toolbar_reconfigured signal to find out in what style
558  * the toolbar is displayed and change themselves accordingly 
559  *
560  * Possibilities are:
561  * <itemizedlist>
562  * <listitem> GTK_TOOLBAR_BOTH, meaning the tool item should show
563  * both an icon and a label, stacked vertically </listitem>
564  * <listitem> GTK_TOOLBAR_ICONS, meaning the toolbar shows
565  * only icons </listitem>
566  * <listitem> GTK_TOOLBAR_TEXT, meaning the tool item should only
567  * show text</listitem>
568  * <listitem> GTK_TOOLBAR_BOTH_HORIZ, meaning the tool item should show
569  * both an icon and a label, arranged horizontally (however, note the 
570  * #GtkToolButton::has_text_horizontally that makes tool buttons not
571  * show labels when the toolbar style is GTK_TOOLBAR_BOTH_HORIZ.
572  * </listitem>
573  * </itemizedlist>
574  * 
575  * Return value: A #GtkToolbarStyle indicating the toolbar style used
576  * for @tool_item.
577  * 
578  * Since: 2.4
579  **/
580 GtkToolbarStyle
581 gtk_tool_item_get_toolbar_style (GtkToolItem *tool_item)
582 {
583   GtkWidget *parent;
584   
585   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), GTK_TOOLBAR_ICONS);
586
587   parent = GTK_WIDGET (tool_item)->parent;
588   if (!parent || !GTK_IS_TOOLBAR (parent))
589     return GTK_TOOLBAR_ICONS;
590
591   return gtk_toolbar_get_style (GTK_TOOLBAR (parent));
592 }
593
594 /**
595  * gtk_tool_item_get_relief_style:
596  * @tool_item: a #GtkToolItem: 
597  * 
598  * Returns the relief style of @tool_item. See gtk_button_set_relief_style().
599  * Custom subclasses of #GtkToolItem should call this function in the handler
600  * of the #GtkToolItem::toolbar_reconfigured signal to find out the
601  * relief style of buttons.
602  * 
603  * Return value: a #GtkReliefStyle indicating the relief style used
604  * for @tool_item.
605  * 
606  * Since: 2.4
607  **/
608 GtkReliefStyle 
609 gtk_tool_item_get_relief_style (GtkToolItem *tool_item)
610 {
611   GtkWidget *parent;
612   
613   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), GTK_RELIEF_NONE);
614
615   parent = GTK_WIDGET (tool_item)->parent;
616   if (!parent || !GTK_IS_TOOLBAR (parent))
617     return GTK_RELIEF_NONE;
618
619   return gtk_toolbar_get_relief_style (GTK_TOOLBAR (parent));
620 }
621
622 /**
623  * gtk_tool_item_set_expand:
624  * @tool_item: a #GtkToolItem: 
625  * @expand: Whether @tool_item is allocated extra space
626  * 
627  * Sets whether @tool_item is allocated extra space when there
628  * is more room on the toolbar then needed for the items. The
629  * effect is that the item gets bigger when the toolbar gets bigger
630  * and smaller when the toolbar gets smaller.
631  * 
632  * Since: 2.4
633  **/
634 void
635 gtk_tool_item_set_expand (GtkToolItem *tool_item,
636                           gboolean     expand)
637 {
638   g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
639     
640   expand = expand != FALSE;
641
642   if (tool_item->priv->expand != expand)
643     {
644       tool_item->priv->expand = expand;
645       gtk_widget_child_notify (GTK_WIDGET (tool_item), "expand");
646       gtk_widget_queue_resize (GTK_WIDGET (tool_item));
647     }
648 }
649
650 /**
651  * gtk_tool_item_get_expand:
652  * @tool_item: a #GtkToolItem: 
653  * 
654  * Returns whether @tool_item is allocated extra space.
655  * See gtk_tool_item_set_expand().
656  * 
657  * Return value: %TRUE if @tool_item is allocated extra space.
658  * 
659  * Since: 2.4
660  **/
661 gboolean
662 gtk_tool_item_get_expand (GtkToolItem *tool_item)
663 {
664   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), FALSE);
665
666   return tool_item->priv->expand;
667 }
668
669 /**
670  * gtk_tool_item_set_homogeneous:
671  * @tool_item: a #GtkToolItem: 
672  * @homogeneous: whether @tool_item is the same size as other homogeneous items
673  * 
674  * Sets whether @tool_item is to be allocated the same size as other
675  * homogeneous items. The effect is that all homogeneous items will have
676  * the same width as the widest of the items.
677  * 
678  * Since: 2.4
679  **/
680 void
681 gtk_tool_item_set_homogeneous (GtkToolItem *tool_item,
682                                gboolean     homogeneous)
683 {
684   g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
685     
686   homogeneous = homogeneous != FALSE;
687
688   if (tool_item->priv->homogeneous != homogeneous)
689     {
690       tool_item->priv->homogeneous = homogeneous;
691       gtk_widget_child_notify (GTK_WIDGET (tool_item), "homogeneous");
692       gtk_widget_queue_resize (GTK_WIDGET (tool_item));
693     }
694 }
695
696 /**
697  * gtk_tool_item_get_homogeneous:
698  * @tool_item: a #GtkToolItem: 
699  * 
700  * Returns whether @tool_item is the same size as other homogeneous
701  * items. See gtk_tool_item_set_homogeneous().
702  * 
703  * Return value: %TRUE if the item is the same size as other homogeneous
704  * item.s
705  * 
706  * Since: 2.4
707  **/
708 gboolean
709 gtk_tool_item_get_homogeneous (GtkToolItem *tool_item)
710 {
711   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), FALSE);
712
713   return tool_item->priv->homogeneous;
714 }
715
716 /**
717  * gtk_tool_item_get_is_important:
718  * @tool_item: a #GtkToolItem
719  * 
720  * Returns whether @tool_item is considered important. See
721  * gtk_tool_item_set_is_important()
722  * 
723  * Return value: %TRUE if @tool_item is considered important.
724  * 
725  * Since: 2.4
726  **/
727 gboolean
728 gtk_tool_item_get_is_important (GtkToolItem *tool_item)
729 {
730   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), FALSE);
731
732   return tool_item->priv->is_important;
733 }
734
735 /**
736  * gtk_tool_item_set_is_important:
737  * @tool_item: a #GtkToolItem
738  * @is_important: whether the tool item should be considered important
739  * 
740  * Sets whether @tool_item should be considered important. The #GtkToolButton
741  * class uses this property to determine whether to show or hide its label
742  * when the toolbar style is %GTK_TOOLBAR_BOTH_HORIZ. The result is that
743  * only tool buttons with the "is_important" property set have labels, an
744  * effect known as "priority text"
745  * 
746  * Since: 2.4
747  **/
748 void
749 gtk_tool_item_set_is_important (GtkToolItem *tool_item, gboolean is_important)
750 {
751   g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
752
753   is_important = is_important != FALSE;
754
755   if (is_important != tool_item->priv->is_important)
756     {
757       tool_item->priv->is_important = is_important;
758
759       gtk_widget_queue_resize (GTK_WIDGET (tool_item));
760
761       g_object_notify (G_OBJECT (tool_item), "is-important");
762     }
763 }
764
765 static gboolean
766 gtk_tool_item_real_set_tooltip (GtkToolItem *tool_item,
767                                 GtkTooltips *tooltips,
768                                 const gchar *tip_text,
769                                 const gchar *tip_private)
770 {
771   GtkWidget *child = GTK_BIN (tool_item)->child;
772
773   if (!child)
774     return FALSE;
775
776   gtk_tooltips_set_tip (tooltips, child, tip_text, tip_private);
777
778   return TRUE;
779 }
780
781 /**
782  * gtk_tool_item_set_tooltip:
783  * @tool_item: a #GtkToolItem: 
784  * @tooltips: The #GtkTooltips object to be used
785  * @tip_text: text to be used as tooltip text for @tool_item
786  * @tip_private: text to be used as private tooltip text
787  *
788  * Sets the #GtkTooltips object to be used for @tool_item, the
789  * text to be displayed as tooltip on the item and the private text
790  * to be used. See gtk_tooltips_set_tip().
791  * 
792  * Since: 2.4
793  **/
794 void
795 gtk_tool_item_set_tooltip (GtkToolItem *tool_item,
796                            GtkTooltips *tooltips,
797                            const gchar *tip_text,
798                            const gchar *tip_private)
799 {
800   gboolean retval;
801   
802   g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
803
804   g_signal_emit (tool_item, toolitem_signals[SET_TOOLTIP], 0,
805                  tooltips, tip_text, tip_private, &retval);
806 }
807
808 /**
809  * gtk_tool_item_set_use_drag_window:
810  * @toolitem: a #GtkToolItem 
811  * @use_drag_window: Whether @toolitem has a drag window.
812  * 
813  * Sets whether @toolitem has a drag window. When %TRUE the
814  * toolitem can be used as a drag source through gtk_drag_source_set().
815  * When @toolitem has a drag window it will intercept all events,
816  * even those that would otherwise be sent to a child of @toolitem.
817  * 
818  * Since: 2.4
819  **/
820 void
821 gtk_tool_item_set_use_drag_window (GtkToolItem *toolitem,
822                                    gboolean     use_drag_window)
823 {
824   g_return_if_fail (GTK_IS_TOOL_ITEM (toolitem));
825
826   use_drag_window = use_drag_window != FALSE;
827
828   if (toolitem->priv->use_drag_window != use_drag_window)
829     {
830       toolitem->priv->use_drag_window = use_drag_window;
831       
832       if (use_drag_window)
833         {
834           if (!toolitem->priv->drag_window && GTK_WIDGET_REALIZED (toolitem))
835             {
836               create_drag_window(toolitem);
837               if (GTK_WIDGET_MAPPED (toolitem))
838                 gdk_window_show (toolitem->priv->drag_window);
839             }
840         }
841       else
842         {
843           destroy_drag_window (toolitem);
844         }
845     }
846 }
847
848 /**
849  * gtk_tool_item_get_use_drag_window:
850  * @toolitem: a #GtkToolItem 
851  * 
852  * Returns whether @toolitem has a drag window. See
853  * gtk_tool_item_set_use_drag_window().
854  * 
855  * Return value: %TRUE if @toolitem uses a drag window.
856  * 
857  * Since: 2.4
858  **/
859 gboolean
860 gtk_tool_item_get_use_drag_window (GtkToolItem *toolitem)
861 {
862   g_return_val_if_fail (GTK_IS_TOOL_ITEM (toolitem), FALSE);
863
864   return toolitem->priv->use_drag_window;
865 }
866
867 /**
868  * gtk_tool_item_set_visible_horizontal:
869  * @toolitem: a #GtkToolItem
870  * @visible_horizontal: Whether @toolitem is visible when in horizontal mode
871  * 
872  * Sets whether @toolitem is visible when the toolbar is docked horizontally.
873  * 
874  * Since: 2.4
875  **/
876 void
877 gtk_tool_item_set_visible_horizontal (GtkToolItem *toolitem,
878                                       gboolean     visible_horizontal)
879 {
880   g_return_if_fail (GTK_IS_TOOL_ITEM (toolitem));
881
882   visible_horizontal = visible_horizontal != FALSE;
883
884   if (toolitem->priv->visible_horizontal != visible_horizontal)
885     {
886       toolitem->priv->visible_horizontal = visible_horizontal;
887
888       g_object_notify (G_OBJECT (toolitem), "visible-horizontal");
889
890       gtk_widget_queue_resize (GTK_WIDGET (toolitem));
891     }
892 }
893
894 /**
895  * gtk_tool_item_get_visible_horizontal:
896  * @toolitem: a #GtkToolItem 
897  * 
898  * Returns whether the @toolitem is visible on toolbars that are
899  * docked horizontally.
900  * 
901  * Return value: %TRUE if @toolitem is visible on toolbars that are
902  * docked horizontally.
903  * 
904  * Since: 2.4
905  **/
906 gboolean
907 gtk_tool_item_get_visible_horizontal (GtkToolItem *toolitem)
908 {
909   g_return_val_if_fail (GTK_IS_TOOL_ITEM (toolitem), FALSE);
910
911   return toolitem->priv->visible_horizontal;
912 }
913
914 /**
915  * gtk_tool_item_set_visible_vertical:
916  * @toolitem: a #GtkToolItem 
917  * @visible_vertical: whether @toolitem is visible when the toolbar
918  * is in vertical mode
919  *
920  * Sets whether @toolitem is visible when the toolbar is docked
921  * vertically. Some tool items, such as text entries, are too wide to be
922  * useful on a vertically docked toolbar. If @visible_vertical is %FALSE
923  * @toolitem will not appear on toolbars that are docked vertically.
924  * 
925  * Since: 2.4
926  **/
927 void
928 gtk_tool_item_set_visible_vertical (GtkToolItem *toolitem,
929                                     gboolean     visible_vertical)
930 {
931   g_return_if_fail (GTK_IS_TOOL_ITEM (toolitem));
932
933   visible_vertical = visible_vertical != FALSE;
934
935   if (toolitem->priv->visible_vertical != visible_vertical)
936     {
937       toolitem->priv->visible_vertical = visible_vertical;
938
939       g_object_notify (G_OBJECT (toolitem), "visible-vertical");
940
941       gtk_widget_queue_resize (GTK_WIDGET (toolitem));
942     }
943 }
944
945 /**
946  * gtk_tool_item_get_visible_vertical:
947  * @toolitem: a #GtkToolItem 
948  * 
949  * Returns whether @toolitem is visible when the toolbar is docked vertically.
950  * See gtk_tool_item_set_visible_vertical().
951  * 
952  * Return value: Whether @toolitem is visible when the toolbar is docked vertically
953  * 
954  * Since: 2.4
955  **/
956 gboolean
957 gtk_tool_item_get_visible_vertical (GtkToolItem *toolitem)
958 {
959   g_return_val_if_fail (GTK_IS_TOOL_ITEM (toolitem), FALSE);
960
961   return toolitem->priv->visible_vertical;
962 }
963
964 /**
965  * gtk_tool_item_retrieve_proxy_menu_item:
966  * @tool_item: a #GtkToolItem: 
967  * 
968  * Returns the #GtkMenuItem that was last set by
969  * gtk_tool_item_set_proxy_menu_item(), ie. the #GtkMenuItem
970  * that is going to appear in the overflow menu.
971  * 
972  * Return value: The #GtkMenuItem that is going to appear in the
973  * overflow menu for @tool_item.
974  * 
975  * Since: 2.4
976  **/
977 GtkWidget *
978 gtk_tool_item_retrieve_proxy_menu_item (GtkToolItem *tool_item)
979 {
980   gboolean retval;
981   
982   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), NULL);
983
984   g_signal_emit (tool_item, toolitem_signals[CREATE_MENU_PROXY], 0,
985                  &retval);
986   
987   return tool_item->priv->menu_item;
988 }
989
990 /**
991  * gtk_tool_item_get_proxy_menu_item:
992  * @tool_item: a #GtkToolItem: 
993  * @menu_item_id: a string used to identify the menu item
994  * 
995  * If @menu_item_id matches the string passed to
996  * gtk_tool_item_set_proxy_menu_item() return the corresponding #GtkMenuItem.
997  *
998  * Custom subclasses of #GtkToolItem should use this function to update
999  * their menu item when the #GtkToolItem changes. That the
1000  * @menu_item_id<!-- -->s must match ensures that a #GtkToolItem will not
1001  * inadvertently change a menu item that they did not create.
1002  * 
1003  * Return value: The #GtkMenuItem passed to
1004  * gtk_tool_item_set_proxy_menu_item(), if the @menu_item_id<!-- -->s match.
1005  * 
1006  * Since: 2.4
1007  **/
1008 GtkWidget *
1009 gtk_tool_item_get_proxy_menu_item (GtkToolItem *tool_item,
1010                                    const gchar *menu_item_id)
1011 {
1012   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), NULL);
1013   g_return_val_if_fail (menu_item_id != NULL, NULL);
1014
1015   if (tool_item->priv->menu_item_id && strcmp (tool_item->priv->menu_item_id, menu_item_id) == 0)
1016     return tool_item->priv->menu_item;
1017
1018   return NULL;
1019 }
1020
1021 /**
1022  * gtk_tool_item_rebuild_menu()
1023  * @tool_item: a #GtkToolItem
1024  * 
1025  * Calling this function signals to the toolbar that the
1026  * overflow menu item for @tool_item has changed. If the
1027  * overflow menu is visible when this function it called,
1028  * the menu will be rebuilt.
1029  *
1030  * The function must be called when the tool item
1031  * changes what it will do in response to the "create_menu_proxy"
1032  * signal.
1033  * 
1034  * Since: 2.6
1035  **/
1036 void
1037 gtk_tool_item_rebuild_menu (GtkToolItem *tool_item)
1038 {
1039   GtkWidget *widget;
1040   
1041   g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
1042
1043   widget = GTK_WIDGET (tool_item);
1044   
1045   if (widget->parent && GTK_IS_TOOLBAR (widget->parent))
1046     _gtk_toolbar_rebuild_menu (GTK_TOOLBAR (widget->parent));
1047 }
1048
1049 /**
1050  * gtk_tool_item_set_proxy_menu_item:
1051  * @tool_item: a #GtkToolItem:
1052  * @menu_item_id: a string used to identify @menu_item
1053  * @menu_item: a #GtkMenuItem to be used in the overflow menu
1054  * 
1055  * Sets the #GtkMenuItem used in the toolbar overflow menu. The
1056  * @menu_item_id is used to identify the caller of this function and
1057  * should also be used with gtk_tool_item_get_proxy_menu_item().
1058  * 
1059  * Since: 2.4
1060  **/
1061 void
1062 gtk_tool_item_set_proxy_menu_item (GtkToolItem *tool_item,
1063                                    const gchar *menu_item_id,
1064                                    GtkWidget   *menu_item)
1065 {
1066   g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
1067   g_return_if_fail (menu_item == NULL || GTK_IS_MENU_ITEM (menu_item));
1068   g_return_if_fail (menu_item_id != NULL);
1069
1070   if (tool_item->priv->menu_item_id)
1071     g_free (tool_item->priv->menu_item_id);
1072       
1073   tool_item->priv->menu_item_id = g_strdup (menu_item_id);
1074
1075   if (tool_item->priv->menu_item != menu_item)
1076     {
1077       if (tool_item->priv->menu_item)
1078         g_object_unref (tool_item->priv->menu_item);
1079       
1080       if (menu_item)
1081         {
1082           g_object_ref_sink (menu_item);
1083
1084           gtk_widget_set_sensitive (menu_item,
1085                                     GTK_WIDGET_SENSITIVE (tool_item));
1086         }
1087       
1088       tool_item->priv->menu_item = menu_item;
1089     }
1090 }
1091
1092 /**
1093  * _gtk_tool_item_toolbar_reconfigured:
1094  * @tool_item: a #GtkToolItem: 
1095  * 
1096  * Emits the signal #GtkToolItem::toolbar_reconfigured on @tool_item. This
1097  * internal function is called by #GtkToolbar when some aspect of its
1098  * configuration changes.
1099  * 
1100  * Since: 2.4
1101  **/
1102 void
1103 _gtk_tool_item_toolbar_reconfigured (GtkToolItem *tool_item)
1104 {
1105   g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
1106
1107   g_signal_emit (tool_item, toolitem_signals[TOOLBAR_RECONFIGURED], 0);
1108   
1109   if (tool_item->priv->drag_window)
1110     gdk_window_raise (tool_item->priv->drag_window);
1111
1112   gtk_widget_queue_resize (GTK_WIDGET (tool_item));
1113 }
1114
1115 #define __GTK_TOOL_ITEM_C__
1116 #include "gtkaliasdef.c"