summaryrefslogtreecommitdiff
path: root/libopie2/opiepim/backend/otodoaccessxml.cpp
Unidiff
Diffstat (limited to 'libopie2/opiepim/backend/otodoaccessxml.cpp') (more/less context) (show whitespace changes)
-rw-r--r--libopie2/opiepim/backend/otodoaccessxml.cpp306
1 files changed, 56 insertions, 250 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
@@ -34,8 +34,11 @@
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>
@@ -142,7 +145,6 @@ bool OPimTodoAccessXML::load() {
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) );
@@ -182,7 +184,6 @@ bool OPimTodoAccessXML::load() {
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;
@@ -238,7 +239,6 @@ bool OPimTodoAccessXML::load() {
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;
@@ -261,7 +261,6 @@ bool OPimTodoAccessXML::load() {
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() {
@@ -269,9 +268,7 @@ bool OPimTodoAccessXML::reload() {
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";
@@ -312,7 +309,6 @@ bool OPimTodoAccessXML::save() {
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
@@ -324,10 +320,10 @@ QArray<int> OPimTodoAccessXML::allRecords()const {
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& ) {
@@ -350,7 +346,6 @@ void OPimTodoAccessXML::clear() {
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
@@ -370,31 +365,27 @@ bool OPimTodoAccessXML::replace( const OPimTodo& todo) {
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();
@@ -409,13 +400,11 @@ QArray<int> OPimTodoAccessXML::overDue() {
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 }
@@ -468,8 +457,6 @@ void OPimTodoAccessXML::todo( QAsciiDict<int>* dict, OPimTodo& ev,
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 }
@@ -542,11 +529,9 @@ void OPimTodoAccessXML::todo( QAsciiDict<int>* dict, OPimTodo& ev,
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());
@@ -575,7 +560,6 @@ QString OPimTodoAccessXML::toString( const OPimTodo& ev )const {
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
@@ -622,7 +606,6 @@ QString OPimTodoAccessXML::toString( const OPimTodo& ev )const {
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
@@ -648,229 +631,66 @@ QString 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
656struct OPimTodoXMLContainer {
657 OPimTodo todo;
658};
659
660namespace {
661 inline QString string( const OPimTodo& todo) {
662 return todo.summary().isEmpty() ?
663 todo.description().left(20 ) :
664 todo.summary();
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
690 return ret;
691 }
692
693};
694
695/*
696 * Returns:
697 * 0 if item1 == item2
698 *
699 * non-zero if item1 != item2
700 *
701 * This function returns int rather than bool so that reimplementations
702 * can return one of three values and use it to sort by:
703 *
704 * 0 if item1 == item2
705 *
706 * > 0 (positive integer) if item1 > item2
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;
765 }
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
779 if ( ret )
780 return ret;
781
782 // default did not gave difference let's try it other way around
783 /*
784 * General try if already checked if not test
785 * and return
786 * 1.Completed
787 * 2.Priority
788 * 3.Description
789 * 4.DueDate
790 */
791 if (!seComp ) {
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 634
816 return 0; 635QArray<int> OPimTodoAccessXML::sorted( const UIDArray& events, bool asc,
817 } 636 int sortOrder,int sortFilter,
818 private: 637 const QArray<int>& categories )const {
819 bool m_asc; 638 Internal::OPimTodoSortVector vector(events.count(), asc,sortOrder );
820 int m_sort; 639 int item = 0;
821 640
822}; 641 bool bCat = sortFilter & OPimTodoAccess::FilterCategory ? true : false;
642 bool bOnly = sortFilter & OPimTodoAccess::OnlyOverDue ? true : false;
643 bool comp = sortFilter & OPimTodoAccess::DoNotShowCompleted ? true : false;
644 bool catPassed = false;
645 int cat;
823 646
824QArray<int> OPimTodoAccessXML::sorted( bool asc, int sortOrder, 647 for ( uint i = 0; i < events.count(); ++i ) {
825 int sortFilter, int cat ) { 648 /* Guard against creating a new item... */
826 OPimTodoXMLVector vector(m_events.count(), asc,sortOrder ); 649 if ( !m_events.contains( events[i] ) )
827 QMap<int, OPimTodo>::Iterator it; 650 continue;
828 int item = 0;
829 651
830 bool bCat = sortFilter & 1 ? true : false; 652 OPimTodo todo = m_events[events[i]];
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 653
835 /* show category */ 654 /* show category */
836 /* -1 == unfiled */ 655 /* -1 == unfiled */
656 catPassed = false;
657 for ( uint cat_nu = 0; cat_nu < categories.count(); ++cat_nu ) {
658 cat = categories[cat_nu];
837 if ( bCat && cat == -1 ) { 659 if ( bCat && cat == -1 ) {
838 if(!(*it).categories().isEmpty() ) 660 if(!todo.categories().isEmpty() )
839 continue; 661 continue;
840 }else if ( bCat && cat != 0) 662 }else if ( bCat && cat != 0)
841 if (!(*it).categories().contains( cat ) ) { 663 if (!todo.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; 664 continue;
665 catPassed = true;
666 break;
848 } 667 }
668
669 /*
670 * If none of the Categories matched
671 * continue
849*/ 672*/
850 if ( !(*it).isOverdue() && bOnly ) { 673 if ( !catPassed )
851 continue; 674 continue;
852 } 675 if ( !todo.isOverdue() && bOnly )
853 676 continue;
854 if ((*it).isCompleted() && comp ) { 677 if (todo.isCompleted() && comp )
855 continue; 678 continue;
856 }
857
858 679
859 OPimTodoXMLContainer* con = new OPimTodoXMLContainer(); 680 vector.insert(item++, todo );
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 ) {
@@ -879,36 +699,22 @@ void OPimTodoAccessXML::removeAllCompleted() {
879 } 699 }
880 m_events = events; 700 m_events = events;
881} 701}
882QBitArray OPimTodoAccessXML::supports()const {
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 702
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}