summaryrefslogtreecommitdiff
path: root/src/backends/evolution/EvolutionCalendarSource.h
blob: df2c6eac9600f2fcc9b2f5dba32b3978563e1f28 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
/*
 * Copyright (C) 2005-2008 Patrick Ohly
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) version 3.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301  USA
 */

#ifndef INCL_EVOLUTIONCALENDARSOURCE
#define INCL_EVOLUTIONCALENDARSOURCE

#include <config.h>
#include "TrackingSyncSource.h"
#include "EvolutionSmartPtr.h"

#ifdef ENABLE_ECAL

/**
 * Implements access to Evolution calendars, either
 * using the to-do item or events. Change tracking
 * is done by looking at the modification time stamp.
 * Recurring events and their detached recurrences are
 * handled as one item for the main event and one item
 * for each detached recurrence.
 */
class EvolutionCalendarSource : public TrackingSyncSource
{
  public:
    /**
     * @param    type        chooses which kind of calendar data to use:
     *                       E_CAL_SOURCE_TYPE_TODO,
     *                       E_CAL_SOURCE_TYPE_JOURNAL,
     *                       E_CAL_SOURCE_TYPE_EVENT
     */
    EvolutionCalendarSource(ECalSourceType type,
                            const EvolutionSyncSourceParams &params);
    EvolutionCalendarSource(const EvolutionCalendarSource &other);
    virtual ~EvolutionCalendarSource() { close(); }

    //
    // implementation of EvolutionSyncSource
    //
    virtual Databases getDatabases();
    virtual void open();
    virtual void close(); 
    virtual void exportData(ostream &out);
    virtual string fileSuffix() const { return "ics"; }
    virtual const char *getMimeType() const { return "text/calendar"; }
    virtual const char *getMimeVersion() const { return "2.0"; }
    virtual const char *getSupportedTypes() const { return "text/calendar:2.0"; }
   
    virtual SyncItem *createItem(const string &luid);

  protected:
    //
    // implementation of TrackingSyncSource callbacks
    //
    virtual void listAllItems(RevisionMap_t &revisions);
    virtual InsertItemResult insertItem(const string &luid, const SyncItem &item);
    virtual void setItemStatusThrow(const char *key, int status);
    virtual void deleteItem(const string &luid);
    virtual void logItem(const string &luid, const string &info, bool debug = false);
    virtual void logItem(const SyncItem &item, const string &info, bool debug = false);

  protected:
    /** valid after open(): the calendar that this source references */
    eptr<ECal, GObject> m_calendar;

    ECalSourceType m_type;         /**< use events or todos? */
    string m_typeName;             /**< "calendar", "task list", "memo list" */
    ECal *(*m_newSystem)(void);    /**< e_cal_new_system_calendar, etc. */
    

    /**
     * An item is identified in the calendar by
     * its UID (unique ID) and RID (recurrence ID).
     * The RID may be empty.
     *
     * This is turned into a SyncML LUID by
     * concatenating them: <uid>-rid<rid>.
     */
    class ItemID {
    public:
    ItemID(const string &uid, const string &rid) :
        m_uid(uid),
            m_rid(rid)
            {}
    ItemID(const char *uid, const char *rid):
        m_uid(uid ? uid : ""),
            m_rid(rid ? rid : "")
                {}
    ItemID(const string &luid);

        const string m_uid, m_rid;

        string getLUID() const;
        static string getLUID(const string &uid, const string &rid);
    };

    /**
     * retrieve the item with the given id - may throw exception
     *
     * caller has to free result
     */
    icalcomponent *retrieveItem(const ItemID &id);

    /** retrieve the item with the given luid as VCALENDAR string - may throw exception */
    string retrieveItemAsString(const ItemID &id);


    /** returns the type which the ical library uses for our components */
    icalcomponent_kind getCompType() {
        return m_type == E_CAL_SOURCE_TYPE_EVENT ? ICAL_VEVENT_COMPONENT :
            m_type == E_CAL_SOURCE_TYPE_JOURNAL ? ICAL_VJOURNAL_COMPONENT :
            ICAL_VTODO_COMPONENT;
    }

    /** ECalAuthFunc which calls the authenticate() methods */
    static char *eCalAuthFunc(ECal *ecal,
                              const char *prompt,
                              const char *key,
                              gpointer user_data) {
        return ((EvolutionCalendarSource *)user_data)->authenticate(prompt, key);
    }

    /** actual implementation of ECalAuthFunc */
    char *authenticate(const char *prompt,
                       const char *key);

    /**
     * Returns the LUID of a calendar item.
     */
    string getLUID(ECalComponent *ecomp);

    /**
     * Extract item ID from calendar item.  An icalcomponent must
     * refer to the VEVENT/VTODO/VJOURNAL component.
     */
    ItemID getItemID(ECalComponent *ecomp);
    ItemID getItemID(icalcomponent *icomp);

    /**
     * Extract modification string from calendar item.
     * @return empty string if no time was available
     */
    string getItemModTime(ECalComponent *ecomp);

    /**
     * Extract modification string of an item stored in
     * the calendar.
     * @return empty string if no time was available
     */
    string getItemModTime(const ItemID &id);

    /**
     * Convert to string in canonical representation.
     */
    string icalTime2Str(const struct icaltimetype &tt);

    /**
     * A set of all existing objects. Initialized in the last call to
     * listAllItems() and then updated as items get
     * added/removed. Used to decide how insertItem() has to be
     * implemented without the troublesome querying of the EDS
     * backend.
     */
    set<string> m_allLUIDs;

    /**
     * A list of ref-counted smart pointers to icalcomponents.
     * The list members can be copied; destroying the last instance
     * will destroy the smart pointer, which then calls
     * icalcomponent_free().
     */
    typedef list< boost::shared_ptr< eptr<icalcomponent> > > ICalComps_t;

    /**
     * Utility function which extracts all icalcomponents with
     * the given UID, stores them in a list and then removes
     * them from the calendar. Trying to remove a non-existant
     * UID is logged, but not an error. It simply returns an
     * empty list.
     *
     * Relies on m_allLUIDs, but does not update it. The caller must
     * ensure that the calendar remains in a consistent state.
     *
     * @param returnOnlyChildren    only return children in list, even if parent is also removed
     */
    ICalComps_t removeEvents(const string &uid, bool returnOnlyChildren);
};

#else

typedef int ECalSourceType;

#endif // ENABLE_ECAL

#endif // INCL_EVOLUTIONSYNCSOURCE