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

No issues found

  1 /*
  2  * e-shell-sidebar.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-sidebar
 24  * @short_description: the left side of the main window
 25  * @include: shell/e-shell-sidebar.h
 26  **/
 27 
 28 #ifdef HAVE_CONFIG_H
 29 #include <config.h>
 30 #endif
 31 
 32 #include "e-shell-sidebar.h"
 33 
 34 #include <libebackend/libebackend.h>
 35 
 36 #include <libevolution-utils/e-alert-sink.h>
 37 #include <e-util/e-unicode.h>
 38 #include <shell/e-shell-view.h>
 39 
 40 #define E_SHELL_SIDEBAR_GET_PRIVATE(obj) \
 41 	(G_TYPE_INSTANCE_GET_PRIVATE \
 42 	((obj), E_TYPE_SHELL_SIDEBAR, EShellSidebarPrivate))
 43 
 44 struct _EShellSidebarPrivate {
 45 
 46 	gpointer shell_view;  /* weak pointer */
 47 
 48 	GtkWidget *event_box;
 49 
 50 	gchar *icon_name;
 51 	gchar *primary_text;
 52 	gchar *secondary_text;
 53 };
 54 
 55 enum {
 56 	PROP_0,
 57 	PROP_ICON_NAME,
 58 	PROP_PRIMARY_TEXT,
 59 	PROP_SECONDARY_TEXT,
 60 	PROP_SHELL_VIEW
 61 };
 62 
 63 /* Forward Declarations */
 64 static void	e_shell_sidebar_alert_sink_init
 65 					(EAlertSinkInterface *interface);
 66 
 67 G_DEFINE_TYPE_WITH_CODE (
 68 	EShellSidebar,
 69 	e_shell_sidebar,
 70 	GTK_TYPE_BIN,
 71 	G_IMPLEMENT_INTERFACE (
 72 		E_TYPE_ALERT_SINK, e_shell_sidebar_alert_sink_init)
 73 	G_IMPLEMENT_INTERFACE (
 74 		E_TYPE_EXTENSIBLE, NULL))
 75 
 76 static void
 77 shell_sidebar_set_shell_view (EShellSidebar *shell_sidebar,
 78                               EShellView *shell_view)
 79 {
 80 	g_return_if_fail (shell_sidebar->priv->shell_view == NULL);
 81 
 82 	shell_sidebar->priv->shell_view = shell_view;
 83 
 84 	g_object_add_weak_pointer (
 85 		G_OBJECT (shell_view),
 86 		&shell_sidebar->priv->shell_view);
 87 }
 88 
 89 static void
 90 shell_sidebar_set_property (GObject *object,
 91                             guint property_id,
 92                             const GValue *value,
 93                             GParamSpec *pspec)
 94 {
 95 	switch (property_id) {
 96 		case PROP_ICON_NAME:
 97 			e_shell_sidebar_set_icon_name (
 98 				E_SHELL_SIDEBAR (object),
 99 				g_value_get_string (value));
100 			return;
101 
102 		case PROP_PRIMARY_TEXT:
103 			e_shell_sidebar_set_primary_text (
104 				E_SHELL_SIDEBAR (object),
105 				g_value_get_string (value));
106 			return;
107 
108 		case PROP_SECONDARY_TEXT:
109 			e_shell_sidebar_set_secondary_text (
110 				E_SHELL_SIDEBAR (object),
111 				g_value_get_string (value));
112 			return;
113 
114 		case PROP_SHELL_VIEW:
115 			shell_sidebar_set_shell_view (
116 				E_SHELL_SIDEBAR (object),
117 				g_value_get_object (value));
118 			return;
119 	}
120 
121 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
122 }
123 
124 static void
125 shell_sidebar_get_property (GObject *object,
126                             guint property_id,
127                             GValue *value,
128                             GParamSpec *pspec)
129 {
130 	switch (property_id) {
131 		case PROP_ICON_NAME:
132 			g_value_set_string (
133 				value, e_shell_sidebar_get_icon_name (
134 				E_SHELL_SIDEBAR (object)));
135 			return;
136 
137 		case PROP_PRIMARY_TEXT:
138 			g_value_set_string (
139 				value, e_shell_sidebar_get_primary_text (
140 				E_SHELL_SIDEBAR (object)));
141 			return;
142 
143 		case PROP_SECONDARY_TEXT:
144 			g_value_set_string (
145 				value, e_shell_sidebar_get_secondary_text (
146 				E_SHELL_SIDEBAR (object)));
147 			return;
148 
149 		case PROP_SHELL_VIEW:
150 			g_value_set_object (
151 				value, e_shell_sidebar_get_shell_view (
152 				E_SHELL_SIDEBAR (object)));
153 			return;
154 	}
155 
156 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
157 }
158 
159 static void
160 shell_sidebar_dispose (GObject *object)
161 {
162 	EShellSidebarPrivate *priv;
163 
164 	priv = E_SHELL_SIDEBAR_GET_PRIVATE (object);
165 
166 	if (priv->shell_view != NULL) {
167 		g_object_remove_weak_pointer (
168 			G_OBJECT (priv->shell_view), &priv->shell_view);
169 		priv->shell_view = NULL;
170 	}
171 
172 	/* Unparent the widget before destroying it to avoid
173 	 * writing a custom GtkContainer::remove() method. */
174 
175 	if (priv->event_box != NULL) {
176 		gtk_widget_unparent (priv->event_box);
177 		gtk_widget_destroy (priv->event_box);
178 		g_object_unref (priv->event_box);
179 		priv->event_box = NULL;
180 	}
181 
182 	/* Chain up to parent's dispose() method. */
183 	G_OBJECT_CLASS (e_shell_sidebar_parent_class)->dispose (object);
184 }
185 
186 static void
187 shell_sidebar_finalize (GObject *object)
188 {
189 	EShellSidebarPrivate *priv;
190 
191 	priv = E_SHELL_SIDEBAR_GET_PRIVATE (object);
192 
193 	g_free (priv->icon_name);
194 	g_free (priv->primary_text);
195 	g_free (priv->secondary_text);
196 
197 	/* Chain up to parent's finalize() method. */
198 	G_OBJECT_CLASS (e_shell_sidebar_parent_class)->finalize (object);
199 }
200 
201 static void
202 shell_sidebar_constructed (GObject *object)
203 {
204 	EShellView *shell_view;
205 	EShellSidebar *shell_sidebar;
206 	GtkSizeGroup *size_group;
207 	GtkAction *action;
208 	GtkWidget *widget;
209 	gchar *label;
210 	gchar *icon_name;
211 
212 	shell_sidebar = E_SHELL_SIDEBAR (object);
213 	shell_view = e_shell_sidebar_get_shell_view (shell_sidebar);
214 	size_group = e_shell_view_get_size_group (shell_view);
215 	action = e_shell_view_get_action (shell_view);
216 
217 	widget = shell_sidebar->priv->event_box;
218 	gtk_size_group_add_widget (size_group, widget);
219 
220 	g_object_get (action, "icon-name", &icon_name, NULL);
221 	e_shell_sidebar_set_icon_name (shell_sidebar, icon_name);
222 	g_free (icon_name);
223 
224 	g_object_get (action, "label", &label, NULL);
225 	e_shell_sidebar_set_primary_text (shell_sidebar, label);
226 	g_free (label);
227 
228 	e_extensible_load_extensions (E_EXTENSIBLE (object));
229 
230 	/* Chain up to parent's constructed() method. */
231 	G_OBJECT_CLASS (e_shell_sidebar_parent_class)->constructed (object);
232 }
233 
234 static void
235 shell_sidebar_get_preferred_width (GtkWidget *widget,
236                                    gint *minimum,
237                                    gint *natural)
238 {
239 	GtkWidget *child;
240 
241 	child = gtk_bin_get_child (GTK_BIN (widget));
242 	gtk_widget_get_preferred_width (child, minimum, natural);
243 
244 	/* Do not use priv->event_box here, otherwise it won't ellipsize. */
245 }
246 
247 static void
248 shell_sidebar_get_preferred_height (GtkWidget *widget,
249                                     gint *minimum,
250                                     gint *natural)
251 {
252 	EShellSidebarPrivate *priv;
253 	gint child_min, child_nat;
254 	GtkWidget *child;
255 
256 	priv = E_SHELL_SIDEBAR_GET_PRIVATE (widget);
257 
258 	child = gtk_bin_get_child (GTK_BIN (widget));
259 	gtk_widget_get_preferred_height (child, minimum, natural);
260 
261 	child = priv->event_box;
262 	gtk_widget_get_preferred_height (child, &child_min, &child_nat);
263 
264 	*minimum += child_min;
265 	*natural += child_nat;
266 }
267 
268 static void
269 shell_sidebar_size_allocate (GtkWidget *widget,
270                              GtkAllocation *allocation)
271 {
272 	EShellSidebarPrivate *priv;
273 	GtkAllocation child_allocation;
274 	GtkRequisition child_requisition;
275 	GtkWidget *child;
276 
277 	priv = E_SHELL_SIDEBAR_GET_PRIVATE (widget);
278 
279 	gtk_widget_set_allocation (widget, allocation);
280 
281 	child = priv->event_box;
282 	gtk_widget_get_preferred_size (child, &child_requisition, NULL);
283 
284 	child_allocation.x = allocation->x;
285 	child_allocation.y = allocation->y;
286 	child_allocation.width = allocation->width;
287 	child_allocation.height = child_requisition.height;
288 
289 	gtk_widget_size_allocate (child, &child_allocation);
290 
291 	child_allocation.y += child_requisition.height;
292 	child_allocation.height =
293 		allocation->height - child_requisition.height;
294 
295 	child = gtk_bin_get_child (GTK_BIN (widget));
296 	if (child != NULL)
297 		gtk_widget_size_allocate (child, &child_allocation);
298 }
299 
300 static void
301 shell_sidebar_forall (GtkContainer *container,
302                       gboolean include_internals,
303                       GtkCallback callback,
304                       gpointer callback_data)
305 {
306 	EShellSidebarPrivate *priv;
307 
308 	priv = E_SHELL_SIDEBAR_GET_PRIVATE (container);
309 
310 	if (include_internals && callback && priv->event_box)
311 		callback (priv->event_box, callback_data);
312 
313 	/* Chain up to parent's forall() method. */
314 	GTK_CONTAINER_CLASS (e_shell_sidebar_parent_class)->forall (
315 		container, include_internals, callback, callback_data);
316 }
317 
318 static void
319 shell_sidebar_submit_alert (EAlertSink *alert_sink,
320                             EAlert *alert)
321 {
322 	EShellView *shell_view;
323 	EShellContent *shell_content;
324 	EShellSidebar *shell_sidebar;
325 
326 	/* EShellSidebar is a proxy alert sink.  Forward the alert
327 	 * to the EShellContent widget for display to the user. */
328 
329 	shell_sidebar = E_SHELL_SIDEBAR (alert_sink);
330 	shell_view = e_shell_sidebar_get_shell_view (shell_sidebar);
331 	shell_content = e_shell_view_get_shell_content (shell_view);
332 
333 	alert_sink = E_ALERT_SINK (shell_content);
334 	e_alert_sink_submit_alert (alert_sink, alert);
335 }
336 
337 static void
338 e_shell_sidebar_class_init (EShellSidebarClass *class)
339 {
340 	GObjectClass *object_class;
341 	GtkWidgetClass *widget_class;
342 	GtkContainerClass *container_class;
343 
344 	g_type_class_add_private (class, sizeof (EShellSidebarPrivate));
345 
346 	object_class = G_OBJECT_CLASS (class);
347 	object_class->set_property = shell_sidebar_set_property;
348 	object_class->get_property = shell_sidebar_get_property;
349 	object_class->dispose = shell_sidebar_dispose;
350 	object_class->finalize = shell_sidebar_finalize;
351 	object_class->constructed = shell_sidebar_constructed;
352 
353 	widget_class = GTK_WIDGET_CLASS (class);
354 	widget_class->get_preferred_width = shell_sidebar_get_preferred_width;
355 	widget_class->get_preferred_height = shell_sidebar_get_preferred_height;
356 	widget_class->size_allocate = shell_sidebar_size_allocate;
357 
358 	container_class = GTK_CONTAINER_CLASS (class);
359 	container_class->forall = shell_sidebar_forall;
360 
361 	/**
362 	 * EShellSidebar:icon-name
363 	 *
364 	 * The named icon is displayed at the top of the sidebar.
365 	 **/
366 	g_object_class_install_property (
367 		object_class,
368 		PROP_ICON_NAME,
369 		g_param_spec_string (
370 			"icon-name",
371 			"Icon Name",
372 			NULL,
373 			NULL,
374 			G_PARAM_READWRITE));
375 
376 	/**
377 	 * EShellSidebar:primary-text
378 	 *
379 	 * The primary text is displayed in bold at the top of the sidebar.
380 	 **/
381 	g_object_class_install_property (
382 		object_class,
383 		PROP_PRIMARY_TEXT,
384 		g_param_spec_string (
385 			"primary-text",
386 			"Primary Text",
387 			NULL,
388 			NULL,
389 			G_PARAM_READWRITE));
390 
391 	/**
392 	 * EShellSidebar:secondary-text
393 	 *
394 	 * The secondary text is displayed in a smaller font at the top of
395 	 * the sidebar.
396 	 **/
397 	g_object_class_install_property (
398 		object_class,
399 		PROP_SECONDARY_TEXT,
400 		g_param_spec_string (
401 			"secondary-text",
402 			"Secondary Text",
403 			NULL,
404 			NULL,
405 			G_PARAM_READWRITE));
406 
407 	/**
408 	 * EShellSidebar:shell-view
409 	 *
410 	 * The #EShellView to which the sidebar widget belongs.
411 	 **/
412 	g_object_class_install_property (
413 		object_class,
414 		PROP_SHELL_VIEW,
415 		g_param_spec_object (
416 			"shell-view",
417 			"Shell View",
418 			NULL,
419 			E_TYPE_SHELL_VIEW,
420 			G_PARAM_READWRITE |
421 			G_PARAM_CONSTRUCT_ONLY));
422 }
423 
424 static void
425 e_shell_sidebar_alert_sink_init (EAlertSinkInterface *interface)
426 {
427 	interface->submit_alert = shell_sidebar_submit_alert;
428 }
429 
430 static void
431 e_shell_sidebar_init (EShellSidebar *shell_sidebar)
432 {
433 	GtkStyle *style;
434 	GtkWidget *widget;
435 	GtkWidget *container;
436 	PangoAttribute *attribute;
437 	PangoAttrList *attribute_list;
438 	const GdkColor *color;
439 	const gchar *icon_name;
440 
441 	shell_sidebar->priv = E_SHELL_SIDEBAR_GET_PRIVATE (shell_sidebar);
442 
443 	gtk_widget_set_has_window (GTK_WIDGET (shell_sidebar), FALSE);
444 
445 	widget = gtk_event_box_new ();
446 	style = gtk_widget_get_style (widget);
447 	color = &style->bg[GTK_STATE_ACTIVE];
448 	gtk_widget_modify_bg (widget, GTK_STATE_NORMAL, color);
449 	gtk_widget_set_parent (widget, GTK_WIDGET (shell_sidebar));
450 	shell_sidebar->priv->event_box = g_object_ref (widget);
451 	gtk_widget_show (widget);
452 
453 	container = widget;
454 
455 	widget = gtk_hbox_new (FALSE, 6);
456 	gtk_container_set_border_width (GTK_CONTAINER (widget), 6);
457 	gtk_container_add (GTK_CONTAINER (container), widget);
458 	gtk_widget_show (widget);
459 
460 	container = widget;
461 
462 	/* Pick a bogus icon name just to get the storage type set. */
463 	icon_name = "evolution";
464 	e_shell_sidebar_set_icon_name (shell_sidebar, icon_name);
465 	widget = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU);
466 	gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
467 	gtk_widget_show (widget);
468 
469 	g_object_bind_property (
470 		shell_sidebar, "icon-name",
471 		widget, "icon-name",
472 		G_BINDING_SYNC_CREATE);
473 
474 	widget = gtk_label_new (NULL);
475 	gtk_label_set_ellipsize (GTK_LABEL (widget), PANGO_ELLIPSIZE_END);
476 	gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
477 	gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
478 	gtk_widget_show (widget);
479 
480 	attribute_list = pango_attr_list_new ();
481 	attribute = pango_attr_weight_new (PANGO_WEIGHT_BOLD);
482 	pango_attr_list_insert (attribute_list, attribute);
483 	gtk_label_set_attributes (GTK_LABEL (widget), attribute_list);
484 	pango_attr_list_unref (attribute_list);
485 
486 	g_object_bind_property (
487 		shell_sidebar, "primary-text",
488 		widget, "label",
489 		G_BINDING_SYNC_CREATE);
490 
491 	widget = gtk_label_new (NULL);
492 	gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5);
493 	gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
494 	gtk_widget_show (widget);
495 
496 	attribute_list = pango_attr_list_new ();
497 	attribute = pango_attr_scale_new (PANGO_SCALE_SMALL);
498 	pango_attr_list_insert (attribute_list, attribute);
499 	gtk_label_set_attributes (GTK_LABEL (widget), attribute_list);
500 	pango_attr_list_unref (attribute_list);
501 
502 	g_object_bind_property (
503 		shell_sidebar, "secondary-text",
504 		widget, "label",
505 		G_BINDING_SYNC_CREATE);
506 }
507 
508 /**
509  * e_shell_sidebar_new:
510  * @shell_view: an #EShellView
511  *
512  * Creates a new #EShellSidebar instance belonging to @shell_view.
513  *
514  * Returns: a new #EShellSidebar instance
515  **/
516 GtkWidget *
517 e_shell_sidebar_new (EShellView *shell_view)
518 {
519 	g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
520 
521 	return g_object_new (
522 		E_TYPE_SHELL_SIDEBAR,
523 		"shell-view", shell_view, NULL);
524 }
525 
526 /**
527  * e_shell_sidebar_check_state:
528  * @shell_sidebar: an #EShellSidebar
529  *
530  * #EShellSidebar subclasses should implement the
531  * <structfield>check_state</structfield> method in #EShellSidebarClass
532  * to return a set of flags describing the current sidebar selection.
533  * Subclasses are responsible for defining their own flags.  This is
534  * primarily used to assist shell views with updating actions (see
535  * e_shell_view_update_actions()).
536  *
537  * Returns: a set of flags describing the current @shell_sidebar selection
538  **/
539 guint32
540 e_shell_sidebar_check_state (EShellSidebar *shell_sidebar)
541 {
542 	EShellSidebarClass *shell_sidebar_class;
543 
544 	g_return_val_if_fail (E_IS_SHELL_SIDEBAR (shell_sidebar), 0);
545 
546 	shell_sidebar_class = E_SHELL_SIDEBAR_GET_CLASS (shell_sidebar);
547 	g_return_val_if_fail (shell_sidebar_class->check_state != NULL, 0);
548 
549 	return shell_sidebar_class->check_state (shell_sidebar);
550 }
551 
552 /**
553  * e_shell_sidebar_get_shell_view:
554  * @shell_sidebar: an #EShellSidebar
555  *
556  * Returns the #EShellView that was passed to e_shell_sidebar_new().
557  *
558  * Returns: the #EShellView to which @shell_sidebar belongs
559  **/
560 EShellView *
561 e_shell_sidebar_get_shell_view (EShellSidebar *shell_sidebar)
562 {
563 	g_return_val_if_fail (E_IS_SHELL_SIDEBAR (shell_sidebar), NULL);
564 
565 	return E_SHELL_VIEW (shell_sidebar->priv->shell_view);
566 }
567 
568 /**
569  * e_shell_sidebar_get_icon_name:
570  * @shell_sidebar: an #EShellSidebar
571  *
572  * Returns the icon name displayed at the top of the sidebar.
573  *
574  * Returns: the icon name for @shell_sidebar
575  **/
576 const gchar *
577 e_shell_sidebar_get_icon_name (EShellSidebar *shell_sidebar)
578 {
579 	g_return_val_if_fail (E_IS_SHELL_SIDEBAR (shell_sidebar), NULL);
580 
581 	return shell_sidebar->priv->icon_name;
582 }
583 
584 /**
585  * e_shell_sidebar_set_icon_name:
586  * @shell_sidebar: an #EShellSidebar
587  * @icon_name: a themed icon name
588  *
589  * Sets the icon name displayed at the top of the sidebar.
590  **/
591 void
592 e_shell_sidebar_set_icon_name (EShellSidebar *shell_sidebar,
593                                const gchar *icon_name)
594 {
595 	g_return_if_fail (E_IS_SHELL_SIDEBAR (shell_sidebar));
596 
597 	if (g_strcmp0 (shell_sidebar->priv->icon_name, icon_name) == 0)
598 		return;
599 
600 	g_free (shell_sidebar->priv->icon_name);
601 	shell_sidebar->priv->icon_name = g_strdup (icon_name);
602 
603 	g_object_notify (G_OBJECT (shell_sidebar), "icon-name");
604 }
605 
606 /**
607  * e_shell_sidebar_get_primary_text:
608  * @shell_sidebar: an #EShellSidebar
609  *
610  * Returns the primary text for @shell_sidebar.
611  *
612  * The primary text is displayed in bold at the top of the sidebar.  It
613  * defaults to the shell view's label (as seen on the switcher button),
614  * but typically shows the name of the selected item in the sidebar.
615  *
616  * Returns: the primary text for @shell_sidebar
617  **/
618 const gchar *
619 e_shell_sidebar_get_primary_text (EShellSidebar *shell_sidebar)
620 {
621 	g_return_val_if_fail (E_IS_SHELL_SIDEBAR (shell_sidebar), NULL);
622 
623 	return shell_sidebar->priv->primary_text;
624 }
625 
626 /**
627  * e_shell_sidebar_set_primary_text:
628  * @shell_sidebar: an #EShellSidebar
629  * @primary_text: text to be displayed in a bold font
630  *
631  * Sets the primary text for @shell_sidebar.
632  *
633  * The primary text is displayed in bold at the top of the sidebar.  It
634  * defaults to the shell view's label (as seen on the switcher button),
635  * but typically shows the name of the selected item in the sidebar.
636  **/
637 void
638 e_shell_sidebar_set_primary_text (EShellSidebar *shell_sidebar,
639                                   const gchar *primary_text)
640 {
641 	g_return_if_fail (E_IS_SHELL_SIDEBAR (shell_sidebar));
642 
643 	if (g_strcmp0 (shell_sidebar->priv->primary_text, primary_text) == 0)
644 		return;
645 
646 	g_free (shell_sidebar->priv->primary_text);
647 	shell_sidebar->priv->primary_text = e_utf8_ensure_valid (primary_text);
648 
649 	gtk_widget_queue_resize (GTK_WIDGET (shell_sidebar));
650 	g_object_notify (G_OBJECT (shell_sidebar), "primary-text");
651 }
652 
653 /**
654  * e_shell_sidebar_get_secondary_text:
655  * @shell_sidebar: an #EShellSidebar
656  *
657  * Returns the secondary text for @shell_sidebar.
658  *
659  * The secondary text is displayed in a smaller font at the top of the
660  * sidebar.  It typically shows information about the contents of the
661  * selected sidebar item, such as total number of items, number of
662  * selected items, etc.
663  *
664  * Returns: the secondary text for @shell_sidebar
665  **/
666 const gchar *
667 e_shell_sidebar_get_secondary_text (EShellSidebar *shell_sidebar)
668 {
669 	g_return_val_if_fail (E_IS_SHELL_SIDEBAR (shell_sidebar), NULL);
670 
671 	return shell_sidebar->priv->secondary_text;
672 }
673 
674 /**
675  * e_shell_sidebar_set_secondary_text:
676  * @shell_sidebar: an #EShellSidebar
677  * @secondary_text: text to be displayed in a smaller font
678  *
679  * Sets the secondary text for @shell_sidebar.
680  *
681  * The secondary text is displayed in a smaller font at the top of the
682  * sidebar.  It typically shows information about the contents of the
683  * selected sidebar item, such as total number of items, number of
684  * selected items, etc.
685  **/
686 void
687 e_shell_sidebar_set_secondary_text (EShellSidebar *shell_sidebar,
688                                     const gchar *secondary_text)
689 {
690 	g_return_if_fail (E_IS_SHELL_SIDEBAR (shell_sidebar));
691 
692 	if (g_strcmp0 (shell_sidebar->priv->secondary_text, secondary_text) == 0)
693 		return;
694 
695 	g_free (shell_sidebar->priv->secondary_text);
696 	shell_sidebar->priv->secondary_text = e_utf8_ensure_valid (secondary_text);
697 
698 	gtk_widget_queue_resize (GTK_WIDGET (shell_sidebar));
699 	g_object_notify (G_OBJECT (shell_sidebar), "secondary-text");
700 }