summaryrefslogtreecommitdiff
path: root/libopie2/opiepim/backend/otodoaccessxml.cpp
Unidiff
Diffstat (limited to 'libopie2/opiepim/backend/otodoaccessxml.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opiepim/backend/otodoaccessxml.cpp316
1 files changed, 61 insertions, 255 deletions
diff --git a/libopie2/opiepim/backend/otodoaccessxml.cpp b/libopie2/opiepim/backend/otodoaccessxml.cpp
index 3e06d88..273f91a 100644
--- a/libopie2/opiepim/backend/otodoaccessxml.cpp
+++ b/libopie2/opiepim/backend/otodoaccessxml.cpp
@@ -25,26 +25,29 @@
25 If not, write to the Free Software Foundation, 25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330, 26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. 27 Boston, MA 02111-1307, USA.
28*/ 28*/
29 29
30/* OPIE */ 30/* OPIE */
31#include <opie2/opimdateconversion.h> 31#include <opie2/opimdateconversion.h>
32#include <opie2/opimstate.h> 32#include <opie2/opimstate.h>
33#include <opie2/opimtimezone.h> 33#include <opie2/opimtimezone.h>
34#include <opie2/opimnotifymanager.h> 34#include <opie2/opimnotifymanager.h>
35#include <opie2/opimrecurrence.h> 35#include <opie2/opimrecurrence.h>
36#include <opie2/otodoaccessxml.h> 36#include <opie2/otodoaccessxml.h>
37#include <opie2/otodoaccess.h>
37#include <opie2/odebug.h> 38#include <opie2/odebug.h>
38 39
40#include <opie2/private/opimtodosortvector.h>
41
39#include <qpe/global.h> 42#include <qpe/global.h>
40#include <qpe/stringutil.h> 43#include <qpe/stringutil.h>
41#include <qpe/timeconversion.h> 44#include <qpe/timeconversion.h>
42 45
43/* QT */ 46/* QT */
44#include <qfile.h> 47#include <qfile.h>
45#include <qvector.h> 48#include <qvector.h>
46 49
47/* STD */ 50/* STD */
48#include <errno.h> 51#include <errno.h>
49#include <fcntl.h> 52#include <fcntl.h>
50 53
@@ -133,25 +136,24 @@ bool OPimTodoAccessXML::load() {
133 dict.insert("Summary" , new int(OPimTodo::Summary) ); 136 dict.insert("Summary" , new int(OPimTodo::Summary) );
134 dict.insert("Priority" , new int(OPimTodo::Priority) ); 137 dict.insert("Priority" , new int(OPimTodo::Priority) );
135 dict.insert("DateDay" , new int(OPimTodo::DateDay) ); 138 dict.insert("DateDay" , new int(OPimTodo::DateDay) );
136 dict.insert("DateMonth" , new int(OPimTodo::DateMonth) ); 139 dict.insert("DateMonth" , new int(OPimTodo::DateMonth) );
137 dict.insert("DateYear" , new int(OPimTodo::DateYear) ); 140 dict.insert("DateYear" , new int(OPimTodo::DateYear) );
138 dict.insert("Progress" , new int(OPimTodo::Progress) ); 141 dict.insert("Progress" , new int(OPimTodo::Progress) );
139 dict.insert("CompletedDate", new int(OPimTodo::CompletedDate) ); 142 dict.insert("CompletedDate", new int(OPimTodo::CompletedDate) );
140 dict.insert("StartDate", new int(OPimTodo::StartDate) ); 143 dict.insert("StartDate", new int(OPimTodo::StartDate) );
141 dict.insert("CrossReference", new int(OPimTodo::CrossReference) ); 144 dict.insert("CrossReference", new int(OPimTodo::CrossReference) );
142 dict.insert("State", new int(OPimTodo::State) ); 145 dict.insert("State", new int(OPimTodo::State) );
143 dict.insert("Alarms", new int(OPimTodo::Alarms) ); 146 dict.insert("Alarms", new int(OPimTodo::Alarms) );
144 dict.insert("Reminders", new int(OPimTodo::Reminders) ); 147 dict.insert("Reminders", new int(OPimTodo::Reminders) );
145 dict.insert("Notifiers", new int(OPimTodo::Notifiers) );
146 dict.insert("Maintainer", new int(OPimTodo::Maintainer) ); 148 dict.insert("Maintainer", new int(OPimTodo::Maintainer) );
147 dict.insert("rtype", new int(FRType) ); 149 dict.insert("rtype", new int(FRType) );
148 dict.insert("rweekdays", new int(FRWeekdays) ); 150 dict.insert("rweekdays", new int(FRWeekdays) );
149 dict.insert("rposition", new int(FRPosition) ); 151 dict.insert("rposition", new int(FRPosition) );
150 dict.insert("rfreq", new int(FRFreq) ); 152 dict.insert("rfreq", new int(FRFreq) );
151 dict.insert("start", new int(FRStart) ); 153 dict.insert("start", new int(FRStart) );
152 dict.insert("rhasenddate", new int(FRHasEndDate) ); 154 dict.insert("rhasenddate", new int(FRHasEndDate) );
153 dict.insert("enddt", new int(FREndDate) ); 155 dict.insert("enddt", new int(FREndDate) );
154 156
155 // here the custom XML parser from TT it's GPL 157 // here the custom XML parser from TT it's GPL
156 // but we want to push OpiePIM... to TT..... 158 // but we want to push OpiePIM... to TT.....
157 // mmap part from zecke :) 159 // mmap part from zecke :)
@@ -173,25 +175,24 @@ bool OPimTodoAccessXML::load() {
173 /* we do not the file any more */ 175 /* we do not the file any more */
174 ::close( fd ); 176 ::close( fd );
175 177
176 char* dt = (char*)map_addr; 178 char* dt = (char*)map_addr;
177 int len = attribut.st_size; 179 int len = attribut.st_size;
178 int i = 0; 180 int i = 0;
179 char *point; 181 char *point;
180 const char* collectionString = "<Task "; 182 const char* collectionString = "<Task ";
181 int strLen = strlen(collectionString); 183 int strLen = strlen(collectionString);
182 while ( ( point = strstrlen( dt+i, len -i, collectionString, strLen ) ) != 0l ) { 184 while ( ( point = strstrlen( dt+i, len -i, collectionString, strLen ) ) != 0l ) {
183 i = point -dt; 185 i = point -dt;
184 i+= strLen; 186 i+= strLen;
185 owarn << "Found a start at " << i << " " << (point-dt) << "" << oendl;
186 187
187 OPimTodo ev; 188 OPimTodo ev;
188 m_year = m_month = m_day = 0; 189 m_year = m_month = m_day = 0;
189 190
190 while ( TRUE ) { 191 while ( TRUE ) {
191 while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) 192 while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') )
192 ++i; 193 ++i;
193 if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) 194 if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') )
194 break; 195 break;
195 196
196 // we have another attribute, read it. 197 // we have another attribute, read it.
197 int j = i; 198 int j = i;
@@ -229,58 +230,54 @@ bool OPimTodoAccessXML::load() {
229 if ( haveEnt ) 230 if ( haveEnt )
230 str = Qtopia::plainString( str ); 231 str = Qtopia::plainString( str );
231 232
232 /* 233 /*
233 * add key + value 234 * add key + value
234 */ 235 */
235 todo( &dict, ev, attr, str ); 236 todo( &dict, ev, attr, str );
236 237
237 } 238 }
238 /* 239 /*
239 * now add it 240 * now add it
240 */ 241 */
241 owarn << "End at " << i << "" << oendl;
242 if (m_events.contains( ev.uid() ) || ev.uid() == 0) { 242 if (m_events.contains( ev.uid() ) || ev.uid() == 0) {
243 ev.setUid( 1 ); 243 ev.setUid( 1 );
244 m_changed = true; 244 m_changed = true;
245 } 245 }
246 if ( ev.hasDueDate() ) { 246 if ( ev.hasDueDate() ) {
247 ev.setDueDate( QDate(m_year, m_month, m_day) ); 247 ev.setDueDate( QDate(m_year, m_month, m_day) );
248 } 248 }
249 if ( rec && rec->doesRecur() ) { 249 if ( rec && rec->doesRecur() ) {
250 OPimTimeZone utc = OPimTimeZone::utc(); 250 OPimTimeZone utc = OPimTimeZone::utc();
251 OPimRecurrence recu( *rec ); // call copy c'tor 251 OPimRecurrence recu( *rec ); // call copy c'tor
252 recu.setEndDate( utc.fromUTCDateTime( rp_end ).date() ); 252 recu.setEndDate( utc.fromUTCDateTime( rp_end ).date() );
253 recu.setStart( ev.dueDate() ); 253 recu.setStart( ev.dueDate() );
254 ev.setRecurrence( recu ); 254 ev.setRecurrence( recu );
255 } 255 }
256 m_events.insert(ev.uid(), ev ); 256 m_events.insert(ev.uid(), ev );
257 m_year = m_month = m_day = -1; 257 m_year = m_month = m_day = -1;
258 delete rec; 258 delete rec;
259 rec = 0; 259 rec = 0;
260 } 260 }
261 261
262 munmap(map_addr, attribut.st_size ); 262 munmap(map_addr, attribut.st_size );
263 263
264 owarn << "counts " << m_events.count() << " records loaded!" << oendl;
265 return true; 264 return true;
266} 265}
267bool OPimTodoAccessXML::reload() { 266bool OPimTodoAccessXML::reload() {
268 m_events.clear(); 267 m_events.clear();
269 return load(); 268 return load();
270} 269}
271bool OPimTodoAccessXML::save() { 270bool OPimTodoAccessXML::save() {
272// owarn << "saving" << oendl;
273 if (!m_opened || !m_changed ) { 271 if (!m_opened || !m_changed ) {
274// owarn << "not saving" << oendl;
275 return true; 272 return true;
276 } 273 }
277 QString strNewFile = m_file + ".new"; 274 QString strNewFile = m_file + ".new";
278 QFile f( strNewFile ); 275 QFile f( strNewFile );
279 if (!f.open( IO_WriteOnly|IO_Raw ) ) 276 if (!f.open( IO_WriteOnly|IO_Raw ) )
280 return false; 277 return false;
281 278
282 int written; 279 int written;
283 QString out; 280 QString out;
284 out = "<!DOCTYPE Tasks>\n<Tasks>\n"; 281 out = "<!DOCTYPE Tasks>\n<Tasks>\n";
285 282
286 // for all todos 283 // for all todos
@@ -303,128 +300,120 @@ bool OPimTodoAccessXML::save() {
303 QCString cstr = out.utf8(); 300 QCString cstr = out.utf8();
304 written = f.writeBlock( cstr.data(), cstr.length() ); 301 written = f.writeBlock( cstr.data(), cstr.length() );
305 302
306 if ( written != (int)cstr.length() ) { 303 if ( written != (int)cstr.length() ) {
307 f.close(); 304 f.close();
308 QFile::remove( strNewFile ); 305 QFile::remove( strNewFile );
309 return false; 306 return false;
310 } 307 }
311 /* flush before renaming */ 308 /* flush before renaming */
312 f.close(); 309 f.close();
313 310
314 if( ::rename( strNewFile.latin1(), m_file.latin1() ) < 0 ) { 311 if( ::rename( strNewFile.latin1(), m_file.latin1() ) < 0 ) {
315// owarn << "error renaming" << oendl;
316 QFile::remove( strNewFile ); 312 QFile::remove( strNewFile );
317 } 313 }
318 314
319 m_changed = false; 315 m_changed = false;
320 return true; 316 return true;
321} 317}
322QArray<int> OPimTodoAccessXML::allRecords()const { 318QArray<int> OPimTodoAccessXML::allRecords()const {
323 QArray<int> ids( m_events.count() ); 319 QArray<int> ids( m_events.count() );
324 QMap<int, OPimTodo>::ConstIterator it; 320 QMap<int, OPimTodo>::ConstIterator it;
325 int i = 0; 321 int i = 0;
326 322
327 for ( it = m_events.begin(); it != m_events.end(); ++it ) { 323 for ( it = m_events.begin(); it != m_events.end(); ++it )
328 ids[i] = it.key(); 324 ids[i++] = it.key();
329 i++; 325
330 } 326
331 return ids; 327 return ids;
332} 328}
333QArray<int> OPimTodoAccessXML::queryByExample( const OPimTodo&, int, const QDateTime& ) { 329QArray<int> OPimTodoAccessXML::queryByExample( const OPimTodo&, int, const QDateTime& ) {
334 QArray<int> ids(0); 330 QArray<int> ids(0);
335 return ids; 331 return ids;
336} 332}
337OPimTodo OPimTodoAccessXML::find( int uid )const { 333OPimTodo OPimTodoAccessXML::find( int uid )const {
338 OPimTodo todo; 334 OPimTodo todo;
339 todo.setUid( 0 ); // isEmpty() 335 todo.setUid( 0 ); // isEmpty()
340 QMap<int, OPimTodo>::ConstIterator it = m_events.find( uid ); 336 QMap<int, OPimTodo>::ConstIterator it = m_events.find( uid );
341 if ( it != m_events.end() ) 337 if ( it != m_events.end() )
342 todo = it.data(); 338 todo = it.data();
343 339
344 return todo; 340 return todo;
345} 341}
346void OPimTodoAccessXML::clear() { 342void OPimTodoAccessXML::clear() {
347 if (m_opened ) 343 if (m_opened )
348 m_changed = true; 344 m_changed = true;
349 345
350 m_events.clear(); 346 m_events.clear();
351} 347}
352bool OPimTodoAccessXML::add( const OPimTodo& todo ) { 348bool OPimTodoAccessXML::add( const OPimTodo& todo ) {
353// owarn << "add" << oendl;
354 m_changed = true; 349 m_changed = true;
355 m_events.insert( todo.uid(), todo ); 350 m_events.insert( todo.uid(), todo );
356 351
357 return true; 352 return true;
358} 353}
359bool OPimTodoAccessXML::remove( int uid ) { 354bool OPimTodoAccessXML::remove( int uid ) {
360 m_changed = true; 355 m_changed = true;
361 m_events.remove( uid ); 356 m_events.remove( uid );
362 357
363 return true; 358 return true;
364} 359}
365bool OPimTodoAccessXML::replace( const OPimTodo& todo) { 360bool OPimTodoAccessXML::replace( const OPimTodo& todo) {
366 m_changed = true; 361 m_changed = true;
367 m_events.replace( todo.uid(), todo ); 362 m_events.replace( todo.uid(), todo );
368 363
369 return true; 364 return true;
370} 365}
371QArray<int> OPimTodoAccessXML::effectiveToDos( const QDate& start, 366QArray<int> OPimTodoAccessXML::effectiveToDos( const QDate& start,
372 const QDate& end, 367 const QDate& end,
373 bool includeNoDates ) { 368 bool includeNoDates )const {
374 QArray<int> ids( m_events.count() ); 369 QArray<int> ids( m_events.count() );
375 QMap<int, OPimTodo>::Iterator it; 370 QMap<int, OPimTodo>::ConstIterator it;
376 371
377 int i = 0; 372 int i = 0;
378 for ( it = m_events.begin(); it != m_events.end(); ++it ) { 373 for ( it = m_events.begin(); it != m_events.end(); ++it ) {
379 if ( !it.data().hasDueDate() ) { 374 if ( !it.data().hasDueDate() && includeNoDates) {
380 if ( includeNoDates ) { 375 ids[i++] = it.key();
381 ids[i] = it.key();
382 i++;
383 }
384 }else if ( it.data().dueDate() >= start && 376 }else if ( it.data().dueDate() >= start &&
385 it.data().dueDate() <= end ) { 377 it.data().dueDate() <= end ) {
386 ids[i] = it.key(); 378 ids[i++] = it.key();
387 i++;
388 } 379 }
389 } 380 }
390 ids.resize( i ); 381 ids.resize( i );
391 return ids; 382 return ids;
392} 383}
393QArray<int> OPimTodoAccessXML::overDue() { 384QArray<int> OPimTodoAccessXML::overDue()const {
394 QArray<int> ids( m_events.count() ); 385 QArray<int> ids( m_events.count() );
395 int i = 0; 386 int i = 0;
396 387
397 QMap<int, OPimTodo>::Iterator it; 388 QMap<int, OPimTodo>::ConstIterator it;
398 for ( it = m_events.begin(); it != m_events.end(); ++it ) { 389 for ( it = m_events.begin(); it != m_events.end(); ++it ) {
399 if ( it.data().isOverdue() ) { 390 if ( it.data().isOverdue() ) {
400 ids[i] = it.key(); 391 ids[i] = it.key();
401 i++; 392 i++;
402 } 393 }
403 } 394 }
404 ids.resize( i ); 395 ids.resize( i );
405 return ids; 396 return ids;
406} 397}
407 398
408 399
409/* private */ 400/* private */
410void OPimTodoAccessXML::todo( QAsciiDict<int>* dict, OPimTodo& ev, 401void OPimTodoAccessXML::todo( QAsciiDict<int>* dict, OPimTodo& ev,
411 const QCString& attr, const QString& val) { 402 const QCString& attr, const QString& val) {
412// owarn << "parse to do from XMLElement" << oendl;
413 403
414 int *find=0; 404 int *find=0;
415 405
416 find = (*dict)[ attr.data() ]; 406 find = (*dict)[ attr.data() ];
417 if (!find ) { 407 if (!find ) {
418// owarn << "Unknown option" + it.key() << oendl;
419 ev.setCustomField( attr, val ); 408 ev.setCustomField( attr, val );
420 return; 409 return;
421 } 410 }
422 411
423 switch( *find ) { 412 switch( *find ) {
424 case OPimTodo::Uid: 413 case OPimTodo::Uid:
425 ev.setUid( val.toInt() ); 414 ev.setUid( val.toInt() );
426 break; 415 break;
427 case OPimTodo::Category: 416 case OPimTodo::Category:
428 ev.setCategories( ev.idsFromString( val ) ); 417 ev.setCategories( ev.idsFromString( val ) );
429 break; 418 break;
430 case OPimTodo::HasDate: 419 case OPimTodo::HasDate:
@@ -459,26 +448,24 @@ void OPimTodoAccessXML::todo( QAsciiDict<int>* dict, OPimTodo& ev,
459 break; 448 break;
460 case OPimTodo::StartDate: 449 case OPimTodo::StartDate:
461 ev.setStartDate( OPimDateConversion::dateFromString( val ) ); 450 ev.setStartDate( OPimDateConversion::dateFromString( val ) );
462 break; 451 break;
463 case OPimTodo::State: 452 case OPimTodo::State:
464 ev.setState( val.toInt() ); 453 ev.setState( val.toInt() );
465 break; 454 break;
466 case OPimTodo::Alarms:{ 455 case OPimTodo::Alarms:{
467 OPimNotifyManager &manager = ev.notifiers(); 456 OPimNotifyManager &manager = ev.notifiers();
468 QStringList als = QStringList::split(";", val ); 457 QStringList als = QStringList::split(";", val );
469 for (QStringList::Iterator it = als.begin(); it != als.end(); ++it ) { 458 for (QStringList::Iterator it = als.begin(); it != als.end(); ++it ) {
470 QStringList alarm = QStringList::split(":", (*it), TRUE ); // allow empty 459 QStringList alarm = QStringList::split(":", (*it), TRUE ); // allow empty
471 owarn << "alarm: " << alarm.join("___") << "" << oendl;
472 owarn << "alarm[0]: " << alarm[0] << " " << OPimDateConversion::dateTimeFromString( alarm[0] ).toString() << "" << oendl;
473 OPimAlarm al( alarm[2].toInt(), OPimDateConversion::dateTimeFromString( alarm[0] ), alarm[1].toInt() ); 460 OPimAlarm al( alarm[2].toInt(), OPimDateConversion::dateTimeFromString( alarm[0] ), alarm[1].toInt() );
474 manager.add( al ); 461 manager.add( al );
475 } 462 }
476 } 463 }
477 break; 464 break;
478 case OPimTodo::Reminders:{ 465 case OPimTodo::Reminders:{
479 OPimNotifyManager &manager = ev.notifiers(); 466 OPimNotifyManager &manager = ev.notifiers();
480 QStringList rems = QStringList::split(";", val ); 467 QStringList rems = QStringList::split(";", val );
481 for (QStringList::Iterator it = rems.begin(); it != rems.end(); ++it ) { 468 for (QStringList::Iterator it = rems.begin(); it != rems.end(); ++it ) {
482 OPimReminder rem( (*it).toInt() ); 469 OPimReminder rem( (*it).toInt() );
483 manager.add( rem ); 470 manager.add( rem );
484 } 471 }
@@ -533,29 +520,27 @@ void OPimTodoAccessXML::todo( QAsciiDict<int>* dict, OPimTodo& ev,
533 break; 520 break;
534 } 521 }
535 default: 522 default:
536 ev.setCustomField( attr, val ); 523 ev.setCustomField( attr, val );
537 break; 524 break;
538 } 525 }
539} 526}
540 527
541// from PalmtopRecord... GPL ### FIXME 528// from PalmtopRecord... GPL ### FIXME
542namespace { 529namespace {
543QString customToXml(const QMap<QString, QString>& customMap ) 530QString customToXml(const QMap<QString, QString>& customMap )
544{ 531{
545 //owarn << QString("writing custom %1").arg(customMap.count()) << oendl;
546 QString buf(" "); 532 QString buf(" ");
547 for ( QMap<QString, QString>::ConstIterator cit = customMap.begin(); 533 for ( QMap<QString, QString>::ConstIterator cit = customMap.begin();
548 cit != customMap.end(); ++cit) { 534 cit != customMap.end(); ++cit) {
549// owarn << ".ITEM." << oendl;
550 buf += cit.key(); 535 buf += cit.key();
551 buf += "=\""; 536 buf += "=\"";
552 buf += Qtopia::escapeString(cit.data()); 537 buf += Qtopia::escapeString(cit.data());
553 buf += "\" "; 538 buf += "\" ";
554 } 539 }
555 return buf; 540 return buf;
556} 541}
557 542
558 543
559} 544}
560 545
561QString OPimTodoAccessXML::toString( const OPimTodo& ev )const { 546QString OPimTodoAccessXML::toString( const OPimTodo& ev )const {
@@ -566,25 +551,24 @@ QString OPimTodoAccessXML::toString( const OPimTodo& ev )const {
566 str += "Priority=\"" + QString::number( ev.priority() ) + "\" "; 551 str += "Priority=\"" + QString::number( ev.priority() ) + "\" ";
567 str += "Progress=\"" + QString::number(ev.progress() ) + "\" "; 552 str += "Progress=\"" + QString::number(ev.progress() ) + "\" ";
568 553
569 str += "Categories=\"" + toString( ev.categories() ) + "\" "; 554 str += "Categories=\"" + toString( ev.categories() ) + "\" ";
570 str += "Description=\"" + Qtopia::escapeString( ev.description() ) + "\" "; 555 str += "Description=\"" + Qtopia::escapeString( ev.description() ) + "\" ";
571 str += "Summary=\"" + Qtopia::escapeString( ev.summary() ) + "\" "; 556 str += "Summary=\"" + Qtopia::escapeString( ev.summary() ) + "\" ";
572 557
573 if ( ev.hasDueDate() ) { 558 if ( ev.hasDueDate() ) {
574 str += "DateYear=\"" + QString::number( ev.dueDate().year() ) + "\" "; 559 str += "DateYear=\"" + QString::number( ev.dueDate().year() ) + "\" ";
575 str += "DateMonth=\"" + QString::number( ev.dueDate().month() ) + "\" "; 560 str += "DateMonth=\"" + QString::number( ev.dueDate().month() ) + "\" ";
576 str += "DateDay=\"" + QString::number( ev.dueDate().day() ) + "\" "; 561 str += "DateDay=\"" + QString::number( ev.dueDate().day() ) + "\" ";
577 } 562 }
578// owarn << "Uid " << ev.uid() << "" << oendl;
579 str += "Uid=\"" + QString::number( ev.uid() ) + "\" "; 563 str += "Uid=\"" + QString::number( ev.uid() ) + "\" ";
580 564
581// append the extra options 565// append the extra options
582 /* FIXME Qtopia::Record this is currently not 566 /* FIXME Qtopia::Record this is currently not
583 * possible you can set custom fields 567 * possible you can set custom fields
584 * but don' iterate over the list 568 * but don' iterate over the list
585 * I may do #define private protected 569 * I may do #define private protected
586 * for this case - cough --zecke 570 * for this case - cough --zecke
587 */ 571 */
588 /* 572 /*
589 QMap<QString, QString> extras = ev.extras(); 573 QMap<QString, QString> extras = ev.extras();
590 QMap<QString, QString>::Iterator extIt; 574 QMap<QString, QString>::Iterator extIt;
@@ -613,25 +597,24 @@ QString OPimTodoAccessXML::toString( const OPimTodo& ev )const {
613 QStringList als; 597 QStringList als;
614 OPimNotifyManager::Alarms::Iterator it = alarms.begin(); 598 OPimNotifyManager::Alarms::Iterator it = alarms.begin();
615 for ( ; it != alarms.end(); ++it ) { 599 for ( ; it != alarms.end(); ++it ) {
616 /* only if time is valid */ 600 /* only if time is valid */
617 if ( (*it).dateTime().isValid() ) { 601 if ( (*it).dateTime().isValid() ) {
618 als << OPimDateConversion::dateTimeToString( (*it).dateTime() ) 602 als << OPimDateConversion::dateTimeToString( (*it).dateTime() )
619 + ":" + QString::number( (*it).duration() ) 603 + ":" + QString::number( (*it).duration() )
620 + ":" + QString::number( (*it).sound() ) 604 + ":" + QString::number( (*it).sound() )
621 + ":"; 605 + ":";
622 } 606 }
623 } 607 }
624 // now write the list 608 // now write the list
625 owarn << "als: " << als.join("____________") << "" << oendl;
626 str += "Alarms=\""+als.join(";") +"\" "; 609 str += "Alarms=\""+als.join(";") +"\" ";
627 } 610 }
628 611
629 /* 612 /*
630 * now the same for reminders but more easy. We just save the uid of the OPimEvent. 613 * now the same for reminders but more easy. We just save the uid of the OPimEvent.
631 */ 614 */
632 OPimNotifyManager::Reminders reminders = manager.reminders(); 615 OPimNotifyManager::Reminders reminders = manager.reminders();
633 if (!reminders.isEmpty() ) { 616 if (!reminders.isEmpty() ) {
634 OPimNotifyManager::Reminders::Iterator it = reminders.begin(); 617 OPimNotifyManager::Reminders::Iterator it = reminders.begin();
635 QStringList records; 618 QStringList records;
636 for ( ; it != reminders.end(); ++it ) { 619 for ( ; it != reminders.end(); ++it ) {
637 records << QString::number( (*it).recordUid() ); 620 records << QString::number( (*it).recordUid() );
@@ -639,276 +622,99 @@ QString OPimTodoAccessXML::toString( const OPimTodo& ev )const {
639 str += "Reminders=\""+ records.join(";") +"\" "; 622 str += "Reminders=\""+ records.join(";") +"\" ";
640 } 623 }
641 } 624 }
642 str += customToXml( ev.toExtraMap() ); 625 str += customToXml( ev.toExtraMap() );
643 626
644 627
645 return str; 628 return str;
646} 629}
647QString OPimTodoAccessXML::toString( const QArray<int>& ints ) const { 630QString OPimTodoAccessXML::toString( const QArray<int>& ints ) const {
648 return Qtopia::Record::idsToString( ints ); 631 return Qtopia::Record::idsToString( ints );
649} 632}
650 633
651/* internal class for sorting
652 *
653 * Inspired by todoxmlio.cpp from TT
654 */
655 634
656struct OPimTodoXMLContainer { 635QArray<int> OPimTodoAccessXML::sorted( const UIDArray& events, bool asc,
657 OPimTodo todo; 636 int sortOrder,int sortFilter,
658}; 637 const QArray<int>& categories )const {
638 Internal::OPimTodoSortVector vector(events.count(), asc,sortOrder );
639 int item = 0;
659 640
660namespace { 641 bool bCat = sortFilter & OPimTodoAccess::FilterCategory ? true : false;
661 inline QString string( const OPimTodo& todo) { 642 bool bOnly = sortFilter & OPimTodoAccess::OnlyOverDue ? true : false;
662 return todo.summary().isEmpty() ? 643 bool comp = sortFilter & OPimTodoAccess::DoNotShowCompleted ? true : false;
663 todo.description().left(20 ) : 644 bool catPassed = false;
664 todo.summary(); 645 int cat;
665 }
666 inline int completed( const OPimTodo& todo1, const OPimTodo& todo2) {
667 int ret = 0;
668 if ( todo1.isCompleted() ) ret++;
669 if ( todo2.isCompleted() ) ret--;
670 return ret;
671 }
672 inline int priority( const OPimTodo& t1, const OPimTodo& t2) {
673 return ( t1.priority() - t2.priority() );
674 }
675 inline int description( const OPimTodo& t1, const OPimTodo& t2) {
676 return QString::compare( string(t1), string(t2) );
677 }
678 inline int deadline( const OPimTodo& t1, const OPimTodo& t2) {
679 int ret = 0;
680 if ( t1.hasDueDate() &&
681 t2.hasDueDate() )
682 ret = t2.dueDate().daysTo( t1.dueDate() );
683 else if ( t1.hasDueDate() )
684 ret = -1;
685 else if ( t2.hasDueDate() )
686 ret = 1;
687 else
688 ret = 0;
689 646
690 return ret; 647 for ( uint i = 0; i < events.count(); ++i ) {
691 } 648 /* Guard against creating a new item... */
649 if ( !m_events.contains( events[i] ) )
650 continue;
692 651
693}; 652 OPimTodo todo = m_events[events[i]];
694 653
695/* 654 /* show category */
696 * Returns: 655 /* -1 == unfiled */
697 * 0 if item1 == item2 656 catPassed = false;
698 * 657 for ( uint cat_nu = 0; cat_nu < categories.count(); ++cat_nu ) {
699 * non-zero if item1 != item2 658 cat = categories[cat_nu];
700 * 659 if ( bCat && cat == -1 ) {
701 * This function returns int rather than bool so that reimplementations 660 if(!todo.categories().isEmpty() )
702 * can return one of three values and use it to sort by: 661 continue;
703 * 662 } else if ( bCat && cat != 0)
704 * 0 if item1 == item2 663 if (!todo.categories().contains( cat ) )
705 * 664 continue;
706 * > 0 (positive integer) if item1 > item2 665 catPassed = true;
707 *
708 * < 0 (negative integer) if item1 < item2
709 *
710 */
711class OPimTodoXMLVector : public QVector<OPimTodoXMLContainer> {
712public:
713 OPimTodoXMLVector(int size, bool asc, int sort)
714 : QVector<OPimTodoXMLContainer>( size )
715 {
716 setAutoDelete( true );
717 m_asc = asc;
718 m_sort = sort;
719 }
720 /* return the summary/description */
721 QString string( const OPimTodo& todo) {
722 return todo.summary().isEmpty() ?
723 todo.description().left(20 ) :
724 todo.summary();
725 }
726 /**
727 * we take the sortorder( switch on it )
728 *
729 */
730 int compareItems( Item d1, Item d2 ) {
731 bool seComp, sePrio, seDesc, seDeadline;
732 seComp = sePrio = seDeadline = seDesc = false;
733 int ret =0;
734 OPimTodoXMLContainer* con1 = (OPimTodoXMLContainer*)d1;
735 OPimTodoXMLContainer* con2 = (OPimTodoXMLContainer*)d2;
736
737 /* same item */
738 if ( con1->todo.uid() == con2->todo.uid() )
739 return 0;
740
741 switch ( m_sort ) {
742 /* completed */
743 case 0: {
744 ret = completed( con1->todo, con2->todo );
745 seComp = TRUE;
746 break;
747 }
748 /* priority */
749 case 1: {
750 ret = priority( con1->todo, con2->todo );
751 sePrio = TRUE;
752 break;
753 }
754 /* description */
755 case 2: {
756 ret = description( con1->todo, con2->todo );
757 seDesc = TRUE;
758 break;
759 }
760 /* deadline */
761 case 3: {
762 ret = deadline( con1->todo, con2->todo );
763 seDeadline = TRUE;
764 break; 666 break;
765 } 667 }
766 default:
767 ret = 0;
768 break;
769 };
770 /*
771 * FIXME do better sorting if the first sort criteria
772 * ret equals 0 start with complete and so on...
773 */
774
775 /* twist it we're not ascending*/
776 if (!m_asc)
777 ret = ret * -1;
778 668
779 if ( ret )
780 return ret;
781
782 // default did not gave difference let's try it other way around
783 /* 669 /*
784 * General try if already checked if not test 670 * If none of the Categories matched
785 * and return 671 * continue
786 * 1.Completed
787 * 2.Priority
788 * 3.Description
789 * 4.DueDate
790 */ 672 */
791 if (!seComp ) { 673 if ( !catPassed )
792 if ( (ret = completed( con1->todo, con2->todo ) ) ) {
793 if (!m_asc ) ret *= -1;
794 return ret;
795 }
796 }
797 if (!sePrio ) {
798 if ( (ret = priority( con1->todo, con2->todo ) ) ) {
799 if (!m_asc ) ret *= -1;
800 return ret;
801 }
802 }
803 if (!seDesc ) {
804 if ( (ret = description(con1->todo, con2->todo ) ) ) {
805 if (!m_asc) ret *= -1;
806 return ret;
807 }
808 }
809 if (!seDeadline) {
810 if ( (ret = deadline( con1->todo, con2->todo ) ) ) {
811 if (!m_asc) ret *= -1;
812 return ret;
813 }
814 }
815
816 return 0;
817 }
818 private:
819 bool m_asc;
820 int m_sort;
821
822};
823
824QArray<int> OPimTodoAccessXML::sorted( bool asc, int sortOrder,
825 int sortFilter, int cat ) {
826 OPimTodoXMLVector vector(m_events.count(), asc,sortOrder );
827 QMap<int, OPimTodo>::Iterator it;
828 int item = 0;
829
830 bool bCat = sortFilter & 1 ? true : false;
831 bool bOnly = sortFilter & 2 ? true : false;
832 bool comp = sortFilter & 4 ? true : false;
833 for ( it = m_events.begin(); it != m_events.end(); ++it ) {
834
835 /* show category */
836 /* -1 == unfiled */
837 if ( bCat && cat == -1 ) {
838 if(!(*it).categories().isEmpty() )
839 continue;
840 }else if ( bCat && cat != 0)
841 if (!(*it).categories().contains( cat ) ) {
842 continue;
843 }
844 /* isOverdue but we should not show overdue - why?*/
845/* if ( (*it).isOverdue() && !bOnly ) {
846 owarn << "item is overdue but !bOnly" << oendl;
847 continue; 674 continue;
848 } 675 if ( !todo.isOverdue() && bOnly )
849*/
850 if ( !(*it).isOverdue() && bOnly ) {
851 continue; 676 continue;
852 } 677 if (todo.isCompleted() && comp )
853
854 if ((*it).isCompleted() && comp ) {
855 continue; 678 continue;
856 }
857 679
858 680 vector.insert(item++, todo );
859 OPimTodoXMLContainer* con = new OPimTodoXMLContainer();
860 con->todo = (*it);
861 vector.insert(item, con );
862 item++;
863 } 681 }
682
864 vector.resize( item ); 683 vector.resize( item );
865 /* sort it now */ 684 /* sort it now */
866 vector.sort(); 685 vector.sort();
867 /* now get the uids */ 686 /* now get the uids */
868 QArray<int> array( vector.count() ); 687 UIDArray array( vector.count() );
869 for (uint i= 0; i < vector.count(); i++ ) { 688 for (uint i= 0; i < vector.count(); i++ )
870 array[i] = ( vector.at(i) )->todo.uid(); 689 array[i] = vector.uidAt( i );
871 } 690
872 return array; 691 return array;
873}; 692}
693
874void OPimTodoAccessXML::removeAllCompleted() { 694void OPimTodoAccessXML::removeAllCompleted() {
875 QMap<int, OPimTodo> events = m_events; 695 QMap<int, OPimTodo> events = m_events;
876 for ( QMap<int, OPimTodo>::Iterator it = m_events.begin(); it != m_events.end(); ++it ) { 696 for ( QMap<int, OPimTodo>::Iterator it = m_events.begin(); it != m_events.end(); ++it ) {
877 if ( (*it).isCompleted() ) 697 if ( (*it).isCompleted() )
878 events.remove( it.key() ); 698 events.remove( it.key() );
879 } 699 }
880 m_events = events; 700 m_events = events;
881} 701}
882QBitArray OPimTodoAccessXML::supports()const { 702
883 static QBitArray ar = sup();
884 return ar;
885}
886QBitArray OPimTodoAccessXML::sup() {
887 QBitArray ar( OPimTodo::CompletedDate +1 );
888 ar.fill( true );
889 ar[OPimTodo::CrossReference] = false;
890 ar[OPimTodo::State ] = false;
891 ar[OPimTodo::Reminders] = false;
892 ar[OPimTodo::Notifiers] = false;
893 ar[OPimTodo::Maintainer] = false;
894
895 return ar;
896}
897QArray<int> OPimTodoAccessXML::matchRegexp( const QRegExp &r ) const 703QArray<int> OPimTodoAccessXML::matchRegexp( const QRegExp &r ) const
898{ 704{
899 QArray<int> m_currentQuery( m_events.count() ); 705 QArray<int> currentQuery( m_events.count() );
900 uint arraycounter = 0; 706 uint arraycounter = 0;
901 707
902 QMap<int, OPimTodo>::ConstIterator it; 708 QMap<int, OPimTodo>::ConstIterator it;
903 for (it = m_events.begin(); it != m_events.end(); ++it ) { 709 for (it = m_events.begin(); it != m_events.end(); ++it ) {
904 if ( it.data().match( r ) ) 710 if ( it.data().match( r ) )
905 m_currentQuery[arraycounter++] = it.data().uid(); 711 currentQuery[arraycounter++] = it.data().uid();
906 712
907 } 713 }
908 // Shrink to fit.. 714 // Shrink to fit..
909 m_currentQuery.resize(arraycounter); 715 currentQuery.resize(arraycounter);
910 716
911 return m_currentQuery; 717 return currentQuery;
912} 718}
913 719
914} 720}