1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * Copyright (C) 2004 Novell Inc.
6 * parthasrathi susarla <sparthasrathi@novell.com>
7 * Based on the IMAP summary class implementation by:
8 * Michael Zucchi <notzed@ximian.com>
9 * Dan Winship <danw@ximian.com>
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of version 2 of the GNU Lesser General Public
13 * License as published by the Free Software Foundation.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this program; if not, write to the
22 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23 * Boston, MA 02110-1301, USA.
36 #include "camel-data-cache.h"
37 #include "camel-file-utils.h"
38 #include "camel-folder.h"
40 #include "camel-groupwise-folder.h"
41 #include "camel-groupwise-summary.h"
43 #define CAMEL_GW_SUMMARY_VERSION (1)
46 static int gw_summary_header_load (CamelFolderSummary *, FILE *);
47 static int gw_summary_header_save (CamelFolderSummary *, FILE *);
49 static CamelMessageInfo *gw_message_info_load (CamelFolderSummary *s, FILE *in) ;
51 static int gw_message_info_save (CamelFolderSummary *s, FILE *out, CamelMessageInfo *info) ;
52 static CamelMessageContentInfo * gw_content_info_load (CamelFolderSummary *s, FILE *in) ;
53 static int gw_content_info_save (CamelFolderSummary *s, FILE *out, CamelMessageContentInfo *info) ;
54 static gboolean gw_info_set_flags(CamelMessageInfo *info, guint32 flags, guint32 set);
56 static void camel_groupwise_summary_class_init (CamelGroupwiseSummaryClass *klass);
57 static void camel_groupwise_summary_init (CamelGroupwiseSummary *obj);
63 static CamelFolderSummaryClass *camel_groupwise_summary_parent ;
67 camel_groupwise_summary_get_type (void)
69 static CamelType type = CAMEL_INVALID_TYPE;
71 if (type == CAMEL_INVALID_TYPE) {
72 type = camel_type_register(
73 camel_folder_summary_get_type(), "CamelGroupwiseSummary",
74 sizeof (CamelGroupwiseSummary),
75 sizeof (CamelGroupwiseSummaryClass),
76 (CamelObjectClassInitFunc) camel_groupwise_summary_class_init,
78 (CamelObjectInitFunc) camel_groupwise_summary_init,
85 static CamelMessageInfo *
86 gw_message_info_clone(CamelFolderSummary *s, const CamelMessageInfo *mi)
88 CamelGroupwiseMessageInfo *to;
89 const CamelGroupwiseMessageInfo *from = (const CamelGroupwiseMessageInfo *)mi;
91 to = (CamelGroupwiseMessageInfo *)camel_groupwise_summary_parent->message_info_clone(s, mi);
92 to->server_flags = from->server_flags;
94 /* FIXME: parent clone should do this */
95 to->info.content = camel_folder_summary_content_info_new(s);
97 return (CamelMessageInfo *)to;
101 camel_groupwise_summary_class_init (CamelGroupwiseSummaryClass *klass)
103 CamelFolderSummaryClass *cfs_class = (CamelFolderSummaryClass *) klass;
105 camel_groupwise_summary_parent = CAMEL_FOLDER_SUMMARY_CLASS (camel_type_get_global_classfuncs (camel_folder_summary_get_type()));
107 cfs_class->message_info_clone = gw_message_info_clone ;
108 cfs_class->summary_header_load = gw_summary_header_load;
109 cfs_class->summary_header_save = gw_summary_header_save;
110 cfs_class->message_info_load = gw_message_info_load;
111 cfs_class->message_info_save = gw_message_info_save;
112 cfs_class->content_info_load = gw_content_info_load;
113 cfs_class->content_info_save = gw_content_info_save;
114 cfs_class->info_set_flags = gw_info_set_flags;
119 camel_groupwise_summary_init (CamelGroupwiseSummary *obj)
121 CamelFolderSummary *s = (CamelFolderSummary *)obj;
123 /* subclasses need to set the right instance data sizes */
124 s->message_info_size = sizeof(CamelGroupwiseMessageInfo);
125 s->content_info_size = sizeof(CamelGroupwiseMessageContentInfo);
127 /* Meta-summary - Overriding UID len */
128 s->meta_summary->uid_len = 2048;
133 * camel_groupwise_summary_new:
134 * @filename: the file to store the summary in.
136 * This will create a new CamelGroupwiseSummary object and read in the
137 * summary data from disk, if it exists.
139 * Return value: A new CamelGroupwiseSummary object.
142 camel_groupwise_summary_new (struct _CamelFolder *folder, const char *filename)
144 CamelFolderSummary *summary = CAMEL_FOLDER_SUMMARY (
145 camel_object_new (camel_groupwise_summary_get_type ()));
147 summary->folder = folder ;
148 camel_folder_summary_set_build_content (summary, TRUE);
149 camel_folder_summary_set_filename (summary, filename);
151 if (camel_folder_summary_load (summary) == -1) {
152 camel_folder_summary_clear (summary);
153 camel_folder_summary_touch (summary);
160 gw_summary_header_load (CamelFolderSummary *s, FILE *in)
162 CamelGroupwiseSummary *ims = CAMEL_GROUPWISE_SUMMARY (s);
164 if (camel_groupwise_summary_parent->summary_header_load (s, in) == -1)
167 if (camel_file_util_decode_fixed_int32(in, &ims->version) == -1
168 || camel_file_util_decode_fixed_int32(in, &ims->validity) == -1)
171 if (camel_file_util_decode_string (in, &ims->time_string) == -1)
178 gw_summary_header_save (CamelFolderSummary *s, FILE *out)
180 CamelGroupwiseSummary *ims = CAMEL_GROUPWISE_SUMMARY(s);
182 if (camel_groupwise_summary_parent->summary_header_save (s, out) == -1)
185 camel_file_util_encode_fixed_int32(out, CAMEL_GW_SUMMARY_VERSION);
186 camel_file_util_encode_fixed_int32(out, ims->validity);
187 return camel_file_util_encode_string (out, ims->time_string);
192 static CamelMessageInfo *
193 gw_message_info_load (CamelFolderSummary *s, FILE *in)
195 CamelMessageInfo *info ;
196 CamelGroupwiseMessageInfo *gw_info ;
199 info = camel_groupwise_summary_parent->message_info_load(s,in) ;
201 gw_info = (CamelGroupwiseMessageInfo*) info ;
202 if (camel_file_util_decode_uint32 (in, &gw_info->server_flags) == -1)
208 camel_message_info_free (info) ;
214 gw_message_info_save (CamelFolderSummary *s, FILE *out, CamelMessageInfo *info)
216 CamelGroupwiseMessageInfo *gw_info = (CamelGroupwiseMessageInfo *)info;
218 if (camel_groupwise_summary_parent->message_info_save (s, out, info) == -1)
221 return camel_file_util_encode_uint32 (out, gw_info->server_flags);
225 static CamelMessageContentInfo *
226 gw_content_info_load (CamelFolderSummary *s, FILE *in)
229 return camel_groupwise_summary_parent->content_info_load (s, in);
231 return camel_folder_summary_content_info_new (s);
236 gw_content_info_save (CamelFolderSummary *s, FILE *out,
237 CamelMessageContentInfo *info)
241 return camel_groupwise_summary_parent->content_info_save (s, out, info);
243 return fputc (0, out);
247 gw_info_set_flags (CamelMessageInfo *info, guint32 flags, guint32 set)
250 CamelMessageInfoBase *mi = (CamelMessageInfoBase *)info;
255 /* we don't set flags which aren't appropriate for the folder*/
256 if ((set == (CAMEL_MESSAGE_JUNK|CAMEL_MESSAGE_JUNK_LEARN|CAMEL_MESSAGE_SEEN)) && (old & CAMEL_GW_MESSAGE_JUNK))
259 mi->flags = (old & ~flags) | (set & flags);
260 if (old != mi->flags) {
261 mi->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED;
263 camel_folder_summary_touch(mi->summary);
265 /* This is a hack, we are using CAMEL_MESSAGE_JUNK justo to hide the item
266 * we make sure this doesn't have any side effects*/
268 if ((set == CAMEL_MESSAGE_JUNK_LEARN) && (old & CAMEL_GW_MESSAGE_JUNK)) {
269 mi->flags |= CAMEL_GW_MESSAGE_NOJUNK | CAMEL_MESSAGE_JUNK;
271 /* This has ugly side-effects. Evo will never learn unjunk.
273 We need to create one CAMEL_MESSAGE_HIDDEN flag which must be used for all hiding operations. We must also get rid of the seperate file that is maintained somewhere in evolution/mail/em-folder-browser.c for hidden messages
277 camel_folder_summary_touch(mi->summary);
280 } else if ((old & ~CAMEL_MESSAGE_SYSTEM_MASK) == (mi->flags & ~CAMEL_MESSAGE_SYSTEM_MASK))
283 if (mi->summary && mi->summary->folder && mi->uid) {
284 CamelFolderChangeInfo *changes = camel_folder_change_info_new();
286 camel_folder_change_info_change_uid(changes, camel_message_info_uid(info));
287 camel_object_trigger_event(mi->summary->folder, "folder_changed", changes);
288 camel_folder_change_info_free(changes);
297 camel_gw_summary_add_offline (CamelFolderSummary *summary, const char *uid, CamelMimeMessage *message, const CamelMessageInfo *info)
299 CamelGroupwiseMessageInfo *mi ;
300 const CamelFlag *flag ;
301 const CamelTag *tag ;
303 /* Create summary entry */
304 mi = (CamelGroupwiseMessageInfo *)camel_folder_summary_info_new_from_message (summary, message) ;
306 /* Copy flags 'n' tags */
307 mi->info.flags = camel_message_info_flags(info) ;
309 flag = camel_message_info_user_flags(info) ;
311 camel_message_info_set_user_flag((CamelMessageInfo *)mi, flag->name, TRUE);
314 tag = camel_message_info_user_tags(info);
316 camel_message_info_set_user_tag((CamelMessageInfo *)mi, tag->name, tag->value);
320 mi->info.size = camel_message_info_size(info);
321 mi->info.uid = g_strdup (uid);
323 camel_folder_summary_add (summary, (CamelMessageInfo *)mi);
328 camel_gw_summary_add_offline_uncached (CamelFolderSummary *summary, const char *uid, const CamelMessageInfo *info)
330 CamelGroupwiseMessageInfo *mi;
332 mi = camel_message_info_clone(info);
333 mi->info.uid = g_strdup(uid);
334 camel_folder_summary_add (summary, (CamelMessageInfo *)mi);
338 groupwise_summary_clear (CamelFolderSummary *summary, gboolean uncache)
340 CamelFolderChangeInfo *changes;
341 CamelMessageInfo *info;
345 changes = camel_folder_change_info_new ();
346 count = camel_folder_summary_count (summary);
347 for (i = 0; i < count; i++) {
348 if (!(info = camel_folder_summary_index (summary, i)))
351 uid = camel_message_info_uid (info);
352 camel_folder_change_info_remove_uid (changes, uid);
353 camel_folder_summary_remove_uid (summary, uid);
354 camel_message_info_free(info);
357 camel_folder_summary_clear (summary);
358 camel_folder_summary_save (summary);
361 camel_data_cache_clear (((CamelGroupwiseFolder *) summary->folder)->cache, "cache", NULL);
363 if (camel_folder_change_info_changed (changes))
364 camel_object_trigger_event (summary->folder, "folder_changed", changes);
365 camel_folder_change_info_free (changes);