gtktoolitem.c 40.9 KB
Newer Older
1 2
/* gtktoolitem.c
 *
3
 * Copyright (C) 2002 Anders Carlsson <andersca@gnome.org>
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
 * Copyright (C) 2002 James Henstridge <james@daa.com.au>
 * Copyright (C) 2003 Soeren Sandmann <sandmann@daimi.au.dk>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

23
#include "config.h"
24

25 26
#include "gtktoolitem.h"

27 28
#include <string.h>

29
#include "gtkmarshalers.h"
30
#include "gtktoolshell.h"
31
#include "gtkseparatormenuitem.h"
32
#include "gtksizerequest.h"
33
#include "gtkactivatable.h"
34 35
#include "gtkintl.h"
#include "gtkmain.h"
36
#include "gtkprivate.h"
37

38

39 40
/**
 * SECTION:gtktoolitem
41
 * @short_description: The base class of widgets that can be added to GtkToolShell
42
 * @Title: GtkToolItem
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
 * @see_also: <variablelist>
 *   <varlistentry>
 *     <term>#GtkToolbar</term>
 *     <listitem><para>The toolbar widget</para></listitem>
 *   </varlistentry>
 *   <varlistentry>
 *     <term>#GtkToolButton</term>
 *     <listitem><para>A subclass of #GtkToolItem that displays buttons on
 *         the toolbar</para></listitem>
 *   </varlistentry>
 *   <varlistentry>
 *     <term>#GtkSeparatorToolItem</term>
 *     <listitem><para>A subclass of #GtkToolItem that separates groups of
 *         items on a toolbar</para></listitem>
 *   </varlistentry>
 * </variablelist>
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
 *
 * #GtkToolItem<!-- -->s are widgets that can appear on a toolbar. To
 * create a toolbar item that contain something else than a button, use
 * gtk_tool_item_new(). Use gtk_container_add() to add a child
 * widget to the tool item.
 *
 * For toolbar items that contain buttons, see the #GtkToolButton,
 * #GtkToggleToolButton and #GtkRadioToolButton classes.
 *
 * See the #GtkToolbar class for a description of the toolbar widget, and
 * #GtkToolShell for a description of the tool shell interface.
 */

/**
 * GtkToolItem:
 *
 * The GtkToolItem struct contains only private data.
 * It should only be accessed through the functions described below.
 */

79 80 81 82 83 84 85 86 87 88
enum {
  CREATE_MENU_PROXY,
  TOOLBAR_RECONFIGURED,
  LAST_SIGNAL
};

enum {
  PROP_0,
  PROP_VISIBLE_HORIZONTAL,
  PROP_VISIBLE_VERTICAL,
89 90 91 92 93
  PROP_IS_IMPORTANT,

  /* activatable properties */
  PROP_ACTIVATABLE_RELATED_ACTION,
  PROP_ACTIVATABLE_USE_ACTION_APPEARANCE
94 95
};

Matthias Clasen's avatar
Matthias Clasen committed
96

97 98 99 100 101 102 103 104 105 106
struct _GtkToolItemPrivate
{
  gchar *tip_text;
  gchar *tip_private;

  guint visible_horizontal : 1;
  guint visible_vertical : 1;
  guint homogeneous : 1;
  guint expand : 1;
  guint use_drag_window : 1;
107
  guint is_important : 1;
108 109 110 111 112

  GdkWindow *drag_window;
  
  gchar *menu_item_id;
  GtkWidget *menu_item;
113 114 115

  GtkAction *action;
  gboolean   use_action_appearance;
116 117
};
  
118 119 120 121
static void gtk_tool_item_finalize     (GObject         *object);
static void gtk_tool_item_dispose      (GObject         *object);
static void gtk_tool_item_parent_set   (GtkWidget       *toolitem,
				        GtkWidget       *parent);
122 123 124 125 126 127 128 129
static void gtk_tool_item_set_property (GObject         *object,
					guint            prop_id,
					const GValue    *value,
					GParamSpec      *pspec);
static void gtk_tool_item_get_property (GObject         *object,
					guint            prop_id,
					GValue          *value,
					GParamSpec      *pspec);
130 131
static void gtk_tool_item_property_notify (GObject      *object,
					   GParamSpec   *pspec);
132 133 134 135 136 137 138 139 140
static void gtk_tool_item_realize       (GtkWidget      *widget);
static void gtk_tool_item_unrealize     (GtkWidget      *widget);
static void gtk_tool_item_map           (GtkWidget      *widget);
static void gtk_tool_item_unmap         (GtkWidget      *widget);
static void gtk_tool_item_size_request  (GtkWidget      *widget,
					 GtkRequisition *requisition);
static void gtk_tool_item_size_allocate (GtkWidget      *widget,
					 GtkAllocation  *allocation);

141
static void gtk_tool_item_activatable_interface_init (GtkActivatableIface  *iface);
142
static void gtk_tool_item_update                     (GtkActivatable       *activatable,
143 144
						      GtkAction            *action,
						      const gchar          *property_name);
145
static void gtk_tool_item_sync_action_properties     (GtkActivatable       *activatable,
146 147 148 149 150
						      GtkAction            *action);
static void gtk_tool_item_set_related_action         (GtkToolItem          *item, 
						      GtkAction            *action);
static void gtk_tool_item_set_use_action_appearance  (GtkToolItem          *item, 
						      gboolean              use_appearance);
151

Matthias Clasen's avatar
Matthias Clasen committed
152
static guint toolitem_signals[LAST_SIGNAL] = { 0 };
153

154 155 156
G_DEFINE_TYPE_WITH_CODE (GtkToolItem, gtk_tool_item, GTK_TYPE_BIN,
			 G_IMPLEMENT_INTERFACE (GTK_TYPE_ACTIVATABLE,
						gtk_tool_item_activatable_interface_init))
157 158 159 160 161 162 163 164 165 166 167 168

static void
gtk_tool_item_class_init (GtkToolItemClass *klass)
{
  GObjectClass *object_class;
  GtkWidgetClass *widget_class;
  
  object_class = (GObjectClass *)klass;
  widget_class = (GtkWidgetClass *)klass;
  
  object_class->set_property = gtk_tool_item_set_property;
  object_class->get_property = gtk_tool_item_get_property;
169 170 171
  object_class->finalize     = gtk_tool_item_finalize;
  object_class->dispose      = gtk_tool_item_dispose;
  object_class->notify       = gtk_tool_item_property_notify;
172 173 174 175 176 177 178 179 180

  widget_class->realize       = gtk_tool_item_realize;
  widget_class->unrealize     = gtk_tool_item_unrealize;
  widget_class->map           = gtk_tool_item_map;
  widget_class->unmap         = gtk_tool_item_unmap;
  widget_class->size_request  = gtk_tool_item_size_request;
  widget_class->size_allocate = gtk_tool_item_size_allocate;
  widget_class->parent_set    = gtk_tool_item_parent_set;

181
  klass->create_menu_proxy = _gtk_tool_item_create_menu_proxy;
182 183 184
  
  g_object_class_install_property (object_class,
				   PROP_VISIBLE_HORIZONTAL,
185
				   g_param_spec_boolean ("visible-horizontal",
186 187
							 P_("Visible when horizontal"),
							 P_("Whether the toolbar item is visible when the toolbar is in a horizontal orientation."),
188
							 TRUE,
189
							 GTK_PARAM_READWRITE));
190 191
  g_object_class_install_property (object_class,
				   PROP_VISIBLE_VERTICAL,
192
				   g_param_spec_boolean ("visible-vertical",
193 194
							 P_("Visible when vertical"),
							 P_("Whether the toolbar item is visible when the toolbar is in a vertical orientation."),
195
							 TRUE,
196
							 GTK_PARAM_READWRITE));
197 198
  g_object_class_install_property (object_class,
 				   PROP_IS_IMPORTANT,
199
 				   g_param_spec_boolean ("is-important",
200 201
 							 P_("Is important"),
 							 P_("Whether the toolbar item is considered important. When TRUE, toolbar buttons show text in GTK_TOOLBAR_BOTH_HORIZ mode"),
202
 							 FALSE,
203
 							 GTK_PARAM_READWRITE));
204

205 206 207 208
  g_object_class_override_property (object_class, PROP_ACTIVATABLE_RELATED_ACTION, "related-action");
  g_object_class_override_property (object_class, PROP_ACTIVATABLE_USE_ACTION_APPEARANCE, "use-action-appearance");


209 210
/**
 * GtkToolItem::create-menu-proxy:
211
 * @tool_item: the object the signal was emitted on
212
 *
213 214 215
 * This signal is emitted when the toolbar needs information from @tool_item
 * about whether the item should appear in the toolbar overflow menu. In
 * response the tool item should either
216
 * <itemizedlist>
217
 * <listitem>call gtk_tool_item_set_proxy_menu_item() with a %NULL
218 219 220 221
 * pointer and return %TRUE to indicate that the item should not appear
 * in the overflow menu
 * </listitem>
 * <listitem> call gtk_tool_item_set_proxy_menu_item() with a new menu
222
 * item and return %TRUE, or 
223
 * </listitem>
224
 * <listitem> return %FALSE to indicate that the signal was not
225 226 227 228 229
 * handled by the item. This means that
 * the item will not appear in the overflow menu unless a later handler
 * installs a menu item.
 * </listitem>
 * </itemizedlist>
230 231 232 233 234 235
 *
 * The toolbar may cache the result of this signal. When the tool item changes
 * how it will respond to this signal it must call gtk_tool_item_rebuild_menu()
 * to invalidate the cache and ensure that the toolbar rebuilds its overflow
 * menu.
 *
236 237
 * Return value: %TRUE if the signal was handled, %FALSE if not
 **/
238
  toolitem_signals[CREATE_MENU_PROXY] =
239
    g_signal_new (I_("create-menu-proxy"),
240 241 242
		  G_OBJECT_CLASS_TYPE (klass),
		  G_SIGNAL_RUN_LAST,
		  G_STRUCT_OFFSET (GtkToolItemClass, create_menu_proxy),
243
		  _gtk_boolean_handled_accumulator, NULL,
244 245
		  _gtk_marshal_BOOLEAN__VOID,
		  G_TYPE_BOOLEAN, 0);
246 247 248

/**
 * GtkToolItem::toolbar-reconfigured:
249
 * @tool_item: the object the signal was emitted on
250 251 252 253 254
 *
 * This signal is emitted when some property of the toolbar that the
 * item is a child of changes. For custom subclasses of #GtkToolItem,
 * the default handler of this signal use the functions
 * <itemizedlist>
255 256 257 258
 * <listitem>gtk_tool_shell_get_orientation()</listitem>
 * <listitem>gtk_tool_shell_get_style()</listitem>
 * <listitem>gtk_tool_shell_get_icon_size()</listitem>
 * <listitem>gtk_tool_shell_get_relief_style()</listitem>
259 260 261 262
 * </itemizedlist>
 * to find out what the toolbar should look like and change
 * themselves accordingly.
 **/
263
  toolitem_signals[TOOLBAR_RECONFIGURED] =
264
    g_signal_new (I_("toolbar-reconfigured"),
265 266 267 268 269 270
		  G_OBJECT_CLASS_TYPE (klass),
		  G_SIGNAL_RUN_LAST,
		  G_STRUCT_OFFSET (GtkToolItemClass, toolbar_reconfigured),
		  NULL, NULL,
		  _gtk_marshal_VOID__VOID,
		  G_TYPE_NONE, 0);
271 272

  g_type_class_add_private (object_class, sizeof (GtkToolItemPrivate));
273 274 275 276 277
}

static void
gtk_tool_item_init (GtkToolItem *toolitem)
{
278
  gtk_widget_set_can_focus (GTK_WIDGET (toolitem), FALSE);
279

280 281 282
  toolitem->priv = G_TYPE_INSTANCE_GET_PRIVATE (toolitem,
                                                GTK_TYPE_TOOL_ITEM,
                                                GtkToolItemPrivate);
283 284 285 286 287

  toolitem->priv->visible_horizontal = TRUE;
  toolitem->priv->visible_vertical = TRUE;
  toolitem->priv->homogeneous = FALSE;
  toolitem->priv->expand = FALSE;
288 289

  toolitem->priv->use_action_appearance = TRUE;
290 291 292 293 294 295 296
}

static void
gtk_tool_item_finalize (GObject *object)
{
  GtkToolItem *item = GTK_TOOL_ITEM (object);

297
  g_free (item->priv->menu_item_id);
298

299 300
  if (item->priv->menu_item)
    g_object_unref (item->priv->menu_item);
301 302

  G_OBJECT_CLASS (gtk_tool_item_parent_class)->finalize (object);
303 304
}

305 306 307 308 309 310 311 312 313 314 315 316 317 318
static void
gtk_tool_item_dispose (GObject *object)
{
  GtkToolItem *item = GTK_TOOL_ITEM (object);

  if (item->priv->action)
    {
      gtk_activatable_do_set_related_action (GTK_ACTIVATABLE (item), NULL);      
      item->priv->action = NULL;
    }
  G_OBJECT_CLASS (gtk_tool_item_parent_class)->dispose (object);
}


319
static void
320 321
gtk_tool_item_parent_set (GtkWidget   *toolitem,
			  GtkWidget   *prev_parent)
322
{
323
  if (gtk_widget_get_parent (GTK_WIDGET (toolitem)) != NULL)
324
    gtk_tool_item_toolbar_reconfigured (GTK_TOOL_ITEM (toolitem));
325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340
}

static void
gtk_tool_item_set_property (GObject      *object,
			    guint         prop_id,
			    const GValue *value,
			    GParamSpec   *pspec)
{
  GtkToolItem *toolitem = GTK_TOOL_ITEM (object);

  switch (prop_id)
    {
    case PROP_VISIBLE_HORIZONTAL:
      gtk_tool_item_set_visible_horizontal (toolitem, g_value_get_boolean (value));
      break;
    case PROP_VISIBLE_VERTICAL:
341
      gtk_tool_item_set_visible_vertical (toolitem, g_value_get_boolean (value));
342
      break;
343 344 345
    case PROP_IS_IMPORTANT:
      gtk_tool_item_set_is_important (toolitem, g_value_get_boolean (value));
      break;
346 347 348 349 350 351
    case PROP_ACTIVATABLE_RELATED_ACTION:
      gtk_tool_item_set_related_action (toolitem, g_value_get_object (value));
      break;
    case PROP_ACTIVATABLE_USE_ACTION_APPEARANCE:
      gtk_tool_item_set_use_action_appearance (toolitem, g_value_get_boolean (value));
      break;
352 353
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
354
      break;
355 356 357 358 359 360 361 362 363 364 365 366 367 368
    }
}

static void
gtk_tool_item_get_property (GObject    *object,
			    guint       prop_id,
			    GValue     *value,
			    GParamSpec *pspec)
{
  GtkToolItem *toolitem = GTK_TOOL_ITEM (object);

  switch (prop_id)
    {
    case PROP_VISIBLE_HORIZONTAL:
369
      g_value_set_boolean (value, toolitem->priv->visible_horizontal);
370 371
      break;
    case PROP_VISIBLE_VERTICAL:
372
      g_value_set_boolean (value, toolitem->priv->visible_vertical);
373
      break;
374 375 376
    case PROP_IS_IMPORTANT:
      g_value_set_boolean (value, toolitem->priv->is_important);
      break;
377 378 379 380 381 382
    case PROP_ACTIVATABLE_RELATED_ACTION:
      g_value_set_object (value, toolitem->priv->action);
      break;
    case PROP_ACTIVATABLE_USE_ACTION_APPEARANCE:
      g_value_set_boolean (value, toolitem->priv->use_action_appearance);
      break;
383 384
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
385
      break;
386 387 388
    }
}

389 390 391 392 393 394 395 396
static void
gtk_tool_item_property_notify (GObject    *object,
			       GParamSpec *pspec)
{
  GtkToolItem *tool_item = GTK_TOOL_ITEM (object);

  if (tool_item->priv->menu_item && strcmp (pspec->name, "sensitive") == 0)
    gtk_widget_set_sensitive (tool_item->priv->menu_item,
397
			      gtk_widget_get_sensitive (GTK_WIDGET (tool_item)));
398 399
}

400 401 402
static void
create_drag_window (GtkToolItem *toolitem)
{
403
  GtkAllocation allocation;
404 405 406 407
  GtkWidget *widget;
  GdkWindowAttr attributes;
  gint attributes_mask, border_width;

408
  g_return_if_fail (toolitem->priv->use_drag_window == TRUE);
409 410

  widget = GTK_WIDGET (toolitem);
411

412
  border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
413
  gtk_widget_get_allocation (widget, &allocation);
414 415

  attributes.window_type = GDK_WINDOW_CHILD;
416 417 418 419
  attributes.x = allocation.x + border_width;
  attributes.y = allocation.y + border_width;
  attributes.width = allocation.width - border_width * 2;
  attributes.height = allocation.height - border_width * 2;
420 421 422 423 424 425
  attributes.wclass = GDK_INPUT_ONLY;
  attributes.event_mask = gtk_widget_get_events (widget);
  attributes.event_mask |= (GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);

  attributes_mask = GDK_WA_X | GDK_WA_Y;

426
  toolitem->priv->drag_window = gdk_window_new (gtk_widget_get_parent_window (widget),
427
					  &attributes, attributes_mask);
428
  gdk_window_set_user_data (toolitem->priv->drag_window, toolitem);
429 430 431 432 433 434
}

static void
gtk_tool_item_realize (GtkWidget *widget)
{
  GtkToolItem *toolitem;
435
  GdkWindow *window;
436 437

  toolitem = GTK_TOOL_ITEM (widget);
438
  gtk_widget_set_realized (widget, TRUE);
439

440 441 442
  window = gtk_widget_get_parent_window (widget);
  gtk_widget_set_window (widget, window);
  g_object_ref (window);
443

444
  if (toolitem->priv->use_drag_window)
445 446
    create_drag_window(toolitem);

447
  gtk_widget_style_attach (widget);
448 449 450 451 452
}

static void
destroy_drag_window (GtkToolItem *toolitem)
{
453
  if (toolitem->priv->drag_window)
454
    {
455 456 457
      gdk_window_set_user_data (toolitem->priv->drag_window, NULL);
      gdk_window_destroy (toolitem->priv->drag_window);
      toolitem->priv->drag_window = NULL;
458 459 460 461 462 463 464 465 466 467 468 469
    }
}

static void
gtk_tool_item_unrealize (GtkWidget *widget)
{
  GtkToolItem *toolitem;

  toolitem = GTK_TOOL_ITEM (widget);

  destroy_drag_window (toolitem);
  
Matthias Clasen's avatar
Matthias Clasen committed
470
  GTK_WIDGET_CLASS (gtk_tool_item_parent_class)->unrealize (widget);
471 472 473 474 475 476 477 478
}

static void
gtk_tool_item_map (GtkWidget *widget)
{
  GtkToolItem *toolitem;

  toolitem = GTK_TOOL_ITEM (widget);
Matthias Clasen's avatar
Matthias Clasen committed
479
  GTK_WIDGET_CLASS (gtk_tool_item_parent_class)->map (widget);
480 481
  if (toolitem->priv->drag_window)
    gdk_window_show (toolitem->priv->drag_window);
482 483 484 485 486 487 488 489
}

static void
gtk_tool_item_unmap (GtkWidget *widget)
{
  GtkToolItem *toolitem;

  toolitem = GTK_TOOL_ITEM (widget);
490 491
  if (toolitem->priv->drag_window)
    gdk_window_hide (toolitem->priv->drag_window);
Matthias Clasen's avatar
Matthias Clasen committed
492
  GTK_WIDGET_CLASS (gtk_tool_item_parent_class)->unmap (widget);
493 494 495 496 497 498
}

static void
gtk_tool_item_size_request (GtkWidget      *widget,
			    GtkRequisition *requisition)
{
Javier Jardón's avatar
Javier Jardón committed
499
  GtkWidget *child;
500
  guint border_width;
501

Javier Jardón's avatar
Javier Jardón committed
502
  child = gtk_bin_get_child (GTK_BIN (widget));
503
  if (child && gtk_widget_get_visible (child))
504
    {
505
      gtk_widget_get_preferred_size (child, requisition, NULL);
506 507 508 509 510 511
    }
  else
    {
      requisition->height = 0;
      requisition->width = 0;
    }
512 513 514 515

  border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
  requisition->width += border_width * 2;
  requisition->height += border_width * 2;
516 517 518 519 520 521 522 523 524
}

static void
gtk_tool_item_size_allocate (GtkWidget     *widget,
			     GtkAllocation *allocation)
{
  GtkToolItem *toolitem = GTK_TOOL_ITEM (widget);
  GtkAllocation child_allocation;
  gint border_width;
Javier Jardón's avatar
Javier Jardón committed
525
  GtkWidget *child;
526

527 528
  gtk_widget_set_allocation (widget, allocation);

529
  border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
530

531 532
  if (toolitem->priv->drag_window)
    gdk_window_move_resize (toolitem->priv->drag_window,
533 534 535 536 537 538
                            allocation->x + border_width,
                            allocation->y + border_width,
                            allocation->width - border_width * 2,
                            allocation->height - border_width * 2);

  child = gtk_bin_get_child (GTK_BIN (widget));
539
  if (child && gtk_widget_get_visible (child))
540
    {
541 542 543 544
      child_allocation.x = allocation->x + border_width;
      child_allocation.y = allocation->y + border_width;
      child_allocation.width = allocation->width - 2 * border_width;
      child_allocation.height = allocation->height - 2 * border_width;
545 546 547 548 549
      
      gtk_widget_size_allocate (child, &child_allocation);
    }
}

550 551
gboolean
_gtk_tool_item_create_menu_proxy (GtkToolItem *item)
552
{
553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569
  GtkWidget *menu_item;
  gboolean visible_overflown;

  if (item->priv->action)
    {
      g_object_get (item->priv->action, "visible-overflown", &visible_overflown, NULL);
    
      if (visible_overflown)
	{
	  menu_item = gtk_action_create_menu_item (item->priv->action);

	  g_object_ref_sink (menu_item);
      	  gtk_tool_item_set_proxy_menu_item (item, "gtk-action-menu-item", menu_item);
	  g_object_unref (menu_item);
	}
      else
	gtk_tool_item_set_proxy_menu_item (item, "gtk-action-menu-item", NULL);
570 571

      return TRUE;
572 573
    }

574 575 576
  return FALSE;
}

577 578
static void
gtk_tool_item_activatable_interface_init (GtkActivatableIface *iface)
579
{
580 581
  iface->update = gtk_tool_item_update;
  iface->sync_action_properties = gtk_tool_item_sync_action_properties;
582 583
}

584 585 586 587
static void
gtk_tool_item_update (GtkActivatable *activatable,
		      GtkAction      *action,
	     	      const gchar    *property_name)
588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611
{
  if (strcmp (property_name, "visible") == 0)
    {
      if (gtk_action_is_visible (action))
	gtk_widget_show (GTK_WIDGET (activatable));
      else
	gtk_widget_hide (GTK_WIDGET (activatable));
    }
  else if (strcmp (property_name, "sensitive") == 0)
    gtk_widget_set_sensitive (GTK_WIDGET (activatable), gtk_action_is_sensitive (action));
  else if (strcmp (property_name, "tooltip") == 0)
    gtk_tool_item_set_tooltip_text (GTK_TOOL_ITEM (activatable),
				    gtk_action_get_tooltip (action));
  else if (strcmp (property_name, "visible-horizontal") == 0)
    gtk_tool_item_set_visible_horizontal (GTK_TOOL_ITEM (activatable),
					  gtk_action_get_visible_horizontal (action));
  else if (strcmp (property_name, "visible-vertical") == 0)
    gtk_tool_item_set_visible_vertical (GTK_TOOL_ITEM (activatable),
					gtk_action_get_visible_vertical (action));
  else if (strcmp (property_name, "is-important") == 0)
    gtk_tool_item_set_is_important (GTK_TOOL_ITEM (activatable),
				    gtk_action_get_is_important (action));
}

612 613 614
static void
gtk_tool_item_sync_action_properties (GtkActivatable *activatable,
				      GtkAction      *action)
615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653
{
  if (!action)
    return;

  if (gtk_action_is_visible (action))
    gtk_widget_show (GTK_WIDGET (activatable));
  else
    gtk_widget_hide (GTK_WIDGET (activatable));
  
  gtk_widget_set_sensitive (GTK_WIDGET (activatable), gtk_action_is_sensitive (action));
  
  gtk_tool_item_set_tooltip_text (GTK_TOOL_ITEM (activatable),
				  gtk_action_get_tooltip (action));
  gtk_tool_item_set_visible_horizontal (GTK_TOOL_ITEM (activatable),
					gtk_action_get_visible_horizontal (action));
  gtk_tool_item_set_visible_vertical (GTK_TOOL_ITEM (activatable),
				      gtk_action_get_visible_vertical (action));
  gtk_tool_item_set_is_important (GTK_TOOL_ITEM (activatable),
				  gtk_action_get_is_important (action));
}

static void
gtk_tool_item_set_related_action (GtkToolItem *item, 
				  GtkAction   *action)
{
  if (item->priv->action == action)
    return;

  gtk_activatable_do_set_related_action (GTK_ACTIVATABLE (item), action);

  item->priv->action = action;

  if (action)
    {
      gtk_tool_item_rebuild_menu (item);
    }
}

static void
654
gtk_tool_item_set_use_action_appearance (GtkToolItem *item,
655 656 657 658 659
					 gboolean     use_appearance)
{
  if (item->priv->use_action_appearance != use_appearance)
    {
      item->priv->use_action_appearance = use_appearance;
660 661

      gtk_activatable_sync_action_properties (GTK_ACTIVATABLE (item), item->priv->action);
662 663 664 665
    }
}


666 667 668 669 670 671 672 673 674
/**
 * gtk_tool_item_new:
 * 
 * Creates a new #GtkToolItem
 * 
 * Return value: the new #GtkToolItem
 * 
 * Since: 2.4
 **/
675 676 677 678 679 680 681 682 683 684
GtkToolItem *
gtk_tool_item_new (void)
{
  GtkToolItem *item;

  item = g_object_new (GTK_TYPE_TOOL_ITEM, NULL);

  return item;
}

685 686
/**
 * gtk_tool_item_get_ellipsize_mode:
687 688
 * @tool_item: a #GtkToolItem
 *
689 690 691
 * Returns the ellipsize mode used for @tool_item. Custom subclasses of
 * #GtkToolItem should call this function to find out how text should
 * be ellipsized.
692
 *
693 694
 * Return value: a #PangoEllipsizeMode indicating how text in @tool_item
 * should be ellipsized.
695 696
 *
 * Since: 2.20
697 698 699 700 701 702 703 704
 **/
PangoEllipsizeMode
gtk_tool_item_get_ellipsize_mode (GtkToolItem *tool_item)
{
  GtkWidget *parent;
  
  g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), GTK_ORIENTATION_HORIZONTAL);

705
  parent = gtk_widget_get_parent (GTK_WIDGET (tool_item));
706 707 708 709 710 711
  if (!parent || !GTK_IS_TOOL_SHELL (parent))
    return PANGO_ELLIPSIZE_NONE;

  return gtk_tool_shell_get_ellipsize_mode (GTK_TOOL_SHELL (parent));
}

712 713
/**
 * gtk_tool_item_get_icon_size:
714
 * @tool_item: a #GtkToolItem
715 716 717 718 719
 * 
 * Returns the icon size used for @tool_item. Custom subclasses of
 * #GtkToolItem should call this function to find out what size icons
 * they should use.
 * 
720 721
 * Return value: (type int): a #GtkIconSize indicating the icon size
 * used for @tool_item
722 723 724
 * 
 * Since: 2.4
 **/
725 726 727 728 729 730 731
GtkIconSize
gtk_tool_item_get_icon_size (GtkToolItem *tool_item)
{
  GtkWidget *parent;

  g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), GTK_ICON_SIZE_LARGE_TOOLBAR);

732
  parent = gtk_widget_get_parent (GTK_WIDGET (tool_item));
733
  if (!parent || !GTK_IS_TOOL_SHELL (parent))
734 735
    return GTK_ICON_SIZE_LARGE_TOOLBAR;

736
  return gtk_tool_shell_get_icon_size (GTK_TOOL_SHELL (parent));
737 738
}

739 740
/**
 * gtk_tool_item_get_orientation:
741
 * @tool_item: a #GtkToolItem 
742 743 744 745 746 747 748 749 750 751
 * 
 * Returns the orientation used for @tool_item. Custom subclasses of
 * #GtkToolItem should call this function to find out what size icons
 * they should use.
 * 
 * Return value: a #GtkOrientation indicating the orientation
 * used for @tool_item
 * 
 * Since: 2.4
 **/
752 753 754 755 756 757 758
GtkOrientation
gtk_tool_item_get_orientation (GtkToolItem *tool_item)
{
  GtkWidget *parent;
  
  g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), GTK_ORIENTATION_HORIZONTAL);

759
  parent = gtk_widget_get_parent (GTK_WIDGET (tool_item));
760
  if (!parent || !GTK_IS_TOOL_SHELL (parent))
761 762
    return GTK_ORIENTATION_HORIZONTAL;

763
  return gtk_tool_shell_get_orientation (GTK_TOOL_SHELL (parent));
764 765
}

766 767
/**
 * gtk_tool_item_get_toolbar_style:
768
 * @tool_item: a #GtkToolItem 
769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794
 * 
 * Returns the toolbar style used for @tool_item. Custom subclasses of
 * #GtkToolItem should call this function in the handler of the
 * GtkToolItem::toolbar_reconfigured signal to find out in what style
 * the toolbar is displayed and change themselves accordingly 
 *
 * Possibilities are:
 * <itemizedlist>
 * <listitem> GTK_TOOLBAR_BOTH, meaning the tool item should show
 * both an icon and a label, stacked vertically </listitem>
 * <listitem> GTK_TOOLBAR_ICONS, meaning the toolbar shows
 * only icons </listitem>
 * <listitem> GTK_TOOLBAR_TEXT, meaning the tool item should only
 * show text</listitem>
 * <listitem> GTK_TOOLBAR_BOTH_HORIZ, meaning the tool item should show
 * both an icon and a label, arranged horizontally (however, note the 
 * #GtkToolButton::has_text_horizontally that makes tool buttons not
 * show labels when the toolbar style is GTK_TOOLBAR_BOTH_HORIZ.
 * </listitem>
 * </itemizedlist>
 * 
 * Return value: A #GtkToolbarStyle indicating the toolbar style used
 * for @tool_item.
 * 
 * Since: 2.4
 **/
795 796 797 798 799 800 801
GtkToolbarStyle
gtk_tool_item_get_toolbar_style (GtkToolItem *tool_item)
{
  GtkWidget *parent;
  
  g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), GTK_TOOLBAR_ICONS);

802
  parent = gtk_widget_get_parent (GTK_WIDGET (tool_item));
803
  if (!parent || !GTK_IS_TOOL_SHELL (parent))
804 805
    return GTK_TOOLBAR_ICONS;

806
  return gtk_tool_shell_get_style (GTK_TOOL_SHELL (parent));
807 808
}

809 810
/**
 * gtk_tool_item_get_relief_style:
811
 * @tool_item: a #GtkToolItem 
812 813 814 815 816 817 818 819 820 821 822
 * 
 * Returns the relief style of @tool_item. See gtk_button_set_relief_style().
 * Custom subclasses of #GtkToolItem should call this function in the handler
 * of the #GtkToolItem::toolbar_reconfigured signal to find out the
 * relief style of buttons.
 * 
 * Return value: a #GtkReliefStyle indicating the relief style used
 * for @tool_item.
 * 
 * Since: 2.4
 **/
823 824 825 826 827 828 829
GtkReliefStyle 
gtk_tool_item_get_relief_style (GtkToolItem *tool_item)
{
  GtkWidget *parent;
  
  g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), GTK_RELIEF_NONE);

830
  parent = gtk_widget_get_parent (GTK_WIDGET (tool_item));
831
  if (!parent || !GTK_IS_TOOL_SHELL (parent))
832 833
    return GTK_RELIEF_NONE;

834
  return gtk_tool_shell_get_relief_style (GTK_TOOL_SHELL (parent));
835 836
}

837 838 839 840 841 842 843 844 845 846 847
/**
 * gtk_tool_item_get_text_alignment:
 * @tool_item: a #GtkToolItem: 
 * 
 * Returns the text alignment used for @tool_item. Custom subclasses of
 * #GtkToolItem should call this function to find out how text should
 * be aligned.
 * 
 * Return value: a #gfloat indicating the horizontal text alignment
 * used for @tool_item
 * 
848
 * Since: 2.20
849 850 851 852 853 854 855 856
 **/
gfloat
gtk_tool_item_get_text_alignment (GtkToolItem *tool_item)
{
  GtkWidget *parent;
  
  g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), GTK_ORIENTATION_HORIZONTAL);

857
  parent = gtk_widget_get_parent (GTK_WIDGET (tool_item));
858 859 860 861 862 863 864 865
  if (!parent || !GTK_IS_TOOL_SHELL (parent))
    return 0.5;

  return gtk_tool_shell_get_text_alignment (GTK_TOOL_SHELL (parent));
}

/**
 * gtk_tool_item_get_text_orientation:
866 867
 * @tool_item: a #GtkToolItem
 *
868 869 870
 * Returns the text orientation used for @tool_item. Custom subclasses of
 * #GtkToolItem should call this function to find out how text should
 * be orientated.
871
 *
872 873
 * Return value: a #GtkOrientation indicating the text orientation
 * used for @tool_item
874 875 876
 *
 * Since: 2.20
 */
877 878 879 880 881 882 883
GtkOrientation
gtk_tool_item_get_text_orientation (GtkToolItem *tool_item)
{
  GtkWidget *parent;
  
  g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), GTK_ORIENTATION_HORIZONTAL);

884
  parent = gtk_widget_get_parent (GTK_WIDGET (tool_item));
885 886 887 888 889 890 891 892
  if (!parent || !GTK_IS_TOOL_SHELL (parent))
    return GTK_ORIENTATION_HORIZONTAL;

  return gtk_tool_shell_get_text_orientation (GTK_TOOL_SHELL (parent));
}

/**
 * gtk_tool_item_get_text_size_group:
893 894
 * @tool_item: a #GtkToolItem
 *
895 896 897
 * Returns the size group used for labels in @tool_item.
 * Custom subclasses of #GtkToolItem should call this function
 * and use the size group for labels.
898
 *
899
 * Return value: (transfer none): a #GtkSizeGroup
900 901 902
 *
 * Since: 2.20
 */
903 904 905 906 907
GtkSizeGroup *
gtk_tool_item_get_text_size_group (GtkToolItem *tool_item)
{
  GtkWidget *parent;
  
908
  g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), NULL);
909

910
  parent = gtk_widget_get_parent (GTK_WIDGET (tool_item));
911 912 913 914 915 916
  if (!parent || !GTK_IS_TOOL_SHELL (parent))
    return NULL;

  return gtk_tool_shell_get_text_size_group (GTK_TOOL_SHELL (parent));
}

917 918
/**
 * gtk_tool_item_set_expand:
919
 * @tool_item: a #GtkToolItem
920
 * @expand: Whether @tool_item is allocated extra space
921
 *
922 923 924 925
 * Sets whether @tool_item is allocated extra space when there
 * is more room on the toolbar then needed for the items. The
 * effect is that the item gets bigger when the toolbar gets bigger
 * and smaller when the toolbar gets smaller.
926
 *
927
 * Since: 2.4
928
 */
929 930 931 932 933 934 935 936
void
gtk_tool_item_set_expand (GtkToolItem *tool_item,
			  gboolean     expand)
{
  g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
    
  expand = expand != FALSE;

937
  if (tool_item->priv->expand != expand)
938
    {
939
      tool_item->priv->expand = expand;
940 941 942 943 944
      gtk_widget_child_notify (GTK_WIDGET (tool_item), "expand");
      gtk_widget_queue_resize (GTK_WIDGET (tool_item));
    }
}

945 946
/**
 * gtk_tool_item_get_expand:
947
 * @tool_item: a #GtkToolItem 
948 949 950 951 952 953 954 955
 * 
 * Returns whether @tool_item is allocated extra space.
 * See gtk_tool_item_set_expand().
 * 
 * Return value: %TRUE if @tool_item is allocated extra space.
 * 
 * Since: 2.4
 **/
956 957 958 959 960 961 962 963
gboolean
gtk_tool_item_get_expand (GtkToolItem *tool_item)
{
  g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), FALSE);

  return tool_item->priv->expand;
}

964 965
/**
 * gtk_tool_item_set_homogeneous:
966
 * @tool_item: a #GtkToolItem 
967 968 969 970 971 972 973 974
 * @homogeneous: whether @tool_item is the same size as other homogeneous items
 * 
 * Sets whether @tool_item is to be allocated the same size as other
 * homogeneous items. The effect is that all homogeneous items will have
 * the same width as the widest of the items.
 * 
 * Since: 2.4
 **/
975 976 977 978 979 980 981 982
void
gtk_tool_item_set_homogeneous (GtkToolItem *tool_item,
			       gboolean     homogeneous)
{
  g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
    
  homogeneous = homogeneous != FALSE;

983
  if (tool_item->priv->homogeneous != homogeneous)
984
    {
985
      tool_item->priv->homogeneous = homogeneous;
986 987 988 989 990
      gtk_widget_child_notify (GTK_WIDGET (tool_item), "homogeneous");
      gtk_widget_queue_resize (GTK_WIDGET (tool_item));
    }
}

991 992
/**
 * gtk_tool_item_get_homogeneous:
993
 * @tool_item: a #GtkToolItem 
994 995 996 997 998
 * 
 * Returns whether @tool_item is the same size as other homogeneous
 * items. See gtk_tool_item_set_homogeneous().
 * 
 * Return value: %TRUE if the item is the same size as other homogeneous
999
 * items.
1000 1001 1002
 * 
 * Since: 2.4
 **/
1003 1004 1005 1006 1007 1008 1009 1010
gboolean
gtk_tool_item_get_homogeneous (GtkToolItem *tool_item)
{
  g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), FALSE);

  return tool_item->priv->homogeneous;
}

1011 1012 1013 1014 1015
/**
 * gtk_tool_item_get_is_important:
 * @tool_item: a #GtkToolItem
 * 
 * Returns whether @tool_item is considered important. See
1016
 * gtk_tool_item_set_is_important()
1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032
 * 
 * Return value: %TRUE if @tool_item is considered important.
 * 
 * Since: 2.4
 **/
gboolean
gtk_tool_item_get_is_important (GtkToolItem *tool_item)
{
  g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), FALSE);

  return tool_item->priv->is_important;
}

/**
 * gtk_tool_item_set_is_important:
 * @tool_item: a #GtkToolItem
Matthias Clasen's avatar
Matthias Clasen committed
1033
 * @is_important: whether the tool item should be considered important
1034 1035 1036 1037
 * 
 * Sets whether @tool_item should be considered important. The #GtkToolButton
 * class uses this property to determine whether to show or hide its label
 * when the toolbar style is %GTK_TOOLBAR_BOTH_HORIZ. The result is that
1038
 * only tool buttons with the "is_important" property set have labels, an
1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055
 * effect known as "priority text"
 * 
 * Since: 2.4
 **/
void
gtk_tool_item_set_is_important (GtkToolItem *tool_item, gboolean is_important)
{
  g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));

  is_important = is_important != FALSE;

  if (is_important != tool_item->priv->is_important)
    {
      tool_item->priv->is_important = is_important;

      gtk_widget_queue_resize (GTK_WIDGET (tool_item));

1056
      g_object_notify (G_OBJECT (tool_item), "is-important");
1057 1058 1059
    }
}

1060 1061
/**
 * gtk_tool_item_set_tooltip_text:
1062
 * @tool_item: a #GtkToolItem 
1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077
 * @text: text to be used as tooltip for @tool_item
 *
 * Sets the text to be displayed as tooltip on the item.
 * See gtk_widget_set_tooltip_text().
 *
 * Since: 2.12
 **/
void
gtk_tool_item_set_tooltip_text (GtkToolItem *tool_item,
			        const gchar *text)
{
  GtkWidget *child;

  g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));

Javier Jardón's avatar
Javier Jardón committed
1078
  child = gtk_bin_get_child (GTK_BIN (tool_item));
1079 1080 1081 1082 1083 1084
  if (child)
    gtk_widget_set_tooltip_text (child, text);
}

/**
 * gtk_tool_item_set_tooltip_markup:
1085
 * @tool_item: a #GtkToolItem 
1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100
 * @markup: markup text to be used as tooltip for @tool_item
 *
 * Sets the markup text to be displayed as tooltip on the item.
 * See gtk_widget_set_tooltip_markup().
 *
 * Since: 2.12
 **/
void
gtk_tool_item_set_tooltip_markup (GtkToolItem *tool_item,
				  const gchar *markup)
{
  GtkWidget *child;

  g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));

Javier Jardón's avatar
Javier Jardón committed
1101
  child = gtk_bin_get_child (GTK_BIN (tool_item));
1102 1103 1104 1105
  if (child)
    gtk_widget_set_tooltip_markup (child, markup);
}

1106 1107
/**
 * gtk_tool_item_set_use_drag_window:
1108 1109
 * @tool_item: a #GtkToolItem 
 * @use_drag_window: Whether @tool_item has a drag window.
1110
 * 
1111
 * Sets whether @tool_item has a drag window. When %TRUE the
1112
 * toolitem can be used as a drag source through gtk_drag_source_set().
1113 1114
 * When @tool_item has a drag window it will intercept all events,
 * even those that would otherwise be sent to a child of @tool_item.
1115 1116 1117
 * 
 * Since: 2.4
 **/
1118 1119 1120 1121 1122 1123 1124 1125
void
gtk_tool_item_set_use_drag_window (GtkToolItem *toolitem,
				   gboolean     use_drag_window)
{
  g_return_if_fail (GTK_IS_TOOL_ITEM (toolitem));

  use_drag_window = use_drag_window != FALSE;

1126
  if (toolitem->priv->use_drag_window != use_drag_window)
1127
    {
1128
      toolitem->priv->use_drag_window = use_drag_window;
1129 1130 1131
      
      if (use_drag_window)
	{
1132 1133
	  if (!toolitem->priv->drag_window &&
              gtk_widget_get_realized (GTK_WIDGET (toolitem)))
1134 1135
	    {
	      create_drag_window(toolitem);
1136
	      if (gtk_widget_get_mapped (GTK_WIDGET (toolitem)))
1137
		gdk_window_show (toolitem->priv->drag_window);
1138 1139 1140 1141 1142 1143 1144 1145 1146
	    }
	}
      else
	{
	  destroy_drag_window (toolitem);
	}
    }
}

1147 1148
/**
 * gtk_tool_item_get_use_drag_window:
1149
 * @tool_item: a #GtkToolItem 
1150
 * 
1151
 * Returns whether @tool_item has a drag window. See
1152 1153
 * gtk_tool_item_set_use_drag_window().
 * 
1154
 * Return value: %TRUE if @tool_item uses a drag window.
1155 1156 1157
 * 
 * Since: 2.4
 **/
1158 1159 1160 1161 1162 1163 1164 1165
gboolean
gtk_tool_item_get_use_drag_window (GtkToolItem *toolitem)
{
  g_return_val_if_fail (GTK_IS_TOOL_ITEM (toolitem), FALSE);

  return toolitem->priv->use_drag_window;
}

1166 1167
/**
 * gtk_tool_item_set_visible_horizontal:
1168 1169
 * @tool_item: a #GtkToolItem
 * @visible_horizontal: Whether @tool_item is visible when in horizontal mode
1170
 * 
1171
 * Sets whether @tool_item is visible when the toolbar is docked horizontally.
1172 1173 1174
 * 
 * Since: 2.4
 **/
1175 1176 1177 1178 1179 1180 1181 1182
void
gtk_tool_item_set_visible_horizontal (GtkToolItem *toolitem,
				      gboolean     visible_horizontal)
{
  g_return_if_fail (GTK_IS_TOOL_ITEM (toolitem));

  visible_horizontal = visible_horizontal != FALSE;

1183
  if (toolitem->priv->visible_horizontal != visible_horizontal)
1184
    {
1185
      toolitem->priv->visible_horizontal = visible_horizontal;
1186

1187
      g_object_notify (G_OBJECT (toolitem), "visible-horizontal");
1188 1189 1190 1191 1192

      gtk_widget_queue_resize (GTK_WIDGET (toolitem));
    }
}

1193 1194
/**
 * gtk_tool_item_get_visible_horizontal:
1195
 * @tool_item: a #GtkToolItem 
1196
 * 
1197
 * Returns whether the @tool_item is visible on toolbars that are
1198
 * docked horizontally.
1199
 * 
1200
 * Return value: %TRUE if @tool_item is visible on toolbars that are
1201 1202 1203 1204
 * docked horizontally.
 * 
 * Since: 2.4
 **/
1205 1206 1207 1208 1209
gboolean
gtk_tool_item_get_visible_horizontal (GtkToolItem *toolitem)
{
  g_return_val_if_fail (GTK_IS_TOOL_ITEM (toolitem), FALSE);

1210
  return toolitem->priv->visible_horizontal;
1211 1212
}

1213 1214
/**
 * gtk_tool_item_set_visible_vertical:
1215 1216
 * @tool_item: a #GtkToolItem 
 * @visible_vertical: whether @tool_item is visible when the toolbar
1217 1218
 * is in vertical mode
 *
1219
 * Sets whether @tool_item is visible when the toolbar is docked
1220 1221
 * vertically. Some tool items, such as text entries, are too wide to be
 * useful on a vertically docked toolbar. If @visible_vertical is %FALSE
1222
 * @tool_item will not appear on toolbars that are docked vertically.
1223 1224 1225
 * 
 * Since: 2.4
 **/
1226 1227 1228 1229 1230 1231 1232 1233
void
gtk_tool_item_set_visible_vertical (GtkToolItem *toolitem,
				    gboolean     visible_vertical)
{
  g_return_if_fail (GTK_IS_TOOL_ITEM (toolitem));

  visible_vertical = visible_vertical != FALSE;

1234
  if (toolitem->priv->visible_vertical != visible_vertical)
1235
    {
1236
      toolitem->priv->visible_vertical = visible_vertical;
1237

1238
      g_object_notify (G_OBJECT (toolitem), "visible-vertical");
1239 1240 1241 1242 1243

      gtk_widget_queue_resize (GTK_WIDGET (toolitem));
    }
}

1244 1245
/**
 * gtk_tool_item_get_visible_vertical:
1246
 * @tool_item: a #GtkToolItem 
1247
 * 
1248
 * Returns whether @tool_item is visible when the toolbar is docked vertically.
1249 1250
 * See gtk_tool_item_set_visible_vertical().
 * 
1251
 * Return value: Whether @tool_item is visible when the toolbar is docked vertically
1252 1253 1254
 * 
 * Since: 2.4
 **/
1255 1256 1257 1258 1259
gboolean
gtk_tool_item_get_visible_vertical (GtkToolItem *toolitem)
{
  g_return_val_if_fail (GTK_IS_TOOL_ITEM (toolitem), FALSE);

1260
  return toolitem->priv->visible_vertical;
1261 1262
}

1263 1264
/**
 * gtk_tool_item_retrieve_proxy_menu_item:
1265
 * @tool_item: a #GtkToolItem 
1266 1267 1268 1269
 * 
 * Returns the #GtkMenuItem that was last set by
 * gtk_tool_item_set_proxy_menu_item(), ie. the #GtkMenuItem
 * that is going to appear in the overflow menu.
1270 1271
 *
 * Return value: (transfer none): The #GtkMenuItem that is going to appear in the
1272
 * overflow menu for @tool_item.
1273
 *
1274 1275
 * Since: 2.4
 **/
1276 1277 1278 1279 1280 1281 1282
GtkWidget *
gtk_tool_item_retrieve_proxy_menu_item (GtkToolItem *tool_item)
{
  gboolean retval;
  
  g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), NULL);

1283 1284
  g_signal_emit (tool_item, toolitem_signals[CREATE_MENU_PROXY], 0,
		 &retval);
1285
  
1286
  return tool_item->priv->menu_item;
1287 1288
}

1289 1290
/**
 * gtk_tool_item_get_proxy_menu_item:
1291
 * @tool_item: a #GtkToolItem
1292
 * @menu_item_id: a string used to identify the menu item
1293
 *
1294 1295 1296
 * If @menu_item_id matches the string passed to
 * gtk_tool_item_set_proxy_menu_item() return the corresponding #GtkMenuItem.
 *
1297 1298 1299 1300 1301 1302 1303 1304 1305
 * Custom subclasses of #GtkToolItem should use this function to
 * update their menu item when the #GtkToolItem changes. That the
 * @menu_item_id<!-- -->s must match ensures that a #GtkToolItem
 * will not inadvertently change a menu item that they did not create.
 *
 * Return value: (transfer none): The #GtkMenuItem passed to
 *     gtk_tool_item_set_proxy_menu_item(), if the @menu_item_id<!-- -->s
 *     match.
 *
1306 1307
 * Since: 2.4
 **/
1308 1309 1310 1311 1312 1313 1314
GtkWidget *
gtk_tool_item_get_proxy_menu_item (GtkToolItem *tool_item,
				   const gchar *menu_item_id)
{
  g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), NULL);
  g_return_val_if_fail (menu_item_id != NULL, NULL);

1315 1316
  if (tool_item->priv->menu_item_id && strcmp (tool_item->priv->menu_item_id, menu_item_id) == 0)
    return tool_item->priv->menu_item;
1317 1318 1319 1320

  return NULL;
}

1321
/**
Matthias Clasen's avatar
Matthias Clasen committed
1322
 * gtk_tool_item_rebuild_menu:
1323
 * @tool_item: a #GtkToolItem
Matthias Clasen's avatar
Matthias Clasen committed
1324
 *
1325 1326 1327 1328 1329
 * Calling this function signals to the toolbar that the
 * overflow menu item for @tool_item has changed. If the
 * overflow menu is visible when this function it called,
 * the menu will be rebuilt.
 *
Matthias Clasen's avatar
Matthias Clasen committed
1330 1331 1332
 * The function must be called when the tool item changes what it
 * will do in response to the #GtkToolItem::create-menu-proxy signal.
 *
1333
 * Since: 2.6
Matthias Clasen's avatar
Matthias Clasen committed
1334
 */
1335 1336 1337
void
gtk_tool_item_rebuild_menu (GtkToolItem *tool_item)
{
1338
  GtkWidget *parent;
1339
  GtkWidget *widget;
1340

1341 1342 1343
  g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));

  widget = GTK_WIDGET (tool_item);
1344

1345 1346 1347
  parent = gtk_widget_get_parent (widget);
  if (GTK_IS_TOOL_SHELL (parent))
    gtk_tool_shell_rebuild_menu (GTK_TOOL_SHELL (parent));
1348 1349
}

1350 1351
/**
 * gtk_tool_item_set_proxy_menu_item:
1352
 * @tool_item: a #GtkToolItem
1353 1354 1355 1356 1357 1358 1359 1360 1361
 * @menu_item_id: a string used to identify @menu_item
 * @menu_item: a #GtkMenuItem to be used in the overflow menu
 * 
 * Sets the #GtkMenuItem used in the toolbar overflow menu. The
 * @menu_item_id is used to identify the caller of this function and
 * should also be used with gtk_tool_item_get_proxy_menu_item().
 * 
 * Since: 2.4
 **/
1362 1363 1364 1365 1366 1367 1368 1369 1370
void
gtk_tool_item_set_proxy_menu_item (GtkToolItem *tool_item,
				   const gchar *menu_item_id,
				   GtkWidget   *menu_item)
{
  g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
  g_return_if_fail (menu_item == NULL || GTK_IS_MENU_ITEM (menu_item));
  g_return_if_fail (menu_item_id != NULL);

1371
  g_free (tool_item->priv->menu_item_id);
1372
      
1373
  tool_item->priv->menu_item_id = g_strdup (menu_item_id);
1374

1375
  if (tool_item->priv->menu_item != menu_item)
1376
    {
1377
      if (tool_item->priv->menu_item)
1378
	g_object_unref (tool_item->priv->menu_item);
1379 1380 1381
      
      if (menu_item)
	{
1382
	  g_object_ref_sink (menu_item);
1383 1384

	  gtk_widget_set_sensitive (menu_item,
1385
				    gtk_widget_get_sensitive (GTK_WIDGET (tool_item)));
1386 1387
	}
      
1388
      tool_item->priv->menu_item = menu_item;
1389 1390
    }
}
1391

1392
/**
1393 1394 1395 1396 1397 1398 1399
 * gtk_tool_item_toolbar_reconfigured:
 * @tool_item: a #GtkToolItem
 *
 * Emits the signal #GtkToolItem::toolbar_reconfigured on @tool_item.
 * #GtkToolbar and other #GtkToolShell implementations use this function
 * to notify children, when some aspect of their configuration changes.
 *
1400
 * Since: 2.14
1401
 **/
1402
void
1403
gtk_tool_item_toolbar_reconfigured (GtkToolItem *tool_item)
1404
{
1405 1406 1407 1408 1409 1410 1411
  /* The slightely inaccurate name "gtk_tool_item_toolbar_reconfigured" was
   * choosen over "gtk_tool_item_tool_shell_reconfigured", since the function
   * emits the "toolbar-reconfigured" signal, not "tool-shell-reconfigured".
   * Its not possible to rename the signal, and emitting another name than
   * indicated by the function name would be quite confusing. That's the
   * price of providing stable APIs.
   */
1412 1413 1414 1415
  g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));

  g_signal_emit (tool_item, toolitem_signals[TOOLBAR_RECONFIGURED], 0);
  
1416 1417
  if (tool_item->priv->drag_window)
    gdk_window_raise (tool_item->priv->drag_window);
Matthias Clasen's avatar
Matthias Clasen committed
1418 1419

  gtk_widget_queue_resize (GTK_WIDGET (tool_item));
1420
}