No issues found
1 /*
2 * e-attachment-paned.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-paned.h"
27
28 #include <glib/gi18n.h>
29
30 #include "e-attachment-view.h"
31 #include "e-attachment-store.h"
32 #include "e-attachment-icon-view.h"
33 #include "e-attachment-tree-view.h"
34
35 #define E_ATTACHMENT_PANED_GET_PRIVATE(obj) \
36 (G_TYPE_INSTANCE_GET_PRIVATE \
37 ((obj), E_TYPE_ATTACHMENT_PANED, EAttachmentPanedPrivate))
38
39 #define NUM_VIEWS 2
40
41 /* Initial height of the lower pane. */
42 static gint initial_height = 150;
43
44 struct _EAttachmentPanedPrivate {
45 GtkTreeModel *model;
46 GtkWidget *expander;
47 GtkWidget *notebook;
48 GtkWidget *combo_box;
49 GtkWidget *controls_container;
50 GtkWidget *icon_view;
51 GtkWidget *tree_view;
52 GtkWidget *show_hide_label;
53 GtkWidget *status_icon;
54 GtkWidget *status_label;
55 GtkWidget *content_area;
56
57 gint active_view;
58 gboolean expanded;
59 gboolean resize_toplevel;
60 };
61
62 enum {
63 PROP_0,
64 PROP_ACTIVE_VIEW,
65 PROP_DRAGGING,
66 PROP_EDITABLE,
67 PROP_EXPANDED,
68 PROP_RESIZE_TOPLEVEL
69 };
70
71 /* Forward Declarations */
72 static void e_attachment_paned_interface_init
73 (EAttachmentViewInterface *interface);
74
75 G_DEFINE_TYPE_WITH_CODE (
76 EAttachmentPaned,
77 e_attachment_paned,
78 GTK_TYPE_VPANED,
79 G_IMPLEMENT_INTERFACE (
80 E_TYPE_ATTACHMENT_VIEW,
81 e_attachment_paned_interface_init))
82
83 void
84 e_attachment_paned_set_default_height (gint height)
85 {
86 initial_height = height;
87 }
88
89 static void
90 attachment_paned_notify_cb (EAttachmentPaned *paned,
91 GParamSpec *pspec,
92 GtkExpander *expander)
93 {
94 GtkAllocation toplevel_allocation;
95 GtkWidget *toplevel;
96 GtkWidget *child;
97 GtkLabel *label;
98 const gchar *text;
99
100 label = GTK_LABEL (paned->priv->show_hide_label);
101
102 /* Update the expander label. */
103 if (gtk_expander_get_expanded (expander))
104 text = _("Hide Attachment _Bar");
105 else
106 text = _("Show Attachment _Bar");
107
108 gtk_label_set_text_with_mnemonic (label, text);
109
110 /* Resize the top-level window if required conditions are met.
111 * This is based on gtk_expander_resize_toplevel(), but adapted
112 * to the fact our GtkExpander has no direct child widget. */
113
114 if (!e_attachment_paned_get_resize_toplevel (paned))
115 return;
116
117 if (!gtk_widget_get_realized (GTK_WIDGET (paned)))
118 return;
119
120 child = gtk_paned_get_child2 (GTK_PANED (paned));
121 toplevel = gtk_widget_get_toplevel (GTK_WIDGET (paned));
122
123 if (toplevel == NULL)
124 return;
125
126 if (!gtk_widget_get_realized (GTK_WIDGET (toplevel)))
127 return;
128
129 gtk_widget_get_allocation (toplevel, &toplevel_allocation);
130
131 if (gtk_expander_get_expanded (expander)) {
132 GtkRequisition child_requisition;
133
134 gtk_widget_get_preferred_size (
135 child, &child_requisition, NULL);
136
137 toplevel_allocation.height += child_requisition.height;
138 } else {
139 GtkAllocation child_allocation;
140
141 gtk_widget_get_allocation (child, &child_allocation);
142
143 toplevel_allocation.height -= child_allocation.height;
144 }
145
146 gtk_window_resize (
147 GTK_WINDOW (toplevel),
148 toplevel_allocation.width,
149 toplevel_allocation.height);
150 }
151
152 static void
153 attachment_paned_update_status (EAttachmentPaned *paned)
154 {
155 EAttachmentView *view;
156 EAttachmentStore *store;
157 GtkExpander *expander;
158 GtkLabel *label;
159 guint num_attachments;
160 guint64 total_size;
161 gchar *display_size;
162 gchar *markup;
163
164 view = E_ATTACHMENT_VIEW (paned);
165 store = e_attachment_view_get_store (view);
166 expander = GTK_EXPANDER (paned->priv->expander);
167 label = GTK_LABEL (paned->priv->status_label);
168
169 num_attachments = e_attachment_store_get_num_attachments (store);
170 total_size = e_attachment_store_get_total_size (store);
171 display_size = g_format_size_for_display (total_size);
172
173 if (total_size > 0)
174 markup = g_strdup_printf (
175 "<b>%d</b> %s (%s)", num_attachments, ngettext (
176 "Attachment", "Attachments", num_attachments),
177 display_size);
178 else
179 markup = g_strdup_printf (
180 "<b>%d</b> %s", num_attachments, ngettext (
181 "Attachment", "Attachments", num_attachments));
182 gtk_label_set_markup (label, markup);
183 g_free (markup);
184
185 g_free (display_size);
186
187 if (num_attachments > 0) {
188 gtk_widget_show (paned->priv->status_icon);
189 gtk_widget_show (paned->priv->status_label);
190 gtk_expander_set_expanded (expander, TRUE);
191 } else {
192 gtk_widget_hide (paned->priv->status_icon);
193 gtk_widget_hide (paned->priv->status_label);
194 gtk_expander_set_expanded (expander, FALSE);
195 }
196 }
197
198 static void
199 attachment_paned_set_property (GObject *object,
200 guint property_id,
201 const GValue *value,
202 GParamSpec *pspec)
203 {
204 switch (property_id) {
205 case PROP_ACTIVE_VIEW:
206 e_attachment_paned_set_active_view (
207 E_ATTACHMENT_PANED (object),
208 g_value_get_int (value));
209 return;
210
211 case PROP_DRAGGING:
212 e_attachment_view_set_dragging (
213 E_ATTACHMENT_VIEW (object),
214 g_value_get_boolean (value));
215 return;
216
217 case PROP_EDITABLE:
218 e_attachment_view_set_editable (
219 E_ATTACHMENT_VIEW (object),
220 g_value_get_boolean (value));
221 return;
222
223 case PROP_EXPANDED:
224 e_attachment_paned_set_expanded (
225 E_ATTACHMENT_PANED (object),
226 g_value_get_boolean (value));
227 return;
228
229 case PROP_RESIZE_TOPLEVEL:
230 e_attachment_paned_set_resize_toplevel (
231 E_ATTACHMENT_PANED (object),
232 g_value_get_boolean (value));
233 return;
234 }
235
236 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
237 }
238
239 static void
240 attachment_paned_get_property (GObject *object,
241 guint property_id,
242 GValue *value,
243 GParamSpec *pspec)
244 {
245 switch (property_id) {
246 case PROP_ACTIVE_VIEW:
247 g_value_set_int (
248 value,
249 e_attachment_paned_get_active_view (
250 E_ATTACHMENT_PANED (object)));
251 return;
252
253 case PROP_DRAGGING:
254 g_value_set_boolean (
255 value,
256 e_attachment_view_get_dragging (
257 E_ATTACHMENT_VIEW (object)));
258 return;
259
260 case PROP_EDITABLE:
261 g_value_set_boolean (
262 value,
263 e_attachment_view_get_editable (
264 E_ATTACHMENT_VIEW (object)));
265 return;
266
267 case PROP_EXPANDED:
268 g_value_set_boolean (
269 value,
270 e_attachment_paned_get_expanded (
271 E_ATTACHMENT_PANED (object)));
272 return;
273
274 case PROP_RESIZE_TOPLEVEL:
275 g_value_set_boolean (
276 value,
277 e_attachment_paned_get_resize_toplevel (
278 E_ATTACHMENT_PANED (object)));
279 return;
280 }
281
282 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
283 }
284
285 static void
286 attachment_paned_dispose (GObject *object)
287 {
288 EAttachmentPanedPrivate *priv;
289
290 priv = E_ATTACHMENT_PANED_GET_PRIVATE (object);
291
292 if (priv->model != NULL) {
293 e_attachment_store_remove_all (E_ATTACHMENT_STORE (priv->model));
294 g_object_unref (priv->model);
295 priv->model = NULL;
296 }
297
298 if (priv->expander != NULL) {
299 g_object_unref (priv->expander);
300 priv->expander = NULL;
301 }
302
303 if (priv->notebook != NULL) {
304 g_object_unref (priv->notebook);
305 priv->notebook = NULL;
306 }
307
308 if (priv->combo_box != NULL) {
309 g_object_unref (priv->combo_box);
310 priv->combo_box = NULL;
311 }
312
313 if (priv->icon_view != NULL) {
314 g_object_unref (priv->icon_view);
315 priv->icon_view = NULL;
316 }
317
318 if (priv->tree_view != NULL) {
319 g_object_unref (priv->tree_view);
320 priv->tree_view = NULL;
321 }
322
323 if (priv->show_hide_label != NULL) {
324 g_object_unref (priv->show_hide_label);
325 priv->show_hide_label = NULL;
326 }
327
328 if (priv->status_icon != NULL) {
329 g_object_unref (priv->status_icon);
330 priv->status_icon = NULL;
331 }
332
333 if (priv->status_label != NULL) {
334 g_object_unref (priv->status_label);
335 priv->status_label = NULL;
336 }
337
338 if (priv->content_area != NULL) {
339 g_object_unref (priv->content_area);
340 priv->content_area = NULL;
341 }
342
343 /* Chain up to parent's dispose() method. */
344 G_OBJECT_CLASS (e_attachment_paned_parent_class)->dispose (object);
345 }
346
347 static void
348 attachment_paned_constructed (GObject *object)
349 {
350 EAttachmentPanedPrivate *priv;
351 GSettings *settings;
352
353 priv = E_ATTACHMENT_PANED_GET_PRIVATE (object);
354
355 settings = g_settings_new ("org.gnome.evolution.shell");
356
357 /* Set up property-to-property bindings. */
358
359 g_object_bind_property (
360 object, "active-view",
361 priv->combo_box, "active",
362 G_BINDING_BIDIRECTIONAL |
363 G_BINDING_SYNC_CREATE);
364
365 g_object_bind_property (
366 object, "active-view",
367 priv->notebook, "page",
368 G_BINDING_BIDIRECTIONAL |
369 G_BINDING_SYNC_CREATE);
370
371 g_object_bind_property (
372 object, "dragging",
373 priv->icon_view, "dragging",
374 G_BINDING_BIDIRECTIONAL |
375 G_BINDING_SYNC_CREATE);
376
377 g_object_bind_property (
378 object, "dragging",
379 priv->tree_view, "dragging",
380 G_BINDING_BIDIRECTIONAL |
381 G_BINDING_SYNC_CREATE);
382
383 g_object_bind_property (
384 object, "editable",
385 priv->icon_view, "editable",
386 G_BINDING_BIDIRECTIONAL |
387 G_BINDING_SYNC_CREATE);
388
389 g_object_bind_property (
390 object, "editable",
391 priv->tree_view, "editable",
392 G_BINDING_BIDIRECTIONAL |
393 G_BINDING_SYNC_CREATE);
394
395 g_object_bind_property (
396 object, "expanded",
397 priv->expander, "expanded",
398 G_BINDING_BIDIRECTIONAL |
399 G_BINDING_SYNC_CREATE);
400
401 g_object_bind_property (
402 object, "expanded",
403 priv->combo_box, "sensitive",
404 G_BINDING_BIDIRECTIONAL |
405 G_BINDING_SYNC_CREATE);
406
407 g_object_bind_property (
408 object, "expanded",
409 priv->notebook, "visible",
410 G_BINDING_BIDIRECTIONAL |
411 G_BINDING_SYNC_CREATE);
412
413 /* Set up property-to-GSettings bindings. */
414 g_settings_bind (
415 settings, "attachment-view",
416 object, "active-view",
417 G_SETTINGS_BIND_DEFAULT);
418
419 g_object_unref (settings);
420
421 /* Chain up to parent's constructed() method. */
422 G_OBJECT_CLASS (e_attachment_paned_parent_class)->constructed (object);
423 }
424
425 static EAttachmentViewPrivate *
426 attachment_paned_get_private (EAttachmentView *view)
427 {
428 EAttachmentPanedPrivate *priv;
429
430 priv = E_ATTACHMENT_PANED_GET_PRIVATE (view);
431 view = E_ATTACHMENT_VIEW (priv->icon_view);
432
433 return e_attachment_view_get_private (view);
434 }
435
436 static EAttachmentStore *
437 attachment_paned_get_store (EAttachmentView *view)
438 {
439 EAttachmentPanedPrivate *priv;
440
441 priv = E_ATTACHMENT_PANED_GET_PRIVATE (view);
442 view = E_ATTACHMENT_VIEW (priv->icon_view);
443
444 return e_attachment_view_get_store (view);
445 }
446
447 static GtkTreePath *
448 attachment_paned_get_path_at_pos (EAttachmentView *view,
449 gint x,
450 gint y)
451 {
452 EAttachmentPanedPrivate *priv;
453
454 priv = E_ATTACHMENT_PANED_GET_PRIVATE (view);
455 view = E_ATTACHMENT_VIEW (priv->icon_view);
456
457 return e_attachment_view_get_path_at_pos (view, x, y);
458 }
459
460 static GList *
461 attachment_paned_get_selected_paths (EAttachmentView *view)
462 {
463 EAttachmentPanedPrivate *priv;
464
465 priv = E_ATTACHMENT_PANED_GET_PRIVATE (view);
466 view = E_ATTACHMENT_VIEW (priv->icon_view);
467
468 return e_attachment_view_get_selected_paths (view);
469 }
470
471 static gboolean
472 attachment_paned_path_is_selected (EAttachmentView *view,
473 GtkTreePath *path)
474 {
475 EAttachmentPanedPrivate *priv;
476
477 priv = E_ATTACHMENT_PANED_GET_PRIVATE (view);
478 view = E_ATTACHMENT_VIEW (priv->icon_view);
479
480 return e_attachment_view_path_is_selected (view, path);
481 }
482
483 static void
484 attachment_paned_select_path (EAttachmentView *view,
485 GtkTreePath *path)
486 {
487 EAttachmentPanedPrivate *priv;
488
489 priv = E_ATTACHMENT_PANED_GET_PRIVATE (view);
490 view = E_ATTACHMENT_VIEW (priv->icon_view);
491
492 e_attachment_view_select_path (view, path);
493 }
494
495 static void
496 attachment_paned_unselect_path (EAttachmentView *view,
497 GtkTreePath *path)
498 {
499 EAttachmentPanedPrivate *priv;
500
501 priv = E_ATTACHMENT_PANED_GET_PRIVATE (view);
502 view = E_ATTACHMENT_VIEW (priv->icon_view);
503
504 e_attachment_view_unselect_path (view, path);
505 }
506
507 static void
508 attachment_paned_select_all (EAttachmentView *view)
509 {
510 EAttachmentPanedPrivate *priv;
511
512 priv = E_ATTACHMENT_PANED_GET_PRIVATE (view);
513 view = E_ATTACHMENT_VIEW (priv->icon_view);
514
515 e_attachment_view_select_all (view);
516 }
517
518 static void
519 attachment_paned_unselect_all (EAttachmentView *view)
520 {
521 EAttachmentPanedPrivate *priv;
522
523 priv = E_ATTACHMENT_PANED_GET_PRIVATE (view);
524 view = E_ATTACHMENT_VIEW (priv->icon_view);
525
526 e_attachment_view_unselect_all (view);
527 }
528
529 static void
530 attachment_paned_update_actions (EAttachmentView *view)
531 {
532 EAttachmentPanedPrivate *priv;
533
534 priv = E_ATTACHMENT_PANED_GET_PRIVATE (view);
535 view = E_ATTACHMENT_VIEW (priv->icon_view);
536
537 e_attachment_view_update_actions (view);
538 }
539
540 static void
541 e_attachment_paned_class_init (EAttachmentPanedClass *class)
542 {
543 GObjectClass *object_class;
544
545 g_type_class_add_private (class, sizeof (EAttachmentPanedPrivate));
546
547 object_class = G_OBJECT_CLASS (class);
548 object_class->set_property = attachment_paned_set_property;
549 object_class->get_property = attachment_paned_get_property;
550 object_class->dispose = attachment_paned_dispose;
551 object_class->constructed = attachment_paned_constructed;
552
553 g_object_class_install_property (
554 object_class,
555 PROP_ACTIVE_VIEW,
556 g_param_spec_int (
557 "active-view",
558 "Active View",
559 NULL,
560 0,
561 NUM_VIEWS,
562 0,
563 G_PARAM_READWRITE |
564 G_PARAM_CONSTRUCT |
565 G_PARAM_STATIC_STRINGS));
566
567 g_object_class_override_property (
568 object_class, PROP_DRAGGING, "dragging");
569
570 g_object_class_override_property (
571 object_class, PROP_EDITABLE, "editable");
572
573 g_object_class_install_property (
574 object_class,
575 PROP_EXPANDED,
576 g_param_spec_boolean (
577 "expanded",
578 "Expanded",
579 NULL,
580 FALSE,
581 G_PARAM_READWRITE |
582 G_PARAM_CONSTRUCT |
583 G_PARAM_STATIC_STRINGS));
584
585 g_object_class_install_property (
586 object_class,
587 PROP_RESIZE_TOPLEVEL,
588 g_param_spec_boolean (
589 "resize-toplevel",
590 "Resize-Toplevel",
591 NULL,
592 FALSE,
593 G_PARAM_READWRITE |
594 G_PARAM_CONSTRUCT |
595 G_PARAM_STATIC_STRINGS));
596 }
597
598 static void
599 e_attachment_paned_init (EAttachmentPaned *paned)
600 {
601 EAttachmentView *view;
602 GtkSizeGroup *size_group;
603 GtkWidget *container;
604 GtkWidget *widget;
605 GtkAction *action;
606
607 paned->priv = E_ATTACHMENT_PANED_GET_PRIVATE (paned);
608 paned->priv->model = e_attachment_store_new ();
609
610 /* Keep the expander label and combo box the same height. */
611 size_group = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL);
612
613 /* Construct the Attachment Views */
614
615 container = GTK_WIDGET (paned);
616
617 widget = gtk_notebook_new ();
618 gtk_widget_set_size_request (widget, -1, initial_height);
619 gtk_notebook_set_show_tabs (GTK_NOTEBOOK (widget), FALSE);
620 gtk_notebook_set_show_border (GTK_NOTEBOOK (widget), FALSE);
621 gtk_paned_pack2 (GTK_PANED (container), widget, FALSE, FALSE);
622 paned->priv->notebook = g_object_ref (widget);
623 gtk_widget_hide (widget);
624
625 container = paned->priv->notebook;
626
627 widget = gtk_scrolled_window_new (NULL, NULL);
628 gtk_scrolled_window_set_policy (
629 GTK_SCROLLED_WINDOW (widget),
630 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
631 gtk_scrolled_window_set_shadow_type (
632 GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN);
633 gtk_notebook_append_page (GTK_NOTEBOOK (container), widget, NULL);
634 gtk_widget_show (widget);
635
636 container = widget;
637
638 widget = e_attachment_icon_view_new ();
639 gtk_widget_set_can_focus (widget, TRUE);
640 gtk_icon_view_set_model (GTK_ICON_VIEW (widget), paned->priv->model);
641 gtk_container_add (GTK_CONTAINER (container), widget);
642 paned->priv->icon_view = g_object_ref (widget);
643 gtk_widget_show (widget);
644
645 container = paned->priv->notebook;
646
647 widget = gtk_scrolled_window_new (NULL, NULL);
648 gtk_scrolled_window_set_policy (
649 GTK_SCROLLED_WINDOW (widget),
650 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
651 gtk_scrolled_window_set_shadow_type (
652 GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN);
653 gtk_notebook_append_page (GTK_NOTEBOOK (container), widget, NULL);
654 gtk_widget_show (widget);
655
656 container = widget;
657
658 widget = e_attachment_tree_view_new ();
659 gtk_widget_set_can_focus (widget, TRUE);
660 gtk_tree_view_set_model (GTK_TREE_VIEW (widget), paned->priv->model);
661 gtk_container_add (GTK_CONTAINER (container), widget);
662 paned->priv->tree_view = g_object_ref (widget);
663 gtk_widget_show (widget);
664
665 /* Construct the Controls */
666
667 container = GTK_WIDGET (paned);
668
669 widget = gtk_vbox_new (FALSE, 6);
670 gtk_paned_pack1 (GTK_PANED (container), widget, TRUE, FALSE);
671 paned->priv->content_area = g_object_ref (widget);
672 gtk_widget_show (widget);
673
674 container = widget;
675
676 widget = gtk_hbox_new (FALSE, 6);
677 gtk_box_pack_end (GTK_BOX (container), widget, FALSE, FALSE, 0);
678 paned->priv->controls_container = widget;
679 gtk_widget_show (widget);
680
681 container = widget;
682
683 widget = gtk_expander_new (NULL);
684 gtk_expander_set_spacing (GTK_EXPANDER (widget), 0);
685 gtk_expander_set_label_fill (GTK_EXPANDER (widget), TRUE);
686 gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
687 paned->priv->expander = g_object_ref (widget);
688 gtk_widget_show (widget);
689
690 /* The "Add Attachment" button proxies the "add" action from
691 * one of the two attachment views. Doesn't matter which. */
692 widget = gtk_button_new ();
693 view = E_ATTACHMENT_VIEW (paned->priv->icon_view);
694 action = e_attachment_view_get_action (view, "add");
695 gtk_button_set_image (GTK_BUTTON (widget), gtk_image_new ());
696 gtk_activatable_set_related_action (GTK_ACTIVATABLE (widget), action);
697 gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
698 gtk_widget_show (widget);
699
700 widget = gtk_combo_box_text_new ();
701 gtk_size_group_add_widget (size_group, widget);
702 gtk_combo_box_text_append_text (
703 GTK_COMBO_BOX_TEXT (widget), _("Icon View"));
704 gtk_combo_box_text_append_text (
705 GTK_COMBO_BOX_TEXT (widget), _("List View"));
706 gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
707 paned->priv->combo_box = g_object_ref (widget);
708 gtk_widget_show (widget);
709
710 container = paned->priv->expander;
711
712 widget = gtk_hbox_new (FALSE, 6);
713 gtk_size_group_add_widget (size_group, widget);
714 gtk_expander_set_label_widget (GTK_EXPANDER (container), widget);
715 gtk_widget_show (widget);
716
717 container = widget;
718
719 widget = gtk_label_new_with_mnemonic (_("Show Attachment _Bar"));
720 gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
721 paned->priv->show_hide_label = g_object_ref (widget);
722 gtk_widget_show (widget);
723
724 widget = gtk_alignment_new (0.5, 0.5, 0.0, 1.0);
725 gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
726 gtk_widget_show (widget);
727
728 container = widget;
729
730 widget = gtk_hbox_new (FALSE, 6);
731 gtk_container_add (GTK_CONTAINER (container), widget);
732 gtk_widget_show (widget);
733
734 container = widget;
735
736 widget = gtk_image_new_from_icon_name (
737 "mail-attachment", GTK_ICON_SIZE_MENU);
738 gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
739 paned->priv->status_icon = g_object_ref (widget);
740 gtk_widget_hide (widget);
741
742 widget = gtk_label_new (NULL);
743 gtk_label_set_use_markup (GTK_LABEL (widget), TRUE);
744 gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
745 paned->priv->status_label = g_object_ref (widget);
746 gtk_widget_hide (widget);
747
748 g_signal_connect_swapped (
749 paned->priv->expander, "notify::expanded",
750 G_CALLBACK (attachment_paned_notify_cb), paned);
751
752 g_signal_connect_swapped (
753 paned->priv->model, "notify::num-attachments",
754 G_CALLBACK (attachment_paned_update_status), paned);
755
756 g_signal_connect_swapped (
757 paned->priv->model, "notify::total-size",
758 G_CALLBACK (attachment_paned_update_status), paned);
759
760 g_object_unref (size_group);
761 }
762
763 static void
764 e_attachment_paned_interface_init (EAttachmentViewInterface *interface)
765 {
766 interface->get_private = attachment_paned_get_private;
767 interface->get_store = attachment_paned_get_store;
768 interface->get_path_at_pos = attachment_paned_get_path_at_pos;
769 interface->get_selected_paths = attachment_paned_get_selected_paths;
770 interface->path_is_selected = attachment_paned_path_is_selected;
771 interface->select_path = attachment_paned_select_path;
772 interface->unselect_path = attachment_paned_unselect_path;
773 interface->select_all = attachment_paned_select_all;
774 interface->unselect_all = attachment_paned_unselect_all;
775 interface->update_actions = attachment_paned_update_actions;
776 }
777
778 GtkWidget *
779 e_attachment_paned_new (void)
780 {
781 return g_object_new (E_TYPE_ATTACHMENT_PANED, NULL);
782 }
783
784 GtkWidget *
785 e_attachment_paned_get_content_area (EAttachmentPaned *paned)
786 {
787 g_return_val_if_fail (E_IS_ATTACHMENT_PANED (paned), NULL);
788
789 return paned->priv->content_area;
790 }
791
792 gint
793 e_attachment_paned_get_active_view (EAttachmentPaned *paned)
794 {
795 g_return_val_if_fail (E_IS_ATTACHMENT_PANED (paned), 0);
796
797 return paned->priv->active_view;
798 }
799
800 void
801 e_attachment_paned_set_active_view (EAttachmentPaned *paned,
802 gint active_view)
803 {
804 EAttachmentView *source;
805 EAttachmentView *target;
806
807 g_return_if_fail (E_IS_ATTACHMENT_PANED (paned));
808 g_return_if_fail (active_view >= 0 && active_view < NUM_VIEWS);
809
810 if (active_view == paned->priv->active_view)
811 return;
812
813 paned->priv->active_view = active_view;
814
815 /* Synchronize the item selection of the view we're
816 * switching TO with the view we're switching FROM. */
817 if (active_view == 0) {
818 /* from tree view to icon view */
819 source = E_ATTACHMENT_VIEW (paned->priv->tree_view);
820 target = E_ATTACHMENT_VIEW (paned->priv->icon_view);
821 } else {
822 /* from icon view to tree view */
823 source = E_ATTACHMENT_VIEW (paned->priv->icon_view);
824 target = E_ATTACHMENT_VIEW (paned->priv->tree_view);
825 }
826
827 e_attachment_view_sync_selection (source, target);
828
829 g_object_notify (G_OBJECT (paned), "active-view");
830 }
831
832 gboolean
833 e_attachment_paned_get_expanded (EAttachmentPaned *paned)
834 {
835 g_return_val_if_fail (E_IS_ATTACHMENT_PANED (paned), FALSE);
836
837 return paned->priv->expanded;
838 }
839
840 void
841 e_attachment_paned_set_expanded (EAttachmentPaned *paned,
842 gboolean expanded)
843 {
844 g_return_if_fail (E_IS_ATTACHMENT_PANED (paned));
845
846 if (paned->priv->expanded == expanded)
847 return;
848
849 paned->priv->expanded = expanded;
850
851 g_object_notify (G_OBJECT (paned), "expanded");
852 }
853
854 gboolean
855 e_attachment_paned_get_resize_toplevel (EAttachmentPaned *paned)
856 {
857 g_return_val_if_fail (E_IS_ATTACHMENT_PANED (paned), FALSE);
858
859 return paned->priv->resize_toplevel;
860 }
861
862 void
863 e_attachment_paned_set_resize_toplevel (EAttachmentPaned *paned,
864 gboolean resize_toplevel)
865 {
866 g_return_if_fail (E_IS_ATTACHMENT_PANED (paned));
867
868 if (paned->priv->resize_toplevel == resize_toplevel)
869 return;
870
871 paned->priv->resize_toplevel = resize_toplevel;
872
873 g_object_notify (G_OBJECT (paned), "resize-toplevel");
874 }
875
876 void
877 e_attachment_paned_drag_data_received (EAttachmentPaned *paned,
878 GdkDragContext *context,
879 gint x,
880 gint y,
881 GtkSelectionData *selection,
882 guint info,
883 guint time)
884 {
885 g_return_if_fail (E_IS_ATTACHMENT_PANED (paned));
886
887 /* XXX Dirty hack for forwarding drop events. */
888 g_signal_emit_by_name (
889 paned->priv->icon_view, "drag-data-received",
890 context, x, y, selection, info, time);
891 }
892
893 GtkWidget *
894 e_attachment_paned_get_controls_container (EAttachmentPaned *paned)
895 {
896 return paned->priv->controls_container;
897 }
898
899 GtkWidget *
900 e_attachment_paned_get_view_combo (EAttachmentPaned *paned)
901 {
902 return paned->priv->combo_box;
903 }