summaryrefslogtreecommitdiff
authorzecke <zecke>2002-10-18 20:49:06 (UTC)
committer zecke <zecke>2002-10-18 20:49:06 (UTC)
commita680c9464bbdea863b623b0449a15146ccaf66c0 (patch) (unidiff)
tree3a71b9172b3ebee7cdd07a9ed119fe9504580494
parent1b84985ad03a39a82c5dc6a80a88e2c73ef14355 (diff)
downloadopie-a680c9464bbdea863b623b0449a15146ccaf66c0.zip
opie-a680c9464bbdea863b623b0449a15146ccaf66c0.tar.gz
opie-a680c9464bbdea863b623b0449a15146ccaf66c0.tar.bz2
Fix sorting
Now if one columns equals another we try harder to find a difference Fixed DueDate sorting... This makes the UI more appealing
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libopie/pim/otodoaccessxml.cpp120
-rw-r--r--libopie2/opiepim/backend/otodoaccessxml.cpp120
2 files changed, 188 insertions, 52 deletions
diff --git a/libopie/pim/otodoaccessxml.cpp b/libopie/pim/otodoaccessxml.cpp
index 385fd27..591e467 100644
--- a/libopie/pim/otodoaccessxml.cpp
+++ b/libopie/pim/otodoaccessxml.cpp
@@ -314,253 +314,321 @@ void OTodoAccessXML::todo( QAsciiDict<int>* dict, OTodo& ev,
314 m_month = val.toInt(); 314 m_month = val.toInt();
315 break; 315 break;
316 case OTodo::DateYear: 316 case OTodo::DateYear:
317 m_year = val.toInt(); 317 m_year = val.toInt();
318 break; 318 break;
319 case OTodo::Progress: 319 case OTodo::Progress:
320 ev.setProgress( val.toInt() ); 320 ev.setProgress( val.toInt() );
321 break; 321 break;
322 case OTodo::CrossReference: 322 case OTodo::CrossReference:
323 { 323 {
324 /* 324 /*
325 * A cross refernce looks like 325 * A cross refernce looks like
326 * appname,id;appname,id 326 * appname,id;appname,id
327 * we need to split it up 327 * we need to split it up
328 */ 328 */
329 QStringList refs = QStringList::split(';', val ); 329 QStringList refs = QStringList::split(';', val );
330 QStringList::Iterator strIt; 330 QStringList::Iterator strIt;
331 for (strIt = refs.begin(); strIt != refs.end(); ++strIt ) { 331 for (strIt = refs.begin(); strIt != refs.end(); ++strIt ) {
332 int pos = (*strIt).find(','); 332 int pos = (*strIt).find(',');
333 if ( pos > -1 ) 333 if ( pos > -1 )
334 ev.addRelation( (*strIt).left(pos), (*strIt).mid(pos+1).toInt() ); 334 ev.addRelation( (*strIt).left(pos), (*strIt).mid(pos+1).toInt() );
335 335
336 } 336 }
337 break; 337 break;
338 } 338 }
339 case OTodo::HasAlarmDateTime: 339 case OTodo::HasAlarmDateTime:
340 ev.setHasAlarmDateTime( val.toInt() ); 340 ev.setHasAlarmDateTime( val.toInt() );
341 break; 341 break;
342 case OTodo::AlarmDateTime: { 342 case OTodo::AlarmDateTime: {
343 /* this sounds better ;) zecke */ 343 /* this sounds better ;) zecke */
344 ev.setAlarmDateTime( TimeConversion::fromISO8601( val.local8Bit() ) ); 344 ev.setAlarmDateTime( TimeConversion::fromISO8601( val.local8Bit() ) );
345 break; 345 break;
346 } 346 }
347 default: 347 default:
348 break; 348 break;
349 } 349 }
350} 350}
351QString OTodoAccessXML::toString( const OTodo& ev )const { 351QString OTodoAccessXML::toString( const OTodo& ev )const {
352 QString str; 352 QString str;
353 353
354 str += "Completed=\"" + QString::number( ev.isCompleted() ) + "\" "; 354 str += "Completed=\"" + QString::number( ev.isCompleted() ) + "\" ";
355 str += "HasDate=\"" + QString::number( ev.hasDueDate() ) + "\" "; 355 str += "HasDate=\"" + QString::number( ev.hasDueDate() ) + "\" ";
356 str += "Priority=\"" + QString::number( ev.priority() ) + "\" "; 356 str += "Priority=\"" + QString::number( ev.priority() ) + "\" ";
357 str += "Progress=\"" + QString::number(ev.progress() ) + "\" "; 357 str += "Progress=\"" + QString::number(ev.progress() ) + "\" ";
358 358
359 str += "Categories=\"" + toString( ev.categories() ) + "\" "; 359 str += "Categories=\"" + toString( ev.categories() ) + "\" ";
360 str += "Description=\"" + Qtopia::escapeString( ev.description() ) + "\" "; 360 str += "Description=\"" + Qtopia::escapeString( ev.description() ) + "\" ";
361 str += "Summary=\"" + Qtopia::escapeString( ev.summary() ) + "\" "; 361 str += "Summary=\"" + Qtopia::escapeString( ev.summary() ) + "\" ";
362 362
363 if ( ev.hasDueDate() ) { 363 if ( ev.hasDueDate() ) {
364 str += "DateYear=\"" + QString::number( ev.dueDate().year() ) + "\" "; 364 str += "DateYear=\"" + QString::number( ev.dueDate().year() ) + "\" ";
365 str += "DateMonth=\"" + QString::number( ev.dueDate().month() ) + "\" "; 365 str += "DateMonth=\"" + QString::number( ev.dueDate().month() ) + "\" ";
366 str += "DateDay=\"" + QString::number( ev.dueDate().day() ) + "\" "; 366 str += "DateDay=\"" + QString::number( ev.dueDate().day() ) + "\" ";
367 } 367 }
368// qWarning( "Uid %d", ev.uid() ); 368// qWarning( "Uid %d", ev.uid() );
369 str += "Uid=\"" + QString::number( ev.uid() ) + "\" "; 369 str += "Uid=\"" + QString::number( ev.uid() ) + "\" ";
370 370
371// append the extra options 371// append the extra options
372 /* FIXME Qtopia::Record this is currently not 372 /* FIXME Qtopia::Record this is currently not
373 * possible you can set custom fields 373 * possible you can set custom fields
374 * but don' iterate over the list 374 * but don' iterate over the list
375 * I may do #define private protected 375 * I may do #define private protected
376 * for this case - cough --zecke 376 * for this case - cough --zecke
377 */ 377 */
378 /* 378 /*
379 QMap<QString, QString> extras = ev.extras(); 379 QMap<QString, QString> extras = ev.extras();
380 QMap<QString, QString>::Iterator extIt; 380 QMap<QString, QString>::Iterator extIt;
381 for (extIt = extras.begin(); extIt != extras.end(); ++extIt ) 381 for (extIt = extras.begin(); extIt != extras.end(); ++extIt )
382 str += extIt.key() + "=\"" + extIt.data() + "\" "; 382 str += extIt.key() + "=\"" + extIt.data() + "\" ";
383 */ 383 */
384 // cross refernce 384 // cross refernce
385 QStringList list = ev.relatedApps(); 385 QStringList list = ev.relatedApps();
386 QStringList::Iterator listIt; 386 QStringList::Iterator listIt;
387 QString refs; 387 QString refs;
388 str += "CrossReference=\""; 388 str += "CrossReference=\"";
389 bool added = false; 389 bool added = false;
390 for ( listIt = list.begin(); listIt != list.end(); ++listIt ) { 390 for ( listIt = list.begin(); listIt != list.end(); ++listIt ) {
391 added = true; 391 added = true;
392 QArray<int> ints = ev.relations( (*listIt) ); 392 QArray<int> ints = ev.relations( (*listIt) );
393 for ( uint i = 0; i< ints.count(); i++ ) { 393 for ( uint i = 0; i< ints.count(); i++ ) {
394 str += (*listIt) + "," + QString::number( i ) + ";"; 394 str += (*listIt) + "," + QString::number( i ) + ";";
395 } 395 }
396 } 396 }
397 if ( added ) 397 if ( added )
398 str = str.remove( str.length()-1, 1 ); 398 str = str.remove( str.length()-1, 1 );
399 399
400 str += "\" "; 400 str += "\" ";
401 401
402 str += "AlarmDateTime=\"" + TimeConversion::toISO8601( ev.alarmDateTime() ) + "\" "; 402 str += "AlarmDateTime=\"" + TimeConversion::toISO8601( ev.alarmDateTime() ) + "\" ";
403 403
404 return str; 404 return str;
405} 405}
406QString OTodoAccessXML::toString( const QArray<int>& ints ) const { 406QString OTodoAccessXML::toString( const QArray<int>& ints ) const {
407 return Qtopia::Record::idsToString( ints ); 407 return Qtopia::Record::idsToString( ints );
408} 408}
409 409
410/* internal class for sorting */ 410/* internal class for sorting
411 *
412 * Inspired by todoxmlio.cpp from TT
413 */
411 414
412struct OTodoXMLContainer { 415struct OTodoXMLContainer {
413 OTodo todo; 416 OTodo todo;
414}; 417};
415 /* 418
419namespace {
420 inline QString string( const OTodo& todo) {
421 return todo.summary().isEmpty() ?
422 todo.description().left(20 ) :
423 todo.summary();
424 }
425 inline int completed( const OTodo& todo1, const OTodo& todo2) {
426 int ret = 0;
427 if ( todo1.isCompleted() ) ret++;
428 if ( todo2.isCompleted() ) ret--;
429 return ret;
430 }
431 inline int priority( const OTodo& t1, const OTodo& t2) {
432 return ( t1.priority() - t2.priority() );
433 }
434 inline int description( const OTodo& t1, const OTodo& t2) {
435 return QString::compare( string(t1), string(t2) );
436 }
437 inline int deadline( const OTodo& t1, const OTodo& t2) {
438 int ret = 0;
439 if ( t1.hasDueDate() &&
440 t2.hasDueDate() )
441 ret = t2.dueDate().daysTo( t1.dueDate() );
442 else if ( t1.hasDueDate() )
443 ret = -1;
444 else if ( t2.hasDueDate() )
445 ret = 1;
446 else
447 ret = 0;
448
449 return ret;
450 }
451
452};
453
454/*
416 * Returns: 455 * Returns:
417 * 0 if item1 == item2 456 * 0 if item1 == item2
418 * 457 *
419 * non-zero if item1 != item2 458 * non-zero if item1 != item2
420 * 459 *
421 * This function returns int rather than bool so that reimplementations 460 * This function returns int rather than bool so that reimplementations
422 * can return one of three values and use it to sort by: 461 * can return one of three values and use it to sort by:
423 * 462 *
424 * 0 if item1 == item2 463 * 0 if item1 == item2
425 * 464 *
426 * > 0 (positive integer) if item1 > item2 465 * > 0 (positive integer) if item1 > item2
427 * 466 *
428 * < 0 (negative integer) if item1 < item2 467 * < 0 (negative integer) if item1 < item2
429 * 468 *
430 */ 469 */
431class OTodoXMLVector : public QVector<OTodoXMLContainer> { 470class OTodoXMLVector : public QVector<OTodoXMLContainer> {
432public: 471public:
433 OTodoXMLVector(int size, bool asc, int sort) 472 OTodoXMLVector(int size, bool asc, int sort)
434 : QVector<OTodoXMLContainer>( size ) 473 : QVector<OTodoXMLContainer>( size )
435 { 474 {
436 setAutoDelete( true ); 475 setAutoDelete( true );
437 m_asc = asc; 476 m_asc = asc;
438 m_sort = sort; 477 m_sort = sort;
439 } 478 }
440 /* return the summary/description */ 479 /* return the summary/description */
441 QString string( const OTodo& todo) { 480 QString string( const OTodo& todo) {
442 return todo.summary().isEmpty() ? 481 return todo.summary().isEmpty() ?
443 todo.description().left(20 ) : 482 todo.description().left(20 ) :
444 todo.summary(); 483 todo.summary();
445 } 484 }
446 /** 485 /**
447 * we take the sortorder( switch on it ) 486 * we take the sortorder( switch on it )
448 * 487 *
449 */ 488 */
450 int compareItems( Item d1, Item d2 ) { 489 int compareItems( Item d1, Item d2 ) {
490 bool seComp, sePrio, seDesc, seDeadline;
491 seComp = sePrio = seDeadline = seDesc = false;
451 int ret =0; 492 int ret =0;
452 OTodoXMLContainer* con1 = (OTodoXMLContainer*)d1; 493 OTodoXMLContainer* con1 = (OTodoXMLContainer*)d1;
453 OTodoXMLContainer* con2 = (OTodoXMLContainer*)d2; 494 OTodoXMLContainer* con2 = (OTodoXMLContainer*)d2;
454 495
455 /* same item */ 496 /* same item */
456 if ( con1->todo.uid() == con2->todo.uid() ) 497 if ( con1->todo.uid() == con2->todo.uid() )
457 return 0; 498 return 0;
458 499
459 switch ( m_sort ) { 500 switch ( m_sort ) {
460 /* completed */ 501 /* completed */
461 case 0: { 502 case 0: {
462 ret = 0; 503 ret = completed( con1->todo, con2->todo );
463 if ( con1->todo.isCompleted() ) ret++; 504 seComp = TRUE;
464 if ( con2->todo.isCompleted() ) ret--;
465 break; 505 break;
466 } 506 }
467 /* priority */ 507 /* priority */
468 case 1: { 508 case 1: {
469 ret = con1->todo.priority() - con2->todo.priority(); 509 ret = priority( con1->todo, con2->todo );
470 qWarning(" priority %d %d %d", ret, 510 sePrio = TRUE;
471 con1->todo.priority(),
472 con2->todo.priority()
473 );
474 break; 511 break;
475 } 512 }
476 /* description */ 513 /* description */
477 case 2: { 514 case 2: {
478 QString str1 = string( con1->todo ); 515 ret = description( con1->todo, con2->todo );
479 QString str2 = string( con2->todo ); 516 seDesc = TRUE;
480 ret = QString::compare( str1, str2 );
481 break; 517 break;
482 } 518 }
483 /* deadline */ 519 /* deadline */
484 case 3: { 520 case 3: {
485 /* either bot got a dueDate 521 ret = deadline( con1->todo, con2->todo );
486 * or one of them got one 522 seDeadline = TRUE;
487 */
488 if ( con1->todo.hasDueDate() &&
489 con2->todo.hasDueDate() )
490 ret = con1->todo.dueDate().daysTo( con2->todo.dueDate() );
491
492
493 else if ( con1->todo.hasDueDate() )
494 ret = -1;
495 else if ( con2->todo.hasDueDate() )
496 ret = 0;
497 break; 523 break;
498 } 524 }
499 default: 525 default:
500 ret = 0; 526 ret = 0;
501 break; 527 break;
502 }; 528 };
529 /*
530 * FIXME do better sorting if the first sort criteria
531 * ret equals 0 start with complete and so on...
532 */
503 533
504 /* twist it we're not ascending*/ 534 /* twist it we're not ascending*/
505 if (!m_asc) 535 if (!m_asc)
506 ret = ret * -1; 536 ret = ret * -1;
507 return ret; 537
538 if ( ret )
539 return ret;
540
541 // default did not gave difference let's try it other way around
542 /*
543 * General try if already checked if not test
544 * and return
545 * 1.Completed
546 * 2.Priority
547 * 3.Description
548 * 4.DueDate
549 */
550 if (!seComp ) {
551 if ( (ret = completed( con1->todo, con2->todo ) ) ) {
552 if (!m_asc ) ret *= -1;
553 return ret;
554 }
555 }
556 if (!sePrio ) {
557 if ( (ret = priority( con1->todo, con2->todo ) ) ) {
558 if (!m_asc ) ret *= -1;
559 return ret;
560 }
561 }
562 if (!seDesc ) {
563 if ( (ret = description(con1->todo, con2->todo ) ) ) {
564 if (!m_asc) ret *= -1;
565 return ret;
566 }
567 }
568 if (!seDeadline) {
569 if ( (ret = deadline( con1->todo, con2->todo ) ) ) {
570 if (!m_asc) ret *= -1;
571 return ret;
572 }
573 }
574
575 return 0;
508 } 576 }
509 private: 577 private:
510 bool m_asc; 578 bool m_asc;
511 int m_sort; 579 int m_sort;
512 580
513}; 581};
514 582
515QArray<int> OTodoAccessXML::sorted( bool asc, int sortOrder, 583QArray<int> OTodoAccessXML::sorted( bool asc, int sortOrder,
516 int sortFilter, int cat ) { 584 int sortFilter, int cat ) {
517 qWarning("sorted! %d cat", cat); 585 qWarning("sorted! %d cat", cat);
518 OTodoXMLVector vector(m_events.count(), asc,sortOrder ); 586 OTodoXMLVector vector(m_events.count(), asc,sortOrder );
519 QMap<int, OTodo>::Iterator it; 587 QMap<int, OTodo>::Iterator it;
520 int item = 0; 588 int item = 0;
521 589
522 bool bCat = sortFilter & 1 ? true : false; 590 bool bCat = sortFilter & 1 ? true : false;
523 bool bOnly = sortFilter & 2 ? true : false; 591 bool bOnly = sortFilter & 2 ? true : false;
524 bool comp = sortFilter & 4 ? true : false; 592 bool comp = sortFilter & 4 ? true : false;
525 for ( it = m_events.begin(); it != m_events.end(); ++it ) { 593 for ( it = m_events.begin(); it != m_events.end(); ++it ) {
526 594
527 /* show category */ 595 /* show category */
528 if ( bCat && cat != 0) 596 if ( bCat && cat != 0)
529 if (!(*it).categories().contains( cat ) ) { 597 if (!(*it).categories().contains( cat ) ) {
530 qWarning("category mis match"); 598 qWarning("category mis match");
531 continue; 599 continue;
532 } 600 }
533 /* isOverdue but we should not show overdue - why?*/ 601 /* isOverdue but we should not show overdue - why?*/
534/* if ( (*it).isOverdue() && !bOnly ) { 602/* if ( (*it).isOverdue() && !bOnly ) {
535 qWarning("item is overdue but !bOnly"); 603 qWarning("item is overdue but !bOnly");
536 continue; 604 continue;
537 } 605 }
538*/ 606*/
539 if ( !(*it).isOverdue() && bOnly ) { 607 if ( !(*it).isOverdue() && bOnly ) {
540 qWarning("item is not overdue but bOnly checked"); 608 qWarning("item is not overdue but bOnly checked");
541 continue; 609 continue;
542 } 610 }
543 611
544 if ((*it).isCompleted() && comp ) { 612 if ((*it).isCompleted() && comp ) {
545 qWarning("completed continue!"); 613 qWarning("completed continue!");
546 continue; 614 continue;
547 } 615 }
548 616
549 617
550 OTodoXMLContainer* con = new OTodoXMLContainer(); 618 OTodoXMLContainer* con = new OTodoXMLContainer();
551 con->todo = (*it); 619 con->todo = (*it);
552 vector.insert(item, con ); 620 vector.insert(item, con );
553 item++; 621 item++;
554 } 622 }
555 qWarning("XXX %d Items added", item); 623 qWarning("XXX %d Items added", item);
556 vector.resize( item ); 624 vector.resize( item );
557 /* sort it now */ 625 /* sort it now */
558 vector.sort(); 626 vector.sort();
559 /* now get the uids */ 627 /* now get the uids */
560 QArray<int> array( vector.count() ); 628 QArray<int> array( vector.count() );
561 for (uint i= 0; i < vector.count(); i++ ) { 629 for (uint i= 0; i < vector.count(); i++ ) {
562 array[i] = ( vector.at(i) )->todo.uid(); 630 array[i] = ( vector.at(i) )->todo.uid();
563 } 631 }
564 qWarning("array count = %d %d", array.count(), vector.count() ); 632 qWarning("array count = %d %d", array.count(), vector.count() );
565 return array; 633 return array;
566}; 634};
diff --git a/libopie2/opiepim/backend/otodoaccessxml.cpp b/libopie2/opiepim/backend/otodoaccessxml.cpp
index 385fd27..591e467 100644
--- a/libopie2/opiepim/backend/otodoaccessxml.cpp
+++ b/libopie2/opiepim/backend/otodoaccessxml.cpp
@@ -314,253 +314,321 @@ void OTodoAccessXML::todo( QAsciiDict<int>* dict, OTodo& ev,
314 m_month = val.toInt(); 314 m_month = val.toInt();
315 break; 315 break;
316 case OTodo::DateYear: 316 case OTodo::DateYear:
317 m_year = val.toInt(); 317 m_year = val.toInt();
318 break; 318 break;
319 case OTodo::Progress: 319 case OTodo::Progress:
320 ev.setProgress( val.toInt() ); 320 ev.setProgress( val.toInt() );
321 break; 321 break;
322 case OTodo::CrossReference: 322 case OTodo::CrossReference:
323 { 323 {
324 /* 324 /*
325 * A cross refernce looks like 325 * A cross refernce looks like
326 * appname,id;appname,id 326 * appname,id;appname,id
327 * we need to split it up 327 * we need to split it up
328 */ 328 */
329 QStringList refs = QStringList::split(';', val ); 329 QStringList refs = QStringList::split(';', val );
330 QStringList::Iterator strIt; 330 QStringList::Iterator strIt;
331 for (strIt = refs.begin(); strIt != refs.end(); ++strIt ) { 331 for (strIt = refs.begin(); strIt != refs.end(); ++strIt ) {
332 int pos = (*strIt).find(','); 332 int pos = (*strIt).find(',');
333 if ( pos > -1 ) 333 if ( pos > -1 )
334 ev.addRelation( (*strIt).left(pos), (*strIt).mid(pos+1).toInt() ); 334 ev.addRelation( (*strIt).left(pos), (*strIt).mid(pos+1).toInt() );
335 335
336 } 336 }
337 break; 337 break;
338 } 338 }
339 case OTodo::HasAlarmDateTime: 339 case OTodo::HasAlarmDateTime:
340 ev.setHasAlarmDateTime( val.toInt() ); 340 ev.setHasAlarmDateTime( val.toInt() );
341 break; 341 break;
342 case OTodo::AlarmDateTime: { 342 case OTodo::AlarmDateTime: {
343 /* this sounds better ;) zecke */ 343 /* this sounds better ;) zecke */
344 ev.setAlarmDateTime( TimeConversion::fromISO8601( val.local8Bit() ) ); 344 ev.setAlarmDateTime( TimeConversion::fromISO8601( val.local8Bit() ) );
345 break; 345 break;
346 } 346 }
347 default: 347 default:
348 break; 348 break;
349 } 349 }
350} 350}
351QString OTodoAccessXML::toString( const OTodo& ev )const { 351QString OTodoAccessXML::toString( const OTodo& ev )const {
352 QString str; 352 QString str;
353 353
354 str += "Completed=\"" + QString::number( ev.isCompleted() ) + "\" "; 354 str += "Completed=\"" + QString::number( ev.isCompleted() ) + "\" ";
355 str += "HasDate=\"" + QString::number( ev.hasDueDate() ) + "\" "; 355 str += "HasDate=\"" + QString::number( ev.hasDueDate() ) + "\" ";
356 str += "Priority=\"" + QString::number( ev.priority() ) + "\" "; 356 str += "Priority=\"" + QString::number( ev.priority() ) + "\" ";
357 str += "Progress=\"" + QString::number(ev.progress() ) + "\" "; 357 str += "Progress=\"" + QString::number(ev.progress() ) + "\" ";
358 358
359 str += "Categories=\"" + toString( ev.categories() ) + "\" "; 359 str += "Categories=\"" + toString( ev.categories() ) + "\" ";
360 str += "Description=\"" + Qtopia::escapeString( ev.description() ) + "\" "; 360 str += "Description=\"" + Qtopia::escapeString( ev.description() ) + "\" ";
361 str += "Summary=\"" + Qtopia::escapeString( ev.summary() ) + "\" "; 361 str += "Summary=\"" + Qtopia::escapeString( ev.summary() ) + "\" ";
362 362
363 if ( ev.hasDueDate() ) { 363 if ( ev.hasDueDate() ) {
364 str += "DateYear=\"" + QString::number( ev.dueDate().year() ) + "\" "; 364 str += "DateYear=\"" + QString::number( ev.dueDate().year() ) + "\" ";
365 str += "DateMonth=\"" + QString::number( ev.dueDate().month() ) + "\" "; 365 str += "DateMonth=\"" + QString::number( ev.dueDate().month() ) + "\" ";
366 str += "DateDay=\"" + QString::number( ev.dueDate().day() ) + "\" "; 366 str += "DateDay=\"" + QString::number( ev.dueDate().day() ) + "\" ";
367 } 367 }
368// qWarning( "Uid %d", ev.uid() ); 368// qWarning( "Uid %d", ev.uid() );
369 str += "Uid=\"" + QString::number( ev.uid() ) + "\" "; 369 str += "Uid=\"" + QString::number( ev.uid() ) + "\" ";
370 370
371// append the extra options 371// append the extra options
372 /* FIXME Qtopia::Record this is currently not 372 /* FIXME Qtopia::Record this is currently not
373 * possible you can set custom fields 373 * possible you can set custom fields
374 * but don' iterate over the list 374 * but don' iterate over the list
375 * I may do #define private protected 375 * I may do #define private protected
376 * for this case - cough --zecke 376 * for this case - cough --zecke
377 */ 377 */
378 /* 378 /*
379 QMap<QString, QString> extras = ev.extras(); 379 QMap<QString, QString> extras = ev.extras();
380 QMap<QString, QString>::Iterator extIt; 380 QMap<QString, QString>::Iterator extIt;
381 for (extIt = extras.begin(); extIt != extras.end(); ++extIt ) 381 for (extIt = extras.begin(); extIt != extras.end(); ++extIt )
382 str += extIt.key() + "=\"" + extIt.data() + "\" "; 382 str += extIt.key() + "=\"" + extIt.data() + "\" ";
383 */ 383 */
384 // cross refernce 384 // cross refernce
385 QStringList list = ev.relatedApps(); 385 QStringList list = ev.relatedApps();
386 QStringList::Iterator listIt; 386 QStringList::Iterator listIt;
387 QString refs; 387 QString refs;
388 str += "CrossReference=\""; 388 str += "CrossReference=\"";
389 bool added = false; 389 bool added = false;
390 for ( listIt = list.begin(); listIt != list.end(); ++listIt ) { 390 for ( listIt = list.begin(); listIt != list.end(); ++listIt ) {
391 added = true; 391 added = true;
392 QArray<int> ints = ev.relations( (*listIt) ); 392 QArray<int> ints = ev.relations( (*listIt) );
393 for ( uint i = 0; i< ints.count(); i++ ) { 393 for ( uint i = 0; i< ints.count(); i++ ) {
394 str += (*listIt) + "," + QString::number( i ) + ";"; 394 str += (*listIt) + "," + QString::number( i ) + ";";
395 } 395 }
396 } 396 }
397 if ( added ) 397 if ( added )
398 str = str.remove( str.length()-1, 1 ); 398 str = str.remove( str.length()-1, 1 );
399 399
400 str += "\" "; 400 str += "\" ";
401 401
402 str += "AlarmDateTime=\"" + TimeConversion::toISO8601( ev.alarmDateTime() ) + "\" "; 402 str += "AlarmDateTime=\"" + TimeConversion::toISO8601( ev.alarmDateTime() ) + "\" ";
403 403
404 return str; 404 return str;
405} 405}
406QString OTodoAccessXML::toString( const QArray<int>& ints ) const { 406QString OTodoAccessXML::toString( const QArray<int>& ints ) const {
407 return Qtopia::Record::idsToString( ints ); 407 return Qtopia::Record::idsToString( ints );
408} 408}
409 409
410/* internal class for sorting */ 410/* internal class for sorting
411 *
412 * Inspired by todoxmlio.cpp from TT
413 */
411 414
412struct OTodoXMLContainer { 415struct OTodoXMLContainer {
413 OTodo todo; 416 OTodo todo;
414}; 417};
415 /* 418
419namespace {
420 inline QString string( const OTodo& todo) {
421 return todo.summary().isEmpty() ?
422 todo.description().left(20 ) :
423 todo.summary();
424 }
425 inline int completed( const OTodo& todo1, const OTodo& todo2) {
426 int ret = 0;
427 if ( todo1.isCompleted() ) ret++;
428 if ( todo2.isCompleted() ) ret--;
429 return ret;
430 }
431 inline int priority( const OTodo& t1, const OTodo& t2) {
432 return ( t1.priority() - t2.priority() );
433 }
434 inline int description( const OTodo& t1, const OTodo& t2) {
435 return QString::compare( string(t1), string(t2) );
436 }
437 inline int deadline( const OTodo& t1, const OTodo& t2) {
438 int ret = 0;
439 if ( t1.hasDueDate() &&
440 t2.hasDueDate() )
441 ret = t2.dueDate().daysTo( t1.dueDate() );
442 else if ( t1.hasDueDate() )
443 ret = -1;
444 else if ( t2.hasDueDate() )
445 ret = 1;
446 else
447 ret = 0;
448
449 return ret;
450 }
451
452};
453
454/*
416 * Returns: 455 * Returns:
417 * 0 if item1 == item2 456 * 0 if item1 == item2
418 * 457 *
419 * non-zero if item1 != item2 458 * non-zero if item1 != item2
420 * 459 *
421 * This function returns int rather than bool so that reimplementations 460 * This function returns int rather than bool so that reimplementations
422 * can return one of three values and use it to sort by: 461 * can return one of three values and use it to sort by:
423 * 462 *
424 * 0 if item1 == item2 463 * 0 if item1 == item2
425 * 464 *
426 * > 0 (positive integer) if item1 > item2 465 * > 0 (positive integer) if item1 > item2
427 * 466 *
428 * < 0 (negative integer) if item1 < item2 467 * < 0 (negative integer) if item1 < item2
429 * 468 *
430 */ 469 */
431class OTodoXMLVector : public QVector<OTodoXMLContainer> { 470class OTodoXMLVector : public QVector<OTodoXMLContainer> {
432public: 471public:
433 OTodoXMLVector(int size, bool asc, int sort) 472 OTodoXMLVector(int size, bool asc, int sort)
434 : QVector<OTodoXMLContainer>( size ) 473 : QVector<OTodoXMLContainer>( size )
435 { 474 {
436 setAutoDelete( true ); 475 setAutoDelete( true );
437 m_asc = asc; 476 m_asc = asc;
438 m_sort = sort; 477 m_sort = sort;
439 } 478 }
440 /* return the summary/description */ 479 /* return the summary/description */
441 QString string( const OTodo& todo) { 480 QString string( const OTodo& todo) {
442 return todo.summary().isEmpty() ? 481 return todo.summary().isEmpty() ?
443 todo.description().left(20 ) : 482 todo.description().left(20 ) :
444 todo.summary(); 483 todo.summary();
445 } 484 }
446 /** 485 /**
447 * we take the sortorder( switch on it ) 486 * we take the sortorder( switch on it )
448 * 487 *
449 */ 488 */
450 int compareItems( Item d1, Item d2 ) { 489 int compareItems( Item d1, Item d2 ) {
490 bool seComp, sePrio, seDesc, seDeadline;
491 seComp = sePrio = seDeadline = seDesc = false;
451 int ret =0; 492 int ret =0;
452 OTodoXMLContainer* con1 = (OTodoXMLContainer*)d1; 493 OTodoXMLContainer* con1 = (OTodoXMLContainer*)d1;
453 OTodoXMLContainer* con2 = (OTodoXMLContainer*)d2; 494 OTodoXMLContainer* con2 = (OTodoXMLContainer*)d2;
454 495
455 /* same item */ 496 /* same item */
456 if ( con1->todo.uid() == con2->todo.uid() ) 497 if ( con1->todo.uid() == con2->todo.uid() )
457 return 0; 498 return 0;
458 499
459 switch ( m_sort ) { 500 switch ( m_sort ) {
460 /* completed */ 501 /* completed */
461 case 0: { 502 case 0: {
462 ret = 0; 503 ret = completed( con1->todo, con2->todo );
463 if ( con1->todo.isCompleted() ) ret++; 504 seComp = TRUE;
464 if ( con2->todo.isCompleted() ) ret--;
465 break; 505 break;
466 } 506 }
467 /* priority */ 507 /* priority */
468 case 1: { 508 case 1: {
469 ret = con1->todo.priority() - con2->todo.priority(); 509 ret = priority( con1->todo, con2->todo );
470 qWarning(" priority %d %d %d", ret, 510 sePrio = TRUE;
471 con1->todo.priority(),
472 con2->todo.priority()
473 );
474 break; 511 break;
475 } 512 }
476 /* description */ 513 /* description */
477 case 2: { 514 case 2: {
478 QString str1 = string( con1->todo ); 515 ret = description( con1->todo, con2->todo );
479 QString str2 = string( con2->todo ); 516 seDesc = TRUE;
480 ret = QString::compare( str1, str2 );
481 break; 517 break;
482 } 518 }
483 /* deadline */ 519 /* deadline */
484 case 3: { 520 case 3: {
485 /* either bot got a dueDate 521 ret = deadline( con1->todo, con2->todo );
486 * or one of them got one 522 seDeadline = TRUE;
487 */
488 if ( con1->todo.hasDueDate() &&
489 con2->todo.hasDueDate() )
490 ret = con1->todo.dueDate().daysTo( con2->todo.dueDate() );
491
492
493 else if ( con1->todo.hasDueDate() )
494 ret = -1;
495 else if ( con2->todo.hasDueDate() )
496 ret = 0;
497 break; 523 break;
498 } 524 }
499 default: 525 default:
500 ret = 0; 526 ret = 0;
501 break; 527 break;
502 }; 528 };
529 /*
530 * FIXME do better sorting if the first sort criteria
531 * ret equals 0 start with complete and so on...
532 */
503 533
504 /* twist it we're not ascending*/ 534 /* twist it we're not ascending*/
505 if (!m_asc) 535 if (!m_asc)
506 ret = ret * -1; 536 ret = ret * -1;
507 return ret; 537
538 if ( ret )
539 return ret;
540
541 // default did not gave difference let's try it other way around
542 /*
543 * General try if already checked if not test
544 * and return
545 * 1.Completed
546 * 2.Priority
547 * 3.Description
548 * 4.DueDate
549 */
550 if (!seComp ) {
551 if ( (ret = completed( con1->todo, con2->todo ) ) ) {
552 if (!m_asc ) ret *= -1;
553 return ret;
554 }
555 }
556 if (!sePrio ) {
557 if ( (ret = priority( con1->todo, con2->todo ) ) ) {
558 if (!m_asc ) ret *= -1;
559 return ret;
560 }
561 }
562 if (!seDesc ) {
563 if ( (ret = description(con1->todo, con2->todo ) ) ) {
564 if (!m_asc) ret *= -1;
565 return ret;
566 }
567 }
568 if (!seDeadline) {
569 if ( (ret = deadline( con1->todo, con2->todo ) ) ) {
570 if (!m_asc) ret *= -1;
571 return ret;
572 }
573 }
574
575 return 0;
508 } 576 }
509 private: 577 private:
510 bool m_asc; 578 bool m_asc;
511 int m_sort; 579 int m_sort;
512 580
513}; 581};
514 582
515QArray<int> OTodoAccessXML::sorted( bool asc, int sortOrder, 583QArray<int> OTodoAccessXML::sorted( bool asc, int sortOrder,
516 int sortFilter, int cat ) { 584 int sortFilter, int cat ) {
517 qWarning("sorted! %d cat", cat); 585 qWarning("sorted! %d cat", cat);
518 OTodoXMLVector vector(m_events.count(), asc,sortOrder ); 586 OTodoXMLVector vector(m_events.count(), asc,sortOrder );
519 QMap<int, OTodo>::Iterator it; 587 QMap<int, OTodo>::Iterator it;
520 int item = 0; 588 int item = 0;
521 589
522 bool bCat = sortFilter & 1 ? true : false; 590 bool bCat = sortFilter & 1 ? true : false;
523 bool bOnly = sortFilter & 2 ? true : false; 591 bool bOnly = sortFilter & 2 ? true : false;
524 bool comp = sortFilter & 4 ? true : false; 592 bool comp = sortFilter & 4 ? true : false;
525 for ( it = m_events.begin(); it != m_events.end(); ++it ) { 593 for ( it = m_events.begin(); it != m_events.end(); ++it ) {
526 594
527 /* show category */ 595 /* show category */
528 if ( bCat && cat != 0) 596 if ( bCat && cat != 0)
529 if (!(*it).categories().contains( cat ) ) { 597 if (!(*it).categories().contains( cat ) ) {
530 qWarning("category mis match"); 598 qWarning("category mis match");
531 continue; 599 continue;
532 } 600 }
533 /* isOverdue but we should not show overdue - why?*/ 601 /* isOverdue but we should not show overdue - why?*/
534/* if ( (*it).isOverdue() && !bOnly ) { 602/* if ( (*it).isOverdue() && !bOnly ) {
535 qWarning("item is overdue but !bOnly"); 603 qWarning("item is overdue but !bOnly");
536 continue; 604 continue;
537 } 605 }
538*/ 606*/
539 if ( !(*it).isOverdue() && bOnly ) { 607 if ( !(*it).isOverdue() && bOnly ) {
540 qWarning("item is not overdue but bOnly checked"); 608 qWarning("item is not overdue but bOnly checked");
541 continue; 609 continue;
542 } 610 }
543 611
544 if ((*it).isCompleted() && comp ) { 612 if ((*it).isCompleted() && comp ) {
545 qWarning("completed continue!"); 613 qWarning("completed continue!");
546 continue; 614 continue;
547 } 615 }
548 616
549 617
550 OTodoXMLContainer* con = new OTodoXMLContainer(); 618 OTodoXMLContainer* con = new OTodoXMLContainer();
551 con->todo = (*it); 619 con->todo = (*it);
552 vector.insert(item, con ); 620 vector.insert(item, con );
553 item++; 621 item++;
554 } 622 }
555 qWarning("XXX %d Items added", item); 623 qWarning("XXX %d Items added", item);
556 vector.resize( item ); 624 vector.resize( item );
557 /* sort it now */ 625 /* sort it now */
558 vector.sort(); 626 vector.sort();
559 /* now get the uids */ 627 /* now get the uids */
560 QArray<int> array( vector.count() ); 628 QArray<int> array( vector.count() );
561 for (uint i= 0; i < vector.count(); i++ ) { 629 for (uint i= 0; i < vector.count(); i++ ) {
562 array[i] = ( vector.at(i) )->todo.uid(); 630 array[i] = ( vector.at(i) )->todo.uid();
563 } 631 }
564 qWarning("array count = %d %d", array.count(), vector.count() ); 632 qWarning("array count = %d %d", array.count(), vector.count() );
565 return array; 633 return array;
566}; 634};