summaryrefslogtreecommitdiff
authorzecke <zecke>2002-10-18 14:09:14 (UTC)
committer zecke <zecke>2002-10-18 14:09:14 (UTC)
commit461113126af82cd6343eedab36ecabb4253780ee (patch) (unidiff)
tree3176b63dd7f99c58138f237805c88db334fd4a38
parenta574a09dd7b24091a4d2093c8b046ccd32e78d63 (diff)
downloadopie-461113126af82cd6343eedab36ecabb4253780ee.zip
opie-461113126af82cd6343eedab36ecabb4253780ee.tar.gz
opie-461113126af82cd6343eedab36ecabb4253780ee.tar.bz2
Add a small quirk mode... for testing
Fix parsing of due Date We can not rely that HasDate is past the dates.. do the final QDate generation just before adding the OTodo
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libopie/pim/otodoaccessxml.cpp13
-rw-r--r--libopie2/opiepim/backend/otodoaccessxml.cpp13
2 files changed, 16 insertions, 10 deletions
diff --git a/libopie/pim/otodoaccessxml.cpp b/libopie/pim/otodoaccessxml.cpp
index 7a55c67..385fd27 100644
--- a/libopie/pim/otodoaccessxml.cpp
+++ b/libopie/pim/otodoaccessxml.cpp
@@ -23,193 +23,201 @@ OTodoAccessXML::~OTodoAccessXML() {
23} 23}
24bool OTodoAccessXML::load() { 24bool OTodoAccessXML::load() {
25 m_opened = true; 25 m_opened = true;
26 m_changed = false; 26 m_changed = false;
27 /* initialize dict */ 27 /* initialize dict */
28 /* 28 /*
29 * UPDATE dict if you change anything!!! 29 * UPDATE dict if you change anything!!!
30 */ 30 */
31 QAsciiDict<int> dict(15); 31 QAsciiDict<int> dict(15);
32 dict.setAutoDelete( TRUE ); 32 dict.setAutoDelete( TRUE );
33 dict.insert("Categories" , new int(OTodo::Category) ); 33 dict.insert("Categories" , new int(OTodo::Category) );
34 dict.insert("Uid" , new int(OTodo::Uid) ); 34 dict.insert("Uid" , new int(OTodo::Uid) );
35 dict.insert("HasDate" , new int(OTodo::HasDate) ); 35 dict.insert("HasDate" , new int(OTodo::HasDate) );
36 dict.insert("Completed" , new int(OTodo::Completed) ); 36 dict.insert("Completed" , new int(OTodo::Completed) );
37 dict.insert("Description" , new int(OTodo::Description) ); 37 dict.insert("Description" , new int(OTodo::Description) );
38 dict.insert("Summary" , new int(OTodo::Summary) ); 38 dict.insert("Summary" , new int(OTodo::Summary) );
39 dict.insert("Priority" , new int(OTodo::Priority) ); 39 dict.insert("Priority" , new int(OTodo::Priority) );
40 dict.insert("DateDay" , new int(OTodo::DateDay) ); 40 dict.insert("DateDay" , new int(OTodo::DateDay) );
41 dict.insert("DateMonth" , new int(OTodo::DateMonth) ); 41 dict.insert("DateMonth" , new int(OTodo::DateMonth) );
42 dict.insert("DateYear" , new int(OTodo::DateYear) ); 42 dict.insert("DateYear" , new int(OTodo::DateYear) );
43 dict.insert("Progress" , new int(OTodo::Progress) ); 43 dict.insert("Progress" , new int(OTodo::Progress) );
44 dict.insert("Completed", new int(OTodo::Completed) ); 44 dict.insert("Completed", new int(OTodo::Completed) );
45 dict.insert("CrossReference", new int(OTodo::CrossReference) ); 45 dict.insert("CrossReference", new int(OTodo::CrossReference) );
46 dict.insert("HasAlarmDateTime",new int(OTodo::HasAlarmDateTime) ); 46 dict.insert("HasAlarmDateTime",new int(OTodo::HasAlarmDateTime) );
47 dict.insert("AlarmDateTime", new int(OTodo::AlarmDateTime) ); 47 dict.insert("AlarmDateTime", new int(OTodo::AlarmDateTime) );
48 48
49 // here the custom XML parser from TT it's GPL 49 // here the custom XML parser from TT it's GPL
50 // but we want to push that to TT..... 50 // but we want to push that to TT.....
51 QFile f(m_file ); 51 QFile f(m_file );
52 if (!f.open(IO_ReadOnly) ) 52 if (!f.open(IO_ReadOnly) )
53 return false; 53 return false;
54 54
55 QByteArray ba = f.readAll(); 55 QByteArray ba = f.readAll();
56 f.close(); 56 f.close();
57 char* dt = ba.data(); 57 char* dt = ba.data();
58 int len = ba.size(); 58 int len = ba.size();
59 int i = 0; 59 int i = 0;
60 char *point; 60 char *point;
61 const char* collectionString = "<Task "; 61 const char* collectionString = "<Task ";
62 while ( dt+i != 0 && ( point = strstr( dt+i, collectionString ) ) != 0l ) { 62 while ( dt+i != 0 && ( point = strstr( dt+i, collectionString ) ) != 0l ) {
63 i = point -dt; 63 i = point -dt;
64 i+= strlen(collectionString); 64 i+= strlen(collectionString);
65 OTodo ev; 65 OTodo ev;
66 m_year = m_month = m_day = 0; 66 m_year = m_month = m_day = 0;
67 67
68 while ( TRUE ) { 68 while ( TRUE ) {
69 while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) 69 while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') )
70 ++i; 70 ++i;
71 if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) 71 if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') )
72 break; 72 break;
73 73
74 // we have another attribute, read it. 74 // we have another attribute, read it.
75 int j = i; 75 int j = i;
76 while ( j < len && dt[j] != '=' ) 76 while ( j < len && dt[j] != '=' )
77 ++j; 77 ++j;
78 QCString attr( dt+i, j-i+1); 78 QCString attr( dt+i, j-i+1);
79 79
80 i = ++j; // skip = 80 i = ++j; // skip =
81 81
82 // find the start of quotes 82 // find the start of quotes
83 while ( i < len && dt[i] != '"' ) 83 while ( i < len && dt[i] != '"' )
84 ++i; 84 ++i;
85 j = ++i; 85 j = ++i;
86 86
87 bool haveUtf = FALSE; 87 bool haveUtf = FALSE;
88 bool haveEnt = FALSE; 88 bool haveEnt = FALSE;
89 while ( j < len && dt[j] != '"' ) { 89 while ( j < len && dt[j] != '"' ) {
90 if ( ((unsigned char)dt[j]) > 0x7f ) 90 if ( ((unsigned char)dt[j]) > 0x7f )
91 haveUtf = TRUE; 91 haveUtf = TRUE;
92 if ( dt[j] == '&' ) 92 if ( dt[j] == '&' )
93 haveEnt = TRUE; 93 haveEnt = TRUE;
94 ++j; 94 ++j;
95 } 95 }
96 if ( i == j ) { 96 if ( i == j ) {
97 // empty value 97 // empty value
98 i = j + 1; 98 i = j + 1;
99 continue; 99 continue;
100 } 100 }
101 101
102 QCString value( dt+i, j-i+1 ); 102 QCString value( dt+i, j-i+1 );
103 i = j + 1; 103 i = j + 1;
104 104
105 QString str = (haveUtf ? QString::fromUtf8( value ) 105 QString str = (haveUtf ? QString::fromUtf8( value )
106 : QString::fromLatin1( value ) ); 106 : QString::fromLatin1( value ) );
107 if ( haveEnt ) 107 if ( haveEnt )
108 str = Qtopia::plainString( str ); 108 str = Qtopia::plainString( str );
109 109
110 /* 110 /*
111 * add key + value 111 * add key + value
112 */ 112 */
113 todo( &dict, ev, attr, str ); 113 todo( &dict, ev, attr, str );
114 114
115 } 115 }
116 /* 116 /*
117 * now add it 117 * now add it
118 */ 118 */
119 if (m_events.contains( ev.uid() ) || ev.uid() == 0) {
120 ev.setUid( 1 );
121 m_changed = true;
122 }
123 if ( ev.hasDueDate() ) {
124 ev.setDueDate( QDate(m_year, m_month, m_day) );
125 }
119 m_events.insert(ev.uid(), ev ); 126 m_events.insert(ev.uid(), ev );
127 m_year = m_month = m_day = -1;
120 } 128 }
121 129
122 qWarning("counts %d records loaded!", m_events.count() ); 130 qWarning("counts %d records loaded!", m_events.count() );
123 return true; 131 return true;
124} 132}
125bool OTodoAccessXML::reload() { 133bool OTodoAccessXML::reload() {
126 return load(); 134 return load();
127} 135}
128bool OTodoAccessXML::save() { 136bool OTodoAccessXML::save() {
129// qWarning("saving"); 137// qWarning("saving");
130 if (!m_opened || !m_changed ) { 138 if (!m_opened || !m_changed ) {
131// qWarning("not saving"); 139// qWarning("not saving");
132 return true; 140 return true;
133 } 141 }
134 QString strNewFile = m_file + ".new"; 142 QString strNewFile = m_file + ".new";
135 QFile f( strNewFile ); 143 QFile f( strNewFile );
136 if (!f.open( IO_WriteOnly|IO_Raw ) ) 144 if (!f.open( IO_WriteOnly|IO_Raw ) )
137 return false; 145 return false;
138 146
139 int written; 147 int written;
140 QString out; 148 QString out;
141 out = "<!DOCTYPE Tasks>\n<Tasks>\n"; 149 out = "<!DOCTYPE Tasks>\n<Tasks>\n";
142 150
143 // for all todos 151 // for all todos
144 QMap<int, OTodo>::Iterator it; 152 QMap<int, OTodo>::Iterator it;
145 for (it = m_events.begin(); it != m_events.end(); ++it ) { 153 for (it = m_events.begin(); it != m_events.end(); ++it ) {
146 out+= "<Task " + toString( (*it) ) + " />\n"; 154 out+= "<Task " + toString( (*it) ) + " />\n";
147 QCString cstr = out.utf8(); 155 QCString cstr = out.utf8();
148 written = f.writeBlock( cstr.data(), cstr.length() ); 156 written = f.writeBlock( cstr.data(), cstr.length() );
149 157
150 /* less written then we wanted */ 158 /* less written then we wanted */
151 if ( written != (int)cstr.length() ) { 159 if ( written != (int)cstr.length() ) {
152 f.close(); 160 f.close();
153 QFile::remove( strNewFile ); 161 QFile::remove( strNewFile );
154 return false; 162 return false;
155 } 163 }
156 out = QString::null; 164 out = QString::null;
157 } 165 }
158 166
159 out += "</Tasks>"; 167 out += "</Tasks>";
160 QCString cstr = out.utf8(); 168 QCString cstr = out.utf8();
161 written = f.writeBlock( cstr.data(), cstr.length() ); 169 written = f.writeBlock( cstr.data(), cstr.length() );
162 170
163 if ( written != (int)cstr.length() ) { 171 if ( written != (int)cstr.length() ) {
164 f.close(); 172 f.close();
165 QFile::remove( strNewFile ); 173 QFile::remove( strNewFile );
166 return false; 174 return false;
167 } 175 }
168 /* flush before renaming */ 176 /* flush before renaming */
169 f.close(); 177 f.close();
170 178
171 if( ::rename( strNewFile.latin1(), m_file.latin1() ) < 0 ) { 179 if( ::rename( strNewFile.latin1(), m_file.latin1() ) < 0 ) {
172// qWarning("error renaming"); 180// qWarning("error renaming");
173 QFile::remove( strNewFile ); 181 QFile::remove( strNewFile );
174 } 182 }
175 183
176 m_changed = false; 184 m_changed = false;
177 return true; 185 return true;
178} 186}
179QArray<int> OTodoAccessXML::allRecords()const { 187QArray<int> OTodoAccessXML::allRecords()const {
180 QArray<int> ids( m_events.count() ); 188 QArray<int> ids( m_events.count() );
181 QMap<int, OTodo>::ConstIterator it; 189 QMap<int, OTodo>::ConstIterator it;
182 int i = 0; 190 int i = 0;
183 191
184 for ( it = m_events.begin(); it != m_events.end(); ++it ) { 192 for ( it = m_events.begin(); it != m_events.end(); ++it ) {
185 ids[i] = it.key(); 193 ids[i] = it.key();
186 i++; 194 i++;
187 } 195 }
188 return ids; 196 return ids;
189} 197}
190QArray<int> OTodoAccessXML::queryByExample( const OTodo&, int ) { 198QArray<int> OTodoAccessXML::queryByExample( const OTodo&, int ) {
191 QArray<int> ids(0); 199 QArray<int> ids(0);
192 return ids; 200 return ids;
193} 201}
194OTodo OTodoAccessXML::find( int uid )const { 202OTodo OTodoAccessXML::find( int uid )const {
195 OTodo todo; 203 OTodo todo;
196 todo.setUid( 0 ); // isEmpty() 204 todo.setUid( 0 ); // isEmpty()
197 QMap<int, OTodo>::ConstIterator it = m_events.find( uid ); 205 QMap<int, OTodo>::ConstIterator it = m_events.find( uid );
198 if ( it != m_events.end() ) 206 if ( it != m_events.end() )
199 todo = it.data(); 207 todo = it.data();
200 208
201 return todo; 209 return todo;
202} 210}
203void OTodoAccessXML::clear() { 211void OTodoAccessXML::clear() {
204 if (m_opened ) 212 if (m_opened )
205 m_changed = true; 213 m_changed = true;
206 214
207 m_events.clear(); 215 m_events.clear();
208} 216}
209bool OTodoAccessXML::add( const OTodo& todo ) { 217bool OTodoAccessXML::add( const OTodo& todo ) {
210// qWarning("add"); 218// qWarning("add");
211 m_changed = true; 219 m_changed = true;
212 m_events.insert( todo.uid(), todo ); 220 m_events.insert( todo.uid(), todo );
213 221
214 return true; 222 return true;
215} 223}
@@ -246,197 +254,192 @@ QArray<int> OTodoAccessXML::effectiveToDos( const QDate& start,
246 } 254 }
247 ids.resize( i ); 255 ids.resize( i );
248 return ids; 256 return ids;
249} 257}
250QArray<int> OTodoAccessXML::overDue() { 258QArray<int> OTodoAccessXML::overDue() {
251 QArray<int> ids( m_events.count() ); 259 QArray<int> ids( m_events.count() );
252 int i = 0; 260 int i = 0;
253 261
254 QMap<int, OTodo>::Iterator it; 262 QMap<int, OTodo>::Iterator it;
255 for ( it = m_events.begin(); it != m_events.end(); ++it ) { 263 for ( it = m_events.begin(); it != m_events.end(); ++it ) {
256 if ( it.data().isOverdue() ) { 264 if ( it.data().isOverdue() ) {
257 ids[i] = it.key(); 265 ids[i] = it.key();
258 i++; 266 i++;
259 } 267 }
260 } 268 }
261 ids.resize( i ); 269 ids.resize( i );
262 return ids; 270 return ids;
263} 271}
264 272
265 273
266/* private */ 274/* private */
267void OTodoAccessXML::todo( QAsciiDict<int>* dict, OTodo& ev, 275void OTodoAccessXML::todo( QAsciiDict<int>* dict, OTodo& ev,
268 const QCString& attr, const QString& val) { 276 const QCString& attr, const QString& val) {
269// qWarning("parse to do from XMLElement" ); 277// qWarning("parse to do from XMLElement" );
270 278
271 int *find=0; 279 int *find=0;
272 280
273 find = (*dict)[ attr.data() ]; 281 find = (*dict)[ attr.data() ];
274 if (!find ) { 282 if (!find ) {
275// qWarning("Unknown option" + it.key() ); 283// qWarning("Unknown option" + it.key() );
276 ev.setCustomField( attr, val ); 284 ev.setCustomField( attr, val );
277 return; 285 return;
278 } 286 }
279 287
280 switch( *find ) { 288 switch( *find ) {
281 case OTodo::Uid: 289 case OTodo::Uid:
282 ev.setUid( val.toInt() ); 290 ev.setUid( val.toInt() );
283 break; 291 break;
284 case OTodo::Category: 292 case OTodo::Category:
285 ev.setCategories( ev.idsFromString( val ) ); 293 ev.setCategories( ev.idsFromString( val ) );
286 break; 294 break;
287 case OTodo::HasDate: 295 case OTodo::HasDate:
288 ev.setHasDueDate( val.toInt() ); 296 ev.setHasDueDate( val.toInt() );
289 break; 297 break;
290 case OTodo::Completed: 298 case OTodo::Completed:
291 ev.setCompleted( val.toInt() ); 299 ev.setCompleted( val.toInt() );
292 break; 300 break;
293 case OTodo::Description: 301 case OTodo::Description:
294 ev.setDescription( val ); 302 ev.setDescription( val );
295 break; 303 break;
296 case OTodo::Summary: 304 case OTodo::Summary:
297 ev.setSummary( val ); 305 ev.setSummary( val );
298 break; 306 break;
299 case OTodo::Priority: 307 case OTodo::Priority:
300 ev.setPriority( val.toInt() ); 308 ev.setPriority( val.toInt() );
301 break; 309 break;
302 case OTodo::DateDay: 310 case OTodo::DateDay:
303 m_day = val.toInt(); 311 m_day = val.toInt();
304 break; 312 break;
305 case OTodo::DateMonth: 313 case OTodo::DateMonth:
306 m_month = val.toInt(); 314 m_month = val.toInt();
307 break; 315 break;
308 case OTodo::DateYear: 316 case OTodo::DateYear:
309 m_year = val.toInt(); 317 m_year = val.toInt();
310 break; 318 break;
311 case OTodo::Progress: 319 case OTodo::Progress:
312 ev.setProgress( val.toInt() ); 320 ev.setProgress( val.toInt() );
313 break; 321 break;
314 case OTodo::CrossReference: 322 case OTodo::CrossReference:
315 { 323 {
316 /* 324 /*
317 * A cross refernce looks like 325 * A cross refernce looks like
318 * appname,id;appname,id 326 * appname,id;appname,id
319 * we need to split it up 327 * we need to split it up
320 */ 328 */
321 QStringList refs = QStringList::split(';', val ); 329 QStringList refs = QStringList::split(';', val );
322 QStringList::Iterator strIt; 330 QStringList::Iterator strIt;
323 for (strIt = refs.begin(); strIt != refs.end(); ++strIt ) { 331 for (strIt = refs.begin(); strIt != refs.end(); ++strIt ) {
324 int pos = (*strIt).find(','); 332 int pos = (*strIt).find(',');
325 if ( pos > -1 ) 333 if ( pos > -1 )
326 ev.addRelation( (*strIt).left(pos), (*strIt).mid(pos+1).toInt() ); 334 ev.addRelation( (*strIt).left(pos), (*strIt).mid(pos+1).toInt() );
327 335
328 } 336 }
329 break; 337 break;
330 } 338 }
331 case OTodo::HasAlarmDateTime: 339 case OTodo::HasAlarmDateTime:
332 ev.setHasAlarmDateTime( val.toInt() ); 340 ev.setHasAlarmDateTime( val.toInt() );
333 break; 341 break;
334 case OTodo::AlarmDateTime: { 342 case OTodo::AlarmDateTime: {
335 /* this sounds better ;) zecke */ 343 /* this sounds better ;) zecke */
336 ev.setAlarmDateTime( TimeConversion::fromISO8601( val.local8Bit() ) ); 344 ev.setAlarmDateTime( TimeConversion::fromISO8601( val.local8Bit() ) );
337 break; 345 break;
338 } 346 }
339 default: 347 default:
340 break; 348 break;
341 } 349 }
342
343 if ( ev.hasDueDate() ) {
344 QDate date( m_year, m_month, m_day );
345 ev.setDueDate( date );
346 }
347} 350}
348QString OTodoAccessXML::toString( const OTodo& ev )const { 351QString OTodoAccessXML::toString( const OTodo& ev )const {
349 QString str; 352 QString str;
350 353
351 str += "Completed=\"" + QString::number( ev.isCompleted() ) + "\" "; 354 str += "Completed=\"" + QString::number( ev.isCompleted() ) + "\" ";
352 str += "HasDate=\"" + QString::number( ev.hasDueDate() ) + "\" "; 355 str += "HasDate=\"" + QString::number( ev.hasDueDate() ) + "\" ";
353 str += "Priority=\"" + QString::number( ev.priority() ) + "\" "; 356 str += "Priority=\"" + QString::number( ev.priority() ) + "\" ";
354 str += "Progress=\"" + QString::number(ev.progress() ) + "\" "; 357 str += "Progress=\"" + QString::number(ev.progress() ) + "\" ";
355 358
356 str += "Categories=\"" + toString( ev.categories() ) + "\" "; 359 str += "Categories=\"" + toString( ev.categories() ) + "\" ";
357 str += "Description=\"" + Qtopia::escapeString( ev.description() ) + "\" "; 360 str += "Description=\"" + Qtopia::escapeString( ev.description() ) + "\" ";
358 str += "Summary=\"" + Qtopia::escapeString( ev.summary() ) + "\" "; 361 str += "Summary=\"" + Qtopia::escapeString( ev.summary() ) + "\" ";
359 362
360 if ( ev.hasDueDate() ) { 363 if ( ev.hasDueDate() ) {
361 str += "DateYear=\"" + QString::number( ev.dueDate().year() ) + "\" "; 364 str += "DateYear=\"" + QString::number( ev.dueDate().year() ) + "\" ";
362 str += "DateMonth=\"" + QString::number( ev.dueDate().month() ) + "\" "; 365 str += "DateMonth=\"" + QString::number( ev.dueDate().month() ) + "\" ";
363 str += "DateDay=\"" + QString::number( ev.dueDate().day() ) + "\" "; 366 str += "DateDay=\"" + QString::number( ev.dueDate().day() ) + "\" ";
364 } 367 }
365// qWarning( "Uid %d", ev.uid() ); 368// qWarning( "Uid %d", ev.uid() );
366 str += "Uid=\"" + QString::number( ev.uid() ) + "\" "; 369 str += "Uid=\"" + QString::number( ev.uid() ) + "\" ";
367 370
368// append the extra options 371// append the extra options
369 /* FIXME Qtopia::Record this is currently not 372 /* FIXME Qtopia::Record this is currently not
370 * possible you can set custom fields 373 * possible you can set custom fields
371 * but don' iterate over the list 374 * but don' iterate over the list
372 * I may do #define private protected 375 * I may do #define private protected
373 * for this case - cough --zecke 376 * for this case - cough --zecke
374 */ 377 */
375 /* 378 /*
376 QMap<QString, QString> extras = ev.extras(); 379 QMap<QString, QString> extras = ev.extras();
377 QMap<QString, QString>::Iterator extIt; 380 QMap<QString, QString>::Iterator extIt;
378 for (extIt = extras.begin(); extIt != extras.end(); ++extIt ) 381 for (extIt = extras.begin(); extIt != extras.end(); ++extIt )
379 str += extIt.key() + "=\"" + extIt.data() + "\" "; 382 str += extIt.key() + "=\"" + extIt.data() + "\" ";
380 */ 383 */
381 // cross refernce 384 // cross refernce
382 QStringList list = ev.relatedApps(); 385 QStringList list = ev.relatedApps();
383 QStringList::Iterator listIt; 386 QStringList::Iterator listIt;
384 QString refs; 387 QString refs;
385 str += "CrossReference=\""; 388 str += "CrossReference=\"";
386 bool added = false; 389 bool added = false;
387 for ( listIt = list.begin(); listIt != list.end(); ++listIt ) { 390 for ( listIt = list.begin(); listIt != list.end(); ++listIt ) {
388 added = true; 391 added = true;
389 QArray<int> ints = ev.relations( (*listIt) ); 392 QArray<int> ints = ev.relations( (*listIt) );
390 for ( uint i = 0; i< ints.count(); i++ ) { 393 for ( uint i = 0; i< ints.count(); i++ ) {
391 str += (*listIt) + "," + QString::number( i ) + ";"; 394 str += (*listIt) + "," + QString::number( i ) + ";";
392 } 395 }
393 } 396 }
394 if ( added ) 397 if ( added )
395 str = str.remove( str.length()-1, 1 ); 398 str = str.remove( str.length()-1, 1 );
396 399
397 str += "\" "; 400 str += "\" ";
398 401
399 str += "AlarmDateTime=\"" + TimeConversion::toISO8601( ev.alarmDateTime() ) + "\" "; 402 str += "AlarmDateTime=\"" + TimeConversion::toISO8601( ev.alarmDateTime() ) + "\" ";
400 403
401 return str; 404 return str;
402} 405}
403QString OTodoAccessXML::toString( const QArray<int>& ints ) const { 406QString OTodoAccessXML::toString( const QArray<int>& ints ) const {
404 return Qtopia::Record::idsToString( ints ); 407 return Qtopia::Record::idsToString( ints );
405} 408}
406 409
407/* internal class for sorting */ 410/* internal class for sorting */
408 411
409struct OTodoXMLContainer { 412struct OTodoXMLContainer {
410 OTodo todo; 413 OTodo todo;
411}; 414};
412 /* 415 /*
413 * Returns: 416 * Returns:
414 * 0 if item1 == item2 417 * 0 if item1 == item2
415 * 418 *
416 * non-zero if item1 != item2 419 * non-zero if item1 != item2
417 * 420 *
418 * This function returns int rather than bool so that reimplementations 421 * This function returns int rather than bool so that reimplementations
419 * can return one of three values and use it to sort by: 422 * can return one of three values and use it to sort by:
420 * 423 *
421 * 0 if item1 == item2 424 * 0 if item1 == item2
422 * 425 *
423 * > 0 (positive integer) if item1 > item2 426 * > 0 (positive integer) if item1 > item2
424 * 427 *
425 * < 0 (negative integer) if item1 < item2 428 * < 0 (negative integer) if item1 < item2
426 * 429 *
427 */ 430 */
428class OTodoXMLVector : public QVector<OTodoXMLContainer> { 431class OTodoXMLVector : public QVector<OTodoXMLContainer> {
429public: 432public:
430 OTodoXMLVector(int size, bool asc, int sort) 433 OTodoXMLVector(int size, bool asc, int sort)
431 : QVector<OTodoXMLContainer>( size ) 434 : QVector<OTodoXMLContainer>( size )
432 { 435 {
433 setAutoDelete( true ); 436 setAutoDelete( true );
434 m_asc = asc; 437 m_asc = asc;
435 m_sort = sort; 438 m_sort = sort;
436 } 439 }
437 /* return the summary/description */ 440 /* return the summary/description */
438 QString string( const OTodo& todo) { 441 QString string( const OTodo& todo) {
439 return todo.summary().isEmpty() ? 442 return todo.summary().isEmpty() ?
440 todo.description().left(20 ) : 443 todo.description().left(20 ) :
441 todo.summary(); 444 todo.summary();
442 } 445 }
diff --git a/libopie2/opiepim/backend/otodoaccessxml.cpp b/libopie2/opiepim/backend/otodoaccessxml.cpp
index 7a55c67..385fd27 100644
--- a/libopie2/opiepim/backend/otodoaccessxml.cpp
+++ b/libopie2/opiepim/backend/otodoaccessxml.cpp
@@ -23,193 +23,201 @@ OTodoAccessXML::~OTodoAccessXML() {
23} 23}
24bool OTodoAccessXML::load() { 24bool OTodoAccessXML::load() {
25 m_opened = true; 25 m_opened = true;
26 m_changed = false; 26 m_changed = false;
27 /* initialize dict */ 27 /* initialize dict */
28 /* 28 /*
29 * UPDATE dict if you change anything!!! 29 * UPDATE dict if you change anything!!!
30 */ 30 */
31 QAsciiDict<int> dict(15); 31 QAsciiDict<int> dict(15);
32 dict.setAutoDelete( TRUE ); 32 dict.setAutoDelete( TRUE );
33 dict.insert("Categories" , new int(OTodo::Category) ); 33 dict.insert("Categories" , new int(OTodo::Category) );
34 dict.insert("Uid" , new int(OTodo::Uid) ); 34 dict.insert("Uid" , new int(OTodo::Uid) );
35 dict.insert("HasDate" , new int(OTodo::HasDate) ); 35 dict.insert("HasDate" , new int(OTodo::HasDate) );
36 dict.insert("Completed" , new int(OTodo::Completed) ); 36 dict.insert("Completed" , new int(OTodo::Completed) );
37 dict.insert("Description" , new int(OTodo::Description) ); 37 dict.insert("Description" , new int(OTodo::Description) );
38 dict.insert("Summary" , new int(OTodo::Summary) ); 38 dict.insert("Summary" , new int(OTodo::Summary) );
39 dict.insert("Priority" , new int(OTodo::Priority) ); 39 dict.insert("Priority" , new int(OTodo::Priority) );
40 dict.insert("DateDay" , new int(OTodo::DateDay) ); 40 dict.insert("DateDay" , new int(OTodo::DateDay) );
41 dict.insert("DateMonth" , new int(OTodo::DateMonth) ); 41 dict.insert("DateMonth" , new int(OTodo::DateMonth) );
42 dict.insert("DateYear" , new int(OTodo::DateYear) ); 42 dict.insert("DateYear" , new int(OTodo::DateYear) );
43 dict.insert("Progress" , new int(OTodo::Progress) ); 43 dict.insert("Progress" , new int(OTodo::Progress) );
44 dict.insert("Completed", new int(OTodo::Completed) ); 44 dict.insert("Completed", new int(OTodo::Completed) );
45 dict.insert("CrossReference", new int(OTodo::CrossReference) ); 45 dict.insert("CrossReference", new int(OTodo::CrossReference) );
46 dict.insert("HasAlarmDateTime",new int(OTodo::HasAlarmDateTime) ); 46 dict.insert("HasAlarmDateTime",new int(OTodo::HasAlarmDateTime) );
47 dict.insert("AlarmDateTime", new int(OTodo::AlarmDateTime) ); 47 dict.insert("AlarmDateTime", new int(OTodo::AlarmDateTime) );
48 48
49 // here the custom XML parser from TT it's GPL 49 // here the custom XML parser from TT it's GPL
50 // but we want to push that to TT..... 50 // but we want to push that to TT.....
51 QFile f(m_file ); 51 QFile f(m_file );
52 if (!f.open(IO_ReadOnly) ) 52 if (!f.open(IO_ReadOnly) )
53 return false; 53 return false;
54 54
55 QByteArray ba = f.readAll(); 55 QByteArray ba = f.readAll();
56 f.close(); 56 f.close();
57 char* dt = ba.data(); 57 char* dt = ba.data();
58 int len = ba.size(); 58 int len = ba.size();
59 int i = 0; 59 int i = 0;
60 char *point; 60 char *point;
61 const char* collectionString = "<Task "; 61 const char* collectionString = "<Task ";
62 while ( dt+i != 0 && ( point = strstr( dt+i, collectionString ) ) != 0l ) { 62 while ( dt+i != 0 && ( point = strstr( dt+i, collectionString ) ) != 0l ) {
63 i = point -dt; 63 i = point -dt;
64 i+= strlen(collectionString); 64 i+= strlen(collectionString);
65 OTodo ev; 65 OTodo ev;
66 m_year = m_month = m_day = 0; 66 m_year = m_month = m_day = 0;
67 67
68 while ( TRUE ) { 68 while ( TRUE ) {
69 while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) 69 while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') )
70 ++i; 70 ++i;
71 if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) 71 if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') )
72 break; 72 break;
73 73
74 // we have another attribute, read it. 74 // we have another attribute, read it.
75 int j = i; 75 int j = i;
76 while ( j < len && dt[j] != '=' ) 76 while ( j < len && dt[j] != '=' )
77 ++j; 77 ++j;
78 QCString attr( dt+i, j-i+1); 78 QCString attr( dt+i, j-i+1);
79 79
80 i = ++j; // skip = 80 i = ++j; // skip =
81 81
82 // find the start of quotes 82 // find the start of quotes
83 while ( i < len && dt[i] != '"' ) 83 while ( i < len && dt[i] != '"' )
84 ++i; 84 ++i;
85 j = ++i; 85 j = ++i;
86 86
87 bool haveUtf = FALSE; 87 bool haveUtf = FALSE;
88 bool haveEnt = FALSE; 88 bool haveEnt = FALSE;
89 while ( j < len && dt[j] != '"' ) { 89 while ( j < len && dt[j] != '"' ) {
90 if ( ((unsigned char)dt[j]) > 0x7f ) 90 if ( ((unsigned char)dt[j]) > 0x7f )
91 haveUtf = TRUE; 91 haveUtf = TRUE;
92 if ( dt[j] == '&' ) 92 if ( dt[j] == '&' )
93 haveEnt = TRUE; 93 haveEnt = TRUE;
94 ++j; 94 ++j;
95 } 95 }
96 if ( i == j ) { 96 if ( i == j ) {
97 // empty value 97 // empty value
98 i = j + 1; 98 i = j + 1;
99 continue; 99 continue;
100 } 100 }
101 101
102 QCString value( dt+i, j-i+1 ); 102 QCString value( dt+i, j-i+1 );
103 i = j + 1; 103 i = j + 1;
104 104
105 QString str = (haveUtf ? QString::fromUtf8( value ) 105 QString str = (haveUtf ? QString::fromUtf8( value )
106 : QString::fromLatin1( value ) ); 106 : QString::fromLatin1( value ) );
107 if ( haveEnt ) 107 if ( haveEnt )
108 str = Qtopia::plainString( str ); 108 str = Qtopia::plainString( str );
109 109
110 /* 110 /*
111 * add key + value 111 * add key + value
112 */ 112 */
113 todo( &dict, ev, attr, str ); 113 todo( &dict, ev, attr, str );
114 114
115 } 115 }
116 /* 116 /*
117 * now add it 117 * now add it
118 */ 118 */
119 if (m_events.contains( ev.uid() ) || ev.uid() == 0) {
120 ev.setUid( 1 );
121 m_changed = true;
122 }
123 if ( ev.hasDueDate() ) {
124 ev.setDueDate( QDate(m_year, m_month, m_day) );
125 }
119 m_events.insert(ev.uid(), ev ); 126 m_events.insert(ev.uid(), ev );
127 m_year = m_month = m_day = -1;
120 } 128 }
121 129
122 qWarning("counts %d records loaded!", m_events.count() ); 130 qWarning("counts %d records loaded!", m_events.count() );
123 return true; 131 return true;
124} 132}
125bool OTodoAccessXML::reload() { 133bool OTodoAccessXML::reload() {
126 return load(); 134 return load();
127} 135}
128bool OTodoAccessXML::save() { 136bool OTodoAccessXML::save() {
129// qWarning("saving"); 137// qWarning("saving");
130 if (!m_opened || !m_changed ) { 138 if (!m_opened || !m_changed ) {
131// qWarning("not saving"); 139// qWarning("not saving");
132 return true; 140 return true;
133 } 141 }
134 QString strNewFile = m_file + ".new"; 142 QString strNewFile = m_file + ".new";
135 QFile f( strNewFile ); 143 QFile f( strNewFile );
136 if (!f.open( IO_WriteOnly|IO_Raw ) ) 144 if (!f.open( IO_WriteOnly|IO_Raw ) )
137 return false; 145 return false;
138 146
139 int written; 147 int written;
140 QString out; 148 QString out;
141 out = "<!DOCTYPE Tasks>\n<Tasks>\n"; 149 out = "<!DOCTYPE Tasks>\n<Tasks>\n";
142 150
143 // for all todos 151 // for all todos
144 QMap<int, OTodo>::Iterator it; 152 QMap<int, OTodo>::Iterator it;
145 for (it = m_events.begin(); it != m_events.end(); ++it ) { 153 for (it = m_events.begin(); it != m_events.end(); ++it ) {
146 out+= "<Task " + toString( (*it) ) + " />\n"; 154 out+= "<Task " + toString( (*it) ) + " />\n";
147 QCString cstr = out.utf8(); 155 QCString cstr = out.utf8();
148 written = f.writeBlock( cstr.data(), cstr.length() ); 156 written = f.writeBlock( cstr.data(), cstr.length() );
149 157
150 /* less written then we wanted */ 158 /* less written then we wanted */
151 if ( written != (int)cstr.length() ) { 159 if ( written != (int)cstr.length() ) {
152 f.close(); 160 f.close();
153 QFile::remove( strNewFile ); 161 QFile::remove( strNewFile );
154 return false; 162 return false;
155 } 163 }
156 out = QString::null; 164 out = QString::null;
157 } 165 }
158 166
159 out += "</Tasks>"; 167 out += "</Tasks>";
160 QCString cstr = out.utf8(); 168 QCString cstr = out.utf8();
161 written = f.writeBlock( cstr.data(), cstr.length() ); 169 written = f.writeBlock( cstr.data(), cstr.length() );
162 170
163 if ( written != (int)cstr.length() ) { 171 if ( written != (int)cstr.length() ) {
164 f.close(); 172 f.close();
165 QFile::remove( strNewFile ); 173 QFile::remove( strNewFile );
166 return false; 174 return false;
167 } 175 }
168 /* flush before renaming */ 176 /* flush before renaming */
169 f.close(); 177 f.close();
170 178
171 if( ::rename( strNewFile.latin1(), m_file.latin1() ) < 0 ) { 179 if( ::rename( strNewFile.latin1(), m_file.latin1() ) < 0 ) {
172// qWarning("error renaming"); 180// qWarning("error renaming");
173 QFile::remove( strNewFile ); 181 QFile::remove( strNewFile );
174 } 182 }
175 183
176 m_changed = false; 184 m_changed = false;
177 return true; 185 return true;
178} 186}
179QArray<int> OTodoAccessXML::allRecords()const { 187QArray<int> OTodoAccessXML::allRecords()const {
180 QArray<int> ids( m_events.count() ); 188 QArray<int> ids( m_events.count() );
181 QMap<int, OTodo>::ConstIterator it; 189 QMap<int, OTodo>::ConstIterator it;
182 int i = 0; 190 int i = 0;
183 191
184 for ( it = m_events.begin(); it != m_events.end(); ++it ) { 192 for ( it = m_events.begin(); it != m_events.end(); ++it ) {
185 ids[i] = it.key(); 193 ids[i] = it.key();
186 i++; 194 i++;
187 } 195 }
188 return ids; 196 return ids;
189} 197}
190QArray<int> OTodoAccessXML::queryByExample( const OTodo&, int ) { 198QArray<int> OTodoAccessXML::queryByExample( const OTodo&, int ) {
191 QArray<int> ids(0); 199 QArray<int> ids(0);
192 return ids; 200 return ids;
193} 201}
194OTodo OTodoAccessXML::find( int uid )const { 202OTodo OTodoAccessXML::find( int uid )const {
195 OTodo todo; 203 OTodo todo;
196 todo.setUid( 0 ); // isEmpty() 204 todo.setUid( 0 ); // isEmpty()
197 QMap<int, OTodo>::ConstIterator it = m_events.find( uid ); 205 QMap<int, OTodo>::ConstIterator it = m_events.find( uid );
198 if ( it != m_events.end() ) 206 if ( it != m_events.end() )
199 todo = it.data(); 207 todo = it.data();
200 208
201 return todo; 209 return todo;
202} 210}
203void OTodoAccessXML::clear() { 211void OTodoAccessXML::clear() {
204 if (m_opened ) 212 if (m_opened )
205 m_changed = true; 213 m_changed = true;
206 214
207 m_events.clear(); 215 m_events.clear();
208} 216}
209bool OTodoAccessXML::add( const OTodo& todo ) { 217bool OTodoAccessXML::add( const OTodo& todo ) {
210// qWarning("add"); 218// qWarning("add");
211 m_changed = true; 219 m_changed = true;
212 m_events.insert( todo.uid(), todo ); 220 m_events.insert( todo.uid(), todo );
213 221
214 return true; 222 return true;
215} 223}
@@ -246,197 +254,192 @@ QArray<int> OTodoAccessXML::effectiveToDos( const QDate& start,
246 } 254 }
247 ids.resize( i ); 255 ids.resize( i );
248 return ids; 256 return ids;
249} 257}
250QArray<int> OTodoAccessXML::overDue() { 258QArray<int> OTodoAccessXML::overDue() {
251 QArray<int> ids( m_events.count() ); 259 QArray<int> ids( m_events.count() );
252 int i = 0; 260 int i = 0;
253 261
254 QMap<int, OTodo>::Iterator it; 262 QMap<int, OTodo>::Iterator it;
255 for ( it = m_events.begin(); it != m_events.end(); ++it ) { 263 for ( it = m_events.begin(); it != m_events.end(); ++it ) {
256 if ( it.data().isOverdue() ) { 264 if ( it.data().isOverdue() ) {
257 ids[i] = it.key(); 265 ids[i] = it.key();
258 i++; 266 i++;
259 } 267 }
260 } 268 }
261 ids.resize( i ); 269 ids.resize( i );
262 return ids; 270 return ids;
263} 271}
264 272
265 273
266/* private */ 274/* private */
267void OTodoAccessXML::todo( QAsciiDict<int>* dict, OTodo& ev, 275void OTodoAccessXML::todo( QAsciiDict<int>* dict, OTodo& ev,
268 const QCString& attr, const QString& val) { 276 const QCString& attr, const QString& val) {
269// qWarning("parse to do from XMLElement" ); 277// qWarning("parse to do from XMLElement" );
270 278
271 int *find=0; 279 int *find=0;
272 280
273 find = (*dict)[ attr.data() ]; 281 find = (*dict)[ attr.data() ];
274 if (!find ) { 282 if (!find ) {
275// qWarning("Unknown option" + it.key() ); 283// qWarning("Unknown option" + it.key() );
276 ev.setCustomField( attr, val ); 284 ev.setCustomField( attr, val );
277 return; 285 return;
278 } 286 }
279 287
280 switch( *find ) { 288 switch( *find ) {
281 case OTodo::Uid: 289 case OTodo::Uid:
282 ev.setUid( val.toInt() ); 290 ev.setUid( val.toInt() );
283 break; 291 break;
284 case OTodo::Category: 292 case OTodo::Category:
285 ev.setCategories( ev.idsFromString( val ) ); 293 ev.setCategories( ev.idsFromString( val ) );
286 break; 294 break;
287 case OTodo::HasDate: 295 case OTodo::HasDate:
288 ev.setHasDueDate( val.toInt() ); 296 ev.setHasDueDate( val.toInt() );
289 break; 297 break;
290 case OTodo::Completed: 298 case OTodo::Completed:
291 ev.setCompleted( val.toInt() ); 299 ev.setCompleted( val.toInt() );
292 break; 300 break;
293 case OTodo::Description: 301 case OTodo::Description:
294 ev.setDescription( val ); 302 ev.setDescription( val );
295 break; 303 break;
296 case OTodo::Summary: 304 case OTodo::Summary:
297 ev.setSummary( val ); 305 ev.setSummary( val );
298 break; 306 break;
299 case OTodo::Priority: 307 case OTodo::Priority:
300 ev.setPriority( val.toInt() ); 308 ev.setPriority( val.toInt() );
301 break; 309 break;
302 case OTodo::DateDay: 310 case OTodo::DateDay:
303 m_day = val.toInt(); 311 m_day = val.toInt();
304 break; 312 break;
305 case OTodo::DateMonth: 313 case OTodo::DateMonth:
306 m_month = val.toInt(); 314 m_month = val.toInt();
307 break; 315 break;
308 case OTodo::DateYear: 316 case OTodo::DateYear:
309 m_year = val.toInt(); 317 m_year = val.toInt();
310 break; 318 break;
311 case OTodo::Progress: 319 case OTodo::Progress:
312 ev.setProgress( val.toInt() ); 320 ev.setProgress( val.toInt() );
313 break; 321 break;
314 case OTodo::CrossReference: 322 case OTodo::CrossReference:
315 { 323 {
316 /* 324 /*
317 * A cross refernce looks like 325 * A cross refernce looks like
318 * appname,id;appname,id 326 * appname,id;appname,id
319 * we need to split it up 327 * we need to split it up
320 */ 328 */
321 QStringList refs = QStringList::split(';', val ); 329 QStringList refs = QStringList::split(';', val );
322 QStringList::Iterator strIt; 330 QStringList::Iterator strIt;
323 for (strIt = refs.begin(); strIt != refs.end(); ++strIt ) { 331 for (strIt = refs.begin(); strIt != refs.end(); ++strIt ) {
324 int pos = (*strIt).find(','); 332 int pos = (*strIt).find(',');
325 if ( pos > -1 ) 333 if ( pos > -1 )
326 ev.addRelation( (*strIt).left(pos), (*strIt).mid(pos+1).toInt() ); 334 ev.addRelation( (*strIt).left(pos), (*strIt).mid(pos+1).toInt() );
327 335
328 } 336 }
329 break; 337 break;
330 } 338 }
331 case OTodo::HasAlarmDateTime: 339 case OTodo::HasAlarmDateTime:
332 ev.setHasAlarmDateTime( val.toInt() ); 340 ev.setHasAlarmDateTime( val.toInt() );
333 break; 341 break;
334 case OTodo::AlarmDateTime: { 342 case OTodo::AlarmDateTime: {
335 /* this sounds better ;) zecke */ 343 /* this sounds better ;) zecke */
336 ev.setAlarmDateTime( TimeConversion::fromISO8601( val.local8Bit() ) ); 344 ev.setAlarmDateTime( TimeConversion::fromISO8601( val.local8Bit() ) );
337 break; 345 break;
338 } 346 }
339 default: 347 default:
340 break; 348 break;
341 } 349 }
342
343 if ( ev.hasDueDate() ) {
344 QDate date( m_year, m_month, m_day );
345 ev.setDueDate( date );
346 }
347} 350}
348QString OTodoAccessXML::toString( const OTodo& ev )const { 351QString OTodoAccessXML::toString( const OTodo& ev )const {
349 QString str; 352 QString str;
350 353
351 str += "Completed=\"" + QString::number( ev.isCompleted() ) + "\" "; 354 str += "Completed=\"" + QString::number( ev.isCompleted() ) + "\" ";
352 str += "HasDate=\"" + QString::number( ev.hasDueDate() ) + "\" "; 355 str += "HasDate=\"" + QString::number( ev.hasDueDate() ) + "\" ";
353 str += "Priority=\"" + QString::number( ev.priority() ) + "\" "; 356 str += "Priority=\"" + QString::number( ev.priority() ) + "\" ";
354 str += "Progress=\"" + QString::number(ev.progress() ) + "\" "; 357 str += "Progress=\"" + QString::number(ev.progress() ) + "\" ";
355 358
356 str += "Categories=\"" + toString( ev.categories() ) + "\" "; 359 str += "Categories=\"" + toString( ev.categories() ) + "\" ";
357 str += "Description=\"" + Qtopia::escapeString( ev.description() ) + "\" "; 360 str += "Description=\"" + Qtopia::escapeString( ev.description() ) + "\" ";
358 str += "Summary=\"" + Qtopia::escapeString( ev.summary() ) + "\" "; 361 str += "Summary=\"" + Qtopia::escapeString( ev.summary() ) + "\" ";
359 362
360 if ( ev.hasDueDate() ) { 363 if ( ev.hasDueDate() ) {
361 str += "DateYear=\"" + QString::number( ev.dueDate().year() ) + "\" "; 364 str += "DateYear=\"" + QString::number( ev.dueDate().year() ) + "\" ";
362 str += "DateMonth=\"" + QString::number( ev.dueDate().month() ) + "\" "; 365 str += "DateMonth=\"" + QString::number( ev.dueDate().month() ) + "\" ";
363 str += "DateDay=\"" + QString::number( ev.dueDate().day() ) + "\" "; 366 str += "DateDay=\"" + QString::number( ev.dueDate().day() ) + "\" ";
364 } 367 }
365// qWarning( "Uid %d", ev.uid() ); 368// qWarning( "Uid %d", ev.uid() );
366 str += "Uid=\"" + QString::number( ev.uid() ) + "\" "; 369 str += "Uid=\"" + QString::number( ev.uid() ) + "\" ";
367 370
368// append the extra options 371// append the extra options
369 /* FIXME Qtopia::Record this is currently not 372 /* FIXME Qtopia::Record this is currently not
370 * possible you can set custom fields 373 * possible you can set custom fields
371 * but don' iterate over the list 374 * but don' iterate over the list
372 * I may do #define private protected 375 * I may do #define private protected
373 * for this case - cough --zecke 376 * for this case - cough --zecke
374 */ 377 */
375 /* 378 /*
376 QMap<QString, QString> extras = ev.extras(); 379 QMap<QString, QString> extras = ev.extras();
377 QMap<QString, QString>::Iterator extIt; 380 QMap<QString, QString>::Iterator extIt;
378 for (extIt = extras.begin(); extIt != extras.end(); ++extIt ) 381 for (extIt = extras.begin(); extIt != extras.end(); ++extIt )
379 str += extIt.key() + "=\"" + extIt.data() + "\" "; 382 str += extIt.key() + "=\"" + extIt.data() + "\" ";
380 */ 383 */
381 // cross refernce 384 // cross refernce
382 QStringList list = ev.relatedApps(); 385 QStringList list = ev.relatedApps();
383 QStringList::Iterator listIt; 386 QStringList::Iterator listIt;
384 QString refs; 387 QString refs;
385 str += "CrossReference=\""; 388 str += "CrossReference=\"";
386 bool added = false; 389 bool added = false;
387 for ( listIt = list.begin(); listIt != list.end(); ++listIt ) { 390 for ( listIt = list.begin(); listIt != list.end(); ++listIt ) {
388 added = true; 391 added = true;
389 QArray<int> ints = ev.relations( (*listIt) ); 392 QArray<int> ints = ev.relations( (*listIt) );
390 for ( uint i = 0; i< ints.count(); i++ ) { 393 for ( uint i = 0; i< ints.count(); i++ ) {
391 str += (*listIt) + "," + QString::number( i ) + ";"; 394 str += (*listIt) + "," + QString::number( i ) + ";";
392 } 395 }
393 } 396 }
394 if ( added ) 397 if ( added )
395 str = str.remove( str.length()-1, 1 ); 398 str = str.remove( str.length()-1, 1 );
396 399
397 str += "\" "; 400 str += "\" ";
398 401
399 str += "AlarmDateTime=\"" + TimeConversion::toISO8601( ev.alarmDateTime() ) + "\" "; 402 str += "AlarmDateTime=\"" + TimeConversion::toISO8601( ev.alarmDateTime() ) + "\" ";
400 403
401 return str; 404 return str;
402} 405}
403QString OTodoAccessXML::toString( const QArray<int>& ints ) const { 406QString OTodoAccessXML::toString( const QArray<int>& ints ) const {
404 return Qtopia::Record::idsToString( ints ); 407 return Qtopia::Record::idsToString( ints );
405} 408}
406 409
407/* internal class for sorting */ 410/* internal class for sorting */
408 411
409struct OTodoXMLContainer { 412struct OTodoXMLContainer {
410 OTodo todo; 413 OTodo todo;
411}; 414};
412 /* 415 /*
413 * Returns: 416 * Returns:
414 * 0 if item1 == item2 417 * 0 if item1 == item2
415 * 418 *
416 * non-zero if item1 != item2 419 * non-zero if item1 != item2
417 * 420 *
418 * This function returns int rather than bool so that reimplementations 421 * This function returns int rather than bool so that reimplementations
419 * can return one of three values and use it to sort by: 422 * can return one of three values and use it to sort by:
420 * 423 *
421 * 0 if item1 == item2 424 * 0 if item1 == item2
422 * 425 *
423 * > 0 (positive integer) if item1 > item2 426 * > 0 (positive integer) if item1 > item2
424 * 427 *
425 * < 0 (negative integer) if item1 < item2 428 * < 0 (negative integer) if item1 < item2
426 * 429 *
427 */ 430 */
428class OTodoXMLVector : public QVector<OTodoXMLContainer> { 431class OTodoXMLVector : public QVector<OTodoXMLContainer> {
429public: 432public:
430 OTodoXMLVector(int size, bool asc, int sort) 433 OTodoXMLVector(int size, bool asc, int sort)
431 : QVector<OTodoXMLContainer>( size ) 434 : QVector<OTodoXMLContainer>( size )
432 { 435 {
433 setAutoDelete( true ); 436 setAutoDelete( true );
434 m_asc = asc; 437 m_asc = asc;
435 m_sort = sort; 438 m_sort = sort;
436 } 439 }
437 /* return the summary/description */ 440 /* return the summary/description */
438 QString string( const OTodo& todo) { 441 QString string( const OTodo& todo) {
439 return todo.summary().isEmpty() ? 442 return todo.summary().isEmpty() ?
440 todo.description().left(20 ) : 443 todo.description().left(20 ) :
441 todo.summary(); 444 todo.summary();
442 } 445 }