1/* Copyright 2016 Software Freedom Conservancy Inc.
2 *
3 * This software is licensed under the GNU Lesser General Public License
4 * (version 2.1 or later).  See the COPYING file in this distribution.
5 */
6
7/**
8 * An IMAP message (email) flag.
9 *
10 * See [[http://tools.ietf.org/html/rfc3501#section-2.3.2]]
11 *
12 * @see StoreCommand
13 * @see FetchCommand
14 * @see FetchedData
15 */
16
17public class Geary.Imap.MessageFlag : Geary.Imap.Flag {
18    private static MessageFlag? _answered = null;
19    public static MessageFlag ANSWERED { get {
20        if (_answered == null)
21            _answered = new MessageFlag("\\answered");
22
23        return _answered;
24    } }
25
26    private static MessageFlag? _deleted = null;
27    public static MessageFlag DELETED { get {
28        if (_deleted == null)
29            _deleted = new MessageFlag("\\deleted");
30
31        return _deleted;
32    } }
33
34    private static MessageFlag? _draft = null;
35    public static MessageFlag DRAFT { get {
36        if (_draft == null)
37            _draft = new MessageFlag("\\draft");
38
39        return _draft;
40    } }
41
42    private static MessageFlag? _flagged = null;
43    public static MessageFlag FLAGGED { get {
44        if (_flagged == null)
45            _flagged = new MessageFlag("\\flagged");
46
47        return _flagged;
48    } }
49
50    private static MessageFlag? _recent = null;
51    public static MessageFlag RECENT { get {
52        if (_recent == null)
53            _recent = new MessageFlag("\\recent");
54
55        return _recent;
56    } }
57
58    private static MessageFlag? _seen = null;
59    public static MessageFlag SEEN { get {
60        if (_seen == null)
61            _seen = new MessageFlag("\\seen");
62
63        return _seen;
64    } }
65
66    private static MessageFlag? _allows_new = null;
67    public static MessageFlag ALLOWS_NEW { get {
68        if (_allows_new == null)
69            _allows_new = new MessageFlag("\\*");
70
71        return _allows_new;
72    } }
73
74    private static MessageFlag? _load_remote_images = null;
75    public static MessageFlag LOAD_REMOTE_IMAGES { get {
76        if (_load_remote_images == null)
77            _load_remote_images = new MessageFlag("LoadRemoteImages");
78
79        return _load_remote_images;
80    } }
81
82    /**
83     * Creates an IMAP message (email) named flag.
84     */
85    public MessageFlag(string value) {
86        base (value);
87    }
88
89    // Call these at init time to prevent thread issues
90    internal static void init() {
91        MessageFlag to_init = ANSWERED;
92        to_init = DELETED;
93        to_init = DRAFT;
94        to_init = FLAGGED;
95        to_init = RECENT;
96        to_init = SEEN;
97        to_init = ALLOWS_NEW;
98        to_init = LOAD_REMOTE_IMAGES;
99    }
100
101    // Converts a list of email flags to add and remove to a list of message
102    // flags to add and remove.
103    public static void from_email_flags(Geary.EmailFlags? email_flags_add,
104        Geary.EmailFlags? email_flags_remove, out Gee.List<MessageFlag> msg_flags_add,
105        out Gee.List<MessageFlag> msg_flags_remove) {
106        msg_flags_add = new Gee.ArrayList<MessageFlag>();
107        msg_flags_remove = new Gee.ArrayList<MessageFlag>();
108
109        if (email_flags_add != null) {
110            if (email_flags_add.contains(Geary.EmailFlags.UNREAD))
111                msg_flags_remove.add(MessageFlag.SEEN);
112            if (email_flags_add.contains(Geary.EmailFlags.FLAGGED))
113                msg_flags_add.add(MessageFlag.FLAGGED);
114            if (email_flags_add.contains(Geary.EmailFlags.LOAD_REMOTE_IMAGES))
115                msg_flags_add.add(MessageFlag.LOAD_REMOTE_IMAGES);
116            if (email_flags_add.contains(Geary.EmailFlags.DRAFT))
117                msg_flags_add.add(MessageFlag.DRAFT);
118            if (email_flags_add.contains(Geary.EmailFlags.DELETED))
119                msg_flags_add.add(MessageFlag.DELETED);
120        }
121
122        if (email_flags_remove != null) {
123            if (email_flags_remove.contains(Geary.EmailFlags.UNREAD))
124                msg_flags_add.add(MessageFlag.SEEN);
125            if (email_flags_remove.contains(Geary.EmailFlags.FLAGGED))
126                msg_flags_remove.add(MessageFlag.FLAGGED);
127            if (email_flags_remove.contains(Geary.EmailFlags.LOAD_REMOTE_IMAGES))
128                msg_flags_remove.add(MessageFlag.LOAD_REMOTE_IMAGES);
129            if (email_flags_remove.contains(Geary.EmailFlags.DRAFT))
130                msg_flags_remove.add(MessageFlag.DRAFT);
131            if (email_flags_remove.contains(Geary.EmailFlags.DELETED))
132                msg_flags_remove.add(MessageFlag.DELETED);
133        }
134    }
135
136    /**
137     * Returns a keyword suitable for the IMAP SEARCH command.
138     *
139     * See [[http://tools.ietf.org/html/rfc3501#section-6.4.4]].  This only returns a value for
140     * SEARCH's known flag keywords, all of which are system keywords.
141     *
142     * If present is false, the ''negative'' value is returned.  So, ANSWERED !present is
143     * UNANSWERED.  One exception: there is no UNRECENT, and so that will return null.
144     */
145    public string? get_search_keyword(bool present) {
146        if (equal_to(ANSWERED))
147            return present ? "answered" : "unanswered";
148
149        if (equal_to(DELETED))
150            return present ? "deleted" : "undeleted";
151
152        if (equal_to(DRAFT))
153            return present ? "draft" : "undraft";
154
155        if (equal_to(FLAGGED))
156            return present ? "flagged" : "unflagged";
157
158        if (equal_to(RECENT))
159            return present ? "recent" : null;
160
161        if (equal_to(SEEN))
162            return present ? "seen" : "unseen";
163
164        return null;
165    }
166}
167
168