evolution-3.6.4/shell/e-shell-switcher.c

Location Tool Test ID Function Issue
e-shell-switcher.c:130:37 clang-analyzer Access to field 'data' results in a dereference of a null pointer (loaded from field 'proxies')
e-shell-switcher.c:130:37 clang-analyzer Access to field 'data' results in a dereference of a null pointer (loaded from field 'proxies')
  1 /*
  2  * e-shell-switcher.c
  3  *
  4  * This program is free software; you can redistribute it and/or
  5  * modify it under the terms of the GNU Lesser General Public
  6  * License as published by the Free Software Foundation; either
  7  * version 2 of the License, or (at your option) version 3.
  8  *
  9  * This program is distributed in the hope that it will be useful,
 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 12  * Lesser General Public License for more details.
 13  *
 14  * You should have received a copy of the GNU Lesser General Public
 15  * License along with the program; if not, see <http://www.gnu.org/licenses/>
 16  *
 17  *
 18  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
 19  *
 20  */
 21 
 22 /**
 23  * SECTION: e-shell-switcher
 24  * @short_description: buttons for switching views
 25  * @include: shell/e-shell-switcher.h
 26  **/
 27 
 28 #ifdef HAVE_CONFIG_H
 29 #include <config.h>
 30 #endif
 31 
 32 #include "e-shell-switcher.h"
 33 
 34 #include <glib/gi18n.h>
 35 #include <libebackend/libebackend.h>
 36 
 37 #define E_SHELL_SWITCHER_GET_PRIVATE(obj) \
 38 	(G_TYPE_INSTANCE_GET_PRIVATE \
 39 	((obj), E_TYPE_SHELL_SWITCHER, EShellSwitcherPrivate))
 40 
 41 #define E_SHELL_SWITCHER_GET_PRIVATE(obj) \
 42 	(G_TYPE_INSTANCE_GET_PRIVATE \
 43 	((obj), E_TYPE_SHELL_SWITCHER, EShellSwitcherPrivate))
 44 
 45 #define H_PADDING 6
 46 #define V_PADDING 6
 47 
 48 struct _EShellSwitcherPrivate {
 49 	GList *proxies;
 50 	gboolean style_set;
 51 	GtkToolbarStyle style;
 52 	GtkSettings *settings;
 53 	gulong settings_handler_id;
 54 	gboolean toolbar_visible;
 55 };
 56 
 57 enum {
 58 	PROP_0,
 59 	PROP_TOOLBAR_STYLE,
 60 	PROP_TOOLBAR_VISIBLE
 61 };
 62 
 63 enum {
 64 	STYLE_CHANGED,
 65 	LAST_SIGNAL
 66 };
 67 
 68 static guint signals[LAST_SIGNAL];
 69 
 70 /* Forward Declarations */
 71 static void shell_switcher_tool_shell_iface_init (GtkToolShellIface *iface);
 72 
 73 G_DEFINE_TYPE_WITH_CODE (
 74 	EShellSwitcher,
 75 	e_shell_switcher,
 76 	GTK_TYPE_BIN,
 77 	G_IMPLEMENT_INTERFACE (
 78 		E_TYPE_EXTENSIBLE, NULL)
 79 	G_IMPLEMENT_INTERFACE (
 80 		GTK_TYPE_TOOL_SHELL,
 81 		shell_switcher_tool_shell_iface_init))
 82 
 83 static gint
 84 shell_switcher_layout_actions (EShellSwitcher *switcher)
 85 {
 86 	GtkAllocation allocation;
 87 	gint num_btns = g_list_length (switcher->priv->proxies), btns_per_row;
 88 	GList **rows, *p;
 89 	gboolean icons_only;
 90 	gint row_number;
 91 	gint max_width = 0;
 92 	gint max_height = 0;
 93 	gint row_last;
 94 	gint x, y;
 95 	gint i;
 96 
 97 	gtk_widget_get_allocation (GTK_WIDGET (switcher), &allocation);
 98 
 99 	y = allocation.y + allocation.height;
100 
101 	if (num_btns == 0)
102 		return allocation.height;
103 
104 	icons_only = (switcher->priv->style == GTK_TOOLBAR_ICONS);
105 
106 	/* Figure out the max width and height. */
107 	for (p = switcher->priv->proxies; p != NULL; p = p->next) {
108 		GtkWidget *widget = p->data;
109 		GtkRequisition requisition;
110 
111 		gtk_widget_get_preferred_size (widget, &requisition, NULL);
112 		max_height = MAX (max_height, requisition.height);
113 		max_width = MAX (max_width, requisition.width);
114 	}
115 
116 	/* Figure out how many rows and columns we'll use. */
117 	btns_per_row = MAX (1, allocation.width / (max_width + H_PADDING));
118 	if (!icons_only) {
119 		/* If using text buttons, we want to try to have a
120 		 * completely filled-in grid, but if we can't, we want
121 		 * the odd row to have just a single button. */
122 		while (btns_per_row > 0 && num_btns % btns_per_row > 1)
123 			btns_per_row--;
124 	}
125 
126 	/* Assign buttons to rows. */
127 	rows = g_new0 (GList *, num_btns / btns_per_row + 1);
128 
129 	if (!icons_only && num_btns % btns_per_row != 0) {
130 		rows[0] = g_list_append (rows[0], switcher->priv->proxies->data);
Access to field 'data' results in a dereference of a null pointer (loaded from field 'proxies')
(emitted by clang-analyzer)

TODO: a detailed trace is available in the data model (not yet rendered in this report)

Access to field 'data' results in a dereference of a null pointer (loaded from field 'proxies')
(emitted by clang-analyzer)

TODO: a detailed trace is available in the data model (not yet rendered in this report)

131 132 p = switcher->priv->proxies->next; 133 row_number = p ? 1 : 0; 134 } else { 135 p = switcher->priv->proxies; 136 row_number = 0; 137 } 138 139 for (; p != NULL; p = p->next) { 140 GtkWidget *widget = p->data; 141 142 if (g_list_length (rows[row_number]) == btns_per_row) 143 row_number++; 144 145 rows[row_number] = g_list_append (rows[row_number], widget); 146 } 147 148 row_last = row_number; 149 150 /* Layout the buttons. */ 151 for (i = row_last; i >= 0; i--) { 152 gint len, extra_width; 153 154 x = H_PADDING + allocation.x; 155 y -= max_height; 156 len = g_list_length (rows[i]); 157 if (!icons_only) 158 extra_width = 159 (allocation.width - (len * max_width) - 160 (len * H_PADDING)) / len; 161 else 162 extra_width = 0; 163 for (p = rows[i]; p != NULL; p = p->next) { 164 GtkAllocation child_allocation; 165 166 child_allocation.x = x; 167 child_allocation.y = y; 168 child_allocation.width = max_width + extra_width; 169 child_allocation.height = max_height; 170 171 gtk_widget_size_allocate (GTK_WIDGET (p->data), &child_allocation); 172 173 x += child_allocation.width + H_PADDING; 174 } 175 176 y -= V_PADDING; 177 } 178 179 for (i = 0; i <= row_last; i++) 180 g_list_free (rows[i]); 181 g_free (rows); 182 183 return y - allocation.y; 184 } 185 186 static void 187 shell_switcher_toolbar_style_changed_cb (EShellSwitcher *switcher) 188 { 189 if (!switcher->priv->style_set) { 190 switcher->priv->style_set = TRUE; 191 e_shell_switcher_unset_style (switcher); 192 } 193 } 194 195 static void 196 shell_switcher_set_property (GObject *object, 197 guint property_id, 198 const GValue *value, 199 GParamSpec *pspec) 200 { 201 switch (property_id) { 202 case PROP_TOOLBAR_STYLE: 203 e_shell_switcher_set_style ( 204 E_SHELL_SWITCHER (object), 205 g_value_get_enum (value)); 206 return; 207 208 case PROP_TOOLBAR_VISIBLE: 209 e_shell_switcher_set_visible ( 210 E_SHELL_SWITCHER (object), 211 g_value_get_boolean (value)); 212 return; 213 } 214 215 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); 216 } 217 218 static void 219 shell_switcher_get_property (GObject *object, 220 guint property_id, 221 GValue *value, 222 GParamSpec *pspec) 223 { 224 switch (property_id) { 225 case PROP_TOOLBAR_STYLE: 226 g_value_set_enum ( 227 value, e_shell_switcher_get_style ( 228 E_SHELL_SWITCHER (object))); 229 return; 230 231 case PROP_TOOLBAR_VISIBLE: 232 g_value_set_boolean ( 233 value, e_shell_switcher_get_visible ( 234 E_SHELL_SWITCHER (object))); 235 return; 236 } 237 238 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); 239 } 240 241 static void 242 shell_switcher_dispose (GObject *object) 243 { 244 EShellSwitcherPrivate *priv; 245 246 priv = E_SHELL_SWITCHER_GET_PRIVATE (object); 247 248 while (priv->proxies != NULL) { 249 GtkWidget *widget = priv->proxies->data; 250 gtk_container_remove (GTK_CONTAINER (object), widget); 251 } 252 253 /* Chain up to parent's dispose() method. */ 254 G_OBJECT_CLASS (e_shell_switcher_parent_class)->dispose (object); 255 } 256 257 static void 258 shell_switcher_get_preferred_width (GtkWidget *widget, 259 gint *minimum, 260 gint *natural) 261 { 262 EShellSwitcherPrivate *priv; 263 GtkWidget *child; 264 GList *iter; 265 266 priv = E_SHELL_SWITCHER_GET_PRIVATE (widget); 267 268 *minimum = *natural = 0; 269 270 child = gtk_bin_get_child (GTK_BIN (widget)); 271 if (child != NULL) 272 gtk_widget_get_preferred_width (child, minimum, natural); 273 274 if (!priv->toolbar_visible) 275 return; 276 277 for (iter = priv->proxies; iter != NULL; iter = iter->next) { 278 GtkWidget *widget_proxy = iter->data; 279 gint child_min, child_nat; 280 281 gtk_widget_get_preferred_width ( 282 widget_proxy, &child_min, &child_nat); 283 284 child_min += H_PADDING; 285 child_nat += H_PADDING; 286 287 *minimum = MAX (*minimum, child_min); 288 *natural = MAX (*natural, child_nat); 289 } 290 } 291 292 static void 293 shell_switcher_get_preferred_height (GtkWidget *widget, 294 gint *minimum, 295 gint *natural) 296 { 297 EShellSwitcherPrivate *priv; 298 GtkWidget *child; 299 GList *iter; 300 301 priv = E_SHELL_SWITCHER_GET_PRIVATE (widget); 302 303 *minimum = *natural = 0; 304 305 child = gtk_bin_get_child (GTK_BIN (widget)); 306 if (child != NULL) 307 gtk_widget_get_preferred_height (child, minimum, natural); 308 309 if (!priv->toolbar_visible) 310 return; 311 312 for (iter = priv->proxies; iter != NULL; iter = iter->next) { 313 GtkWidget *widget = iter->data; 314 gint child_min, child_nat; 315 316 gtk_widget_get_preferred_height ( 317 widget, &child_min, &child_nat); 318 319 child_min += V_PADDING; 320 child_nat += V_PADDING; 321 322 *minimum += child_min; 323 *natural += child_nat; 324 } 325 } 326 327 static void 328 shell_switcher_size_allocate (GtkWidget *widget, 329 GtkAllocation *allocation) 330 { 331 EShellSwitcher *switcher; 332 GtkAllocation child_allocation; 333 GtkWidget *child; 334 gint height; 335 336 switcher = E_SHELL_SWITCHER (widget); 337 338 gtk_widget_set_allocation (widget, allocation); 339 340 if (switcher->priv->toolbar_visible) 341 height = shell_switcher_layout_actions (switcher); 342 else 343 height = allocation->height; 344 345 child_allocation.x = allocation->x; 346 child_allocation.y = allocation->y; 347 child_allocation.width = allocation->width; 348 child_allocation.height = height; 349 350 child = gtk_bin_get_child (GTK_BIN (widget)); 351 if (child != NULL) 352 gtk_widget_size_allocate (child, &child_allocation); 353 } 354 355 static void 356 shell_switcher_screen_changed (GtkWidget *widget, 357 GdkScreen *previous_screen) 358 { 359 EShellSwitcherPrivate *priv; 360 GtkSettings *settings; 361 362 priv = E_SHELL_SWITCHER_GET_PRIVATE (widget); 363 364 if (gtk_widget_has_screen (widget)) 365 settings = gtk_widget_get_settings (widget); 366 else 367 settings = NULL; 368 369 if (settings == priv->settings) 370 return; 371 372 if (priv->settings != NULL) { 373 g_signal_handler_disconnect ( 374 priv->settings, priv->settings_handler_id); 375 g_object_unref (priv->settings); 376 } 377 378 if (settings != NULL) { 379 priv->settings = g_object_ref (settings); 380 priv->settings_handler_id = g_signal_connect_swapped ( 381 settings, "notify::gtk-toolbar-style", 382 G_CALLBACK (shell_switcher_toolbar_style_changed_cb), 383 widget); 384 } else 385 priv->settings = NULL; 386 387 shell_switcher_toolbar_style_changed_cb (E_SHELL_SWITCHER (widget)); 388 } 389 390 static void 391 shell_switcher_remove (GtkContainer *container, 392 GtkWidget *widget) 393 { 394 EShellSwitcherPrivate *priv; 395 GList *link; 396 397 priv = E_SHELL_SWITCHER_GET_PRIVATE (container); 398 399 /* Look in the internal widgets first. */ 400 401 link = g_list_find (priv->proxies, widget); 402 if (link != NULL) { 403 GtkWidget *widget = link->data; 404 405 gtk_widget_unparent (widget); 406 priv->proxies = g_list_delete_link (priv->proxies, link); 407 gtk_widget_queue_resize (GTK_WIDGET (container)); 408 return; 409 } 410 411 /* Chain up to parent's remove() method. */ 412 GTK_CONTAINER_CLASS (e_shell_switcher_parent_class)->remove ( 413 container, widget); 414 } 415 416 static void 417 shell_switcher_forall (GtkContainer *container, 418 gboolean include_internals, 419 GtkCallback callback, 420 gpointer callback_data) 421 { 422 EShellSwitcherPrivate *priv; 423 424 priv = E_SHELL_SWITCHER_GET_PRIVATE (container); 425 426 if (include_internals) 427 g_list_foreach ( 428 priv->proxies, (GFunc) callback, callback_data); 429 430 /* Chain up to parent's forall() method. */ 431 GTK_CONTAINER_CLASS (e_shell_switcher_parent_class)->forall ( 432 container, include_internals, callback, callback_data); 433 } 434 435 static void 436 shell_switcher_style_changed (EShellSwitcher *switcher, 437 GtkToolbarStyle style) 438 { 439 if (switcher->priv->style == style) 440 return; 441 442 switcher->priv->style = style; 443 444 g_list_foreach ( 445 switcher->priv->proxies, 446 (GFunc) gtk_tool_item_toolbar_reconfigured, NULL); 447 448 gtk_widget_queue_resize (GTK_WIDGET (switcher)); 449 g_object_notify (G_OBJECT (switcher), "toolbar-style"); 450 } 451 452 static GtkIconSize 453 shell_switcher_get_icon_size (GtkToolShell *shell) 454 { 455 return GTK_ICON_SIZE_LARGE_TOOLBAR; 456 } 457 458 static GtkOrientation 459 shell_switcher_get_orientation (GtkToolShell *shell) 460 { 461 return GTK_ORIENTATION_HORIZONTAL; 462 } 463 464 static GtkToolbarStyle 465 shell_switcher_get_style (GtkToolShell *shell) 466 { 467 return e_shell_switcher_get_style (E_SHELL_SWITCHER (shell)); 468 } 469 470 static GtkReliefStyle 471 shell_switcher_get_relief_style (GtkToolShell *shell) 472 { 473 return GTK_RELIEF_NORMAL; 474 } 475 476 static gfloat 477 shell_switcher_get_text_alignment (GtkToolShell *shell) 478 { 479 return 0.0; 480 } 481 482 static void 483 e_shell_switcher_class_init (EShellSwitcherClass *class) 484 { 485 GObjectClass *object_class; 486 GtkWidgetClass *widget_class; 487 GtkContainerClass *container_class; 488 489 g_type_class_add_private (class, sizeof (EShellSwitcherPrivate)); 490 491 object_class = G_OBJECT_CLASS (class); 492 object_class->set_property = shell_switcher_set_property; 493 object_class->get_property = shell_switcher_get_property; 494 object_class->dispose = shell_switcher_dispose; 495 496 widget_class = GTK_WIDGET_CLASS (class); 497 widget_class->get_preferred_width = shell_switcher_get_preferred_width; 498 widget_class->get_preferred_height = shell_switcher_get_preferred_height; 499 widget_class->size_allocate = shell_switcher_size_allocate; 500 widget_class->screen_changed = shell_switcher_screen_changed; 501 502 container_class = GTK_CONTAINER_CLASS (class); 503 container_class->remove = shell_switcher_remove; 504 container_class->forall = shell_switcher_forall; 505 506 class->style_changed = shell_switcher_style_changed; 507 508 /** 509 * EShellSwitcher:toolbar-style 510 * 511 * The switcher's toolbar style. 512 **/ 513 g_object_class_install_property ( 514 object_class, 515 PROP_TOOLBAR_STYLE, 516 g_param_spec_enum ( 517 "toolbar-style", 518 "Toolbar Style", 519 "The switcher's toolbar style", 520 GTK_TYPE_TOOLBAR_STYLE, 521 E_SHELL_SWITCHER_DEFAULT_TOOLBAR_STYLE, 522 G_PARAM_READWRITE | 523 G_PARAM_CONSTRUCT)); 524 525 /** 526 * EShellSwitcher:toolbar-visible 527 * 528 * Whether the switcher is visible. 529 **/ 530 g_object_class_install_property ( 531 object_class, 532 PROP_TOOLBAR_VISIBLE, 533 g_param_spec_boolean ( 534 "toolbar-visible", 535 "Toolbar Visible", 536 "Whether the switcher is visible", 537 TRUE, 538 G_PARAM_READWRITE | 539 G_PARAM_CONSTRUCT)); 540 541 /** 542 * EShellSwitcher::style-changed 543 * @switcher: the #EShellSwitcher which emitted the signal 544 * @style: the new #GtkToolbarStyle of the switcher 545 * 546 * Emitted when the style of the switcher changes. 547 **/ 548 signals[STYLE_CHANGED] = g_signal_new ( 549 "style-changed", 550 G_OBJECT_CLASS_TYPE (class), 551 G_SIGNAL_RUN_FIRST, 552 G_STRUCT_OFFSET (EShellSwitcherClass, style_changed), 553 NULL, NULL, 554 g_cclosure_marshal_VOID__ENUM, 555 G_TYPE_NONE, 1, 556 GTK_TYPE_TOOLBAR_STYLE); 557 } 558 559 static void 560 e_shell_switcher_init (EShellSwitcher *switcher) 561 { 562 switcher->priv = E_SHELL_SWITCHER_GET_PRIVATE (switcher); 563 564 gtk_widget_set_has_window (GTK_WIDGET (switcher), FALSE); 565 566 e_extensible_load_extensions (E_EXTENSIBLE (switcher)); 567 } 568 569 static void 570 shell_switcher_tool_shell_iface_init (GtkToolShellIface *iface) 571 { 572 iface->get_icon_size = shell_switcher_get_icon_size; 573 iface->get_orientation = shell_switcher_get_orientation; 574 iface->get_style = shell_switcher_get_style; 575 iface->get_relief_style = shell_switcher_get_relief_style; 576 iface->get_text_alignment = shell_switcher_get_text_alignment; 577 } 578 579 /** 580 * e_shell_switcher_new: 581 * 582 * Creates a new #EShellSwitcher instance. 583 * 584 * Returns: a new #EShellSwitcher instance 585 **/ 586 GtkWidget * 587 e_shell_switcher_new (void) 588 { 589 return g_object_new (E_TYPE_SHELL_SWITCHER, NULL); 590 } 591 592 /* 593 * gtk+ doesn't give us what we want - a middle click, 594 * option on toolbar items, so we have to get it by force. 595 */ 596 static GtkButton * 597 tool_item_get_button (GtkWidget *widget) 598 { 599 GtkWidget *child; 600 601 g_return_val_if_fail (GTK_IS_TOOL_ITEM (widget), NULL); 602 603 child = gtk_bin_get_child (GTK_BIN (widget)); 604 if (child != NULL && GTK_IS_BUTTON (child)) 605 return GTK_BUTTON (child); 606 else 607 return NULL; 608 } 609 610 static gboolean 611 tool_item_button_cb (GtkWidget *internal_widget, 612 GdkEventButton *event, 613 GtkAction *action) 614 { 615 g_return_val_if_fail (GTK_IS_ACTION (action), FALSE); 616 617 if (event->button == 2) { 618 gtk_action_activate (action); 619 return TRUE; 620 } 621 return FALSE; 622 } 623 624 /** 625 * e_shell_switcher_add_action: 626 * @switcher: an #EShellSwitcher 627 * @switch_action: a #GtkAction 628 * @new_window_action: a #GtkAction 629 * 630 * Adds a button to @switcher that proxies for @switcher_action. 631 * Switcher buttons appear in the order they were added. A middle 632 * click opens a new window of this type. 633 * 634 * #EShellWindow adds switcher actions in the order given by the 635 * <structfield>sort_order</structfield> field in #EShellBackendClass. 636 **/ 637 void 638 e_shell_switcher_add_action (EShellSwitcher *switcher, 639 GtkAction *switch_action, 640 GtkAction *new_window_action) 641 { 642 GtkWidget *widget; 643 GtkButton *button; 644 645 g_return_if_fail (E_IS_SHELL_SWITCHER (switcher)); 646 g_return_if_fail (GTK_IS_ACTION (switch_action)); 647 g_return_if_fail (GTK_IS_ACTION (new_window_action)); 648 649 g_object_ref (switch_action); 650 widget = gtk_action_create_tool_item (switch_action); 651 gtk_tool_item_set_is_important (GTK_TOOL_ITEM (widget), TRUE); 652 gtk_widget_show (widget); 653 654 button = tool_item_get_button (widget); 655 if (button != NULL) 656 g_signal_connect ( 657 button, "button-release-event", 658 G_CALLBACK (tool_item_button_cb), 659 new_window_action); 660 661 switcher->priv->proxies = g_list_append ( 662 switcher->priv->proxies, widget); 663 664 gtk_widget_set_parent (widget, GTK_WIDGET (switcher)); 665 gtk_widget_queue_resize (GTK_WIDGET (switcher)); 666 } 667 668 /** 669 * e_shell_switcher_get_style: 670 * @switcher: an #EShellSwitcher 671 * 672 * Returns whether @switcher has text, icons or both. 673 * 674 * Returns: the current style of @shell 675 **/ 676 GtkToolbarStyle 677 e_shell_switcher_get_style (EShellSwitcher *switcher) 678 { 679 g_return_val_if_fail ( 680 E_IS_SHELL_SWITCHER (switcher), 681 E_SHELL_SWITCHER_DEFAULT_TOOLBAR_STYLE); 682 683 return switcher->priv->style; 684 } 685 686 /** 687 * e_shell_switcher_set_style: 688 * @switcher: an #EShellSwitcher 689 * @style: the new style for @switcher 690 * 691 * Alters the view of @switcher to display either icons only, text only, 692 * or both. 693 **/ 694 void 695 e_shell_switcher_set_style (EShellSwitcher *switcher, 696 GtkToolbarStyle style) 697 { 698 g_return_if_fail (E_IS_SHELL_SWITCHER (switcher)); 699 700 switcher->priv->style_set = TRUE; 701 g_signal_emit (switcher, signals[STYLE_CHANGED], 0, style); 702 } 703 704 /** 705 * e_shell_switcher_unset_style: 706 * @switcher: an #EShellSwitcher 707 * 708 * Unsets a switcher style set with e_shell_switcher_set_style(), so 709 * that user preferences will be used to determine the switcher style. 710 **/ 711 void 712 e_shell_switcher_unset_style (EShellSwitcher *switcher) 713 { 714 GtkSettings *settings; 715 GtkToolbarStyle style; 716 717 g_return_if_fail (E_IS_SHELL_SWITCHER (switcher)); 718 719 if (!switcher->priv->style_set) 720 return; 721 722 settings = switcher->priv->settings; 723 if (settings != NULL) 724 g_object_get (settings, "gtk-toolbar-style", &style, NULL); 725 else 726 style = E_SHELL_SWITCHER_DEFAULT_TOOLBAR_STYLE; 727 728 if (style == GTK_TOOLBAR_BOTH) 729 style = GTK_TOOLBAR_BOTH_HORIZ; 730 731 if (style != switcher->priv->style) 732 g_signal_emit (switcher, signals[STYLE_CHANGED], 0, style); 733 734 switcher->priv->style_set = FALSE; 735 } 736 737 /** 738 * e_shell_switcher_get_visible: 739 * @switcher: an #EShellSwitcher 740 * 741 * Returns %TRUE if the switcher buttons are visible. 742 * 743 * Note that switcher button visibility is different than 744 * @switcher<!-- -->'s GTK_VISIBLE flag, since #EShellSwitcher 745 * is actually a container widget for #EShellSidebar. 746 * 747 * Returns: %TRUE if the switcher buttons are visible 748 **/ 749 gboolean 750 e_shell_switcher_get_visible (EShellSwitcher *switcher) 751 { 752 g_return_val_if_fail (E_IS_SHELL_SWITCHER (switcher), FALSE); 753 754 return switcher->priv->toolbar_visible; 755 } 756 757 /** 758 * e_shell_switcher_set_visible: 759 * @switcher: an #EShellSwitcher 760 * @visible: whether the switcher buttons should be visible 761 * 762 * Sets the switcher button visiblity to @visible. 763 * 764 * Note that switcher button visibility is different than 765 * @switcher<!-- -->'s GTK_VISIBLE flag, since #EShellSwitcher 766 * is actually a container widget for #EShellSidebar. 767 **/ 768 void 769 e_shell_switcher_set_visible (EShellSwitcher *switcher, 770 gboolean visible) 771 { 772 GList *iter; 773 774 g_return_if_fail (E_IS_SHELL_SWITCHER (switcher)); 775 776 if (switcher->priv->toolbar_visible == visible) 777 return; 778 779 switcher->priv->toolbar_visible = visible; 780 781 for (iter = switcher->priv->proxies; iter != NULL; iter = iter->next) 782 g_object_set (iter->data, "visible", visible, NULL); 783 784 gtk_widget_queue_resize (GTK_WIDGET (switcher)); 785 786 g_object_notify (G_OBJECT (switcher), "toolbar-visible"); 787 }