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.
5 *
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.
10 *
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/>.
13 *
14 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
15 */
16
17 #include "evolution-config.h"
18
19 #include "e-composer-header-table.h"
20
21 #include <glib/gi18n-lib.h>
22
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"
30
31 #define E_COMPOSER_HEADER_TABLE_GET_PRIVATE(obj) \
32 (G_TYPE_INSTANCE_GET_PRIVATE \
33 ((obj), E_TYPE_COMPOSER_HEADER_TABLE, EComposerHeaderTablePrivate))
34
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")
44
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;
51
52 gchar *previous_from_uid;
53 };
54
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
67 };
68
G_DEFINE_TYPE(EComposerHeaderTable,e_composer_header_table,GTK_TYPE_TABLE)69 G_DEFINE_TYPE (
70 EComposerHeaderTable,
71 e_composer_header_table,
72 GTK_TYPE_TABLE)
73
74 static void
75 g_value_set_destinations (GValue *value,
76 EDestination **destinations)
77 {
78 GPtrArray *array;
79 gint ii;
80
81 /* Preallocate some reasonable number. */
82 array = g_ptr_array_new_full (64, g_object_unref);
83
84 for (ii = 0; destinations[ii] != NULL; ii++) {
85 g_ptr_array_add (array, e_destination_copy (destinations[ii]));
86 }
87
88 g_value_take_boxed (value, array);
89 }
90
91 static EDestination **
g_value_dup_destinations(const GValue * value)92 g_value_dup_destinations (const GValue *value)
93 {
94 EDestination **destinations;
95 const EDestination *dest;
96 GPtrArray *array;
97 guint ii;
98
99 array = g_value_get_boxed (value);
100 destinations = g_new0 (EDestination *, array->len + 1);
101
102 for (ii = 0; ii < array->len; ii++) {
103 dest = g_ptr_array_index (array, ii);
104 destinations[ii] = e_destination_copy (dest);
105 }
106
107 return destinations;
108 }
109
110 static void
g_value_set_string_list(GValue * value,GList * list)111 g_value_set_string_list (GValue *value,
112 GList *list)
113 {
114 GPtrArray *array;
115
116 array = g_ptr_array_new_full (g_list_length (list), g_free);
117
118 while (list != NULL) {
119 g_ptr_array_add (array, g_strdup (list->data));
120 list = list->next;
121 }
122
123 g_value_take_boxed (value, array);
124 }
125
126 static GList *
g_value_dup_string_list(const GValue * value)127 g_value_dup_string_list (const GValue *value)
128 {
129 GPtrArray *array;
130 GList *list = NULL;
131 gint ii;
132
133 array = g_value_get_boxed (value);
134
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));
138 }
139
140 return g_list_reverse (list);
141 }
142
143 static void
composer_header_table_notify_header(EComposerHeader * header,const gchar * property_name)144 composer_header_table_notify_header (EComposerHeader *header,
145 const gchar *property_name)
146 {
147 GtkWidget *parent;
148
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);
152 }
153
154 static void
composer_header_table_notify_widget(GtkWidget * widget,const gchar * property_name)155 composer_header_table_notify_widget (GtkWidget *widget,
156 const gchar *property_name)
157 {
158 GtkWidget *parent;
159
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);
163 }
164
165 static void
composer_header_table_bind_header(const gchar * property_name,const gchar * signal_name,EComposerHeader * header)166 composer_header_table_bind_header (const gchar *property_name,
167 const gchar *signal_name,
168 EComposerHeader *header)
169 {
170 /* Propagate the signal as "notify::property_name". */
171
172 g_signal_connect (
173 header, signal_name,
174 G_CALLBACK (composer_header_table_notify_header),
175 (gpointer) property_name);
176 }
177
178 static void
composer_header_table_bind_widget(const gchar * property_name,const gchar * signal_name,GtkWidget * widget)179 composer_header_table_bind_widget (const gchar *property_name,
180 const gchar *signal_name,
181 GtkWidget *widget)
182 {
183 /* Propagate the signal as "notify::property_name". */
184
185 g_signal_connect (
186 widget, signal_name,
187 G_CALLBACK (composer_header_table_notify_widget),
188 (gpointer) property_name);
189 }
190
191 static EDestination **
composer_header_table_update_destinations(EDestination ** old_destinations,const gchar * const * auto_addresses)192 composer_header_table_update_destinations (EDestination **old_destinations,
193 const gchar * const *auto_addresses)
194 {
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;
202
203 /* Include automatic recipients for the selected account. */
204
205 if (auto_addresses == NULL)
206 goto skip_auto;
207
208 inet_address = camel_internet_address_new ();
209 address = CAMEL_ADDRESS (inet_address);
210
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]);
216
217 for (ii = 0; ii < camel_address_length (address); ii++) {
218 const gchar *name, *email;
219
220 if (!camel_internet_address_get (
221 inet_address, ii, &name, &email))
222 continue;
223
224 destination = e_destination_new ();
225 e_destination_set_auto_recipient (destination, TRUE);
226
227 if (name != NULL)
228 e_destination_set_name (destination, name);
229
230 if (email != NULL)
231 e_destination_set_email (destination, email);
232
233 g_queue_push_tail (&queue, destination);
234 }
235
236 g_object_unref (inet_address);
237
238 skip_auto:
239
240 /* Include custom recipients for this message. */
241
242 if (old_destinations == NULL)
243 goto skip_custom;
244
245 for (ii = 0; old_destinations[ii] != NULL; ii++) {
246 if (e_destination_is_auto_recipient (old_destinations[ii]))
247 continue;
248
249 destination = e_destination_copy (old_destinations[ii]);
250 g_queue_push_tail (&queue, destination);
251 }
252
253 skip_custom:
254
255 length = g_queue_get_length (&queue);
256 new_destinations = g_new0 (EDestination *, length + 1);
257
258 for (ii = 0; ii < length; ii++)
259 new_destinations[ii] = g_queue_pop_head (&queue);
260
261 /* Sanity check. */
262 g_warn_if_fail (g_queue_is_empty (&queue));
263
264 return new_destinations;
265 }
266
267 static void
composer_header_table_setup_mail_headers(EComposerHeaderTable * table)268 composer_header_table_setup_mail_headers (EComposerHeaderTable *table)
269 {
270 GSettings *settings;
271 gint ii;
272
273 settings = e_util_ref_settings ("org.gnome.evolution.mail");
274
275 for (ii = 0; ii < E_COMPOSER_NUM_HEADERS; ii++) {
276 EComposerHeader *header;
277 const gchar *key;
278 gboolean sensitive;
279 gboolean visible;
280
281 header = e_composer_header_table_get_header (table, ii);
282
283 switch (ii) {
284 case E_COMPOSER_HEADER_FROM:
285 key = "composer-show-from-override";
286 break;
287
288 case E_COMPOSER_HEADER_BCC:
289 key = "composer-show-bcc";
290 break;
291
292 case E_COMPOSER_HEADER_CC:
293 key = "composer-show-cc";
294 break;
295
296 case E_COMPOSER_HEADER_REPLY_TO:
297 key = "composer-show-reply-to";
298 break;
299
300 default:
301 key = NULL;
302 break;
303 }
304
305 if (key != NULL)
306 g_settings_unbind (header, "visible");
307
308 switch (ii) {
309 case E_COMPOSER_HEADER_FROM:
310 sensitive = TRUE;
311 visible = TRUE;
312 break;
313
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;
322
323 default:
324 sensitive = FALSE;
325 visible = FALSE;
326 break;
327 }
328
329 e_composer_header_set_sensitive (header, sensitive);
330 e_composer_header_set_visible (header, visible);
331
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);
343 }
344 }
345
346 g_object_unref (settings);
347 }
348
349 static void
composer_header_table_setup_post_headers(EComposerHeaderTable * table)350 composer_header_table_setup_post_headers (EComposerHeaderTable *table)
351 {
352 GSettings *settings;
353 gint ii;
354
355 settings = e_util_ref_settings ("org.gnome.evolution.mail");
356
357 for (ii = 0; ii < E_COMPOSER_NUM_HEADERS; ii++) {
358 EComposerHeader *header;
359 const gchar *key;
360
361 header = e_composer_header_table_get_header (table, ii);
362
363 switch (ii) {
364 case E_COMPOSER_HEADER_FROM:
365 key = "composer-show-post-from";
366 break;
367
368 case E_COMPOSER_HEADER_REPLY_TO:
369 key = "composer-show-post-reply-to";
370 break;
371
372 default:
373 key = NULL;
374 break;
375 }
376
377 if (key != NULL)
378 g_settings_unbind (header, "visible");
379
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;
388
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;
393 }
394
395 if (key != NULL)
396 g_settings_bind (
397 settings, key,
398 header, "visible",
399 G_SETTINGS_BIND_DEFAULT);
400 }
401
402 g_object_unref (settings);
403 }
404
405 static gboolean
composer_header_table_show_post_headers(EComposerHeaderTable * table)406 composer_header_table_show_post_headers (EComposerHeaderTable *table)
407 {
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;
414
415 client_cache = e_composer_header_table_ref_client_cache (table);
416 registry = e_client_cache_ref_registry (client_cache);
417
418 target_uid = e_composer_header_table_dup_identity_uid (table, NULL, NULL);
419
420 extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
421 list = e_source_registry_list_sources (registry, extension_name);
422
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.
426 *
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?
430 */
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;
436
437 extension = e_source_get_extension (source, extension_name);
438
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));
443
444 if (g_strcmp0 (identity_uid, target_uid) != 0)
445 continue;
446
447 if (g_strcmp0 (backend_name, "nntp") != 0)
448 continue;
449
450 show_post_headers = TRUE;
451 break;
452 }
453
454 g_list_free_full (list, (GDestroyNotify) g_object_unref);
455
456 g_object_unref (client_cache);
457 g_object_unref (registry);
458 g_free (target_uid);
459
460 return show_post_headers;
461 }
462
463 static void
composer_header_table_from_changed_cb(EComposerHeaderTable * table)464 composer_header_table_from_changed_cb (EComposerHeaderTable *table)
465 {
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;
481
482 /* Keep "Post-To" and "Reply-To" synchronized with "From" */
483
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);
488
489 /* Make sure this is really a mail identity source. */
490 if (source != NULL) {
491 const gchar *extension_name;
492
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;
497 }
498 }
499
500 if (source != NULL) {
501 ESourceMailIdentity *mi;
502 ESourceMailComposition *mc;
503 const gchar *extension_name;
504
505 extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
506 mi = e_source_get_extension (source, extension_name);
507
508 extension_name = E_SOURCE_EXTENSION_MAIL_COMPOSITION;
509 mc = e_source_get_extension (source, extension_name);
510
511 if (!address) {
512 g_free (name);
513
514 name = e_source_mail_identity_dup_name (mi);
515 address = e_source_mail_identity_dup_address (mi);
516 }
517
518 if (!name)
519 name = e_source_mail_identity_dup_name (mi);
520
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);
524
525 if (table->priv->previous_from_uid) {
526 ESource *previous_source;
527
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;
533
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);
536
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);
540
541 matches = ((!current_reply_to || !*current_reply_to) && (!previous_reply_to || !*previous_reply_to)) ||
542 g_strcmp0 (current_reply_to, previous_reply_to) == 0;
543
544 /* Do not change Reply-To, if the user changed it. */
545 if (!matches)
546 reply_to = current_reply_to;
547 }
548 }
549
550 g_free (table->priv->previous_from_uid);
551 table->priv->previous_from_uid = g_strdup (e_source_get_uid (source));
552
553 g_object_unref (source);
554 } else {
555 g_free (table->priv->previous_from_uid);
556 table->priv->previous_from_uid = NULL;
557 }
558
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);
564
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);
569
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);
574
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);
584
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);
594
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);
599
600 g_free (name);
601 g_free (address);
602 }
603
604 static void
composer_header_table_set_client_cache(EComposerHeaderTable * table,EClientCache * client_cache)605 composer_header_table_set_client_cache (EComposerHeaderTable *table,
606 EClientCache *client_cache)
607 {
608 g_return_if_fail (E_IS_CLIENT_CACHE (client_cache));
609 g_return_if_fail (table->priv->client_cache == NULL);
610
611 table->priv->client_cache = g_object_ref (client_cache);
612 }
613
614 static void
composer_header_table_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)615 composer_header_table_set_property (GObject *object,
616 guint property_id,
617 const GValue *value,
618 GParamSpec *pspec)
619 {
620 EDestination **destinations;
621 GList *list;
622
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;
629
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;
637
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;
645
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;
653
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;
659
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;
667
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;
673
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;
679
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;
685 }
686
687 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
688 }
689
690 static void
composer_header_table_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)691 composer_header_table_get_property (GObject *object,
692 guint property_id,
693 GValue *value,
694 GParamSpec *pspec)
695 {
696 EDestination **destinations;
697 GList *list;
698
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;
706
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;
714
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;
722
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;
730
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;
737
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;
745
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;
752
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;
759
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;
766
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;
773 }
774
775 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
776 }
777
778 static void
composer_header_table_dispose(GObject * object)779 composer_header_table_dispose (GObject *object)
780 {
781 EComposerHeaderTablePrivate *priv;
782 gint ii;
783
784 priv = E_COMPOSER_HEADER_TABLE_GET_PRIVATE (object);
785
786 for (ii = 0; ii < G_N_ELEMENTS (priv->headers); ii++) {
787 g_clear_object (&priv->headers[ii]);
788 }
789
790 g_clear_object (&priv->signature_combo_box);
791
792 if (priv->name_selector != NULL) {
793 e_name_selector_cancel_loading (priv->name_selector);
794 g_object_unref (priv->name_selector);
795 priv->name_selector = NULL;
796 }
797
798 g_clear_object (&priv->client_cache);
799
800 g_free (priv->previous_from_uid);
801 priv->previous_from_uid = NULL;
802
803 /* Chain up to parent's dispose() method. */
804 G_OBJECT_CLASS (e_composer_header_table_parent_class)->dispose (object);
805 }
806
807 static void
composer_header_table_constructed(GObject * object)808 composer_header_table_constructed (GObject *object)
809 {
810 EComposerHeaderTable *table;
811 EComposerFromHeader *from_header;
812 ENameSelector *name_selector;
813 EClientCache *client_cache;
814 ESourceRegistry *registry;
815 EComposerHeader *header;
816 GtkWidget *widget;
817 guint ii;
818 gint row_padding;
819
820 /* Chain up to parent's constructed() method. */
821 G_OBJECT_CLASS (e_composer_header_table_parent_class)->constructed (object);
822
823 table = E_COMPOSER_HEADER_TABLE (object);
824
825 client_cache = e_composer_header_table_ref_client_cache (table);
826 registry = e_client_cache_ref_registry (client_cache);
827
828 name_selector = e_name_selector_new (client_cache);
829 table->priv->name_selector = name_selector;
830
831 header = e_composer_from_header_new (registry, _("Fr_om:"));
832 composer_header_table_bind_header ("identity-uid", "changed", header);
833 g_signal_connect_swapped (
834 header, "changed", G_CALLBACK (
835 composer_header_table_from_changed_cb), table);
836 table->priv->headers[E_COMPOSER_HEADER_FROM] = header;
837
838 header = e_composer_text_header_new_label (registry, _("_Reply-To:"));
839 composer_header_table_bind_header ("reply-to", "changed", header);
840 table->priv->headers[E_COMPOSER_HEADER_REPLY_TO] = header;
841
842 header = e_composer_name_header_new (
843 registry, _("_To:"), name_selector);
844 e_composer_header_set_input_tooltip (header, HEADER_TOOLTIP_TO);
845 composer_header_table_bind_header ("destinations-to", "changed", header);
846 table->priv->headers[E_COMPOSER_HEADER_TO] = header;
847
848 header = e_composer_name_header_new (
849 registry, _("_Cc:"), name_selector);
850 e_composer_header_set_input_tooltip (header, HEADER_TOOLTIP_CC);
851 composer_header_table_bind_header ("destinations-cc", "changed", header);
852 table->priv->headers[E_COMPOSER_HEADER_CC] = header;
853
854 header = e_composer_name_header_new (
855 registry, _("_Bcc:"), name_selector);
856 e_composer_header_set_input_tooltip (header, HEADER_TOOLTIP_BCC);
857 composer_header_table_bind_header ("destinations-bcc", "changed", header);
858 table->priv->headers[E_COMPOSER_HEADER_BCC] = header;
859
860 header = e_composer_post_header_new (registry, _("_Post To:"));
861 composer_header_table_bind_header ("post-to", "changed", header);
862 table->priv->headers[E_COMPOSER_HEADER_POST_TO] = header;
863
864 header = e_composer_spell_header_new_label (registry, _("S_ubject:"));
865 composer_header_table_bind_header ("subject", "changed", header);
866 e_composer_header_set_title_has_tooltip (header, FALSE);
867 e_composer_header_set_input_has_tooltip (header, FALSE);
868 table->priv->headers[E_COMPOSER_HEADER_SUBJECT] = header;
869
870 widget = e_mail_signature_combo_box_new (registry);
871 composer_header_table_bind_widget ("signature-uid", "changed", widget);
872 table->priv->signature_combo_box = g_object_ref_sink (widget);
873
874 widget = gtk_label_new_with_mnemonic (_("Si_gnature:"));
875 gtk_label_set_mnemonic_widget (
876 GTK_LABEL (widget), table->priv->signature_combo_box);
877 table->priv->signature_label = g_object_ref_sink (widget);
878
879 /* Use "ypadding" instead of "row-spacing" because some rows may
880 * be invisible and we don't want spacing around them. */
881
882 row_padding = 3;
883
884 for (ii = 0; ii < G_N_ELEMENTS (table->priv->headers); ii++) {
885 gint row = ii;
886
887 if (ii > E_COMPOSER_HEADER_FROM)
888 row++;
889
890 gtk_table_attach (
891 GTK_TABLE (object),
892 table->priv->headers[ii]->title_widget, 0, 1,
893 row, row + 1, GTK_FILL, GTK_FILL, 0, row_padding);
894 gtk_table_attach (
895 GTK_TABLE (object),
896 table->priv->headers[ii]->input_widget, 1, 4,
897 row, row + 1, GTK_FILL | GTK_EXPAND, 0, 0, row_padding);
898 }
899
900 ii = E_COMPOSER_HEADER_FROM;
901
902 /* Leave room in the "From" row for signature stuff. */
903 gtk_container_child_set (
904 GTK_CONTAINER (object),
905 table->priv->headers[ii]->input_widget,
906 "right-attach", 2, NULL);
907
908 e_binding_bind_property (
909 table->priv->headers[ii]->input_widget, "visible",
910 table->priv->signature_combo_box, "visible",
911 G_BINDING_SYNC_CREATE);
912
913 e_binding_bind_property (
914 table->priv->signature_combo_box, "visible",
915 table->priv->signature_label, "visible",
916 G_BINDING_SYNC_CREATE);
917
918 /* Now add the signature stuff. */
919 gtk_table_attach (
920 GTK_TABLE (object),
921 table->priv->signature_label,
922 2, 3, ii, ii + 1, 0, 0, 0, row_padding);
923 gtk_table_attach (
924 GTK_TABLE (object),
925 table->priv->signature_combo_box,
926 3, 4, ii, ii + 1, 0, 0, 0, row_padding);
927
928 from_header = E_COMPOSER_FROM_HEADER (e_composer_header_table_get_header (table, E_COMPOSER_HEADER_FROM));
929
930 gtk_table_attach (
931 GTK_TABLE (object),
932 from_header->override_widget, 1, 2,
933 ii + 1, ii + 2, GTK_FILL, GTK_FILL, 0, row_padding);
934
935 /* Initialize the headers. */
936 composer_header_table_from_changed_cb (table);
937
938 g_object_unref (client_cache);
939 g_object_unref (registry);
940 }
941
942 static void
e_composer_header_table_class_init(EComposerHeaderTableClass * class)943 e_composer_header_table_class_init (EComposerHeaderTableClass *class)
944 {
945 GObjectClass *object_class;
946
947 g_type_class_add_private (class, sizeof (EComposerHeaderTablePrivate));
948
949 object_class = G_OBJECT_CLASS (class);
950 object_class->set_property = composer_header_table_set_property;
951 object_class->get_property = composer_header_table_get_property;
952 object_class->dispose = composer_header_table_dispose;
953 object_class->constructed = composer_header_table_constructed;
954
955 /**
956 * EComposerHeaderTable:client-cache:
957 *
958 * Cache of shared #EClient instances.
959 **/
960 g_object_class_install_property (
961 object_class,
962 PROP_CLIENT_CACHE,
963 g_param_spec_object (
964 "client-cache",
965 "Client Cache",
966 "Cache of shared EClient instances",
967 E_TYPE_CLIENT_CACHE,
968 G_PARAM_READWRITE |
969 G_PARAM_CONSTRUCT_ONLY |
970 G_PARAM_STATIC_STRINGS));
971
972 g_object_class_install_property (
973 object_class,
974 PROP_DESTINATIONS_BCC,
975 g_param_spec_boxed (
976 "destinations-bcc",
977 NULL,
978 NULL,
979 G_TYPE_PTR_ARRAY,
980 G_PARAM_READWRITE |
981 G_PARAM_STATIC_STRINGS));
982
983 g_object_class_install_property (
984 object_class,
985 PROP_DESTINATIONS_CC,
986 g_param_spec_boxed (
987 "destinations-cc",
988 NULL,
989 NULL,
990 G_TYPE_PTR_ARRAY,
991 G_PARAM_READWRITE |
992 G_PARAM_STATIC_STRINGS));
993
994 g_object_class_install_property (
995 object_class,
996 PROP_DESTINATIONS_TO,
997 g_param_spec_boxed (
998 "destinations-to",
999 NULL,
1000 NULL,
1001 G_TYPE_PTR_ARRAY,
1002 G_PARAM_READWRITE |
1003 G_PARAM_STATIC_STRINGS));
1004
1005 g_object_class_install_property (
1006 object_class,
1007 PROP_IDENTITY_UID,
1008 g_param_spec_string (
1009 "identity-uid",
1010 NULL,
1011 NULL,
1012 NULL,
1013 G_PARAM_READWRITE |
1014 G_PARAM_STATIC_STRINGS));
1015
1016 g_object_class_install_property (
1017 object_class,
1018 PROP_POST_TO,
1019 g_param_spec_boxed (
1020 "post-to",
1021 NULL,
1022 NULL,
1023 G_TYPE_PTR_ARRAY,
1024 G_PARAM_READWRITE |
1025 G_PARAM_STATIC_STRINGS));
1026
1027 g_object_class_install_property (
1028 object_class,
1029 PROP_REPLY_TO,
1030 g_param_spec_string (
1031 "reply-to",
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_SIGNATURE_COMBO_BOX,
1041 g_param_spec_string (
1042 "signature-combo-box",
1043 NULL,
1044 NULL,
1045 NULL,
1046 G_PARAM_READABLE |
1047 G_PARAM_STATIC_STRINGS));
1048
1049 g_object_class_install_property (
1050 object_class,
1051 PROP_SIGNATURE_UID,
1052 g_param_spec_string (
1053 "signature-uid",
1054 NULL,
1055 NULL,
1056 NULL,
1057 G_PARAM_READWRITE |
1058 G_PARAM_STATIC_STRINGS));
1059
1060 g_object_class_install_property (
1061 object_class,
1062 PROP_SUBJECT,
1063 g_param_spec_string (
1064 "subject",
1065 NULL,
1066 NULL,
1067 NULL,
1068 G_PARAM_READWRITE |
1069 G_PARAM_STATIC_STRINGS));
1070 }
1071
1072 static void
composer_header_table_realize_cb(EComposerHeaderTable * table)1073 composer_header_table_realize_cb (EComposerHeaderTable *table)
1074 {
1075 g_return_if_fail (table != NULL);
1076 g_return_if_fail (table->priv != NULL);
1077
1078 g_signal_handlers_disconnect_by_func (
1079 table, composer_header_table_realize_cb, NULL);
1080
1081 e_name_selector_load_books (table->priv->name_selector);
1082 }
1083
1084 static void
e_composer_header_table_init(EComposerHeaderTable * table)1085 e_composer_header_table_init (EComposerHeaderTable *table)
1086 {
1087 gint rows;
1088
1089 table->priv = E_COMPOSER_HEADER_TABLE_GET_PRIVATE (table);
1090
1091 rows = G_N_ELEMENTS (table->priv->headers);
1092 gtk_table_resize (GTK_TABLE (table), rows, 4);
1093 gtk_table_set_row_spacings (GTK_TABLE (table), 0);
1094 gtk_table_set_col_spacings (GTK_TABLE (table), 6);
1095
1096 /* postpone name_selector loading, do that only when really needed */
1097 g_signal_connect (
1098 table, "realize",
1099 G_CALLBACK (composer_header_table_realize_cb), NULL);
1100 }
1101
1102 GtkWidget *
e_composer_header_table_new(EClientCache * client_cache)1103 e_composer_header_table_new (EClientCache *client_cache)
1104 {
1105 g_return_val_if_fail (E_IS_CLIENT_CACHE (client_cache), NULL);
1106
1107 return g_object_new (
1108 E_TYPE_COMPOSER_HEADER_TABLE,
1109 "client-cache", client_cache, NULL);
1110 }
1111
1112 EClientCache *
e_composer_header_table_ref_client_cache(EComposerHeaderTable * table)1113 e_composer_header_table_ref_client_cache (EComposerHeaderTable *table)
1114 {
1115 g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL);
1116
1117 return g_object_ref (table->priv->client_cache);
1118 }
1119
1120 EComposerHeader *
e_composer_header_table_get_header(EComposerHeaderTable * table,EComposerHeaderType type)1121 e_composer_header_table_get_header (EComposerHeaderTable *table,
1122 EComposerHeaderType type)
1123 {
1124 g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL);
1125 g_return_val_if_fail (type < E_COMPOSER_NUM_HEADERS, NULL);
1126
1127 return table->priv->headers[type];
1128 }
1129
1130 EMailSignatureComboBox *
e_composer_header_table_get_signature_combo_box(EComposerHeaderTable * table)1131 e_composer_header_table_get_signature_combo_box (EComposerHeaderTable *table)
1132 {
1133 g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL);
1134
1135 return E_MAIL_SIGNATURE_COMBO_BOX (table->priv->signature_combo_box);
1136 }
1137
1138 EDestination **
e_composer_header_table_get_destinations(EComposerHeaderTable * table)1139 e_composer_header_table_get_destinations (EComposerHeaderTable *table)
1140 {
1141 EDestination **destinations;
1142 EDestination **to, **cc, **bcc;
1143 gint total, n_to, n_cc, n_bcc;
1144
1145 g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL);
1146
1147 to = e_composer_header_table_get_destinations_to (table);
1148 for (n_to = 0; to != NULL && to[n_to] != NULL; n_to++);
1149
1150 cc = e_composer_header_table_get_destinations_cc (table);
1151 for (n_cc = 0; cc != NULL && cc[n_cc] != NULL; n_cc++);
1152
1153 bcc = e_composer_header_table_get_destinations_bcc (table);
1154 for (n_bcc = 0; bcc != NULL && bcc[n_bcc] != NULL; n_bcc++);
1155
1156 total = n_to + n_cc + n_bcc;
1157 destinations = g_new0 (EDestination *, total + 1);
1158
1159 while (n_bcc > 0 && total > 0)
1160 destinations[--total] = g_object_ref (bcc[--n_bcc]);
1161
1162 while (n_cc > 0 && total > 0)
1163 destinations[--total] = g_object_ref (cc[--n_cc]);
1164
1165 while (n_to > 0 && total > 0)
1166 destinations[--total] = g_object_ref (to[--n_to]);
1167
1168 /* Counters should all be zero now. */
1169 g_return_val_if_fail (total == 0 && n_to == 0 && n_cc == 0 && n_bcc == 0, destinations);
1170
1171 e_destination_freev (to);
1172 e_destination_freev (cc);
1173 e_destination_freev (bcc);
1174
1175 return destinations;
1176 }
1177
1178 EDestination **
e_composer_header_table_get_destinations_bcc(EComposerHeaderTable * table)1179 e_composer_header_table_get_destinations_bcc (EComposerHeaderTable *table)
1180 {
1181 EComposerHeader *header;
1182 EComposerHeaderType type;
1183 EComposerNameHeader *name_header;
1184
1185 g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL);
1186
1187 type = E_COMPOSER_HEADER_BCC;
1188 header = e_composer_header_table_get_header (table, type);
1189 name_header = E_COMPOSER_NAME_HEADER (header);
1190
1191 return e_composer_name_header_get_destinations (name_header);
1192 }
1193
1194 void
e_composer_header_table_add_destinations_bcc(EComposerHeaderTable * table,EDestination ** destinations)1195 e_composer_header_table_add_destinations_bcc (EComposerHeaderTable *table,
1196 EDestination **destinations)
1197 {
1198 EComposerHeader *header;
1199 EComposerHeaderType type;
1200 EComposerNameHeader *name_header;
1201
1202 g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (table));
1203
1204 type = E_COMPOSER_HEADER_BCC;
1205 header = e_composer_header_table_get_header (table, type);
1206 name_header = E_COMPOSER_NAME_HEADER (header);
1207
1208 e_composer_name_header_add_destinations (name_header, destinations);
1209
1210 if (destinations != NULL && *destinations != NULL)
1211 e_composer_header_set_visible (header, TRUE);
1212 }
1213
1214 void
e_composer_header_table_set_destinations_bcc(EComposerHeaderTable * table,EDestination ** destinations)1215 e_composer_header_table_set_destinations_bcc (EComposerHeaderTable *table,
1216 EDestination **destinations)
1217 {
1218 EComposerHeader *header;
1219 EComposerHeaderType type;
1220 EComposerNameHeader *name_header;
1221
1222 g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (table));
1223
1224 type = E_COMPOSER_HEADER_BCC;
1225 header = e_composer_header_table_get_header (table, type);
1226 name_header = E_COMPOSER_NAME_HEADER (header);
1227
1228 e_composer_name_header_set_destinations (name_header, destinations);
1229
1230 if (destinations != NULL && *destinations != NULL)
1231 e_composer_header_set_visible (header, TRUE);
1232 }
1233
1234 EDestination **
e_composer_header_table_get_destinations_cc(EComposerHeaderTable * table)1235 e_composer_header_table_get_destinations_cc (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_CC;
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
e_composer_header_table_add_destinations_cc(EComposerHeaderTable * table,EDestination ** destinations)1251 e_composer_header_table_add_destinations_cc (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_CC;
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
e_composer_header_table_set_destinations_cc(EComposerHeaderTable * table,EDestination ** destinations)1271 e_composer_header_table_set_destinations_cc (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_CC;
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 **
e_composer_header_table_get_destinations_to(EComposerHeaderTable * table)1291 e_composer_header_table_get_destinations_to (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_TO;
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
e_composer_header_table_add_destinations_to(EComposerHeaderTable * table,EDestination ** destinations)1307 e_composer_header_table_add_destinations_to (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_TO;
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
1323 void
e_composer_header_table_set_destinations_to(EComposerHeaderTable * table,EDestination ** destinations)1324 e_composer_header_table_set_destinations_to (EComposerHeaderTable *table,
1325 EDestination **destinations)
1326 {
1327 EComposerHeader *header;
1328 EComposerHeaderType type;
1329 EComposerNameHeader *name_header;
1330
1331 g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (table));
1332
1333 type = E_COMPOSER_HEADER_TO;
1334 header = e_composer_header_table_get_header (table, type);
1335 name_header = E_COMPOSER_NAME_HEADER (header);
1336
1337 e_composer_name_header_set_destinations (name_header, destinations);
1338 }
1339
1340 gchar *
e_composer_header_table_dup_identity_uid(EComposerHeaderTable * table,gchar ** chosen_alias_name,gchar ** chosen_alias_address)1341 e_composer_header_table_dup_identity_uid (EComposerHeaderTable *table,
1342 gchar **chosen_alias_name,
1343 gchar **chosen_alias_address)
1344 {
1345 EComposerHeader *header;
1346 EComposerHeaderType type;
1347 EComposerFromHeader *from_header;
1348
1349 g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL);
1350
1351 type = E_COMPOSER_HEADER_FROM;
1352 header = e_composer_header_table_get_header (table, type);
1353 from_header = E_COMPOSER_FROM_HEADER (header);
1354
1355 return e_composer_from_header_dup_active_id (from_header, chosen_alias_name, chosen_alias_address);
1356 }
1357
1358 void
e_composer_header_table_set_identity_uid(EComposerHeaderTable * table,const gchar * identity_uid,const gchar * alias_name,const gchar * alias_address)1359 e_composer_header_table_set_identity_uid (EComposerHeaderTable *table,
1360 const gchar *identity_uid,
1361 const gchar *alias_name,
1362 const gchar *alias_address)
1363 {
1364 EComposerHeader *header;
1365 EComposerHeaderType type;
1366 EComposerFromHeader *from_header;
1367
1368 g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (table));
1369
1370 type = E_COMPOSER_HEADER_FROM;
1371 header = e_composer_header_table_get_header (table, type);
1372 from_header = E_COMPOSER_FROM_HEADER (header);
1373
1374 e_composer_from_header_set_active_id (from_header, identity_uid, alias_name, alias_address);
1375 }
1376
1377 const gchar *
e_composer_header_table_get_from_name(EComposerHeaderTable * table)1378 e_composer_header_table_get_from_name (EComposerHeaderTable *table)
1379 {
1380 EComposerHeader *header;
1381 EComposerHeaderType type;
1382 EComposerFromHeader *from_header;
1383
1384 g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL);
1385
1386 type = E_COMPOSER_HEADER_FROM;
1387 header = e_composer_header_table_get_header (table, type);
1388 from_header = E_COMPOSER_FROM_HEADER (header);
1389
1390 return e_composer_from_header_get_name (from_header);
1391 }
1392
1393 const gchar *
e_composer_header_table_get_from_address(EComposerHeaderTable * table)1394 e_composer_header_table_get_from_address (EComposerHeaderTable *table)
1395 {
1396 EComposerHeader *header;
1397 EComposerHeaderType type;
1398 EComposerFromHeader *from_header;
1399
1400 g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL);
1401
1402 type = E_COMPOSER_HEADER_FROM;
1403 header = e_composer_header_table_get_header (table, type);
1404 from_header = E_COMPOSER_FROM_HEADER (header);
1405
1406 return e_composer_from_header_get_address (from_header);
1407 }
1408
1409 GList *
e_composer_header_table_get_post_to(EComposerHeaderTable * table)1410 e_composer_header_table_get_post_to (EComposerHeaderTable *table)
1411 {
1412 EComposerHeader *header;
1413 EComposerHeaderType type;
1414 EComposerPostHeader *post_header;
1415
1416 g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL);
1417
1418 type = E_COMPOSER_HEADER_POST_TO;
1419 header = e_composer_header_table_get_header (table, type);
1420 post_header = E_COMPOSER_POST_HEADER (header);
1421
1422 return e_composer_post_header_get_folders (post_header);
1423 }
1424
1425 void
e_composer_header_table_set_post_to_base(EComposerHeaderTable * table,const gchar * base_url,const gchar * folders)1426 e_composer_header_table_set_post_to_base (EComposerHeaderTable *table,
1427 const gchar *base_url,
1428 const gchar *folders)
1429 {
1430 EComposerHeader *header;
1431 EComposerHeaderType type;
1432 EComposerPostHeader *post_header;
1433
1434 g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (table));
1435
1436 type = E_COMPOSER_HEADER_POST_TO;
1437 header = e_composer_header_table_get_header (table, type);
1438 post_header = E_COMPOSER_POST_HEADER (header);
1439
1440 e_composer_post_header_set_folders_base (post_header, base_url, folders);
1441 }
1442
1443 void
e_composer_header_table_set_post_to_list(EComposerHeaderTable * table,GList * folders)1444 e_composer_header_table_set_post_to_list (EComposerHeaderTable *table,
1445 GList *folders)
1446 {
1447 EComposerHeader *header;
1448 EComposerHeaderType type;
1449 EComposerPostHeader *post_header;
1450
1451 g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (table));
1452
1453 type = E_COMPOSER_HEADER_POST_TO;
1454 header = e_composer_header_table_get_header (table, type);
1455 post_header = E_COMPOSER_POST_HEADER (header);
1456
1457 e_composer_post_header_set_folders (post_header, folders);
1458 }
1459
1460 const gchar *
e_composer_header_table_get_reply_to(EComposerHeaderTable * table)1461 e_composer_header_table_get_reply_to (EComposerHeaderTable *table)
1462 {
1463 EComposerHeader *header;
1464 EComposerHeaderType type;
1465 EComposerTextHeader *text_header;
1466
1467 g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL);
1468
1469 type = E_COMPOSER_HEADER_REPLY_TO;
1470 header = e_composer_header_table_get_header (table, type);
1471 text_header = E_COMPOSER_TEXT_HEADER (header);
1472
1473 return e_composer_text_header_get_text (text_header);
1474 }
1475
1476 void
e_composer_header_table_set_reply_to(EComposerHeaderTable * table,const gchar * reply_to)1477 e_composer_header_table_set_reply_to (EComposerHeaderTable *table,
1478 const gchar *reply_to)
1479 {
1480 EComposerHeader *header;
1481 EComposerHeaderType type;
1482 EComposerTextHeader *text_header;
1483
1484 g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (table));
1485
1486 type = E_COMPOSER_HEADER_REPLY_TO;
1487 header = e_composer_header_table_get_header (table, type);
1488 text_header = E_COMPOSER_TEXT_HEADER (header);
1489
1490 e_composer_text_header_set_text (text_header, reply_to);
1491
1492 if (reply_to != NULL && *reply_to != '\0')
1493 e_composer_header_set_visible (header, TRUE);
1494 }
1495
1496 const gchar *
e_composer_header_table_get_signature_uid(EComposerHeaderTable * table)1497 e_composer_header_table_get_signature_uid (EComposerHeaderTable *table)
1498 {
1499 EMailSignatureComboBox *combo_box;
1500
1501 g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL);
1502
1503 combo_box = e_composer_header_table_get_signature_combo_box (table);
1504
1505 return gtk_combo_box_get_active_id (GTK_COMBO_BOX (combo_box));
1506 }
1507
1508 void
e_composer_header_table_set_signature_uid(EComposerHeaderTable * table,const gchar * signature_uid)1509 e_composer_header_table_set_signature_uid (EComposerHeaderTable *table,
1510 const gchar *signature_uid)
1511 {
1512 EMailSignatureComboBox *combo_box;
1513
1514 g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (table));
1515
1516 combo_box = e_composer_header_table_get_signature_combo_box (table);
1517
1518 gtk_combo_box_set_active_id (GTK_COMBO_BOX (combo_box), signature_uid);
1519 }
1520
1521 const gchar *
e_composer_header_table_get_subject(EComposerHeaderTable * table)1522 e_composer_header_table_get_subject (EComposerHeaderTable *table)
1523 {
1524 EComposerHeader *header;
1525 EComposerHeaderType type;
1526 EComposerTextHeader *text_header;
1527
1528 g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL);
1529
1530 type = E_COMPOSER_HEADER_SUBJECT;
1531 header = e_composer_header_table_get_header (table, type);
1532 text_header = E_COMPOSER_TEXT_HEADER (header);
1533
1534 return e_composer_text_header_get_text (text_header);
1535 }
1536
1537 void
e_composer_header_table_set_subject(EComposerHeaderTable * table,const gchar * subject)1538 e_composer_header_table_set_subject (EComposerHeaderTable *table,
1539 const gchar *subject)
1540 {
1541 EComposerHeader *header;
1542 EComposerHeaderType type;
1543 EComposerTextHeader *text_header;
1544
1545 g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (table));
1546
1547 type = E_COMPOSER_HEADER_SUBJECT;
1548 header = e_composer_header_table_get_header (table, type);
1549 text_header = E_COMPOSER_TEXT_HEADER (header);
1550
1551 e_composer_text_header_set_text (text_header, subject);
1552 }
1553
1554 void
e_composer_header_table_set_header_visible(EComposerHeaderTable * table,EComposerHeaderType type,gboolean visible)1555 e_composer_header_table_set_header_visible (EComposerHeaderTable *table,
1556 EComposerHeaderType type,
1557 gboolean visible)
1558 {
1559 EComposerHeader *header;
1560
1561 header = e_composer_header_table_get_header (table, type);
1562 e_composer_header_set_visible (header, visible);
1563
1564 /* Signature widgets track the "From" header. */
1565 if (type == E_COMPOSER_HEADER_FROM) {
1566 if (visible) {
1567 gtk_widget_show (table->priv->signature_label);
1568 gtk_widget_show (table->priv->signature_combo_box);
1569 } else {
1570 gtk_widget_hide (table->priv->signature_label);
1571 gtk_widget_hide (table->priv->signature_combo_box);
1572 }
1573 }
1574 }
1575
1576 /**
1577 * e_composer_header_table_ref_source:
1578 * @table: an #EComposerHeaderTable
1579 * @uid: a unique identifier string
1580 *
1581 * Convenience function that works just like e_source_registry_ref_source(),
1582 * but spares the caller from digging out the #ESourceRegistry from @table.
1583 *
1584 * The returned #ESource is referenced for thread-safety and must be
1585 * unreferenced with g_object_unref() when finished with it.
1586 *
1587 * Returns: an #ESource, or %NULL if no match was found
1588 **/
1589 ESource *
e_composer_header_table_ref_source(EComposerHeaderTable * table,const gchar * uid)1590 e_composer_header_table_ref_source (EComposerHeaderTable *table,
1591 const gchar *uid)
1592 {
1593 EClientCache *client_cache;
1594 ESourceRegistry *registry;
1595 ESource *source;
1596
1597 g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL);
1598 g_return_val_if_fail (uid != NULL, NULL);
1599
1600 client_cache = e_composer_header_table_ref_client_cache (table);
1601 registry = e_client_cache_ref_registry (client_cache);
1602
1603 source = e_source_registry_ref_source (registry, uid);
1604
1605 g_object_unref (client_cache);
1606 g_object_unref (registry);
1607
1608 return source;
1609 }
1610
1611