1 /*
2  * LibSylph -- E-Mail client library
3  * Copyright (C) 1999-2012 Hiroyuki Yamamoto
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18  */
19 
20 #ifndef __FOLDER_H__
21 #define __FOLDER_H__
22 
23 #ifdef HAVE_CONFIG_H
24 #  include "config.h"
25 #endif
26 
27 #include <glib.h>
28 #include <time.h>
29 
30 typedef struct _Folder		Folder;
31 typedef struct _FolderClass	FolderClass;
32 
33 typedef struct _LocalFolder	LocalFolder;
34 typedef struct _RemoteFolder	RemoteFolder;
35 #if 0
36 typedef struct _MboxFolder	MboxFolder;
37 typedef struct _MaildirFolder	MaildirFolder;
38 #endif
39 
40 typedef struct _FolderItem	FolderItem;
41 
42 #define FOLDER(obj)		((Folder *)obj)
43 #define FOLDER_CLASS(obj)	(FOLDER(obj)->klass)
44 #define FOLDER_TYPE(obj)	(FOLDER(obj)->klass->type)
45 
46 #define LOCAL_FOLDER(obj)	((LocalFolder *)obj)
47 #define REMOTE_FOLDER(obj)	((RemoteFolder *)obj)
48 
49 #define FOLDER_IS_LOCAL(obj)	(FOLDER_TYPE(obj) == F_MH      || \
50 				 FOLDER_TYPE(obj) == F_MBOX    || \
51 				 FOLDER_TYPE(obj) == F_MAILDIR)
52 #define FOLDER_IS_REMOTE(obj)	(FOLDER_TYPE(obj) == F_IMAP || \
53 				 FOLDER_TYPE(obj) == F_NEWS)
54 
55 #if 0
56 #define MBOX_FOLDER(obj)	((MboxFolder *)obj)
57 #define MAILDIR_FOLDER(obj)	((MaildirFolder *)obj)
58 #endif
59 
60 #define FOLDER_ITEM(obj)	((FolderItem *)obj)
61 
62 #define FOLDER_ITEM_CAN_ADD(obj)					\
63 		((obj) && FOLDER_ITEM(obj)->folder &&			\
64 		 FOLDER_ITEM(obj)->path &&				\
65 		 (FOLDER_IS_LOCAL(FOLDER_ITEM(obj)->folder) ||		\
66 		  FOLDER_TYPE(FOLDER_ITEM(obj)->folder) == F_IMAP) &&	\
67 		 !FOLDER_ITEM(obj)->no_select)
68 
69 #define FOLDER_ITEM_IS_SENT_FOLDER(obj)	((obj) &&			\
70 					 ((obj)->stype == F_OUTBOX ||	\
71 					  (obj)->stype == F_DRAFT ||	\
72 					  (obj)->stype == F_QUEUE))
73 
74 typedef enum
75 {
76 	F_MH,
77 	F_MBOX,
78 	F_MAILDIR,
79 	F_IMAP,
80 	F_NEWS,
81 	F_UNKNOWN
82 } FolderType;
83 
84 typedef enum
85 {
86 	F_NORMAL,
87 	F_INBOX,
88 	F_OUTBOX,
89 	F_DRAFT,
90 	F_QUEUE,
91 	F_TRASH,
92 	F_JUNK,
93 	F_VIRTUAL
94 } SpecialFolderItemType;
95 
96 typedef enum
97 {
98 	SORT_BY_NONE,
99 	SORT_BY_NUMBER,
100 	SORT_BY_SIZE,
101 	SORT_BY_DATE,
102 	SORT_BY_TDATE,
103 	SORT_BY_FROM,
104 	SORT_BY_SUBJECT,
105 	SORT_BY_SCORE,
106 	SORT_BY_LABEL,
107 	SORT_BY_MARK,
108 	SORT_BY_UNREAD,
109 	SORT_BY_MIME,
110 	SORT_BY_TO
111 } FolderSortKey;
112 
113 typedef enum
114 {
115 	SORT_ASCENDING,
116 	SORT_DESCENDING
117 } FolderSortType;
118 
119 typedef void (*FolderUIFunc)		(Folder		*folder,
120 					 FolderItem	*item,
121 					 gpointer	 data);
122 typedef gboolean (*FolderUIFunc2)	(Folder		*folder,
123 					 FolderItem	*item,
124 					 guint		 count,
125 					 guint		 total,
126 					 gpointer	 data);
127 typedef void (*FolderDestroyNotify)	(Folder		*folder,
128 					 FolderItem	*item,
129 					 gpointer	 data);
130 
131 #include "prefs_account.h"
132 #include "session.h"
133 #include "procmsg.h"
134 #include "utils.h"
135 
136 struct _Folder
137 {
138 	FolderClass *klass;
139 
140 	gchar *name;
141 	PrefsAccount *account;
142 
143 	FolderItem *inbox;
144 	FolderItem *outbox;
145 	FolderItem *draft;
146 	FolderItem *queue;
147 	FolderItem *trash;
148 
149 	FolderUIFunc ui_func;
150 	gpointer     ui_func_data;
151 
152 	GNode *node;
153 
154 	gpointer data;
155 };
156 
157 struct _FolderClass
158 {
159 	FolderType type;
160 
161 	/* virtual functions */
162 	Folder * (*folder_new)		(const gchar	*name,
163 					 const gchar	*path);
164 	void     (*destroy)		(Folder		*folder);
165 
166 	gint     (*scan_tree)		(Folder		*folder);
167 	gint     (*create_tree)		(Folder		*folder);
168 
169 	GSList * (*get_msg_list)	(Folder		*folder,
170 					 FolderItem	*item,
171 					 gboolean	 use_cache);
172 	GSList * (*get_uncached_msg_list)
173 					(Folder		*folder,
174 					 FolderItem	*item);
175 	/* return value is filename encoding */
176 	gchar *  (*fetch_msg)		(Folder		*folder,
177 					 FolderItem	*item,
178 					 gint		 num);
179 	MsgInfo * (*get_msginfo)	(Folder		*folder,
180 					 FolderItem	*item,
181 					 gint		 num);
182 	gint     (*add_msg)		(Folder		*folder,
183 					 FolderItem	*dest,
184 					 const gchar	*file,
185 					 MsgFlags	*flags,
186 					 gboolean	 remove_source);
187 	gint     (*add_msgs)		(Folder		*folder,
188 					 FolderItem	*dest,
189 					 GSList		*file_list,
190 					 gboolean	 remove_source,
191 					 gint		*first);
192 	gint     (*add_msg_msginfo)	(Folder		*folder,
193 					 FolderItem	*dest,
194 					 MsgInfo	*msginfo,
195 					 gboolean	 remove_source);
196 	gint     (*add_msgs_msginfo)	(Folder		*folder,
197 					 FolderItem	*dest,
198 					 GSList		*msginfo_list,
199 					 gboolean	 remove_source,
200 					 gint		*first);
201 	gint     (*move_msg)		(Folder		*folder,
202 					 FolderItem	*dest,
203 					 MsgInfo	*msginfo);
204 	gint     (*move_msgs)		(Folder		*folder,
205 					 FolderItem	*dest,
206 					 GSList		*msglist);
207 	gint     (*copy_msg)		(Folder		*folder,
208 					 FolderItem	*dest,
209 					 MsgInfo	*msginfo);
210 	gint     (*copy_msgs)		(Folder		*folder,
211 					 FolderItem	*dest,
212 					 GSList		*msglist);
213 	gint     (*remove_msg)		(Folder		*folder,
214 					 FolderItem	*item,
215 					 MsgInfo	*msginfo);
216 	gint     (*remove_msgs)		(Folder		*folder,
217 					 FolderItem	*item,
218 					 GSList		*msglist);
219 	gint     (*remove_all_msg)	(Folder		*folder,
220 					 FolderItem	*item);
221 	gboolean (*is_msg_changed)	(Folder		*folder,
222 					 FolderItem	*item,
223 					 MsgInfo	*msginfo);
224 	gint     (*close)		(Folder		*folder,
225 					 FolderItem	*item);
226 	gint     (*scan)		(Folder		*folder,
227 					 FolderItem	*item);
228 
229 	FolderItem * (*create_folder)	(Folder		*folder,
230 					 FolderItem	*parent,
231 					 const gchar	*name);
232 	gint     (*rename_folder)	(Folder		*folder,
233 					 FolderItem	*item,
234 					 const gchar	*name);
235 	gint     (*move_folder)		(Folder		*folder,
236 					 FolderItem	*item,
237 					 FolderItem	*new_parent);
238 	gint     (*remove_folder)	(Folder		*folder,
239 					 FolderItem	*item);
240 };
241 
242 struct _LocalFolder
243 {
244 	Folder folder;
245 
246 	gchar *rootpath;
247 };
248 
249 struct _RemoteFolder
250 {
251 	Folder folder;
252 
253 	Session *session;
254 
255 	guint remove_cache_on_destroy : 1;
256 	guint dummy1 : 1;
257 	guint dummy2 : 1;
258 	guint dummy3 : 1;
259 };
260 
261 #if 0
262 struct _MboxFolder
263 {
264 	LocalFolder lfolder;
265 };
266 
267 struct _MaildirFolder
268 {
269 	LocalFolder lfolder;
270 };
271 #endif
272 
273 struct _FolderItem
274 {
275 	SpecialFolderItemType stype;
276 
277 	gchar *name; /* UTF-8 */
278 	gchar *path; /* UTF-8 */
279 
280 	stime_t mtime;
281 
282 	gint new;
283 	gint unread;
284 	gint total;
285 	gint unmarked_num;
286 
287 	gint last_num;
288 
289 	/* special flags */
290 	guint no_sub    : 1; /* no child allowed?    */
291 	guint no_select : 1; /* not selectable?      */
292 	guint collapsed : 1; /* collapsed item       */
293 	guint threaded  : 1; /* threaded folder view */
294 
295 	guint opened    : 1; /* opened by summary view */
296 	guint updated   : 1; /* folderview should be updated */
297 
298 	guint cache_dirty : 1; /* cache file needs to be updated */
299 	guint mark_dirty  : 1; /* mark file needs to be updated */
300 
301 	FolderSortKey sort_key;
302 	FolderSortType sort_type;
303 
304 	GNode *node;
305 
306 	FolderItem *parent;
307 
308 	Folder *folder;
309 
310 	PrefsAccount *account;
311 
312 	gboolean ac_apply_sub;
313 
314 	gchar *auto_to;
315 	gboolean use_auto_to_on_reply;
316 	gchar *auto_cc;
317 	gchar *auto_bcc;
318 	gchar *auto_replyto;
319 
320 	gboolean trim_summary_subject;
321 	gboolean trim_compose_subject;
322 
323 	GSList *cache_queue;
324 	GSList *mark_queue;
325 
326 	guint last_selected;
327 	gint qsearch_cond_type;
328 
329 	gpointer data;
330 };
331 
332 Folder     *folder_new			(FolderType	 type,
333 					 const gchar	*name,
334 					 const gchar	*path);
335 void        folder_local_folder_init	(Folder		*folder,
336 					 const gchar	*name,
337 					 const gchar	*path);
338 void        folder_remote_folder_init	(Folder		*folder,
339 					 const gchar	*name,
340 					 const gchar	*path);
341 
342 void        folder_destroy		(Folder		*folder);
343 void        folder_local_folder_destroy	(LocalFolder	*lfolder);
344 void        folder_remote_folder_destroy(RemoteFolder	*rfolder);
345 
346 gint        folder_remote_folder_destroy_all_sessions	(void);
347 
348 gboolean    folder_remote_folder_is_session_active
349 					(RemoteFolder	*rfolder);
350 gboolean folder_remote_folder_active_session_exist	(void);
351 
352 gint        folder_scan_tree		(Folder		*folder);
353 gint        folder_create_tree		(Folder		*folder);
354 
355 FolderItem *folder_item_new		(const gchar	*name,
356 					 const gchar	*path);
357 void        folder_item_append		(FolderItem	*parent,
358 					 FolderItem	*item);
359 FolderItem *folder_item_copy		(FolderItem	*item);
360 void        folder_item_remove		(FolderItem	*item);
361 void        folder_item_remove_children	(FolderItem	*item);
362 void        folder_item_destroy		(FolderItem	*item);
363 
364 gint        folder_item_compare		(FolderItem	*item_a,
365 					 FolderItem	*item_b);
366 
367 void        folder_set_ui_func		(Folder		*folder,
368 					 FolderUIFunc	 func,
369 					 gpointer	 data);
370 void        folder_set_ui_func2		(Folder		*folder,
371 					 FolderUIFunc2	 func,
372 					 gpointer	 data);
373 FolderUIFunc2 folder_get_ui_func2	(Folder		*folder);
374 gboolean    folder_call_ui_func2	(Folder		*folder,
375 					 FolderItem	*item,
376 					 guint		 count,
377 					 guint		 total);
378 
379 void        folder_set_name	(Folder		*folder,
380 				 const gchar	*name);
381 void        folder_tree_destroy	(Folder		*folder);
382 
383 void   folder_add		(Folder		*folder);
384 
385 GList *folder_get_list		(void);
386 gint   folder_read_list		(void);
387 void   folder_write_list	(void);
388 
389 gchar *folder_get_status	(GPtrArray	*folders,
390 				 gboolean	 full);
391 
392 Folder     *folder_find_from_path		(const gchar	*path);
393 Folder     *folder_find_from_name		(const gchar	*name,
394 						 FolderType	 type);
395 FolderItem *folder_find_item_from_path		(const gchar	*path);
396 FolderItem *folder_find_child_item_by_name	(FolderItem	*item,
397 						 const gchar	*name);
398 gchar      *folder_get_identifier		(Folder		*folder);
399 gchar      *folder_item_get_identifier		(FolderItem	*item);
400 FolderItem *folder_find_item_from_identifier	(const gchar	*identifier);
401 FolderItem *folder_find_item_and_num_from_id	(const gchar	*identifier,
402 						 gint		*num);
403 
404 Folder     *folder_get_default_folder	(void);
405 FolderItem *folder_get_default_inbox	(void);
406 FolderItem *folder_get_default_outbox	(void);
407 FolderItem *folder_get_default_draft	(void);
408 FolderItem *folder_get_default_queue	(void);
409 FolderItem *folder_get_default_trash	(void);
410 FolderItem *folder_get_default_junk	(void);
411 
412 gboolean folder_item_is_trash		(FolderItem	*item);
413 
414 FolderItem *folder_get_junk		(Folder		*folder);
415 void folder_set_junk			(Folder		*folder,
416 					 FolderItem	*item);
417 
418 void folder_set_missing_folders		(void);
419 void folder_unref_account_all		(PrefsAccount	*account);
420 
421 /* return value is filename encoding */
422 gchar *folder_get_path			(Folder		*folder);
423 gchar *folder_item_get_path		(FolderItem	*item);
424 
425 gint   folder_item_scan			(FolderItem	*item);
426 void   folder_item_scan_foreach		(GHashTable	*table);
427 GSList *folder_item_get_msg_list	(FolderItem	*item,
428 					 gboolean	 use_cache);
429 GSList *folder_item_get_uncached_msg_list
430 					(FolderItem	*item);
431 /* return value is filename encoding */
432 gchar *folder_item_fetch_msg		(FolderItem	*item,
433 					 gint		 num);
434 gint   folder_item_fetch_all_msg	(FolderItem	*item);
435 MsgInfo *folder_item_get_msginfo	(FolderItem	*item,
436 					 gint		 num);
437 gint   folder_item_add_msg		(FolderItem	*dest,
438 					 const gchar	*file,
439 					 MsgFlags	*flags,
440 					 gboolean	 remove_source);
441 gint   folder_item_add_msgs		(FolderItem	*dest,
442 					 GSList		*file_list,
443 					 gboolean	 remove_source,
444 					 gint		*first);
445 gint   folder_item_add_msg_msginfo	(FolderItem	*dest,
446 					 MsgInfo	*msginfo,
447 					 gboolean	 remove_source);
448 gint   folder_item_add_msgs_msginfo	(FolderItem	*dest,
449 					 GSList		*msginfo_list,
450 					 gboolean	 remove_source,
451 					 gint		*first);
452 gint   folder_item_move_msg		(FolderItem	*dest,
453 					 MsgInfo	*msginfo);
454 gint   folder_item_move_msgs		(FolderItem	*dest,
455 					 GSList		*msglist);
456 gint   folder_item_copy_msg		(FolderItem	*dest,
457 					 MsgInfo	*msginfo);
458 gint   folder_item_copy_msgs		(FolderItem	*dest,
459 					 GSList		*msglist);
460 gint   folder_item_remove_msg		(FolderItem	*item,
461 					 MsgInfo	*msginfo);
462 gint   folder_item_remove_msgs		(FolderItem	*item,
463 					 GSList		*msglist);
464 gint   folder_item_remove_all_msg	(FolderItem	*item);
465 
466 gboolean folder_item_is_msg_changed	(FolderItem	*item,
467 					 MsgInfo	*msginfo);
468 
469 /* return value is filename encoding */
470 gchar *folder_item_get_cache_file	(FolderItem	*item);
471 gchar *folder_item_get_mark_file	(FolderItem	*item);
472 
473 gint   folder_item_close		(FolderItem	*item);
474 
475 #endif /* __FOLDER_H__ */
476