evolution-3.6.4/widgets/misc/e-attachment-bar.c

No issues found

  1 /*
  2  * e-attachment-bar.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 #ifdef HAVE_CONFIG_H
 23 #include <config.h>
 24 #endif
 25 
 26 #include "e-attachment-bar.h"
 27 
 28 #include <glib/gi18n.h>
 29 
 30 #include "e-attachment-store.h"
 31 #include "e-attachment-icon-view.h"
 32 #include "e-attachment-tree-view.h"
 33 
 34 #define E_ATTACHMENT_BAR_GET_PRIVATE(obj) \
 35 	(G_TYPE_INSTANCE_GET_PRIVATE \
 36 	((obj), E_TYPE_ATTACHMENT_BAR, EAttachmentBarPrivate))
 37 
 38 #define NUM_VIEWS 2
 39 
 40 struct _EAttachmentBarPrivate {
 41 	GtkTreeModel *model;
 42 	GtkWidget *vbox;
 43 	GtkWidget *expander;
 44 	GtkWidget *combo_box;
 45 	GtkWidget *icon_view;
 46 	GtkWidget *tree_view;
 47 	GtkWidget *icon_frame;
 48 	GtkWidget *tree_frame;
 49 	GtkWidget *status_icon;
 50 	GtkWidget *status_label;
 51 	GtkWidget *save_all_button;
 52 	GtkWidget *save_one_button;
 53 
 54 	gint active_view;
 55 	guint expanded : 1;
 56 };
 57 
 58 enum {
 59 	PROP_0,
 60 	PROP_ACTIVE_VIEW,
 61 	PROP_DRAGGING,
 62 	PROP_EDITABLE,
 63 	PROP_EXPANDED,
 64 	PROP_STORE
 65 };
 66 
 67 /* Forward Declarations */
 68 static void	e_attachment_bar_interface_init
 69 				(EAttachmentViewInterface *interface);
 70 
 71 G_DEFINE_TYPE_WITH_CODE (
 72 	EAttachmentBar,
 73 	e_attachment_bar,
 74 	GTK_TYPE_VBOX,
 75 	G_IMPLEMENT_INTERFACE (
 76 		E_TYPE_ATTACHMENT_VIEW,
 77 		e_attachment_bar_interface_init))
 78 
 79 static void
 80 attachment_bar_update_status (EAttachmentBar *bar)
 81 {
 82 	EAttachmentStore *store;
 83 	GtkActivatable *activatable;
 84 	GtkAction *action;
 85 	GtkLabel *label;
 86 	gint num_attachments;
 87 	guint64 total_size;
 88 	gchar *display_size;
 89 	gchar *markup;
 90 
 91 	store = E_ATTACHMENT_STORE (bar->priv->model);
 92 	label = GTK_LABEL (bar->priv->status_label);
 93 
 94 	num_attachments = e_attachment_store_get_num_attachments (store);
 95 	total_size = e_attachment_store_get_total_size (store);
 96 	display_size = g_format_size_for_display (total_size);
 97 
 98 	if (total_size > 0)
 99 		markup = g_strdup_printf (
100 			"<b>%d</b> %s (%s)", num_attachments, ngettext (
101 			"Attachment", "Attachments", num_attachments),
102 			display_size);
103 	else
104 		markup = g_strdup_printf (
105 			"<b>%d</b> %s", num_attachments, ngettext (
106 			"Attachment", "Attachments", num_attachments));
107 	gtk_label_set_markup (label, markup);
108 	g_free (markup);
109 
110 	activatable = GTK_ACTIVATABLE (bar->priv->save_all_button);
111 	action = gtk_activatable_get_related_action (activatable);
112 	gtk_action_set_visible (action, (num_attachments > 1));
113 
114 	activatable = GTK_ACTIVATABLE (bar->priv->save_one_button);
115 	action = gtk_activatable_get_related_action (activatable);
116 	gtk_action_set_visible (action, (num_attachments == 1));
117 
118 	g_free (display_size);
119 }
120 
121 static void
122 attachment_bar_set_store (EAttachmentBar *bar,
123                           EAttachmentStore *store)
124 {
125 	g_return_if_fail (E_IS_ATTACHMENT_STORE (store));
126 
127 	bar->priv->model = g_object_ref (store);
128 
129 	gtk_icon_view_set_model (
130 		GTK_ICON_VIEW (bar->priv->icon_view),
131 		bar->priv->model);
132 	gtk_tree_view_set_model (
133 		GTK_TREE_VIEW (bar->priv->tree_view),
134 		bar->priv->model);
135 
136 	g_signal_connect_object (
137 		bar->priv->model, "notify::num-attachments",
138 		G_CALLBACK (attachment_bar_update_status), bar,
139 		G_CONNECT_SWAPPED);
140 
141 	g_signal_connect_object (
142 		bar->priv->model, "notify::total-size",
143 		G_CALLBACK (attachment_bar_update_status), bar,
144 		G_CONNECT_SWAPPED);
145 
146 	/* Initialize */
147 	attachment_bar_update_status (bar);
148 }
149 
150 static void
151 attachment_bar_set_property (GObject *object,
152                              guint property_id,
153                              const GValue *value,
154                              GParamSpec *pspec)
155 {
156 	switch (property_id) {
157 		case PROP_ACTIVE_VIEW:
158 				e_attachment_bar_set_active_view (
159 				E_ATTACHMENT_BAR (object),
160 				g_value_get_int (value));
161 			return;
162 
163 		case PROP_DRAGGING:
164 			e_attachment_view_set_dragging (
165 				E_ATTACHMENT_VIEW (object),
166 				g_value_get_boolean (value));
167 			return;
168 
169 		case PROP_EDITABLE:
170 			e_attachment_view_set_editable (
171 				E_ATTACHMENT_VIEW (object),
172 				g_value_get_boolean (value));
173 			return;
174 
175 		case PROP_EXPANDED:
176 			e_attachment_bar_set_expanded (
177 				E_ATTACHMENT_BAR (object),
178 				g_value_get_boolean (value));
179 			return;
180 		case PROP_STORE:
181 			attachment_bar_set_store (
182 				E_ATTACHMENT_BAR (object),
183 				g_value_get_object (value));
184 			return;
185 	}
186 
187 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
188 }
189 
190 static void
191 attachment_bar_get_property (GObject *object,
192                              guint property_id,
193                              GValue *value,
194                              GParamSpec *pspec)
195 {
196 	switch (property_id) {
197 		case PROP_ACTIVE_VIEW:
198 			g_value_set_int (
199 				value,
200 				e_attachment_bar_get_active_view (
201 				E_ATTACHMENT_BAR (object)));
202 			return;
203 
204 		case PROP_DRAGGING:
205 			g_value_set_boolean (
206 				value,
207 				e_attachment_view_get_dragging (
208 				E_ATTACHMENT_VIEW (object)));
209 			return;
210 
211 		case PROP_EDITABLE:
212 			g_value_set_boolean (
213 				value,
214 				e_attachment_view_get_editable (
215 				E_ATTACHMENT_VIEW (object)));
216 			return;
217 
218 		case PROP_EXPANDED:
219 			g_value_set_boolean (
220 				value,
221 				e_attachment_bar_get_expanded (
222 				E_ATTACHMENT_BAR (object)));
223 			return;
224 		case PROP_STORE:
225 			g_value_set_object (
226 				value,
227 				e_attachment_bar_get_store (
228 				E_ATTACHMENT_BAR (object)));
229 	}
230 
231 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
232 }
233 
234 static void
235 attachment_bar_dispose (GObject *object)
236 {
237 	EAttachmentBarPrivate *priv;
238 
239 	priv = E_ATTACHMENT_BAR_GET_PRIVATE (object);
240 
241 	if (priv->model != NULL) {
242 		g_object_unref (priv->model);
243 		priv->model = NULL;
244 	}
245 
246 	if (priv->vbox != NULL) {
247 		g_object_unref (priv->vbox);
248 		priv->vbox = NULL;
249 	}
250 
251 	if (priv->expander != NULL) {
252 		g_object_unref (priv->expander);
253 		priv->expander = NULL;
254 	}
255 
256 	if (priv->combo_box != NULL) {
257 		g_object_unref (priv->combo_box);
258 		priv->combo_box = NULL;
259 	}
260 
261 	if (priv->icon_view != NULL) {
262 		g_object_unref (priv->icon_view);
263 		priv->icon_view = NULL;
264 	}
265 
266 	if (priv->tree_view != NULL) {
267 		g_object_unref (priv->tree_view);
268 		priv->tree_view = NULL;
269 	}
270 
271 	if (priv->icon_frame != NULL) {
272 		g_object_unref (priv->icon_frame);
273 		priv->icon_frame = NULL;
274 	}
275 
276 	if (priv->tree_frame != NULL) {
277 		g_object_unref (priv->tree_frame);
278 		priv->tree_frame = NULL;
279 	}
280 
281 	if (priv->status_icon != NULL) {
282 		g_object_unref (priv->status_icon);
283 		priv->status_icon = NULL;
284 	}
285 
286 	if (priv->status_label != NULL) {
287 		g_object_unref (priv->status_label);
288 		priv->status_label = NULL;
289 	}
290 
291 	if (priv->save_all_button != NULL) {
292 		g_object_unref (priv->save_all_button);
293 		priv->save_all_button = NULL;
294 	}
295 
296 	if (priv->save_one_button != NULL) {
297 		g_object_unref (priv->save_one_button);
298 		priv->save_one_button = NULL;
299 	}
300 
301 	/* Chain up to parent's dispose() method. */
302 	G_OBJECT_CLASS (e_attachment_bar_parent_class)->dispose (object);
303 }
304 
305 static void
306 attachment_bar_constructed (GObject *object)
307 {
308 	EAttachmentBarPrivate *priv;
309 	GSettings *settings;
310 
311 	priv = E_ATTACHMENT_BAR_GET_PRIVATE (object);
312 
313 	/* Set up property-to-property bindings. */
314 
315 	g_object_bind_property (
316 		object, "active-view",
317 		priv->combo_box, "active",
318 		G_BINDING_BIDIRECTIONAL |
319 		G_BINDING_SYNC_CREATE);
320 
321 	g_object_bind_property (
322 		object, "dragging",
323 		priv->icon_view, "dragging",
324 		G_BINDING_BIDIRECTIONAL |
325 		G_BINDING_SYNC_CREATE);
326 
327 	g_object_bind_property (
328 		object, "dragging",
329 		priv->tree_view, "dragging",
330 		G_BINDING_BIDIRECTIONAL |
331 		G_BINDING_SYNC_CREATE);
332 
333 	g_object_bind_property (
334 		object, "editable",
335 		priv->icon_view, "editable",
336 		G_BINDING_BIDIRECTIONAL |
337 		G_BINDING_SYNC_CREATE);
338 
339 	g_object_bind_property (
340 		object, "editable",
341 		priv->tree_view, "editable",
342 		G_BINDING_BIDIRECTIONAL |
343 		G_BINDING_SYNC_CREATE);
344 
345 	g_object_bind_property (
346 		object, "expanded",
347 		priv->expander, "expanded",
348 		G_BINDING_BIDIRECTIONAL |
349 		G_BINDING_SYNC_CREATE);
350 
351 	g_object_bind_property (
352 		object, "expanded",
353 		priv->combo_box, "visible",
354 		G_BINDING_BIDIRECTIONAL |
355 		G_BINDING_SYNC_CREATE);
356 
357 	g_object_bind_property (
358 		object, "expanded",
359 		priv->vbox, "visible",
360 		G_BINDING_BIDIRECTIONAL |
361 		G_BINDING_SYNC_CREATE);
362 
363 	/* Set up property-to-GSettings bindings. */
364 	settings = g_settings_new ("org.gnome.evolution.shell");
365 	g_settings_bind (
366 		settings, "attachment-view",
367 		object, "active-view",
368 		G_SETTINGS_BIND_DEFAULT);
369 	g_object_unref (settings);
370 
371 	/* Chain up to parent's constructed() method. */
372 	G_OBJECT_CLASS (e_attachment_bar_parent_class)->constructed (object);
373 }
374 
375 static EAttachmentViewPrivate *
376 attachment_bar_get_private (EAttachmentView *view)
377 {
378 	EAttachmentBar *bar;
379 
380 	bar = E_ATTACHMENT_BAR (view);
381 	view = E_ATTACHMENT_VIEW (bar->priv->icon_view);
382 
383 	return e_attachment_view_get_private (view);
384 }
385 
386 static GtkTreePath *
387 attachment_bar_get_path_at_pos (EAttachmentView *view,
388                                 gint x,
389                                 gint y)
390 {
391 	EAttachmentBar *bar;
392 
393 	bar = E_ATTACHMENT_BAR (view);
394 	view = E_ATTACHMENT_VIEW (bar->priv->icon_view);
395 
396 	return e_attachment_view_get_path_at_pos (view, x, y);
397 }
398 
399 static EAttachmentStore *
400 attachment_bar_get_store (EAttachmentView *view)
401 {
402 	return e_attachment_bar_get_store (E_ATTACHMENT_BAR (view));
403 }
404 
405 static GList *
406 attachment_bar_get_selected_paths (EAttachmentView *view)
407 {
408 	EAttachmentBar *bar;
409 
410 	bar = E_ATTACHMENT_BAR (view);
411 	view = E_ATTACHMENT_VIEW (bar->priv->icon_view);
412 
413 	return e_attachment_view_get_selected_paths (view);
414 }
415 
416 static gboolean
417 attachment_bar_path_is_selected (EAttachmentView *view,
418                                  GtkTreePath *path)
419 {
420 	EAttachmentBar *bar;
421 
422 	bar = E_ATTACHMENT_BAR (view);
423 	view = E_ATTACHMENT_VIEW (bar->priv->icon_view);
424 
425 	return e_attachment_view_path_is_selected (view, path);
426 }
427 
428 static void
429 attachment_bar_select_path (EAttachmentView *view,
430                             GtkTreePath *path)
431 {
432 	EAttachmentBar *bar;
433 
434 	bar = E_ATTACHMENT_BAR (view);
435 	view = E_ATTACHMENT_VIEW (bar->priv->icon_view);
436 
437 	e_attachment_view_select_path (view, path);
438 }
439 
440 static void
441 attachment_bar_unselect_path (EAttachmentView *view,
442                               GtkTreePath *path)
443 {
444 	EAttachmentBar *bar;
445 
446 	bar = E_ATTACHMENT_BAR (view);
447 	view = E_ATTACHMENT_VIEW (bar->priv->icon_view);
448 
449 	e_attachment_view_unselect_path (view, path);
450 }
451 
452 static void
453 attachment_bar_select_all (EAttachmentView *view)
454 {
455 	EAttachmentBar *bar;
456 
457 	bar = E_ATTACHMENT_BAR (view);
458 	view = E_ATTACHMENT_VIEW (bar->priv->icon_view);
459 
460 	e_attachment_view_select_all (view);
461 }
462 
463 static void
464 attachment_bar_unselect_all (EAttachmentView *view)
465 {
466 	EAttachmentBar *bar;
467 
468 	bar = E_ATTACHMENT_BAR (view);
469 	view = E_ATTACHMENT_VIEW (bar->priv->icon_view);
470 
471 	e_attachment_view_unselect_all (view);
472 }
473 
474 static void
475 attachment_bar_update_actions (EAttachmentView *view)
476 {
477 	EAttachmentBar *bar;
478 
479 	bar = E_ATTACHMENT_BAR (view);
480 	view = E_ATTACHMENT_VIEW (bar->priv->icon_view);
481 
482 	e_attachment_view_update_actions (view);
483 }
484 
485 static void
486 e_attachment_bar_class_init (EAttachmentBarClass *class)
487 {
488 	GObjectClass *object_class;
489 
490 	g_type_class_add_private (class, sizeof (EAttachmentBarPrivate));
491 
492 	object_class = G_OBJECT_CLASS (class);
493 	object_class->set_property = attachment_bar_set_property;
494 	object_class->get_property = attachment_bar_get_property;
495 	object_class->dispose = attachment_bar_dispose;
496 	object_class->constructed = attachment_bar_constructed;
497 
498 	g_object_class_install_property (
499 		object_class,
500 		PROP_ACTIVE_VIEW,
501 		g_param_spec_int (
502 			"active-view",
503 			"Active View",
504 			NULL,
505 			0,
506 			NUM_VIEWS,
507 			0,
508 			G_PARAM_READWRITE |
509 			G_PARAM_CONSTRUCT));
510 
511 	g_object_class_install_property (
512 		object_class,
513 		PROP_EXPANDED,
514 		g_param_spec_boolean (
515 			"expanded",
516 			"Expanded",
517 			NULL,
518 			FALSE,
519 			G_PARAM_READWRITE |
520 			G_PARAM_CONSTRUCT));
521 
522 	g_object_class_install_property (
523 		object_class,
524 		PROP_STORE,
525 		g_param_spec_object (
526 			"store",
527 			"Attachment Store",
528 			NULL,
529 			E_TYPE_ATTACHMENT_STORE,
530 			G_PARAM_READWRITE |
531 			G_PARAM_CONSTRUCT_ONLY));
532 
533 	g_object_class_override_property (
534 		object_class, PROP_DRAGGING, "dragging");
535 
536 	g_object_class_override_property (
537 		object_class, PROP_EDITABLE, "editable");
538 }
539 
540 static void
541 e_attachment_bar_interface_init (EAttachmentViewInterface *interface)
542 {
543 	interface->get_private = attachment_bar_get_private;
544 	interface->get_store = attachment_bar_get_store;
545 	interface->get_path_at_pos = attachment_bar_get_path_at_pos;
546 	interface->get_selected_paths = attachment_bar_get_selected_paths;
547 	interface->path_is_selected = attachment_bar_path_is_selected;
548 	interface->select_path = attachment_bar_select_path;
549 	interface->unselect_path = attachment_bar_unselect_path;
550 	interface->select_all = attachment_bar_select_all;
551 	interface->unselect_all = attachment_bar_unselect_all;
552 	interface->update_actions = attachment_bar_update_actions;
553 }
554 
555 static void
556 e_attachment_bar_init (EAttachmentBar *bar)
557 {
558 	EAttachmentView *view;
559 	GtkSizeGroup *size_group;
560 	GtkWidget *container;
561 	GtkWidget *widget;
562 	GtkAction *action;
563 
564 	bar->priv = E_ATTACHMENT_BAR_GET_PRIVATE (bar);
565 
566 	gtk_box_set_spacing (GTK_BOX (bar), 6);
567 
568 	/* Keep the expander label and save button the same height. */
569 	size_group = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL);
570 
571 	/* Construct the Attachment Views */
572 
573 	container = GTK_WIDGET (bar);
574 
575 	widget = gtk_vbox_new (FALSE, 0);
576 	gtk_box_pack_end (GTK_BOX (container), widget, FALSE, FALSE, 0);
577 	bar->priv->vbox = g_object_ref (widget);
578 	gtk_widget_show (widget);
579 
580 	container = bar->priv->vbox;
581 
582 	widget = gtk_frame_new (NULL);
583 	gtk_frame_set_shadow_type (GTK_FRAME (widget), GTK_SHADOW_IN);
584 	gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
585 	bar->priv->icon_frame = g_object_ref (widget);
586 	gtk_widget_show (widget);
587 
588 	container = widget;
589 
590 	widget = e_attachment_icon_view_new ();
591 	gtk_widget_set_can_focus (widget, TRUE);
592 	gtk_icon_view_set_model (GTK_ICON_VIEW (widget), bar->priv->model);
593 	gtk_container_add (GTK_CONTAINER (container), widget);
594 	bar->priv->icon_view = g_object_ref (widget);
595 	gtk_widget_show (widget);
596 
597 	container = bar->priv->vbox;
598 
599 	widget = gtk_frame_new (NULL);
600 	gtk_frame_set_shadow_type (GTK_FRAME (widget), GTK_SHADOW_IN);
601 	gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
602 	bar->priv->tree_frame = g_object_ref (widget);
603 	gtk_widget_hide (widget);
604 
605 	container = widget;
606 
607 	widget = e_attachment_tree_view_new ();
608 	gtk_widget_set_can_focus (widget, TRUE);
609 	gtk_tree_view_set_model (GTK_TREE_VIEW (widget), bar->priv->model);
610 	gtk_container_add (GTK_CONTAINER (container), widget);
611 	bar->priv->tree_view = g_object_ref (widget);
612 	gtk_widget_show (widget);
613 
614 	/* Construct the Controls */
615 
616 	container = GTK_WIDGET (bar);
617 
618 	widget = gtk_hbox_new (FALSE, 12);
619 	gtk_box_pack_end (GTK_BOX (container), widget, FALSE, FALSE, 0);
620 	gtk_widget_show (widget);
621 
622 	container = widget;
623 
624 	widget = gtk_expander_new (NULL);
625 	gtk_expander_set_spacing (GTK_EXPANDER (widget), 0);
626 	gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
627 	bar->priv->expander = g_object_ref (widget);
628 	gtk_widget_show (widget);
629 
630 	/* The "Save All" button proxies the "save-all" action from
631 	 * one of the two attachment views.  Doesn't matter which. */
632 	widget = gtk_button_new ();
633 	view = E_ATTACHMENT_VIEW (bar->priv->icon_view);
634 	action = e_attachment_view_get_action (view, "save-all");
635 	gtk_button_set_image (GTK_BUTTON (widget), gtk_image_new ());
636 	gtk_activatable_set_related_action (GTK_ACTIVATABLE (widget), action);
637 	gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
638 	bar->priv->save_all_button = g_object_ref (widget);
639 	gtk_widget_show (widget);
640 
641 	/* Same deal with the "Save" button. */
642 	widget = gtk_button_new ();
643 	view = E_ATTACHMENT_VIEW (bar->priv->icon_view);
644 	action = e_attachment_view_get_action (view, "save-one");
645 	gtk_button_set_image (GTK_BUTTON (widget), gtk_image_new ());
646 	gtk_activatable_set_related_action (GTK_ACTIVATABLE (widget), action);
647 	gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
648 	bar->priv->save_one_button = g_object_ref (widget);
649 	gtk_widget_show (widget);
650 
651 	widget = gtk_alignment_new (1.0, 0.5, 0.0, 0.0);
652 	gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
653 	gtk_widget_show (widget);
654 
655 	container = widget;
656 
657 	widget = gtk_combo_box_text_new ();
658 	gtk_size_group_add_widget (size_group, widget);
659 	gtk_combo_box_text_append_text (
660 		GTK_COMBO_BOX_TEXT (widget), _("Icon View"));
661 	gtk_combo_box_text_append_text (
662 		GTK_COMBO_BOX_TEXT (widget), _("List View"));
663 	gtk_container_add (GTK_CONTAINER (container), widget);
664 	bar->priv->combo_box = g_object_ref (widget);
665 	gtk_widget_show (widget);
666 
667 	container = bar->priv->expander;
668 
669 	widget = gtk_hbox_new (FALSE, 6);
670 	gtk_size_group_add_widget (size_group, widget);
671 	gtk_expander_set_label_widget (GTK_EXPANDER (container), widget);
672 	gtk_widget_show (widget);
673 
674 	container = widget;
675 
676 	widget = gtk_image_new_from_icon_name (
677 		"mail-attachment", GTK_ICON_SIZE_MENU);
678 	gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
679 	bar->priv->status_icon = g_object_ref (widget);
680 	gtk_widget_show (widget);
681 
682 	widget = gtk_label_new (NULL);
683 	gtk_label_set_use_markup (GTK_LABEL (widget), TRUE);
684 	gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
685 	bar->priv->status_label = g_object_ref (widget);
686 	gtk_widget_show (widget);
687 
688 	g_object_unref (size_group);
689 }
690 
691 GtkWidget *
692 e_attachment_bar_new (EAttachmentStore *store)
693 {
694 	g_return_val_if_fail (E_IS_ATTACHMENT_STORE (store), NULL);
695 
696 	return g_object_new (
697 		E_TYPE_ATTACHMENT_BAR,
698 		"editable", FALSE,
699 		"store", store, NULL);
700 }
701 
702 gint
703 e_attachment_bar_get_active_view (EAttachmentBar *bar)
704 {
705 	g_return_val_if_fail (E_IS_ATTACHMENT_BAR (bar), 0);
706 
707 	return bar->priv->active_view;
708 }
709 
710 void
711 e_attachment_bar_set_active_view (EAttachmentBar *bar,
712                                   gint active_view)
713 {
714 	EAttachmentView *source;
715 	EAttachmentView *target;
716 
717 	g_return_if_fail (E_IS_ATTACHMENT_BAR (bar));
718 	g_return_if_fail (active_view >= 0 && active_view < NUM_VIEWS);
719 
720 	if (active_view == bar->priv->active_view)
721 		return;
722 
723 	bar->priv->active_view = active_view;
724 
725 	if (active_view == 0) {
726 		gtk_widget_show (bar->priv->icon_frame);
727 		gtk_widget_hide (bar->priv->tree_frame);
728 	} else {
729 		gtk_widget_hide (bar->priv->icon_frame);
730 		gtk_widget_show (bar->priv->tree_frame);
731 	}
732 
733 	/* Synchronize the item selection of the view we're
734 	 * switching TO with the view we're switching FROM. */
735 	if (active_view == 0) {
736 		/* from tree view to icon view */
737 		source = E_ATTACHMENT_VIEW (bar->priv->tree_view);
738 		target = E_ATTACHMENT_VIEW (bar->priv->icon_view);
739 	} else {
740 		/* from icon view to tree view */
741 		source = E_ATTACHMENT_VIEW (bar->priv->icon_view);
742 		target = E_ATTACHMENT_VIEW (bar->priv->tree_view);
743 	}
744 
745 	e_attachment_view_sync_selection (source, target);
746 
747 	g_object_notify (G_OBJECT (bar), "active-view");
748 }
749 
750 gboolean
751 e_attachment_bar_get_expanded (EAttachmentBar *bar)
752 {
753 	g_return_val_if_fail (E_IS_ATTACHMENT_BAR (bar), FALSE);
754 
755 	return bar->priv->expanded;
756 }
757 
758 void
759 e_attachment_bar_set_expanded (EAttachmentBar *bar,
760                                     gboolean expanded)
761 {
762 	g_return_if_fail (E_IS_ATTACHMENT_BAR (bar));
763 
764 	if (bar->priv->expanded == expanded)
765 		return;
766 
767 	bar->priv->expanded = expanded;
768 
769 	g_object_notify (G_OBJECT (bar), "expanded");
770 }
771 
772 EAttachmentStore *
773 e_attachment_bar_get_store (EAttachmentBar *bar)
774 {
775 	g_return_val_if_fail (E_IS_ATTACHMENT_BAR (bar), NULL);
776 
777 	return E_ATTACHMENT_STORE (bar->priv->model);
778 }