-rw-r--r-- | libopie/pim/orecordlist.h | 17 | ||||
-rw-r--r-- | libopie/pim/otodo.cpp | 1 | ||||
-rw-r--r-- | libopie/pim/otodoaccess.cpp | 8 | ||||
-rw-r--r-- | libopie/pim/otodoaccess.h | 16 | ||||
-rw-r--r-- | libopie/pim/otodoaccessbackend.h | 2 | ||||
-rw-r--r-- | libopie/pim/otodoaccessxml.cpp | 145 | ||||
-rw-r--r-- | libopie/pim/otodoaccessxml.h | 2 |
7 files changed, 183 insertions, 8 deletions
diff --git a/libopie/pim/orecordlist.h b/libopie/pim/orecordlist.h index c63d813..1fd0741 100644 --- a/libopie/pim/orecordlist.h +++ b/libopie/pim/orecordlist.h @@ -25,149 +25,150 @@ public: * The c'tor used internally from * ORecordList */ ORecordListIterator( const QArray<int>, const Base* ); /** * The standard c'tor */ ORecordListIterator(); ~ORecordListIterator(); ORecordListIterator( const ORecordListIterator& ); ORecordListIterator &operator=(const ORecordListIterator& ); /** * a * operator ;) * use it like this T = (*it); */ T operator*(); ORecordListIterator &operator++(); ORecordListIterator &operator--(); bool operator==( const ORecordListIterator& it ); bool operator!=( const ORecordListIterator& it ); - + /** * the current item */ uint current()const; - + /** * the number of items */ uint count()const; - + /** * sets the current item */ void setCurrent( uint cur ); private: QArray<int> m_uids; uint m_current; const Base* m_temp; bool m_end : 1; T m_record; /* d pointer for future versions */ class IteratorPrivate; IteratorPrivate *d; }; /** * The recordlist used as a return type * from OPimAccessTemplate */ template <class T = OPimRecord > class ORecordList { public: typedef OTemplateBase<T> Base; typedef ORecordListIterator<T> Iterator; /** * c'tor */ ORecordList () { } ORecordList( const QArray<int>& ids, const Base* ); ~ORecordList(); /** * the first iterator */ Iterator begin(); /** * the end */ Iterator end(); - + /** * the number of items in the list */ uint count()const; - + + T operator[]( uint i ); // FIXME implemenent remove /* ConstIterator begin()const; ConstIterator end()const; */ private: QArray<int> m_ids; const Base* m_acc; }; /* ok now implement it */ template <class T> ORecordListIterator<T>::ORecordListIterator() { m_current = 0; m_temp = 0l; m_end = true; m_record = T(); } template <class T> ORecordListIterator<T>::~ORecordListIterator() { /* nothing to delete */ } template <class T> ORecordListIterator<T>::ORecordListIterator( const ORecordListIterator<T>& it) { // qWarning("ORecordListIterator copy c'tor"); m_uids = it.m_uids; m_current = it.m_current; m_temp = it.m_temp; m_end = it.m_end; m_record = it.m_record; } template <class T> ORecordListIterator<T> &ORecordListIterator<T>::operator=( const ORecordListIterator<T>& it) { m_uids = it.m_uids; m_current = it.m_current; m_temp = it.m_temp; m_end = it.m_end; -// m_record = it.m_record; + m_record = it.m_record; return *this; } template <class T> T ORecordListIterator<T>::operator*() { // qWarning("operator* %d %d", m_current, m_uids[m_current] ); if (!m_end ) /* FIXME * until the cache is in place * we do the uid match uid check */ if(m_record.uid() != m_uids[m_current] ) m_record = m_temp->find( m_uids[m_current] ); else m_record = T(); return m_record; } template <class T> ORecordListIterator<T> &ORecordListIterator<T>::operator++() { if (m_current < m_uids.count() ) { m_end = false; @@ -231,25 +232,29 @@ ORecordList<T>::ORecordList( const QArray<int>& ids, : m_ids( ids ), m_acc( acc ) { } template <class T> ORecordList<T>::~ORecordList() { /* nothing to do here */ } template <class T> ORecordList<T>::Iterator ORecordList<T>::begin() { Iterator it( m_ids, m_acc ); return it; } template <class T> ORecordList<T>::Iterator ORecordList<T>::end() { Iterator it( m_ids, m_acc ); it.m_end = true; it.m_current = m_ids.count(); return it; } template <class T> uint ORecordList<T>::count()const { return m_ids.count(); } +template <class T> +T ORecordList<T>::operator[]( uint i ) { + return m_acc->find( m_ids[i] ); +} #endif diff --git a/libopie/pim/otodo.cpp b/libopie/pim/otodo.cpp index 6dd4c0e..eb9dad3 100644 --- a/libopie/pim/otodo.cpp +++ b/libopie/pim/otodo.cpp @@ -151,48 +151,49 @@ void OTodo::setCompleted( bool completed ) } void OTodo::setHasDueDate( bool hasDate ) { changeOrModify(); data->hasDate = hasDate; } void OTodo::setHasAlarmDateTime( bool hasAlarmDateTime ) { changeOrModify(); data->hasAlarmDateTime = hasAlarmDateTime; } void OTodo::setDescription(const QString &desc ) { // qWarning( "desc " + desc ); changeOrModify(); data->desc = Qtopia::simplifyMultiLineSpace(desc ); } void OTodo::setSummary( const QString& sum ) { changeOrModify(); data->sum = sum; } void OTodo::setPriority(int prio ) { + qWarning("set priority %d", prio); changeOrModify(); data->priority = prio; } void OTodo::setDueDate( QDate date ) { changeOrModify(); data->date = date; } void OTodo::setAlarmDateTime( const QDateTime& alarm ) { changeOrModify(); data->alarmDateTime = alarm; } bool OTodo::isOverdue( ) { if( data->hasDate ) return QDate::currentDate() > data->date; return false; } void OTodo::setProgress(ushort progress ) { changeOrModify(); data->prog = progress; } diff --git a/libopie/pim/otodoaccess.cpp b/libopie/pim/otodoaccess.cpp index 8ec09bc..f51da29 100644 --- a/libopie/pim/otodoaccess.cpp +++ b/libopie/pim/otodoaccess.cpp @@ -47,25 +47,31 @@ void OTodoAccess::addAlarm( const OTodo& event) { QDateTime now = QDateTime::currentDateTime(); QDateTime schedule = event.alarmDateTime(); if ( schedule > now ){ AlarmServer::addAlarm( schedule, "QPE/Application/todolist", "alarm(QDateTime,int)", event.uid() ); } } void OTodoAccess::delAlarm( int uid) { QDateTime schedule; // Create null DateTime // I hope this will remove all scheduled alarms // with the given uid !? // If not: I have to rethink how to remove already // scheduled events... (se) // it should be fine -zecke // qWarning("Removing alarm for event with uid %d", uid ); AlarmServer::deleteAlarm( schedule , "QPE/Application/todolist", "alarm(QDateTime,int)", uid ); } - +/* sort order */ +OTodoAccess::List OTodoAccess::sorted( bool ascending, int sort,int filter, int cat ) { + QArray<int> ints = m_todoBackEnd->sorted( ascending, sort, + filter, cat ); + OTodoAccess::List list( ints, this ); + return list; +} diff --git a/libopie/pim/otodoaccess.h b/libopie/pim/otodoaccess.h index c43efe9..12997aa 100644 --- a/libopie/pim/otodoaccess.h +++ b/libopie/pim/otodoaccess.h @@ -1,79 +1,93 @@ #ifndef OPIE_TODO_ACCESS_H #define OPIE_TODO_ACCESS_H #include <qobject.h> #include <qvaluelist.h> #include "otodo.h" #include "otodoaccessbackend.h" #include "opimaccesstemplate.h" /** * OTodoAccess * the class to get access to * the todolist */ class OTodoAccess : public QObject, public OPimAccessTemplate<OTodo> { Q_OBJECT public: + enum SortOrder { Completed = 0, + Priority, + Description, + Deadline }; + enum SortFilter{ ShowOverdue = 0, + Category =1, + OnlyOverDue= 2 }; /** * if you use 0l * the default resource will be - * icked up + * picked up */ OTodoAccess( OTodoAccessBackend* = 0l); ~OTodoAccess(); /* our functions here */ /** * include todos from start to end * includeNoDates whether or not to include * events with no dates */ List effectiveToDos( const QDate& start, const QDate& end, bool includeNoDates = true ); /** * start * end date taken from the currentDate() */ List effectiveToDos( const QDate& start, bool includeNoDates = true ); /** * return overdue OTodos */ List overDue(); + + /** + * + */ + List sorted( bool ascending, int sortOrder, int sortFilter, int cat ); + /** * merge a list of OTodos into * the resource */ void mergeWith( const QValueList<OTodo>& ); /** * add an Alarm to the AlarmServer */ void addAlarm( const OTodo& ); /** * delete an alarm with the uid from * the alarm server */ void delAlarm( int uid ); signals: /** * if the OTodoAccess was changed */ void signalChanged( const OTodoAccess* ); private: + int m_cat; OTodoAccessBackend* m_todoBackEnd; class OTodoAccessPrivate; OTodoAccessPrivate* d; }; #endif diff --git a/libopie/pim/otodoaccessbackend.h b/libopie/pim/otodoaccessbackend.h index ebe2189..3bad6b7 100644 --- a/libopie/pim/otodoaccessbackend.h +++ b/libopie/pim/otodoaccessbackend.h @@ -1,18 +1,20 @@ #ifndef OPIE_TODO_ACCESS_BACKEND_H #define OPIE_TODO_ACCESS_BACKEND_H #include "otodo.h" #include "opimaccessbackend.h" class OTodoAccessBackend : public OPimAccessBackend<OTodo> { public: OTodoAccessBackend(); ~OTodoAccessBackend(); virtual QArray<int> effectiveToDos( const QDate& start, const QDate& end, bool includeNoDates ) = 0; virtual QArray<int> overDue() = 0; + virtual QArray<int> sorted( bool asc, int sortOrder, int sortFilter, + int cat ) = 0; }; #endif diff --git a/libopie/pim/otodoaccessxml.cpp b/libopie/pim/otodoaccessxml.cpp index 5fe733c..692483e 100644 --- a/libopie/pim/otodoaccessxml.cpp +++ b/libopie/pim/otodoaccessxml.cpp @@ -1,25 +1,26 @@ #include <qfile.h> +#include <qvector.h> #include <qpe/global.h> #include <qpe/stringutil.h> #include <qpe/timeconversion.h> #include <opie/xmltree.h> #include "otodoaccessxml.h" OTodoAccessXML::OTodoAccessXML( const QString& appName, const QString& fileName ) : OTodoAccessBackend(), m_app( appName ), m_opened( false ), m_changed( false ) { if (!fileName.isEmpty() ) m_file = fileName; else m_file = Global::applicationFileName( "todolist", "todolist.xml" ); } OTodoAccessXML::~OTodoAccessXML() { } bool OTodoAccessXML::load() { m_opened = true; m_changed = false; @@ -235,48 +236,49 @@ OTodo OTodoAccessXML::todo( QAsciiDict<int>* dict, Opie::XMLElement* element)con ev.setCustomField( it.key(), it.data() ); continue; } switch( *find ) { case OTodo::Uid: ev.setUid( it.data().toInt() ); break; case OTodo::Category: ev.setCategories( ev.idsFromString( it.data() ) ); break; case OTodo::HasDate: ev.setHasDueDate( it.data().toInt() ); break; case OTodo::Completed: ev.setCompleted( it.data().toInt() ); break; case OTodo::Description: ev.setDescription( it.data() ); break; case OTodo::Summary: ev.setSummary( it.data() ); break; case OTodo::Priority: + qWarning("ParsePriority " + it.data() ); ev.setPriority( it.data().toInt() ); break; case OTodo::DateDay: day = it.data().toInt(); break; case OTodo::DateMonth: month = it.data().toInt(); break; case OTodo::DateYear: year = it.data().toInt(); break; case OTodo::Progress: ev.setProgress( it.data().toInt() ); break; case OTodo::CrossReference: { /* * A cross refernce looks like * appname,id;appname,id * we need to split it up */ QStringList refs = QStringList::split(';', it.data() ); QStringList::Iterator strIt; for (strIt = refs.begin(); strIt != refs.end(); ++strIt ) { @@ -343,24 +345,167 @@ QString OTodoAccessXML::toString( const OTodo& ev )const { QStringList list = ev.relatedApps(); QStringList::Iterator listIt; QString refs; str += "CrossReference=\""; bool added = false; for ( listIt = list.begin(); listIt != list.end(); ++listIt ) { added = true; QArray<int> ints = ev.relations( (*listIt) ); for ( uint i = 0; i< ints.count(); i++ ) { str += (*listIt) + "," + QString::number( i ) + ";"; } } if ( added ) str = str.remove( str.length()-1, 1 ); str += "\" "; str += "AlarmDateTime=\"" + TimeConversion::toISO8601( ev.alarmDateTime() ) + "\" "; return str; } QString OTodoAccessXML::toString( const QArray<int>& ints ) const { return Qtopia::Record::idsToString( ints ); } + +/* internal class for sorting */ + +struct OTodoXMLContainer { + OTodo todo; +}; + /* + * Returns: + * 0 if item1 == item2 + * + * non-zero if item1 != item2 + * + * This function returns int rather than bool so that reimplementations + * can return one of three values and use it to sort by: + * + * 0 if item1 == item2 + * + * > 0 (positive integer) if item1 > item2 + * + * < 0 (negative integer) if item1 < item2 + * + */ +class OTodoXMLVector : public QVector<OTodoXMLContainer> { +public: + OTodoXMLVector(int size, bool asc, int sort) + : QVector<OTodoXMLContainer>( size ) + { + setAutoDelete( true ); + m_asc = asc; + m_sort = sort; + } + /* return the summary/description */ + QString string( const OTodo& todo) { + return todo.summary().isEmpty() ? + todo.description().left(20 ) : + todo.summary(); + } + /** + * we take the sortorder( switch on it ) + * + */ + int compareItems( Item d1, Item d2 ) { + qWarning("compare items"); + int ret =0; + OTodoXMLContainer* con1 = (OTodoXMLContainer*)d1; + OTodoXMLContainer* con2 = (OTodoXMLContainer*)d2; + + /* same item */ + if ( con1->todo.uid() == con2->todo.uid() ) + return 0; + qWarning("m_sort %d", m_sort ); + + switch ( m_sort ) { + /* completed */ + case 0: { + ret = 0; + if ( con1->todo.isCompleted() ) ret++; + if ( con2->todo.isCompleted() ) ret--; + break; + } + /* priority */ + case 1: { + ret = con1->todo.priority() - con2->todo.priority(); + qWarning(" priority %d %d %d", ret, + con1->todo.priority(), + con2->todo.priority() + ); + break; + } + /* description */ + case 2: { + QString str1 = string( con1->todo ); + QString str2 = string( con2->todo ); + ret = QString::compare( str1, str2 ); + break; + } + /* deadline */ + case 3: { + /* either bot got a dueDate + * or one of them got one + */ + if ( con1->todo.hasDueDate() && + con2->todo.hasDueDate() ) + ret = con1->todo.dueDate().daysTo( con2->todo.dueDate() ); + else if ( con1->todo.hasDueDate() ) + ret = -1; + else if ( con2->todo.hasDueDate() ) + ret = 0; + break; + } + default: + ret = 0; + break; + }; + + /* twist it we're not ascending*/ + if (!m_asc) + ret = ret * -1; + return ret; + } + private: + bool m_asc; + int m_sort; + +}; + +QArray<int> OTodoAccessXML::sorted( bool asc, int sortOrder, + int sortFilter, int cat ) { + OTodoXMLVector vector(m_events.count(), asc,sortOrder ); + QMap<int, OTodo>::Iterator it; + int item = 0; + + bool bCat = sortFilter & 1 ? true : false; + bool bOver = sortFilter & 0 ? true : false; + bool bOnly = split & 2 ? true : false; + for ( it = m_events.begin(); it != m_events.end(); ++it ) { + + /* show category */ + if ( bCat ) + if (!(*it).categories().contains( cat ) ) + continue; + /* isOverdue but we should not show overdue */ + if ( (*it).isOverdue() && ( !bOver || !bOnly ) ) + continue; + if ( !(*it).isOverdue() && bOnly ) + continue; + + + OTodoXMLContainer* con = new OTodoXMLContainer(); + con->todo = (*it); + vector.insert(item, con ); + item++; + } + vector.resize( item ); + /* sort it now */ + vector.sort(); + /* now get the uids */ + QArray<int> array( vector.count() ); + for (uint i= 0; i < vector.count(); i++ ) { + array[i] = ( vector.at(i) )->todo.uid(); + } + return array; +}; diff --git a/libopie/pim/otodoaccessxml.h b/libopie/pim/otodoaccessxml.h index be9109d..6886bab 100644 --- a/libopie/pim/otodoaccessxml.h +++ b/libopie/pim/otodoaccessxml.h @@ -15,39 +15,41 @@ public: /** * fileName if Empty we will use the default path */ OTodoAccessXML( const QString& appName, const QString& fileName = QString::null ); ~OTodoAccessXML(); bool load(); bool reload(); bool save(); QArray<int> allRecords()const; QArray<int> queryByExample( const OTodo&, int sort ); OTodo find( int uid )const; void clear(); bool add( const OTodo& ); bool remove( int uid ); bool replace( const OTodo& ); /* our functions */ QArray<int> effectiveToDos( const QDate& start, const QDate& end, bool includeNoDates ); QArray<int> overDue(); + QArray<int> sorted( bool asc, int sortOrder, + int sortFilter, int cat ); private: OTodo todo( QAsciiDict<int>*, Opie::XMLElement* )const; QString toString( const OTodo& )const; QString toString( const QArray<int>& ints ) const; QMap<int, OTodo> m_events; QString m_file; QString m_app; bool m_opened : 1; bool m_changed : 1; class OTodoAccessXMLPrivate; OTodoAccessXMLPrivate* d; }; #endif |