summaryrefslogtreecommitdiffabout
authorzautrix <zautrix>2004-10-25 15:27:39 (UTC)
committer zautrix <zautrix>2004-10-25 15:27:39 (UTC)
commit03ca6830a9e6742b8873aee04d77b3e094b65d30 (patch) (unidiff)
tree170ab278ffeb371aae783815101f64275cd30c53
parent62e92aa86b6281b4e4c2a2bdb57f3ceb5a87f4e3 (diff)
downloadkdepimpi-03ca6830a9e6742b8873aee04d77b3e094b65d30.zip
kdepimpi-03ca6830a9e6742b8873aee04d77b3e094b65d30.tar.gz
kdepimpi-03ca6830a9e6742b8873aee04d77b3e094b65d30.tar.bz2
fix of vcal crash
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libkcal/vcalformat.cpp39
-rw-r--r--libkcal/vcalformat.h3
-rw-r--r--libkcal/versit/vcc.c3
3 files changed, 37 insertions, 8 deletions
diff --git a/libkcal/vcalformat.cpp b/libkcal/vcalformat.cpp
index df93209..223aa5a 100644
--- a/libkcal/vcalformat.cpp
+++ b/libkcal/vcalformat.cpp
@@ -1,1720 +1,1747 @@
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 <kglobal.h> 32#include <kglobal.h>
33#include <kmessagebox.h> 33#include <kmessagebox.h>
34#include <kiconloader.h> 34#include <kiconloader.h>
35#include <klocale.h> 35#include <klocale.h>
36 36
37#include "vcc.h" 37#include "vcc.h"
38#include "vobject.h" 38#include "vobject.h"
39 39
40#include "vcaldrag.h" 40#include "vcaldrag.h"
41#include "calendar.h" 41#include "calendar.h"
42 42
43#include "vcalformat.h" 43#include "vcalformat.h"
44 44
45using namespace KCal; 45using namespace KCal;
46 46
47VCalFormat::VCalFormat() 47VCalFormat::VCalFormat()
48{ 48{
49 mCalendar = 0; 49 mCalendar = 0;
50 useLocalTime = false; 50 useLocalTime = false;
51} 51}
52 52
53VCalFormat::~VCalFormat() 53VCalFormat::~VCalFormat()
54{ 54{
55} 55}
56 56
57void VCalFormat::setLocalTime ( bool b ) 57void VCalFormat::setLocalTime ( bool b )
58{ 58{
59 useLocalTime = b; 59 useLocalTime = b;
60} 60}
61bool VCalFormat::load(Calendar *calendar, const QString &fileName) 61bool VCalFormat::load(Calendar *calendar, const QString &fileName)
62{ 62{
63 mCalendar = calendar; 63 mCalendar = calendar;
64 clearException(); 64 clearException();
65 if ( ! useLocalTime ) 65 if ( ! useLocalTime )
66 useLocalTime = mCalendar->isLocalTime(); 66 useLocalTime = mCalendar->isLocalTime();
67 VObject *vcal = 0; 67 VObject *vcal = 0;
68 68
69 // this is not necessarily only 1 vcal. Could be many vcals, or include 69 // this is not necessarily only 1 vcal. Could be many vcals, or include
70 // a vcard... 70 // a vcard...
71 vcal = Parse_MIME_FromFileName(const_cast<char *>(QFile::encodeName(fileName).data())); 71 vcal = Parse_MIME_FromFileName(const_cast<char *>(QFile::encodeName(fileName).data()));
72 72
73 if (!vcal) { 73 if (!vcal) {
74 setException(new ErrorFormat(ErrorFormat::CalVersionUnknown)); 74 setException(new ErrorFormat(ErrorFormat::CalVersionUnknown));
75 return FALSE; 75 return FALSE;
76 } 76 }
77 77
78 // any other top-level calendar stuff should be added/initialized here 78 // any other top-level calendar stuff should be added/initialized here
79 79
80 // put all vobjects into their proper places 80 // put all vobjects into their proper places
81 populate(vcal); 81 populate(vcal);
82 82
83 // clean up from vcal API stuff 83 // clean up from vcal API stuff
84 cleanVObjects(vcal); 84 cleanVObjects(vcal);
85 cleanStrTbl(); 85 cleanStrTbl();
86 86
87 return true; 87 return true;
88} 88}
89 89
90 90
91bool VCalFormat::save(Calendar *calendar, const QString &fileName) 91bool VCalFormat::save(Calendar *calendar, const QString &fileName)
92{ 92{
93 mCalendar = calendar; 93 mCalendar = calendar;
94 if ( ! useLocalTime ) 94 if ( ! useLocalTime )
95 useLocalTime = mCalendar->isLocalTime(); 95 useLocalTime = mCalendar->isLocalTime();
96 96
97 QString tmpStr; 97 QString tmpStr;
98 VObject *vcal, *vo; 98 VObject *vcal, *vo;
99 99
100 100
101 vcal = newVObject(VCCalProp); 101 vcal = newVObject(VCCalProp);
102 102
103 // addPropValue(vcal,VCLocationProp, "0.0"); 103 // addPropValue(vcal,VCLocationProp, "0.0");
104 addPropValue(vcal,VCProdIdProp, productId()); 104 addPropValue(vcal,VCProdIdProp, productId());
105 tmpStr = mCalendar->getTimeZoneStr(); 105 tmpStr = mCalendar->getTimeZoneStr();
106 //qDebug("mCalendar->getTimeZoneStr() %s",tmpStr.latin1() ); 106 //qDebug("mCalendar->getTimeZoneStr() %s",tmpStr.latin1() );
107 addPropValue(vcal,VCTimeZoneProp, tmpStr.local8Bit()); 107 addPropValue(vcal,VCTimeZoneProp, tmpStr.local8Bit());
108 addPropValue(vcal,VCVersionProp, _VCAL_VERSION); 108 addPropValue(vcal,VCVersionProp, _VCAL_VERSION);
109 109
110 // TODO STUFF 110 // TODO STUFF
111 QPtrList<Todo> todoList = mCalendar->rawTodos(); 111 QPtrList<Todo> todoList = mCalendar->rawTodos();
112 QPtrListIterator<Todo> qlt(todoList); 112 QPtrListIterator<Todo> qlt(todoList);
113 for (; qlt.current(); ++qlt) { 113 for (; qlt.current(); ++qlt) {
114 vo = eventToVTodo(qlt.current()); 114 vo = eventToVTodo(qlt.current());
115 addVObjectProp(vcal, vo); 115 addVObjectProp(vcal, vo);
116 } 116 }
117 117
118 // EVENT STUFF 118 // EVENT STUFF
119 QPtrList<Event> events = mCalendar->rawEvents(); 119 QPtrList<Event> events = mCalendar->rawEvents();
120 Event *ev; 120 Event *ev;
121 for(ev=events.first();ev;ev=events.next()) { 121 for(ev=events.first();ev;ev=events.next()) {
122 vo = eventToVEvent(ev); 122 vo = eventToVEvent(ev);
123 addVObjectProp(vcal, vo); 123 addVObjectProp(vcal, vo);
124 } 124 }
125 125
126 writeVObjectToFile(QFile::encodeName(fileName).data() ,vcal); 126 writeVObjectToFile(QFile::encodeName(fileName).data() ,vcal);
127 cleanVObjects(vcal); 127 cleanVObjects(vcal);
128 cleanStrTbl(); 128 cleanStrTbl();
129 129
130 if (QFile::exists(fileName)) { 130 if (QFile::exists(fileName)) {
131 return true; 131 return true;
132 } else { 132 } else {
133 return false; // error 133 return false; // error
134 } 134 }
135} 135}
136 136
137bool VCalFormat::fromString( Calendar *calendar, const QString &text ) 137bool VCalFormat::fromString( Calendar *calendar, const QString &text )
138{ 138{
139 // TODO: Factor out VCalFormat::fromString() 139 // TODO: Factor out VCalFormat::fromString()
140 140
141 QCString data = text.utf8(); 141 QCString data = text.utf8();
142 142
143 if ( !data.size() ) return false; 143 if ( !data.size() ) return false;
144 144
145 VObject *vcal = Parse_MIME( data.data(), data.size()); 145 VObject *vcal = Parse_MIME( data.data(), data.size());
146 if ( !vcal ) return false; 146 if ( !vcal ) return false;
147 147
148 VObjectIterator i; 148 VObjectIterator i;
149 VObject *curvo; 149 VObject *curvo;
150 initPropIterator( &i, vcal ); 150 initPropIterator( &i, vcal );
151 151
152 // we only take the first object. TODO: parse all incidences. 152 // we only take the first object. TODO: parse all incidences.
153 do { 153 do {
154 curvo = nextVObject( &i ); 154 curvo = nextVObject( &i );
155 } while ( strcmp( vObjectName( curvo ), VCEventProp ) && 155 } while ( strcmp( vObjectName( curvo ), VCEventProp ) &&
156 strcmp( vObjectName( curvo ), VCTodoProp ) ); 156 strcmp( vObjectName( curvo ), VCTodoProp ) );
157 157
158 if ( strcmp( vObjectName( curvo ), VCEventProp ) == 0 ) { 158 if ( strcmp( vObjectName( curvo ), VCEventProp ) == 0 ) {
159 Event *event = VEventToEvent( curvo ); 159 Event *event = VEventToEvent( curvo );
160 calendar->addEvent( event ); 160 calendar->addEvent( event );
161 } else { 161 } else {
162 qDebug("VCalFormat::fromString(): Unknown object type. "); 162 qDebug("VCalFormat::fromString(): Unknown object type. ");
163 deleteVObject( vcal ); 163 deleteVObject( vcal );
164 return false; 164 return false;
165 } 165 }
166 166
167 deleteVObject( vcal ); 167 deleteVObject( vcal );
168 168
169 return true; 169 return true;
170} 170}
171 171
172QString VCalFormat::eventToString( Event * event, Calendar *calendar, bool useLocal) 172QString VCalFormat::eventToString( Event * event, Calendar *calendar, bool useLocal)
173{ 173{
174 174
175 if ( !event ) return QString::null; 175 if ( !event ) return QString::null;
176 bool useL = useLocalTime; 176 bool useL = useLocalTime;
177 useLocalTime = useLocal; 177 useLocalTime = useLocal;
178 mCalendar = calendar; 178 mCalendar = calendar;
179 VObject *vevent = eventToVEvent( event ); 179 VObject *vevent = eventToVEvent( event );
180 char *buf = writeMemVObject( 0, 0, vevent ); 180 char *buf = writeMemVObject( 0, 0, vevent );
181 QString result( buf ); 181 QString result( buf );
182 cleanVObject( vevent ); 182 cleanVObject( vevent );
183 useLocalTime = useL; 183 useLocalTime = useL;
184 return result; 184 return result;
185} 185}
186QString VCalFormat::todoToString( Todo * todo, Calendar *calendar, bool useLocal ) 186QString VCalFormat::todoToString( Todo * todo, Calendar *calendar, bool useLocal )
187{ 187{
188 188
189 if ( !todo ) return QString::null; 189 if ( !todo ) return QString::null;
190 bool useL = useLocalTime; 190 bool useL = useLocalTime;
191 useLocalTime = useLocal; 191 useLocalTime = useLocal;
192 mCalendar = calendar; 192 mCalendar = calendar;
193 VObject *vevent = eventToVTodo( todo ); 193 VObject *vevent = eventToVTodo( todo );
194 char *buf = writeMemVObject( 0, 0, vevent ); 194 char *buf = writeMemVObject( 0, 0, vevent );
195 QString result( buf ); 195 QString result( buf );
196 cleanVObject( vevent ); 196 cleanVObject( vevent );
197 useLocalTime = useL; 197 useLocalTime = useL;
198 return result; 198 return result;
199} 199}
200 200
201QString VCalFormat::toString( Calendar *calendar ) 201QString VCalFormat::toString( Calendar *calendar )
202{ 202{
203 // TODO: Factor out VCalFormat::asString() 203 // TODO: Factor out VCalFormat::asString()
204 204
205 VObject *vcal = newVObject(VCCalProp); 205 VObject *vcal = newVObject(VCCalProp);
206 206
207 addPropValue( vcal, VCProdIdProp, CalFormat::productId() ); 207 addPropValue( vcal, VCProdIdProp, CalFormat::productId() );
208 QString tmpStr = mCalendar->getTimeZoneStr(); 208 QString tmpStr = mCalendar->getTimeZoneStr();
209 addPropValue( vcal, VCTimeZoneProp, tmpStr.local8Bit() ); 209 addPropValue( vcal, VCTimeZoneProp, tmpStr.local8Bit() );
210 addPropValue( vcal, VCVersionProp, _VCAL_VERSION ); 210 addPropValue( vcal, VCVersionProp, _VCAL_VERSION );
211 211
212 // TODO: Use all data. 212 // TODO: Use all data.
213 QPtrList<Event> events = calendar->events(); 213 QPtrList<Event> events = calendar->events();
214 Event *event = events.first(); 214 Event *event = events.first();
215 if ( !event ) return QString::null; 215 if ( !event ) return QString::null;
216 216
217 VObject *vevent = eventToVEvent( event ); 217 VObject *vevent = eventToVEvent( event );
218 218
219 addVObjectProp( vcal, vevent ); 219 addVObjectProp( vcal, vevent );
220 220
221 char *buf = writeMemVObject( 0, 0, vcal ); 221 char *buf = writeMemVObject( 0, 0, vcal );
222 222
223 QString result( buf ); 223 QString result( buf );
224 224
225 cleanVObject( vcal ); 225 cleanVObject( vcal );
226 226
227 return result; 227 return result;
228} 228}
229 229
230VObject *VCalFormat::eventToVTodo(const Todo *anEvent) 230VObject *VCalFormat::eventToVTodo(const Todo *anEvent)
231{ 231{
232 VObject *vtodo; 232 VObject *vtodo;
233 QString tmpStr; 233 QString tmpStr;
234 QStringList tmpStrList; 234 QStringList tmpStrList;
235 235
236 vtodo = newVObject(VCTodoProp); 236 vtodo = newVObject(VCTodoProp);
237 237
238 // due date 238 // due date
239 if (anEvent->hasDueDate()) { 239 if (anEvent->hasDueDate()) {
240 tmpStr = qDateTimeToISO(anEvent->dtDue(), 240 tmpStr = qDateTimeToISO(anEvent->dtDue(),
241 !anEvent->doesFloat()); 241 !anEvent->doesFloat());
242 addPropValue(vtodo, VCDueProp, tmpStr.local8Bit()); 242 addPropValue(vtodo, VCDueProp, tmpStr.local8Bit());
243 } 243 }
244 244
245 // start date 245 // start date
246 if (anEvent->hasStartDate()) { 246 if (anEvent->hasStartDate()) {
247 tmpStr = qDateTimeToISO(anEvent->dtStart(), 247 tmpStr = qDateTimeToISO(anEvent->dtStart(),
248 !anEvent->doesFloat()); 248 !anEvent->doesFloat());
249 addPropValue(vtodo, VCDTstartProp, tmpStr.local8Bit()); 249 addPropValue(vtodo, VCDTstartProp, tmpStr.local8Bit());
250 } 250 }
251 251
252 // creation date 252 // creation date
253 tmpStr = qDateTimeToISO(anEvent->created()); 253 tmpStr = qDateTimeToISO(anEvent->created());
254 addPropValue(vtodo, VCDCreatedProp, tmpStr.local8Bit()); 254 addPropValue(vtodo, VCDCreatedProp, tmpStr.local8Bit());
255 255
256 // unique id 256 // unique id
257 addPropValue(vtodo, VCUniqueStringProp, 257 addPropValue(vtodo, VCUniqueStringProp,
258 anEvent->uid().local8Bit()); 258 anEvent->uid().local8Bit());
259 259
260 // revision 260 // revision
261 tmpStr.sprintf("%i", anEvent->revision()); 261 tmpStr.sprintf("%i", anEvent->revision());
262 addPropValue(vtodo, VCSequenceProp, tmpStr.local8Bit()); 262 addPropValue(vtodo, VCSequenceProp, tmpStr.local8Bit());
263 263
264 // last modification date 264 // last modification date
265 tmpStr = qDateTimeToISO(anEvent->lastModified()); 265 tmpStr = qDateTimeToISO(anEvent->lastModified());
266 addPropValue(vtodo, VCLastModifiedProp, tmpStr.local8Bit()); 266 addPropValue(vtodo, VCLastModifiedProp, tmpStr.local8Bit());
267 267
268 // organizer stuff 268 // organizer stuff
269 tmpStr = "MAILTO:" + anEvent->organizer(); 269 tmpStr = "MAILTO:" + anEvent->organizer();
270 addPropValue(vtodo, ICOrganizerProp, tmpStr.local8Bit()); 270 addPropValue(vtodo, ICOrganizerProp, tmpStr.local8Bit());
271 271
272 // attendees 272 // attendees
273 if (anEvent->attendeeCount() != 0) { 273 if (anEvent->attendeeCount() != 0) {
274 QPtrList<Attendee> al = anEvent->attendees(); 274 QPtrList<Attendee> al = anEvent->attendees();
275 QPtrListIterator<Attendee> ai(al); 275 QPtrListIterator<Attendee> ai(al);
276 Attendee *curAttendee; 276 Attendee *curAttendee;
277 277
278 for (; ai.current(); ++ai) { 278 for (; ai.current(); ++ai) {
279 curAttendee = ai.current(); 279 curAttendee = ai.current();
280 if (!curAttendee->email().isEmpty() && 280 if (!curAttendee->email().isEmpty() &&
281 !curAttendee->name().isEmpty()) 281 !curAttendee->name().isEmpty())
282 tmpStr = "MAILTO:" + curAttendee->name() + " <" + 282 tmpStr = "MAILTO:" + curAttendee->name() + " <" +
283 curAttendee->email() + ">"; 283 curAttendee->email() + ">";
284 else if (curAttendee->name().isEmpty()) 284 else if (curAttendee->name().isEmpty())
285 tmpStr = "MAILTO: " + curAttendee->email(); 285 tmpStr = "MAILTO: " + curAttendee->email();
286 else if (curAttendee->email().isEmpty()) 286 else if (curAttendee->email().isEmpty())
287 tmpStr = "MAILTO: " + curAttendee->name(); 287 tmpStr = "MAILTO: " + curAttendee->name();
288 else if (curAttendee->name().isEmpty() && 288 else if (curAttendee->name().isEmpty() &&
289 curAttendee->email().isEmpty()) 289 curAttendee->email().isEmpty())
290 kdDebug(5800) << "warning! this Event has an attendee w/o name or email!" << endl; 290 kdDebug(5800) << "warning! this Event has an attendee w/o name or email!" << endl;
291 VObject *aProp = addPropValue(vtodo, VCAttendeeProp, tmpStr.local8Bit()); 291 VObject *aProp = addPropValue(vtodo, VCAttendeeProp, tmpStr.local8Bit());
292 addPropValue(aProp, VCRoleProp, writeRole(curAttendee->role()));
292 addPropValue(aProp, VCRSVPProp, curAttendee->RSVP() ? "TRUE" : "FALSE"); 293 addPropValue(aProp, VCRSVPProp, curAttendee->RSVP() ? "TRUE" : "FALSE");
293 addPropValue(aProp, VCStatusProp, writeStatus(curAttendee->status())); 294 addPropValue(aProp, VCStatusProp, writeStatus(curAttendee->status()));
294 } 295 }
295 } 296 }
296 297
297 // description BL: 298 // description BL:
298 if (!anEvent->description().isEmpty()) { 299 if (!anEvent->description().isEmpty()) {
299 VObject *d = addPropValue(vtodo, VCDescriptionProp, 300 VObject *d = addPropValue(vtodo, VCDescriptionProp,
300 anEvent->description().local8Bit()); 301 anEvent->description().local8Bit());
301 if (anEvent->description().find('\n') != -1) 302 if (anEvent->description().find('\n') != -1)
302 addProp(d, VCQuotedPrintableProp); 303 addProp(d, VCQuotedPrintableProp);
303 } 304 }
304 305
305 // summary 306 // summary
306 if (!anEvent->summary().isEmpty()) 307 if (!anEvent->summary().isEmpty())
307 addPropValue(vtodo, VCSummaryProp, anEvent->summary().local8Bit()); 308 addPropValue(vtodo, VCSummaryProp, anEvent->summary().local8Bit());
308 309
309 if (!anEvent->location().isEmpty()) 310 if (!anEvent->location().isEmpty())
310 addPropValue(vtodo, VCLocationProp, anEvent->location().local8Bit()); 311 addPropValue(vtodo, VCLocationProp, anEvent->location().local8Bit());
311 312
312 // completed 313 // completed
313 // status 314 // status
314 // backward compatibility, KOrganizer used to interpret only these two values 315 // backward compatibility, KOrganizer used to interpret only these two values
315 addPropValue(vtodo, VCStatusProp, anEvent->isCompleted() ? "COMPLETED" : 316 addPropValue(vtodo, VCStatusProp, anEvent->isCompleted() ? "COMPLETED" :
316 "NEEDS_ACTION"); 317 "NEEDS_ACTION");
317 // completion date 318 // completion date
318 if (anEvent->hasCompletedDate()) { 319 if (anEvent->hasCompletedDate()) {
319 tmpStr = qDateTimeToISO(anEvent->completed()); 320 tmpStr = qDateTimeToISO(anEvent->completed());
320 addPropValue(vtodo, VCCompletedProp, tmpStr.local8Bit()); 321 addPropValue(vtodo, VCCompletedProp, tmpStr.local8Bit());
321 } 322 }
322 323
323 // priority 324 // priority
324 tmpStr.sprintf("%i",anEvent->priority()); 325 tmpStr.sprintf("%i",anEvent->priority());
325 addPropValue(vtodo, VCPriorityProp, tmpStr.local8Bit()); 326 addPropValue(vtodo, VCPriorityProp, tmpStr.local8Bit());
326 327
327 // related event 328 // related event
328 if (anEvent->relatedTo()) { 329 if (anEvent->relatedTo()) {
329 addPropValue(vtodo, VCRelatedToProp, 330 addPropValue(vtodo, VCRelatedToProp,
330 anEvent->relatedTo()->uid().local8Bit()); 331 anEvent->relatedTo()->uid().local8Bit());
331 } 332 }
332 333
333 // categories 334 // categories
334 tmpStrList = anEvent->categories(); 335 tmpStrList = anEvent->categories();
335 tmpStr = ""; 336 tmpStr = "";
336 QString catStr; 337 QString catStr;
337 for ( QStringList::Iterator it = tmpStrList.begin(); 338 for ( QStringList::Iterator it = tmpStrList.begin();
338 it != tmpStrList.end(); 339 it != tmpStrList.end();
339 ++it ) { 340 ++it ) {
340 catStr = *it; 341 catStr = *it;
341 if (catStr[0] == ' ') 342 if (catStr[0] == ' ')
342 tmpStr += catStr.mid(1); 343 tmpStr += catStr.mid(1);
343 else 344 else
344 tmpStr += catStr; 345 tmpStr += catStr;
345 // this must be a ';' character as the vCalendar specification requires! 346 // this must be a ';' character as the vCalendar specification requires!
346 // vcc.y has been hacked to translate the ';' to a ',' when the vcal is 347 // vcc.y has been hacked to translate the ';' to a ',' when the vcal is
347 // read in. 348 // read in.
348 tmpStr += ";"; 349 tmpStr += ";";
349 } 350 }
350 if (!tmpStr.isEmpty()) { 351 if (!tmpStr.isEmpty()) {
351 tmpStr.truncate(tmpStr.length()-1); 352 tmpStr.truncate(tmpStr.length()-1);
352 addPropValue(vtodo, VCCategoriesProp, tmpStr.local8Bit()); 353 addPropValue(vtodo, VCCategoriesProp, tmpStr.local8Bit());
353 } 354 }
354 355
355 // alarm stuff 356 // alarm stuff
356 kdDebug(5800) << "vcalformat::eventToVTodo was called" << endl; 357 kdDebug(5800) << "vcalformat::eventToVTodo was called" << endl;
357 QPtrList<Alarm> alarms = anEvent->alarms(); 358 QPtrList<Alarm> alarms = anEvent->alarms();
358 Alarm* alarm; 359 Alarm* alarm;
359 for (alarm = alarms.first(); alarm; alarm = alarms.next()) { 360 for (alarm = alarms.first(); alarm; alarm = alarms.next()) {
360 if (alarm->enabled()) { 361 if (alarm->enabled()) {
361 VObject *a; 362 VObject *a;
362 tmpStr = qDateTimeToISO(alarm->time()); 363 tmpStr = qDateTimeToISO(alarm->time());
363 if (alarm->type() == Alarm::Audio) { 364 if (alarm->type() == Alarm::Audio) {
364 a = addProp(vtodo, VCAAlarmProp); 365 a = addProp(vtodo, VCAAlarmProp);
365 addPropValue(a, VCRunTimeProp, tmpStr.local8Bit()); 366 addPropValue(a, VCRunTimeProp, tmpStr.local8Bit());
366 addPropValue(a, VCRepeatCountProp, "1"); 367 addPropValue(a, VCRepeatCountProp, "1");
367 addPropValue(a, VCAudioContentProp, QFile::encodeName(alarm->audioFile())); 368 addPropValue(a, VCAudioContentProp, QFile::encodeName(alarm->audioFile()));
368 } 369 }
369 else if (alarm->type() == Alarm::Procedure) { 370 else if (alarm->type() == Alarm::Procedure) {
370 a = addProp(vtodo, VCPAlarmProp); 371 a = addProp(vtodo, VCPAlarmProp);
371 addPropValue(a, VCRunTimeProp, tmpStr.local8Bit()); 372 addPropValue(a, VCRunTimeProp, tmpStr.local8Bit());
372 addPropValue(a, VCRepeatCountProp, "1"); 373 addPropValue(a, VCRepeatCountProp, "1");
373 addPropValue(a, VCProcedureNameProp, QFile::encodeName(alarm->programFile())); 374 addPropValue(a, VCProcedureNameProp, QFile::encodeName(alarm->programFile()));
374 } else { 375 } else {
375 a = addProp(vtodo, VCDAlarmProp); 376 a = addProp(vtodo, VCDAlarmProp);
376 addPropValue(a, VCRunTimeProp, tmpStr.local8Bit()); 377 addPropValue(a, VCRunTimeProp, tmpStr.local8Bit());
377 addPropValue(a, VCRepeatCountProp, "1"); 378 addPropValue(a, VCRepeatCountProp, "1");
378 addPropValue(a, VCDisplayStringProp, "beep!"); 379 addPropValue(a, VCDisplayStringProp, "beep!");
379 } 380 }
380 } 381 }
381 } 382 }
382 383
383 if (anEvent->pilotId()) { 384 if (anEvent->pilotId()) {
384 // pilot sync stuff 385 // pilot sync stuff
385 tmpStr.sprintf("%i",anEvent->pilotId()); 386 tmpStr.sprintf("%i",anEvent->pilotId());
386 addPropValue(vtodo, XPilotIdProp, tmpStr.local8Bit()); 387 addPropValue(vtodo, XPilotIdProp, tmpStr.local8Bit());
387 tmpStr.sprintf("%i",anEvent->syncStatus()); 388 tmpStr.sprintf("%i",anEvent->syncStatus());
388 addPropValue(vtodo, XPilotStatusProp, tmpStr.local8Bit()); 389 addPropValue(vtodo, XPilotStatusProp, tmpStr.local8Bit());
389 } 390 }
390 391
391 return vtodo; 392 return vtodo;
392} 393}
393 394
394VObject* VCalFormat::eventToVEvent(const Event *anEvent) 395VObject* VCalFormat::eventToVEvent(const Event *anEvent)
395{ 396{
396 VObject *vevent; 397 VObject *vevent;
397 QString tmpStr; 398 QString tmpStr;
398 QStringList tmpStrList; 399 QStringList tmpStrList;
399 400
400 vevent = newVObject(VCEventProp); 401 vevent = newVObject(VCEventProp);
401 402
402 // start and end time 403 // start and end time
403 tmpStr = qDateTimeToISO(anEvent->dtStart(), 404 tmpStr = qDateTimeToISO(anEvent->dtStart(),
404 !anEvent->doesFloat()); 405 !anEvent->doesFloat());
405 addPropValue(vevent, VCDTstartProp, tmpStr.local8Bit()); 406 addPropValue(vevent, VCDTstartProp, tmpStr.local8Bit());
406 407
407 // events that have time associated but take up no time should 408 // events that have time associated but take up no time should
408 // not have both DTSTART and DTEND. 409 // not have both DTSTART and DTEND.
409 if (anEvent->dtStart() != anEvent->dtEnd()) { 410 if (anEvent->dtStart() != anEvent->dtEnd()) {
410 tmpStr = qDateTimeToISO(anEvent->dtEnd(), 411 tmpStr = qDateTimeToISO(anEvent->dtEnd(),
411 !anEvent->doesFloat()); 412 !anEvent->doesFloat());
412 addPropValue(vevent, VCDTendProp, tmpStr.local8Bit()); 413 addPropValue(vevent, VCDTendProp, tmpStr.local8Bit());
413 } 414 }
414 415
415 // creation date 416 // creation date
416 tmpStr = qDateTimeToISO(anEvent->created()); 417 tmpStr = qDateTimeToISO(anEvent->created());
417 addPropValue(vevent, VCDCreatedProp, tmpStr.local8Bit()); 418 addPropValue(vevent, VCDCreatedProp, tmpStr.local8Bit());
418 419
419 // unique id 420 // unique id
420 addPropValue(vevent, VCUniqueStringProp, 421 addPropValue(vevent, VCUniqueStringProp,
421 anEvent->uid().local8Bit()); 422 anEvent->uid().local8Bit());
422 423
423 // revision 424 // revision
424 tmpStr.sprintf("%i", anEvent->revision()); 425 tmpStr.sprintf("%i", anEvent->revision());
425 addPropValue(vevent, VCSequenceProp, tmpStr.local8Bit()); 426 addPropValue(vevent, VCSequenceProp, tmpStr.local8Bit());
426 427
427 // last modification date 428 // last modification date
428 tmpStr = qDateTimeToISO(anEvent->lastModified()); 429 tmpStr = qDateTimeToISO(anEvent->lastModified());
429 addPropValue(vevent, VCLastModifiedProp, tmpStr.local8Bit()); 430 addPropValue(vevent, VCLastModifiedProp, tmpStr.local8Bit());
430 431
431 // attendee and organizer stuff 432 // attendee and organizer stuff
432 tmpStr = "MAILTO:" + anEvent->organizer(); 433 tmpStr = "MAILTO:" + anEvent->organizer();
433 addPropValue(vevent, ICOrganizerProp, tmpStr.local8Bit()); 434 addPropValue(vevent, ICOrganizerProp, tmpStr.local8Bit());
434 435
435 if (anEvent->attendeeCount() != 0) { 436 if (anEvent->attendeeCount() != 0) {
436 QPtrList<Attendee> al = anEvent->attendees(); 437 QPtrList<Attendee> al = anEvent->attendees();
437 QPtrListIterator<Attendee> ai(al); 438 QPtrListIterator<Attendee> ai(al);
438 Attendee *curAttendee; 439 Attendee *curAttendee;
439 440
440 // TODO: Put this functionality into Attendee class 441 // TODO: Put this functionality into Attendee class
441 for (; ai.current(); ++ai) { 442 for (; ai.current(); ++ai) {
442 curAttendee = ai.current(); 443 curAttendee = ai.current();
443 if (!curAttendee->email().isEmpty() && 444 if (!curAttendee->email().isEmpty() &&
444 !curAttendee->name().isEmpty()) 445 !curAttendee->name().isEmpty())
445 tmpStr = "MAILTO:" + curAttendee->name() + " <" + 446 tmpStr = "MAILTO:" + curAttendee->name() + " <" +
446 curAttendee->email() + ">"; 447 curAttendee->email() + ">";
447 else if (curAttendee->name().isEmpty()) 448 else if (curAttendee->name().isEmpty())
448 tmpStr = "MAILTO: " + curAttendee->email(); 449 tmpStr = "MAILTO: " + curAttendee->email();
449 else if (curAttendee->email().isEmpty()) 450 else if (curAttendee->email().isEmpty())
450 tmpStr = "MAILTO: " + curAttendee->name(); 451 tmpStr = "MAILTO: " + curAttendee->name();
451 else if (curAttendee->name().isEmpty() && 452 else if (curAttendee->name().isEmpty() &&
452 curAttendee->email().isEmpty()) 453 curAttendee->email().isEmpty())
453 kdDebug(5800) << "warning! this Event has an attendee w/o name or email!" << endl; 454 kdDebug(5800) << "warning! this Event has an attendee w/o name or email!" << endl;
454 VObject *aProp = addPropValue(vevent, VCAttendeeProp, tmpStr.local8Bit()); 455 VObject *aProp = addPropValue(vevent, VCAttendeeProp, tmpStr.local8Bit());
455 addPropValue(aProp, VCRSVPProp, curAttendee->RSVP() ? "TRUE" : "FALSE");; 456 addPropValue(aProp, VCRoleProp, writeRole(curAttendee->role()));
457 addPropValue(aProp, VCRSVPProp, curAttendee->RSVP() ? "TRUE" : "FALSE");
456 addPropValue(aProp, VCStatusProp, writeStatus(curAttendee->status())); 458 addPropValue(aProp, VCStatusProp, writeStatus(curAttendee->status()));
457 } 459 }
458 } 460 }
459 461
460 // recurrence rule stuff 462 // recurrence rule stuff
461 if (anEvent->recurrence()->doesRecur()) { 463 if (anEvent->recurrence()->doesRecur()) {
462 // some more variables 464 // some more variables
463 QPtrList<Recurrence::rMonthPos> tmpPositions; 465 QPtrList<Recurrence::rMonthPos> tmpPositions;
464 QPtrList<int> tmpDays; 466 QPtrList<int> tmpDays;
465 int *tmpDay; 467 int *tmpDay;
466 Recurrence::rMonthPos *tmpPos; 468 Recurrence::rMonthPos *tmpPos;
467 QString tmpStr2; 469 QString tmpStr2;
468 int i; 470 int i;
469 471
470 switch(anEvent->recurrence()->doesRecur()) { 472 switch(anEvent->recurrence()->doesRecur()) {
471 case Recurrence::rDaily: 473 case Recurrence::rDaily:
472 tmpStr.sprintf("D%i ",anEvent->recurrence()->frequency()); 474 tmpStr.sprintf("D%i ",anEvent->recurrence()->frequency());
473// if (anEvent->rDuration > 0) 475// if (anEvent->rDuration > 0)
474 //tmpStr += "#"; 476 //tmpStr += "#";
475 break; 477 break;
476 case Recurrence::rWeekly: 478 case Recurrence::rWeekly:
477 tmpStr.sprintf("W%i ",anEvent->recurrence()->frequency()); 479 tmpStr.sprintf("W%i ",anEvent->recurrence()->frequency());
478 for (i = 0; i < 7; i++) { 480 for (i = 0; i < 7; i++) {
479 if (anEvent->recurrence()->days().testBit(i)) 481 if (anEvent->recurrence()->days().testBit(i))
480 tmpStr += dayFromNum(i); 482 tmpStr += dayFromNum(i);
481 } 483 }
482 break; 484 break;
483 case Recurrence::rMonthlyPos: 485 case Recurrence::rMonthlyPos:
484 tmpStr.sprintf("MP%i ", anEvent->recurrence()->frequency()); 486 tmpStr.sprintf("MP%i ", anEvent->recurrence()->frequency());
485 // write out all rMonthPos's 487 // write out all rMonthPos's
486 tmpPositions = anEvent->recurrence()->monthPositions(); 488 tmpPositions = anEvent->recurrence()->monthPositions();
487 for (tmpPos = tmpPositions.first(); 489 for (tmpPos = tmpPositions.first();
488 tmpPos; 490 tmpPos;
489 tmpPos = tmpPositions.next()) { 491 tmpPos = tmpPositions.next()) {
490 492
491 tmpStr2.sprintf("%i", tmpPos->rPos); 493 tmpStr2.sprintf("%i", tmpPos->rPos);
492 if (tmpPos->negative) 494 if (tmpPos->negative)
493 tmpStr2 += "- "; 495 tmpStr2 += "- ";
494 else 496 else
495 tmpStr2 += "+ "; 497 tmpStr2 += "+ ";
496 tmpStr += tmpStr2; 498 tmpStr += tmpStr2;
497 for (i = 0; i < 7; i++) { 499 for (i = 0; i < 7; i++) {
498 if (tmpPos->rDays.testBit(i)) 500 if (tmpPos->rDays.testBit(i))
499 tmpStr += dayFromNum(i); 501 tmpStr += dayFromNum(i);
500 } 502 }
501 } // loop for all rMonthPos's 503 } // loop for all rMonthPos's
502 break; 504 break;
503 case Recurrence::rMonthlyDay: 505 case Recurrence::rMonthlyDay:
504 tmpStr.sprintf("MD%i ", anEvent->recurrence()->frequency()); 506 tmpStr.sprintf("MD%i ", anEvent->recurrence()->frequency());
505 // write out all rMonthDays; 507 // write out all rMonthDays;
506 tmpDays = anEvent->recurrence()->monthDays(); 508 tmpDays = anEvent->recurrence()->monthDays();
507 for (tmpDay = tmpDays.first(); 509 for (tmpDay = tmpDays.first();
508 tmpDay; 510 tmpDay;
509 tmpDay = tmpDays.next()) { 511 tmpDay = tmpDays.next()) {
510 tmpStr2.sprintf("%i ", *tmpDay); 512 tmpStr2.sprintf("%i ", *tmpDay);
511 tmpStr += tmpStr2; 513 tmpStr += tmpStr2;
512 } 514 }
513 break; 515 break;
514 case Recurrence::rYearlyMonth: 516 case Recurrence::rYearlyMonth:
515 tmpStr.sprintf("YM%i ", anEvent->recurrence()->frequency()); 517 tmpStr.sprintf("YM%i ", anEvent->recurrence()->frequency());
516 // write out all the rYearNums; 518 // write out all the rYearNums;
517 tmpDays = anEvent->recurrence()->yearNums(); 519 tmpDays = anEvent->recurrence()->yearNums();
518 for (tmpDay = tmpDays.first(); 520 for (tmpDay = tmpDays.first();
519 tmpDay; 521 tmpDay;
520 tmpDay = tmpDays.next()) { 522 tmpDay = tmpDays.next()) {
521 tmpStr2.sprintf("%i ", *tmpDay); 523 tmpStr2.sprintf("%i ", *tmpDay);
522 tmpStr += tmpStr2; 524 tmpStr += tmpStr2;
523 } 525 }
524 break; 526 break;
525 case Recurrence::rYearlyDay: 527 case Recurrence::rYearlyDay:
526 tmpStr.sprintf("YD%i ", anEvent->recurrence()->frequency()); 528 tmpStr.sprintf("YD%i ", anEvent->recurrence()->frequency());
527 // write out all the rYearNums; 529 // write out all the rYearNums;
528 tmpDays = anEvent->recurrence()->yearNums(); 530 tmpDays = anEvent->recurrence()->yearNums();
529 for (tmpDay = tmpDays.first(); 531 for (tmpDay = tmpDays.first();
530 tmpDay; 532 tmpDay;
531 tmpDay = tmpDays.next()) { 533 tmpDay = tmpDays.next()) {
532 tmpStr2.sprintf("%i ", *tmpDay); 534 tmpStr2.sprintf("%i ", *tmpDay);
533 tmpStr += tmpStr2; 535 tmpStr += tmpStr2;
534 } 536 }
535 break; 537 break;
536 default: 538 default:
537 kdDebug(5800) << "ERROR, it should never get here in eventToVEvent!" << endl; 539 kdDebug(5800) << "ERROR, it should never get here in eventToVEvent!" << endl;
538 break; 540 break;
539 } // switch 541 } // switch
540 542
541 if (anEvent->recurrence()->duration() > 0) { 543 if (anEvent->recurrence()->duration() > 0) {
542 tmpStr2.sprintf("#%i",anEvent->recurrence()->duration()); 544 tmpStr2.sprintf("#%i",anEvent->recurrence()->duration());
543 tmpStr += tmpStr2; 545 tmpStr += tmpStr2;
544 } else if (anEvent->recurrence()->duration() == -1) { 546 } else if (anEvent->recurrence()->duration() == -1) {
545 tmpStr += "#0"; // defined as repeat forever 547 tmpStr += "#0"; // defined as repeat forever
546 } else { 548 } else {
547 tmpStr += qDateTimeToISO(anEvent->recurrence()->endDate(), FALSE); 549 tmpStr += qDateTimeToISO(anEvent->recurrence()->endDate(), FALSE);
548 } 550 }
549 addPropValue(vevent,VCRRuleProp, tmpStr.local8Bit()); 551 addPropValue(vevent,VCRRuleProp, tmpStr.local8Bit());
550 552
551 } // event repeats 553 } // event repeats
552 554
553 // exceptions to recurrence 555 // exceptions to recurrence
554 DateList dateList = anEvent->exDates(); 556 DateList dateList = anEvent->exDates();
555 DateList::ConstIterator it; 557 DateList::ConstIterator it;
556 QString tmpStr2; 558 QString tmpStr2;
557 559
558 for (it = dateList.begin(); it != dateList.end(); ++it) { 560 for (it = dateList.begin(); it != dateList.end(); ++it) {
559 tmpStr = qDateToISO(*it) + ";"; 561 tmpStr = qDateToISO(*it) + ";";
560 tmpStr2 += tmpStr; 562 tmpStr2 += tmpStr;
561 } 563 }
562 if (!tmpStr2.isEmpty()) { 564 if (!tmpStr2.isEmpty()) {
563 tmpStr2.truncate(tmpStr2.length()-1); 565 tmpStr2.truncate(tmpStr2.length()-1);
564 addPropValue(vevent, VCExpDateProp, tmpStr2.local8Bit()); 566 addPropValue(vevent, VCExpDateProp, tmpStr2.local8Bit());
565 } 567 }
566 568
567 // description 569 // description
568 if (!anEvent->description().isEmpty()) { 570 if (!anEvent->description().isEmpty()) {
569 VObject *d = addPropValue(vevent, VCDescriptionProp, 571 VObject *d = addPropValue(vevent, VCDescriptionProp,
570 anEvent->description().local8Bit()); 572 anEvent->description().local8Bit());
571 if (anEvent->description().find('\n') != -1) 573 if (anEvent->description().find('\n') != -1)
572 addProp(d, VCQuotedPrintableProp); 574 addProp(d, VCQuotedPrintableProp);
573 } 575 }
574 576
575 // summary 577 // summary
576 if (!anEvent->summary().isEmpty()) 578 if (!anEvent->summary().isEmpty())
577 addPropValue(vevent, VCSummaryProp, anEvent->summary().local8Bit()); 579 addPropValue(vevent, VCSummaryProp, anEvent->summary().local8Bit());
578 580
579 if (!anEvent->location().isEmpty()) 581 if (!anEvent->location().isEmpty())
580 addPropValue(vevent, VCLocationProp, anEvent->location().local8Bit()); 582 addPropValue(vevent, VCLocationProp, anEvent->location().local8Bit());
581 583
582 // status 584 // status
583// TODO: define Event status 585// TODO: define Event status
584// addPropValue(vevent, VCStatusProp, anEvent->statusStr().local8Bit()); 586// addPropValue(vevent, VCStatusProp, anEvent->statusStr().local8Bit());
585 587
586 // secrecy 588 // secrecy
587 const char *text = 0; 589 const char *text = 0;
588 switch (anEvent->secrecy()) { 590 switch (anEvent->secrecy()) {
589 case Incidence::SecrecyPublic: 591 case Incidence::SecrecyPublic:
590 text = "PUBLIC"; 592 text = "PUBLIC";
591 break; 593 break;
592 case Incidence::SecrecyPrivate: 594 case Incidence::SecrecyPrivate:
593 text = "PRIVATE"; 595 text = "PRIVATE";
594 break; 596 break;
595 case Incidence::SecrecyConfidential: 597 case Incidence::SecrecyConfidential:
596 text = "CONFIDENTIAL"; 598 text = "CONFIDENTIAL";
597 break; 599 break;
598 } 600 }
599 if (text) { 601 if (text) {
600 addPropValue(vevent, VCClassProp, text); 602 addPropValue(vevent, VCClassProp, text);
601 } 603 }
602 604
603 // categories 605 // categories
604 tmpStrList = anEvent->categories(); 606 tmpStrList = anEvent->categories();
605 tmpStr = ""; 607 tmpStr = "";
606 QString catStr; 608 QString catStr;
607 for ( QStringList::Iterator it = tmpStrList.begin(); 609 for ( QStringList::Iterator it = tmpStrList.begin();
608 it != tmpStrList.end(); 610 it != tmpStrList.end();
609 ++it ) { 611 ++it ) {
610 catStr = *it; 612 catStr = *it;
611 if (catStr[0] == ' ') 613 if (catStr[0] == ' ')
612 tmpStr += catStr.mid(1); 614 tmpStr += catStr.mid(1);
613 else 615 else
614 tmpStr += catStr; 616 tmpStr += catStr;
615 // this must be a ';' character as the vCalendar specification requires! 617 // this must be a ';' character as the vCalendar specification requires!
616 // vcc.y has been hacked to translate the ';' to a ',' when the vcal is 618 // vcc.y has been hacked to translate the ';' to a ',' when the vcal is
617 // read in. 619 // read in.
618 tmpStr += ";"; 620 tmpStr += ";";
619 } 621 }
620 if (!tmpStr.isEmpty()) { 622 if (!tmpStr.isEmpty()) {
621 tmpStr.truncate(tmpStr.length()-1); 623 tmpStr.truncate(tmpStr.length()-1);
622 addPropValue(vevent, VCCategoriesProp, tmpStr.local8Bit()); 624 addPropValue(vevent, VCCategoriesProp, tmpStr.local8Bit());
623 } 625 }
624 626
625 // attachments 627 // attachments
626 // TODO: handle binary attachments! 628 // TODO: handle binary attachments!
627 QPtrList<Attachment> attachments = anEvent->attachments(); 629 QPtrList<Attachment> attachments = anEvent->attachments();
628 for ( Attachment *at = attachments.first(); at; at = attachments.next() ) 630 for ( Attachment *at = attachments.first(); at; at = attachments.next() )
629 addPropValue(vevent, VCAttachProp, at->uri().local8Bit()); 631 addPropValue(vevent, VCAttachProp, at->uri().local8Bit());
630 632
631 // resources 633 // resources
632 tmpStrList = anEvent->resources(); 634 tmpStrList = anEvent->resources();
633 tmpStr = tmpStrList.join(";"); 635 tmpStr = tmpStrList.join(";");
634 if (!tmpStr.isEmpty()) 636 if (!tmpStr.isEmpty())
635 addPropValue(vevent, VCResourcesProp, tmpStr.local8Bit()); 637 addPropValue(vevent, VCResourcesProp, tmpStr.local8Bit());
636 638
637 // alarm stuff 639 // alarm stuff
638 QPtrList<Alarm> alarms = anEvent->alarms(); 640 QPtrList<Alarm> alarms = anEvent->alarms();
639 Alarm* alarm; 641 Alarm* alarm;
640 for (alarm = alarms.first(); alarm; alarm = alarms.next()) { 642 for (alarm = alarms.first(); alarm; alarm = alarms.next()) {
641 if (alarm->enabled()) { 643 if (alarm->enabled()) {
642 VObject *a ; 644 VObject *a ;
643 tmpStr = qDateTimeToISO(alarm->time()); 645 tmpStr = qDateTimeToISO(alarm->time());
644 if (alarm->type() == Alarm::Audio) { 646 if (alarm->type() == Alarm::Audio) {
645 a = addProp(vevent, VCAAlarmProp); 647 a = addProp(vevent, VCAAlarmProp);
646 addPropValue(a, VCRunTimeProp, tmpStr.local8Bit()); 648 addPropValue(a, VCRunTimeProp, tmpStr.local8Bit());
647 addPropValue(a, VCRepeatCountProp, "1"); 649 addPropValue(a, VCRepeatCountProp, "1");
648 addPropValue(a, VCAudioContentProp, QFile::encodeName(alarm->audioFile())); 650 addPropValue(a, VCAudioContentProp, QFile::encodeName(alarm->audioFile()));
649 } 651 }
650 if (alarm->type() == Alarm::Procedure) { 652 if (alarm->type() == Alarm::Procedure) {
651 a = addProp(vevent, VCPAlarmProp); 653 a = addProp(vevent, VCPAlarmProp);
652 addPropValue(a, VCRunTimeProp, tmpStr.local8Bit()); 654 addPropValue(a, VCRunTimeProp, tmpStr.local8Bit());
653 addPropValue(a, VCRepeatCountProp, "1"); 655 addPropValue(a, VCRepeatCountProp, "1");
654 addPropValue(a, VCProcedureNameProp, QFile::encodeName(alarm->programFile())); 656 addPropValue(a, VCProcedureNameProp, QFile::encodeName(alarm->programFile()));
655 } else { 657 } else {
656 a = addProp(vevent, VCDAlarmProp); 658 a = addProp(vevent, VCDAlarmProp);
657 addPropValue(a, VCRunTimeProp, tmpStr.local8Bit()); 659 addPropValue(a, VCRunTimeProp, tmpStr.local8Bit());
658 addPropValue(a, VCRepeatCountProp, "1"); 660 addPropValue(a, VCRepeatCountProp, "1");
659 addPropValue(a, VCDisplayStringProp, "beep!"); 661 addPropValue(a, VCDisplayStringProp, "beep!");
660 662
661 } 663 }
662 } 664 }
663 } 665 }
664 666
665 // priority 667 // priority
666 tmpStr.sprintf("%i",anEvent->priority()); 668 tmpStr.sprintf("%i",anEvent->priority());
667 addPropValue(vevent, VCPriorityProp, tmpStr.local8Bit()); 669 addPropValue(vevent, VCPriorityProp, tmpStr.local8Bit());
668 670
669 // transparency 671 // transparency
670 tmpStr.sprintf("%i",anEvent->transparency()); 672 tmpStr.sprintf("%i",anEvent->transparency());
671 addPropValue(vevent, VCTranspProp, tmpStr.local8Bit()); 673 addPropValue(vevent, VCTranspProp, tmpStr.local8Bit());
672 674
673 // related event 675 // related event
674 if (anEvent->relatedTo()) { 676 if (anEvent->relatedTo()) {
675 addPropValue(vevent, VCRelatedToProp, 677 addPropValue(vevent, VCRelatedToProp,
676 anEvent->relatedTo()->uid().local8Bit()); 678 anEvent->relatedTo()->uid().local8Bit());
677 } 679 }
678 680
679 if (anEvent->pilotId()) { 681 if (anEvent->pilotId()) {
680 // pilot sync stuff 682 // pilot sync stuff
681 tmpStr.sprintf("%i",anEvent->pilotId()); 683 tmpStr.sprintf("%i",anEvent->pilotId());
682 addPropValue(vevent, XPilotIdProp, tmpStr.local8Bit()); 684 addPropValue(vevent, XPilotIdProp, tmpStr.local8Bit());
683 tmpStr.sprintf("%i",anEvent->syncStatus()); 685 tmpStr.sprintf("%i",anEvent->syncStatus());
684 addPropValue(vevent, XPilotStatusProp, tmpStr.local8Bit()); 686 addPropValue(vevent, XPilotStatusProp, tmpStr.local8Bit());
685 } 687 }
686 688
687 return vevent; 689 return vevent;
688} 690}
689 691
690Todo *VCalFormat::VTodoToEvent(VObject *vtodo) 692Todo *VCalFormat::VTodoToEvent(VObject *vtodo)
691{ 693{
692 VObject *vo; 694 VObject *vo;
693 VObjectIterator voi; 695 VObjectIterator voi;
694 char *s; 696 char *s;
695 697
696 Todo *anEvent = new Todo; 698 Todo *anEvent = new Todo;
697 699
698 // creation date 700 // creation date
699 if ((vo = isAPropertyOf(vtodo, VCDCreatedProp)) != 0) { 701 if ((vo = isAPropertyOf(vtodo, VCDCreatedProp)) != 0) {
700 anEvent->setCreated(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo)))); 702 anEvent->setCreated(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo))));
701 deleteStr(s); 703 deleteStr(s);
702 } 704 }
703 705
704 // unique id 706 // unique id
705 vo = isAPropertyOf(vtodo, VCUniqueStringProp); 707 vo = isAPropertyOf(vtodo, VCUniqueStringProp);
706 // while the UID property is preferred, it is not required. We'll use the 708 // while the UID property is preferred, it is not required. We'll use the
707 // default Event UID if none is given. 709 // default Event UID if none is given.
708 if (vo) { 710 if (vo) {
709 anEvent->setUid(s = fakeCString(vObjectUStringZValue(vo))); 711 anEvent->setUid(s = fakeCString(vObjectUStringZValue(vo)));
710 deleteStr(s); 712 deleteStr(s);
711 } 713 }
712 714
713 // last modification date 715 // last modification date
714 if ((vo = isAPropertyOf(vtodo, VCLastModifiedProp)) != 0) { 716 if ((vo = isAPropertyOf(vtodo, VCLastModifiedProp)) != 0) {
715 anEvent->setLastModified(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo)))); 717 anEvent->setLastModified(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo))));
716 deleteStr(s); 718 deleteStr(s);
717 } 719 }
718 else 720 else
719 anEvent->setLastModified(QDateTime(QDate::currentDate(), 721 anEvent->setLastModified(QDateTime(QDate::currentDate(),
720 QTime::currentTime())); 722 QTime::currentTime()));
721 723
722 // organizer 724 // organizer
723 // if our extension property for the event's ORGANIZER exists, add it. 725 // if our extension property for the event's ORGANIZER exists, add it.
724 if ((vo = isAPropertyOf(vtodo, ICOrganizerProp)) != 0) { 726 if ((vo = isAPropertyOf(vtodo, ICOrganizerProp)) != 0) {
725 anEvent->setOrganizer(s = fakeCString(vObjectUStringZValue(vo))); 727 anEvent->setOrganizer(s = fakeCString(vObjectUStringZValue(vo)));
726 deleteStr(s); 728 deleteStr(s);
727 } else { 729 } else {
728 anEvent->setOrganizer(mCalendar->getEmail()); 730 anEvent->setOrganizer(mCalendar->getEmail());
729 } 731 }
730 732
731 // attendees. 733 // attendees.
732 initPropIterator(&voi, vtodo); 734 initPropIterator(&voi, vtodo);
733 while (moreIteration(&voi)) { 735 while (moreIteration(&voi)) {
734 vo = nextVObject(&voi); 736 vo = nextVObject(&voi);
735 if (strcmp(vObjectName(vo), VCAttendeeProp) == 0) { 737 if (strcmp(vObjectName(vo), VCAttendeeProp) == 0) {
736 Attendee *a; 738 Attendee *a;
737 VObject *vp; 739 VObject *vp;
738 s = fakeCString(vObjectUStringZValue(vo)); 740 s = fakeCString(vObjectUStringZValue(vo));
739 QString tmpStr = QString::fromLocal8Bit(s); 741 QString tmpStr = QString::fromLocal8Bit(s);
740 deleteStr(s); 742 deleteStr(s);
741 tmpStr = tmpStr.simplifyWhiteSpace(); 743 tmpStr = tmpStr.simplifyWhiteSpace();
742 int emailPos1, emailPos2; 744 int emailPos1, emailPos2;
743 if ((emailPos1 = tmpStr.find('<')) > 0) { 745 if ((emailPos1 = tmpStr.find('<')) > 0) {
744 // both email address and name 746 // both email address and name
745 emailPos2 = tmpStr.findRev('>'); 747 emailPos2 = tmpStr.findRev('>');
746 a = new Attendee(tmpStr.left(emailPos1 - 1), 748 a = new Attendee(tmpStr.left(emailPos1 - 1),
747 tmpStr.mid(emailPos1 + 1, 749 tmpStr.mid(emailPos1 + 1,
748 emailPos2 - (emailPos1 + 1))); 750 emailPos2 - (emailPos1 + 1)));
749 } else if (tmpStr.find('@') > 0) { 751 } else if (tmpStr.find('@') > 0) {
750 // just an email address 752 // just an email address
751 a = new Attendee(0, tmpStr); 753 a = new Attendee(0, tmpStr);
752 } else { 754 } else {
753 // just a name 755 // just a name
754 QString email = tmpStr.replace( QRegExp(" "), "." ); 756 // QString email = tmpStr.replace( QRegExp(" "), "." );
755 a = new Attendee(tmpStr,email); 757 a = new Attendee(tmpStr,0);
756 } 758 }
757 759 // is there a Role property?
760 if ((vp = isAPropertyOf(vo, VCRoleProp)) != 0)
761 a->setRole(readRole(vObjectStringZValue(vp)));
758 // is there an RSVP property? 762 // is there an RSVP property?
759 if ((vp = isAPropertyOf(vo, VCRSVPProp)) != 0) 763 if ((vp = isAPropertyOf(vo, VCRSVPProp)) != 0)
760 a->setRSVP(vObjectStringZValue(vp)); 764 a->setRSVP(vObjectStringZValue(vp));
761 // is there a status property? 765 // is there a status property?
762 if ((vp = isAPropertyOf(vo, VCStatusProp)) != 0) 766 if ((vp = isAPropertyOf(vo, VCStatusProp)) != 0)
763 a->setStatus(readStatus(vObjectStringZValue(vp))); 767 a->setStatus(readStatus(vObjectStringZValue(vp)));
764 // add the attendee 768 // add the attendee
765 anEvent->addAttendee(a); 769 anEvent->addAttendee(a);
766 } 770 }
767 } 771 }
768 772
769 // description for todo 773 // description for todo
770 if ((vo = isAPropertyOf(vtodo, VCDescriptionProp)) != 0) { 774 if ((vo = isAPropertyOf(vtodo, VCDescriptionProp)) != 0) {
771 s = fakeCString(vObjectUStringZValue(vo)); 775 s = fakeCString(vObjectUStringZValue(vo));
772 anEvent->setDescription(QString::fromLocal8Bit(s)); 776 anEvent->setDescription(QString::fromLocal8Bit(s));
773 deleteStr(s); 777 deleteStr(s);
774 } 778 }
775 779
776 // summary 780 // summary
777 if ((vo = isAPropertyOf(vtodo, VCSummaryProp))) { 781 if ((vo = isAPropertyOf(vtodo, VCSummaryProp))) {
778 s = fakeCString(vObjectUStringZValue(vo)); 782 s = fakeCString(vObjectUStringZValue(vo));
779 anEvent->setSummary(QString::fromLocal8Bit(s)); 783 anEvent->setSummary(QString::fromLocal8Bit(s));
780 deleteStr(s); 784 deleteStr(s);
781 } 785 }
782 if ((vo = isAPropertyOf(vtodo, VCLocationProp))) { 786 if ((vo = isAPropertyOf(vtodo, VCLocationProp))) {
783 s = fakeCString(vObjectUStringZValue(vo)); 787 s = fakeCString(vObjectUStringZValue(vo));
784 anEvent->setLocation(QString::fromLocal8Bit(s)); 788 anEvent->setLocation(QString::fromLocal8Bit(s));
785 deleteStr(s); 789 deleteStr(s);
786 } 790 }
787 791
788 792
789 // completed 793 // completed
790 // was: status 794 // was: status
791 if ((vo = isAPropertyOf(vtodo, VCStatusProp)) != 0) { 795 if ((vo = isAPropertyOf(vtodo, VCStatusProp)) != 0) {
792 s = fakeCString(vObjectUStringZValue(vo)); 796 s = fakeCString(vObjectUStringZValue(vo));
793 if (strcmp(s,"COMPLETED") == 0) { 797 if (strcmp(s,"COMPLETED") == 0) {
794 anEvent->setCompleted(true); 798 anEvent->setCompleted(true);
795 } else { 799 } else {
796 anEvent->setCompleted(false); 800 anEvent->setCompleted(false);
797 } 801 }
798 deleteStr(s); 802 deleteStr(s);
799 } 803 }
800 else 804 else
801 anEvent->setCompleted(false); 805 anEvent->setCompleted(false);
802 806
803 // completion date 807 // completion date
804 if ((vo = isAPropertyOf(vtodo, VCCompletedProp)) != 0) { 808 if ((vo = isAPropertyOf(vtodo, VCCompletedProp)) != 0) {
805 anEvent->setCompleted(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo)))); 809 anEvent->setCompleted(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo))));
806 deleteStr(s); 810 deleteStr(s);
807 } 811 }
808 812
809 // priority 813 // priority
810 if ((vo = isAPropertyOf(vtodo, VCPriorityProp))) { 814 if ((vo = isAPropertyOf(vtodo, VCPriorityProp))) {
811 anEvent->setPriority(atoi(s = fakeCString(vObjectUStringZValue(vo)))); 815 anEvent->setPriority(atoi(s = fakeCString(vObjectUStringZValue(vo))));
812 deleteStr(s); 816 deleteStr(s);
813 } 817 }
814 818
815 // due date 819 // due date
816 if ((vo = isAPropertyOf(vtodo, VCDueProp)) != 0) { 820 if ((vo = isAPropertyOf(vtodo, VCDueProp)) != 0) {
817 anEvent->setDtDue(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo)))); 821 anEvent->setDtDue(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo))));
818 deleteStr(s); 822 deleteStr(s);
819 anEvent->setHasDueDate(true); 823 anEvent->setHasDueDate(true);
820 } else { 824 } else {
821 anEvent->setHasDueDate(false); 825 anEvent->setHasDueDate(false);
822 } 826 }
823 827
824 // start time 828 // start time
825 if ((vo = isAPropertyOf(vtodo, VCDTstartProp)) != 0) { 829 if ((vo = isAPropertyOf(vtodo, VCDTstartProp)) != 0) {
826 anEvent->setDtStart(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo)))); 830 anEvent->setDtStart(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo))));
827 // kdDebug(5800) << "s is " << // s << ", ISO is " << ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo))).toString() << endl; 831 // kdDebug(5800) << "s is " << // s << ", ISO is " << ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo))).toString() << endl;
828 deleteStr(s); 832 deleteStr(s);
829 anEvent->setHasStartDate(true); 833 anEvent->setHasStartDate(true);
830 } else { 834 } else {
831 anEvent->setHasStartDate(false); 835 anEvent->setHasStartDate(false);
832 } 836 }
833 837
834 /* alarm stuff */ 838 /* alarm stuff */
835 //kdDebug(5800) << "vcalformat::VTodoToEvent called" << endl; 839 //kdDebug(5800) << "vcalformat::VTodoToEvent called" << endl;
836 if ((vo = isAPropertyOf(vtodo, VCDAlarmProp))) { 840 if ((vo = isAPropertyOf(vtodo, VCDAlarmProp))) {
837 Alarm* alarm = anEvent->newAlarm(); 841 Alarm* alarm = anEvent->newAlarm();
838 VObject *a; 842 VObject *a;
839 if ((a = isAPropertyOf(vo, VCRunTimeProp))) { 843 if ((a = isAPropertyOf(vo, VCRunTimeProp))) {
840 alarm->setTime(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(a)))); 844 alarm->setTime(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(a))));
841 deleteStr(s); 845 deleteStr(s);
842 } 846 }
843 alarm->setEnabled(true); 847 alarm->setEnabled(true);
844 if ((vo = isAPropertyOf(vtodo, VCPAlarmProp))) { 848 if ((vo = isAPropertyOf(vtodo, VCPAlarmProp))) {
845 if ((a = isAPropertyOf(vo, VCProcedureNameProp))) { 849 if ((a = isAPropertyOf(vo, VCProcedureNameProp))) {
846 s = fakeCString(vObjectUStringZValue(a)); 850 s = fakeCString(vObjectUStringZValue(a));
847 alarm->setProcedureAlarm(QFile::decodeName(s)); 851 alarm->setProcedureAlarm(QFile::decodeName(s));
848 deleteStr(s); 852 deleteStr(s);
849 } 853 }
850 } 854 }
851 if ((vo = isAPropertyOf(vtodo, VCAAlarmProp))) { 855 if ((vo = isAPropertyOf(vtodo, VCAAlarmProp))) {
852 if ((a = isAPropertyOf(vo, VCAudioContentProp))) { 856 if ((a = isAPropertyOf(vo, VCAudioContentProp))) {
853 s = fakeCString(vObjectUStringZValue(a)); 857 s = fakeCString(vObjectUStringZValue(a));
854 alarm->setAudioAlarm(QFile::decodeName(s)); 858 alarm->setAudioAlarm(QFile::decodeName(s));
855 deleteStr(s); 859 deleteStr(s);
856 } 860 }
857 } 861 }
858 } 862 }
859 863
860 // related todo 864 // related todo
861 if ((vo = isAPropertyOf(vtodo, VCRelatedToProp)) != 0) { 865 if ((vo = isAPropertyOf(vtodo, VCRelatedToProp)) != 0) {
862 anEvent->setRelatedToUid(s = fakeCString(vObjectUStringZValue(vo))); 866 anEvent->setRelatedToUid(s = fakeCString(vObjectUStringZValue(vo)));
863 deleteStr(s); 867 deleteStr(s);
864 mTodosRelate.append(anEvent); 868 mTodosRelate.append(anEvent);
865 } 869 }
866 870
867 // categories 871 // categories
868 QStringList tmpStrList; 872 QStringList tmpStrList;
869 int index1 = 0; 873 int index1 = 0;
870 int index2 = 0; 874 int index2 = 0;
871 if ((vo = isAPropertyOf(vtodo, VCCategoriesProp)) != 0) { 875 if ((vo = isAPropertyOf(vtodo, VCCategoriesProp)) != 0) {
872 s = fakeCString(vObjectUStringZValue(vo)); 876 s = fakeCString(vObjectUStringZValue(vo));
873 QString categories = QString::fromLocal8Bit(s); 877 QString categories = QString::fromLocal8Bit(s);
874 deleteStr(s); 878 deleteStr(s);
875 //const char* category; 879 //const char* category;
876 QString category; 880 QString category;
877 while ((index2 = categories.find(',', index1)) != -1) { 881 while ((index2 = categories.find(',', index1)) != -1) {
878 //category = (const char *) categories.mid(index1, (index2 - index1)); 882 //category = (const char *) categories.mid(index1, (index2 - index1));
879 category = categories.mid(index1, (index2 - index1)); 883 category = categories.mid(index1, (index2 - index1));
880 tmpStrList.append(category); 884 tmpStrList.append(category);
881 index1 = index2+1; 885 index1 = index2+1;
882 } 886 }
883 // get last category 887 // get last category
884 category = categories.mid(index1, (categories.length()-index1)); 888 category = categories.mid(index1, (categories.length()-index1));
885 tmpStrList.append(category); 889 tmpStrList.append(category);
886 anEvent->setCategories(tmpStrList); 890 anEvent->setCategories(tmpStrList);
887 } 891 }
888 892
889 /* PILOT SYNC STUFF */ 893 /* PILOT SYNC STUFF */
890 if ((vo = isAPropertyOf(vtodo, XPilotIdProp))) { 894 if ((vo = isAPropertyOf(vtodo, XPilotIdProp))) {
891 anEvent->setPilotId(atoi(s = fakeCString(vObjectUStringZValue(vo)))); 895 anEvent->setPilotId(atoi(s = fakeCString(vObjectUStringZValue(vo))));
892 deleteStr(s); 896 deleteStr(s);
893 } 897 }
894 else 898 else
895 anEvent->setPilotId(0); 899 anEvent->setPilotId(0);
896 900
897 if ((vo = isAPropertyOf(vtodo, XPilotStatusProp))) { 901 if ((vo = isAPropertyOf(vtodo, XPilotStatusProp))) {
898 anEvent->setSyncStatus(atoi(s = fakeCString(vObjectUStringZValue(vo)))); 902 anEvent->setSyncStatus(atoi(s = fakeCString(vObjectUStringZValue(vo))));
899 deleteStr(s); 903 deleteStr(s);
900 } 904 }
901 else 905 else
902 anEvent->setSyncStatus(Event::SYNCMOD); 906 anEvent->setSyncStatus(Event::SYNCMOD);
903 907
904 return anEvent; 908 return anEvent;
905} 909}
906 910
907Event* VCalFormat::VEventToEvent(VObject *vevent) 911Event* VCalFormat::VEventToEvent(VObject *vevent)
908{ 912{
909 VObject *vo; 913 VObject *vo;
910 VObjectIterator voi; 914 VObjectIterator voi;
911 char *s; 915 char *s;
912 916
913 Event *anEvent = new Event; 917 Event *anEvent = new Event;
914 918
915 // creation date 919 // creation date
916 if ((vo = isAPropertyOf(vevent, VCDCreatedProp)) != 0) { 920 if ((vo = isAPropertyOf(vevent, VCDCreatedProp)) != 0) {
917 anEvent->setCreated(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo)))); 921 anEvent->setCreated(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo))));
918 deleteStr(s); 922 deleteStr(s);
919 } 923 }
920 924
921 // unique id 925 // unique id
922 vo = isAPropertyOf(vevent, VCUniqueStringProp); 926 vo = isAPropertyOf(vevent, VCUniqueStringProp);
923 // while the UID property is preferred, it is not required. We'll use the 927 // while the UID property is preferred, it is not required. We'll use the
924 // default Event UID if none is given. 928 // default Event UID if none is given.
925 if (vo) { 929 if (vo) {
926 anEvent->setUid(s = fakeCString(vObjectUStringZValue(vo))); 930 anEvent->setUid(s = fakeCString(vObjectUStringZValue(vo)));
927 deleteStr(s); 931 deleteStr(s);
928 } 932 }
929 933
930 // revision 934 // revision
931 // again NSCAL doesn't give us much to work with, so we improvise... 935 // again NSCAL doesn't give us much to work with, so we improvise...
932 if ((vo = isAPropertyOf(vevent, VCSequenceProp)) != 0) { 936 if ((vo = isAPropertyOf(vevent, VCSequenceProp)) != 0) {
933 anEvent->setRevision(atoi(s = fakeCString(vObjectUStringZValue(vo)))); 937 anEvent->setRevision(atoi(s = fakeCString(vObjectUStringZValue(vo))));
934 deleteStr(s); 938 deleteStr(s);
935 } 939 }
936 else 940 else
937 anEvent->setRevision(0); 941 anEvent->setRevision(0);
938 942
939 // last modification date 943 // last modification date
940 if ((vo = isAPropertyOf(vevent, VCLastModifiedProp)) != 0) { 944 if ((vo = isAPropertyOf(vevent, VCLastModifiedProp)) != 0) {
941 anEvent->setLastModified(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo)))); 945 anEvent->setLastModified(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo))));
942 deleteStr(s); 946 deleteStr(s);
943 } 947 }
944 else 948 else
945 anEvent->setLastModified(QDateTime(QDate::currentDate(), 949 anEvent->setLastModified(QDateTime(QDate::currentDate(),
946 QTime::currentTime())); 950 QTime::currentTime()));
947 951
948 // organizer 952 // organizer
949 // if our extension property for the event's ORGANIZER exists, add it. 953 // if our extension property for the event's ORGANIZER exists, add it.
950 if ((vo = isAPropertyOf(vevent, ICOrganizerProp)) != 0) { 954 if ((vo = isAPropertyOf(vevent, ICOrganizerProp)) != 0) {
951 anEvent->setOrganizer(s = fakeCString(vObjectUStringZValue(vo))); 955 anEvent->setOrganizer(s = fakeCString(vObjectUStringZValue(vo)));
952 deleteStr(s); 956 deleteStr(s);
953 } else { 957 } else {
954 anEvent->setOrganizer(mCalendar->getEmail()); 958 anEvent->setOrganizer(mCalendar->getEmail());
955 } 959 }
956 960
957 // deal with attendees. 961 // deal with attendees.
958 initPropIterator(&voi, vevent); 962 initPropIterator(&voi, vevent);
959 while (moreIteration(&voi)) { 963 while (moreIteration(&voi)) {
960 vo = nextVObject(&voi); 964 vo = nextVObject(&voi);
961 if (strcmp(vObjectName(vo), VCAttendeeProp) == 0) { 965 if (strcmp(vObjectName(vo), VCAttendeeProp) == 0) {
962 Attendee *a; 966 Attendee *a;
963 VObject *vp; 967 VObject *vp;
964 s = fakeCString(vObjectUStringZValue(vo)); 968 s = fakeCString(vObjectUStringZValue(vo));
965 QString tmpStr = QString::fromLocal8Bit(s); 969 QString tmpStr = QString::fromLocal8Bit(s);
966 deleteStr(s); 970 deleteStr(s);
967 tmpStr = tmpStr.simplifyWhiteSpace(); 971 tmpStr = tmpStr.simplifyWhiteSpace();
968 int emailPos1, emailPos2; 972 int emailPos1, emailPos2;
969 if ((emailPos1 = tmpStr.find('<')) > 0) { 973 if ((emailPos1 = tmpStr.find('<')) > 0) {
970 // both email address and name 974 // both email address and name
971 emailPos2 = tmpStr.findRev('>'); 975 emailPos2 = tmpStr.findRev('>');
972 a = new Attendee(tmpStr.left(emailPos1 - 1), 976 a = new Attendee(tmpStr.left(emailPos1 - 1),
973 tmpStr.mid(emailPos1 + 1, 977 tmpStr.mid(emailPos1 + 1,
974 emailPos2 - (emailPos1 + 1))); 978 emailPos2 - (emailPos1 + 1)));
975 } else if (tmpStr.find('@') > 0) { 979 } else if (tmpStr.find('@') > 0) {
976 // just an email address 980 // just an email address
977 a = new Attendee(0, tmpStr); 981 a = new Attendee(0, tmpStr);
978 } else { 982 } else {
979 // just a name 983 // just a name
980 QString email = tmpStr.replace( QRegExp(" "), "." ); 984 //QString email = tmpStr.replace( QRegExp(" "), "." );
981 a = new Attendee(tmpStr,email); 985 a = new Attendee(tmpStr,0);
982 } 986 }
983 987
988
989 // is there a Role property?
990 if ((vp = isAPropertyOf(vo, VCRoleProp)) != 0)
991 a->setRole(readRole(vObjectStringZValue(vp)));
992
984 // is there an RSVP property? 993 // is there an RSVP property?
985 if ((vp = isAPropertyOf(vo, VCRSVPProp)) != 0) 994 if ((vp = isAPropertyOf(vo, VCRSVPProp)) != 0)
986 a->setRSVP(vObjectStringZValue(vp)); 995 a->setRSVP(vObjectStringZValue(vp));
987 // is there a status property? 996 // is there a status property?
988 if ((vp = isAPropertyOf(vo, VCStatusProp)) != 0) 997 if ((vp = isAPropertyOf(vo, VCStatusProp)) != 0)
989 a->setStatus(readStatus(vObjectStringZValue(vp))); 998 a->setStatus(readStatus(vObjectStringZValue(vp)));
990 // add the attendee 999 // add the attendee
991 anEvent->addAttendee(a); 1000 anEvent->addAttendee(a);
992 } 1001 }
993 } 1002 }
994 1003
995 // This isn't strictly true. An event that doesn't have a start time 1004 // This isn't strictly true. An event that doesn't have a start time
996 // or an end time doesn't "float", it has an anchor in time but it doesn't 1005 // or an end time doesn't "float", it has an anchor in time but it doesn't
997 // "take up" any time. 1006 // "take up" any time.
998 /*if ((isAPropertyOf(vevent, VCDTstartProp) == 0) || 1007 /*if ((isAPropertyOf(vevent, VCDTstartProp) == 0) ||
999 (isAPropertyOf(vevent, VCDTendProp) == 0)) { 1008 (isAPropertyOf(vevent, VCDTendProp) == 0)) {
1000 anEvent->setFloats(TRUE); 1009 anEvent->setFloats(TRUE);
1001 } else { 1010 } else {
1002 }*/ 1011 }*/
1003 1012
1004 anEvent->setFloats(FALSE); 1013 anEvent->setFloats(FALSE);
1005 1014
1006 // start time 1015 // start time
1007 if ((vo = isAPropertyOf(vevent, VCDTstartProp)) != 0) { 1016 if ((vo = isAPropertyOf(vevent, VCDTstartProp)) != 0) {
1008 anEvent->setDtStart(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo)))); 1017 anEvent->setDtStart(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo))));
1009 // kdDebug(5800) << "s is " << // s << ", ISO is " << ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo))).toString() << endl; 1018 // kdDebug(5800) << "s is " << // s << ", ISO is " << ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo))).toString() << endl;
1010 deleteStr(s); 1019 deleteStr(s);
1011 if (anEvent->dtStart().time().isNull()) 1020 if (anEvent->dtStart().time().isNull())
1012 anEvent->setFloats(TRUE); 1021 anEvent->setFloats(TRUE);
1013 } 1022 }
1014 1023
1015 // stop time 1024 // stop time
1016 if ((vo = isAPropertyOf(vevent, VCDTendProp)) != 0) { 1025 if ((vo = isAPropertyOf(vevent, VCDTendProp)) != 0) {
1017 anEvent->setDtEnd(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo)))); 1026 anEvent->setDtEnd(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo))));
1018 deleteStr(s); 1027 deleteStr(s);
1019 if (anEvent->dtEnd().time().isNull()) 1028 if (anEvent->dtEnd().time().isNull())
1020 anEvent->setFloats(TRUE); 1029 anEvent->setFloats(TRUE);
1021 } 1030 }
1022 1031
1023 // at this point, there should be at least a start or end time. 1032 // at this point, there should be at least a start or end time.
1024 // fix up for events that take up no time but have a time associated 1033 // fix up for events that take up no time but have a time associated
1025 if (!(vo = isAPropertyOf(vevent, VCDTstartProp))) 1034 if (!(vo = isAPropertyOf(vevent, VCDTstartProp)))
1026 anEvent->setDtStart(anEvent->dtEnd()); 1035 anEvent->setDtStart(anEvent->dtEnd());
1027 if (!(vo = isAPropertyOf(vevent, VCDTendProp))) 1036 if (!(vo = isAPropertyOf(vevent, VCDTendProp)))
1028 anEvent->setDtEnd(anEvent->dtStart()); 1037 anEvent->setDtEnd(anEvent->dtStart());
1029 1038
1030 /////////////////////////////////////////////////////////////////////////// 1039 ///////////////////////////////////////////////////////////////////////////
1031 1040
1032 // repeat stuff 1041 // repeat stuff
1033 if ((vo = isAPropertyOf(vevent, VCRRuleProp)) != 0) { 1042 if ((vo = isAPropertyOf(vevent, VCRRuleProp)) != 0) {
1034 QString tmpStr = (s = fakeCString(vObjectUStringZValue(vo))); 1043 QString tmpStr = (s = fakeCString(vObjectUStringZValue(vo)));
1035 deleteStr(s); 1044 deleteStr(s);
1036 tmpStr.simplifyWhiteSpace(); 1045 tmpStr.simplifyWhiteSpace();
1037 tmpStr = tmpStr.upper(); 1046 tmpStr = tmpStr.upper();
1038 1047
1039 /********************************* DAILY ******************************/ 1048 /********************************* DAILY ******************************/
1040 if (tmpStr.left(1) == "D") { 1049 if (tmpStr.left(1) == "D") {
1041 int index = tmpStr.find(' '); 1050 int index = tmpStr.find(' ');
1042 int rFreq = tmpStr.mid(1, (index-1)).toInt(); 1051 int rFreq = tmpStr.mid(1, (index-1)).toInt();
1043 index = tmpStr.findRev(' ') + 1; // advance to last field 1052 index = tmpStr.findRev(' ') + 1; // advance to last field
1044 if (tmpStr.mid(index,1) == "#") index++; 1053 if (tmpStr.mid(index,1) == "#") index++;
1045 if (tmpStr.find('T', index) != -1) { 1054 if (tmpStr.find('T', index) != -1) {
1046 QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date(); 1055 QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date();
1047 anEvent->recurrence()->setDaily(rFreq, rEndDate); 1056 anEvent->recurrence()->setDaily(rFreq, rEndDate);
1048 } else { 1057 } else {
1049 int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt(); 1058 int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt();
1050 if (rDuration == 0) // VEvents set this to 0 forever, we use -1 1059 if (rDuration == 0) // VEvents set this to 0 forever, we use -1
1051 anEvent->recurrence()->setDaily(rFreq, -1); 1060 anEvent->recurrence()->setDaily(rFreq, -1);
1052 else 1061 else
1053 anEvent->recurrence()->setDaily(rFreq, rDuration); 1062 anEvent->recurrence()->setDaily(rFreq, rDuration);
1054 } 1063 }
1055 } 1064 }
1056 /********************************* WEEKLY ******************************/ 1065 /********************************* WEEKLY ******************************/
1057 else if (tmpStr.left(1) == "W") { 1066 else if (tmpStr.left(1) == "W") {
1058 int index = tmpStr.find(' '); 1067 int index = tmpStr.find(' ');
1059 int last = tmpStr.findRev(' ') + 1; 1068 int last = tmpStr.findRev(' ') + 1;
1060 int rFreq = tmpStr.mid(1, (index-1)).toInt(); 1069 int rFreq = tmpStr.mid(1, (index-1)).toInt();
1061 index += 1; // advance to beginning of stuff after freq 1070 index += 1; // advance to beginning of stuff after freq
1062 QBitArray qba(7); 1071 QBitArray qba(7);
1063 QString dayStr; 1072 QString dayStr;
1064 if( index == last ) { 1073 if( index == last ) {
1065 // e.g. W1 #0 1074 // e.g. W1 #0
1066 qba.setBit(anEvent->dtStart().date().dayOfWeek() - 1); 1075 qba.setBit(anEvent->dtStart().date().dayOfWeek() - 1);
1067 } 1076 }
1068 else { 1077 else {
1069 // e.g. W1 SU #0 1078 // e.g. W1 SU #0
1070 while (index < last) { 1079 while (index < last) {
1071 dayStr = tmpStr.mid(index, 3); 1080 dayStr = tmpStr.mid(index, 3);
1072 int dayNum = numFromDay(dayStr); 1081 int dayNum = numFromDay(dayStr);
1073 qba.setBit(dayNum); 1082 qba.setBit(dayNum);
1074 index += 3; // advance to next day, or possibly "#" 1083 index += 3; // advance to next day, or possibly "#"
1075 } 1084 }
1076 } 1085 }
1077 index = last; if (tmpStr.mid(index,1) == "#") index++; 1086 index = last; if (tmpStr.mid(index,1) == "#") index++;
1078 if (tmpStr.find('T', index) != -1) { 1087 if (tmpStr.find('T', index) != -1) {
1079 QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date(); 1088 QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date();
1080 anEvent->recurrence()->setWeekly(rFreq, qba, rEndDate); 1089 anEvent->recurrence()->setWeekly(rFreq, qba, rEndDate);
1081 } else { 1090 } else {
1082 int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt(); 1091 int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt();
1083 if (rDuration == 0) 1092 if (rDuration == 0)
1084 anEvent->recurrence()->setWeekly(rFreq, qba, -1); 1093 anEvent->recurrence()->setWeekly(rFreq, qba, -1);
1085 else 1094 else
1086 anEvent->recurrence()->setWeekly(rFreq, qba, rDuration); 1095 anEvent->recurrence()->setWeekly(rFreq, qba, rDuration);
1087 } 1096 }
1088 } 1097 }
1089 /**************************** MONTHLY-BY-POS ***************************/ 1098 /**************************** MONTHLY-BY-POS ***************************/
1090 else if (tmpStr.left(2) == "MP") { 1099 else if (tmpStr.left(2) == "MP") {
1091 int index = tmpStr.find(' '); 1100 int index = tmpStr.find(' ');
1092 int last = tmpStr.findRev(' ') + 1; 1101 int last = tmpStr.findRev(' ') + 1;
1093 int rFreq = tmpStr.mid(2, (index-1)).toInt(); 1102 int rFreq = tmpStr.mid(2, (index-1)).toInt();
1094 index += 1; // advance to beginning of stuff after freq 1103 index += 1; // advance to beginning of stuff after freq
1095 QBitArray qba(7); 1104 QBitArray qba(7);
1096 short tmpPos; 1105 short tmpPos;
1097 if( index == last ) { 1106 if( index == last ) {
1098 // e.g. MP1 #0 1107 // e.g. MP1 #0
1099 tmpPos = anEvent->dtStart().date().day()/7 + 1; 1108 tmpPos = anEvent->dtStart().date().day()/7 + 1;
1100 if( tmpPos == 5 ) 1109 if( tmpPos == 5 )
1101 tmpPos = -1; 1110 tmpPos = -1;
1102 qba.setBit(anEvent->dtStart().date().dayOfWeek() - 1); 1111 qba.setBit(anEvent->dtStart().date().dayOfWeek() - 1);
1103 anEvent->recurrence()->addMonthlyPos(tmpPos, qba); 1112 anEvent->recurrence()->addMonthlyPos(tmpPos, qba);
1104 } 1113 }
1105 else { 1114 else {
1106 // e.g. MP1 1+ SU #0 1115 // e.g. MP1 1+ SU #0
1107 while (index < last) { 1116 while (index < last) {
1108 tmpPos = tmpStr.mid(index,1).toShort(); 1117 tmpPos = tmpStr.mid(index,1).toShort();
1109 index += 1; 1118 index += 1;
1110 if (tmpStr.mid(index,1) == "-") 1119 if (tmpStr.mid(index,1) == "-")
1111 // convert tmpPos to negative 1120 // convert tmpPos to negative
1112 tmpPos = 0 - tmpPos; 1121 tmpPos = 0 - tmpPos;
1113 index += 2; // advance to day(s) 1122 index += 2; // advance to day(s)
1114 while (numFromDay(tmpStr.mid(index,3)) >= 0) { 1123 while (numFromDay(tmpStr.mid(index,3)) >= 0) {
1115 int dayNum = numFromDay(tmpStr.mid(index,3)); 1124 int dayNum = numFromDay(tmpStr.mid(index,3));
1116 qba.setBit(dayNum); 1125 qba.setBit(dayNum);
1117 index += 3; // advance to next day, or possibly pos or "#" 1126 index += 3; // advance to next day, or possibly pos or "#"
1118 } 1127 }
1119 anEvent->recurrence()->addMonthlyPos(tmpPos, qba); 1128 anEvent->recurrence()->addMonthlyPos(tmpPos, qba);
1120 qba.detach(); 1129 qba.detach();
1121 qba.fill(FALSE); // clear out 1130 qba.fill(FALSE); // clear out
1122 } // while != "#" 1131 } // while != "#"
1123 } 1132 }
1124 index = last; if (tmpStr.mid(index,1) == "#") index++; 1133 index = last; if (tmpStr.mid(index,1) == "#") index++;
1125 if (tmpStr.find('T', index) != -1) { 1134 if (tmpStr.find('T', index) != -1) {
1126 QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length() - 1135 QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length() -
1127 index))).date(); 1136 index))).date();
1128 anEvent->recurrence()->setMonthly(Recurrence::rMonthlyPos, rFreq, rEndDate); 1137 anEvent->recurrence()->setMonthly(Recurrence::rMonthlyPos, rFreq, rEndDate);
1129 } else { 1138 } else {
1130 int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt(); 1139 int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt();
1131 if (rDuration == 0) 1140 if (rDuration == 0)
1132 anEvent->recurrence()->setMonthly(Recurrence::rMonthlyPos, rFreq, -1); 1141 anEvent->recurrence()->setMonthly(Recurrence::rMonthlyPos, rFreq, -1);
1133 else 1142 else
1134 anEvent->recurrence()->setMonthly(Recurrence::rMonthlyPos, rFreq, rDuration); 1143 anEvent->recurrence()->setMonthly(Recurrence::rMonthlyPos, rFreq, rDuration);
1135 } 1144 }
1136 } 1145 }
1137 1146
1138 /**************************** MONTHLY-BY-DAY ***************************/ 1147 /**************************** MONTHLY-BY-DAY ***************************/
1139 else if (tmpStr.left(2) == "MD") { 1148 else if (tmpStr.left(2) == "MD") {
1140 int index = tmpStr.find(' '); 1149 int index = tmpStr.find(' ');
1141 int last = tmpStr.findRev(' ') + 1; 1150 int last = tmpStr.findRev(' ') + 1;
1142 int rFreq = tmpStr.mid(2, (index-1)).toInt(); 1151 int rFreq = tmpStr.mid(2, (index-1)).toInt();
1143 index += 1; 1152 index += 1;
1144 short tmpDay; 1153 short tmpDay;
1145 if( index == last ) { 1154 if( index == last ) {
1146 // e.g. MD1 #0 1155 // e.g. MD1 #0
1147 tmpDay = anEvent->dtStart().date().day(); 1156 tmpDay = anEvent->dtStart().date().day();
1148 anEvent->recurrence()->addMonthlyDay(tmpDay); 1157 anEvent->recurrence()->addMonthlyDay(tmpDay);
1149 } 1158 }
1150 else { 1159 else {
1151 // e.g. MD1 3 #0 1160 // e.g. MD1 3 #0
1152 while (index < last) { 1161 while (index < last) {
1153 int index2 = tmpStr.find(' ', index); 1162 int index2 = tmpStr.find(' ', index);
1154 tmpDay = tmpStr.mid(index, (index2-index)).toShort(); 1163 tmpDay = tmpStr.mid(index, (index2-index)).toShort();
1155 index = index2-1; 1164 index = index2-1;
1156 if (tmpStr.mid(index, 1) == "-") 1165 if (tmpStr.mid(index, 1) == "-")
1157 tmpDay = 0 - tmpDay; 1166 tmpDay = 0 - tmpDay;
1158 index += 2; // advance the index; 1167 index += 2; // advance the index;
1159 anEvent->recurrence()->addMonthlyDay(tmpDay); 1168 anEvent->recurrence()->addMonthlyDay(tmpDay);
1160 } // while != # 1169 } // while != #
1161 } 1170 }
1162 index = last; if (tmpStr.mid(index,1) == "#") index++; 1171 index = last; if (tmpStr.mid(index,1) == "#") index++;
1163 if (tmpStr.find('T', index) != -1) { 1172 if (tmpStr.find('T', index) != -1) {
1164 QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date(); 1173 QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date();
1165 anEvent->recurrence()->setMonthly(Recurrence::rMonthlyDay, rFreq, rEndDate); 1174 anEvent->recurrence()->setMonthly(Recurrence::rMonthlyDay, rFreq, rEndDate);
1166 } else { 1175 } else {
1167 int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt(); 1176 int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt();
1168 if (rDuration == 0) 1177 if (rDuration == 0)
1169 anEvent->recurrence()->setMonthly(Recurrence::rMonthlyDay, rFreq, -1); 1178 anEvent->recurrence()->setMonthly(Recurrence::rMonthlyDay, rFreq, -1);
1170 else 1179 else
1171 anEvent->recurrence()->setMonthly(Recurrence::rMonthlyDay, rFreq, rDuration); 1180 anEvent->recurrence()->setMonthly(Recurrence::rMonthlyDay, rFreq, rDuration);
1172 } 1181 }
1173 } 1182 }
1174 1183
1175 /*********************** YEARLY-BY-MONTH *******************************/ 1184 /*********************** YEARLY-BY-MONTH *******************************/
1176 else if (tmpStr.left(2) == "YM") { 1185 else if (tmpStr.left(2) == "YM") {
1177 // we have to set this such that recurrence accepts addYearlyNum(tmpDay); 1186 // we have to set this such that recurrence accepts addYearlyNum(tmpDay);
1178 anEvent->recurrence()->setYearly(Recurrence::rYearlyMonth, 1, -1); 1187 anEvent->recurrence()->setYearly(Recurrence::rYearlyMonth, 1, -1);
1179 int index = tmpStr.find(' '); 1188 int index = tmpStr.find(' ');
1180 int last = tmpStr.findRev(' ') + 1; 1189 int last = tmpStr.findRev(' ') + 1;
1181 int rFreq = tmpStr.mid(2, (index-1)).toInt(); 1190 int rFreq = tmpStr.mid(2, (index-1)).toInt();
1182 index += 1; 1191 index += 1;
1183 short tmpMonth; 1192 short tmpMonth;
1184 if( index == last ) { 1193 if( index == last ) {
1185 // e.g. YM1 #0 1194 // e.g. YM1 #0
1186 tmpMonth = anEvent->dtStart().date().month(); 1195 tmpMonth = anEvent->dtStart().date().month();
1187 anEvent->recurrence()->addYearlyNum(tmpMonth); 1196 anEvent->recurrence()->addYearlyNum(tmpMonth);
1188 } 1197 }
1189 else { 1198 else {
1190 // e.g. YM1 3 #0 1199 // e.g. YM1 3 #0
1191 while (index < last) { 1200 while (index < last) {
1192 int index2 = tmpStr.find(' ', index); 1201 int index2 = tmpStr.find(' ', index);
1193 tmpMonth = tmpStr.mid(index, (index2-index)).toShort(); 1202 tmpMonth = tmpStr.mid(index, (index2-index)).toShort();
1194 index = index2+1; 1203 index = index2+1;
1195 anEvent->recurrence()->addYearlyNum(tmpMonth); 1204 anEvent->recurrence()->addYearlyNum(tmpMonth);
1196 } // while != # 1205 } // while != #
1197 } 1206 }
1198 index = last; if (tmpStr.mid(index,1) == "#") index++; 1207 index = last; if (tmpStr.mid(index,1) == "#") index++;
1199 if (tmpStr.find('T', index) != -1) { 1208 if (tmpStr.find('T', index) != -1) {
1200 QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date(); 1209 QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date();
1201 anEvent->recurrence()->setYearly(Recurrence::rYearlyMonth, rFreq, rEndDate); 1210 anEvent->recurrence()->setYearly(Recurrence::rYearlyMonth, rFreq, rEndDate);
1202 } else { 1211 } else {
1203 int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt(); 1212 int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt();
1204 if (rDuration == 0) 1213 if (rDuration == 0)
1205 anEvent->recurrence()->setYearly(Recurrence::rYearlyMonth, rFreq, -1); 1214 anEvent->recurrence()->setYearly(Recurrence::rYearlyMonth, rFreq, -1);
1206 else 1215 else
1207 anEvent->recurrence()->setYearly(Recurrence::rYearlyMonth, rFreq, rDuration); 1216 anEvent->recurrence()->setYearly(Recurrence::rYearlyMonth, rFreq, rDuration);
1208 } 1217 }
1209 } 1218 }
1210 1219
1211 /*********************** YEARLY-BY-DAY *********************************/ 1220 /*********************** YEARLY-BY-DAY *********************************/
1212 else if (tmpStr.left(2) == "YD") { 1221 else if (tmpStr.left(2) == "YD") {
1213 // we have to set this such that recurrence accepts addYearlyNum(tmpDay); 1222 // we have to set this such that recurrence accepts addYearlyNum(tmpDay);
1214 anEvent->recurrence()->setYearly(Recurrence::rYearlyDay, 1, -1); 1223 anEvent->recurrence()->setYearly(Recurrence::rYearlyDay, 1, -1);
1215 int index = tmpStr.find(' '); 1224 int index = tmpStr.find(' ');
1216 int last = tmpStr.findRev(' ') + 1; 1225 int last = tmpStr.findRev(' ') + 1;
1217 int rFreq = tmpStr.mid(2, (index-1)).toInt(); 1226 int rFreq = tmpStr.mid(2, (index-1)).toInt();
1218 index += 1; 1227 index += 1;
1219 short tmpDay; 1228 short tmpDay;
1220 if( index == last ) { 1229 if( index == last ) {
1221 // e.g. YD1 #0 1230 // e.g. YD1 #0
1222 tmpDay = anEvent->dtStart().date().dayOfYear(); 1231 tmpDay = anEvent->dtStart().date().dayOfYear();
1223 anEvent->recurrence()->addYearlyNum(tmpDay); 1232 anEvent->recurrence()->addYearlyNum(tmpDay);
1224 } 1233 }
1225 else { 1234 else {
1226 // e.g. YD1 123 #0 1235 // e.g. YD1 123 #0
1227 while (index < last) { 1236 while (index < last) {
1228 int index2 = tmpStr.find(' ', index); 1237 int index2 = tmpStr.find(' ', index);
1229 tmpDay = tmpStr.mid(index, (index2-index)).toShort(); 1238 tmpDay = tmpStr.mid(index, (index2-index)).toShort();
1230 index = index2+1; 1239 index = index2+1;
1231 anEvent->recurrence()->addYearlyNum(tmpDay); 1240 anEvent->recurrence()->addYearlyNum(tmpDay);
1232 } // while != # 1241 } // while != #
1233 } 1242 }
1234 index = last; if (tmpStr.mid(index,1) == "#") index++; 1243 index = last; if (tmpStr.mid(index,1) == "#") index++;
1235 if (tmpStr.find('T', index) != -1) { 1244 if (tmpStr.find('T', index) != -1) {
1236 QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date(); 1245 QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date();
1237 anEvent->recurrence()->setYearly(Recurrence::rYearlyDay, rFreq, rEndDate); 1246 anEvent->recurrence()->setYearly(Recurrence::rYearlyDay, rFreq, rEndDate);
1238 } else { 1247 } else {
1239 int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt(); 1248 int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt();
1240 if (rDuration == 0) 1249 if (rDuration == 0)
1241 anEvent->recurrence()->setYearly(Recurrence::rYearlyDay, rFreq, -1); 1250 anEvent->recurrence()->setYearly(Recurrence::rYearlyDay, rFreq, -1);
1242 else 1251 else
1243 anEvent->recurrence()->setYearly(Recurrence::rYearlyDay, rFreq, rDuration); 1252 anEvent->recurrence()->setYearly(Recurrence::rYearlyDay, rFreq, rDuration);
1244 } 1253 }
1245 } else { 1254 } else {
1246 kdDebug(5800) << "we don't understand this type of recurrence!" << endl; 1255 kdDebug(5800) << "we don't understand this type of recurrence!" << endl;
1247 } // if 1256 } // if
1248 } // repeats 1257 } // repeats
1249 1258
1250 1259
1251 // recurrence exceptions 1260 // recurrence exceptions
1252 if ((vo = isAPropertyOf(vevent, VCExpDateProp)) != 0) { 1261 if ((vo = isAPropertyOf(vevent, VCExpDateProp)) != 0) {
1253 s = fakeCString(vObjectUStringZValue(vo)); 1262 s = fakeCString(vObjectUStringZValue(vo));
1254 QStringList exDates = QStringList::split(",",s); 1263 QStringList exDates = QStringList::split(",",s);
1255 QStringList::ConstIterator it; 1264 QStringList::ConstIterator it;
1256 for(it = exDates.begin(); it != exDates.end(); ++it ) { 1265 for(it = exDates.begin(); it != exDates.end(); ++it ) {
1257 anEvent->addExDate(ISOToQDate(*it)); 1266 anEvent->addExDate(ISOToQDate(*it));
1258 } 1267 }
1259 deleteStr(s); 1268 deleteStr(s);
1260 } 1269 }
1261 1270
1262 // summary 1271 // summary
1263 if ((vo = isAPropertyOf(vevent, VCSummaryProp))) { 1272 if ((vo = isAPropertyOf(vevent, VCSummaryProp))) {
1264 s = fakeCString(vObjectUStringZValue(vo)); 1273 s = fakeCString(vObjectUStringZValue(vo));
1265 anEvent->setSummary(QString::fromLocal8Bit(s)); 1274 anEvent->setSummary(QString::fromLocal8Bit(s));
1266 deleteStr(s); 1275 deleteStr(s);
1267 } 1276 }
1268 if ((vo = isAPropertyOf(vevent, VCLocationProp))) { 1277 if ((vo = isAPropertyOf(vevent, VCLocationProp))) {
1269 s = fakeCString(vObjectUStringZValue(vo)); 1278 s = fakeCString(vObjectUStringZValue(vo));
1270 anEvent->setLocation(QString::fromLocal8Bit(s)); 1279 anEvent->setLocation(QString::fromLocal8Bit(s));
1271 deleteStr(s); 1280 deleteStr(s);
1272 } 1281 }
1273 1282
1274 // description 1283 // description
1275 if ((vo = isAPropertyOf(vevent, VCDescriptionProp)) != 0) { 1284 if ((vo = isAPropertyOf(vevent, VCDescriptionProp)) != 0) {
1276 s = fakeCString(vObjectUStringZValue(vo)); 1285 s = fakeCString(vObjectUStringZValue(vo));
1277 if (!anEvent->description().isEmpty()) { 1286 if (!anEvent->description().isEmpty()) {
1278 anEvent->setDescription(anEvent->description() + "\n" + 1287 anEvent->setDescription(anEvent->description() + "\n" +
1279 QString::fromLocal8Bit(s)); 1288 QString::fromLocal8Bit(s));
1280 } else { 1289 } else {
1281 anEvent->setDescription(QString::fromLocal8Bit(s)); 1290 anEvent->setDescription(QString::fromLocal8Bit(s));
1282 } 1291 }
1283 deleteStr(s); 1292 deleteStr(s);
1284 } 1293 }
1285 1294
1286 // some stupid vCal exporters ignore the standard and use Description 1295 // some stupid vCal exporters ignore the standard and use Description
1287 // instead of Summary for the default field. Correct for this. 1296 // instead of Summary for the default field. Correct for this.
1288 if (anEvent->summary().isEmpty() && 1297 if (anEvent->summary().isEmpty() &&
1289 !(anEvent->description().isEmpty())) { 1298 !(anEvent->description().isEmpty())) {
1290 QString tmpStr = anEvent->description().simplifyWhiteSpace(); 1299 QString tmpStr = anEvent->description().simplifyWhiteSpace();
1291 anEvent->setDescription(""); 1300 anEvent->setDescription("");
1292 anEvent->setSummary(tmpStr); 1301 anEvent->setSummary(tmpStr);
1293 } 1302 }
1294 1303
1295#if 0 1304#if 0
1296 // status 1305 // status
1297 if ((vo = isAPropertyOf(vevent, VCStatusProp)) != 0) { 1306 if ((vo = isAPropertyOf(vevent, VCStatusProp)) != 0) {
1298 QString tmpStr(s = fakeCString(vObjectUStringZValue(vo))); 1307 QString tmpStr(s = fakeCString(vObjectUStringZValue(vo)));
1299 deleteStr(s); 1308 deleteStr(s);
1300// TODO: Define Event status 1309// TODO: Define Event status
1301// anEvent->setStatus(tmpStr); 1310// anEvent->setStatus(tmpStr);
1302 } 1311 }
1303 else 1312 else
1304// anEvent->setStatus("NEEDS ACTION"); 1313// anEvent->setStatus("NEEDS ACTION");
1305#endif 1314#endif
1306 1315
1307 // secrecy 1316 // secrecy
1308 int secrecy = Incidence::SecrecyPublic; 1317 int secrecy = Incidence::SecrecyPublic;
1309 if ((vo = isAPropertyOf(vevent, VCClassProp)) != 0) { 1318 if ((vo = isAPropertyOf(vevent, VCClassProp)) != 0) {
1310 s = fakeCString(vObjectUStringZValue(vo)); 1319 s = fakeCString(vObjectUStringZValue(vo));
1311 if (strcmp(s,"PRIVATE") == 0) { 1320 if (strcmp(s,"PRIVATE") == 0) {
1312 secrecy = Incidence::SecrecyPrivate; 1321 secrecy = Incidence::SecrecyPrivate;
1313 } else if (strcmp(s,"CONFIDENTIAL") == 0) { 1322 } else if (strcmp(s,"CONFIDENTIAL") == 0) {
1314 secrecy = Incidence::SecrecyConfidential; 1323 secrecy = Incidence::SecrecyConfidential;
1315 } 1324 }
1316 deleteStr(s); 1325 deleteStr(s);
1317 } 1326 }
1318 anEvent->setSecrecy(secrecy); 1327 anEvent->setSecrecy(secrecy);
1319 1328
1320 // categories 1329 // categories
1321 QStringList tmpStrList; 1330 QStringList tmpStrList;
1322 int index1 = 0; 1331 int index1 = 0;
1323 int index2 = 0; 1332 int index2 = 0;
1324 if ((vo = isAPropertyOf(vevent, VCCategoriesProp)) != 0) { 1333 if ((vo = isAPropertyOf(vevent, VCCategoriesProp)) != 0) {
1325 s = fakeCString(vObjectUStringZValue(vo)); 1334 s = fakeCString(vObjectUStringZValue(vo));
1326 QString categories = QString::fromLocal8Bit(s); 1335 QString categories = QString::fromLocal8Bit(s);
1327 deleteStr(s); 1336 deleteStr(s);
1328 //const char* category; 1337 //const char* category;
1329 QString category; 1338 QString category;
1330 while ((index2 = categories.find(',', index1)) != -1) { 1339 while ((index2 = categories.find(',', index1)) != -1) {
1331 //category = (const char *) categories.mid(index1, (index2 - index1)); 1340 //category = (const char *) categories.mid(index1, (index2 - index1));
1332 category = categories.mid(index1, (index2 - index1)); 1341 category = categories.mid(index1, (index2 - index1));
1333 tmpStrList.append(category); 1342 tmpStrList.append(category);
1334 index1 = index2+1; 1343 index1 = index2+1;
1335 } 1344 }
1336 // get last category 1345 // get last category
1337 category = categories.mid(index1, (categories.length()-index1)); 1346 category = categories.mid(index1, (categories.length()-index1));
1338 tmpStrList.append(category); 1347 tmpStrList.append(category);
1339 anEvent->setCategories(tmpStrList); 1348 anEvent->setCategories(tmpStrList);
1340 } 1349 }
1341 1350
1342 // attachments 1351 // attachments
1343 tmpStrList.clear(); 1352 tmpStrList.clear();
1344 initPropIterator(&voi, vevent); 1353 initPropIterator(&voi, vevent);
1345 while (moreIteration(&voi)) { 1354 while (moreIteration(&voi)) {
1346 vo = nextVObject(&voi); 1355 vo = nextVObject(&voi);
1347 if (strcmp(vObjectName(vo), VCAttachProp) == 0) { 1356 if (strcmp(vObjectName(vo), VCAttachProp) == 0) {
1348 s = fakeCString(vObjectUStringZValue(vo)); 1357 s = fakeCString(vObjectUStringZValue(vo));
1349 anEvent->addAttachment(new Attachment(QString(s))); 1358 anEvent->addAttachment(new Attachment(QString(s)));
1350 deleteStr(s); 1359 deleteStr(s);
1351 } 1360 }
1352 } 1361 }
1353 1362
1354 // resources 1363 // resources
1355 if ((vo = isAPropertyOf(vevent, VCResourcesProp)) != 0) { 1364 if ((vo = isAPropertyOf(vevent, VCResourcesProp)) != 0) {
1356 QString resources = (s = fakeCString(vObjectUStringZValue(vo))); 1365 QString resources = (s = fakeCString(vObjectUStringZValue(vo)));
1357 deleteStr(s); 1366 deleteStr(s);
1358 tmpStrList.clear(); 1367 tmpStrList.clear();
1359 index1 = 0; 1368 index1 = 0;
1360 index2 = 0; 1369 index2 = 0;
1361 QString resource; 1370 QString resource;
1362 while ((index2 = resources.find(';', index1)) != -1) { 1371 while ((index2 = resources.find(';', index1)) != -1) {
1363 resource = resources.mid(index1, (index2 - index1)); 1372 resource = resources.mid(index1, (index2 - index1));
1364 tmpStrList.append(resource); 1373 tmpStrList.append(resource);
1365 index1 = index2; 1374 index1 = index2;
1366 } 1375 }
1367 anEvent->setResources(tmpStrList); 1376 anEvent->setResources(tmpStrList);
1368 } 1377 }
1369 1378
1370 /* alarm stuff */ 1379 /* alarm stuff */
1371 if ((vo = isAPropertyOf(vevent, VCDAlarmProp))) { 1380 if ((vo = isAPropertyOf(vevent, VCDAlarmProp))) {
1372 Alarm* alarm = anEvent->newAlarm(); 1381 Alarm* alarm = anEvent->newAlarm();
1373 VObject *a; 1382 VObject *a;
1374 if ((a = isAPropertyOf(vo, VCRunTimeProp))) { 1383 if ((a = isAPropertyOf(vo, VCRunTimeProp))) {
1375 alarm->setTime(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(a)))); 1384 alarm->setTime(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(a))));
1376 deleteStr(s); 1385 deleteStr(s);
1377 } 1386 }
1378 alarm->setEnabled(true); 1387 alarm->setEnabled(true);
1379 if ((vo = isAPropertyOf(vevent, VCPAlarmProp))) { 1388 if ((vo = isAPropertyOf(vevent, VCPAlarmProp))) {
1380 if ((a = isAPropertyOf(vo, VCProcedureNameProp))) { 1389 if ((a = isAPropertyOf(vo, VCProcedureNameProp))) {
1381 s = fakeCString(vObjectUStringZValue(a)); 1390 s = fakeCString(vObjectUStringZValue(a));
1382 alarm->setProcedureAlarm(QFile::decodeName(s)); 1391 alarm->setProcedureAlarm(QFile::decodeName(s));
1383 deleteStr(s); 1392 deleteStr(s);
1384 } 1393 }
1385 } 1394 }
1386 if ((vo = isAPropertyOf(vevent, VCAAlarmProp))) { 1395 if ((vo = isAPropertyOf(vevent, VCAAlarmProp))) {
1387 if ((a = isAPropertyOf(vo, VCAudioContentProp))) { 1396 if ((a = isAPropertyOf(vo, VCAudioContentProp))) {
1388 s = fakeCString(vObjectUStringZValue(a)); 1397 s = fakeCString(vObjectUStringZValue(a));
1389 alarm->setAudioAlarm(QFile::decodeName(s)); 1398 alarm->setAudioAlarm(QFile::decodeName(s));
1390 deleteStr(s); 1399 deleteStr(s);
1391 } 1400 }
1392 } 1401 }
1393 } 1402 }
1394 1403
1395 // priority 1404 // priority
1396 if ((vo = isAPropertyOf(vevent, VCPriorityProp))) { 1405 if ((vo = isAPropertyOf(vevent, VCPriorityProp))) {
1397 anEvent->setPriority(atoi(s = fakeCString(vObjectUStringZValue(vo)))); 1406 anEvent->setPriority(atoi(s = fakeCString(vObjectUStringZValue(vo))));
1398 deleteStr(s); 1407 deleteStr(s);
1399 } 1408 }
1400 1409
1401 // transparency 1410 // transparency
1402 if ((vo = isAPropertyOf(vevent, VCTranspProp)) != 0) { 1411 if ((vo = isAPropertyOf(vevent, VCTranspProp)) != 0) {
1403 int i = atoi(s = fakeCString(vObjectUStringZValue(vo))); 1412 int i = atoi(s = fakeCString(vObjectUStringZValue(vo)));
1404 anEvent->setTransparency( i == 1 ? Event::Transparent : Event::Opaque ); 1413 anEvent->setTransparency( i == 1 ? Event::Transparent : Event::Opaque );
1405 deleteStr(s); 1414 deleteStr(s);
1406 } 1415 }
1407 1416
1408 // related event 1417 // related event
1409 if ((vo = isAPropertyOf(vevent, VCRelatedToProp)) != 0) { 1418 if ((vo = isAPropertyOf(vevent, VCRelatedToProp)) != 0) {
1410 anEvent->setRelatedToUid(s = fakeCString(vObjectUStringZValue(vo))); 1419 anEvent->setRelatedToUid(s = fakeCString(vObjectUStringZValue(vo)));
1411 deleteStr(s); 1420 deleteStr(s);
1412 mEventsRelate.append(anEvent); 1421 mEventsRelate.append(anEvent);
1413 } 1422 }
1414 1423
1415 /* PILOT SYNC STUFF */ 1424 /* PILOT SYNC STUFF */
1416 if ((vo = isAPropertyOf(vevent, XPilotIdProp))) { 1425 if ((vo = isAPropertyOf(vevent, XPilotIdProp))) {
1417 anEvent->setPilotId(atoi(s = fakeCString(vObjectUStringZValue(vo)))); 1426 anEvent->setPilotId(atoi(s = fakeCString(vObjectUStringZValue(vo))));
1418 deleteStr(s); 1427 deleteStr(s);
1419 } 1428 }
1420 else 1429 else
1421 anEvent->setPilotId(0); 1430 anEvent->setPilotId(0);
1422 1431
1423 if ((vo = isAPropertyOf(vevent, XPilotStatusProp))) { 1432 if ((vo = isAPropertyOf(vevent, XPilotStatusProp))) {
1424 anEvent->setSyncStatus(atoi(s = fakeCString(vObjectUStringZValue(vo)))); 1433 anEvent->setSyncStatus(atoi(s = fakeCString(vObjectUStringZValue(vo))));
1425 deleteStr(s); 1434 deleteStr(s);
1426 } 1435 }
1427 else 1436 else
1428 anEvent->setSyncStatus(Event::SYNCMOD); 1437 anEvent->setSyncStatus(Event::SYNCMOD);
1429 1438
1430 return anEvent; 1439 return anEvent;
1431} 1440}
1432 1441
1433 1442
1434QString VCalFormat::qDateToISO(const QDate &qd) 1443QString VCalFormat::qDateToISO(const QDate &qd)
1435{ 1444{
1436 QString tmpStr; 1445 QString tmpStr;
1437 1446
1438 ASSERT(qd.isValid()); 1447 ASSERT(qd.isValid());
1439 1448
1440 tmpStr.sprintf("%.2d%.2d%.2d", 1449 tmpStr.sprintf("%.2d%.2d%.2d",
1441 qd.year(), qd.month(), qd.day()); 1450 qd.year(), qd.month(), qd.day());
1442 return tmpStr; 1451 return tmpStr;
1443 1452
1444} 1453}
1445 1454
1446QString VCalFormat::qDateTimeToISO(const QDateTime &qdt, bool zulu) 1455QString VCalFormat::qDateTimeToISO(const QDateTime &qdt, bool zulu)
1447{ 1456{
1448 QString tmpStr; 1457 QString tmpStr;
1449 1458
1450 ASSERT(qdt.date().isValid()); 1459 ASSERT(qdt.date().isValid());
1451 ASSERT(qdt.time().isValid()); 1460 ASSERT(qdt.time().isValid());
1452 if (zulu && !useLocalTime ) { 1461 if (zulu && !useLocalTime ) {
1453 QDateTime tmpDT = qdt.addSecs ( -KGlobal::locale()->localTimeOffset( qdt )*60); 1462 QDateTime tmpDT = qdt.addSecs ( -KGlobal::locale()->localTimeOffset( qdt )*60);
1454 tmpStr.sprintf("%.2d%.2d%.2dT%.2d%.2d%.2dZ", 1463 tmpStr.sprintf("%.2d%.2d%.2dT%.2d%.2d%.2dZ",
1455 tmpDT.date().year(), tmpDT.date().month(), 1464 tmpDT.date().year(), tmpDT.date().month(),
1456 tmpDT.date().day(), tmpDT.time().hour(), 1465 tmpDT.date().day(), tmpDT.time().hour(),
1457 tmpDT.time().minute(), tmpDT.time().second()); 1466 tmpDT.time().minute(), tmpDT.time().second());
1458 } else { 1467 } else {
1459 tmpStr.sprintf("%.2d%.2d%.2dT%.2d%.2d%.2d", 1468 tmpStr.sprintf("%.2d%.2d%.2dT%.2d%.2d%.2d",
1460 qdt.date().year(), qdt.date().month(), 1469 qdt.date().year(), qdt.date().month(),
1461 qdt.date().day(), qdt.time().hour(), 1470 qdt.date().day(), qdt.time().hour(),
1462 qdt.time().minute(), qdt.time().second()); 1471 qdt.time().minute(), qdt.time().second());
1463 } 1472 }
1464 return tmpStr; 1473 return tmpStr;
1465} 1474}
1466 1475
1467QDateTime VCalFormat::ISOToQDateTime(const QString & dtStr) 1476QDateTime VCalFormat::ISOToQDateTime(const QString & dtStr)
1468{ 1477{
1469 QDate tmpDate; 1478 QDate tmpDate;
1470 QTime tmpTime; 1479 QTime tmpTime;
1471 QString tmpStr; 1480 QString tmpStr;
1472 int year, month, day, hour, minute, second; 1481 int year, month, day, hour, minute, second;
1473 1482
1474 tmpStr = dtStr; 1483 tmpStr = dtStr;
1475 year = tmpStr.left(4).toInt(); 1484 year = tmpStr.left(4).toInt();
1476 month = tmpStr.mid(4,2).toInt(); 1485 month = tmpStr.mid(4,2).toInt();
1477 day = tmpStr.mid(6,2).toInt(); 1486 day = tmpStr.mid(6,2).toInt();
1478 hour = tmpStr.mid(9,2).toInt(); 1487 hour = tmpStr.mid(9,2).toInt();
1479 minute = tmpStr.mid(11,2).toInt(); 1488 minute = tmpStr.mid(11,2).toInt();
1480 second = tmpStr.mid(13,2).toInt(); 1489 second = tmpStr.mid(13,2).toInt();
1481 tmpDate.setYMD(year, month, day); 1490 tmpDate.setYMD(year, month, day);
1482 tmpTime.setHMS(hour, minute, second); 1491 tmpTime.setHMS(hour, minute, second);
1483 1492
1484 ASSERT(tmpDate.isValid()); 1493 ASSERT(tmpDate.isValid());
1485 ASSERT(tmpTime.isValid()); 1494 ASSERT(tmpTime.isValid());
1486 QDateTime tmpDT(tmpDate, tmpTime); 1495 QDateTime tmpDT(tmpDate, tmpTime);
1487 // correct for GMT if string is in Zulu format 1496 // correct for GMT if string is in Zulu format
1488 if (dtStr.at(dtStr.length()-1) == 'Z') 1497 if (dtStr.at(dtStr.length()-1) == 'Z')
1489 tmpDT = tmpDT.addSecs (KGlobal::locale()->localTimeOffset( tmpDT )*60); 1498 tmpDT = tmpDT.addSecs (KGlobal::locale()->localTimeOffset( tmpDT )*60);
1490 return tmpDT; 1499 return tmpDT;
1491} 1500}
1492 1501
1493QDate VCalFormat::ISOToQDate(const QString &dateStr) 1502QDate VCalFormat::ISOToQDate(const QString &dateStr)
1494{ 1503{
1495 int year, month, day; 1504 int year, month, day;
1496 1505
1497 year = dateStr.left(4).toInt(); 1506 year = dateStr.left(4).toInt();
1498 month = dateStr.mid(4,2).toInt(); 1507 month = dateStr.mid(4,2).toInt();
1499 day = dateStr.mid(6,2).toInt(); 1508 day = dateStr.mid(6,2).toInt();
1500 1509
1501 return(QDate(year, month, day)); 1510 return(QDate(year, month, day));
1502} 1511}
1503 1512
1504// take a raw vcalendar (i.e. from a file on disk, clipboard, etc. etc. 1513// take a raw vcalendar (i.e. from a file on disk, clipboard, etc. etc.
1505// and break it down from it's tree-like format into the dictionary format 1514// and break it down from it's tree-like format into the dictionary format
1506// that is used internally in the VCalFormat. 1515// that is used internally in the VCalFormat.
1507void VCalFormat::populate(VObject *vcal) 1516void VCalFormat::populate(VObject *vcal)
1508{ 1517{
1509 // this function will populate the caldict dictionary and other event 1518 // this function will populate the caldict dictionary and other event
1510 // lists. It turns vevents into Events and then inserts them. 1519 // lists. It turns vevents into Events and then inserts them.
1511 1520
1512 VObjectIterator i; 1521 VObjectIterator i;
1513 VObject *curVO, *curVOProp; 1522 VObject *curVO, *curVOProp;
1514 Event *anEvent; 1523 Event *anEvent;
1515 1524
1516 if ((curVO = isAPropertyOf(vcal, ICMethodProp)) != 0) { 1525 if ((curVO = isAPropertyOf(vcal, ICMethodProp)) != 0) {
1517 char *methodType = 0; 1526 char *methodType = 0;
1518 methodType = fakeCString(vObjectUStringZValue(curVO)); 1527 methodType = fakeCString(vObjectUStringZValue(curVO));
1519 kdDebug() << "This calendar is an iTIP transaction of type '" 1528 kdDebug() << "This calendar is an iTIP transaction of type '"
1520 << methodType << "'" << endl; 1529 << methodType << "'" << endl;
1521 delete methodType; 1530 delete methodType;
1522 } 1531 }
1523 1532
1524 // warn the user that we might have trouble reading non-known calendar. 1533 // warn the user that we might have trouble reading non-known calendar.
1525 if ((curVO = isAPropertyOf(vcal, VCProdIdProp)) != 0) { 1534 if ((curVO = isAPropertyOf(vcal, VCProdIdProp)) != 0) {
1526 char *s = fakeCString(vObjectUStringZValue(curVO)); 1535 char *s = fakeCString(vObjectUStringZValue(curVO));
1527 if (strcmp(productId().local8Bit(), s) != 0) 1536 if (strcmp(productId().local8Bit(), s) != 0)
1528 kdDebug() << "This vCalendar file was not created by KOrganizer " 1537 kdDebug() << "This vCalendar file was not created by KOrganizer "
1529 "or any other product we support. Loading anyway..." << endl; 1538 "or any other product we support. Loading anyway..." << endl;
1530 mLoadedProductId = s; 1539 mLoadedProductId = s;
1531 deleteStr(s); 1540 deleteStr(s);
1532 } 1541 }
1533 1542
1534 // warn the user we might have trouble reading this unknown version. 1543 // warn the user we might have trouble reading this unknown version.
1535 if ((curVO = isAPropertyOf(vcal, VCVersionProp)) != 0) { 1544 if ((curVO = isAPropertyOf(vcal, VCVersionProp)) != 0) {
1536 char *s = fakeCString(vObjectUStringZValue(curVO)); 1545 char *s = fakeCString(vObjectUStringZValue(curVO));
1537 if (strcmp(_VCAL_VERSION, s) != 0) 1546 if (strcmp(_VCAL_VERSION, s) != 0)
1538 kdDebug() << "This vCalendar file has version " << s 1547 kdDebug() << "This vCalendar file has version " << s
1539 << "We only support " << _VCAL_VERSION << endl; 1548 << "We only support " << _VCAL_VERSION << endl;
1540 deleteStr(s); 1549 deleteStr(s);
1541 } 1550 }
1542 1551
1543 // set the time zone 1552 // set the time zone
1544 if ((curVO = isAPropertyOf(vcal, VCTimeZoneProp)) != 0) { 1553 if ((curVO = isAPropertyOf(vcal, VCTimeZoneProp)) != 0) {
1545 if ( vObjectUStringZValue(curVO) != 0 ) { 1554 if ( vObjectUStringZValue(curVO) != 0 ) {
1546 char *s = fakeCString(vObjectUStringZValue(curVO)); 1555 char *s = fakeCString(vObjectUStringZValue(curVO));
1547 mCalendar->setTimeZone(s); 1556 mCalendar->setTimeZone(s);
1548 deleteStr(s); 1557 deleteStr(s);
1549 } 1558 }
1550 } 1559 }
1551 1560
1552 // Store all events with a relatedTo property in a list for post-processing 1561 // Store all events with a relatedTo property in a list for post-processing
1553 mEventsRelate.clear(); 1562 mEventsRelate.clear();
1554 mTodosRelate.clear(); 1563 mTodosRelate.clear();
1555 1564
1556 initPropIterator(&i, vcal); 1565 initPropIterator(&i, vcal);
1557 1566
1558 // go through all the vobjects in the vcal 1567 // go through all the vobjects in the vcal
1559 while (moreIteration(&i)) { 1568 while (moreIteration(&i)) {
1560 curVO = nextVObject(&i); 1569 curVO = nextVObject(&i);
1561 1570
1562 /************************************************************************/ 1571 /************************************************************************/
1563 1572
1564 // now, check to see that the object is an event or todo. 1573 // now, check to see that the object is an event or todo.
1565 if (strcmp(vObjectName(curVO), VCEventProp) == 0) { 1574 if (strcmp(vObjectName(curVO), VCEventProp) == 0) {
1566 1575
1567 if ((curVOProp = isAPropertyOf(curVO, XPilotStatusProp)) != 0) { 1576 if ((curVOProp = isAPropertyOf(curVO, XPilotStatusProp)) != 0) {
1568 char *s; 1577 char *s;
1569 s = fakeCString(vObjectUStringZValue(curVOProp)); 1578 s = fakeCString(vObjectUStringZValue(curVOProp));
1570 // check to see if event was deleted by the kpilot conduit 1579 // check to see if event was deleted by the kpilot conduit
1571 if (atoi(s) == Event::SYNCDEL) { 1580 if (atoi(s) == Event::SYNCDEL) {
1572 deleteStr(s); 1581 deleteStr(s);
1573 kdDebug(5800) << "skipping pilot-deleted event" << endl; 1582 kdDebug(5800) << "skipping pilot-deleted event" << endl;
1574 goto SKIP; 1583 goto SKIP;
1575 } 1584 }
1576 deleteStr(s); 1585 deleteStr(s);
1577 } 1586 }
1578 1587
1579 // this code checks to see if we are trying to read in an event 1588 // this code checks to see if we are trying to read in an event
1580 // that we already find to be in the calendar. If we find this 1589 // that we already find to be in the calendar. If we find this
1581 // to be the case, we skip the event. 1590 // to be the case, we skip the event.
1582 if ((curVOProp = isAPropertyOf(curVO, VCUniqueStringProp)) != 0) { 1591 if ((curVOProp = isAPropertyOf(curVO, VCUniqueStringProp)) != 0) {
1583 char *s = fakeCString(vObjectUStringZValue(curVOProp)); 1592 char *s = fakeCString(vObjectUStringZValue(curVOProp));
1584 QString tmpStr(s); 1593 QString tmpStr(s);
1585 deleteStr(s); 1594 deleteStr(s);
1586 1595
1587 if (mCalendar->event(tmpStr)) { 1596 if (mCalendar->event(tmpStr)) {
1588 goto SKIP; 1597 goto SKIP;
1589 } 1598 }
1590 if (mCalendar->todo(tmpStr)) { 1599 if (mCalendar->todo(tmpStr)) {
1591 goto SKIP; 1600 goto SKIP;
1592 } 1601 }
1593 } 1602 }
1594 1603
1595 if ((!(curVOProp = isAPropertyOf(curVO, VCDTstartProp))) && 1604 if ((!(curVOProp = isAPropertyOf(curVO, VCDTstartProp))) &&
1596 (!(curVOProp = isAPropertyOf(curVO, VCDTendProp)))) { 1605 (!(curVOProp = isAPropertyOf(curVO, VCDTendProp)))) {
1597 kdDebug(5800) << "found a VEvent with no DTSTART and no DTEND! Skipping..." << endl; 1606 kdDebug(5800) << "found a VEvent with no DTSTART and no DTEND! Skipping..." << endl;
1598 goto SKIP; 1607 goto SKIP;
1599 } 1608 }
1600 1609
1601 anEvent = VEventToEvent(curVO); 1610 anEvent = VEventToEvent(curVO);
1602 // we now use addEvent instead of insertEvent so that the 1611 // we now use addEvent instead of insertEvent so that the
1603 // signal/slot get connected. 1612 // signal/slot get connected.
1604 if (anEvent) { 1613 if (anEvent) {
1605 if ( !anEvent->dtStart().isValid() || !anEvent->dtEnd().isValid() ) { 1614 if ( !anEvent->dtStart().isValid() || !anEvent->dtEnd().isValid() ) {
1606 kdDebug() << "VCalFormat::populate(): Event has invalid dates." 1615 kdDebug() << "VCalFormat::populate(): Event has invalid dates."
1607 << endl; 1616 << endl;
1608 } else { 1617 } else {
1609 mCalendar->addEvent(anEvent); 1618 mCalendar->addEvent(anEvent);
1610 } 1619 }
1611 } else { 1620 } else {
1612 // some sort of error must have occurred while in translation. 1621 // some sort of error must have occurred while in translation.
1613 goto SKIP; 1622 goto SKIP;
1614 } 1623 }
1615 } else if (strcmp(vObjectName(curVO), VCTodoProp) == 0) { 1624 } else if (strcmp(vObjectName(curVO), VCTodoProp) == 0) {
1616 Todo *aTodo = VTodoToEvent(curVO); 1625 Todo *aTodo = VTodoToEvent(curVO);
1617 mCalendar->addTodo(aTodo); 1626 mCalendar->addTodo(aTodo);
1618 } else if ((strcmp(vObjectName(curVO), VCVersionProp) == 0) || 1627 } else if ((strcmp(vObjectName(curVO), VCVersionProp) == 0) ||
1619 (strcmp(vObjectName(curVO), VCProdIdProp) == 0) || 1628 (strcmp(vObjectName(curVO), VCProdIdProp) == 0) ||
1620 (strcmp(vObjectName(curVO), VCTimeZoneProp) == 0)) { 1629 (strcmp(vObjectName(curVO), VCTimeZoneProp) == 0)) {
1621 // do nothing, we know these properties and we want to skip them. 1630 // do nothing, we know these properties and we want to skip them.
1622 // we have either already processed them or are ignoring them. 1631 // we have either already processed them or are ignoring them.
1623 ; 1632 ;
1624 } else { 1633 } else {
1625 kdDebug(5800) << "Ignoring unknown vObject \"" << vObjectName(curVO) << "\"" << endl; 1634 kdDebug(5800) << "Ignoring unknown vObject \"" << vObjectName(curVO) << "\"" << endl;
1626 } 1635 }
1627 SKIP: 1636 SKIP:
1628 ; 1637 ;
1629 } // while 1638 } // while
1630 1639
1631 // Post-Process list of events with relations, put Event objects in relation 1640 // Post-Process list of events with relations, put Event objects in relation
1632 Event *ev; 1641 Event *ev;
1633 for ( ev=mEventsRelate.first(); ev != 0; ev=mEventsRelate.next() ) { 1642 for ( ev=mEventsRelate.first(); ev != 0; ev=mEventsRelate.next() ) {
1634 ev->setRelatedTo(mCalendar->event(ev->relatedToUid())); 1643 ev->setRelatedTo(mCalendar->event(ev->relatedToUid()));
1635 } 1644 }
1636 Todo *todo; 1645 Todo *todo;
1637 for ( todo=mTodosRelate.first(); todo != 0; todo=mTodosRelate.next() ) { 1646 for ( todo=mTodosRelate.first(); todo != 0; todo=mTodosRelate.next() ) {
1638 todo->setRelatedTo(mCalendar->todo(todo->relatedToUid())); 1647 todo->setRelatedTo(mCalendar->todo(todo->relatedToUid()));
1639 } 1648 }
1640} 1649}
1641 1650
1642const char *VCalFormat::dayFromNum(int day) 1651const char *VCalFormat::dayFromNum(int day)
1643{ 1652{
1644 const char *days[7] = { "MO ", "TU ", "WE ", "TH ", "FR ", "SA ", "SU " }; 1653 const char *days[7] = { "MO ", "TU ", "WE ", "TH ", "FR ", "SA ", "SU " };
1645 1654
1646 return days[day]; 1655 return days[day];
1647} 1656}
1648 1657
1649int VCalFormat::numFromDay(const QString &day) 1658int VCalFormat::numFromDay(const QString &day)
1650{ 1659{
1651 if (day == "MO ") return 0; 1660 if (day == "MO ") return 0;
1652 if (day == "TU ") return 1; 1661 if (day == "TU ") return 1;
1653 if (day == "WE ") return 2; 1662 if (day == "WE ") return 2;
1654 if (day == "TH ") return 3; 1663 if (day == "TH ") return 3;
1655 if (day == "FR ") return 4; 1664 if (day == "FR ") return 4;
1656 if (day == "SA ") return 5; 1665 if (day == "SA ") return 5;
1657 if (day == "SU ") return 6; 1666 if (day == "SU ") return 6;
1658 1667
1659 return -1; // something bad happened. :) 1668 return -1; // something bad happened. :)
1660} 1669}
1670Attendee::Role VCalFormat::readRole(const char *s) const
1671{
1672 QString statStr = s;
1673 statStr = statStr.upper();
1674 Attendee::Role role = Attendee::ReqParticipant;
1675
1676 if ( statStr == "OWNER")
1677 role = Attendee::Chair;
1678 // enum Role { ReqParticipant, OptParticipant, NonParticipant, Chair };
1679
1680 return role;
1681}
1661 1682
1683QCString VCalFormat::writeRole(Attendee::Role role) const
1684{
1685 if ( role == Attendee::Chair )
1686 return "OWNER";
1687 return "ATTENDEE";
1688}
1662Attendee::PartStat VCalFormat::readStatus(const char *s) const 1689Attendee::PartStat VCalFormat::readStatus(const char *s) const
1663{ 1690{
1664 QString statStr = s; 1691 QString statStr = s;
1665 statStr = statStr.upper(); 1692 statStr = statStr.upper();
1666 Attendee::PartStat status; 1693 Attendee::PartStat status;
1667 1694
1668 if (statStr == "X-ACTION") 1695 if (statStr == "X-ACTION")
1669 status = Attendee::NeedsAction; 1696 status = Attendee::NeedsAction;
1670 else if (statStr == "NEEDS ACTION") 1697 else if (statStr == "NEEDS ACTION")
1671 status = Attendee::NeedsAction; 1698 status = Attendee::NeedsAction;
1672 else if (statStr== "ACCEPTED") 1699 else if (statStr== "ACCEPTED")
1673 status = Attendee::Accepted; 1700 status = Attendee::Accepted;
1674 else if (statStr== "SENT") 1701 else if (statStr== "SENT")
1675 status = Attendee::NeedsAction; 1702 status = Attendee::NeedsAction;
1676 else if (statStr== "TENTATIVE") 1703 else if (statStr== "TENTATIVE")
1677 status = Attendee::Tentative; 1704 status = Attendee::Tentative;
1678 else if (statStr== "CONFIRMED") 1705 else if (statStr== "CONFIRMED")
1679 status = Attendee::Accepted; 1706 status = Attendee::Accepted;
1680 else if (statStr== "DECLINED") 1707 else if (statStr== "DECLINED")
1681 status = Attendee::Declined; 1708 status = Attendee::Declined;
1682 else if (statStr== "COMPLETED") 1709 else if (statStr== "COMPLETED")
1683 status = Attendee::Completed; 1710 status = Attendee::Completed;
1684 else if (statStr== "DELEGATED") 1711 else if (statStr== "DELEGATED")
1685 status = Attendee::Delegated; 1712 status = Attendee::Delegated;
1686 else { 1713 else {
1687 kdDebug(5800) << "error setting attendee mStatus, unknown mStatus!" << endl; 1714 kdDebug(5800) << "error setting attendee mStatus, unknown mStatus!" << endl;
1688 status = Attendee::NeedsAction; 1715 status = Attendee::NeedsAction;
1689 } 1716 }
1690 1717
1691 return status; 1718 return status;
1692} 1719}
1693 1720
1694QCString VCalFormat::writeStatus(Attendee::PartStat status) const 1721QCString VCalFormat::writeStatus(Attendee::PartStat status) const
1695{ 1722{
1696 switch(status) { 1723 switch(status) {
1697 default: 1724 default:
1698 case Attendee::NeedsAction: 1725 case Attendee::NeedsAction:
1699 return "NEEDS ACTION"; 1726 return "NEEDS ACTION";
1700 break; 1727 break;
1701 case Attendee::Accepted: 1728 case Attendee::Accepted:
1702 return "ACCEPTED"; 1729 return "ACCEPTED";
1703 break; 1730 break;
1704 case Attendee::Declined: 1731 case Attendee::Declined:
1705 return "DECLINED"; 1732 return "DECLINED";
1706 break; 1733 break;
1707 case Attendee::Tentative: 1734 case Attendee::Tentative:
1708 return "TENTATIVE"; 1735 return "TENTATIVE";
1709 break; 1736 break;
1710 case Attendee::Delegated: 1737 case Attendee::Delegated:
1711 return "DELEGATED"; 1738 return "DELEGATED";
1712 break; 1739 break;
1713 case Attendee::Completed: 1740 case Attendee::Completed:
1714 return "COMPLETED"; 1741 return "COMPLETED";
1715 break; 1742 break;
1716 case Attendee::InProcess: 1743 case Attendee::InProcess:
1717 return "NEEDS ACTION"; 1744 return "NEEDS ACTION";
1718 break; 1745 break;
1719 } 1746 }
1720} 1747}
diff --git a/libkcal/vcalformat.h b/libkcal/vcalformat.h
index 5bef7ed..c7df017 100644
--- a/libkcal/vcalformat.h
+++ b/libkcal/vcalformat.h
@@ -1,112 +1,113 @@
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 _VCALFORMAT_H 22#ifndef _VCALFORMAT_H
23#define _VCALFORMAT_H 23#define _VCALFORMAT_H
24 24
25#include "calformat.h" 25#include "calformat.h"
26 26
27#define _VCAL_VERSION "1.0" 27#define _VCAL_VERSION "1.0"
28 28
29class VObject; 29class VObject;
30 30
31namespace KCal { 31namespace KCal {
32 32
33/** 33/**
34 This class implements the vCalendar format. It provides methods for 34 This class implements the vCalendar format. It provides methods for
35 loading/saving/converting vCalendar format data into the internal KOrganizer 35 loading/saving/converting vCalendar format data into the internal KOrganizer
36 representation as Calendar and Events. 36 representation as Calendar and Events.
37 37
38 @short vCalendar format implementation 38 @short vCalendar format implementation
39*/ 39*/
40class VCalFormat : public CalFormat { 40class VCalFormat : public CalFormat {
41 public: 41 public:
42 VCalFormat(); 42 VCalFormat();
43 virtual ~VCalFormat(); 43 virtual ~VCalFormat();
44 44
45 /** loads a calendar on disk in vCalendar format into the current calendar. 45 /** loads a calendar on disk in vCalendar format into the current calendar.
46 * any information already present is lost. Returns TRUE if successful, 46 * any information already present is lost. Returns TRUE if successful,
47 * else returns FALSE. 47 * else returns FALSE.
48 * @param fileName the name of the calendar on disk. 48 * @param fileName the name of the calendar on disk.
49 */ 49 */
50 bool load(Calendar *,const QString &fileName ); 50 bool load(Calendar *,const QString &fileName );
51 /** writes out the calendar to disk in vCalendar format. Returns true if 51 /** writes out the calendar to disk in vCalendar format. Returns true if
52 * successful and false on error. 52 * successful and false on error.
53 * @param fileName the name of the file 53 * @param fileName the name of the file
54 */ 54 */
55 bool save(Calendar *,const QString &fileName ); 55 bool save(Calendar *,const QString &fileName );
56 56
57 /** 57 /**
58 Parse string and populate calendar with that information. 58 Parse string and populate calendar with that information.
59 */ 59 */
60 bool fromString( Calendar *, const QString & ); 60 bool fromString( Calendar *, const QString & );
61 /** 61 /**
62 Return calendar information as string. 62 Return calendar information as string.
63 */ 63 */
64 void setLocalTime ( bool ); 64 void setLocalTime ( bool );
65 QString toString( Calendar * ); 65 QString toString( Calendar * );
66 QString eventToString( Event *, Calendar *calendar, bool useLocalTime = true ); 66 QString eventToString( Event *, Calendar *calendar, bool useLocalTime = true );
67 QString todoToString( Todo * ,Calendar *calendar, bool useLocalTime = true ); 67 QString todoToString( Todo * ,Calendar *calendar, bool useLocalTime = true );
68 68
69 protected: 69 protected:
70 /** translates a VObject of the TODO type into a Event */ 70 /** translates a VObject of the TODO type into a Event */
71 Todo *VTodoToEvent(VObject *vtodo); 71 Todo *VTodoToEvent(VObject *vtodo);
72 /** translates a VObject into a Event and returns a pointer to it. */ 72 /** translates a VObject into a Event and returns a pointer to it. */
73 Event *VEventToEvent(VObject *vevent); 73 Event *VEventToEvent(VObject *vevent);
74 /** translate a Event into a VTodo-type VObject and return pointer */ 74 /** translate a Event into a VTodo-type VObject and return pointer */
75 VObject *eventToVTodo(const Todo *anEvent); 75 VObject *eventToVTodo(const Todo *anEvent);
76 /** translate a Event into a VObject and returns a pointer to it. */ 76 /** translate a Event into a VObject and returns a pointer to it. */
77 VObject* eventToVEvent(const Event *anEvent); 77 VObject* eventToVEvent(const Event *anEvent);
78 78
79 /** takes a QDate and returns a string in the format YYYYMMDDTHHMMSS */ 79 /** takes a QDate and returns a string in the format YYYYMMDDTHHMMSS */
80 QString qDateToISO(const QDate &); 80 QString qDateToISO(const QDate &);
81 /** takes a QDateTime and returns a string in format YYYYMMDDTHHMMSS */ 81 /** takes a QDateTime and returns a string in format YYYYMMDDTHHMMSS */
82 QString qDateTimeToISO(const QDateTime &, bool zulu=TRUE); 82 QString qDateTimeToISO(const QDateTime &, bool zulu=TRUE);
83 /** takes a string in the format YYYYMMDDTHHMMSS and returns a 83 /** takes a string in the format YYYYMMDDTHHMMSS and returns a
84 * valid QDateTime. */ 84 * valid QDateTime. */
85 QDateTime ISOToQDateTime(const QString & dtStr); 85 QDateTime ISOToQDateTime(const QString & dtStr);
86 /** takes a string in the format YYYYMMDD and returns a 86 /** takes a string in the format YYYYMMDD and returns a
87 * valid QDate. */ 87 * valid QDate. */
88 QDate ISOToQDate(const QString & dtStr); 88 QDate ISOToQDate(const QString & dtStr);
89 /** takes a vCalendar tree of VObjects, and puts all of them that have 89 /** takes a vCalendar tree of VObjects, and puts all of them that have
90 * the "event" property into the dictionary, todos in the todo-list, etc. */ 90 * the "event" property into the dictionary, todos in the todo-list, etc. */
91 void populate(VObject *vcal); 91 void populate(VObject *vcal);
92 92
93 /** takes a number 0 - 6 and returns the two letter string of that day, 93 /** takes a number 0 - 6 and returns the two letter string of that day,
94 * i.e. MO, TU, WE, etc. */ 94 * i.e. MO, TU, WE, etc. */
95 const char *dayFromNum(int day); 95 const char *dayFromNum(int day);
96 /** the reverse of the above function. */ 96 /** the reverse of the above function. */
97 int numFromDay(const QString &day); 97 int numFromDay(const QString &day);
98 98 Attendee::Role VCalFormat::readRole(const char *s) const;
99 QCString writeRole(Attendee::Role role) const;
99 Attendee::PartStat readStatus(const char *s) const; 100 Attendee::PartStat readStatus(const char *s) const;
100 QCString writeStatus(Attendee::PartStat status) const; 101 QCString writeStatus(Attendee::PartStat status) const;
101 102
102 private: 103 private:
103 Calendar *mCalendar; 104 Calendar *mCalendar;
104 bool useLocalTime; 105 bool useLocalTime;
105 106
106 QPtrList<Event> mEventsRelate; // events with relations 107 QPtrList<Event> mEventsRelate; // events with relations
107 QPtrList<Todo> mTodosRelate; // todos with relations 108 QPtrList<Todo> mTodosRelate; // todos with relations
108}; 109};
109 110
110} 111}
111 112
112#endif 113#endif
diff --git a/libkcal/versit/vcc.c b/libkcal/versit/vcc.c
index 9be752d..5413813 100644
--- a/libkcal/versit/vcc.c
+++ b/libkcal/versit/vcc.c
@@ -1253,1025 +1253,1026 @@ case 46:
1253{ 1253{
1254 lexPopMode(0); 1254 lexPopMode(0);
1255 popVObject(); 1255 popVObject();
1256 } 1256 }
1257 break; 1257 break;
1258} 1258}
1259 1259
1260#line 705 "/usr/share/bison/bison.simple" 1260#line 705 "/usr/share/bison/bison.simple"
1261 1261
1262 1262
1263 yyvsp -= yylen; 1263 yyvsp -= yylen;
1264 yyssp -= yylen; 1264 yyssp -= yylen;
1265#if YYLSP_NEEDED 1265#if YYLSP_NEEDED
1266 yylsp -= yylen; 1266 yylsp -= yylen;
1267#endif 1267#endif
1268 1268
1269#if YYDEBUG 1269#if YYDEBUG
1270 if (yydebug) 1270 if (yydebug)
1271 { 1271 {
1272 short *yyssp1 = yyss - 1; 1272 short *yyssp1 = yyss - 1;
1273 YYFPRINTF (stderr, "state stack now"); 1273 YYFPRINTF (stderr, "state stack now");
1274 while (yyssp1 != yyssp) 1274 while (yyssp1 != yyssp)
1275 YYFPRINTF (stderr, " %d", *++yyssp1); 1275 YYFPRINTF (stderr, " %d", *++yyssp1);
1276 YYFPRINTF (stderr, "\n"); 1276 YYFPRINTF (stderr, "\n");
1277 } 1277 }
1278#endif 1278#endif
1279 1279
1280 *++yyvsp = yyval; 1280 *++yyvsp = yyval;
1281#if YYLSP_NEEDED 1281#if YYLSP_NEEDED
1282 *++yylsp = yyloc; 1282 *++yylsp = yyloc;
1283#endif 1283#endif
1284 1284
1285 /* Now `shift' the result of the reduction. Determine what state 1285 /* Now `shift' the result of the reduction. Determine what state
1286 that goes to, based on the state we popped back to and the rule 1286 that goes to, based on the state we popped back to and the rule
1287 number reduced by. */ 1287 number reduced by. */
1288 1288
1289 yyn = yyr1[yyn]; 1289 yyn = yyr1[yyn];
1290 1290
1291 yystate = yypgoto[yyn - YYNTBASE] + *yyssp; 1291 yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
1292 if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp) 1292 if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
1293 yystate = yytable[yystate]; 1293 yystate = yytable[yystate];
1294 else 1294 else
1295 yystate = yydefgoto[yyn - YYNTBASE]; 1295 yystate = yydefgoto[yyn - YYNTBASE];
1296 1296
1297 goto yynewstate; 1297 goto yynewstate;
1298 1298
1299 1299
1300/*------------------------------------. 1300/*------------------------------------.
1301| yyerrlab -- here on detecting error | 1301| yyerrlab -- here on detecting error |
1302`------------------------------------*/ 1302`------------------------------------*/
1303yyerrlab: 1303yyerrlab:
1304 /* If not already recovering from an error, report this error. */ 1304 /* If not already recovering from an error, report this error. */
1305 if (!yyerrstatus) 1305 if (!yyerrstatus)
1306 { 1306 {
1307 ++yynerrs; 1307 ++yynerrs;
1308 1308
1309#ifdef YYERROR_VERBOSE 1309#ifdef YYERROR_VERBOSE
1310 yyn = yypact[yystate]; 1310 yyn = yypact[yystate];
1311 1311
1312 if (yyn > YYFLAG && yyn < YYLAST) 1312 if (yyn > YYFLAG && yyn < YYLAST)
1313 { 1313 {
1314 YYSIZE_T yysize = 0; 1314 YYSIZE_T yysize = 0;
1315 char *yymsg; 1315 char *yymsg;
1316 int yyx, yycount; 1316 int yyx, yycount;
1317 1317
1318 yycount = 0; 1318 yycount = 0;
1319 /* Start YYX at -YYN if negative to avoid negative indexes in 1319 /* Start YYX at -YYN if negative to avoid negative indexes in
1320 YYCHECK. */ 1320 YYCHECK. */
1321 for (yyx = yyn < 0 ? -yyn : 0; 1321 for (yyx = yyn < 0 ? -yyn : 0;
1322 yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++) 1322 yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++)
1323 if (yycheck[yyx + yyn] == yyx) 1323 if (yycheck[yyx + yyn] == yyx)
1324 yysize += yystrlen (yytname[yyx]) + 15, yycount++; 1324 yysize += yystrlen (yytname[yyx]) + 15, yycount++;
1325 yysize += yystrlen ("parse error, unexpected ") + 1; 1325 yysize += yystrlen ("parse error, unexpected ") + 1;
1326 yysize += yystrlen (yytname[YYTRANSLATE (yychar)]); 1326 yysize += yystrlen (yytname[YYTRANSLATE (yychar)]);
1327 yymsg = (char *) YYSTACK_ALLOC (yysize); 1327 yymsg = (char *) YYSTACK_ALLOC (yysize);
1328 if (yymsg != 0) 1328 if (yymsg != 0)
1329 { 1329 {
1330 char *yyp = yystpcpy (yymsg, "parse error, unexpected "); 1330 char *yyp = yystpcpy (yymsg, "parse error, unexpected ");
1331 yyp = yystpcpy (yyp, yytname[YYTRANSLATE (yychar)]); 1331 yyp = yystpcpy (yyp, yytname[YYTRANSLATE (yychar)]);
1332 1332
1333 if (yycount < 5) 1333 if (yycount < 5)
1334 { 1334 {
1335 yycount = 0; 1335 yycount = 0;
1336 for (yyx = yyn < 0 ? -yyn : 0; 1336 for (yyx = yyn < 0 ? -yyn : 0;
1337 yyx < (int) (sizeof (yytname) / sizeof (char *)); 1337 yyx < (int) (sizeof (yytname) / sizeof (char *));
1338 yyx++) 1338 yyx++)
1339 if (yycheck[yyx + yyn] == yyx) 1339 if (yycheck[yyx + yyn] == yyx)
1340 { 1340 {
1341 const char *yyq = ! yycount ? ", expecting " : " or "; 1341 const char *yyq = ! yycount ? ", expecting " : " or ";
1342 yyp = yystpcpy (yyp, yyq); 1342 yyp = yystpcpy (yyp, yyq);
1343 yyp = yystpcpy (yyp, yytname[yyx]); 1343 yyp = yystpcpy (yyp, yytname[yyx]);
1344 yycount++; 1344 yycount++;
1345 } 1345 }
1346 } 1346 }
1347 yyerror (yymsg); 1347 yyerror (yymsg);
1348 YYSTACK_FREE (yymsg); 1348 YYSTACK_FREE (yymsg);
1349 } 1349 }
1350 else 1350 else
1351 yyerror ("parse error; also virtual memory exhausted"); 1351 yyerror ("parse error; also virtual memory exhausted");
1352 } 1352 }
1353 else 1353 else
1354#endif /* defined (YYERROR_VERBOSE) */ 1354#endif /* defined (YYERROR_VERBOSE) */
1355 yyerror ("parse error"); 1355 yyerror ("parse error");
1356 } 1356 }
1357 goto yyerrlab1; 1357 goto yyerrlab1;
1358 1358
1359 1359
1360/*--------------------------------------------------. 1360/*--------------------------------------------------.
1361| yyerrlab1 -- error raised explicitly by an action | 1361| yyerrlab1 -- error raised explicitly by an action |
1362`--------------------------------------------------*/ 1362`--------------------------------------------------*/
1363yyerrlab1: 1363yyerrlab1:
1364 if (yyerrstatus == 3) 1364 if (yyerrstatus == 3)
1365 { 1365 {
1366 /* If just tried and failed to reuse lookahead token after an 1366 /* If just tried and failed to reuse lookahead token after an
1367 error, discard it. */ 1367 error, discard it. */
1368 1368
1369 /* return failure if at end of input */ 1369 /* return failure if at end of input */
1370 if (yychar == YYEOF) 1370 if (yychar == YYEOF)
1371 YYABORT; 1371 YYABORT;
1372 YYDPRINTF ((stderr, "Discarding token %d (%s).\n", 1372 YYDPRINTF ((stderr, "Discarding token %d (%s).\n",
1373 yychar, yytname[yychar1])); 1373 yychar, yytname[yychar1]));
1374 yychar = YYEMPTY; 1374 yychar = YYEMPTY;
1375 } 1375 }
1376 1376
1377 /* Else will try to reuse lookahead token after shifting the error 1377 /* Else will try to reuse lookahead token after shifting the error
1378 token. */ 1378 token. */
1379 1379
1380 yyerrstatus = 3; /* Each real token shifted decrements this */ 1380 yyerrstatus = 3; /* Each real token shifted decrements this */
1381 1381
1382 goto yyerrhandle; 1382 goto yyerrhandle;
1383 1383
1384 1384
1385/*-------------------------------------------------------------------. 1385/*-------------------------------------------------------------------.
1386| yyerrdefault -- current state does not do anything special for the | 1386| yyerrdefault -- current state does not do anything special for the |
1387| error token. | 1387| error token. |
1388`-------------------------------------------------------------------*/ 1388`-------------------------------------------------------------------*/
1389yyerrdefault: 1389yyerrdefault:
1390#if 0 1390#if 0
1391 /* This is wrong; only states that explicitly want error tokens 1391 /* This is wrong; only states that explicitly want error tokens
1392 should shift them. */ 1392 should shift them. */
1393 1393
1394 /* If its default is to accept any token, ok. Otherwise pop it. */ 1394 /* If its default is to accept any token, ok. Otherwise pop it. */
1395 yyn = yydefact[yystate]; 1395 yyn = yydefact[yystate];
1396 if (yyn) 1396 if (yyn)
1397 goto yydefault; 1397 goto yydefault;
1398#endif 1398#endif
1399 1399
1400 1400
1401/*---------------------------------------------------------------. 1401/*---------------------------------------------------------------.
1402| yyerrpop -- pop the current state because it cannot handle the | 1402| yyerrpop -- pop the current state because it cannot handle the |
1403| error token | 1403| error token |
1404`---------------------------------------------------------------*/ 1404`---------------------------------------------------------------*/
1405yyerrpop: 1405yyerrpop:
1406 if (yyssp == yyss) 1406 if (yyssp == yyss)
1407 YYABORT; 1407 YYABORT;
1408 yyvsp--; 1408 yyvsp--;
1409 yystate = *--yyssp; 1409 yystate = *--yyssp;
1410#if YYLSP_NEEDED 1410#if YYLSP_NEEDED
1411 yylsp--; 1411 yylsp--;
1412#endif 1412#endif
1413 1413
1414#if YYDEBUG 1414#if YYDEBUG
1415 if (yydebug) 1415 if (yydebug)
1416 { 1416 {
1417 short *yyssp1 = yyss - 1; 1417 short *yyssp1 = yyss - 1;
1418 YYFPRINTF (stderr, "Error: state stack now"); 1418 YYFPRINTF (stderr, "Error: state stack now");
1419 while (yyssp1 != yyssp) 1419 while (yyssp1 != yyssp)
1420 YYFPRINTF (stderr, " %d", *++yyssp1); 1420 YYFPRINTF (stderr, " %d", *++yyssp1);
1421 YYFPRINTF (stderr, "\n"); 1421 YYFPRINTF (stderr, "\n");
1422 } 1422 }
1423#endif 1423#endif
1424 1424
1425/*--------------. 1425/*--------------.
1426| yyerrhandle. | 1426| yyerrhandle. |
1427`--------------*/ 1427`--------------*/
1428yyerrhandle: 1428yyerrhandle:
1429 yyn = yypact[yystate]; 1429 yyn = yypact[yystate];
1430 if (yyn == YYFLAG) 1430 if (yyn == YYFLAG)
1431 goto yyerrdefault; 1431 goto yyerrdefault;
1432 1432
1433 yyn += YYTERROR; 1433 yyn += YYTERROR;
1434 if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR) 1434 if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
1435 goto yyerrdefault; 1435 goto yyerrdefault;
1436 1436
1437 yyn = yytable[yyn]; 1437 yyn = yytable[yyn];
1438 if (yyn < 0) 1438 if (yyn < 0)
1439 { 1439 {
1440 if (yyn == YYFLAG) 1440 if (yyn == YYFLAG)
1441 goto yyerrpop; 1441 goto yyerrpop;
1442 yyn = -yyn; 1442 yyn = -yyn;
1443 goto yyreduce; 1443 goto yyreduce;
1444 } 1444 }
1445 else if (yyn == 0) 1445 else if (yyn == 0)
1446 goto yyerrpop; 1446 goto yyerrpop;
1447 1447
1448 if (yyn == YYFINAL) 1448 if (yyn == YYFINAL)
1449 YYACCEPT; 1449 YYACCEPT;
1450 1450
1451 YYDPRINTF ((stderr, "Shifting error token, ")); 1451 YYDPRINTF ((stderr, "Shifting error token, "));
1452 1452
1453 *++yyvsp = yylval; 1453 *++yyvsp = yylval;
1454#if YYLSP_NEEDED 1454#if YYLSP_NEEDED
1455 *++yylsp = yylloc; 1455 *++yylsp = yylloc;
1456#endif 1456#endif
1457 1457
1458 yystate = yyn; 1458 yystate = yyn;
1459 goto yynewstate; 1459 goto yynewstate;
1460 1460
1461 1461
1462/*-------------------------------------. 1462/*-------------------------------------.
1463| yyacceptlab -- YYACCEPT comes here. | 1463| yyacceptlab -- YYACCEPT comes here. |
1464`-------------------------------------*/ 1464`-------------------------------------*/
1465yyacceptlab: 1465yyacceptlab:
1466 yyresult = 0; 1466 yyresult = 0;
1467 goto yyreturn; 1467 goto yyreturn;
1468 1468
1469/*-----------------------------------. 1469/*-----------------------------------.
1470| yyabortlab -- YYABORT comes here. | 1470| yyabortlab -- YYABORT comes here. |
1471`-----------------------------------*/ 1471`-----------------------------------*/
1472yyabortlab: 1472yyabortlab:
1473 yyresult = 1; 1473 yyresult = 1;
1474 goto yyreturn; 1474 goto yyreturn;
1475 1475
1476/*---------------------------------------------. 1476/*---------------------------------------------.
1477| yyoverflowab -- parser overflow comes here. | 1477| yyoverflowab -- parser overflow comes here. |
1478`---------------------------------------------*/ 1478`---------------------------------------------*/
1479yyoverflowlab: 1479yyoverflowlab:
1480 yyerror ("parser stack overflow"); 1480 yyerror ("parser stack overflow");
1481 yyresult = 2; 1481 yyresult = 2;
1482 /* Fall through. */ 1482 /* Fall through. */
1483 1483
1484yyreturn: 1484yyreturn:
1485#ifndef yyoverflow 1485#ifndef yyoverflow
1486 if (yyss != yyssa) 1486 if (yyss != yyssa)
1487 YYSTACK_FREE (yyss); 1487 YYSTACK_FREE (yyss);
1488#endif 1488#endif
1489 return yyresult; 1489 return yyresult;
1490} 1490}
1491#line 373 "vcc.y" 1491#line 373 "vcc.y"
1492 1492
1493static int pushVObject(const char *prop) 1493static int pushVObject(const char *prop)
1494 { 1494 {
1495 VObject *newObj; 1495 VObject *newObj;
1496 if (ObjStackTop == MAXLEVEL) 1496 if (ObjStackTop == MAXLEVEL)
1497 return FALSE; 1497 return FALSE;
1498 1498
1499 ObjStack[++ObjStackTop] = curObj; 1499 ObjStack[++ObjStackTop] = curObj;
1500 1500
1501 if (curObj) { 1501 if (curObj) {
1502 newObj = addProp(curObj,prop); 1502 newObj = addProp(curObj,prop);
1503 curObj = newObj; 1503 curObj = newObj;
1504 } 1504 }
1505 else 1505 else
1506 curObj = newVObject(prop); 1506 curObj = newVObject(prop);
1507 1507
1508 return TRUE; 1508 return TRUE;
1509 } 1509 }
1510 1510
1511 1511
1512/* 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. */
1513static VObject* popVObject() 1513static VObject* popVObject()
1514 { 1514 {
1515 VObject *oldObj; 1515 VObject *oldObj;
1516 if (ObjStackTop < 0) { 1516 if (ObjStackTop < 0) {
1517 yyerror("pop on empty Object Stack\n"); 1517 yyerror("pop on empty Object Stack\n");
1518 return 0; 1518 return 0;
1519 } 1519 }
1520 oldObj = curObj; 1520 oldObj = curObj;
1521 curObj = ObjStack[ObjStackTop--]; 1521 curObj = ObjStack[ObjStackTop--];
1522 1522
1523 return oldObj; 1523 return oldObj;
1524 } 1524 }
1525 1525
1526 1526
1527static void enterValues(const char *value) 1527static void enterValues(const char *value)
1528 { 1528 {
1529 if (fieldedProp && *fieldedProp) { 1529 if (fieldedProp && *fieldedProp) {
1530 if (value) { 1530 if (value) {
1531 addPropValue(curProp,*fieldedProp,value); 1531 addPropValue(curProp,*fieldedProp,value);
1532 } 1532 }
1533 /* else this field is empty, advance to next field */ 1533 /* else this field is empty, advance to next field */
1534 fieldedProp++; 1534 fieldedProp++;
1535 } 1535 }
1536 else { 1536 else {
1537 if (value) { 1537 if (value) {
1538 char *p1, *p2; 1538 char *p1, *p2;
1539 wchar_t *p3; 1539 wchar_t *p3;
1540 int i; 1540 int i;
1541 1541
1542 /* If the property already has a string value, we append this one, 1542 /* If the property already has a string value, we append this one,
1543 using ';' to separate the values. */ 1543 using ';' to separate the values. */
1544 if (vObjectUStringZValue(curProp)) { 1544 if (vObjectUStringZValue(curProp)) {
1545 p1 = fakeCString(vObjectUStringZValue(curProp)); 1545 p1 = fakeCString(vObjectUStringZValue(curProp));
1546 p2 = malloc((strlen(p1)+strlen(value)+1)); 1546 p2 = malloc((strlen(p1)+strlen(value)+1));
1547 strcpy(p2, p1); 1547 strcpy(p2, p1);
1548 deleteStr(p1); 1548 deleteStr(p1);
1549 1549
1550 i = strlen(p2); 1550 i = strlen(p2);
1551 p2[i] = ';'; 1551 p2[i] = ';';
1552 p2[i+1] = '\0'; 1552 p2[i+1] = '\0';
1553 p2 = strcat(p2, value); 1553 p2 = strcat(p2, value);
1554 p3 = (wchar_t *) vObjectUStringZValue(curProp); 1554 p3 = (wchar_t *) vObjectUStringZValue(curProp);
1555 free(p3); 1555 free(p3);
1556 setVObjectUStringZValue_(curProp,fakeUnicode(p2,0)); 1556 setVObjectUStringZValue_(curProp,fakeUnicode(p2,0));
1557 deleteStr(p2); 1557 deleteStr(p2);
1558 } else { 1558 } else {
1559 setVObjectUStringZValue_(curProp,fakeUnicode(value,0)); 1559 setVObjectUStringZValue_(curProp,fakeUnicode(value,0));
1560 } 1560 }
1561 } 1561 }
1562 } 1562 }
1563 deleteStr(value); 1563 deleteStr(value);
1564 } 1564 }
1565 1565
1566static void enterProps(const char *s) 1566static void enterProps(const char *s)
1567 { 1567 {
1568 curProp = addGroup(curObj,s); 1568 curProp = addGroup(curObj,s);
1569 deleteStr(s); 1569 deleteStr(s);
1570 } 1570 }
1571 1571
1572static void enterAttr(const char *s1, const char *s2) 1572static void enterAttr(const char *s1, const char *s2)
1573 { 1573 {
1574 const char *p1, *p2; 1574 const char *p1, *p2;
1575 p1 = lookupProp_(s1); 1575 p1 = lookupProp_(s1);
1576 if (s2) { 1576 if (s2) {
1577 VObject *a; 1577 VObject *a;
1578 p2 = lookupProp_(s2); 1578 p2 = lookupProp_(s2);
1579 a = addProp(curProp,p1); 1579 a = addProp(curProp,p1);
1580 setVObjectStringZValue(a,p2); 1580 setVObjectStringZValue(a,p2);
1581 } 1581 }
1582 else 1582 else
1583 addProp(curProp,p1); 1583 addProp(curProp,p1);
1584 if (stricmp(p1,VCBase64Prop) == 0 || (s2 && stricmp(p2,VCBase64Prop)==0)) 1584 if (stricmp(p1,VCBase64Prop) == 0 || (s2 && stricmp(p2,VCBase64Prop)==0))
1585 lexPushMode(L_BASE64); 1585 lexPushMode(L_BASE64);
1586 else if (stricmp(p1,VCQuotedPrintableProp) == 0 1586 else if (stricmp(p1,VCQuotedPrintableProp) == 0
1587 || (s2 && stricmp(p2,VCQuotedPrintableProp)==0)) 1587 || (s2 && stricmp(p2,VCQuotedPrintableProp)==0))
1588 lexPushMode(L_QUOTED_PRINTABLE); 1588 lexPushMode(L_QUOTED_PRINTABLE);
1589 deleteStr(s1); deleteStr(s2); 1589 deleteStr(s1); deleteStr(s2);
1590 } 1590 }
1591 1591
1592 1592
1593#define MAX_LEX_LOOKAHEAD_0 32 1593#define MAX_LEX_LOOKAHEAD_0 32
1594#define MAX_LEX_LOOKAHEAD 64 1594#define MAX_LEX_LOOKAHEAD 64
1595#define MAX_LEX_MODE_STACK_SIZE 10 1595#define MAX_LEX_MODE_STACK_SIZE 10
1596#define LEXMODE() (lexBuf.lexModeStack[lexBuf.lexModeStackTop]) 1596#define LEXMODE() (lexBuf.lexModeStack[lexBuf.lexModeStackTop])
1597 1597
1598struct LexBuf { 1598struct LexBuf {
1599 /* input */ 1599 /* input */
1600#ifdef INCLUDEMFC 1600#ifdef INCLUDEMFC
1601 CFile *inputFile; 1601 CFile *inputFile;
1602#else 1602#else
1603 FILE *inputFile; 1603 FILE *inputFile;
1604#endif 1604#endif
1605 char *inputString; 1605 char *inputString;
1606 unsigned long curPos; 1606 unsigned long curPos;
1607 unsigned long inputLen; 1607 unsigned long inputLen;
1608 /* lookahead buffer */ 1608 /* lookahead buffer */
1609 /* -- lookahead buffer is short instead of char so that EOF 1609 /* -- lookahead buffer is short instead of char so that EOF
1610 / can be represented correctly. 1610 / can be represented correctly.
1611 */ 1611 */
1612 unsigned long len; 1612 unsigned long len;
1613 short buf[MAX_LEX_LOOKAHEAD]; 1613 short buf[MAX_LEX_LOOKAHEAD];
1614 unsigned long getPtr; 1614 unsigned long getPtr;
1615 /* context stack */ 1615 /* context stack */
1616 unsigned long lexModeStackTop; 1616 unsigned long lexModeStackTop;
1617 enum LexMode lexModeStack[MAX_LEX_MODE_STACK_SIZE]; 1617 enum LexMode lexModeStack[MAX_LEX_MODE_STACK_SIZE];
1618 /* token buffer */ 1618 /* token buffer */
1619 unsigned long maxToken; 1619 unsigned long maxToken;
1620 char *strs; 1620 char *strs;
1621 unsigned long strsLen; 1621 unsigned long strsLen;
1622 } lexBuf; 1622 } lexBuf;
1623 1623
1624static void lexPushMode(enum LexMode mode) 1624static void lexPushMode(enum LexMode mode)
1625 { 1625 {
1626 if (lexBuf.lexModeStackTop == (MAX_LEX_MODE_STACK_SIZE-1)) 1626 if (lexBuf.lexModeStackTop == (MAX_LEX_MODE_STACK_SIZE-1))
1627 yyerror("lexical context stack overflow"); 1627 yyerror("lexical context stack overflow");
1628 else { 1628 else {
1629 lexBuf.lexModeStack[++lexBuf.lexModeStackTop] = mode; 1629 lexBuf.lexModeStack[++lexBuf.lexModeStackTop] = mode;
1630 } 1630 }
1631 } 1631 }
1632 1632
1633static void lexPopMode(int top) 1633static void lexPopMode(int top)
1634 { 1634 {
1635 /* special case of pop for ease of error recovery -- this 1635 /* special case of pop for ease of error recovery -- this
1636 version will never underflow */ 1636 version will never underflow */
1637 if (top) 1637 if (top)
1638 lexBuf.lexModeStackTop = 0; 1638 lexBuf.lexModeStackTop = 0;
1639 else 1639 else
1640 if (lexBuf.lexModeStackTop > 0) lexBuf.lexModeStackTop--; 1640 if (lexBuf.lexModeStackTop > 0) lexBuf.lexModeStackTop--;
1641 } 1641 }
1642 1642
1643static int lexWithinMode(enum LexMode mode) { 1643static int lexWithinMode(enum LexMode mode) {
1644 unsigned long i; 1644 unsigned long i;
1645 for (i=0;i<lexBuf.lexModeStackTop;i++) 1645 for (i=0;i<lexBuf.lexModeStackTop;i++)
1646 if (mode == lexBuf.lexModeStack[i]) return 1; 1646 if (mode == lexBuf.lexModeStack[i]) return 1;
1647 return 0; 1647 return 0;
1648 } 1648 }
1649 1649
1650static char lexGetc_() 1650static char lexGetc_()
1651 { 1651 {
1652 /* get next char from input, no buffering. */ 1652 /* get next char from input, no buffering. */
1653 if (lexBuf.curPos == lexBuf.inputLen) 1653 if (lexBuf.curPos == lexBuf.inputLen)
1654 return EOF; 1654 return EOF;
1655 else if (lexBuf.inputString) 1655 else if (lexBuf.inputString)
1656 return *(lexBuf.inputString + lexBuf.curPos++); 1656 return *(lexBuf.inputString + lexBuf.curPos++);
1657 else { 1657 else {
1658#ifdef INCLUDEMFC 1658#ifdef INCLUDEMFC
1659 char result; 1659 char result;
1660 return lexBuf.inputFile->Read(&result, 1) == 1 ? result : EOF; 1660 return lexBuf.inputFile->Read(&result, 1) == 1 ? result : EOF;
1661#else 1661#else
1662 return fgetc(lexBuf.inputFile); 1662 return fgetc(lexBuf.inputFile);
1663#endif 1663#endif
1664 } 1664 }
1665 } 1665 }
1666 1666
1667static int lexGeta() 1667static int lexGeta()
1668 { 1668 {
1669 ++lexBuf.len; 1669 ++lexBuf.len;
1670 return (lexBuf.buf[lexBuf.getPtr] = lexGetc_()); 1670 return (lexBuf.buf[lexBuf.getPtr] = lexGetc_());
1671 } 1671 }
1672 1672
1673static int lexGeta_(int i) 1673static int lexGeta_(int i)
1674 { 1674 {
1675 ++lexBuf.len; 1675 ++lexBuf.len;
1676 return (lexBuf.buf[(lexBuf.getPtr+i)%MAX_LEX_LOOKAHEAD] = lexGetc_()); 1676 return (lexBuf.buf[(lexBuf.getPtr+i)%MAX_LEX_LOOKAHEAD] = lexGetc_());
1677 } 1677 }
1678 1678
1679static void lexSkipLookahead() { 1679static void lexSkipLookahead() {
1680 if (lexBuf.len > 0 && lexBuf.buf[lexBuf.getPtr]!=EOF) { 1680 if (lexBuf.len > 0 && lexBuf.buf[lexBuf.getPtr]!=EOF) {
1681 /* don't skip EOF. */ 1681 /* don't skip EOF. */
1682 lexBuf.getPtr = (lexBuf.getPtr + 1) % MAX_LEX_LOOKAHEAD; 1682 lexBuf.getPtr = (lexBuf.getPtr + 1) % MAX_LEX_LOOKAHEAD;
1683 lexBuf.len--; 1683 lexBuf.len--;
1684 } 1684 }
1685 } 1685 }
1686 1686
1687static int lexLookahead() { 1687static int lexLookahead() {
1688 int c = (lexBuf.len)? 1688 int c = (lexBuf.len)?
1689 lexBuf.buf[lexBuf.getPtr]: 1689 lexBuf.buf[lexBuf.getPtr]:
1690 lexGeta(); 1690 lexGeta();
1691 /* do the \r\n -> \n or \r -> \n translation here */ 1691 /* do the \r\n -> \n or \r -> \n translation here */
1692 if (c == '\r') { 1692 if (c == '\r') {
1693 int a = (lexBuf.len>1)? 1693 int a = (lexBuf.len>1)?
1694 lexBuf.buf[(lexBuf.getPtr+1)%MAX_LEX_LOOKAHEAD]: 1694 lexBuf.buf[(lexBuf.getPtr+1)%MAX_LEX_LOOKAHEAD]:
1695 lexGeta_(1); 1695 lexGeta_(1);
1696 if (a == '\n') { 1696 if (a == '\n') {
1697 lexSkipLookahead(); 1697 lexSkipLookahead();
1698 } 1698 }
1699 lexBuf.buf[lexBuf.getPtr] = c = '\n'; 1699 lexBuf.buf[lexBuf.getPtr] = c = '\n';
1700 } 1700 }
1701 else if (c == '\n') { 1701 else if (c == '\n') {
1702 int a = (lexBuf.len>1)? 1702 int a = (lexBuf.len>1)?
1703 lexBuf.buf[lexBuf.getPtr+1]: 1703 lexBuf.buf[lexBuf.getPtr+1]:
1704 lexGeta_(1); 1704 lexGeta_(1);
1705 if (a == '\r') { 1705 if (a == '\r') {
1706 lexSkipLookahead(); 1706 lexSkipLookahead();
1707 } 1707 }
1708 lexBuf.buf[lexBuf.getPtr] = '\n'; 1708 lexBuf.buf[lexBuf.getPtr] = '\n';
1709 } 1709 }
1710 return c; 1710 return c;
1711 } 1711 }
1712 1712
1713static int lexGetc() { 1713static int lexGetc() {
1714 int c = lexLookahead(); 1714 int c = lexLookahead();
1715 if (lexBuf.len > 0 && lexBuf.buf[lexBuf.getPtr]!=EOF) { 1715 if (lexBuf.len > 0 && lexBuf.buf[lexBuf.getPtr]!=EOF) {
1716 /* EOF will remain in lookahead buffer */ 1716 /* EOF will remain in lookahead buffer */
1717 lexBuf.getPtr = (lexBuf.getPtr + 1) % MAX_LEX_LOOKAHEAD; 1717 lexBuf.getPtr = (lexBuf.getPtr + 1) % MAX_LEX_LOOKAHEAD;
1718 lexBuf.len--; 1718 lexBuf.len--;
1719 } 1719 }
1720 return c; 1720 return c;
1721 } 1721 }
1722 1722
1723static void lexSkipLookaheadWord() { 1723static void lexSkipLookaheadWord() {
1724 if (lexBuf.strsLen <= lexBuf.len) { 1724 if (lexBuf.strsLen <= lexBuf.len) {
1725 lexBuf.len -= lexBuf.strsLen; 1725 lexBuf.len -= lexBuf.strsLen;
1726 lexBuf.getPtr = (lexBuf.getPtr + lexBuf.strsLen) % MAX_LEX_LOOKAHEAD; 1726 lexBuf.getPtr = (lexBuf.getPtr + lexBuf.strsLen) % MAX_LEX_LOOKAHEAD;
1727 } 1727 }
1728 } 1728 }
1729 1729
1730static void lexClearToken() 1730static void lexClearToken()
1731 { 1731 {
1732 lexBuf.strsLen = 0; 1732 lexBuf.strsLen = 0;
1733 } 1733 }
1734 1734
1735static void lexAppendc(int c) 1735static void lexAppendc(int c)
1736 { 1736 {
1737 lexBuf.strs[lexBuf.strsLen] = c; 1737 lexBuf.strs[lexBuf.strsLen] = c;
1738 /* append up to zero termination */ 1738 /* append up to zero termination */
1739 if (c == 0) return; 1739 if (c == 0) return;
1740 lexBuf.strsLen++; 1740 lexBuf.strsLen++;
1741 if (lexBuf.strsLen > lexBuf.maxToken) { 1741 if (lexBuf.strsLen > lexBuf.maxToken) {
1742 /* double the token string size */ 1742 /* double the token string size */
1743 lexBuf.maxToken <<= 1; 1743 lexBuf.maxToken <<= 1;
1744 lexBuf.strs = (char*) realloc(lexBuf.strs,(size_t)lexBuf.maxToken); 1744 lexBuf.strs = (char*) realloc(lexBuf.strs,(size_t)lexBuf.maxToken);
1745 } 1745 }
1746 } 1746 }
1747 1747
1748static char* lexStr() { 1748static char* lexStr() {
1749 return dupStr(lexBuf.strs,(size_t)lexBuf.strsLen+1); 1749 return dupStr(lexBuf.strs,(size_t)lexBuf.strsLen+1);
1750 } 1750 }
1751 1751
1752static void lexSkipWhite() { 1752static void lexSkipWhite() {
1753 int c = lexLookahead(); 1753 int c = lexLookahead();
1754 while (c == ' ' || c == '\t') { 1754 while (c == ' ' || c == '\t') {
1755 lexSkipLookahead(); 1755 lexSkipLookahead();
1756 c = lexLookahead(); 1756 c = lexLookahead();
1757 } 1757 }
1758 } 1758 }
1759 1759
1760static char* lexGetWord() { 1760static char* lexGetWord() {
1761 int c; 1761 int c;
1762 lexSkipWhite(); 1762 lexSkipWhite();
1763 lexClearToken(); 1763 lexClearToken();
1764 c = lexLookahead(); 1764 c = lexLookahead();
1765 while (c != EOF && !strchr("\t\n ;:=",c)) { 1765 // LR while (c != EOF && !strchr("\t\n ;:=",c)) {
1766 while (c != EOF && !strchr("\t\n;:=",c)) {
1766 lexAppendc(c); 1767 lexAppendc(c);
1767 lexSkipLookahead(); 1768 lexSkipLookahead();
1768 c = lexLookahead(); 1769 c = lexLookahead();
1769 } 1770 }
1770 lexAppendc(0); 1771 lexAppendc(0);
1771 return lexStr(); 1772 return lexStr();
1772 } 1773 }
1773 1774
1774static void lexPushLookaheadc(int c) { 1775static void lexPushLookaheadc(int c) {
1775 int putptr; 1776 int putptr;
1776 /* can't putback EOF, because it never leaves lookahead buffer */ 1777 /* can't putback EOF, because it never leaves lookahead buffer */
1777 if (c == EOF) return; 1778 if (c == EOF) return;
1778 putptr = (int)lexBuf.getPtr - 1; 1779 putptr = (int)lexBuf.getPtr - 1;
1779 if (putptr < 0) putptr += MAX_LEX_LOOKAHEAD; 1780 if (putptr < 0) putptr += MAX_LEX_LOOKAHEAD;
1780 lexBuf.getPtr = putptr; 1781 lexBuf.getPtr = putptr;
1781 lexBuf.buf[putptr] = c; 1782 lexBuf.buf[putptr] = c;
1782 lexBuf.len += 1; 1783 lexBuf.len += 1;
1783 } 1784 }
1784 1785
1785static char* lexLookaheadWord() { 1786static char* lexLookaheadWord() {
1786 /* this function can lookahead word with max size of MAX_LEX_LOOKAHEAD_0 1787 /* this function can lookahead word with max size of MAX_LEX_LOOKAHEAD_0
1787 / and thing bigger than that will stop the lookahead and return 0; 1788 / and thing bigger than that will stop the lookahead and return 0;
1788 / leading white spaces are not recoverable. 1789 / leading white spaces are not recoverable.
1789 */ 1790 */
1790 int c; 1791 int c;
1791 int len = 0; 1792 int len = 0;
1792 int curgetptr = 0; 1793 int curgetptr = 0;
1793 lexSkipWhite(); 1794 lexSkipWhite();
1794 lexClearToken(); 1795 lexClearToken();
1795 curgetptr = (int)lexBuf.getPtr;/* remember! */ 1796 curgetptr = (int)lexBuf.getPtr;/* remember! */
1796 while (len < (MAX_LEX_LOOKAHEAD_0)) { 1797 while (len < (MAX_LEX_LOOKAHEAD_0)) {
1797 c = lexGetc(); 1798 c = lexGetc();
1798 len++; 1799 len++;
1799 if (c == EOF || strchr("\t\n ;:=", c)) { 1800 if (c == EOF || strchr("\t\n ;:=", c)) {
1800 lexAppendc(0); 1801 lexAppendc(0);
1801 /* restore lookahead buf. */ 1802 /* restore lookahead buf. */
1802 lexBuf.len += len; 1803 lexBuf.len += len;
1803 lexBuf.getPtr = curgetptr; 1804 lexBuf.getPtr = curgetptr;
1804 return lexStr(); 1805 return lexStr();
1805 } 1806 }
1806 else 1807 else
1807 lexAppendc(c); 1808 lexAppendc(c);
1808 } 1809 }
1809 lexBuf.len += len;/* char that has been moved to lookahead buffer */ 1810 lexBuf.len += len;/* char that has been moved to lookahead buffer */
1810 lexBuf.getPtr = curgetptr; 1811 lexBuf.getPtr = curgetptr;
1811 return 0; 1812 return 0;
1812 } 1813 }
1813 1814
1814#ifdef _SUPPORT_LINE_FOLDING 1815#ifdef _SUPPORT_LINE_FOLDING
1815static void handleMoreRFC822LineBreak(int c) { 1816static void handleMoreRFC822LineBreak(int c) {
1816 /* suport RFC 822 line break in cases like 1817 /* suport RFC 822 line break in cases like
1817 *ADR: foo; 1818 *ADR: foo;
1818 * morefoo; 1819 * morefoo;
1819 * more foo; 1820 * more foo;
1820 */ 1821 */
1821 if (c == ';') { 1822 if (c == ';') {
1822 int a; 1823 int a;
1823 lexSkipLookahead(); 1824 lexSkipLookahead();
1824 /* skip white spaces */ 1825 /* skip white spaces */
1825 a = lexLookahead(); 1826 a = lexLookahead();
1826 while (a == ' ' || a == '\t') { 1827 while (a == ' ' || a == '\t') {
1827 lexSkipLookahead(); 1828 lexSkipLookahead();
1828 a = lexLookahead(); 1829 a = lexLookahead();
1829 } 1830 }
1830 if (a == '\n') { 1831 if (a == '\n') {
1831 lexSkipLookahead(); 1832 lexSkipLookahead();
1832 a = lexLookahead(); 1833 a = lexLookahead();
1833 if (a == ' ' || a == '\t') { 1834 if (a == ' ' || a == '\t') {
1834 /* continuation, throw away all the \n and spaces read so 1835 /* continuation, throw away all the \n and spaces read so
1835 * far 1836 * far
1836 */ 1837 */
1837 lexSkipWhite(); 1838 lexSkipWhite();
1838 lexPushLookaheadc(';'); 1839 lexPushLookaheadc(';');
1839 } 1840 }
1840 else { 1841 else {
1841 lexPushLookaheadc('\n'); 1842 lexPushLookaheadc('\n');
1842 lexPushLookaheadc(';'); 1843 lexPushLookaheadc(';');
1843 } 1844 }
1844 } 1845 }
1845 else { 1846 else {
1846 lexPushLookaheadc(';'); 1847 lexPushLookaheadc(';');
1847 } 1848 }
1848 } 1849 }
1849 } 1850 }
1850 1851
1851static char* lexGet1Value() { 1852static char* lexGet1Value() {
1852 int c; 1853 int c;
1853 lexSkipWhite(); 1854 lexSkipWhite();
1854 c = lexLookahead(); 1855 c = lexLookahead();
1855 lexClearToken(); 1856 lexClearToken();
1856 while (c != EOF && c != ';') { 1857 while (c != EOF && c != ';') {
1857 if (c == '\n') { 1858 if (c == '\n') {
1858 int a; 1859 int a;
1859 lexSkipLookahead(); 1860 lexSkipLookahead();
1860 a = lexLookahead(); 1861 a = lexLookahead();
1861 if (a == ' ' || a == '\t') { 1862 if (a == ' ' || a == '\t') {
1862 lexAppendc(' '); 1863 lexAppendc(' ');
1863 lexSkipLookahead(); 1864 lexSkipLookahead();
1864 } 1865 }
1865 else { 1866 else {
1866 lexPushLookaheadc('\n'); 1867 lexPushLookaheadc('\n');
1867 break; 1868 break;
1868 } 1869 }
1869 } 1870 }
1870 else { 1871 else {
1871 lexAppendc(c); 1872 lexAppendc(c);
1872 lexSkipLookahead(); 1873 lexSkipLookahead();
1873 } 1874 }
1874 c = lexLookahead(); 1875 c = lexLookahead();
1875 } 1876 }
1876 lexAppendc(0); 1877 lexAppendc(0);
1877 handleMoreRFC822LineBreak(c); 1878 handleMoreRFC822LineBreak(c);
1878 return c==EOF?0:lexStr(); 1879 return c==EOF?0:lexStr();
1879 } 1880 }
1880#endif 1881#endif
1881 1882
1882 1883
1883static int match_begin_name(int end) { 1884static int match_begin_name(int end) {
1884 char *n = lexLookaheadWord(); 1885 char *n = lexLookaheadWord();
1885 int token = ID; 1886 int token = ID;
1886 if (n) { 1887 if (n) {
1887 if (!stricmp(n,"vcard")) token = end?END_VCARD:BEGIN_VCARD; 1888 if (!stricmp(n,"vcard")) token = end?END_VCARD:BEGIN_VCARD;
1888 else if (!stricmp(n,"vcalendar")) token = end?END_VCAL:BEGIN_VCAL; 1889 else if (!stricmp(n,"vcalendar")) token = end?END_VCAL:BEGIN_VCAL;
1889 else if (!stricmp(n,"vevent")) token = end?END_VEVENT:BEGIN_VEVENT; 1890 else if (!stricmp(n,"vevent")) token = end?END_VEVENT:BEGIN_VEVENT;
1890 else if (!stricmp(n,"vtodo")) token = end?END_VTODO:BEGIN_VTODO; 1891 else if (!stricmp(n,"vtodo")) token = end?END_VTODO:BEGIN_VTODO;
1891 deleteStr(n); 1892 deleteStr(n);
1892 return token; 1893 return token;
1893 } 1894 }
1894 return 0; 1895 return 0;
1895 } 1896 }
1896 1897
1897 1898
1898#ifdef INCLUDEMFC 1899#ifdef INCLUDEMFC
1899void initLex(const char *inputstring, unsigned long inputlen, CFile *inputfile) 1900void initLex(const char *inputstring, unsigned long inputlen, CFile *inputfile)
1900#else 1901#else
1901void initLex(const char *inputstring, unsigned long inputlen, FILE *inputfile) 1902void initLex(const char *inputstring, unsigned long inputlen, FILE *inputfile)
1902#endif 1903#endif
1903 { 1904 {
1904 /* initialize lex mode stack */ 1905 /* initialize lex mode stack */
1905 lexBuf.lexModeStack[lexBuf.lexModeStackTop=0] = L_NORMAL; 1906 lexBuf.lexModeStack[lexBuf.lexModeStackTop=0] = L_NORMAL;
1906 1907
1907 /* iniatialize lex buffer. */ 1908 /* iniatialize lex buffer. */
1908 lexBuf.inputString = (char*) inputstring; 1909 lexBuf.inputString = (char*) inputstring;
1909 lexBuf.inputLen = inputlen; 1910 lexBuf.inputLen = inputlen;
1910 lexBuf.curPos = 0; 1911 lexBuf.curPos = 0;
1911 lexBuf.inputFile = inputfile; 1912 lexBuf.inputFile = inputfile;
1912 1913
1913 lexBuf.len = 0; 1914 lexBuf.len = 0;
1914 lexBuf.getPtr = 0; 1915 lexBuf.getPtr = 0;
1915 1916
1916 lexBuf.maxToken = MAXTOKEN; 1917 lexBuf.maxToken = MAXTOKEN;
1917 lexBuf.strs = (char*)malloc(MAXTOKEN); 1918 lexBuf.strs = (char*)malloc(MAXTOKEN);
1918 lexBuf.strsLen = 0; 1919 lexBuf.strsLen = 0;
1919 1920
1920 } 1921 }
1921 1922
1922static void finiLex() { 1923static void finiLex() {
1923 free(lexBuf.strs); 1924 free(lexBuf.strs);
1924 } 1925 }
1925 1926
1926 1927
1927/* This parses and converts the base64 format for binary encoding into 1928/* This parses and converts the base64 format for binary encoding into
1928 * a decoded buffer (allocated with new). See RFC 1521. 1929 * a decoded buffer (allocated with new). See RFC 1521.
1929 */ 1930 */
1930static char * lexGetDataFromBase64() 1931static char * lexGetDataFromBase64()
1931 { 1932 {
1932 unsigned long bytesLen = 0, bytesMax = 0; 1933 unsigned long bytesLen = 0, bytesMax = 0;
1933 int quadIx = 0, pad = 0; 1934 int quadIx = 0, pad = 0;
1934 unsigned long trip = 0; 1935 unsigned long trip = 0;
1935 unsigned char b; 1936 unsigned char b;
1936 int c; 1937 int c;
1937 unsigned char *bytes = NULL; 1938 unsigned char *bytes = NULL;
1938 unsigned char *oldBytes = NULL; 1939 unsigned char *oldBytes = NULL;
1939 1940
1940 DBG_(("db: lexGetDataFromBase64\n")); 1941 DBG_(("db: lexGetDataFromBase64\n"));
1941 while (1) { 1942 while (1) {
1942 c = lexGetc(); 1943 c = lexGetc();
1943 if (c == '\n') { 1944 if (c == '\n') {
1944 ++mime_lineNum; 1945 ++mime_lineNum;
1945 if (lexLookahead() == '\n') { 1946 if (lexLookahead() == '\n') {
1946 /* a '\n' character by itself means end of data */ 1947 /* a '\n' character by itself means end of data */
1947 break; 1948 break;
1948 } 1949 }
1949 else continue; /* ignore '\n' */ 1950 else continue; /* ignore '\n' */
1950 } 1951 }
1951 else { 1952 else {
1952 if ((c >= 'A') && (c <= 'Z')) 1953 if ((c >= 'A') && (c <= 'Z'))
1953 b = (unsigned char)(c - 'A'); 1954 b = (unsigned char)(c - 'A');
1954 else if ((c >= 'a') && (c <= 'z')) 1955 else if ((c >= 'a') && (c <= 'z'))
1955 b = (unsigned char)(c - 'a') + 26; 1956 b = (unsigned char)(c - 'a') + 26;
1956 else if ((c >= '0') && (c <= '9')) 1957 else if ((c >= '0') && (c <= '9'))
1957 b = (unsigned char)(c - '0') + 52; 1958 b = (unsigned char)(c - '0') + 52;
1958 else if (c == '+') 1959 else if (c == '+')
1959 b = 62; 1960 b = 62;
1960 else if (c == '/') 1961 else if (c == '/')
1961 b = 63; 1962 b = 63;
1962 else if (c == '=') { 1963 else if (c == '=') {
1963 b = 0; 1964 b = 0;
1964 pad++; 1965 pad++;
1965 } else if ((c == ' ') || (c == '\t')) { 1966 } else if ((c == ' ') || (c == '\t')) {
1966 continue; 1967 continue;
1967 } else { /* error condition */ 1968 } else { /* error condition */
1968 if (bytes) free(bytes); 1969 if (bytes) free(bytes);
1969 else if (oldBytes) free(oldBytes); 1970 else if (oldBytes) free(oldBytes);
1970 /* error recovery: skip until 2 adjacent newlines. */ 1971 /* error recovery: skip until 2 adjacent newlines. */
1971 DBG_(("db: invalid character 0x%x '%c'\n", c,c)); 1972 DBG_(("db: invalid character 0x%x '%c'\n", c,c));
1972 if (c != EOF) { 1973 if (c != EOF) {
1973 c = lexGetc(); 1974 c = lexGetc();
1974 while (c != EOF) { 1975 while (c != EOF) {
1975 if (c == '\n' && lexLookahead() == '\n') { 1976 if (c == '\n' && lexLookahead() == '\n') {
1976 ++mime_lineNum; 1977 ++mime_lineNum;
1977 break; 1978 break;
1978 } 1979 }
1979 c = lexGetc(); 1980 c = lexGetc();
1980 } 1981 }
1981 } 1982 }
1982 return NULL; 1983 return NULL;
1983 } 1984 }
1984 trip = (trip << 6) | b; 1985 trip = (trip << 6) | b;
1985 if (++quadIx == 4) { 1986 if (++quadIx == 4) {
1986 unsigned char outBytes[3]; 1987 unsigned char outBytes[3];
1987 int numOut; 1988 int numOut;
1988 int i; 1989 int i;
1989 for (i = 0; i < 3; i++) { 1990 for (i = 0; i < 3; i++) {
1990 outBytes[2-i] = (unsigned char)(trip & 0xFF); 1991 outBytes[2-i] = (unsigned char)(trip & 0xFF);
1991 trip >>= 8; 1992 trip >>= 8;
1992 } 1993 }
1993 numOut = 3 - pad; 1994 numOut = 3 - pad;
1994 if (bytesLen + numOut > bytesMax) { 1995 if (bytesLen + numOut > bytesMax) {
1995 if (!bytes) { 1996 if (!bytes) {
1996 bytesMax = 1024; 1997 bytesMax = 1024;
1997 bytes = (unsigned char*)malloc((size_t)bytesMax); 1998 bytes = (unsigned char*)malloc((size_t)bytesMax);
1998 } 1999 }
1999 else { 2000 else {
2000 bytesMax <<= 2; 2001 bytesMax <<= 2;
2001 oldBytes = bytes; 2002 oldBytes = bytes;
2002 bytes = (unsigned char*)realloc(bytes,(size_t)bytesMax); 2003 bytes = (unsigned char*)realloc(bytes,(size_t)bytesMax);
2003 } 2004 }
2004 if (bytes == 0) { 2005 if (bytes == 0) {
2005 mime_error("out of memory while processing BASE64 data\n"); 2006 mime_error("out of memory while processing BASE64 data\n");
2006 } 2007 }
2007 } 2008 }
2008 if (bytes) { 2009 if (bytes) {
2009 memcpy(bytes + bytesLen, outBytes, numOut); 2010 memcpy(bytes + bytesLen, outBytes, numOut);
2010 bytesLen += numOut; 2011 bytesLen += numOut;
2011 } 2012 }
2012 trip = 0; 2013 trip = 0;
2013 quadIx = 0; 2014 quadIx = 0;
2014 } 2015 }
2015 } 2016 }
2016 } /* while */ 2017 } /* while */
2017 DBG_(("db: bytesLen = %d\n", bytesLen)); 2018 DBG_(("db: bytesLen = %d\n", bytesLen));
2018 /* kludge: all this won't be necessary if we have tree form 2019 /* kludge: all this won't be necessary if we have tree form
2019 representation */ 2020 representation */
2020 if (bytes) { 2021 if (bytes) {
2021 setValueWithSize(curProp,bytes,(unsigned int)bytesLen); 2022 setValueWithSize(curProp,bytes,(unsigned int)bytesLen);
2022 free(bytes); 2023 free(bytes);
2023 } 2024 }
2024 else if (oldBytes) { 2025 else if (oldBytes) {
2025 setValueWithSize(curProp,oldBytes,(unsigned int)bytesLen); 2026 setValueWithSize(curProp,oldBytes,(unsigned int)bytesLen);
2026 free(oldBytes); 2027 free(oldBytes);
2027 } 2028 }
2028 return 0; 2029 return 0;
2029 } 2030 }
2030 2031
2031static int match_begin_end_name(int end) { 2032static int match_begin_end_name(int end) {
2032 int token; 2033 int token;
2033 lexSkipWhite(); 2034 lexSkipWhite();
2034 if (lexLookahead() != ':') return ID; 2035 if (lexLookahead() != ':') return ID;
2035 lexSkipLookahead(); 2036 lexSkipLookahead();
2036 lexSkipWhite(); 2037 lexSkipWhite();
2037 token = match_begin_name(end); 2038 token = match_begin_name(end);
2038 if (token == ID) { 2039 if (token == ID) {
2039 lexPushLookaheadc(':'); 2040 lexPushLookaheadc(':');
2040 DBG_(("db: ID '%s'\n", yylval.str)); 2041 DBG_(("db: ID '%s'\n", yylval.str));
2041 return ID; 2042 return ID;
2042 } 2043 }
2043 else if (token != 0) { 2044 else if (token != 0) {
2044 lexSkipLookaheadWord(); 2045 lexSkipLookaheadWord();
2045 deleteStr(yylval.str); 2046 deleteStr(yylval.str);
2046 DBG_(("db: begin/end %d\n", token)); 2047 DBG_(("db: begin/end %d\n", token));
2047 return token; 2048 return token;
2048 } 2049 }
2049 return 0; 2050 return 0;
2050 } 2051 }
2051 2052
2052static char* lexGetQuotedPrintable() 2053static char* lexGetQuotedPrintable()
2053 { 2054 {
2054 char cur; 2055 char cur;
2055 2056
2056 lexClearToken(); 2057 lexClearToken();
2057 do { 2058 do {
2058 cur = lexGetc(); 2059 cur = lexGetc();
2059 switch (cur) { 2060 switch (cur) {
2060 case '=': { 2061 case '=': {
2061 int c = 0; 2062 int c = 0;
2062 int next[2]; 2063 int next[2];
2063 int i; 2064 int i;
2064 for (i = 0; i < 2; i++) { 2065 for (i = 0; i < 2; i++) {
2065 next[i] = lexGetc(); 2066 next[i] = lexGetc();
2066 if (next[i] >= '0' && next[i] <= '9') 2067 if (next[i] >= '0' && next[i] <= '9')
2067 c = c * 16 + next[i] - '0'; 2068 c = c * 16 + next[i] - '0';
2068 else if (next[i] >= 'A' && next[i] <= 'F') 2069 else if (next[i] >= 'A' && next[i] <= 'F')
2069 c = c * 16 + next[i] - 'A' + 10; 2070 c = c * 16 + next[i] - 'A' + 10;
2070 else 2071 else
2071 break; 2072 break;
2072 } 2073 }
2073 if (i == 0) { 2074 if (i == 0) {
2074 /* single '=' follow by LINESEP is continuation sign? */ 2075 /* single '=' follow by LINESEP is continuation sign? */
2075 if (next[0] == '\n') { 2076 if (next[0] == '\n') {
2076 ++mime_lineNum; 2077 ++mime_lineNum;
2077 } 2078 }
2078 else { 2079 else {
2079 lexPushLookaheadc('='); 2080 lexPushLookaheadc('=');
2080 goto EndString; 2081 goto EndString;
2081 } 2082 }
2082 } 2083 }
2083 else if (i == 1) { 2084 else if (i == 1) {
2084 lexPushLookaheadc(next[1]); 2085 lexPushLookaheadc(next[1]);
2085 lexPushLookaheadc(next[0]); 2086 lexPushLookaheadc(next[0]);
2086 lexAppendc('='); 2087 lexAppendc('=');
2087 } else { 2088 } else {
2088 lexAppendc(c); 2089 lexAppendc(c);
2089 } 2090 }
2090 break; 2091 break;
2091 } /* '=' */ 2092 } /* '=' */
2092 case '\n': { 2093 case '\n': {
2093 lexPushLookaheadc('\n'); 2094 lexPushLookaheadc('\n');
2094 goto EndString; 2095 goto EndString;
2095 } 2096 }
2096 case (char)EOF: 2097 case (char)EOF:
2097 break; 2098 break;
2098 default: 2099 default:
2099 lexAppendc(cur); 2100 lexAppendc(cur);
2100 break; 2101 break;
2101 } /* switch */ 2102 } /* switch */
2102 } while (cur != (char)EOF); 2103 } while (cur != (char)EOF);
2103 2104
2104EndString: 2105EndString:
2105 lexAppendc(0); 2106 lexAppendc(0);
2106 return lexStr(); 2107 return lexStr();
2107 } /* LexQuotedPrintable */ 2108 } /* LexQuotedPrintable */
2108 2109
2109int yylex() { 2110int yylex() {
2110 2111
2111 int lexmode = LEXMODE(); 2112 int lexmode = LEXMODE();
2112 if (lexmode == L_VALUES) { 2113 if (lexmode == L_VALUES) {
2113 int c = lexGetc(); 2114 int c = lexGetc();
2114 if (c == ';') { 2115 if (c == ';') {
2115 DBG_(("db: SEMICOLON\n")); 2116 DBG_(("db: SEMICOLON\n"));
2116 lexPushLookaheadc(c); 2117 lexPushLookaheadc(c);
2117#ifdef _SUPPORT_LINE_FOLDING 2118#ifdef _SUPPORT_LINE_FOLDING
2118 handleMoreRFC822LineBreak(c); 2119 handleMoreRFC822LineBreak(c);
2119#endif 2120#endif
2120 lexSkipLookahead(); 2121 lexSkipLookahead();
2121 return SEMICOLON; 2122 return SEMICOLON;
2122 } 2123 }
2123 else if (strchr("\n",c)) { 2124 else if (strchr("\n",c)) {
2124 ++mime_lineNum; 2125 ++mime_lineNum;
2125 /* consume all line separator(s) adjacent to each other */ 2126 /* consume all line separator(s) adjacent to each other */
2126 c = lexLookahead(); 2127 c = lexLookahead();
2127 while (strchr("\n",c)) { 2128 while (strchr("\n",c)) {
2128 lexSkipLookahead(); 2129 lexSkipLookahead();
2129 c = lexLookahead(); 2130 c = lexLookahead();
2130 ++mime_lineNum; 2131 ++mime_lineNum;
2131 } 2132 }
2132 DBG_(("db: LINESEP\n")); 2133 DBG_(("db: LINESEP\n"));
2133 return LINESEP; 2134 return LINESEP;
2134 } 2135 }
2135 else { 2136 else {
2136 char *p = 0; 2137 char *p = 0;
2137 lexPushLookaheadc(c); 2138 lexPushLookaheadc(c);
2138 if (lexWithinMode(L_BASE64)) { 2139 if (lexWithinMode(L_BASE64)) {
2139 /* get each char and convert to bin on the fly... */ 2140 /* get each char and convert to bin on the fly... */
2140 p = lexGetDataFromBase64(); 2141 p = lexGetDataFromBase64();
2141 yylval.str = p; 2142 yylval.str = p;
2142 return STRING; 2143 return STRING;
2143 } 2144 }
2144 else if (lexWithinMode(L_QUOTED_PRINTABLE)) { 2145 else if (lexWithinMode(L_QUOTED_PRINTABLE)) {
2145 p = lexGetQuotedPrintable(); 2146 p = lexGetQuotedPrintable();
2146 } 2147 }
2147 else { 2148 else {
2148#ifdef _SUPPORT_LINE_FOLDING 2149#ifdef _SUPPORT_LINE_FOLDING
2149 p = lexGet1Value(); 2150 p = lexGet1Value();
2150#else 2151#else
2151 p = lexGetStrUntil(";\n"); 2152 p = lexGetStrUntil(";\n");
2152#endif 2153#endif
2153 } 2154 }
2154 if (p) { 2155 if (p) {
2155 DBG_(("db: STRING: '%s'\n", p)); 2156 DBG_(("db: STRING: '%s'\n", p));
2156 yylval.str = p; 2157 yylval.str = p;
2157 return STRING; 2158 return STRING;
2158 } 2159 }
2159 else return 0; 2160 else return 0;
2160 } 2161 }
2161 } 2162 }
2162 else { 2163 else {
2163 /* normal mode */ 2164 /* normal mode */
2164 while (1) { 2165 while (1) {
2165 int c = lexGetc(); 2166 int c = lexGetc();
2166 switch(c) { 2167 switch(c) {
2167 case ':': { 2168 case ':': {
2168 /* consume all line separator(s) adjacent to each other */ 2169 /* consume all line separator(s) adjacent to each other */
2169 /* ignoring linesep immediately after colon. */ 2170 /* ignoring linesep immediately after colon. */
2170 /* c = lexLookahead(); 2171 /* c = lexLookahead();
2171 while (strchr("\n",c)) { 2172 while (strchr("\n",c)) {
2172 lexSkipLookahead(); 2173 lexSkipLookahead();
2173 c = lexLookahead(); 2174 c = lexLookahead();
2174 ++mime_lineNum; 2175 ++mime_lineNum;
2175 }*/ 2176 }*/
2176 DBG_(("db: COLON\n")); 2177 DBG_(("db: COLON\n"));
2177 return COLON; 2178 return COLON;
2178 } 2179 }
2179 case ';': 2180 case ';':
2180 DBG_(("db: SEMICOLON\n")); 2181 DBG_(("db: SEMICOLON\n"));
2181 return SEMICOLON; 2182 return SEMICOLON;
2182 case '=': 2183 case '=':
2183 DBG_(("db: EQ\n")); 2184 DBG_(("db: EQ\n"));
2184 return EQ; 2185 return EQ;
2185 /* ignore whitespace in this mode */ 2186 /* ignore whitespace in this mode */
2186 case '\t': 2187 case '\t':
2187 case ' ': continue; 2188 case ' ': continue;
2188 case '\n': { 2189 case '\n': {
2189 ++mime_lineNum; 2190 ++mime_lineNum;
2190 continue; 2191 continue;
2191 } 2192 }
2192 case EOF: return 0; 2193 case EOF: return 0;
2193 break; 2194 break;
2194 default: { 2195 default: {
2195 lexPushLookaheadc(c); 2196 lexPushLookaheadc(c);
2196 if (isalpha(c)) { 2197 if (isalpha(c)) {
2197 char *t = lexGetWord(); 2198 char *t = lexGetWord();
2198 yylval.str = t; 2199 yylval.str = t;
2199 if (!stricmp(t, "begin")) { 2200 if (!stricmp(t, "begin")) {
2200 return match_begin_end_name(0); 2201 return match_begin_end_name(0);
2201 } 2202 }
2202 else if (!stricmp(t,"end")) { 2203 else if (!stricmp(t,"end")) {
2203 return match_begin_end_name(1); 2204 return match_begin_end_name(1);
2204 } 2205 }
2205 else { 2206 else {
2206 DBG_(("db: ID '%s'\n", t)); 2207 DBG_(("db: ID '%s'\n", t));
2207 return ID; 2208 return ID;
2208 } 2209 }
2209 } 2210 }
2210 else { 2211 else {
2211 /* unknow token */ 2212 /* unknow token */
2212 return 0; 2213 return 0;
2213 } 2214 }
2214 break; 2215 break;
2215 } 2216 }
2216 } 2217 }
2217 } 2218 }
2218 } 2219 }
2219 return 0; 2220 return 0;
2220 } 2221 }
2221 2222
2222 2223
2223/***************************************************************************/ 2224/***************************************************************************/
2224 /*** Public Functions ****/ 2225 /*** Public Functions ****/
2225/***************************************************************************/ 2226/***************************************************************************/
2226 2227
2227static VObject* Parse_MIMEHelper() 2228static VObject* Parse_MIMEHelper()
2228 { 2229 {
2229 ObjStackTop = -1; 2230 ObjStackTop = -1;
2230 mime_numErrors = 0; 2231 mime_numErrors = 0;
2231 mime_lineNum = 1; 2232 mime_lineNum = 1;
2232 vObjList = 0; 2233 vObjList = 0;
2233 curObj = 0; 2234 curObj = 0;
2234 2235
2235 if (yyparse() != 0) 2236 if (yyparse() != 0)
2236 return 0; 2237 return 0;
2237 2238
2238 finiLex(); 2239 finiLex();
2239 return vObjList; 2240 return vObjList;
2240 } 2241 }
2241 2242
2242DLLEXPORT(VObject*) Parse_MIME(const char *input, unsigned long len) 2243DLLEXPORT(VObject*) Parse_MIME(const char *input, unsigned long len)
2243 { 2244 {
2244 initLex(input, len, 0); 2245 initLex(input, len, 0);
2245 return Parse_MIMEHelper(); 2246 return Parse_MIMEHelper();
2246 } 2247 }
2247 2248
2248 2249
2249#if INCLUDEMFC 2250#if INCLUDEMFC
2250 2251
2251DLLEXPORT(VObject*) Parse_MIME_FromFile(CFile *file) 2252DLLEXPORT(VObject*) Parse_MIME_FromFile(CFile *file)
2252 { 2253 {
2253 unsigned long startPos; 2254 unsigned long startPos;
2254 VObject *result; 2255 VObject *result;
2255 2256
2256 initLex(0,-1,file); 2257 initLex(0,-1,file);
2257 startPos = file->GetPosition(); 2258 startPos = file->GetPosition();
2258 if (!(result = Parse_MIMEHelper())) 2259 if (!(result = Parse_MIMEHelper()))
2259 file->Seek(startPos, CFile::begin); 2260 file->Seek(startPos, CFile::begin);
2260 return result; 2261 return result;
2261 } 2262 }
2262 2263
2263#else 2264#else
2264 2265
2265VObject* Parse_MIME_FromFile(FILE *file) 2266VObject* Parse_MIME_FromFile(FILE *file)
2266 { 2267 {
2267 VObject *result; 2268 VObject *result;
2268 long startPos; 2269 long startPos;
2269 2270
2270 initLex(0,(unsigned long)-1,file); 2271 initLex(0,(unsigned long)-1,file);
2271 startPos = ftell(file); 2272 startPos = ftell(file);
2272 if (!(result = Parse_MIMEHelper())) { 2273 if (!(result = Parse_MIMEHelper())) {
2273 fseek(file,startPos,SEEK_SET); 2274 fseek(file,startPos,SEEK_SET);
2274 } 2275 }
2275 return result; 2276 return result;
2276 } 2277 }
2277 2278