No issues found
1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU Lesser General Public
4 * License as published by the Free Software Foundation; either
5 * version 2 of the License, or (at your option) version 3.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 * Lesser General Public License for more details.
11 *
12 * You should have received a copy of the GNU Lesser General Public
13 * License along with the program; if not, see <http://www.gnu.org/licenses/>
14 *
15 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
16 */
17
18 #ifdef HAVE_CONFIG_H
19 #include <config.h>
20 #endif
21
22 #include "e-composer-header-table.h"
23
24 #include <glib/gi18n-lib.h>
25 #include <libedataserverui/libedataserverui.h>
26
27 #include <shell/e-shell.h>
28 #include <misc/e-mail-signature-combo-box.h>
29
30 #include "e-msg-composer.h"
31 #include "e-composer-private.h"
32 #include "e-composer-from-header.h"
33 #include "e-composer-name-header.h"
34 #include "e-composer-post-header.h"
35 #include "e-composer-spell-header.h"
36 #include "e-composer-text-header.h"
37
38 #define E_COMPOSER_HEADER_TABLE_GET_PRIVATE(obj) \
39 (G_TYPE_INSTANCE_GET_PRIVATE \
40 ((obj), E_TYPE_COMPOSER_HEADER_TABLE, EComposerHeaderTablePrivate))
41
42 #define HEADER_TOOLTIP_TO \
43 _("Enter the recipients of the message")
44 #define HEADER_TOOLTIP_CC \
45 _("Enter the addresses that will receive a " \
46 "carbon copy of the message")
47 #define HEADER_TOOLTIP_BCC \
48 _("Enter the addresses that will receive a " \
49 "carbon copy of the message without appearing " \
50 "in the recipient list of the message")
51
52 #define E_COMPOSER_HEADER_TABLE_GET_PRIVATE(obj) \
53 (G_TYPE_INSTANCE_GET_PRIVATE \
54 ((obj), E_TYPE_COMPOSER_HEADER_TABLE, EComposerHeaderTablePrivate))
55
56 struct _EComposerHeaderTablePrivate {
57 EComposerHeader *headers[E_COMPOSER_NUM_HEADERS];
58 GtkWidget *signature_label;
59 GtkWidget *signature_combo_box;
60 ENameSelector *name_selector;
61 ESourceRegistry *registry;
62 EShell *shell;
63 };
64
65 enum {
66 PROP_0,
67 PROP_DESTINATIONS_BCC,
68 PROP_DESTINATIONS_CC,
69 PROP_DESTINATIONS_TO,
70 PROP_IDENTITY_UID,
71 PROP_POST_TO,
72 PROP_REGISTRY,
73 PROP_REPLY_TO,
74 PROP_SHELL,
75 PROP_SIGNATURE_COMBO_BOX,
76 PROP_SIGNATURE_UID,
77 PROP_SUBJECT
78 };
79
80 G_DEFINE_TYPE (
81 EComposerHeaderTable,
82 e_composer_header_table,
83 GTK_TYPE_TABLE)
84
85 static void
86 g_value_set_destinations (GValue *value,
87 EDestination **destinations)
88 {
89 GValueArray *value_array;
90 GValue element = G_VALUE_INIT;
91 gint ii;
92
93 g_value_init (&element, E_TYPE_DESTINATION);
94
95 /* Preallocate some reasonable number. */
96 value_array = g_value_array_new (64);
97
98 for (ii = 0; destinations[ii] != NULL; ii++) {
99 g_value_set_object (&element, destinations[ii]);
100 g_value_array_append (value_array, &element);
101 }
102
103 g_value_take_boxed (value, value_array);
104 }
105
106 static EDestination **
107 g_value_dup_destinations (const GValue *value)
108 {
109 EDestination **destinations;
110 GValueArray *value_array;
111 GValue *element;
112 gint ii;
113
114 value_array = g_value_get_boxed (value);
115 destinations = g_new0 (EDestination *, value_array->n_values + 1);
116
117 for (ii = 0; ii < value_array->n_values; ii++) {
118 element = g_value_array_get_nth (value_array, ii);
119 destinations[ii] = g_value_dup_object (element);
120 }
121
122 return destinations;
123 }
124
125 static void
126 g_value_set_string_list (GValue *value,
127 GList *list)
128 {
129 GValueArray *value_array;
130 GValue element = G_VALUE_INIT;
131
132 g_value_init (&element, G_TYPE_STRING);
133
134 value_array = g_value_array_new (g_list_length (list));
135
136 while (list != NULL) {
137 g_value_set_string (&element, list->data);
138 g_value_array_append (value_array, &element);
139 }
140
141 g_value_take_boxed (value, value_array);
142 }
143
144 static GList *
145 g_value_dup_string_list (const GValue *value)
146 {
147 GValueArray *value_array;
148 GList *list = NULL;
149 GValue *element;
150 gint ii;
151
152 value_array = g_value_get_boxed (value);
153
154 for (ii = 0; ii < value_array->n_values; ii++) {
155 element = g_value_array_get_nth (value_array, ii);
156 list = g_list_prepend (list, g_value_dup_string (element));
157 }
158
159 return g_list_reverse (list);
160 }
161
162 static void
163 composer_header_table_notify_header (EComposerHeader *header,
164 const gchar *property_name)
165 {
166 GtkWidget *parent;
167
168 parent = gtk_widget_get_parent (header->input_widget);
169 g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (parent));
170 g_object_notify (G_OBJECT (parent), property_name);
171 }
172
173 static void
174 composer_header_table_notify_widget (GtkWidget *widget,
175 const gchar *property_name)
176 {
177 EShell *shell;
178 GtkWidget *parent;
179
180 /* FIXME Pass this in somehow. */
181 shell = e_shell_get_default ();
182
183 if (e_shell_get_small_screen_mode (shell)) {
184 parent = gtk_widget_get_parent (widget);
185 parent = g_object_get_data (G_OBJECT (parent), "pdata");
186 } else
187 parent = gtk_widget_get_parent (widget);
188 g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (parent));
189 g_object_notify (G_OBJECT (parent), property_name);
190 }
191
192 static void
193 composer_header_table_bind_header (const gchar *property_name,
194 const gchar *signal_name,
195 EComposerHeader *header)
196 {
197 /* Propagate the signal as "notify::property_name". */
198
199 g_signal_connect (
200 header, signal_name,
201 G_CALLBACK (composer_header_table_notify_header),
202 (gpointer) property_name);
203 }
204
205 static void
206 composer_header_table_bind_widget (const gchar *property_name,
207 const gchar *signal_name,
208 GtkWidget *widget)
209 {
210 /* Propagate the signal as "notify::property_name". */
211
212 g_signal_connect (
213 widget, signal_name,
214 G_CALLBACK (composer_header_table_notify_widget),
215 (gpointer) property_name);
216 }
217
218 static EDestination **
219 composer_header_table_update_destinations (EDestination **old_destinations,
220 const gchar * const *auto_addresses)
221 {
222 CamelAddress *address;
223 CamelInternetAddress *inet_address;
224 EDestination **new_destinations;
225 EDestination *destination;
226 GQueue queue = G_QUEUE_INIT;
227 guint length;
228 gint ii;
229
230 /* Include automatic recipients for the selected account. */
231
232 if (auto_addresses == NULL)
233 goto skip_auto;
234
235 inet_address = camel_internet_address_new ();
236 address = CAMEL_ADDRESS (inet_address);
237
238 /* XXX Calling camel_address_decode() multiple times on the same
239 * CamelInternetAddress has a cumulative effect, which isn't
240 * well documented. */
241 for (ii = 0; auto_addresses[ii] != NULL; ii++)
242 camel_address_decode (address, auto_addresses[ii]);
243
244 for (ii = 0; ii < camel_address_length (address); ii++) {
245 const gchar *name, *email;
246
247 if (!camel_internet_address_get (
248 inet_address, ii, &name, &email))
249 continue;
250
251 destination = e_destination_new ();
252 e_destination_set_auto_recipient (destination, TRUE);
253
254 if (name != NULL)
255 e_destination_set_name (destination, name);
256
257 if (email != NULL)
258 e_destination_set_email (destination, email);
259
260 g_queue_push_tail (&queue, destination);
261 }
262
263 g_object_unref (inet_address);
264
265 skip_auto:
266
267 /* Include custom recipients for this message. */
268
269 if (old_destinations == NULL)
270 goto skip_custom;
271
272 for (ii = 0; old_destinations[ii] != NULL; ii++) {
273 if (e_destination_is_auto_recipient (old_destinations[ii]))
274 continue;
275
276 destination = e_destination_copy (old_destinations[ii]);
277 g_queue_push_tail (&queue, destination);
278 }
279
280 skip_custom:
281
282 length = g_queue_get_length (&queue);
283 new_destinations = g_new0 (EDestination *, length + 1);
284
285 for (ii = 0; ii < length; ii++)
286 new_destinations[ii] = g_queue_pop_head (&queue);
287
288 /* Sanity check. */
289 g_warn_if_fail (g_queue_is_empty (&queue));
290
291 return new_destinations;
292 }
293
294 static gboolean
295 from_header_should_be_visible (EComposerHeaderTable *table)
296 {
297 EShell *shell;
298 EComposerHeader *header;
299 EComposerHeaderType type;
300 GtkComboBox *combo_box;
301 GtkTreeModel *tree_model;
302
303 shell = e_composer_header_table_get_shell (table);
304
305 /* Always display From in standard mode. */
306 if (!e_shell_get_express_mode (shell))
307 return TRUE;
308
309 type = E_COMPOSER_HEADER_FROM;
310 header = e_composer_header_table_get_header (table, type);
311
312 combo_box = GTK_COMBO_BOX (header->input_widget);
313 tree_model = gtk_combo_box_get_model (combo_box);
314
315 return (gtk_tree_model_iter_n_children (tree_model, NULL) > 1);
316 }
317
318 static void
319 composer_header_table_setup_mail_headers (EComposerHeaderTable *table)
320 {
321 GSettings *settings;
322 gint ii;
323
324 settings = g_settings_new ("org.gnome.evolution.mail");
325
326 for (ii = 0; ii < E_COMPOSER_NUM_HEADERS; ii++) {
327 EComposerHeader *header;
328 const gchar *key;
329 gboolean sensitive;
330 gboolean visible;
331
332 header = e_composer_header_table_get_header (table, ii);
333
334 switch (ii) {
335 case E_COMPOSER_HEADER_BCC:
336 key = "composer-show-bcc";
337 break;
338
339 case E_COMPOSER_HEADER_CC:
340 key = "composer-show-cc";
341 break;
342
343 case E_COMPOSER_HEADER_REPLY_TO:
344 key = "composer-show-reply-to";
345 break;
346
347 default:
348 key = NULL;
349 break;
350 }
351
352 if (key != NULL)
353 g_settings_unbind (header, "visible");
354
355 switch (ii) {
356 case E_COMPOSER_HEADER_FROM:
357 sensitive = TRUE;
358 visible = from_header_should_be_visible (table);
359 break;
360
361 case E_COMPOSER_HEADER_BCC:
362 case E_COMPOSER_HEADER_CC:
363 case E_COMPOSER_HEADER_REPLY_TO:
364 case E_COMPOSER_HEADER_SUBJECT:
365 case E_COMPOSER_HEADER_TO:
366 sensitive = TRUE;
367 visible = TRUE;
368 break;
369
370 default:
371 sensitive = FALSE;
372 visible = FALSE;
373 break;
374 }
375
376 e_composer_header_set_sensitive (header, sensitive);
377 e_composer_header_set_visible (header, visible);
378
379 if (key != NULL)
380 g_settings_bind (
381 settings, key,
382 header, "visible",
383 G_SETTINGS_BIND_DEFAULT);
384 }
385
386 g_object_unref (settings);
387 }
388
389 static void
390 composer_header_table_setup_post_headers (EComposerHeaderTable *table)
391 {
392 GSettings *settings;
393 gint ii;
394
395 settings = g_settings_new ("org.gnome.evolution.mail");
396
397 for (ii = 0; ii < E_COMPOSER_NUM_HEADERS; ii++) {
398 EComposerHeader *header;
399 const gchar *key;
400
401 header = e_composer_header_table_get_header (table, ii);
402
403 switch (ii) {
404 case E_COMPOSER_HEADER_FROM:
405 key = "composer-show-post-from";
406 break;
407
408 case E_COMPOSER_HEADER_REPLY_TO:
409 key = "composer-show-post-reply-to";
410 break;
411
412 default:
413 key = NULL;
414 break;
415 }
416
417 if (key != NULL)
418 g_settings_unbind (header, "visible");
419
420 switch (ii) {
421 case E_COMPOSER_HEADER_FROM:
422 case E_COMPOSER_HEADER_POST_TO:
423 case E_COMPOSER_HEADER_REPLY_TO:
424 case E_COMPOSER_HEADER_SUBJECT:
425 e_composer_header_set_sensitive (header, TRUE);
426 e_composer_header_set_visible (header, TRUE);
427 break;
428
429 default: /* this includes TO, CC and BCC */
430 e_composer_header_set_sensitive (header, FALSE);
431 e_composer_header_set_visible (header, FALSE);
432 break;
433 }
434
435 if (key != NULL)
436 g_settings_bind (
437 settings, key,
438 header, "visible",
439 G_SETTINGS_BIND_DEFAULT);
440 }
441
442 g_object_unref (settings);
443 }
444
445 static gboolean
446 composer_header_table_show_post_headers (EComposerHeaderTable *table)
447 {
448 ESourceRegistry *registry;
449 GList *list, *link;
450 const gchar *extension_name;
451 const gchar *target_uid;
452 gboolean show_post_headers = FALSE;
453
454 registry = e_composer_header_table_get_registry (table);
455 target_uid = e_composer_header_table_get_identity_uid (table);
456
457 extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
458 list = e_source_registry_list_sources (registry, extension_name);
459
460 /* Look for a mail account referencing this mail identity.
461 * If the mail account's backend name is "nntp", show the
462 * post headers. Otherwise show the mail headers.
463 *
464 * XXX What if multiple accounts use this identity but only
465 * one is "nntp"? Maybe it should be indicated by the
466 * transport somehow?
467 */
468 for (link = list; link != NULL; link = link->next) {
469 ESource *source = E_SOURCE (link->data);
470 ESourceExtension *extension;
471 const gchar *backend_name;
472 const gchar *identity_uid;
473
474 extension = e_source_get_extension (source, extension_name);
475
476 backend_name = e_source_backend_get_backend_name (
477 E_SOURCE_BACKEND (extension));
478 identity_uid = e_source_mail_account_get_identity_uid (
479 E_SOURCE_MAIL_ACCOUNT (extension));
480
481 if (g_strcmp0 (identity_uid, target_uid) != 0)
482 continue;
483
484 if (g_strcmp0 (backend_name, "nntp") != 0)
485 continue;
486
487 show_post_headers = TRUE;
488 break;
489 }
490
491 g_list_free_full (list, (GDestroyNotify) g_object_unref);
492
493 return show_post_headers;
494 }
495
496 static void
497 composer_header_table_from_changed_cb (EComposerHeaderTable *table)
498 {
499 ESource *source = NULL;
500 ESource *mail_account = NULL;
501 ESourceRegistry *registry;
502 EComposerHeader *header;
503 EComposerHeaderType type;
504 EComposerPostHeader *post_header;
505 EComposerTextHeader *text_header;
506 EDestination **old_destinations;
507 EDestination **new_destinations;
508 const gchar *reply_to = NULL;
509 const gchar * const *bcc = NULL;
510 const gchar * const *cc = NULL;
511 const gchar *uid;
512
513 /* Keep "Post-To" and "Reply-To" synchronized with "From" */
514
515 registry = e_composer_header_table_get_registry (table);
516 uid = e_composer_header_table_get_identity_uid (table);
517
518 if (uid != NULL)
519 source = e_source_registry_ref_source (registry, uid);
520
521 /* Make sure this is really a mail identity source. */
522 if (source != NULL) {
523 const gchar *extension_name;
524
525 extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
526 if (!e_source_has_extension (source, extension_name)) {
527 g_object_unref (source);
528 source = NULL;
529 }
530 }
531
532 if (source != NULL) {
533 ESourceMailIdentity *mi;
534 ESourceMailComposition *mc;
535 const gchar *extension_name;
536
537 extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
538 mi = e_source_get_extension (source, extension_name);
539
540 extension_name = E_SOURCE_EXTENSION_MAIL_COMPOSITION;
541 mc = e_source_get_extension (source, extension_name);
542
543 reply_to = e_source_mail_identity_get_reply_to (mi);
544 bcc = e_source_mail_composition_get_bcc (mc);
545 cc = e_source_mail_composition_get_cc (mc);
546
547 g_object_unref (source);
548 }
549
550 type = E_COMPOSER_HEADER_POST_TO;
551 header = e_composer_header_table_get_header (table, type);
552 post_header = E_COMPOSER_POST_HEADER (header);
553 e_composer_post_header_set_mail_account (post_header, mail_account);
554
555 type = E_COMPOSER_HEADER_REPLY_TO;
556 header = e_composer_header_table_get_header (table, type);
557 text_header = E_COMPOSER_TEXT_HEADER (header);
558 e_composer_text_header_set_text (text_header, reply_to);
559
560 /* Update automatic CC destinations. */
561 old_destinations =
562 e_composer_header_table_get_destinations_cc (table);
563 new_destinations =
564 composer_header_table_update_destinations (
565 old_destinations, cc);
566 e_composer_header_table_set_destinations_cc (table, new_destinations);
567 e_destination_freev (old_destinations);
568 e_destination_freev (new_destinations);
569
570 /* Update automatic BCC destinations. */
571 old_destinations =
572 e_composer_header_table_get_destinations_bcc (table);
573 new_destinations =
574 composer_header_table_update_destinations (
575 old_destinations, bcc);
576 e_composer_header_table_set_destinations_bcc (table, new_destinations);
577 e_destination_freev (old_destinations);
578 e_destination_freev (new_destinations);
579
580 if (composer_header_table_show_post_headers (table))
581 composer_header_table_setup_post_headers (table);
582 else
583 composer_header_table_setup_mail_headers (table);
584 }
585
586 static void
587 composer_header_table_set_registry (EComposerHeaderTable *table,
588 ESourceRegistry *registry)
589 {
590 g_return_if_fail (E_IS_SOURCE_REGISTRY (registry));
591 g_return_if_fail (table->priv->registry == NULL);
592
593 table->priv->registry = g_object_ref (registry);
594 }
595
596 static void
597 composer_header_table_set_shell (EComposerHeaderTable *table,
598 EShell *shell)
599 {
600 g_return_if_fail (E_IS_SHELL (shell));
601 g_return_if_fail (table->priv->shell == NULL);
602
603 table->priv->shell = g_object_ref (shell);
604 }
605
606 static void
607 composer_header_table_set_property (GObject *object,
608 guint property_id,
609 const GValue *value,
610 GParamSpec *pspec)
611 {
612 EDestination **destinations;
613 GList *list;
614
615 switch (property_id) {
616 case PROP_DESTINATIONS_BCC:
617 destinations = g_value_dup_destinations (value);
618 e_composer_header_table_set_destinations_bcc (
619 E_COMPOSER_HEADER_TABLE (object),
620 destinations);
621 e_destination_freev (destinations);
622 return;
623
624 case PROP_DESTINATIONS_CC:
625 destinations = g_value_dup_destinations (value);
626 e_composer_header_table_set_destinations_cc (
627 E_COMPOSER_HEADER_TABLE (object),
628 destinations);
629 e_destination_freev (destinations);
630 return;
631
632 case PROP_DESTINATIONS_TO:
633 destinations = g_value_dup_destinations (value);
634 e_composer_header_table_set_destinations_to (
635 E_COMPOSER_HEADER_TABLE (object),
636 destinations);
637 e_destination_freev (destinations);
638 return;
639
640 case PROP_IDENTITY_UID:
641 e_composer_header_table_set_identity_uid (
642 E_COMPOSER_HEADER_TABLE (object),
643 g_value_get_string (value));
644 return;
645
646 case PROP_POST_TO:
647 list = g_value_dup_string_list (value);
648 e_composer_header_table_set_post_to_list (
649 E_COMPOSER_HEADER_TABLE (object), list);
650 g_list_foreach (list, (GFunc) g_free, NULL);
651 g_list_free (list);
652 return;
653
654 case PROP_REGISTRY:
655 composer_header_table_set_registry (
656 E_COMPOSER_HEADER_TABLE (object),
657 g_value_get_object (value));
658 return;
659
660 case PROP_REPLY_TO:
661 e_composer_header_table_set_reply_to (
662 E_COMPOSER_HEADER_TABLE (object),
663 g_value_get_string (value));
664 return;
665
666 case PROP_SHELL:
667 composer_header_table_set_shell (
668 E_COMPOSER_HEADER_TABLE (object),
669 g_value_get_object (value));
670 return;
671
672 case PROP_SIGNATURE_UID:
673 e_composer_header_table_set_signature_uid (
674 E_COMPOSER_HEADER_TABLE (object),
675 g_value_get_string (value));
676 return;
677
678 case PROP_SUBJECT:
679 e_composer_header_table_set_subject (
680 E_COMPOSER_HEADER_TABLE (object),
681 g_value_get_string (value));
682 return;
683 }
684
685 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
686 }
687
688 static void
689 composer_header_table_get_property (GObject *object,
690 guint property_id,
691 GValue *value,
692 GParamSpec *pspec)
693 {
694 EDestination **destinations;
695 GList *list;
696
697 switch (property_id) {
698 case PROP_DESTINATIONS_BCC:
699 destinations =
700 e_composer_header_table_get_destinations_bcc (
701 E_COMPOSER_HEADER_TABLE (object));
702 g_value_set_destinations (value, destinations);
703 e_destination_freev (destinations);
704 return;
705
706 case PROP_DESTINATIONS_CC:
707 destinations =
708 e_composer_header_table_get_destinations_cc (
709 E_COMPOSER_HEADER_TABLE (object));
710 g_value_set_destinations (value, destinations);
711 e_destination_freev (destinations);
712 return;
713
714 case PROP_DESTINATIONS_TO:
715 destinations =
716 e_composer_header_table_get_destinations_to (
717 E_COMPOSER_HEADER_TABLE (object));
718 g_value_set_destinations (value, destinations);
719 e_destination_freev (destinations);
720 return;
721
722 case PROP_IDENTITY_UID:
723 g_value_set_string (
724 value,
725 e_composer_header_table_get_identity_uid (
726 E_COMPOSER_HEADER_TABLE (object)));
727 return;
728
729 case PROP_POST_TO:
730 list = e_composer_header_table_get_post_to (
731 E_COMPOSER_HEADER_TABLE (object));
732 g_value_set_string_list (value, list);
733 g_list_foreach (list, (GFunc) g_free, NULL);
734 g_list_free (list);
735 return;
736
737 case PROP_REGISTRY:
738 g_value_set_object (
739 value,
740 e_composer_header_table_get_registry (
741 E_COMPOSER_HEADER_TABLE (object)));
742 return;
743
744 case PROP_REPLY_TO:
745 g_value_set_string (
746 value,
747 e_composer_header_table_get_reply_to (
748 E_COMPOSER_HEADER_TABLE (object)));
749 return;
750
751 case PROP_SHELL:
752 g_value_set_object (
753 value,
754 e_composer_header_table_get_shell (
755 E_COMPOSER_HEADER_TABLE (object)));
756 return;
757
758 case PROP_SIGNATURE_COMBO_BOX:
759 g_value_set_object (
760 value,
761 e_composer_header_table_get_signature_combo_box (
762 E_COMPOSER_HEADER_TABLE (object)));
763 return;
764
765 case PROP_SIGNATURE_UID:
766 g_value_set_string (
767 value,
768 e_composer_header_table_get_signature_uid (
769 E_COMPOSER_HEADER_TABLE (object)));
770 return;
771
772 case PROP_SUBJECT:
773 g_value_set_string (
774 value,
775 e_composer_header_table_get_subject (
776 E_COMPOSER_HEADER_TABLE (object)));
777 return;
778 }
779
780 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
781 }
782
783 static void
784 composer_header_table_dispose (GObject *object)
785 {
786 EComposerHeaderTablePrivate *priv;
787 gint ii;
788
789 priv = E_COMPOSER_HEADER_TABLE_GET_PRIVATE (object);
790
791 for (ii = 0; ii < G_N_ELEMENTS (priv->headers); ii++) {
792 if (priv->headers[ii] != NULL) {
793 g_object_unref (priv->headers[ii]);
794 priv->headers[ii] = NULL;
795 }
796 }
797
798 if (priv->signature_combo_box != NULL) {
799 g_object_unref (priv->signature_combo_box);
800 priv->signature_combo_box = NULL;
801 }
802
803 if (priv->name_selector != NULL) {
804 e_name_selector_cancel_loading (priv->name_selector);
805 g_object_unref (priv->name_selector);
806 priv->name_selector = NULL;
807 }
808
809 if (priv->registry != NULL) {
810 g_object_unref (priv->registry);
811 priv->registry = NULL;
812 }
813
814 if (priv->shell != NULL) {
815 g_object_unref (priv->shell);
816 priv->shell = NULL;
817 }
818
819 /* Chain up to parent's dispose() method. */
820 G_OBJECT_CLASS (e_composer_header_table_parent_class)->dispose (object);
821 }
822
823 static void
824 composer_header_table_constructed (GObject *object)
825 {
826 EComposerHeaderTable *table;
827 ENameSelector *name_selector;
828 ESourceRegistry *registry;
829 EComposerHeader *header;
830 GtkWidget *widget;
831 EShell *shell;
832 guint ii;
833 gint row_padding;
834 gboolean small_screen_mode;
835
836 /* Chain up to parent's constructed() method. */
837 G_OBJECT_CLASS (e_composer_header_table_parent_class)->
838 constructed (object);
839
840 table = E_COMPOSER_HEADER_TABLE (object);
841 shell = e_composer_header_table_get_shell (table);
842 registry = e_composer_header_table_get_registry (table);
843
844 small_screen_mode = e_shell_get_small_screen_mode (shell);
845
846 name_selector = e_name_selector_new (registry);
847 table->priv->name_selector = name_selector;
848
849 header = e_composer_from_header_new (registry, _("Fr_om:"));
850 composer_header_table_bind_header ("identity-uid", "changed", header);
851 g_signal_connect_swapped (
852 header, "changed", G_CALLBACK (
853 composer_header_table_from_changed_cb), table);
854 table->priv->headers[E_COMPOSER_HEADER_FROM] = header;
855
856 header = e_composer_text_header_new_label (registry, _("_Reply-To:"));
857 composer_header_table_bind_header ("reply-to", "changed", header);
858 table->priv->headers[E_COMPOSER_HEADER_REPLY_TO] = header;
859
860 header = e_composer_name_header_new (
861 registry, _("_To:"), name_selector);
862 e_composer_header_set_input_tooltip (header, HEADER_TOOLTIP_TO);
863 composer_header_table_bind_header ("destinations-to", "changed", header);
864 table->priv->headers[E_COMPOSER_HEADER_TO] = header;
865
866 header = e_composer_name_header_new (
867 registry, _("_Cc:"), name_selector);
868 e_composer_header_set_input_tooltip (header, HEADER_TOOLTIP_CC);
869 composer_header_table_bind_header ("destinations-cc", "changed", header);
870 table->priv->headers[E_COMPOSER_HEADER_CC] = header;
871
872 header = e_composer_name_header_new (
873 registry, _("_Bcc:"), name_selector);
874 e_composer_header_set_input_tooltip (header, HEADER_TOOLTIP_BCC);
875 composer_header_table_bind_header ("destinations-bcc", "changed", header);
876 table->priv->headers[E_COMPOSER_HEADER_BCC] = header;
877
878 header = e_composer_post_header_new (registry, _("_Post To:"));
879 composer_header_table_bind_header ("post-to", "changed", header);
880 table->priv->headers[E_COMPOSER_HEADER_POST_TO] = header;
881
882 header = e_composer_spell_header_new_label (registry, _("S_ubject:"));
883 composer_header_table_bind_header ("subject", "changed", header);
884 table->priv->headers[E_COMPOSER_HEADER_SUBJECT] = header;
885
886 widget = e_mail_signature_combo_box_new (registry);
887 composer_header_table_bind_widget ("signature-uid", "changed", widget);
888 table->priv->signature_combo_box = g_object_ref_sink (widget);
889
890 widget = gtk_label_new_with_mnemonic (_("Si_gnature:"));
891 gtk_label_set_mnemonic_widget (
892 GTK_LABEL (widget), table->priv->signature_combo_box);
893 table->priv->signature_label = g_object_ref_sink (widget);
894
895 /* Use "ypadding" instead of "row-spacing" because some rows may
896 * be invisible and we don't want spacing around them. */
897
898 /* For small screens, pack the table's rows closely together. */
899 row_padding = small_screen_mode ? 0 : 3;
900
901 for (ii = 0; ii < G_N_ELEMENTS (table->priv->headers); ii++) {
902 gtk_table_attach (
903 GTK_TABLE (object),
904 table->priv->headers[ii]->title_widget, 0, 1,
905 ii, ii + 1, GTK_FILL, GTK_FILL, 0, row_padding);
906 gtk_table_attach (
907 GTK_TABLE (object),
908 table->priv->headers[ii]->input_widget, 1, 4,
909 ii, ii + 1, GTK_FILL | GTK_EXPAND, 0, 0, row_padding);
910 }
911
912 ii = E_COMPOSER_HEADER_FROM;
913
914 /* Leave room in the "From" row for signature stuff. */
915 gtk_container_child_set (
916 GTK_CONTAINER (object),
917 table->priv->headers[ii]->input_widget,
918 "right-attach", 2, NULL);
919
920 g_object_bind_property (
921 table->priv->headers[ii]->input_widget, "visible",
922 table->priv->signature_label, "visible",
923 G_BINDING_SYNC_CREATE);
924
925 g_object_bind_property (
926 table->priv->headers[ii]->input_widget, "visible",
927 table->priv->signature_combo_box, "visible",
928 G_BINDING_SYNC_CREATE);
929
930 /* Now add the signature stuff. */
931 if (!small_screen_mode) {
932 gtk_table_attach (
933 GTK_TABLE (object),
934 table->priv->signature_label,
935 2, 3, ii, ii + 1, 0, 0, 0, row_padding);
936 gtk_table_attach (
937 GTK_TABLE (object),
938 table->priv->signature_combo_box,
939 3, 4, ii, ii + 1, 0, 0, 0, row_padding);
940 } else {
941 GtkWidget *box = gtk_hbox_new (FALSE, 0);
942
943 gtk_box_pack_start (
944 GTK_BOX (box),
945 table->priv->signature_label,
946 FALSE, FALSE, 4);
947 gtk_box_pack_end (
948 GTK_BOX (box),
949 table->priv->signature_combo_box,
950 TRUE, TRUE, 0);
951 g_object_set_data (G_OBJECT (box), "pdata", object);
952 gtk_table_attach (
953 GTK_TABLE (object), box,
954 3, 4, ii, ii + 1, GTK_FILL, 0, 0, row_padding);
955 gtk_widget_hide (box);
956 }
957
958 /* Initialize the headers. */
959 composer_header_table_from_changed_cb (table);
960 }
961
962 static void
963 e_composer_header_table_class_init (EComposerHeaderTableClass *class)
964 {
965 GObjectClass *object_class;
966 GParamSpec *element_spec;
967
968 g_type_class_add_private (class, sizeof (EComposerHeaderTablePrivate));
969
970 object_class = G_OBJECT_CLASS (class);
971 object_class->set_property = composer_header_table_set_property;
972 object_class->get_property = composer_header_table_get_property;
973 object_class->dispose = composer_header_table_dispose;
974 object_class->constructed = composer_header_table_constructed;
975
976 /* floating reference */
977 element_spec = g_param_spec_object (
978 "value-array-element",
979 NULL,
980 NULL,
981 E_TYPE_DESTINATION,
982 G_PARAM_READWRITE |
983 G_PARAM_STATIC_STRINGS);
984
985 g_object_class_install_property (
986 object_class,
987 PROP_DESTINATIONS_BCC,
988 g_param_spec_value_array (
989 "destinations-bcc",
990 NULL,
991 NULL,
992 element_spec,
993 G_PARAM_READWRITE |
994 G_PARAM_STATIC_STRINGS));
995
996 g_object_class_install_property (
997 object_class,
998 PROP_DESTINATIONS_CC,
999 g_param_spec_value_array (
1000 "destinations-cc",
1001 NULL,
1002 NULL,
1003 element_spec,
1004 G_PARAM_READWRITE |
1005 G_PARAM_STATIC_STRINGS));
1006
1007 g_object_class_install_property (
1008 object_class,
1009 PROP_DESTINATIONS_TO,
1010 g_param_spec_value_array (
1011 "destinations-to",
1012 NULL,
1013 NULL,
1014 element_spec,
1015 G_PARAM_READWRITE |
1016 G_PARAM_STATIC_STRINGS));
1017
1018 g_object_class_install_property (
1019 object_class,
1020 PROP_IDENTITY_UID,
1021 g_param_spec_string (
1022 "identity-uid",
1023 NULL,
1024 NULL,
1025 NULL,
1026 G_PARAM_READWRITE |
1027 G_PARAM_STATIC_STRINGS));
1028
1029 /* floating reference */
1030 element_spec = g_param_spec_string (
1031 "value-array-element",
1032 NULL,
1033 NULL,
1034 NULL,
1035 G_PARAM_READWRITE |
1036 G_PARAM_STATIC_STRINGS);
1037
1038 g_object_class_install_property (
1039 object_class,
1040 PROP_POST_TO,
1041 g_param_spec_value_array (
1042 "post-to",
1043 NULL,
1044 NULL,
1045 element_spec,
1046 G_PARAM_READWRITE |
1047 G_PARAM_STATIC_STRINGS));
1048
1049 g_object_class_install_property (
1050 object_class,
1051 PROP_REGISTRY,
1052 g_param_spec_object (
1053 "registry",
1054 NULL,
1055 NULL,
1056 E_TYPE_SOURCE_REGISTRY,
1057 G_PARAM_READWRITE |
1058 G_PARAM_CONSTRUCT_ONLY |
1059 G_PARAM_STATIC_STRINGS));
1060
1061 g_object_class_install_property (
1062 object_class,
1063 PROP_REPLY_TO,
1064 g_param_spec_string (
1065 "reply-to",
1066 NULL,
1067 NULL,
1068 NULL,
1069 G_PARAM_READWRITE |
1070 G_PARAM_STATIC_STRINGS));
1071
1072 g_object_class_install_property (
1073 object_class,
1074 PROP_SHELL,
1075 g_param_spec_object (
1076 "shell",
1077 NULL,
1078 NULL,
1079 E_TYPE_SHELL,
1080 G_PARAM_READWRITE |
1081 G_PARAM_CONSTRUCT_ONLY |
1082 G_PARAM_STATIC_STRINGS));
1083
1084 g_object_class_install_property (
1085 object_class,
1086 PROP_SIGNATURE_COMBO_BOX,
1087 g_param_spec_string (
1088 "signature-combo-box",
1089 NULL,
1090 NULL,
1091 NULL,
1092 G_PARAM_READABLE |
1093 G_PARAM_STATIC_STRINGS));
1094
1095 g_object_class_install_property (
1096 object_class,
1097 PROP_SIGNATURE_UID,
1098 g_param_spec_string (
1099 "signature-uid",
1100 NULL,
1101 NULL,
1102 NULL,
1103 G_PARAM_READWRITE |
1104 G_PARAM_STATIC_STRINGS));
1105
1106 g_object_class_install_property (
1107 object_class,
1108 PROP_SUBJECT,
1109 g_param_spec_string (
1110 "subject",
1111 NULL,
1112 NULL,
1113 NULL,
1114 G_PARAM_READWRITE |
1115 G_PARAM_STATIC_STRINGS));
1116 }
1117
1118 static void
1119 composer_header_table_realize_cb (EComposerHeaderTable *table)
1120 {
1121 g_return_if_fail (table != NULL);
1122 g_return_if_fail (table->priv != NULL);
1123
1124 g_signal_handlers_disconnect_by_func (
1125 table, composer_header_table_realize_cb, NULL);
1126
1127 e_name_selector_load_books (table->priv->name_selector);
1128 }
1129
1130 static void
1131 e_composer_header_table_init (EComposerHeaderTable *table)
1132 {
1133 gint rows;
1134
1135 table->priv = E_COMPOSER_HEADER_TABLE_GET_PRIVATE (table);
1136
1137 rows = G_N_ELEMENTS (table->priv->headers);
1138 gtk_table_resize (GTK_TABLE (table), rows, 4);
1139 gtk_table_set_row_spacings (GTK_TABLE (table), 0);
1140 gtk_table_set_col_spacings (GTK_TABLE (table), 6);
1141
1142 /* postpone name_selector loading, do that only when really needed */
1143 g_signal_connect (
1144 table, "realize",
1145 G_CALLBACK (composer_header_table_realize_cb), NULL);
1146 }
1147
1148 GtkWidget *
1149 e_composer_header_table_new (EShell *shell,
1150 ESourceRegistry *registry)
1151 {
1152 g_return_val_if_fail (E_IS_SHELL (shell), NULL);
1153 g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
1154
1155 return g_object_new (
1156 E_TYPE_COMPOSER_HEADER_TABLE,
1157 "shell", shell, "registry", registry, NULL);
1158 }
1159
1160 EShell *
1161 e_composer_header_table_get_shell (EComposerHeaderTable *table)
1162 {
1163 g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL);
1164
1165 return table->priv->shell;
1166 }
1167
1168 ESourceRegistry *
1169 e_composer_header_table_get_registry (EComposerHeaderTable *table)
1170 {
1171 g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL);
1172
1173 return table->priv->registry;
1174 }
1175
1176 EComposerHeader *
1177 e_composer_header_table_get_header (EComposerHeaderTable *table,
1178 EComposerHeaderType type)
1179 {
1180 g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL);
1181 g_return_val_if_fail (type < E_COMPOSER_NUM_HEADERS, NULL);
1182
1183 return table->priv->headers[type];
1184 }
1185
1186 EMailSignatureComboBox *
1187 e_composer_header_table_get_signature_combo_box (EComposerHeaderTable *table)
1188 {
1189 g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL);
1190
1191 return E_MAIL_SIGNATURE_COMBO_BOX (table->priv->signature_combo_box);
1192 }
1193
1194 EDestination **
1195 e_composer_header_table_get_destinations (EComposerHeaderTable *table)
1196 {
1197 EDestination **destinations;
1198 EDestination **to, **cc, **bcc;
1199 gint total, n_to, n_cc, n_bcc;
1200
1201 g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL);
1202
1203 to = e_composer_header_table_get_destinations_to (table);
1204 for (n_to = 0; to != NULL && to[n_to] != NULL; n_to++);
1205
1206 cc = e_composer_header_table_get_destinations_cc (table);
1207 for (n_cc = 0; cc != NULL && cc[n_cc] != NULL; n_cc++);
1208
1209 bcc = e_composer_header_table_get_destinations_bcc (table);
1210 for (n_bcc = 0; bcc != NULL && bcc[n_bcc] != NULL; n_bcc++);
1211
1212 total = n_to + n_cc + n_bcc;
1213 destinations = g_new0 (EDestination *, total + 1);
1214
1215 while (n_bcc > 0 && total > 0)
1216 destinations[--total] = g_object_ref (bcc[--n_bcc]);
1217
1218 while (n_cc > 0 && total > 0)
1219 destinations[--total] = g_object_ref (cc[--n_cc]);
1220
1221 while (n_to > 0 && total > 0)
1222 destinations[--total] = g_object_ref (to[--n_to]);
1223
1224 /* Counters should all be zero now. */
1225 g_assert (total == 0 && n_to == 0 && n_cc == 0 && n_bcc == 0);
1226
1227 e_destination_freev (to);
1228 e_destination_freev (cc);
1229 e_destination_freev (bcc);
1230
1231 return destinations;
1232 }
1233
1234 EDestination **
1235 e_composer_header_table_get_destinations_bcc (EComposerHeaderTable *table)
1236 {
1237 EComposerHeader *header;
1238 EComposerHeaderType type;
1239 EComposerNameHeader *name_header;
1240
1241 g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL);
1242
1243 type = E_COMPOSER_HEADER_BCC;
1244 header = e_composer_header_table_get_header (table, type);
1245 name_header = E_COMPOSER_NAME_HEADER (header);
1246
1247 return e_composer_name_header_get_destinations (name_header);
1248 }
1249
1250 void
1251 e_composer_header_table_add_destinations_bcc (EComposerHeaderTable *table,
1252 EDestination **destinations)
1253 {
1254 EComposerHeader *header;
1255 EComposerHeaderType type;
1256 EComposerNameHeader *name_header;
1257
1258 g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (table));
1259
1260 type = E_COMPOSER_HEADER_BCC;
1261 header = e_composer_header_table_get_header (table, type);
1262 name_header = E_COMPOSER_NAME_HEADER (header);
1263
1264 e_composer_name_header_add_destinations (name_header, destinations);
1265
1266 if (destinations != NULL && *destinations != NULL)
1267 e_composer_header_set_visible (header, TRUE);
1268 }
1269
1270 void
1271 e_composer_header_table_set_destinations_bcc (EComposerHeaderTable *table,
1272 EDestination **destinations)
1273 {
1274 EComposerHeader *header;
1275 EComposerHeaderType type;
1276 EComposerNameHeader *name_header;
1277
1278 g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (table));
1279
1280 type = E_COMPOSER_HEADER_BCC;
1281 header = e_composer_header_table_get_header (table, type);
1282 name_header = E_COMPOSER_NAME_HEADER (header);
1283
1284 e_composer_name_header_set_destinations (name_header, destinations);
1285
1286 if (destinations != NULL && *destinations != NULL)
1287 e_composer_header_set_visible (header, TRUE);
1288 }
1289
1290 EDestination **
1291 e_composer_header_table_get_destinations_cc (EComposerHeaderTable *table)
1292 {
1293 EComposerHeader *header;
1294 EComposerHeaderType type;
1295 EComposerNameHeader *name_header;
1296
1297 g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL);
1298
1299 type = E_COMPOSER_HEADER_CC;
1300 header = e_composer_header_table_get_header (table, type);
1301 name_header = E_COMPOSER_NAME_HEADER (header);
1302
1303 return e_composer_name_header_get_destinations (name_header);
1304 }
1305
1306 void
1307 e_composer_header_table_add_destinations_cc (EComposerHeaderTable *table,
1308 EDestination **destinations)
1309 {
1310 EComposerHeader *header;
1311 EComposerHeaderType type;
1312 EComposerNameHeader *name_header;
1313
1314 g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (table));
1315
1316 type = E_COMPOSER_HEADER_CC;
1317 header = e_composer_header_table_get_header (table, type);
1318 name_header = E_COMPOSER_NAME_HEADER (header);
1319
1320 e_composer_name_header_add_destinations (name_header, destinations);
1321
1322 if (destinations != NULL && *destinations != NULL)
1323 e_composer_header_set_visible (header, TRUE);
1324 }
1325
1326 void
1327 e_composer_header_table_set_destinations_cc (EComposerHeaderTable *table,
1328 EDestination **destinations)
1329 {
1330 EComposerHeader *header;
1331 EComposerHeaderType type;
1332 EComposerNameHeader *name_header;
1333
1334 g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (table));
1335
1336 type = E_COMPOSER_HEADER_CC;
1337 header = e_composer_header_table_get_header (table, type);
1338 name_header = E_COMPOSER_NAME_HEADER (header);
1339
1340 e_composer_name_header_set_destinations (name_header, destinations);
1341
1342 if (destinations != NULL && *destinations != NULL)
1343 e_composer_header_set_visible (header, TRUE);
1344 }
1345
1346 EDestination **
1347 e_composer_header_table_get_destinations_to (EComposerHeaderTable *table)
1348 {
1349 EComposerHeader *header;
1350 EComposerHeaderType type;
1351 EComposerNameHeader *name_header;
1352
1353 g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL);
1354
1355 type = E_COMPOSER_HEADER_TO;
1356 header = e_composer_header_table_get_header (table, type);
1357 name_header = E_COMPOSER_NAME_HEADER (header);
1358
1359 return e_composer_name_header_get_destinations (name_header);
1360 }
1361
1362 void
1363 e_composer_header_table_add_destinations_to (EComposerHeaderTable *table,
1364 EDestination **destinations)
1365 {
1366 EComposerHeader *header;
1367 EComposerHeaderType type;
1368 EComposerNameHeader *name_header;
1369
1370 g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (table));
1371
1372 type = E_COMPOSER_HEADER_TO;
1373 header = e_composer_header_table_get_header (table, type);
1374 name_header = E_COMPOSER_NAME_HEADER (header);
1375
1376 e_composer_name_header_add_destinations (name_header, destinations);
1377 }
1378
1379 void
1380 e_composer_header_table_set_destinations_to (EComposerHeaderTable *table,
1381 EDestination **destinations)
1382 {
1383 EComposerHeader *header;
1384 EComposerHeaderType type;
1385 EComposerNameHeader *name_header;
1386
1387 g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (table));
1388
1389 type = E_COMPOSER_HEADER_TO;
1390 header = e_composer_header_table_get_header (table, type);
1391 name_header = E_COMPOSER_NAME_HEADER (header);
1392
1393 e_composer_name_header_set_destinations (name_header, destinations);
1394 }
1395
1396 const gchar *
1397 e_composer_header_table_get_identity_uid (EComposerHeaderTable *table)
1398 {
1399 EComposerHeader *header;
1400 EComposerHeaderType type;
1401 EComposerFromHeader *from_header;
1402
1403 g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL);
1404
1405 type = E_COMPOSER_HEADER_FROM;
1406 header = e_composer_header_table_get_header (table, type);
1407 from_header = E_COMPOSER_FROM_HEADER (header);
1408
1409 return e_composer_from_header_get_active_id (from_header);
1410 }
1411
1412 void
1413 e_composer_header_table_set_identity_uid (EComposerHeaderTable *table,
1414 const gchar *identity_uid)
1415 {
1416 EComposerHeader *header;
1417 EComposerHeaderType type;
1418 EComposerFromHeader *from_header;
1419
1420 g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (table));
1421
1422 type = E_COMPOSER_HEADER_FROM;
1423 header = e_composer_header_table_get_header (table, type);
1424 from_header = E_COMPOSER_FROM_HEADER (header);
1425
1426 e_composer_from_header_set_active_id (from_header, identity_uid);
1427 }
1428
1429 GList *
1430 e_composer_header_table_get_post_to (EComposerHeaderTable *table)
1431 {
1432 EComposerHeader *header;
1433 EComposerHeaderType type;
1434 EComposerPostHeader *post_header;
1435
1436 g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL);
1437
1438 type = E_COMPOSER_HEADER_POST_TO;
1439 header = e_composer_header_table_get_header (table, type);
1440 post_header = E_COMPOSER_POST_HEADER (header);
1441
1442 return e_composer_post_header_get_folders (post_header);
1443 }
1444
1445 void
1446 e_composer_header_table_set_post_to_base (EComposerHeaderTable *table,
1447 const gchar *base_url,
1448 const gchar *folders)
1449 {
1450 EComposerHeader *header;
1451 EComposerHeaderType type;
1452 EComposerPostHeader *post_header;
1453
1454 g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (table));
1455
1456 type = E_COMPOSER_HEADER_POST_TO;
1457 header = e_composer_header_table_get_header (table, type);
1458 post_header = E_COMPOSER_POST_HEADER (header);
1459
1460 e_composer_post_header_set_folders_base (post_header, base_url, folders);
1461 }
1462
1463 void
1464 e_composer_header_table_set_post_to_list (EComposerHeaderTable *table,
1465 GList *folders)
1466 {
1467 EComposerHeader *header;
1468 EComposerHeaderType type;
1469 EComposerPostHeader *post_header;
1470
1471 g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (table));
1472
1473 type = E_COMPOSER_HEADER_POST_TO;
1474 header = e_composer_header_table_get_header (table, type);
1475 post_header = E_COMPOSER_POST_HEADER (header);
1476
1477 e_composer_post_header_set_folders (post_header, folders);
1478 }
1479
1480 const gchar *
1481 e_composer_header_table_get_reply_to (EComposerHeaderTable *table)
1482 {
1483 EComposerHeader *header;
1484 EComposerHeaderType type;
1485 EComposerTextHeader *text_header;
1486
1487 g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL);
1488
1489 type = E_COMPOSER_HEADER_REPLY_TO;
1490 header = e_composer_header_table_get_header (table, type);
1491 text_header = E_COMPOSER_TEXT_HEADER (header);
1492
1493 return e_composer_text_header_get_text (text_header);
1494 }
1495
1496 void
1497 e_composer_header_table_set_reply_to (EComposerHeaderTable *table,
1498 const gchar *reply_to)
1499 {
1500 EComposerHeader *header;
1501 EComposerHeaderType type;
1502 EComposerTextHeader *text_header;
1503
1504 g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (table));
1505
1506 type = E_COMPOSER_HEADER_REPLY_TO;
1507 header = e_composer_header_table_get_header (table, type);
1508 text_header = E_COMPOSER_TEXT_HEADER (header);
1509
1510 e_composer_text_header_set_text (text_header, reply_to);
1511
1512 if (reply_to != NULL && *reply_to != '\0')
1513 e_composer_header_set_visible (header, TRUE);
1514 }
1515
1516 const gchar *
1517 e_composer_header_table_get_signature_uid (EComposerHeaderTable *table)
1518 {
1519 EMailSignatureComboBox *combo_box;
1520
1521 g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL);
1522
1523 combo_box = e_composer_header_table_get_signature_combo_box (table);
1524
1525 return gtk_combo_box_get_active_id (GTK_COMBO_BOX (combo_box));
1526 }
1527
1528 void
1529 e_composer_header_table_set_signature_uid (EComposerHeaderTable *table,
1530 const gchar *signature_uid)
1531 {
1532 EMailSignatureComboBox *combo_box;
1533
1534 g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (table));
1535
1536 combo_box = e_composer_header_table_get_signature_combo_box (table);
1537
1538 gtk_combo_box_set_active_id (GTK_COMBO_BOX (combo_box), signature_uid);
1539 }
1540
1541 const gchar *
1542 e_composer_header_table_get_subject (EComposerHeaderTable *table)
1543 {
1544 EComposerHeader *header;
1545 EComposerHeaderType type;
1546 EComposerTextHeader *text_header;
1547
1548 g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL);
1549
1550 type = E_COMPOSER_HEADER_SUBJECT;
1551 header = e_composer_header_table_get_header (table, type);
1552 text_header = E_COMPOSER_TEXT_HEADER (header);
1553
1554 return e_composer_text_header_get_text (text_header);
1555 }
1556
1557 void
1558 e_composer_header_table_set_subject (EComposerHeaderTable *table,
1559 const gchar *subject)
1560 {
1561 EComposerHeader *header;
1562 EComposerHeaderType type;
1563 EComposerTextHeader *text_header;
1564
1565 g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (table));
1566
1567 type = E_COMPOSER_HEADER_SUBJECT;
1568 header = e_composer_header_table_get_header (table, type);
1569 text_header = E_COMPOSER_TEXT_HEADER (header);
1570
1571 e_composer_text_header_set_text (text_header, subject);
1572 }
1573
1574 void
1575 e_composer_header_table_set_header_visible (EComposerHeaderTable *table,
1576 EComposerHeaderType type,
1577 gboolean visible)
1578 {
1579 EComposerHeader *header;
1580
1581 header = e_composer_header_table_get_header (table, type);
1582 e_composer_header_set_visible (header, visible);
1583
1584 /* Signature widgets track the "From" header. */
1585 if (type == E_COMPOSER_HEADER_FROM) {
1586 if (visible) {
1587 gtk_widget_show (table->priv->signature_label);
1588 gtk_widget_show (table->priv->signature_combo_box);
1589 } else {
1590 gtk_widget_hide (table->priv->signature_label);
1591 gtk_widget_hide (table->priv->signature_combo_box);
1592 }
1593 }
1594 }