Crash when making links clickable in composer
[evolution.git] / src / composer / e-composer-header-table.c
blob70b67b3b976b81478283df829afe510fd507ec79
1 /*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU Lesser General Public License as published by
4 * the Free Software Foundation.
6 * This program is distributed in the hope that it will be useful, but
7 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
8 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
9 * for more details.
11 * You should have received a copy of the GNU Lesser General Public License
12 * along with this program; if not, see <http://www.gnu.org/licenses/>.
14 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
17 #include "evolution-config.h"
19 #include "e-composer-header-table.h"
21 #include <glib/gi18n-lib.h>
23 #include "e-msg-composer.h"
24 #include "e-composer-private.h"
25 #include "e-composer-from-header.h"
26 #include "e-composer-name-header.h"
27 #include "e-composer-post-header.h"
28 #include "e-composer-spell-header.h"
29 #include "e-composer-text-header.h"
31 #define E_COMPOSER_HEADER_TABLE_GET_PRIVATE(obj) \
32 (G_TYPE_INSTANCE_GET_PRIVATE \
33 ((obj), E_TYPE_COMPOSER_HEADER_TABLE, EComposerHeaderTablePrivate))
35 #define HEADER_TOOLTIP_TO \
36 _("Enter the recipients of the message")
37 #define HEADER_TOOLTIP_CC \
38 _("Enter the addresses that will receive a " \
39 "carbon copy of the message")
40 #define HEADER_TOOLTIP_BCC \
41 _("Enter the addresses that will receive a " \
42 "carbon copy of the message without appearing " \
43 "in the recipient list of the message")
45 struct _EComposerHeaderTablePrivate {
46 EComposerHeader *headers[E_COMPOSER_NUM_HEADERS];
47 GtkWidget *signature_label;
48 GtkWidget *signature_combo_box;
49 ENameSelector *name_selector;
50 EClientCache *client_cache;
52 gchar *previous_from_uid;
55 enum {
56 PROP_0,
57 PROP_CLIENT_CACHE,
58 PROP_DESTINATIONS_BCC,
59 PROP_DESTINATIONS_CC,
60 PROP_DESTINATIONS_TO,
61 PROP_IDENTITY_UID,
62 PROP_POST_TO,
63 PROP_REPLY_TO,
64 PROP_SIGNATURE_COMBO_BOX,
65 PROP_SIGNATURE_UID,
66 PROP_SUBJECT
69 G_DEFINE_TYPE (
70 EComposerHeaderTable,
71 e_composer_header_table,
72 GTK_TYPE_TABLE)
74 static void
75 g_value_set_destinations (GValue *value,
76 EDestination **destinations)
78 GPtrArray *array;
79 gint ii;
81 /* Preallocate some reasonable number. */
82 array = g_ptr_array_new_full (64, g_object_unref);
84 for (ii = 0; destinations[ii] != NULL; ii++) {
85 g_ptr_array_add (array, e_destination_copy (destinations[ii]));
88 g_value_take_boxed (value, array);
91 static EDestination **
92 g_value_dup_destinations (const GValue *value)
94 EDestination **destinations;
95 const EDestination *dest;
96 GPtrArray *array;
97 guint ii;
99 array = g_value_get_boxed (value);
100 destinations = g_new0 (EDestination *, array->len + 1);
102 for (ii = 0; ii < array->len; ii++) {
103 dest = g_ptr_array_index (array, ii);
104 destinations[ii] = e_destination_copy (dest);
107 return destinations;
110 static void
111 g_value_set_string_list (GValue *value,
112 GList *list)
114 GPtrArray *array;
116 array = g_ptr_array_new_full (g_list_length (list), g_free);
118 while (list != NULL) {
119 g_ptr_array_add (array, g_strdup (list->data));
120 list = list->next;
123 g_value_take_boxed (value, array);
126 static GList *
127 g_value_dup_string_list (const GValue *value)
129 GPtrArray *array;
130 GList *list = NULL;
131 gint ii;
133 array = g_value_get_boxed (value);
135 for (ii = 0; ii < array->len; ii++) {
136 const gchar *element = g_ptr_array_index (array, ii);
137 list = g_list_prepend (list, g_strdup (element));
140 return g_list_reverse (list);
143 static void
144 composer_header_table_notify_header (EComposerHeader *header,
145 const gchar *property_name)
147 GtkWidget *parent;
149 parent = gtk_widget_get_parent (header->input_widget);
150 g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (parent));
151 g_object_notify (G_OBJECT (parent), property_name);
154 static void
155 composer_header_table_notify_widget (GtkWidget *widget,
156 const gchar *property_name)
158 GtkWidget *parent;
160 parent = gtk_widget_get_parent (widget);
161 g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (parent));
162 g_object_notify (G_OBJECT (parent), property_name);
165 static void
166 composer_header_table_bind_header (const gchar *property_name,
167 const gchar *signal_name,
168 EComposerHeader *header)
170 /* Propagate the signal as "notify::property_name". */
172 g_signal_connect (
173 header, signal_name,
174 G_CALLBACK (composer_header_table_notify_header),
175 (gpointer) property_name);
178 static void
179 composer_header_table_bind_widget (const gchar *property_name,
180 const gchar *signal_name,
181 GtkWidget *widget)
183 /* Propagate the signal as "notify::property_name". */
185 g_signal_connect (
186 widget, signal_name,
187 G_CALLBACK (composer_header_table_notify_widget),
188 (gpointer) property_name);
191 static EDestination **
192 composer_header_table_update_destinations (EDestination **old_destinations,
193 const gchar * const *auto_addresses)
195 CamelAddress *address;
196 CamelInternetAddress *inet_address;
197 EDestination **new_destinations;
198 EDestination *destination;
199 GQueue queue = G_QUEUE_INIT;
200 guint length;
201 gint ii;
203 /* Include automatic recipients for the selected account. */
205 if (auto_addresses == NULL)
206 goto skip_auto;
208 inet_address = camel_internet_address_new ();
209 address = CAMEL_ADDRESS (inet_address);
211 /* XXX Calling camel_address_decode() multiple times on the same
212 * CamelInternetAddress has a cumulative effect, which isn't
213 * well documented. */
214 for (ii = 0; auto_addresses[ii] != NULL; ii++)
215 camel_address_decode (address, auto_addresses[ii]);
217 for (ii = 0; ii < camel_address_length (address); ii++) {
218 const gchar *name, *email;
220 if (!camel_internet_address_get (
221 inet_address, ii, &name, &email))
222 continue;
224 destination = e_destination_new ();
225 e_destination_set_auto_recipient (destination, TRUE);
227 if (name != NULL)
228 e_destination_set_name (destination, name);
230 if (email != NULL)
231 e_destination_set_email (destination, email);
233 g_queue_push_tail (&queue, destination);
236 g_object_unref (inet_address);
238 skip_auto:
240 /* Include custom recipients for this message. */
242 if (old_destinations == NULL)
243 goto skip_custom;
245 for (ii = 0; old_destinations[ii] != NULL; ii++) {
246 if (e_destination_is_auto_recipient (old_destinations[ii]))
247 continue;
249 destination = e_destination_copy (old_destinations[ii]);
250 g_queue_push_tail (&queue, destination);
253 skip_custom:
255 length = g_queue_get_length (&queue);
256 new_destinations = g_new0 (EDestination *, length + 1);
258 for (ii = 0; ii < length; ii++)
259 new_destinations[ii] = g_queue_pop_head (&queue);
261 /* Sanity check. */
262 g_warn_if_fail (g_queue_is_empty (&queue));
264 return new_destinations;
267 static void
268 composer_header_table_setup_mail_headers (EComposerHeaderTable *table)
270 GSettings *settings;
271 gint ii;
273 settings = e_util_ref_settings ("org.gnome.evolution.mail");
275 for (ii = 0; ii < E_COMPOSER_NUM_HEADERS; ii++) {
276 EComposerHeader *header;
277 const gchar *key;
278 gboolean sensitive;
279 gboolean visible;
281 header = e_composer_header_table_get_header (table, ii);
283 switch (ii) {
284 case E_COMPOSER_HEADER_FROM:
285 key = "composer-show-from-override";
286 break;
288 case E_COMPOSER_HEADER_BCC:
289 key = "composer-show-bcc";
290 break;
292 case E_COMPOSER_HEADER_CC:
293 key = "composer-show-cc";
294 break;
296 case E_COMPOSER_HEADER_REPLY_TO:
297 key = "composer-show-reply-to";
298 break;
300 default:
301 key = NULL;
302 break;
305 if (key != NULL)
306 g_settings_unbind (header, "visible");
308 switch (ii) {
309 case E_COMPOSER_HEADER_FROM:
310 sensitive = TRUE;
311 visible = TRUE;
312 break;
314 case E_COMPOSER_HEADER_BCC:
315 case E_COMPOSER_HEADER_CC:
316 case E_COMPOSER_HEADER_REPLY_TO:
317 case E_COMPOSER_HEADER_SUBJECT:
318 case E_COMPOSER_HEADER_TO:
319 sensitive = TRUE;
320 visible = TRUE;
321 break;
323 default:
324 sensitive = FALSE;
325 visible = FALSE;
326 break;
329 e_composer_header_set_sensitive (header, sensitive);
330 e_composer_header_set_visible (header, visible);
332 if (key != NULL) {
333 if (ii == E_COMPOSER_HEADER_FROM)
334 g_settings_bind (
335 settings, key,
336 header, "override-visible",
337 G_SETTINGS_BIND_DEFAULT);
338 else
339 g_settings_bind (
340 settings, key,
341 header, "visible",
342 G_SETTINGS_BIND_DEFAULT);
346 g_object_unref (settings);
349 static void
350 composer_header_table_setup_post_headers (EComposerHeaderTable *table)
352 GSettings *settings;
353 gint ii;
355 settings = e_util_ref_settings ("org.gnome.evolution.mail");
357 for (ii = 0; ii < E_COMPOSER_NUM_HEADERS; ii++) {
358 EComposerHeader *header;
359 const gchar *key;
361 header = e_composer_header_table_get_header (table, ii);
363 switch (ii) {
364 case E_COMPOSER_HEADER_FROM:
365 key = "composer-show-post-from";
366 break;
368 case E_COMPOSER_HEADER_REPLY_TO:
369 key = "composer-show-post-reply-to";
370 break;
372 default:
373 key = NULL;
374 break;
377 if (key != NULL)
378 g_settings_unbind (header, "visible");
380 switch (ii) {
381 case E_COMPOSER_HEADER_FROM:
382 case E_COMPOSER_HEADER_POST_TO:
383 case E_COMPOSER_HEADER_REPLY_TO:
384 case E_COMPOSER_HEADER_SUBJECT:
385 e_composer_header_set_sensitive (header, TRUE);
386 e_composer_header_set_visible (header, TRUE);
387 break;
389 default: /* this includes TO, CC and BCC */
390 e_composer_header_set_sensitive (header, FALSE);
391 e_composer_header_set_visible (header, FALSE);
392 break;
395 if (key != NULL)
396 g_settings_bind (
397 settings, key,
398 header, "visible",
399 G_SETTINGS_BIND_DEFAULT);
402 g_object_unref (settings);
405 static gboolean
406 composer_header_table_show_post_headers (EComposerHeaderTable *table)
408 EClientCache *client_cache;
409 ESourceRegistry *registry;
410 GList *list, *link;
411 const gchar *extension_name;
412 gchar *target_uid;
413 gboolean show_post_headers = FALSE;
415 client_cache = e_composer_header_table_ref_client_cache (table);
416 registry = e_client_cache_ref_registry (client_cache);
418 target_uid = e_composer_header_table_dup_identity_uid (table, NULL, NULL);
420 extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
421 list = e_source_registry_list_sources (registry, extension_name);
423 /* Look for a mail account referencing this mail identity.
424 * If the mail account's backend name is "nntp", show the
425 * post headers. Otherwise show the mail headers.
427 * XXX What if multiple accounts use this identity but only
428 * one is "nntp"? Maybe it should be indicated by the
429 * transport somehow?
431 for (link = list; link != NULL; link = link->next) {
432 ESource *source = E_SOURCE (link->data);
433 ESourceExtension *extension;
434 const gchar *backend_name;
435 const gchar *identity_uid;
437 extension = e_source_get_extension (source, extension_name);
439 backend_name = e_source_backend_get_backend_name (
440 E_SOURCE_BACKEND (extension));
441 identity_uid = e_source_mail_account_get_identity_uid (
442 E_SOURCE_MAIL_ACCOUNT (extension));
444 if (g_strcmp0 (identity_uid, target_uid) != 0)
445 continue;
447 if (g_strcmp0 (backend_name, "nntp") != 0)
448 continue;
450 show_post_headers = TRUE;
451 break;
454 g_list_free_full (list, (GDestroyNotify) g_object_unref);
456 g_object_unref (client_cache);
457 g_object_unref (registry);
458 g_free (target_uid);
460 return show_post_headers;
463 static void
464 composer_header_table_from_changed_cb (EComposerHeaderTable *table)
466 ESource *source = NULL;
467 ESource *mail_account = NULL;
468 EComposerHeader *header;
469 EComposerHeaderType type;
470 EComposerFromHeader *from_header;
471 EComposerPostHeader *post_header;
472 EComposerTextHeader *text_header;
473 EDestination **old_destinations;
474 EDestination **new_destinations;
475 gchar *name = NULL;
476 gchar *address = NULL;
477 gchar *uid;
478 const gchar *reply_to = NULL;
479 const gchar * const *bcc = NULL;
480 const gchar * const *cc = NULL;
482 /* Keep "Post-To" and "Reply-To" synchronized with "From" */
484 uid = e_composer_header_table_dup_identity_uid (table, &name, &address);
485 if (uid != NULL)
486 source = e_composer_header_table_ref_source (table, uid);
487 g_free (uid);
489 /* Make sure this is really a mail identity source. */
490 if (source != NULL) {
491 const gchar *extension_name;
493 extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
494 if (!e_source_has_extension (source, extension_name)) {
495 g_object_unref (source);
496 source = NULL;
500 if (source != NULL) {
501 ESourceMailIdentity *mi;
502 ESourceMailComposition *mc;
503 const gchar *extension_name;
505 extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
506 mi = e_source_get_extension (source, extension_name);
508 extension_name = E_SOURCE_EXTENSION_MAIL_COMPOSITION;
509 mc = e_source_get_extension (source, extension_name);
511 if (!address) {
512 g_free (name);
514 name = e_source_mail_identity_dup_name (mi);
515 address = e_source_mail_identity_dup_address (mi);
518 if (!name)
519 name = e_source_mail_identity_dup_name (mi);
521 reply_to = e_source_mail_identity_get_reply_to (mi);
522 bcc = e_source_mail_composition_get_bcc (mc);
523 cc = e_source_mail_composition_get_cc (mc);
525 if (table->priv->previous_from_uid) {
526 ESource *previous_source;
528 previous_source = e_composer_header_table_ref_source (table, table->priv->previous_from_uid);
529 if (previous_source && e_source_has_extension (previous_source, E_SOURCE_EXTENSION_MAIL_IDENTITY)) {
530 const gchar *previous_reply_to;
531 const gchar *current_reply_to;
532 gboolean matches;
534 mi = e_source_get_extension (previous_source, E_SOURCE_EXTENSION_MAIL_IDENTITY);
535 previous_reply_to = e_source_mail_identity_get_reply_to (mi);
537 header = e_composer_header_table_get_header (table, E_COMPOSER_HEADER_REPLY_TO);
538 text_header = E_COMPOSER_TEXT_HEADER (header);
539 current_reply_to = e_composer_text_header_get_text (text_header);
541 matches = ((!current_reply_to || !*current_reply_to) && (!previous_reply_to || !*previous_reply_to)) ||
542 g_strcmp0 (current_reply_to, previous_reply_to) == 0;
544 /* Do not change Reply-To, if the user changed it. */
545 if (!matches)
546 reply_to = current_reply_to;
550 g_free (table->priv->previous_from_uid);
551 table->priv->previous_from_uid = g_strdup (e_source_get_uid (source));
553 g_object_unref (source);
554 } else {
555 g_free (table->priv->previous_from_uid);
556 table->priv->previous_from_uid = NULL;
559 type = E_COMPOSER_HEADER_FROM;
560 header = e_composer_header_table_get_header (table, type);
561 from_header = E_COMPOSER_FROM_HEADER (header);
562 e_composer_from_header_set_name (from_header, name);
563 e_composer_from_header_set_address (from_header, address);
565 type = E_COMPOSER_HEADER_POST_TO;
566 header = e_composer_header_table_get_header (table, type);
567 post_header = E_COMPOSER_POST_HEADER (header);
568 e_composer_post_header_set_mail_account (post_header, mail_account);
570 type = E_COMPOSER_HEADER_REPLY_TO;
571 header = e_composer_header_table_get_header (table, type);
572 text_header = E_COMPOSER_TEXT_HEADER (header);
573 e_composer_text_header_set_text (text_header, reply_to);
575 /* Update automatic CC destinations. */
576 old_destinations =
577 e_composer_header_table_get_destinations_cc (table);
578 new_destinations =
579 composer_header_table_update_destinations (
580 old_destinations, cc);
581 e_composer_header_table_set_destinations_cc (table, new_destinations);
582 e_destination_freev (old_destinations);
583 e_destination_freev (new_destinations);
585 /* Update automatic BCC destinations. */
586 old_destinations =
587 e_composer_header_table_get_destinations_bcc (table);
588 new_destinations =
589 composer_header_table_update_destinations (
590 old_destinations, bcc);
591 e_composer_header_table_set_destinations_bcc (table, new_destinations);
592 e_destination_freev (old_destinations);
593 e_destination_freev (new_destinations);
595 if (composer_header_table_show_post_headers (table))
596 composer_header_table_setup_post_headers (table);
597 else
598 composer_header_table_setup_mail_headers (table);
600 g_free (name);
601 g_free (address);
604 static void
605 composer_header_table_set_client_cache (EComposerHeaderTable *table,
606 EClientCache *client_cache)
608 g_return_if_fail (E_IS_CLIENT_CACHE (client_cache));
609 g_return_if_fail (table->priv->client_cache == NULL);
611 table->priv->client_cache = g_object_ref (client_cache);
614 static void
615 composer_header_table_set_property (GObject *object,
616 guint property_id,
617 const GValue *value,
618 GParamSpec *pspec)
620 EDestination **destinations;
621 GList *list;
623 switch (property_id) {
624 case PROP_CLIENT_CACHE:
625 composer_header_table_set_client_cache (
626 E_COMPOSER_HEADER_TABLE (object),
627 g_value_get_object (value));
628 return;
630 case PROP_DESTINATIONS_BCC:
631 destinations = g_value_dup_destinations (value);
632 e_composer_header_table_set_destinations_bcc (
633 E_COMPOSER_HEADER_TABLE (object),
634 destinations);
635 e_destination_freev (destinations);
636 return;
638 case PROP_DESTINATIONS_CC:
639 destinations = g_value_dup_destinations (value);
640 e_composer_header_table_set_destinations_cc (
641 E_COMPOSER_HEADER_TABLE (object),
642 destinations);
643 e_destination_freev (destinations);
644 return;
646 case PROP_DESTINATIONS_TO:
647 destinations = g_value_dup_destinations (value);
648 e_composer_header_table_set_destinations_to (
649 E_COMPOSER_HEADER_TABLE (object),
650 destinations);
651 e_destination_freev (destinations);
652 return;
654 case PROP_IDENTITY_UID:
655 e_composer_header_table_set_identity_uid (
656 E_COMPOSER_HEADER_TABLE (object),
657 g_value_get_string (value), NULL, NULL);
658 return;
660 case PROP_POST_TO:
661 list = g_value_dup_string_list (value);
662 e_composer_header_table_set_post_to_list (
663 E_COMPOSER_HEADER_TABLE (object), list);
664 g_list_foreach (list, (GFunc) g_free, NULL);
665 g_list_free (list);
666 return;
668 case PROP_REPLY_TO:
669 e_composer_header_table_set_reply_to (
670 E_COMPOSER_HEADER_TABLE (object),
671 g_value_get_string (value));
672 return;
674 case PROP_SIGNATURE_UID:
675 e_composer_header_table_set_signature_uid (
676 E_COMPOSER_HEADER_TABLE (object),
677 g_value_get_string (value));
678 return;
680 case PROP_SUBJECT:
681 e_composer_header_table_set_subject (
682 E_COMPOSER_HEADER_TABLE (object),
683 g_value_get_string (value));
684 return;
687 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
690 static void
691 composer_header_table_get_property (GObject *object,
692 guint property_id,
693 GValue *value,
694 GParamSpec *pspec)
696 EDestination **destinations;
697 GList *list;
699 switch (property_id) {
700 case PROP_CLIENT_CACHE:
701 g_value_take_object (
702 value,
703 e_composer_header_table_ref_client_cache (
704 E_COMPOSER_HEADER_TABLE (object)));
705 return;
707 case PROP_DESTINATIONS_BCC:
708 destinations =
709 e_composer_header_table_get_destinations_bcc (
710 E_COMPOSER_HEADER_TABLE (object));
711 g_value_set_destinations (value, destinations);
712 e_destination_freev (destinations);
713 return;
715 case PROP_DESTINATIONS_CC:
716 destinations =
717 e_composer_header_table_get_destinations_cc (
718 E_COMPOSER_HEADER_TABLE (object));
719 g_value_set_destinations (value, destinations);
720 e_destination_freev (destinations);
721 return;
723 case PROP_DESTINATIONS_TO:
724 destinations =
725 e_composer_header_table_get_destinations_to (
726 E_COMPOSER_HEADER_TABLE (object));
727 g_value_set_destinations (value, destinations);
728 e_destination_freev (destinations);
729 return;
731 case PROP_IDENTITY_UID:
732 g_value_take_string (
733 value,
734 e_composer_header_table_dup_identity_uid (
735 E_COMPOSER_HEADER_TABLE (object), NULL, NULL));
736 return;
738 case PROP_POST_TO:
739 list = e_composer_header_table_get_post_to (
740 E_COMPOSER_HEADER_TABLE (object));
741 g_value_set_string_list (value, list);
742 g_list_foreach (list, (GFunc) g_free, NULL);
743 g_list_free (list);
744 return;
746 case PROP_REPLY_TO:
747 g_value_set_string (
748 value,
749 e_composer_header_table_get_reply_to (
750 E_COMPOSER_HEADER_TABLE (object)));
751 return;
753 case PROP_SIGNATURE_COMBO_BOX:
754 g_value_set_object (
755 value,
756 e_composer_header_table_get_signature_combo_box (
757 E_COMPOSER_HEADER_TABLE (object)));
758 return;
760 case PROP_SIGNATURE_UID:
761 g_value_set_string (
762 value,
763 e_composer_header_table_get_signature_uid (
764 E_COMPOSER_HEADER_TABLE (object)));
765 return;
767 case PROP_SUBJECT:
768 g_value_set_string (
769 value,
770 e_composer_header_table_get_subject (
771 E_COMPOSER_HEADER_TABLE (object)));
772 return;
775 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
778 static void
779 composer_header_table_dispose (GObject *object)
781 EComposerHeaderTablePrivate *priv;
782 gint ii;
784 priv = E_COMPOSER_HEADER_TABLE_GET_PRIVATE (object);
786 for (ii = 0; ii < G_N_ELEMENTS (priv->headers); ii++) {
787 if (priv->headers[ii] != NULL) {
788 g_object_unref (priv->headers[ii]);
789 priv->headers[ii] = NULL;
793 if (priv->signature_combo_box != NULL) {
794 g_object_unref (priv->signature_combo_box);
795 priv->signature_combo_box = NULL;
798 if (priv->name_selector != NULL) {
799 e_name_selector_cancel_loading (priv->name_selector);
800 g_object_unref (priv->name_selector);
801 priv->name_selector = NULL;
804 if (priv->client_cache != NULL) {
805 g_object_unref (priv->client_cache);
806 priv->client_cache = NULL;
809 g_free (priv->previous_from_uid);
810 priv->previous_from_uid = NULL;
812 /* Chain up to parent's dispose() method. */
813 G_OBJECT_CLASS (e_composer_header_table_parent_class)->dispose (object);
816 static void
817 composer_header_table_constructed (GObject *object)
819 EComposerHeaderTable *table;
820 EComposerFromHeader *from_header;
821 ENameSelector *name_selector;
822 EClientCache *client_cache;
823 ESourceRegistry *registry;
824 EComposerHeader *header;
825 GtkWidget *widget;
826 guint ii;
827 gint row_padding;
829 /* Chain up to parent's constructed() method. */
830 G_OBJECT_CLASS (e_composer_header_table_parent_class)->constructed (object);
832 table = E_COMPOSER_HEADER_TABLE (object);
834 client_cache = e_composer_header_table_ref_client_cache (table);
835 registry = e_client_cache_ref_registry (client_cache);
837 name_selector = e_name_selector_new (client_cache);
838 table->priv->name_selector = name_selector;
840 header = e_composer_from_header_new (registry, _("Fr_om:"));
841 composer_header_table_bind_header ("identity-uid", "changed", header);
842 g_signal_connect_swapped (
843 header, "changed", G_CALLBACK (
844 composer_header_table_from_changed_cb), table);
845 table->priv->headers[E_COMPOSER_HEADER_FROM] = header;
847 header = e_composer_text_header_new_label (registry, _("_Reply-To:"));
848 composer_header_table_bind_header ("reply-to", "changed", header);
849 table->priv->headers[E_COMPOSER_HEADER_REPLY_TO] = header;
851 header = e_composer_name_header_new (
852 registry, _("_To:"), name_selector);
853 e_composer_header_set_input_tooltip (header, HEADER_TOOLTIP_TO);
854 composer_header_table_bind_header ("destinations-to", "changed", header);
855 table->priv->headers[E_COMPOSER_HEADER_TO] = header;
857 header = e_composer_name_header_new (
858 registry, _("_Cc:"), name_selector);
859 e_composer_header_set_input_tooltip (header, HEADER_TOOLTIP_CC);
860 composer_header_table_bind_header ("destinations-cc", "changed", header);
861 table->priv->headers[E_COMPOSER_HEADER_CC] = header;
863 header = e_composer_name_header_new (
864 registry, _("_Bcc:"), name_selector);
865 e_composer_header_set_input_tooltip (header, HEADER_TOOLTIP_BCC);
866 composer_header_table_bind_header ("destinations-bcc", "changed", header);
867 table->priv->headers[E_COMPOSER_HEADER_BCC] = header;
869 header = e_composer_post_header_new (registry, _("_Post To:"));
870 composer_header_table_bind_header ("post-to", "changed", header);
871 table->priv->headers[E_COMPOSER_HEADER_POST_TO] = header;
873 header = e_composer_spell_header_new_label (registry, _("S_ubject:"));
874 composer_header_table_bind_header ("subject", "changed", header);
875 e_composer_header_set_title_has_tooltip (header, FALSE);
876 e_composer_header_set_input_has_tooltip (header, FALSE);
877 table->priv->headers[E_COMPOSER_HEADER_SUBJECT] = header;
879 widget = e_mail_signature_combo_box_new (registry);
880 composer_header_table_bind_widget ("signature-uid", "changed", widget);
881 table->priv->signature_combo_box = g_object_ref_sink (widget);
883 widget = gtk_label_new_with_mnemonic (_("Si_gnature:"));
884 gtk_label_set_mnemonic_widget (
885 GTK_LABEL (widget), table->priv->signature_combo_box);
886 table->priv->signature_label = g_object_ref_sink (widget);
888 /* Use "ypadding" instead of "row-spacing" because some rows may
889 * be invisible and we don't want spacing around them. */
891 row_padding = 3;
893 for (ii = 0; ii < G_N_ELEMENTS (table->priv->headers); ii++) {
894 gint row = ii;
896 if (ii > E_COMPOSER_HEADER_FROM)
897 row++;
899 gtk_table_attach (
900 GTK_TABLE (object),
901 table->priv->headers[ii]->title_widget, 0, 1,
902 row, row + 1, GTK_FILL, GTK_FILL, 0, row_padding);
903 gtk_table_attach (
904 GTK_TABLE (object),
905 table->priv->headers[ii]->input_widget, 1, 4,
906 row, row + 1, GTK_FILL | GTK_EXPAND, 0, 0, row_padding);
909 ii = E_COMPOSER_HEADER_FROM;
911 /* Leave room in the "From" row for signature stuff. */
912 gtk_container_child_set (
913 GTK_CONTAINER (object),
914 table->priv->headers[ii]->input_widget,
915 "right-attach", 2, NULL);
917 e_binding_bind_property (
918 table->priv->headers[ii]->input_widget, "visible",
919 table->priv->signature_label, "visible",
920 G_BINDING_SYNC_CREATE);
922 e_binding_bind_property (
923 table->priv->headers[ii]->input_widget, "visible",
924 table->priv->signature_combo_box, "visible",
925 G_BINDING_SYNC_CREATE);
927 /* Now add the signature stuff. */
928 gtk_table_attach (
929 GTK_TABLE (object),
930 table->priv->signature_label,
931 2, 3, ii, ii + 1, 0, 0, 0, row_padding);
932 gtk_table_attach (
933 GTK_TABLE (object),
934 table->priv->signature_combo_box,
935 3, 4, ii, ii + 1, 0, 0, 0, row_padding);
937 from_header = E_COMPOSER_FROM_HEADER (e_composer_header_table_get_header (table, E_COMPOSER_HEADER_FROM));
939 gtk_table_attach (
940 GTK_TABLE (object),
941 from_header->override_widget, 1, 2,
942 ii + 1, ii + 2, GTK_FILL, GTK_FILL, 0, row_padding);
944 /* Initialize the headers. */
945 composer_header_table_from_changed_cb (table);
947 g_object_unref (client_cache);
948 g_object_unref (registry);
951 static void
952 e_composer_header_table_class_init (EComposerHeaderTableClass *class)
954 GObjectClass *object_class;
956 g_type_class_add_private (class, sizeof (EComposerHeaderTablePrivate));
958 object_class = G_OBJECT_CLASS (class);
959 object_class->set_property = composer_header_table_set_property;
960 object_class->get_property = composer_header_table_get_property;
961 object_class->dispose = composer_header_table_dispose;
962 object_class->constructed = composer_header_table_constructed;
965 * EComposerHeaderTable:client-cache:
967 * Cache of shared #EClient instances.
969 g_object_class_install_property (
970 object_class,
971 PROP_CLIENT_CACHE,
972 g_param_spec_object (
973 "client-cache",
974 "Client Cache",
975 "Cache of shared EClient instances",
976 E_TYPE_CLIENT_CACHE,
977 G_PARAM_READWRITE |
978 G_PARAM_CONSTRUCT_ONLY |
979 G_PARAM_STATIC_STRINGS));
981 g_object_class_install_property (
982 object_class,
983 PROP_DESTINATIONS_BCC,
984 g_param_spec_boxed (
985 "destinations-bcc",
986 NULL,
987 NULL,
988 G_TYPE_PTR_ARRAY,
989 G_PARAM_READWRITE |
990 G_PARAM_STATIC_STRINGS));
992 g_object_class_install_property (
993 object_class,
994 PROP_DESTINATIONS_CC,
995 g_param_spec_boxed (
996 "destinations-cc",
997 NULL,
998 NULL,
999 G_TYPE_PTR_ARRAY,
1000 G_PARAM_READWRITE |
1001 G_PARAM_STATIC_STRINGS));
1003 g_object_class_install_property (
1004 object_class,
1005 PROP_DESTINATIONS_TO,
1006 g_param_spec_boxed (
1007 "destinations-to",
1008 NULL,
1009 NULL,
1010 G_TYPE_PTR_ARRAY,
1011 G_PARAM_READWRITE |
1012 G_PARAM_STATIC_STRINGS));
1014 g_object_class_install_property (
1015 object_class,
1016 PROP_IDENTITY_UID,
1017 g_param_spec_string (
1018 "identity-uid",
1019 NULL,
1020 NULL,
1021 NULL,
1022 G_PARAM_READWRITE |
1023 G_PARAM_STATIC_STRINGS));
1025 g_object_class_install_property (
1026 object_class,
1027 PROP_POST_TO,
1028 g_param_spec_boxed (
1029 "post-to",
1030 NULL,
1031 NULL,
1032 G_TYPE_PTR_ARRAY,
1033 G_PARAM_READWRITE |
1034 G_PARAM_STATIC_STRINGS));
1036 g_object_class_install_property (
1037 object_class,
1038 PROP_REPLY_TO,
1039 g_param_spec_string (
1040 "reply-to",
1041 NULL,
1042 NULL,
1043 NULL,
1044 G_PARAM_READWRITE |
1045 G_PARAM_STATIC_STRINGS));
1047 g_object_class_install_property (
1048 object_class,
1049 PROP_SIGNATURE_COMBO_BOX,
1050 g_param_spec_string (
1051 "signature-combo-box",
1052 NULL,
1053 NULL,
1054 NULL,
1055 G_PARAM_READABLE |
1056 G_PARAM_STATIC_STRINGS));
1058 g_object_class_install_property (
1059 object_class,
1060 PROP_SIGNATURE_UID,
1061 g_param_spec_string (
1062 "signature-uid",
1063 NULL,
1064 NULL,
1065 NULL,
1066 G_PARAM_READWRITE |
1067 G_PARAM_STATIC_STRINGS));
1069 g_object_class_install_property (
1070 object_class,
1071 PROP_SUBJECT,
1072 g_param_spec_string (
1073 "subject",
1074 NULL,
1075 NULL,
1076 NULL,
1077 G_PARAM_READWRITE |
1078 G_PARAM_STATIC_STRINGS));
1081 static void
1082 composer_header_table_realize_cb (EComposerHeaderTable *table)
1084 g_return_if_fail (table != NULL);
1085 g_return_if_fail (table->priv != NULL);
1087 g_signal_handlers_disconnect_by_func (
1088 table, composer_header_table_realize_cb, NULL);
1090 e_name_selector_load_books (table->priv->name_selector);
1093 static void
1094 e_composer_header_table_init (EComposerHeaderTable *table)
1096 gint rows;
1098 table->priv = E_COMPOSER_HEADER_TABLE_GET_PRIVATE (table);
1100 rows = G_N_ELEMENTS (table->priv->headers);
1101 gtk_table_resize (GTK_TABLE (table), rows, 4);
1102 gtk_table_set_row_spacings (GTK_TABLE (table), 0);
1103 gtk_table_set_col_spacings (GTK_TABLE (table), 6);
1105 /* postpone name_selector loading, do that only when really needed */
1106 g_signal_connect (
1107 table, "realize",
1108 G_CALLBACK (composer_header_table_realize_cb), NULL);
1111 GtkWidget *
1112 e_composer_header_table_new (EClientCache *client_cache)
1114 g_return_val_if_fail (E_IS_CLIENT_CACHE (client_cache), NULL);
1116 return g_object_new (
1117 E_TYPE_COMPOSER_HEADER_TABLE,
1118 "client-cache", client_cache, NULL);
1121 EClientCache *
1122 e_composer_header_table_ref_client_cache (EComposerHeaderTable *table)
1124 g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL);
1126 return g_object_ref (table->priv->client_cache);
1129 EComposerHeader *
1130 e_composer_header_table_get_header (EComposerHeaderTable *table,
1131 EComposerHeaderType type)
1133 g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL);
1134 g_return_val_if_fail (type < E_COMPOSER_NUM_HEADERS, NULL);
1136 return table->priv->headers[type];
1139 EMailSignatureComboBox *
1140 e_composer_header_table_get_signature_combo_box (EComposerHeaderTable *table)
1142 g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL);
1144 return E_MAIL_SIGNATURE_COMBO_BOX (table->priv->signature_combo_box);
1147 EDestination **
1148 e_composer_header_table_get_destinations (EComposerHeaderTable *table)
1150 EDestination **destinations;
1151 EDestination **to, **cc, **bcc;
1152 gint total, n_to, n_cc, n_bcc;
1154 g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL);
1156 to = e_composer_header_table_get_destinations_to (table);
1157 for (n_to = 0; to != NULL && to[n_to] != NULL; n_to++);
1159 cc = e_composer_header_table_get_destinations_cc (table);
1160 for (n_cc = 0; cc != NULL && cc[n_cc] != NULL; n_cc++);
1162 bcc = e_composer_header_table_get_destinations_bcc (table);
1163 for (n_bcc = 0; bcc != NULL && bcc[n_bcc] != NULL; n_bcc++);
1165 total = n_to + n_cc + n_bcc;
1166 destinations = g_new0 (EDestination *, total + 1);
1168 while (n_bcc > 0 && total > 0)
1169 destinations[--total] = g_object_ref (bcc[--n_bcc]);
1171 while (n_cc > 0 && total > 0)
1172 destinations[--total] = g_object_ref (cc[--n_cc]);
1174 while (n_to > 0 && total > 0)
1175 destinations[--total] = g_object_ref (to[--n_to]);
1177 /* Counters should all be zero now. */
1178 g_return_val_if_fail (total == 0 && n_to == 0 && n_cc == 0 && n_bcc == 0, destinations);
1180 e_destination_freev (to);
1181 e_destination_freev (cc);
1182 e_destination_freev (bcc);
1184 return destinations;
1187 EDestination **
1188 e_composer_header_table_get_destinations_bcc (EComposerHeaderTable *table)
1190 EComposerHeader *header;
1191 EComposerHeaderType type;
1192 EComposerNameHeader *name_header;
1194 g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL);
1196 type = E_COMPOSER_HEADER_BCC;
1197 header = e_composer_header_table_get_header (table, type);
1198 name_header = E_COMPOSER_NAME_HEADER (header);
1200 return e_composer_name_header_get_destinations (name_header);
1203 void
1204 e_composer_header_table_add_destinations_bcc (EComposerHeaderTable *table,
1205 EDestination **destinations)
1207 EComposerHeader *header;
1208 EComposerHeaderType type;
1209 EComposerNameHeader *name_header;
1211 g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (table));
1213 type = E_COMPOSER_HEADER_BCC;
1214 header = e_composer_header_table_get_header (table, type);
1215 name_header = E_COMPOSER_NAME_HEADER (header);
1217 e_composer_name_header_add_destinations (name_header, destinations);
1219 if (destinations != NULL && *destinations != NULL)
1220 e_composer_header_set_visible (header, TRUE);
1223 void
1224 e_composer_header_table_set_destinations_bcc (EComposerHeaderTable *table,
1225 EDestination **destinations)
1227 EComposerHeader *header;
1228 EComposerHeaderType type;
1229 EComposerNameHeader *name_header;
1231 g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (table));
1233 type = E_COMPOSER_HEADER_BCC;
1234 header = e_composer_header_table_get_header (table, type);
1235 name_header = E_COMPOSER_NAME_HEADER (header);
1237 e_composer_name_header_set_destinations (name_header, destinations);
1239 if (destinations != NULL && *destinations != NULL)
1240 e_composer_header_set_visible (header, TRUE);
1243 EDestination **
1244 e_composer_header_table_get_destinations_cc (EComposerHeaderTable *table)
1246 EComposerHeader *header;
1247 EComposerHeaderType type;
1248 EComposerNameHeader *name_header;
1250 g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL);
1252 type = E_COMPOSER_HEADER_CC;
1253 header = e_composer_header_table_get_header (table, type);
1254 name_header = E_COMPOSER_NAME_HEADER (header);
1256 return e_composer_name_header_get_destinations (name_header);
1259 void
1260 e_composer_header_table_add_destinations_cc (EComposerHeaderTable *table,
1261 EDestination **destinations)
1263 EComposerHeader *header;
1264 EComposerHeaderType type;
1265 EComposerNameHeader *name_header;
1267 g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (table));
1269 type = E_COMPOSER_HEADER_CC;
1270 header = e_composer_header_table_get_header (table, type);
1271 name_header = E_COMPOSER_NAME_HEADER (header);
1273 e_composer_name_header_add_destinations (name_header, destinations);
1275 if (destinations != NULL && *destinations != NULL)
1276 e_composer_header_set_visible (header, TRUE);
1279 void
1280 e_composer_header_table_set_destinations_cc (EComposerHeaderTable *table,
1281 EDestination **destinations)
1283 EComposerHeader *header;
1284 EComposerHeaderType type;
1285 EComposerNameHeader *name_header;
1287 g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (table));
1289 type = E_COMPOSER_HEADER_CC;
1290 header = e_composer_header_table_get_header (table, type);
1291 name_header = E_COMPOSER_NAME_HEADER (header);
1293 e_composer_name_header_set_destinations (name_header, destinations);
1295 if (destinations != NULL && *destinations != NULL)
1296 e_composer_header_set_visible (header, TRUE);
1299 EDestination **
1300 e_composer_header_table_get_destinations_to (EComposerHeaderTable *table)
1302 EComposerHeader *header;
1303 EComposerHeaderType type;
1304 EComposerNameHeader *name_header;
1306 g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL);
1308 type = E_COMPOSER_HEADER_TO;
1309 header = e_composer_header_table_get_header (table, type);
1310 name_header = E_COMPOSER_NAME_HEADER (header);
1312 return e_composer_name_header_get_destinations (name_header);
1315 void
1316 e_composer_header_table_add_destinations_to (EComposerHeaderTable *table,
1317 EDestination **destinations)
1319 EComposerHeader *header;
1320 EComposerHeaderType type;
1321 EComposerNameHeader *name_header;
1323 g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (table));
1325 type = E_COMPOSER_HEADER_TO;
1326 header = e_composer_header_table_get_header (table, type);
1327 name_header = E_COMPOSER_NAME_HEADER (header);
1329 e_composer_name_header_add_destinations (name_header, destinations);
1332 void
1333 e_composer_header_table_set_destinations_to (EComposerHeaderTable *table,
1334 EDestination **destinations)
1336 EComposerHeader *header;
1337 EComposerHeaderType type;
1338 EComposerNameHeader *name_header;
1340 g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (table));
1342 type = E_COMPOSER_HEADER_TO;
1343 header = e_composer_header_table_get_header (table, type);
1344 name_header = E_COMPOSER_NAME_HEADER (header);
1346 e_composer_name_header_set_destinations (name_header, destinations);
1349 gchar *
1350 e_composer_header_table_dup_identity_uid (EComposerHeaderTable *table,
1351 gchar **chosen_alias_name,
1352 gchar **chosen_alias_address)
1354 EComposerHeader *header;
1355 EComposerHeaderType type;
1356 EComposerFromHeader *from_header;
1358 g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL);
1360 type = E_COMPOSER_HEADER_FROM;
1361 header = e_composer_header_table_get_header (table, type);
1362 from_header = E_COMPOSER_FROM_HEADER (header);
1364 return e_composer_from_header_dup_active_id (from_header, chosen_alias_name, chosen_alias_address);
1367 void
1368 e_composer_header_table_set_identity_uid (EComposerHeaderTable *table,
1369 const gchar *identity_uid,
1370 const gchar *alias_name,
1371 const gchar *alias_address)
1373 EComposerHeader *header;
1374 EComposerHeaderType type;
1375 EComposerFromHeader *from_header;
1377 g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (table));
1379 type = E_COMPOSER_HEADER_FROM;
1380 header = e_composer_header_table_get_header (table, type);
1381 from_header = E_COMPOSER_FROM_HEADER (header);
1383 e_composer_from_header_set_active_id (from_header, identity_uid, alias_name, alias_address);
1386 const gchar *
1387 e_composer_header_table_get_from_name (EComposerHeaderTable *table)
1389 EComposerHeader *header;
1390 EComposerHeaderType type;
1391 EComposerFromHeader *from_header;
1393 g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL);
1395 type = E_COMPOSER_HEADER_FROM;
1396 header = e_composer_header_table_get_header (table, type);
1397 from_header = E_COMPOSER_FROM_HEADER (header);
1399 return e_composer_from_header_get_name (from_header);
1402 const gchar *
1403 e_composer_header_table_get_from_address (EComposerHeaderTable *table)
1405 EComposerHeader *header;
1406 EComposerHeaderType type;
1407 EComposerFromHeader *from_header;
1409 g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL);
1411 type = E_COMPOSER_HEADER_FROM;
1412 header = e_composer_header_table_get_header (table, type);
1413 from_header = E_COMPOSER_FROM_HEADER (header);
1415 return e_composer_from_header_get_address (from_header);
1418 GList *
1419 e_composer_header_table_get_post_to (EComposerHeaderTable *table)
1421 EComposerHeader *header;
1422 EComposerHeaderType type;
1423 EComposerPostHeader *post_header;
1425 g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL);
1427 type = E_COMPOSER_HEADER_POST_TO;
1428 header = e_composer_header_table_get_header (table, type);
1429 post_header = E_COMPOSER_POST_HEADER (header);
1431 return e_composer_post_header_get_folders (post_header);
1434 void
1435 e_composer_header_table_set_post_to_base (EComposerHeaderTable *table,
1436 const gchar *base_url,
1437 const gchar *folders)
1439 EComposerHeader *header;
1440 EComposerHeaderType type;
1441 EComposerPostHeader *post_header;
1443 g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (table));
1445 type = E_COMPOSER_HEADER_POST_TO;
1446 header = e_composer_header_table_get_header (table, type);
1447 post_header = E_COMPOSER_POST_HEADER (header);
1449 e_composer_post_header_set_folders_base (post_header, base_url, folders);
1452 void
1453 e_composer_header_table_set_post_to_list (EComposerHeaderTable *table,
1454 GList *folders)
1456 EComposerHeader *header;
1457 EComposerHeaderType type;
1458 EComposerPostHeader *post_header;
1460 g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (table));
1462 type = E_COMPOSER_HEADER_POST_TO;
1463 header = e_composer_header_table_get_header (table, type);
1464 post_header = E_COMPOSER_POST_HEADER (header);
1466 e_composer_post_header_set_folders (post_header, folders);
1469 const gchar *
1470 e_composer_header_table_get_reply_to (EComposerHeaderTable *table)
1472 EComposerHeader *header;
1473 EComposerHeaderType type;
1474 EComposerTextHeader *text_header;
1476 g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL);
1478 type = E_COMPOSER_HEADER_REPLY_TO;
1479 header = e_composer_header_table_get_header (table, type);
1480 text_header = E_COMPOSER_TEXT_HEADER (header);
1482 return e_composer_text_header_get_text (text_header);
1485 void
1486 e_composer_header_table_set_reply_to (EComposerHeaderTable *table,
1487 const gchar *reply_to)
1489 EComposerHeader *header;
1490 EComposerHeaderType type;
1491 EComposerTextHeader *text_header;
1493 g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (table));
1495 type = E_COMPOSER_HEADER_REPLY_TO;
1496 header = e_composer_header_table_get_header (table, type);
1497 text_header = E_COMPOSER_TEXT_HEADER (header);
1499 e_composer_text_header_set_text (text_header, reply_to);
1501 if (reply_to != NULL && *reply_to != '\0')
1502 e_composer_header_set_visible (header, TRUE);
1505 const gchar *
1506 e_composer_header_table_get_signature_uid (EComposerHeaderTable *table)
1508 EMailSignatureComboBox *combo_box;
1510 g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL);
1512 combo_box = e_composer_header_table_get_signature_combo_box (table);
1514 return gtk_combo_box_get_active_id (GTK_COMBO_BOX (combo_box));
1517 void
1518 e_composer_header_table_set_signature_uid (EComposerHeaderTable *table,
1519 const gchar *signature_uid)
1521 EMailSignatureComboBox *combo_box;
1523 g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (table));
1525 combo_box = e_composer_header_table_get_signature_combo_box (table);
1527 gtk_combo_box_set_active_id (GTK_COMBO_BOX (combo_box), signature_uid);
1530 const gchar *
1531 e_composer_header_table_get_subject (EComposerHeaderTable *table)
1533 EComposerHeader *header;
1534 EComposerHeaderType type;
1535 EComposerTextHeader *text_header;
1537 g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL);
1539 type = E_COMPOSER_HEADER_SUBJECT;
1540 header = e_composer_header_table_get_header (table, type);
1541 text_header = E_COMPOSER_TEXT_HEADER (header);
1543 return e_composer_text_header_get_text (text_header);
1546 void
1547 e_composer_header_table_set_subject (EComposerHeaderTable *table,
1548 const gchar *subject)
1550 EComposerHeader *header;
1551 EComposerHeaderType type;
1552 EComposerTextHeader *text_header;
1554 g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (table));
1556 type = E_COMPOSER_HEADER_SUBJECT;
1557 header = e_composer_header_table_get_header (table, type);
1558 text_header = E_COMPOSER_TEXT_HEADER (header);
1560 e_composer_text_header_set_text (text_header, subject);
1563 void
1564 e_composer_header_table_set_header_visible (EComposerHeaderTable *table,
1565 EComposerHeaderType type,
1566 gboolean visible)
1568 EComposerHeader *header;
1570 header = e_composer_header_table_get_header (table, type);
1571 e_composer_header_set_visible (header, visible);
1573 /* Signature widgets track the "From" header. */
1574 if (type == E_COMPOSER_HEADER_FROM) {
1575 if (visible) {
1576 gtk_widget_show (table->priv->signature_label);
1577 gtk_widget_show (table->priv->signature_combo_box);
1578 } else {
1579 gtk_widget_hide (table->priv->signature_label);
1580 gtk_widget_hide (table->priv->signature_combo_box);
1586 * e_composer_header_table_ref_source:
1587 * @table: an #EComposerHeaderTable
1588 * @uid: a unique identifier string
1590 * Convenience function that works just like e_source_registry_ref_source(),
1591 * but spares the caller from digging out the #ESourceRegistry from @table.
1593 * The returned #ESource is referenced for thread-safety and must be
1594 * unreferenced with g_object_unref() when finished with it.
1596 * Returns: an #ESource, or %NULL if no match was found
1598 ESource *
1599 e_composer_header_table_ref_source (EComposerHeaderTable *table,
1600 const gchar *uid)
1602 EClientCache *client_cache;
1603 ESourceRegistry *registry;
1604 ESource *source;
1606 g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL);
1607 g_return_val_if_fail (uid != NULL, NULL);
1609 client_cache = e_composer_header_table_ref_client_cache (table);
1610 registry = e_client_cache_ref_registry (client_cache);
1612 source = e_source_registry_ref_source (registry, uid);
1614 g_object_unref (client_cache);
1615 g_object_unref (registry);
1617 return source;