1
/* libtinymail-camel - The Tiny Mail base library for Camel
2
* Copyright (C) 2006-2007 Philip Van Hoof <pvanhoof@gnome.org>
4
* This library is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU Lesser General Public
6
* License as published by the Free Software Foundation; either
7
* version 2 of the License, or (at your option) any later version.
9
* This library is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
* Lesser General Public License for more details.
14
* You should have received a copy of the GNU Lesser General Public
15
* License along with self library; if not, write to the
16
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17
* Boston, MA 02111-1307, USA.
22
#include <glib/gi18n-lib.h>
27
#include <tny-header.h>
28
#include <tny-camel-header.h>
29
#include <tny-camel-folder.h>
31
#include "tny-camel-common-priv.h"
32
#include "tny-camel-folder-priv.h"
33
#include "tny-camel-msg-header-priv.h"
35
#include <tny-camel-shared.h>
37
#include <camel/camel-folder.h>
38
#include <camel/camel.h>
39
#include <camel/camel-folder-summary.h>
40
#include <camel/camel-stream-null.h>
42
static GObjectClass *parent_class = NULL;
46
tny_camel_msg_header_get_replyto (TnyHeader *self)
48
TnyCamelMsgHeader *me = TNY_CAMEL_MSG_HEADER (self);
49
const gchar *retval = NULL;
51
CamelInternetAddress *addr = (CamelInternetAddress*)
52
camel_mime_message_get_reply_to (me->msg);
54
retval = camel_address_format (CAMEL_ADDRESS (addr));
61
tny_camel_msg_header_set_bcc (TnyHeader *self, const gchar *bcc)
63
TnyCamelMsgHeader *me;
64
CamelInternetAddress *addr;
66
me = TNY_CAMEL_MSG_HEADER (self);
67
addr = camel_internet_address_new ();
69
_foreach_email_add_to_inet_addr (bcc, addr);
71
camel_mime_message_set_recipients (me->msg,
72
CAMEL_RECIPIENT_TYPE_BCC, addr);
74
camel_object_unref (CAMEL_OBJECT (addr));
80
tny_camel_msg_header_set_cc (TnyHeader *self, const gchar *cc)
82
TnyCamelMsgHeader *me = TNY_CAMEL_MSG_HEADER (self);
83
CamelInternetAddress *addr = camel_internet_address_new ();
85
_foreach_email_add_to_inet_addr (cc, addr);
87
camel_mime_message_set_recipients (me->msg,
88
CAMEL_RECIPIENT_TYPE_CC, addr);
90
camel_object_unref (CAMEL_OBJECT (addr));
96
tny_camel_msg_header_set_from (TnyHeader *self, const gchar *from)
98
TnyCamelMsgHeader *me = TNY_CAMEL_MSG_HEADER (self);
99
CamelInternetAddress *addr = camel_internet_address_new ();
102
dup = g_strdup (from);
103
_string_to_camel_inet_addr (dup, addr);
106
camel_mime_message_set_from (me->msg, addr);
107
camel_object_unref (CAMEL_OBJECT (addr));
113
tny_camel_msg_header_set_subject (TnyHeader *self, const gchar *subject)
115
TnyCamelMsgHeader *me = TNY_CAMEL_MSG_HEADER (self);
117
camel_mime_message_set_subject (me->msg, subject);
123
tny_camel_msg_header_set_to (TnyHeader *self, const gchar *to)
125
TnyCamelMsgHeader *me = TNY_CAMEL_MSG_HEADER (self);
126
CamelInternetAddress *addr = camel_internet_address_new ();
130
_foreach_email_add_to_inet_addr (dup, addr);
133
camel_mime_message_set_recipients (me->msg,
134
CAMEL_RECIPIENT_TYPE_TO, addr);
136
camel_object_unref (CAMEL_OBJECT (addr));
143
tny_camel_msg_header_set_replyto (TnyHeader *self, const gchar *replyto)
145
TnyCamelMsgHeader *me = TNY_CAMEL_MSG_HEADER (self);
146
CamelInternetAddress *addr = camel_internet_address_new ();
149
dup = g_strdup (replyto);
150
_foreach_email_add_to_inet_addr (dup, addr);
153
camel_mime_message_set_reply_to (me->msg, addr);
155
camel_object_unref (CAMEL_OBJECT (addr));
162
tny_camel_msg_header_get_cc (TnyHeader *self)
164
TnyCamelMsgHeader *me = TNY_CAMEL_MSG_HEADER (self);
165
const gchar *retval = NULL;
167
retval = camel_medium_get_header (CAMEL_MEDIUM (me->msg), "cc");
173
tny_camel_msg_header_get_bcc (TnyHeader *self)
175
TnyCamelMsgHeader *me = TNY_CAMEL_MSG_HEADER (self);
176
const gchar *retval = NULL;
178
retval = camel_medium_get_header (CAMEL_MEDIUM (me->msg), "bcc");
183
static TnyHeaderFlags
184
tny_camel_msg_header_get_flags (TnyHeader *self)
187
TnyCamelMsgHeader *me = TNY_CAMEL_MSG_HEADER (self);
188
const gchar *priority_string = NULL;
189
const gchar *attachments_string = NULL;
190
TnyHeaderFlags result = 0;
191
TnyHeaderFlags decorated_flags;
193
result |= TNY_HEADER_FLAG_CACHED;
195
priority_string = camel_medium_get_header (CAMEL_MEDIUM (me->msg), "X-Priority");
196
attachments_string = camel_medium_get_header (CAMEL_MEDIUM (me->msg), "X-MS-Has-Attach");
197
if (priority_string != NULL) {
198
if (g_strrstr (priority_string, "1") != NULL)
199
result |= TNY_HEADER_FLAG_HIGH_PRIORITY;
200
else if (g_strrstr (priority_string, "3") != NULL)
201
result |= TNY_HEADER_FLAG_LOW_PRIORITY;
203
result |= TNY_HEADER_FLAG_NORMAL_PRIORITY;
206
if (attachments_string != NULL)
207
result |= TNY_HEADER_FLAG_ATTACHMENTS;
210
result |= TNY_HEADER_FLAG_PARTIAL;
213
decorated_flags = tny_header_get_flags (me->decorated);
214
result |= decorated_flags;
221
tny_camel_msg_header_set_flags (TnyHeader *self, TnyHeaderFlags mask)
223
TnyHeaderPriorityFlags priority_flags;
224
TnyCamelMsgHeader *me = TNY_CAMEL_MSG_HEADER (self);
227
tny_header_set_flags (me->decorated, mask);
230
if (mask & TNY_HEADER_FLAG_CACHED || mask & TNY_HEADER_FLAG_PARTIAL) {
231
if (mask & TNY_HEADER_FLAG_PARTIAL)
237
priority_flags = mask & TNY_HEADER_FLAG_PRIORITY;
239
camel_medium_remove_header (CAMEL_MEDIUM (me->msg), "X-MSMail-Priority");
240
camel_medium_remove_header (CAMEL_MEDIUM (me->msg), "X-Priority");
242
switch (priority_flags) {
243
case TNY_HEADER_FLAG_SUSPENDED_PRIORITY:
244
camel_medium_add_header (CAMEL_MEDIUM (me->msg), "X-MSMail-Priority", "Suspended");
245
camel_medium_add_header (CAMEL_MEDIUM (me->msg), "X-Priority", "-1");
248
case TNY_HEADER_FLAG_HIGH_PRIORITY:
249
camel_medium_add_header (CAMEL_MEDIUM (me->msg), "X-MSMail-Priority", "High");
250
camel_medium_add_header (CAMEL_MEDIUM (me->msg), "X-Priority", "1");
252
case TNY_HEADER_FLAG_LOW_PRIORITY:
253
camel_medium_add_header (CAMEL_MEDIUM (me->msg), "X-MSMail-Priority", "Low");
254
camel_medium_add_header (CAMEL_MEDIUM (me->msg), "X-Priority", "5");
256
case TNY_HEADER_FLAG_NORMAL_PRIORITY:
257
camel_medium_add_header (CAMEL_MEDIUM (me->msg), "X-MSMail-Priority", "Normal");
258
camel_medium_add_header (CAMEL_MEDIUM (me->msg), "X-Priority", "3");
262
if (mask & TNY_HEADER_FLAG_ATTACHMENTS) {
263
camel_medium_remove_header (CAMEL_MEDIUM (me->msg), "X-MS-Has-Attach");
264
camel_medium_add_header (CAMEL_MEDIUM (me->msg), "X-MS-Has-Attach", "Yes");
271
tny_camel_msg_header_unset_flags (TnyHeader *self, TnyHeaderFlags mask)
273
TnyHeaderPriorityFlags priority_flags;
274
TnyCamelMsgHeader *me = TNY_CAMEL_MSG_HEADER (self);
277
tny_header_set_flags (me->decorated, mask);
280
priority_flags = mask & TNY_HEADER_FLAG_PRIORITY;
282
if (priority_flags) {
283
camel_medium_remove_header (CAMEL_MEDIUM (me->msg), "X-MSMail-Priority");
284
camel_medium_remove_header (CAMEL_MEDIUM (me->msg), "X-Priority");
287
if (mask & TNY_HEADER_FLAG_ATTACHMENTS)
288
camel_medium_remove_header (CAMEL_MEDIUM (me->msg), "X-MS-Has-Attach");
290
if (mask & TNY_HEADER_FLAG_PARTIAL)
297
tny_camel_msg_header_get_date_received (TnyHeader *self)
299
TnyCamelMsgHeader *me = TNY_CAMEL_MSG_HEADER (self);
303
if (me->has_received)
306
retval = camel_mime_message_get_date_received (me->msg, &tzone);
307
if (retval == CAMEL_MESSAGE_DATE_CURRENT)
308
retval = camel_mime_message_get_date (me->msg, &tzone);
310
/* return 0 if we really cannot find a date */
311
if (retval == CAMEL_MESSAGE_DATE_CURRENT)
318
tny_camel_msg_header_get_date_sent (TnyHeader *self)
320
TnyCamelMsgHeader *me = TNY_CAMEL_MSG_HEADER (self);
324
/* first try _date, if that doesn't work, use received instead
325
* however, that is set by the *receiver* so will not be totally
328
* NOTE: we ignore the timezone, as the camel function already
329
* returns a UTC-normalized time_t
331
retval = camel_mime_message_get_date (me->msg, &tzone);
333
if (retval == CAMEL_MESSAGE_DATE_CURRENT)
334
retval = camel_mime_message_get_date_received (me->msg, &tzone);
335
if (retval == CAMEL_MESSAGE_DATE_CURRENT)
342
tny_camel_msg_header_get_from (TnyHeader *self)
344
TnyCamelMsgHeader *me = TNY_CAMEL_MSG_HEADER (self);
345
const gchar *retval = NULL;
347
if (G_LIKELY (!me->mime_from))
349
CamelInternetAddress *addr = (CamelInternetAddress*)
350
camel_mime_message_get_from (me->msg);
352
me->mime_from = camel_address_format (CAMEL_ADDRESS (addr));
353
else me->mime_from = NULL;
356
retval = (const gchar*)me->mime_from;
362
tny_camel_msg_header_get_subject (TnyHeader *self)
364
TnyCamelMsgHeader *me = TNY_CAMEL_MSG_HEADER (self);
365
const gchar *retval = NULL;
367
retval = camel_mime_message_get_subject (me->msg);
374
tny_camel_msg_header_get_to (TnyHeader *self)
376
TnyCamelMsgHeader *me = TNY_CAMEL_MSG_HEADER (self);
377
const gchar *retval = NULL;
379
retval = camel_medium_get_header (CAMEL_MEDIUM (me->msg), "to");
385
tny_camel_msg_header_get_message_id (TnyHeader *self)
387
TnyCamelMsgHeader *me = TNY_CAMEL_MSG_HEADER (self);
388
const gchar *retval = NULL;
390
retval = camel_mime_message_get_message_id (me->msg);
398
tny_camel_msg_header_get_message_size (TnyHeader *self)
400
TnyCamelMsgHeader *me = TNY_CAMEL_MSG_HEADER (self);
402
CamelStreamNull *sn = (CamelStreamNull *)camel_stream_null_new();
404
camel_data_wrapper_write_to_stream((CamelDataWrapper *)me->msg, (CamelStream *)sn);
406
retval = (guint) sn->written;
407
camel_object_unref((CamelObject *)sn);
413
tny_camel_msg_header_get_uid (TnyHeader *self)
415
TnyCamelMsgHeader *me = TNY_CAMEL_MSG_HEADER (self);
419
g_warning ("tny_header_get_uid: This is a header instance for a new message. "
420
"The uid of it is therefore not available. This indicates a problem "
428
tny_camel_msg_header_finalize (GObject *object)
430
TnyCamelMsgHeader *me = (TnyCamelMsgHeader *) object;
433
g_free (me->old_uid);
436
g_object_unref (me->decorated);
437
me->decorated = NULL;
441
(*parent_class->finalize) (object);
447
tny_camel_msg_header_get_folder (TnyHeader *self)
449
TnyCamelMsgHeader *me = TNY_CAMEL_MSG_HEADER (self);
452
g_object_ref (G_OBJECT (me->folder));
454
return (TnyFolder*) me->folder;
458
_tny_camel_msg_header_new (CamelMimeMessage *msg, TnyFolder *folder, time_t received)
460
TnyCamelMsgHeader *self = g_object_new (TNY_TYPE_CAMEL_MSG_HEADER, NULL);
462
/* For this implementation of TnyHeader: self dies when the TnyMsg dies who
463
owns this msg. If this ever changes then we need to add a reference here,
464
and remove it in the finalize. Same for folder. */
467
self->has_received = FALSE;
468
self->received = received;
469
self->old_uid = NULL;
471
self->folder = folder;
472
self->has_received = FALSE;
473
self->partial = FALSE;
474
self->decorated = NULL;
476
return (TnyHeader*) self;
480
_tny_camel_msg_header_set_decorated (TnyCamelMsgHeader *header,
481
TnyHeader *decorated)
483
g_assert (TNY_IS_HEADER (decorated));
484
if (header->decorated) {
485
g_object_unref (header->decorated);
488
header->decorated = TNY_HEADER (g_object_ref (decorated));
494
tny_header_init (gpointer g, gpointer iface_data)
496
TnyHeaderIface *klass = (TnyHeaderIface *)g;
498
klass->get_from_func = tny_camel_msg_header_get_from;
499
klass->get_message_id_func = tny_camel_msg_header_get_message_id;
500
klass->get_message_size_func = tny_camel_msg_header_get_message_size;
501
klass->get_to_func = tny_camel_msg_header_get_to;
502
klass->get_subject_func = tny_camel_msg_header_get_subject;
503
klass->get_date_received_func = tny_camel_msg_header_get_date_received;
504
klass->get_date_sent_func = tny_camel_msg_header_get_date_sent;
505
klass->get_cc_func = tny_camel_msg_header_get_cc;
506
klass->get_bcc_func = tny_camel_msg_header_get_bcc;
507
klass->get_replyto_func = tny_camel_msg_header_get_replyto;
508
klass->get_uid_func = tny_camel_msg_header_get_uid;
509
klass->get_folder_func = tny_camel_msg_header_get_folder;
510
klass->set_bcc_func = tny_camel_msg_header_set_bcc;
511
klass->set_cc_func = tny_camel_msg_header_set_cc;
512
klass->set_to_func = tny_camel_msg_header_set_to;
513
klass->set_from_func = tny_camel_msg_header_set_from;
514
klass->set_subject_func = tny_camel_msg_header_set_subject;
515
klass->set_replyto_func = tny_camel_msg_header_set_replyto;
516
klass->set_flags_func = tny_camel_msg_header_set_flags;
517
klass->unset_flags_func = tny_camel_msg_header_unset_flags;
518
klass->get_flags_func = tny_camel_msg_header_get_flags;
525
tny_camel_msg_header_class_init (TnyCamelMsgHeaderClass *class)
527
GObjectClass *object_class;
529
parent_class = g_type_class_peek_parent (class);
530
object_class = (GObjectClass*) class;
532
object_class->finalize = tny_camel_msg_header_finalize;
539
* tny_camel_msg_header_get_type:
541
* GType system helper function
543
* Return value: a GType
546
tny_camel_msg_header_get_type (void)
548
static GType type = 0;
550
if (G_UNLIKELY (!_camel_type_init_done))
552
if (!g_thread_supported ())
553
g_thread_init (NULL);
556
_camel_type_init_done = TRUE;
559
if (G_UNLIKELY(type == 0))
561
static const GTypeInfo info =
563
sizeof (TnyCamelMsgHeaderClass),
564
NULL, /* base_init */
565
NULL, /* base_finalize */
566
(GClassInitFunc) tny_camel_msg_header_class_init, /* class_init */
567
NULL, /* class_finalize */
568
NULL, /* class_data */
569
sizeof (TnyCamelMsgHeader),
571
NULL, /* instance_init */
575
static const GInterfaceInfo tny_header_info =
577
(GInterfaceInitFunc) tny_header_init, /* interface_init */
578
NULL, /* interface_finalize */
579
NULL /* interface_data */
582
type = g_type_register_static (G_TYPE_OBJECT,
586
g_type_add_interface_static (type, TNY_TYPE_HEADER,