1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
5 * Authors: Michael Zucchi <notzed@ximian.com>
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of version 2 of the GNU Lesser General Public
9 * License as published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this program; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
22 #if !defined (__CAMEL_H_INSIDE__) && !defined (CAMEL_COMPILATION)
23 #error "Only <camel/camel.h> can be included directly."
26 #ifndef CAMEL_FOLDER_SUMMARY_H
27 #define CAMEL_FOLDER_SUMMARY_H
32 #include <camel/camel-index.h>
33 #include <camel/camel-memchunk.h>
34 #include <camel/camel-mime-message.h>
35 #include <camel/camel-mime-parser.h>
37 /* Standard GObject macros */
38 #define CAMEL_TYPE_FOLDER_SUMMARY \
39 (camel_folder_summary_get_type ())
40 #define CAMEL_FOLDER_SUMMARY(obj) \
41 (G_TYPE_CHECK_INSTANCE_CAST \
42 ((obj), CAMEL_TYPE_FOLDER_SUMMARY, CamelFolderSummary))
43 #define CAMEL_FOLDER_SUMMARY_CLASS(cls) \
44 (G_TYPE_CHECK_CLASS_CAST \
45 ((cls), CAMEL_TYPE_FOLDER_SUMMARY, CamelFolderSummaryClass))
46 #define CAMEL_IS_FOLDER_SUMMARY(obj) \
47 (G_TYPE_CHECK_INSTANCE_TYPE \
48 ((obj), CAMEL_TYPE_FOLDER_SUMMARY))
49 #define CAMEL_IS_FOLDER_SUMMARY_CLASS(cls) \
50 (G_TYPE_CHECK_CLASS_TYPE \
51 ((cls), CAMEL_TYPE_FOLDER_SUMMARY))
52 #define CAMEL_FOLDER_SUMMARY_GET_CLASS(obj) \
53 (G_TYPE_INSTANCE_GET_CLASS \
54 ((obj), CAMEL_TYPE_FOLDER_SUMMARY, CamelFolderSummaryClass))
61 typedef struct _CamelFolderSummary CamelFolderSummary;
62 typedef struct _CamelFolderSummaryClass CamelFolderSummaryClass;
63 typedef struct _CamelFolderSummaryPrivate CamelFolderSummaryPrivate;
65 typedef struct _CamelMessageInfo CamelMessageInfo;
66 typedef struct _CamelMessageInfoBase CamelMessageInfoBase;
68 typedef struct _CamelMessageContentInfo CamelMessageContentInfo;
70 /* A tree of message content info structures
71 * describe the content structure of the message (if it has any) */
72 struct _CamelMessageContentInfo {
73 CamelMessageContentInfo *next;
75 CamelMessageContentInfo *childs;
76 CamelMessageContentInfo *parent;
78 CamelContentType *type;
81 gchar *encoding; /* this should be an enum?? */
85 /* system flag bits */
86 typedef enum _CamelMessageFlags {
87 CAMEL_MESSAGE_ANSWERED = 1 << 0,
88 CAMEL_MESSAGE_DELETED = 1 << 1,
89 CAMEL_MESSAGE_DRAFT = 1 << 2,
90 CAMEL_MESSAGE_FLAGGED = 1 << 3,
91 CAMEL_MESSAGE_SEEN = 1 << 4,
93 /* these aren't really system flag bits, but are convenience flags */
94 CAMEL_MESSAGE_ATTACHMENTS = 1 << 5,
95 CAMEL_MESSAGE_ANSWERED_ALL = 1 << 6,
96 CAMEL_MESSAGE_JUNK = 1 << 7,
97 CAMEL_MESSAGE_SECURE = 1 << 8,
98 CAMEL_MESSAGE_USER_NOT_DELETABLE = 1 << 9,
99 CAMEL_MESSAGE_HIDDEN = 1 << 10,
100 CAMEL_MESSAGE_NOTJUNK = 1 << 11,
101 CAMEL_MESSAGE_FORWARDED = 1 << 12,
103 /* following flags are for the folder, and are not really permanent flags */
104 CAMEL_MESSAGE_FOLDER_FLAGGED = 1 << 16, /* for use by the folder implementation */
105 /* flags after 1 << 16 are used by camel providers,
106 * if adding non permanent flags, add them to the end */
108 CAMEL_MESSAGE_JUNK_LEARN = 1 << 30, /* used when setting CAMEL_MESSAGE_JUNK flag
109 * to say that we request junk plugin
110 * to learn that message as junk/non junk */
111 CAMEL_MESSAGE_USER = 1 << 31 /* supports user flags */
114 /* Changes to system flags will NOT trigger a folder changed event */
115 #define CAMEL_MESSAGE_SYSTEM_MASK (0xffff << 16)
117 typedef struct _CamelFlag {
118 struct _CamelFlag *next;
119 gchar name[1]; /* name allocated as part of the structure */
122 typedef struct _CamelTag {
123 struct _CamelTag *next;
125 gchar name[1]; /* name allocated as part of the structure */
128 /* a summary messageid is a 64 bit identifier (partial md5 hash) */
129 typedef struct _CamelSummaryMessageID {
138 } CamelSummaryMessageID;
140 /* summary references is a fixed size array of references */
141 typedef struct _CamelSummaryReferences {
143 CamelSummaryMessageID references[1];
144 } CamelSummaryReferences;
148 CAMEL_MESSAGE_INFO_SUBJECT,
149 CAMEL_MESSAGE_INFO_FROM,
150 CAMEL_MESSAGE_INFO_TO,
151 CAMEL_MESSAGE_INFO_CC,
152 CAMEL_MESSAGE_INFO_MLIST,
154 CAMEL_MESSAGE_INFO_FLAGS,
155 CAMEL_MESSAGE_INFO_SIZE,
157 CAMEL_MESSAGE_INFO_DATE_SENT,
158 CAMEL_MESSAGE_INFO_DATE_RECEIVED,
160 CAMEL_MESSAGE_INFO_MESSAGE_ID,
161 CAMEL_MESSAGE_INFO_REFERENCES,
162 CAMEL_MESSAGE_INFO_USER_FLAGS,
163 CAMEL_MESSAGE_INFO_USER_TAGS,
165 CAMEL_MESSAGE_INFO_HEADERS,
166 CAMEL_MESSAGE_INFO_PREVIEW,
167 CAMEL_MESSAGE_INFO_CONTENT,
168 CAMEL_MESSAGE_INFO_LAST
171 /* information about a given message, use accessors */
172 struct _CamelMessageInfo {
173 CamelFolderSummary *summary;
175 guint32 refcount; /* ??? */
177 /*FIXME: Make it work with the CAMEL_MESSADE_DB_DIRTY flag instead of another 4 bytes*/
181 /* For classes wishing to do the provided i/o, or for anonymous users,
182 * they must subclass or use this messageinfo structure */
183 /* Otherwise they can do their own thing entirely */
184 struct _CamelMessageInfoBase {
185 CamelFolderSummary *summary;
187 guint32 refcount; /* ??? */
189 /*FIXME: Make it work with the CAMEL_MESSADE_DB_DIRTY flag instead of another 4 bytes*/
192 const gchar *subject;
198 CamelMessageFlags flags;
202 time_t date_received;
204 CamelSummaryMessageID message_id;
205 CamelSummaryReferences *references;/* from parent to root */
207 struct _CamelFlag *user_flags;
208 struct _CamelTag *user_tags;
210 /* tree of content description - NULL if it is not available */
211 CamelMessageContentInfo *content;
212 struct _camel_header_param *headers;
214 gchar *bodystructure;
218 * CamelFolderSummaryFlags:
219 * @CAMEL_FOLDER_SUMMARY_DIRTY:
220 * There are changes in summary, which should be saved.
221 * @CAMEL_FOLDER_SUMMARY_IN_MEMORY_ONLY:
222 * Summary with this flag doesn't use DB for storing its content,
223 * it is always created on the fly.
226 CAMEL_FOLDER_SUMMARY_DIRTY = 1 << 0,
227 CAMEL_FOLDER_SUMMARY_IN_MEMORY_ONLY = 1 << 1
228 } CamelFolderSummaryFlags;
231 * CamelFolderSummaryLock:
235 typedef enum _CamelFolderSummaryLock {
236 CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK,
237 CAMEL_FOLDER_SUMMARY_IO_LOCK,
238 CAMEL_FOLDER_SUMMARY_FILTER_LOCK,
239 CAMEL_FOLDER_SUMMARY_ALLOC_LOCK,
240 CAMEL_FOLDER_SUMMARY_REF_LOCK
241 } CamelFolderSummaryLock;
243 struct _CamelFolderSummary {
245 CamelFolderSummaryPrivate *priv;
248 guint32 version; /* version of file loaded/loading */
249 time_t time; /* timestamp for this summary (for implementors to use) */
250 CamelFolderSummaryFlags flags;
252 const gchar *collate;
253 const gchar *sort_by;
255 /* Future ABI expansion */
259 struct _CamelMIRecord;
260 struct _CamelFIRecord;
262 struct _CamelFolderSummaryClass {
263 CamelObjectClass parent_class;
265 /* sizes of memory objects */
266 gsize message_info_size;
267 gsize content_info_size;
269 /* Load/Save folder summary from DB*/
270 gboolean (*summary_header_from_db)(CamelFolderSummary *, struct _CamelFIRecord *);
271 struct _CamelFIRecord * (*summary_header_to_db)(CamelFolderSummary *, GError **error);
272 CamelMessageInfo * (*message_info_from_db) (CamelFolderSummary *, struct _CamelMIRecord *);
273 struct _CamelMIRecord * (*message_info_to_db) (CamelFolderSummary *, CamelMessageInfo *);
274 CamelMessageContentInfo * (*content_info_from_db) (CamelFolderSummary *, struct _CamelMIRecord *);
275 gboolean (*content_info_to_db) (CamelFolderSummary *, CamelMessageContentInfo *, struct _CamelMIRecord *);
277 /* create/save/load an individual message info */
278 CamelMessageInfo * (*message_info_new_from_header)(CamelFolderSummary *, struct _camel_header_raw *);
279 CamelMessageInfo * (*message_info_new_from_parser)(CamelFolderSummary *, CamelMimeParser *);
280 CamelMessageInfo * (*message_info_new_from_message)(CamelFolderSummary *, CamelMimeMessage *, const gchar *);
281 void (*message_info_free)(CamelFolderSummary *, CamelMessageInfo *);
282 CamelMessageInfo * (*message_info_clone)(CamelFolderSummary *, const CamelMessageInfo *);
284 /* save/load individual content info's */
285 CamelMessageContentInfo * (*content_info_new_from_header)(CamelFolderSummary *, struct _camel_header_raw *);
286 CamelMessageContentInfo * (*content_info_new_from_parser)(CamelFolderSummary *, CamelMimeParser *);
287 CamelMessageContentInfo * (*content_info_new_from_message)(CamelFolderSummary *, CamelMimePart *);
288 void (*content_info_free)(CamelFolderSummary *, CamelMessageContentInfo *);
289 CamelMessageInfo * (*message_info_from_uid) (CamelFolderSummary *, const gchar *);
290 /* get the next uid */
291 gchar *(*next_uid_string)(CamelFolderSummary *);
293 /* virtual accessors on messageinfo's */
294 gconstpointer (*info_ptr)(const CamelMessageInfo *mi, gint id);
295 guint32 (*info_uint32)(const CamelMessageInfo *mi, gint id);
296 time_t (*info_time)(const CamelMessageInfo *mi, gint id);
298 gboolean (*info_user_flag)(const CamelMessageInfo *mi, const gchar *id);
299 const gchar *(*info_user_tag)(const CamelMessageInfo *mi, const gchar *id);
301 /* set accessors for the modifyable bits */
302 gboolean (*info_set_user_flag)(CamelMessageInfo *mi, const gchar *id, gboolean state);
303 gboolean (*info_set_user_tag)(CamelMessageInfo *mi, const gchar *id, const gchar *val);
304 gboolean (*info_set_flags)(CamelMessageInfo *mi, guint32 mask, guint32 set);
307 GType camel_folder_summary_get_type (void);
308 CamelFolderSummary * camel_folder_summary_new (struct _CamelFolder *folder);
310 struct _CamelFolder * camel_folder_summary_get_folder (CamelFolderSummary *summary);
312 guint32 camel_folder_summary_get_saved_count
313 (CamelFolderSummary *summary);
314 guint32 camel_folder_summary_get_unread_count
315 (CamelFolderSummary *summary);
316 guint32 camel_folder_summary_get_deleted_count
317 (CamelFolderSummary *summary);
318 guint32 camel_folder_summary_get_junk_count
319 (CamelFolderSummary *summary);
320 guint32 camel_folder_summary_get_junk_not_deleted_count
321 (CamelFolderSummary *summary);
322 guint32 camel_folder_summary_get_visible_count
323 (CamelFolderSummary *summary);
325 void camel_folder_summary_set_index (CamelFolderSummary *summary,
327 CamelIndex * camel_folder_summary_get_index (CamelFolderSummary *summary);
328 void camel_folder_summary_set_build_content
329 (CamelFolderSummary *summary,
331 gboolean camel_folder_summary_get_build_content
332 (CamelFolderSummary *summary);
333 void camel_folder_summary_set_need_preview
334 (CamelFolderSummary *summary,
336 gboolean camel_folder_summary_get_need_preview
337 (CamelFolderSummary *summary);
338 guint32 camel_folder_summary_next_uid (CamelFolderSummary *summary);
339 void camel_folder_summary_set_next_uid
340 (CamelFolderSummary *summary,
342 guint32 camel_folder_summary_get_next_uid
343 (CamelFolderSummary *summary);
344 gchar * camel_folder_summary_next_uid_string
345 (CamelFolderSummary *summary);
347 /* load/save the full summary from/to the db */
348 gboolean camel_folder_summary_save_to_db (CamelFolderSummary *summary,
350 gboolean camel_folder_summary_load_from_db
351 (CamelFolderSummary *summary,
354 /* only load the header */
355 gboolean camel_folder_summary_header_load_from_db
356 (CamelFolderSummary *summary,
357 struct _CamelStore *store,
358 const gchar *folder_name,
360 gboolean camel_folder_summary_header_save_to_db
361 (CamelFolderSummary *summary,
364 /* set the dirty bit on the summary */
365 void camel_folder_summary_touch (CamelFolderSummary *summary);
367 /* Just build raw summary items */
368 CamelMessageInfo * camel_folder_summary_info_new_from_header
369 (CamelFolderSummary *summary,
370 struct _camel_header_raw *headers);
371 CamelMessageInfo * camel_folder_summary_info_new_from_parser
372 (CamelFolderSummary *summary,
373 CamelMimeParser *parser);
374 CamelMessageInfo * camel_folder_summary_info_new_from_message
375 (CamelFolderSummary *summary,
376 CamelMimeMessage *message,
377 const gchar *bodystructure);
379 CamelMessageContentInfo *camel_folder_summary_content_info_new
380 (CamelFolderSummary *summary);
381 void camel_folder_summary_content_info_free
382 (CamelFolderSummary *summary,
383 CamelMessageContentInfo *ci);
385 void camel_folder_summary_add_preview
386 (CamelFolderSummary *summary,
387 CamelMessageInfo *info);
389 /* build/add raw summary items */
390 CamelMessageInfo * camel_folder_summary_add_from_header
391 (CamelFolderSummary *summary,
392 struct _camel_header_raw *headers);
393 CamelMessageInfo * camel_folder_summary_add_from_parser
394 (CamelFolderSummary *summary,
395 CamelMimeParser *parser);
396 CamelMessageInfo * camel_folder_summary_add_from_message
397 (CamelFolderSummary *summary,
398 CamelMimeMessage *message);
400 /* add a new raw summary item */
401 void camel_folder_summary_add (CamelFolderSummary *summary,
402 CamelMessageInfo *info);
404 /* insert mi to summary */
405 void camel_folder_summary_insert (CamelFolderSummary *summary,
406 CamelMessageInfo *info,
409 gboolean camel_folder_summary_remove (CamelFolderSummary *summary,
410 CamelMessageInfo *info);
412 gboolean camel_folder_summary_remove_uid (CamelFolderSummary *summary,
414 gboolean camel_folder_summary_remove_uids (CamelFolderSummary *summary,
417 /* remove all items */
418 gboolean camel_folder_summary_clear (CamelFolderSummary *summary,
421 /* lookup functions */
422 guint camel_folder_summary_count (CamelFolderSummary *summary);
424 gboolean camel_folder_summary_check_uid (CamelFolderSummary *summary,
426 CamelMessageInfo * camel_folder_summary_get (CamelFolderSummary *summary,
428 GPtrArray * camel_folder_summary_get_array (CamelFolderSummary *summary);
429 void camel_folder_summary_free_array (GPtrArray *array);
431 GHashTable * camel_folder_summary_get_hash (CamelFolderSummary *summary);
433 gboolean camel_folder_summary_replace_flags
434 (CamelFolderSummary *summary,
435 CamelMessageInfo *info);
437 /* Peek from mem only */
438 CamelMessageInfo * camel_folder_summary_peek_loaded
439 (CamelFolderSummary *summary,
442 /* Get only the uids of dirty/changed things to sync to server/db */
443 GPtrArray * camel_folder_summary_get_changed
444 (CamelFolderSummary *summary);
446 /* reload the summary at any required point if required */
447 void camel_folder_summary_prepare_fetch_all
448 (CamelFolderSummary *summary,
451 /* summary locking */
452 void camel_folder_summary_lock (CamelFolderSummary *summary,
453 CamelFolderSummaryLock lock);
454 void camel_folder_summary_unlock (CamelFolderSummary *summary,
455 CamelFolderSummaryLock lock);
457 /* message flag operations */
458 gboolean camel_flag_get (CamelFlag **list,
460 gboolean camel_flag_set (CamelFlag **list,
463 gboolean camel_flag_list_copy (CamelFlag **to,
465 gint camel_flag_list_size (CamelFlag **list);
466 void camel_flag_list_free (CamelFlag **list);
468 CamelMessageFlags camel_system_flag (const gchar *name);
469 gboolean camel_system_flag_get (CamelMessageFlags flags,
472 /* message tag operations */
473 const gchar * camel_tag_get (CamelTag **list,
475 gboolean camel_tag_set (CamelTag **list,
478 gboolean camel_tag_list_copy (CamelTag **to,
480 gint camel_tag_list_size (CamelTag **list);
481 void camel_tag_list_free (CamelTag **list);
483 /* Summary may be null */
484 /* Use anonymous pointers to avoid tons of cast crap */
485 gpointer camel_message_info_new (CamelFolderSummary *summary);
486 gpointer camel_message_info_ref (gpointer info);
487 CamelMessageInfo * camel_message_info_new_from_header
488 (CamelFolderSummary *summary,
489 struct _camel_header_raw *header);
490 void camel_message_info_free (gpointer info);
491 gpointer camel_message_info_clone (gconstpointer info);
494 gconstpointer camel_message_info_ptr (const CamelMessageInfo *mi,
496 guint32 camel_message_info_uint32 (const CamelMessageInfo *mi,
498 time_t camel_message_info_time (const CamelMessageInfo *mi,
501 #define camel_message_info_uid(mi) ((const gchar *)((const CamelMessageInfo *)mi)->uid)
503 #define camel_message_info_subject(mi) ((const gchar *)camel_message_info_ptr((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_SUBJECT))
506 * camel_message_info_preview:
507 * @mi: a #CamelMessageInfo
513 #define camel_message_info_preview(mi) ((const gchar *)camel_message_info_ptr((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_PREVIEW))
515 #define camel_message_info_from(mi) ((const gchar *)camel_message_info_ptr((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_FROM))
516 #define camel_message_info_to(mi) ((const gchar *)camel_message_info_ptr((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_TO))
517 #define camel_message_info_cc(mi) ((const gchar *)camel_message_info_ptr((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_CC))
518 #define camel_message_info_mlist(mi) ((const gchar *)camel_message_info_ptr((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_MLIST))
520 #define camel_message_info_flags(mi) camel_message_info_uint32((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_FLAGS)
521 #define camel_message_info_size(mi) camel_message_info_uint32((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_SIZE)
523 #define camel_message_info_date_sent(mi) camel_message_info_time((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_DATE_SENT)
524 #define camel_message_info_date_received(mi) camel_message_info_time((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_DATE_RECEIVED)
526 #define camel_message_info_message_id(mi) ((const CamelSummaryMessageID *)camel_message_info_ptr((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_MESSAGE_ID))
527 #define camel_message_info_references(mi) ((const CamelSummaryReferences *)camel_message_info_ptr((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_REFERENCES))
528 #define camel_message_info_user_flags(mi) ((const CamelFlag *)camel_message_info_ptr((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_USER_FLAGS))
529 #define camel_message_info_user_tags(mi) ((const CamelTag *)camel_message_info_ptr((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_USER_TAGS))
532 * camel_message_info_headers:
533 * @mi: a #CamelMessageInfo
539 #define camel_message_info_headers(mi) ((const struct _camel_header_param *)camel_message_info_ptr((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_HEADERS))
542 * camel_message_info_content:
543 * @mi: a #CamelMessageInfo
549 #define camel_message_info_content(mi) ((const CamelMessageContentInfo *)camel_message_info_ptr((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_CONTENT))
551 gboolean camel_message_info_user_flag (const CamelMessageInfo *mi,
553 const gchar * camel_message_info_user_tag (const CamelMessageInfo *mi,
556 gboolean camel_message_info_set_flags (CamelMessageInfo *mi,
557 CamelMessageFlags flags,
559 gboolean camel_message_info_set_user_flag
560 (CamelMessageInfo *mi,
563 gboolean camel_message_info_set_user_tag (CamelMessageInfo *mi,
567 const CamelMessageContentInfo *
568 camel_folder_summary_guess_content_info
569 (CamelMessageInfo *mi,
570 CamelContentType *ctype);
572 /* debugging functions */
573 void camel_content_info_dump (CamelMessageContentInfo *ci,
575 void camel_message_info_dump (CamelMessageInfo *mi);
577 /* utility functions for bdata string decomposition */
578 gint bdata_extract_digit (/* const */ gchar **part);
579 gchar * bdata_extract_string (/* const */ gchar **part);
583 #endif /* CAMEL_FOLDER_SUMMARY_H */