summaryrefslogtreecommitdiffabout
path: root/libkcal
authorzautrix <zautrix>2004-06-29 11:59:46 (UTC)
committer zautrix <zautrix>2004-06-29 11:59:46 (UTC)
commitda43dbdc6c82453228f34766fc74585615cba938 (patch) (unidiff)
tree16576932cea08bf117b2d0320b0d5f66ee8ad093 /libkcal
parent627489ea2669d3997676bc3cee0f5d0d0c16c4d4 (diff)
downloadkdepimpi-da43dbdc6c82453228f34766fc74585615cba938.zip
kdepimpi-da43dbdc6c82453228f34766fc74585615cba938.tar.gz
kdepimpi-da43dbdc6c82453228f34766fc74585615cba938.tar.bz2
New lib ical.Some minor changes as well.
Diffstat (limited to 'libkcal') (more/less context) (ignore whitespace changes)
-rw-r--r--libkcal/calendar.h1
-rw-r--r--libkcal/calendarlocal.cpp31
-rw-r--r--libkcal/calendarlocal.h1
-rw-r--r--libkcal/icalformat.cpp8
-rw-r--r--libkcal/icalformatimpl.cpp79
-rw-r--r--libkcal/icalformatimpl.h2
-rw-r--r--libkcal/vcalformat.cpp22
-rw-r--r--libkcal/versit/port.h109
-rw-r--r--libkcal/versit/vcc.c1817
-rw-r--r--libkcal/versit/vcc.h12
-rw-r--r--libkcal/versit/vobject.c363
-rw-r--r--libkcal/versit/vobject.h173
12 files changed, 1415 insertions, 1203 deletions
diff --git a/libkcal/calendar.h b/libkcal/calendar.h
index 7a85e74..7d23619 100644
--- a/libkcal/calendar.h
+++ b/libkcal/calendar.h
@@ -1,349 +1,350 @@
1/* 1/*
2 This file is part of libkcal. 2 This file is part of libkcal.
3 Copyright (c) 1998 Preston Brown 3 Copyright (c) 1998 Preston Brown
4 Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org> 4 Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
5 5
6 This library is free software; you can redistribute it and/or 6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public 7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either 8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version. 9 version 2 of the License, or (at your option) any later version.
10 10
11 This library is distributed in the hope that it will be useful, 11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details. 14 Library General Public License for more details.
15 15
16 You should have received a copy of the GNU Library General Public License 16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to 17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. 19 Boston, MA 02111-1307, USA.
20*/ 20*/
21 21
22#ifndef CALENDAR_H 22#ifndef CALENDAR_H
23#define CALENDAR_H 23#define CALENDAR_H
24 24
25#include <qobject.h> 25#include <qobject.h>
26#include <qstring.h> 26#include <qstring.h>
27#include <qdatetime.h> 27#include <qdatetime.h>
28#include <qptrlist.h> 28#include <qptrlist.h>
29#include <qdict.h> 29#include <qdict.h>
30 30
31#include "customproperties.h" 31#include "customproperties.h"
32#include "event.h" 32#include "event.h"
33#include "todo.h" 33#include "todo.h"
34#include "journal.h" 34#include "journal.h"
35 35
36#define _TIME_ZONE "-0500" /* hardcoded, overridden in config file. */ 36#define _TIME_ZONE "-0500" /* hardcoded, overridden in config file. */
37 37
38class KConfig; 38class KConfig;
39 39
40namespace KCal { 40namespace KCal {
41 41
42class CalFilter; 42class CalFilter;
43 43
44/** 44/**
45 This is the main "calendar" object class for KOrganizer. It holds 45 This is the main "calendar" object class for KOrganizer. It holds
46 information like all appointments/events, user information, etc. etc. 46 information like all appointments/events, user information, etc. etc.
47 one calendar is associated with each CalendarView (@see calendarview.h). 47 one calendar is associated with each CalendarView (@see calendarview.h).
48 This is an abstract base class defining the interface to a calendar. It is 48 This is an abstract base class defining the interface to a calendar. It is
49 implemented by subclasses like @see CalendarLocal, which use different 49 implemented by subclasses like @see CalendarLocal, which use different
50 methods to store and access the data. 50 methods to store and access the data.
51 51
52 Ownership of events etc. is handled by the following policy: As soon as an 52 Ownership of events etc. is handled by the following policy: As soon as an
53 event (or any other subclass of IncidenceBase) object is added to the 53 event (or any other subclass of IncidenceBase) object is added to the
54 Calendar by addEvent() it is owned by the Calendar object. The Calendar takes 54 Calendar by addEvent() it is owned by the Calendar object. The Calendar takes
55 care of deleting it. All Events returned by the query functions are returned 55 care of deleting it. All Events returned by the query functions are returned
56 as pointers, that means all changes to the returned events are immediately 56 as pointers, that means all changes to the returned events are immediately
57 visible in the Calendar. You shouldn't delete any Event object you get from 57 visible in the Calendar. You shouldn't delete any Event object you get from
58 Calendar. 58 Calendar.
59*/ 59*/
60class Calendar : public QObject, public CustomProperties, 60class Calendar : public QObject, public CustomProperties,
61 public IncidenceBase::Observer 61 public IncidenceBase::Observer
62{ 62{
63 Q_OBJECT 63 Q_OBJECT
64public: 64public:
65 Calendar(); 65 Calendar();
66 Calendar(const QString &timeZoneId); 66 Calendar(const QString &timeZoneId);
67 virtual ~Calendar(); 67 virtual ~Calendar();
68 void deleteIncidence(Incidence *in); 68 void deleteIncidence(Incidence *in);
69 /** 69 /**
70 Clears out the current calendar, freeing all used memory etc. 70 Clears out the current calendar, freeing all used memory etc.
71 */ 71 */
72 virtual void close() = 0; 72 virtual void close() = 0;
73 73
74 /** 74 /**
75 Sync changes in memory to persistant storage. 75 Sync changes in memory to persistant storage.
76 */ 76 */
77 virtual void save() = 0; 77 virtual void save() = 0;
78 78
79 virtual bool isSaving() { return false; } 79 virtual bool isSaving() { return false; }
80 80
81 /** 81 /**
82 Return the owner of the calendar's full name. 82 Return the owner of the calendar's full name.
83 */ 83 */
84 const QString &getOwner() const; 84 const QString &getOwner() const;
85 /** 85 /**
86 Set the owner of the calendar. Should be owner's full name. 86 Set the owner of the calendar. Should be owner's full name.
87 */ 87 */
88 void setOwner( const QString &os ); 88 void setOwner( const QString &os );
89 /** 89 /**
90 Return the email address of the calendar owner. 90 Return the email address of the calendar owner.
91 */ 91 */
92 const QString &getEmail(); 92 const QString &getEmail();
93 /** 93 /**
94 Set the email address of the calendar owner. 94 Set the email address of the calendar owner.
95 */ 95 */
96 void setEmail( const QString & ); 96 void setEmail( const QString & );
97 97
98 /** 98 /**
99 Set time zone from a timezone string (e.g. -2:00) 99 Set time zone from a timezone string (e.g. -2:00)
100 */ 100 */
101 void setTimeZone( const QString &tz ); 101 void setTimeZone( const QString &tz );
102 /** 102 /**
103 Set time zone from a minutes value (e.g. -60) 103 Set time zone from a minutes value (e.g. -60)
104 */ 104 */
105 void setTimeZone( int tz ); 105 void setTimeZone( int tz );
106 /** 106 /**
107 Return time zone as offest in minutes. 107 Return time zone as offest in minutes.
108 */ 108 */
109 int getTimeZone() const; 109 int getTimeZone() const;
110 /** 110 /**
111 Compute an ISO 8601 format string from the time zone. 111 Compute an ISO 8601 format string from the time zone.
112 */ 112 */
113 QString getTimeZoneStr() const; 113 QString getTimeZoneStr() const;
114 /** 114 /**
115 Set time zone id (see /usr/share/zoneinfo/zone.tab for list of legal 115 Set time zone id (see /usr/share/zoneinfo/zone.tab for list of legal
116 values). 116 values).
117 */ 117 */
118 void setTimeZoneId( const QString & ); 118 void setTimeZoneId( const QString & );
119 /** 119 /**
120 Return time zone id. 120 Return time zone id.
121 */ 121 */
122 QString timeZoneId() const; 122 QString timeZoneId() const;
123 /** 123 /**
124 Use local time, not UTC or a time zone. 124 Use local time, not UTC or a time zone.
125 */ 125 */
126 void setLocalTime(); 126 void setLocalTime();
127 /** 127 /**
128 Return whether local time is being used. 128 Return whether local time is being used.
129 */ 129 */
130 bool isLocalTime() const; 130 bool isLocalTime() const;
131 131
132 /** 132 /**
133 Add an incidence to calendar. 133 Add an incidence to calendar.
134 134
135 @return true on success, false on error. 135 @return true on success, false on error.
136 */ 136 */
137 virtual bool addIncidence( Incidence * ); 137 virtual bool addIncidence( Incidence * );
138 /** 138 /**
139 Return filtered list of all incidences of this calendar. 139 Return filtered list of all incidences of this calendar.
140 */ 140 */
141 virtual QPtrList<Incidence> incidences(); 141 virtual QPtrList<Incidence> incidences();
142 142
143 /** 143 /**
144 Return unfiltered list of all incidences of this calendar. 144 Return unfiltered list of all incidences of this calendar.
145 */ 145 */
146 virtual QPtrList<Incidence> rawIncidences(); 146 virtual QPtrList<Incidence> rawIncidences();
147 147
148 /** 148 /**
149 Adds a Event to this calendar object. 149 Adds a Event to this calendar object.
150 @param anEvent a pointer to the event to add 150 @param anEvent a pointer to the event to add
151 151
152 @return true on success, false on error. 152 @return true on success, false on error.
153 */ 153 */
154 virtual bool addEventNoDup( Event *event ) = 0; 154 virtual bool addEventNoDup( Event *event ) = 0;
155 virtual bool addAnniversaryNoDup( Event *event ) = 0;
155 virtual bool addEvent( Event *anEvent ) = 0; 156 virtual bool addEvent( Event *anEvent ) = 0;
156 /** 157 /**
157 Delete event from calendar. 158 Delete event from calendar.
158 */ 159 */
159 virtual void deleteEvent( Event * ) = 0; 160 virtual void deleteEvent( Event * ) = 0;
160 /** 161 /**
161 Retrieves an event on the basis of the unique string ID. 162 Retrieves an event on the basis of the unique string ID.
162 */ 163 */
163 virtual Event *event( const QString &UniqueStr ) = 0; 164 virtual Event *event( const QString &UniqueStr ) = 0;
164 virtual Event *event( int ) = 0; 165 virtual Event *event( int ) = 0;
165 /** 166 /**
166 Builds and then returns a list of all events that match for the 167 Builds and then returns a list of all events that match for the
167 date specified. useful for dayView, etc. etc. 168 date specified. useful for dayView, etc. etc.
168 The calendar filter is applied. 169 The calendar filter is applied.
169 */ 170 */
170 QPtrList<Event> events( const QDate &date, bool sorted = false); 171 QPtrList<Event> events( const QDate &date, bool sorted = false);
171 /** 172 /**
172 Get events, which occur on the given date. 173 Get events, which occur on the given date.
173 The calendar filter is applied. 174 The calendar filter is applied.
174 */ 175 */
175 QPtrList<Event> events( const QDateTime &qdt ); 176 QPtrList<Event> events( const QDateTime &qdt );
176 /** 177 /**
177 Get events in a range of dates. If inclusive is set to true, only events 178 Get events in a range of dates. If inclusive is set to true, only events
178 are returned, which are completely included in the range. 179 are returned, which are completely included in the range.
179 The calendar filter is applied. 180 The calendar filter is applied.
180 */ 181 */
181 QPtrList<Event> events( const QDate &start, const QDate &end, 182 QPtrList<Event> events( const QDate &start, const QDate &end,
182 bool inclusive = false); 183 bool inclusive = false);
183 /** 184 /**
184 Return filtered list of all events in calendar. 185 Return filtered list of all events in calendar.
185 */ 186 */
186 virtual QPtrList<Event> events(); 187 virtual QPtrList<Event> events();
187 /** 188 /**
188 Return unfiltered list of all events in calendar. 189 Return unfiltered list of all events in calendar.
189 */ 190 */
190 virtual QPtrList<Event> rawEvents() = 0; 191 virtual QPtrList<Event> rawEvents() = 0;
191 192
192 /** 193 /**
193 Add a todo to the todolist. 194 Add a todo to the todolist.
194 195
195 @return true on success, false on error. 196 @return true on success, false on error.
196 */ 197 */
197 virtual bool addTodo( Todo *todo ) = 0; 198 virtual bool addTodo( Todo *todo ) = 0;
198 virtual bool addTodoNoDup( Todo *todo ) = 0; 199 virtual bool addTodoNoDup( Todo *todo ) = 0;
199 /** 200 /**
200 Remove a todo from the todolist. 201 Remove a todo from the todolist.
201 */ 202 */
202 virtual void deleteTodo( Todo * ) = 0; 203 virtual void deleteTodo( Todo * ) = 0;
203 virtual void deleteJournal( Journal * ) = 0; 204 virtual void deleteJournal( Journal * ) = 0;
204 /** 205 /**
205 Return filterd list of todos. 206 Return filterd list of todos.
206 */ 207 */
207 virtual QPtrList<Todo> todos(); 208 virtual QPtrList<Todo> todos();
208 /** 209 /**
209 Searches todolist for an event with this unique string identifier, 210 Searches todolist for an event with this unique string identifier,
210 returns a pointer or null. 211 returns a pointer or null.
211 */ 212 */
212 virtual Todo *todo( const QString &uid ) = 0; 213 virtual Todo *todo( const QString &uid ) = 0;
213 virtual Todo *todo( int ) = 0; 214 virtual Todo *todo( int ) = 0;
214 /** 215 /**
215 Returns list of todos due on the specified date. 216 Returns list of todos due on the specified date.
216 */ 217 */
217 virtual QPtrList<Todo> todos( const QDate &date ) = 0; 218 virtual QPtrList<Todo> todos( const QDate &date ) = 0;
218 /** 219 /**
219 Return unfiltered list of todos. 220 Return unfiltered list of todos.
220 */ 221 */
221 virtual QPtrList<Todo> rawTodos() = 0; 222 virtual QPtrList<Todo> rawTodos() = 0;
222 223
223 /** 224 /**
224 Add a Journal entry to calendar. 225 Add a Journal entry to calendar.
225 226
226 @return true on success, false on error. 227 @return true on success, false on error.
227 */ 228 */
228 virtual bool addJournal( Journal * ) = 0; 229 virtual bool addJournal( Journal * ) = 0;
229 /** 230 /**
230 Return Journal for given date. 231 Return Journal for given date.
231 */ 232 */
232 virtual Journal *journal( const QDate & ) = 0; 233 virtual Journal *journal( const QDate & ) = 0;
233 /** 234 /**
234 Return Journal with given UID. 235 Return Journal with given UID.
235 */ 236 */
236 virtual Journal *journal( const QString &UID ) = 0; 237 virtual Journal *journal( const QString &UID ) = 0;
237 /** 238 /**
238 Return list of all Journal entries. 239 Return list of all Journal entries.
239 */ 240 */
240 virtual QPtrList<Journal> journals() = 0; 241 virtual QPtrList<Journal> journals() = 0;
241 242
242 /** 243 /**
243 Searches all incidence types for an incidence with this unique 244 Searches all incidence types for an incidence with this unique
244 string identifier, returns a pointer or null. 245 string identifier, returns a pointer or null.
245 */ 246 */
246 Incidence* incidence( const QString&UID ); 247 Incidence* incidence( const QString&UID );
247 248
248 /** 249 /**
249 Setup relations for an incidence. 250 Setup relations for an incidence.
250 */ 251 */
251 virtual void setupRelations( Incidence * ); 252 virtual void setupRelations( Incidence * );
252 /** 253 /**
253 Remove all relations to an incidence 254 Remove all relations to an incidence
254 */ 255 */
255 virtual void removeRelations( Incidence * ); 256 virtual void removeRelations( Incidence * );
256 257
257 /** 258 /**
258 Set calendar filter, which filters events for the events() functions. 259 Set calendar filter, which filters events for the events() functions.
259 The Filter object is owned by the caller. 260 The Filter object is owned by the caller.
260 */ 261 */
261 void setFilter( CalFilter * ); 262 void setFilter( CalFilter * );
262 /** 263 /**
263 Return calendar filter. 264 Return calendar filter.
264 */ 265 */
265 CalFilter *filter(); 266 CalFilter *filter();
266 virtual QDateTime nextAlarm( int daysTo ) = 0; 267 virtual QDateTime nextAlarm( int daysTo ) = 0;
267 virtual QString nextSummary( ) const = 0; 268 virtual QString nextSummary( ) const = 0;
268 virtual void reInitAlarmSettings() = 0; 269 virtual void reInitAlarmSettings() = 0;
269 virtual QDateTime nextAlarmEventDateTime() const = 0; 270 virtual QDateTime nextAlarmEventDateTime() const = 0;
270 virtual void checkAlarmForIncidence( Incidence *, bool ) = 0; 271 virtual void checkAlarmForIncidence( Incidence *, bool ) = 0;
271 /** 272 /**
272 Return all alarms, which ocur in the given time interval. 273 Return all alarms, which ocur in the given time interval.
273 */ 274 */
274 virtual Alarm::List alarms( const QDateTime &from, 275 virtual Alarm::List alarms( const QDateTime &from,
275 const QDateTime &to ) = 0; 276 const QDateTime &to ) = 0;
276 277
277 class Observer { 278 class Observer {
278 public: 279 public:
279 virtual void calendarModified( bool, Calendar * ) = 0; 280 virtual void calendarModified( bool, Calendar * ) = 0;
280 }; 281 };
281 282
282 void registerObserver( Observer * ); 283 void registerObserver( Observer * );
283 284
284 void setModified( bool ); 285 void setModified( bool );
285 286
286 /** 287 /**
287 Set product id returned by loadedProductId(). This function is only 288 Set product id returned by loadedProductId(). This function is only
288 useful for the calendar loading code. 289 useful for the calendar loading code.
289 */ 290 */
290 void setLoadedProductId( const QString & ); 291 void setLoadedProductId( const QString & );
291 /** 292 /**
292 Return product id taken from file that has been loaded. Returns 293 Return product id taken from file that has been loaded. Returns
293 QString::null, if no calendar has been loaded. 294 QString::null, if no calendar has been loaded.
294 */ 295 */
295 QString loadedProductId(); 296 QString loadedProductId();
296 297
297 signals: 298 signals:
298 void calendarChanged(); 299 void calendarChanged();
299 void calendarSaved(); 300 void calendarSaved();
300 void calendarLoaded(); 301 void calendarLoaded();
301 void addAlarm(const QDateTime &qdt, const QString &noti ); 302 void addAlarm(const QDateTime &qdt, const QString &noti );
302 void removeAlarm(const QDateTime &qdt, const QString &noti ); 303 void removeAlarm(const QDateTime &qdt, const QString &noti );
303 304
304 protected: 305 protected:
305 /** 306 /**
306 Get unfiltered events, which occur on the given date. 307 Get unfiltered events, which occur on the given date.
307 */ 308 */
308 virtual QPtrList<Event> rawEventsForDate( const QDateTime &qdt ) = 0; 309 virtual QPtrList<Event> rawEventsForDate( const QDateTime &qdt ) = 0;
309 /** 310 /**
310 Get unfiltered events, which occur on the given date. 311 Get unfiltered events, which occur on the given date.
311 */ 312 */
312 virtual QPtrList<Event> rawEventsForDate( const QDate &date, 313 virtual QPtrList<Event> rawEventsForDate( const QDate &date,
313 bool sorted = false ) = 0; 314 bool sorted = false ) = 0;
314 /** 315 /**
315 Get events in a range of dates. If inclusive is set to true, only events 316 Get events in a range of dates. If inclusive is set to true, only events
316 are returned, which are completely included in the range. 317 are returned, which are completely included in the range.
317 */ 318 */
318 virtual QPtrList<Event> rawEvents( const QDate &start, const QDate &end, 319 virtual QPtrList<Event> rawEvents( const QDate &start, const QDate &end,
319 bool inclusive = false ) = 0; 320 bool inclusive = false ) = 0;
320 Incidence *mNextAlarmIncidence; 321 Incidence *mNextAlarmIncidence;
321 322
322private: 323private:
323 void init(); 324 void init();
324 325
325 QString mOwner; // who the calendar belongs to 326 QString mOwner; // who the calendar belongs to
326 QString mOwnerEmail; // email address of the owner 327 QString mOwnerEmail; // email address of the owner
327 int mTimeZone; // timezone OFFSET from GMT (MINUTES) 328 int mTimeZone; // timezone OFFSET from GMT (MINUTES)
328 bool mLocalTime; // use local time, not UTC or a time zone 329 bool mLocalTime; // use local time, not UTC or a time zone
329 330
330 CalFilter *mFilter; 331 CalFilter *mFilter;
331 CalFilter *mDefaultFilter; 332 CalFilter *mDefaultFilter;
332 333
333 QString mTimeZoneId; 334 QString mTimeZoneId;
334 335
335 Observer *mObserver; 336 Observer *mObserver;
336 bool mNewObserver; 337 bool mNewObserver;
337 338
338 bool mModified; 339 bool mModified;
339 340
340 QString mLoadedProductId; 341 QString mLoadedProductId;
341 342
342 // This list is used to put together related todos 343 // This list is used to put together related todos
343 QDict<Incidence> mOrphans; 344 QDict<Incidence> mOrphans;
344 QDict<Incidence> mOrphanUids; 345 QDict<Incidence> mOrphanUids;
345}; 346};
346 347
347} 348}
348 349
349#endif 350#endif
diff --git a/libkcal/calendarlocal.cpp b/libkcal/calendarlocal.cpp
index 8ff8b14..3c572f0 100644
--- a/libkcal/calendarlocal.cpp
+++ b/libkcal/calendarlocal.cpp
@@ -1,655 +1,686 @@
1/* 1/*
2 This file is part of libkcal. 2 This file is part of libkcal.
3 3
4 Copyright (c) 1998 Preston Brown 4 Copyright (c) 1998 Preston Brown
5 Copyright (c) 2001,2003 Cornelius Schumacher <schumacher@kde.org> 5 Copyright (c) 2001,2003 Cornelius Schumacher <schumacher@kde.org>
6 6
7 This library is free software; you can redistribute it and/or 7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public 8 modify it under the terms of the GNU Library General Public
9 License as published by the Free Software Foundation; either 9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version. 10 version 2 of the License, or (at your option) any later version.
11 11
12 This library is distributed in the hope that it will be useful, 12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Library General Public License for more details. 15 Library General Public License for more details.
16 16
17 You should have received a copy of the GNU Library General Public License 17 You should have received a copy of the GNU Library General Public License
18 along with this library; see the file COPYING.LIB. If not, write to 18 along with this library; see the file COPYING.LIB. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. 20 Boston, MA 02111-1307, USA.
21*/ 21*/
22 22
23#include <qdatetime.h> 23#include <qdatetime.h>
24#include <qstring.h> 24#include <qstring.h>
25#include <qptrlist.h> 25#include <qptrlist.h>
26 26
27#include <kdebug.h> 27#include <kdebug.h>
28#include <kconfig.h> 28#include <kconfig.h>
29#include <kglobal.h> 29#include <kglobal.h>
30#include <klocale.h> 30#include <klocale.h>
31 31
32#include "vcaldrag.h" 32#include "vcaldrag.h"
33#include "vcalformat.h" 33#include "vcalformat.h"
34#include "icalformat.h" 34#include "icalformat.h"
35#include "exceptions.h" 35#include "exceptions.h"
36#include "incidence.h" 36#include "incidence.h"
37#include "journal.h" 37#include "journal.h"
38#include "filestorage.h" 38#include "filestorage.h"
39#include "calfilter.h" 39#include "calfilter.h"
40 40
41#include "calendarlocal.h" 41#include "calendarlocal.h"
42 42
43// #ifndef DESKTOP_VERSION 43// #ifndef DESKTOP_VERSION
44// #include <qtopia/alarmserver.h> 44// #include <qtopia/alarmserver.h>
45// #endif 45// #endif
46using namespace KCal; 46using namespace KCal;
47 47
48CalendarLocal::CalendarLocal() 48CalendarLocal::CalendarLocal()
49 : Calendar() 49 : Calendar()
50{ 50{
51 init(); 51 init();
52} 52}
53 53
54CalendarLocal::CalendarLocal(const QString &timeZoneId) 54CalendarLocal::CalendarLocal(const QString &timeZoneId)
55 : Calendar(timeZoneId) 55 : Calendar(timeZoneId)
56{ 56{
57 init(); 57 init();
58} 58}
59 59
60void CalendarLocal::init() 60void CalendarLocal::init()
61{ 61{
62 mNextAlarmIncidence = 0; 62 mNextAlarmIncidence = 0;
63} 63}
64 64
65 65
66CalendarLocal::~CalendarLocal() 66CalendarLocal::~CalendarLocal()
67{ 67{
68 close(); 68 close();
69} 69}
70 70
71bool CalendarLocal::load( const QString &fileName ) 71bool CalendarLocal::load( const QString &fileName )
72{ 72{
73 FileStorage storage( this, fileName ); 73 FileStorage storage( this, fileName );
74 return storage.load(); 74 return storage.load();
75} 75}
76 76
77bool CalendarLocal::save( const QString &fileName, CalFormat *format ) 77bool CalendarLocal::save( const QString &fileName, CalFormat *format )
78{ 78{
79 FileStorage storage( this, fileName, format ); 79 FileStorage storage( this, fileName, format );
80 return storage.save(); 80 return storage.save();
81} 81}
82 82
83void CalendarLocal::close() 83void CalendarLocal::close()
84{ 84{
85 mEventList.setAutoDelete( true ); 85 mEventList.setAutoDelete( true );
86 mTodoList.setAutoDelete( true ); 86 mTodoList.setAutoDelete( true );
87 mJournalList.setAutoDelete( false ); 87 mJournalList.setAutoDelete( false );
88 88
89 mEventList.clear(); 89 mEventList.clear();
90 mTodoList.clear(); 90 mTodoList.clear();
91 mJournalList.clear(); 91 mJournalList.clear();
92 92
93 mEventList.setAutoDelete( false ); 93 mEventList.setAutoDelete( false );
94 mTodoList.setAutoDelete( false ); 94 mTodoList.setAutoDelete( false );
95 mJournalList.setAutoDelete( false ); 95 mJournalList.setAutoDelete( false );
96 96
97 setModified( false ); 97 setModified( false );
98} 98}
99
100bool CalendarLocal::addAnniversaryNoDup( Event *event )
101{
102 QString cat;
103 bool isBirthday = true;
104 if( event->categoriesStr() == i18n( "Anniversary" ) ) {
105 isBirthday = false;
106 cat = i18n( "Anniversary" );
107 } else if( event->categoriesStr() == i18n( "Birthday" ) ) {
108 isBirthday = true;
109 cat = i18n( "Birthday" );
110 } else {
111 qDebug("addAnniversaryNoDup called without fitting category! ");
112 return false;
113 }
114 Event * eve;
115 for ( eve = mEventList.first(); eve ; eve = mEventList.next() ) {
116 if ( !(eve->categories().contains( cat ) ))
117 continue;
118 // now we have an event with fitting category
119 if ( eve->dtStart().date() != event->dtStart().date() )
120 continue;
121 // now we have an event with fitting category+date
122 if ( eve->summary() != event->summary() )
123 continue;
124 // now we have an event with fitting category+date+summary
125 return false;
126 }
127 return addEvent( event );
128
129}
99bool CalendarLocal::addEventNoDup( Event *event ) 130bool CalendarLocal::addEventNoDup( Event *event )
100{ 131{
101 Event * eve; 132 Event * eve;
102 for ( eve = mEventList.first(); eve ; eve = mEventList.next() ) { 133 for ( eve = mEventList.first(); eve ; eve = mEventList.next() ) {
103 if ( *eve == *event ) { 134 if ( *eve == *event ) {
104 //qDebug("CalendarLocal::Duplicate event found! Not inserted! "); 135 //qDebug("CalendarLocal::Duplicate event found! Not inserted! ");
105 return false; 136 return false;
106 } 137 }
107 } 138 }
108 return addEvent( event ); 139 return addEvent( event );
109} 140}
110 141
111bool CalendarLocal::addEvent( Event *event ) 142bool CalendarLocal::addEvent( Event *event )
112{ 143{
113 insertEvent( event ); 144 insertEvent( event );
114 145
115 event->registerObserver( this ); 146 event->registerObserver( this );
116 147
117 setModified( true ); 148 setModified( true );
118 149
119 return true; 150 return true;
120} 151}
121 152
122void CalendarLocal::deleteEvent( Event *event ) 153void CalendarLocal::deleteEvent( Event *event )
123{ 154{
124 155
125 156
126 if ( mEventList.removeRef( event ) ) { 157 if ( mEventList.removeRef( event ) ) {
127 setModified( true ); 158 setModified( true );
128 } 159 }
129} 160}
130 161
131 162
132Event *CalendarLocal::event( const QString &uid ) 163Event *CalendarLocal::event( const QString &uid )
133{ 164{
134 165
135 Event *event; 166 Event *event;
136 167
137 for ( event = mEventList.first(); event; event = mEventList.next() ) { 168 for ( event = mEventList.first(); event; event = mEventList.next() ) {
138 if ( event->uid() == uid ) { 169 if ( event->uid() == uid ) {
139 return event; 170 return event;
140 } 171 }
141 } 172 }
142 173
143 return 0; 174 return 0;
144} 175}
145bool CalendarLocal::addTodoNoDup( Todo *todo ) 176bool CalendarLocal::addTodoNoDup( Todo *todo )
146{ 177{
147 Todo * eve; 178 Todo * eve;
148 for ( eve = mTodoList.first(); eve ; eve = mTodoList.next() ) { 179 for ( eve = mTodoList.first(); eve ; eve = mTodoList.next() ) {
149 if ( *eve == *todo ) { 180 if ( *eve == *todo ) {
150 //qDebug("duplicate todo found! not inserted! "); 181 //qDebug("duplicate todo found! not inserted! ");
151 return false; 182 return false;
152 } 183 }
153 } 184 }
154 return addTodo( todo ); 185 return addTodo( todo );
155} 186}
156bool CalendarLocal::addTodo( Todo *todo ) 187bool CalendarLocal::addTodo( Todo *todo )
157{ 188{
158 mTodoList.append( todo ); 189 mTodoList.append( todo );
159 190
160 todo->registerObserver( this ); 191 todo->registerObserver( this );
161 192
162 // Set up subtask relations 193 // Set up subtask relations
163 setupRelations( todo ); 194 setupRelations( todo );
164 195
165 setModified( true ); 196 setModified( true );
166 197
167 return true; 198 return true;
168} 199}
169 200
170void CalendarLocal::deleteTodo( Todo *todo ) 201void CalendarLocal::deleteTodo( Todo *todo )
171{ 202{
172 // Handle orphaned children 203 // Handle orphaned children
173 removeRelations( todo ); 204 removeRelations( todo );
174 205
175 if ( mTodoList.removeRef( todo ) ) { 206 if ( mTodoList.removeRef( todo ) ) {
176 setModified( true ); 207 setModified( true );
177 } 208 }
178} 209}
179 210
180QPtrList<Todo> CalendarLocal::rawTodos() 211QPtrList<Todo> CalendarLocal::rawTodos()
181{ 212{
182 return mTodoList; 213 return mTodoList;
183} 214}
184Todo *CalendarLocal::todo( int id ) 215Todo *CalendarLocal::todo( int id )
185{ 216{
186 Todo *todo; 217 Todo *todo;
187 for ( todo = mTodoList.first(); todo; todo = mTodoList.next() ) { 218 for ( todo = mTodoList.first(); todo; todo = mTodoList.next() ) {
188 if ( todo->zaurusId() == id ) return todo; 219 if ( todo->zaurusId() == id ) return todo;
189 } 220 }
190 221
191 return 0; 222 return 0;
192} 223}
193 224
194Event *CalendarLocal::event( int id ) 225Event *CalendarLocal::event( int id )
195{ 226{
196 Event *todo; 227 Event *todo;
197 for ( todo = mEventList.first(); todo; todo = mEventList.next() ) { 228 for ( todo = mEventList.first(); todo; todo = mEventList.next() ) {
198 if ( todo->zaurusId() == id ) return todo; 229 if ( todo->zaurusId() == id ) return todo;
199 } 230 }
200 231
201 return 0; 232 return 0;
202} 233}
203Todo *CalendarLocal::todo( const QString &uid ) 234Todo *CalendarLocal::todo( const QString &uid )
204{ 235{
205 Todo *todo; 236 Todo *todo;
206 for ( todo = mTodoList.first(); todo; todo = mTodoList.next() ) { 237 for ( todo = mTodoList.first(); todo; todo = mTodoList.next() ) {
207 if ( todo->uid() == uid ) return todo; 238 if ( todo->uid() == uid ) return todo;
208 } 239 }
209 240
210 return 0; 241 return 0;
211} 242}
212QString CalendarLocal::nextSummary() const 243QString CalendarLocal::nextSummary() const
213{ 244{
214 return mNextSummary; 245 return mNextSummary;
215} 246}
216QDateTime CalendarLocal::nextAlarmEventDateTime() const 247QDateTime CalendarLocal::nextAlarmEventDateTime() const
217{ 248{
218 return mNextAlarmEventDateTime; 249 return mNextAlarmEventDateTime;
219} 250}
220void CalendarLocal::checkAlarmForIncidence( Incidence * incidence, bool deleted) 251void CalendarLocal::checkAlarmForIncidence( Incidence * incidence, bool deleted)
221{ 252{
222 //mNextAlarmIncidence 253 //mNextAlarmIncidence
223 //mNextAlarmDateTime 254 //mNextAlarmDateTime
224 //return mNextSummary; 255 //return mNextSummary;
225 //return mNextAlarmEventDateTime; 256 //return mNextAlarmEventDateTime;
226 bool newNextAlarm = false; 257 bool newNextAlarm = false;
227 bool computeNextAlarm = false; 258 bool computeNextAlarm = false;
228 bool ok; 259 bool ok;
229 int offset; 260 int offset;
230 QDateTime nextA; 261 QDateTime nextA;
231 // QString nextSum; 262 // QString nextSum;
232 //QDateTime nextEvent; 263 //QDateTime nextEvent;
233 if ( mNextAlarmIncidence == 0 || incidence == 0 ) { 264 if ( mNextAlarmIncidence == 0 || incidence == 0 ) {
234 computeNextAlarm = true; 265 computeNextAlarm = true;
235 } else { 266 } else {
236 if ( ! deleted ) { 267 if ( ! deleted ) {
237 nextA = incidence->getNextAlarmDateTime(& ok, &offset ) ; 268 nextA = incidence->getNextAlarmDateTime(& ok, &offset ) ;
238 if ( ok ) { 269 if ( ok ) {
239 if ( nextA < mNextAlarmDateTime ) { 270 if ( nextA < mNextAlarmDateTime ) {
240 deRegisterAlarm(); 271 deRegisterAlarm();
241 mNextAlarmDateTime = nextA; 272 mNextAlarmDateTime = nextA;
242 mNextSummary = incidence->summary(); 273 mNextSummary = incidence->summary();
243 mNextAlarmEventDateTime = nextA.addSecs(offset ) ; 274 mNextAlarmEventDateTime = nextA.addSecs(offset ) ;
244 mNextAlarmEventDateTimeString = KGlobal::locale()->formatDateTime(mNextAlarmEventDateTime); 275 mNextAlarmEventDateTimeString = KGlobal::locale()->formatDateTime(mNextAlarmEventDateTime);
245 newNextAlarm = true; 276 newNextAlarm = true;
246 mNextAlarmIncidence = incidence; 277 mNextAlarmIncidence = incidence;
247 } else { 278 } else {
248 if ( incidence == mNextAlarmIncidence ) { 279 if ( incidence == mNextAlarmIncidence ) {
249 computeNextAlarm = true; 280 computeNextAlarm = true;
250 } 281 }
251 } 282 }
252 } else { 283 } else {
253 if ( mNextAlarmIncidence == incidence ) { 284 if ( mNextAlarmIncidence == incidence ) {
254 computeNextAlarm = true; 285 computeNextAlarm = true;
255 } 286 }
256 } 287 }
257 } else { // deleted 288 } else { // deleted
258 if ( incidence == mNextAlarmIncidence ) { 289 if ( incidence == mNextAlarmIncidence ) {
259 computeNextAlarm = true; 290 computeNextAlarm = true;
260 } 291 }
261 } 292 }
262 } 293 }
263 if ( computeNextAlarm ) { 294 if ( computeNextAlarm ) {
264 deRegisterAlarm(); 295 deRegisterAlarm();
265 nextA = nextAlarm( 1000 ); 296 nextA = nextAlarm( 1000 );
266 if (! mNextAlarmIncidence ) { 297 if (! mNextAlarmIncidence ) {
267 return; 298 return;
268 } 299 }
269 newNextAlarm = true; 300 newNextAlarm = true;
270 } 301 }
271 if ( newNextAlarm ) 302 if ( newNextAlarm )
272 registerAlarm(); 303 registerAlarm();
273} 304}
274QString CalendarLocal:: getAlarmNotification() 305QString CalendarLocal:: getAlarmNotification()
275{ 306{
276 QString ret; 307 QString ret;
277 // this should not happen 308 // this should not happen
278 if (! mNextAlarmIncidence ) 309 if (! mNextAlarmIncidence )
279 return "cal_alarm"+ mNextSummary.left( 25 )+"\n"+mNextAlarmEventDateTimeString; 310 return "cal_alarm"+ mNextSummary.left( 25 )+"\n"+mNextAlarmEventDateTimeString;
280 Alarm* alarm = mNextAlarmIncidence->alarms().first(); 311 Alarm* alarm = mNextAlarmIncidence->alarms().first();
281 if ( alarm->type() == Alarm::Procedure ) { 312 if ( alarm->type() == Alarm::Procedure ) {
282 ret = "proc_alarm" + alarm->programFile()+"+++"; 313 ret = "proc_alarm" + alarm->programFile()+"+++";
283 } else { 314 } else {
284 ret = "audio_alarm" +alarm->audioFile() +"+++"; 315 ret = "audio_alarm" +alarm->audioFile() +"+++";
285 } 316 }
286 ret += "cal_alarm"+ mNextSummary.left( 25 ); 317 ret += "cal_alarm"+ mNextSummary.left( 25 );
287 if ( mNextSummary.length() > 25 ) 318 if ( mNextSummary.length() > 25 )
288 ret += "\n" + mNextSummary.mid(25, 25 ); 319 ret += "\n" + mNextSummary.mid(25, 25 );
289 ret+= "\n"+mNextAlarmEventDateTimeString; 320 ret+= "\n"+mNextAlarmEventDateTimeString;
290 return ret; 321 return ret;
291} 322}
292 323
293void CalendarLocal::registerAlarm() 324void CalendarLocal::registerAlarm()
294{ 325{
295 mLastAlarmNotificationString = getAlarmNotification(); 326 mLastAlarmNotificationString = getAlarmNotification();
296 // qDebug("++ register Alarm %s %s",mNextAlarmDateTime.toString().latin1(), mLastAlarmNotificationString.latin1() ); 327 // qDebug("++ register Alarm %s %s",mNextAlarmDateTime.toString().latin1(), mLastAlarmNotificationString.latin1() );
297 emit addAlarm ( mNextAlarmDateTime, mLastAlarmNotificationString ); 328 emit addAlarm ( mNextAlarmDateTime, mLastAlarmNotificationString );
298// #ifndef DESKTOP_VERSION 329// #ifndef DESKTOP_VERSION
299// AlarmServer::addAlarm ( mNextAlarmDateTime,"koalarm", mLastAlarmNotificationString.latin1() ); 330// AlarmServer::addAlarm ( mNextAlarmDateTime,"koalarm", mLastAlarmNotificationString.latin1() );
300// #endif 331// #endif
301} 332}
302void CalendarLocal::deRegisterAlarm() 333void CalendarLocal::deRegisterAlarm()
303{ 334{
304 if ( mLastAlarmNotificationString.isNull() ) 335 if ( mLastAlarmNotificationString.isNull() )
305 return; 336 return;
306 //qDebug("-- deregister Alarm %s ", mLastAlarmNotificationString.latin1() ); 337 //qDebug("-- deregister Alarm %s ", mLastAlarmNotificationString.latin1() );
307 338
308 emit removeAlarm ( mNextAlarmDateTime, mLastAlarmNotificationString ); 339 emit removeAlarm ( mNextAlarmDateTime, mLastAlarmNotificationString );
309// #ifndef DESKTOP_VERSION 340// #ifndef DESKTOP_VERSION
310// AlarmServer::deleteAlarm (mNextAlarmDateTime ,"koalarm" ,mLastAlarmNotificationString.latin1() ); 341// AlarmServer::deleteAlarm (mNextAlarmDateTime ,"koalarm" ,mLastAlarmNotificationString.latin1() );
311// #endif 342// #endif
312} 343}
313 344
314QPtrList<Todo> CalendarLocal::todos( const QDate &date ) 345QPtrList<Todo> CalendarLocal::todos( const QDate &date )
315{ 346{
316 QPtrList<Todo> todos; 347 QPtrList<Todo> todos;
317 348
318 Todo *todo; 349 Todo *todo;
319 for ( todo = mTodoList.first(); todo; todo = mTodoList.next() ) { 350 for ( todo = mTodoList.first(); todo; todo = mTodoList.next() ) {
320 if ( todo->hasDueDate() && todo->dtDue().date() == date ) { 351 if ( todo->hasDueDate() && todo->dtDue().date() == date ) {
321 todos.append( todo ); 352 todos.append( todo );
322 } 353 }
323 } 354 }
324 355
325 filter()->apply( &todos ); 356 filter()->apply( &todos );
326 return todos; 357 return todos;
327} 358}
328void CalendarLocal::reInitAlarmSettings() 359void CalendarLocal::reInitAlarmSettings()
329{ 360{
330 if ( !mNextAlarmIncidence ) { 361 if ( !mNextAlarmIncidence ) {
331 nextAlarm( 1000 ); 362 nextAlarm( 1000 );
332 } 363 }
333 deRegisterAlarm(); 364 deRegisterAlarm();
334 mNextAlarmIncidence = 0; 365 mNextAlarmIncidence = 0;
335 checkAlarmForIncidence( 0, false ); 366 checkAlarmForIncidence( 0, false );
336 367
337} 368}
338 369
339 370
340 371
341QDateTime CalendarLocal::nextAlarm( int daysTo ) 372QDateTime CalendarLocal::nextAlarm( int daysTo )
342{ 373{
343 QDateTime nextA = QDateTime::currentDateTime().addDays( daysTo ); 374 QDateTime nextA = QDateTime::currentDateTime().addDays( daysTo );
344 QDateTime start = QDateTime::currentDateTime().addSecs( 30 ); 375 QDateTime start = QDateTime::currentDateTime().addSecs( 30 );
345 QDateTime next; 376 QDateTime next;
346 Event *e; 377 Event *e;
347 bool ok; 378 bool ok;
348 bool found = false; 379 bool found = false;
349 int offset; 380 int offset;
350 mNextAlarmIncidence = 0; 381 mNextAlarmIncidence = 0;
351 for( e = mEventList.first(); e; e = mEventList.next() ) { 382 for( e = mEventList.first(); e; e = mEventList.next() ) {
352 next = e->getNextAlarmDateTime(& ok, &offset ) ; 383 next = e->getNextAlarmDateTime(& ok, &offset ) ;
353 if ( ok ) { 384 if ( ok ) {
354 if ( next < nextA ) { 385 if ( next < nextA ) {
355 nextA = next; 386 nextA = next;
356 found = true; 387 found = true;
357 mNextSummary = e->summary(); 388 mNextSummary = e->summary();
358 mNextAlarmEventDateTime = next.addSecs(offset ) ; 389 mNextAlarmEventDateTime = next.addSecs(offset ) ;
359 mNextAlarmIncidence = (Incidence *) e; 390 mNextAlarmIncidence = (Incidence *) e;
360 } 391 }
361 } 392 }
362 } 393 }
363 Todo *t; 394 Todo *t;
364 for( t = mTodoList.first(); t; t = mTodoList.next() ) { 395 for( t = mTodoList.first(); t; t = mTodoList.next() ) {
365 next = t->getNextAlarmDateTime(& ok, &offset ) ; 396 next = t->getNextAlarmDateTime(& ok, &offset ) ;
366 if ( ok ) { 397 if ( ok ) {
367 if ( next < nextA ) { 398 if ( next < nextA ) {
368 nextA = next; 399 nextA = next;
369 found = true; 400 found = true;
370 mNextSummary = t->summary(); 401 mNextSummary = t->summary();
371 mNextAlarmEventDateTime = next.addSecs(offset ); 402 mNextAlarmEventDateTime = next.addSecs(offset );
372 mNextAlarmIncidence = (Incidence *) t; 403 mNextAlarmIncidence = (Incidence *) t;
373 } 404 }
374 } 405 }
375 } 406 }
376 if ( mNextAlarmIncidence ) { 407 if ( mNextAlarmIncidence ) {
377 mNextAlarmEventDateTimeString = KGlobal::locale()->formatDateTime(mNextAlarmEventDateTime); 408 mNextAlarmEventDateTimeString = KGlobal::locale()->formatDateTime(mNextAlarmEventDateTime);
378 mNextAlarmDateTime = nextA; 409 mNextAlarmDateTime = nextA;
379 } 410 }
380 return nextA; 411 return nextA;
381} 412}
382Alarm::List CalendarLocal::alarmsTo( const QDateTime &to ) 413Alarm::List CalendarLocal::alarmsTo( const QDateTime &to )
383{ 414{
384 return alarms( QDateTime( QDate( 1900, 1, 1 ) ), to ); 415 return alarms( QDateTime( QDate( 1900, 1, 1 ) ), to );
385} 416}
386 417
387Alarm::List CalendarLocal::alarms( const QDateTime &from, const QDateTime &to ) 418Alarm::List CalendarLocal::alarms( const QDateTime &from, const QDateTime &to )
388{ 419{
389 kdDebug(5800) << "CalendarLocal::alarms(" << from.toString() << " - " 420 kdDebug(5800) << "CalendarLocal::alarms(" << from.toString() << " - "
390 << to.toString() << ")\n"; 421 << to.toString() << ")\n";
391 422
392 Alarm::List alarms; 423 Alarm::List alarms;
393 424
394 Event *e; 425 Event *e;
395 426
396 for( e = mEventList.first(); e; e = mEventList.next() ) { 427 for( e = mEventList.first(); e; e = mEventList.next() ) {
397 if ( e->doesRecur() ) appendRecurringAlarms( alarms, e, from, to ); 428 if ( e->doesRecur() ) appendRecurringAlarms( alarms, e, from, to );
398 else appendAlarms( alarms, e, from, to ); 429 else appendAlarms( alarms, e, from, to );
399 } 430 }
400 431
401 Todo *t; 432 Todo *t;
402 for( t = mTodoList.first(); t; t = mTodoList.next() ) { 433 for( t = mTodoList.first(); t; t = mTodoList.next() ) {
403 appendAlarms( alarms, t, from, to ); 434 appendAlarms( alarms, t, from, to );
404 } 435 }
405 436
406 return alarms; 437 return alarms;
407} 438}
408 439
409void CalendarLocal::appendAlarms( Alarm::List &alarms, Incidence *incidence, 440void CalendarLocal::appendAlarms( Alarm::List &alarms, Incidence *incidence,
410 const QDateTime &from, const QDateTime &to ) 441 const QDateTime &from, const QDateTime &to )
411{ 442{
412 QPtrList<Alarm> alarmList = incidence->alarms(); 443 QPtrList<Alarm> alarmList = incidence->alarms();
413 Alarm *alarm; 444 Alarm *alarm;
414 for( alarm = alarmList.first(); alarm; alarm = alarmList.next() ) { 445 for( alarm = alarmList.first(); alarm; alarm = alarmList.next() ) {
415// kdDebug(5800) << "CalendarLocal::appendAlarms() '" << alarm->text() 446// kdDebug(5800) << "CalendarLocal::appendAlarms() '" << alarm->text()
416// << "': " << alarm->time().toString() << " - " << alarm->enabled() << endl; 447// << "': " << alarm->time().toString() << " - " << alarm->enabled() << endl;
417 if ( alarm->enabled() ) { 448 if ( alarm->enabled() ) {
418 if ( alarm->time() >= from && alarm->time() <= to ) { 449 if ( alarm->time() >= from && alarm->time() <= to ) {
419 kdDebug(5800) << "CalendarLocal::appendAlarms() '" << incidence->summary() 450 kdDebug(5800) << "CalendarLocal::appendAlarms() '" << incidence->summary()
420 << "': " << alarm->time().toString() << endl; 451 << "': " << alarm->time().toString() << endl;
421 alarms.append( alarm ); 452 alarms.append( alarm );
422 } 453 }
423 } 454 }
424 } 455 }
425} 456}
426 457
427void CalendarLocal::appendRecurringAlarms( Alarm::List &alarms, 458void CalendarLocal::appendRecurringAlarms( Alarm::List &alarms,
428 Incidence *incidence, 459 Incidence *incidence,
429 const QDateTime &from, 460 const QDateTime &from,
430 const QDateTime &to ) 461 const QDateTime &to )
431{ 462{
432 463
433 QPtrList<Alarm> alarmList = incidence->alarms(); 464 QPtrList<Alarm> alarmList = incidence->alarms();
434 Alarm *alarm; 465 Alarm *alarm;
435 QDateTime qdt; 466 QDateTime qdt;
436 for( alarm = alarmList.first(); alarm; alarm = alarmList.next() ) { 467 for( alarm = alarmList.first(); alarm; alarm = alarmList.next() ) {
437 if (incidence->recursOn(from.date())) { 468 if (incidence->recursOn(from.date())) {
438 qdt.setTime(alarm->time().time()); 469 qdt.setTime(alarm->time().time());
439 qdt.setDate(from.date()); 470 qdt.setDate(from.date());
440 } 471 }
441 else qdt = alarm->time(); 472 else qdt = alarm->time();
442 // qDebug("1 %s %s %s", qdt.toString().latin1(), from.toString().latin1(), to.toString().latin1()); 473 // qDebug("1 %s %s %s", qdt.toString().latin1(), from.toString().latin1(), to.toString().latin1());
443 if ( alarm->enabled() ) { 474 if ( alarm->enabled() ) {
444 if ( qdt >= from && qdt <= to ) { 475 if ( qdt >= from && qdt <= to ) {
445 alarms.append( alarm ); 476 alarms.append( alarm );
446 } 477 }
447 } 478 }
448 } 479 }
449} 480}
450 481
451 482
452/****************************** PROTECTED METHODS ****************************/ 483/****************************** PROTECTED METHODS ****************************/
453 484
454// after changes are made to an event, this should be called. 485// after changes are made to an event, this should be called.
455void CalendarLocal::update( IncidenceBase *incidence ) 486void CalendarLocal::update( IncidenceBase *incidence )
456{ 487{
457 incidence->setSyncStatus( Event::SYNCMOD ); 488 incidence->setSyncStatus( Event::SYNCMOD );
458 incidence->setLastModified( QDateTime::currentDateTime() ); 489 incidence->setLastModified( QDateTime::currentDateTime() );
459 // we should probably update the revision number here, 490 // we should probably update the revision number here,
460 // or internally in the Event itself when certain things change. 491 // or internally in the Event itself when certain things change.
461 // need to verify with ical documentation. 492 // need to verify with ical documentation.
462 493
463 setModified( true ); 494 setModified( true );
464} 495}
465 496
466void CalendarLocal::insertEvent( Event *event ) 497void CalendarLocal::insertEvent( Event *event )
467{ 498{
468 if ( mEventList.findRef( event ) < 0 ) mEventList.append( event ); 499 if ( mEventList.findRef( event ) < 0 ) mEventList.append( event );
469} 500}
470 501
471 502
472QPtrList<Event> CalendarLocal::rawEventsForDate( const QDate &qd, bool sorted ) 503QPtrList<Event> CalendarLocal::rawEventsForDate( const QDate &qd, bool sorted )
473{ 504{
474 QPtrList<Event> eventList; 505 QPtrList<Event> eventList;
475 506
476 Event *event; 507 Event *event;
477 for( event = mEventList.first(); event; event = mEventList.next() ) { 508 for( event = mEventList.first(); event; event = mEventList.next() ) {
478 if ( event->doesRecur() ) { 509 if ( event->doesRecur() ) {
479 if ( event->isMultiDay() ) { 510 if ( event->isMultiDay() ) {
480 int extraDays = event->dtStart().date().daysTo( event->dtEnd().date() ); 511 int extraDays = event->dtStart().date().daysTo( event->dtEnd().date() );
481 int i; 512 int i;
482 for ( i = 0; i <= extraDays; i++ ) { 513 for ( i = 0; i <= extraDays; i++ ) {
483 if ( event->recursOn( qd.addDays( -i ) ) ) { 514 if ( event->recursOn( qd.addDays( -i ) ) ) {
484 eventList.append( event ); 515 eventList.append( event );
485 break; 516 break;
486 } 517 }
487 } 518 }
488 } else { 519 } else {
489 if ( event->recursOn( qd ) ) 520 if ( event->recursOn( qd ) )
490 eventList.append( event ); 521 eventList.append( event );
491 } 522 }
492 } else { 523 } else {
493 if ( event->dtStart().date() <= qd && event->dtEnd().date() >= qd ) { 524 if ( event->dtStart().date() <= qd && event->dtEnd().date() >= qd ) {
494 eventList.append( event ); 525 eventList.append( event );
495 } 526 }
496 } 527 }
497 } 528 }
498 529
499 if ( !sorted ) { 530 if ( !sorted ) {
500 return eventList; 531 return eventList;
501 } 532 }
502 533
503 // kdDebug(5800) << "Sorting events for date\n" << endl; 534 // kdDebug(5800) << "Sorting events for date\n" << endl;
504 // now, we have to sort it based on dtStart.time() 535 // now, we have to sort it based on dtStart.time()
505 QPtrList<Event> eventListSorted; 536 QPtrList<Event> eventListSorted;
506 Event *sortEvent; 537 Event *sortEvent;
507 for ( event = eventList.first(); event; event = eventList.next() ) { 538 for ( event = eventList.first(); event; event = eventList.next() ) {
508 sortEvent = eventListSorted.first(); 539 sortEvent = eventListSorted.first();
509 int i = 0; 540 int i = 0;
510 while ( sortEvent && event->dtStart().time()>=sortEvent->dtStart().time() ) 541 while ( sortEvent && event->dtStart().time()>=sortEvent->dtStart().time() )
511 { 542 {
512 i++; 543 i++;
513 sortEvent = eventListSorted.next(); 544 sortEvent = eventListSorted.next();
514 } 545 }
515 eventListSorted.insert( i, event ); 546 eventListSorted.insert( i, event );
516 } 547 }
517 return eventListSorted; 548 return eventListSorted;
518} 549}
519 550
520 551
521QPtrList<Event> CalendarLocal::rawEvents( const QDate &start, const QDate &end, 552QPtrList<Event> CalendarLocal::rawEvents( const QDate &start, const QDate &end,
522 bool inclusive ) 553 bool inclusive )
523{ 554{
524 Event *event = 0; 555 Event *event = 0;
525 556
526 QPtrList<Event> eventList; 557 QPtrList<Event> eventList;
527 558
528 // Get non-recurring events 559 // Get non-recurring events
529 for( event = mEventList.first(); event; event = mEventList.next() ) { 560 for( event = mEventList.first(); event; event = mEventList.next() ) {
530 if ( event->doesRecur() ) { 561 if ( event->doesRecur() ) {
531 QDate rStart = event->dtStart().date(); 562 QDate rStart = event->dtStart().date();
532 bool found = false; 563 bool found = false;
533 if ( inclusive ) { 564 if ( inclusive ) {
534 if ( rStart >= start && rStart <= end ) { 565 if ( rStart >= start && rStart <= end ) {
535 // Start date of event is in range. Now check for end date. 566 // Start date of event is in range. Now check for end date.
536 // if duration is negative, event recurs forever, so do not include it. 567 // if duration is negative, event recurs forever, so do not include it.
537 if ( event->recurrence()->duration() == 0 ) { // End date set 568 if ( event->recurrence()->duration() == 0 ) { // End date set
538 QDate rEnd = event->recurrence()->endDate(); 569 QDate rEnd = event->recurrence()->endDate();
539 if ( rEnd >= start && rEnd <= end ) { // End date within range 570 if ( rEnd >= start && rEnd <= end ) { // End date within range
540 found = true; 571 found = true;
541 } 572 }
542 } else if ( event->recurrence()->duration() > 0 ) { // Duration set 573 } else if ( event->recurrence()->duration() > 0 ) { // Duration set
543 // TODO: Calculate end date from duration. Should be done in Event 574 // TODO: Calculate end date from duration. Should be done in Event
544 // For now exclude all events with a duration. 575 // For now exclude all events with a duration.
545 } 576 }
546 } 577 }
547 } else { 578 } else {
548 bool founOne; 579 bool founOne;
549 QDate next = event->getNextOccurence( start, &founOne ).date(); 580 QDate next = event->getNextOccurence( start, &founOne ).date();
550 if ( founOne ) { 581 if ( founOne ) {
551 if ( next <= end ) { 582 if ( next <= end ) {
552 found = true; 583 found = true;
553 } 584 }
554 } 585 }
555 586
556 /* 587 /*
557 // crap !!! 588 // crap !!!
558 if ( rStart <= end ) { // Start date not after range 589 if ( rStart <= end ) { // Start date not after range
559 if ( rStart >= start ) { // Start date within range 590 if ( rStart >= start ) { // Start date within range
560 found = true; 591 found = true;
561 } else if ( event->recurrence()->duration() == -1 ) { // Recurs forever 592 } else if ( event->recurrence()->duration() == -1 ) { // Recurs forever
562 found = true; 593 found = true;
563 } else if ( event->recurrence()->duration() == 0 ) { // End date set 594 } else if ( event->recurrence()->duration() == 0 ) { // End date set
564 QDate rEnd = event->recurrence()->endDate(); 595 QDate rEnd = event->recurrence()->endDate();
565 if ( rEnd >= start && rEnd <= end ) { // End date within range 596 if ( rEnd >= start && rEnd <= end ) { // End date within range
566 found = true; 597 found = true;
567 } 598 }
568 } else { // Duration set 599 } else { // Duration set
569 // TODO: Calculate end date from duration. Should be done in Event 600 // TODO: Calculate end date from duration. Should be done in Event
570 // For now include all events with a duration. 601 // For now include all events with a duration.
571 found = true; 602 found = true;
572 } 603 }
573 } 604 }
574 */ 605 */
575 606
576 } 607 }
577 608
578 if ( found ) eventList.append( event ); 609 if ( found ) eventList.append( event );
579 } else { 610 } else {
580 QDate s = event->dtStart().date(); 611 QDate s = event->dtStart().date();
581 QDate e = event->dtEnd().date(); 612 QDate e = event->dtEnd().date();
582 613
583 if ( inclusive ) { 614 if ( inclusive ) {
584 if ( s >= start && e <= end ) { 615 if ( s >= start && e <= end ) {
585 eventList.append( event ); 616 eventList.append( event );
586 } 617 }
587 } else { 618 } else {
588 if ( ( s >= start && s <= end ) || ( e >= start && e <= end ) ) { 619 if ( ( s >= start && s <= end ) || ( e >= start && e <= end ) ) {
589 eventList.append( event ); 620 eventList.append( event );
590 } 621 }
591 } 622 }
592 } 623 }
593 } 624 }
594 625
595 return eventList; 626 return eventList;
596} 627}
597 628
598QPtrList<Event> CalendarLocal::rawEventsForDate( const QDateTime &qdt ) 629QPtrList<Event> CalendarLocal::rawEventsForDate( const QDateTime &qdt )
599{ 630{
600 return rawEventsForDate( qdt.date() ); 631 return rawEventsForDate( qdt.date() );
601} 632}
602 633
603QPtrList<Event> CalendarLocal::rawEvents() 634QPtrList<Event> CalendarLocal::rawEvents()
604{ 635{
605 return mEventList; 636 return mEventList;
606} 637}
607 638
608bool CalendarLocal::addJournal(Journal *journal) 639bool CalendarLocal::addJournal(Journal *journal)
609{ 640{
610 if ( journal->dtStart().isValid()) 641 if ( journal->dtStart().isValid())
611 kdDebug(5800) << "Adding Journal on " << journal->dtStart().toString() << endl; 642 kdDebug(5800) << "Adding Journal on " << journal->dtStart().toString() << endl;
612 else 643 else
613 kdDebug(5800) << "Adding Journal without a DTSTART" << endl; 644 kdDebug(5800) << "Adding Journal without a DTSTART" << endl;
614 645
615 mJournalList.append(journal); 646 mJournalList.append(journal);
616 647
617 journal->registerObserver( this ); 648 journal->registerObserver( this );
618 649
619 setModified( true ); 650 setModified( true );
620 651
621 return true; 652 return true;
622} 653}
623 654
624void CalendarLocal::deleteJournal( Journal *journal ) 655void CalendarLocal::deleteJournal( Journal *journal )
625{ 656{
626 if ( mJournalList.removeRef(journal) ) { 657 if ( mJournalList.removeRef(journal) ) {
627 setModified( true ); 658 setModified( true );
628 } 659 }
629} 660}
630 661
631Journal *CalendarLocal::journal( const QDate &date ) 662Journal *CalendarLocal::journal( const QDate &date )
632{ 663{
633// kdDebug(5800) << "CalendarLocal::journal() " << date.toString() << endl; 664// kdDebug(5800) << "CalendarLocal::journal() " << date.toString() << endl;
634 665
635 for ( Journal *it = mJournalList.first(); it; it = mJournalList.next() ) 666 for ( Journal *it = mJournalList.first(); it; it = mJournalList.next() )
636 if ( it->dtStart().date() == date ) 667 if ( it->dtStart().date() == date )
637 return it; 668 return it;
638 669
639 return 0; 670 return 0;
640} 671}
641 672
642Journal *CalendarLocal::journal( const QString &uid ) 673Journal *CalendarLocal::journal( const QString &uid )
643{ 674{
644 for ( Journal *it = mJournalList.first(); it; it = mJournalList.next() ) 675 for ( Journal *it = mJournalList.first(); it; it = mJournalList.next() )
645 if ( it->uid() == uid ) 676 if ( it->uid() == uid )
646 return it; 677 return it;
647 678
648 return 0; 679 return 0;
649} 680}
650 681
651QPtrList<Journal> CalendarLocal::journals() 682QPtrList<Journal> CalendarLocal::journals()
652{ 683{
653 return mJournalList; 684 return mJournalList;
654} 685}
655 686
diff --git a/libkcal/calendarlocal.h b/libkcal/calendarlocal.h
index a17cf11..a2e50e3 100644
--- a/libkcal/calendarlocal.h
+++ b/libkcal/calendarlocal.h
@@ -1,216 +1,217 @@
1/* 1/*
2 This file is part of libkcal. 2 This file is part of libkcal.
3 3
4 Copyright (c) 1998 Preston Brown 4 Copyright (c) 1998 Preston Brown
5 Copyright (c) 2001,2003 Cornelius Schumacher <schumacher@kde.org> 5 Copyright (c) 2001,2003 Cornelius Schumacher <schumacher@kde.org>
6 6
7 This library is free software; you can redistribute it and/or 7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public 8 modify it under the terms of the GNU Library General Public
9 License as published by the Free Software Foundation; either 9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version. 10 version 2 of the License, or (at your option) any later version.
11 11
12 This library is distributed in the hope that it will be useful, 12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Library General Public License for more details. 15 Library General Public License for more details.
16 16
17 You should have received a copy of the GNU Library General Public License 17 You should have received a copy of the GNU Library General Public License
18 along with this library; see the file COPYING.LIB. If not, write to 18 along with this library; see the file COPYING.LIB. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. 20 Boston, MA 02111-1307, USA.
21*/ 21*/
22#ifndef KCAL_CALENDARLOCAL_H 22#ifndef KCAL_CALENDARLOCAL_H
23#define KCAL_CALENDARLOCAL_H 23#define KCAL_CALENDARLOCAL_H
24 24
25#include "calendar.h" 25#include "calendar.h"
26 26
27namespace KCal { 27namespace KCal {
28 28
29class CalFormat; 29class CalFormat;
30 30
31/** 31/**
32 This class provides a calendar stored as a local file. 32 This class provides a calendar stored as a local file.
33*/ 33*/
34class CalendarLocal : public Calendar 34class CalendarLocal : public Calendar
35{ 35{
36 public: 36 public:
37 /** 37 /**
38 Constructs a new calendar, with variables initialized to sane values. 38 Constructs a new calendar, with variables initialized to sane values.
39 */ 39 */
40 CalendarLocal(); 40 CalendarLocal();
41 /** 41 /**
42 Constructs a new calendar, with variables initialized to sane values. 42 Constructs a new calendar, with variables initialized to sane values.
43 */ 43 */
44 CalendarLocal( const QString &timeZoneId ); 44 CalendarLocal( const QString &timeZoneId );
45 ~CalendarLocal(); 45 ~CalendarLocal();
46 46
47 /** 47 /**
48 Loads a calendar on disk in vCalendar or iCalendar format into the current 48 Loads a calendar on disk in vCalendar or iCalendar format into the current
49 calendar. Any information already present is lost. 49 calendar. Any information already present is lost.
50 @return true, if successfull, false on error. 50 @return true, if successfull, false on error.
51 @param fileName the name of the calendar on disk. 51 @param fileName the name of the calendar on disk.
52 */ 52 */
53 bool load( const QString &fileName ); 53 bool load( const QString &fileName );
54 /** 54 /**
55 Writes out the calendar to disk in the specified \a format. 55 Writes out the calendar to disk in the specified \a format.
56 CalendarLocal takes ownership of the CalFormat object. 56 CalendarLocal takes ownership of the CalFormat object.
57 @return true, if successfull, false on error. 57 @return true, if successfull, false on error.
58 @param fileName the name of the file 58 @param fileName the name of the file
59 */ 59 */
60 bool save( const QString &fileName, CalFormat *format = 0 ); 60 bool save( const QString &fileName, CalFormat *format = 0 );
61 61
62 /** 62 /**
63 Clears out the current calendar, freeing all used memory etc. etc. 63 Clears out the current calendar, freeing all used memory etc. etc.
64 */ 64 */
65 void close(); 65 void close();
66 66
67 void save() {} 67 void save() {}
68 68
69 /** 69 /**
70 Add Event to calendar. 70 Add Event to calendar.
71 */ 71 */
72 bool addAnniversaryNoDup( Event *event );
72 bool addEventNoDup( Event *event ); 73 bool addEventNoDup( Event *event );
73 bool addEvent( Event *event ); 74 bool addEvent( Event *event );
74 /** 75 /**
75 Deletes an event from this calendar. 76 Deletes an event from this calendar.
76 */ 77 */
77 void deleteEvent( Event *event ); 78 void deleteEvent( Event *event );
78 79
79 /** 80 /**
80 Retrieves an event on the basis of the unique string ID. 81 Retrieves an event on the basis of the unique string ID.
81 */ 82 */
82 Event *event( const QString &uid ); 83 Event *event( const QString &uid );
83 /** 84 /**
84 Return unfiltered list of all events in calendar. 85 Return unfiltered list of all events in calendar.
85 */ 86 */
86 QPtrList<Event> rawEvents(); 87 QPtrList<Event> rawEvents();
87 88
88 /** 89 /**
89 Add a todo to the todolist. 90 Add a todo to the todolist.
90 */ 91 */
91 bool addTodo( Todo *todo ); 92 bool addTodo( Todo *todo );
92 bool addTodoNoDup( Todo *todo ); 93 bool addTodoNoDup( Todo *todo );
93 /** 94 /**
94 Remove a todo from the todolist. 95 Remove a todo from the todolist.
95 */ 96 */
96 void deleteTodo( Todo * ); 97 void deleteTodo( Todo * );
97 /** 98 /**
98 Searches todolist for an event with this unique string identifier, 99 Searches todolist for an event with this unique string identifier,
99 returns a pointer or null. 100 returns a pointer or null.
100 */ 101 */
101 Todo *todo( const QString &uid ); 102 Todo *todo( const QString &uid );
102 /** 103 /**
103 Return list of all todos. 104 Return list of all todos.
104 */ 105 */
105 QPtrList<Todo> rawTodos(); 106 QPtrList<Todo> rawTodos();
106 /** 107 /**
107 Returns list of todos due on the specified date. 108 Returns list of todos due on the specified date.
108 */ 109 */
109 QPtrList<Todo> todos( const QDate &date ); 110 QPtrList<Todo> todos( const QDate &date );
110 /** 111 /**
111 Return list of all todos. 112 Return list of all todos.
112 113
113 Workaround because compiler does not recognize function of base class. 114 Workaround because compiler does not recognize function of base class.
114 */ 115 */
115 QPtrList<Todo> todos() { return Calendar::todos(); } 116 QPtrList<Todo> todos() { return Calendar::todos(); }
116 117
117 /** 118 /**
118 Add a Journal entry to calendar. 119 Add a Journal entry to calendar.
119 */ 120 */
120 bool addJournal( Journal * ); 121 bool addJournal( Journal * );
121 /** 122 /**
122 Remove a Journal from the calendar. 123 Remove a Journal from the calendar.
123 */ 124 */
124 void deleteJournal( Journal * ); 125 void deleteJournal( Journal * );
125 /** 126 /**
126 Return Journal for given date. 127 Return Journal for given date.
127 */ 128 */
128 Journal *journal( const QDate & ); 129 Journal *journal( const QDate & );
129 /** 130 /**
130 Return Journal with given UID. 131 Return Journal with given UID.
131 */ 132 */
132 Journal *journal( const QString &uid ); 133 Journal *journal( const QString &uid );
133 /** 134 /**
134 Return list of all Journals stored in calendar. 135 Return list of all Journals stored in calendar.
135 */ 136 */
136 QPtrList<Journal> journals(); 137 QPtrList<Journal> journals();
137 138
138 /** 139 /**
139 Return all alarms, which ocur in the given time interval. 140 Return all alarms, which ocur in the given time interval.
140 */ 141 */
141 Alarm::List alarms( const QDateTime &from, const QDateTime &to ); 142 Alarm::List alarms( const QDateTime &from, const QDateTime &to );
142 143
143 /** 144 /**
144 Return all alarms, which ocur before given date. 145 Return all alarms, which ocur before given date.
145 */ 146 */
146 Alarm::List alarmsTo( const QDateTime &to ); 147 Alarm::List alarmsTo( const QDateTime &to );
147 148
148 QDateTime nextAlarm( int daysTo ) ; 149 QDateTime nextAlarm( int daysTo ) ;
149 QDateTime nextAlarmEventDateTime() const; 150 QDateTime nextAlarmEventDateTime() const;
150 void checkAlarmForIncidence( Incidence *, bool deleted ) ; 151 void checkAlarmForIncidence( Incidence *, bool deleted ) ;
151 void registerAlarm(); 152 void registerAlarm();
152 void deRegisterAlarm(); 153 void deRegisterAlarm();
153 QString getAlarmNotification(); 154 QString getAlarmNotification();
154 QString nextSummary() const ; 155 QString nextSummary() const ;
155 /** 156 /**
156 This method should be called whenever a Event is modified directly 157 This method should be called whenever a Event is modified directly
157 via it's pointer. It makes sure that the calendar is internally 158 via it's pointer. It makes sure that the calendar is internally
158 consistent. 159 consistent.
159 */ 160 */
160 void update( IncidenceBase *incidence ); 161 void update( IncidenceBase *incidence );
161 162
162 /** 163 /**
163 Builds and then returns a list of all events that match for the 164 Builds and then returns a list of all events that match for the
164 date specified. useful for dayView, etc. etc. 165 date specified. useful for dayView, etc. etc.
165 */ 166 */
166 QPtrList<Event> rawEventsForDate( const QDate &date, bool sorted = false ); 167 QPtrList<Event> rawEventsForDate( const QDate &date, bool sorted = false );
167 /** 168 /**
168 Get unfiltered events for date \a qdt. 169 Get unfiltered events for date \a qdt.
169 */ 170 */
170 QPtrList<Event> rawEventsForDate( const QDateTime &qdt ); 171 QPtrList<Event> rawEventsForDate( const QDateTime &qdt );
171 /** 172 /**
172 Get unfiltered events in a range of dates. If inclusive is set to true, 173 Get unfiltered events in a range of dates. If inclusive is set to true,
173 only events are returned, which are completely included in the range. 174 only events are returned, which are completely included in the range.
174 */ 175 */
175 QPtrList<Event> rawEvents( const QDate &start, const QDate &end, 176 QPtrList<Event> rawEvents( const QDate &start, const QDate &end,
176 bool inclusive = false ); 177 bool inclusive = false );
177 Todo *CalendarLocal::todo( int uid ); 178 Todo *CalendarLocal::todo( int uid );
178 Event *CalendarLocal::event( int uid ); 179 Event *CalendarLocal::event( int uid );
179 180
180 181
181 182
182 protected: 183 protected:
183 184
184 // Event* mNextAlarmEvent; 185 // Event* mNextAlarmEvent;
185 QString mNextSummary; 186 QString mNextSummary;
186 QString mNextAlarmEventDateTimeString; 187 QString mNextAlarmEventDateTimeString;
187 QString mLastAlarmNotificationString; 188 QString mLastAlarmNotificationString;
188 QDateTime mNextAlarmEventDateTime; 189 QDateTime mNextAlarmEventDateTime;
189 QDateTime mNextAlarmDateTime; 190 QDateTime mNextAlarmDateTime;
190 void reInitAlarmSettings(); 191 void reInitAlarmSettings();
191 192
192 /** Notification function of IncidenceBase::Observer. */ 193 /** Notification function of IncidenceBase::Observer. */
193 void incidenceUpdated( IncidenceBase *i ) { update( i ); } 194 void incidenceUpdated( IncidenceBase *i ) { update( i ); }
194 195
195 /** inserts an event into its "proper place" in the calendar. */ 196 /** inserts an event into its "proper place" in the calendar. */
196 void insertEvent( Event *event ); 197 void insertEvent( Event *event );
197 198
198 /** Append alarms of incidence in interval to list of alarms. */ 199 /** Append alarms of incidence in interval to list of alarms. */
199 void appendAlarms( Alarm::List &alarms, Incidence *incidence, 200 void appendAlarms( Alarm::List &alarms, Incidence *incidence,
200 const QDateTime &from, const QDateTime &to ); 201 const QDateTime &from, const QDateTime &to );
201 202
202 /** Append alarms of recurring events in interval to list of alarms. */ 203 /** Append alarms of recurring events in interval to list of alarms. */
203 void appendRecurringAlarms( Alarm::List &alarms, Incidence *incidence, 204 void appendRecurringAlarms( Alarm::List &alarms, Incidence *incidence,
204 const QDateTime &from, const QDateTime &to ); 205 const QDateTime &from, const QDateTime &to );
205 206
206 private: 207 private:
207 void init(); 208 void init();
208 209
209 QPtrList<Event> mEventList; 210 QPtrList<Event> mEventList;
210 QPtrList<Todo> mTodoList; 211 QPtrList<Todo> mTodoList;
211 QPtrList<Journal> mJournalList; 212 QPtrList<Journal> mJournalList;
212}; 213};
213 214
214} 215}
215 216
216#endif 217#endif
diff --git a/libkcal/icalformat.cpp b/libkcal/icalformat.cpp
index 5893db5..f2e7dfc 100644
--- a/libkcal/icalformat.cpp
+++ b/libkcal/icalformat.cpp
@@ -1,478 +1,480 @@
1/* 1/*
2 This file is part of libkcal. 2 This file is part of libkcal.
3 Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org> 3 Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
4 4
5 This library is free software; you can redistribute it and/or 5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public 6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either 7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version. 8 version 2 of the License, or (at your option) any later version.
9 9
10 This library is distributed in the hope that it will be useful, 10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details. 13 Library General Public License for more details.
14 14
15 You should have received a copy of the GNU Library General Public License 15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to 16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. 18 Boston, MA 02111-1307, USA.
19*/ 19*/
20 20
21#include <qdatetime.h> 21#include <qdatetime.h>
22#include <qstring.h> 22#include <qstring.h>
23#include <qptrlist.h> 23#include <qptrlist.h>
24#include <qregexp.h> 24#include <qregexp.h>
25#include <qclipboard.h> 25#include <qclipboard.h>
26#include <qfile.h> 26#include <qfile.h>
27#include <qtextstream.h> 27#include <qtextstream.h>
28#include <qtextcodec.h> 28#include <qtextcodec.h>
29#include <stdlib.h> 29#include <stdlib.h>
30 30
31#include <kdebug.h> 31#include <kdebug.h>
32#include <kglobal.h> 32#include <kglobal.h>
33#include <klocale.h> 33#include <klocale.h>
34 34
35extern "C" { 35extern "C" {
36 #include <ical.h> 36 #include <ical.h>
37 #include <icalss.h> 37 #include <icalss.h>
38 #include <icalparser.h> 38 #include <icalparser.h>
39 #include <icalrestriction.h> 39 #include <icalrestriction.h>
40} 40}
41 41
42#include "calendar.h" 42#include "calendar.h"
43#include "calendarlocal.h" 43#include "calendarlocal.h"
44#include "journal.h" 44#include "journal.h"
45 45
46#include "icalformat.h" 46#include "icalformat.h"
47#include "icalformatimpl.h" 47#include "icalformatimpl.h"
48 48
49#define _ICAL_VERSION "2.0" 49#define _ICAL_VERSION "2.0"
50 50
51using namespace KCal; 51using namespace KCal;
52 52
53ICalFormat::ICalFormat(bool quick ) 53ICalFormat::ICalFormat(bool quick )
54{ 54{
55 mQuicksave = false; //quick; 55 mQuicksave = false; //quick;
56 mImpl = new ICalFormatImpl( this ); 56 mImpl = new ICalFormatImpl( this );
57 tzOffsetMin = 0; 57 tzOffsetMin = 0;
58 //qDebug("new ICalFormat() "); 58 //qDebug("new ICalFormat() ");
59} 59}
60 60
61ICalFormat::~ICalFormat() 61ICalFormat::~ICalFormat()
62{ 62{
63 delete mImpl; 63 delete mImpl;
64 //qDebug("delete ICalFormat "); 64 //qDebug("delete ICalFormat ");
65} 65}
66 66
67bool ICalFormat::load( Calendar *calendar, const QString &fileName) 67bool ICalFormat::load( Calendar *calendar, const QString &fileName)
68{ 68{
69 69
70 clearException(); 70 clearException();
71 71
72 QFile file( fileName ); 72 QFile file( fileName );
73 if (!file.open( IO_ReadOnly ) ) { 73 if (!file.open( IO_ReadOnly ) ) {
74 setException(new ErrorFormat(ErrorFormat::LoadError)); 74 setException(new ErrorFormat(ErrorFormat::LoadError));
75 return false; 75 return false;
76 } 76 }
77 QTextStream ts( &file ); 77 QTextStream ts( &file );
78 QString text; 78 QString text;
79#if 0 79#if 0
80 if ( !mQuicksave ) { 80 if ( !mQuicksave ) {
81 qDebug("KO: No quickload!"); 81 qDebug("KO: No quickload!");
82 ts.setEncoding( QTextStream::Latin1 ); 82 ts.setEncoding( QTextStream::Latin1 );
83 text = ts.read(); 83 text = ts.read();
84 } else { 84 } else {
85 ts.setCodec( QTextCodec::codecForName("utf8") ); 85 ts.setCodec( QTextCodec::codecForName("utf8") );
86 text = ts.read(); 86 text = ts.read();
87 } 87 }
88#endif 88#endif
89 ts.setEncoding( QTextStream::Latin1 ); 89 ts.setEncoding( QTextStream::Latin1 );
90 text = ts.read(); 90 text = ts.read();
91 file.close(); 91 file.close();
92 92
93 return fromString( calendar, text ); 93 return fromString( calendar, text );
94} 94}
95 95
96//#include <qdatetime.h> 96//#include <qdatetime.h>
97bool ICalFormat::save( Calendar *calendar, const QString &fileName ) 97bool ICalFormat::save( Calendar *calendar, const QString &fileName )
98{ 98{
99 //kdDebug(5800) << "ICalFormat::save(): " << fileName << endl; 99 //kdDebug(5800) << "ICalFormat::save(): " << fileName << endl;
100 //qDebug("ICalFormat::save "); 100 //qDebug("ICalFormat::save ");
101 clearException(); 101 clearException();
102 QString text = toString( calendar ); 102 QString text = toString( calendar );
103 //return false; 103 //return false;
104 // qDebug("to string takes ms: %d ",is.elapsed() ); 104 // qDebug("to string takes ms: %d ",is.elapsed() );
105 if ( text.isNull() ) return false; 105 if ( text.isNull() ) return false;
106 106
107 // TODO: write backup file 107 // TODO: write backup file
108 //is.restart(); 108 //is.restart();
109 QFile file( fileName ); 109 QFile file( fileName );
110 if (!file.open( IO_WriteOnly ) ) { 110 if (!file.open( IO_WriteOnly ) ) {
111 setException(new ErrorFormat(ErrorFormat::SaveError, 111 setException(new ErrorFormat(ErrorFormat::SaveError,
112 i18n("Could not open file '%1'").arg(fileName))); 112 i18n("Could not open file '%1'").arg(fileName)));
113 return false; 113 return false;
114 } 114 }
115 QTextStream ts( &file ); 115 QTextStream ts( &file );
116 116
117// #ifdef DESKTOP_VERSION 117// #ifdef DESKTOP_VERSION
118// mQuicksave = false; 118// mQuicksave = false;
119// #endif 119// #endif
120// if ( mQuicksave ) { 120// if ( mQuicksave ) {
121// ts << text.utf8(); 121// ts << text.utf8();
122// } else { 122// } else {
123// ts.setEncoding( QTextStream::Latin1 ); 123// ts.setEncoding( QTextStream::Latin1 );
124// ts << text; 124// ts << text;
125// //ts << text.latin1(); 125// //ts << text.latin1();
126// } 126// }
127 ts.setEncoding( QTextStream::Latin1 ); 127 ts.setEncoding( QTextStream::Latin1 );
128 ts << text; 128 ts << text;
129 file.close(); 129 file.close();
130 //qDebug("saving file takes ms: %d ", is.elapsed() ); 130 //qDebug("saving file takes ms: %d ", is.elapsed() );
131 return true; 131 return true;
132} 132}
133 133
134bool ICalFormat::fromString( Calendar *cal, const QString &text ) 134bool ICalFormat::fromString( Calendar *cal, const QString &text )
135{ 135{
136 setTimeZone( cal->timeZoneId(), !cal->isLocalTime() ); 136 setTimeZone( cal->timeZoneId(), !cal->isLocalTime() );
137 // qDebug("ICalFormat::fromString tz: %s ", cal->timeZoneId().latin1()); 137 // qDebug("ICalFormat::fromString tz: %s ", cal->timeZoneId().latin1());
138 // Get first VCALENDAR component. 138 // Get first VCALENDAR component.
139 // TODO: Handle more than one VCALENDAR or non-VCALENDAR top components 139 // TODO: Handle more than one VCALENDAR or non-VCALENDAR top components
140 icalcomponent *calendar; 140 icalcomponent *calendar;
141 141
142 //calendar = icalcomponent_new_from_string( text.local8Bit().data()); 142 //calendar = icalcomponent_new_from_string( text.local8Bit().data());
143 // good calendar = icalcomponent_new_from_string( text.utf8().data()); 143 // good calendar = icalcomponent_new_from_string( text.utf8().data());
144 calendar = icalcomponent_new_from_string( (char*)text.latin1()); 144 calendar = icalcomponent_new_from_string( (char*)text.latin1());
145 if (!calendar) { 145 if (!calendar) {
146 setException(new ErrorFormat(ErrorFormat::ParseErrorIcal)); 146 setException(new ErrorFormat(ErrorFormat::ParseErrorIcal));
147 return false; 147 return false;
148 } 148 }
149 149
150 bool success = true; 150 bool success = true;
151 151
152 if (icalcomponent_isa(calendar) != ICAL_VCALENDAR_COMPONENT) { 152 if (icalcomponent_isa(calendar) != ICAL_VCALENDAR_COMPONENT) {
153 setException(new ErrorFormat(ErrorFormat::NoCalendar)); 153 setException(new ErrorFormat(ErrorFormat::NoCalendar));
154 success = false; 154 success = false;
155 } else { 155 } else {
156 // put all objects into their proper places 156 // put all objects into their proper places
157 if ( !mImpl->populate( cal, calendar ) ) { 157 if ( !mImpl->populate( cal, calendar ) ) {
158 if ( !exception() ) { 158 if ( !exception() ) {
159 setException(new ErrorFormat(ErrorFormat::ParseErrorKcal)); 159 setException(new ErrorFormat(ErrorFormat::ParseErrorKcal));
160 } 160 }
161 success = false; 161 success = false;
162 } else 162 } else
163 mLoadedProductId = mImpl->loadedProductId(); 163 mLoadedProductId = mImpl->loadedProductId();
164 } 164 }
165 165
166 icalcomponent_free( calendar ); 166 icalcomponent_free( calendar );
167 167
168 return success; 168 return success;
169} 169}
170 170
171Incidence *ICalFormat::fromString( const QString &text ) 171Incidence *ICalFormat::fromString( const QString &text )
172{ 172{
173 CalendarLocal cal( mTimeZoneId ); 173 CalendarLocal cal( mTimeZoneId );
174 fromString(&cal, text); 174 fromString(&cal, text);
175 175
176 Incidence *ical = 0; 176 Incidence *ical = 0;
177 QPtrList<Event> elist = cal.events(); 177 QPtrList<Event> elist = cal.events();
178 if ( elist.count() > 0 ) { 178 if ( elist.count() > 0 ) {
179 ical = elist.first(); 179 ical = elist.first();
180 } else { 180 } else {
181 QPtrList<Todo> tlist = cal.todos(); 181 QPtrList<Todo> tlist = cal.todos();
182 if ( tlist.count() > 0 ) { 182 if ( tlist.count() > 0 ) {
183 ical = tlist.first(); 183 ical = tlist.first();
184 } else { 184 } else {
185 QPtrList<Journal> jlist = cal.journals(); 185 QPtrList<Journal> jlist = cal.journals();
186 if ( jlist.count() > 0 ) { 186 if ( jlist.count() > 0 ) {
187 ical = jlist.first(); 187 ical = jlist.first();
188 } 188 }
189 } 189 }
190 } 190 }
191 return ical; 191 return ical;
192} 192}
193#include <qapp.h> 193#include <qapp.h>
194 194
195QString ICalFormat::toString( Calendar *cal ) 195QString ICalFormat::toString( Calendar *cal )
196{ 196{
197 197
198 setTimeZone( cal->timeZoneId(), !cal->isLocalTime() ); 198 setTimeZone( cal->timeZoneId(), !cal->isLocalTime() );
199 199
200 icalcomponent *calendar = mImpl->createCalendarComponent(cal); 200 icalcomponent *calendar = mImpl->createCalendarComponent(cal);
201 201
202 icalcomponent *component; 202 icalcomponent *component;
203 203
204 // todos 204 // todos
205 QPtrList<Todo> todoList = cal->rawTodos(); 205 QPtrList<Todo> todoList = cal->rawTodos();
206 QPtrListIterator<Todo> qlt(todoList); 206 QPtrListIterator<Todo> qlt(todoList);
207 for (; qlt.current(); ++qlt) { 207 for (; qlt.current(); ++qlt) {
208 component = mImpl->writeTodo(qlt.current()); 208 component = mImpl->writeTodo(qlt.current());
209 icalcomponent_add_component(calendar,component); 209 icalcomponent_add_component(calendar,component);
210 //qDebug(" todos "); 210 //qDebug(" todos ");
211 qApp->processEvents(); 211 qApp->processEvents();
212 } 212 }
213 // events 213 // events
214 QPtrList<Event> events = cal->rawEvents(); 214 QPtrList<Event> events = cal->rawEvents();
215 Event *ev; 215 Event *ev;
216 for(ev=events.first();ev;ev=events.next()) { 216 for(ev=events.first();ev;ev=events.next()) {
217 component = mImpl->writeEvent(ev); 217 component = mImpl->writeEvent(ev);
218 icalcomponent_add_component(calendar,component); 218 icalcomponent_add_component(calendar,component);
219 //qDebug("events "); 219 //qDebug("events ");
220 qApp->processEvents(); 220 qApp->processEvents();
221 } 221 }
222 222
223 // journals 223 // journals
224 QPtrList<Journal> journals = cal->journals(); 224 QPtrList<Journal> journals = cal->journals();
225 Journal *j; 225 Journal *j;
226 for(j=journals.first();j;j=journals.next()) { 226 for(j=journals.first();j;j=journals.next()) {
227 component = mImpl->writeJournal(j); 227 component = mImpl->writeJournal(j);
228 icalcomponent_add_component(calendar,component); 228 icalcomponent_add_component(calendar,component);
229 //qDebug("journals "); 229 //qDebug("journals ");
230 qApp->processEvents(); 230 qApp->processEvents();
231 } 231 }
232 const char *text; 232 const char *text;
233 QString ret =""; 233 QString ret ="";
234 text = icalcomponent_as_ical_string( calendar ); 234 text = icalcomponent_as_ical_string( calendar );
235 qApp->processEvents(); 235 qApp->processEvents();
236 236
237 // text = "BEGIN:VCALENDAR\nPRODID\n :-//K Desktop Environment//NONSGML libkcal 3.1//EN\nVERSION\n :2.0\nBEGIN:VEVENT\nDTSTAMP\n :20031231T213514Z\nORGANIZER\n :MAILTO:lutz@putz.de\nCREATED\n :20031231T213513Z\nUID\n :libkcal-1295166342.120\nSEQUENCE\n :0\nLAST-MODIFIED\n :20031231T213513Z\nSUMMARY\n :test1\nCLASS\n :PUBLIC\nPRIORITY\n :3\nDTSTART\n :20040101T090000Z\nDTEND\n :20040101T110000Z\nTRANSP\n :OPAQUE\nEND:VEVENT\nEND:VCALENDAR\n"; 237 // text = "BEGIN:VCALENDAR\nPRODID\n :-//K Desktop Environment//NONSGML libkcal 3.1//EN\nVERSION\n :2.0\nBEGIN:VEVENT\nDTSTAMP\n :20031231T213514Z\nORGANIZER\n :MAILTO:lutz@putz.de\nCREATED\n :20031231T213513Z\nUID\n :libkcal-1295166342.120\nSEQUENCE\n :0\nLAST-MODIFIED\n :20031231T213513Z\nSUMMARY\n :test1\nCLASS\n :PUBLIC\nPRIORITY\n :3\nDTSTART\n :20040101T090000Z\nDTEND\n :20040101T110000Z\nTRANSP\n :OPAQUE\nEND:VEVENT\nEND:VCALENDAR\n";
238 238
239 239
240 if ( text ) { 240 if ( text ) {
241 ret = QString ( text ); 241 ret = QString ( text );
242 } 242 }
243 icalcomponent_free( calendar ); 243 icalcomponent_free( calendar );
244 244
245 if (!text) { 245 if (!text) {
246 setException(new ErrorFormat(ErrorFormat::SaveError, 246 setException(new ErrorFormat(ErrorFormat::SaveError,
247 i18n("libical error"))); 247 i18n("libical error")));
248 return QString::null; 248 return QString::null;
249 } 249 }
250 250
251 return ret; 251 return ret;
252} 252}
253 253
254QString ICalFormat::toICalString( Incidence *incidence ) 254QString ICalFormat::toICalString( Incidence *incidence )
255{ 255{
256 CalendarLocal cal( mTimeZoneId ); 256 CalendarLocal cal( mTimeZoneId );
257 cal.addIncidence( incidence->clone() ); 257 cal.addIncidence( incidence->clone() );
258 return toString( &cal ); 258 return toString( &cal );
259} 259}
260 260
261QString ICalFormat::toString( Incidence *incidence ) 261QString ICalFormat::toString( Incidence *incidence )
262{ 262{
263 icalcomponent *component; 263 icalcomponent *component;
264 264
265 component = mImpl->writeIncidence( incidence ); 265 component = mImpl->writeIncidence( incidence );
266 266
267 const char *text = icalcomponent_as_ical_string( component ); 267 const char *text = icalcomponent_as_ical_string( component );
268 268
269 icalcomponent_free( component ); 269 icalcomponent_free( component );
270 270
271 return QString::fromLocal8Bit( text ); 271 return QString::fromLocal8Bit( text );
272} 272}
273 273
274QString ICalFormat::toString( Recurrence *recurrence ) 274QString ICalFormat::toString( Recurrence *recurrence )
275{ 275{
276 icalproperty *property; 276 icalproperty *property;
277 property = mImpl->writeRecurrenceRule( recurrence ); 277 property = mImpl->writeRecurrenceRule( recurrence );
278 const char *text = icalproperty_as_ical_string( property ); 278 const char *text = icalproperty_as_ical_string( property );
279 icalproperty_free( property ); 279 icalproperty_free( property );
280 return QString::fromLocal8Bit( text ); 280 return QString::fromLocal8Bit( text );
281} 281}
282/* 282/*
283bool ICalFormat::fromString( Recurrence * recurrence, const QString& rrule ) 283bool ICalFormat::fromString( Recurrence * recurrence, const QString& rrule )
284{ 284{
285 bool success = true; 285 bool success = true;
286 icalerror_clear_errno(); 286 icalerror_clear_errno();
287 struct icalrecurrencetype recur = icalrecurrencetype_from_string( rrule ); 287 struct icalrecurrencetype recur = icalrecurrencetype_from_string( rrule );
288 if ( icalerrno != ICAL_NO_ERROR ) { 288 if ( icalerrno != ICAL_NO_ERROR ) {
289 kdDebug() << "Recurrence parsing error: " << icalerror_strerror( icalerrno ) << endl; 289 kdDebug() << "Recurrence parsing error: " << icalerror_strerror( icalerrno ) << endl;
290 success = false; 290 success = false;
291 } 291 }
292 292
293 if ( success ) { 293 if ( success ) {
294 mImpl->readRecurrence( recur, recurrence ); 294 mImpl->readRecurrence( recur, recurrence );
295 } 295 }
296 296
297 return success; 297 return success;
298} 298}
299*/ 299*/
300 300
301QString ICalFormat::createScheduleMessage(IncidenceBase *incidence, 301QString ICalFormat::createScheduleMessage(IncidenceBase *incidence,
302 Scheduler::Method method) 302 Scheduler::Method method)
303{ 303{
304 icalcomponent *message = mImpl->createScheduleComponent(incidence,method); 304 icalcomponent *message = mImpl->createScheduleComponent(incidence,method);
305 305
306 QString messageText = icalcomponent_as_ical_string(message); 306 QString messageText = icalcomponent_as_ical_string(message);
307 307
308 308
309 309
310 return messageText; 310 return messageText;
311} 311}
312 312
313ScheduleMessage *ICalFormat::parseScheduleMessage( Calendar *cal, 313ScheduleMessage *ICalFormat::parseScheduleMessage( Calendar *cal,
314 const QString &messageText ) 314 const QString &messageText )
315{ 315{
316 setTimeZone( cal->timeZoneId(), !cal->isLocalTime() ); 316 setTimeZone( cal->timeZoneId(), !cal->isLocalTime() );
317 clearException(); 317 clearException();
318 318
319 if (messageText.isEmpty()) return 0; 319 if (messageText.isEmpty()) return 0;
320 320
321 icalcomponent *message; 321 icalcomponent *message;
322 message = icalparser_parse_string(messageText.local8Bit()); 322 message = icalparser_parse_string(messageText.local8Bit());
323 323
324 if (!message) return 0; 324 if (!message) return 0;
325 325
326 icalproperty *m = icalcomponent_get_first_property(message, 326 icalproperty *m = icalcomponent_get_first_property(message,
327 ICAL_METHOD_PROPERTY); 327 ICAL_METHOD_PROPERTY);
328 328
329 if (!m) return 0; 329 if (!m) return 0;
330 330
331 icalcomponent *c; 331 icalcomponent *c;
332 332
333 IncidenceBase *incidence = 0; 333 IncidenceBase *incidence = 0;
334 c = icalcomponent_get_first_component(message,ICAL_VEVENT_COMPONENT); 334 c = icalcomponent_get_first_component(message,ICAL_VEVENT_COMPONENT);
335 if (c) { 335 if (c) {
336 incidence = mImpl->readEvent(c); 336 incidence = mImpl->readEvent(c);
337 } 337 }
338 338
339 if (!incidence) { 339 if (!incidence) {
340 c = icalcomponent_get_first_component(message,ICAL_VTODO_COMPONENT); 340 c = icalcomponent_get_first_component(message,ICAL_VTODO_COMPONENT);
341 if (c) { 341 if (c) {
342 incidence = mImpl->readTodo(c); 342 incidence = mImpl->readTodo(c);
343 } 343 }
344 } 344 }
345 345
346 if (!incidence) { 346 if (!incidence) {
347 c = icalcomponent_get_first_component(message,ICAL_VFREEBUSY_COMPONENT); 347 c = icalcomponent_get_first_component(message,ICAL_VFREEBUSY_COMPONENT);
348 if (c) { 348 if (c) {
349 incidence = mImpl->readFreeBusy(c); 349 incidence = mImpl->readFreeBusy(c);
350 } 350 }
351 } 351 }
352 352
353 if (!incidence) { 353 if (!incidence) {
354 kdDebug() << "ICalFormat:parseScheduleMessage: object is not a freebusy, event or todo" << endl; 354 kdDebug() << "ICalFormat:parseScheduleMessage: object is not a freebusy, event or todo" << endl;
355 return 0; 355 return 0;
356 } 356 }
357 357
358 kdDebug(5800) << "ICalFormat::parseScheduleMessage() getting method..." << endl; 358 kdDebug(5800) << "ICalFormat::parseScheduleMessage() getting method..." << endl;
359 359
360 icalproperty_method icalmethod = icalproperty_get_method(m); 360 icalproperty_method icalmethod = icalproperty_get_method(m);
361 Scheduler::Method method; 361 Scheduler::Method method;
362 362
363 switch (icalmethod) { 363 switch (icalmethod) {
364 case ICAL_METHOD_PUBLISH: 364 case ICAL_METHOD_PUBLISH:
365 method = Scheduler::Publish; 365 method = Scheduler::Publish;
366 break; 366 break;
367 case ICAL_METHOD_REQUEST: 367 case ICAL_METHOD_REQUEST:
368 method = Scheduler::Request; 368 method = Scheduler::Request;
369 break; 369 break;
370 case ICAL_METHOD_REFRESH: 370 case ICAL_METHOD_REFRESH:
371 method = Scheduler::Refresh; 371 method = Scheduler::Refresh;
372 break; 372 break;
373 case ICAL_METHOD_CANCEL: 373 case ICAL_METHOD_CANCEL:
374 method = Scheduler::Cancel; 374 method = Scheduler::Cancel;
375 break; 375 break;
376 case ICAL_METHOD_ADD: 376 case ICAL_METHOD_ADD:
377 method = Scheduler::Add; 377 method = Scheduler::Add;
378 break; 378 break;
379 case ICAL_METHOD_REPLY: 379 case ICAL_METHOD_REPLY:
380 method = Scheduler::Reply; 380 method = Scheduler::Reply;
381 break; 381 break;
382 case ICAL_METHOD_COUNTER: 382 case ICAL_METHOD_COUNTER:
383 method = Scheduler::Counter; 383 method = Scheduler::Counter;
384 break; 384 break;
385 case ICAL_METHOD_DECLINECOUNTER: 385 case ICAL_METHOD_DECLINECOUNTER:
386 method = Scheduler::Declinecounter; 386 method = Scheduler::Declinecounter;
387 break; 387 break;
388 default: 388 default:
389 method = Scheduler::NoMethod; 389 method = Scheduler::NoMethod;
390 kdDebug(5800) << "ICalFormat::parseScheduleMessage(): Unknow method" << endl; 390 kdDebug(5800) << "ICalFormat::parseScheduleMessage(): Unknow method" << endl;
391 break; 391 break;
392 } 392 }
393 393
394 394
395 if (!icalrestriction_check(message)) { 395 if (!icalrestriction_check(message)) {
396 setException(new ErrorFormat(ErrorFormat::Restriction, 396 setException(new ErrorFormat(ErrorFormat::Restriction,
397 Scheduler::translatedMethodName(method) + ": " + 397 Scheduler::translatedMethodName(method) + ": " +
398 mImpl->extractErrorProperty(c))); 398 mImpl->extractErrorProperty(c)));
399 return 0; 399 return 0;
400 } 400 }
401 401
402 icalcomponent *calendarComponent = mImpl->createCalendarComponent(cal); 402 icalcomponent *calendarComponent = mImpl->createCalendarComponent(cal);
403 403
404 Incidence *existingIncidence = cal->event(incidence->uid()); 404 Incidence *existingIncidence = cal->event(incidence->uid());
405 if (existingIncidence) { 405 if (existingIncidence) {
406 // TODO: check, if cast is required, or if it can be done by virtual funcs. 406 // TODO: check, if cast is required, or if it can be done by virtual funcs.
407 if (existingIncidence->type() == "Todo") { 407 if (existingIncidence->type() == "Todo") {
408 Todo *todo = static_cast<Todo *>(existingIncidence); 408 Todo *todo = static_cast<Todo *>(existingIncidence);
409 icalcomponent_add_component(calendarComponent, 409 icalcomponent_add_component(calendarComponent,
410 mImpl->writeTodo(todo)); 410 mImpl->writeTodo(todo));
411 } 411 }
412 if (existingIncidence->type() == "Event") { 412 if (existingIncidence->type() == "Event") {
413 Event *event = static_cast<Event *>(existingIncidence); 413 Event *event = static_cast<Event *>(existingIncidence);
414 icalcomponent_add_component(calendarComponent, 414 icalcomponent_add_component(calendarComponent,
415 mImpl->writeEvent(event)); 415 mImpl->writeEvent(event));
416 } 416 }
417 } else { 417 } else {
418 calendarComponent = 0; 418 calendarComponent = 0;
419 } 419 }
420 420 qDebug("icalclassify commented out ");
421 ScheduleMessage::Status status;
422#if 0
421 423
422 icalclass result = icalclassify(message,calendarComponent,(char *)""); 424 icalclass result = icalclassify(message,calendarComponent,(char *)"");
423 425
424 426
425 ScheduleMessage::Status status;
426 427
427 switch (result) { 428 switch (result) {
428 case ICAL_PUBLISH_NEW_CLASS: 429 case ICAL_PUBLISH_NEW_CLASS:
429 status = ScheduleMessage::PublishNew; 430 status = ScheduleMessage::PublishNew;
430 break; 431 break;
431 case ICAL_OBSOLETE_CLASS: 432 case ICAL_OBSOLETE_CLASS:
432 status = ScheduleMessage::Obsolete; 433 status = ScheduleMessage::Obsolete;
433 break; 434 break;
434 case ICAL_REQUEST_NEW_CLASS: 435 case ICAL_REQUEST_NEW_CLASS:
435 status = ScheduleMessage::RequestNew; 436 status = ScheduleMessage::RequestNew;
436 break; 437 break;
437 case ICAL_REQUEST_UPDATE_CLASS: 438 case ICAL_REQUEST_UPDATE_CLASS:
438 status = ScheduleMessage::RequestUpdate; 439 status = ScheduleMessage::RequestUpdate;
439 break; 440 break;
440 case ICAL_UNKNOWN_CLASS: 441 case ICAL_UNKNOWN_CLASS:
441 default: 442 default:
442 status = ScheduleMessage::Unknown; 443 status = ScheduleMessage::Unknown;
443 break; 444 break;
444 } 445 }
445 446#endif
447 status = ScheduleMessage::RequestUpdate;
446 return new ScheduleMessage(incidence,method,status); 448 return new ScheduleMessage(incidence,method,status);
447} 449}
448 450
449void ICalFormat::setTimeZone( const QString &id, bool utc ) 451void ICalFormat::setTimeZone( const QString &id, bool utc )
450{ 452{
451 453
452 454
453 mTimeZoneId = id; 455 mTimeZoneId = id;
454 mUtc = utc; 456 mUtc = utc;
455 457
456 tzOffsetMin = KGlobal::locale()->timezoneOffset(mTimeZoneId); 458 tzOffsetMin = KGlobal::locale()->timezoneOffset(mTimeZoneId);
457 459
458 //qDebug("ICalFormat::setTimeZoneOffset %s %d ",mTimeZoneId.latin1(), tzOffsetMin); 460 //qDebug("ICalFormat::setTimeZoneOffset %s %d ",mTimeZoneId.latin1(), tzOffsetMin);
459} 461}
460 462
461QString ICalFormat::timeZoneId() const 463QString ICalFormat::timeZoneId() const
462{ 464{
463 return mTimeZoneId; 465 return mTimeZoneId;
464} 466}
465 467
466bool ICalFormat::utc() const 468bool ICalFormat::utc() const
467{ 469{
468 return mUtc; 470 return mUtc;
469} 471}
470int ICalFormat::timeOffset() 472int ICalFormat::timeOffset()
471{ 473{
472 return tzOffsetMin; 474 return tzOffsetMin;
473} 475}
474const char *ICalFormat::tzString() 476const char *ICalFormat::tzString()
475{ 477{
476 const char* ret = (const char* ) mTzString; 478 const char* ret = (const char* ) mTzString;
477 return ret; 479 return ret;
478} 480}
diff --git a/libkcal/icalformatimpl.cpp b/libkcal/icalformatimpl.cpp
index e5c27a0..32a1337 100644
--- a/libkcal/icalformatimpl.cpp
+++ b/libkcal/icalformatimpl.cpp
@@ -1,2173 +1,2170 @@
1/* 1/*
2 This file is part of libkcal. 2 This file is part of libkcal.
3 Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org> 3 Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
4 4
5 This library is free software; you can redistribute it and/or 5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public 6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either 7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version. 8 version 2 of the License, or (at your option) any later version.
9 9
10 This library is distributed in the hope that it will be useful, 10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details. 13 Library General Public License for more details.
14 14
15 You should have received a copy of the GNU Library General Public License 15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to 16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. 18 Boston, MA 02111-1307, USA.
19*/ 19*/
20 20
21#include <qdatetime.h> 21#include <qdatetime.h>
22#include <qstring.h> 22#include <qstring.h>
23#include <qptrlist.h> 23#include <qptrlist.h>
24#include <qfile.h> 24#include <qfile.h>
25 25
26#include <kdebug.h> 26#include <kdebug.h>
27#include <klocale.h> 27#include <klocale.h>
28#include <kglobal.h> 28#include <kglobal.h>
29 29
30extern "C" { 30extern "C" {
31 #include <ical.h> 31 #include <ical.h>
32 #include <icalss.h> 32 #include <icalss.h>
33 #include <icalparser.h> 33 #include <icalparser.h>
34 #include <icalrestriction.h> 34 #include <icalrestriction.h>
35} 35}
36 36
37#include "calendar.h" 37#include "calendar.h"
38#include "journal.h" 38#include "journal.h"
39#include "icalformat.h" 39#include "icalformat.h"
40#include "icalformatimpl.h" 40#include "icalformatimpl.h"
41#include "compat.h" 41#include "compat.h"
42 42
43#define _ICAL_VERSION "2.0" 43#define _ICAL_VERSION "2.0"
44 44
45using namespace KCal; 45using namespace KCal;
46 46
47const int gSecondsPerMinute = 60; 47const int gSecondsPerMinute = 60;
48const int gSecondsPerHour = gSecondsPerMinute * 60; 48const int gSecondsPerHour = gSecondsPerMinute * 60;
49const int gSecondsPerDay = gSecondsPerHour * 24; 49const int gSecondsPerDay = gSecondsPerHour * 24;
50const int gSecondsPerWeek = gSecondsPerDay * 7; 50const int gSecondsPerWeek = gSecondsPerDay * 7;
51 51
52ICalFormatImpl::ICalFormatImpl( ICalFormat *parent ) : 52ICalFormatImpl::ICalFormatImpl( ICalFormat *parent ) :
53 mParent( parent ), mCalendarVersion( 0 ) 53 mParent( parent ), mCalendarVersion( 0 )
54{ 54{
55 mCompat = new Compat; 55 mCompat = new Compat;
56} 56}
57 57
58ICalFormatImpl::~ICalFormatImpl() 58ICalFormatImpl::~ICalFormatImpl()
59{ 59{
60 delete mCompat; 60 delete mCompat;
61} 61}
62 62
63class ToStringVisitor : public Incidence::Visitor 63class ToStringVisitor : public Incidence::Visitor
64{ 64{
65 public: 65 public:
66 ToStringVisitor( ICalFormatImpl *impl ) : mImpl( impl ), mComponent( 0 ) {} 66 ToStringVisitor( ICalFormatImpl *impl ) : mImpl( impl ), mComponent( 0 ) {}
67 67
68 bool visit( Event *e ) { mComponent = mImpl->writeEvent( e ); return true; } 68 bool visit( Event *e ) { mComponent = mImpl->writeEvent( e ); return true; }
69 bool visit( Todo *e ) { mComponent = mImpl->writeTodo( e ); return true; } 69 bool visit( Todo *e ) { mComponent = mImpl->writeTodo( e ); return true; }
70 bool visit( Journal *e ) { mComponent = mImpl->writeJournal( e ); return true; } 70 bool visit( Journal *e ) { mComponent = mImpl->writeJournal( e ); return true; }
71 71
72 icalcomponent *component() { return mComponent; } 72 icalcomponent *component() { return mComponent; }
73 73
74 private: 74 private:
75 ICalFormatImpl *mImpl; 75 ICalFormatImpl *mImpl;
76 icalcomponent *mComponent; 76 icalcomponent *mComponent;
77}; 77};
78 78
79icalcomponent *ICalFormatImpl::writeIncidence(Incidence *incidence) 79icalcomponent *ICalFormatImpl::writeIncidence(Incidence *incidence)
80{ 80{
81 ToStringVisitor v( this ); 81 ToStringVisitor v( this );
82 incidence->accept(v); 82 incidence->accept(v);
83 return v.component(); 83 return v.component();
84} 84}
85 85
86icalcomponent *ICalFormatImpl::writeTodo(Todo *todo) 86icalcomponent *ICalFormatImpl::writeTodo(Todo *todo)
87{ 87{
88 QString tmpStr; 88 QString tmpStr;
89 QStringList tmpStrList; 89 QStringList tmpStrList;
90 90
91 icalcomponent *vtodo = icalcomponent_new(ICAL_VTODO_COMPONENT); 91 icalcomponent *vtodo = icalcomponent_new(ICAL_VTODO_COMPONENT);
92 92
93 writeIncidence(vtodo,todo); 93 writeIncidence(vtodo,todo);
94 94
95 // due date 95 // due date
96 if (todo->hasDueDate()) { 96 if (todo->hasDueDate()) {
97 icaltimetype due; 97 icaltimetype due;
98 if (todo->doesFloat()) { 98 if (todo->doesFloat()) {
99 due = writeICalDate(todo->dtDue().date()); 99 due = writeICalDate(todo->dtDue().date());
100 } else { 100 } else {
101 due = writeICalDateTime(todo->dtDue()); 101 due = writeICalDateTime(todo->dtDue());
102 } 102 }
103 icalcomponent_add_property(vtodo,icalproperty_new_due(due)); 103 icalcomponent_add_property(vtodo,icalproperty_new_due(due));
104 } 104 }
105 105
106 // start time 106 // start time
107 if (todo->hasStartDate()) { 107 if (todo->hasStartDate()) {
108 icaltimetype start; 108 icaltimetype start;
109 if (todo->doesFloat()) { 109 if (todo->doesFloat()) {
110// kdDebug(5800) << "§§ Incidence " << todo->summary() << " floats." << endl; 110// kdDebug(5800) << "§§ Incidence " << todo->summary() << " floats." << endl;
111 start = writeICalDate(todo->dtStart().date()); 111 start = writeICalDate(todo->dtStart().date());
112 } else { 112 } else {
113// kdDebug(5800) << "§§ incidence " << todo->summary() << " has time." << endl; 113// kdDebug(5800) << "§§ incidence " << todo->summary() << " has time." << endl;
114 start = writeICalDateTime(todo->dtStart()); 114 start = writeICalDateTime(todo->dtStart());
115 } 115 }
116 icalcomponent_add_property(vtodo,icalproperty_new_dtstart(start)); 116 icalcomponent_add_property(vtodo,icalproperty_new_dtstart(start));
117 } 117 }
118 118
119 // completion date 119 // completion date
120 if (todo->isCompleted()) { 120 if (todo->isCompleted()) {
121 if (!todo->hasCompletedDate()) { 121 if (!todo->hasCompletedDate()) {
122 // If todo was created by KOrganizer <2.2 it has no correct completion 122 // If todo was created by KOrganizer <2.2 it has no correct completion
123 // date. Set it to now. 123 // date. Set it to now.
124 todo->setCompleted(QDateTime::currentDateTime()); 124 todo->setCompleted(QDateTime::currentDateTime());
125 } 125 }
126 icaltimetype completed = writeICalDateTime(todo->completed()); 126 icaltimetype completed = writeICalDateTime(todo->completed());
127 icalcomponent_add_property(vtodo,icalproperty_new_completed(completed)); 127 icalcomponent_add_property(vtodo,icalproperty_new_completed(completed));
128 } 128 }
129 129
130 icalcomponent_add_property(vtodo, 130 icalcomponent_add_property(vtodo,
131 icalproperty_new_percentcomplete(todo->percentComplete())); 131 icalproperty_new_percentcomplete(todo->percentComplete()));
132 132
133 return vtodo; 133 return vtodo;
134} 134}
135 135
136icalcomponent *ICalFormatImpl::writeEvent(Event *event) 136icalcomponent *ICalFormatImpl::writeEvent(Event *event)
137{ 137{
138 kdDebug(5800) << "Write Event '" << event->summary() << "' (" << event->uid() 138 kdDebug(5800) << "Write Event '" << event->summary() << "' (" << event->uid()
139 << ")" << endl; 139 << ")" << endl;
140 140
141 QString tmpStr; 141 QString tmpStr;
142 QStringList tmpStrList; 142 QStringList tmpStrList;
143 143
144 icalcomponent *vevent = icalcomponent_new(ICAL_VEVENT_COMPONENT); 144 icalcomponent *vevent = icalcomponent_new(ICAL_VEVENT_COMPONENT);
145 145
146 writeIncidence(vevent,event); 146 writeIncidence(vevent,event);
147 147
148 // start time 148 // start time
149 icaltimetype start; 149 icaltimetype start;
150 if (event->doesFloat()) { 150 if (event->doesFloat()) {
151// kdDebug(5800) << "§§ Incidence " << event->summary() << " floats." << endl; 151// kdDebug(5800) << "§§ Incidence " << event->summary() << " floats." << endl;
152 start = writeICalDate(event->dtStart().date()); 152 start = writeICalDate(event->dtStart().date());
153 } else { 153 } else {
154// kdDebug(5800) << "§§ incidence " << event->summary() << " has time." << endl; 154// kdDebug(5800) << "§§ incidence " << event->summary() << " has time." << endl;
155 start = writeICalDateTime(event->dtStart()); 155 start = writeICalDateTime(event->dtStart());
156 } 156 }
157 icalcomponent_add_property(vevent,icalproperty_new_dtstart(start)); 157 icalcomponent_add_property(vevent,icalproperty_new_dtstart(start));
158 158
159 if (event->hasEndDate()) { 159 if (event->hasEndDate()) {
160 // end time 160 // end time
161 icaltimetype end; 161 icaltimetype end;
162 if (event->doesFloat()) { 162 if (event->doesFloat()) {
163// kdDebug(5800) << "§§ Event " << event->summary() << " floats." << endl; 163// kdDebug(5800) << "§§ Event " << event->summary() << " floats." << endl;
164 // +1 day because end date is non-inclusive. 164 // +1 day because end date is non-inclusive.
165 end = writeICalDate( event->dtEnd().date().addDays( 1 ) ); 165 end = writeICalDate( event->dtEnd().date().addDays( 1 ) );
166 } else { 166 } else {
167// kdDebug(5800) << "§§ Event " << event->summary() << " has time." << endl; 167// kdDebug(5800) << "§§ Event " << event->summary() << " has time." << endl;
168 end = writeICalDateTime(event->dtEnd()); 168 end = writeICalDateTime(event->dtEnd());
169 } 169 }
170 icalcomponent_add_property(vevent,icalproperty_new_dtend(end)); 170 icalcomponent_add_property(vevent,icalproperty_new_dtend(end));
171 } 171 }
172 172
173// TODO: attachments, resources 173// TODO: attachments, resources
174#if 0 174#if 0
175 // attachments 175 // attachments
176 tmpStrList = anEvent->attachments(); 176 tmpStrList = anEvent->attachments();
177 for ( QStringList::Iterator it = tmpStrList.begin(); 177 for ( QStringList::Iterator it = tmpStrList.begin();
178 it != tmpStrList.end(); 178 it != tmpStrList.end();
179 ++it ) 179 ++it )
180 addPropValue(vevent, VCAttachProp, (*it).utf8()); 180 addPropValue(vevent, VCAttachProp, (*it).utf8());
181 181
182 // resources 182 // resources
183 tmpStrList = anEvent->resources(); 183 tmpStrList = anEvent->resources();
184 tmpStr = tmpStrList.join(";"); 184 tmpStr = tmpStrList.join(";");
185 if (!tmpStr.isEmpty()) 185 if (!tmpStr.isEmpty())
186 addPropValue(vevent, VCResourcesProp, tmpStr.utf8()); 186 addPropValue(vevent, VCResourcesProp, tmpStr.utf8());
187 187
188#endif 188#endif
189 189
190 // Transparency 190 // Transparency
191 switch( event->transparency() ) { 191 switch( event->transparency() ) {
192 case Event::Transparent: 192 case Event::Transparent:
193 icalcomponent_add_property(vevent, icalproperty_new_transp("TRANSPARENT")); 193 icalcomponent_add_property(vevent, icalproperty_new_transp(ICAL_TRANSP_TRANSPARENT));
194 break; 194 break;
195 case Event::Opaque: 195 case Event::Opaque:
196 icalcomponent_add_property(vevent, icalproperty_new_transp("OPAQUE")); 196 icalcomponent_add_property(vevent, icalproperty_new_transp(ICAL_TRANSP_OPAQUE));
197 break; 197 break;
198 } 198 }
199 199
200 return vevent; 200 return vevent;
201} 201}
202 202
203icalcomponent *ICalFormatImpl::writeFreeBusy(FreeBusy *freebusy, 203icalcomponent *ICalFormatImpl::writeFreeBusy(FreeBusy *freebusy,
204 Scheduler::Method method) 204 Scheduler::Method method)
205{ 205{
206#if QT_VERSION >= 300 206#if QT_VERSION >= 300
207 kdDebug(5800) << "icalformatimpl: writeFreeBusy: startDate: " 207 kdDebug(5800) << "icalformatimpl: writeFreeBusy: startDate: "
208 << freebusy->dtStart().toString("ddd MMMM d yyyy: h:m:s ap") << " End Date: " 208 << freebusy->dtStart().toString("ddd MMMM d yyyy: h:m:s ap") << " End Date: "
209 << freebusy->dtEnd().toString("ddd MMMM d yyyy: h:m:s ap") << endl; 209 << freebusy->dtEnd().toString("ddd MMMM d yyyy: h:m:s ap") << endl;
210#endif 210#endif
211 211
212 icalcomponent *vfreebusy = icalcomponent_new(ICAL_VFREEBUSY_COMPONENT); 212 icalcomponent *vfreebusy = icalcomponent_new(ICAL_VFREEBUSY_COMPONENT);
213 213
214 writeIncidenceBase(vfreebusy,freebusy); 214 writeIncidenceBase(vfreebusy,freebusy);
215 215
216 icalcomponent_add_property(vfreebusy, icalproperty_new_dtstart( 216 icalcomponent_add_property(vfreebusy, icalproperty_new_dtstart(
217 writeICalDateTime(freebusy->dtStart()))); 217 writeICalDateTime(freebusy->dtStart())));
218 218
219 icalcomponent_add_property(vfreebusy, icalproperty_new_dtend( 219 icalcomponent_add_property(vfreebusy, icalproperty_new_dtend(
220 writeICalDateTime(freebusy->dtEnd()))); 220 writeICalDateTime(freebusy->dtEnd())));
221 221
222 if (method == Scheduler::Request) { 222 if (method == Scheduler::Request) {
223 icalcomponent_add_property(vfreebusy,icalproperty_new_uid( 223 icalcomponent_add_property(vfreebusy,icalproperty_new_uid(
224 freebusy->uid().utf8())); 224 freebusy->uid().utf8()));
225 } 225 }
226 226
227 //Loops through all the periods in the freebusy object 227 //Loops through all the periods in the freebusy object
228 QValueList<Period> list = freebusy->busyPeriods(); 228 QValueList<Period> list = freebusy->busyPeriods();
229 QValueList<Period>::Iterator it; 229 QValueList<Period>::Iterator it;
230 icalperiodtype period; 230 icalperiodtype period;
231 for (it = list.begin(); it!= list.end(); ++it) { 231 for (it = list.begin(); it!= list.end(); ++it) {
232 period.start = writeICalDateTime((*it).start()); 232 period.start = writeICalDateTime((*it).start());
233 period.end = writeICalDateTime((*it).end()); 233 period.end = writeICalDateTime((*it).end());
234 icalcomponent_add_property(vfreebusy, icalproperty_new_freebusy(period) ); 234 icalcomponent_add_property(vfreebusy, icalproperty_new_freebusy(period) );
235 } 235 }
236 236
237 return vfreebusy; 237 return vfreebusy;
238} 238}
239 239
240icalcomponent *ICalFormatImpl::writeJournal(Journal *journal) 240icalcomponent *ICalFormatImpl::writeJournal(Journal *journal)
241{ 241{
242 icalcomponent *vjournal = icalcomponent_new(ICAL_VJOURNAL_COMPONENT); 242 icalcomponent *vjournal = icalcomponent_new(ICAL_VJOURNAL_COMPONENT);
243 243
244 writeIncidence(vjournal,journal); 244 writeIncidence(vjournal,journal);
245 245
246 // start time 246 // start time
247 if (journal->dtStart().isValid()) { 247 if (journal->dtStart().isValid()) {
248 icaltimetype start; 248 icaltimetype start;
249 if (journal->doesFloat()) { 249 if (journal->doesFloat()) {
250// kdDebug(5800) << "§§ Incidence " << event->summary() << " floats." << endl; 250// kdDebug(5800) << "§§ Incidence " << event->summary() << " floats." << endl;
251 start = writeICalDate(journal->dtStart().date()); 251 start = writeICalDate(journal->dtStart().date());
252 } else { 252 } else {
253// kdDebug(5800) << "§§ incidence " << event->summary() << " has time." << endl; 253// kdDebug(5800) << "§§ incidence " << event->summary() << " has time." << endl;
254 start = writeICalDateTime(journal->dtStart()); 254 start = writeICalDateTime(journal->dtStart());
255 } 255 }
256 icalcomponent_add_property(vjournal,icalproperty_new_dtstart(start)); 256 icalcomponent_add_property(vjournal,icalproperty_new_dtstart(start));
257 } 257 }
258 258
259 return vjournal; 259 return vjournal;
260} 260}
261 261
262void ICalFormatImpl::writeIncidence(icalcomponent *parent,Incidence *incidence) 262void ICalFormatImpl::writeIncidence(icalcomponent *parent,Incidence *incidence)
263{ 263{
264 // pilot sync stuff 264 // pilot sync stuff
265// TODO: move this application-specific code to kpilot 265// TODO: move this application-specific code to kpilot
266 if (incidence->pilotId()) { 266 if (incidence->pilotId()) {
267 incidence->setNonKDECustomProperty("X-PILOTID", QString::number(incidence->pilotId())); 267 incidence->setNonKDECustomProperty("X-PILOTID", QString::number(incidence->pilotId()));
268 incidence->setNonKDECustomProperty("X-PILOTSTAT", QString::number(incidence->syncStatus())); 268 incidence->setNonKDECustomProperty("X-PILOTSTAT", QString::number(incidence->syncStatus()));
269 } 269 }
270 if (incidence->zaurusId() >= 0) { 270 if (incidence->zaurusId() >= 0) {
271 incidence->setNonKDECustomProperty("X-ZAURUSID", QString::number(incidence->zaurusId())); 271 incidence->setNonKDECustomProperty("X-ZAURUSID", QString::number(incidence->zaurusId()));
272 } 272 }
273 273
274 if (incidence->zaurusUid() > 0) { 274 if (incidence->zaurusUid() > 0) {
275 incidence->setNonKDECustomProperty("X-ZAURUSUID", QString::number(incidence->zaurusUid())); 275 incidence->setNonKDECustomProperty("X-ZAURUSUID", QString::number(incidence->zaurusUid()));
276 } 276 }
277 if (incidence->zaurusStat() > 0) { 277 if (incidence->zaurusStat() > 0) {
278 incidence->setNonKDECustomProperty("X-ZAURUSSTAT", QString::number(incidence->zaurusStat())); 278 incidence->setNonKDECustomProperty("X-ZAURUSSTAT", QString::number(incidence->zaurusStat()));
279 } 279 }
280 280
281 writeIncidenceBase(parent,incidence); 281 writeIncidenceBase(parent,incidence);
282 if (incidence->cancelled()) { 282 if (incidence->cancelled()) {
283 icalcomponent_add_property(parent,icalproperty_new_status(ICAL_STATUS_CANCELLED)); 283 icalcomponent_add_property(parent,icalproperty_new_status(ICAL_STATUS_CANCELLED));
284 } 284 }
285 285
286 // creation date 286 // creation date
287 icalcomponent_add_property(parent,icalproperty_new_created( 287 icalcomponent_add_property(parent,icalproperty_new_created(
288 writeICalDateTime(incidence->created()))); 288 writeICalDateTime(incidence->created())));
289 289
290 // unique id 290 // unique id
291 icalcomponent_add_property(parent,icalproperty_new_uid( 291 icalcomponent_add_property(parent,icalproperty_new_uid(
292 incidence->uid().utf8())); 292 incidence->uid().utf8()));
293 293
294 // revision 294 // revision
295 icalcomponent_add_property(parent,icalproperty_new_sequence( 295 icalcomponent_add_property(parent,icalproperty_new_sequence(
296 incidence->revision())); 296 incidence->revision()));
297 297
298 // last modification date 298 // last modification date
299 icalcomponent_add_property(parent,icalproperty_new_lastmodified( 299 icalcomponent_add_property(parent,icalproperty_new_lastmodified(
300 writeICalDateTime(incidence->lastModified()))); 300 writeICalDateTime(incidence->lastModified())));
301 301
302 // description 302 // description
303 if (!incidence->description().isEmpty()) { 303 if (!incidence->description().isEmpty()) {
304 icalcomponent_add_property(parent,icalproperty_new_description( 304 icalcomponent_add_property(parent,icalproperty_new_description(
305 incidence->description().utf8())); 305 incidence->description().utf8()));
306 } 306 }
307 307
308 // summary 308 // summary
309 if (!incidence->summary().isEmpty()) { 309 if (!incidence->summary().isEmpty()) {
310 icalcomponent_add_property(parent,icalproperty_new_summary( 310 icalcomponent_add_property(parent,icalproperty_new_summary(
311 incidence->summary().utf8())); 311 incidence->summary().utf8()));
312 } 312 }
313 313
314 // location 314 // location
315 if (!incidence->location().isEmpty()) { 315 if (!incidence->location().isEmpty()) {
316 icalcomponent_add_property(parent,icalproperty_new_location( 316 icalcomponent_add_property(parent,icalproperty_new_location(
317 incidence->location().utf8())); 317 incidence->location().utf8()));
318 } 318 }
319 319
320// TODO: 320// TODO:
321 // status 321 // status
322// addPropValue(parent, VCStatusProp, incidence->getStatusStr().utf8()); 322// addPropValue(parent, VCStatusProp, incidence->getStatusStr().utf8());
323 323
324 // secrecy 324 // secrecy
325 const char *classStr; 325 enum icalproperty_class classInt;
326 switch (incidence->secrecy()) { 326 switch (incidence->secrecy()) {
327 case Incidence::SecrecyPublic: 327 case Incidence::SecrecyPublic:
328 classStr = "PUBLIC"; 328 classInt = ICAL_CLASS_PUBLIC;
329 break; 329 break;
330 case Incidence::SecrecyConfidential: 330 case Incidence::SecrecyConfidential:
331 classStr = "CONFIDENTIAL"; 331 classInt = ICAL_CLASS_CONFIDENTIAL;
332 break; 332 break;
333 case Incidence::SecrecyPrivate: 333 case Incidence::SecrecyPrivate:
334 classInt =ICAL_CLASS_PRIVATE ;
334 default: 335 default:
335 classStr = "PRIVATE"; 336 classInt =ICAL_CLASS_PRIVATE ;
336 break; 337 break;
337 } 338 }
338 icalcomponent_add_property(parent,icalproperty_new_class(classStr)); 339 icalcomponent_add_property(parent,icalproperty_new_class(classInt));
339 340
340 // priority 341 // priority
341 icalcomponent_add_property(parent,icalproperty_new_priority( 342 icalcomponent_add_property(parent,icalproperty_new_priority(
342 incidence->priority())); 343 incidence->priority()));
343 344
344 // categories 345 // categories
345 QStringList categories = incidence->categories(); 346 QStringList categories = incidence->categories();
346 QStringList::Iterator it; 347 QStringList::Iterator it;
347 for(it = categories.begin(); it != categories.end(); ++it ) { 348 for(it = categories.begin(); it != categories.end(); ++it ) {
348 icalcomponent_add_property(parent,icalproperty_new_categories((*it).utf8())); 349 icalcomponent_add_property(parent,icalproperty_new_categories((*it).utf8()));
349 } 350 }
350// TODO: Ensure correct concatenation of categories properties. 351// TODO: Ensure correct concatenation of categories properties.
351 352
352/* 353/*
353 // categories 354 // categories
354 tmpStrList = incidence->getCategories(); 355 tmpStrList = incidence->getCategories();
355 tmpStr = ""; 356 tmpStr = "";
356 QString catStr; 357 QString catStr;
357 for ( QStringList::Iterator it = tmpStrList.begin(); 358 for ( QStringList::Iterator it = tmpStrList.begin();
358 it != tmpStrList.end(); 359 it != tmpStrList.end();
359 ++it ) { 360 ++it ) {
360 catStr = *it; 361 catStr = *it;
361 if (catStr[0] == ' ') 362 if (catStr[0] == ' ')
362 tmpStr += catStr.mid(1); 363 tmpStr += catStr.mid(1);
363 else 364 else
364 tmpStr += catStr; 365 tmpStr += catStr;
365 // this must be a ';' character as the vCalendar specification requires! 366 // this must be a ';' character as the vCalendar specification requires!
366 // vcc.y has been hacked to translate the ';' to a ',' when the vcal is 367 // vcc.y has been hacked to translate the ';' to a ',' when the vcal is
367 // read in. 368 // read in.
368 tmpStr += ";"; 369 tmpStr += ";";
369 } 370 }
370 if (!tmpStr.isEmpty()) { 371 if (!tmpStr.isEmpty()) {
371 tmpStr.truncate(tmpStr.length()-1); 372 tmpStr.truncate(tmpStr.length()-1);
372 icalcomponent_add_property(parent,icalproperty_new_categories( 373 icalcomponent_add_property(parent,icalproperty_new_categories(
373 writeText(incidence->getCategories().join(";")))); 374 writeText(incidence->getCategories().join(";"))));
374 } 375 }
375*/ 376*/
376 377
377 // related event 378 // related event
378 if (incidence->relatedTo()) { 379 if (incidence->relatedTo()) {
379 icalcomponent_add_property(parent,icalproperty_new_relatedto( 380 icalcomponent_add_property(parent,icalproperty_new_relatedto(
380 incidence->relatedTo()->uid().utf8())); 381 incidence->relatedTo()->uid().utf8()));
381 } 382 }
382 383
383 // recurrence rule stuff 384 // recurrence rule stuff
384 Recurrence *recur = incidence->recurrence(); 385 Recurrence *recur = incidence->recurrence();
385 if (recur->doesRecur()) { 386 if (recur->doesRecur()) {
386 387
387 icalcomponent_add_property(parent,writeRecurrenceRule(recur)); 388 icalcomponent_add_property(parent,writeRecurrenceRule(recur));
388 } 389 }
389 390
390 // recurrence excpetion dates 391 // recurrence excpetion dates
391 DateList dateList = incidence->exDates(); 392 DateList dateList = incidence->exDates();
392 DateList::ConstIterator exIt; 393 DateList::ConstIterator exIt;
393 for(exIt = dateList.begin(); exIt != dateList.end(); ++exIt) { 394 for(exIt = dateList.begin(); exIt != dateList.end(); ++exIt) {
394 icalcomponent_add_property(parent,icalproperty_new_exdate( 395 icalcomponent_add_property(parent,icalproperty_new_exdate(
395 writeICalDate(*exIt))); 396 writeICalDate(*exIt)));
396 } 397 }
397 398
398 // attachments 399 // attachments
399 QPtrList<Attachment> attachments = incidence->attachments(); 400 QPtrList<Attachment> attachments = incidence->attachments();
400 for (Attachment *at = attachments.first(); at; at = attachments.next()) 401 for (Attachment *at = attachments.first(); at; at = attachments.next())
401 icalcomponent_add_property(parent,writeAttachment(at)); 402 icalcomponent_add_property(parent,writeAttachment(at));
402 403
403 // alarms 404 // alarms
404 QPtrList<Alarm> alarms = incidence->alarms(); 405 QPtrList<Alarm> alarms = incidence->alarms();
405 Alarm* alarm; 406 Alarm* alarm;
406 for (alarm = alarms.first(); alarm; alarm = alarms.next()) { 407 for (alarm = alarms.first(); alarm; alarm = alarms.next()) {
407 if (alarm->enabled()) { 408 if (alarm->enabled()) {
408 kdDebug(5800) << "Write alarm for " << incidence->summary() << endl; 409 kdDebug(5800) << "Write alarm for " << incidence->summary() << endl;
409 icalcomponent_add_component(parent,writeAlarm(alarm)); 410 icalcomponent_add_component(parent,writeAlarm(alarm));
410 } 411 }
411 } 412 }
412 413
413 // duration 414 // duration
414 415
415// turned off as it always is set to PTS0 (and must not occur together with DTEND 416// turned off as it always is set to PTS0 (and must not occur together with DTEND
416 417
417// if (incidence->hasDuration()) { 418// if (incidence->hasDuration()) {
418// icaldurationtype duration; 419// icaldurationtype duration;
419// duration = writeICalDuration(incidence->duration()); 420// duration = writeICalDuration(incidence->duration());
420// icalcomponent_add_property(parent,icalproperty_new_duration(duration)); 421// icalcomponent_add_property(parent,icalproperty_new_duration(duration));
421// } 422// }
422} 423}
423 424
424void ICalFormatImpl::writeIncidenceBase(icalcomponent *parent,IncidenceBase *incidenceBase) 425void ICalFormatImpl::writeIncidenceBase(icalcomponent *parent,IncidenceBase *incidenceBase)
425{ 426{
426 icalcomponent_add_property(parent,icalproperty_new_dtstamp( 427 icalcomponent_add_property(parent,icalproperty_new_dtstamp(
427 writeICalDateTime(QDateTime::currentDateTime()))); 428 writeICalDateTime(QDateTime::currentDateTime())));
428 429
429 // organizer stuff 430 // organizer stuff
430 icalcomponent_add_property(parent,icalproperty_new_organizer( 431 icalcomponent_add_property(parent,icalproperty_new_organizer(
431 ("MAILTO:" + incidenceBase->organizer()).utf8())); 432 ("MAILTO:" + incidenceBase->organizer()).utf8()));
432 433
433 // attendees 434 // attendees
434 if (incidenceBase->attendeeCount() != 0) { 435 if (incidenceBase->attendeeCount() != 0) {
435 QPtrList<Attendee> al = incidenceBase->attendees(); 436 QPtrList<Attendee> al = incidenceBase->attendees();
436 QPtrListIterator<Attendee> ai(al); 437 QPtrListIterator<Attendee> ai(al);
437 for (; ai.current(); ++ai) { 438 for (; ai.current(); ++ai) {
438 icalcomponent_add_property(parent,writeAttendee(ai.current())); 439 icalcomponent_add_property(parent,writeAttendee(ai.current()));
439 } 440 }
440 } 441 }
441 442
442 // custom properties 443 // custom properties
443 writeCustomProperties(parent, incidenceBase); 444 writeCustomProperties(parent, incidenceBase);
444} 445}
445 446
446void ICalFormatImpl::writeCustomProperties(icalcomponent *parent,CustomProperties *properties) 447void ICalFormatImpl::writeCustomProperties(icalcomponent *parent,CustomProperties *properties)
447{ 448{
448 QMap<QCString, QString> custom = properties->customProperties(); 449 QMap<QCString, QString> custom = properties->customProperties();
449 for (QMap<QCString, QString>::Iterator c = custom.begin(); c != custom.end(); ++c) { 450 for (QMap<QCString, QString>::Iterator c = custom.begin(); c != custom.end(); ++c) {
450 icalproperty *p = icalproperty_new_x(c.data().utf8()); 451 icalproperty *p = icalproperty_new_x(c.data().utf8());
451 icalproperty_set_x_name(p,c.key()); 452 icalproperty_set_x_name(p,c.key());
452 icalcomponent_add_property(parent,p); 453 icalcomponent_add_property(parent,p);
453 } 454 }
454} 455}
455 456
456icalproperty *ICalFormatImpl::writeAttendee(Attendee *attendee) 457icalproperty *ICalFormatImpl::writeAttendee(Attendee *attendee)
457{ 458{
458 icalproperty *p = icalproperty_new_attendee("mailto:" + attendee->email().utf8()); 459 icalproperty *p = icalproperty_new_attendee("mailto:" + attendee->email().utf8());
459 460
460 if (!attendee->name().isEmpty()) { 461 if (!attendee->name().isEmpty()) {
461 icalproperty_add_parameter(p,icalparameter_new_cn(attendee->name().utf8())); 462 icalproperty_add_parameter(p,icalparameter_new_cn(attendee->name().utf8()));
462 } 463 }
463 464
464 465
465 icalproperty_add_parameter(p,icalparameter_new_rsvp( 466 icalproperty_add_parameter(p,icalparameter_new_rsvp(
466 attendee->RSVP() ? ICAL_RSVP_TRUE : ICAL_RSVP_FALSE )); 467 attendee->RSVP() ? ICAL_RSVP_TRUE : ICAL_RSVP_FALSE ));
467 468
468 icalparameter_partstat status = ICAL_PARTSTAT_NEEDSACTION; 469 icalparameter_partstat status = ICAL_PARTSTAT_NEEDSACTION;
469 switch (attendee->status()) { 470 switch (attendee->status()) {
470 default: 471 default:
471 case Attendee::NeedsAction: 472 case Attendee::NeedsAction:
472 status = ICAL_PARTSTAT_NEEDSACTION; 473 status = ICAL_PARTSTAT_NEEDSACTION;
473 break; 474 break;
474 case Attendee::Accepted: 475 case Attendee::Accepted:
475 status = ICAL_PARTSTAT_ACCEPTED; 476 status = ICAL_PARTSTAT_ACCEPTED;
476 break; 477 break;
477 case Attendee::Declined: 478 case Attendee::Declined:
478 status = ICAL_PARTSTAT_DECLINED; 479 status = ICAL_PARTSTAT_DECLINED;
479 break; 480 break;
480 case Attendee::Tentative: 481 case Attendee::Tentative:
481 status = ICAL_PARTSTAT_TENTATIVE; 482 status = ICAL_PARTSTAT_TENTATIVE;
482 break; 483 break;
483 case Attendee::Delegated: 484 case Attendee::Delegated:
484 status = ICAL_PARTSTAT_DELEGATED; 485 status = ICAL_PARTSTAT_DELEGATED;
485 break; 486 break;
486 case Attendee::Completed: 487 case Attendee::Completed:
487 status = ICAL_PARTSTAT_COMPLETED; 488 status = ICAL_PARTSTAT_COMPLETED;
488 break; 489 break;
489 case Attendee::InProcess: 490 case Attendee::InProcess:
490 status = ICAL_PARTSTAT_INPROCESS; 491 status = ICAL_PARTSTAT_INPROCESS;
491 break; 492 break;
492 } 493 }
493 icalproperty_add_parameter(p,icalparameter_new_partstat(status)); 494 icalproperty_add_parameter(p,icalparameter_new_partstat(status));
494 495
495 icalparameter_role role = ICAL_ROLE_REQPARTICIPANT; 496 icalparameter_role role = ICAL_ROLE_REQPARTICIPANT;
496 switch (attendee->role()) { 497 switch (attendee->role()) {
497 case Attendee::Chair: 498 case Attendee::Chair:
498 role = ICAL_ROLE_CHAIR; 499 role = ICAL_ROLE_CHAIR;
499 break; 500 break;
500 default: 501 default:
501 case Attendee::ReqParticipant: 502 case Attendee::ReqParticipant:
502 role = ICAL_ROLE_REQPARTICIPANT; 503 role = ICAL_ROLE_REQPARTICIPANT;
503 break; 504 break;
504 case Attendee::OptParticipant: 505 case Attendee::OptParticipant:
505 role = ICAL_ROLE_OPTPARTICIPANT; 506 role = ICAL_ROLE_OPTPARTICIPANT;
506 break; 507 break;
507 case Attendee::NonParticipant: 508 case Attendee::NonParticipant:
508 role = ICAL_ROLE_NONPARTICIPANT; 509 role = ICAL_ROLE_NONPARTICIPANT;
509 break; 510 break;
510 } 511 }
511 icalproperty_add_parameter(p,icalparameter_new_role(role)); 512 icalproperty_add_parameter(p,icalparameter_new_role(role));
512 513
513 if (!attendee->uid().isEmpty()) { 514 if (!attendee->uid().isEmpty()) {
514 icalparameter* icalparameter_uid = icalparameter_new_x(attendee->uid().utf8()); 515 icalparameter* icalparameter_uid = icalparameter_new_x(attendee->uid().utf8());
515 icalparameter_set_xname(icalparameter_uid,"X-UID"); 516 icalparameter_set_xname(icalparameter_uid,"X-UID");
516 icalproperty_add_parameter(p,icalparameter_uid); 517 icalproperty_add_parameter(p,icalparameter_uid);
517 } 518 }
518 519
519 return p; 520 return p;
520} 521}
521 522
522icalproperty *ICalFormatImpl::writeAttachment(Attachment *att) 523icalproperty *ICalFormatImpl::writeAttachment(Attachment *att)
523{ 524{
524 icalattachtype* attach = icalattachtype_new(); 525#if 0
526 icalattachtype* attach = icalattachtype_new();
525 if (att->isURI()) 527 if (att->isURI())
526 icalattachtype_set_url(attach, att->uri().utf8().data()); 528 icalattachtype_set_url(attach, att->uri().utf8().data());
527 else 529 else
528 icalattachtype_set_base64(attach, att->data(), 0); 530 icalattachtype_set_base64(attach, att->data(), 0);
529 531#endif
532 icalattach *attach;
533 if (att->isURI())
534 attach = icalattach_new_from_url( att->uri().utf8().data());
535 else
536 attach = icalattach_new_from_data ( (unsigned char *)att->data(), 0, 0);
530 icalproperty *p = icalproperty_new_attach(attach); 537 icalproperty *p = icalproperty_new_attach(attach);
531
532 if (!att->mimeType().isEmpty()) 538 if (!att->mimeType().isEmpty())
533 icalproperty_add_parameter(p,icalparameter_new_fmttype(att->mimeType().utf8().data())); 539 icalproperty_add_parameter(p,icalparameter_new_fmttype(att->mimeType().utf8().data()));
534 540
535 if (att->isBinary()) { 541 if (att->isBinary()) {
536 icalproperty_add_parameter(p,icalparameter_new_value(ICAL_VALUE_BINARY)); 542 icalproperty_add_parameter(p,icalparameter_new_value(ICAL_VALUE_BINARY));
537 icalproperty_add_parameter(p,icalparameter_new_encoding(ICAL_ENCODING_BASE64)); 543 icalproperty_add_parameter(p,icalparameter_new_encoding(ICAL_ENCODING_BASE64));
538 } 544 }
539 return p; 545 return p;
540} 546}
541 547
542icalproperty *ICalFormatImpl::writeRecurrenceRule(Recurrence *recur) 548icalproperty *ICalFormatImpl::writeRecurrenceRule(Recurrence *recur)
543{ 549{
544// kdDebug(5800) << "ICalFormatImpl::writeRecurrenceRule()" << endl; 550// kdDebug(5800) << "ICalFormatImpl::writeRecurrenceRule()" << endl;
545 551
546 icalrecurrencetype r; 552 icalrecurrencetype r;
547 553
548 icalrecurrencetype_clear(&r); 554 icalrecurrencetype_clear(&r);
549 555
550 int index = 0; 556 int index = 0;
551 int index2 = 0; 557 int index2 = 0;
552 558
553 QPtrList<Recurrence::rMonthPos> tmpPositions; 559 QPtrList<Recurrence::rMonthPos> tmpPositions;
554 QPtrList<int> tmpDays; 560 QPtrList<int> tmpDays;
555 int *tmpDay; 561 int *tmpDay;
556 Recurrence::rMonthPos *tmpPos; 562 Recurrence::rMonthPos *tmpPos;
557 bool datetime = false; 563 bool datetime = false;
558 int day; 564 int day;
559 int i; 565 int i;
560 566
561 switch(recur->doesRecur()) { 567 switch(recur->doesRecur()) {
562 case Recurrence::rMinutely: 568 case Recurrence::rMinutely:
563 r.freq = ICAL_MINUTELY_RECURRENCE; 569 r.freq = ICAL_MINUTELY_RECURRENCE;
564 datetime = true; 570 datetime = true;
565 break; 571 break;
566 case Recurrence::rHourly: 572 case Recurrence::rHourly:
567 r.freq = ICAL_HOURLY_RECURRENCE; 573 r.freq = ICAL_HOURLY_RECURRENCE;
568 datetime = true; 574 datetime = true;
569 break; 575 break;
570 case Recurrence::rDaily: 576 case Recurrence::rDaily:
571 r.freq = ICAL_DAILY_RECURRENCE; 577 r.freq = ICAL_DAILY_RECURRENCE;
572 break; 578 break;
573 case Recurrence::rWeekly: 579 case Recurrence::rWeekly:
574 r.freq = ICAL_WEEKLY_RECURRENCE; 580 r.freq = ICAL_WEEKLY_RECURRENCE;
575 r.week_start = static_cast<icalrecurrencetype_weekday>(recur->weekStart()%7 + 1); 581 r.week_start = static_cast<icalrecurrencetype_weekday>(recur->weekStart()%7 + 1);
576 for (i = 0; i < 7; i++) { 582 for (i = 0; i < 7; i++) {
577 if (recur->days().testBit(i)) { 583 if (recur->days().testBit(i)) {
578 day = (i + 1)%7 + 1; // convert from Monday=0 to Sunday=1 584 day = (i + 1)%7 + 1; // convert from Monday=0 to Sunday=1
579 r.by_day[index++] = icalrecurrencetype_day_day_of_week(day); 585 r.by_day[index++] = icalrecurrencetype_day_day_of_week(day);
580 } 586 }
581 } 587 }
582// r.by_day[index] = ICAL_RECURRENCE_ARRAY_MAX; 588// r.by_day[index] = ICAL_RECURRENCE_ARRAY_MAX;
583 break; 589 break;
584 case Recurrence::rMonthlyPos: 590 case Recurrence::rMonthlyPos:
585 r.freq = ICAL_MONTHLY_RECURRENCE; 591 r.freq = ICAL_MONTHLY_RECURRENCE;
586 592
587 tmpPositions = recur->monthPositions(); 593 tmpPositions = recur->monthPositions();
588 for (tmpPos = tmpPositions.first(); 594 for (tmpPos = tmpPositions.first();
589 tmpPos; 595 tmpPos;
590 tmpPos = tmpPositions.next()) { 596 tmpPos = tmpPositions.next()) {
591 for (i = 0; i < 7; i++) { 597 for (i = 0; i < 7; i++) {
592 if (tmpPos->rDays.testBit(i)) { 598 if (tmpPos->rDays.testBit(i)) {
593 day = (i + 1)%7 + 1; // convert from Monday=0 to Sunday=1 599 day = (i + 1)%7 + 1; // convert from Monday=0 to Sunday=1
594 day += tmpPos->rPos*8; 600 day += tmpPos->rPos*8;
595 if (tmpPos->negative) day = -day; 601 if (tmpPos->negative) day = -day;
596 r.by_day[index++] = day; 602 r.by_day[index++] = day;
597 } 603 }
598 } 604 }
599 } 605 }
600// r.by_day[index] = ICAL_RECURRENCE_ARRAY_MAX; 606// r.by_day[index] = ICAL_RECURRENCE_ARRAY_MAX;
601 break; 607 break;
602 case Recurrence::rMonthlyDay: 608 case Recurrence::rMonthlyDay:
603 r.freq = ICAL_MONTHLY_RECURRENCE; 609 r.freq = ICAL_MONTHLY_RECURRENCE;
604 610
605 tmpDays = recur->monthDays(); 611 tmpDays = recur->monthDays();
606 for (tmpDay = tmpDays.first(); 612 for (tmpDay = tmpDays.first();
607 tmpDay; 613 tmpDay;
608 tmpDay = tmpDays.next()) { 614 tmpDay = tmpDays.next()) {
609 r.by_month_day[index++] = icalrecurrencetype_day_position(*tmpDay*8);//*tmpDay); 615 r.by_month_day[index++] = icalrecurrencetype_day_position(*tmpDay*8);//*tmpDay);
610 } 616 }
611// r.by_day[index] = ICAL_RECURRENCE_ARRAY_MAX; 617// r.by_day[index] = ICAL_RECURRENCE_ARRAY_MAX;
612 break; 618 break;
613 case Recurrence::rYearlyMonth: 619 case Recurrence::rYearlyMonth:
614 case Recurrence::rYearlyPos: 620 case Recurrence::rYearlyPos:
615 r.freq = ICAL_YEARLY_RECURRENCE; 621 r.freq = ICAL_YEARLY_RECURRENCE;
616 622
617 tmpDays = recur->yearNums(); 623 tmpDays = recur->yearNums();
618 for (tmpDay = tmpDays.first(); 624 for (tmpDay = tmpDays.first();
619 tmpDay; 625 tmpDay;
620 tmpDay = tmpDays.next()) { 626 tmpDay = tmpDays.next()) {
621 r.by_month[index++] = *tmpDay; 627 r.by_month[index++] = *tmpDay;
622 } 628 }
623// r.by_set_pos[index] = ICAL_RECURRENCE_ARRAY_MAX; 629// r.by_set_pos[index] = ICAL_RECURRENCE_ARRAY_MAX;
624 if (recur->doesRecur() == Recurrence::rYearlyPos) { 630 if (recur->doesRecur() == Recurrence::rYearlyPos) {
625 tmpPositions = recur->monthPositions(); 631 tmpPositions = recur->monthPositions();
626 for (tmpPos = tmpPositions.first(); 632 for (tmpPos = tmpPositions.first();
627 tmpPos; 633 tmpPos;
628 tmpPos = tmpPositions.next()) { 634 tmpPos = tmpPositions.next()) {
629 for (i = 0; i < 7; i++) { 635 for (i = 0; i < 7; i++) {
630 if (tmpPos->rDays.testBit(i)) { 636 if (tmpPos->rDays.testBit(i)) {
631 day = (i + 1)%7 + 1; // convert from Monday=0 to Sunday=1 637 day = (i + 1)%7 + 1; // convert from Monday=0 to Sunday=1
632 day += tmpPos->rPos*8; 638 day += tmpPos->rPos*8;
633 if (tmpPos->negative) day = -day; 639 if (tmpPos->negative) day = -day;
634 r.by_day[index2++] = day; 640 r.by_day[index2++] = day;
635 } 641 }
636 } 642 }
637 } 643 }
638// r.by_day[index2] = ICAL_RECURRENCE_ARRAY_MAX; 644// r.by_day[index2] = ICAL_RECURRENCE_ARRAY_MAX;
639 } 645 }
640 break; 646 break;
641 case Recurrence::rYearlyDay: 647 case Recurrence::rYearlyDay:
642 r.freq = ICAL_YEARLY_RECURRENCE; 648 r.freq = ICAL_YEARLY_RECURRENCE;
643 649
644 tmpDays = recur->yearNums(); 650 tmpDays = recur->yearNums();
645 for (tmpDay = tmpDays.first(); 651 for (tmpDay = tmpDays.first();
646 tmpDay; 652 tmpDay;
647 tmpDay = tmpDays.next()) { 653 tmpDay = tmpDays.next()) {
648 r.by_year_day[index++] = *tmpDay; 654 r.by_year_day[index++] = *tmpDay;
649 } 655 }
650// r.by_year_day[index] = ICAL_RECURRENCE_ARRAY_MAX; 656// r.by_year_day[index] = ICAL_RECURRENCE_ARRAY_MAX;
651 break; 657 break;
652 default: 658 default:
653 r.freq = ICAL_NO_RECURRENCE; 659 r.freq = ICAL_NO_RECURRENCE;
654 kdDebug(5800) << "ICalFormatImpl::writeRecurrence(): no recurrence" << endl; 660 kdDebug(5800) << "ICalFormatImpl::writeRecurrence(): no recurrence" << endl;
655 break; 661 break;
656 } 662 }
657 663
658 r.interval = recur->frequency(); 664 r.interval = recur->frequency();
659 665
660 if (recur->duration() > 0) { 666 if (recur->duration() > 0) {
661 r.count = recur->duration(); 667 r.count = recur->duration();
662 } else if (recur->duration() == -1) { 668 } else if (recur->duration() == -1) {
663 r.count = 0; 669 r.count = 0;
664 } else { 670 } else {
665 if (datetime) 671 if (datetime)
666 r.until = writeICalDateTime(recur->endDateTime()); 672 r.until = writeICalDateTime(recur->endDateTime());
667 else 673 else
668 r.until = writeICalDate(recur->endDate()); 674 r.until = writeICalDate(recur->endDate());
669 } 675 }
670 676
671// Debug output 677// Debug output
672#if 0 678#if 0
673 const char *str = icalrecurrencetype_as_string(&r); 679 const char *str = icalrecurrencetype_as_string(&r);
674 if (str) { 680 if (str) {
675 kdDebug(5800) << " String: " << str << endl; 681 kdDebug(5800) << " String: " << str << endl;
676 } else { 682 } else {
677 kdDebug(5800) << " No String" << endl; 683 kdDebug(5800) << " No String" << endl;
678 } 684 }
679#endif 685#endif
680 686
681 return icalproperty_new_rrule(r); 687 return icalproperty_new_rrule(r);
682} 688}
683 689
684icalcomponent *ICalFormatImpl::writeAlarm(Alarm *alarm) 690icalcomponent *ICalFormatImpl::writeAlarm(Alarm *alarm)
685{ 691{
686 icalcomponent *a = icalcomponent_new(ICAL_VALARM_COMPONENT); 692 icalcomponent *a = icalcomponent_new(ICAL_VALARM_COMPONENT);
687 693
688 icalproperty_action action; 694 icalproperty_action action;
689 icalattachtype *attach = 0; 695 icalattach *attach = 0;
690 696
691 switch (alarm->type()) { 697 switch (alarm->type()) {
692 case Alarm::Procedure: 698 case Alarm::Procedure:
693 action = ICAL_ACTION_PROCEDURE; 699 action = ICAL_ACTION_PROCEDURE;
694 attach = icalattachtype_new(); 700 attach = icalattach_new_from_url( QFile::encodeName(alarm->programFile()).data() );
695 icalattachtype_set_url(attach,QFile::encodeName(alarm->programFile()).data());
696 icalcomponent_add_property(a,icalproperty_new_attach(attach)); 701 icalcomponent_add_property(a,icalproperty_new_attach(attach));
697 icalattachtype_free(attach);
698 if (!alarm->programArguments().isEmpty()) { 702 if (!alarm->programArguments().isEmpty()) {
699 icalcomponent_add_property(a,icalproperty_new_description(alarm->programArguments().utf8())); 703 icalcomponent_add_property(a,icalproperty_new_description(alarm->programArguments().utf8()));
700 } 704 }
701 break; 705 break;
702 case Alarm::Audio: 706 case Alarm::Audio:
703 action = ICAL_ACTION_AUDIO; 707 action = ICAL_ACTION_AUDIO;
704 if (!alarm->audioFile().isEmpty()) { 708 if (!alarm->audioFile().isEmpty()) {
705 attach = icalattachtype_new(); 709 attach = icalattach_new_from_url(QFile::encodeName( alarm->audioFile() ).data());
706 icalattachtype_set_url(attach,QFile::encodeName( alarm->audioFile() ).data());
707 icalcomponent_add_property(a,icalproperty_new_attach(attach)); 710 icalcomponent_add_property(a,icalproperty_new_attach(attach));
708 icalattachtype_free(attach);
709 } 711 }
710 break; 712 break;
711 case Alarm::Email: { 713 case Alarm::Email: {
712 action = ICAL_ACTION_EMAIL; 714 action = ICAL_ACTION_EMAIL;
713 QValueList<Person> addresses = alarm->mailAddresses(); 715 QValueList<Person> addresses = alarm->mailAddresses();
714 for (QValueList<Person>::Iterator ad = addresses.begin(); ad != addresses.end(); ++ad) { 716 for (QValueList<Person>::Iterator ad = addresses.begin(); ad != addresses.end(); ++ad) {
715 icalproperty *p = icalproperty_new_attendee("MAILTO:" + (*ad).email().utf8()); 717 icalproperty *p = icalproperty_new_attendee("MAILTO:" + (*ad).email().utf8());
716 if (!(*ad).name().isEmpty()) { 718 if (!(*ad).name().isEmpty()) {
717 icalproperty_add_parameter(p,icalparameter_new_cn((*ad).name().utf8())); 719 icalproperty_add_parameter(p,icalparameter_new_cn((*ad).name().utf8()));
718 } 720 }
719 icalcomponent_add_property(a,p); 721 icalcomponent_add_property(a,p);
720 } 722 }
721 icalcomponent_add_property(a,icalproperty_new_summary(alarm->mailSubject().utf8())); 723 icalcomponent_add_property(a,icalproperty_new_summary(alarm->mailSubject().utf8()));
722 icalcomponent_add_property(a,icalproperty_new_description(alarm->text().utf8())); 724 icalcomponent_add_property(a,icalproperty_new_description(alarm->text().utf8()));
723 QStringList attachments = alarm->mailAttachments(); 725 QStringList attachments = alarm->mailAttachments();
724 if (attachments.count() > 0) { 726 if (attachments.count() > 0) {
725 for (QStringList::Iterator at = attachments.begin(); at != attachments.end(); ++at) { 727 for (QStringList::Iterator at = attachments.begin(); at != attachments.end(); ++at) {
726 attach = icalattachtype_new(); 728 attach = icalattach_new_from_url(QFile::encodeName( *at ).data());
727 icalattachtype_set_url(attach,QFile::encodeName( *at ).data());
728 icalcomponent_add_property(a,icalproperty_new_attach(attach)); 729 icalcomponent_add_property(a,icalproperty_new_attach(attach));
729 icalattachtype_free(attach);
730 } 730 }
731 } 731 }
732 break; 732 break;
733 } 733 }
734 case Alarm::Display: 734 case Alarm::Display:
735 action = ICAL_ACTION_DISPLAY; 735 action = ICAL_ACTION_DISPLAY;
736 icalcomponent_add_property(a,icalproperty_new_description(alarm->text().utf8())); 736 icalcomponent_add_property(a,icalproperty_new_description(alarm->text().utf8()));
737 break; 737 break;
738 case Alarm::Invalid: 738 case Alarm::Invalid:
739 default: 739 default:
740 kdDebug(5800) << "Unknown type of alarm" << endl; 740 kdDebug(5800) << "Unknown type of alarm" << endl;
741 action = ICAL_ACTION_NONE; 741 action = ICAL_ACTION_NONE;
742 break; 742 break;
743 } 743 }
744 icalcomponent_add_property(a,icalproperty_new_action(action)); 744 icalcomponent_add_property(a,icalproperty_new_action(action));
745 745
746 // Trigger time 746 // Trigger time
747 icaltriggertype trigger; 747 icaltriggertype trigger;
748 if ( alarm->hasTime() ) { 748 if ( alarm->hasTime() ) {
749 trigger.time = writeICalDateTime(alarm->time()); 749 trigger.time = writeICalDateTime(alarm->time());
750 trigger.duration = icaldurationtype_null_duration(); 750 trigger.duration = icaldurationtype_null_duration();
751 } else { 751 } else {
752 trigger.time = icaltime_null_time(); 752 trigger.time = icaltime_null_time();
753 Duration offset; 753 Duration offset;
754 if ( alarm->hasStartOffset() ) 754 if ( alarm->hasStartOffset() )
755 offset = alarm->startOffset(); 755 offset = alarm->startOffset();
756 else 756 else
757 offset = alarm->endOffset(); 757 offset = alarm->endOffset();
758 trigger.duration = icaldurationtype_from_int( offset.asSeconds() ); 758 trigger.duration = icaldurationtype_from_int( offset.asSeconds() );
759 } 759 }
760 icalproperty *p = icalproperty_new_trigger(trigger); 760 icalproperty *p = icalproperty_new_trigger(trigger);
761 if ( alarm->hasEndOffset() ) 761 if ( alarm->hasEndOffset() )
762 icalproperty_add_parameter(p,icalparameter_new_related(ICAL_RELATED_END)); 762 icalproperty_add_parameter(p,icalparameter_new_related(ICAL_RELATED_END));
763 icalcomponent_add_property(a,p); 763 icalcomponent_add_property(a,p);
764 764
765 // Repeat count and duration 765 // Repeat count and duration
766 if (alarm->repeatCount()) { 766 if (alarm->repeatCount()) {
767 icalcomponent_add_property(a,icalproperty_new_repeat(alarm->repeatCount())); 767 icalcomponent_add_property(a,icalproperty_new_repeat(alarm->repeatCount()));
768 icalcomponent_add_property(a,icalproperty_new_duration( 768 icalcomponent_add_property(a,icalproperty_new_duration(
769 icaldurationtype_from_int(alarm->snoozeTime()*60))); 769 icaldurationtype_from_int(alarm->snoozeTime()*60)));
770 } 770 }
771 771
772 // Custom properties 772 // Custom properties
773 QMap<QCString, QString> custom = alarm->customProperties(); 773 QMap<QCString, QString> custom = alarm->customProperties();
774 for (QMap<QCString, QString>::Iterator c = custom.begin(); c != custom.end(); ++c) { 774 for (QMap<QCString, QString>::Iterator c = custom.begin(); c != custom.end(); ++c) {
775 icalproperty *p = icalproperty_new_x(c.data().utf8()); 775 icalproperty *p = icalproperty_new_x(c.data().utf8());
776 icalproperty_set_x_name(p,c.key()); 776 icalproperty_set_x_name(p,c.key());
777 icalcomponent_add_property(a,p); 777 icalcomponent_add_property(a,p);
778 } 778 }
779 779
780 return a; 780 return a;
781} 781}
782 782
783Todo *ICalFormatImpl::readTodo(icalcomponent *vtodo) 783Todo *ICalFormatImpl::readTodo(icalcomponent *vtodo)
784{ 784{
785 Todo *todo = new Todo; 785 Todo *todo = new Todo;
786 786
787 readIncidence(vtodo,todo); 787 readIncidence(vtodo,todo);
788 788
789 icalproperty *p = icalcomponent_get_first_property(vtodo,ICAL_ANY_PROPERTY); 789 icalproperty *p = icalcomponent_get_first_property(vtodo,ICAL_ANY_PROPERTY);
790 790
791// int intvalue; 791// int intvalue;
792 icaltimetype icaltime; 792 icaltimetype icaltime;
793 793
794 QStringList categories; 794 QStringList categories;
795 795
796 while (p) { 796 while (p) {
797 icalproperty_kind kind = icalproperty_isa(p); 797 icalproperty_kind kind = icalproperty_isa(p);
798 switch (kind) { 798 switch (kind) {
799 799
800 case ICAL_DUE_PROPERTY: // due date 800 case ICAL_DUE_PROPERTY: // due date
801 icaltime = icalproperty_get_due(p); 801 icaltime = icalproperty_get_due(p);
802 if (icaltime.is_date) { 802 if (icaltime.is_date) {
803 todo->setDtDue(QDateTime(readICalDate(icaltime),QTime(0,0,0))); 803 todo->setDtDue(QDateTime(readICalDate(icaltime),QTime(0,0,0)));
804 todo->setFloats(true); 804 todo->setFloats(true);
805 805
806 } else { 806 } else {
807 todo->setDtDue(readICalDateTime(icaltime)); 807 todo->setDtDue(readICalDateTime(icaltime));
808 todo->setFloats(false); 808 todo->setFloats(false);
809 } 809 }
810 todo->setHasDueDate(true); 810 todo->setHasDueDate(true);
811 break; 811 break;
812 812
813 case ICAL_COMPLETED_PROPERTY: // completion date 813 case ICAL_COMPLETED_PROPERTY: // completion date
814 icaltime = icalproperty_get_completed(p); 814 icaltime = icalproperty_get_completed(p);
815 todo->setCompleted(readICalDateTime(icaltime)); 815 todo->setCompleted(readICalDateTime(icaltime));
816 break; 816 break;
817 817
818 case ICAL_PERCENTCOMPLETE_PROPERTY: // Percent completed 818 case ICAL_PERCENTCOMPLETE_PROPERTY: // Percent completed
819 todo->setPercentComplete(icalproperty_get_percentcomplete(p)); 819 todo->setPercentComplete(icalproperty_get_percentcomplete(p));
820 break; 820 break;
821 821
822 case ICAL_RELATEDTO_PROPERTY: // related todo (parent) 822 case ICAL_RELATEDTO_PROPERTY: // related todo (parent)
823 todo->setRelatedToUid(QString::fromUtf8(icalproperty_get_relatedto(p))); 823 todo->setRelatedToUid(QString::fromUtf8(icalproperty_get_relatedto(p)));
824 mTodosRelate.append(todo); 824 mTodosRelate.append(todo);
825 break; 825 break;
826 826
827 case ICAL_DTSTART_PROPERTY: 827 case ICAL_DTSTART_PROPERTY:
828 // Flag that todo has start date. Value is read in by readIncidence(). 828 // Flag that todo has start date. Value is read in by readIncidence().
829 todo->setHasStartDate(true); 829 todo->setHasStartDate(true);
830 break; 830 break;
831 831
832 default: 832 default:
833// kdDebug(5800) << "ICALFormat::readTodo(): Unknown property: " << kind 833// kdDebug(5800) << "ICALFormat::readTodo(): Unknown property: " << kind
834// << endl; 834// << endl;
835 break; 835 break;
836 } 836 }
837 837
838 p = icalcomponent_get_next_property(vtodo,ICAL_ANY_PROPERTY); 838 p = icalcomponent_get_next_property(vtodo,ICAL_ANY_PROPERTY);
839 } 839 }
840 840
841 return todo; 841 return todo;
842} 842}
843 843
844Event *ICalFormatImpl::readEvent(icalcomponent *vevent) 844Event *ICalFormatImpl::readEvent(icalcomponent *vevent)
845{ 845{
846 Event *event = new Event; 846 Event *event = new Event;
847 event->setFloats(false); 847 event->setFloats(false);
848 848
849 readIncidence(vevent,event); 849 readIncidence(vevent,event);
850 850
851 icalproperty *p = icalcomponent_get_first_property(vevent,ICAL_ANY_PROPERTY); 851 icalproperty *p = icalcomponent_get_first_property(vevent,ICAL_ANY_PROPERTY);
852 852
853// int intvalue; 853// int intvalue;
854 icaltimetype icaltime; 854 icaltimetype icaltime;
855 855
856 QStringList categories; 856 QStringList categories;
857 QString transparency; 857 QString transparency;
858 858
859 while (p) { 859 while (p) {
860 icalproperty_kind kind = icalproperty_isa(p); 860 icalproperty_kind kind = icalproperty_isa(p);
861 switch (kind) { 861 switch (kind) {
862 862
863 case ICAL_DTEND_PROPERTY: // start date and time 863 case ICAL_DTEND_PROPERTY: // start date and time
864 icaltime = icalproperty_get_dtend(p); 864 icaltime = icalproperty_get_dtend(p);
865 if (icaltime.is_date) { 865 if (icaltime.is_date) {
866 event->setFloats( true ); 866 event->setFloats( true );
867 // End date is non-inclusive 867 // End date is non-inclusive
868 QDate endDate = readICalDate( icaltime ).addDays( -1 ); 868 QDate endDate = readICalDate( icaltime ).addDays( -1 );
869 mCompat->fixFloatingEnd( endDate ); 869 mCompat->fixFloatingEnd( endDate );
870 if ( endDate < event->dtStart().date() ) { 870 if ( endDate < event->dtStart().date() ) {
871 endDate = event->dtStart().date(); 871 endDate = event->dtStart().date();
872 } 872 }
873 event->setDtEnd( QDateTime( endDate, QTime( 0, 0, 0 ) ) ); 873 event->setDtEnd( QDateTime( endDate, QTime( 0, 0, 0 ) ) );
874 } else { 874 } else {
875 event->setDtEnd(readICalDateTime(icaltime)); 875 event->setDtEnd(readICalDateTime(icaltime));
876 } 876 }
877 break; 877 break;
878 878
879// TODO: 879// TODO:
880 // at this point, there should be at least a start or end time. 880 // at this point, there should be at least a start or end time.
881 // fix up for events that take up no time but have a time associated 881 // fix up for events that take up no time but have a time associated
882#if 0 882#if 0
883 if (!(vo = isAPropertyOf(vevent, VCDTstartProp))) 883 if (!(vo = isAPropertyOf(vevent, VCDTstartProp)))
884 anEvent->setDtStart(anEvent->dtEnd()); 884 anEvent->setDtStart(anEvent->dtEnd());
885 if (!(vo = isAPropertyOf(vevent, VCDTendProp))) 885 if (!(vo = isAPropertyOf(vevent, VCDTendProp)))
886 anEvent->setDtEnd(anEvent->dtStart()); 886 anEvent->setDtEnd(anEvent->dtStart());
887#endif 887#endif
888 888
889// TODO: exdates 889// TODO: exdates
890#if 0 890#if 0
891 // recurrence exceptions 891 // recurrence exceptions
892 if ((vo = isAPropertyOf(vevent, VCExDateProp)) != 0) { 892 if ((vo = isAPropertyOf(vevent, VCExDateProp)) != 0) {
893 anEvent->setExDates(s = fakeCString(vObjectUStringZValue(vo))); 893 anEvent->setExDates(s = fakeCString(vObjectUStringZValue(vo)));
894 deleteStr(s); 894 deleteStr(s);
895 } 895 }
896#endif 896#endif
897 897
898#if 0 898#if 0
899 // secrecy 899 // secrecy
900 if ((vo = isAPropertyOf(vevent, VCClassProp)) != 0) { 900 if ((vo = isAPropertyOf(vevent, VCClassProp)) != 0) {
901 anEvent->setSecrecy(s = fakeCString(vObjectUStringZValue(vo))); 901 anEvent->setSecrecy(s = fakeCString(vObjectUStringZValue(vo)));
902 deleteStr(s); 902 deleteStr(s);
903 } 903 }
904 else 904 else
905 anEvent->setSecrecy("PUBLIC"); 905 anEvent->setSecrecy("PUBLIC");
906 906
907 // attachments 907 // attachments
908 tmpStrList.clear(); 908 tmpStrList.clear();
909 initPropIterator(&voi, vevent); 909 initPropIterator(&voi, vevent);
910 while (moreIteration(&voi)) { 910 while (moreIteration(&voi)) {
911 vo = nextVObject(&voi); 911 vo = nextVObject(&voi);
912 if (strcmp(vObjectName(vo), VCAttachProp) == 0) { 912 if (strcmp(vObjectName(vo), VCAttachProp) == 0) {
913 tmpStrList.append(s = fakeCString(vObjectUStringZValue(vo))); 913 tmpStrList.append(s = fakeCString(vObjectUStringZValue(vo)));
914 deleteStr(s); 914 deleteStr(s);
915 } 915 }
916 } 916 }
917 anEvent->setAttachments(tmpStrList); 917 anEvent->setAttachments(tmpStrList);
918 918
919 // resources 919 // resources
920 if ((vo = isAPropertyOf(vevent, VCResourcesProp)) != 0) { 920 if ((vo = isAPropertyOf(vevent, VCResourcesProp)) != 0) {
921 QString resources = (s = fakeCString(vObjectUStringZValue(vo))); 921 QString resources = (s = fakeCString(vObjectUStringZValue(vo)));
922 deleteStr(s); 922 deleteStr(s);
923 tmpStrList.clear(); 923 tmpStrList.clear();
924 index1 = 0; 924 index1 = 0;
925 index2 = 0; 925 index2 = 0;
926 QString resource; 926 QString resource;
927 while ((index2 = resources.find(';', index1)) != -1) { 927 while ((index2 = resources.find(';', index1)) != -1) {
928 resource = resources.mid(index1, (index2 - index1)); 928 resource = resources.mid(index1, (index2 - index1));
929 tmpStrList.append(resource); 929 tmpStrList.append(resource);
930 index1 = index2; 930 index1 = index2;
931 } 931 }
932 anEvent->setResources(tmpStrList); 932 anEvent->setResources(tmpStrList);
933 } 933 }
934#endif 934#endif
935 935
936 case ICAL_RELATEDTO_PROPERTY: // releated event (parent) 936 case ICAL_RELATEDTO_PROPERTY: // releated event (parent)
937 event->setRelatedToUid(QString::fromUtf8(icalproperty_get_relatedto(p))); 937 event->setRelatedToUid(QString::fromUtf8(icalproperty_get_relatedto(p)));
938 mEventsRelate.append(event); 938 mEventsRelate.append(event);
939 break; 939 break;
940 940
941
942 case ICAL_TRANSP_PROPERTY: // Transparency 941 case ICAL_TRANSP_PROPERTY: // Transparency
943 transparency = QString::fromUtf8(icalproperty_get_transp(p)); 942 if(icalproperty_get_transp(p) == ICAL_TRANSP_TRANSPARENT )
944 if( transparency == "TRANSPARENT" )
945 event->setTransparency( Event::Transparent ); 943 event->setTransparency( Event::Transparent );
946 else 944 else
947 event->setTransparency( Event::Opaque ); 945 event->setTransparency( Event::Opaque );
948 break; 946 break;
949 947
950 default: 948 default:
951// kdDebug(5800) << "ICALFormat::readEvent(): Unknown property: " << kind 949// kdDebug(5800) << "ICALFormat::readEvent(): Unknown property: " << kind
952// << endl; 950// << endl;
953 break; 951 break;
954 } 952 }
955 953
956 p = icalcomponent_get_next_property(vevent,ICAL_ANY_PROPERTY); 954 p = icalcomponent_get_next_property(vevent,ICAL_ANY_PROPERTY);
957 } 955 }
958 956
959 QString msade = event->nonKDECustomProperty("X-MICROSOFT-CDO-ALLDAYEVENT"); 957 QString msade = event->nonKDECustomProperty("X-MICROSOFT-CDO-ALLDAYEVENT");
960 if (!msade.isNull()) { 958 if (!msade.isNull()) {
961 bool floats = (msade == QString::fromLatin1("TRUE")); 959 bool floats = (msade == QString::fromLatin1("TRUE"));
962 kdDebug(5800) << "ICALFormat::readEvent(): all day event: " << floats << endl; 960 kdDebug(5800) << "ICALFormat::readEvent(): all day event: " << floats << endl;
963 event->setFloats(floats); 961 event->setFloats(floats);
964 if (floats) { 962 if (floats) {
965 QDateTime endDate = event->dtEnd(); 963 QDateTime endDate = event->dtEnd();
966 event->setDtEnd(endDate.addDays(-1)); 964 event->setDtEnd(endDate.addDays(-1));
967 } 965 }
968 } 966 }
969 967
970 // some stupid vCal exporters ignore the standard and use Description 968 // some stupid vCal exporters ignore the standard and use Description
971 // instead of Summary for the default field. Correct for this. 969 // instead of Summary for the default field. Correct for this.
972 if (event->summary().isEmpty() && 970 if (event->summary().isEmpty() &&
973 !(event->description().isEmpty())) { 971 !(event->description().isEmpty())) {
974 QString tmpStr = event->description().simplifyWhiteSpace(); 972 QString tmpStr = event->description().simplifyWhiteSpace();
975 event->setDescription(""); 973 event->setDescription("");
976 event->setSummary(tmpStr); 974 event->setSummary(tmpStr);
977 } 975 }
978 976
979 return event; 977 return event;
980} 978}
981 979
982FreeBusy *ICalFormatImpl::readFreeBusy(icalcomponent *vfreebusy) 980FreeBusy *ICalFormatImpl::readFreeBusy(icalcomponent *vfreebusy)
983{ 981{
984 FreeBusy *freebusy = new FreeBusy; 982 FreeBusy *freebusy = new FreeBusy;
985 983
986 readIncidenceBase(vfreebusy,freebusy); 984 readIncidenceBase(vfreebusy,freebusy);
987 985
988 icalproperty *p = icalcomponent_get_first_property(vfreebusy,ICAL_ANY_PROPERTY); 986 icalproperty *p = icalcomponent_get_first_property(vfreebusy,ICAL_ANY_PROPERTY);
989 987
990 icaltimetype icaltime; 988 icaltimetype icaltime;
991 icalperiodtype icalperiod; 989 icalperiodtype icalperiod;
992 QDateTime period_start, period_end; 990 QDateTime period_start, period_end;
993 991
994 while (p) { 992 while (p) {
995 icalproperty_kind kind = icalproperty_isa(p); 993 icalproperty_kind kind = icalproperty_isa(p);
996 switch (kind) { 994 switch (kind) {
997 995
998 case ICAL_DTSTART_PROPERTY: // start date and time 996 case ICAL_DTSTART_PROPERTY: // start date and time
999 icaltime = icalproperty_get_dtstart(p); 997 icaltime = icalproperty_get_dtstart(p);
1000 freebusy->setDtStart(readICalDateTime(icaltime)); 998 freebusy->setDtStart(readICalDateTime(icaltime));
1001 break; 999 break;
1002 1000
1003 case ICAL_DTEND_PROPERTY: // start End Date and Time 1001 case ICAL_DTEND_PROPERTY: // start End Date and Time
1004 icaltime = icalproperty_get_dtend(p); 1002 icaltime = icalproperty_get_dtend(p);
1005 freebusy->setDtEnd(readICalDateTime(icaltime)); 1003 freebusy->setDtEnd(readICalDateTime(icaltime));
1006 break; 1004 break;
1007 1005
1008 case ICAL_FREEBUSY_PROPERTY: //Any FreeBusy Times 1006 case ICAL_FREEBUSY_PROPERTY: //Any FreeBusy Times
1009 icalperiod = icalproperty_get_freebusy(p); 1007 icalperiod = icalproperty_get_freebusy(p);
1010 period_start = readICalDateTime(icalperiod.start); 1008 period_start = readICalDateTime(icalperiod.start);
1011 period_end = readICalDateTime(icalperiod.end); 1009 period_end = readICalDateTime(icalperiod.end);
1012 freebusy->addPeriod(period_start, period_end); 1010 freebusy->addPeriod(period_start, period_end);
1013 break; 1011 break;
1014 1012
1015 default: 1013 default:
1016 kdDebug(5800) << "ICALFormat::readIncidence(): Unknown property: " << kind 1014 kdDebug(5800) << "ICALFormat::readIncidence(): Unknown property: " << kind
1017 << endl; 1015 << endl;
1018 break; 1016 break;
1019 } 1017 }
1020 p = icalcomponent_get_next_property(vfreebusy,ICAL_ANY_PROPERTY); 1018 p = icalcomponent_get_next_property(vfreebusy,ICAL_ANY_PROPERTY);
1021 } 1019 }
1022 1020
1023 return freebusy; 1021 return freebusy;
1024} 1022}
1025 1023
1026Journal *ICalFormatImpl::readJournal(icalcomponent *vjournal) 1024Journal *ICalFormatImpl::readJournal(icalcomponent *vjournal)
1027{ 1025{
1028 Journal *journal = new Journal; 1026 Journal *journal = new Journal;
1029 1027
1030 readIncidence(vjournal,journal); 1028 readIncidence(vjournal,journal);
1031 1029
1032 return journal; 1030 return journal;
1033} 1031}
1034 1032
1035Attendee *ICalFormatImpl::readAttendee(icalproperty *attendee) 1033Attendee *ICalFormatImpl::readAttendee(icalproperty *attendee)
1036{ 1034{
1037 icalparameter *p = 0; 1035 icalparameter *p = 0;
1038 1036
1039 QString email = QString::fromUtf8(icalproperty_get_attendee(attendee)); 1037 QString email = QString::fromUtf8(icalproperty_get_attendee(attendee));
1040 1038
1041 QString name; 1039 QString name;
1042 QString uid = QString::null; 1040 QString uid = QString::null;
1043 p = icalproperty_get_first_parameter(attendee,ICAL_CN_PARAMETER); 1041 p = icalproperty_get_first_parameter(attendee,ICAL_CN_PARAMETER);
1044 if (p) { 1042 if (p) {
1045 name = QString::fromUtf8(icalparameter_get_cn(p)); 1043 name = QString::fromUtf8(icalparameter_get_cn(p));
1046 } else { 1044 } else {
1047 } 1045 }
1048 1046
1049 bool rsvp=false; 1047 bool rsvp=false;
1050 p = icalproperty_get_first_parameter(attendee,ICAL_RSVP_PARAMETER); 1048 p = icalproperty_get_first_parameter(attendee,ICAL_RSVP_PARAMETER);
1051 if (p) { 1049 if (p) {
1052 icalparameter_rsvp rsvpParameter = icalparameter_get_rsvp(p); 1050 icalparameter_rsvp rsvpParameter = icalparameter_get_rsvp(p);
1053 if (rsvpParameter == ICAL_RSVP_TRUE) rsvp = true; 1051 if (rsvpParameter == ICAL_RSVP_TRUE) rsvp = true;
1054 } 1052 }
1055 1053
1056 Attendee::PartStat status = Attendee::NeedsAction; 1054 Attendee::PartStat status = Attendee::NeedsAction;
1057 p = icalproperty_get_first_parameter(attendee,ICAL_PARTSTAT_PARAMETER); 1055 p = icalproperty_get_first_parameter(attendee,ICAL_PARTSTAT_PARAMETER);
1058 if (p) { 1056 if (p) {
1059 icalparameter_partstat partStatParameter = icalparameter_get_partstat(p); 1057 icalparameter_partstat partStatParameter = icalparameter_get_partstat(p);
1060 switch(partStatParameter) { 1058 switch(partStatParameter) {
1061 default: 1059 default:
1062 case ICAL_PARTSTAT_NEEDSACTION: 1060 case ICAL_PARTSTAT_NEEDSACTION:
1063 status = Attendee::NeedsAction; 1061 status = Attendee::NeedsAction;
1064 break; 1062 break;
1065 case ICAL_PARTSTAT_ACCEPTED: 1063 case ICAL_PARTSTAT_ACCEPTED:
1066 status = Attendee::Accepted; 1064 status = Attendee::Accepted;
1067 break; 1065 break;
1068 case ICAL_PARTSTAT_DECLINED: 1066 case ICAL_PARTSTAT_DECLINED:
1069 status = Attendee::Declined; 1067 status = Attendee::Declined;
1070 break; 1068 break;
1071 case ICAL_PARTSTAT_TENTATIVE: 1069 case ICAL_PARTSTAT_TENTATIVE:
1072 status = Attendee::Tentative; 1070 status = Attendee::Tentative;
1073 break; 1071 break;
1074 case ICAL_PARTSTAT_DELEGATED: 1072 case ICAL_PARTSTAT_DELEGATED:
1075 status = Attendee::Delegated; 1073 status = Attendee::Delegated;
1076 break; 1074 break;
1077 case ICAL_PARTSTAT_COMPLETED: 1075 case ICAL_PARTSTAT_COMPLETED:
1078 status = Attendee::Completed; 1076 status = Attendee::Completed;
1079 break; 1077 break;
1080 case ICAL_PARTSTAT_INPROCESS: 1078 case ICAL_PARTSTAT_INPROCESS:
1081 status = Attendee::InProcess; 1079 status = Attendee::InProcess;
1082 break; 1080 break;
1083 } 1081 }
1084 } 1082 }
1085 1083
1086 Attendee::Role role = Attendee::ReqParticipant; 1084 Attendee::Role role = Attendee::ReqParticipant;
1087 p = icalproperty_get_first_parameter(attendee,ICAL_ROLE_PARAMETER); 1085 p = icalproperty_get_first_parameter(attendee,ICAL_ROLE_PARAMETER);
1088 if (p) { 1086 if (p) {
1089 icalparameter_role roleParameter = icalparameter_get_role(p); 1087 icalparameter_role roleParameter = icalparameter_get_role(p);
1090 switch(roleParameter) { 1088 switch(roleParameter) {
1091 case ICAL_ROLE_CHAIR: 1089 case ICAL_ROLE_CHAIR:
1092 role = Attendee::Chair; 1090 role = Attendee::Chair;
1093 break; 1091 break;
1094 default: 1092 default:
1095 case ICAL_ROLE_REQPARTICIPANT: 1093 case ICAL_ROLE_REQPARTICIPANT:
1096 role = Attendee::ReqParticipant; 1094 role = Attendee::ReqParticipant;
1097 break; 1095 break;
1098 case ICAL_ROLE_OPTPARTICIPANT: 1096 case ICAL_ROLE_OPTPARTICIPANT:
1099 role = Attendee::OptParticipant; 1097 role = Attendee::OptParticipant;
1100 break; 1098 break;
1101 case ICAL_ROLE_NONPARTICIPANT: 1099 case ICAL_ROLE_NONPARTICIPANT:
1102 role = Attendee::NonParticipant; 1100 role = Attendee::NonParticipant;
1103 break; 1101 break;
1104 } 1102 }
1105 } 1103 }
1106 1104
1107 p = icalproperty_get_first_parameter(attendee,ICAL_X_PARAMETER); 1105 p = icalproperty_get_first_parameter(attendee,ICAL_X_PARAMETER);
1108 uid = icalparameter_get_xvalue(p); 1106 uid = icalparameter_get_xvalue(p);
1109 // This should be added, but there seems to be a libical bug here. 1107 // This should be added, but there seems to be a libical bug here.
1110 /*while (p) { 1108 /*while (p) {
1111 // if (icalparameter_get_xname(p) == "X-UID") { 1109 // if (icalparameter_get_xname(p) == "X-UID") {
1112 uid = icalparameter_get_xvalue(p); 1110 uid = icalparameter_get_xvalue(p);
1113 p = icalproperty_get_next_parameter(attendee,ICAL_X_PARAMETER); 1111 p = icalproperty_get_next_parameter(attendee,ICAL_X_PARAMETER);
1114 } */ 1112 } */
1115 1113
1116 return new Attendee( name, email, rsvp, status, role, uid ); 1114 return new Attendee( name, email, rsvp, status, role, uid );
1117} 1115}
1118 1116
1119Attachment *ICalFormatImpl::readAttachment(icalproperty *attach) 1117Attachment *ICalFormatImpl::readAttachment(icalproperty *attach)
1120{ 1118{
1121 icalattachtype *a = icalproperty_get_attach(attach); 1119 icalattach *a = icalproperty_get_attach(attach);
1122 icalparameter_value v = ICAL_VALUE_NONE; 1120 icalparameter_value v = ICAL_VALUE_NONE;
1123 icalparameter_encoding e = ICAL_ENCODING_NONE; 1121 icalparameter_encoding e = ICAL_ENCODING_NONE;
1124 1122
1125 Attachment *attachment = 0; 1123 Attachment *attachment = 0;
1126 1124 /*
1127 icalparameter *vp = icalproperty_get_first_parameter(attach, ICAL_VALUE_PARAMETER); 1125 icalparameter *vp = icalproperty_get_first_parameter(attach, ICAL_VALUE_PARAMETER);
1128 if (vp) 1126 if (vp)
1129 v = icalparameter_get_value(vp); 1127 v = icalparameter_get_value(vp);
1130 1128
1131 icalparameter *ep = icalproperty_get_first_parameter(attach, ICAL_ENCODING_PARAMETER); 1129 icalparameter *ep = icalproperty_get_first_parameter(attach, ICAL_ENCODING_PARAMETER);
1132 if (ep) 1130 if (ep)
1133 e = icalparameter_get_encoding(ep); 1131 e = icalparameter_get_encoding(ep);
1134 1132 */
1135 if (v == ICAL_VALUE_BINARY && e == ICAL_ENCODING_BASE64) 1133 int isurl = icalattach_get_is_url (a);
1136 attachment = new Attachment(icalattachtype_get_base64(a)); 1134 if (isurl == 0)
1137 else if ((v == ICAL_VALUE_NONE || v == ICAL_VALUE_URI) && (e == ICAL_ENCODING_NONE || e == ICAL_ENCODING_8BIT)) { 1135 attachment = new Attachment((const char*)icalattach_get_data(a));
1138 attachment = new Attachment(QString(icalattachtype_get_url(a))); 1136 else {
1139 } else { 1137 attachment = new Attachment(QString(icalattach_get_url(a)));
1140 kdWarning(5800) << "Unsupported attachment format, discarding it!" << endl;
1141 return 0;
1142 } 1138 }
1143 1139
1144 icalparameter *p = icalproperty_get_first_parameter(attach, ICAL_FMTTYPE_PARAMETER); 1140 icalparameter *p = icalproperty_get_first_parameter(attach, ICAL_FMTTYPE_PARAMETER);
1145 if (p) 1141 if (p)
1146 attachment->setMimeType(QString(icalparameter_get_fmttype(p))); 1142 attachment->setMimeType(QString(icalparameter_get_fmttype(p)));
1147 1143
1148 return attachment; 1144 return attachment;
1149} 1145}
1150#include <qtextcodec.h> 1146#include <qtextcodec.h>
1151void ICalFormatImpl::readIncidence(icalcomponent *parent,Incidence *incidence) 1147void ICalFormatImpl::readIncidence(icalcomponent *parent,Incidence *incidence)
1152{ 1148{
1153 readIncidenceBase(parent,incidence); 1149 readIncidenceBase(parent,incidence);
1154 1150
1155 icalproperty *p = icalcomponent_get_first_property(parent,ICAL_ANY_PROPERTY); 1151 icalproperty *p = icalcomponent_get_first_property(parent,ICAL_ANY_PROPERTY);
1156 bool readrec = false; 1152 bool readrec = false;
1157 const char *text; 1153 const char *text;
1158 int intvalue; 1154 int intvalue;
1159 icaltimetype icaltime; 1155 icaltimetype icaltime;
1160 icaldurationtype icalduration; 1156 icaldurationtype icalduration;
1161 struct icalrecurrencetype rectype; 1157 struct icalrecurrencetype rectype;
1162 QStringList categories; 1158 QStringList categories;
1163 1159
1164 while (p) { 1160 while (p) {
1165 icalproperty_kind kind = icalproperty_isa(p); 1161 icalproperty_kind kind = icalproperty_isa(p);
1166 switch (kind) { 1162 switch (kind) {
1167 1163
1168 case ICAL_CREATED_PROPERTY: 1164 case ICAL_CREATED_PROPERTY:
1169 icaltime = icalproperty_get_created(p); 1165 icaltime = icalproperty_get_created(p);
1170 incidence->setCreated(readICalDateTime(icaltime)); 1166 incidence->setCreated(readICalDateTime(icaltime));
1171 break; 1167 break;
1172 1168
1173 case ICAL_SEQUENCE_PROPERTY: // sequence 1169 case ICAL_SEQUENCE_PROPERTY: // sequence
1174 intvalue = icalproperty_get_sequence(p); 1170 intvalue = icalproperty_get_sequence(p);
1175 incidence->setRevision(intvalue); 1171 incidence->setRevision(intvalue);
1176 break; 1172 break;
1177 1173
1178 case ICAL_LASTMODIFIED_PROPERTY: // last modification date 1174 case ICAL_LASTMODIFIED_PROPERTY: // last modification date
1179 icaltime = icalproperty_get_lastmodified(p); 1175 icaltime = icalproperty_get_lastmodified(p);
1180 incidence->setLastModified(readICalDateTime(icaltime)); 1176 incidence->setLastModified(readICalDateTime(icaltime));
1181 break; 1177 break;
1182 1178
1183 case ICAL_DTSTART_PROPERTY: // start date and time 1179 case ICAL_DTSTART_PROPERTY: // start date and time
1184 icaltime = icalproperty_get_dtstart(p); 1180 icaltime = icalproperty_get_dtstart(p);
1185 if (icaltime.is_date) { 1181 if (icaltime.is_date) {
1186 incidence->setDtStart(QDateTime(readICalDate(icaltime),QTime(0,0,0))); 1182 incidence->setDtStart(QDateTime(readICalDate(icaltime),QTime(0,0,0)));
1187 incidence->setFloats(true); 1183 incidence->setFloats(true);
1188 } else { 1184 } else {
1189 incidence->setDtStart(readICalDateTime(icaltime)); 1185 incidence->setDtStart(readICalDateTime(icaltime));
1190 } 1186 }
1191 break; 1187 break;
1192 1188
1193 case ICAL_DURATION_PROPERTY: // start date and time 1189 case ICAL_DURATION_PROPERTY: // start date and time
1194 icalduration = icalproperty_get_duration(p); 1190 icalduration = icalproperty_get_duration(p);
1195 incidence->setDuration(readICalDuration(icalduration)); 1191 incidence->setDuration(readICalDuration(icalduration));
1196 break; 1192 break;
1197 1193
1198 case ICAL_DESCRIPTION_PROPERTY: // description 1194 case ICAL_DESCRIPTION_PROPERTY: // description
1199 text = icalproperty_get_description(p); 1195 text = icalproperty_get_description(p);
1200 incidence->setDescription(QString::fromUtf8(text)); 1196 incidence->setDescription(QString::fromUtf8(text));
1201 break; 1197 break;
1202 1198
1203 case ICAL_SUMMARY_PROPERTY: // summary 1199 case ICAL_SUMMARY_PROPERTY: // summary
1204 { 1200 {
1205 text = icalproperty_get_summary(p); 1201 text = icalproperty_get_summary(p);
1206 incidence->setSummary(QString::fromUtf8(text)); 1202 incidence->setSummary(QString::fromUtf8(text));
1207 } 1203 }
1208 break; 1204 break;
1209 case ICAL_STATUS_PROPERTY: // summary 1205 case ICAL_STATUS_PROPERTY: // summary
1210 { 1206 {
1211 if ( ICAL_STATUS_CANCELLED == icalproperty_get_status(p) ) 1207 if ( ICAL_STATUS_CANCELLED == icalproperty_get_status(p) )
1212 incidence->setCancelled( true ); 1208 incidence->setCancelled( true );
1213 } 1209 }
1214 break; 1210 break;
1215 1211
1216 case ICAL_LOCATION_PROPERTY: // location 1212 case ICAL_LOCATION_PROPERTY: // location
1217 text = icalproperty_get_location(p); 1213 text = icalproperty_get_location(p);
1218 incidence->setLocation(QString::fromUtf8(text)); 1214 incidence->setLocation(QString::fromUtf8(text));
1219 break; 1215 break;
1220 1216
1221#if 0 1217#if 0
1222 // status 1218 // status
1223 if ((vo = isAPropertyOf(vincidence, VCStatusProp)) != 0) { 1219 if ((vo = isAPropertyOf(vincidence, VCStatusProp)) != 0) {
1224 incidence->setStatus(s = fakeCString(vObjectUStringZValue(vo))); 1220 incidence->setStatus(s = fakeCString(vObjectUStringZValue(vo)));
1225 deleteStr(s); 1221 deleteStr(s);
1226 } 1222 }
1227 else 1223 else
1228 incidence->setStatus("NEEDS ACTION"); 1224 incidence->setStatus("NEEDS ACTION");
1229#endif 1225#endif
1230 1226
1231 case ICAL_PRIORITY_PROPERTY: // priority 1227 case ICAL_PRIORITY_PROPERTY: // priority
1232 intvalue = icalproperty_get_priority(p); 1228 intvalue = icalproperty_get_priority(p);
1233 incidence->setPriority(intvalue); 1229 incidence->setPriority(intvalue);
1234 break; 1230 break;
1235 1231
1236 case ICAL_CATEGORIES_PROPERTY: // categories 1232 case ICAL_CATEGORIES_PROPERTY: // categories
1237 text = icalproperty_get_categories(p); 1233 text = icalproperty_get_categories(p);
1238 categories.append(QString::fromUtf8(text)); 1234 categories.append(QString::fromUtf8(text));
1239 break; 1235 break;
1240 //******************************************* 1236 //*******************************************
1241 case ICAL_RRULE_PROPERTY: 1237 case ICAL_RRULE_PROPERTY:
1242 // we do need (maybe )start datetime of incidence for recurrence 1238 // we do need (maybe )start datetime of incidence for recurrence
1243 // such that we can read recurrence only after we read incidence completely 1239 // such that we can read recurrence only after we read incidence completely
1244 readrec = true; 1240 readrec = true;
1245 rectype = icalproperty_get_rrule(p); 1241 rectype = icalproperty_get_rrule(p);
1246 break; 1242 break;
1247 1243
1248 case ICAL_EXDATE_PROPERTY: 1244 case ICAL_EXDATE_PROPERTY:
1249 icaltime = icalproperty_get_exdate(p); 1245 icaltime = icalproperty_get_exdate(p);
1250 incidence->addExDate(readICalDate(icaltime)); 1246 incidence->addExDate(readICalDate(icaltime));
1251 break; 1247 break;
1252 1248
1253 case ICAL_CLASS_PROPERTY: 1249 case ICAL_CLASS_PROPERTY: {
1254 text = icalproperty_get_class(p); 1250 int inttext = icalproperty_get_class(p);
1255 if (strcmp(text,"PUBLIC") == 0) { 1251 if (inttext == ICAL_CLASS_PUBLIC ) {
1256 incidence->setSecrecy(Incidence::SecrecyPublic); 1252 incidence->setSecrecy(Incidence::SecrecyPublic);
1257 } else if (strcmp(text,"CONFIDENTIAL") == 0) { 1253 } else if (inttext == ICAL_CLASS_CONFIDENTIAL ) {
1258 incidence->setSecrecy(Incidence::SecrecyConfidential); 1254 incidence->setSecrecy(Incidence::SecrecyConfidential);
1259 } else { 1255 } else {
1260 incidence->setSecrecy(Incidence::SecrecyPrivate); 1256 incidence->setSecrecy(Incidence::SecrecyPrivate);
1261 } 1257 }
1258 }
1262 break; 1259 break;
1263 1260
1264 case ICAL_ATTACH_PROPERTY: // attachments 1261 case ICAL_ATTACH_PROPERTY: // attachments
1265 incidence->addAttachment(readAttachment(p)); 1262 incidence->addAttachment(readAttachment(p));
1266 break; 1263 break;
1267 1264
1268 default: 1265 default:
1269// kdDebug(5800) << "ICALFormat::readIncidence(): Unknown property: " << kind 1266// kdDebug(5800) << "ICALFormat::readIncidence(): Unknown property: " << kind
1270// << endl; 1267// << endl;
1271 break; 1268 break;
1272 } 1269 }
1273 1270
1274 p = icalcomponent_get_next_property(parent,ICAL_ANY_PROPERTY); 1271 p = icalcomponent_get_next_property(parent,ICAL_ANY_PROPERTY);
1275 } 1272 }
1276 if ( readrec ) { 1273 if ( readrec ) {
1277 readRecurrenceRule(rectype,incidence); 1274 readRecurrenceRule(rectype,incidence);
1278 } 1275 }
1279 // kpilot stuff 1276 // kpilot stuff
1280// TODO: move this application-specific code to kpilot 1277// TODO: move this application-specific code to kpilot
1281 QString kp = incidence->nonKDECustomProperty("X-PILOTID"); 1278 QString kp = incidence->nonKDECustomProperty("X-PILOTID");
1282 if (!kp.isNull()) { 1279 if (!kp.isNull()) {
1283 incidence->setPilotId(kp.toInt()); 1280 incidence->setPilotId(kp.toInt());
1284 } 1281 }
1285 kp = incidence->nonKDECustomProperty("X-PILOTSTAT"); 1282 kp = incidence->nonKDECustomProperty("X-PILOTSTAT");
1286 if (!kp.isNull()) { 1283 if (!kp.isNull()) {
1287 incidence->setSyncStatus(kp.toInt()); 1284 incidence->setSyncStatus(kp.toInt());
1288 } 1285 }
1289 kp = incidence->nonKDECustomProperty("X-ZAURUSID"); 1286 kp = incidence->nonKDECustomProperty("X-ZAURUSID");
1290 if (!kp.isNull()) { 1287 if (!kp.isNull()) {
1291 incidence->setZaurusId(kp.toInt()); 1288 incidence->setZaurusId(kp.toInt());
1292 } 1289 }
1293 1290
1294 kp = incidence->nonKDECustomProperty("X-ZAURUSUID"); 1291 kp = incidence->nonKDECustomProperty("X-ZAURUSUID");
1295 if (!kp.isNull()) { 1292 if (!kp.isNull()) {
1296 incidence->setZaurusUid(kp.toInt()); 1293 incidence->setZaurusUid(kp.toInt());
1297 } 1294 }
1298 1295
1299 kp = incidence->nonKDECustomProperty("X-ZAURUSSTAT"); 1296 kp = incidence->nonKDECustomProperty("X-ZAURUSSTAT");
1300 if (!kp.isNull()) { 1297 if (!kp.isNull()) {
1301 incidence->setZaurusStat(kp.toInt()); 1298 incidence->setZaurusStat(kp.toInt());
1302 } 1299 }
1303 1300
1304 // Cancel backwards compatibility mode for subsequent changes by the application 1301 // Cancel backwards compatibility mode for subsequent changes by the application
1305 incidence->recurrence()->setCompatVersion(); 1302 incidence->recurrence()->setCompatVersion();
1306 1303
1307 // add categories 1304 // add categories
1308 incidence->setCategories(categories); 1305 incidence->setCategories(categories);
1309 1306
1310 // iterate through all alarms 1307 // iterate through all alarms
1311 for (icalcomponent *alarm = icalcomponent_get_first_component(parent,ICAL_VALARM_COMPONENT); 1308 for (icalcomponent *alarm = icalcomponent_get_first_component(parent,ICAL_VALARM_COMPONENT);
1312 alarm; 1309 alarm;
1313 alarm = icalcomponent_get_next_component(parent,ICAL_VALARM_COMPONENT)) { 1310 alarm = icalcomponent_get_next_component(parent,ICAL_VALARM_COMPONENT)) {
1314 readAlarm(alarm,incidence); 1311 readAlarm(alarm,incidence);
1315 } 1312 }
1316} 1313}
1317 1314
1318void ICalFormatImpl::readIncidenceBase(icalcomponent *parent,IncidenceBase *incidenceBase) 1315void ICalFormatImpl::readIncidenceBase(icalcomponent *parent,IncidenceBase *incidenceBase)
1319{ 1316{
1320 icalproperty *p = icalcomponent_get_first_property(parent,ICAL_ANY_PROPERTY); 1317 icalproperty *p = icalcomponent_get_first_property(parent,ICAL_ANY_PROPERTY);
1321 1318
1322 while (p) { 1319 while (p) {
1323 icalproperty_kind kind = icalproperty_isa(p); 1320 icalproperty_kind kind = icalproperty_isa(p);
1324 switch (kind) { 1321 switch (kind) {
1325 1322
1326 case ICAL_UID_PROPERTY: // unique id 1323 case ICAL_UID_PROPERTY: // unique id
1327 incidenceBase->setUid(QString::fromUtf8(icalproperty_get_uid(p))); 1324 incidenceBase->setUid(QString::fromUtf8(icalproperty_get_uid(p)));
1328 break; 1325 break;
1329 1326
1330 case ICAL_ORGANIZER_PROPERTY: // organizer 1327 case ICAL_ORGANIZER_PROPERTY: // organizer
1331 incidenceBase->setOrganizer(QString::fromUtf8(icalproperty_get_organizer(p))); 1328 incidenceBase->setOrganizer(QString::fromUtf8(icalproperty_get_organizer(p)));
1332 break; 1329 break;
1333 1330
1334 case ICAL_ATTENDEE_PROPERTY: // attendee 1331 case ICAL_ATTENDEE_PROPERTY: // attendee
1335 incidenceBase->addAttendee(readAttendee(p)); 1332 incidenceBase->addAttendee(readAttendee(p));
1336 break; 1333 break;
1337 1334
1338 default: 1335 default:
1339 break; 1336 break;
1340 } 1337 }
1341 1338
1342 p = icalcomponent_get_next_property(parent,ICAL_ANY_PROPERTY); 1339 p = icalcomponent_get_next_property(parent,ICAL_ANY_PROPERTY);
1343 } 1340 }
1344 1341
1345 // custom properties 1342 // custom properties
1346 readCustomProperties(parent, incidenceBase); 1343 readCustomProperties(parent, incidenceBase);
1347} 1344}
1348 1345
1349void ICalFormatImpl::readCustomProperties(icalcomponent *parent,CustomProperties *properties) 1346void ICalFormatImpl::readCustomProperties(icalcomponent *parent,CustomProperties *properties)
1350{ 1347{
1351 QMap<QCString, QString> customProperties; 1348 QMap<QCString, QString> customProperties;
1352 1349
1353 icalproperty *p = icalcomponent_get_first_property(parent,ICAL_X_PROPERTY); 1350 icalproperty *p = icalcomponent_get_first_property(parent,ICAL_X_PROPERTY);
1354 1351
1355 while (p) { 1352 while (p) {
1356
1357 QString value = QString::fromUtf8(icalproperty_get_x(p)); 1353 QString value = QString::fromUtf8(icalproperty_get_x(p));
1358 customProperties[icalproperty_get_name(p)] = value; 1354 customProperties[icalproperty_get_x_name(p)] = value;
1355 //qDebug("ICalFormatImpl::readCustomProperties %s %s",value.latin1(), icalproperty_get_x_name(p) );
1359 1356
1360 p = icalcomponent_get_next_property(parent,ICAL_X_PROPERTY); 1357 p = icalcomponent_get_next_property(parent,ICAL_X_PROPERTY);
1361 } 1358 }
1362 1359
1363 properties->setCustomProperties(customProperties); 1360 properties->setCustomProperties(customProperties);
1364} 1361}
1365 1362
1366void ICalFormatImpl::readRecurrenceRule(struct icalrecurrencetype rrule,Incidence *incidence) 1363void ICalFormatImpl::readRecurrenceRule(struct icalrecurrencetype rrule,Incidence *incidence)
1367{ 1364{
1368// kdDebug(5800) << "Read recurrence for " << incidence->summary() << endl; 1365// kdDebug(5800) << "Read recurrence for " << incidence->summary() << endl;
1369 1366
1370 Recurrence *recur = incidence->recurrence(); 1367 Recurrence *recur = incidence->recurrence();
1371 recur->setCompatVersion(mCalendarVersion); 1368 recur->setCompatVersion(mCalendarVersion);
1372 recur->unsetRecurs(); 1369 recur->unsetRecurs();
1373 1370
1374 struct icalrecurrencetype r = rrule; 1371 struct icalrecurrencetype r = rrule;
1375 1372
1376 dumpIcalRecurrence(r); 1373 dumpIcalRecurrence(r);
1377 readRecurrence( r, recur, incidence); 1374 readRecurrence( r, recur, incidence);
1378} 1375}
1379 1376
1380void ICalFormatImpl::readRecurrence( const struct icalrecurrencetype &r, Recurrence* recur, Incidence *incidence) 1377void ICalFormatImpl::readRecurrence( const struct icalrecurrencetype &r, Recurrence* recur, Incidence *incidence)
1381{ 1378{
1382 int wkst; 1379 int wkst;
1383 int index = 0; 1380 int index = 0;
1384 short day = 0; 1381 short day = 0;
1385 QBitArray qba(7); 1382 QBitArray qba(7);
1386 int frequ = r.freq; 1383 int frequ = r.freq;
1387 int interv = r.interval; 1384 int interv = r.interval;
1388 // preprocessing for odd recurrence definitions 1385 // preprocessing for odd recurrence definitions
1389 1386
1390 if ( r.freq == ICAL_MONTHLY_RECURRENCE ) { 1387 if ( r.freq == ICAL_MONTHLY_RECURRENCE ) {
1391 if ( r.by_month[0] != ICAL_RECURRENCE_ARRAY_MAX) { 1388 if ( r.by_month[0] != ICAL_RECURRENCE_ARRAY_MAX) {
1392 interv = 12; 1389 interv = 12;
1393 } 1390 }
1394 } 1391 }
1395 if ( r.freq == ICAL_YEARLY_RECURRENCE ) { 1392 if ( r.freq == ICAL_YEARLY_RECURRENCE ) {
1396 if ( r.by_month[0] != ICAL_RECURRENCE_ARRAY_MAX && r.by_day[0] != ICAL_RECURRENCE_ARRAY_MAX ) { 1393 if ( r.by_month[0] != ICAL_RECURRENCE_ARRAY_MAX && r.by_day[0] != ICAL_RECURRENCE_ARRAY_MAX ) {
1397 frequ = ICAL_MONTHLY_RECURRENCE; 1394 frequ = ICAL_MONTHLY_RECURRENCE;
1398 interv = 12; 1395 interv = 12;
1399 } 1396 }
1400 } 1397 }
1401 1398
1402 switch (frequ) { 1399 switch (frequ) {
1403 case ICAL_MINUTELY_RECURRENCE: 1400 case ICAL_MINUTELY_RECURRENCE:
1404 if (!icaltime_is_null_time(r.until)) { 1401 if (!icaltime_is_null_time(r.until)) {
1405 recur->setMinutely(interv,readICalDateTime(r.until)); 1402 recur->setMinutely(interv,readICalDateTime(r.until));
1406 } else { 1403 } else {
1407 if (r.count == 0) 1404 if (r.count == 0)
1408 recur->setMinutely(interv,-1); 1405 recur->setMinutely(interv,-1);
1409 else 1406 else
1410 recur->setMinutely(interv,r.count); 1407 recur->setMinutely(interv,r.count);
1411 } 1408 }
1412 break; 1409 break;
1413 case ICAL_HOURLY_RECURRENCE: 1410 case ICAL_HOURLY_RECURRENCE:
1414 if (!icaltime_is_null_time(r.until)) { 1411 if (!icaltime_is_null_time(r.until)) {
1415 recur->setHourly(interv,readICalDateTime(r.until)); 1412 recur->setHourly(interv,readICalDateTime(r.until));
1416 } else { 1413 } else {
1417 if (r.count == 0) 1414 if (r.count == 0)
1418 recur->setHourly(interv,-1); 1415 recur->setHourly(interv,-1);
1419 else 1416 else
1420 recur->setHourly(interv,r.count); 1417 recur->setHourly(interv,r.count);
1421 } 1418 }
1422 break; 1419 break;
1423 case ICAL_DAILY_RECURRENCE: 1420 case ICAL_DAILY_RECURRENCE:
1424 if (!icaltime_is_null_time(r.until)) { 1421 if (!icaltime_is_null_time(r.until)) {
1425 recur->setDaily(interv,readICalDate(r.until)); 1422 recur->setDaily(interv,readICalDate(r.until));
1426 } else { 1423 } else {
1427 if (r.count == 0) 1424 if (r.count == 0)
1428 recur->setDaily(interv,-1); 1425 recur->setDaily(interv,-1);
1429 else 1426 else
1430 recur->setDaily(interv,r.count); 1427 recur->setDaily(interv,r.count);
1431 } 1428 }
1432 break; 1429 break;
1433 case ICAL_WEEKLY_RECURRENCE: 1430 case ICAL_WEEKLY_RECURRENCE:
1434 // kdDebug(5800) << "WEEKLY_RECURRENCE" << endl; 1431 // kdDebug(5800) << "WEEKLY_RECURRENCE" << endl;
1435 wkst = (r.week_start + 5)%7 + 1; 1432 wkst = (r.week_start + 5)%7 + 1;
1436 if (!icaltime_is_null_time(r.until)) { 1433 if (!icaltime_is_null_time(r.until)) {
1437 recur->setWeekly(interv,qba,readICalDate(r.until),wkst); 1434 recur->setWeekly(interv,qba,readICalDate(r.until),wkst);
1438 } else { 1435 } else {
1439 if (r.count == 0) 1436 if (r.count == 0)
1440 recur->setWeekly(interv,qba,-1,wkst); 1437 recur->setWeekly(interv,qba,-1,wkst);
1441 else 1438 else
1442 recur->setWeekly(interv,qba,r.count,wkst); 1439 recur->setWeekly(interv,qba,r.count,wkst);
1443 } 1440 }
1444 if ( r.by_day[0] == ICAL_RECURRENCE_ARRAY_MAX) { 1441 if ( r.by_day[0] == ICAL_RECURRENCE_ARRAY_MAX) {
1445 int wday = incidence->dtStart().date().dayOfWeek ()-1; 1442 int wday = incidence->dtStart().date().dayOfWeek ()-1;
1446 //qDebug("weekly error found "); 1443 //qDebug("weekly error found ");
1447 qba.setBit(wday); 1444 qba.setBit(wday);
1448 } else { 1445 } else {
1449 while((day = r.by_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) { 1446 while((day = r.by_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
1450 // kdDebug(5800) << " " << day << endl; 1447 // kdDebug(5800) << " " << day << endl;
1451 qba.setBit((day+5)%7); // convert from Sunday=1 to Monday=0 1448 qba.setBit((day+5)%7); // convert from Sunday=1 to Monday=0
1452 } 1449 }
1453 } 1450 }
1454 break; 1451 break;
1455 case ICAL_MONTHLY_RECURRENCE: 1452 case ICAL_MONTHLY_RECURRENCE:
1456 1453
1457 if (r.by_day[0] != ICAL_RECURRENCE_ARRAY_MAX) { 1454 if (r.by_day[0] != ICAL_RECURRENCE_ARRAY_MAX) {
1458 if (!icaltime_is_null_time(r.until)) { 1455 if (!icaltime_is_null_time(r.until)) {
1459 recur->setMonthly(Recurrence::rMonthlyPos,interv, 1456 recur->setMonthly(Recurrence::rMonthlyPos,interv,
1460 readICalDate(r.until)); 1457 readICalDate(r.until));
1461 } else { 1458 } else {
1462 if (r.count == 0) 1459 if (r.count == 0)
1463 recur->setMonthly(Recurrence::rMonthlyPos,interv,-1); 1460 recur->setMonthly(Recurrence::rMonthlyPos,interv,-1);
1464 else 1461 else
1465 recur->setMonthly(Recurrence::rMonthlyPos,interv,r.count); 1462 recur->setMonthly(Recurrence::rMonthlyPos,interv,r.count);
1466 } 1463 }
1467 bool useSetPos = false; 1464 bool useSetPos = false;
1468 short pos = 0; 1465 short pos = 0;
1469 while((day = r.by_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) { 1466 while((day = r.by_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
1470 // kdDebug(5800) << "----a " << index << ": " << day << endl; 1467 // kdDebug(5800) << "----a " << index << ": " << day << endl;
1471 pos = icalrecurrencetype_day_position(day); 1468 pos = icalrecurrencetype_day_position(day);
1472 if (pos) { 1469 if (pos) {
1473 day = icalrecurrencetype_day_day_of_week(day); 1470 day = icalrecurrencetype_day_day_of_week(day);
1474 QBitArray ba(7); // don't wipe qba 1471 QBitArray ba(7); // don't wipe qba
1475 ba.setBit((day+5)%7); // convert from Sunday=1 to Monday=0 1472 ba.setBit((day+5)%7); // convert from Sunday=1 to Monday=0
1476 recur->addMonthlyPos(pos,ba); 1473 recur->addMonthlyPos(pos,ba);
1477 } else { 1474 } else {
1478 qba.setBit((day+5)%7); // convert from Sunday=1 to Monday=0 1475 qba.setBit((day+5)%7); // convert from Sunday=1 to Monday=0
1479 useSetPos = true; 1476 useSetPos = true;
1480 } 1477 }
1481 } 1478 }
1482 if (useSetPos) { 1479 if (useSetPos) {
1483 if (r.by_set_pos[0] != ICAL_RECURRENCE_ARRAY_MAX) { 1480 if (r.by_set_pos[0] != ICAL_RECURRENCE_ARRAY_MAX) {
1484 recur->addMonthlyPos(r.by_set_pos[0],qba); 1481 recur->addMonthlyPos(r.by_set_pos[0],qba);
1485 } 1482 }
1486 } 1483 }
1487 } else if (r.by_month_day[0] != ICAL_RECURRENCE_ARRAY_MAX) { 1484 } else if (r.by_month_day[0] != ICAL_RECURRENCE_ARRAY_MAX) {
1488 if (!icaltime_is_null_time(r.until)) { 1485 if (!icaltime_is_null_time(r.until)) {
1489 recur->setMonthly(Recurrence::rMonthlyDay,interv, 1486 recur->setMonthly(Recurrence::rMonthlyDay,interv,
1490 readICalDate(r.until)); 1487 readICalDate(r.until));
1491 } else { 1488 } else {
1492 if (r.count == 0) 1489 if (r.count == 0)
1493 recur->setMonthly(Recurrence::rMonthlyDay,interv,-1); 1490 recur->setMonthly(Recurrence::rMonthlyDay,interv,-1);
1494 else 1491 else
1495 recur->setMonthly(Recurrence::rMonthlyDay,interv,r.count); 1492 recur->setMonthly(Recurrence::rMonthlyDay,interv,r.count);
1496 } 1493 }
1497 while((day = r.by_month_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) { 1494 while((day = r.by_month_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
1498 // kdDebug(5800) << "----b " << day << endl; 1495 // kdDebug(5800) << "----b " << day << endl;
1499 recur->addMonthlyDay(day); 1496 recur->addMonthlyDay(day);
1500 } 1497 }
1501 } 1498 }
1502 break; 1499 break;
1503 case ICAL_YEARLY_RECURRENCE: 1500 case ICAL_YEARLY_RECURRENCE:
1504 if (r.by_year_day[0] != ICAL_RECURRENCE_ARRAY_MAX) { 1501 if (r.by_year_day[0] != ICAL_RECURRENCE_ARRAY_MAX) {
1505 if (!icaltime_is_null_time(r.until)) { 1502 if (!icaltime_is_null_time(r.until)) {
1506 recur->setYearly(Recurrence::rYearlyDay,interv, 1503 recur->setYearly(Recurrence::rYearlyDay,interv,
1507 readICalDate(r.until)); 1504 readICalDate(r.until));
1508 } else { 1505 } else {
1509 if (r.count == 0) 1506 if (r.count == 0)
1510 recur->setYearly(Recurrence::rYearlyDay,interv,-1); 1507 recur->setYearly(Recurrence::rYearlyDay,interv,-1);
1511 else 1508 else
1512 recur->setYearly(Recurrence::rYearlyDay,interv,r.count); 1509 recur->setYearly(Recurrence::rYearlyDay,interv,r.count);
1513 } 1510 }
1514 while((day = r.by_year_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) { 1511 while((day = r.by_year_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
1515 recur->addYearlyNum(day); 1512 recur->addYearlyNum(day);
1516 } 1513 }
1517 } else if ( true /*r.by_month[0] != ICAL_RECURRENCE_ARRAY_MAX*/) { 1514 } else if ( true /*r.by_month[0] != ICAL_RECURRENCE_ARRAY_MAX*/) {
1518 if (r.by_day[0] != ICAL_RECURRENCE_ARRAY_MAX) { 1515 if (r.by_day[0] != ICAL_RECURRENCE_ARRAY_MAX) {
1519 if (!icaltime_is_null_time(r.until)) { 1516 if (!icaltime_is_null_time(r.until)) {
1520 recur->setYearly(Recurrence::rYearlyPos,interv, 1517 recur->setYearly(Recurrence::rYearlyPos,interv,
1521 readICalDate(r.until)); 1518 readICalDate(r.until));
1522 } else { 1519 } else {
1523 if (r.count == 0) 1520 if (r.count == 0)
1524 recur->setYearly(Recurrence::rYearlyPos,interv,-1); 1521 recur->setYearly(Recurrence::rYearlyPos,interv,-1);
1525 else 1522 else
1526 recur->setYearly(Recurrence::rYearlyPos,interv,r.count); 1523 recur->setYearly(Recurrence::rYearlyPos,interv,r.count);
1527 } 1524 }
1528 bool useSetPos = false; 1525 bool useSetPos = false;
1529 short pos = 0; 1526 short pos = 0;
1530 while((day = r.by_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) { 1527 while((day = r.by_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
1531 // kdDebug(5800) << "----a " << index << ": " << day << endl; 1528 // kdDebug(5800) << "----a " << index << ": " << day << endl;
1532 pos = icalrecurrencetype_day_position(day); 1529 pos = icalrecurrencetype_day_position(day);
1533 if (pos) { 1530 if (pos) {
1534 day = icalrecurrencetype_day_day_of_week(day); 1531 day = icalrecurrencetype_day_day_of_week(day);
1535 QBitArray ba(7); // don't wipe qba 1532 QBitArray ba(7); // don't wipe qba
1536 ba.setBit((day+5)%7); // convert from Sunday=1 to Monday=0 1533 ba.setBit((day+5)%7); // convert from Sunday=1 to Monday=0
1537 recur->addYearlyMonthPos(pos,ba); 1534 recur->addYearlyMonthPos(pos,ba);
1538 } else { 1535 } else {
1539 qba.setBit((day+5)%7); // convert from Sunday=1 to Monday=0 1536 qba.setBit((day+5)%7); // convert from Sunday=1 to Monday=0
1540 useSetPos = true; 1537 useSetPos = true;
1541 } 1538 }
1542 } 1539 }
1543 if (useSetPos) { 1540 if (useSetPos) {
1544 if (r.by_set_pos[0] != ICAL_RECURRENCE_ARRAY_MAX) { 1541 if (r.by_set_pos[0] != ICAL_RECURRENCE_ARRAY_MAX) {
1545 recur->addYearlyMonthPos(r.by_set_pos[0],qba); 1542 recur->addYearlyMonthPos(r.by_set_pos[0],qba);
1546 } 1543 }
1547 } 1544 }
1548 } else { 1545 } else {
1549 if (!icaltime_is_null_time(r.until)) { 1546 if (!icaltime_is_null_time(r.until)) {
1550 recur->setYearly(Recurrence::rYearlyMonth,interv, 1547 recur->setYearly(Recurrence::rYearlyMonth,interv,
1551 readICalDate(r.until)); 1548 readICalDate(r.until));
1552 } else { 1549 } else {
1553 if (r.count == 0) 1550 if (r.count == 0)
1554 recur->setYearly(Recurrence::rYearlyMonth,interv,-1); 1551 recur->setYearly(Recurrence::rYearlyMonth,interv,-1);
1555 else 1552 else
1556 recur->setYearly(Recurrence::rYearlyMonth,interv,r.count); 1553 recur->setYearly(Recurrence::rYearlyMonth,interv,r.count);
1557 } 1554 }
1558 } 1555 }
1559 if ( r.by_month[0] != ICAL_RECURRENCE_ARRAY_MAX ) { 1556 if ( r.by_month[0] != ICAL_RECURRENCE_ARRAY_MAX ) {
1560 index = 0; 1557 index = 0;
1561 while((day = r.by_month[index++]) != ICAL_RECURRENCE_ARRAY_MAX) { 1558 while((day = r.by_month[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
1562 recur->addYearlyNum(day); 1559 recur->addYearlyNum(day);
1563 } 1560 }
1564 } else { 1561 } else {
1565 recur->addYearlyNum(incidence->dtStart().date().month()); 1562 recur->addYearlyNum(incidence->dtStart().date().month());
1566 } 1563 }
1567 } 1564 }
1568 break; 1565 break;
1569 default: 1566 default:
1570 ; 1567 ;
1571 break; 1568 break;
1572 } 1569 }
1573} 1570}
1574 1571
1575void ICalFormatImpl::readAlarm(icalcomponent *alarm,Incidence *incidence) 1572void ICalFormatImpl::readAlarm(icalcomponent *alarm,Incidence *incidence)
1576{ 1573{
1577 //kdDebug(5800) << "Read alarm for " << incidence->summary() << endl; 1574 //kdDebug(5800) << "Read alarm for " << incidence->summary() << endl;
1578 1575
1579 Alarm* ialarm = incidence->newAlarm(); 1576 Alarm* ialarm = incidence->newAlarm();
1580 ialarm->setRepeatCount(0); 1577 ialarm->setRepeatCount(0);
1581 ialarm->setEnabled(true); 1578 ialarm->setEnabled(true);
1582 1579
1583 // Determine the alarm's action type 1580 // Determine the alarm's action type
1584 icalproperty *p = icalcomponent_get_first_property(alarm,ICAL_ACTION_PROPERTY); 1581 icalproperty *p = icalcomponent_get_first_property(alarm,ICAL_ACTION_PROPERTY);
1585 if ( !p ) { 1582 if ( !p ) {
1586 return; 1583 return;
1587 } 1584 }
1588 1585
1589 icalproperty_action action = icalproperty_get_action(p); 1586 icalproperty_action action = icalproperty_get_action(p);
1590 Alarm::Type type = Alarm::Display; 1587 Alarm::Type type = Alarm::Display;
1591 switch ( action ) { 1588 switch ( action ) {
1592 case ICAL_ACTION_DISPLAY: type = Alarm::Display; break; 1589 case ICAL_ACTION_DISPLAY: type = Alarm::Display; break;
1593 case ICAL_ACTION_AUDIO: type = Alarm::Audio; break; 1590 case ICAL_ACTION_AUDIO: type = Alarm::Audio; break;
1594 case ICAL_ACTION_PROCEDURE: type = Alarm::Procedure; break; 1591 case ICAL_ACTION_PROCEDURE: type = Alarm::Procedure; break;
1595 case ICAL_ACTION_EMAIL: type = Alarm::Email; break; 1592 case ICAL_ACTION_EMAIL: type = Alarm::Email; break;
1596 default: 1593 default:
1597 ; 1594 ;
1598 return; 1595 return;
1599 } 1596 }
1600 ialarm->setType(type); 1597 ialarm->setType(type);
1601 1598
1602 p = icalcomponent_get_first_property(alarm,ICAL_ANY_PROPERTY); 1599 p = icalcomponent_get_first_property(alarm,ICAL_ANY_PROPERTY);
1603 while (p) { 1600 while (p) {
1604 icalproperty_kind kind = icalproperty_isa(p); 1601 icalproperty_kind kind = icalproperty_isa(p);
1605 1602
1606 switch (kind) { 1603 switch (kind) {
1607 case ICAL_TRIGGER_PROPERTY: { 1604 case ICAL_TRIGGER_PROPERTY: {
1608 icaltriggertype trigger = icalproperty_get_trigger(p); 1605 icaltriggertype trigger = icalproperty_get_trigger(p);
1609 if (icaltime_is_null_time(trigger.time)) { 1606 if (icaltime_is_null_time(trigger.time)) {
1610 if (icaldurationtype_is_null_duration(trigger.duration)) { 1607 if (icaldurationtype_is_null_duration(trigger.duration)) {
1611 kdDebug(5800) << "ICalFormatImpl::readAlarm(): Trigger has no time and no duration." << endl; 1608 kdDebug(5800) << "ICalFormatImpl::readAlarm(): Trigger has no time and no duration." << endl;
1612 } else { 1609 } else {
1613 Duration duration = icaldurationtype_as_int( trigger.duration ); 1610 Duration duration = icaldurationtype_as_int( trigger.duration );
1614 icalparameter *param = icalproperty_get_first_parameter(p,ICAL_RELATED_PARAMETER); 1611 icalparameter *param = icalproperty_get_first_parameter(p,ICAL_RELATED_PARAMETER);
1615 if (param && icalparameter_get_related(param) == ICAL_RELATED_END) 1612 if (param && icalparameter_get_related(param) == ICAL_RELATED_END)
1616 ialarm->setEndOffset(duration); 1613 ialarm->setEndOffset(duration);
1617 else 1614 else
1618 ialarm->setStartOffset(duration); 1615 ialarm->setStartOffset(duration);
1619 } 1616 }
1620 } else { 1617 } else {
1621 ialarm->setTime(readICalDateTime(trigger.time)); 1618 ialarm->setTime(readICalDateTime(trigger.time));
1622 } 1619 }
1623 break; 1620 break;
1624 } 1621 }
1625 case ICAL_DURATION_PROPERTY: { 1622 case ICAL_DURATION_PROPERTY: {
1626 icaldurationtype duration = icalproperty_get_duration(p); 1623 icaldurationtype duration = icalproperty_get_duration(p);
1627 ialarm->setSnoozeTime(icaldurationtype_as_int(duration)/60); 1624 ialarm->setSnoozeTime(icaldurationtype_as_int(duration)/60);
1628 break; 1625 break;
1629 } 1626 }
1630 case ICAL_REPEAT_PROPERTY: 1627 case ICAL_REPEAT_PROPERTY:
1631 ialarm->setRepeatCount(icalproperty_get_repeat(p)); 1628 ialarm->setRepeatCount(icalproperty_get_repeat(p));
1632 break; 1629 break;
1633 1630
1634 // Only in DISPLAY and EMAIL and PROCEDURE alarms 1631 // Only in DISPLAY and EMAIL and PROCEDURE alarms
1635 case ICAL_DESCRIPTION_PROPERTY: { 1632 case ICAL_DESCRIPTION_PROPERTY: {
1636 QString description = QString::fromUtf8(icalproperty_get_description(p)); 1633 QString description = QString::fromUtf8(icalproperty_get_description(p));
1637 switch ( action ) { 1634 switch ( action ) {
1638 case ICAL_ACTION_DISPLAY: 1635 case ICAL_ACTION_DISPLAY:
1639 ialarm->setText( description ); 1636 ialarm->setText( description );
1640 break; 1637 break;
1641 case ICAL_ACTION_PROCEDURE: 1638 case ICAL_ACTION_PROCEDURE:
1642 ialarm->setProgramArguments( description ); 1639 ialarm->setProgramArguments( description );
1643 break; 1640 break;
1644 case ICAL_ACTION_EMAIL: 1641 case ICAL_ACTION_EMAIL:
1645 ialarm->setMailText( description ); 1642 ialarm->setMailText( description );
1646 break; 1643 break;
1647 default: 1644 default:
1648 break; 1645 break;
1649 } 1646 }
1650 break; 1647 break;
1651 } 1648 }
1652 // Only in EMAIL alarm 1649 // Only in EMAIL alarm
1653 case ICAL_SUMMARY_PROPERTY: 1650 case ICAL_SUMMARY_PROPERTY:
1654 ialarm->setMailSubject(QString::fromUtf8(icalproperty_get_summary(p))); 1651 ialarm->setMailSubject(QString::fromUtf8(icalproperty_get_summary(p)));
1655 break; 1652 break;
1656 1653
1657 // Only in EMAIL alarm 1654 // Only in EMAIL alarm
1658 case ICAL_ATTENDEE_PROPERTY: { 1655 case ICAL_ATTENDEE_PROPERTY: {
1659 QString email = QString::fromUtf8(icalproperty_get_attendee(p)); 1656 QString email = QString::fromUtf8(icalproperty_get_attendee(p));
1660 QString name; 1657 QString name;
1661 icalparameter *param = icalproperty_get_first_parameter(p,ICAL_CN_PARAMETER); 1658 icalparameter *param = icalproperty_get_first_parameter(p,ICAL_CN_PARAMETER);
1662 if (param) { 1659 if (param) {
1663 name = QString::fromUtf8(icalparameter_get_cn(param)); 1660 name = QString::fromUtf8(icalparameter_get_cn(param));
1664 } 1661 }
1665 ialarm->addMailAddress(Person(name, email)); 1662 ialarm->addMailAddress(Person(name, email));
1666 break; 1663 break;
1667 } 1664 }
1668 // Only in AUDIO and EMAIL and PROCEDURE alarms 1665 // Only in AUDIO and EMAIL and PROCEDURE alarms
1669 case ICAL_ATTACH_PROPERTY: { 1666 case ICAL_ATTACH_PROPERTY: {
1670 icalattachtype *attach = icalproperty_get_attach(p); 1667 icalattach *attach = icalproperty_get_attach(p);
1671 QString url = QFile::decodeName(icalattachtype_get_url(attach)); 1668 QString url = QFile::decodeName(icalattach_get_url(attach));
1672 switch ( action ) { 1669 switch ( action ) {
1673 case ICAL_ACTION_AUDIO: 1670 case ICAL_ACTION_AUDIO:
1674 ialarm->setAudioFile( url ); 1671 ialarm->setAudioFile( url );
1675 break; 1672 break;
1676 case ICAL_ACTION_PROCEDURE: 1673 case ICAL_ACTION_PROCEDURE:
1677 ialarm->setProgramFile( url ); 1674 ialarm->setProgramFile( url );
1678 break; 1675 break;
1679 case ICAL_ACTION_EMAIL: 1676 case ICAL_ACTION_EMAIL:
1680 ialarm->addMailAttachment( url ); 1677 ialarm->addMailAttachment( url );
1681 break; 1678 break;
1682 default: 1679 default:
1683 break; 1680 break;
1684 } 1681 }
1685 break; 1682 break;
1686 } 1683 }
1687 default: 1684 default:
1688 break; 1685 break;
1689 } 1686 }
1690 1687
1691 p = icalcomponent_get_next_property(alarm,ICAL_ANY_PROPERTY); 1688 p = icalcomponent_get_next_property(alarm,ICAL_ANY_PROPERTY);
1692 } 1689 }
1693 1690
1694 // custom properties 1691 // custom properties
1695 readCustomProperties(alarm, ialarm); 1692 readCustomProperties(alarm, ialarm);
1696 1693
1697 // TODO: check for consistency of alarm properties 1694 // TODO: check for consistency of alarm properties
1698} 1695}
1699 1696
1700icaltimetype ICalFormatImpl::writeICalDate(const QDate &date) 1697icaltimetype ICalFormatImpl::writeICalDate(const QDate &date)
1701{ 1698{
1702 icaltimetype t; 1699 icaltimetype t;
1703 1700
1704 t.year = date.year(); 1701 t.year = date.year();
1705 t.month = date.month(); 1702 t.month = date.month();
1706 t.day = date.day(); 1703 t.day = date.day();
1707 1704
1708 t.hour = 0; 1705 t.hour = 0;
1709 t.minute = 0; 1706 t.minute = 0;
1710 t.second = 0; 1707 t.second = 0;
1711 1708
1712 t.is_date = 1; 1709 t.is_date = 1;
1713 1710
1714 t.is_utc = 0; 1711 t.is_utc = 0;
1715 1712
1716 t.zone = 0; 1713 t.zone = 0;
1717 1714
1718 return t; 1715 return t;
1719} 1716}
1720 1717
1721icaltimetype ICalFormatImpl::writeICalDateTime(const QDateTime &dt ) 1718icaltimetype ICalFormatImpl::writeICalDateTime(const QDateTime &dt )
1722{ 1719{
1723 icaltimetype t; 1720 icaltimetype t;
1724 t.is_date = 0; 1721 t.is_date = 0;
1725 t.zone = 0; 1722 t.zone = 0;
1726 QDateTime datetime; 1723 QDateTime datetime;
1727 if ( mParent->utc() ) { 1724 if ( mParent->utc() ) {
1728 int offset = KGlobal::locale()->localTimeOffset( dt ); 1725 int offset = KGlobal::locale()->localTimeOffset( dt );
1729 datetime = dt.addSecs ( -offset*60); 1726 datetime = dt.addSecs ( -offset*60);
1730 t.is_utc = 1; 1727 t.is_utc = 1;
1731 } 1728 }
1732 else { 1729 else {
1733 datetime = dt; 1730 datetime = dt;
1734 t.is_utc = 0; 1731 t.is_utc = 0;
1735 1732
1736 } 1733 }
1737 t.year = datetime.date().year(); 1734 t.year = datetime.date().year();
1738 t.month = datetime.date().month(); 1735 t.month = datetime.date().month();
1739 t.day = datetime.date().day(); 1736 t.day = datetime.date().day();
1740 1737
1741 t.hour = datetime.time().hour(); 1738 t.hour = datetime.time().hour();
1742 t.minute = datetime.time().minute(); 1739 t.minute = datetime.time().minute();
1743 t.second = datetime.time().second(); 1740 t.second = datetime.time().second();
1744 1741
1745 //qDebug("*** time %s localtime %s ",dt .toString().latin1() ,datetime .toString().latin1() ); 1742 //qDebug("*** time %s localtime %s ",dt .toString().latin1() ,datetime .toString().latin1() );
1746 1743
1747// if ( mParent->utc() ) { 1744// if ( mParent->utc() ) {
1748// datetime = KGlobal::locale()->localTime( dt ); 1745// datetime = KGlobal::locale()->localTime( dt );
1749// qDebug("*** time %s localtime %s ",dt .toString().latin1() ,datetime .toString().latin1() ); 1746// qDebug("*** time %s localtime %s ",dt .toString().latin1() ,datetime .toString().latin1() );
1750// if (mParent->timeZoneId().isEmpty()) 1747// if (mParent->timeZoneId().isEmpty())
1751// t = icaltime_as_utc(t, 0); 1748// t = icaltime_as_utc(t, 0);
1752// else 1749// else
1753// t = icaltime_as_utc(t,mParent->timeZoneId().local8Bit()); 1750// t = icaltime_as_utc(t,mParent->timeZoneId().local8Bit());
1754// } 1751// }
1755 1752
1756 return t; 1753 return t;
1757} 1754}
1758 1755
1759QDateTime ICalFormatImpl::readICalDateTime(icaltimetype t) 1756QDateTime ICalFormatImpl::readICalDateTime(icaltimetype t)
1760{ 1757{
1761 QDateTime dt (QDate(t.year,t.month,t.day), 1758 QDateTime dt (QDate(t.year,t.month,t.day),
1762 QTime(t.hour,t.minute,t.second) ); 1759 QTime(t.hour,t.minute,t.second) );
1763 1760
1764 if (t.is_utc) { 1761 if (t.is_utc) {
1765 int offset = KGlobal::locale()->localTimeOffset( dt ); 1762 int offset = KGlobal::locale()->localTimeOffset( dt );
1766 dt = dt.addSecs ( offset*60); 1763 dt = dt.addSecs ( offset*60);
1767 } 1764 }
1768 1765
1769 return dt; 1766 return dt;
1770} 1767}
1771 1768
1772QDate ICalFormatImpl::readICalDate(icaltimetype t) 1769QDate ICalFormatImpl::readICalDate(icaltimetype t)
1773{ 1770{
1774 return QDate(t.year,t.month,t.day); 1771 return QDate(t.year,t.month,t.day);
1775} 1772}
1776 1773
1777icaldurationtype ICalFormatImpl::writeICalDuration(int seconds) 1774icaldurationtype ICalFormatImpl::writeICalDuration(int seconds)
1778{ 1775{
1779 icaldurationtype d; 1776 icaldurationtype d;
1780 1777
1781 d.weeks = seconds % gSecondsPerWeek; 1778 d.weeks = seconds % gSecondsPerWeek;
1782 seconds -= d.weeks * gSecondsPerWeek; 1779 seconds -= d.weeks * gSecondsPerWeek;
1783 d.days = seconds % gSecondsPerDay; 1780 d.days = seconds % gSecondsPerDay;
1784 seconds -= d.days * gSecondsPerDay; 1781 seconds -= d.days * gSecondsPerDay;
1785 d.hours = seconds % gSecondsPerHour; 1782 d.hours = seconds % gSecondsPerHour;
1786 seconds -= d.hours * gSecondsPerHour; 1783 seconds -= d.hours * gSecondsPerHour;
1787 d.minutes = seconds % gSecondsPerMinute; 1784 d.minutes = seconds % gSecondsPerMinute;
1788 seconds -= d.minutes * gSecondsPerMinute; 1785 seconds -= d.minutes * gSecondsPerMinute;
1789 d.seconds = seconds; 1786 d.seconds = seconds;
1790 d.is_neg = 0; 1787 d.is_neg = 0;
1791 1788
1792 return d; 1789 return d;
1793} 1790}
1794 1791
1795int ICalFormatImpl::readICalDuration(icaldurationtype d) 1792int ICalFormatImpl::readICalDuration(icaldurationtype d)
1796{ 1793{
1797 int result = 0; 1794 int result = 0;
1798 1795
1799 result += d.weeks * gSecondsPerWeek; 1796 result += d.weeks * gSecondsPerWeek;
1800 result += d.days * gSecondsPerDay; 1797 result += d.days * gSecondsPerDay;
1801 result += d.hours * gSecondsPerHour; 1798 result += d.hours * gSecondsPerHour;
1802 result += d.minutes * gSecondsPerMinute; 1799 result += d.minutes * gSecondsPerMinute;
1803 result += d.seconds; 1800 result += d.seconds;
1804 1801
1805 if (d.is_neg) result *= -1; 1802 if (d.is_neg) result *= -1;
1806 1803
1807 return result; 1804 return result;
1808} 1805}
1809 1806
1810icalcomponent *ICalFormatImpl::createCalendarComponent(Calendar *cal) 1807icalcomponent *ICalFormatImpl::createCalendarComponent(Calendar *cal)
1811{ 1808{
1812 icalcomponent *calendar; 1809 icalcomponent *calendar;
1813 1810
1814 // Root component 1811 // Root component
1815 calendar = icalcomponent_new(ICAL_VCALENDAR_COMPONENT); 1812 calendar = icalcomponent_new(ICAL_VCALENDAR_COMPONENT);
1816 1813
1817 icalproperty *p; 1814 icalproperty *p;
1818 1815
1819 // Product Identifier 1816 // Product Identifier
1820 p = icalproperty_new_prodid(CalFormat::productId().utf8()); 1817 p = icalproperty_new_prodid(CalFormat::productId().utf8());
1821 icalcomponent_add_property(calendar,p); 1818 icalcomponent_add_property(calendar,p);
1822 1819
1823 // TODO: Add time zone 1820 // TODO: Add time zone
1824 1821
1825 // iCalendar version (2.0) 1822 // iCalendar version (2.0)
1826 p = icalproperty_new_version(const_cast<char *>(_ICAL_VERSION)); 1823 p = icalproperty_new_version(const_cast<char *>(_ICAL_VERSION));
1827 icalcomponent_add_property(calendar,p); 1824 icalcomponent_add_property(calendar,p);
1828 1825
1829 // Custom properties 1826 // Custom properties
1830 if( cal != 0 ) 1827 if( cal != 0 )
1831 writeCustomProperties(calendar, cal); 1828 writeCustomProperties(calendar, cal);
1832 1829
1833 return calendar; 1830 return calendar;
1834} 1831}
1835 1832
1836 1833
1837 1834
1838// take a raw vcalendar (i.e. from a file on disk, clipboard, etc. etc. 1835// take a raw vcalendar (i.e. from a file on disk, clipboard, etc. etc.
1839// and break it down from its tree-like format into the dictionary format 1836// and break it down from its tree-like format into the dictionary format
1840// that is used internally in the ICalFormatImpl. 1837// that is used internally in the ICalFormatImpl.
1841bool ICalFormatImpl::populate( Calendar *cal, icalcomponent *calendar) 1838bool ICalFormatImpl::populate( Calendar *cal, icalcomponent *calendar)
1842{ 1839{
1843 // this function will populate the caldict dictionary and other event 1840 // this function will populate the caldict dictionary and other event
1844 // lists. It turns vevents into Events and then inserts them. 1841 // lists. It turns vevents into Events and then inserts them.
1845 1842
1846 if (!calendar) return false; 1843 if (!calendar) return false;
1847 1844
1848// TODO: check for METHOD 1845// TODO: check for METHOD
1849#if 0 1846#if 0
1850 if ((curVO = isAPropertyOf(vcal, ICMethodProp)) != 0) { 1847 if ((curVO = isAPropertyOf(vcal, ICMethodProp)) != 0) {
1851 char *methodType = 0; 1848 char *methodType = 0;
1852 methodType = fakeCString(vObjectUStringZValue(curVO)); 1849 methodType = fakeCString(vObjectUStringZValue(curVO));
1853 if (mEnableDialogs) 1850 if (mEnableDialogs)
1854 KMessageBox::information(mTopWidget, 1851 KMessageBox::information(mTopWidget,
1855 i18n("This calendar is an iTIP transaction of type \"%1\".") 1852 i18n("This calendar is an iTIP transaction of type \"%1\".")
1856 .arg(methodType), 1853 .arg(methodType),
1857 i18n("%1: iTIP Transaction").arg(CalFormat::application())); 1854 i18n("%1: iTIP Transaction").arg(CalFormat::application()));
1858 delete methodType; 1855 delete methodType;
1859 } 1856 }
1860#endif 1857#endif
1861 1858
1862 icalproperty *p; 1859 icalproperty *p;
1863 1860
1864 p = icalcomponent_get_first_property(calendar,ICAL_PRODID_PROPERTY); 1861 p = icalcomponent_get_first_property(calendar,ICAL_PRODID_PROPERTY);
1865 if (!p) { 1862 if (!p) {
1866// TODO: does no PRODID really matter? 1863// TODO: does no PRODID really matter?
1867// mParent->setException(new ErrorFormat(ErrorFormat::CalVersionUnknown)); 1864// mParent->setException(new ErrorFormat(ErrorFormat::CalVersionUnknown));
1868// return false; 1865// return false;
1869 mLoadedProductId = ""; 1866 mLoadedProductId = "";
1870 mCalendarVersion = 0; 1867 mCalendarVersion = 0;
1871 } else { 1868 } else {
1872 mLoadedProductId = QString::fromUtf8(icalproperty_get_prodid(p)); 1869 mLoadedProductId = QString::fromUtf8(icalproperty_get_prodid(p));
1873 mCalendarVersion = CalFormat::calendarVersion(mLoadedProductId); 1870 mCalendarVersion = CalFormat::calendarVersion(mLoadedProductId);
1874 1871
1875 delete mCompat; 1872 delete mCompat;
1876 mCompat = CompatFactory::createCompat( mLoadedProductId ); 1873 mCompat = CompatFactory::createCompat( mLoadedProductId );
1877 } 1874 }
1878 1875
1879// TODO: check for unknown PRODID 1876// TODO: check for unknown PRODID
1880#if 0 1877#if 0
1881 if (!mCalendarVersion 1878 if (!mCalendarVersion
1882 && CalFormat::productId() != mLoadedProductId) { 1879 && CalFormat::productId() != mLoadedProductId) {
1883 // warn the user that we might have trouble reading non-known calendar. 1880 // warn the user that we might have trouble reading non-known calendar.
1884 if (mEnableDialogs) 1881 if (mEnableDialogs)
1885 KMessageBox::information(mTopWidget, 1882 KMessageBox::information(mTopWidget,
1886 i18n("This vCalendar file was not created by KOrganizer " 1883 i18n("This vCalendar file was not created by KOrganizer "
1887 "or any other product we support. Loading anyway..."), 1884 "or any other product we support. Loading anyway..."),
1888 i18n("%1: Unknown vCalendar Vendor").arg(CalFormat::application())); 1885 i18n("%1: Unknown vCalendar Vendor").arg(CalFormat::application()));
1889 } 1886 }
1890#endif 1887#endif
1891 1888
1892 p = icalcomponent_get_first_property(calendar,ICAL_VERSION_PROPERTY); 1889 p = icalcomponent_get_first_property(calendar,ICAL_VERSION_PROPERTY);
1893 if (!p) { 1890 if (!p) {
1894 mParent->setException(new ErrorFormat(ErrorFormat::CalVersionUnknown)); 1891 mParent->setException(new ErrorFormat(ErrorFormat::CalVersionUnknown));
1895 return false; 1892 return false;
1896 } else { 1893 } else {
1897 const char *version = icalproperty_get_version(p); 1894 const char *version = icalproperty_get_version(p);
1898 1895
1899 if (strcmp(version,"1.0") == 0) { 1896 if (strcmp(version,"1.0") == 0) {
1900 mParent->setException(new ErrorFormat(ErrorFormat::CalVersion1, 1897 mParent->setException(new ErrorFormat(ErrorFormat::CalVersion1,
1901 i18n("Expected iCalendar format"))); 1898 i18n("Expected iCalendar format")));
1902 return false; 1899 return false;
1903 } else if (strcmp(version,"2.0") != 0) { 1900 } else if (strcmp(version,"2.0") != 0) {
1904 mParent->setException(new ErrorFormat(ErrorFormat::CalVersionUnknown)); 1901 mParent->setException(new ErrorFormat(ErrorFormat::CalVersionUnknown));
1905 return false; 1902 return false;
1906 } 1903 }
1907 } 1904 }
1908 1905
1909 1906
1910// TODO: check for calendar format version 1907// TODO: check for calendar format version
1911#if 0 1908#if 0
1912 // warn the user we might have trouble reading this unknown version. 1909 // warn the user we might have trouble reading this unknown version.
1913 if ((curVO = isAPropertyOf(vcal, VCVersionProp)) != 0) { 1910 if ((curVO = isAPropertyOf(vcal, VCVersionProp)) != 0) {
1914 char *s = fakeCString(vObjectUStringZValue(curVO)); 1911 char *s = fakeCString(vObjectUStringZValue(curVO));
1915 if (strcmp(_VCAL_VERSION, s) != 0) 1912 if (strcmp(_VCAL_VERSION, s) != 0)
1916 if (mEnableDialogs) 1913 if (mEnableDialogs)
1917 KMessageBox::sorry(mTopWidget, 1914 KMessageBox::sorry(mTopWidget,
1918 i18n("This vCalendar file has version %1.\n" 1915 i18n("This vCalendar file has version %1.\n"
1919 "We only support %2.") 1916 "We only support %2.")
1920 .arg(s).arg(_VCAL_VERSION), 1917 .arg(s).arg(_VCAL_VERSION),
1921 i18n("%1: Unknown vCalendar Version").arg(CalFormat::application())); 1918 i18n("%1: Unknown vCalendar Version").arg(CalFormat::application()));
1922 deleteStr(s); 1919 deleteStr(s);
1923 } 1920 }
1924#endif 1921#endif
1925 1922
1926 // custom properties 1923 // custom properties
1927 readCustomProperties(calendar, cal); 1924 readCustomProperties(calendar, cal);
1928 1925
1929// TODO: set time zone 1926// TODO: set time zone
1930#if 0 1927#if 0
1931 // set the time zone 1928 // set the time zone
1932 if ((curVO = isAPropertyOf(vcal, VCTimeZoneProp)) != 0) { 1929 if ((curVO = isAPropertyOf(vcal, VCTimeZoneProp)) != 0) {
1933 char *s = fakeCString(vObjectUStringZValue(curVO)); 1930 char *s = fakeCString(vObjectUStringZValue(curVO));
1934 cal->setTimeZone(s); 1931 cal->setTimeZone(s);
1935 deleteStr(s); 1932 deleteStr(s);
1936 } 1933 }
1937#endif 1934#endif
1938 1935
1939 // Store all events with a relatedTo property in a list for post-processing 1936 // Store all events with a relatedTo property in a list for post-processing
1940 mEventsRelate.clear(); 1937 mEventsRelate.clear();
1941 mTodosRelate.clear(); 1938 mTodosRelate.clear();
1942 // TODO: make sure that only actually added ecvens go to this lists. 1939 // TODO: make sure that only actually added ecvens go to this lists.
1943 1940
1944 icalcomponent *c; 1941 icalcomponent *c;
1945 1942
1946 // Iterate through all todos 1943 // Iterate through all todos
1947 c = icalcomponent_get_first_component(calendar,ICAL_VTODO_COMPONENT); 1944 c = icalcomponent_get_first_component(calendar,ICAL_VTODO_COMPONENT);
1948 while (c) { 1945 while (c) {
1949// kdDebug(5800) << "----Todo found" << endl; 1946// kdDebug(5800) << "----Todo found" << endl;
1950 Todo *todo = readTodo(c); 1947 Todo *todo = readTodo(c);
1951 if (!cal->todo(todo->uid())) cal->addTodo(todo); 1948 if (!cal->todo(todo->uid())) cal->addTodo(todo);
1952 c = icalcomponent_get_next_component(calendar,ICAL_VTODO_COMPONENT); 1949 c = icalcomponent_get_next_component(calendar,ICAL_VTODO_COMPONENT);
1953 } 1950 }
1954 1951
1955 // Iterate through all events 1952 // Iterate through all events
1956 c = icalcomponent_get_first_component(calendar,ICAL_VEVENT_COMPONENT); 1953 c = icalcomponent_get_first_component(calendar,ICAL_VEVENT_COMPONENT);
1957 while (c) { 1954 while (c) {
1958// kdDebug(5800) << "----Event found" << endl; 1955// kdDebug(5800) << "----Event found" << endl;
1959 Event *event = readEvent(c); 1956 Event *event = readEvent(c);
1960 if (!cal->event(event->uid())) cal->addEvent(event); 1957 if (!cal->event(event->uid())) cal->addEvent(event);
1961 c = icalcomponent_get_next_component(calendar,ICAL_VEVENT_COMPONENT); 1958 c = icalcomponent_get_next_component(calendar,ICAL_VEVENT_COMPONENT);
1962 } 1959 }
1963 1960
1964 // Iterate through all journals 1961 // Iterate through all journals
1965 c = icalcomponent_get_first_component(calendar,ICAL_VJOURNAL_COMPONENT); 1962 c = icalcomponent_get_first_component(calendar,ICAL_VJOURNAL_COMPONENT);
1966 while (c) { 1963 while (c) {
1967// kdDebug(5800) << "----Journal found" << endl; 1964// kdDebug(5800) << "----Journal found" << endl;
1968 Journal *journal = readJournal(c); 1965 Journal *journal = readJournal(c);
1969 if (!cal->journal(journal->uid())) cal->addJournal(journal); 1966 if (!cal->journal(journal->uid())) cal->addJournal(journal);
1970 c = icalcomponent_get_next_component(calendar,ICAL_VJOURNAL_COMPONENT); 1967 c = icalcomponent_get_next_component(calendar,ICAL_VJOURNAL_COMPONENT);
1971 } 1968 }
1972 1969
1973#if 0 1970#if 0
1974 initPropIterator(&i, vcal); 1971 initPropIterator(&i, vcal);
1975 1972
1976 // go through all the vobjects in the vcal 1973 // go through all the vobjects in the vcal
1977 while (moreIteration(&i)) { 1974 while (moreIteration(&i)) {
1978 curVO = nextVObject(&i); 1975 curVO = nextVObject(&i);
1979 1976
1980 /************************************************************************/ 1977 /************************************************************************/
1981 1978
1982 // now, check to see that the object is an event or todo. 1979 // now, check to see that the object is an event or todo.
1983 if (strcmp(vObjectName(curVO), VCEventProp) == 0) { 1980 if (strcmp(vObjectName(curVO), VCEventProp) == 0) {
1984 1981
1985 if ((curVOProp = isAPropertyOf(curVO, KPilotStatusProp)) != 0) { 1982 if ((curVOProp = isAPropertyOf(curVO, KPilotStatusProp)) != 0) {
1986 char *s; 1983 char *s;
1987 s = fakeCString(vObjectUStringZValue(curVOProp)); 1984 s = fakeCString(vObjectUStringZValue(curVOProp));
1988 // check to see if event was deleted by the kpilot conduit 1985 // check to see if event was deleted by the kpilot conduit
1989 if (atoi(s) == Event::SYNCDEL) { 1986 if (atoi(s) == Event::SYNCDEL) {
1990 deleteStr(s); 1987 deleteStr(s);
1991 goto SKIP; 1988 goto SKIP;
1992 } 1989 }
1993 deleteStr(s); 1990 deleteStr(s);
1994 } 1991 }
1995 1992
1996 // this code checks to see if we are trying to read in an event 1993 // this code checks to see if we are trying to read in an event
1997 // that we already find to be in the calendar. If we find this 1994 // that we already find to be in the calendar. If we find this
1998 // to be the case, we skip the event. 1995 // to be the case, we skip the event.
1999 if ((curVOProp = isAPropertyOf(curVO, VCUniqueStringProp)) != 0) { 1996 if ((curVOProp = isAPropertyOf(curVO, VCUniqueStringProp)) != 0) {
2000 char *s = fakeCString(vObjectUStringZValue(curVOProp)); 1997 char *s = fakeCString(vObjectUStringZValue(curVOProp));
2001 QString tmpStr(s); 1998 QString tmpStr(s);
2002 deleteStr(s); 1999 deleteStr(s);
2003 2000
2004 if (cal->event(tmpStr)) { 2001 if (cal->event(tmpStr)) {
2005 goto SKIP; 2002 goto SKIP;
2006 } 2003 }
2007 if (cal->todo(tmpStr)) { 2004 if (cal->todo(tmpStr)) {
2008 goto SKIP; 2005 goto SKIP;
2009 } 2006 }
2010 } 2007 }
2011 2008
2012 if ((!(curVOProp = isAPropertyOf(curVO, VCDTstartProp))) && 2009 if ((!(curVOProp = isAPropertyOf(curVO, VCDTstartProp))) &&
2013 (!(curVOProp = isAPropertyOf(curVO, VCDTendProp)))) { 2010 (!(curVOProp = isAPropertyOf(curVO, VCDTendProp)))) {
2014 kdDebug(5800) << "found a VEvent with no DTSTART and no DTEND! Skipping..." << endl; 2011 kdDebug(5800) << "found a VEvent with no DTSTART and no DTEND! Skipping..." << endl;
2015 goto SKIP; 2012 goto SKIP;
2016 } 2013 }
2017 2014
2018 anEvent = VEventToEvent(curVO); 2015 anEvent = VEventToEvent(curVO);
2019 // we now use addEvent instead of insertEvent so that the 2016 // we now use addEvent instead of insertEvent so that the
2020 // signal/slot get connected. 2017 // signal/slot get connected.
2021 if (anEvent) 2018 if (anEvent)
2022 cal->addEvent(anEvent); 2019 cal->addEvent(anEvent);
2023 else { 2020 else {
2024 // some sort of error must have occurred while in translation. 2021 // some sort of error must have occurred while in translation.
2025 goto SKIP; 2022 goto SKIP;
2026 } 2023 }
2027 } else if (strcmp(vObjectName(curVO), VCTodoProp) == 0) { 2024 } else if (strcmp(vObjectName(curVO), VCTodoProp) == 0) {
2028 anEvent = VTodoToEvent(curVO); 2025 anEvent = VTodoToEvent(curVO);
2029 cal->addTodo(anEvent); 2026 cal->addTodo(anEvent);
2030 } else if ((strcmp(vObjectName(curVO), VCVersionProp) == 0) || 2027 } else if ((strcmp(vObjectName(curVO), VCVersionProp) == 0) ||
2031 (strcmp(vObjectName(curVO), VCProdIdProp) == 0) || 2028 (strcmp(vObjectName(curVO), VCProdIdProp) == 0) ||
2032 (strcmp(vObjectName(curVO), VCTimeZoneProp) == 0)) { 2029 (strcmp(vObjectName(curVO), VCTimeZoneProp) == 0)) {
2033 // do nothing, we know these properties and we want to skip them. 2030 // do nothing, we know these properties and we want to skip them.
2034 // we have either already processed them or are ignoring them. 2031 // we have either already processed them or are ignoring them.
2035 ; 2032 ;
2036 } else { 2033 } else {
2037 ; 2034 ;
2038 } 2035 }
2039 SKIP: 2036 SKIP:
2040 ; 2037 ;
2041 } // while 2038 } // while
2042#endif 2039#endif
2043 2040
2044 // Post-Process list of events with relations, put Event objects in relation 2041 // Post-Process list of events with relations, put Event objects in relation
2045 Event *ev; 2042 Event *ev;
2046 for ( ev=mEventsRelate.first(); ev != 0; ev=mEventsRelate.next() ) { 2043 for ( ev=mEventsRelate.first(); ev != 0; ev=mEventsRelate.next() ) {
2047 ev->setRelatedTo(cal->event(ev->relatedToUid())); 2044 ev->setRelatedTo(cal->event(ev->relatedToUid()));
2048 } 2045 }
2049 Todo *todo; 2046 Todo *todo;
2050 for ( todo=mTodosRelate.first(); todo != 0; todo=mTodosRelate.next() ) { 2047 for ( todo=mTodosRelate.first(); todo != 0; todo=mTodosRelate.next() ) {
2051 todo->setRelatedTo(cal->todo(todo->relatedToUid())); 2048 todo->setRelatedTo(cal->todo(todo->relatedToUid()));
2052 } 2049 }
2053 2050
2054 return true; 2051 return true;
2055} 2052}
2056 2053
2057QString ICalFormatImpl::extractErrorProperty(icalcomponent *c) 2054QString ICalFormatImpl::extractErrorProperty(icalcomponent *c)
2058{ 2055{
2059// kdDebug(5800) << "ICalFormatImpl:extractErrorProperty: " 2056// kdDebug(5800) << "ICalFormatImpl:extractErrorProperty: "
2060// << icalcomponent_as_ical_string(c) << endl; 2057// << icalcomponent_as_ical_string(c) << endl;
2061 2058
2062 QString errorMessage; 2059 QString errorMessage;
2063 2060
2064 icalproperty *error; 2061 icalproperty *error;
2065 error = icalcomponent_get_first_property(c,ICAL_XLICERROR_PROPERTY); 2062 error = icalcomponent_get_first_property(c,ICAL_XLICERROR_PROPERTY);
2066 while(error) { 2063 while(error) {
2067 errorMessage += icalproperty_get_xlicerror(error); 2064 errorMessage += icalproperty_get_xlicerror(error);
2068 errorMessage += "\n"; 2065 errorMessage += "\n";
2069 error = icalcomponent_get_next_property(c,ICAL_XLICERROR_PROPERTY); 2066 error = icalcomponent_get_next_property(c,ICAL_XLICERROR_PROPERTY);
2070 } 2067 }
2071 2068
2072// kdDebug(5800) << "ICalFormatImpl:extractErrorProperty: " << errorMessage << endl; 2069// kdDebug(5800) << "ICalFormatImpl:extractErrorProperty: " << errorMessage << endl;
2073 2070
2074 return errorMessage; 2071 return errorMessage;
2075} 2072}
2076 2073
2077void ICalFormatImpl::dumpIcalRecurrence(icalrecurrencetype r) 2074void ICalFormatImpl::dumpIcalRecurrence(icalrecurrencetype r)
2078{ 2075{
2079 int i; 2076 int i;
2080 2077
2081 2078
2082 if (r.by_day[0] != ICAL_RECURRENCE_ARRAY_MAX) { 2079 if (r.by_day[0] != ICAL_RECURRENCE_ARRAY_MAX) {
2083 int index = 0; 2080 int index = 0;
2084 QString out = " By Day: "; 2081 QString out = " By Day: ";
2085 while((i = r.by_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) { 2082 while((i = r.by_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
2086 out.append(QString::number(i) + " "); 2083 out.append(QString::number(i) + " ");
2087 } 2084 }
2088 } 2085 }
2089 if (r.by_month_day[0] != ICAL_RECURRENCE_ARRAY_MAX) { 2086 if (r.by_month_day[0] != ICAL_RECURRENCE_ARRAY_MAX) {
2090 int index = 0; 2087 int index = 0;
2091 QString out = " By Month Day: "; 2088 QString out = " By Month Day: ";
2092 while((i = r.by_month_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) { 2089 while((i = r.by_month_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
2093 out.append(QString::number(i) + " "); 2090 out.append(QString::number(i) + " ");
2094 } 2091 }
2095 } 2092 }
2096 if (r.by_year_day[0] != ICAL_RECURRENCE_ARRAY_MAX) { 2093 if (r.by_year_day[0] != ICAL_RECURRENCE_ARRAY_MAX) {
2097 int index = 0; 2094 int index = 0;
2098 QString out = " By Year Day: "; 2095 QString out = " By Year Day: ";
2099 while((i = r.by_year_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) { 2096 while((i = r.by_year_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
2100 out.append(QString::number(i) + " "); 2097 out.append(QString::number(i) + " ");
2101 } 2098 }
2102 } 2099 }
2103 if (r.by_month[0] != ICAL_RECURRENCE_ARRAY_MAX) { 2100 if (r.by_month[0] != ICAL_RECURRENCE_ARRAY_MAX) {
2104 int index = 0; 2101 int index = 0;
2105 QString out = " By Month: "; 2102 QString out = " By Month: ";
2106 while((i = r.by_month[index++]) != ICAL_RECURRENCE_ARRAY_MAX) { 2103 while((i = r.by_month[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
2107 out.append(QString::number(i) + " "); 2104 out.append(QString::number(i) + " ");
2108 } 2105 }
2109 } 2106 }
2110 if (r.by_set_pos[0] != ICAL_RECURRENCE_ARRAY_MAX) { 2107 if (r.by_set_pos[0] != ICAL_RECURRENCE_ARRAY_MAX) {
2111 int index = 0; 2108 int index = 0;
2112 QString out = " By Set Pos: "; 2109 QString out = " By Set Pos: ";
2113 while((i = r.by_set_pos[index++]) != ICAL_RECURRENCE_ARRAY_MAX) { 2110 while((i = r.by_set_pos[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
2114 out.append(QString::number(i) + " "); 2111 out.append(QString::number(i) + " ");
2115 } 2112 }
2116 } 2113 }
2117} 2114}
2118 2115
2119icalcomponent *ICalFormatImpl::createScheduleComponent(IncidenceBase *incidence, 2116icalcomponent *ICalFormatImpl::createScheduleComponent(IncidenceBase *incidence,
2120 Scheduler::Method method) 2117 Scheduler::Method method)
2121{ 2118{
2122 icalcomponent *message = createCalendarComponent(); 2119 icalcomponent *message = createCalendarComponent();
2123 2120
2124 icalproperty_method icalmethod = ICAL_METHOD_NONE; 2121 icalproperty_method icalmethod = ICAL_METHOD_NONE;
2125 2122
2126 switch (method) { 2123 switch (method) {
2127 case Scheduler::Publish: 2124 case Scheduler::Publish:
2128 icalmethod = ICAL_METHOD_PUBLISH; 2125 icalmethod = ICAL_METHOD_PUBLISH;
2129 break; 2126 break;
2130 case Scheduler::Request: 2127 case Scheduler::Request:
2131 icalmethod = ICAL_METHOD_REQUEST; 2128 icalmethod = ICAL_METHOD_REQUEST;
2132 break; 2129 break;
2133 case Scheduler::Refresh: 2130 case Scheduler::Refresh:
2134 icalmethod = ICAL_METHOD_REFRESH; 2131 icalmethod = ICAL_METHOD_REFRESH;
2135 break; 2132 break;
2136 case Scheduler::Cancel: 2133 case Scheduler::Cancel:
2137 icalmethod = ICAL_METHOD_CANCEL; 2134 icalmethod = ICAL_METHOD_CANCEL;
2138 break; 2135 break;
2139 case Scheduler::Add: 2136 case Scheduler::Add:
2140 icalmethod = ICAL_METHOD_ADD; 2137 icalmethod = ICAL_METHOD_ADD;
2141 break; 2138 break;
2142 case Scheduler::Reply: 2139 case Scheduler::Reply:
2143 icalmethod = ICAL_METHOD_REPLY; 2140 icalmethod = ICAL_METHOD_REPLY;
2144 break; 2141 break;
2145 case Scheduler::Counter: 2142 case Scheduler::Counter:
2146 icalmethod = ICAL_METHOD_COUNTER; 2143 icalmethod = ICAL_METHOD_COUNTER;
2147 break; 2144 break;
2148 case Scheduler::Declinecounter: 2145 case Scheduler::Declinecounter:
2149 icalmethod = ICAL_METHOD_DECLINECOUNTER; 2146 icalmethod = ICAL_METHOD_DECLINECOUNTER;
2150 break; 2147 break;
2151 default: 2148 default:
2152 2149
2153 return message; 2150 return message;
2154 } 2151 }
2155 2152
2156 icalcomponent_add_property(message,icalproperty_new_method(icalmethod)); 2153 icalcomponent_add_property(message,icalproperty_new_method(icalmethod));
2157 2154
2158 // TODO: check, if dynamic cast is required 2155 // TODO: check, if dynamic cast is required
2159 if(incidence->type() == "Todo") { 2156 if(incidence->type() == "Todo") {
2160 Todo *todo = static_cast<Todo *>(incidence); 2157 Todo *todo = static_cast<Todo *>(incidence);
2161 icalcomponent_add_component(message,writeTodo(todo)); 2158 icalcomponent_add_component(message,writeTodo(todo));
2162 } 2159 }
2163 if(incidence->type() == "Event") { 2160 if(incidence->type() == "Event") {
2164 Event *event = static_cast<Event *>(incidence); 2161 Event *event = static_cast<Event *>(incidence);
2165 icalcomponent_add_component(message,writeEvent(event)); 2162 icalcomponent_add_component(message,writeEvent(event));
2166 } 2163 }
2167 if(incidence->type() == "FreeBusy") { 2164 if(incidence->type() == "FreeBusy") {
2168 FreeBusy *freebusy = static_cast<FreeBusy *>(incidence); 2165 FreeBusy *freebusy = static_cast<FreeBusy *>(incidence);
2169 icalcomponent_add_component(message,writeFreeBusy(freebusy, method)); 2166 icalcomponent_add_component(message,writeFreeBusy(freebusy, method));
2170 } 2167 }
2171 2168
2172 return message; 2169 return message;
2173} 2170}
diff --git a/libkcal/icalformatimpl.h b/libkcal/icalformatimpl.h
index 2f32365..203c302 100644
--- a/libkcal/icalformatimpl.h
+++ b/libkcal/icalformatimpl.h
@@ -1,109 +1,109 @@
1/* 1/*
2 This file is part of libkcal. 2 This file is part of libkcal.
3 Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org> 3 Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
4 4
5 This library is free software; you can redistribute it and/or 5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public 6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either 7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version. 8 version 2 of the License, or (at your option) any later version.
9 9
10 This library is distributed in the hope that it will be useful, 10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details. 13 Library General Public License for more details.
14 14
15 You should have received a copy of the GNU Library General Public License 15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to 16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. 18 Boston, MA 02111-1307, USA.
19*/ 19*/
20#ifndef ICALFORMATIMPL_H 20#ifndef ICALFORMATIMPL_H
21#define ICALFORMATIMPL_H 21#define ICALFORMATIMPL_H
22 22
23#include <qstring.h> 23#include <qstring.h>
24 24
25#include "scheduler.h" 25#include "scheduler.h"
26#include "freebusy.h" 26#include "freebusy.h"
27 27
28extern "C" { 28extern "C" {
29 #include <ical.h> 29 #include <ical.h>
30 #include <icalss.h> 30 #include <icalss.h>
31} 31}
32 32
33namespace KCal { 33namespace KCal {
34 34
35class Compat; 35class Compat;
36 36
37/** 37/**
38 This class provides the libical dependent functions for ICalFormat. 38 This class provides the libical dependent functions for ICalFormat.
39*/ 39*/
40class ICalFormatImpl { 40class ICalFormatImpl {
41 public: 41 public:
42 /** Create new iCal format for calendar object */ 42 /** Create new iCal format for calendar object */
43 ICalFormatImpl( ICalFormat *parent ); 43 ICalFormatImpl( ICalFormat *parent );
44 virtual ~ICalFormatImpl(); 44 virtual ~ICalFormatImpl();
45 45
46 bool populate( Calendar *, icalcomponent *fs); 46 bool populate( Calendar *, icalcomponent *fs);
47 47
48 icalcomponent *writeIncidence(Incidence *incidence); 48 icalcomponent *writeIncidence(Incidence *incidence);
49 icalcomponent *writeTodo(Todo *todo); 49 icalcomponent *writeTodo(Todo *todo);
50 icalcomponent *writeEvent(Event *event); 50 icalcomponent *writeEvent(Event *event);
51 icalcomponent *writeFreeBusy(FreeBusy *freebusy, 51 icalcomponent *writeFreeBusy(FreeBusy *freebusy,
52 Scheduler::Method method); 52 Scheduler::Method method);
53 icalcomponent *writeJournal(Journal *journal); 53 icalcomponent *writeJournal(Journal *journal);
54 void writeIncidence(icalcomponent *parent,Incidence *incidence); 54 void writeIncidence(icalcomponent *parent,Incidence *incidence);
55 icalproperty *writeAttendee(Attendee *attendee); 55 icalproperty *writeAttendee(Attendee *attendee);
56 icalproperty *writeAttachment(Attachment *attach); 56 icalproperty *writeAttachment(Attachment *attach);
57 icalproperty *writeRecurrenceRule(Recurrence *); 57 icalproperty *writeRecurrenceRule(Recurrence *);
58 icalproperty *writeAlarm(Alarm *alarm); 58 icalcomponent *writeAlarm(Alarm *alarm);
59 59
60 QString extractErrorProperty(icalcomponent *); 60 QString extractErrorProperty(icalcomponent *);
61 Todo *readTodo(icalcomponent *vtodo); 61 Todo *readTodo(icalcomponent *vtodo);
62 Event *readEvent(icalcomponent *vevent); 62 Event *readEvent(icalcomponent *vevent);
63 FreeBusy *readFreeBusy(icalcomponent *vfreebusy); 63 FreeBusy *readFreeBusy(icalcomponent *vfreebusy);
64 Journal *readJournal(icalcomponent *vjournal); 64 Journal *readJournal(icalcomponent *vjournal);
65 Attendee *readAttendee(icalproperty *attendee); 65 Attendee *readAttendee(icalproperty *attendee);
66 Attachment *readAttachment(icalproperty *attach); 66 Attachment *readAttachment(icalproperty *attach);
67 void readIncidence(icalcomponent *parent,Incidence *incidence); 67 void readIncidence(icalcomponent *parent,Incidence *incidence);
68 void readRecurrenceRule(struct icalrecurrencetype rrule,Incidence *event); 68 void readRecurrenceRule(struct icalrecurrencetype rrule,Incidence *event);
69 void readRecurrence( const struct icalrecurrencetype &r, Recurrence* recur,Incidence *event ); 69 void readRecurrence( const struct icalrecurrencetype &r, Recurrence* recur,Incidence *event );
70 void readAlarm(icalcomponent *alarm,Incidence *incidence); 70 void readAlarm(icalcomponent *alarm,Incidence *incidence);
71 /** Return the PRODID string loaded from calendar file */ 71 /** Return the PRODID string loaded from calendar file */
72 const QString &loadedProductId() { return mLoadedProductId; } 72 const QString &loadedProductId() { return mLoadedProductId; }
73 73
74 icaltimetype writeICalDate(const QDate &); 74 icaltimetype writeICalDate(const QDate &);
75 QDate readICalDate(icaltimetype); 75 QDate readICalDate(icaltimetype);
76 icaltimetype writeICalDateTime(const QDateTime &); 76 icaltimetype writeICalDateTime(const QDateTime &);
77 QDateTime readICalDateTime(icaltimetype); 77 QDateTime readICalDateTime(icaltimetype);
78 icaldurationtype writeICalDuration(int seconds); 78 icaldurationtype writeICalDuration(int seconds);
79 int readICalDuration(icaldurationtype); 79 int readICalDuration(icaldurationtype);
80 icalcomponent *createCalendarComponent(Calendar * = 0); 80 icalcomponent *createCalendarComponent(Calendar * = 0);
81 icalcomponent *createScheduleComponent(IncidenceBase *,Scheduler::Method); 81 icalcomponent *createScheduleComponent(IncidenceBase *,Scheduler::Method);
82 82
83 private: 83 private:
84 void writeIncidenceBase(icalcomponent *parent,IncidenceBase *); 84 void writeIncidenceBase(icalcomponent *parent,IncidenceBase *);
85 void readIncidenceBase(icalcomponent *parent,IncidenceBase *); 85 void readIncidenceBase(icalcomponent *parent,IncidenceBase *);
86 void writeCustomProperties(icalcomponent *parent,CustomProperties *); 86 void writeCustomProperties(icalcomponent *parent,CustomProperties *);
87 void readCustomProperties(icalcomponent *parent,CustomProperties *); 87 void readCustomProperties(icalcomponent *parent,CustomProperties *);
88 void dumpIcalRecurrence(icalrecurrencetype); 88 void dumpIcalRecurrence(icalrecurrencetype);
89 89
90 ICalFormat *mParent; 90 ICalFormat *mParent;
91 Calendar *mCalendar; 91 Calendar *mCalendar;
92 92
93 QString mLoadedProductId; // PRODID string loaded from calendar file 93 QString mLoadedProductId; // PRODID string loaded from calendar file
94 int mCalendarVersion; // determines backward compatibility mode on read 94 int mCalendarVersion; // determines backward compatibility mode on read
95 95
96 QPtrList<Event> mEventsRelate; // events with relations 96 QPtrList<Event> mEventsRelate; // events with relations
97 QPtrList<Todo> mTodosRelate; // todos with relations 97 QPtrList<Todo> mTodosRelate; // todos with relations
98 98
99 static const int mSecondsPerWeek; 99 static const int mSecondsPerWeek;
100 static const int mSecondsPerDay; 100 static const int mSecondsPerDay;
101 static const int mSecondsPerHour; 101 static const int mSecondsPerHour;
102 static const int mSecondsPerMinute; 102 static const int mSecondsPerMinute;
103 103
104 Compat *mCompat; 104 Compat *mCompat;
105}; 105};
106 106
107} 107}
108 108
109#endif 109#endif
diff --git a/libkcal/vcalformat.cpp b/libkcal/vcalformat.cpp
index 59030d5..72a781a 100644
--- a/libkcal/vcalformat.cpp
+++ b/libkcal/vcalformat.cpp
@@ -1,1678 +1,1678 @@
1/* 1/*
2 This file is part of libkcal. 2 This file is part of libkcal.
3 Copyright (c) 1998 Preston Brwon 3 Copyright (c) 1998 Preston Brwon
4 Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org> 4 Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
5 5
6 This library is free software; you can redistribute it and/or 6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public 7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either 8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version. 9 version 2 of the License, or (at your option) any later version.
10 10
11 This library is distributed in the hope that it will be useful, 11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details. 14 Library General Public License for more details.
15 15
16 You should have received a copy of the GNU Library General Public License 16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to 17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. 19 Boston, MA 02111-1307, USA.
20*/ 20*/
21 21
22#include <qapplication.h> 22#include <qapplication.h>
23#include <qdatetime.h> 23#include <qdatetime.h>
24#include <qstring.h> 24#include <qstring.h>
25#include <qptrlist.h> 25#include <qptrlist.h>
26#include <qregexp.h> 26#include <qregexp.h>
27#include <qclipboard.h> 27#include <qclipboard.h>
28#include <qdialog.h> 28#include <qdialog.h>
29#include <qfile.h> 29#include <qfile.h>
30 30
31#include <kdebug.h> 31#include <kdebug.h>
32#include <kmessagebox.h> 32#include <kmessagebox.h>
33#include <kiconloader.h> 33#include <kiconloader.h>
34#include <klocale.h> 34#include <klocale.h>
35 35
36#include "vcc.h" 36#include "vcc.h"
37#include "vobject.h" 37#include "vobject.h"
38 38
39#include "vcaldrag.h" 39#include "vcaldrag.h"
40#include "calendar.h" 40#include "calendar.h"
41 41
42#include "vcalformat.h" 42#include "vcalformat.h"
43 43
44using namespace KCal; 44using namespace KCal;
45 45
46VCalFormat::VCalFormat() 46VCalFormat::VCalFormat()
47{ 47{
48} 48}
49 49
50VCalFormat::~VCalFormat() 50VCalFormat::~VCalFormat()
51{ 51{
52} 52}
53 53
54bool VCalFormat::load(Calendar *calendar, const QString &fileName) 54bool VCalFormat::load(Calendar *calendar, const QString &fileName)
55{ 55{
56 mCalendar = calendar; 56 mCalendar = calendar;
57 57
58 clearException(); 58 clearException();
59 59
60 kdDebug(5800) << "VCalFormat::load() " << fileName << endl; 60 kdDebug(5800) << "VCalFormat::load() " << fileName << endl;
61 61
62 VObject *vcal = 0; 62 VObject *vcal = 0;
63 63
64 // this is not necessarily only 1 vcal. Could be many vcals, or include 64 // this is not necessarily only 1 vcal. Could be many vcals, or include
65 // a vcard... 65 // a vcard...
66 vcal = Parse_MIME_FromFileName(const_cast<char *>(QFile::encodeName(fileName).data())); 66 vcal = Parse_MIME_FromFileName(const_cast<char *>(QFile::encodeName(fileName).data()));
67 67
68 if (!vcal) { 68 if (!vcal) {
69 setException(new ErrorFormat(ErrorFormat::CalVersionUnknown)); 69 setException(new ErrorFormat(ErrorFormat::CalVersionUnknown));
70 return FALSE; 70 return FALSE;
71 } 71 }
72 72
73 // any other top-level calendar stuff should be added/initialized here 73 // any other top-level calendar stuff should be added/initialized here
74 74
75 // put all vobjects into their proper places 75 // put all vobjects into their proper places
76 populate(vcal); 76 populate(vcal);
77 77
78 // clean up from vcal API stuff 78 // clean up from vcal API stuff
79 cleanVObjects(vcal); 79 cleanVObjects(vcal);
80 cleanStrTbl(); 80 cleanStrTbl();
81 81
82 return true; 82 return true;
83} 83}
84 84
85 85
86bool VCalFormat::save(Calendar *calendar, const QString &fileName) 86bool VCalFormat::save(Calendar *calendar, const QString &fileName)
87{ 87{
88 mCalendar = calendar; 88 mCalendar = calendar;
89 89
90 QString tmpStr; 90 QString tmpStr;
91 VObject *vcal, *vo; 91 VObject *vcal, *vo;
92 92
93 kdDebug(5800) << "VCalFormat::save(): " << fileName << endl; 93 kdDebug(5800) << "VCalFormat::save(): " << fileName << endl;
94 94
95 vcal = newVObject(VCCalProp); 95 vcal = newVObject(VCCalProp);
96 96
97 // addPropValue(vcal,VCLocationProp, "0.0"); 97 // addPropValue(vcal,VCLocationProp, "0.0");
98 addPropValue(vcal,VCProdIdProp, productId()); 98 addPropValue(vcal,VCProdIdProp, productId());
99 tmpStr = mCalendar->getTimeZoneStr(); 99 tmpStr = mCalendar->getTimeZoneStr();
100 //qDebug("mCalendar->getTimeZoneStr() %s",tmpStr.latin1() ); 100 //qDebug("mCalendar->getTimeZoneStr() %s",tmpStr.latin1() );
101 addPropValue(vcal,VCTimeZoneProp, tmpStr.local8Bit()); 101 addPropValue(vcal,VCTimeZoneProp, tmpStr.local8Bit());
102 addPropValue(vcal,VCVersionProp, _VCAL_VERSION); 102 addPropValue(vcal,VCVersionProp, _VCAL_VERSION);
103 103
104 // TODO STUFF 104 // TODO STUFF
105 QPtrList<Todo> todoList = mCalendar->rawTodos(); 105 QPtrList<Todo> todoList = mCalendar->rawTodos();
106 QPtrListIterator<Todo> qlt(todoList); 106 QPtrListIterator<Todo> qlt(todoList);
107 for (; qlt.current(); ++qlt) { 107 for (; qlt.current(); ++qlt) {
108 vo = eventToVTodo(qlt.current()); 108 vo = eventToVTodo(qlt.current());
109 addVObjectProp(vcal, vo); 109 addVObjectProp(vcal, vo);
110 } 110 }
111 111
112 // EVENT STUFF 112 // EVENT STUFF
113 QPtrList<Event> events = mCalendar->rawEvents(); 113 QPtrList<Event> events = mCalendar->rawEvents();
114 Event *ev; 114 Event *ev;
115 for(ev=events.first();ev;ev=events.next()) { 115 for(ev=events.first();ev;ev=events.next()) {
116 vo = eventToVEvent(ev); 116 vo = eventToVEvent(ev);
117 addVObjectProp(vcal, vo); 117 addVObjectProp(vcal, vo);
118 } 118 }
119 119
120 writeVObjectToFile(QFile::encodeName(fileName).data() ,vcal); 120 writeVObjectToFile(QFile::encodeName(fileName).data() ,vcal);
121 cleanVObjects(vcal); 121 cleanVObjects(vcal);
122 cleanStrTbl(); 122 cleanStrTbl();
123 123
124 if (QFile::exists(fileName)) { 124 if (QFile::exists(fileName)) {
125 kdDebug(5800) << "No error" << endl; 125 kdDebug(5800) << "No error" << endl;
126 return true; 126 return true;
127 } else { 127 } else {
128 kdDebug(5800) << "Error" << endl; 128 kdDebug(5800) << "Error" << endl;
129 return false; // error 129 return false; // error
130 } 130 }
131} 131}
132 132
133bool VCalFormat::fromString( Calendar *calendar, const QString &text ) 133bool VCalFormat::fromString( Calendar *calendar, const QString &text )
134{ 134{
135 // TODO: Factor out VCalFormat::fromString() 135 // TODO: Factor out VCalFormat::fromString()
136 136
137 QCString data = text.utf8(); 137 QCString data = text.utf8();
138 138
139 if ( !data.size() ) return false; 139 if ( !data.size() ) return false;
140 140
141 VObject *vcal = Parse_MIME( data.data(), data.size()); 141 VObject *vcal = Parse_MIME( data.data(), data.size());
142 if ( !vcal ) return false; 142 if ( !vcal ) return false;
143 143
144 VObjectIterator i; 144 VObjectIterator i;
145 VObject *curvo; 145 VObject *curvo;
146 initPropIterator( &i, vcal ); 146 initPropIterator( &i, vcal );
147 147
148 // we only take the first object. TODO: parse all incidences. 148 // we only take the first object. TODO: parse all incidences.
149 do { 149 do {
150 curvo = nextVObject( &i ); 150 curvo = nextVObject( &i );
151 } while ( strcmp( vObjectName( curvo ), VCEventProp ) && 151 } while ( strcmp( vObjectName( curvo ), VCEventProp ) &&
152 strcmp( vObjectName( curvo ), VCTodoProp ) ); 152 strcmp( vObjectName( curvo ), VCTodoProp ) );
153 153
154 if ( strcmp( vObjectName( curvo ), VCEventProp ) == 0 ) { 154 if ( strcmp( vObjectName( curvo ), VCEventProp ) == 0 ) {
155 Event *event = VEventToEvent( curvo ); 155 Event *event = VEventToEvent( curvo );
156 calendar->addEvent( event ); 156 calendar->addEvent( event );
157 } else { 157 } else {
158 kdDebug(5800) << "VCalFormat::fromString(): Unknown object type." << endl; 158 kdDebug(5800) << "VCalFormat::fromString(): Unknown object type." << endl;
159 deleteVObject( vcal ); 159 deleteVObject( vcal );
160 return false; 160 return false;
161 } 161 }
162 162
163 deleteVObject( vcal ); 163 deleteVObject( vcal );
164 164
165 return true; 165 return true;
166} 166}
167 167
168QString VCalFormat::toString( Calendar *calendar ) 168QString VCalFormat::toString( Calendar *calendar )
169{ 169{
170 // TODO: Factor out VCalFormat::asString() 170 // TODO: Factor out VCalFormat::asString()
171 171
172 VObject *vcal = newVObject(VCCalProp); 172 VObject *vcal = newVObject(VCCalProp);
173 173
174 addPropValue( vcal, VCProdIdProp, CalFormat::productId() ); 174 addPropValue( vcal, VCProdIdProp, CalFormat::productId() );
175 QString tmpStr = mCalendar->getTimeZoneStr(); 175 QString tmpStr = mCalendar->getTimeZoneStr();
176 addPropValue( vcal, VCTimeZoneProp, tmpStr.local8Bit() ); 176 addPropValue( vcal, VCTimeZoneProp, tmpStr.local8Bit() );
177 addPropValue( vcal, VCVersionProp, _VCAL_VERSION ); 177 addPropValue( vcal, VCVersionProp, _VCAL_VERSION );
178 178
179 // TODO: Use all data. 179 // TODO: Use all data.
180 QPtrList<Event> events = calendar->events(); 180 QPtrList<Event> events = calendar->events();
181 Event *event = events.first(); 181 Event *event = events.first();
182 if ( !event ) return QString::null; 182 if ( !event ) return QString::null;
183 183
184 VObject *vevent = eventToVEvent( event ); 184 VObject *vevent = eventToVEvent( event );
185 185
186 addVObjectProp( vcal, vevent ); 186 addVObjectProp( vcal, vevent );
187 187
188 char *buf = writeMemVObject( 0, 0, vcal ); 188 char *buf = writeMemVObject( 0, 0, vcal );
189 189
190 QString result( buf ); 190 QString result( buf );
191 191
192 cleanVObject( vcal ); 192 cleanVObject( vcal );
193 193
194 return result; 194 return result;
195} 195}
196 196
197VObject *VCalFormat::eventToVTodo(const Todo *anEvent) 197VObject *VCalFormat::eventToVTodo(const Todo *anEvent)
198{ 198{
199 VObject *vtodo; 199 VObject *vtodo;
200 QString tmpStr; 200 QString tmpStr;
201 QStringList tmpStrList; 201 QStringList tmpStrList;
202 202
203 vtodo = newVObject(VCTodoProp); 203 vtodo = newVObject(VCTodoProp);
204 204
205 // due date 205 // due date
206 if (anEvent->hasDueDate()) { 206 if (anEvent->hasDueDate()) {
207 tmpStr = qDateTimeToISO(anEvent->dtDue(), 207 tmpStr = qDateTimeToISO(anEvent->dtDue(),
208 !anEvent->doesFloat()); 208 !anEvent->doesFloat());
209 addPropValue(vtodo, VCDueProp, tmpStr.local8Bit()); 209 addPropValue(vtodo, VCDueProp, tmpStr.local8Bit());
210 } 210 }
211 211
212 // start date 212 // start date
213 if (anEvent->hasStartDate()) { 213 if (anEvent->hasStartDate()) {
214 tmpStr = qDateTimeToISO(anEvent->dtStart(), 214 tmpStr = qDateTimeToISO(anEvent->dtStart(),
215 !anEvent->doesFloat()); 215 !anEvent->doesFloat());
216 addPropValue(vtodo, VCDTstartProp, tmpStr.local8Bit()); 216 addPropValue(vtodo, VCDTstartProp, tmpStr.local8Bit());
217 } 217 }
218 218
219 // creation date 219 // creation date
220 tmpStr = qDateTimeToISO(anEvent->created()); 220 tmpStr = qDateTimeToISO(anEvent->created());
221 addPropValue(vtodo, VCDCreatedProp, tmpStr.local8Bit()); 221 addPropValue(vtodo, VCDCreatedProp, tmpStr.local8Bit());
222 222
223 // unique id 223 // unique id
224 addPropValue(vtodo, VCUniqueStringProp, 224 addPropValue(vtodo, VCUniqueStringProp,
225 anEvent->uid().local8Bit()); 225 anEvent->uid().local8Bit());
226 226
227 // revision 227 // revision
228 tmpStr.sprintf("%i", anEvent->revision()); 228 tmpStr.sprintf("%i", anEvent->revision());
229 addPropValue(vtodo, VCSequenceProp, tmpStr.local8Bit()); 229 addPropValue(vtodo, VCSequenceProp, tmpStr.local8Bit());
230 230
231 // last modification date 231 // last modification date
232 tmpStr = qDateTimeToISO(anEvent->lastModified()); 232 tmpStr = qDateTimeToISO(anEvent->lastModified());
233 addPropValue(vtodo, VCLastModifiedProp, tmpStr.local8Bit()); 233 addPropValue(vtodo, VCLastModifiedProp, tmpStr.local8Bit());
234 234
235 // organizer stuff 235 // organizer stuff
236 tmpStr = "MAILTO:" + anEvent->organizer(); 236 tmpStr = "MAILTO:" + anEvent->organizer();
237 addPropValue(vtodo, ICOrganizerProp, tmpStr.local8Bit()); 237 addPropValue(vtodo, ICOrganizerProp, tmpStr.local8Bit());
238 238
239 // attendees 239 // attendees
240 if (anEvent->attendeeCount() != 0) { 240 if (anEvent->attendeeCount() != 0) {
241 QPtrList<Attendee> al = anEvent->attendees(); 241 QPtrList<Attendee> al = anEvent->attendees();
242 QPtrListIterator<Attendee> ai(al); 242 QPtrListIterator<Attendee> ai(al);
243 Attendee *curAttendee; 243 Attendee *curAttendee;
244 244
245 for (; ai.current(); ++ai) { 245 for (; ai.current(); ++ai) {
246 curAttendee = ai.current(); 246 curAttendee = ai.current();
247 if (!curAttendee->email().isEmpty() && 247 if (!curAttendee->email().isEmpty() &&
248 !curAttendee->name().isEmpty()) 248 !curAttendee->name().isEmpty())
249 tmpStr = "MAILTO:" + curAttendee->name() + " <" + 249 tmpStr = "MAILTO:" + curAttendee->name() + " <" +
250 curAttendee->email() + ">"; 250 curAttendee->email() + ">";
251 else if (curAttendee->name().isEmpty()) 251 else if (curAttendee->name().isEmpty())
252 tmpStr = "MAILTO: " + curAttendee->email(); 252 tmpStr = "MAILTO: " + curAttendee->email();
253 else if (curAttendee->email().isEmpty()) 253 else if (curAttendee->email().isEmpty())
254 tmpStr = "MAILTO: " + curAttendee->name(); 254 tmpStr = "MAILTO: " + curAttendee->name();
255 else if (curAttendee->name().isEmpty() && 255 else if (curAttendee->name().isEmpty() &&
256 curAttendee->email().isEmpty()) 256 curAttendee->email().isEmpty())
257 kdDebug(5800) << "warning! this Event has an attendee w/o name or email!" << endl; 257 kdDebug(5800) << "warning! this Event has an attendee w/o name or email!" << endl;
258 VObject *aProp = addPropValue(vtodo, VCAttendeeProp, tmpStr.local8Bit()); 258 VObject *aProp = addPropValue(vtodo, VCAttendeeProp, tmpStr.local8Bit());
259 addPropValue(aProp, VCRSVPProp, curAttendee->RSVP() ? "TRUE" : "FALSE"); 259 addPropValue(aProp, VCRSVPProp, curAttendee->RSVP() ? "TRUE" : "FALSE");
260 addPropValue(aProp, VCStatusProp, writeStatus(curAttendee->status())); 260 addPropValue(aProp, VCStatusProp, writeStatus(curAttendee->status()));
261 } 261 }
262 } 262 }
263 263
264 // description BL: 264 // description BL:
265 if (!anEvent->description().isEmpty()) { 265 if (!anEvent->description().isEmpty()) {
266 VObject *d = addPropValue(vtodo, VCDescriptionProp, 266 VObject *d = addPropValue(vtodo, VCDescriptionProp,
267 anEvent->description().local8Bit()); 267 anEvent->description().local8Bit());
268 if (anEvent->description().find('\n') != -1) 268 if (anEvent->description().find('\n') != -1)
269 addProp(d, VCQuotedPrintableProp); 269 addProp(d, VCQuotedPrintableProp);
270 } 270 }
271 271
272 // summary 272 // summary
273 if (!anEvent->summary().isEmpty()) 273 if (!anEvent->summary().isEmpty())
274 addPropValue(vtodo, VCSummaryProp, anEvent->summary().local8Bit()); 274 addPropValue(vtodo, VCSummaryProp, anEvent->summary().local8Bit());
275 275
276 if (!anEvent->location().isEmpty()) 276 if (!anEvent->location().isEmpty())
277 addPropValue(vtodo, VCLocationProp, anEvent->location().local8Bit()); 277 addPropValue(vtodo, VCLocationProp, anEvent->location().local8Bit());
278 278
279 // completed 279 // completed
280 // status 280 // status
281 // backward compatibility, KOrganizer used to interpret only these two values 281 // backward compatibility, KOrganizer used to interpret only these two values
282 addPropValue(vtodo, VCStatusProp, anEvent->isCompleted() ? "COMPLETED" : 282 addPropValue(vtodo, VCStatusProp, anEvent->isCompleted() ? "COMPLETED" :
283 "NEEDS_ACTION"); 283 "NEEDS_ACTION");
284 // completion date 284 // completion date
285 if (anEvent->hasCompletedDate()) { 285 if (anEvent->hasCompletedDate()) {
286 tmpStr = qDateTimeToISO(anEvent->completed()); 286 tmpStr = qDateTimeToISO(anEvent->completed());
287 addPropValue(vtodo, VCCompletedProp, tmpStr.local8Bit()); 287 addPropValue(vtodo, VCCompletedProp, tmpStr.local8Bit());
288 } 288 }
289 289
290 // priority 290 // priority
291 tmpStr.sprintf("%i",anEvent->priority()); 291 tmpStr.sprintf("%i",anEvent->priority());
292 addPropValue(vtodo, VCPriorityProp, tmpStr.local8Bit()); 292 addPropValue(vtodo, VCPriorityProp, tmpStr.local8Bit());
293 293
294 // related event 294 // related event
295 if (anEvent->relatedTo()) { 295 if (anEvent->relatedTo()) {
296 addPropValue(vtodo, VCRelatedToProp, 296 addPropValue(vtodo, VCRelatedToProp,
297 anEvent->relatedTo()->uid().local8Bit()); 297 anEvent->relatedTo()->uid().local8Bit());
298 } 298 }
299 299
300 // categories 300 // categories
301 tmpStrList = anEvent->categories(); 301 tmpStrList = anEvent->categories();
302 tmpStr = ""; 302 tmpStr = "";
303 QString catStr; 303 QString catStr;
304 for ( QStringList::Iterator it = tmpStrList.begin(); 304 for ( QStringList::Iterator it = tmpStrList.begin();
305 it != tmpStrList.end(); 305 it != tmpStrList.end();
306 ++it ) { 306 ++it ) {
307 catStr = *it; 307 catStr = *it;
308 if (catStr[0] == ' ') 308 if (catStr[0] == ' ')
309 tmpStr += catStr.mid(1); 309 tmpStr += catStr.mid(1);
310 else 310 else
311 tmpStr += catStr; 311 tmpStr += catStr;
312 // this must be a ';' character as the vCalendar specification requires! 312 // this must be a ';' character as the vCalendar specification requires!
313 // vcc.y has been hacked to translate the ';' to a ',' when the vcal is 313 // vcc.y has been hacked to translate the ';' to a ',' when the vcal is
314 // read in. 314 // read in.
315 tmpStr += ";"; 315 tmpStr += ";";
316 } 316 }
317 if (!tmpStr.isEmpty()) { 317 if (!tmpStr.isEmpty()) {
318 tmpStr.truncate(tmpStr.length()-1); 318 tmpStr.truncate(tmpStr.length()-1);
319 addPropValue(vtodo, VCCategoriesProp, tmpStr.local8Bit()); 319 addPropValue(vtodo, VCCategoriesProp, tmpStr.local8Bit());
320 } 320 }
321 321
322 // alarm stuff 322 // alarm stuff
323 kdDebug(5800) << "vcalformat::eventToVTodo was called" << endl; 323 kdDebug(5800) << "vcalformat::eventToVTodo was called" << endl;
324 QPtrList<Alarm> alarms = anEvent->alarms(); 324 QPtrList<Alarm> alarms = anEvent->alarms();
325 Alarm* alarm; 325 Alarm* alarm;
326 for (alarm = alarms.first(); alarm; alarm = alarms.next()) { 326 for (alarm = alarms.first(); alarm; alarm = alarms.next()) {
327 if (alarm->enabled()) { 327 if (alarm->enabled()) {
328 VObject *a = addProp(vtodo, VCDAlarmProp); 328 VObject *a = addProp(vtodo, VCDAlarmProp);
329 tmpStr = qDateTimeToISO(alarm->time()); 329 tmpStr = qDateTimeToISO(alarm->time());
330 addPropValue(a, VCRunTimeProp, tmpStr.local8Bit()); 330 addPropValue(a, VCRunTimeProp, tmpStr.local8Bit());
331 addPropValue(a, VCRepeatCountProp, "1"); 331 addPropValue(a, VCRepeatCountProp, "1");
332 addPropValue(a, VCDisplayStringProp, "beep!"); 332 addPropValue(a, VCDisplayStringProp, "beep!");
333 if (alarm->type() == Alarm::Audio) { 333 if (alarm->type() == Alarm::Audio) {
334 a = addProp(vtodo, VCAAlarmProp); 334 a = addProp(vtodo, VCAAlarmProp);
335 addPropValue(a, VCRunTimeProp, tmpStr.local8Bit()); 335 addPropValue(a, VCRunTimeProp, tmpStr.local8Bit());
336 addPropValue(a, VCRepeatCountProp, "1"); 336 addPropValue(a, VCRepeatCountProp, "1");
337 addPropValue(a, VCAudioContentProp, QFile::encodeName(alarm->audioFile())); 337 addPropValue(a, VCAudioContentProp, QFile::encodeName(alarm->audioFile()));
338 } 338 }
339 else if (alarm->type() == Alarm::Procedure) { 339 else if (alarm->type() == Alarm::Procedure) {
340 a = addProp(vtodo, VCPAlarmProp); 340 a = addProp(vtodo, VCPAlarmProp);
341 addPropValue(a, VCRunTimeProp, tmpStr.local8Bit()); 341 addPropValue(a, VCRunTimeProp, tmpStr.local8Bit());
342 addPropValue(a, VCRepeatCountProp, "1"); 342 addPropValue(a, VCRepeatCountProp, "1");
343 addPropValue(a, VCProcedureNameProp, QFile::encodeName(alarm->programFile())); 343 addPropValue(a, VCProcedureNameProp, QFile::encodeName(alarm->programFile()));
344 } 344 }
345 } 345 }
346 } 346 }
347 347
348 if (anEvent->pilotId()) { 348 if (anEvent->pilotId()) {
349 // pilot sync stuff 349 // pilot sync stuff
350 tmpStr.sprintf("%i",anEvent->pilotId()); 350 tmpStr.sprintf("%i",anEvent->pilotId());
351 addPropValue(vtodo, KPilotIdProp, tmpStr.local8Bit()); 351 addPropValue(vtodo, XPilotIdProp, tmpStr.local8Bit());
352 tmpStr.sprintf("%i",anEvent->syncStatus()); 352 tmpStr.sprintf("%i",anEvent->syncStatus());
353 addPropValue(vtodo, KPilotStatusProp, tmpStr.local8Bit()); 353 addPropValue(vtodo, XPilotStatusProp, tmpStr.local8Bit());
354 } 354 }
355 355
356 return vtodo; 356 return vtodo;
357} 357}
358 358
359VObject* VCalFormat::eventToVEvent(const Event *anEvent) 359VObject* VCalFormat::eventToVEvent(const Event *anEvent)
360{ 360{
361 VObject *vevent; 361 VObject *vevent;
362 QString tmpStr; 362 QString tmpStr;
363 QStringList tmpStrList; 363 QStringList tmpStrList;
364 364
365 vevent = newVObject(VCEventProp); 365 vevent = newVObject(VCEventProp);
366 366
367 // start and end time 367 // start and end time
368 tmpStr = qDateTimeToISO(anEvent->dtStart(), 368 tmpStr = qDateTimeToISO(anEvent->dtStart(),
369 !anEvent->doesFloat()); 369 !anEvent->doesFloat());
370 addPropValue(vevent, VCDTstartProp, tmpStr.local8Bit()); 370 addPropValue(vevent, VCDTstartProp, tmpStr.local8Bit());
371 371
372 // events that have time associated but take up no time should 372 // events that have time associated but take up no time should
373 // not have both DTSTART and DTEND. 373 // not have both DTSTART and DTEND.
374 if (anEvent->dtStart() != anEvent->dtEnd()) { 374 if (anEvent->dtStart() != anEvent->dtEnd()) {
375 tmpStr = qDateTimeToISO(anEvent->dtEnd(), 375 tmpStr = qDateTimeToISO(anEvent->dtEnd(),
376 !anEvent->doesFloat()); 376 !anEvent->doesFloat());
377 addPropValue(vevent, VCDTendProp, tmpStr.local8Bit()); 377 addPropValue(vevent, VCDTendProp, tmpStr.local8Bit());
378 } 378 }
379 379
380 // creation date 380 // creation date
381 tmpStr = qDateTimeToISO(anEvent->created()); 381 tmpStr = qDateTimeToISO(anEvent->created());
382 addPropValue(vevent, VCDCreatedProp, tmpStr.local8Bit()); 382 addPropValue(vevent, VCDCreatedProp, tmpStr.local8Bit());
383 383
384 // unique id 384 // unique id
385 addPropValue(vevent, VCUniqueStringProp, 385 addPropValue(vevent, VCUniqueStringProp,
386 anEvent->uid().local8Bit()); 386 anEvent->uid().local8Bit());
387 387
388 // revision 388 // revision
389 tmpStr.sprintf("%i", anEvent->revision()); 389 tmpStr.sprintf("%i", anEvent->revision());
390 addPropValue(vevent, VCSequenceProp, tmpStr.local8Bit()); 390 addPropValue(vevent, VCSequenceProp, tmpStr.local8Bit());
391 391
392 // last modification date 392 // last modification date
393 tmpStr = qDateTimeToISO(anEvent->lastModified()); 393 tmpStr = qDateTimeToISO(anEvent->lastModified());
394 addPropValue(vevent, VCLastModifiedProp, tmpStr.local8Bit()); 394 addPropValue(vevent, VCLastModifiedProp, tmpStr.local8Bit());
395 395
396 // attendee and organizer stuff 396 // attendee and organizer stuff
397 tmpStr = "MAILTO:" + anEvent->organizer(); 397 tmpStr = "MAILTO:" + anEvent->organizer();
398 addPropValue(vevent, ICOrganizerProp, tmpStr.local8Bit()); 398 addPropValue(vevent, ICOrganizerProp, tmpStr.local8Bit());
399 399
400 if (anEvent->attendeeCount() != 0) { 400 if (anEvent->attendeeCount() != 0) {
401 QPtrList<Attendee> al = anEvent->attendees(); 401 QPtrList<Attendee> al = anEvent->attendees();
402 QPtrListIterator<Attendee> ai(al); 402 QPtrListIterator<Attendee> ai(al);
403 Attendee *curAttendee; 403 Attendee *curAttendee;
404 404
405 // TODO: Put this functionality into Attendee class 405 // TODO: Put this functionality into Attendee class
406 for (; ai.current(); ++ai) { 406 for (; ai.current(); ++ai) {
407 curAttendee = ai.current(); 407 curAttendee = ai.current();
408 if (!curAttendee->email().isEmpty() && 408 if (!curAttendee->email().isEmpty() &&
409 !curAttendee->name().isEmpty()) 409 !curAttendee->name().isEmpty())
410 tmpStr = "MAILTO:" + curAttendee->name() + " <" + 410 tmpStr = "MAILTO:" + curAttendee->name() + " <" +
411 curAttendee->email() + ">"; 411 curAttendee->email() + ">";
412 else if (curAttendee->name().isEmpty()) 412 else if (curAttendee->name().isEmpty())
413 tmpStr = "MAILTO: " + curAttendee->email(); 413 tmpStr = "MAILTO: " + curAttendee->email();
414 else if (curAttendee->email().isEmpty()) 414 else if (curAttendee->email().isEmpty())
415 tmpStr = "MAILTO: " + curAttendee->name(); 415 tmpStr = "MAILTO: " + curAttendee->name();
416 else if (curAttendee->name().isEmpty() && 416 else if (curAttendee->name().isEmpty() &&
417 curAttendee->email().isEmpty()) 417 curAttendee->email().isEmpty())
418 kdDebug(5800) << "warning! this Event has an attendee w/o name or email!" << endl; 418 kdDebug(5800) << "warning! this Event has an attendee w/o name or email!" << endl;
419 VObject *aProp = addPropValue(vevent, VCAttendeeProp, tmpStr.local8Bit()); 419 VObject *aProp = addPropValue(vevent, VCAttendeeProp, tmpStr.local8Bit());
420 addPropValue(aProp, VCRSVPProp, curAttendee->RSVP() ? "TRUE" : "FALSE");; 420 addPropValue(aProp, VCRSVPProp, curAttendee->RSVP() ? "TRUE" : "FALSE");;
421 addPropValue(aProp, VCStatusProp, writeStatus(curAttendee->status())); 421 addPropValue(aProp, VCStatusProp, writeStatus(curAttendee->status()));
422 } 422 }
423 } 423 }
424 424
425 // recurrence rule stuff 425 // recurrence rule stuff
426 if (anEvent->recurrence()->doesRecur()) { 426 if (anEvent->recurrence()->doesRecur()) {
427 // some more variables 427 // some more variables
428 QPtrList<Recurrence::rMonthPos> tmpPositions; 428 QPtrList<Recurrence::rMonthPos> tmpPositions;
429 QPtrList<int> tmpDays; 429 QPtrList<int> tmpDays;
430 int *tmpDay; 430 int *tmpDay;
431 Recurrence::rMonthPos *tmpPos; 431 Recurrence::rMonthPos *tmpPos;
432 QString tmpStr2; 432 QString tmpStr2;
433 int i; 433 int i;
434 434
435 switch(anEvent->recurrence()->doesRecur()) { 435 switch(anEvent->recurrence()->doesRecur()) {
436 case Recurrence::rDaily: 436 case Recurrence::rDaily:
437 tmpStr.sprintf("D%i ",anEvent->recurrence()->frequency()); 437 tmpStr.sprintf("D%i ",anEvent->recurrence()->frequency());
438// if (anEvent->rDuration > 0) 438// if (anEvent->rDuration > 0)
439 //tmpStr += "#"; 439 //tmpStr += "#";
440 break; 440 break;
441 case Recurrence::rWeekly: 441 case Recurrence::rWeekly:
442 tmpStr.sprintf("W%i ",anEvent->recurrence()->frequency()); 442 tmpStr.sprintf("W%i ",anEvent->recurrence()->frequency());
443 for (i = 0; i < 7; i++) { 443 for (i = 0; i < 7; i++) {
444 if (anEvent->recurrence()->days().testBit(i)) 444 if (anEvent->recurrence()->days().testBit(i))
445 tmpStr += dayFromNum(i); 445 tmpStr += dayFromNum(i);
446 } 446 }
447 break; 447 break;
448 case Recurrence::rMonthlyPos: 448 case Recurrence::rMonthlyPos:
449 tmpStr.sprintf("MP%i ", anEvent->recurrence()->frequency()); 449 tmpStr.sprintf("MP%i ", anEvent->recurrence()->frequency());
450 // write out all rMonthPos's 450 // write out all rMonthPos's
451 tmpPositions = anEvent->recurrence()->monthPositions(); 451 tmpPositions = anEvent->recurrence()->monthPositions();
452 for (tmpPos = tmpPositions.first(); 452 for (tmpPos = tmpPositions.first();
453 tmpPos; 453 tmpPos;
454 tmpPos = tmpPositions.next()) { 454 tmpPos = tmpPositions.next()) {
455 455
456 tmpStr2.sprintf("%i", tmpPos->rPos); 456 tmpStr2.sprintf("%i", tmpPos->rPos);
457 if (tmpPos->negative) 457 if (tmpPos->negative)
458 tmpStr2 += "- "; 458 tmpStr2 += "- ";
459 else 459 else
460 tmpStr2 += "+ "; 460 tmpStr2 += "+ ";
461 tmpStr += tmpStr2; 461 tmpStr += tmpStr2;
462 for (i = 0; i < 7; i++) { 462 for (i = 0; i < 7; i++) {
463 if (tmpPos->rDays.testBit(i)) 463 if (tmpPos->rDays.testBit(i))
464 tmpStr += dayFromNum(i); 464 tmpStr += dayFromNum(i);
465 } 465 }
466 } // loop for all rMonthPos's 466 } // loop for all rMonthPos's
467 break; 467 break;
468 case Recurrence::rMonthlyDay: 468 case Recurrence::rMonthlyDay:
469 tmpStr.sprintf("MD%i ", anEvent->recurrence()->frequency()); 469 tmpStr.sprintf("MD%i ", anEvent->recurrence()->frequency());
470 // write out all rMonthDays; 470 // write out all rMonthDays;
471 tmpDays = anEvent->recurrence()->monthDays(); 471 tmpDays = anEvent->recurrence()->monthDays();
472 for (tmpDay = tmpDays.first(); 472 for (tmpDay = tmpDays.first();
473 tmpDay; 473 tmpDay;
474 tmpDay = tmpDays.next()) { 474 tmpDay = tmpDays.next()) {
475 tmpStr2.sprintf("%i ", *tmpDay); 475 tmpStr2.sprintf("%i ", *tmpDay);
476 tmpStr += tmpStr2; 476 tmpStr += tmpStr2;
477 } 477 }
478 break; 478 break;
479 case Recurrence::rYearlyMonth: 479 case Recurrence::rYearlyMonth:
480 tmpStr.sprintf("YM%i ", anEvent->recurrence()->frequency()); 480 tmpStr.sprintf("YM%i ", anEvent->recurrence()->frequency());
481 // write out all the rYearNums; 481 // write out all the rYearNums;
482 tmpDays = anEvent->recurrence()->yearNums(); 482 tmpDays = anEvent->recurrence()->yearNums();
483 for (tmpDay = tmpDays.first(); 483 for (tmpDay = tmpDays.first();
484 tmpDay; 484 tmpDay;
485 tmpDay = tmpDays.next()) { 485 tmpDay = tmpDays.next()) {
486 tmpStr2.sprintf("%i ", *tmpDay); 486 tmpStr2.sprintf("%i ", *tmpDay);
487 tmpStr += tmpStr2; 487 tmpStr += tmpStr2;
488 } 488 }
489 break; 489 break;
490 case Recurrence::rYearlyDay: 490 case Recurrence::rYearlyDay:
491 tmpStr.sprintf("YD%i ", anEvent->recurrence()->frequency()); 491 tmpStr.sprintf("YD%i ", anEvent->recurrence()->frequency());
492 // write out all the rYearNums; 492 // write out all the rYearNums;
493 tmpDays = anEvent->recurrence()->yearNums(); 493 tmpDays = anEvent->recurrence()->yearNums();
494 for (tmpDay = tmpDays.first(); 494 for (tmpDay = tmpDays.first();
495 tmpDay; 495 tmpDay;
496 tmpDay = tmpDays.next()) { 496 tmpDay = tmpDays.next()) {
497 tmpStr2.sprintf("%i ", *tmpDay); 497 tmpStr2.sprintf("%i ", *tmpDay);
498 tmpStr += tmpStr2; 498 tmpStr += tmpStr2;
499 } 499 }
500 break; 500 break;
501 default: 501 default:
502 kdDebug(5800) << "ERROR, it should never get here in eventToVEvent!" << endl; 502 kdDebug(5800) << "ERROR, it should never get here in eventToVEvent!" << endl;
503 break; 503 break;
504 } // switch 504 } // switch
505 505
506 if (anEvent->recurrence()->duration() > 0) { 506 if (anEvent->recurrence()->duration() > 0) {
507 tmpStr2.sprintf("#%i",anEvent->recurrence()->duration()); 507 tmpStr2.sprintf("#%i",anEvent->recurrence()->duration());
508 tmpStr += tmpStr2; 508 tmpStr += tmpStr2;
509 } else if (anEvent->recurrence()->duration() == -1) { 509 } else if (anEvent->recurrence()->duration() == -1) {
510 tmpStr += "#0"; // defined as repeat forever 510 tmpStr += "#0"; // defined as repeat forever
511 } else { 511 } else {
512 tmpStr += qDateTimeToISO(anEvent->recurrence()->endDate(), FALSE); 512 tmpStr += qDateTimeToISO(anEvent->recurrence()->endDate(), FALSE);
513 } 513 }
514 addPropValue(vevent,VCRRuleProp, tmpStr.local8Bit()); 514 addPropValue(vevent,VCRRuleProp, tmpStr.local8Bit());
515 515
516 } // event repeats 516 } // event repeats
517 517
518 // exceptions to recurrence 518 // exceptions to recurrence
519 DateList dateList = anEvent->exDates(); 519 DateList dateList = anEvent->exDates();
520 DateList::ConstIterator it; 520 DateList::ConstIterator it;
521 QString tmpStr2; 521 QString tmpStr2;
522 522
523 for (it = dateList.begin(); it != dateList.end(); ++it) { 523 for (it = dateList.begin(); it != dateList.end(); ++it) {
524 tmpStr = qDateToISO(*it) + ";"; 524 tmpStr = qDateToISO(*it) + ";";
525 tmpStr2 += tmpStr; 525 tmpStr2 += tmpStr;
526 } 526 }
527 if (!tmpStr2.isEmpty()) { 527 if (!tmpStr2.isEmpty()) {
528 tmpStr2.truncate(tmpStr2.length()-1); 528 tmpStr2.truncate(tmpStr2.length()-1);
529 addPropValue(vevent, VCExDateProp, tmpStr2.local8Bit()); 529 addPropValue(vevent, VCExpDateProp, tmpStr2.local8Bit());
530 } 530 }
531 531
532 // description 532 // description
533 if (!anEvent->description().isEmpty()) { 533 if (!anEvent->description().isEmpty()) {
534 VObject *d = addPropValue(vevent, VCDescriptionProp, 534 VObject *d = addPropValue(vevent, VCDescriptionProp,
535 anEvent->description().local8Bit()); 535 anEvent->description().local8Bit());
536 if (anEvent->description().find('\n') != -1) 536 if (anEvent->description().find('\n') != -1)
537 addProp(d, VCQuotedPrintableProp); 537 addProp(d, VCQuotedPrintableProp);
538 } 538 }
539 539
540 // summary 540 // summary
541 if (!anEvent->summary().isEmpty()) 541 if (!anEvent->summary().isEmpty())
542 addPropValue(vevent, VCSummaryProp, anEvent->summary().local8Bit()); 542 addPropValue(vevent, VCSummaryProp, anEvent->summary().local8Bit());
543 543
544 if (!anEvent->location().isEmpty()) 544 if (!anEvent->location().isEmpty())
545 addPropValue(vevent, VCLocationProp, anEvent->location().local8Bit()); 545 addPropValue(vevent, VCLocationProp, anEvent->location().local8Bit());
546 546
547 // status 547 // status
548// TODO: define Event status 548// TODO: define Event status
549// addPropValue(vevent, VCStatusProp, anEvent->statusStr().local8Bit()); 549// addPropValue(vevent, VCStatusProp, anEvent->statusStr().local8Bit());
550 550
551 // secrecy 551 // secrecy
552 const char *text = 0; 552 const char *text = 0;
553 switch (anEvent->secrecy()) { 553 switch (anEvent->secrecy()) {
554 case Incidence::SecrecyPublic: 554 case Incidence::SecrecyPublic:
555 text = "PUBLIC"; 555 text = "PUBLIC";
556 break; 556 break;
557 case Incidence::SecrecyPrivate: 557 case Incidence::SecrecyPrivate:
558 text = "PRIVATE"; 558 text = "PRIVATE";
559 break; 559 break;
560 case Incidence::SecrecyConfidential: 560 case Incidence::SecrecyConfidential:
561 text = "CONFIDENTIAL"; 561 text = "CONFIDENTIAL";
562 break; 562 break;
563 } 563 }
564 if (text) { 564 if (text) {
565 addPropValue(vevent, VCClassProp, text); 565 addPropValue(vevent, VCClassProp, text);
566 } 566 }
567 567
568 // categories 568 // categories
569 tmpStrList = anEvent->categories(); 569 tmpStrList = anEvent->categories();
570 tmpStr = ""; 570 tmpStr = "";
571 QString catStr; 571 QString catStr;
572 for ( QStringList::Iterator it = tmpStrList.begin(); 572 for ( QStringList::Iterator it = tmpStrList.begin();
573 it != tmpStrList.end(); 573 it != tmpStrList.end();
574 ++it ) { 574 ++it ) {
575 catStr = *it; 575 catStr = *it;
576 if (catStr[0] == ' ') 576 if (catStr[0] == ' ')
577 tmpStr += catStr.mid(1); 577 tmpStr += catStr.mid(1);
578 else 578 else
579 tmpStr += catStr; 579 tmpStr += catStr;
580 // this must be a ';' character as the vCalendar specification requires! 580 // this must be a ';' character as the vCalendar specification requires!
581 // vcc.y has been hacked to translate the ';' to a ',' when the vcal is 581 // vcc.y has been hacked to translate the ';' to a ',' when the vcal is
582 // read in. 582 // read in.
583 tmpStr += ";"; 583 tmpStr += ";";
584 } 584 }
585 if (!tmpStr.isEmpty()) { 585 if (!tmpStr.isEmpty()) {
586 tmpStr.truncate(tmpStr.length()-1); 586 tmpStr.truncate(tmpStr.length()-1);
587 addPropValue(vevent, VCCategoriesProp, tmpStr.local8Bit()); 587 addPropValue(vevent, VCCategoriesProp, tmpStr.local8Bit());
588 } 588 }
589 589
590 // attachments 590 // attachments
591 // TODO: handle binary attachments! 591 // TODO: handle binary attachments!
592 QPtrList<Attachment> attachments = anEvent->attachments(); 592 QPtrList<Attachment> attachments = anEvent->attachments();
593 for ( Attachment *at = attachments.first(); at; at = attachments.next() ) 593 for ( Attachment *at = attachments.first(); at; at = attachments.next() )
594 addPropValue(vevent, VCAttachProp, at->uri().local8Bit()); 594 addPropValue(vevent, VCAttachProp, at->uri().local8Bit());
595 595
596 // resources 596 // resources
597 tmpStrList = anEvent->resources(); 597 tmpStrList = anEvent->resources();
598 tmpStr = tmpStrList.join(";"); 598 tmpStr = tmpStrList.join(";");
599 if (!tmpStr.isEmpty()) 599 if (!tmpStr.isEmpty())
600 addPropValue(vevent, VCResourcesProp, tmpStr.local8Bit()); 600 addPropValue(vevent, VCResourcesProp, tmpStr.local8Bit());
601 601
602 // alarm stuff 602 // alarm stuff
603 QPtrList<Alarm> alarms = anEvent->alarms(); 603 QPtrList<Alarm> alarms = anEvent->alarms();
604 Alarm* alarm; 604 Alarm* alarm;
605 for (alarm = alarms.first(); alarm; alarm = alarms.next()) { 605 for (alarm = alarms.first(); alarm; alarm = alarms.next()) {
606 if (alarm->enabled()) { 606 if (alarm->enabled()) {
607 VObject *a = addProp(vevent, VCDAlarmProp); 607 VObject *a = addProp(vevent, VCDAlarmProp);
608 tmpStr = qDateTimeToISO(alarm->time()); 608 tmpStr = qDateTimeToISO(alarm->time());
609 addPropValue(a, VCRunTimeProp, tmpStr.local8Bit()); 609 addPropValue(a, VCRunTimeProp, tmpStr.local8Bit());
610 addPropValue(a, VCRepeatCountProp, "1"); 610 addPropValue(a, VCRepeatCountProp, "1");
611 addPropValue(a, VCDisplayStringProp, "beep!"); 611 addPropValue(a, VCDisplayStringProp, "beep!");
612 if (alarm->type() == Alarm::Audio) { 612 if (alarm->type() == Alarm::Audio) {
613 a = addProp(vevent, VCAAlarmProp); 613 a = addProp(vevent, VCAAlarmProp);
614 addPropValue(a, VCRunTimeProp, tmpStr.local8Bit()); 614 addPropValue(a, VCRunTimeProp, tmpStr.local8Bit());
615 addPropValue(a, VCRepeatCountProp, "1"); 615 addPropValue(a, VCRepeatCountProp, "1");
616 addPropValue(a, VCAudioContentProp, QFile::encodeName(alarm->audioFile())); 616 addPropValue(a, VCAudioContentProp, QFile::encodeName(alarm->audioFile()));
617 } 617 }
618 if (alarm->type() == Alarm::Procedure) { 618 if (alarm->type() == Alarm::Procedure) {
619 a = addProp(vevent, VCPAlarmProp); 619 a = addProp(vevent, VCPAlarmProp);
620 addPropValue(a, VCRunTimeProp, tmpStr.local8Bit()); 620 addPropValue(a, VCRunTimeProp, tmpStr.local8Bit());
621 addPropValue(a, VCRepeatCountProp, "1"); 621 addPropValue(a, VCRepeatCountProp, "1");
622 addPropValue(a, VCProcedureNameProp, QFile::encodeName(alarm->programFile())); 622 addPropValue(a, VCProcedureNameProp, QFile::encodeName(alarm->programFile()));
623 } 623 }
624 } 624 }
625 } 625 }
626 626
627 // priority 627 // priority
628 tmpStr.sprintf("%i",anEvent->priority()); 628 tmpStr.sprintf("%i",anEvent->priority());
629 addPropValue(vevent, VCPriorityProp, tmpStr.local8Bit()); 629 addPropValue(vevent, VCPriorityProp, tmpStr.local8Bit());
630 630
631 // transparency 631 // transparency
632 tmpStr.sprintf("%i",anEvent->transparency()); 632 tmpStr.sprintf("%i",anEvent->transparency());
633 addPropValue(vevent, VCTranspProp, tmpStr.local8Bit()); 633 addPropValue(vevent, VCTranspProp, tmpStr.local8Bit());
634 634
635 // related event 635 // related event
636 if (anEvent->relatedTo()) { 636 if (anEvent->relatedTo()) {
637 addPropValue(vevent, VCRelatedToProp, 637 addPropValue(vevent, VCRelatedToProp,
638 anEvent->relatedTo()->uid().local8Bit()); 638 anEvent->relatedTo()->uid().local8Bit());
639 } 639 }
640 640
641 if (anEvent->pilotId()) { 641 if (anEvent->pilotId()) {
642 // pilot sync stuff 642 // pilot sync stuff
643 tmpStr.sprintf("%i",anEvent->pilotId()); 643 tmpStr.sprintf("%i",anEvent->pilotId());
644 addPropValue(vevent, KPilotIdProp, tmpStr.local8Bit()); 644 addPropValue(vevent, XPilotIdProp, tmpStr.local8Bit());
645 tmpStr.sprintf("%i",anEvent->syncStatus()); 645 tmpStr.sprintf("%i",anEvent->syncStatus());
646 addPropValue(vevent, KPilotStatusProp, tmpStr.local8Bit()); 646 addPropValue(vevent, XPilotStatusProp, tmpStr.local8Bit());
647 } 647 }
648 648
649 return vevent; 649 return vevent;
650} 650}
651 651
652Todo *VCalFormat::VTodoToEvent(VObject *vtodo) 652Todo *VCalFormat::VTodoToEvent(VObject *vtodo)
653{ 653{
654 VObject *vo; 654 VObject *vo;
655 VObjectIterator voi; 655 VObjectIterator voi;
656 char *s; 656 char *s;
657 657
658 Todo *anEvent = new Todo; 658 Todo *anEvent = new Todo;
659 659
660 // creation date 660 // creation date
661 if ((vo = isAPropertyOf(vtodo, VCDCreatedProp)) != 0) { 661 if ((vo = isAPropertyOf(vtodo, VCDCreatedProp)) != 0) {
662 anEvent->setCreated(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo)))); 662 anEvent->setCreated(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo))));
663 deleteStr(s); 663 deleteStr(s);
664 } 664 }
665 665
666 // unique id 666 // unique id
667 vo = isAPropertyOf(vtodo, VCUniqueStringProp); 667 vo = isAPropertyOf(vtodo, VCUniqueStringProp);
668 // while the UID property is preferred, it is not required. We'll use the 668 // while the UID property is preferred, it is not required. We'll use the
669 // default Event UID if none is given. 669 // default Event UID if none is given.
670 if (vo) { 670 if (vo) {
671 anEvent->setUid(s = fakeCString(vObjectUStringZValue(vo))); 671 anEvent->setUid(s = fakeCString(vObjectUStringZValue(vo)));
672 deleteStr(s); 672 deleteStr(s);
673 } 673 }
674 674
675 // last modification date 675 // last modification date
676 if ((vo = isAPropertyOf(vtodo, VCLastModifiedProp)) != 0) { 676 if ((vo = isAPropertyOf(vtodo, VCLastModifiedProp)) != 0) {
677 anEvent->setLastModified(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo)))); 677 anEvent->setLastModified(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo))));
678 deleteStr(s); 678 deleteStr(s);
679 } 679 }
680 else 680 else
681 anEvent->setLastModified(QDateTime(QDate::currentDate(), 681 anEvent->setLastModified(QDateTime(QDate::currentDate(),
682 QTime::currentTime())); 682 QTime::currentTime()));
683 683
684 // organizer 684 // organizer
685 // if our extension property for the event's ORGANIZER exists, add it. 685 // if our extension property for the event's ORGANIZER exists, add it.
686 if ((vo = isAPropertyOf(vtodo, ICOrganizerProp)) != 0) { 686 if ((vo = isAPropertyOf(vtodo, ICOrganizerProp)) != 0) {
687 anEvent->setOrganizer(s = fakeCString(vObjectUStringZValue(vo))); 687 anEvent->setOrganizer(s = fakeCString(vObjectUStringZValue(vo)));
688 deleteStr(s); 688 deleteStr(s);
689 } else { 689 } else {
690 anEvent->setOrganizer(mCalendar->getEmail()); 690 anEvent->setOrganizer(mCalendar->getEmail());
691 } 691 }
692 692
693 // attendees. 693 // attendees.
694 initPropIterator(&voi, vtodo); 694 initPropIterator(&voi, vtodo);
695 while (moreIteration(&voi)) { 695 while (moreIteration(&voi)) {
696 vo = nextVObject(&voi); 696 vo = nextVObject(&voi);
697 if (strcmp(vObjectName(vo), VCAttendeeProp) == 0) { 697 if (strcmp(vObjectName(vo), VCAttendeeProp) == 0) {
698 Attendee *a; 698 Attendee *a;
699 VObject *vp; 699 VObject *vp;
700 s = fakeCString(vObjectUStringZValue(vo)); 700 s = fakeCString(vObjectUStringZValue(vo));
701 QString tmpStr = QString::fromLocal8Bit(s); 701 QString tmpStr = QString::fromLocal8Bit(s);
702 deleteStr(s); 702 deleteStr(s);
703 tmpStr = tmpStr.simplifyWhiteSpace(); 703 tmpStr = tmpStr.simplifyWhiteSpace();
704 int emailPos1, emailPos2; 704 int emailPos1, emailPos2;
705 if ((emailPos1 = tmpStr.find('<')) > 0) { 705 if ((emailPos1 = tmpStr.find('<')) > 0) {
706 // both email address and name 706 // both email address and name
707 emailPos2 = tmpStr.findRev('>'); 707 emailPos2 = tmpStr.findRev('>');
708 a = new Attendee(tmpStr.left(emailPos1 - 1), 708 a = new Attendee(tmpStr.left(emailPos1 - 1),
709 tmpStr.mid(emailPos1 + 1, 709 tmpStr.mid(emailPos1 + 1,
710 emailPos2 - (emailPos1 + 1))); 710 emailPos2 - (emailPos1 + 1)));
711 } else if (tmpStr.find('@') > 0) { 711 } else if (tmpStr.find('@') > 0) {
712 // just an email address 712 // just an email address
713 a = new Attendee(0, tmpStr); 713 a = new Attendee(0, tmpStr);
714 } else { 714 } else {
715 // just a name 715 // just a name
716 QString email = tmpStr.replace( QRegExp(" "), "." ); 716 QString email = tmpStr.replace( QRegExp(" "), "." );
717 a = new Attendee(tmpStr,email); 717 a = new Attendee(tmpStr,email);
718 } 718 }
719 719
720 // is there an RSVP property? 720 // is there an RSVP property?
721 if ((vp = isAPropertyOf(vo, VCRSVPProp)) != 0) 721 if ((vp = isAPropertyOf(vo, VCRSVPProp)) != 0)
722 a->setRSVP(vObjectStringZValue(vp)); 722 a->setRSVP(vObjectStringZValue(vp));
723 // is there a status property? 723 // is there a status property?
724 if ((vp = isAPropertyOf(vo, VCStatusProp)) != 0) 724 if ((vp = isAPropertyOf(vo, VCStatusProp)) != 0)
725 a->setStatus(readStatus(vObjectStringZValue(vp))); 725 a->setStatus(readStatus(vObjectStringZValue(vp)));
726 // add the attendee 726 // add the attendee
727 anEvent->addAttendee(a); 727 anEvent->addAttendee(a);
728 } 728 }
729 } 729 }
730 730
731 // description for todo 731 // description for todo
732 if ((vo = isAPropertyOf(vtodo, VCDescriptionProp)) != 0) { 732 if ((vo = isAPropertyOf(vtodo, VCDescriptionProp)) != 0) {
733 s = fakeCString(vObjectUStringZValue(vo)); 733 s = fakeCString(vObjectUStringZValue(vo));
734 anEvent->setDescription(QString::fromLocal8Bit(s)); 734 anEvent->setDescription(QString::fromLocal8Bit(s));
735 deleteStr(s); 735 deleteStr(s);
736 } 736 }
737 737
738 // summary 738 // summary
739 if ((vo = isAPropertyOf(vtodo, VCSummaryProp))) { 739 if ((vo = isAPropertyOf(vtodo, VCSummaryProp))) {
740 s = fakeCString(vObjectUStringZValue(vo)); 740 s = fakeCString(vObjectUStringZValue(vo));
741 anEvent->setSummary(QString::fromLocal8Bit(s)); 741 anEvent->setSummary(QString::fromLocal8Bit(s));
742 deleteStr(s); 742 deleteStr(s);
743 } 743 }
744 if ((vo = isAPropertyOf(vtodo, VCLocationProp))) { 744 if ((vo = isAPropertyOf(vtodo, VCLocationProp))) {
745 s = fakeCString(vObjectUStringZValue(vo)); 745 s = fakeCString(vObjectUStringZValue(vo));
746 anEvent->setLocation(QString::fromLocal8Bit(s)); 746 anEvent->setLocation(QString::fromLocal8Bit(s));
747 deleteStr(s); 747 deleteStr(s);
748 } 748 }
749 749
750 750
751 // completed 751 // completed
752 // was: status 752 // was: status
753 if ((vo = isAPropertyOf(vtodo, VCStatusProp)) != 0) { 753 if ((vo = isAPropertyOf(vtodo, VCStatusProp)) != 0) {
754 s = fakeCString(vObjectUStringZValue(vo)); 754 s = fakeCString(vObjectUStringZValue(vo));
755 if (strcmp(s,"COMPLETED") == 0) { 755 if (strcmp(s,"COMPLETED") == 0) {
756 anEvent->setCompleted(true); 756 anEvent->setCompleted(true);
757 } else { 757 } else {
758 anEvent->setCompleted(false); 758 anEvent->setCompleted(false);
759 } 759 }
760 deleteStr(s); 760 deleteStr(s);
761 } 761 }
762 else 762 else
763 anEvent->setCompleted(false); 763 anEvent->setCompleted(false);
764 764
765 // completion date 765 // completion date
766 if ((vo = isAPropertyOf(vtodo, VCCompletedProp)) != 0) { 766 if ((vo = isAPropertyOf(vtodo, VCCompletedProp)) != 0) {
767 anEvent->setCompleted(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo)))); 767 anEvent->setCompleted(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo))));
768 deleteStr(s); 768 deleteStr(s);
769 } 769 }
770 770
771 // priority 771 // priority
772 if ((vo = isAPropertyOf(vtodo, VCPriorityProp))) { 772 if ((vo = isAPropertyOf(vtodo, VCPriorityProp))) {
773 anEvent->setPriority(atoi(s = fakeCString(vObjectUStringZValue(vo)))); 773 anEvent->setPriority(atoi(s = fakeCString(vObjectUStringZValue(vo))));
774 deleteStr(s); 774 deleteStr(s);
775 } 775 }
776 776
777 // due date 777 // due date
778 if ((vo = isAPropertyOf(vtodo, VCDueProp)) != 0) { 778 if ((vo = isAPropertyOf(vtodo, VCDueProp)) != 0) {
779 anEvent->setDtDue(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo)))); 779 anEvent->setDtDue(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo))));
780 deleteStr(s); 780 deleteStr(s);
781 anEvent->setHasDueDate(true); 781 anEvent->setHasDueDate(true);
782 } else { 782 } else {
783 anEvent->setHasDueDate(false); 783 anEvent->setHasDueDate(false);
784 } 784 }
785 785
786 // start time 786 // start time
787 if ((vo = isAPropertyOf(vtodo, VCDTstartProp)) != 0) { 787 if ((vo = isAPropertyOf(vtodo, VCDTstartProp)) != 0) {
788 anEvent->setDtStart(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo)))); 788 anEvent->setDtStart(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo))));
789 // kdDebug(5800) << "s is " << // s << ", ISO is " << ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo))).toString() << endl; 789 // kdDebug(5800) << "s is " << // s << ", ISO is " << ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo))).toString() << endl;
790 deleteStr(s); 790 deleteStr(s);
791 anEvent->setHasStartDate(true); 791 anEvent->setHasStartDate(true);
792 } else { 792 } else {
793 anEvent->setHasStartDate(false); 793 anEvent->setHasStartDate(false);
794 } 794 }
795 795
796 /* alarm stuff */ 796 /* alarm stuff */
797 //kdDebug(5800) << "vcalformat::VTodoToEvent called" << endl; 797 //kdDebug(5800) << "vcalformat::VTodoToEvent called" << endl;
798 if ((vo = isAPropertyOf(vtodo, VCDAlarmProp))) { 798 if ((vo = isAPropertyOf(vtodo, VCDAlarmProp))) {
799 Alarm* alarm = anEvent->newAlarm(); 799 Alarm* alarm = anEvent->newAlarm();
800 VObject *a; 800 VObject *a;
801 if ((a = isAPropertyOf(vo, VCRunTimeProp))) { 801 if ((a = isAPropertyOf(vo, VCRunTimeProp))) {
802 alarm->setTime(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(a)))); 802 alarm->setTime(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(a))));
803 deleteStr(s); 803 deleteStr(s);
804 } 804 }
805 alarm->setEnabled(true); 805 alarm->setEnabled(true);
806 if ((vo = isAPropertyOf(vtodo, VCPAlarmProp))) { 806 if ((vo = isAPropertyOf(vtodo, VCPAlarmProp))) {
807 if ((a = isAPropertyOf(vo, VCProcedureNameProp))) { 807 if ((a = isAPropertyOf(vo, VCProcedureNameProp))) {
808 s = fakeCString(vObjectUStringZValue(a)); 808 s = fakeCString(vObjectUStringZValue(a));
809 alarm->setProcedureAlarm(QFile::decodeName(s)); 809 alarm->setProcedureAlarm(QFile::decodeName(s));
810 deleteStr(s); 810 deleteStr(s);
811 } 811 }
812 } 812 }
813 if ((vo = isAPropertyOf(vtodo, VCAAlarmProp))) { 813 if ((vo = isAPropertyOf(vtodo, VCAAlarmProp))) {
814 if ((a = isAPropertyOf(vo, VCAudioContentProp))) { 814 if ((a = isAPropertyOf(vo, VCAudioContentProp))) {
815 s = fakeCString(vObjectUStringZValue(a)); 815 s = fakeCString(vObjectUStringZValue(a));
816 alarm->setAudioAlarm(QFile::decodeName(s)); 816 alarm->setAudioAlarm(QFile::decodeName(s));
817 deleteStr(s); 817 deleteStr(s);
818 } 818 }
819 } 819 }
820 } 820 }
821 821
822 // related todo 822 // related todo
823 if ((vo = isAPropertyOf(vtodo, VCRelatedToProp)) != 0) { 823 if ((vo = isAPropertyOf(vtodo, VCRelatedToProp)) != 0) {
824 anEvent->setRelatedToUid(s = fakeCString(vObjectUStringZValue(vo))); 824 anEvent->setRelatedToUid(s = fakeCString(vObjectUStringZValue(vo)));
825 deleteStr(s); 825 deleteStr(s);
826 mTodosRelate.append(anEvent); 826 mTodosRelate.append(anEvent);
827 } 827 }
828 828
829 // categories 829 // categories
830 QStringList tmpStrList; 830 QStringList tmpStrList;
831 int index1 = 0; 831 int index1 = 0;
832 int index2 = 0; 832 int index2 = 0;
833 if ((vo = isAPropertyOf(vtodo, VCCategoriesProp)) != 0) { 833 if ((vo = isAPropertyOf(vtodo, VCCategoriesProp)) != 0) {
834 s = fakeCString(vObjectUStringZValue(vo)); 834 s = fakeCString(vObjectUStringZValue(vo));
835 QString categories = QString::fromLocal8Bit(s); 835 QString categories = QString::fromLocal8Bit(s);
836 deleteStr(s); 836 deleteStr(s);
837 //const char* category; 837 //const char* category;
838 QString category; 838 QString category;
839 while ((index2 = categories.find(',', index1)) != -1) { 839 while ((index2 = categories.find(',', index1)) != -1) {
840 //category = (const char *) categories.mid(index1, (index2 - index1)); 840 //category = (const char *) categories.mid(index1, (index2 - index1));
841 category = categories.mid(index1, (index2 - index1)); 841 category = categories.mid(index1, (index2 - index1));
842 tmpStrList.append(category); 842 tmpStrList.append(category);
843 index1 = index2+1; 843 index1 = index2+1;
844 } 844 }
845 // get last category 845 // get last category
846 category = categories.mid(index1, (categories.length()-index1)); 846 category = categories.mid(index1, (categories.length()-index1));
847 tmpStrList.append(category); 847 tmpStrList.append(category);
848 anEvent->setCategories(tmpStrList); 848 anEvent->setCategories(tmpStrList);
849 } 849 }
850 850
851 /* PILOT SYNC STUFF */ 851 /* PILOT SYNC STUFF */
852 if ((vo = isAPropertyOf(vtodo, KPilotIdProp))) { 852 if ((vo = isAPropertyOf(vtodo, XPilotIdProp))) {
853 anEvent->setPilotId(atoi(s = fakeCString(vObjectUStringZValue(vo)))); 853 anEvent->setPilotId(atoi(s = fakeCString(vObjectUStringZValue(vo))));
854 deleteStr(s); 854 deleteStr(s);
855 } 855 }
856 else 856 else
857 anEvent->setPilotId(0); 857 anEvent->setPilotId(0);
858 858
859 if ((vo = isAPropertyOf(vtodo, KPilotStatusProp))) { 859 if ((vo = isAPropertyOf(vtodo, XPilotStatusProp))) {
860 anEvent->setSyncStatus(atoi(s = fakeCString(vObjectUStringZValue(vo)))); 860 anEvent->setSyncStatus(atoi(s = fakeCString(vObjectUStringZValue(vo))));
861 deleteStr(s); 861 deleteStr(s);
862 } 862 }
863 else 863 else
864 anEvent->setSyncStatus(Event::SYNCMOD); 864 anEvent->setSyncStatus(Event::SYNCMOD);
865 865
866 return anEvent; 866 return anEvent;
867} 867}
868 868
869Event* VCalFormat::VEventToEvent(VObject *vevent) 869Event* VCalFormat::VEventToEvent(VObject *vevent)
870{ 870{
871 VObject *vo; 871 VObject *vo;
872 VObjectIterator voi; 872 VObjectIterator voi;
873 char *s; 873 char *s;
874 874
875 Event *anEvent = new Event; 875 Event *anEvent = new Event;
876 876
877 // creation date 877 // creation date
878 if ((vo = isAPropertyOf(vevent, VCDCreatedProp)) != 0) { 878 if ((vo = isAPropertyOf(vevent, VCDCreatedProp)) != 0) {
879 anEvent->setCreated(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo)))); 879 anEvent->setCreated(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo))));
880 deleteStr(s); 880 deleteStr(s);
881 } 881 }
882 882
883 // unique id 883 // unique id
884 vo = isAPropertyOf(vevent, VCUniqueStringProp); 884 vo = isAPropertyOf(vevent, VCUniqueStringProp);
885 // while the UID property is preferred, it is not required. We'll use the 885 // while the UID property is preferred, it is not required. We'll use the
886 // default Event UID if none is given. 886 // default Event UID if none is given.
887 if (vo) { 887 if (vo) {
888 anEvent->setUid(s = fakeCString(vObjectUStringZValue(vo))); 888 anEvent->setUid(s = fakeCString(vObjectUStringZValue(vo)));
889 deleteStr(s); 889 deleteStr(s);
890 } 890 }
891 891
892 // revision 892 // revision
893 // again NSCAL doesn't give us much to work with, so we improvise... 893 // again NSCAL doesn't give us much to work with, so we improvise...
894 if ((vo = isAPropertyOf(vevent, VCSequenceProp)) != 0) { 894 if ((vo = isAPropertyOf(vevent, VCSequenceProp)) != 0) {
895 anEvent->setRevision(atoi(s = fakeCString(vObjectUStringZValue(vo)))); 895 anEvent->setRevision(atoi(s = fakeCString(vObjectUStringZValue(vo))));
896 deleteStr(s); 896 deleteStr(s);
897 } 897 }
898 else 898 else
899 anEvent->setRevision(0); 899 anEvent->setRevision(0);
900 900
901 // last modification date 901 // last modification date
902 if ((vo = isAPropertyOf(vevent, VCLastModifiedProp)) != 0) { 902 if ((vo = isAPropertyOf(vevent, VCLastModifiedProp)) != 0) {
903 anEvent->setLastModified(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo)))); 903 anEvent->setLastModified(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo))));
904 deleteStr(s); 904 deleteStr(s);
905 } 905 }
906 else 906 else
907 anEvent->setLastModified(QDateTime(QDate::currentDate(), 907 anEvent->setLastModified(QDateTime(QDate::currentDate(),
908 QTime::currentTime())); 908 QTime::currentTime()));
909 909
910 // organizer 910 // organizer
911 // if our extension property for the event's ORGANIZER exists, add it. 911 // if our extension property for the event's ORGANIZER exists, add it.
912 if ((vo = isAPropertyOf(vevent, ICOrganizerProp)) != 0) { 912 if ((vo = isAPropertyOf(vevent, ICOrganizerProp)) != 0) {
913 anEvent->setOrganizer(s = fakeCString(vObjectUStringZValue(vo))); 913 anEvent->setOrganizer(s = fakeCString(vObjectUStringZValue(vo)));
914 deleteStr(s); 914 deleteStr(s);
915 } else { 915 } else {
916 anEvent->setOrganizer(mCalendar->getEmail()); 916 anEvent->setOrganizer(mCalendar->getEmail());
917 } 917 }
918 918
919 // deal with attendees. 919 // deal with attendees.
920 initPropIterator(&voi, vevent); 920 initPropIterator(&voi, vevent);
921 while (moreIteration(&voi)) { 921 while (moreIteration(&voi)) {
922 vo = nextVObject(&voi); 922 vo = nextVObject(&voi);
923 if (strcmp(vObjectName(vo), VCAttendeeProp) == 0) { 923 if (strcmp(vObjectName(vo), VCAttendeeProp) == 0) {
924 Attendee *a; 924 Attendee *a;
925 VObject *vp; 925 VObject *vp;
926 s = fakeCString(vObjectUStringZValue(vo)); 926 s = fakeCString(vObjectUStringZValue(vo));
927 QString tmpStr = QString::fromLocal8Bit(s); 927 QString tmpStr = QString::fromLocal8Bit(s);
928 deleteStr(s); 928 deleteStr(s);
929 tmpStr = tmpStr.simplifyWhiteSpace(); 929 tmpStr = tmpStr.simplifyWhiteSpace();
930 int emailPos1, emailPos2; 930 int emailPos1, emailPos2;
931 if ((emailPos1 = tmpStr.find('<')) > 0) { 931 if ((emailPos1 = tmpStr.find('<')) > 0) {
932 // both email address and name 932 // both email address and name
933 emailPos2 = tmpStr.findRev('>'); 933 emailPos2 = tmpStr.findRev('>');
934 a = new Attendee(tmpStr.left(emailPos1 - 1), 934 a = new Attendee(tmpStr.left(emailPos1 - 1),
935 tmpStr.mid(emailPos1 + 1, 935 tmpStr.mid(emailPos1 + 1,
936 emailPos2 - (emailPos1 + 1))); 936 emailPos2 - (emailPos1 + 1)));
937 } else if (tmpStr.find('@') > 0) { 937 } else if (tmpStr.find('@') > 0) {
938 // just an email address 938 // just an email address
939 a = new Attendee(0, tmpStr); 939 a = new Attendee(0, tmpStr);
940 } else { 940 } else {
941 // just a name 941 // just a name
942 QString email = tmpStr.replace( QRegExp(" "), "." ); 942 QString email = tmpStr.replace( QRegExp(" "), "." );
943 a = new Attendee(tmpStr,email); 943 a = new Attendee(tmpStr,email);
944 } 944 }
945 945
946 // is there an RSVP property? 946 // is there an RSVP property?
947 if ((vp = isAPropertyOf(vo, VCRSVPProp)) != 0) 947 if ((vp = isAPropertyOf(vo, VCRSVPProp)) != 0)
948 a->setRSVP(vObjectStringZValue(vp)); 948 a->setRSVP(vObjectStringZValue(vp));
949 // is there a status property? 949 // is there a status property?
950 if ((vp = isAPropertyOf(vo, VCStatusProp)) != 0) 950 if ((vp = isAPropertyOf(vo, VCStatusProp)) != 0)
951 a->setStatus(readStatus(vObjectStringZValue(vp))); 951 a->setStatus(readStatus(vObjectStringZValue(vp)));
952 // add the attendee 952 // add the attendee
953 anEvent->addAttendee(a); 953 anEvent->addAttendee(a);
954 } 954 }
955 } 955 }
956 956
957 // This isn't strictly true. An event that doesn't have a start time 957 // This isn't strictly true. An event that doesn't have a start time
958 // or an end time doesn't "float", it has an anchor in time but it doesn't 958 // or an end time doesn't "float", it has an anchor in time but it doesn't
959 // "take up" any time. 959 // "take up" any time.
960 /*if ((isAPropertyOf(vevent, VCDTstartProp) == 0) || 960 /*if ((isAPropertyOf(vevent, VCDTstartProp) == 0) ||
961 (isAPropertyOf(vevent, VCDTendProp) == 0)) { 961 (isAPropertyOf(vevent, VCDTendProp) == 0)) {
962 anEvent->setFloats(TRUE); 962 anEvent->setFloats(TRUE);
963 } else { 963 } else {
964 }*/ 964 }*/
965 965
966 anEvent->setFloats(FALSE); 966 anEvent->setFloats(FALSE);
967 967
968 // start time 968 // start time
969 if ((vo = isAPropertyOf(vevent, VCDTstartProp)) != 0) { 969 if ((vo = isAPropertyOf(vevent, VCDTstartProp)) != 0) {
970 anEvent->setDtStart(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo)))); 970 anEvent->setDtStart(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo))));
971 // kdDebug(5800) << "s is " << // s << ", ISO is " << ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo))).toString() << endl; 971 // kdDebug(5800) << "s is " << // s << ", ISO is " << ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo))).toString() << endl;
972 deleteStr(s); 972 deleteStr(s);
973 if (anEvent->dtStart().time().isNull()) 973 if (anEvent->dtStart().time().isNull())
974 anEvent->setFloats(TRUE); 974 anEvent->setFloats(TRUE);
975 } 975 }
976 976
977 // stop time 977 // stop time
978 if ((vo = isAPropertyOf(vevent, VCDTendProp)) != 0) { 978 if ((vo = isAPropertyOf(vevent, VCDTendProp)) != 0) {
979 anEvent->setDtEnd(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo)))); 979 anEvent->setDtEnd(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo))));
980 deleteStr(s); 980 deleteStr(s);
981 if (anEvent->dtEnd().time().isNull()) 981 if (anEvent->dtEnd().time().isNull())
982 anEvent->setFloats(TRUE); 982 anEvent->setFloats(TRUE);
983 } 983 }
984 984
985 // at this point, there should be at least a start or end time. 985 // at this point, there should be at least a start or end time.
986 // fix up for events that take up no time but have a time associated 986 // fix up for events that take up no time but have a time associated
987 if (!(vo = isAPropertyOf(vevent, VCDTstartProp))) 987 if (!(vo = isAPropertyOf(vevent, VCDTstartProp)))
988 anEvent->setDtStart(anEvent->dtEnd()); 988 anEvent->setDtStart(anEvent->dtEnd());
989 if (!(vo = isAPropertyOf(vevent, VCDTendProp))) 989 if (!(vo = isAPropertyOf(vevent, VCDTendProp)))
990 anEvent->setDtEnd(anEvent->dtStart()); 990 anEvent->setDtEnd(anEvent->dtStart());
991 991
992 /////////////////////////////////////////////////////////////////////////// 992 ///////////////////////////////////////////////////////////////////////////
993 993
994 // repeat stuff 994 // repeat stuff
995 if ((vo = isAPropertyOf(vevent, VCRRuleProp)) != 0) { 995 if ((vo = isAPropertyOf(vevent, VCRRuleProp)) != 0) {
996 QString tmpStr = (s = fakeCString(vObjectUStringZValue(vo))); 996 QString tmpStr = (s = fakeCString(vObjectUStringZValue(vo)));
997 deleteStr(s); 997 deleteStr(s);
998 tmpStr.simplifyWhiteSpace(); 998 tmpStr.simplifyWhiteSpace();
999 tmpStr = tmpStr.upper(); 999 tmpStr = tmpStr.upper();
1000 1000
1001 /********************************* DAILY ******************************/ 1001 /********************************* DAILY ******************************/
1002 if (tmpStr.left(1) == "D") { 1002 if (tmpStr.left(1) == "D") {
1003 int index = tmpStr.find(' '); 1003 int index = tmpStr.find(' ');
1004 int rFreq = tmpStr.mid(1, (index-1)).toInt(); 1004 int rFreq = tmpStr.mid(1, (index-1)).toInt();
1005 index = tmpStr.findRev(' ') + 1; // advance to last field 1005 index = tmpStr.findRev(' ') + 1; // advance to last field
1006 if (tmpStr.mid(index,1) == "#") index++; 1006 if (tmpStr.mid(index,1) == "#") index++;
1007 if (tmpStr.find('T', index) != -1) { 1007 if (tmpStr.find('T', index) != -1) {
1008 QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date(); 1008 QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date();
1009 anEvent->recurrence()->setDaily(rFreq, rEndDate); 1009 anEvent->recurrence()->setDaily(rFreq, rEndDate);
1010 } else { 1010 } else {
1011 int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt(); 1011 int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt();
1012 if (rDuration == 0) // VEvents set this to 0 forever, we use -1 1012 if (rDuration == 0) // VEvents set this to 0 forever, we use -1
1013 anEvent->recurrence()->setDaily(rFreq, -1); 1013 anEvent->recurrence()->setDaily(rFreq, -1);
1014 else 1014 else
1015 anEvent->recurrence()->setDaily(rFreq, rDuration); 1015 anEvent->recurrence()->setDaily(rFreq, rDuration);
1016 } 1016 }
1017 } 1017 }
1018 /********************************* WEEKLY ******************************/ 1018 /********************************* WEEKLY ******************************/
1019 else if (tmpStr.left(1) == "W") { 1019 else if (tmpStr.left(1) == "W") {
1020 int index = tmpStr.find(' '); 1020 int index = tmpStr.find(' ');
1021 int last = tmpStr.findRev(' ') + 1; 1021 int last = tmpStr.findRev(' ') + 1;
1022 int rFreq = tmpStr.mid(1, (index-1)).toInt(); 1022 int rFreq = tmpStr.mid(1, (index-1)).toInt();
1023 index += 1; // advance to beginning of stuff after freq 1023 index += 1; // advance to beginning of stuff after freq
1024 QBitArray qba(7); 1024 QBitArray qba(7);
1025 QString dayStr; 1025 QString dayStr;
1026 if( index == last ) { 1026 if( index == last ) {
1027 // e.g. W1 #0 1027 // e.g. W1 #0
1028 qba.setBit(anEvent->dtStart().date().dayOfWeek() - 1); 1028 qba.setBit(anEvent->dtStart().date().dayOfWeek() - 1);
1029 } 1029 }
1030 else { 1030 else {
1031 // e.g. W1 SU #0 1031 // e.g. W1 SU #0
1032 while (index < last) { 1032 while (index < last) {
1033 dayStr = tmpStr.mid(index, 3); 1033 dayStr = tmpStr.mid(index, 3);
1034 int dayNum = numFromDay(dayStr); 1034 int dayNum = numFromDay(dayStr);
1035 qba.setBit(dayNum); 1035 qba.setBit(dayNum);
1036 index += 3; // advance to next day, or possibly "#" 1036 index += 3; // advance to next day, or possibly "#"
1037 } 1037 }
1038 } 1038 }
1039 index = last; if (tmpStr.mid(index,1) == "#") index++; 1039 index = last; if (tmpStr.mid(index,1) == "#") index++;
1040 if (tmpStr.find('T', index) != -1) { 1040 if (tmpStr.find('T', index) != -1) {
1041 QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date(); 1041 QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date();
1042 anEvent->recurrence()->setWeekly(rFreq, qba, rEndDate); 1042 anEvent->recurrence()->setWeekly(rFreq, qba, rEndDate);
1043 } else { 1043 } else {
1044 int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt(); 1044 int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt();
1045 if (rDuration == 0) 1045 if (rDuration == 0)
1046 anEvent->recurrence()->setWeekly(rFreq, qba, -1); 1046 anEvent->recurrence()->setWeekly(rFreq, qba, -1);
1047 else 1047 else
1048 anEvent->recurrence()->setWeekly(rFreq, qba, rDuration); 1048 anEvent->recurrence()->setWeekly(rFreq, qba, rDuration);
1049 } 1049 }
1050 } 1050 }
1051 /**************************** MONTHLY-BY-POS ***************************/ 1051 /**************************** MONTHLY-BY-POS ***************************/
1052 else if (tmpStr.left(2) == "MP") { 1052 else if (tmpStr.left(2) == "MP") {
1053 int index = tmpStr.find(' '); 1053 int index = tmpStr.find(' ');
1054 int last = tmpStr.findRev(' ') + 1; 1054 int last = tmpStr.findRev(' ') + 1;
1055 int rFreq = tmpStr.mid(2, (index-1)).toInt(); 1055 int rFreq = tmpStr.mid(2, (index-1)).toInt();
1056 index += 1; // advance to beginning of stuff after freq 1056 index += 1; // advance to beginning of stuff after freq
1057 QBitArray qba(7); 1057 QBitArray qba(7);
1058 short tmpPos; 1058 short tmpPos;
1059 if( index == last ) { 1059 if( index == last ) {
1060 // e.g. MP1 #0 1060 // e.g. MP1 #0
1061 tmpPos = anEvent->dtStart().date().day()/7 + 1; 1061 tmpPos = anEvent->dtStart().date().day()/7 + 1;
1062 if( tmpPos == 5 ) 1062 if( tmpPos == 5 )
1063 tmpPos = -1; 1063 tmpPos = -1;
1064 qba.setBit(anEvent->dtStart().date().dayOfWeek() - 1); 1064 qba.setBit(anEvent->dtStart().date().dayOfWeek() - 1);
1065 anEvent->recurrence()->addMonthlyPos(tmpPos, qba); 1065 anEvent->recurrence()->addMonthlyPos(tmpPos, qba);
1066 } 1066 }
1067 else { 1067 else {
1068 // e.g. MP1 1+ SU #0 1068 // e.g. MP1 1+ SU #0
1069 while (index < last) { 1069 while (index < last) {
1070 tmpPos = tmpStr.mid(index,1).toShort(); 1070 tmpPos = tmpStr.mid(index,1).toShort();
1071 index += 1; 1071 index += 1;
1072 if (tmpStr.mid(index,1) == "-") 1072 if (tmpStr.mid(index,1) == "-")
1073 // convert tmpPos to negative 1073 // convert tmpPos to negative
1074 tmpPos = 0 - tmpPos; 1074 tmpPos = 0 - tmpPos;
1075 index += 2; // advance to day(s) 1075 index += 2; // advance to day(s)
1076 while (numFromDay(tmpStr.mid(index,3)) >= 0) { 1076 while (numFromDay(tmpStr.mid(index,3)) >= 0) {
1077 int dayNum = numFromDay(tmpStr.mid(index,3)); 1077 int dayNum = numFromDay(tmpStr.mid(index,3));
1078 qba.setBit(dayNum); 1078 qba.setBit(dayNum);
1079 index += 3; // advance to next day, or possibly pos or "#" 1079 index += 3; // advance to next day, or possibly pos or "#"
1080 } 1080 }
1081 anEvent->recurrence()->addMonthlyPos(tmpPos, qba); 1081 anEvent->recurrence()->addMonthlyPos(tmpPos, qba);
1082 qba.detach(); 1082 qba.detach();
1083 qba.fill(FALSE); // clear out 1083 qba.fill(FALSE); // clear out
1084 } // while != "#" 1084 } // while != "#"
1085 } 1085 }
1086 index = last; if (tmpStr.mid(index,1) == "#") index++; 1086 index = last; if (tmpStr.mid(index,1) == "#") index++;
1087 if (tmpStr.find('T', index) != -1) { 1087 if (tmpStr.find('T', index) != -1) {
1088 QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length() - 1088 QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length() -
1089 index))).date(); 1089 index))).date();
1090 anEvent->recurrence()->setMonthly(Recurrence::rMonthlyPos, rFreq, rEndDate); 1090 anEvent->recurrence()->setMonthly(Recurrence::rMonthlyPos, rFreq, rEndDate);
1091 } else { 1091 } else {
1092 int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt(); 1092 int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt();
1093 if (rDuration == 0) 1093 if (rDuration == 0)
1094 anEvent->recurrence()->setMonthly(Recurrence::rMonthlyPos, rFreq, -1); 1094 anEvent->recurrence()->setMonthly(Recurrence::rMonthlyPos, rFreq, -1);
1095 else 1095 else
1096 anEvent->recurrence()->setMonthly(Recurrence::rMonthlyPos, rFreq, rDuration); 1096 anEvent->recurrence()->setMonthly(Recurrence::rMonthlyPos, rFreq, rDuration);
1097 } 1097 }
1098 } 1098 }
1099 1099
1100 /**************************** MONTHLY-BY-DAY ***************************/ 1100 /**************************** MONTHLY-BY-DAY ***************************/
1101 else if (tmpStr.left(2) == "MD") { 1101 else if (tmpStr.left(2) == "MD") {
1102 int index = tmpStr.find(' '); 1102 int index = tmpStr.find(' ');
1103 int last = tmpStr.findRev(' ') + 1; 1103 int last = tmpStr.findRev(' ') + 1;
1104 int rFreq = tmpStr.mid(2, (index-1)).toInt(); 1104 int rFreq = tmpStr.mid(2, (index-1)).toInt();
1105 index += 1; 1105 index += 1;
1106 short tmpDay; 1106 short tmpDay;
1107 if( index == last ) { 1107 if( index == last ) {
1108 // e.g. MD1 #0 1108 // e.g. MD1 #0
1109 tmpDay = anEvent->dtStart().date().day(); 1109 tmpDay = anEvent->dtStart().date().day();
1110 anEvent->recurrence()->addMonthlyDay(tmpDay); 1110 anEvent->recurrence()->addMonthlyDay(tmpDay);
1111 } 1111 }
1112 else { 1112 else {
1113 // e.g. MD1 3 #0 1113 // e.g. MD1 3 #0
1114 while (index < last) { 1114 while (index < last) {
1115 int index2 = tmpStr.find(' ', index); 1115 int index2 = tmpStr.find(' ', index);
1116 tmpDay = tmpStr.mid(index, (index2-index)).toShort(); 1116 tmpDay = tmpStr.mid(index, (index2-index)).toShort();
1117 index = index2-1; 1117 index = index2-1;
1118 if (tmpStr.mid(index, 1) == "-") 1118 if (tmpStr.mid(index, 1) == "-")
1119 tmpDay = 0 - tmpDay; 1119 tmpDay = 0 - tmpDay;
1120 index += 2; // advance the index; 1120 index += 2; // advance the index;
1121 anEvent->recurrence()->addMonthlyDay(tmpDay); 1121 anEvent->recurrence()->addMonthlyDay(tmpDay);
1122 } // while != # 1122 } // while != #
1123 } 1123 }
1124 index = last; if (tmpStr.mid(index,1) == "#") index++; 1124 index = last; if (tmpStr.mid(index,1) == "#") index++;
1125 if (tmpStr.find('T', index) != -1) { 1125 if (tmpStr.find('T', index) != -1) {
1126 QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date(); 1126 QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date();
1127 anEvent->recurrence()->setMonthly(Recurrence::rMonthlyDay, rFreq, rEndDate); 1127 anEvent->recurrence()->setMonthly(Recurrence::rMonthlyDay, rFreq, rEndDate);
1128 } else { 1128 } else {
1129 int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt(); 1129 int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt();
1130 if (rDuration == 0) 1130 if (rDuration == 0)
1131 anEvent->recurrence()->setMonthly(Recurrence::rMonthlyDay, rFreq, -1); 1131 anEvent->recurrence()->setMonthly(Recurrence::rMonthlyDay, rFreq, -1);
1132 else 1132 else
1133 anEvent->recurrence()->setMonthly(Recurrence::rMonthlyDay, rFreq, rDuration); 1133 anEvent->recurrence()->setMonthly(Recurrence::rMonthlyDay, rFreq, rDuration);
1134 } 1134 }
1135 } 1135 }
1136 1136
1137 /*********************** YEARLY-BY-MONTH *******************************/ 1137 /*********************** YEARLY-BY-MONTH *******************************/
1138 else if (tmpStr.left(2) == "YM") { 1138 else if (tmpStr.left(2) == "YM") {
1139 int index = tmpStr.find(' '); 1139 int index = tmpStr.find(' ');
1140 int last = tmpStr.findRev(' ') + 1; 1140 int last = tmpStr.findRev(' ') + 1;
1141 int rFreq = tmpStr.mid(2, (index-1)).toInt(); 1141 int rFreq = tmpStr.mid(2, (index-1)).toInt();
1142 index += 1; 1142 index += 1;
1143 short tmpMonth; 1143 short tmpMonth;
1144 if( index == last ) { 1144 if( index == last ) {
1145 // e.g. YM1 #0 1145 // e.g. YM1 #0
1146 tmpMonth = anEvent->dtStart().date().month(); 1146 tmpMonth = anEvent->dtStart().date().month();
1147 anEvent->recurrence()->addYearlyNum(tmpMonth); 1147 anEvent->recurrence()->addYearlyNum(tmpMonth);
1148 } 1148 }
1149 else { 1149 else {
1150 // e.g. YM1 3 #0 1150 // e.g. YM1 3 #0
1151 while (index < last) { 1151 while (index < last) {
1152 int index2 = tmpStr.find(' ', index); 1152 int index2 = tmpStr.find(' ', index);
1153 tmpMonth = tmpStr.mid(index, (index2-index)).toShort(); 1153 tmpMonth = tmpStr.mid(index, (index2-index)).toShort();
1154 index = index2+1; 1154 index = index2+1;
1155 anEvent->recurrence()->addYearlyNum(tmpMonth); 1155 anEvent->recurrence()->addYearlyNum(tmpMonth);
1156 } // while != # 1156 } // while != #
1157 } 1157 }
1158 index = last; if (tmpStr.mid(index,1) == "#") index++; 1158 index = last; if (tmpStr.mid(index,1) == "#") index++;
1159 if (tmpStr.find('T', index) != -1) { 1159 if (tmpStr.find('T', index) != -1) {
1160 QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date(); 1160 QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date();
1161 anEvent->recurrence()->setYearly(Recurrence::rYearlyMonth, rFreq, rEndDate); 1161 anEvent->recurrence()->setYearly(Recurrence::rYearlyMonth, rFreq, rEndDate);
1162 } else { 1162 } else {
1163 int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt(); 1163 int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt();
1164 if (rDuration == 0) 1164 if (rDuration == 0)
1165 anEvent->recurrence()->setYearly(Recurrence::rYearlyMonth, rFreq, -1); 1165 anEvent->recurrence()->setYearly(Recurrence::rYearlyMonth, rFreq, -1);
1166 else 1166 else
1167 anEvent->recurrence()->setYearly(Recurrence::rYearlyMonth, rFreq, rDuration); 1167 anEvent->recurrence()->setYearly(Recurrence::rYearlyMonth, rFreq, rDuration);
1168 } 1168 }
1169 } 1169 }
1170 1170
1171 /*********************** YEARLY-BY-DAY *********************************/ 1171 /*********************** YEARLY-BY-DAY *********************************/
1172 else if (tmpStr.left(2) == "YD") { 1172 else if (tmpStr.left(2) == "YD") {
1173 int index = tmpStr.find(' '); 1173 int index = tmpStr.find(' ');
1174 int last = tmpStr.findRev(' ') + 1; 1174 int last = tmpStr.findRev(' ') + 1;
1175 int rFreq = tmpStr.mid(2, (index-1)).toInt(); 1175 int rFreq = tmpStr.mid(2, (index-1)).toInt();
1176 index += 1; 1176 index += 1;
1177 short tmpDay; 1177 short tmpDay;
1178 if( index == last ) { 1178 if( index == last ) {
1179 // e.g. YD1 #0 1179 // e.g. YD1 #0
1180 tmpDay = anEvent->dtStart().date().dayOfYear(); 1180 tmpDay = anEvent->dtStart().date().dayOfYear();
1181 anEvent->recurrence()->addYearlyNum(tmpDay); 1181 anEvent->recurrence()->addYearlyNum(tmpDay);
1182 } 1182 }
1183 else { 1183 else {
1184 // e.g. YD1 123 #0 1184 // e.g. YD1 123 #0
1185 while (index < last) { 1185 while (index < last) {
1186 int index2 = tmpStr.find(' ', index); 1186 int index2 = tmpStr.find(' ', index);
1187 tmpDay = tmpStr.mid(index, (index2-index)).toShort(); 1187 tmpDay = tmpStr.mid(index, (index2-index)).toShort();
1188 index = index2+1; 1188 index = index2+1;
1189 anEvent->recurrence()->addYearlyNum(tmpDay); 1189 anEvent->recurrence()->addYearlyNum(tmpDay);
1190 } // while != # 1190 } // while != #
1191 } 1191 }
1192 index = last; if (tmpStr.mid(index,1) == "#") index++; 1192 index = last; if (tmpStr.mid(index,1) == "#") index++;
1193 if (tmpStr.find('T', index) != -1) { 1193 if (tmpStr.find('T', index) != -1) {
1194 QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date(); 1194 QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date();
1195 anEvent->recurrence()->setYearly(Recurrence::rYearlyDay, rFreq, rEndDate); 1195 anEvent->recurrence()->setYearly(Recurrence::rYearlyDay, rFreq, rEndDate);
1196 } else { 1196 } else {
1197 int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt(); 1197 int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt();
1198 if (rDuration == 0) 1198 if (rDuration == 0)
1199 anEvent->recurrence()->setYearly(Recurrence::rYearlyDay, rFreq, -1); 1199 anEvent->recurrence()->setYearly(Recurrence::rYearlyDay, rFreq, -1);
1200 else 1200 else
1201 anEvent->recurrence()->setYearly(Recurrence::rYearlyDay, rFreq, rDuration); 1201 anEvent->recurrence()->setYearly(Recurrence::rYearlyDay, rFreq, rDuration);
1202 } 1202 }
1203 } else { 1203 } else {
1204 kdDebug(5800) << "we don't understand this type of recurrence!" << endl; 1204 kdDebug(5800) << "we don't understand this type of recurrence!" << endl;
1205 } // if 1205 } // if
1206 } // repeats 1206 } // repeats
1207 1207
1208 1208
1209 // recurrence exceptions 1209 // recurrence exceptions
1210 if ((vo = isAPropertyOf(vevent, VCExDateProp)) != 0) { 1210 if ((vo = isAPropertyOf(vevent, VCExpDateProp)) != 0) {
1211 s = fakeCString(vObjectUStringZValue(vo)); 1211 s = fakeCString(vObjectUStringZValue(vo));
1212 QStringList exDates = QStringList::split(",",s); 1212 QStringList exDates = QStringList::split(",",s);
1213 QStringList::ConstIterator it; 1213 QStringList::ConstIterator it;
1214 for(it = exDates.begin(); it != exDates.end(); ++it ) { 1214 for(it = exDates.begin(); it != exDates.end(); ++it ) {
1215 anEvent->addExDate(ISOToQDate(*it)); 1215 anEvent->addExDate(ISOToQDate(*it));
1216 } 1216 }
1217 deleteStr(s); 1217 deleteStr(s);
1218 } 1218 }
1219 1219
1220 // summary 1220 // summary
1221 if ((vo = isAPropertyOf(vevent, VCSummaryProp))) { 1221 if ((vo = isAPropertyOf(vevent, VCSummaryProp))) {
1222 s = fakeCString(vObjectUStringZValue(vo)); 1222 s = fakeCString(vObjectUStringZValue(vo));
1223 anEvent->setSummary(QString::fromLocal8Bit(s)); 1223 anEvent->setSummary(QString::fromLocal8Bit(s));
1224 deleteStr(s); 1224 deleteStr(s);
1225 } 1225 }
1226 if ((vo = isAPropertyOf(vevent, VCLocationProp))) { 1226 if ((vo = isAPropertyOf(vevent, VCLocationProp))) {
1227 s = fakeCString(vObjectUStringZValue(vo)); 1227 s = fakeCString(vObjectUStringZValue(vo));
1228 anEvent->setLocation(QString::fromLocal8Bit(s)); 1228 anEvent->setLocation(QString::fromLocal8Bit(s));
1229 deleteStr(s); 1229 deleteStr(s);
1230 } 1230 }
1231 1231
1232 // description 1232 // description
1233 if ((vo = isAPropertyOf(vevent, VCDescriptionProp)) != 0) { 1233 if ((vo = isAPropertyOf(vevent, VCDescriptionProp)) != 0) {
1234 s = fakeCString(vObjectUStringZValue(vo)); 1234 s = fakeCString(vObjectUStringZValue(vo));
1235 if (!anEvent->description().isEmpty()) { 1235 if (!anEvent->description().isEmpty()) {
1236 anEvent->setDescription(anEvent->description() + "\n" + 1236 anEvent->setDescription(anEvent->description() + "\n" +
1237 QString::fromLocal8Bit(s)); 1237 QString::fromLocal8Bit(s));
1238 } else { 1238 } else {
1239 anEvent->setDescription(QString::fromLocal8Bit(s)); 1239 anEvent->setDescription(QString::fromLocal8Bit(s));
1240 } 1240 }
1241 deleteStr(s); 1241 deleteStr(s);
1242 } 1242 }
1243 1243
1244 // some stupid vCal exporters ignore the standard and use Description 1244 // some stupid vCal exporters ignore the standard and use Description
1245 // instead of Summary for the default field. Correct for this. 1245 // instead of Summary for the default field. Correct for this.
1246 if (anEvent->summary().isEmpty() && 1246 if (anEvent->summary().isEmpty() &&
1247 !(anEvent->description().isEmpty())) { 1247 !(anEvent->description().isEmpty())) {
1248 QString tmpStr = anEvent->description().simplifyWhiteSpace(); 1248 QString tmpStr = anEvent->description().simplifyWhiteSpace();
1249 anEvent->setDescription(""); 1249 anEvent->setDescription("");
1250 anEvent->setSummary(tmpStr); 1250 anEvent->setSummary(tmpStr);
1251 } 1251 }
1252 1252
1253#if 0 1253#if 0
1254 // status 1254 // status
1255 if ((vo = isAPropertyOf(vevent, VCStatusProp)) != 0) { 1255 if ((vo = isAPropertyOf(vevent, VCStatusProp)) != 0) {
1256 QString tmpStr(s = fakeCString(vObjectUStringZValue(vo))); 1256 QString tmpStr(s = fakeCString(vObjectUStringZValue(vo)));
1257 deleteStr(s); 1257 deleteStr(s);
1258// TODO: Define Event status 1258// TODO: Define Event status
1259// anEvent->setStatus(tmpStr); 1259// anEvent->setStatus(tmpStr);
1260 } 1260 }
1261 else 1261 else
1262// anEvent->setStatus("NEEDS ACTION"); 1262// anEvent->setStatus("NEEDS ACTION");
1263#endif 1263#endif
1264 1264
1265 // secrecy 1265 // secrecy
1266 int secrecy = Incidence::SecrecyPublic; 1266 int secrecy = Incidence::SecrecyPublic;
1267 if ((vo = isAPropertyOf(vevent, VCClassProp)) != 0) { 1267 if ((vo = isAPropertyOf(vevent, VCClassProp)) != 0) {
1268 s = fakeCString(vObjectUStringZValue(vo)); 1268 s = fakeCString(vObjectUStringZValue(vo));
1269 if (strcmp(s,"PRIVATE") == 0) { 1269 if (strcmp(s,"PRIVATE") == 0) {
1270 secrecy = Incidence::SecrecyPrivate; 1270 secrecy = Incidence::SecrecyPrivate;
1271 } else if (strcmp(s,"CONFIDENTIAL") == 0) { 1271 } else if (strcmp(s,"CONFIDENTIAL") == 0) {
1272 secrecy = Incidence::SecrecyConfidential; 1272 secrecy = Incidence::SecrecyConfidential;
1273 } 1273 }
1274 deleteStr(s); 1274 deleteStr(s);
1275 } 1275 }
1276 anEvent->setSecrecy(secrecy); 1276 anEvent->setSecrecy(secrecy);
1277 1277
1278 // categories 1278 // categories
1279 QStringList tmpStrList; 1279 QStringList tmpStrList;
1280 int index1 = 0; 1280 int index1 = 0;
1281 int index2 = 0; 1281 int index2 = 0;
1282 if ((vo = isAPropertyOf(vevent, VCCategoriesProp)) != 0) { 1282 if ((vo = isAPropertyOf(vevent, VCCategoriesProp)) != 0) {
1283 s = fakeCString(vObjectUStringZValue(vo)); 1283 s = fakeCString(vObjectUStringZValue(vo));
1284 QString categories = QString::fromLocal8Bit(s); 1284 QString categories = QString::fromLocal8Bit(s);
1285 deleteStr(s); 1285 deleteStr(s);
1286 //const char* category; 1286 //const char* category;
1287 QString category; 1287 QString category;
1288 while ((index2 = categories.find(',', index1)) != -1) { 1288 while ((index2 = categories.find(',', index1)) != -1) {
1289 //category = (const char *) categories.mid(index1, (index2 - index1)); 1289 //category = (const char *) categories.mid(index1, (index2 - index1));
1290 category = categories.mid(index1, (index2 - index1)); 1290 category = categories.mid(index1, (index2 - index1));
1291 tmpStrList.append(category); 1291 tmpStrList.append(category);
1292 index1 = index2+1; 1292 index1 = index2+1;
1293 } 1293 }
1294 // get last category 1294 // get last category
1295 category = categories.mid(index1, (categories.length()-index1)); 1295 category = categories.mid(index1, (categories.length()-index1));
1296 tmpStrList.append(category); 1296 tmpStrList.append(category);
1297 anEvent->setCategories(tmpStrList); 1297 anEvent->setCategories(tmpStrList);
1298 } 1298 }
1299 1299
1300 // attachments 1300 // attachments
1301 tmpStrList.clear(); 1301 tmpStrList.clear();
1302 initPropIterator(&voi, vevent); 1302 initPropIterator(&voi, vevent);
1303 while (moreIteration(&voi)) { 1303 while (moreIteration(&voi)) {
1304 vo = nextVObject(&voi); 1304 vo = nextVObject(&voi);
1305 if (strcmp(vObjectName(vo), VCAttachProp) == 0) { 1305 if (strcmp(vObjectName(vo), VCAttachProp) == 0) {
1306 s = fakeCString(vObjectUStringZValue(vo)); 1306 s = fakeCString(vObjectUStringZValue(vo));
1307 anEvent->addAttachment(new Attachment(QString(s))); 1307 anEvent->addAttachment(new Attachment(QString(s)));
1308 deleteStr(s); 1308 deleteStr(s);
1309 } 1309 }
1310 } 1310 }
1311 1311
1312 // resources 1312 // resources
1313 if ((vo = isAPropertyOf(vevent, VCResourcesProp)) != 0) { 1313 if ((vo = isAPropertyOf(vevent, VCResourcesProp)) != 0) {
1314 QString resources = (s = fakeCString(vObjectUStringZValue(vo))); 1314 QString resources = (s = fakeCString(vObjectUStringZValue(vo)));
1315 deleteStr(s); 1315 deleteStr(s);
1316 tmpStrList.clear(); 1316 tmpStrList.clear();
1317 index1 = 0; 1317 index1 = 0;
1318 index2 = 0; 1318 index2 = 0;
1319 QString resource; 1319 QString resource;
1320 while ((index2 = resources.find(';', index1)) != -1) { 1320 while ((index2 = resources.find(';', index1)) != -1) {
1321 resource = resources.mid(index1, (index2 - index1)); 1321 resource = resources.mid(index1, (index2 - index1));
1322 tmpStrList.append(resource); 1322 tmpStrList.append(resource);
1323 index1 = index2; 1323 index1 = index2;
1324 } 1324 }
1325 anEvent->setResources(tmpStrList); 1325 anEvent->setResources(tmpStrList);
1326 } 1326 }
1327 1327
1328 /* alarm stuff */ 1328 /* alarm stuff */
1329 if ((vo = isAPropertyOf(vevent, VCDAlarmProp))) { 1329 if ((vo = isAPropertyOf(vevent, VCDAlarmProp))) {
1330 Alarm* alarm = anEvent->newAlarm(); 1330 Alarm* alarm = anEvent->newAlarm();
1331 VObject *a; 1331 VObject *a;
1332 if ((a = isAPropertyOf(vo, VCRunTimeProp))) { 1332 if ((a = isAPropertyOf(vo, VCRunTimeProp))) {
1333 alarm->setTime(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(a)))); 1333 alarm->setTime(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(a))));
1334 deleteStr(s); 1334 deleteStr(s);
1335 } 1335 }
1336 alarm->setEnabled(true); 1336 alarm->setEnabled(true);
1337 if ((vo = isAPropertyOf(vevent, VCPAlarmProp))) { 1337 if ((vo = isAPropertyOf(vevent, VCPAlarmProp))) {
1338 if ((a = isAPropertyOf(vo, VCProcedureNameProp))) { 1338 if ((a = isAPropertyOf(vo, VCProcedureNameProp))) {
1339 s = fakeCString(vObjectUStringZValue(a)); 1339 s = fakeCString(vObjectUStringZValue(a));
1340 alarm->setProcedureAlarm(QFile::decodeName(s)); 1340 alarm->setProcedureAlarm(QFile::decodeName(s));
1341 deleteStr(s); 1341 deleteStr(s);
1342 } 1342 }
1343 } 1343 }
1344 if ((vo = isAPropertyOf(vevent, VCAAlarmProp))) { 1344 if ((vo = isAPropertyOf(vevent, VCAAlarmProp))) {
1345 if ((a = isAPropertyOf(vo, VCAudioContentProp))) { 1345 if ((a = isAPropertyOf(vo, VCAudioContentProp))) {
1346 s = fakeCString(vObjectUStringZValue(a)); 1346 s = fakeCString(vObjectUStringZValue(a));
1347 alarm->setAudioAlarm(QFile::decodeName(s)); 1347 alarm->setAudioAlarm(QFile::decodeName(s));
1348 deleteStr(s); 1348 deleteStr(s);
1349 } 1349 }
1350 } 1350 }
1351 } 1351 }
1352 1352
1353 // priority 1353 // priority
1354 if ((vo = isAPropertyOf(vevent, VCPriorityProp))) { 1354 if ((vo = isAPropertyOf(vevent, VCPriorityProp))) {
1355 anEvent->setPriority(atoi(s = fakeCString(vObjectUStringZValue(vo)))); 1355 anEvent->setPriority(atoi(s = fakeCString(vObjectUStringZValue(vo))));
1356 deleteStr(s); 1356 deleteStr(s);
1357 } 1357 }
1358 1358
1359 // transparency 1359 // transparency
1360 if ((vo = isAPropertyOf(vevent, VCTranspProp)) != 0) { 1360 if ((vo = isAPropertyOf(vevent, VCTranspProp)) != 0) {
1361 int i = atoi(s = fakeCString(vObjectUStringZValue(vo))); 1361 int i = atoi(s = fakeCString(vObjectUStringZValue(vo)));
1362 anEvent->setTransparency( i == 1 ? Event::Transparent : Event::Opaque ); 1362 anEvent->setTransparency( i == 1 ? Event::Transparent : Event::Opaque );
1363 deleteStr(s); 1363 deleteStr(s);
1364 } 1364 }
1365 1365
1366 // related event 1366 // related event
1367 if ((vo = isAPropertyOf(vevent, VCRelatedToProp)) != 0) { 1367 if ((vo = isAPropertyOf(vevent, VCRelatedToProp)) != 0) {
1368 anEvent->setRelatedToUid(s = fakeCString(vObjectUStringZValue(vo))); 1368 anEvent->setRelatedToUid(s = fakeCString(vObjectUStringZValue(vo)));
1369 deleteStr(s); 1369 deleteStr(s);
1370 mEventsRelate.append(anEvent); 1370 mEventsRelate.append(anEvent);
1371 } 1371 }
1372 1372
1373 /* PILOT SYNC STUFF */ 1373 /* PILOT SYNC STUFF */
1374 if ((vo = isAPropertyOf(vevent, KPilotIdProp))) { 1374 if ((vo = isAPropertyOf(vevent, XPilotIdProp))) {
1375 anEvent->setPilotId(atoi(s = fakeCString(vObjectUStringZValue(vo)))); 1375 anEvent->setPilotId(atoi(s = fakeCString(vObjectUStringZValue(vo))));
1376 deleteStr(s); 1376 deleteStr(s);
1377 } 1377 }
1378 else 1378 else
1379 anEvent->setPilotId(0); 1379 anEvent->setPilotId(0);
1380 1380
1381 if ((vo = isAPropertyOf(vevent, KPilotStatusProp))) { 1381 if ((vo = isAPropertyOf(vevent, XPilotStatusProp))) {
1382 anEvent->setSyncStatus(atoi(s = fakeCString(vObjectUStringZValue(vo)))); 1382 anEvent->setSyncStatus(atoi(s = fakeCString(vObjectUStringZValue(vo))));
1383 deleteStr(s); 1383 deleteStr(s);
1384 } 1384 }
1385 else 1385 else
1386 anEvent->setSyncStatus(Event::SYNCMOD); 1386 anEvent->setSyncStatus(Event::SYNCMOD);
1387 1387
1388 return anEvent; 1388 return anEvent;
1389} 1389}
1390 1390
1391 1391
1392QString VCalFormat::qDateToISO(const QDate &qd) 1392QString VCalFormat::qDateToISO(const QDate &qd)
1393{ 1393{
1394 QString tmpStr; 1394 QString tmpStr;
1395 1395
1396 ASSERT(qd.isValid()); 1396 ASSERT(qd.isValid());
1397 1397
1398 tmpStr.sprintf("%.2d%.2d%.2d", 1398 tmpStr.sprintf("%.2d%.2d%.2d",
1399 qd.year(), qd.month(), qd.day()); 1399 qd.year(), qd.month(), qd.day());
1400 return tmpStr; 1400 return tmpStr;
1401 1401
1402} 1402}
1403 1403
1404QString VCalFormat::qDateTimeToISO(const QDateTime &qdt, bool zulu) 1404QString VCalFormat::qDateTimeToISO(const QDateTime &qdt, bool zulu)
1405{ 1405{
1406 QString tmpStr; 1406 QString tmpStr;
1407 1407
1408 ASSERT(qdt.date().isValid()); 1408 ASSERT(qdt.date().isValid());
1409 ASSERT(qdt.time().isValid()); 1409 ASSERT(qdt.time().isValid());
1410 if (zulu) { 1410 if (zulu) {
1411 QDateTime tmpDT(qdt); 1411 QDateTime tmpDT(qdt);
1412 tmpDT = tmpDT.addSecs(60*(-mCalendar->getTimeZone())); // correct to GMT. 1412 tmpDT = tmpDT.addSecs(60*(-mCalendar->getTimeZone())); // correct to GMT.
1413 tmpStr.sprintf("%.2d%.2d%.2dT%.2d%.2d%.2dZ", 1413 tmpStr.sprintf("%.2d%.2d%.2dT%.2d%.2d%.2dZ",
1414 tmpDT.date().year(), tmpDT.date().month(), 1414 tmpDT.date().year(), tmpDT.date().month(),
1415 tmpDT.date().day(), tmpDT.time().hour(), 1415 tmpDT.date().day(), tmpDT.time().hour(),
1416 tmpDT.time().minute(), tmpDT.time().second()); 1416 tmpDT.time().minute(), tmpDT.time().second());
1417 } else { 1417 } else {
1418 tmpStr.sprintf("%.2d%.2d%.2dT%.2d%.2d%.2d", 1418 tmpStr.sprintf("%.2d%.2d%.2dT%.2d%.2d%.2d",
1419 qdt.date().year(), qdt.date().month(), 1419 qdt.date().year(), qdt.date().month(),
1420 qdt.date().day(), qdt.time().hour(), 1420 qdt.date().day(), qdt.time().hour(),
1421 qdt.time().minute(), qdt.time().second()); 1421 qdt.time().minute(), qdt.time().second());
1422 } 1422 }
1423 return tmpStr; 1423 return tmpStr;
1424} 1424}
1425 1425
1426QDateTime VCalFormat::ISOToQDateTime(const QString & dtStr) 1426QDateTime VCalFormat::ISOToQDateTime(const QString & dtStr)
1427{ 1427{
1428 QDate tmpDate; 1428 QDate tmpDate;
1429 QTime tmpTime; 1429 QTime tmpTime;
1430 QString tmpStr; 1430 QString tmpStr;
1431 int year, month, day, hour, minute, second; 1431 int year, month, day, hour, minute, second;
1432 1432
1433 tmpStr = dtStr; 1433 tmpStr = dtStr;
1434 year = tmpStr.left(4).toInt(); 1434 year = tmpStr.left(4).toInt();
1435 month = tmpStr.mid(4,2).toInt(); 1435 month = tmpStr.mid(4,2).toInt();
1436 day = tmpStr.mid(6,2).toInt(); 1436 day = tmpStr.mid(6,2).toInt();
1437 hour = tmpStr.mid(9,2).toInt(); 1437 hour = tmpStr.mid(9,2).toInt();
1438 minute = tmpStr.mid(11,2).toInt(); 1438 minute = tmpStr.mid(11,2).toInt();
1439 second = tmpStr.mid(13,2).toInt(); 1439 second = tmpStr.mid(13,2).toInt();
1440 tmpDate.setYMD(year, month, day); 1440 tmpDate.setYMD(year, month, day);
1441 tmpTime.setHMS(hour, minute, second); 1441 tmpTime.setHMS(hour, minute, second);
1442 1442
1443 ASSERT(tmpDate.isValid()); 1443 ASSERT(tmpDate.isValid());
1444 ASSERT(tmpTime.isValid()); 1444 ASSERT(tmpTime.isValid());
1445 QDateTime tmpDT(tmpDate, tmpTime); 1445 QDateTime tmpDT(tmpDate, tmpTime);
1446 // correct for GMT if string is in Zulu format 1446 // correct for GMT if string is in Zulu format
1447 if (dtStr.at(dtStr.length()-1) == 'Z') 1447 if (dtStr.at(dtStr.length()-1) == 'Z')
1448 tmpDT = tmpDT.addSecs(60*mCalendar->getTimeZone()); 1448 tmpDT = tmpDT.addSecs(60*mCalendar->getTimeZone());
1449 return tmpDT; 1449 return tmpDT;
1450} 1450}
1451 1451
1452QDate VCalFormat::ISOToQDate(const QString &dateStr) 1452QDate VCalFormat::ISOToQDate(const QString &dateStr)
1453{ 1453{
1454 int year, month, day; 1454 int year, month, day;
1455 1455
1456 year = dateStr.left(4).toInt(); 1456 year = dateStr.left(4).toInt();
1457 month = dateStr.mid(4,2).toInt(); 1457 month = dateStr.mid(4,2).toInt();
1458 day = dateStr.mid(6,2).toInt(); 1458 day = dateStr.mid(6,2).toInt();
1459 1459
1460 return(QDate(year, month, day)); 1460 return(QDate(year, month, day));
1461} 1461}
1462 1462
1463// take a raw vcalendar (i.e. from a file on disk, clipboard, etc. etc. 1463// take a raw vcalendar (i.e. from a file on disk, clipboard, etc. etc.
1464// and break it down from it's tree-like format into the dictionary format 1464// and break it down from it's tree-like format into the dictionary format
1465// that is used internally in the VCalFormat. 1465// that is used internally in the VCalFormat.
1466void VCalFormat::populate(VObject *vcal) 1466void VCalFormat::populate(VObject *vcal)
1467{ 1467{
1468 // this function will populate the caldict dictionary and other event 1468 // this function will populate the caldict dictionary and other event
1469 // lists. It turns vevents into Events and then inserts them. 1469 // lists. It turns vevents into Events and then inserts them.
1470 1470
1471 VObjectIterator i; 1471 VObjectIterator i;
1472 VObject *curVO, *curVOProp; 1472 VObject *curVO, *curVOProp;
1473 Event *anEvent; 1473 Event *anEvent;
1474 1474
1475 if ((curVO = isAPropertyOf(vcal, ICMethodProp)) != 0) { 1475 if ((curVO = isAPropertyOf(vcal, ICMethodProp)) != 0) {
1476 char *methodType = 0; 1476 char *methodType = 0;
1477 methodType = fakeCString(vObjectUStringZValue(curVO)); 1477 methodType = fakeCString(vObjectUStringZValue(curVO));
1478 kdDebug() << "This calendar is an iTIP transaction of type '" 1478 kdDebug() << "This calendar is an iTIP transaction of type '"
1479 << methodType << "'" << endl; 1479 << methodType << "'" << endl;
1480 delete methodType; 1480 delete methodType;
1481 } 1481 }
1482 1482
1483 // warn the user that we might have trouble reading non-known calendar. 1483 // warn the user that we might have trouble reading non-known calendar.
1484 if ((curVO = isAPropertyOf(vcal, VCProdIdProp)) != 0) { 1484 if ((curVO = isAPropertyOf(vcal, VCProdIdProp)) != 0) {
1485 char *s = fakeCString(vObjectUStringZValue(curVO)); 1485 char *s = fakeCString(vObjectUStringZValue(curVO));
1486 if (strcmp(productId().local8Bit(), s) != 0) 1486 if (strcmp(productId().local8Bit(), s) != 0)
1487 kdDebug() << "This vCalendar file was not created by KOrganizer " 1487 kdDebug() << "This vCalendar file was not created by KOrganizer "
1488 "or any other product we support. Loading anyway..." << endl; 1488 "or any other product we support. Loading anyway..." << endl;
1489 mLoadedProductId = s; 1489 mLoadedProductId = s;
1490 deleteStr(s); 1490 deleteStr(s);
1491 } 1491 }
1492 1492
1493 // warn the user we might have trouble reading this unknown version. 1493 // warn the user we might have trouble reading this unknown version.
1494 if ((curVO = isAPropertyOf(vcal, VCVersionProp)) != 0) { 1494 if ((curVO = isAPropertyOf(vcal, VCVersionProp)) != 0) {
1495 char *s = fakeCString(vObjectUStringZValue(curVO)); 1495 char *s = fakeCString(vObjectUStringZValue(curVO));
1496 if (strcmp(_VCAL_VERSION, s) != 0) 1496 if (strcmp(_VCAL_VERSION, s) != 0)
1497 kdDebug() << "This vCalendar file has version " << s 1497 kdDebug() << "This vCalendar file has version " << s
1498 << "We only support " << _VCAL_VERSION << endl; 1498 << "We only support " << _VCAL_VERSION << endl;
1499 deleteStr(s); 1499 deleteStr(s);
1500 } 1500 }
1501 1501
1502 // set the time zone 1502 // set the time zone
1503 if ((curVO = isAPropertyOf(vcal, VCTimeZoneProp)) != 0) { 1503 if ((curVO = isAPropertyOf(vcal, VCTimeZoneProp)) != 0) {
1504 char *s = fakeCString(vObjectUStringZValue(curVO)); 1504 char *s = fakeCString(vObjectUStringZValue(curVO));
1505 mCalendar->setTimeZone(s); 1505 mCalendar->setTimeZone(s);
1506 deleteStr(s); 1506 deleteStr(s);
1507 } 1507 }
1508 1508
1509 1509
1510 // Store all events with a relatedTo property in a list for post-processing 1510 // Store all events with a relatedTo property in a list for post-processing
1511 mEventsRelate.clear(); 1511 mEventsRelate.clear();
1512 mTodosRelate.clear(); 1512 mTodosRelate.clear();
1513 1513
1514 initPropIterator(&i, vcal); 1514 initPropIterator(&i, vcal);
1515 1515
1516 // go through all the vobjects in the vcal 1516 // go through all the vobjects in the vcal
1517 while (moreIteration(&i)) { 1517 while (moreIteration(&i)) {
1518 curVO = nextVObject(&i); 1518 curVO = nextVObject(&i);
1519 1519
1520 /************************************************************************/ 1520 /************************************************************************/
1521 1521
1522 // now, check to see that the object is an event or todo. 1522 // now, check to see that the object is an event or todo.
1523 if (strcmp(vObjectName(curVO), VCEventProp) == 0) { 1523 if (strcmp(vObjectName(curVO), VCEventProp) == 0) {
1524 1524
1525 if ((curVOProp = isAPropertyOf(curVO, KPilotStatusProp)) != 0) { 1525 if ((curVOProp = isAPropertyOf(curVO, XPilotStatusProp)) != 0) {
1526 char *s; 1526 char *s;
1527 s = fakeCString(vObjectUStringZValue(curVOProp)); 1527 s = fakeCString(vObjectUStringZValue(curVOProp));
1528 // check to see if event was deleted by the kpilot conduit 1528 // check to see if event was deleted by the kpilot conduit
1529 if (atoi(s) == Event::SYNCDEL) { 1529 if (atoi(s) == Event::SYNCDEL) {
1530 deleteStr(s); 1530 deleteStr(s);
1531 kdDebug(5800) << "skipping pilot-deleted event" << endl; 1531 kdDebug(5800) << "skipping pilot-deleted event" << endl;
1532 goto SKIP; 1532 goto SKIP;
1533 } 1533 }
1534 deleteStr(s); 1534 deleteStr(s);
1535 } 1535 }
1536 1536
1537 // this code checks to see if we are trying to read in an event 1537 // this code checks to see if we are trying to read in an event
1538 // that we already find to be in the calendar. If we find this 1538 // that we already find to be in the calendar. If we find this
1539 // to be the case, we skip the event. 1539 // to be the case, we skip the event.
1540 if ((curVOProp = isAPropertyOf(curVO, VCUniqueStringProp)) != 0) { 1540 if ((curVOProp = isAPropertyOf(curVO, VCUniqueStringProp)) != 0) {
1541 char *s = fakeCString(vObjectUStringZValue(curVOProp)); 1541 char *s = fakeCString(vObjectUStringZValue(curVOProp));
1542 QString tmpStr(s); 1542 QString tmpStr(s);
1543 deleteStr(s); 1543 deleteStr(s);
1544 1544
1545 if (mCalendar->event(tmpStr)) { 1545 if (mCalendar->event(tmpStr)) {
1546 goto SKIP; 1546 goto SKIP;
1547 } 1547 }
1548 if (mCalendar->todo(tmpStr)) { 1548 if (mCalendar->todo(tmpStr)) {
1549 goto SKIP; 1549 goto SKIP;
1550 } 1550 }
1551 } 1551 }
1552 1552
1553 if ((!(curVOProp = isAPropertyOf(curVO, VCDTstartProp))) && 1553 if ((!(curVOProp = isAPropertyOf(curVO, VCDTstartProp))) &&
1554 (!(curVOProp = isAPropertyOf(curVO, VCDTendProp)))) { 1554 (!(curVOProp = isAPropertyOf(curVO, VCDTendProp)))) {
1555 kdDebug(5800) << "found a VEvent with no DTSTART and no DTEND! Skipping..." << endl; 1555 kdDebug(5800) << "found a VEvent with no DTSTART and no DTEND! Skipping..." << endl;
1556 goto SKIP; 1556 goto SKIP;
1557 } 1557 }
1558 1558
1559 anEvent = VEventToEvent(curVO); 1559 anEvent = VEventToEvent(curVO);
1560 // we now use addEvent instead of insertEvent so that the 1560 // we now use addEvent instead of insertEvent so that the
1561 // signal/slot get connected. 1561 // signal/slot get connected.
1562 if (anEvent) { 1562 if (anEvent) {
1563 if ( !anEvent->dtStart().isValid() || !anEvent->dtEnd().isValid() ) { 1563 if ( !anEvent->dtStart().isValid() || !anEvent->dtEnd().isValid() ) {
1564 kdDebug() << "VCalFormat::populate(): Event has invalid dates." 1564 kdDebug() << "VCalFormat::populate(): Event has invalid dates."
1565 << endl; 1565 << endl;
1566 } else { 1566 } else {
1567 mCalendar->addEvent(anEvent); 1567 mCalendar->addEvent(anEvent);
1568 } 1568 }
1569 } else { 1569 } else {
1570 // some sort of error must have occurred while in translation. 1570 // some sort of error must have occurred while in translation.
1571 goto SKIP; 1571 goto SKIP;
1572 } 1572 }
1573 } else if (strcmp(vObjectName(curVO), VCTodoProp) == 0) { 1573 } else if (strcmp(vObjectName(curVO), VCTodoProp) == 0) {
1574 Todo *aTodo = VTodoToEvent(curVO); 1574 Todo *aTodo = VTodoToEvent(curVO);
1575 mCalendar->addTodo(aTodo); 1575 mCalendar->addTodo(aTodo);
1576 } else if ((strcmp(vObjectName(curVO), VCVersionProp) == 0) || 1576 } else if ((strcmp(vObjectName(curVO), VCVersionProp) == 0) ||
1577 (strcmp(vObjectName(curVO), VCProdIdProp) == 0) || 1577 (strcmp(vObjectName(curVO), VCProdIdProp) == 0) ||
1578 (strcmp(vObjectName(curVO), VCTimeZoneProp) == 0)) { 1578 (strcmp(vObjectName(curVO), VCTimeZoneProp) == 0)) {
1579 // do nothing, we know these properties and we want to skip them. 1579 // do nothing, we know these properties and we want to skip them.
1580 // we have either already processed them or are ignoring them. 1580 // we have either already processed them or are ignoring them.
1581 ; 1581 ;
1582 } else { 1582 } else {
1583 kdDebug(5800) << "Ignoring unknown vObject \"" << vObjectName(curVO) << "\"" << endl; 1583 kdDebug(5800) << "Ignoring unknown vObject \"" << vObjectName(curVO) << "\"" << endl;
1584 } 1584 }
1585 SKIP: 1585 SKIP:
1586 ; 1586 ;
1587 } // while 1587 } // while
1588 1588
1589 // Post-Process list of events with relations, put Event objects in relation 1589 // Post-Process list of events with relations, put Event objects in relation
1590 Event *ev; 1590 Event *ev;
1591 for ( ev=mEventsRelate.first(); ev != 0; ev=mEventsRelate.next() ) { 1591 for ( ev=mEventsRelate.first(); ev != 0; ev=mEventsRelate.next() ) {
1592 ev->setRelatedTo(mCalendar->event(ev->relatedToUid())); 1592 ev->setRelatedTo(mCalendar->event(ev->relatedToUid()));
1593 } 1593 }
1594 Todo *todo; 1594 Todo *todo;
1595 for ( todo=mTodosRelate.first(); todo != 0; todo=mTodosRelate.next() ) { 1595 for ( todo=mTodosRelate.first(); todo != 0; todo=mTodosRelate.next() ) {
1596 todo->setRelatedTo(mCalendar->todo(todo->relatedToUid())); 1596 todo->setRelatedTo(mCalendar->todo(todo->relatedToUid()));
1597 } 1597 }
1598} 1598}
1599 1599
1600const char *VCalFormat::dayFromNum(int day) 1600const char *VCalFormat::dayFromNum(int day)
1601{ 1601{
1602 const char *days[7] = { "MO ", "TU ", "WE ", "TH ", "FR ", "SA ", "SU " }; 1602 const char *days[7] = { "MO ", "TU ", "WE ", "TH ", "FR ", "SA ", "SU " };
1603 1603
1604 return days[day]; 1604 return days[day];
1605} 1605}
1606 1606
1607int VCalFormat::numFromDay(const QString &day) 1607int VCalFormat::numFromDay(const QString &day)
1608{ 1608{
1609 if (day == "MO ") return 0; 1609 if (day == "MO ") return 0;
1610 if (day == "TU ") return 1; 1610 if (day == "TU ") return 1;
1611 if (day == "WE ") return 2; 1611 if (day == "WE ") return 2;
1612 if (day == "TH ") return 3; 1612 if (day == "TH ") return 3;
1613 if (day == "FR ") return 4; 1613 if (day == "FR ") return 4;
1614 if (day == "SA ") return 5; 1614 if (day == "SA ") return 5;
1615 if (day == "SU ") return 6; 1615 if (day == "SU ") return 6;
1616 1616
1617 return -1; // something bad happened. :) 1617 return -1; // something bad happened. :)
1618} 1618}
1619 1619
1620Attendee::PartStat VCalFormat::readStatus(const char *s) const 1620Attendee::PartStat VCalFormat::readStatus(const char *s) const
1621{ 1621{
1622 QString statStr = s; 1622 QString statStr = s;
1623 statStr = statStr.upper(); 1623 statStr = statStr.upper();
1624 Attendee::PartStat status; 1624 Attendee::PartStat status;
1625 1625
1626 if (statStr == "X-ACTION") 1626 if (statStr == "X-ACTION")
1627 status = Attendee::NeedsAction; 1627 status = Attendee::NeedsAction;
1628 else if (statStr == "NEEDS ACTION") 1628 else if (statStr == "NEEDS ACTION")
1629 status = Attendee::NeedsAction; 1629 status = Attendee::NeedsAction;
1630 else if (statStr== "ACCEPTED") 1630 else if (statStr== "ACCEPTED")
1631 status = Attendee::Accepted; 1631 status = Attendee::Accepted;
1632 else if (statStr== "SENT") 1632 else if (statStr== "SENT")
1633 status = Attendee::NeedsAction; 1633 status = Attendee::NeedsAction;
1634 else if (statStr== "TENTATIVE") 1634 else if (statStr== "TENTATIVE")
1635 status = Attendee::Tentative; 1635 status = Attendee::Tentative;
1636 else if (statStr== "CONFIRMED") 1636 else if (statStr== "CONFIRMED")
1637 status = Attendee::Accepted; 1637 status = Attendee::Accepted;
1638 else if (statStr== "DECLINED") 1638 else if (statStr== "DECLINED")
1639 status = Attendee::Declined; 1639 status = Attendee::Declined;
1640 else if (statStr== "COMPLETED") 1640 else if (statStr== "COMPLETED")
1641 status = Attendee::Completed; 1641 status = Attendee::Completed;
1642 else if (statStr== "DELEGATED") 1642 else if (statStr== "DELEGATED")
1643 status = Attendee::Delegated; 1643 status = Attendee::Delegated;
1644 else { 1644 else {
1645 kdDebug(5800) << "error setting attendee mStatus, unknown mStatus!" << endl; 1645 kdDebug(5800) << "error setting attendee mStatus, unknown mStatus!" << endl;
1646 status = Attendee::NeedsAction; 1646 status = Attendee::NeedsAction;
1647 } 1647 }
1648 1648
1649 return status; 1649 return status;
1650} 1650}
1651 1651
1652QCString VCalFormat::writeStatus(Attendee::PartStat status) const 1652QCString VCalFormat::writeStatus(Attendee::PartStat status) const
1653{ 1653{
1654 switch(status) { 1654 switch(status) {
1655 default: 1655 default:
1656 case Attendee::NeedsAction: 1656 case Attendee::NeedsAction:
1657 return "NEEDS ACTION"; 1657 return "NEEDS ACTION";
1658 break; 1658 break;
1659 case Attendee::Accepted: 1659 case Attendee::Accepted:
1660 return "ACCEPTED"; 1660 return "ACCEPTED";
1661 break; 1661 break;
1662 case Attendee::Declined: 1662 case Attendee::Declined:
1663 return "DECLINED"; 1663 return "DECLINED";
1664 break; 1664 break;
1665 case Attendee::Tentative: 1665 case Attendee::Tentative:
1666 return "TENTATIVE"; 1666 return "TENTATIVE";
1667 break; 1667 break;
1668 case Attendee::Delegated: 1668 case Attendee::Delegated:
1669 return "DELEGATED"; 1669 return "DELEGATED";
1670 break; 1670 break;
1671 case Attendee::Completed: 1671 case Attendee::Completed:
1672 return "COMPLETED"; 1672 return "COMPLETED";
1673 break; 1673 break;
1674 case Attendee::InProcess: 1674 case Attendee::InProcess:
1675 return "NEEDS ACTION"; 1675 return "NEEDS ACTION";
1676 break; 1676 break;
1677 } 1677 }
1678} 1678}
diff --git a/libkcal/versit/port.h b/libkcal/versit/port.h
index afc16dd..1768bee 100644
--- a/libkcal/versit/port.h
+++ b/libkcal/versit/port.h
@@ -1,75 +1,88 @@
1/*************************************************************************** 1/***************************************************************************
2(C) Copyright 1996 Apple Computer, Inc., AT&T Corp., International 2(C) Copyright 1996 Apple Computer, Inc., AT&T Corp., International
3Business Machines Corporation and Siemens Rolm Communications Inc. 3Business Machines Corporation and Siemens Rolm Communications Inc.
4 4
5For purposes of this license notice, the term Licensors shall mean, 5For purposes of this license notice, the term Licensors shall mean,
6collectively, Apple Computer, Inc., AT&T Corp., International 6collectively, Apple Computer, Inc., AT&T Corp., International
7Business Machines Corporation and Siemens Rolm Communications Inc. 7Business Machines Corporation and Siemens Rolm Communications Inc.
8The term Licensor shall mean any of the Licensors. 8The term Licensor shall mean any of the Licensors.
9 9
10Subject to acceptance of the following conditions, permission is hereby 10Subject to acceptance of the following conditions, permission is hereby
11granted by Licensors without the need for written agreement and without 11granted by Licensors without the need for written agreement and without
12license or royalty fees, to use, copy, modify and distribute this 12license or royalty fees, to use, copy, modify and distribute this
13software for any purpose. 13software for any purpose.
14 14
15The above copyright notice and the following four paragraphs must be 15The above copyright notice and the following four paragraphs must be
16reproduced in all copies of this software and any software including 16reproduced in all copies of this software and any software including
17this software. 17this software.
18 18
19THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS AND NO LICENSOR SHALL HAVE 19THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS AND NO LICENSOR SHALL HAVE
20ANY OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR 20ANY OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR
21MODIFICATIONS. 21MODIFICATIONS.
22 22
23IN NO EVENT SHALL ANY LICENSOR BE LIABLE TO ANY PARTY FOR DIRECT, 23IN NO EVENT SHALL ANY LICENSOR BE LIABLE TO ANY PARTY FOR DIRECT,
24INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT 24INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT
25OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 25OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
26DAMAGE. 26DAMAGE.
27 27
28EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, 28EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED,
29INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE 29INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE
30IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 30IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31PURPOSE. 31PURPOSE.
32 32
33The software is provided with RESTRICTED RIGHTS. Use, duplication, or 33The software is provided with RESTRICTED RIGHTS. Use, duplication, or
34disclosure by the government are subject to restrictions set forth in 34disclosure by the government are subject to restrictions set forth in
35DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable. 35DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable.
36 36
37***************************************************************************/ 37***************************************************************************/
38 38
39#ifndef __PORT_H__ 39#ifndef __PORT_H__
40#define __PORT_H__ 1 40#define __PORT_H__ 1
41 41
42
42#if defined(__CPLUSPLUS__) || defined(__cplusplus) 43#if defined(__CPLUSPLUS__) || defined(__cplusplus)
43extern "C" { 44extern "C" {
44#endif 45#endif
45 46
46#define vCardClipboardFormat "+//ISBN 1-887687-00-9::versit::PDI//vCard" 47/* some of these #defines are commented out because */
47#define vCalendarClipboardFormat "+//ISBN 1-887687-00-9::versit::PDI//vCalendar" 48/* Visual C++ sets them on the compiler command line instead */
48 49
49/* The above strings vCardClipboardFormat and vCalendarClipboardFormat 50/* #define _DEBUG */
50are globally unique IDs which can be used to generate clipboard format 51/* #define WIN32 */
51ID's as per the requirements of a specific platform. For example, in 52/* #define WIN16 */
52Windows they are used as the parameter in a call to RegisterClipboardFormat. 53/* #define _WINDOWS */
54/* #define __MWERKS__ */
55/* #define INCLUDEMFC */
56
57 #define vCardClipboardFormat "+//ISBN 1-887687-00-9::versit::PDI//vCard"
58 #define vCalendarClipboardFormat"+//ISBN 1-887687-00-9::versit::PDI//vCalendar"
59
60/* The above strings vCardClipboardFormat and vCalendarClipboardFormat
61are globally unique IDs which can be used to generate clipboard format
62ID's as per the requirements of a specific platform. For example, in
63Windows they are used as the parameter in a call to RegisterClipboardFormat.
53For example: 64For example:
54 65
55 CLIPFORMAT foo = RegisterClipboardFormat(vCardClipboardFormat); 66 CLIPFORMAT foo = RegisterClipboardFormat(vCardClipboardFormat);
56 67
57*/ 68*/
58 69
59#define vCardMimeType "text/x-vCard" 70 #define vCardMimeType "text/x-vCard"
60#define vCalendarMimeType "text/x-vCalendar" 71 #define vCalendarMimeType"text/x-vCalendar"
72
73#define DLLEXPORT(t) t
61 74
62#ifndef FALSE 75#ifndef FALSE
63#define FALSE 0 76 #define FALSE0
64#endif 77#endif
65#ifndef TRUE 78#ifndef TRUE
66#define TRUE 1 79 #define TRUE1
67#endif 80#endif
68 81
69#define Parse_Debug(t) 82#define stricmp strcasecmp
70 83
71#if defined(__CPLUSPLUS__) || defined(__cplusplus) 84#if defined(__CPLUSPLUS__) || defined(__cplusplus)
72} 85}
73#endif 86#endif
74 87
75#endif /* __PORT_H__ */ 88#endif /* __PORT_H__ */
diff --git a/libkcal/versit/vcc.c b/libkcal/versit/vcc.c
index 350cac3..9be752d 100644
--- a/libkcal/versit/vcc.c
+++ b/libkcal/versit/vcc.c
@@ -1,2162 +1,2319 @@
1 1/* A Bison parser, made from vcc.y
2/* A Bison parser, made from ./vcc.y 2 by GNU bison 1.35. */
3 by GNU Bison version 1.28 */
4 3
5#define YYBISON 1 /* Identify Bison output. */ 4#define YYBISON 1 /* Identify Bison output. */
6 5
7#ifdef _WIN32_ 6 # define EQ257
8#define strcasecmp _stricmp 7 # define COLON258
9#endif 8 # define DOT259
10 9 # define SEMICOLON260
11 #define EQ257 10 # define SPACE261
12 #define COLON258 11 # define HTAB262
13 #define DOT259 12 # define LINESEP263
14 #define SEMICOLON260 13 # define NEWLINE264
15 #define SPACE261 14 # define BEGIN_VCARD265
16 #define HTAB262 15 # define END_VCARD266
17 #define LINESEP263 16 # define BEGIN_VCAL267
18 #define NEWLINE264 17 # define END_VCAL268
19 #define BEGIN_VCARD265 18 # define BEGIN_VEVENT269
20 #define END_VCARD266 19 # define END_VEVENT270
21 #define BEGIN_VCAL267 20 # define BEGIN_VTODO271
22 #define END_VCAL268 21 # define END_VTODO272
23 #define BEGIN_VEVENT269 22 # define ID273
24 #define END_VEVENT270 23 # define STRING274
25 #define BEGIN_VTODO271 24
26 #define END_VTODO272 25#line 1 "vcc.y"
27 #define ID273
28 #define STRING274
29
30#line 1 "./vcc.y"
31 26
32 27
33/*************************************************************************** 28/***************************************************************************
34(C) Copyright 1996 Apple Computer, Inc., AT&T Corp., International 29(C) Copyright 1996 Apple Computer, Inc., AT&T Corp., International
35Business Machines Corporation and Siemens Rolm Communications Inc. 30Business Machines Corporation and Siemens Rolm Communications Inc.
36 31
37For purposes of this license notice, the term Licensors shall mean, 32For purposes of this license notice, the term Licensors shall mean,
38collectively, Apple Computer, Inc., AT&T Corp., International 33collectively, Apple Computer, Inc., AT&T Corp., International
39Business Machines Corporation and Siemens Rolm Communications Inc. 34Business Machines Corporation and Siemens Rolm Communications Inc.
40The term Licensor shall mean any of the Licensors. 35The term Licensor shall mean any of the Licensors.
41 36
42Subject to acceptance of the following conditions, permission is hereby 37Subject to acceptance of the following conditions, permission is hereby
43granted by Licensors without the need for written agreement and without 38granted by Licensors without the need for written agreement and without
44license or royalty fees, to use, copy, modify and distribute this 39license or royalty fees, to use, copy, modify and distribute this
45software for any purpose. 40software for any purpose.
46 41
47The above copyright notice and the following four paragraphs must be 42The above copyright notice and the following four paragraphs must be
48reproduced in all copies of this software and any software including 43reproduced in all copies of this software and any software including
49this software. 44this software.
50 45
51THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS AND NO LICENSOR SHALL HAVE 46THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS AND NO LICENSOR SHALL HAVE
52ANY OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR 47ANY OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR
53MODIFICATIONS. 48MODIFICATIONS.
54 49
55IN NO EVENT SHALL ANY LICENSOR BE LIABLE TO ANY PARTY FOR DIRECT, 50IN NO EVENT SHALL ANY LICENSOR BE LIABLE TO ANY PARTY FOR DIRECT,
56INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT 51INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT
57OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 52OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
58DAMAGE. 53DAMAGE.
59 54
60EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, 55EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED,
61INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE 56INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE
62IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 57IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
63PURPOSE. 58PURPOSE.
64 59
65The software is provided with RESTRICTED RIGHTS. Use, duplication, or 60The software is provided with RESTRICTED RIGHTS. Use, duplication, or
66disclosure by the government are subject to restrictions set forth in 61disclosure by the government are subject to restrictions set forth in
67DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable. 62DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable.
68 63
69***************************************************************************/ 64***************************************************************************/
70 65
71/* 66/*
72 * src: vcc.c 67 * src: vcc.c
73 * doc: Parser for vCard and vCalendar. Note that this code is 68 * doc: Parser for vCard and vCalendar. Note that this code is
74 * generated by a yacc parser generator. Generally it should not 69 * generated by a yacc parser generator. Generally it should not
75 * be edited by hand. The real source is vcc.y. The #line directives 70 * be edited by hand. The real source is vcc.y. The #line directives
76 * can be commented out here to make it easier to trace through 71 * can be commented out here to make it easier to trace through
77 * in a debugger. However, if a bug is found it should 72 * in a debugger. However, if a bug is found it should
78 * be fixed in vcc.y and this file regenerated. 73 * be fixed in vcc.y and this file regenerated.
79 */ 74 */
80 75
81 76
82/* debugging utilities */ 77/* debugging utilities */
83#if __DEBUG 78#if __DEBUG
84#define DBG_(x) printf x 79#define DBG_(x) printf x
85#else 80#else
86#define DBG_(x) 81#define DBG_(x)
87#endif 82#endif
88 83
84#ifdef WIN32
85#define snprintf _snprintf
86#define strcasecmp stricmp
87#endif
88
89/**** External Functions ****/ 89/**** External Functions ****/
90 90
91/* assign local name to parser variables and functions so that 91/* assign local name to parser variables and functions so that
92 we can use more than one yacc based parser. 92 we can use more than one yacc based parser.
93*/ 93*/
94 94
95#define yyparse mime_parse 95#define yyparse mime_parse
96#define yylex mime_lex 96#define yylex mime_lex
97#define yyerror mime_error 97#define yyerror mime_error
98#define yychar mime_char 98#define yychar mime_char
99/* #define p_yyval p_mime_val */ 99/* #define p_yyval p_mime_val */
100#undef yyval 100#undef yyval
101#define yyval mime_yyval 101#define yyval mime_yyval
102/* #define p_yylval p_mime_lval */ 102/* #define p_yylval p_mime_lval */
103#undef yylval 103#undef yylval
104#define yylval mime_yylval 104#define yylval mime_yylval
105#define yydebug mime_debug 105#define yydebug mime_debug
106#define yynerrs mime_nerrs 106#define yynerrs mime_nerrs
107#define yyerrflag mime_errflag 107#define yyerrflag mime_errflag
108#define yyss mime_ss 108#define yyss mime_ss
109#define yyssp mime_ssp 109#define yyssp mime_ssp
110#define yyvs mime_vs 110#define yyvs mime_vs
111#define yyvsp mime_vsp 111#define yyvsp mime_vsp
112#define yylhs mime_lhs 112#define yylhs mime_lhs
113#define yylen mime_len 113#define yylen mime_len
114#define yydefred mime_defred 114#define yydefred mime_defred
115#define yydgoto mime_dgoto 115#define yydgoto mime_dgoto
116#define yysindex mime_sindex 116#define yysindex mime_sindex
117#define yyrindex mime_rindex 117#define yyrindex mime_rindex
118#define yygindex mime_gindex 118#define yygindex mime_gindex
119#define yytable mime_table 119#define yytable mime_table
120#define yycheck mime_check 120#define yycheck mime_check
121#define yyname mime_name 121#define yyname mime_name
122#define yyrule mime_rule 122#define yyrule mime_rule
123#undef YYPREFIX
124#define YYPREFIX "mime_" 123#define YYPREFIX "mime_"
125 124
126 125
127#ifndef _NO_LINE_FOLDING 126#ifndef _NO_LINE_FOLDING
128#define _SUPPORT_LINE_FOLDING 1 127#define _SUPPORT_LINE_FOLDING 1
129#endif 128#endif
130 129
131#include <string.h> 130/* undef below if compile with MFC */
132#ifndef __FreeBSD__ 131/* #define INCLUDEMFC 1 */
133#include <malloc.h> 132
133#if defined(WIN32) || defined(_WIN32)
134#ifdef INCLUDEMFC
135#include <afx.h>
134#endif 136#endif
137#endif
138
139#include <string.h>
135#include <stdio.h> 140#include <stdio.h>
136#include <stdlib.h> 141#include <stdlib.h>
137#include <ctype.h> 142#include <ctype.h>
138#include "vcc.h" 143#include "vcc.h"
139 144
140/* The following is a hack that I hope will get things compiling
141 * on SunOS 4.1.x systems
142 */
143#ifndef SEEK_SET
144#define SEEK_SET 0 /* Seek from beginning of file. */
145#define SEEK_CUR 1 /* Seek from current position. */
146#define SEEK_END 2 /* Seek from end of file. */
147#endif
148
149/**** Types, Constants ****/ 145/**** Types, Constants ****/
150 146
151 #define YYDEBUG 0/* 1 to compile in some debugging code */ 147 #define YYDEBUG 1/* 1 to compile in some debugging code */
152 #define MAXTOKEN 256/* maximum token (line) length */ 148 #define MAXTOKEN 256/* maximum token (line) length */
153 #define YYSTACKSIZE 1000/* ~unref ? */ 149 #define YYSTACKSIZE 50/* ~unref ? */
154 #define MAXLEVEL 10/* max # of nested objects parseable */ 150 #define MAXLEVEL 10/* max # of nested objects parseable */
155 /* (includes outermost) */ 151 /* (includes outermost) */
156 152
157 153
158/**** Global Variables ****/ 154/**** Global Variables ****/
159int mime_lineNum, mime_numErrors; /* yyerror() can use these */ 155int mime_lineNum, mime_numErrors; /* yyerror() can use these */
160static VObject* vObjList; 156static VObject* vObjList;
161static VObject *curProp; 157static VObject *curProp;
162static VObject *curObj; 158static VObject *curObj;
163static VObject* ObjStack[MAXLEVEL]; 159static VObject* ObjStack[MAXLEVEL];
164static int ObjStackTop; 160static int ObjStackTop;
165 161
166 162
167/* A helpful utility for the rest of the app. */ 163/* A helpful utility for the rest of the app. */
168#if __CPLUSPLUS__ 164#if __CPLUSPLUS__
169extern "C" { 165extern "C" {
170#endif 166#endif
171 167
172 /* static void Parse_Debug(const char *s);*/ 168 extern void Parse_Debug(const char *s);
173 static void yyerror(char *s); 169 static void yyerror(char *s);
174 170
175#if __CPLUSPLUS__ 171#if __CPLUSPLUS__
176 }; 172 };
177#endif 173#endif
178 174
179int yyparse(); 175int yyparse();
180static int yylex(); 176
181enum LexMode { 177enum LexMode {
182 L_NORMAL, 178 L_NORMAL,
183 L_VCARD, 179 L_VCARD,
184 L_VCAL, 180 L_VCAL,
185 L_VEVENT, 181 L_VEVENT,
186 L_VTODO, 182 L_VTODO,
187 L_VALUES, 183 L_VALUES,
188 L_BASE64, 184 L_BASE64,
189 L_QUOTED_PRINTABLE 185 L_QUOTED_PRINTABLE
190 }; 186 };
191 187
192/**** Private Forward Declarations ****/ 188/**** Private Forward Declarations ****/
193static int pushVObject(const char *prop); 189static int pushVObject(const char *prop);
194static VObject* popVObject(); 190static VObject* popVObject();
195char* lexDataFromBase64();
196static void lexPopMode(int top); 191static void lexPopMode(int top);
197static int lexWithinMode(enum LexMode mode); 192static int lexWithinMode(enum LexMode mode);
198static void lexPushMode(enum LexMode mode); 193static void lexPushMode(enum LexMode mode);
199static void enterProps(const char *s); 194static void enterProps(const char *s);
200static void enterAttr(const char *s1, const char *s2); 195static void enterAttr(const char *s1, const char *s2);
201/* static void enterValues(const char *value); */ 196static void enterValues(const char *value);
202static void appendValue(const char *value);
203static void mime_error_(char *s); 197static void mime_error_(char *s);
204 198
205 199
206#line 181 "./vcc.y" 200#line 180 "vcc.y"
201#ifndef YYSTYPE
207typedef union { 202typedef union {
208 char *str; 203 char *str;
209 VObject *vobj; 204 VObject *vobj;
210 } YYSTYPE; 205 } yystype;
211#include <stdio.h> 206# define YYSTYPE yystype
212 207# define YYSTYPE_IS_TRIVIAL 1
213#ifndef __cplusplus
214#ifndef __STDC__
215#define const
216#endif 208#endif
209#ifndef YYDEBUG
210# define YYDEBUG 0
217#endif 211#endif
218 212
219 213
220 214
221 #define YYFINAL 62 215 #define YYFINAL 62
222 #define YYFLAG -32768 216 #define YYFLAG -32768
223 #define YYNTBASE21 217 #define YYNTBASE21
224 218
219/* YYTRANSLATE(YYLEX) -- Bison token number corresponding to YYLEX. */
225#define YYTRANSLATE(x) ((unsigned)(x) <= 274 ? yytranslate[x] : 51) 220#define YYTRANSLATE(x) ((unsigned)(x) <= 274 ? yytranslate[x] : 51)
226 221
227static const char yytranslate[] = { 0, 222/* YYTRANSLATE[YYLEX] -- Bison token number corresponding to YYLEX. */
228 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 223static const char yytranslate[] =
229 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 224{
230 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 225 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
231 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 226 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
232 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 227 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
233 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 228 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
234 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 229 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
235 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 230 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
236 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 231 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
237 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 232 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
238 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 233 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
239 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 234 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
240 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 235 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
241 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 236 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
242 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 237 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
243 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 238 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
244 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 239 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
245 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 240 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
246 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 241 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
247 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 242 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
248 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 243 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
249 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 244 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
250 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 245 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
251 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 246 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
252 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 247 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
253 2, 2, 2, 2, 2, 1, 3, 4, 5, 6, 248 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
254 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 249 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
255 17, 18, 19, 20 250 2, 2, 2, 2, 2, 2, 1, 3, 4, 5,
251 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
252 16, 17, 18, 19, 20
256}; 253};
257 254
258#if YYDEBUG != 0 255#if YYDEBUG
259static const short yyprhs[] = { 0, 256static const short yyprhs[] =
260 0, 2, 3, 7, 9, 11, 13, 14, 19, 20, 257{
261 24, 27, 29, 30, 36, 38, 39, 43, 45, 48, 258 0, 0, 2, 3, 7, 9, 11, 13, 14, 19,
262 50, 53, 55, 59, 61, 62, 67, 69, 71, 72, 259 20, 24, 27, 29, 30, 36, 38, 39, 43, 45,
263 73, 78, 79, 83, 86, 88, 90, 92, 94, 95, 260 48, 50, 53, 55, 59, 61, 62, 67, 69, 71,
264 100, 101, 105, 106, 111, 112 261 72, 73, 78, 79, 83, 86, 88, 90, 92, 94,
262 95, 100, 101, 105, 106, 111, 112
265}; 263};
266 264static const short yyrhs[] =
267static const short yyrhs[] = { 22, 265{
268 0, 0, 24, 23, 22, 0, 24, 0, 25, 0, 266 22, 0, 0, 24, 23, 22, 0, 24, 0, 25,
269 40, 0, 0, 11, 26, 28, 12, 0, 0, 11, 267 0, 40, 0, 0, 11, 26, 28, 12, 0, 0,
270 27, 12, 0, 29, 28, 0, 29, 0, 0, 31, 268 11, 27, 12, 0, 29, 28, 0, 29, 0, 0,
271 4, 30, 37, 9, 0, 1, 0, 0, 36, 32, 269 31, 4, 30, 37, 9, 0, 1, 0, 0, 36,
272 33, 0, 36, 0, 34, 33, 0, 34, 0, 6, 270 32, 33, 0, 36, 0, 34, 33, 0, 34, 0,
273 35, 0, 36, 0, 36, 3, 36, 0, 19, 0, 271 6, 35, 0, 36, 0, 36, 3, 36, 0, 19,
274 0, 39, 6, 38, 37, 0, 39, 0, 20, 0, 272 0, 0, 39, 6, 38, 37, 0, 39, 0, 20,
275 0, 0, 13, 41, 43, 14, 0, 0, 13, 42, 273 0, 0, 0, 13, 41, 43, 14, 0, 0, 13,
276 14, 0, 44, 43, 0, 44, 0, 45, 0, 48, 274 42, 14, 0, 44, 43, 0, 44, 0, 45, 0,
277 0, 28, 0, 0, 15, 46, 28, 16, 0, 0, 275 48, 0, 28, 0, 0, 15, 46, 28, 16, 0,
278 15, 47, 16, 0, 0, 17, 49, 28, 18, 0, 276 0, 15, 47, 16, 0, 0, 17, 49, 28, 18,
279 0, 17, 50, 18, 0 277 0, 0, 17, 50, 18, 0
280}; 278};
281 279
282#endif 280#endif
283 281
284#if YYDEBUG != 0 282#if YYDEBUG
285static const short yyrline[] = { 0, 283/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
286 209, 212, 215, 215, 219, 220, 223, 229, 234, 240, 284static const short yyrline[] =
287 246, 247, 250, 254, 260, 263, 268, 268, 274, 275, 285{
288 278, 281, 285, 292, 295, 296, 296, 300, 301, 305, 286 0, 208, 211, 211, 214, 218, 219, 222, 222, 233,
289 309, 311, 314, 317, 318, 321, 323, 324, 327, 334, 287 233, 245, 246, 249, 249, 259, 262, 262, 267, 273,
290 339, 345, 351, 358, 363, 369 288 274, 277, 280, 284, 291, 294, 294, 295, 299, 300,
289 303, 303, 309, 309, 315, 316, 319, 321, 322, 325,
290 325, 337, 337, 349, 349, 361, 361
291}; 291};
292#endif 292#endif
293 293
294 294
295#if YYDEBUG != 0 || defined (YYERROR_VERBOSE) 295#if (YYDEBUG) || defined YYERROR_VERBOSE
296 296
297static const char * const yytname[] = { "$","error","$undefined.","EQ","COLON", 297/* YYTNAME[TOKEN_NUM] -- String name of the token TOKEN_NUM. */
298"DOT","SEMICOLON","SPACE","HTAB","LINESEP","NEWLINE","BEGIN_VCARD","END_VCARD", 298static const char *const yytname[] =
299"BEGIN_VCAL","END_VCAL","BEGIN_VEVENT","END_VEVENT","BEGIN_VTODO","END_VTODO", 299{
300"ID","STRING","mime","vobjects","@1","vobject","vcard","@2","@3","items","item", 300 "$", "error", "$undefined.", "EQ", "COLON", "DOT", "SEMICOLON", "SPACE",
301"@4","prop","@5","attr_params","attr_param","attr","name","values","@6","value", 301 "HTAB", "LINESEP", "NEWLINE", "BEGIN_VCARD", "END_VCARD", "BEGIN_VCAL",
302"vcal","@7","@8","calitems","calitem","eventitem","@9","@10","todoitem","@11", 302 "END_VCAL", "BEGIN_VEVENT", "END_VEVENT", "BEGIN_VTODO", "END_VTODO",
303"@12", NULL 303 "ID", "STRING", "mime", "vobjects", "@1", "vobject", "vcard", "@2",
304 "@3", "items", "item", "@4", "prop", "@5", "attr_params", "attr_param",
305 "attr", "name", "values", "@6", "value", "vcal", "@7", "@8", "calitems",
306 "calitem", "eventitem", "@9", "@10", "todoitem", "@11", "@12", 0
304}; 307};
305#endif 308#endif
306 309
307static const short yyr1[] = { 0, 310/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
308 21, 23, 22, 22, 24, 24, 26, 25, 27, 25, 311static const short yyr1[] =
309 28, 28, 30, 29, 29, 32, 31, 31, 33, 33, 312{
310 34, 35, 35, 36, 38, 37, 37, 39, 39, 41, 313 0, 21, 23, 22, 22, 24, 24, 26, 25, 27,
311 40, 42, 40, 43, 43, 44, 44, 44, 46, 45, 314 25, 28, 28, 30, 29, 29, 32, 31, 31, 33,
312 47, 45, 49, 48, 50, 48 315 33, 34, 35, 35, 36, 38, 37, 37, 39, 39,
316 41, 40, 42, 40, 43, 43, 44, 44, 44, 46,
317 45, 47, 45, 49, 48, 50, 48
313}; 318};
314 319
315static const short yyr2[] = { 0, 320/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
316 1, 0, 3, 1, 1, 1, 0, 4, 0, 3, 321static const short yyr2[] =
317 2, 1, 0, 5, 1, 0, 3, 1, 2, 1, 322{
318 2, 1, 3, 1, 0, 4, 1, 1, 0, 0, 323 0, 1, 0, 3, 1, 1, 1, 0, 4, 0,
319 4, 0, 3, 2, 1, 1, 1, 1, 0, 4, 324 3, 2, 1, 0, 5, 1, 0, 3, 1, 2,
320 0, 3, 0, 4, 0, 3 325 1, 2, 1, 3, 1, 0, 4, 1, 1, 0,
326 0, 4, 0, 3, 2, 1, 1, 1, 1, 0,
327 4, 0, 3, 0, 4, 0, 3
321}; 328};
322 329
323static const short yydefact[] = { 0, 330/* YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE
324 7, 30, 1, 2, 5, 6, 0, 0, 0, 0, 331 doesn't specify something else to do. Zero means the default is an
325 0, 15, 24, 0, 0, 0, 16, 10, 39, 43, 332 error. */
326 38, 0, 0, 36, 37, 33, 3, 8, 11, 13, 333static const short yydefact[] =
327 0, 0, 0, 0, 0, 31, 34, 29, 0, 17, 334{
328 20, 0, 42, 0, 46, 28, 0, 27, 21, 22, 335 0, 7, 30, 1, 2, 5, 6, 0, 0, 0,
329 19, 40, 44, 14, 25, 0, 29, 23, 26, 0, 336 0, 0, 15, 24, 0, 0, 0, 16, 10, 39,
330 0, 0 337 43, 38, 0, 0, 36, 37, 33, 3, 8, 11,
338 13, 0, 0, 0, 0, 0, 31, 34, 29, 0,
339 17, 20, 0, 42, 0, 46, 28, 0, 27, 21,
340 22, 19, 40, 44, 14, 25, 0, 29, 23, 26,
341 0, 0, 0
331}; 342};
332 343
333static const short yydefgoto[] = { 60, 344static const short yydefgoto[] =
334 3, 11, 4, 5, 7, 8, 21, 15, 38, 16, 345{
335 31, 40, 41, 49, 17, 47, 57, 48, 6, 9, 346 60, 3, 11, 4, 5, 7, 8, 21, 15, 38,
336 10, 22, 23, 24, 32, 33, 25, 34, 35 347 16, 31, 40, 41, 49, 17, 47, 57, 48, 6,
348 9, 10, 22, 23, 24, 32, 33, 25, 34, 35
337}; 349};
338 350
339static const short yypact[] = { -9, 351static const short yypact[] =
340 -6, -5,-32768, 7,-32768,-32768, 2, -1, 19, 15, 352{
341 -9,-32768,-32768, 1, 0, 26, 27,-32768, 16, 17, 353 -9, -6, -5,-32768, 7,-32768,-32768, 2, -1, 19,
342-32768, 23, 9,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 354 15, -9,-32768,-32768, 1, 0, 26, 27,-32768, 16,
343 33, 2, 24, 2, 25,-32768,-32768, 13, 22,-32768, 355 17,-32768, 23, 9,-32768,-32768,-32768,-32768,-32768,-32768,
344 33, 28,-32768, 29,-32768,-32768, 36, 40,-32768, 39, 356 -32768, 33, 2, 24, 2, 25,-32768,-32768, 13, 22,
345-32768,-32768,-32768,-32768,-32768, 22, 13,-32768,-32768, 48, 357 -32768, 33, 28,-32768, 29,-32768,-32768, 36, 40,-32768,
346 49,-32768 358 39,-32768,-32768,-32768,-32768,-32768, 22, 13,-32768,-32768,
359 48, 49,-32768
347}; 360};
348 361
349static const short yypgoto[] = {-32768, 362static const short yypgoto[] =
350 41,-32768,-32768,-32768,-32768,-32768, -7,-32768,-32768,-32768, 363{
351-32768, 10,-32768,-32768, -34, -4,-32768,-32768,-32768,-32768, 364 -32768, 41,-32768,-32768,-32768,-32768,-32768, -7,-32768,-32768,
352-32768, 31,-32768,-32768,-32768,-32768,-32768,-32768,-32768 365 -32768,-32768, 10,-32768,-32768, -34, -4,-32768,-32768,-32768,
366 -32768,-32768, 31,-32768,-32768,-32768,-32768,-32768,-32768,-32768
353}; 367};
354 368
355 369
356 #define YYLAST 54 370 #define YYLAST 54
357 371
358 372
359static const short yytable[] = { 14, 373static const short yytable[] =
360 12, 1, 12, 2, 50, -9, -4, 29, -32, 12, 374{
361 18, -12, 28, -12, -12, -12, -12, -12, 13, 12, 375 14, 12, 1, 12, 2, 50, -9, -4, 29, -32,
362 13, 58, -35, 19, 42, 20, 44, 13, 26, 30, 376 12, 18, -12, 28, -12, -12, -12, -12, -12, 13,
363 -18, -41, 46, 19, -45, 20, 36, 13, 39, 43, 377 12, 13, 58, -35, 19, 42, 20, 44, 13, 26,
364 13, 56, 45, 52, 54, 55, 53, 61, 62, 0, 378 30, -18, -41, 46, 19, -45, 20, 36, 13, 39,
365 51, 27, 59, 37 379 43, 13, 56, 45, 52, 54, 55, 53, 61, 62,
380 0, 51, 27, 59, 37
366}; 381};
367 382
368static const short yycheck[] = { 7, 383static const short yycheck[] =
369 1, 11, 1, 13, 39, 12, 0, 15, 14, 1, 384{
370 12, 12, 12, 14, 15, 16, 17, 18, 19, 1, 385 7, 1, 11, 1, 13, 39, 12, 0, 15, 14,
371 19, 56, 14, 15, 32, 17, 34, 19, 14, 4, 386 1, 12, 12, 12, 14, 15, 16, 17, 18, 19,
372 4, 16, 20, 15, 18, 17, 14, 19, 6, 16, 387 1, 19, 56, 14, 15, 32, 17, 34, 19, 14,
373 19, 3, 18, 16, 9, 6, 18, 0, 0, -1, 388 4, 4, 16, 20, 15, 18, 17, 14, 19, 6,
374 41, 11, 57, 23 389 16, 19, 3, 18, 16, 9, 6, 18, 0, 0,
390 -1, 41, 11, 57, 23
375}; 391};
376/* -*-C-*- Note some compilers choke on comments on `#line' lines. */ 392/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
377#line 3 "/usr/share/bison.simple" 393#line 3 "/usr/share/bison/bison.simple"
378/* This file comes from bison-1.28. */
379 394
380/* Skeleton output parser for bison, 395/* Skeleton output parser for bison,
381 Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc. 396
397 Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software
398 Foundation, Inc.
382 399
383 This program is free software; you can redistribute it and/or modify 400 This program is free software; you can redistribute it and/or modify
384 it under the terms of the GNU General Public License as published by 401 it under the terms of the GNU General Public License as published by
385 the Free Software Foundation; either version 2, or (at your option) 402 the Free Software Foundation; either version 2, or (at your option)
386 any later version. 403 any later version.
387 404
388 This program is distributed in the hope that it will be useful, 405 This program is distributed in the hope that it will be useful,
389 but WITHOUT ANY WARRANTY; without even the implied warranty of 406 but WITHOUT ANY WARRANTY; without even the implied warranty of
390 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 407 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
391 GNU General Public License for more details. 408 GNU General Public License for more details.
392 409
393 You should have received a copy of the GNU General Public License 410 You should have received a copy of the GNU General Public License
394 along with this program; if not, write to the Free Software 411 along with this program; if not, write to the Free Software
395 Foundation, Inc., 59 Temple Place - Suite 330, 412 Foundation, Inc., 59 Temple Place - Suite 330,
396 Boston, MA 02111-1307, USA. */ 413 Boston, MA 02111-1307, USA. */
397 414
398/* As a special exception, when this file is copied by Bison into a 415/* As a special exception, when this file is copied by Bison into a
399 Bison output file, you may use that output file without restriction. 416 Bison output file, you may use that output file without restriction.
400 This special exception was added by the Free Software Foundation 417 This special exception was added by the Free Software Foundation
401 in version 1.24 of Bison. */ 418 in version 1.24 of Bison. */
402 419
403/* This is the parser code that is written into each bison parser 420/* This is the parser code that is written into each bison parser when
404 when the %semantic_parser declaration is not specified in the grammar. 421 the %semantic_parser declaration is not specified in the grammar.
405 It was written by Richard Stallman by simplifying the hairy parser 422 It was written by Richard Stallman by simplifying the hairy parser
406 used when %semantic_parser is specified. */ 423 used when %semantic_parser is specified. */
424
425/* All symbols defined below should begin with yy or YY, to avoid
426 infringing on user name space. This should be done even for local
427 variables, as they might otherwise be expanded by user macros.
428 There are some unavoidable exceptions within include files to
429 define necessary library symbols; they are noted "INFRINGES ON
430 USER NAME SPACE" below. */
431
432#if ! defined (yyoverflow) || defined (YYERROR_VERBOSE)
433
434/* The parser invokes alloca or malloc; define the necessary symbols. */
435
436# if YYSTACK_USE_ALLOCA
437# define YYSTACK_ALLOC alloca
438# else
439# ifndef YYSTACK_USE_ALLOCA
440# if defined (alloca) || defined (_ALLOCA_H)
441# define YYSTACK_ALLOC alloca
442# else
443# ifdef __GNUC__
444# define YYSTACK_ALLOC __builtin_alloca
445# endif
446# endif
447# endif
448# endif
449
450# ifdef YYSTACK_ALLOC
451 /* Pacify GCC's `empty if-body' warning. */
452# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
453# else
454# if defined (__STDC__) || defined (__cplusplus)
455# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
456# define YYSIZE_T size_t
457# endif
458# define YYSTACK_ALLOC malloc
459# define YYSTACK_FREE free
460# endif
461#endif /* ! defined (yyoverflow) || defined (YYERROR_VERBOSE) */
462
463
464#if (! defined (yyoverflow) \
465 && (! defined (__cplusplus) \
466 || (YYLTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
467
468/* A type that is properly aligned for any stack member. */
469union yyalloc
470{
471 short yyss;
472 YYSTYPE yyvs;
473# if YYLSP_NEEDED
474 YYLTYPE yyls;
475# endif
476};
477
478/* The size of the maximum gap between one aligned stack and the next. */
479# define YYSTACK_GAP_MAX (sizeof (union yyalloc) - 1)
480
481/* The size of an array large to enough to hold all stacks, each with
482 N elements. */
483# if YYLSP_NEEDED
484# define YYSTACK_BYTES(N) \
485 ((N) * (sizeof (short) + sizeof (YYSTYPE) + sizeof (YYLTYPE))\
486 + 2 * YYSTACK_GAP_MAX)
487# else
488# define YYSTACK_BYTES(N) \
489 ((N) * (sizeof (short) + sizeof (YYSTYPE)) \
490 + YYSTACK_GAP_MAX)
491# endif
492
493/* Copy COUNT objects from FROM to TO. The source and destination do
494 not overlap. */
495# ifndef YYCOPY
496# if 1 < __GNUC__
497# define YYCOPY(To, From, Count) \
498 __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
499# else
500 # define YYCOPY(To, From, Count) \
501 do \
502 { \
503 register YYSIZE_T yyi; \
504 for (yyi = 0; yyi < (Count); yyi++)\
505 (To)[yyi] = (From)[yyi]; \
506 } \
507 while (0)
508# endif
509# endif
510
511/* Relocate STACK from its old location to the new one. The
512 local variables YYSIZE and YYSTACKSIZE give the old and new number of
513 elements in the stack, and YYPTR gives the new location of the
514 stack. Advance YYPTR to a properly aligned location for the next
515 stack. */
516 # define YYSTACK_RELOCATE(Stack) \
517 do \
518 { \
519 YYSIZE_T yynewbytes; \
520 YYCOPY (&yyptr->Stack, Stack, yysize); \
521 Stack = &yyptr->Stack; \
522 yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAX;\
523 yyptr += yynewbytes / sizeof (*yyptr); \
524 } \
525 while (0)
407 526
408#ifndef YYSTACK_USE_ALLOCA
409#ifdef alloca
410#define YYSTACK_USE_ALLOCA
411#else /* alloca not defined */
412#ifdef __GNUC__
413#define YYSTACK_USE_ALLOCA
414#define alloca __builtin_alloca
415#else /* not GNU C. */
416#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) || (defined (__sun) && defined (__i386))
417#define YYSTACK_USE_ALLOCA
418#include <alloca.h>
419#else /* not sparc */
420/* We think this test detects Watcom and Microsoft C. */
421/* This used to test MSDOS, but that is a bad idea
422 since that symbol is in the user namespace. */
423#if (defined (_MSDOS) || defined (_MSDOS_)) && !defined (__TURBOC__)
424#if 0 /* No need for malloc.h, which pollutes the namespace;
425 instead, just don't use alloca. */
426#include <malloc.h>
427#endif 527#endif
428#else /* not MSDOS, or __TURBOC__ */ 528
429#if defined(_AIX) 529
430/* I don't know what this was needed for, but it pollutes the namespace. 530#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
431 So I turned it off. rms, 2 May 1997. */ 531# define YYSIZE_T __SIZE_TYPE__
432/* #include <malloc.h> */
433 #pragma alloca
434#define YYSTACK_USE_ALLOCA
435#else /* not MSDOS, or __TURBOC__, or _AIX */
436#if 0
437#ifdef __hpux /* haible@ilog.fr says this works for HPUX 9.05 and up,
438 and on HPUX 10. Eventually we can turn this on. */
439#define YYSTACK_USE_ALLOCA
440#define alloca __builtin_alloca
441#endif /* __hpux */
442#endif 532#endif
443#endif /* not _AIX */ 533#if ! defined (YYSIZE_T) && defined (size_t)
444#endif /* not MSDOS, or __TURBOC__ */ 534# define YYSIZE_T size_t
445#endif /* not sparc */ 535#endif
446#endif /* not GNU C */ 536#if ! defined (YYSIZE_T)
447#endif /* alloca not defined */ 537# if defined (__STDC__) || defined (__cplusplus)
448#endif /* YYSTACK_USE_ALLOCA not defined */ 538# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
449 539# define YYSIZE_T size_t
450#ifdef YYSTACK_USE_ALLOCA 540# endif
451#define YYSTACK_ALLOC alloca 541#endif
452#else 542#if ! defined (YYSIZE_T)
453#define YYSTACK_ALLOC malloc 543# define YYSIZE_T unsigned int
454#endif 544#endif
455
456/* Note: there must be only one dollar sign in this file.
457 It is replaced by the list of actions, each action
458 as one case of the switch. */
459 545
460 #define yyerrok (yyerrstatus = 0) 546 #define yyerrok (yyerrstatus = 0)
461 #define yyclearin(yychar = YYEMPTY) 547 #define yyclearin(yychar = YYEMPTY)
462 #define YYEMPTY -2 548 #define YYEMPTY -2
463 #define YYEOF 0 549 #define YYEOF 0
464 #define YYACCEPTgoto yyacceptlab 550 #define YYACCEPTgoto yyacceptlab
465 #define YYABORT goto yyabortlab 551 #define YYABORT goto yyabortlab
466 #define YYERROR goto yyerrlab1 552 #define YYERROR goto yyerrlab1
467/* Like YYERROR except do call yyerror. 553/* Like YYERROR except do call yyerror. This remains here temporarily
468 This remains here temporarily to ease the 554 to ease the transition to the new meaning of YYERROR, for GCC.
469 transition to the new meaning of YYERROR, for GCC.
470 Once GCC version 2 has supplanted version 1, this can go. */ 555 Once GCC version 2 has supplanted version 1, this can go. */
471 #define YYFAIL goto yyerrlab 556 #define YYFAIL goto yyerrlab
472#define YYRECOVERING() (!!yyerrstatus) 557#define YYRECOVERING() (!!yyerrstatus)
473#define YYBACKUP(token, value) \ 558 #define YYBACKUP(Token, Value) \
474 do \ 559 do \
475 if (yychar == YYEMPTY && yylen == 1) \ 560 if (yychar == YYEMPTY && yylen == 1) \
476 { yychar = (token), yylval = (value); \ 561 { \
562 yychar = (Token); \
563 yylval = (Value); \
477 yychar1 = YYTRANSLATE (yychar); \ 564 yychar1 = YYTRANSLATE (yychar); \
478 YYPOPSTACK; \ 565 YYPOPSTACK; \
479 goto yybackup; \ 566 goto yybackup; \
480 } \ 567 } \
481 else \ 568 else \
482 { yyerror ("syntax error: cannot back up"); YYERROR; }\ 569 { \
570 yyerror ("syntax error: cannot back up"); \
571 YYERROR; \
572 } \
483while (0) 573while (0)
484 574
485 #define YYTERROR1 575 #define YYTERROR1
486 #define YYERRCODE256 576 #define YYERRCODE256
487 577
488#ifndef YYPURE
489 #define YYLEX yylex()
490#endif
491 578
492#ifdef YYPURE 579/* YYLLOC_DEFAULT -- Compute the default location (before the actions
493#ifdef YYLSP_NEEDED 580 are run).
494#ifdef YYLEX_PARAM
495 #define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM)
496#else
497 #define YYLEX yylex(&yylval, &yylloc)
498#endif
499#else /* not YYLSP_NEEDED */
500#ifdef YYLEX_PARAM
501 #define YYLEX yylex(&yylval, YYLEX_PARAM)
502#else
503 #define YYLEX yylex(&yylval)
504#endif
505#endif /* not YYLSP_NEEDED */
506#endif
507 581
508/* If nonreentrant, generate the variables here */ 582 When YYLLOC_DEFAULT is run, CURRENT is set the location of the
583 first token. By default, to implement support for ranges, extend
584 its range to the last symbol. */
509 585
510#ifndef YYPURE 586#ifndef YYLLOC_DEFAULT
511 587 # define YYLLOC_DEFAULT(Current, Rhs, N) \
512 int yychar; /* the lookahead symbol */ 588 Current.last_line = Rhs[N].last_line;\
513 YYSTYPE yylval; /* the semantic value of the */ 589 Current.last_column = Rhs[N].last_column;
514 /* lookahead symbol */
515
516#ifdef YYLSP_NEEDED
517 YYLTYPE yylloc; /* location data for the lookahead*/
518 /* symbol */
519#endif 590#endif
520 591
521 int yynerrs; /* number of parse errors so far */
522#endif /* not YYPURE */
523
524#if YYDEBUG != 0
525 int yydebug; /* nonzero means print parse trace*/
526/* Since this is uninitialized, it does not stop multiple parsers
527 from coexisting. */
528#endif
529
530 /* YYINITDEPTH indicates the initial size of the parser's stacks*/
531 592
593/* YYLEX -- calling `yylex' with the right arguments. */
594
595#if YYPURE
596# if YYLSP_NEEDED
597# ifdef YYLEX_PARAM
598 # define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM)
599# else
600 # define YYLEX yylex (&yylval, &yylloc)
601# endif
602# else /* !YYLSP_NEEDED */
603# ifdef YYLEX_PARAM
604 # define YYLEX yylex (&yylval, YYLEX_PARAM)
605# else
606 # define YYLEX yylex (&yylval)
607# endif
608# endif /* !YYLSP_NEEDED */
609#else /* !YYPURE */
610 # define YYLEX yylex ()
611#endif /* !YYPURE */
612
613
614/* Enable debugging if requested. */
615#if YYDEBUG
616
617# ifndef YYFPRINTF
618# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
619# define YYFPRINTF fprintf
620# endif
621
622 # define YYDPRINTF(Args) \
623 do { \
624 if (yydebug) \
625 YYFPRINTF Args; \
626} while (0)
627/* Nonzero means print parse trace. It is left uninitialized so that
628 multiple parsers can coexist. */
629int yydebug;
630#else /* !YYDEBUG */
631# define YYDPRINTF(Args)
632#endif /* !YYDEBUG */
633
634/* YYINITDEPTH -- initial size of the parser's stacks. */
532 #ifndefYYINITDEPTH 635 #ifndefYYINITDEPTH
533#define YYINITDEPTH 200 636# define YYINITDEPTH 200
534#endif 637#endif
535 638
536/* YYMAXDEPTH is the maximum size the stacks can grow to 639/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
537 (effective only if the built-in stack extension method is used). */ 640 if the built-in stack extension method is used).
641
642 Do not make this value too large; the results are undefined if
643 SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
644 evaluated with infinite-precision integer arithmetic. */
538 645
539#if YYMAXDEPTH == 0 646#if YYMAXDEPTH == 0
540#undef YYMAXDEPTH 647# undef YYMAXDEPTH
541#endif 648#endif
542 649
543#ifndef YYMAXDEPTH 650#ifndef YYMAXDEPTH
544#define YYMAXDEPTH 10000 651# define YYMAXDEPTH 10000
545#endif 652#endif
546 653
547/* Define __yy_memcpy. Note that the size argument 654#ifdef YYERROR_VERBOSE
548 should be passed with type unsigned int, because that is what the non-GCC
549 definitions require. With GCC, __builtin_memcpy takes an arg
550 of type size_t, but it can handle unsigned int. */
551
552 #if __GNUC__ > 1 /* GNU C and GNU C++ define this. */
553 #define __yy_memcpy(TO,FROM,COUNT)__builtin_memcpy(TO,FROM,COUNT)
554 #else /* not GNU C or C++ */
555#ifndef __cplusplus
556
557/* This is the most reliable way to avoid incompatibilities
558 in available built-in functions on various systems. */
559static void
560__yy_memcpy (to, from, count)
561 char *to;
562 char *from;
563 unsigned int count;
564{
565 register char *f = from;
566 register char *t = to;
567 register int i = count;
568 655
569 while (i-- > 0) 656# ifndef yystrlen
570 *t++ = *f++; 657# if defined (__GLIBC__) && defined (_STRING_H)
571} 658# define yystrlen strlen
659# else
660/* Return the length of YYSTR. */
661static YYSIZE_T
662# if defined (__STDC__) || defined (__cplusplus)
663yystrlen (const char *yystr)
664# else
665yystrlen (yystr)
666 const char *yystr;
667# endif
668{
669 register const char *yys = yystr;
572 670
573#else /* __cplusplus */ 671 while (*yys++ != '\0')
672 continue;
574 673
575/* This is the most reliable way to avoid incompatibilities 674 return yys - yystr - 1;
576 in available built-in functions on various systems. */ 675}
577static void 676# endif
578__yy_memcpy (char *to, char *from, unsigned int count) 677# endif
678
679# ifndef yystpcpy
680# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
681# define yystpcpy stpcpy
682# else
683/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
684 YYDEST. */
685static char *
686# if defined (__STDC__) || defined (__cplusplus)
687yystpcpy (char *yydest, const char *yysrc)
688# else
689yystpcpy (yydest, yysrc)
690 char *yydest;
691 const char *yysrc;
692# endif
579{ 693{
580 register char *t = to; 694 register char *yyd = yydest;
581 register char *f = from; 695 register const char *yys = yysrc;
582 register int i = count;
583 696
584 while (i-- > 0) 697 while ((*yyd++ = *yys++) != '\0')
585 *t++ = *f++; 698 continue;
586}
587 699
588#endif 700 return yyd - 1;
701}
702# endif
703# endif
589#endif 704#endif
590 705
591#line 217 "/usr/share/bison.simple" 706#line 315 "/usr/share/bison/bison.simple"
707
592 708
593/* The user can define YYPARSE_PARAM as the name of an argument to be passed 709/* The user can define YYPARSE_PARAM as the name of an argument to be passed
594 into yyparse. The argument should have type void *. 710 into yyparse. The argument should have type void *.
595 It should actually point to an object. 711 It should actually point to an object.
596 Grammar actions can access the variable by casting it 712 Grammar actions can access the variable by casting it
597 to the proper pointer type. */ 713 to the proper pointer type. */
598 714
599#ifdef YYPARSE_PARAM 715#ifdef YYPARSE_PARAM
600#ifdef __cplusplus 716# if defined (__STDC__) || defined (__cplusplus)
601#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM 717# define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
602#define YYPARSE_PARAM_DECL 718# define YYPARSE_PARAM_DECL
603#else /* not __cplusplus */ 719# else
604#define YYPARSE_PARAM_ARG YYPARSE_PARAM 720# define YYPARSE_PARAM_ARG YYPARSE_PARAM
605#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM; 721# define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
606#endif /* not __cplusplus */ 722# endif
607#else /* not YYPARSE_PARAM */ 723#else /* !YYPARSE_PARAM */
608#define YYPARSE_PARAM_ARG 724# define YYPARSE_PARAM_ARG
609#define YYPARSE_PARAM_DECL 725# define YYPARSE_PARAM_DECL
610#endif /* not YYPARSE_PARAM */ 726#endif /* !YYPARSE_PARAM */
611 727
612/* Prevent warning if -Wstrict-prototypes. */ 728/* Prevent warning if -Wstrict-prototypes. */
613#if defined (__GNUC__) && ! defined (__cplusplus) 729#ifdef __GNUC__
614#ifdef YYPARSE_PARAM 730# ifdef YYPARSE_PARAM
615int yyparse (void *); 731int yyparse (void *);
616#else 732# else
617int yyparse (void); 733int yyparse (void);
734# endif
618#endif 735#endif
736
737/* YY_DECL_VARIABLES -- depending whether we use a pure parser,
738 variables are global, or local to YYPARSE. */
739
740 #define YY_DECL_NON_LSP_VARIABLES \
741 /* The lookahead symbol. */ \
742 int yychar; \
743 \
744 /* The semantic value of the lookahead symbol. */\
745 YYSTYPE yylval; \
746 \
747 /* Number of parse errors so far. */ \
748int yynerrs;
749
750#if YYLSP_NEEDED
751 # define YY_DECL_VARIABLES \
752 YY_DECL_NON_LSP_VARIABLES \
753 \
754 /* Location data for the lookahead symbol. */\
755YYLTYPE yylloc;
756#else
757 # define YY_DECL_VARIABLES \
758YY_DECL_NON_LSP_VARIABLES
619#endif 759#endif
620 760
761
762/* If nonreentrant, generate the variables here. */
763
764#if !YYPURE
765YY_DECL_VARIABLES
766#endif /* !YYPURE */
767
621int 768int
622yyparse(YYPARSE_PARAM_ARG) 769yyparse (YYPARSE_PARAM_ARG)
623 YYPARSE_PARAM_DECL 770 YYPARSE_PARAM_DECL
624{ 771{
772 /* If reentrant, generate the variables here. */
773#if YYPURE
774 YY_DECL_VARIABLES
775#endif /* !YYPURE */
776
625 register int yystate; 777 register int yystate;
626 register int yyn; 778 register int yyn;
779 int yyresult;
780 /* Number of tokens to shift before error messages enabled. */
781 int yyerrstatus;
782 /* Lookahead token as an internal (translated) token number. */
783 int yychar1 = 0;
784
785 /* Three stacks and their tools:
786 `yyss': related to states,
787 `yyvs': related to semantic values,
788 `yyls': related to locations.
789
790 Refer to the stacks thru separate pointers, to allow yyoverflow
791 to reallocate them elsewhere. */
792
793 /* The state stack. */
794 shortyyssa[YYINITDEPTH];
795 short *yyss = yyssa;
627 register short *yyssp; 796 register short *yyssp;
628 register YYSTYPE *yyvsp;
629 int yyerrstatus;/* number of tokens to shift before error messages enabled */
630 int yychar1 = 0; /* lookahead token as an internal (translated) token number */
631 797
632 short yyssa[YYINITDEPTH]; /* the state stack */ 798 /* The semantic value stack. */
633 YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */ 799 YYSTYPE yyvsa[YYINITDEPTH];
634 800 YYSTYPE *yyvs = yyvsa;
635 short *yyss = yyssa; /* refer to the stacks thru separate pointers */ 801 register YYSTYPE *yyvsp;
636 YYSTYPE *yyvs = yyvsa;/* to allow yyoverflow to reallocate them elsewhere */
637 802
638#ifdef YYLSP_NEEDED 803#if YYLSP_NEEDED
639 YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */ 804 /* The location stack. */
805 YYLTYPE yylsa[YYINITDEPTH];
640 YYLTYPE *yyls = yylsa; 806 YYLTYPE *yyls = yylsa;
641 YYLTYPE *yylsp; 807 YYLTYPE *yylsp;
808#endif
642 809
643#define YYPOPSTACK (yyvsp--, yyssp--, yylsp--) 810#if YYLSP_NEEDED
811# define YYPOPSTACK (yyvsp--, yyssp--, yylsp--)
644#else 812#else
645#define YYPOPSTACK (yyvsp--, yyssp--) 813# define YYPOPSTACK (yyvsp--, yyssp--)
646#endif 814#endif
647 815
648 int yystacksize = YYINITDEPTH; 816 YYSIZE_T yystacksize = YYINITDEPTH;
649 int yyfree_stacks = 0;
650 817
651#ifdef YYPURE
652 int yychar;
653 YYSTYPE yylval;
654 int yynerrs;
655#ifdef YYLSP_NEEDED
656 YYLTYPE yylloc;
657#endif
658#endif
659 818
660 YYSTYPE yyval; /* the variable used to return */ 819 /* The variables used to return semantic value and location from the
661 /* semantic values from the action*/ 820 action routines. */
662 /* routines */ 821 YYSTYPE yyval;
822#if YYLSP_NEEDED
823 YYLTYPE yyloc;
824#endif
663 825
826 /* When reducing, the number of symbols on the RHS of the reduced
827 rule. */
664 int yylen; 828 int yylen;
665 829
666#if YYDEBUG != 0 830 YYDPRINTF ((stderr, "Starting parse\n"));
667 if (yydebug)
668 fprintf(stderr, "Starting parse\n");
669#endif
670 831
671 yystate = 0; 832 yystate = 0;
672 yyerrstatus = 0; 833 yyerrstatus = 0;
673 yynerrs = 0; 834 yynerrs = 0;
674 yychar = YYEMPTY; /* Cause a token to be read. */ 835 yychar = YYEMPTY; /* Cause a token to be read. */
675 836
676 /* Initialize stack pointers. 837 /* Initialize stack pointers.
677 Waste one element of value and location stack 838 Waste one element of value and location stack
678 so that they stay on the same level as the state stack. 839 so that they stay on the same level as the state stack.
679 The wasted elements are never initialized. */ 840 The wasted elements are never initialized. */
680 841
681 yyssp = yyss - 1; 842 yyssp = yyss;
682 yyvsp = yyvs; 843 yyvsp = yyvs;
683#ifdef YYLSP_NEEDED 844#if YYLSP_NEEDED
684 yylsp = yyls; 845 yylsp = yyls;
685#endif 846#endif
847 goto yysetstate;
848
849/*------------------------------------------------------------.
850| yynewstate -- Push a new state, which is found in yystate. |
851`------------------------------------------------------------*/
852 yynewstate:
853 /* In all cases, when you get here, the value and location stacks
854 have just been pushed. so pushing a state here evens the stacks.
855 */
856 yyssp++;
686 857
687/* Push a new state, which is found in yystate . */ 858 yysetstate:
688/* In all cases, when you get here, the value and location stacks 859 *yyssp = yystate;
689 have just been pushed. so pushing a state here evens the stacks. */
690yynewstate:
691
692 *++yyssp = yystate;
693 860
694 if (yyssp >= yyss + yystacksize - 1) 861 if (yyssp >= yyss + yystacksize - 1)
695 { 862 {
696 /* Give user a chance to reallocate the stack */
697 /* Use copies of these so that the &'s don't force the real ones into memory. */
698 YYSTYPE *yyvs1 = yyvs;
699 short *yyss1 = yyss;
700#ifdef YYLSP_NEEDED
701 YYLTYPE *yyls1 = yyls;
702#endif
703
704 /* Get the current used size of the three stacks, in elements. */ 863 /* Get the current used size of the three stacks, in elements. */
705 int size = yyssp - yyss + 1; 864 YYSIZE_T yysize = yyssp - yyss + 1;
706 865
707#ifdef yyoverflow 866#ifdef yyoverflow
708 /* Each stack pointer address is followed by the size of 867 {
709 the data in use in that stack, in bytes. */ 868 /* Give user a chance to reallocate the stack. Use copies of
710#ifdef YYLSP_NEEDED 869 these so that the &'s don't force the real ones into
711 /* This used to be a conditional around just the two extra args, 870 memory. */
712 but that might be undefined if yyoverflow is a macro. */ 871 YYSTYPE *yyvs1 = yyvs;
713 yyoverflow("parser stack overflow", 872 short *yyss1 = yyss;
714 &yyss1, size * sizeof (*yyssp), 873
715 &yyvs1, size * sizeof (*yyvsp), 874 /* Each stack pointer address is followed by the size of the
716 &yyls1, size * sizeof (*yylsp), 875 data in use in that stack, in bytes. */
717 &yystacksize); 876# if YYLSP_NEEDED
718#else 877 YYLTYPE *yyls1 = yyls;
719 yyoverflow("parser stack overflow", 878 /* This used to be a conditional around just the two extra args,
720 &yyss1, size * sizeof (*yyssp), 879 but that might be undefined if yyoverflow is a macro. */
721 &yyvs1, size * sizeof (*yyvsp), 880 yyoverflow ("parser stack overflow",
722 &yystacksize); 881 &yyss1, yysize * sizeof (*yyssp),
723#endif 882 &yyvs1, yysize * sizeof (*yyvsp),
724 883 &yyls1, yysize * sizeof (*yylsp),
725 yyss = yyss1; yyvs = yyvs1; 884 &yystacksize);
726#ifdef YYLSP_NEEDED 885 yyls = yyls1;
727 yyls = yyls1; 886# else
728#endif 887 yyoverflow ("parser stack overflow",
888 &yyss1, yysize * sizeof (*yyssp),
889 &yyvs1, yysize * sizeof (*yyvsp),
890 &yystacksize);
891# endif
892 yyss = yyss1;
893 yyvs = yyvs1;
894 }
729#else /* no yyoverflow */ 895#else /* no yyoverflow */
896# ifndef YYSTACK_RELOCATE
897 goto yyoverflowlab;
898# else
730 /* Extend the stack our own way. */ 899 /* Extend the stack our own way. */
731 if (yystacksize >= YYMAXDEPTH) 900 if (yystacksize >= YYMAXDEPTH)
732 { 901 goto yyoverflowlab;
733 yyerror("parser stack overflow");
734 if (yyfree_stacks)
735 {
736 free (yyss);
737 free (yyvs);
738#ifdef YYLSP_NEEDED
739 free (yyls);
740#endif
741 }
742 return 2;
743 }
744 yystacksize *= 2; 902 yystacksize *= 2;
745 if (yystacksize > YYMAXDEPTH) 903 if (yystacksize > YYMAXDEPTH)
746 yystacksize = YYMAXDEPTH; 904 yystacksize = YYMAXDEPTH;
747#ifndef YYSTACK_USE_ALLOCA 905
748 yyfree_stacks = 1; 906 {
749#endif 907 short *yyss1 = yyss;
750 yyss = (short *) YYSTACK_ALLOC (yystacksize * sizeof (*yyssp)); 908 union yyalloc *yyptr =
751 __yy_memcpy ((char *)yyss, (char *)yyss1, 909 (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
752 size * (unsigned int) sizeof (*yyssp)); 910 if (! yyptr)
753 yyvs = (YYSTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yyvsp)); 911 goto yyoverflowlab;
754 __yy_memcpy ((char *)yyvs, (char *)yyvs1, 912 YYSTACK_RELOCATE (yyss);
755 size * (unsigned int) sizeof (*yyvsp)); 913 YYSTACK_RELOCATE (yyvs);
756#ifdef YYLSP_NEEDED 914# if YYLSP_NEEDED
757 yyls = (YYLTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yylsp)); 915 YYSTACK_RELOCATE (yyls);
758 __yy_memcpy ((char *)yyls, (char *)yyls1, 916# endif
759 size * (unsigned int) sizeof (*yylsp)); 917# undef YYSTACK_RELOCATE
760#endif 918 if (yyss1 != yyssa)
919 YYSTACK_FREE (yyss1);
920 }
921# endif
761#endif /* no yyoverflow */ 922#endif /* no yyoverflow */
762 923
763 yyssp = yyss + size - 1; 924 yyssp = yyss + yysize - 1;
764 yyvsp = yyvs + size - 1; 925 yyvsp = yyvs + yysize - 1;
765#ifdef YYLSP_NEEDED 926#if YYLSP_NEEDED
766 yylsp = yyls + size - 1; 927 yylsp = yyls + yysize - 1;
767#endif 928#endif
768 929
769#if YYDEBUG != 0 930 YYDPRINTF ((stderr, "Stack size increased to %lu\n",
770 if (yydebug) 931 (unsigned long int) yystacksize));
771 fprintf(stderr, "Stack size increased to %d\n", yystacksize);
772#endif
773 932
774 if (yyssp >= yyss + yystacksize - 1) 933 if (yyssp >= yyss + yystacksize - 1)
775 YYABORT; 934 YYABORT;
776 } 935 }
777 936
778#if YYDEBUG != 0 937 YYDPRINTF ((stderr, "Entering state %d\n", yystate));
779 if (yydebug)
780 fprintf(stderr, "Entering state %d\n", yystate);
781#endif
782 938
783 goto yybackup; 939 goto yybackup;
784 yybackup: 940
941
942/*-----------.
943| yybackup. |
944`-----------*/
945yybackup:
785 946
786/* Do appropriate processing given the current state. */ 947/* Do appropriate processing given the current state. */
787/* Read a lookahead token if we need one and don't already have one. */ 948/* Read a lookahead token if we need one and don't already have one. */
788/* yyresume: */ 949/* yyresume: */
789 950
790 /* First try to decide what to do without reference to lookahead token. */ 951 /* First try to decide what to do without reference to lookahead token. */
791 952
792 yyn = yypact[yystate]; 953 yyn = yypact[yystate];
793 if (yyn == YYFLAG) 954 if (yyn == YYFLAG)
794 goto yydefault; 955 goto yydefault;
795 956
796 /* Not known => get a lookahead token if don't already have one. */ 957 /* Not known => get a lookahead token if don't already have one. */
797 958
798 /* yychar is either YYEMPTY or YYEOF 959 /* yychar is either YYEMPTY or YYEOF
799 or a valid token in external form. */ 960 or a valid token in external form. */
800 961
801 if (yychar == YYEMPTY) 962 if (yychar == YYEMPTY)
802 { 963 {
803#if YYDEBUG != 0 964 YYDPRINTF ((stderr, "Reading a token: "));
804 if (yydebug)
805 fprintf(stderr, "Reading a token: ");
806#endif
807 yychar = YYLEX; 965 yychar = YYLEX;
808 } 966 }
809 967
810 /* Convert token to internal form (in yychar1) for indexing tables with */ 968 /* Convert token to internal form (in yychar1) for indexing tables with */
811 969
812 if (yychar <= 0) /* This means end of input. */ 970 if (yychar <= 0) /* This means end of input. */
813 { 971 {
814 yychar1 = 0; 972 yychar1 = 0;
815 yychar = YYEOF; /* Don't call YYLEX any more */ 973 yychar = YYEOF; /* Don't call YYLEX any more */
816 974
817#if YYDEBUG != 0 975 YYDPRINTF ((stderr, "Now at end of input.\n"));
818 if (yydebug)
819 fprintf(stderr, "Now at end of input.\n");
820#endif
821 } 976 }
822 else 977 else
823 { 978 {
824 yychar1 = YYTRANSLATE(yychar); 979 yychar1 = YYTRANSLATE (yychar);
825 980
826#if YYDEBUG != 0 981#if YYDEBUG
982 /* We have to keep this `#if YYDEBUG', since we use variables
983 which are defined only if `YYDEBUG' is set. */
827 if (yydebug) 984 if (yydebug)
828 { 985 {
829 fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]); 986 YYFPRINTF (stderr, "Next token is %d (%s",
830 /* Give the individual parser a way to print the precise meaning 987 yychar, yytname[yychar1]);
831 of a token, for further debugging info. */ 988 /* Give the individual parser a way to print the precise
832#ifdef YYPRINT 989 meaning of a token, for further debugging info. */
990# ifdef YYPRINT
833 YYPRINT (stderr, yychar, yylval); 991 YYPRINT (stderr, yychar, yylval);
834#endif 992# endif
835 fprintf (stderr, ")\n"); 993 YYFPRINTF (stderr, ")\n");
836 } 994 }
837#endif 995#endif
838 } 996 }
839 997
840 yyn += yychar1; 998 yyn += yychar1;
841 if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1) 999 if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
842 goto yydefault; 1000 goto yydefault;
843 1001
844 yyn = yytable[yyn]; 1002 yyn = yytable[yyn];
845 1003
846 /* yyn is what to do for this token type in this state. 1004 /* yyn is what to do for this token type in this state.
847 Negative => reduce, -yyn is rule number. 1005 Negative => reduce, -yyn is rule number.
848 Positive => shift, yyn is new state. 1006 Positive => shift, yyn is new state.
849 New state is final state => don't bother to shift, 1007 New state is final state => don't bother to shift,
850 just return success. 1008 just return success.
851 0, or most negative number => error. */ 1009 0, or most negative number => error. */
852 1010
853 if (yyn < 0) 1011 if (yyn < 0)
854 { 1012 {
855 if (yyn == YYFLAG) 1013 if (yyn == YYFLAG)
856 goto yyerrlab; 1014 goto yyerrlab;
857 yyn = -yyn; 1015 yyn = -yyn;
858 goto yyreduce; 1016 goto yyreduce;
859 } 1017 }
860 else if (yyn == 0) 1018 else if (yyn == 0)
861 goto yyerrlab; 1019 goto yyerrlab;
862 1020
863 if (yyn == YYFINAL) 1021 if (yyn == YYFINAL)
864 YYACCEPT; 1022 YYACCEPT;
865 1023
866 /* Shift the lookahead token. */ 1024 /* Shift the lookahead token. */
867 1025 YYDPRINTF ((stderr, "Shifting token %d (%s), ",
868#if YYDEBUG != 0 1026 yychar, yytname[yychar1]));
869 if (yydebug)
870 fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
871#endif
872 1027
873 /* Discard the token being shifted unless it is eof. */ 1028 /* Discard the token being shifted unless it is eof. */
874 if (yychar != YYEOF) 1029 if (yychar != YYEOF)
875 yychar = YYEMPTY; 1030 yychar = YYEMPTY;
876 1031
877 *++yyvsp = yylval; 1032 *++yyvsp = yylval;
878#ifdef YYLSP_NEEDED 1033#if YYLSP_NEEDED
879 *++yylsp = yylloc; 1034 *++yylsp = yylloc;
880#endif 1035#endif
881 1036
882 /* count tokens shifted since error; after three, turn off error status. */ 1037 /* Count tokens shifted since error; after three, turn off error
883 if (yyerrstatus) yyerrstatus--; 1038 status. */
1039 if (yyerrstatus)
1040 yyerrstatus--;
884 1041
885 yystate = yyn; 1042 yystate = yyn;
886 goto yynewstate; 1043 goto yynewstate;
887 1044
888/* Do the default action for the current state. */
889yydefault:
890 1045
1046/*-----------------------------------------------------------.
1047| yydefault -- do the default action for the current state. |
1048`-----------------------------------------------------------*/
1049yydefault:
891 yyn = yydefact[yystate]; 1050 yyn = yydefact[yystate];
892 if (yyn == 0) 1051 if (yyn == 0)
893 goto yyerrlab; 1052 goto yyerrlab;
1053 goto yyreduce;
894 1054
895/* Do a reduction. yyn is the number of a rule to reduce with. */ 1055
1056/*-----------------------------.
1057| yyreduce -- Do a reduction. |
1058`-----------------------------*/
896yyreduce: 1059yyreduce:
1060 /* yyn is the number of a rule to reduce with. */
897 yylen = yyr2[yyn]; 1061 yylen = yyr2[yyn];
898 if (yylen > 0)
899 yyval = yyvsp[1-yylen]; /* implement default value of the action */
900 1062
901#if YYDEBUG != 0 1063 /* If YYLEN is nonzero, implement the default value of the action:
1064 `$$ = $1'.
1065
1066 Otherwise, the following line sets YYVAL to the semantic value of
1067 the lookahead token. This behavior is undocumented and Bison
1068 users should not rely upon it. Assigning to YYVAL
1069 unconditionally makes the parser a bit smaller, and it avoids a
1070 GCC warning that YYVAL may be used uninitialized. */
1071 yyval = yyvsp[1-yylen];
1072
1073#if YYLSP_NEEDED
1074 /* Similarly for the default location. Let the user run additional
1075 commands if for instance locations are ranges. */
1076 yyloc = yylsp[1-yylen];
1077 YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);
1078#endif
1079
1080#if YYDEBUG
1081 /* We have to keep this `#if YYDEBUG', since we use variables which
1082 are defined only if `YYDEBUG' is set. */
902 if (yydebug) 1083 if (yydebug)
903 { 1084 {
904 int i; 1085 int yyi;
905 1086
906 fprintf (stderr, "Reducing via rule %d (line %d), ", 1087 YYFPRINTF (stderr, "Reducing via rule %d (line %d), ",
907 yyn, yyrline[yyn]); 1088 yyn, yyrline[yyn]);
908 1089
909 /* Print the symbols being reduced, and their result. */ 1090 /* Print the symbols being reduced, and their result. */
910 for (i = yyprhs[yyn]; yyrhs[i] > 0; i++) 1091 for (yyi = yyprhs[yyn]; yyrhs[yyi] > 0; yyi++)
911 fprintf (stderr, "%s ", yytname[yyrhs[i]]); 1092 YYFPRINTF (stderr, "%s ", yytname[yyrhs[yyi]]);
912 fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]); 1093 YYFPRINTF (stderr, " -> %s\n", yytname[yyr1[yyn]]);
913 } 1094 }
914#endif 1095#endif
915 1096
916
917 switch (yyn) { 1097 switch (yyn) {
918 1098
919case 2: 1099case 2:
920#line 213 "./vcc.y" 1100#line 212 "vcc.y"
921{ addList(&vObjList, yyvsp[0].vobj); curObj = 0; ; 1101{ addList(&vObjList, yyvsp[0].vobj); curObj = 0; }
922 break;} 1102 break;
923case 4: 1103case 4:
924#line 216 "./vcc.y" 1104#line 215 "vcc.y"
925{ addList(&vObjList, yyvsp[0].vobj); curObj = 0; ; 1105{ addList(&vObjList, yyvsp[0].vobj); curObj = 0; }
926 break;} 1106 break;
927case 7: 1107case 7:
928#line 225 "./vcc.y" 1108#line 224 "vcc.y"
929{ 1109{
930 lexPushMode(L_VCARD); 1110 lexPushMode(L_VCARD);
931 if (!pushVObject(VCCardProp)) YYERROR; 1111 if (!pushVObject(VCCardProp)) YYERROR;
932 ; 1112 }
933 break;} 1113 break;
934case 8: 1114case 8:
935#line 230 "./vcc.y" 1115#line 229 "vcc.y"
936{ 1116{
937 lexPopMode(0); 1117 lexPopMode(0);
938 yyval.vobj = popVObject(); 1118 yyval.vobj = popVObject();
939 ; 1119 }
940 break;} 1120 break;
941case 9: 1121case 9:
942#line 235 "./vcc.y" 1122#line 234 "vcc.y"
943{ 1123{
944 lexPushMode(L_VCARD); 1124 lexPushMode(L_VCARD);
945 if (!pushVObject(VCCardProp)) YYERROR; 1125 if (!pushVObject(VCCardProp)) YYERROR;
946 ; 1126 }
947 break;} 1127 break;
948case 10: 1128case 10:
949#line 240 "./vcc.y" 1129#line 239 "vcc.y"
950{ 1130{
951 lexPopMode(0); 1131 lexPopMode(0);
952 yyval.vobj = popVObject(); 1132 yyval.vobj = popVObject();
953 ; 1133 }
954 break;} 1134 break;
955case 13: 1135case 13:
956#line 251 "./vcc.y" 1136#line 250 "vcc.y"
957{ 1137{
958 lexPushMode(L_VALUES); 1138 lexPushMode(L_VALUES);
959 ; 1139 }
960 break;} 1140 break;
961case 14: 1141case 14:
962#line 255 "./vcc.y" 1142#line 254 "vcc.y"
963{ 1143{
964 if (lexWithinMode(L_BASE64) || lexWithinMode(L_QUOTED_PRINTABLE)) 1144 if (lexWithinMode(L_BASE64) || lexWithinMode(L_QUOTED_PRINTABLE))
965 lexPopMode(0); 1145 lexPopMode(0);
966 lexPopMode(0); 1146 lexPopMode(0);
967 ; 1147 }
968 break;} 1148 break;
969case 16: 1149case 16:
970#line 264 "./vcc.y" 1150#line 263 "vcc.y"
971{ 1151{
972 enterProps(yyvsp[0].str); 1152 enterProps(yyvsp[0].str);
973 ; 1153 }
974 break;} 1154 break;
975case 18: 1155case 18:
976#line 269 "./vcc.y" 1156#line 268 "vcc.y"
977{ 1157{
978 enterProps(yyvsp[0].str); 1158 enterProps(yyvsp[0].str);
979 ; 1159 }
980 break;} 1160 break;
981case 22: 1161case 22:
982#line 282 "./vcc.y" 1162#line 281 "vcc.y"
983{ 1163{
984 enterAttr(yyvsp[0].str,0); 1164 enterAttr(yyvsp[0].str,0);
985 ; 1165 }
986 break;} 1166 break;
987case 23: 1167case 23:
988#line 286 "./vcc.y" 1168#line 285 "vcc.y"
989{ 1169{
990 enterAttr(yyvsp[-2].str,yyvsp[0].str); 1170 enterAttr(yyvsp[-2].str,yyvsp[0].str);
991 1171
992 ; 1172 }
993 break;} 1173 break;
994case 25: 1174case 25:
995#line 295 "./vcc.y" 1175#line 294 "vcc.y"
996{ appendValue(yyvsp[-1].str); ; 1176{ enterValues(yyvsp[-1].str); }
997 break;} 1177 break;
998case 27: 1178case 27:
999#line 297 "./vcc.y" 1179#line 296 "vcc.y"
1000{ appendValue(yyvsp[0].str); ; 1180{ enterValues(yyvsp[0].str); }
1001 break;} 1181 break;
1002case 29: 1182case 29:
1003#line 302 "./vcc.y" 1183#line 300 "vcc.y"
1004{ yyval.str = 0; ; 1184{ yyval.str = 0; }
1005 break;} 1185 break;
1006case 30: 1186case 30:
1007#line 307 "./vcc.y" 1187#line 305 "vcc.y"
1008{ if (!pushVObject(VCCalProp)) YYERROR; ; 1188{ if (!pushVObject(VCCalProp)) YYERROR; }
1009 break;} 1189 break;
1010case 31: 1190case 31:
1011#line 310 "./vcc.y" 1191#line 308 "vcc.y"
1012{ yyval.vobj = popVObject(); ; 1192{ yyval.vobj = popVObject(); }
1013 break;} 1193 break;
1014case 32: 1194case 32:
1015#line 312 "./vcc.y" 1195#line 310 "vcc.y"
1016{ if (!pushVObject(VCCalProp)) YYERROR; ; 1196{ if (!pushVObject(VCCalProp)) YYERROR; }
1017 break;} 1197 break;
1018case 33: 1198case 33:
1019#line 314 "./vcc.y" 1199#line 312 "vcc.y"
1020{ yyval.vobj = popVObject(); ; 1200{ yyval.vobj = popVObject(); }
1021 break;} 1201 break;
1022case 39: 1202case 39:
1023#line 329 "./vcc.y" 1203#line 327 "vcc.y"
1024{ 1204{
1025 lexPushMode(L_VEVENT); 1205 lexPushMode(L_VEVENT);
1026 if (!pushVObject(VCEventProp)) YYERROR; 1206 if (!pushVObject(VCEventProp)) YYERROR;
1027 ; 1207 }
1028 break;} 1208 break;
1029case 40: 1209case 40:
1030#line 335 "./vcc.y" 1210#line 333 "vcc.y"
1031{ 1211{
1032 lexPopMode(0); 1212 lexPopMode(0);
1033 popVObject(); 1213 popVObject();
1034 ; 1214 }
1035 break;} 1215 break;
1036case 41: 1216case 41:
1037#line 340 "./vcc.y" 1217#line 338 "vcc.y"
1038{ 1218{
1039 lexPushMode(L_VEVENT); 1219 lexPushMode(L_VEVENT);
1040 if (!pushVObject(VCEventProp)) YYERROR; 1220 if (!pushVObject(VCEventProp)) YYERROR;
1041 ; 1221 }
1042 break;} 1222 break;
1043case 42: 1223case 42:
1044#line 345 "./vcc.y" 1224#line 343 "vcc.y"
1045{ 1225{
1046 lexPopMode(0); 1226 lexPopMode(0);
1047 popVObject(); 1227 popVObject();
1048 ; 1228 }
1049 break;} 1229 break;
1050case 43: 1230case 43:
1051#line 353 "./vcc.y" 1231#line 351 "vcc.y"
1052{ 1232{
1053 lexPushMode(L_VTODO); 1233 lexPushMode(L_VTODO);
1054 if (!pushVObject(VCTodoProp)) YYERROR; 1234 if (!pushVObject(VCTodoProp)) YYERROR;
1055 ; 1235 }
1056 break;} 1236 break;
1057case 44: 1237case 44:
1058#line 359 "./vcc.y" 1238#line 357 "vcc.y"
1059{ 1239{
1060 lexPopMode(0); 1240 lexPopMode(0);
1061 popVObject(); 1241 popVObject();
1062 ; 1242 }
1063 break;} 1243 break;
1064case 45: 1244case 45:
1065#line 364 "./vcc.y" 1245#line 362 "vcc.y"
1066{ 1246{
1067 lexPushMode(L_VTODO); 1247 lexPushMode(L_VTODO);
1068 if (!pushVObject(VCTodoProp)) YYERROR; 1248 if (!pushVObject(VCTodoProp)) YYERROR;
1069 ; 1249 }
1070 break;} 1250 break;
1071case 46: 1251case 46:
1072#line 369 "./vcc.y" 1252#line 367 "vcc.y"
1073{ 1253{
1074 lexPopMode(0); 1254 lexPopMode(0);
1075 popVObject(); 1255 popVObject();
1076 ; 1256 }
1077 break;} 1257 break;
1078} 1258}
1079 /* the action file gets copied in in place of this dollarsign */
1080#line 543 "/usr/share/bison.simple"
1081 1259
1260#line 705 "/usr/share/bison/bison.simple"
1261
1262
1082 yyvsp -= yylen; 1263 yyvsp -= yylen;
1083 yyssp -= yylen; 1264 yyssp -= yylen;
1084#ifdef YYLSP_NEEDED 1265#if YYLSP_NEEDED
1085 yylsp -= yylen; 1266 yylsp -= yylen;
1086#endif 1267#endif
1087 1268
1088#if YYDEBUG != 0 1269#if YYDEBUG
1089 if (yydebug) 1270 if (yydebug)
1090 { 1271 {
1091 short *ssp1 = yyss - 1; 1272 short *yyssp1 = yyss - 1;
1092 fprintf (stderr, "state stack now"); 1273 YYFPRINTF (stderr, "state stack now");
1093 while (ssp1 != yyssp) 1274 while (yyssp1 != yyssp)
1094 fprintf (stderr, " %d", *++ssp1); 1275 YYFPRINTF (stderr, " %d", *++yyssp1);
1095 fprintf (stderr, "\n"); 1276 YYFPRINTF (stderr, "\n");
1096 } 1277 }
1097#endif 1278#endif
1098 1279
1099 *++yyvsp = yyval; 1280 *++yyvsp = yyval;
1100 1281#if YYLSP_NEEDED
1101#ifdef YYLSP_NEEDED 1282 *++yylsp = yyloc;
1102 yylsp++;
1103 if (yylen == 0)
1104 {
1105 yylsp->first_line = yylloc.first_line;
1106 yylsp->first_column = yylloc.first_column;
1107 yylsp->last_line = (yylsp-1)->last_line;
1108 yylsp->last_column = (yylsp-1)->last_column;
1109 yylsp->text = 0;
1110 }
1111 else
1112 {
1113 yylsp->last_line = (yylsp+yylen-1)->last_line;
1114 yylsp->last_column = (yylsp+yylen-1)->last_column;
1115 }
1116#endif 1283#endif
1117 1284
1118 /* Now "shift" the result of the reduction. 1285 /* Now `shift' the result of the reduction. Determine what state
1119 Determine what state that goes to, 1286 that goes to, based on the state we popped back to and the rule
1120 based on the state we popped back to 1287 number reduced by. */
1121 and the rule number reduced by. */
1122 1288
1123 yyn = yyr1[yyn]; 1289 yyn = yyr1[yyn];
1124 1290
1125 yystate = yypgoto[yyn - YYNTBASE] + *yyssp; 1291 yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
1126 if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp) 1292 if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
1127 yystate = yytable[yystate]; 1293 yystate = yytable[yystate];
1128 else 1294 else
1129 yystate = yydefgoto[yyn - YYNTBASE]; 1295 yystate = yydefgoto[yyn - YYNTBASE];
1130 1296
1131 goto yynewstate; 1297 goto yynewstate;
1132 1298
1133yyerrlab: /* here on detecting error */
1134 1299
1135 if (! yyerrstatus) 1300/*------------------------------------.
1136 /* If not already recovering from an error, report this error. */ 1301| yyerrlab -- here on detecting error |
1302`------------------------------------*/
1303yyerrlab:
1304 /* If not already recovering from an error, report this error. */
1305 if (!yyerrstatus)
1137 { 1306 {
1138 ++yynerrs; 1307 ++yynerrs;
1139 1308
1140#ifdef YYERROR_VERBOSE 1309#ifdef YYERROR_VERBOSE
1141 yyn = yypact[yystate]; 1310 yyn = yypact[yystate];
1142 1311
1143 if (yyn > YYFLAG && yyn < YYLAST) 1312 if (yyn > YYFLAG && yyn < YYLAST)
1144 { 1313 {
1145 int size = 0; 1314 YYSIZE_T yysize = 0;
1146 char *msg; 1315 char *yymsg;
1147 int x, count; 1316 int yyx, yycount;
1148 1317
1149 count = 0; 1318 yycount = 0;
1150 /* Start X at -yyn if nec to avoid negative indexes in yycheck. */ 1319 /* Start YYX at -YYN if negative to avoid negative indexes in
1151 for (x = (yyn < 0 ? -yyn : 0); 1320 YYCHECK. */
1152 x < (sizeof(yytname) / sizeof(char *)); x++) 1321 for (yyx = yyn < 0 ? -yyn : 0;
1153 if (yycheck[x + yyn] == x) 1322 yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++)
1154 size += strlen(yytname[x]) + 15, count++; 1323 if (yycheck[yyx + yyn] == yyx)
1155 msg = (char *) malloc(size + 15); 1324 yysize += yystrlen (yytname[yyx]) + 15, yycount++;
1156 if (msg != 0) 1325 yysize += yystrlen ("parse error, unexpected ") + 1;
1326 yysize += yystrlen (yytname[YYTRANSLATE (yychar)]);
1327 yymsg = (char *) YYSTACK_ALLOC (yysize);
1328 if (yymsg != 0)
1157 { 1329 {
1158 strcpy(msg, "parse error"); 1330 char *yyp = yystpcpy (yymsg, "parse error, unexpected ");
1331 yyp = yystpcpy (yyp, yytname[YYTRANSLATE (yychar)]);
1159 1332
1160 if (count < 5) 1333 if (yycount < 5)
1161 { 1334 {
1162 count = 0; 1335 yycount = 0;
1163 for (x = (yyn < 0 ? -yyn : 0); 1336 for (yyx = yyn < 0 ? -yyn : 0;
1164 x < (sizeof(yytname) / sizeof(char *)); x++) 1337 yyx < (int) (sizeof (yytname) / sizeof (char *));
1165 if (yycheck[x + yyn] == x) 1338 yyx++)
1339 if (yycheck[yyx + yyn] == yyx)
1166 { 1340 {
1167 strcat(msg, count == 0 ? ", expecting `" : " or `"); 1341 const char *yyq = ! yycount ? ", expecting " : " or ";
1168 strcat(msg, yytname[x]); 1342 yyp = yystpcpy (yyp, yyq);
1169 strcat(msg, "'"); 1343 yyp = yystpcpy (yyp, yytname[yyx]);
1170 count++; 1344 yycount++;
1171 } 1345 }
1172 } 1346 }
1173 yyerror(msg); 1347 yyerror (yymsg);
1174 free(msg); 1348 YYSTACK_FREE (yymsg);
1175 } 1349 }
1176 else 1350 else
1177 yyerror ("parse error; also virtual memory exceeded"); 1351 yyerror ("parse error; also virtual memory exhausted");
1178 } 1352 }
1179 else 1353 else
1180#endif /* YYERROR_VERBOSE */ 1354#endif /* defined (YYERROR_VERBOSE) */
1181 yyerror("parse error"); 1355 yyerror ("parse error");
1182 } 1356 }
1183
1184 goto yyerrlab1; 1357 goto yyerrlab1;
1185yyerrlab1: /* here on error raised explicitly by an action */
1186 1358
1359
1360/*--------------------------------------------------.
1361| yyerrlab1 -- error raised explicitly by an action |
1362`--------------------------------------------------*/
1363yyerrlab1:
1187 if (yyerrstatus == 3) 1364 if (yyerrstatus == 3)
1188 { 1365 {
1189 /* if just tried and failed to reuse lookahead token after an error, discard it. */ 1366 /* If just tried and failed to reuse lookahead token after an
1367 error, discard it. */
1190 1368
1191 /* return failure if at end of input */ 1369 /* return failure if at end of input */
1192 if (yychar == YYEOF) 1370 if (yychar == YYEOF)
1193 YYABORT; 1371 YYABORT;
1194 1372 YYDPRINTF ((stderr, "Discarding token %d (%s).\n",
1195#if YYDEBUG != 0 1373 yychar, yytname[yychar1]));
1196 if (yydebug)
1197 fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
1198#endif
1199
1200 yychar = YYEMPTY; 1374 yychar = YYEMPTY;
1201 } 1375 }
1202 1376
1203 /* Else will try to reuse lookahead token 1377 /* Else will try to reuse lookahead token after shifting the error
1204 after shifting the error token. */ 1378 token. */
1205 1379
1206 yyerrstatus = 3; /* Each real token shifted decrements this */ 1380 yyerrstatus = 3; /* Each real token shifted decrements this */
1207 1381
1208 goto yyerrhandle; 1382 goto yyerrhandle;
1209 1383
1210yyerrdefault: /* current state does not do anything special for the error token. */
1211 1384
1385/*-------------------------------------------------------------------.
1386| yyerrdefault -- current state does not do anything special for the |
1387| error token. |
1388`-------------------------------------------------------------------*/
1389yyerrdefault:
1212#if 0 1390#if 0
1213 /* This is wrong; only states that explicitly want error tokens 1391 /* This is wrong; only states that explicitly want error tokens
1214 should shift them. */ 1392 should shift them. */
1215 yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/ 1393
1216 if (yyn) goto yydefault; 1394 /* If its default is to accept any token, ok. Otherwise pop it. */
1395 yyn = yydefact[yystate];
1396 if (yyn)
1397 goto yydefault;
1217#endif 1398#endif
1218 1399
1219yyerrpop: /* pop the current state because it cannot handle the error token */
1220 1400
1221 if (yyssp == yyss) YYABORT; 1401/*---------------------------------------------------------------.
1402| yyerrpop -- pop the current state because it cannot handle the |
1403| error token |
1404`---------------------------------------------------------------*/
1405yyerrpop:
1406 if (yyssp == yyss)
1407 YYABORT;
1222 yyvsp--; 1408 yyvsp--;
1223 yystate = *--yyssp; 1409 yystate = *--yyssp;
1224#ifdef YYLSP_NEEDED 1410#if YYLSP_NEEDED
1225 yylsp--; 1411 yylsp--;
1226#endif 1412#endif
1227 1413
1228#if YYDEBUG != 0 1414#if YYDEBUG
1229 if (yydebug) 1415 if (yydebug)
1230 { 1416 {
1231 short *ssp1 = yyss - 1; 1417 short *yyssp1 = yyss - 1;
1232 fprintf (stderr, "Error: state stack now"); 1418 YYFPRINTF (stderr, "Error: state stack now");
1233 while (ssp1 != yyssp) 1419 while (yyssp1 != yyssp)
1234 fprintf (stderr, " %d", *++ssp1); 1420 YYFPRINTF (stderr, " %d", *++yyssp1);
1235 fprintf (stderr, "\n"); 1421 YYFPRINTF (stderr, "\n");
1236 } 1422 }
1237#endif 1423#endif
1238 1424
1425/*--------------.
1426| yyerrhandle. |
1427`--------------*/
1239yyerrhandle: 1428yyerrhandle:
1240
1241 yyn = yypact[yystate]; 1429 yyn = yypact[yystate];
1242 if (yyn == YYFLAG) 1430 if (yyn == YYFLAG)
1243 goto yyerrdefault; 1431 goto yyerrdefault;
1244 1432
1245 yyn += YYTERROR; 1433 yyn += YYTERROR;
1246 if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR) 1434 if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
1247 goto yyerrdefault; 1435 goto yyerrdefault;
1248 1436
1249 yyn = yytable[yyn]; 1437 yyn = yytable[yyn];
1250 if (yyn < 0) 1438 if (yyn < 0)
1251 { 1439 {
1252 if (yyn == YYFLAG) 1440 if (yyn == YYFLAG)
1253 goto yyerrpop; 1441 goto yyerrpop;
1254 yyn = -yyn; 1442 yyn = -yyn;
1255 goto yyreduce; 1443 goto yyreduce;
1256 } 1444 }
1257 else if (yyn == 0) 1445 else if (yyn == 0)
1258 goto yyerrpop; 1446 goto yyerrpop;
1259 1447
1260 if (yyn == YYFINAL) 1448 if (yyn == YYFINAL)
1261 YYACCEPT; 1449 YYACCEPT;
1262 1450
1263#if YYDEBUG != 0 1451 YYDPRINTF ((stderr, "Shifting error token, "));
1264 if (yydebug)
1265 fprintf(stderr, "Shifting error token, ");
1266#endif
1267 1452
1268 *++yyvsp = yylval; 1453 *++yyvsp = yylval;
1269#ifdef YYLSP_NEEDED 1454#if YYLSP_NEEDED
1270 *++yylsp = yylloc; 1455 *++yylsp = yylloc;
1271#endif 1456#endif
1272 1457
1273 yystate = yyn; 1458 yystate = yyn;
1274 goto yynewstate; 1459 goto yynewstate;
1275 1460
1276 yyacceptlab:
1277 /* YYACCEPT comes here. */
1278 if (yyfree_stacks)
1279 {
1280 free (yyss);
1281 free (yyvs);
1282#ifdef YYLSP_NEEDED
1283 free (yyls);
1284#endif
1285 }
1286 return 0;
1287 1461
1288 yyabortlab: 1462/*-------------------------------------.
1289 /* YYABORT comes here. */ 1463| yyacceptlab -- YYACCEPT comes here. |
1290 if (yyfree_stacks) 1464`-------------------------------------*/
1291 { 1465yyacceptlab:
1292 free (yyss); 1466 yyresult = 0;
1293 free (yyvs); 1467 goto yyreturn;
1294#ifdef YYLSP_NEEDED 1468
1295 free (yyls); 1469/*-----------------------------------.
1470| yyabortlab -- YYABORT comes here. |
1471`-----------------------------------*/
1472yyabortlab:
1473 yyresult = 1;
1474 goto yyreturn;
1475
1476/*---------------------------------------------.
1477| yyoverflowab -- parser overflow comes here. |
1478`---------------------------------------------*/
1479yyoverflowlab:
1480 yyerror ("parser stack overflow");
1481 yyresult = 2;
1482 /* Fall through. */
1483
1484yyreturn:
1485#ifndef yyoverflow
1486 if (yyss != yyssa)
1487 YYSTACK_FREE (yyss);
1296#endif 1488#endif
1297 } 1489 return yyresult;
1298 return 1;
1299} 1490}
1300#line 375 "./vcc.y" 1491#line 373 "vcc.y"
1301 1492
1302/****************************************************************************/
1303static int pushVObject(const char *prop) 1493static int pushVObject(const char *prop)
1304 { 1494 {
1305 VObject *newObj; 1495 VObject *newObj;
1306 if (ObjStackTop == MAXLEVEL) 1496 if (ObjStackTop == MAXLEVEL)
1307 return FALSE; 1497 return FALSE;
1308 1498
1309 ObjStack[++ObjStackTop] = curObj; 1499 ObjStack[++ObjStackTop] = curObj;
1310 1500
1311 if (curObj) { 1501 if (curObj) {
1312 newObj = addProp(curObj,prop); 1502 newObj = addProp(curObj,prop);
1313 curObj = newObj; 1503 curObj = newObj;
1314 } 1504 }
1315 else 1505 else
1316 curObj = newVObject(prop); 1506 curObj = newVObject(prop);
1317 1507
1318 return TRUE; 1508 return TRUE;
1319 } 1509 }
1320 1510
1321 1511
1322/****************************************************************************/
1323/* This pops the recently built vCard off the stack and returns it. */ 1512/* This pops the recently built vCard off the stack and returns it. */
1324static VObject* popVObject() 1513static VObject* popVObject()
1325 { 1514 {
1326 VObject *oldObj; 1515 VObject *oldObj;
1327 if (ObjStackTop < 0) { 1516 if (ObjStackTop < 0) {
1328 yyerror("pop on empty Object Stack\n"); 1517 yyerror("pop on empty Object Stack\n");
1329 return 0; 1518 return 0;
1330 } 1519 }
1331 oldObj = curObj; 1520 oldObj = curObj;
1332 curObj = ObjStack[ObjStackTop--]; 1521 curObj = ObjStack[ObjStackTop--];
1333 1522
1334 return oldObj; 1523 return oldObj;
1335 } 1524 }
1336 1525
1337 1526
1338/* static void enterValues(const char *value) */ 1527static void enterValues(const char *value)
1339/* { */ 1528 {
1340/* if (fieldedProp && *fieldedProp) { */ 1529 if (fieldedProp && *fieldedProp) {
1341 /* if (value) { */ 1530 if (value) {
1342 /* addPropValue(curProp,*fieldedProp,value); */ 1531 addPropValue(curProp,*fieldedProp,value);
1343 /* } */ 1532 }
1344 /* else this field is empty, advance to next field */ 1533 /* else this field is empty, advance to next field */
1345 /* fieldedProp++; */ 1534 fieldedProp++;
1346 /* } */ 1535 }
1347/* else { */ 1536 else {
1348 /* if (value) { */ 1537 if (value) {
1349 /* setVObjectUStringZValue_(curProp,fakeUnicode(value,0)); */ 1538 char *p1, *p2;
1350 /* } */ 1539 wchar_t *p3;
1351 /* } */ 1540 int i;
1352/* deleteStr(value); */ 1541
1353/* } */ 1542 /* If the property already has a string value, we append this one,
1354 1543 using ';' to separate the values. */
1355static void appendValue(const char *value) 1544 if (vObjectUStringZValue(curProp)) {
1356{ 1545 p1 = fakeCString(vObjectUStringZValue(curProp));
1357 char *p1, *p2; 1546 p2 = malloc((strlen(p1)+strlen(value)+1));
1358 wchar_t *p3; 1547 strcpy(p2, p1);
1359 int i; 1548 deleteStr(p1);
1360 1549
1361 if (fieldedProp && *fieldedProp) { 1550 i = strlen(p2);
1362 if (value) { 1551 p2[i] = ';';
1363 addPropValue(curProp, *fieldedProp, value); 1552 p2[i+1] = '\0';
1553 p2 = strcat(p2, value);
1554 p3 = (wchar_t *) vObjectUStringZValue(curProp);
1555 free(p3);
1556 setVObjectUStringZValue_(curProp,fakeUnicode(p2,0));
1557 deleteStr(p2);
1558 } else {
1559 setVObjectUStringZValue_(curProp,fakeUnicode(value,0));
1560 }
1561 }
1364 } 1562 }
1365 /* else this field is empty, advance to next field */ 1563 deleteStr(value);
1366 fieldedProp++;
1367 } else {
1368 if (value) {
1369 if (vObjectUStringZValue(curProp)) {
1370 p1 = fakeCString(vObjectUStringZValue(curProp));
1371 p2 = malloc(sizeof(char *) * (strlen(p1)+strlen(value)+1));
1372 strcpy(p2, p1);
1373 deleteStr(p1);
1374
1375 i = strlen(p2);
1376 p2[i] = ',';
1377 p2[i+1] = '\0';
1378 p2 = strcat(p2, value);
1379 p3 = (wchar_t *) vObjectUStringZValue(curProp);
1380 free(p3);
1381 setVObjectUStringZValue_(curProp,fakeUnicode(p2,0));
1382 deleteStr(p2);
1383 } else {
1384 setVObjectUStringZValue_(curProp,fakeUnicode(value,0));
1385 }
1386 } 1564 }
1387 }
1388 deleteStr(value);
1389}
1390
1391 1565
1392static void enterProps(const char *s) 1566static void enterProps(const char *s)
1393 { 1567 {
1394 curProp = addGroup(curObj,s); 1568 curProp = addGroup(curObj,s);
1395 deleteStr(s); 1569 deleteStr(s);
1396 } 1570 }
1397 1571
1398static void enterAttr(const char *s1, const char *s2) 1572static void enterAttr(const char *s1, const char *s2)
1399 { 1573 {
1400 const char *p1=0L, *p2=0L; 1574 const char *p1, *p2;
1401 p1 = lookupProp_(s1); 1575 p1 = lookupProp_(s1);
1402 if (s2) { 1576 if (s2) {
1403 VObject *a; 1577 VObject *a;
1404 p2 = lookupProp_(s2); 1578 p2 = lookupProp_(s2);
1405 a = addProp(curProp,p1); 1579 a = addProp(curProp,p1);
1406 setVObjectStringZValue(a,p2); 1580 setVObjectStringZValue(a,p2);
1407 } 1581 }
1408 else 1582 else
1409 addProp(curProp,p1); 1583 addProp(curProp,p1);
1410 if (strcasecmp(p1,VCBase64Prop) == 0 || (s2 && strcasecmp(p2,VCBase64Prop)==0)) 1584 if (stricmp(p1,VCBase64Prop) == 0 || (s2 && stricmp(p2,VCBase64Prop)==0))
1411 lexPushMode(L_BASE64); 1585 lexPushMode(L_BASE64);
1412 else if (strcasecmp(p1,VCQuotedPrintableProp) == 0 1586 else if (stricmp(p1,VCQuotedPrintableProp) == 0
1413 || (s2 && strcasecmp(p2,VCQuotedPrintableProp)==0)) 1587 || (s2 && stricmp(p2,VCQuotedPrintableProp)==0))
1414 lexPushMode(L_QUOTED_PRINTABLE); 1588 lexPushMode(L_QUOTED_PRINTABLE);
1415 deleteStr(s1); deleteStr(s2); 1589 deleteStr(s1); deleteStr(s2);
1416 } 1590 }
1417 1591
1418 1592
1419#define MAX_LEX_LOOKAHEAD_0 32 1593#define MAX_LEX_LOOKAHEAD_0 32
1420#define MAX_LEX_LOOKAHEAD 64 1594#define MAX_LEX_LOOKAHEAD 64
1421#define MAX_LEX_MODE_STACK_SIZE 10 1595#define MAX_LEX_MODE_STACK_SIZE 10
1422#define LEXMODE() (lexBuf.lexModeStack[lexBuf.lexModeStackTop]) 1596#define LEXMODE() (lexBuf.lexModeStack[lexBuf.lexModeStackTop])
1423 1597
1424struct LexBuf { 1598struct LexBuf {
1425 /* input */ 1599 /* input */
1600#ifdef INCLUDEMFC
1601 CFile *inputFile;
1602#else
1426 FILE *inputFile; 1603 FILE *inputFile;
1604#endif
1427 char *inputString; 1605 char *inputString;
1428 unsigned long curPos; 1606 unsigned long curPos;
1429 unsigned long inputLen; 1607 unsigned long inputLen;
1430 /* lookahead buffer */ 1608 /* lookahead buffer */
1431 /* -- lookahead buffer is short instead of char so that EOF 1609 /* -- lookahead buffer is short instead of char so that EOF
1432 / can be represented correctly. 1610 / can be represented correctly.
1433 */ 1611 */
1434 unsigned long len; 1612 unsigned long len;
1435 short buf[MAX_LEX_LOOKAHEAD]; 1613 short buf[MAX_LEX_LOOKAHEAD];
1436 unsigned long getPtr; 1614 unsigned long getPtr;
1437 /* context stack */ 1615 /* context stack */
1438 unsigned long lexModeStackTop; 1616 unsigned long lexModeStackTop;
1439 enum LexMode lexModeStack[MAX_LEX_MODE_STACK_SIZE]; 1617 enum LexMode lexModeStack[MAX_LEX_MODE_STACK_SIZE];
1440 /* token buffer */ 1618 /* token buffer */
1441 unsigned long maxToken; 1619 unsigned long maxToken;
1442 char *strs; 1620 char *strs;
1443 unsigned long strsLen; 1621 unsigned long strsLen;
1444 } lexBuf; 1622 } lexBuf;
1445 1623
1446static void lexPushMode(enum LexMode mode) 1624static void lexPushMode(enum LexMode mode)
1447 { 1625 {
1448 if (lexBuf.lexModeStackTop == (MAX_LEX_MODE_STACK_SIZE-1)) 1626 if (lexBuf.lexModeStackTop == (MAX_LEX_MODE_STACK_SIZE-1))
1449 yyerror("lexical context stack overflow"); 1627 yyerror("lexical context stack overflow");
1450 else { 1628 else {
1451 lexBuf.lexModeStack[++lexBuf.lexModeStackTop] = mode; 1629 lexBuf.lexModeStack[++lexBuf.lexModeStackTop] = mode;
1452 } 1630 }
1453 } 1631 }
1454 1632
1455static void lexPopMode(int top) 1633static void lexPopMode(int top)
1456 { 1634 {
1457 /* special case of pop for ease of error recovery -- this 1635 /* special case of pop for ease of error recovery -- this
1458 version will never underflow */ 1636 version will never underflow */
1459 if (top) 1637 if (top)
1460 lexBuf.lexModeStackTop = 0; 1638 lexBuf.lexModeStackTop = 0;
1461 else 1639 else
1462 if (lexBuf.lexModeStackTop > 0) lexBuf.lexModeStackTop--; 1640 if (lexBuf.lexModeStackTop > 0) lexBuf.lexModeStackTop--;
1463 } 1641 }
1464 1642
1465static int lexWithinMode(enum LexMode mode) { 1643static int lexWithinMode(enum LexMode mode) {
1466 unsigned long i; 1644 unsigned long i;
1467 for (i=0;i<lexBuf.lexModeStackTop;i++) 1645 for (i=0;i<lexBuf.lexModeStackTop;i++)
1468 if (mode == lexBuf.lexModeStack[i]) return 1; 1646 if (mode == lexBuf.lexModeStack[i]) return 1;
1469 return 0; 1647 return 0;
1470 } 1648 }
1471 1649
1472static int lexGetc_() 1650static char lexGetc_()
1473 { 1651 {
1474 /* get next char from input, no buffering. */ 1652 /* get next char from input, no buffering. */
1475 if (lexBuf.curPos == lexBuf.inputLen) 1653 if (lexBuf.curPos == lexBuf.inputLen)
1476 return EOF; 1654 return EOF;
1477 else if (lexBuf.inputString) 1655 else if (lexBuf.inputString)
1478 return *(lexBuf.inputString + lexBuf.curPos++); 1656 return *(lexBuf.inputString + lexBuf.curPos++);
1479 else { 1657 else {
1480 if (!feof(lexBuf.inputFile)) 1658#ifdef INCLUDEMFC
1481 return fgetc(lexBuf.inputFile); 1659 char result;
1482 else 1660 return lexBuf.inputFile->Read(&result, 1) == 1 ? result : EOF;
1483 return EOF; 1661#else
1662 return fgetc(lexBuf.inputFile);
1663#endif
1484 } 1664 }
1485 } 1665 }
1486 1666
1487static int lexGeta() 1667static int lexGeta()
1488 { 1668 {
1489 ++lexBuf.len; 1669 ++lexBuf.len;
1490 return (lexBuf.buf[lexBuf.getPtr] = lexGetc_()); 1670 return (lexBuf.buf[lexBuf.getPtr] = lexGetc_());
1491 } 1671 }
1492 1672
1493static int lexGeta_(int i) 1673static int lexGeta_(int i)
1494 { 1674 {
1495 ++lexBuf.len; 1675 ++lexBuf.len;
1496 return (lexBuf.buf[(lexBuf.getPtr+i)%MAX_LEX_LOOKAHEAD] = lexGetc_()); 1676 return (lexBuf.buf[(lexBuf.getPtr+i)%MAX_LEX_LOOKAHEAD] = lexGetc_());
1497 } 1677 }
1498 1678
1499static void lexSkipLookahead() { 1679static void lexSkipLookahead() {
1500 if (lexBuf.len > 0 && lexBuf.buf[lexBuf.getPtr]!=EOF) { 1680 if (lexBuf.len > 0 && lexBuf.buf[lexBuf.getPtr]!=EOF) {
1501 /* don't skip EOF. */ 1681 /* don't skip EOF. */
1502 lexBuf.getPtr = (lexBuf.getPtr + 1) % MAX_LEX_LOOKAHEAD; 1682 lexBuf.getPtr = (lexBuf.getPtr + 1) % MAX_LEX_LOOKAHEAD;
1503 lexBuf.len--; 1683 lexBuf.len--;
1504 } 1684 }
1505 } 1685 }
1506 1686
1507static int lexLookahead() { 1687static int lexLookahead() {
1508 int c = (lexBuf.len)? 1688 int c = (lexBuf.len)?
1509 lexBuf.buf[lexBuf.getPtr]: 1689 lexBuf.buf[lexBuf.getPtr]:
1510 lexGeta(); 1690 lexGeta();
1511 /* do the \r\n -> \n or \r -> \n translation here */ 1691 /* do the \r\n -> \n or \r -> \n translation here */
1512 if (c == '\r') { 1692 if (c == '\r') {
1513 int a = (lexBuf.len>1)? 1693 int a = (lexBuf.len>1)?
1514 lexBuf.buf[(lexBuf.getPtr+1)%MAX_LEX_LOOKAHEAD]: 1694 lexBuf.buf[(lexBuf.getPtr+1)%MAX_LEX_LOOKAHEAD]:
1515 lexGeta_(1); 1695 lexGeta_(1);
1516 if (a == '\n') { 1696 if (a == '\n') {
1517 lexSkipLookahead(); 1697 lexSkipLookahead();
1518 } 1698 }
1519 lexBuf.buf[lexBuf.getPtr] = c = '\n'; 1699 lexBuf.buf[lexBuf.getPtr] = c = '\n';
1520 } 1700 }
1521 else if (c == '\n') { 1701 else if (c == '\n') {
1522 int a; 1702 int a = (lexBuf.len>1)?
1523 if (lexBuf.len > 1) 1703 lexBuf.buf[lexBuf.getPtr+1]:
1524 a = lexBuf.buf[lexBuf.getPtr]; 1704 lexGeta_(1);
1525 else
1526 a = lexGeta_(1);
1527 if (a == '\r') { 1705 if (a == '\r') {
1528 lexSkipLookahead(); 1706 lexSkipLookahead();
1529 } 1707 }
1530 lexBuf.buf[lexBuf.getPtr] = '\n'; 1708 lexBuf.buf[lexBuf.getPtr] = '\n';
1531 } 1709 }
1532 return c; 1710 return c;
1533 } 1711 }
1534 1712
1535static int lexGetc() { 1713static int lexGetc() {
1536 int c = lexLookahead(); 1714 int c = lexLookahead();
1537 if (lexBuf.len > 0 && lexBuf.buf[lexBuf.getPtr]!=EOF) { 1715 if (lexBuf.len > 0 && lexBuf.buf[lexBuf.getPtr]!=EOF) {
1538 /* EOF will remain in lookahead buffer */ 1716 /* EOF will remain in lookahead buffer */
1539 lexBuf.getPtr = (lexBuf.getPtr + 1) % MAX_LEX_LOOKAHEAD; 1717 lexBuf.getPtr = (lexBuf.getPtr + 1) % MAX_LEX_LOOKAHEAD;
1540 lexBuf.len--; 1718 lexBuf.len--;
1541 } 1719 }
1542 return c; 1720 return c;
1543 } 1721 }
1544 1722
1545static void lexSkipLookaheadWord() { 1723static void lexSkipLookaheadWord() {
1546 if (lexBuf.strsLen <= lexBuf.len) { 1724 if (lexBuf.strsLen <= lexBuf.len) {
1547 lexBuf.len -= lexBuf.strsLen; 1725 lexBuf.len -= lexBuf.strsLen;
1548 lexBuf.getPtr = (lexBuf.getPtr + lexBuf.strsLen) % MAX_LEX_LOOKAHEAD; 1726 lexBuf.getPtr = (lexBuf.getPtr + lexBuf.strsLen) % MAX_LEX_LOOKAHEAD;
1549 } 1727 }
1550 } 1728 }
1551 1729
1552static void lexClearToken() 1730static void lexClearToken()
1553 { 1731 {
1554 lexBuf.strsLen = 0; 1732 lexBuf.strsLen = 0;
1555 } 1733 }
1556 1734
1557static void lexAppendc(int c) 1735static void lexAppendc(int c)
1558 { 1736 {
1559 /* not sure if I am doing this right to fix purify report -- PGB */
1560 lexBuf.strs = (char *) realloc(lexBuf.strs, (size_t) lexBuf.strsLen + 1);
1561 lexBuf.strs[lexBuf.strsLen] = c; 1737 lexBuf.strs[lexBuf.strsLen] = c;
1562 /* append up to zero termination */ 1738 /* append up to zero termination */
1563 if (c == 0) return; 1739 if (c == 0) return;
1564 lexBuf.strsLen++; 1740 lexBuf.strsLen++;
1565 if (lexBuf.strsLen > lexBuf.maxToken) { 1741 if (lexBuf.strsLen > lexBuf.maxToken) {
1566 /* double the token string size */ 1742 /* double the token string size */
1567 lexBuf.maxToken <<= 1; 1743 lexBuf.maxToken <<= 1;
1568 lexBuf.strs = (char*) realloc(lexBuf.strs,(size_t)lexBuf.maxToken); 1744 lexBuf.strs = (char*) realloc(lexBuf.strs,(size_t)lexBuf.maxToken);
1569 } 1745 }
1570 } 1746 }
1571 1747
1572static char* lexStr() { 1748static char* lexStr() {
1573 return dupStr(lexBuf.strs,(size_t)lexBuf.strsLen+1); 1749 return dupStr(lexBuf.strs,(size_t)lexBuf.strsLen+1);
1574 } 1750 }
1575 1751
1576static void lexSkipWhite() { 1752static void lexSkipWhite() {
1577 int c = lexLookahead(); 1753 int c = lexLookahead();
1578 while (c == ' ' || c == '\t') { 1754 while (c == ' ' || c == '\t') {
1579 lexSkipLookahead(); 1755 lexSkipLookahead();
1580 c = lexLookahead(); 1756 c = lexLookahead();
1581 } 1757 }
1582 } 1758 }
1583 1759
1584static char* lexGetWord() { 1760static char* lexGetWord() {
1585 int c; 1761 int c;
1586 lexSkipWhite(); 1762 lexSkipWhite();
1587 lexClearToken(); 1763 lexClearToken();
1588 c = lexLookahead(); 1764 c = lexLookahead();
1589 /* some "words" have a space in them, like "NEEDS ACTION". 1765 while (c != EOF && !strchr("\t\n ;:=",c)) {
1590 this may be an oversight of the spec, but it is true nevertheless.
1591 while (c != EOF && !strchr("\t\n ;:=",c)) { */
1592 while (c != EOF && !strchr("\n;:=",c)) {
1593 lexAppendc(c); 1766 lexAppendc(c);
1594 lexSkipLookahead(); 1767 lexSkipLookahead();
1595 c = lexLookahead(); 1768 c = lexLookahead();
1596 } 1769 }
1597 lexAppendc(0); 1770 lexAppendc(0);
1598 return lexStr(); 1771 return lexStr();
1599 } 1772 }
1600 1773
1601void lexPushLookahead(char *s, int len) {
1602 int putptr;
1603 if (len == 0) len = strlen(s);
1604 putptr = (int)lexBuf.getPtr - len;
1605 /* this function assumes that length of word to push back
1606 / is not greater than MAX_LEX_LOOKAHEAD.
1607 */
1608 if (putptr < 0) putptr += MAX_LEX_LOOKAHEAD;
1609 lexBuf.getPtr = putptr;
1610 while (*s) {
1611 lexBuf.buf[putptr] = *s++;
1612 putptr = (putptr + 1) % MAX_LEX_LOOKAHEAD;
1613 }
1614 lexBuf.len += len;
1615 }
1616
1617static void lexPushLookaheadc(int c) { 1774static void lexPushLookaheadc(int c) {
1618 int putptr; 1775 int putptr;
1619 /* can't putback EOF, because it never leaves lookahead buffer */ 1776 /* can't putback EOF, because it never leaves lookahead buffer */
1620 if (c == EOF) return; 1777 if (c == EOF) return;
1621 putptr = (int)lexBuf.getPtr - 1; 1778 putptr = (int)lexBuf.getPtr - 1;
1622 if (putptr < 0) putptr += MAX_LEX_LOOKAHEAD; 1779 if (putptr < 0) putptr += MAX_LEX_LOOKAHEAD;
1623 lexBuf.getPtr = putptr; 1780 lexBuf.getPtr = putptr;
1624 lexBuf.buf[putptr] = c; 1781 lexBuf.buf[putptr] = c;
1625 lexBuf.len += 1; 1782 lexBuf.len += 1;
1626 } 1783 }
1627 1784
1628static char* lexLookaheadWord() { 1785static char* lexLookaheadWord() {
1629 /* this function can lookahead word with max size of MAX_LEX_LOOKAHEAD_0 1786 /* this function can lookahead word with max size of MAX_LEX_LOOKAHEAD_0
1630 / and thing bigger than that will stop the lookahead and return 0; 1787 / and thing bigger than that will stop the lookahead and return 0;
1631 / leading white spaces are not recoverable. 1788 / leading white spaces are not recoverable.
1632 */ 1789 */
1633 int c; 1790 int c;
1634 int len = 0; 1791 int len = 0;
1635 int curgetptr = 0; 1792 int curgetptr = 0;
1636 lexSkipWhite(); 1793 lexSkipWhite();
1637 lexClearToken(); 1794 lexClearToken();
1638 curgetptr = (int)lexBuf.getPtr;/* remember! */ 1795 curgetptr = (int)lexBuf.getPtr;/* remember! */
1639 while (len < (MAX_LEX_LOOKAHEAD_0)) { 1796 while (len < (MAX_LEX_LOOKAHEAD_0)) {
1640 c = lexGetc(); 1797 c = lexGetc();
1641 len++; 1798 len++;
1642 if (c == EOF || strchr("\t\n ;:=", c)) { 1799 if (c == EOF || strchr("\t\n ;:=", c)) {
1643 lexAppendc(0); 1800 lexAppendc(0);
1644 /* restore lookahead buf. */ 1801 /* restore lookahead buf. */
1645 lexBuf.len += len; 1802 lexBuf.len += len;
1646 lexBuf.getPtr = curgetptr; 1803 lexBuf.getPtr = curgetptr;
1647 return lexStr(); 1804 return lexStr();
1648 } 1805 }
1649 else 1806 else
1650 lexAppendc(c); 1807 lexAppendc(c);
1651 } 1808 }
1652 lexBuf.len += len;/* char that has been moved to lookahead buffer */ 1809 lexBuf.len += len;/* char that has been moved to lookahead buffer */
1653 lexBuf.getPtr = curgetptr; 1810 lexBuf.getPtr = curgetptr;
1654 return 0; 1811 return 0;
1655 } 1812 }
1656 1813
1657#ifdef _SUPPORT_LINE_FOLDING 1814#ifdef _SUPPORT_LINE_FOLDING
1658static void handleMoreRFC822LineBreak(int c) { 1815static void handleMoreRFC822LineBreak(int c) {
1659 /* suport RFC 822 line break in cases like 1816 /* suport RFC 822 line break in cases like
1660 *ADR: foo; 1817 *ADR: foo;
1661 * morefoo; 1818 * morefoo;
1662 * more foo; 1819 * more foo;
1663 */ 1820 */
1664 if (c == ';') { 1821 if (c == ';') {
1665 int a; 1822 int a;
1666 lexSkipLookahead(); 1823 lexSkipLookahead();
1667 /* skip white spaces */ 1824 /* skip white spaces */
1668 a = lexLookahead(); 1825 a = lexLookahead();
1669 while (a == ' ' || a == '\t') { 1826 while (a == ' ' || a == '\t') {
1670 lexSkipLookahead(); 1827 lexSkipLookahead();
1671 a = lexLookahead(); 1828 a = lexLookahead();
1672 } 1829 }
1673 if (a == '\n') { 1830 if (a == '\n') {
1674 lexSkipLookahead(); 1831 lexSkipLookahead();
1675 a = lexLookahead(); 1832 a = lexLookahead();
1676 if (a == ' ' || a == '\t') { 1833 if (a == ' ' || a == '\t') {
1677 /* continuation, throw away all the \n and spaces read so 1834 /* continuation, throw away all the \n and spaces read so
1678 * far 1835 * far
1679 */ 1836 */
1680 lexSkipWhite(); 1837 lexSkipWhite();
1681 lexPushLookaheadc(';'); 1838 lexPushLookaheadc(';');
1682 } 1839 }
1683 else { 1840 else {
1684 lexPushLookaheadc('\n'); 1841 lexPushLookaheadc('\n');
1685 lexPushLookaheadc(';'); 1842 lexPushLookaheadc(';');
1686 } 1843 }
1687 } 1844 }
1688 else { 1845 else {
1689 lexPushLookaheadc(';'); 1846 lexPushLookaheadc(';');
1690 } 1847 }
1691 } 1848 }
1692 } 1849 }
1693 1850
1694static char* lexGet1Value() { 1851static char* lexGet1Value() {
1695 int c; 1852 int c;
1696 lexSkipWhite(); 1853 lexSkipWhite();
1697 c = lexLookahead(); 1854 c = lexLookahead();
1698 lexClearToken(); 1855 lexClearToken();
1699 while (c != EOF && c != ';') { 1856 while (c != EOF && c != ';') {
1700 if (c == '\n') { 1857 if (c == '\n') {
1701 int a; 1858 int a;
1702 lexSkipLookahead(); 1859 lexSkipLookahead();
1703 a = lexLookahead(); 1860 a = lexLookahead();
1704 if (a == ' ' || a == '\t') { 1861 if (a == ' ' || a == '\t') {
1705 lexAppendc(' '); 1862 lexAppendc(' ');
1706 lexSkipLookahead(); 1863 lexSkipLookahead();
1707 } 1864 }
1708 else { 1865 else {
1709 lexPushLookaheadc('\n'); 1866 lexPushLookaheadc('\n');
1710 break; 1867 break;
1711 } 1868 }
1712 } 1869 }
1713 else { 1870 else {
1714 lexAppendc(c); 1871 lexAppendc(c);
1715 lexSkipLookahead(); 1872 lexSkipLookahead();
1716 } 1873 }
1717 c = lexLookahead(); 1874 c = lexLookahead();
1718 } 1875 }
1719 lexAppendc(0); 1876 lexAppendc(0);
1720 handleMoreRFC822LineBreak(c); 1877 handleMoreRFC822LineBreak(c);
1721 return c==EOF?0:lexStr(); 1878 return c==EOF?0:lexStr();
1722 } 1879 }
1723#endif 1880#endif
1724 1881
1725char* lexGetStrUntil(char *termset) {
1726 int c = lexLookahead();
1727 lexClearToken();
1728 while (c != EOF && !strchr(termset,c)) {
1729 lexAppendc(c);
1730 lexSkipLookahead();
1731 c = lexLookahead();
1732 }
1733 lexAppendc(0);
1734 return c==EOF?0:lexStr();
1735 }
1736 1882
1737static int match_begin_name(int end) { 1883static int match_begin_name(int end) {
1738 char *n = lexLookaheadWord(); 1884 char *n = lexLookaheadWord();
1739 int token = ID; 1885 int token = ID;
1740 if (n) { 1886 if (n) {
1741 if (!strcasecmp(n,"vcard")) token = end?END_VCARD:BEGIN_VCARD; 1887 if (!stricmp(n,"vcard")) token = end?END_VCARD:BEGIN_VCARD;
1742 else if (!strcasecmp(n,"vcalendar")) token = end?END_VCAL:BEGIN_VCAL; 1888 else if (!stricmp(n,"vcalendar")) token = end?END_VCAL:BEGIN_VCAL;
1743 else if (!strcasecmp(n,"vevent")) token = end?END_VEVENT:BEGIN_VEVENT; 1889 else if (!stricmp(n,"vevent")) token = end?END_VEVENT:BEGIN_VEVENT;
1744 else if (!strcasecmp(n,"vtodo")) token = end?END_VTODO:BEGIN_VTODO; 1890 else if (!stricmp(n,"vtodo")) token = end?END_VTODO:BEGIN_VTODO;
1745 deleteStr(n); 1891 deleteStr(n);
1746 return token; 1892 return token;
1747 } 1893 }
1748 return 0; 1894 return 0;
1749 } 1895 }
1750 1896
1751 1897
1898#ifdef INCLUDEMFC
1899void initLex(const char *inputstring, unsigned long inputlen, CFile *inputfile)
1900#else
1752void initLex(const char *inputstring, unsigned long inputlen, FILE *inputfile) 1901void initLex(const char *inputstring, unsigned long inputlen, FILE *inputfile)
1902#endif
1753 { 1903 {
1754 /* initialize lex mode stack */ 1904 /* initialize lex mode stack */
1755 lexBuf.lexModeStack[lexBuf.lexModeStackTop=0] = L_NORMAL; 1905 lexBuf.lexModeStack[lexBuf.lexModeStackTop=0] = L_NORMAL;
1756 1906
1757 /* iniatialize lex buffer. */ 1907 /* iniatialize lex buffer. */
1758 lexBuf.inputString = (char*) inputstring; 1908 lexBuf.inputString = (char*) inputstring;
1759 lexBuf.inputLen = inputlen; 1909 lexBuf.inputLen = inputlen;
1760 lexBuf.curPos = 0; 1910 lexBuf.curPos = 0;
1761 lexBuf.inputFile = inputfile; 1911 lexBuf.inputFile = inputfile;
1762 1912
1763 lexBuf.len = 0; 1913 lexBuf.len = 0;
1764 lexBuf.getPtr = 0; 1914 lexBuf.getPtr = 0;
1765 1915
1766 lexBuf.maxToken = MAXTOKEN; 1916 lexBuf.maxToken = MAXTOKEN;
1767 lexBuf.strs = (char*)malloc(MAXTOKEN); 1917 lexBuf.strs = (char*)malloc(MAXTOKEN);
1768 lexBuf.strsLen = 0; 1918 lexBuf.strsLen = 0;
1769 1919
1770 } 1920 }
1771 1921
1772static void finiLex() { 1922static void finiLex() {
1773 free(lexBuf.strs); 1923 free(lexBuf.strs);
1774 } 1924 }
1775 1925
1776 1926
1777/****************************************************************************/
1778/* This parses and converts the base64 format for binary encoding into 1927/* This parses and converts the base64 format for binary encoding into
1779 * a decoded buffer (allocated with new). See RFC 1521. 1928 * a decoded buffer (allocated with new). See RFC 1521.
1780 */ 1929 */
1781static char * lexGetDataFromBase64() 1930static char * lexGetDataFromBase64()
1782 { 1931 {
1783 unsigned long bytesLen = 0, bytesMax = 0; 1932 unsigned long bytesLen = 0, bytesMax = 0;
1784 int quadIx = 0, pad = 0; 1933 int quadIx = 0, pad = 0;
1785 unsigned long trip = 0; 1934 unsigned long trip = 0;
1786 unsigned char b; 1935 unsigned char b;
1787 int c; 1936 int c;
1788 unsigned char *bytes = NULL; 1937 unsigned char *bytes = NULL;
1789 unsigned char *oldBytes = NULL; 1938 unsigned char *oldBytes = NULL;
1790 1939
1791 DBG_(("db: lexGetDataFromBase64\n")); 1940 DBG_(("db: lexGetDataFromBase64\n"));
1792 while (1) { 1941 while (1) {
1793 c = lexGetc(); 1942 c = lexGetc();
1794 if (c == '\n') { 1943 if (c == '\n') {
1795 ++mime_lineNum; 1944 ++mime_lineNum;
1796 if (lexLookahead() == '\n') { 1945 if (lexLookahead() == '\n') {
1797 /* a '\n' character by itself means end of data */ 1946 /* a '\n' character by itself means end of data */
1798 break; 1947 break;
1799 } 1948 }
1800 else continue; /* ignore '\n' */ 1949 else continue; /* ignore '\n' */
1801 } 1950 }
1802 else { 1951 else {
1803 if ((c >= 'A') && (c <= 'Z')) 1952 if ((c >= 'A') && (c <= 'Z'))
1804 b = (unsigned char)(c - 'A'); 1953 b = (unsigned char)(c - 'A');
1805 else if ((c >= 'a') && (c <= 'z')) 1954 else if ((c >= 'a') && (c <= 'z'))
1806 b = (unsigned char)(c - 'a') + 26; 1955 b = (unsigned char)(c - 'a') + 26;
1807 else if ((c >= '0') && (c <= '9')) 1956 else if ((c >= '0') && (c <= '9'))
1808 b = (unsigned char)(c - '0') + 52; 1957 b = (unsigned char)(c - '0') + 52;
1809 else if (c == '+') 1958 else if (c == '+')
1810 b = 62; 1959 b = 62;
1811 else if (c == '/') 1960 else if (c == '/')
1812 b = 63; 1961 b = 63;
1813 else if (c == '=') { 1962 else if (c == '=') {
1814 b = 0; 1963 b = 0;
1815 pad++; 1964 pad++;
1816 } else if ((c == ' ') || (c == '\t')) { 1965 } else if ((c == ' ') || (c == '\t')) {
1817 continue; 1966 continue;
1818 } else { /* error condition */ 1967 } else { /* error condition */
1819 if (bytes) free(bytes); 1968 if (bytes) free(bytes);
1820 else if (oldBytes) free(oldBytes); 1969 else if (oldBytes) free(oldBytes);
1821 /* error recovery: skip until 2 adjacent newlines. */ 1970 /* error recovery: skip until 2 adjacent newlines. */
1822 DBG_(("db: invalid character 0x%x '%c'\n", c,c)); 1971 DBG_(("db: invalid character 0x%x '%c'\n", c,c));
1823 if (c != EOF) { 1972 if (c != EOF) {
1824 c = lexGetc(); 1973 c = lexGetc();
1825 while (c != EOF) { 1974 while (c != EOF) {
1826 if (c == '\n' && lexLookahead() == '\n') { 1975 if (c == '\n' && lexLookahead() == '\n') {
1827 ++mime_lineNum; 1976 ++mime_lineNum;
1828 break; 1977 break;
1829 } 1978 }
1830 c = lexGetc(); 1979 c = lexGetc();
1831 } 1980 }
1832 } 1981 }
1833 return NULL; 1982 return NULL;
1834 } 1983 }
1835 trip = (trip << 6) | b; 1984 trip = (trip << 6) | b;
1836 if (++quadIx == 4) { 1985 if (++quadIx == 4) {
1837 unsigned char outBytes[3]; 1986 unsigned char outBytes[3];
1838 int numOut; 1987 int numOut;
1839 int i; 1988 int i;
1840 for (i = 0; i < 3; i++) { 1989 for (i = 0; i < 3; i++) {
1841 outBytes[2-i] = (unsigned char)(trip & 0xFF); 1990 outBytes[2-i] = (unsigned char)(trip & 0xFF);
1842 trip >>= 8; 1991 trip >>= 8;
1843 } 1992 }
1844 numOut = 3 - pad; 1993 numOut = 3 - pad;
1845 if (bytesLen + numOut > bytesMax) { 1994 if (bytesLen + numOut > bytesMax) {
1846 if (!bytes) { 1995 if (!bytes) {
1847 bytesMax = 1024; 1996 bytesMax = 1024;
1848 bytes = (unsigned char*)malloc((size_t)bytesMax); 1997 bytes = (unsigned char*)malloc((size_t)bytesMax);
1849 } 1998 }
1850 else { 1999 else {
1851 bytesMax <<= 2; 2000 bytesMax <<= 2;
1852 oldBytes = bytes; 2001 oldBytes = bytes;
1853 bytes = (unsigned char*)realloc(bytes,(size_t)bytesMax); 2002 bytes = (unsigned char*)realloc(bytes,(size_t)bytesMax);
1854 } 2003 }
1855 if (bytes == 0) { 2004 if (bytes == 0) {
1856 mime_error("out of memory while processing BASE64 data\n"); 2005 mime_error("out of memory while processing BASE64 data\n");
1857 } 2006 }
1858 } 2007 }
1859 if (bytes) { 2008 if (bytes) {
1860 memcpy(bytes + bytesLen, outBytes, numOut); 2009 memcpy(bytes + bytesLen, outBytes, numOut);
1861 bytesLen += numOut; 2010 bytesLen += numOut;
1862 } 2011 }
1863 trip = 0; 2012 trip = 0;
1864 quadIx = 0; 2013 quadIx = 0;
1865 } 2014 }
1866 } 2015 }
1867 } /* while */ 2016 } /* while */
1868 DBG_(("db: bytesLen = %d\n", bytesLen)); 2017 DBG_(("db: bytesLen = %d\n", bytesLen));
1869 /* kludge: all this won't be necessary if we have tree form 2018 /* kludge: all this won't be necessary if we have tree form
1870 representation */ 2019 representation */
1871 if (bytes) { 2020 if (bytes) {
1872 setValueWithSize(curProp,bytes,(unsigned int)bytesLen); 2021 setValueWithSize(curProp,bytes,(unsigned int)bytesLen);
1873 free(bytes); 2022 free(bytes);
1874 } 2023 }
1875 else if (oldBytes) { 2024 else if (oldBytes) {
1876 setValueWithSize(curProp,oldBytes,(unsigned int)bytesLen); 2025 setValueWithSize(curProp,oldBytes,(unsigned int)bytesLen);
1877 free(oldBytes); 2026 free(oldBytes);
1878 } 2027 }
1879 return 0; 2028 return 0;
1880 } 2029 }
1881 2030
1882static int match_begin_end_name(int end) { 2031static int match_begin_end_name(int end) {
1883 int token; 2032 int token;
1884 lexSkipWhite(); 2033 lexSkipWhite();
1885 if (lexLookahead() != ':') return ID; 2034 if (lexLookahead() != ':') return ID;
1886 lexSkipLookahead(); 2035 lexSkipLookahead();
1887 lexSkipWhite(); 2036 lexSkipWhite();
1888 token = match_begin_name(end); 2037 token = match_begin_name(end);
1889 if (token == ID) { 2038 if (token == ID) {
1890 lexPushLookaheadc(':'); 2039 lexPushLookaheadc(':');
1891 DBG_(("db: ID '%s'\n", yylval.str)); 2040 DBG_(("db: ID '%s'\n", yylval.str));
1892 return ID; 2041 return ID;
1893 } 2042 }
1894 else if (token != 0) { 2043 else if (token != 0) {
1895 lexSkipLookaheadWord(); 2044 lexSkipLookaheadWord();
1896 deleteStr(yylval.str); 2045 deleteStr(yylval.str);
1897 DBG_(("db: begin/end %d\n", token)); 2046 DBG_(("db: begin/end %d\n", token));
1898 return token; 2047 return token;
1899 } 2048 }
1900 return 0; 2049 return 0;
1901 } 2050 }
1902 2051
1903static char* lexGetQuotedPrintable() 2052static char* lexGetQuotedPrintable()
1904 { 2053 {
1905 char cur; 2054 char cur;
1906 2055
1907 lexClearToken(); 2056 lexClearToken();
1908 do { 2057 do {
1909 cur = lexGetc(); 2058 cur = lexGetc();
1910 switch (cur) { 2059 switch (cur) {
1911 case '=': { 2060 case '=': {
1912 int c = 0; 2061 int c = 0;
1913 int next[2]; 2062 int next[2];
1914 int i; 2063 int i;
1915 for (i = 0; i < 2; i++) { 2064 for (i = 0; i < 2; i++) {
1916 next[i] = lexGetc(); 2065 next[i] = lexGetc();
1917 if (next[i] >= '0' && next[i] <= '9') 2066 if (next[i] >= '0' && next[i] <= '9')
1918 c = c * 16 + next[i] - '0'; 2067 c = c * 16 + next[i] - '0';
1919 else if (next[i] >= 'A' && next[i] <= 'F') 2068 else if (next[i] >= 'A' && next[i] <= 'F')
1920 c = c * 16 + next[i] - 'A' + 10; 2069 c = c * 16 + next[i] - 'A' + 10;
1921 else 2070 else
1922 break; 2071 break;
1923 } 2072 }
1924 if (i == 0) { 2073 if (i == 0) {
1925 /* single '=' follow by LINESEP is continuation sign? */ 2074 /* single '=' follow by LINESEP is continuation sign? */
1926 if (next[0] == '\n') { 2075 if (next[0] == '\n') {
1927 ++mime_lineNum; 2076 ++mime_lineNum;
1928 } 2077 }
1929 else { 2078 else {
1930 lexPushLookaheadc('='); 2079 lexPushLookaheadc('=');
1931 goto EndString; 2080 goto EndString;
1932 } 2081 }
1933 } 2082 }
1934 else if (i == 1) { 2083 else if (i == 1) {
1935 lexPushLookaheadc(next[1]); 2084 lexPushLookaheadc(next[1]);
1936 lexPushLookaheadc(next[0]); 2085 lexPushLookaheadc(next[0]);
1937 lexAppendc('='); 2086 lexAppendc('=');
1938 } else { 2087 } else {
1939 lexAppendc(c); 2088 lexAppendc(c);
1940 } 2089 }
1941 break; 2090 break;
1942 } /* '=' */ 2091 } /* '=' */
1943 case '\n': { 2092 case '\n': {
1944 lexPushLookaheadc('\n'); 2093 lexPushLookaheadc('\n');
1945 goto EndString; 2094 goto EndString;
1946 } 2095 }
1947 case (char)EOF: 2096 case (char)EOF:
1948 break; 2097 break;
1949 default: 2098 default:
1950 lexAppendc(cur); 2099 lexAppendc(cur);
1951 break; 2100 break;
1952 } /* switch */ 2101 } /* switch */
1953 } while (cur != (char)EOF); 2102 } while (cur != (char)EOF);
1954 2103
1955EndString: 2104EndString:
1956 lexAppendc(0); 2105 lexAppendc(0);
1957 return lexStr(); 2106 return lexStr();
1958 } /* LexQuotedPrintable */ 2107 } /* LexQuotedPrintable */
1959 2108
1960static int yylex() { 2109int yylex() {
1961 2110
1962 int lexmode = LEXMODE(); 2111 int lexmode = LEXMODE();
1963 if (lexmode == L_VALUES) { 2112 if (lexmode == L_VALUES) {
1964 int c = lexGetc(); 2113 int c = lexGetc();
1965 if (c == ';') { 2114 if (c == ';') {
1966 DBG_(("db: SEMICOLON\n")); 2115 DBG_(("db: SEMICOLON\n"));
1967 lexPushLookaheadc(c); 2116 lexPushLookaheadc(c);
2117#ifdef _SUPPORT_LINE_FOLDING
1968 handleMoreRFC822LineBreak(c); 2118 handleMoreRFC822LineBreak(c);
2119#endif
1969 lexSkipLookahead(); 2120 lexSkipLookahead();
1970 return SEMICOLON; 2121 return SEMICOLON;
1971 } 2122 }
1972 else if (strchr("\n",c)) { 2123 else if (strchr("\n",c)) {
1973 ++mime_lineNum; 2124 ++mime_lineNum;
1974 /* consume all line separator(s) adjacent to each other */ 2125 /* consume all line separator(s) adjacent to each other */
1975 c = lexLookahead(); 2126 c = lexLookahead();
1976 while (strchr("\n",c)) { 2127 while (strchr("\n",c)) {
1977 lexSkipLookahead(); 2128 lexSkipLookahead();
1978 c = lexLookahead(); 2129 c = lexLookahead();
1979 ++mime_lineNum; 2130 ++mime_lineNum;
1980 } 2131 }
1981 DBG_(("db: LINESEP\n")); 2132 DBG_(("db: LINESEP\n"));
1982 return LINESEP; 2133 return LINESEP;
1983 } 2134 }
1984 else { 2135 else {
1985 char *p = 0; 2136 char *p = 0;
1986 lexPushLookaheadc(c); 2137 lexPushLookaheadc(c);
1987 if (lexWithinMode(L_BASE64)) { 2138 if (lexWithinMode(L_BASE64)) {
1988 /* get each char and convert to bin on the fly... */ 2139 /* get each char and convert to bin on the fly... */
1989 p = lexGetDataFromBase64(); 2140 p = lexGetDataFromBase64();
1990 yylval.str = p; 2141 yylval.str = p;
1991 return STRING; 2142 return STRING;
1992 } 2143 }
1993 else if (lexWithinMode(L_QUOTED_PRINTABLE)) { 2144 else if (lexWithinMode(L_QUOTED_PRINTABLE)) {
1994 p = lexGetQuotedPrintable(); 2145 p = lexGetQuotedPrintable();
1995 } 2146 }
1996 else { 2147 else {
1997#ifdef _SUPPORT_LINE_FOLDING 2148#ifdef _SUPPORT_LINE_FOLDING
1998 p = lexGet1Value(); 2149 p = lexGet1Value();
1999#else 2150#else
2000 p = lexGetStrUntil(";\n"); 2151 p = lexGetStrUntil(";\n");
2001#endif 2152#endif
2002 } 2153 }
2003 if (p) { 2154 if (p) {
2004 DBG_(("db: STRING: '%s'\n", p)); 2155 DBG_(("db: STRING: '%s'\n", p));
2005 yylval.str = p; 2156 yylval.str = p;
2006 return STRING; 2157 return STRING;
2007 } 2158 }
2008 else return 0; 2159 else return 0;
2009 } 2160 }
2010 } 2161 }
2011
2012 else { 2162 else {
2013 /* normal mode */ 2163 /* normal mode */
2014 while (1) { 2164 while (1) {
2015 int c = lexGetc(); 2165 int c = lexGetc();
2016 switch(c) { 2166 switch(c) {
2017 case ':': { 2167 case ':': {
2018 /* consume all line separator(s) adjacent to each other */ 2168 /* consume all line separator(s) adjacent to each other */
2019 /* ignoring linesep immediately after colon. */ 2169 /* ignoring linesep immediately after colon. */
2020 c = lexLookahead(); 2170 /* c = lexLookahead();
2021 while (strchr("\n",c)) { 2171 while (strchr("\n",c)) {
2022 lexSkipLookahead(); 2172 lexSkipLookahead();
2023 c = lexLookahead(); 2173 c = lexLookahead();
2024 ++mime_lineNum; 2174 ++mime_lineNum;
2025 } 2175 }*/
2026 DBG_(("db: COLON\n")); 2176 DBG_(("db: COLON\n"));
2027 return COLON; 2177 return COLON;
2028 } 2178 }
2029 case ';': 2179 case ';':
2030 DBG_(("db: SEMICOLON\n")); 2180 DBG_(("db: SEMICOLON\n"));
2031 return SEMICOLON; 2181 return SEMICOLON;
2032 case '=': 2182 case '=':
2033 DBG_(("db: EQ\n")); 2183 DBG_(("db: EQ\n"));
2034 return EQ; 2184 return EQ;
2035 /* ignore tabs/newlines in this mode. We can't ignore 2185 /* ignore whitespace in this mode */
2036 * spaces, because values like NEEDS ACTION have a space. */ 2186 case '\t':
2037 case '\t': continue; 2187 case ' ': continue;
2038 case '\n': { 2188 case '\n': {
2039 ++mime_lineNum; 2189 ++mime_lineNum;
2040 continue; 2190 continue;
2041 } 2191 }
2042 case EOF: return 0; 2192 case EOF: return 0;
2043 break; 2193 break;
2044 default: { 2194 default: {
2045 lexPushLookaheadc(c); 2195 lexPushLookaheadc(c);
2046 /* pending lutz : why linker error with isalpha(c)? */ 2196 if (isalpha(c)) {
2047 /*if ( isalpha(c) || c == ' ') { */
2048 if ( ( c >= 'A' && c <= 'Z') || ( c >= 'a' && c <= 'z') || c == ' ') {
2049
2050 char *t = lexGetWord(); 2197 char *t = lexGetWord();
2051 yylval.str = t; 2198 yylval.str = t;
2052 if (!strcasecmp(t, "begin")) { 2199 if (!stricmp(t, "begin")) {
2053 return match_begin_end_name(0); 2200 return match_begin_end_name(0);
2054 } 2201 }
2055 else if (!strcasecmp(t,"end")) { 2202 else if (!stricmp(t,"end")) {
2056 return match_begin_end_name(1); 2203 return match_begin_end_name(1);
2057 } 2204 }
2058 else { 2205 else {
2059 DBG_(("db: ID '%s'\n", t)); 2206 DBG_(("db: ID '%s'\n", t));
2060 return ID; 2207 return ID;
2061 } 2208 }
2062 } 2209 }
2063 else { 2210 else {
2064 /* unknown token */ 2211 /* unknow token */
2065 return 0; 2212 return 0;
2066 } 2213 }
2067 break; 2214 break;
2068 } 2215 }
2069 } 2216 }
2070 } 2217 }
2071 } 2218 }
2072
2073 return 0; 2219 return 0;
2074 } 2220 }
2075 2221
2076 2222
2077/***************************************************************************/ 2223/***************************************************************************/
2078 /*** Public Functions ****/ 2224 /*** Public Functions ****/
2079/***************************************************************************/ 2225/***************************************************************************/
2080 2226
2081static VObject* Parse_MIMEHelper() 2227static VObject* Parse_MIMEHelper()
2082 { 2228 {
2083 ObjStackTop = -1; 2229 ObjStackTop = -1;
2084 mime_numErrors = 0; 2230 mime_numErrors = 0;
2085 mime_lineNum = 1; 2231 mime_lineNum = 1;
2086 vObjList = 0; 2232 vObjList = 0;
2087 curObj = 0; 2233 curObj = 0;
2088 2234
2089 if (yyparse() != 0) 2235 if (yyparse() != 0)
2090 return 0; 2236 return 0;
2091 2237
2092 finiLex(); 2238 finiLex();
2093 return vObjList; 2239 return vObjList;
2094 } 2240 }
2095 2241
2096/****************************************************************************/ 2242DLLEXPORT(VObject*) Parse_MIME(const char *input, unsigned long len)
2097VObject* Parse_MIME(const char *input, unsigned long len)
2098 { 2243 {
2099 initLex(input, len, 0); 2244 initLex(input, len, 0);
2100 return Parse_MIMEHelper(); 2245 return Parse_MIMEHelper();
2101 } 2246 }
2102 2247
2103 2248
2249#if INCLUDEMFC
2250
2251DLLEXPORT(VObject*) Parse_MIME_FromFile(CFile *file)
2252 {
2253 unsigned long startPos;
2254 VObject *result;
2255
2256 initLex(0,-1,file);
2257 startPos = file->GetPosition();
2258 if (!(result = Parse_MIMEHelper()))
2259 file->Seek(startPos, CFile::begin);
2260 return result;
2261 }
2262
2263#else
2264
2104VObject* Parse_MIME_FromFile(FILE *file) 2265VObject* Parse_MIME_FromFile(FILE *file)
2105 { 2266 {
2106 VObject *result; 2267 VObject *result;
2107 long startPos; 2268 long startPos;
2108 2269
2109 initLex(0,(unsigned long)-1,file); 2270 initLex(0,(unsigned long)-1,file);
2110 startPos = ftell(file); 2271 startPos = ftell(file);
2111 if (!(result = Parse_MIMEHelper())) { 2272 if (!(result = Parse_MIMEHelper())) {
2112 fseek(file,startPos,SEEK_SET); 2273 fseek(file,startPos,SEEK_SET);
2113 } 2274 }
2114 return result; 2275 return result;
2115 } 2276 }
2116 2277
2117VObject* Parse_MIME_FromFileName(const char *fname) 2278DLLEXPORT(VObject*) Parse_MIME_FromFileName(char *fname)
2118 { 2279 {
2119 FILE *fp = fopen(fname,"r"); 2280 FILE *fp = fopen(fname,"r");
2120 if (fp) { 2281 if (fp) {
2121 VObject* o = Parse_MIME_FromFile(fp); 2282 VObject* o = Parse_MIME_FromFile(fp);
2122 fclose(fp); 2283 fclose(fp);
2123 return o; 2284 return o;
2124 } 2285 }
2125 else { 2286 else {
2126 char msg[255]; 2287 char msg[256];
2127 sprintf(msg, "can't open file '%s' for reading\n", fname); 2288 snprintf(msg, sizeof(msg), "can't open file '%s' for reading\n", fname);
2128 mime_error_(msg); 2289 mime_error_(msg);
2129 return 0; 2290 return 0;
2130 } 2291 }
2131 } 2292 }
2132 2293
2133/****************************************************************************/ 2294#endif
2134void YYDebug(const char *s)
2135{
2136 Parse_Debug(s);
2137}
2138 2295
2139 2296
2140static MimeErrorHandler mimeErrorHandler; 2297static MimeErrorHandler mimeErrorHandler;
2141 2298
2142void registerMimeErrorHandler(MimeErrorHandler me) 2299DLLEXPORT(void) registerMimeErrorHandler(MimeErrorHandler me)
2143 { 2300 {
2144 mimeErrorHandler = me; 2301 mimeErrorHandler = me;
2145 } 2302 }
2146 2303
2147static void mime_error(char *s) 2304static void mime_error(char *s)
2148 { 2305 {
2149 char msg[256]; 2306 char msg[256];
2150 if (mimeErrorHandler) { 2307 if (mimeErrorHandler) {
2151 sprintf(msg,"%s at line %d", s, mime_lineNum); 2308 sprintf(msg,"%s at line %d", s, mime_lineNum);
2152 mimeErrorHandler(msg); 2309 mimeErrorHandler(msg);
2153 } 2310 }
2154 } 2311 }
2155 2312
2156static void mime_error_(char *s) 2313static void mime_error_(char *s)
2157 { 2314 {
2158 if (mimeErrorHandler) { 2315 if (mimeErrorHandler) {
2159 mimeErrorHandler(s); 2316 mimeErrorHandler(s);
2160 } 2317 }
2161 } 2318 }
2162 2319
diff --git a/libkcal/versit/vcc.h b/libkcal/versit/vcc.h
index 03886d1..0e52034 100644
--- a/libkcal/versit/vcc.h
+++ b/libkcal/versit/vcc.h
@@ -1,76 +1,80 @@
1/*************************************************************************** 1/***************************************************************************
2(C) Copyright 1996 Apple Computer, Inc., AT&T Corp., International 2(C) Copyright 1996 Apple Computer, Inc., AT&T Corp., International
3Business Machines Corporation and Siemens Rolm Communications Inc. 3Business Machines Corporation and Siemens Rolm Communications Inc.
4 4
5For purposes of this license notice, the term Licensors shall mean, 5For purposes of this license notice, the term Licensors shall mean,
6collectively, Apple Computer, Inc., AT&T Corp., International 6collectively, Apple Computer, Inc., AT&T Corp., International
7Business Machines Corporation and Siemens Rolm Communications Inc. 7Business Machines Corporation and Siemens Rolm Communications Inc.
8The term Licensor shall mean any of the Licensors. 8The term Licensor shall mean any of the Licensors.
9 9
10Subject to acceptance of the following conditions, permission is hereby 10Subject to acceptance of the following conditions, permission is hereby
11granted by Licensors without the need for written agreement and without 11granted by Licensors without the need for written agreement and without
12license or royalty fees, to use, copy, modify and distribute this 12license or royalty fees, to use, copy, modify and distribute this
13software for any purpose. 13software for any purpose.
14 14
15The above copyright notice and the following four paragraphs must be 15The above copyright notice and the following four paragraphs must be
16reproduced in all copies of this software and any software including 16reproduced in all copies of this software and any software including
17this software. 17this software.
18 18
19THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS AND NO LICENSOR SHALL HAVE 19THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS AND NO LICENSOR SHALL HAVE
20ANY OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR 20ANY OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR
21MODIFICATIONS. 21MODIFICATIONS.
22 22
23IN NO EVENT SHALL ANY LICENSOR BE LIABLE TO ANY PARTY FOR DIRECT, 23IN NO EVENT SHALL ANY LICENSOR BE LIABLE TO ANY PARTY FOR DIRECT,
24INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT 24INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT
25OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 25OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
26DAMAGE. 26DAMAGE.
27 27
28EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, 28EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED,
29INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE 29INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE
30IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 30IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31PURPOSE. 31PURPOSE.
32 32
33The software is provided with RESTRICTED RIGHTS. Use, duplication, or 33The software is provided with RESTRICTED RIGHTS. Use, duplication, or
34disclosure by the government are subject to restrictions set forth in 34disclosure by the government are subject to restrictions set forth in
35DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable. 35DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable.
36 36
37***************************************************************************/ 37***************************************************************************/
38 38
39#ifndef __VCC_H__ 39#ifndef __VCC_H__
40#define __VCC_H__ 1 40#define __VCC_H__ 1
41 41
42#include "vobject.h" 42#include "vobject.h"
43 43
44 44
45#if defined(__CPLUSPLUS__) || defined(__cplusplus) 45#if defined(__CPLUSPLUS__) || defined(__cplusplus)
46extern "C" { 46extern "C" {
47#endif 47#endif
48 48
49typedef void (*MimeErrorHandler)(char *); 49typedef void (*MimeErrorHandler)(char *);
50 50
51extern void registerMimeErrorHandler(MimeErrorHandler); 51extern DLLEXPORT(void) registerMimeErrorHandler(MimeErrorHandler);
52 52
53extern VObject* Parse_MIME(const char *input, unsigned long len); 53extern DLLEXPORT(VObject*) Parse_MIME(const char *input, unsigned long len);
54extern VObject* Parse_MIME_FromFileName(const char* fname); 54extern DLLEXPORT(VObject*) Parse_MIME_FromFileName(char* fname);
55 55
56 56
57/* NOTE regarding Parse_MIME_FromFile 57/* NOTE regarding Parse_MIME_FromFile
58The function below, Parse_MIME_FromFile, come in two flavors, 58The function above, Parse_MIME_FromFile, comes in two flavors,
59neither of which is exported from the DLL. Each version takes 59neither of which is exported from the DLL. Each version takes
60a CFile or FILE* as a parameter, neither of which can be 60a CFile or FILE* as a parameter, neither of which can be
61passed across a DLL interface (at least that is my experience). 61passed across a DLL interface (at least that is my experience).
62If you are linking this code into your build directly then 62If you are linking this code into your build directly then
63you may find them a more convenient API that the other flavors 63you may find them a more convenient API that the other flavors
64that take a file name. If you use them with the DLL LIB you 64that take a file name. If you use them with the DLL LIB you
65will get a link error. 65will get a link error.
66*/ 66*/
67 67
68 68
69#if INCLUDEMFC
70extern VObject* Parse_MIME_FromFile(CFile *file);
71#else
69extern VObject* Parse_MIME_FromFile(FILE *file); 72extern VObject* Parse_MIME_FromFile(FILE *file);
73#endif
70 74
71#if defined(__CPLUSPLUS__) || defined(__cplusplus) 75#if defined(__CPLUSPLUS__) || defined(__cplusplus)
72} 76}
73#endif 77#endif
74 78
75#endif /* __VCC_H__ */ 79#endif /* __VCC_H__ */
76 80
diff --git a/libkcal/versit/vobject.c b/libkcal/versit/vobject.c
index 637efb2..3fac63e 100644
--- a/libkcal/versit/vobject.c
+++ b/libkcal/versit/vobject.c
@@ -1,1433 +1,1454 @@
1/*************************************************************************** 1/***************************************************************************
2(C) Copyright 1996 Apple Computer, Inc., AT&T Corp., International 2(C) Copyright 1996 Apple Computer, Inc., AT&T Corp., International
3Business Machines Corporation and Siemens Rolm Communications Inc. 3Business Machines Corporation and Siemens Rolm Communications Inc.
4 4
5For purposes of this license notice, the term Licensors shall mean, 5For purposes of this license notice, the term Licensors shall mean,
6collectively, Apple Computer, Inc., AT&T Corp., International 6collectively, Apple Computer, Inc., AT&T Corp., International
7Business Machines Corporation and Siemens Rolm Communications Inc. 7Business Machines Corporation and Siemens Rolm Communications Inc.
8The term Licensor shall mean any of the Licensors. 8The term Licensor shall mean any of the Licensors.
9 9
10Subject to acceptance of the following conditions, permission is hereby 10Subject to acceptance of the following conditions, permission is hereby
11granted by Licensors without the need for written agreement and without 11granted by Licensors without the need for written agreement and without
12license or royalty fees, to use, copy, modify and distribute this 12license or royalty fees, to use, copy, modify and distribute this
13software for any purpose. 13software for any purpose.
14 14
15The above copyright notice and the following four paragraphs must be 15The above copyright notice and the following four paragraphs must be
16reproduced in all copies of this software and any software including 16reproduced in all copies of this software and any software including
17this software. 17this software.
18 18
19THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS AND NO LICENSOR SHALL HAVE 19THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS AND NO LICENSOR SHALL HAVE
20ANY OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR 20ANY OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR
21MODIFICATIONS. 21MODIFICATIONS.
22 22
23IN NO EVENT SHALL ANY LICENSOR BE LIABLE TO ANY PARTY FOR DIRECT, 23IN NO EVENT SHALL ANY LICENSOR BE LIABLE TO ANY PARTY FOR DIRECT,
24INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT 24INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT
25OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 25OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
26DAMAGE. 26DAMAGE.
27 27
28EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, 28EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED,
29INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE 29INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE
30IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 30IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31PURPOSE. 31PURPOSE.
32 32
33The software is provided with RESTRICTED RIGHTS. Use, duplication, or 33The software is provided with RESTRICTED RIGHTS. Use, duplication, or
34disclosure by the government are subject to restrictions set forth in 34disclosure by the government are subject to restrictions set forth in
35DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable. 35DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable.
36 36
37***************************************************************************/ 37***************************************************************************/
38 38
39/* 39/*
40 * src: vobject.c 40 * src: vobject.c
41 * doc: vobject and APIs to construct vobject, APIs pretty print 41 * doc: vobject and APIs to construct vobject, APIs pretty print
42 * vobject, and convert a vobject into its textual representation. 42 * vobject, and convert a vobject into its textual representation.
43 */ 43 */
44 44
45#include <stdlib.h> 45#ifdef WIN32
46#define snprintf _snprintf
47#define strcasecmp stricmp
48#endif
46 49
47#include "vobject.h" 50#include "vobject.h"
51#include <stdlib.h>
48#include <string.h> 52#include <string.h>
49#include <stdio.h> 53#include <stdio.h>
50#ifdef _WIN32_ 54#include <fcntl.h>
51 55
52 #define strcasecmp _stricmp
53 56
54#endif 57 #define NAME_OF(o) o->id
55
56 #define NAME_OF(o) o->id
57 #define VALUE_TYPE(o) o->valType 58 #define VALUE_TYPE(o) o->valType
58 #define STRINGZ_VALUE_OF(o) o->val.strs 59 #define STRINGZ_VALUE_OF(o) o->val.strs
59 #define USTRINGZ_VALUE_OF(o)o->val.ustrs 60 #define USTRINGZ_VALUE_OF(o)o->val.ustrs
60 #define INTEGER_VALUE_OF(o) o->val.i 61 #define INTEGER_VALUE_OF(o) o->val.i
61 #define LONG_VALUE_OF(o) o->val.l 62 #define LONG_VALUE_OF(o) o->val.l
62 #define ANY_VALUE_OF(o) o->val.any 63 #define ANY_VALUE_OF(o) o->val.any
63 #define VOBJECT_VALUE_OF(o) o->val.vobj 64 #define VOBJECT_VALUE_OF(o) o->val.vobj
64 65
66typedef union ValueItem {
67 const char *strs;
68 const wchar_t *ustrs;
69 unsigned int i;
70 unsigned long l;
71 void *any;
72 VObject *vobj;
73 } ValueItem;
74
75struct VObject {
76 VObject *next;
77 const char *id;
78 VObject *prop;
79 unsigned short valType;
80 ValueItem val;
81 };
82
83typedef struct StrItem StrItem;
84
85struct StrItem {
86 StrItem *next;
87 const char *s;
88 unsigned int refCnt;
89 };
90
65const char** fieldedProp; 91const char** fieldedProp;
66 92
67 93
68 94
69/*---------------------------------------------------------------------- 95/*----------------------------------------------------------------------
70 The following functions involve with memory allocation: 96 The following functions involve with memory allocation:
71 newVObject 97 newVObject
72 deleteVObject 98 deleteVObject
73 dupStr 99 dupStr
74 deleteStr 100 deleteStr
75 newStrItem 101 newStrItem
76 deleteStrItem 102 deleteStrItem
77 ----------------------------------------------------------------------*/ 103 ----------------------------------------------------------------------*/
78 104
79VObject* newVObject_(const char *id) 105DLLEXPORT(VObject*) newVObject_(const char *id)
80{ 106{
81 VObject *p = (VObject*)malloc(sizeof(VObject)); 107 VObject *p = (VObject*)malloc(sizeof(VObject));
82 p->next = 0; 108 p->next = 0;
83 p->id = id; 109 p->id = id;
84 p->prop = 0; 110 p->prop = 0;
85 VALUE_TYPE(p) = 0; 111 VALUE_TYPE(p) = 0;
86 ANY_VALUE_OF(p) = 0; 112 ANY_VALUE_OF(p) = 0;
87 return p; 113 return p;
88} 114}
89 115
90VObject* newVObject(const char *id) 116DLLEXPORT(VObject*) newVObject(const char *id)
91{ 117{
92 return newVObject_(lookupStr(id)); 118 return newVObject_(lookupStr(id));
93} 119}
94 120
95void deleteVObject(VObject *p) 121DLLEXPORT(void) deleteVObject(VObject *p)
96{ 122{
97 if (p->id)
98 unUseStr(p->id); 123 unUseStr(p->id);
99 if (p)
100 free(p); 124 free(p);
101 p = NULL;
102} 125}
103 126
104char* dupStr(const char *s, unsigned int size) 127DLLEXPORT(char*) dupStr(const char *s, unsigned int size)
105{ 128{
106 char *t; 129 char *t;
107 if (size == 0) { 130 if (size == 0) {
108 size = strlen(s); 131 size = strlen(s);
109 } 132 }
110 t = (char*)malloc(size+1); 133 t = (char*)malloc(size+1);
111 if (t) { 134 if (t) {
112 memcpy(t,s,size); 135 memcpy(t,s,size);
113 t[size] = 0; 136 t[size] = 0;
114 return t; 137 return t;
115 } 138 }
116 else { 139 else {
117 return (char*)0; 140 return (char*)0;
118 } 141 }
119} 142}
120 143
121void deleteStr(const char *p) 144DLLEXPORT(void) deleteStr(const char *p)
122{ 145{
123 if (p) 146 if (p) free((void*)p);
124 free((void*)p);
125 p = NULL;
126} 147}
127 148
128 149
129static StrItem* newStrItem(const char *s, StrItem *next) 150static StrItem* newStrItem(const char *s, StrItem *next)
130{ 151{
131 StrItem *p = (StrItem*)malloc(sizeof(StrItem)); 152 StrItem *p = (StrItem*)malloc(sizeof(StrItem));
132 p->next = next; 153 p->next = next;
133 p->s = s; 154 p->s = s;
134 p->refCnt = 1; 155 p->refCnt = 1;
135 return p; 156 return p;
136} 157}
137 158
138static void deleteStrItem(StrItem *p) 159static void deleteStrItem(StrItem *p)
139{ 160{
140 if (p) 161 free((void*)p);
141 free((void*)p);
142 p = NULL;
143} 162}
144 163
145 164
146/*---------------------------------------------------------------------- 165/*----------------------------------------------------------------------
147 The following function provide accesses to VObject's value. 166 The following function provide accesses to VObject's value.
148 ----------------------------------------------------------------------*/ 167 ----------------------------------------------------------------------*/
149 168
150const char* vObjectName(VObject *o) 169DLLEXPORT(const char*) vObjectName(VObject *o)
151{ 170{
152 return NAME_OF(o); 171 return NAME_OF(o);
153} 172}
154 173
155void setVObjectName(VObject *o, const char* id) 174DLLEXPORT(void) setVObjectName(VObject *o, const char* id)
156{ 175{
157 NAME_OF(o) = id; 176 NAME_OF(o) = id;
158} 177}
159 178
160const char* vObjectStringZValue(VObject *o) 179DLLEXPORT(const char*) vObjectStringZValue(VObject *o)
161{ 180{
162 return STRINGZ_VALUE_OF(o); 181 return STRINGZ_VALUE_OF(o);
163} 182}
164 183
165void setVObjectStringZValue(VObject *o, const char *s) 184DLLEXPORT(void) setVObjectStringZValue(VObject *o, const char *s)
166{ 185{
167 STRINGZ_VALUE_OF(o) = dupStr(s,0); 186 STRINGZ_VALUE_OF(o) = dupStr(s,0);
168 VALUE_TYPE(o) = VCVT_STRINGZ; 187 VALUE_TYPE(o) = VCVT_STRINGZ;
169} 188}
170 189
171void setVObjectStringZValue_(VObject *o, const char *s) 190DLLEXPORT(void) setVObjectStringZValue_(VObject *o, const char *s)
172{ 191{
173 STRINGZ_VALUE_OF(o) = s; 192 STRINGZ_VALUE_OF(o) = s;
174 VALUE_TYPE(o) = VCVT_STRINGZ; 193 VALUE_TYPE(o) = VCVT_STRINGZ;
175} 194}
176 195
177const wchar_t* vObjectUStringZValue(VObject *o) 196DLLEXPORT(const wchar_t*) vObjectUStringZValue(VObject *o)
178{ 197{
179 return USTRINGZ_VALUE_OF(o); 198 return USTRINGZ_VALUE_OF(o);
180} 199}
181 200
182void setVObjectUStringZValue(VObject *o, const wchar_t *s) 201DLLEXPORT(void) setVObjectUStringZValue(VObject *o, const wchar_t *s)
183{ 202{
184 USTRINGZ_VALUE_OF(o) = (wchar_t*) dupStr((char*)s,(uStrLen(s)+1)*2); 203 USTRINGZ_VALUE_OF(o) = (wchar_t*) dupStr((char*)s,(uStrLen(s)+1)*2);
185 VALUE_TYPE(o) = VCVT_USTRINGZ; 204 VALUE_TYPE(o) = VCVT_USTRINGZ;
186} 205}
187 206
188void setVObjectUStringZValue_(VObject *o, const wchar_t *s) 207DLLEXPORT(void) setVObjectUStringZValue_(VObject *o, const wchar_t *s)
189{ 208{
190 USTRINGZ_VALUE_OF(o) = s; 209 USTRINGZ_VALUE_OF(o) = s;
191 VALUE_TYPE(o) = VCVT_USTRINGZ; 210 VALUE_TYPE(o) = VCVT_USTRINGZ;
192} 211}
193 212
194unsigned int vObjectIntegerValue(VObject *o) 213DLLEXPORT(unsigned int) vObjectIntegerValue(VObject *o)
195{ 214{
196 return INTEGER_VALUE_OF(o); 215 return INTEGER_VALUE_OF(o);
197} 216}
198 217
199void setVObjectIntegerValue(VObject *o, unsigned int i) 218DLLEXPORT(void) setVObjectIntegerValue(VObject *o, unsigned int i)
200{ 219{
201 INTEGER_VALUE_OF(o) = i; 220 INTEGER_VALUE_OF(o) = i;
202 VALUE_TYPE(o) = VCVT_UINT; 221 VALUE_TYPE(o) = VCVT_UINT;
203} 222}
204 223
205unsigned long vObjectLongValue(VObject *o) 224DLLEXPORT(unsigned long) vObjectLongValue(VObject *o)
206{ 225{
207 return LONG_VALUE_OF(o); 226 return LONG_VALUE_OF(o);
208} 227}
209 228
210void setVObjectLongValue(VObject *o, unsigned long l) 229DLLEXPORT(void) setVObjectLongValue(VObject *o, unsigned long l)
211{ 230{
212 LONG_VALUE_OF(o) = l; 231 LONG_VALUE_OF(o) = l;
213 VALUE_TYPE(o) = VCVT_ULONG; 232 VALUE_TYPE(o) = VCVT_ULONG;
214} 233}
215 234
216void* vObjectAnyValue(VObject *o) 235DLLEXPORT(void*) vObjectAnyValue(VObject *o)
217{ 236{
218 return ANY_VALUE_OF(o); 237 return ANY_VALUE_OF(o);
219} 238}
220 239
221void setVObjectAnyValue(VObject *o, void *t) 240DLLEXPORT(void) setVObjectAnyValue(VObject *o, void *t)
222{ 241{
223 ANY_VALUE_OF(o) = t; 242 ANY_VALUE_OF(o) = t;
224 VALUE_TYPE(o) = VCVT_RAW; 243 VALUE_TYPE(o) = VCVT_RAW;
225} 244}
226 245
227VObject* vObjectVObjectValue(VObject *o) 246DLLEXPORT(VObject*) vObjectVObjectValue(VObject *o)
228{ 247{
229 return VOBJECT_VALUE_OF(o); 248 return VOBJECT_VALUE_OF(o);
230} 249}
231 250
232void setVObjectVObjectValue(VObject *o, VObject *p) 251DLLEXPORT(void) setVObjectVObjectValue(VObject *o, VObject *p)
233{ 252{
234 VOBJECT_VALUE_OF(o) = p; 253 VOBJECT_VALUE_OF(o) = p;
235 VALUE_TYPE(o) = VCVT_VOBJECT; 254 VALUE_TYPE(o) = VCVT_VOBJECT;
236} 255}
237 256
238int vObjectValueType(VObject *o) 257DLLEXPORT(int) vObjectValueType(VObject *o)
239{ 258{
240 return VALUE_TYPE(o); 259 return VALUE_TYPE(o);
241} 260}
242 261
243 262
244/*---------------------------------------------------------------------- 263/*----------------------------------------------------------------------
245 The following functions can be used to build VObject. 264 The following functions can be used to build VObject.
246 ----------------------------------------------------------------------*/ 265 ----------------------------------------------------------------------*/
247 266
248VObject* addVObjectProp(VObject *o, VObject *p) 267DLLEXPORT(VObject*) addVObjectProp(VObject *o, VObject *p)
249{ 268{
250 /* circular link list pointed to tail */ 269 /* circular link list pointed to tail */
251 /* 270 /*
252 o {next,id,prop,val} 271 o {next,id,prop,val}
253 V 272 V
254 pn {next,id,prop,val} 273 pn {next,id,prop,val}
255 V 274 V
256 ... 275 ...
257 p1 {next,id,prop,val} 276 p1 {next,id,prop,val}
258 V 277 V
259 pn 278 pn
260 --> 279 -->
261 o {next,id,prop,val} 280 o {next,id,prop,val}
262 V 281 V
263 pn {next,id,prop,val} 282 pn {next,id,prop,val}
264 V 283 V
265 p {next,id,prop,val} 284 p {next,id,prop,val}
266 ... 285 ...
267 p1 {next,id,prop,val} 286 p1 {next,id,prop,val}
268 V 287 V
269 pn 288 pn
270 */ 289 */
271 290
272 VObject *tail = o->prop; 291 VObject *tail = o->prop;
273 if (tail) { 292 if (tail) {
274 p->next = tail->next; 293 p->next = tail->next;
275 o->prop = tail->next = p; 294 o->prop = tail->next = p;
276 } 295 }
277 else { 296 else {
278 o->prop = p->next = p; 297 o->prop = p->next = p;
279 } 298 }
280 return p; 299 return p;
281} 300}
282 301
283VObject* addProp(VObject *o, const char *id) 302DLLEXPORT(VObject*) addProp(VObject *o, const char *id)
284{ 303{
285 return addVObjectProp(o,newVObject(id)); 304 return addVObjectProp(o,newVObject(id));
286} 305}
287 306
288VObject* addProp_(VObject *o, const char *id) 307DLLEXPORT(VObject*) addProp_(VObject *o, const char *id)
289{ 308{
290 return addVObjectProp(o,newVObject_(id)); 309 return addVObjectProp(o,newVObject_(id));
291} 310}
292 311
293void addList(VObject **o, VObject *p) 312DLLEXPORT(void) addList(VObject **o, VObject *p)
294{ 313{
295 p->next = 0; 314 p->next = 0;
296 if (*o == 0) { 315 if (*o == 0) {
297 *o = p; 316 *o = p;
298 } 317 }
299 else { 318 else {
300 VObject *t = *o; 319 VObject *t = *o;
301 while (t->next) { 320 while (t->next) {
302 t = t->next; 321 t = t->next;
303 } 322 }
304 t->next = p; 323 t->next = p;
305 } 324 }
306} 325}
307 326
308VObject* nextVObjectInList(VObject *o) 327DLLEXPORT(VObject*) nextVObjectInList(VObject *o)
309{ 328{
310 return o->next; 329 return o->next;
311} 330}
312 331
313VObject* setValueWithSize_(VObject *prop, void *val, unsigned int size) 332DLLEXPORT(VObject*) setValueWithSize_(VObject *prop, void *val, unsigned int size)
314{ 333{
315 VObject *sizeProp; 334 VObject *sizeProp;
316 setVObjectAnyValue(prop, val); 335 setVObjectAnyValue(prop, val);
317 sizeProp = addProp(prop,VCDataSizeProp); 336 sizeProp = addProp(prop,VCDataSizeProp);
318 setVObjectLongValue(sizeProp, size); 337 setVObjectLongValue(sizeProp, size);
319 return prop; 338 return prop;
320} 339}
321 340
322VObject* setValueWithSize(VObject *prop, void *val, unsigned int size) 341DLLEXPORT(VObject*) setValueWithSize(VObject *prop, void *val, unsigned int size)
323{ 342{
324 void *p = dupStr(val,size); 343 void *p = dupStr((const char *)val,size);
325 return setValueWithSize_(prop,p,p?size:0); 344 return setValueWithSize_(prop,p,p?size:0);
326} 345}
327 346
328void initPropIterator(VObjectIterator *i, VObject *o) 347DLLEXPORT(void) initPropIterator(VObjectIterator *i, VObject *o)
329{ 348{
330 i->start = o->prop; 349 i->start = o->prop;
331 i->next = 0; 350 i->next = 0;
332} 351}
333 352
334void initVObjectIterator(VObjectIterator *i, VObject *o) 353DLLEXPORT(void) initVObjectIterator(VObjectIterator *i, VObject *o)
335{ 354{
336 i->start = o->next; 355 i->start = o->next;
337 i->next = 0; 356 i->next = 0;
338} 357}
339 358
340int moreIteration(VObjectIterator *i) 359DLLEXPORT(int) moreIteration(VObjectIterator *i)
341{ 360{
342 return (i->start && (i->next==0 || i->next!=i->start)); 361 return (i->start && (i->next==0 || i->next!=i->start));
343} 362}
344 363
345VObject* nextVObject(VObjectIterator *i) 364DLLEXPORT(VObject*) nextVObject(VObjectIterator *i)
346{ 365{
347 if (i->start && i->next != i->start) { 366 if (i->start && i->next != i->start) {
348 if (i->next == 0) { 367 if (i->next == 0) {
349 i->next = i->start->next; 368 i->next = i->start->next;
350 return i->next; 369 return i->next;
351 } 370 }
352 else { 371 else {
353 i->next = i->next->next; 372 i->next = i->next->next;
354 return i->next; 373 return i->next;
355 } 374 }
356 } 375 }
357 else return (VObject*)0; 376 else return (VObject*)0;
358} 377}
359 378
360VObject* isAPropertyOf(VObject *o, const char *id) 379DLLEXPORT(VObject*) isAPropertyOf(VObject *o, const char *id)
361{ 380{
362 VObjectIterator i; 381 VObjectIterator i;
363 initPropIterator(&i,o); 382 initPropIterator(&i,o);
364 while (moreIteration(&i)) { 383 while (moreIteration(&i)) {
365 VObject *each = nextVObject(&i); 384 VObject *each = nextVObject(&i);
366 if (!strcasecmp(id,each->id)) 385 if (!stricmp(id,each->id))
367 return each; 386 return each;
368 } 387 }
369 return (VObject*)0; 388 return (VObject*)0;
370} 389}
371 390
372VObject* addGroup(VObject *o, const char *g) 391DLLEXPORT(VObject*) addGroup(VObject *o, const char *g)
373{ 392{
374 /* 393 /*
375 a.b.c 394 a.b.c
376 --> 395 -->
377 prop(c) 396 prop(c)
378 prop(VCGrouping=b) 397 prop(VCGrouping=b)
379 prop(VCGrouping=a) 398 prop(VCGrouping=a)
380 */ 399 */
381 char *dot = strrchr(g,'.'); 400 char *dot = strrchr(g,'.');
382 if (dot) { 401 if (dot) {
383 VObject *p, *t; 402 VObject *p, *t;
384 char *gs, *n = dot+1; 403 char *gs, *n = dot+1;
385 gs = dupStr(g,0);/* so we can write to it. */ 404 gs = dupStr(g,0);/* so we can write to it. */
386 /* used to be 405 /* used to be
387 * t = p = addProp_(o,lookupProp_(n)); 406 * t = p = addProp_(o,lookupProp_(n));
388 */ 407 */
389 t = p = addProp_(o,lookupProp(n)); 408 t = p = addProp_(o,lookupProp(n));
390 dot = strrchr(gs,'.'); 409 dot = strrchr(gs,'.');
391 *dot = 0; 410 *dot = 0;
392 do { 411 do {
393 dot = strrchr(gs,'.'); 412 dot = strrchr(gs,'.');
394 if (dot) { 413 if (dot) {
395 n = dot+1; 414 n = dot+1;
396 *dot=0; 415 *dot=0;
397 } 416 }
398 else 417 else
399 n = gs; 418 n = gs;
400 /* property(VCGroupingProp=n); 419 /* property(VCGroupingProp=n);
401 *and the value may have VCGrouping property 420 *and the value may have VCGrouping property
402 */ 421 */
403 t = addProp(t,VCGroupingProp); 422 t = addProp(t,VCGroupingProp);
404 setVObjectStringZValue(t,lookupProp_(n)); 423 setVObjectStringZValue(t,lookupProp_(n));
405 } while (n != gs); 424 } while (n != gs);
406 deleteStr(gs); 425 deleteStr(gs);
407 return p; 426 return p;
408 } 427 }
409 else 428 else
410 return addProp_(o,lookupProp(g)); 429 return addProp_(o,lookupProp(g));
411} 430}
412 431
413VObject* addPropValue(VObject *o, const char *p, const char *v) 432DLLEXPORT(VObject*) addPropValue(VObject *o, const char *p, const char *v)
414{ 433{
415 VObject *prop; 434 VObject *prop;
416 prop = addProp(o,p); 435 prop = addProp(o,p);
417 setVObjectUStringZValue_(prop, fakeUnicode(v,0)); 436 setVObjectUStringZValue_(prop, fakeUnicode(v,0));
418 return prop; 437 return prop;
419} 438}
420 439
421VObject* addPropSizedValue_(VObject *o, const char *p, const char *v, 440DLLEXPORT(VObject*) addPropSizedValue_(VObject *o, const char *p, const char *v,
422 unsigned int size) 441 unsigned int size)
423{ 442{
424 VObject *prop; 443 VObject *prop;
425 prop = addProp(o,p); 444 prop = addProp(o,p);
426 setValueWithSize_(prop, (void*)v, size); 445 setValueWithSize_(prop, (void*)v, size);
427 return prop; 446 return prop;
428} 447}
429 448
430VObject* addPropSizedValue(VObject *o, const char *p, const char *v, 449DLLEXPORT(VObject*) addPropSizedValue(VObject *o, const char *p, const char *v,
431 unsigned int size) 450 unsigned int size)
432{ 451{
433 return addPropSizedValue_(o,p,dupStr(v,size),size); 452 return addPropSizedValue_(o,p,dupStr(v,size),size);
434} 453}
435 454
436 455
437 456
438/*---------------------------------------------------------------------- 457/*----------------------------------------------------------------------
439 The following pretty print a VObject 458 The following pretty print a VObject
440 ----------------------------------------------------------------------*/ 459 ----------------------------------------------------------------------*/
441 460
442static void printVObject_(FILE *fp, VObject *o, int level); 461static void printVObject_(FILE *fp, VObject *o, int level);
443 462
444static void indent(FILE *fp, int level) 463static void indent(FILE *fp, int level)
445{ 464{
446 int i; 465 int i;
447 for (i=0;i<level*4;i++) { 466 for (i=0;i<level*4;i++) {
448 fputc(' ', fp); 467 fputc(' ', fp);
449 } 468 }
450} 469}
451 470
452static void printValue(FILE *fp, VObject *o, int level) 471static void printValue(FILE *fp, VObject *o, int level)
453{ 472{
454 switch (VALUE_TYPE(o)) { 473 switch (VALUE_TYPE(o)) {
455 case VCVT_USTRINGZ: { 474 case VCVT_USTRINGZ: {
456 char c; 475 char c;
457 char *t,*s; 476 char *t,*s;
458 s = t = fakeCString(USTRINGZ_VALUE_OF(o)); 477 s = t = fakeCString(USTRINGZ_VALUE_OF(o));
459 fputc('"',fp); 478 fputc('"',fp);
460 while (c=*t,c) { 479 while (c=*t,c) {
461 fputc(c,fp); 480 fputc(c,fp);
462 if (c == '\n') indent(fp,level+2); 481 if (c == '\n') indent(fp,level+2);
463 t++; 482 t++;
464 } 483 }
465 fputc('"',fp); 484 fputc('"',fp);
466 deleteStr(s); 485 deleteStr(s);
467 break; 486 break;
468 } 487 }
469 case VCVT_STRINGZ: { 488 case VCVT_STRINGZ: {
470 char c; 489 char c;
471 const char *s = STRINGZ_VALUE_OF(o); 490 const char *s = STRINGZ_VALUE_OF(o);
472 fputc('"',fp); 491 fputc('"',fp);
473 while (c=*s,c) { 492 while (c=*s,c) {
474 fputc(c,fp); 493 fputc(c,fp);
475 if (c == '\n') indent(fp,level+2); 494 if (c == '\n') indent(fp,level+2);
476 s++; 495 s++;
477 } 496 }
478 fputc('"',fp); 497 fputc('"',fp);
479 break; 498 break;
480 } 499 }
481 case VCVT_UINT: 500 case VCVT_UINT:
482 fprintf(fp,"%d", INTEGER_VALUE_OF(o)); break; 501 fprintf(fp,"%d", INTEGER_VALUE_OF(o)); break;
483 case VCVT_ULONG: 502 case VCVT_ULONG:
484 fprintf(fp,"%ld", LONG_VALUE_OF(o)); break; 503 fprintf(fp,"%ld", LONG_VALUE_OF(o)); break;
485 case VCVT_RAW: 504 case VCVT_RAW:
486 fprintf(fp,"[raw data]"); break; 505 fprintf(fp,"[raw data]"); break;
487 case VCVT_VOBJECT: 506 case VCVT_VOBJECT:
488 fprintf(fp,"[vobject]\n"); 507 fprintf(fp,"[vobject]\n");
489 printVObject_(fp,VOBJECT_VALUE_OF(o),level+1); 508 printVObject_(fp,VOBJECT_VALUE_OF(o),level+1);
490 break; 509 break;
491 case 0: 510 case 0:
492 fprintf(fp,"[none]"); break; 511 fprintf(fp,"[none]"); break;
493 default: 512 default:
494 fprintf(fp,"[unknown]"); break; 513 fprintf(fp,"[unknown]"); break;
495 } 514 }
496} 515}
497 516
498static void printNameValue(FILE *fp,VObject *o, int level) 517static void printNameValue(FILE *fp,VObject *o, int level)
499{ 518{
500 indent(fp,level); 519 indent(fp,level);
501 if (NAME_OF(o)) { 520 if (NAME_OF(o)) {
502 fprintf(fp,"%s", NAME_OF(o)); 521 fprintf(fp,"%s", NAME_OF(o));
503 } 522 }
504 if (VALUE_TYPE(o)) { 523 if (VALUE_TYPE(o)) {
505 fputc('=',fp); 524 fputc('=',fp);
506 printValue(fp,o, level); 525 printValue(fp,o, level);
507 } 526 }
508 fprintf(fp,"\n"); 527 fprintf(fp,"\n");
509} 528}
510 529
511static void printVObject_(FILE *fp, VObject *o, int level) 530static void printVObject_(FILE *fp, VObject *o, int level)
512 { 531 {
513 VObjectIterator t; 532 VObjectIterator t;
514 if (o == 0) { 533 if (o == 0) {
515 fprintf(fp,"[NULL]\n"); 534 fprintf(fp,"[NULL]\n");
516 return; 535 return;
517 } 536 }
518 printNameValue(fp,o,level); 537 printNameValue(fp,o,level);
519 initPropIterator(&t,o); 538 initPropIterator(&t,o);
520 while (moreIteration(&t)) { 539 while (moreIteration(&t)) {
521 VObject *eachProp = nextVObject(&t); 540 VObject *eachProp = nextVObject(&t);
522 printVObject_(fp,eachProp,level+1); 541 printVObject_(fp,eachProp,level+1);
523 } 542 }
524 } 543 }
525 544
526void printVObject(FILE *fp,VObject *o) 545void printVObject(FILE *fp,VObject *o)
527{ 546{
528 printVObject_(fp,o,0); 547 printVObject_(fp,o,0);
529} 548}
530 549
531void printVObjectToFile(char *fname,VObject *o) 550DLLEXPORT(void) printVObjectToFile(char *fname,VObject *o)
532{ 551{
533 FILE *fp = fopen(fname,"w"); 552 FILE *fp = fopen(fname,"w");
534 if (fp) { 553 if (fp) {
535 printVObject(fp,o); 554 printVObject(fp,o);
536 fclose(fp); 555 fclose(fp);
537 } 556 }
538} 557}
539 558
540void printVObjectsToFile(char *fname,VObject *list) 559DLLEXPORT(void) printVObjectsToFile(char *fname,VObject *list)
541{ 560{
542 FILE *fp = fopen(fname,"w"); 561 FILE *fp = fopen(fname,"w");
543 if (fp) { 562 if (fp) {
544 while (list) { 563 while (list) {
545 printVObject(fp,list); 564 printVObject(fp,list);
546 list = nextVObjectInList(list); 565 list = nextVObjectInList(list);
547 } 566 }
548 fclose(fp); 567 fclose(fp);
549 } 568 }
550} 569}
551 570
552void cleanVObject(VObject *o) 571DLLEXPORT(void) cleanVObject(VObject *o)
553{ 572{
554 if (o == 0) return; 573 if (o == 0) return;
555 if (o->prop) { 574 if (o->prop) {
556 /* destroy time: cannot use the iterator here. 575 /* destroy time: cannot use the iterator here.
557 Have to break the cycle in the circular link 576 Have to break the cycle in the circular link
558 list and turns it into regular NULL-terminated 577 list and turns it into regular NULL-terminated
559 list -- since at some point of destruction, 578 list -- since at some point of destruction,
560 the reference entry for the iterator to work 579 the reference entry for the iterator to work
561 will not longer be valid. 580 will not longer be valid.
562 */ 581 */
563 VObject *p; 582 VObject *p;
564 p = o->prop->next; 583 p = o->prop->next;
565 o->prop->next = 0; 584 o->prop->next = 0;
566 do { 585 do {
567 VObject *t = p->next; 586 VObject *t = p->next;
568 cleanVObject(p); 587 cleanVObject(p);
569 p = t; 588 p = t;
570 } while (p); 589 } while (p);
571 } 590 }
572 switch (VALUE_TYPE(o)) { 591 switch (VALUE_TYPE(o)) {
573 case VCVT_USTRINGZ: 592 case VCVT_USTRINGZ:
574 case VCVT_STRINGZ: 593 case VCVT_STRINGZ:
575 case VCVT_RAW: 594 case VCVT_RAW:
576 /* assume they are all allocated by malloc. */ 595 /* assume they are all allocated by malloc. */
577 free((char*)STRINGZ_VALUE_OF(o)); 596 free((char*)STRINGZ_VALUE_OF(o));
578 break; 597 break;
579 case VCVT_VOBJECT: 598 case VCVT_VOBJECT:
580 cleanVObject(VOBJECT_VALUE_OF(o)); 599 cleanVObject(VOBJECT_VALUE_OF(o));
581 break; 600 break;
582 } 601 }
583 deleteVObject(o); 602 deleteVObject(o);
584} 603}
585 604
586void cleanVObjects(VObject *list) 605DLLEXPORT(void) cleanVObjects(VObject *list)
587{ 606{
588 while (list) { 607 while (list) {
589 VObject *t = list; 608 VObject *t = list;
590 list = nextVObjectInList(list); 609 list = nextVObjectInList(list);
591 cleanVObject(t); 610 cleanVObject(t);
592 } 611 }
593} 612}
594 613
595/*---------------------------------------------------------------------- 614/*----------------------------------------------------------------------
596 The following is a String Table Facilities. 615 The following is a String Table Facilities.
597 ----------------------------------------------------------------------*/ 616 ----------------------------------------------------------------------*/
598 617
599#define STRTBLSIZE 255 618#define STRTBLSIZE 255
600 619
601static StrItem *strTbl[STRTBLSIZE]; 620static StrItem *strTbl[STRTBLSIZE];
602 621
603static unsigned int hashStr(const char *s) 622static unsigned int hashStr(const char *s)
604{ 623{
605 unsigned int h = 0; 624 unsigned int h = 0;
606 int i; 625 int i;
607 for (i=0;s[i];i++) { 626 for (i=0;s[i];i++) {
608 h += s[i]*i; 627 h += s[i]*i;
609 } 628 }
610 return h % STRTBLSIZE; 629 return h % STRTBLSIZE;
611} 630}
612 631
613const char* lookupStr(const char *s) 632DLLEXPORT(const char*) lookupStr(const char *s)
614{ 633{
615 char *newS; 634 StrItem *t;
616 635 unsigned int h = hashStr(s);
617 StrItem *t; 636 if ((t = strTbl[h]) != 0) {
618 unsigned int h = hashStr(s); 637 do {
619 if ((t = strTbl[h]) != 0) { 638 if (stricmp(t->s,s) == 0) {
620 do { 639 t->refCnt++;
621 if (strcasecmp(t->s,s) == 0) { 640 return t->s;
622 t->refCnt++; 641 }
623 return t->s; 642 t = t->next;
624 } 643 } while (t);
625 t = t->next; 644 }
626 } while (t); 645 s = dupStr(s,0);
627 } 646 strTbl[h] = newStrItem(s,strTbl[h]);
628 newS = dupStr(s,0); 647 return s;
629 strTbl[h] = newStrItem(newS,strTbl[h]);
630 return newS;
631} 648}
632 649
633void unUseStr(const char *s) 650DLLEXPORT(void) unUseStr(const char *s)
634{ 651{
635 StrItem *cur, *prev; 652 StrItem *t, *p;
636
637 unsigned int h = hashStr(s); 653 unsigned int h = hashStr(s);
638 cur = strTbl[h]; 654 if ((t = strTbl[h]) != 0) {
639 prev = cur; 655 p = t;
640 while (cur != 0) { 656 do {
641 if (strcasecmp(cur->s,s) == 0) { 657 if (stricmp(t->s,s) == 0) {
642 cur->refCnt--; 658 t->refCnt--;
643 /* if that was the last reference to this string, kill it. */ 659 if (t->refCnt == 0) {
644 if (cur->refCnt == 0) { 660 if (p == strTbl[h]) {
645 if (cur == strTbl[h]) { 661 strTbl[h] = t->next;
646 strTbl[h] = cur->next; 662 }
647 deleteStr(prev->s); 663 else {
648 deleteStrItem(prev); 664 p->next = t->next;
649 } else { 665 }
650 prev->next = cur->next; 666 deleteStr(t->s);
651 deleteStr(cur->s); 667 deleteStrItem(t);
652 deleteStrItem(cur); 668 return;
653 } 669 }
654 return; 670 }
671 p = t;
672 t = t->next;
673 } while (t);
655 } 674 }
656 }
657 prev = cur;
658 cur = cur->next;
659 }
660} 675}
661 676
662void cleanStrTbl() 677DLLEXPORT(void) cleanStrTbl()
663{ 678{
664 int i; 679 int i;
665 for (i=0; i<STRTBLSIZE;i++) { 680 for (i=0; i<STRTBLSIZE;i++) {
666 StrItem *t = strTbl[i]; 681 StrItem *t = strTbl[i];
667 while (t) { 682 while (t) {
668 StrItem *p; 683 StrItem *p;
669 deleteStr(t->s); 684 deleteStr(t->s);
670 p = t; 685 p = t;
671 t = t->next; 686 t = t->next;
672 deleteStrItem(p); 687 deleteStrItem(p);
673 } 688 } while (t);
674 strTbl[i] = 0; 689 strTbl[i] = 0;
675 } 690 }
676} 691}
677 692
678 693
679struct PreDefProp { 694struct PreDefProp {
680 const char *name; 695 const char *name;
681 const char *alias; 696 const char *alias;
682 const char** fields; 697 const char** fields;
683 unsigned int flags; 698 unsigned int flags;
684 }; 699 };
685 700
686/* flags in PreDefProp */ 701/* flags in PreDefProp */
687 #define PD_BEGIN0x1 702 #define PD_BEGIN0x1
688 #define PD_INTERNAL0x2 703 #define PD_INTERNAL0x2
689 704
690static const char *adrFields[] = { 705static const char *adrFields[] = {
691 VCPostalBoxProp, 706 VCPostalBoxProp,
692 VCExtAddressProp, 707 VCExtAddressProp,
693 VCStreetAddressProp, 708 VCStreetAddressProp,
694 VCCityProp, 709 VCCityProp,
695 VCRegionProp, 710 VCRegionProp,
696 VCPostalCodeProp, 711 VCPostalCodeProp,
697 VCCountryNameProp, 712 VCCountryNameProp,
698 0 713 0
699}; 714};
700 715
701static const char *nameFields[] = { 716static const char *nameFields[] = {
702 VCFamilyNameProp, 717 VCFamilyNameProp,
703 VCGivenNameProp, 718 VCGivenNameProp,
704 VCAdditionalNamesProp, 719 VCAdditionalNamesProp,
705 VCNamePrefixesProp, 720 VCNamePrefixesProp,
706 VCNameSuffixesProp, 721 VCNameSuffixesProp,
707 NULL 722 NULL
708 }; 723 };
709 724
710static const char *orgFields[] = { 725static const char *orgFields[] = {
711 VCOrgNameProp, 726 VCOrgNameProp,
712 VCOrgUnitProp, 727 VCOrgUnitProp,
713 VCOrgUnit2Prop, 728 VCOrgUnit2Prop,
714 VCOrgUnit3Prop, 729 VCOrgUnit3Prop,
715 VCOrgUnit4Prop, 730 VCOrgUnit4Prop,
716 NULL 731 NULL
717 }; 732 };
718 733
719static const char *AAlarmFields[] = { 734static const char *AAlarmFields[] = {
720 VCRunTimeProp, 735 VCRunTimeProp,
721 VCSnoozeTimeProp, 736 VCSnoozeTimeProp,
722 VCRepeatCountProp, 737 VCRepeatCountProp,
723 VCAudioContentProp, 738 VCAudioContentProp,
724 0 739 0
725 }; 740 };
726 741
727/* ExDate -- has unamed fields */ 742/* ExDate -- has unamed fields */
728/* RDate -- has unamed fields */ 743/* RDate -- has unamed fields */
729 744
730static const char *DAlarmFields[] = { 745static const char *DAlarmFields[] = {
731 VCRunTimeProp, 746 VCRunTimeProp,
732 VCSnoozeTimeProp, 747 VCSnoozeTimeProp,
733 VCRepeatCountProp, 748 VCRepeatCountProp,
734 VCDisplayStringProp, 749 VCDisplayStringProp,
735 0 750 0
736 }; 751 };
737 752
738static const char *MAlarmFields[] = { 753static const char *MAlarmFields[] = {
739 VCRunTimeProp, 754 VCRunTimeProp,
740 VCSnoozeTimeProp, 755 VCSnoozeTimeProp,
741 VCRepeatCountProp, 756 VCRepeatCountProp,
742 VCEmailAddressProp, 757 VCEmailAddressProp,
743 VCNoteProp, 758 VCNoteProp,
744 0 759 0
745 }; 760 };
746 761
747static const char *PAlarmFields[] = { 762static const char *PAlarmFields[] = {
748 VCRunTimeProp, 763 VCRunTimeProp,
749 VCSnoozeTimeProp, 764 VCSnoozeTimeProp,
750 VCRepeatCountProp, 765 VCRepeatCountProp,
751 VCProcedureNameProp, 766 VCProcedureNameProp,
752 0 767 0
753 }; 768 };
754 769
755static struct PreDefProp propNames[] = { 770static struct PreDefProp propNames[] = {
756 { VC7bitProp, 0, 0, 0 }, 771 { VC7bitProp, 0, 0, 0 },
757 { VC8bitProp, 0, 0, 0 }, 772 { VC8bitProp, 0, 0, 0 },
758 { VCAAlarmProp, 0, AAlarmFields, 0 }, 773 { VCAAlarmProp, 0, AAlarmFields, 0 },
759 { VCAdditionalNamesProp, 0, 0, 0 }, 774 { VCAdditionalNamesProp, 0, 0, 0 },
760 { VCAdrProp, 0, adrFields, 0 }, 775 { VCAdrProp, 0, adrFields, 0 },
761 { VCAgentProp, 0, 0, 0 }, 776 { VCAgentProp, 0, 0, 0 },
762 { VCAIFFProp, 0, 0, 0 }, 777 { VCAIFFProp, 0, 0, 0 },
763 { VCAOLProp, 0, 0, 0 }, 778 { VCAOLProp, 0, 0, 0 },
764 { VCAppleLinkProp, 0, 0, 0 }, 779 { VCAppleLinkProp, 0, 0, 0 },
765 { VCAttachProp, 0, 0, 0 }, 780 { VCAttachProp, 0, 0, 0 },
766 { VCAttendeeProp, 0, 0, 0 }, 781 { VCAttendeeProp, 0, 0, 0 },
767 { VCATTMailProp, 0, 0, 0 }, 782 { VCATTMailProp, 0, 0, 0 },
768 { VCAudioContentProp, 0, 0, 0 }, 783 { VCAudioContentProp, 0, 0, 0 },
769 { VCAVIProp, 0, 0, 0 }, 784 { VCAVIProp, 0, 0, 0 },
770 { VCBase64Prop, 0, 0, 0 }, 785 { VCBase64Prop, 0, 0, 0 },
771 { VCBBSProp, 0, 0, 0 }, 786 { VCBBSProp, 0, 0, 0 },
772 { VCBirthDateProp, 0, 0, 0 }, 787 { VCBirthDateProp, 0, 0, 0 },
773 { VCBMPProp, 0, 0, 0 }, 788 { VCBMPProp, 0, 0, 0 },
774 { VCBodyProp, 0, 0, 0 }, 789 { VCBodyProp, 0, 0, 0 },
775 { VCBusinessRoleProp, 0, 0, 0 }, 790 { VCBusinessRoleProp, 0, 0, 0 },
776 { VCCalProp, 0, 0, PD_BEGIN }, 791 { VCCalProp, 0, 0, PD_BEGIN },
777 { VCCaptionProp, 0, 0, 0 }, 792 { VCCaptionProp, 0, 0, 0 },
778 { VCCardProp, 0, 0, PD_BEGIN }, 793 { VCCardProp, 0, 0, PD_BEGIN },
779 { VCCarProp, 0, 0, 0 }, 794 { VCCarProp, 0, 0, 0 },
780 { VCCategoriesProp, 0, 0, 0 }, 795 { VCCategoriesProp, 0, 0, 0 },
781 { VCCellularProp, 0, 0, 0 }, 796 { VCCellularProp, 0, 0, 0 },
782 { VCCGMProp, 0, 0, 0 }, 797 { VCCGMProp, 0, 0, 0 },
783 { VCCharSetProp, 0, 0, 0 }, 798 { VCCharSetProp, 0, 0, 0 },
784 { VCCIDProp, VCContentIDProp, 0, 0 }, 799 { VCCIDProp, VCContentIDProp, 0, 0 },
785 { VCCISProp, 0, 0, 0 }, 800 { VCCISProp, 0, 0, 0 },
786 { VCCityProp, 0, 0, 0 }, 801 { VCCityProp, 0, 0, 0 },
787 { VCClassProp, 0, 0, 0 }, 802 { VCClassProp, 0, 0, 0 },
788 { VCCommentProp, 0, 0, 0 }, 803 { VCCommentProp, 0, 0, 0 },
789 { VCCompletedProp, 0, 0, 0 }, 804 { VCCompletedProp, 0, 0, 0 },
790 { VCContentIDProp, 0, 0, 0 }, 805 { VCContentIDProp, 0, 0, 0 },
791 { VCCountryNameProp, 0, 0, 0 }, 806 { VCCountryNameProp, 0, 0, 0 },
792 { VCDAlarmProp, 0, DAlarmFields, 0 }, 807 { VCDAlarmProp, 0, DAlarmFields, 0 },
793 { VCDataSizeProp, 0, 0, PD_INTERNAL }, 808 { VCDataSizeProp, 0, 0, PD_INTERNAL },
794 { VCDayLightProp, 0, 0, 0 }, 809 { VCDayLightProp, 0, 0, 0 },
795 { VCDCreatedProp, 0, 0, 0 }, 810 { VCDCreatedProp, 0, 0, 0 },
796 { VCDeliveryLabelProp, 0, 0, 0 }, 811 { VCDeliveryLabelProp, 0, 0, 0 },
797 { VCDescriptionProp, 0, 0, 0 }, 812 { VCDescriptionProp, 0, 0, 0 },
798 { VCDIBProp, 0, 0, 0 }, 813 { VCDIBProp, 0, 0, 0 },
799 { VCDisplayStringProp, 0, 0, 0 }, 814 { VCDisplayStringProp, 0, 0, 0 },
800 { VCDomesticProp, 0, 0, 0 }, 815 { VCDomesticProp, 0, 0, 0 },
801 { VCDTendProp, 0, 0, 0 }, 816 { VCDTendProp, 0, 0, 0 },
802 { VCDTstartProp, 0, 0, 0 }, 817 { VCDTstartProp, 0, 0, 0 },
803 { VCDueProp, 0, 0, 0 }, 818 { VCDueProp, 0, 0, 0 },
804 { VCEmailAddressProp, 0, 0, 0 }, 819 { VCEmailAddressProp, 0, 0, 0 },
805 { VCEncodingProp, 0, 0, 0 }, 820 { VCEncodingProp, 0, 0, 0 },
806 { VCEndProp, 0, 0, 0 }, 821 { VCEndProp, 0, 0, 0 },
807 { VCEventProp, 0, 0, PD_BEGIN }, 822 { VCEventProp, 0, 0, PD_BEGIN },
808 { VCEWorldProp, 0, 0, 0 }, 823 { VCEWorldProp, 0, 0, 0 },
809 { VCExNumProp, 0, 0, 0 }, 824 { VCExNumProp, 0, 0, 0 },
810 { VCExDateProp, 0, 0, 0 }, 825 { VCExpDateProp, 0, 0, 0 },
811 { VCExpectProp, 0, 0, 0 }, 826 { VCExpectProp, 0, 0, 0 },
812 { VCExtAddressProp, 0, 0, 0 }, 827 { VCExtAddressProp, 0, 0, 0 },
813 { VCFamilyNameProp, 0, 0, 0 }, 828 { VCFamilyNameProp, 0, 0, 0 },
814 { VCFaxProp, 0, 0, 0 }, 829 { VCFaxProp, 0, 0, 0 },
815 { VCFullNameProp, 0, 0, 0 }, 830 { VCFullNameProp, 0, 0, 0 },
816 { VCGeoLocationProp, 0, 0, 0 }, 831 { VCGeoLocationProp, 0, 0, 0 },
817 { VCGeoProp, 0, 0, 0 }, 832 { VCGeoProp, 0, 0, 0 },
818 { VCGIFProp, 0, 0, 0 }, 833 { VCGIFProp, 0, 0, 0 },
819 { VCGivenNameProp, 0, 0, 0 }, 834 { VCGivenNameProp, 0, 0, 0 },
820 { VCGroupingProp, 0, 0, 0 }, 835 { VCGroupingProp, 0, 0, 0 },
821 { VCHomeProp, 0, 0, 0 }, 836 { VCHomeProp, 0, 0, 0 },
822 { VCIBMMailProp, 0, 0, 0 }, 837 { VCIBMMailProp, 0, 0, 0 },
823 { VCInlineProp, 0, 0, 0 }, 838 { VCInlineProp, 0, 0, 0 },
824 { VCInternationalProp, 0, 0, 0 }, 839 { VCInternationalProp, 0, 0, 0 },
825 { VCInternetProp, 0, 0, 0 }, 840 { VCInternetProp, 0, 0, 0 },
826 { VCISDNProp, 0, 0, 0 }, 841 { VCISDNProp, 0, 0, 0 },
827 { VCJPEGProp, 0, 0, 0 }, 842 { VCJPEGProp, 0, 0, 0 },
828 { VCLanguageProp, 0, 0, 0 }, 843 { VCLanguageProp, 0, 0, 0 },
829 { VCLastModifiedProp, 0, 0, 0 }, 844 { VCLastModifiedProp, 0, 0, 0 },
830 { VCLastRevisedProp, 0, 0, 0 }, 845 { VCLastRevisedProp, 0, 0, 0 },
831 { VCLocationProp, 0, 0, 0 }, 846 { VCLocationProp, 0, 0, 0 },
832 { VCLogoProp, 0, 0, 0 }, 847 { VCLogoProp, 0, 0, 0 },
833 { VCMailerProp, 0, 0, 0 }, 848 { VCMailerProp, 0, 0, 0 },
834 { VCMAlarmProp, 0, MAlarmFields, 0 }, 849 { VCMAlarmProp, 0, MAlarmFields, 0 },
835 { VCMCIMailProp, 0, 0, 0 }, 850 { VCMCIMailProp, 0, 0, 0 },
836 { VCMessageProp, 0, 0, 0 }, 851 { VCMessageProp, 0, 0, 0 },
837 { VCMETProp, 0, 0, 0 }, 852 { VCMETProp, 0, 0, 0 },
838 { VCModemProp, 0, 0, 0 }, 853 { VCModemProp, 0, 0, 0 },
839 { VCMPEG2Prop, 0, 0, 0 }, 854 { VCMPEG2Prop, 0, 0, 0 },
840 { VCMPEGProp, 0, 0, 0 }, 855 { VCMPEGProp, 0, 0, 0 },
841 { VCMSNProp, 0, 0, 0 }, 856 { VCMSNProp, 0, 0, 0 },
842 { VCNamePrefixesProp, 0, 0, 0 }, 857 { VCNamePrefixesProp, 0, 0, 0 },
843 { VCNameProp, 0, nameFields, 0 }, 858 { VCNameProp, 0, nameFields, 0 },
844 { VCNameSuffixesProp, 0, 0, 0 }, 859 { VCNameSuffixesProp, 0, 0, 0 },
845 { VCNoteProp, 0, 0, 0 }, 860 { VCNoteProp, 0, 0, 0 },
846 { VCOrgNameProp, 0, 0, 0 }, 861 { VCOrgNameProp, 0, 0, 0 },
847 { VCOrgProp, 0, orgFields, 0 }, 862 { VCOrgProp, 0, orgFields, 0 },
848 { VCOrgUnit2Prop, 0, 0, 0 }, 863 { VCOrgUnit2Prop, 0, 0, 0 },
849 { VCOrgUnit3Prop, 0, 0, 0 }, 864 { VCOrgUnit3Prop, 0, 0, 0 },
850 { VCOrgUnit4Prop, 0, 0, 0 }, 865 { VCOrgUnit4Prop, 0, 0, 0 },
851 { VCOrgUnitProp, 0, 0, 0 }, 866 { VCOrgUnitProp, 0, 0, 0 },
852 { VCPagerProp, 0, 0, 0 }, 867 { VCPagerProp, 0, 0, 0 },
853 { VCPAlarmProp, 0, PAlarmFields, 0 }, 868 { VCPAlarmProp, 0, PAlarmFields, 0 },
854 { VCParcelProp, 0, 0, 0 }, 869 { VCParcelProp, 0, 0, 0 },
855 { VCPartProp, 0, 0, 0 }, 870 { VCPartProp, 0, 0, 0 },
856 { VCPCMProp, 0, 0, 0 }, 871 { VCPCMProp, 0, 0, 0 },
857 { VCPDFProp, 0, 0, 0 }, 872 { VCPDFProp, 0, 0, 0 },
858 { VCPGPProp, 0, 0, 0 }, 873 { VCPGPProp, 0, 0, 0 },
859 { VCPhotoProp, 0, 0, 0 }, 874 { VCPhotoProp, 0, 0, 0 },
860 { VCPICTProp, 0, 0, 0 }, 875 { VCPICTProp, 0, 0, 0 },
861 { VCPMBProp, 0, 0, 0 }, 876 { VCPMBProp, 0, 0, 0 },
862 { VCPostalBoxProp, 0, 0, 0 }, 877 { VCPostalBoxProp, 0, 0, 0 },
863 { VCPostalCodeProp, 0, 0, 0 }, 878 { VCPostalCodeProp, 0, 0, 0 },
864 { VCPostalProp, 0, 0, 0 }, 879 { VCPostalProp, 0, 0, 0 },
865 { VCPowerShareProp, 0, 0, 0 }, 880 { VCPowerShareProp, 0, 0, 0 },
866 { VCPreferredProp, 0, 0, 0 }, 881 { VCPreferredProp, 0, 0, 0 },
867 { VCPriorityProp, 0, 0, 0 }, 882 { VCPriorityProp, 0, 0, 0 },
868 { VCProcedureNameProp, 0, 0, 0 }, 883 { VCProcedureNameProp, 0, 0, 0 },
869 { VCProdIdProp, 0, 0, 0 }, 884 { VCProdIdProp, 0, 0, 0 },
870 { VCProdigyProp, 0, 0, 0 }, 885 { VCProdigyProp, 0, 0, 0 },
871 { VCPronunciationProp, 0, 0, 0 }, 886 { VCPronunciationProp, 0, 0, 0 },
872 { VCPSProp, 0, 0, 0 }, 887 { VCPSProp, 0, 0, 0 },
873 { VCPublicKeyProp, 0, 0, 0 }, 888 { VCPublicKeyProp, 0, 0, 0 },
874 { VCQPProp, VCQuotedPrintableProp, 0, 0 }, 889 { VCQPProp, VCQuotedPrintableProp, 0, 0 },
875 { VCQuickTimeProp, 0, 0, 0 }, 890 { VCQuickTimeProp, 0, 0, 0 },
876 { VCQuotedPrintableProp, 0, 0, 0 }, 891 { VCQuotedPrintableProp, 0, 0, 0 },
877 { VCRDateProp, 0, 0, 0 }, 892 { VCRDateProp, 0, 0, 0 },
878 { VCRegionProp, 0, 0, 0 }, 893 { VCRegionProp, 0, 0, 0 },
879 { VCRelatedToProp, 0, 0, 0 }, 894 { VCRelatedToProp, 0, 0, 0 },
880 { VCRepeatCountProp, 0, 0, 0 }, 895 { VCRepeatCountProp, 0, 0, 0 },
881 { VCResourcesProp, 0, 0, 0 }, 896 { VCResourcesProp, 0, 0, 0 },
882 { VCRNumProp, 0, 0, 0 }, 897 { VCRNumProp, 0, 0, 0 },
883 { VCRoleProp, 0, 0, 0 }, 898 { VCRoleProp, 0, 0, 0 },
884 { VCRRuleProp, 0, 0, 0 }, 899 { VCRRuleProp, 0, 0, 0 },
885 { VCRSVPProp, 0, 0, 0 }, 900 { VCRSVPProp, 0, 0, 0 },
886 { VCRunTimeProp, 0, 0, 0 }, 901 { VCRunTimeProp, 0, 0, 0 },
887 { VCSequenceProp, 0, 0, 0 }, 902 { VCSequenceProp, 0, 0, 0 },
888 { VCSnoozeTimeProp, 0, 0, 0 }, 903 { VCSnoozeTimeProp, 0, 0, 0 },
889 { VCStartProp, 0, 0, 0 }, 904 { VCStartProp, 0, 0, 0 },
890 { VCStatusProp, 0, 0, 0 }, 905 { VCStatusProp, 0, 0, 0 },
891 { VCStreetAddressProp, 0, 0, 0 }, 906 { VCStreetAddressProp, 0, 0, 0 },
892 { VCSubTypeProp, 0, 0, 0 }, 907 { VCSubTypeProp, 0, 0, 0 },
893 { VCSummaryProp, 0, 0, 0 }, 908 { VCSummaryProp, 0, 0, 0 },
894 { VCTelephoneProp, 0, 0, 0 }, 909 { VCTelephoneProp, 0, 0, 0 },
895 { VCTIFFProp, 0, 0, 0 }, 910 { VCTIFFProp, 0, 0, 0 },
896 { VCTimeZoneProp, 0, 0, 0 }, 911 { VCTimeZoneProp, 0, 0, 0 },
897 { VCTitleProp, 0, 0, 0 }, 912 { VCTitleProp, 0, 0, 0 },
898 { VCTLXProp, 0, 0, 0 }, 913 { VCTLXProp, 0, 0, 0 },
899 { VCTodoProp, 0, 0, PD_BEGIN }, 914 { VCTodoProp, 0, 0, PD_BEGIN },
900 { VCTranspProp, 0, 0, 0 }, 915 { VCTranspProp, 0, 0, 0 },
901 { VCUniqueStringProp, 0, 0, 0 }, 916 { VCUniqueStringProp, 0, 0, 0 },
902 { VCURLProp, 0, 0, 0 }, 917 { VCURLProp, 0, 0, 0 },
903 { VCURLValueProp, 0, 0, 0 }, 918 { VCURLValueProp, 0, 0, 0 },
904 { VCValueProp, 0, 0, 0 }, 919 { VCValueProp, 0, 0, 0 },
905 { VCVersionProp, 0, 0, 0 }, 920 { VCVersionProp, 0, 0, 0 },
906 { VCVideoProp, 0, 0, 0 }, 921 { VCVideoProp, 0, 0, 0 },
907 { VCVoiceProp, 0, 0, 0 }, 922 { VCVoiceProp, 0, 0, 0 },
908 { VCWAVEProp, 0, 0, 0 }, 923 { VCWAVEProp, 0, 0, 0 },
909 { VCWMFProp, 0, 0, 0 }, 924 { VCWMFProp, 0, 0, 0 },
910 { VCWorkProp, 0, 0, 0 }, 925 { VCWorkProp, 0, 0, 0 },
911 { VCX400Prop, 0, 0, 0 }, 926 { VCX400Prop, 0, 0, 0 },
912 { VCX509Prop, 0, 0, 0 }, 927 { VCX509Prop, 0, 0, 0 },
913 { VCXRuleProp, 0, 0, 0 }, 928 { VCXRuleProp, 0, 0, 0 },
914 { 0,0,0,0 } 929 { 0,0,0,0 }
915 }; 930 };
916 931
917 932
918static struct PreDefProp* lookupPropInfo(const char* str) 933static struct PreDefProp* lookupPropInfo(const char* str)
919{ 934{
920 /* brute force for now, could use a hash table here. */ 935 /* brute force for now, could use a hash table here. */
921 int i; 936 int i;
922 937
923 for (i = 0; propNames[i].name; i++) 938 for (i = 0; propNames[i].name; i++)
924 if (strcasecmp(str, propNames[i].name) == 0) { 939 if (stricmp(str, propNames[i].name) == 0) {
925 return &propNames[i]; 940 return &propNames[i];
926 } 941 }
927 942
928 return 0; 943 return 0;
929} 944}
930 945
931 946
932const char* lookupProp_(const char* str) 947DLLEXPORT(const char*) lookupProp_(const char* str)
933{ 948{
934 int i; 949 int i;
935 950
936 for (i = 0; propNames[i].name; i++) 951 for (i = 0; propNames[i].name; i++)
937 if (strcasecmp(str, propNames[i].name) == 0) { 952 if (stricmp(str, propNames[i].name) == 0) {
938 const char* s; 953 const char* s;
939 s = propNames[i].alias?propNames[i].alias:propNames[i].name; 954 s = propNames[i].alias?propNames[i].alias:propNames[i].name;
940 return lookupStr(s); 955 return lookupStr(s);
941 } 956 }
942 return lookupStr(str); 957 return lookupStr(str);
943} 958}
944 959
945 960
946const char* lookupProp(const char* str) 961DLLEXPORT(const char*) lookupProp(const char* str)
947{ 962{
948 int i; 963 int i;
949 964
950 for (i = 0; propNames[i].name; i++) 965 for (i = 0; propNames[i].name; i++)
951 if (strcasecmp(str, propNames[i].name) == 0) { 966 if (stricmp(str, propNames[i].name) == 0) {
952 const char *s; 967 const char *s;
953 fieldedProp = propNames[i].fields; 968 fieldedProp = propNames[i].fields;
954 s = propNames[i].alias?propNames[i].alias:propNames[i].name; 969 s = propNames[i].alias?propNames[i].alias:propNames[i].name;
955 return lookupStr(s); 970 return lookupStr(s);
956 } 971 }
957 fieldedProp = 0; 972 fieldedProp = 0;
958 return lookupStr(str); 973 return lookupStr(str);
959} 974}
960 975
961 976
962/*---------------------------------------------------------------------- 977/*----------------------------------------------------------------------
963 APIs to Output text form. 978 APIs to Output text form.
964 ----------------------------------------------------------------------*/ 979 ----------------------------------------------------------------------*/
965#define OFILE_REALLOC_SIZE 256 980#define OFILE_REALLOC_SIZE 256
966typedef struct OFile { 981typedef struct OFile {
967 FILE *fp; 982 FILE *fp;
968 char *s; 983 char *s;
969 int len; 984 int len;
970 int limit; 985 int limit;
971 int alloc:1; 986 int alloc:1;
972 int fail:1; 987 int fail:1;
973 } OFile; 988 } OFile;
974 989
975
976/* vCalendar files need crlf linebreaks. The disabled functions didn't provide
977 that. */
978#if 0 990#if 0
979
980static void appendsOFile(OFile *fp, const char *s) 991static void appendsOFile(OFile *fp, const char *s)
981{ 992{
982 int slen; 993 int slen;
983 if (fp->fail) return; 994 if (fp->fail) return;
984 slen = strlen(s); 995 slen = strlen(s);
985 if (fp->fp) { 996 if (fp->fp) {
986 fwrite(s,1,slen,fp->fp); 997 fwrite(s,1,slen,fp->fp);
987 } 998 }
988 else { 999 else {
989stuff: 1000stuff:
990 if (fp->len + slen < fp->limit) { 1001 if (fp->len + slen < fp->limit) {
991 memcpy(fp->s+fp->len,s,slen); 1002 memcpy(fp->s+fp->len,s,slen);
992 fp->len += slen; 1003 fp->len += slen;
993 return; 1004 return;
994 } 1005 }
995 else if (fp->alloc) { 1006 else if (fp->alloc) {
996 fp->limit = fp->limit + OFILE_REALLOC_SIZE; 1007 fp->limit = fp->limit + OFILE_REALLOC_SIZE;
997 if (OFILE_REALLOC_SIZE <= slen) fp->limit += slen; 1008 if (OFILE_REALLOC_SIZE <= slen) fp->limit += slen;
998 if (fp->s) 1009 fp->s = (char *) realloc(fp->s,fp->limit);
999 fp->s = realloc(fp->s,fp->limit);
1000 else
1001 fp->s = malloc(fp->limit);
1002 if (fp->s) goto stuff; 1010 if (fp->s) goto stuff;
1003 } 1011 }
1004 if (fp->alloc) 1012 if (fp->alloc)
1005 free(fp->s); 1013 free(fp->s);
1006 fp->s = 0; 1014 fp->s = 0;
1007 fp->fail = 1; 1015 fp->fail = 1;
1008 } 1016 }
1009} 1017}
1010 1018
1011static void appendcOFile(OFile *fp, char c) 1019static void appendcOFile(OFile *fp, char c)
1012{ 1020{
1013 if (fp->fail) return; 1021 if (fp->fail) return;
1014 if (fp->fp) { 1022 if (fp->fp) {
1015 fputc(c,fp->fp); 1023 fputc(c,fp->fp);
1016 } 1024 }
1017 else { 1025 else {
1018stuff: 1026stuff:
1019 if (fp->len+1 < fp->limit) { 1027 if (fp->len+1 < fp->limit) {
1020 fp->s[fp->len] = c; 1028 fp->s[fp->len] = c;
1021 fp->len++; 1029 fp->len++;
1022 return; 1030 return;
1023 } 1031 }
1024 else if (fp->alloc) { 1032 else if (fp->alloc) {
1025 fp->limit = fp->limit + OFILE_REALLOC_SIZE; 1033 fp->limit = fp->limit + OFILE_REALLOC_SIZE;
1026 fp->s = realloc(fp->s,fp->limit); 1034 fp->s = (char *) realloc(fp->s,fp->limit);
1027 if (fp->s) goto stuff; 1035 if (fp->s) goto stuff;
1028 } 1036 }
1029 if (fp->alloc) 1037 if (fp->alloc)
1030 free(fp->s); 1038 free(fp->s);
1031 fp->s = 0; 1039 fp->s = 0;
1032 fp->fail = 1; 1040 fp->fail = 1;
1033 } 1041 }
1034} 1042}
1035
1036#else 1043#else
1037
1038static void appendcOFile_(OFile *fp, char c) 1044static void appendcOFile_(OFile *fp, char c)
1039{ 1045{
1040 if (fp->fail) return; 1046 if (fp->fail) return;
1041 if (fp->fp) { 1047 if (fp->fp) {
1042 fputc(c,fp->fp); 1048 fputc(c,fp->fp);
1043 } 1049 }
1044 else { 1050 else {
1045stuff: 1051stuff:
1046 if (fp->len+1 < fp->limit) { 1052 if (fp->len+1 < fp->limit) {
1047 fp->s[fp->len] = c; 1053 fp->s[fp->len] = c;
1048 fp->len++; 1054 fp->len++;
1049 return; 1055 return;
1050 } 1056 }
1051 else if (fp->alloc) { 1057 else if (fp->alloc) {
1052 fp->limit = fp->limit + OFILE_REALLOC_SIZE; 1058 fp->limit = fp->limit + OFILE_REALLOC_SIZE;
1053 fp->s = realloc(fp->s,fp->limit); 1059 fp->s = realloc(fp->s,fp->limit);
1054 if (fp->s) goto stuff; 1060 if (fp->s) goto stuff;
1055 } 1061 }
1056 if (fp->alloc) 1062 if (fp->alloc)
1057 free(fp->s); 1063 free(fp->s);
1058 fp->s = 0; 1064 fp->s = 0;
1059 fp->fail = 1; 1065 fp->fail = 1;
1060 } 1066 }
1061} 1067}
1062 1068
1063static void appendcOFile(OFile *fp, char c) 1069static void appendcOFile(OFile *fp, char c)
1064{ 1070{
1065 if (c == '\n') { 1071 if (c == '\n') {
1066 /* write out as <CR><LF> */ 1072 /* write out as <CR><LF> */
1067 appendcOFile_(fp,0xd); 1073 appendcOFile_(fp,0xd);
1068 appendcOFile_(fp,0xa); 1074 appendcOFile_(fp,0xa);
1069 } 1075 }
1070 else 1076 else
1071 appendcOFile_(fp,c); 1077 appendcOFile_(fp,c);
1072} 1078}
1073 1079
1074static void appendsOFile(OFile *fp, const char *s) 1080static void appendsOFile(OFile *fp, const char *s)
1075{ 1081{
1076 int i, slen; 1082 int i, slen;
1077 slen = strlen(s); 1083 slen = strlen(s);
1078 for (i=0; i<slen; i++) { 1084 for (i=0; i<slen; i++) {
1079 appendcOFile(fp,s[i]); 1085 appendcOFile(fp,s[i]);
1080 } 1086 }
1081} 1087}
1082 1088
1083#endif 1089#endif
1084 1090
1085static void initOFile(OFile *fp, FILE *ofp) 1091static void initOFile(OFile *fp, FILE *ofp)
1086{ 1092{
1087 fp->fp = ofp; 1093 fp->fp = ofp;
1088 fp->s = 0; 1094 fp->s = 0;
1089 fp->len = 0; 1095 fp->len = 0;
1090 fp->limit = 0; 1096 fp->limit = 0;
1091 fp->alloc = 0; 1097 fp->alloc = 0;
1092 fp->fail = 0; 1098 fp->fail = 0;
1093} 1099}
1094 1100
1095static void initMemOFile(OFile *fp, char *s, int len) 1101static void initMemOFile(OFile *fp, char *s, int len)
1096{ 1102{
1097 fp->fp = 0; 1103 fp->fp = 0;
1098 fp->s = s; 1104 fp->s = s;
1099 fp->len = 0; 1105 fp->len = 0;
1100 fp->limit = s?len:0; 1106 fp->limit = s?len:0;
1101 fp->alloc = s?0:1; 1107 fp->alloc = s?0:1;
1102 fp->fail = 0; 1108 fp->fail = 0;
1103} 1109}
1104 1110
1105 1111
1106static int writeBase64(OFile *fp, unsigned char *s, long len) 1112static int writeBase64(OFile *fp, unsigned char *s, long len)
1107{ 1113{
1108 long cur = 0; 1114 long cur = 0;
1109 int i, numQuads = 0; 1115 int i, numQuads = 0;
1110 unsigned long trip; 1116 unsigned long trip;
1111 unsigned char b; 1117 unsigned char b;
1112 char quad[5]; 1118 char quad[5];
1113#define MAXQUADS 16 1119#define MAXQUADS 16
1114 1120
1115 quad[4] = 0; 1121 quad[4] = 0;
1116 1122
1117 while (cur < len) { 1123 while (cur < len) {
1118 /* collect the triplet of bytes into 'trip' */ 1124 /* collect the triplet of bytes into 'trip' */
1119 trip = 0; 1125 trip = 0;
1120 for (i = 0; i < 3; i++) { 1126 for (i = 0; i < 3; i++) {
1121 b = (cur < len) ? *(s + cur) : 0; 1127 b = (cur < len) ? *(s + cur) : 0;
1122 cur++; 1128 cur++;
1123 trip = trip << 8 | b; 1129 trip = trip << 8 | b;
1124 } 1130 }
1125 /* fill in 'quad' with the appropriate four characters */ 1131 /* fill in 'quad' with the appropriate four characters */
1126 for (i = 3; i >= 0; i--) { 1132 for (i = 3; i >= 0; i--) {
1127 b = (unsigned char)(trip & 0x3F); 1133 b = (unsigned char)(trip & 0x3F);
1128 trip = trip >> 6; 1134 trip = trip >> 6;
1129 if ((3 - i) < (cur - len)) 1135 if ((3 - i) < (cur - len))
1130 quad[i] = '='; /* pad char */ 1136 quad[i] = '='; /* pad char */
1131 else if (b < 26) quad[i] = (char)b + 'A'; 1137 else if (b < 26) quad[i] = (char)b + 'A';
1132 else if (b < 52) quad[i] = (char)(b - 26) + 'a'; 1138 else if (b < 52) quad[i] = (char)(b - 26) + 'a';
1133 else if (b < 62) quad[i] = (char)(b - 52) + '0'; 1139 else if (b < 62) quad[i] = (char)(b - 52) + '0';
1134 else if (b == 62) quad[i] = '+'; 1140 else if (b == 62) quad[i] = '+';
1135 else quad[i] = '/'; 1141 else quad[i] = '/';
1136 } 1142 }
1137 /* now output 'quad' with appropriate whitespace and line ending */ 1143 /* now output 'quad' with appropriate whitespace and line ending */
1138 appendsOFile(fp, (numQuads == 0 ? " " : "")); 1144 appendsOFile(fp, (numQuads == 0 ? " " : ""));
1139 appendsOFile(fp, quad); 1145 appendsOFile(fp, quad);
1140 appendsOFile(fp, ((cur >= len)?"\n" :(numQuads==MAXQUADS-1?"\n" : ""))); 1146 appendsOFile(fp, ((cur >= len)?"\n" :(numQuads==MAXQUADS-1?"\n" : "")));
1141 numQuads = (numQuads + 1) % MAXQUADS; 1147 numQuads = (numQuads + 1) % MAXQUADS;
1142 } 1148 }
1143 appendcOFile(fp,'\n'); 1149 appendcOFile(fp,'\n');
1144 1150
1145 return 1; 1151 return 1;
1146} 1152}
1147 1153
1148/* this function really sucks. Too basic. */ 1154static void writeString(OFile *fp, const char *s)
1149static void writeQPString(OFile *fp, const char *s, int qp) 1155{
1156 appendsOFile(fp,s);
1157}
1158
1159static void writeQPString(OFile *fp, const char *s)
1150{ 1160{
1161 char buf[4];
1162 int count=0;
1151 const char *p = s; 1163 const char *p = s;
1164
1152 while (*p) { 1165 while (*p) {
1153 if (*p == '\n') { 1166 /* break up lines biggger than 75 chars */
1154 if (p[1]) appendsOFile(fp,"=0A="); 1167 if(count >=74){
1155 } 1168 count=0;
1156 if (*p == '=' && qp) 1169 appendsOFile(fp,"=\n");
1157 appendsOFile(fp,"=3D"); 1170 }
1158 else 1171
1159 appendcOFile(fp,*p); 1172 /* escape any non ASCII characters and '=' as per rfc1521 */
1160 p++; 1173 if (*p<= 0x1f || *p >=0x7f || *p == '=' ) {
1174 sprintf(buf,"=%02X",(unsigned char)*p);
1175 appendsOFile(fp,buf);
1176 count+=3;
1177 } else {
1178 appendcOFile(fp,*p);
1179 count++;
1180 }
1181 p++;
1161 } 1182 }
1162} 1183}
1163 1184
1185
1186
1164static void writeVObject_(OFile *fp, VObject *o); 1187static void writeVObject_(OFile *fp, VObject *o);
1165 1188
1166static void writeValue(OFile *fp, VObject *o, unsigned long size) 1189static void writeValue(OFile *fp, VObject *o, unsigned long size,int quote)
1167{ 1190{
1168 if (o == 0) return; 1191 if (o == 0) return;
1169 switch (VALUE_TYPE(o)) { 1192 switch (VALUE_TYPE(o)) {
1170 case VCVT_USTRINGZ: { 1193 case VCVT_USTRINGZ: {
1171 char *s = fakeCString(USTRINGZ_VALUE_OF(o)); 1194 char *s = fakeCString(USTRINGZ_VALUE_OF(o));
1172 if (isAPropertyOf(o, VCQuotedPrintableProp)) 1195 if(quote) writeQPString(fp, s);
1173 writeQPString(fp, s, 1); 1196 else writeString(fp,s);
1174 else
1175 writeQPString(fp, s, 0);
1176 deleteStr(s); 1197 deleteStr(s);
1177 break; 1198 break;
1178 } 1199 }
1179 case VCVT_STRINGZ: { 1200 case VCVT_STRINGZ: {
1180 if (isAPropertyOf(o, VCQuotedPrintableProp)) 1201 if(quote) writeQPString(fp, STRINGZ_VALUE_OF(o));
1181 writeQPString(fp, STRINGZ_VALUE_OF(o), 1); 1202 else writeString(fp,STRINGZ_VALUE_OF(o));
1182 else
1183 writeQPString(fp, STRINGZ_VALUE_OF(o), 0);
1184 break; 1203 break;
1185 } 1204 }
1186 case VCVT_UINT: { 1205 case VCVT_UINT: {
1187 char buf[16]; 1206 char buf[16];
1188 sprintf(buf,"%u", INTEGER_VALUE_OF(o)); 1207 sprintf(buf,"%u", INTEGER_VALUE_OF(o));
1189 appendsOFile(fp,buf); 1208 appendsOFile(fp,buf);
1190 break; 1209 break;
1191 } 1210 }
1192 case VCVT_ULONG: { 1211 case VCVT_ULONG: {
1193 char buf[16]; 1212 char buf[16];
1194 sprintf(buf,"%lu", LONG_VALUE_OF(o)); 1213 sprintf(buf,"%lu", LONG_VALUE_OF(o));
1195 appendsOFile(fp,buf); 1214 appendsOFile(fp,buf);
1196 break; 1215 break;
1197 } 1216 }
1198 case VCVT_RAW: { 1217 case VCVT_RAW: {
1199 appendcOFile(fp,'\n'); 1218 appendcOFile(fp,'\n');
1200 writeBase64(fp,(unsigned char*)(ANY_VALUE_OF(o)),size); 1219 writeBase64(fp,(unsigned char*)(ANY_VALUE_OF(o)),size);
1201 break; 1220 break;
1202 } 1221 }
1203 case VCVT_VOBJECT: 1222 case VCVT_VOBJECT:
1204 appendcOFile(fp,'\n'); 1223 appendcOFile(fp,'\n');
1205 writeVObject_(fp,VOBJECT_VALUE_OF(o)); 1224 writeVObject_(fp,VOBJECT_VALUE_OF(o));
1206 break; 1225 break;
1207 } 1226 }
1208} 1227}
1209 1228
1210static void writeAttrValue(OFile *fp, VObject *o) 1229static void writeAttrValue(OFile *fp, VObject *o)
1211{ 1230{
1212 if (NAME_OF(o)) { 1231 if (NAME_OF(o)) {
1213 struct PreDefProp *pi; 1232 struct PreDefProp *pi;
1214 pi = lookupPropInfo(NAME_OF(o)); 1233 pi = lookupPropInfo(NAME_OF(o));
1215 if (pi && ((pi->flags & PD_INTERNAL) != 0)) return; 1234 if (pi && ((pi->flags & PD_INTERNAL) != 0)) return;
1216 appendcOFile(fp,';'); 1235 appendcOFile(fp,';');
1217 appendsOFile(fp,NAME_OF(o)); 1236 appendsOFile(fp,NAME_OF(o));
1218 } 1237 }
1219 else 1238 else
1220 appendcOFile(fp,';'); 1239 appendcOFile(fp,';');
1221 if (VALUE_TYPE(o)) { 1240 if (VALUE_TYPE(o)) {
1222 appendcOFile(fp,'='); 1241 appendcOFile(fp,'=');
1223 writeValue(fp,o,0); 1242 writeValue(fp,o,0,0);
1224 } 1243 }
1225} 1244}
1226 1245
1227static void writeGroup(OFile *fp, VObject *o) 1246static void writeGroup(OFile *fp, VObject *o)
1228{ 1247{
1229 char buf1[256]; 1248 char buf1[256];
1230 char buf2[256]; 1249 char buf2[256];
1231 strcpy(buf1,NAME_OF(o)); 1250 strcpy(buf1,NAME_OF(o));
1232 while ((o=isAPropertyOf(o,VCGroupingProp)) != 0) { 1251 while ((o=isAPropertyOf(o,VCGroupingProp)) != 0) {
1233 strncpy(buf2,STRINGZ_VALUE_OF(o),sizeof(buf2)); 1252 strcpy(buf2,STRINGZ_VALUE_OF(o));
1234 buf2[sizeof(buf2)] = '\0'; 1253 strcat(buf2,".");
1235 strncat(buf2,".",sizeof(buf2)-strlen(buf2)-1); 1254 strcat(buf2,buf1);
1236 strncat(buf2,buf1,sizeof(buf2)-strlen(buf2)-1);
1237 strcpy(buf1,buf2); 1255 strcpy(buf1,buf2);
1238 } 1256 }
1239 appendsOFile(fp,buf1); 1257 appendsOFile(fp,buf1);
1240} 1258}
1241 1259
1242static int inList(const char **list, const char *s) 1260static int inList(const char **list, const char *s)
1243{ 1261{
1244 if (list == 0) return 0; 1262 if (list == 0) return 0;
1245 while (*list) { 1263 while (*list) {
1246 if (strcasecmp(*list,s) == 0) return 1; 1264 if (stricmp(*list,s) == 0) return 1;
1247 list++; 1265 list++;
1248 } 1266 }
1249 return 0; 1267 return 0;
1250} 1268}
1251 1269
1252static void writeProp(OFile *fp, VObject *o) 1270static void writeProp(OFile *fp, VObject *o)
1253{ 1271{
1272 int isQuoted=0;
1254 if (NAME_OF(o)) { 1273 if (NAME_OF(o)) {
1255 struct PreDefProp *pi; 1274 struct PreDefProp *pi;
1256 VObjectIterator t; 1275 VObjectIterator t;
1257 const char **fields_ = 0; 1276 const char **fields_ = 0;
1258 pi = lookupPropInfo(NAME_OF(o)); 1277 pi = lookupPropInfo(NAME_OF(o));
1259 if (pi && ((pi->flags & PD_BEGIN) != 0)) { 1278 if (pi && ((pi->flags & PD_BEGIN) != 0)) {
1260 writeVObject_(fp,o); 1279 writeVObject_(fp,o);
1261 return; 1280 return;
1262 } 1281 }
1263 if (isAPropertyOf(o,VCGroupingProp)) 1282 if (isAPropertyOf(o,VCGroupingProp))
1264 writeGroup(fp,o); 1283 writeGroup(fp,o);
1265 else 1284 else
1266 appendsOFile(fp,NAME_OF(o)); 1285 appendsOFile(fp,NAME_OF(o));
1267 if (pi) fields_ = pi->fields; 1286 if (pi) fields_ = pi->fields;
1268 initPropIterator(&t,o); 1287 initPropIterator(&t,o);
1269 while (moreIteration(&t)) { 1288 while (moreIteration(&t)) {
1270 const char *s; 1289 const char *s;
1271 VObject *eachProp = nextVObject(&t); 1290 VObject *eachProp = nextVObject(&t);
1272 s = NAME_OF(eachProp); 1291 s = NAME_OF(eachProp);
1273 if (strcasecmp(VCGroupingProp,s) && !inList(fields_,s)) 1292 if (stricmp(VCGroupingProp,s) && !inList(fields_,s))
1274 writeAttrValue(fp,eachProp); 1293 writeAttrValue(fp,eachProp);
1294 if (stricmp(VCQPProp,s)==0 || stricmp(VCQuotedPrintableProp,s)==0)
1295 isQuoted=1;
1275 } 1296 }
1276 if (fields_) { 1297 if (fields_) {
1277 int i = 0, n = 0; 1298 int i = 0, n = 0;
1278 const char** fields = fields_; 1299 const char** fields = fields_;
1279 /* output prop as fields */ 1300 /* output prop as fields */
1280 appendcOFile(fp,':'); 1301 appendcOFile(fp,':');
1281 while (*fields) { 1302 while (*fields) {
1282 VObject *tl = isAPropertyOf(o,*fields); 1303 VObject *t = isAPropertyOf(o,*fields);
1283 i++; 1304 i++;
1284 if (tl) n = i; 1305 if (t) n = i;
1285 fields++; 1306 fields++;
1286 } 1307 }
1287 fields = fields_; 1308 fields = fields_;
1288 for (i=0;i<n;i++) { 1309 for (i=0;i<n;i++) {
1289 writeValue(fp,isAPropertyOf(o,*fields),0); 1310 writeValue(fp,isAPropertyOf(o,*fields),0,isQuoted);
1290 fields++; 1311 fields++;
1291 if (i<(n-1)) appendcOFile(fp,';'); 1312 if (i<(n-1)) appendcOFile(fp,';');
1292 } 1313 }
1293 } 1314 }
1294 } 1315 }
1295 1316
1296 if (VALUE_TYPE(o)) { 1317 if (VALUE_TYPE(o)) {
1297 unsigned long size = 0; 1318 unsigned long size = 0;
1298 VObject *p = isAPropertyOf(o,VCDataSizeProp); 1319 VObject *p = isAPropertyOf(o,VCDataSizeProp);
1299 if (p) size = LONG_VALUE_OF(p); 1320 if (p) size = LONG_VALUE_OF(p);
1300 appendcOFile(fp,':'); 1321 appendcOFile(fp,':');
1301 writeValue(fp,o,size); 1322 writeValue(fp,o,size,isQuoted);
1302 } 1323 }
1303 1324
1304 appendcOFile(fp,'\n'); 1325 appendcOFile(fp,'\n');
1305} 1326}
1306 1327
1307static void writeVObject_(OFile *fp, VObject *o) 1328static void writeVObject_(OFile *fp, VObject *o)
1308{ 1329{
1309 if (NAME_OF(o)) { 1330 if (NAME_OF(o)) {
1310 struct PreDefProp *pi; 1331 struct PreDefProp *pi;
1311 pi = lookupPropInfo(NAME_OF(o)); 1332 pi = lookupPropInfo(NAME_OF(o));
1312 1333
1313 if (pi && ((pi->flags & PD_BEGIN) != 0)) { 1334 if (pi && ((pi->flags & PD_BEGIN) != 0)) {
1314 VObjectIterator t; 1335 VObjectIterator t;
1315 const char *begin = NAME_OF(o); 1336 const char *begin = NAME_OF(o);
1316 appendsOFile(fp,"BEGIN:"); 1337 appendsOFile(fp,"BEGIN:");
1317 appendsOFile(fp,begin); 1338 appendsOFile(fp,begin);
1318 appendcOFile(fp,'\n'); 1339 appendcOFile(fp,'\n');
1319 initPropIterator(&t,o); 1340 initPropIterator(&t,o);
1320 while (moreIteration(&t)) { 1341 while (moreIteration(&t)) {
1321 VObject *eachProp = nextVObject(&t); 1342 VObject *eachProp = nextVObject(&t);
1322 writeProp(fp, eachProp); 1343 writeProp(fp, eachProp);
1323 } 1344 }
1324 appendsOFile(fp,"END:"); 1345 appendsOFile(fp,"END:");
1325 appendsOFile(fp,begin); 1346 appendsOFile(fp,begin);
1326 appendsOFile(fp,"\n\n"); 1347 appendsOFile(fp,"\n\n");
1327 } 1348 }
1328 } 1349 }
1329} 1350}
1330 1351
1331void writeVObject(FILE *fp, VObject *o) 1352void writeVObject(FILE *fp, VObject *o)
1332{ 1353{
1333 OFile ofp; 1354 OFile ofp;
1334 initOFile(&ofp,fp); 1355 initOFile(&ofp,fp);
1335 writeVObject_(&ofp,o); 1356 writeVObject_(&ofp,o);
1336} 1357}
1337 1358
1338void writeVObjectToFile(char *fname, VObject *o) 1359DLLEXPORT(void) writeVObjectToFile(char *fname, VObject *o)
1339{ 1360{
1340 FILE *fp = fopen(fname,"w"); 1361 FILE *fp = fopen(fname,"w");
1341 if (fp) { 1362 if (fp) {
1342 writeVObject(fp,o); 1363 writeVObject(fp,o);
1343 fclose(fp); 1364 fclose(fp);
1344 } 1365 }
1345} 1366}
1346 1367
1347void writeVObjectsToFile(char *fname, VObject *list) 1368DLLEXPORT(void) writeVObjectsToFile(char *fname, VObject *list)
1348{ 1369{
1349 FILE *fp = fopen(fname,"w"); 1370 FILE *fp = fopen(fname,"w");
1350 if (fp) { 1371 if (fp) {
1351 while (list) { 1372 while (list) {
1352 writeVObject(fp,list); 1373 writeVObject(fp,list);
1353 list = nextVObjectInList(list); 1374 list = nextVObjectInList(list);
1354 } 1375 }
1355 fclose(fp); 1376 fclose(fp);
1356 } 1377 }
1357} 1378}
1358 1379
1359char* writeMemVObject(char *s, int *len, VObject *o) 1380DLLEXPORT(char*) writeMemVObject(char *s, int *len, VObject *o)
1360{ 1381{
1361 OFile ofp; 1382 OFile ofp;
1362 initMemOFile(&ofp,s,len?*len:0); 1383 initMemOFile(&ofp,s,len?*len:0);
1363 writeVObject_(&ofp,o); 1384 writeVObject_(&ofp,o);
1364 if (len) *len = ofp.len; 1385 if (len) *len = ofp.len;
1365 appendcOFile(&ofp,0); 1386 appendcOFile(&ofp,0);
1366 return ofp.s; 1387 return ofp.s;
1367} 1388}
1368 1389
1369char* writeMemVObjects(char *s, int *len, VObject *list) 1390DLLEXPORT(char*) writeMemVObjects(char *s, int *len, VObject *list)
1370{ 1391{
1371 OFile ofp; 1392 OFile ofp;
1372 initMemOFile(&ofp,s,len?*len:0); 1393 initMemOFile(&ofp,s,len?*len:0);
1373 while (list) { 1394 while (list) {
1374 writeVObject_(&ofp,list); 1395 writeVObject_(&ofp,list);
1375 list = nextVObjectInList(list); 1396 list = nextVObjectInList(list);
1376 } 1397 }
1377 if (len) *len = ofp.len; 1398 if (len) *len = ofp.len;
1378 appendcOFile(&ofp,0); 1399 appendcOFile(&ofp,0);
1379 return ofp.s; 1400 return ofp.s;
1380} 1401}
1381 1402
1382/*---------------------------------------------------------------------- 1403/*----------------------------------------------------------------------
1383 APIs to do fake Unicode stuff. 1404 APIs to do fake Unicode stuff.
1384 ----------------------------------------------------------------------*/ 1405 ----------------------------------------------------------------------*/
1385wchar_t* fakeUnicode(const char *ps, int *bytes) 1406DLLEXPORT(wchar_t*) fakeUnicode(const char *ps, int *bytes)
1386{ 1407{
1387 wchar_t *r, *pw; 1408 wchar_t *r, *pw;
1388 int len = strlen(ps)+1; 1409 int len = strlen(ps)+1;
1389 1410
1390 pw = r = (wchar_t*)malloc(sizeof(wchar_t)*len); 1411 pw = r = (wchar_t*)malloc(sizeof(wchar_t)*len);
1391 if (bytes) 1412 if (bytes)
1392 *bytes = len * sizeof(wchar_t); 1413 *bytes = len * sizeof(wchar_t);
1393 1414
1394 while (*ps) { 1415 while (*ps) {
1395 if (*ps == '\n') 1416 if (*ps == '\n')
1396 *pw = (wchar_t)0x2028; 1417 *pw = (wchar_t)0x2028;
1397 else if (*ps == '\r') 1418 else if (*ps == '\r')
1398 *pw = (wchar_t)0x2029; 1419 *pw = (wchar_t)0x2029;
1399 else 1420 else
1400 *pw = (wchar_t)(unsigned char)*ps; 1421 *pw = (wchar_t)(unsigned char)*ps;
1401 ps++; pw++; 1422 ps++; pw++;
1402 } 1423 }
1403 *pw = (wchar_t)0; 1424 *pw = (wchar_t)0;
1404 1425
1405 return r; 1426 return r;
1406} 1427}
1407 1428
1408int uStrLen(const wchar_t *u) 1429DLLEXPORT(int) uStrLen(const wchar_t *u)
1409{ 1430{
1410 int i = 0; 1431 int i = 0;
1411 while (*u != (wchar_t)0) { u++; i++; } 1432 while (*u != (wchar_t)0) { u++; i++; }
1412 return i; 1433 return i;
1413} 1434}
1414 1435
1415char* fakeCString(const wchar_t *u) 1436DLLEXPORT(char*) fakeCString(const wchar_t *u)
1416{ 1437{
1417 char *s, *t; 1438 char *s, *t;
1418 int len = uStrLen(u) + 1; 1439 int len = uStrLen(u) + 1;
1419 t = s = (char*)malloc(len+1); 1440 t = s = (char*)malloc(len);
1420 while (*u) { 1441 while (*u) {
1421 if (*u == (wchar_t)0x2028) 1442 if (*u == (wchar_t)0x2028)
1422 *t = '\n'; 1443 *t = '\n';
1423 else if (*u == (wchar_t)0x2029) 1444 else if (*u == (wchar_t)0x2029)
1424 *t = '\r'; 1445 *t = '\r';
1425 else 1446 else
1426 *t = (char)*u; 1447 *t = (char)*u;
1427 u++; t++; 1448 u++; t++;
1428 } 1449 }
1429 *t = 0; 1450 *t = 0;
1430 return s; 1451 return s;
1431} 1452}
1432 1453
1433/* end of source file vobject.c */ 1454/* end of source file vobject.c */
diff --git a/libkcal/versit/vobject.h b/libkcal/versit/vobject.h
index 0ec8b31..85c299e 100644
--- a/libkcal/versit/vobject.h
+++ b/libkcal/versit/vobject.h
@@ -1,384 +1,369 @@
1/*************************************************************************** 1/***************************************************************************
2(C) Copyright 1996 Apple Computer, Inc., AT&T Corp., International 2(C) Copyright 1996 Apple Computer, Inc., AT&T Corp., International
3Business Machines Corporation and Siemens Rolm Communications Inc. 3Business Machines Corporation and Siemens Rolm Communications Inc.
4 4
5For purposes of this license notice, the term Licensors shall mean, 5For purposes of this license notice, the term Licensors shall mean,
6collectively, Apple Computer, Inc., AT&T Corp., International 6collectively, Apple Computer, Inc., AT&T Corp., International
7Business Machines Corporation and Siemens Rolm Communications Inc. 7Business Machines Corporation and Siemens Rolm Communications Inc.
8The term Licensor shall mean any of the Licensors. 8The term Licensor shall mean any of the Licensors.
9 9
10Subject to acceptance of the following conditions, permission is hereby 10Subject to acceptance of the following conditions, permission is hereby
11granted by Licensors without the need for written agreement and without 11granted by Licensors without the need for written agreement and without
12license or royalty fees, to use, copy, modify and distribute this 12license or royalty fees, to use, copy, modify and distribute this
13software for any purpose. 13software for any purpose.
14 14
15The above copyright notice and the following four paragraphs must be 15The above copyright notice and the following four paragraphs must be
16reproduced in all copies of this software and any software including 16reproduced in all copies of this software and any software including
17this software. 17this software.
18 18
19THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS AND NO LICENSOR SHALL HAVE 19THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS AND NO LICENSOR SHALL HAVE
20ANY OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR 20ANY OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR
21MODIFICATIONS. 21MODIFICATIONS.
22 22
23IN NO EVENT SHALL ANY LICENSOR BE LIABLE TO ANY PARTY FOR DIRECT, 23IN NO EVENT SHALL ANY LICENSOR BE LIABLE TO ANY PARTY FOR DIRECT,
24INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT 24INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT
25OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 25OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
26DAMAGE. 26DAMAGE.
27 27
28EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, 28EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED,
29INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE 29INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE
30IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 30IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31PURPOSE. 31PURPOSE.
32 32
33The software is provided with RESTRICTED RIGHTS. Use, duplication, or 33The software is provided with RESTRICTED RIGHTS. Use, duplication, or
34disclosure by the government are subject to restrictions set forth in 34disclosure by the government are subject to restrictions set forth in
35DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable. 35DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable.
36 36
37***************************************************************************/ 37***************************************************************************/
38 38
39/* 39/*
40 40
41The vCard/vCalendar C interface is implemented in the set 41The vCard/vCalendar C interface is implemented in the set
42of files as follows: 42of files as follows:
43 43
44vcc.y, yacc source, and vcc.c, the yacc output you will use 44vcc.y, yacc source, and vcc.c, the yacc output you will use
45implements the core parser 45implements the core parser
46 46
47vobject.c implements an API that insulates the caller from 47vobject.c implements an API that insulates the caller from
48the parser and changes in the vCard/vCalendar BNF 48the parser and changes in the vCard/vCalendar BNF
49 49
50port.h defines compilation environment dependent stuff 50port.h defines compilation environment dependent stuff
51 51
52vcc.h and vobject.h are header files for their .c counterparts 52vcc.h and vobject.h are header files for their .c counterparts
53 53
54vcaltmp.h and vcaltmp.c implement vCalendar "macro" functions 54vcaltmp.h and vcaltmp.c implement vCalendar "macro" functions
55which you may find useful. 55which you may find useful.
56 56
57test.c is a standalone test driver that exercises some of 57test.c is a standalone test driver that exercises some of
58the features of the APIs provided. Invoke test.exe on a 58the features of the APIs provided. Invoke test.exe on a
59VCARD/VCALENDAR input text file and you will see the pretty 59VCARD/VCALENDAR input text file and you will see the pretty
60print output of the internal representation (this pretty print 60print output of the internal representation (this pretty print
61output should give you a good idea of how the internal 61output should give you a good idea of how the internal
62representation looks like -- there is one such output in the 62representation looks like -- there is one such output in the
63following too). Also, a file with the .out suffix is generated 63following too). Also, a file with the .out suffix is generated
64to show that the internal representation can be written back 64to show that the internal representation can be written back
65in the original text format. 65in the original text format.
66 66
67For more information on this API see the readme.txt file 67For more information on this API see the readme.txt file
68which accompanied this distribution. 68which accompanied this distribution.
69 69
70 Also visit: 70 Also visit:
71 71
72 http://www.versit.com 72 http://www.versit.com
73 http://www.ralden.com 73 http://www.ralden.com
74 74
75*/ 75*/
76 76
77 77
78#ifndef __VOBJECT_H__ 78#ifndef __VOBJECT_H__
79#define __VOBJECT_H__ 1 79#define __VOBJECT_H__ 1
80 80
81 81
82#include "port.h" 82#include "port.h"
83#include <stdlib.h> 83#include <stdlib.h>
84#include <stdio.h> 84#include <stdio.h>
85 85
86#if defined(__CPLUSPLUS__) || defined(__cplusplus) 86#if defined(__CPLUSPLUS__) || defined(__cplusplus)
87extern "C" { 87extern "C" {
88#endif 88#endif
89 89
90 90
91 #define VC7bitProp "7BIT" 91 #define VC7bitProp "7BIT"
92 #define VC8bitProp "8BIT" 92 #define VC8bitProp "8BIT"
93 #define VCAAlarmProp "AALARM" 93 #define VCAAlarmProp "AALARM"
94 #define VCAdditionalNamesProp"ADDN" 94 #define VCAdditionalNamesProp"ADDN"
95 #define VCAdrProp "ADR" 95 #define VCAdrProp "ADR"
96 #define VCAgentProp "AGENT" 96 #define VCAgentProp "AGENT"
97 #define VCAIFFProp "AIFF" 97 #define VCAIFFProp "AIFF"
98 #define VCAOLProp "AOL" 98 #define VCAOLProp "AOL"
99 #define VCAppleLinkProp "APPLELINK" 99 #define VCAppleLinkProp "APPLELINK"
100 #define VCAttachProp "ATTACH" 100 #define VCAttachProp "ATTACH"
101 #define VCAttendeeProp "ATTENDEE" 101 #define VCAttendeeProp "ATTENDEE"
102 #define VCATTMailProp "ATTMAIL" 102 #define VCATTMailProp "ATTMAIL"
103 #define VCAudioContentProp "AUDIOCONTENT" 103 #define VCAudioContentProp "AUDIOCONTENT"
104 #define VCAVIProp "AVI" 104 #define VCAVIProp "AVI"
105 #define VCBase64Prop "BASE64" 105 #define VCBase64Prop "BASE64"
106 #define VCBBSProp "BBS" 106 #define VCBBSProp "BBS"
107 #define VCBirthDateProp "BDAY" 107 #define VCBirthDateProp "BDAY"
108 #define VCBMPProp "BMP" 108 #define VCBMPProp "BMP"
109 #define VCBodyProp "BODY" 109 #define VCBodyProp "BODY"
110 #define VCBusinessRoleProp "ROLE" 110 #define VCBusinessRoleProp "ROLE"
111 #define VCCalProp "VCALENDAR" 111 #define VCCalProp "VCALENDAR"
112 #define VCCaptionProp "CAP" 112 #define VCCaptionProp "CAP"
113 #define VCCardProp "VCARD" 113 #define VCCardProp "VCARD"
114 #define VCCarProp "CAR" 114 #define VCCarProp "CAR"
115 #define VCCategoriesProp "CATEGORIES" 115 #define VCCategoriesProp "CATEGORIES"
116 #define VCCellularProp "CELL" 116 #define VCCellularProp "CELL"
117 #define VCCGMProp "CGM" 117 #define VCCGMProp "CGM"
118 #define VCCharSetProp "CS" 118 #define VCCharSetProp "CS"
119 #define VCCIDProp "CID" 119 #define VCCIDProp "CID"
120 #define VCCISProp "CIS" 120 #define VCCISProp "CIS"
121 #define VCCityProp "L" 121 #define VCCityProp "L"
122 #define VCClassProp "CLASS" 122 #define VCClassProp "CLASS"
123 #define VCCommentProp "NOTE" 123 #define VCCommentProp "NOTE"
124 #define VCCompletedProp "COMPLETED" 124 #define VCCompletedProp "COMPLETED"
125 #define VCContentIDProp "CONTENT-ID" 125 #define VCContentIDProp "CONTENT-ID"
126 #define VCCountryNameProp "C" 126 #define VCCountryNameProp "C"
127 #define VCDAlarmProp "DALARM" 127 #define VCDAlarmProp "DALARM"
128 #define VCDataSizeProp "DATASIZE" 128 #define VCDataSizeProp "DATASIZE"
129 #define VCDayLightProp "DAYLIGHT" 129 #define VCDayLightProp "DAYLIGHT"
130 #define VCDCreatedProp "DCREATED" 130 #define VCDCreatedProp "DCREATED"
131#define VCDeliveryLabelProp "LABEL" 131#define VCDeliveryLabelProp "LABEL"
132 #define VCDescriptionProp "DESCRIPTION" 132 #define VCDescriptionProp "DESCRIPTION"
133 #define VCDIBProp "DIB" 133 #define VCDIBProp "DIB"
134 #define VCDisplayStringProp "DISPLAYSTRING" 134 #define VCDisplayStringProp "DISPLAYSTRING"
135 #define VCDomesticProp "DOM" 135 #define VCDomesticProp "DOM"
136 #define VCDTendProp "DTEND" 136 #define VCDTendProp "DTEND"
137 #define VCDTstartProp "DTSTART" 137 #define VCDTstartProp "DTSTART"
138 #define VCDueProp "DUE" 138 #define VCDueProp "DUE"
139 #define VCEmailAddressProp "EMAIL" 139 #define VCEmailAddressProp "EMAIL"
140 #define VCEncodingProp "ENCODING" 140 #define VCEncodingProp "ENCODING"
141 #define VCEndProp "END" 141 #define VCEndProp "END"
142 #define VCEventProp "VEVENT" 142 #define VCEventProp "VEVENT"
143 #define VCEWorldProp "EWORLD" 143 #define VCEWorldProp "EWORLD"
144 #define VCExNumProp "EXNUM" 144 #define VCExNumProp "EXNUM"
145 #define VCExDateProp "EXDATE" 145 #define VCExpDateProp "EXDATE"
146 #define VCExpectProp "EXPECT" 146 #define VCExpectProp "EXPECT"
147 #define VCExtAddressProp "EXT ADD" 147 #define VCExtAddressProp "EXT ADD"
148 #define VCFamilyNameProp "F" 148 #define VCFamilyNameProp "F"
149 #define VCFaxProp "FAX" 149 #define VCFaxProp "FAX"
150 #define VCFullNameProp "FN" 150 #define VCFullNameProp "FN"
151 #define VCGeoProp "GEO" 151 #define VCGeoProp "GEO"
152 #define VCGeoLocationProp "GEO" 152 #define VCGeoLocationProp "GEO"
153 #define VCGIFProp "GIF" 153 #define VCGIFProp "GIF"
154 #define VCGivenNameProp "G" 154 #define VCGivenNameProp "G"
155 #define VCGroupingProp "Grouping" 155 #define VCGroupingProp "Grouping"
156 #define VCHomeProp "HOME" 156 #define VCHomeProp "HOME"
157 #define VCIBMMailProp "IBMMail" 157 #define VCIBMMailProp "IBMMail"
158 #define VCInlineProp "INLINE" 158 #define VCInlineProp "INLINE"
159 #define VCInternationalProp "INTL" 159 #define VCInternationalProp "INTL"
160 #define VCInternetProp "INTERNET" 160 #define VCInternetProp "INTERNET"
161 #define VCISDNProp "ISDN" 161 #define VCISDNProp "ISDN"
162 #define VCJPEGProp "JPEG" 162 #define VCJPEGProp "JPEG"
163 #define VCLanguageProp "LANG" 163 #define VCLanguageProp "LANG"
164 #define VCLastModifiedProp "LAST-MODIFIED" 164 #define VCLastModifiedProp "LAST-MODIFIED"
165 #define VCLastRevisedProp "REV" 165 #define VCLastRevisedProp "REV"
166 #define VCLocationProp "LOCATION" 166 #define VCLocationProp "LOCATION"
167 #define VCLogoProp "LOGO" 167 #define VCLogoProp "LOGO"
168 #define VCMailerProp "MAILER" 168 #define VCMailerProp "MAILER"
169 #define VCMAlarmProp "MALARM" 169 #define VCMAlarmProp "MALARM"
170 #define VCMCIMailProp "MCIMAIL" 170 #define VCMCIMailProp "MCIMAIL"
171 #define VCMessageProp "MSG" 171 #define VCMessageProp "MSG"
172 #define VCMETProp "MET" 172 #define VCMETProp "MET"
173 #define VCModemProp "MODEM" 173 #define VCModemProp "MODEM"
174 #define VCMPEG2Prop "MPEG2" 174 #define VCMPEG2Prop "MPEG2"
175 #define VCMPEGProp "MPEG" 175 #define VCMPEGProp "MPEG"
176 #define VCMSNProp "MSN" 176 #define VCMSNProp "MSN"
177 #define VCNamePrefixesProp "NPRE" 177 #define VCNamePrefixesProp "NPRE"
178 #define VCNameProp "N" 178 #define VCNameProp "N"
179 #define VCNameSuffixesProp "NSUF" 179 #define VCNameSuffixesProp "NSUF"
180 #define VCNoteProp "NOTE" 180 #define VCNoteProp "NOTE"
181 #define VCOrgNameProp "ORGNAME" 181 #define VCOrgNameProp "ORGNAME"
182 #define VCOrgProp "ORG" 182 #define VCOrgProp "ORG"
183 #define VCOrgUnit2Prop "OUN2" 183 #define VCOrgUnit2Prop "OUN2"
184 #define VCOrgUnit3Prop "OUN3" 184 #define VCOrgUnit3Prop "OUN3"
185 #define VCOrgUnit4Prop "OUN4" 185 #define VCOrgUnit4Prop "OUN4"
186 #define VCOrgUnitProp "OUN" 186 #define VCOrgUnitProp "OUN"
187 #define VCPagerProp "PAGER" 187 #define VCPagerProp "PAGER"
188 #define VCPAlarmProp "PALARM" 188 #define VCPAlarmProp "PALARM"
189 #define VCParcelProp "PARCEL" 189 #define VCParcelProp "PARCEL"
190 #define VCPartProp "PART" 190 #define VCPartProp "PART"
191 #define VCPCMProp "PCM" 191 #define VCPCMProp "PCM"
192 #define VCPDFProp "PDF" 192 #define VCPDFProp "PDF"
193 #define VCPGPProp "PGP" 193 #define VCPGPProp "PGP"
194 #define VCPhotoProp "PHOTO" 194 #define VCPhotoProp "PHOTO"
195 #define VCPICTProp "PICT" 195 #define VCPICTProp "PICT"
196 #define VCPMBProp "PMB" 196 #define VCPMBProp "PMB"
197 #define VCPostalBoxProp "BOX" 197 #define VCPostalBoxProp "BOX"
198 #define VCPostalCodeProp "PC" 198 #define VCPostalCodeProp "PC"
199 #define VCPostalProp "POSTAL" 199 #define VCPostalProp "POSTAL"
200 #define VCPowerShareProp "POWERSHARE" 200 #define VCPowerShareProp "POWERSHARE"
201 #define VCPreferredProp "PREF" 201 #define VCPreferredProp "PREF"
202 #define VCPriorityProp "PRIORITY" 202 #define VCPriorityProp "PRIORITY"
203 #define VCProcedureNameProp "PROCEDURENAME" 203 #define VCProcedureNameProp "PROCEDURENAME"
204 #define VCProdIdProp "PRODID" 204 #define VCProdIdProp "PRODID"
205 #define VCProdigyProp "PRODIGY" 205 #define VCProdigyProp "PRODIGY"
206 #define VCPronunciationProp "SOUND" 206 #define VCPronunciationProp "SOUND"
207 #define VCPSProp "PS" 207 #define VCPSProp "PS"
208 #define VCPublicKeyProp "KEY" 208 #define VCPublicKeyProp "KEY"
209 #define VCQPProp "QP" 209 #define VCQPProp "QP"
210 #define VCQuickTimeProp "QTIME" 210 #define VCQuickTimeProp "QTIME"
211 #define VCQuotedPrintableProp"QUOTED-PRINTABLE" 211 #define VCQuotedPrintableProp"QUOTED-PRINTABLE"
212 #define VCRDateProp "RDATE" 212 #define VCRDateProp "RDATE"
213 #define VCRegionProp "R" 213 #define VCRegionProp "R"
214 #define VCRelatedToProp "RELATED-TO" 214 #define VCRelatedToProp "RELATED-TO"
215 #define VCRepeatCountProp "REPEATCOUNT" 215 #define VCRepeatCountProp "REPEATCOUNT"
216 #define VCResourcesProp "RESOURCES" 216 #define VCResourcesProp "RESOURCES"
217 #define VCRNumProp "RNUM" 217 #define VCRNumProp "RNUM"
218 #define VCRoleProp "ROLE" 218 #define VCRoleProp "ROLE"
219 #define VCRRuleProp "RRULE" 219 #define VCRRuleProp "RRULE"
220 #define VCRSVPProp "RSVP" 220 #define VCRSVPProp "RSVP"
221 #define VCRunTimeProp "RUNTIME" 221 #define VCRunTimeProp "RUNTIME"
222 #define VCSequenceProp "SEQUENCE" 222 #define VCSequenceProp "SEQUENCE"
223 #define VCSnoozeTimeProp "SNOOZETIME" 223 #define VCSnoozeTimeProp "SNOOZETIME"
224 #define VCStartProp "START" 224 #define VCStartProp "START"
225 #define VCStatusProp "STATUS" 225 #define VCStatusProp "STATUS"
226 #define VCStreetAddressProp "STREET" 226 #define VCStreetAddressProp "STREET"
227 #define VCSubTypeProp "SUBTYPE" 227 #define VCSubTypeProp "SUBTYPE"
228 #define VCSummaryProp "SUMMARY" 228 #define VCSummaryProp "SUMMARY"
229 #define VCTelephoneProp "TEL" 229 #define VCTelephoneProp "TEL"
230 #define VCTIFFProp "TIFF" 230 #define VCTIFFProp "TIFF"
231 #define VCTimeZoneProp "TZ" 231 #define VCTimeZoneProp "TZ"
232 #define VCTitleProp "TITLE" 232 #define VCTitleProp "TITLE"
233 #define VCTLXProp "TLX" 233 #define VCTLXProp "TLX"
234 #define VCTodoProp "VTODO" 234 #define VCTodoProp "VTODO"
235 #define VCTranspProp "TRANSP" 235 #define VCTranspProp "TRANSP"
236 #define VCUniqueStringProp "UID" 236 #define VCUniqueStringProp "UID"
237 #define VCURLProp "URL" 237 #define VCURLProp "URL"
238 #define VCURLValueProp "URLVAL" 238 #define VCURLValueProp "URLVAL"
239 #define VCValueProp "VALUE" 239 #define VCValueProp "VALUE"
240 #define VCVersionProp "VERSION" 240 #define VCVersionProp "VERSION"
241 #define VCVideoProp "VIDEO" 241 #define VCVideoProp "VIDEO"
242 #define VCVoiceProp "VOICE" 242 #define VCVoiceProp "VOICE"
243 #define VCWAVEProp "WAVE" 243 #define VCWAVEProp "WAVE"
244 #define VCWMFProp "WMF" 244 #define VCWMFProp "WMF"
245 #define VCWorkProp "WORK" 245 #define VCWorkProp "WORK"
246 #define VCX400Prop "X400" 246 #define VCX400Prop "X400"
247 #define VCX509Prop "X509" 247 #define VCX509Prop "X509"
248 #define VCXRuleProp "XRULE" 248 #define VCXRuleProp "XRULE"
249 249
250/* extensions for KOrganizer / KPilot */ 250/* Extensions */
251#define KPilotIdProp "X-PILOTID"
252#define KPilotStatusProp "X-PILOTSTAT"
253 251
252#define XPilotIdProp "X-PILOTID"
253#define XPilotStatusProp "X-PILOTSTAT"
254/* extensions for iMIP / iTIP */ 254/* extensions for iMIP / iTIP */
255#define ICOrganizerProp "X-ORGANIZER" 255#define ICOrganizerProp "X-ORGANIZER"
256#define ICMethodProp "X-METHOD" 256#define ICMethodProp "X-METHOD"
257#define ICRequestStatusProp "X-REQUEST-STATUS" 257#define ICRequestStatusProp "X-REQUEST-STATUS"
258
259typedef struct VObject VObject; 258typedef struct VObject VObject;
260 259
261typedef union ValueItem {
262 const char *strs;
263 const wchar_t *ustrs;
264 unsigned int i;
265 unsigned long l;
266 void *any;
267 VObject *vobj;
268 } ValueItem;
269
270struct VObject {
271 VObject *next;
272 const char *id;
273 VObject *prop;
274 unsigned short valType;
275 ValueItem val;
276 };
277
278typedef struct StrItem StrItem;
279
280struct StrItem {
281 StrItem *next;
282 const char *s;
283 unsigned int refCnt;
284 };
285
286typedef struct VObjectIterator { 260typedef struct VObjectIterator {
287 VObject* start; 261 VObject* start;
288 VObject* next; 262 VObject* next;
289 } VObjectIterator; 263 } VObjectIterator;
290 264
291extern VObject* newVObject(const char *id); 265extern DLLEXPORT(VObject*) newVObject(const char *id);
292extern void deleteVObject(VObject *p); 266extern DLLEXPORT(void) deleteVObject(VObject *p);
293extern char* dupStr(const char *s, unsigned int size); 267extern DLLEXPORT(char*) dupStr(const char *s, unsigned int size);
294extern void deleteStr(const char *p); 268extern DLLEXPORT(void) deleteStr(const char *p);
295extern void unUseStr(const char *s); 269extern DLLEXPORT(void) unUseStr(const char *s);
296 270
297extern void setVObjectName(VObject *o, const char* id); 271extern DLLEXPORT(void) setVObjectName(VObject *o, const char* id);
298extern void setVObjectStringZValue(VObject *o, const char *s); 272extern DLLEXPORT(void) setVObjectStringZValue(VObject *o, const char *s);
299extern void setVObjectStringZValue_(VObject *o, const char *s); 273extern DLLEXPORT(void) setVObjectStringZValue_(VObject *o, const char *s);
300extern void setVObjectUStringZValue(VObject *o, const wchar_t *s); 274extern DLLEXPORT(void) setVObjectUStringZValue(VObject *o, const wchar_t *s);
301extern void setVObjectUStringZValue_(VObject *o, const wchar_t *s); 275extern DLLEXPORT(void) setVObjectUStringZValue_(VObject *o, const wchar_t *s);
302extern void setVObjectIntegerValue(VObject *o, unsigned int i); 276extern DLLEXPORT(void) setVObjectIntegerValue(VObject *o, unsigned int i);
303extern void setVObjectLongValue(VObject *o, unsigned long l); 277extern DLLEXPORT(void) setVObjectLongValue(VObject *o, unsigned long l);
304extern void setVObjectAnyValue(VObject *o, void *t); 278extern DLLEXPORT(void) setVObjectAnyValue(VObject *o, void *t);
305extern VObject* setValueWithSize(VObject *prop, void *val, unsigned int size); 279extern DLLEXPORT(VObject*) setValueWithSize(VObject *prop, void *val, unsigned int size);
306extern VObject* setValueWithSize_(VObject *prop, void *val, unsigned int size); 280extern DLLEXPORT(VObject*) setValueWithSize_(VObject *prop, void *val, unsigned int size);
307 281
308extern const char* vObjectName(VObject *o); 282extern DLLEXPORT(const char*) vObjectName(VObject *o);
309extern const char* vObjectStringZValue(VObject *o); 283extern DLLEXPORT(const char*) vObjectStringZValue(VObject *o);
310extern const wchar_t* vObjectUStringZValue(VObject *o); 284extern DLLEXPORT(const wchar_t*) vObjectUStringZValue(VObject *o);
311extern unsigned int vObjectIntegerValue(VObject *o); 285extern DLLEXPORT(unsigned int) vObjectIntegerValue(VObject *o);
312extern unsigned long vObjectLongValue(VObject *o); 286extern DLLEXPORT(unsigned long) vObjectLongValue(VObject *o);
313extern void* vObjectAnyValue(VObject *o); 287extern DLLEXPORT(void*) vObjectAnyValue(VObject *o);
314extern VObject* vObjectVObjectValue(VObject *o); 288extern DLLEXPORT(VObject*) vObjectVObjectValue(VObject *o);
315extern void setVObjectVObjectValue(VObject *o, VObject *p); 289extern DLLEXPORT(void) setVObjectVObjectValue(VObject *o, VObject *p);
316 290
317extern VObject* addVObjectProp(VObject *o, VObject *p); 291extern DLLEXPORT(VObject*) addVObjectProp(VObject *o, VObject *p);
318extern VObject* addProp(VObject *o, const char *id); 292extern DLLEXPORT(VObject*) addProp(VObject *o, const char *id);
319extern VObject* addProp_(VObject *o, const char *id); 293extern DLLEXPORT(VObject*) addProp_(VObject *o, const char *id);
320extern VObject* addPropValue(VObject *o, const char *p, const char *v); 294extern DLLEXPORT(VObject*) addPropValue(VObject *o, const char *p, const char *v);
321extern VObject* addPropSizedValue_(VObject *o, const char *p, const char *v, unsigned int size); 295extern DLLEXPORT(VObject*) addPropSizedValue_(VObject *o, const char *p, const char *v, unsigned int size);
322extern VObject* addPropSizedValue(VObject *o, const char *p, const char *v, unsigned int size); 296extern DLLEXPORT(VObject*) addPropSizedValue(VObject *o, const char *p, const char *v, unsigned int size);
323extern VObject* addGroup(VObject *o, const char *g); 297extern DLLEXPORT(VObject*) addGroup(VObject *o, const char *g);
324extern void addList(VObject **o, VObject *p); 298extern DLLEXPORT(void) addList(VObject **o, VObject *p);
325 299
326extern VObject* isAPropertyOf(VObject *o, const char *id); 300extern DLLEXPORT(VObject*) isAPropertyOf(VObject *o, const char *id);
327 301
328extern VObject* nextVObjectInList(VObject *o); 302extern DLLEXPORT(VObject*) nextVObjectInList(VObject *o);
329extern void initPropIterator(VObjectIterator *i, VObject *o); 303extern DLLEXPORT(void) initPropIterator(VObjectIterator *i, VObject *o);
330extern int moreIteration(VObjectIterator *i); 304extern DLLEXPORT(int) moreIteration(VObjectIterator *i);
331extern VObject* nextVObject(VObjectIterator *i); 305extern DLLEXPORT(VObject*) nextVObject(VObjectIterator *i);
332 306
333extern char* writeMemVObject(char *s, int *len, VObject *o); 307extern DLLEXPORT(char*) writeMemVObject(char *s, int *len, VObject *o);
334extern char* writeMemVObjects(char *s, int *len, VObject *list); 308extern DLLEXPORT(char*) writeMemVObjects(char *s, int *len, VObject *list);
335 309
336extern const char* lookupStr(const char *s); 310extern DLLEXPORT(const char*) lookupStr(const char *s);
337extern void cleanStrTbl(); 311extern DLLEXPORT(void) cleanStrTbl();
338 312
339extern void cleanVObject(VObject *o); 313extern DLLEXPORT(void) cleanVObject(VObject *o);
340extern void cleanVObjects(VObject *list); 314extern DLLEXPORT(void) cleanVObjects(VObject *list);
341 315
342extern const char* lookupProp(const char* str); 316extern DLLEXPORT(const char*) lookupProp(const char* str);
343extern const char* lookupProp_(const char* str); 317extern DLLEXPORT(const char*) lookupProp_(const char* str);
344 318
345extern wchar_t* fakeUnicode(const char *ps, int *bytes); 319extern DLLEXPORT(wchar_t*) fakeUnicode(const char *ps, int *bytes);
346extern int uStrLen(const wchar_t *u); 320extern DLLEXPORT(int) uStrLen(const wchar_t *u);
347extern char* fakeCString(const wchar_t *u); 321extern DLLEXPORT(char*) fakeCString(const wchar_t *u);
348 322
349extern void printVObjectToFile(char *fname,VObject *o); 323extern DLLEXPORT(void) printVObjectToFile(char *fname,VObject *o);
350extern void printVObjectsToFile(char *fname,VObject *list); 324extern DLLEXPORT(void) printVObjectsToFile(char *fname,VObject *list);
351extern void writeVObjectToFile(char *fname, VObject *o); 325extern DLLEXPORT(void) writeVObjectToFile(char *fname, VObject *o);
352extern void writeVObjectsToFile(char *fname, VObject *list); 326extern DLLEXPORT(void) writeVObjectsToFile(char *fname, VObject *list);
353 327
354extern int vObjectValueType(VObject *o); 328extern DLLEXPORT(int) vObjectValueType(VObject *o);
355 329
356/* return type of vObjectValueType: */ 330/* return type of vObjectValueType: */
357 #define VCVT_NOVALUE0 331 #define VCVT_NOVALUE0
358 /* if the VObject has no value associated with it. */ 332 /* if the VObject has no value associated with it. */
359 #define VCVT_STRINGZ1 333 #define VCVT_STRINGZ1
360 /* if the VObject has value set by setVObjectStringZValue. */ 334 /* if the VObject has value set by setVObjectStringZValue. */
361 #define VCVT_USTRINGZ2 335 #define VCVT_USTRINGZ2
362 /* if the VObject has value set by setVObjectUStringZValue. */ 336 /* if the VObject has value set by setVObjectUStringZValue. */
363 #define VCVT_UINT 3 337 #define VCVT_UINT 3
364 /* if the VObject has value set by setVObjectIntegerValue. */ 338 /* if the VObject has value set by setVObjectIntegerValue. */
365 #define VCVT_ULONG 4 339 #define VCVT_ULONG 4
366 /* if the VObject has value set by setVObjectLongValue. */ 340 /* if the VObject has value set by setVObjectLongValue. */
367 #define VCVT_RAW 5 341 #define VCVT_RAW 5
368 /* if the VObject has value set by setVObjectAnyValue. */ 342 /* if the VObject has value set by setVObjectAnyValue. */
369 #define VCVT_VOBJECT6 343 #define VCVT_VOBJECT6
370 /* if the VObject has value set by setVObjectVObjectValue. */ 344 /* if the VObject has value set by setVObjectVObjectValue. */
371 345
372extern const char** fieldedProp; 346extern const char** fieldedProp;
373 347
348/* NOTE regarding printVObject and writeVObject
349
350The functions below are not exported from the DLL because they
351take a FILE* as a parameter, which cannot be passed across a DLL
352interface (at least that is my experience). Instead you can use
353their companion functions which take file names or pointers
354to memory. However, if you are linking this code into
355your build directly then you may find them a more convenient API
356and you can go ahead and use them. If you try to use them with
357the DLL LIB you will get a link error.
358*/
374extern void printVObject(FILE *fp,VObject *o); 359extern void printVObject(FILE *fp,VObject *o);
375extern void writeVObject(FILE *fp, VObject *o); 360extern void writeVObject(FILE *fp, VObject *o);
376 361
377 362
378#if defined(__CPLUSPLUS__) || defined(__cplusplus) 363#if defined(__CPLUSPLUS__) || defined(__cplusplus)
379} 364}
380#endif 365#endif
381 366
382#endif /* __VOBJECT_H__ */ 367#endif /* __VOBJECT_H__ */
383 368
384 369