-rw-r--r-- | libopie2/opiepim/ChangeLog | 3 | ||||
-rw-r--r-- | libopie2/opiepim/backend/ocontactaccessbackend.cpp | 5 | ||||
-rw-r--r-- | libopie2/opiepim/backend/ocontactaccessbackend.h | 3 | ||||
-rw-r--r-- | libopie2/opiepim/backend/odatebookaccessbackend.cpp | 58 | ||||
-rw-r--r-- | libopie2/opiepim/core/odatebookaccess.h | 25 | ||||
-rw-r--r-- | libopie2/opiepim/private/opimeventsortvector.cpp | 134 | ||||
-rw-r--r-- | libopie2/opiepim/private/opimeventsortvector.h | 48 | ||||
-rw-r--r-- | libopie2/opiepim/private/opimsortvector.h | 34 | ||||
-rw-r--r-- | libopie2/opiepim/private/opimtodosortvector.cpp | 2 | ||||
-rw-r--r-- | libopie2/opiepim/private/private.pro | 2 |
10 files changed, 308 insertions, 6 deletions
diff --git a/libopie2/opiepim/ChangeLog b/libopie2/opiepim/ChangeLog index 320b189..e94fa59 100644 --- a/libopie2/opiepim/ChangeLog +++ b/libopie2/opiepim/ChangeLog @@ -1,26 +1,29 @@ +2005-01-16 Stefan Eilers <stefan@eilers-online.net> + * Added new OPimEventSortVector class, improved OPimSortVector + * OPimAccessBackend now supports generic sorting. 2005-01-03 Stefan Eilers <stefan@eilers-online.net> * Fixing bug in API documentation * Moving hasQuerySettings() and querySettings() to OPimAccessTemplate to be available for all frontends 2004-12-28 Stefan Eilers <stefan@eilers-online.net> * Make improved query by example accessable via frontend * Some API documentation improvement * Cleanup of backend api.. * Fixing bug #1501 2004-11-23 Stefan Eilers <stefan@eilers-online.net> * Implement fast and full featured version of sorted() for addressbook * Implement generic queryByExample for all Addressboook backends. It allows incremental search. * Update of API Documentation 2004-11-18 Holger Freyther <freyther@handhelds.org> * Every Access can give a set of Occurrences for a period or a datetime * QueryByExample, Find, Sort can be generically accessed by OPimBase pointer interface * OPimBackendOccurrence gets split up to OPimOccurrences by OPimTemplateBase * Add safeCast to various OPimRecords * Kill memleak in OPimTodo * Add SortVector implementations for OPimTodo and OPimContact 2004-??-?? The Opie Team <opie@handhelds.org> * Implemented some important modifications to allow to use OPimRecords as it is, without have to cast them. This makes it possible to write applications which handling pim data in a generic manner (see opimconvertion tool) (eilers)
\ No newline at end of file diff --git a/libopie2/opiepim/backend/ocontactaccessbackend.cpp b/libopie2/opiepim/backend/ocontactaccessbackend.cpp index b4fdd46..c09427c 100644 --- a/libopie2/opiepim/backend/ocontactaccessbackend.cpp +++ b/libopie2/opiepim/backend/ocontactaccessbackend.cpp @@ -1,99 +1,100 @@ /* This file is part of the Opie Project - Copyright (C) 2004 Holger Freyther <freyther@handhelds.org> + Copyright (C) Holger Freyther <freyther@handhelds.org> + Copyright (C) Stefan Eilers <stefan@eilers-online.net> =. Copyright (C) The Opie Team <opie-devel@handhelds.org> .=l. .>+-= _;:, .> :=|. This program is free software; you can .> <`_, > . <= redistribute it and/or modify it under :`=1 )Y*s>-.-- : the terms of the GNU Library General Public .="- .-=="i, .._ License as published by the Free Software - . .-<_> .<> Foundation; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+i> _;_. .i_,=:_. -<s. This program is distributed in the hope that + . -:. = it will be useful, but WITHOUT ANY WARRANTY; : .. .:, . . . without even the implied warranty of =_ + =;=|` MERCHANTABILITY or FITNESS FOR A _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU ..}^=.= = ; Library General Public License for more ++= -. .` .: details. : = ...= . :.=- -. .:....=;==+<; You should have received a copy of the GNU -_. . . )=. = Library General Public License along with -- :-=` this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "ocontactaccessbackend.h" #include <opie2/private/opimcontactsortvector.h> #include <opie2/ocontactaccess.h> #include <opie2/odebug.h> #include <qdatetime.h> namespace Opie { OPimContactAccessBackend::OPimContactAccessBackend() {} UIDArray OPimContactAccessBackend::queryByExample( const UIDArray& uid_array, const OPimContact& query, int settings, const QDateTime& d )const { odebug << "Using Unaccelerated OPimContactAccessBackend implementation of queryByExample!" << oendl; UIDArray m_currentQuery( uid_array.count() ); uint arraycounter = 0; for( uint it = 0; it < uid_array.count(); ++it ){ /* Search all fields and compare them with query object. Store them into list * if all fields matches. */ QDate* queryDate = 0l; QDate* checkDate = 0l; bool allcorrect = true; for ( int i = 0; i < Qtopia::Groups; i++ ) { // Birthday and anniversary are special nonstring fields and should // be handled specially switch ( i ){ case Qtopia::Birthday: queryDate = new QDate( query.birthday() ); checkDate = new QDate( find( uid_array[it] ).birthday() ); // fall through case Qtopia::Anniversary: if ( queryDate == 0l ){ queryDate = new QDate( query.anniversary() ); checkDate = new QDate( find( uid_array[it] ).anniversary() ); } if ( queryDate->isValid() ){ if( checkDate->isValid() ){ if ( settings & OPimContactAccess::DateYear ){ if ( queryDate->year() != checkDate->year() ) allcorrect = false; } if ( settings & OPimContactAccess::DateMonth ){ if ( queryDate->month() != checkDate->month() ) allcorrect = false; } if ( settings & OPimContactAccess::DateDay ){ if ( queryDate->day() != checkDate->day() ) allcorrect = false; } if ( settings & OPimContactAccess::DateDiff ) { QDate current; // If we get an additional date, we // will take this date instead of // the current one.. if ( !d.date().isValid() ) current = QDate::currentDate(); else current = d.date(); // We have to equalize the year, otherwise // the search will fail.. checkDate->setYMD( current.year(), checkDate->month(), checkDate->day() ); if ( *checkDate < current ) checkDate->setYMD( current.year()+1, @@ -144,171 +145,171 @@ UIDArray OPimContactAccessBackend::queryByExample( const UIDArray& uid_array, co QRegExp expr ( query.field(i), !(settings & OPimContactAccess::IgnoreCase), true ); if ( expr.find ( find( uid_array[it] ).field(i), 0 ) == -1 ) allcorrect = false; } break; case OPimContactAccess::ExactMatch:{ if (settings & OPimContactAccess::IgnoreCase){ if ( query.field(i).upper() != find( uid_array[it] ).field(i).upper() ) allcorrect = false; }else{ if ( query.field(i) != find( uid_array[it] ).field(i) ) allcorrect = false; } } break; } } } } if ( allcorrect ){ m_currentQuery[arraycounter++] = uid_array[it]; } } // Shrink to fit.. m_currentQuery.resize(arraycounter); return m_currentQuery; } const uint OPimContactAccessBackend::querySettings() const { return ( OPimContactAccess::WildCards | OPimContactAccess::IgnoreCase | OPimContactAccess::RegExp | OPimContactAccess::ExactMatch | OPimContactAccess::DateDiff | OPimContactAccess::DateYear | OPimContactAccess::DateMonth | OPimContactAccess::DateDay ); } bool OPimContactAccessBackend::hasQuerySettings (uint querySettings) const { /* OPimContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay * may be added with any of the other settings. IgnoreCase should never used alone. * Wildcards, RegExp, ExactMatch should never used at the same time... */ // Step 1: Check whether the given settings are supported by this backend if ( ( querySettings & ( OPimContactAccess::IgnoreCase | OPimContactAccess::WildCards | OPimContactAccess::DateDiff | OPimContactAccess::DateYear | OPimContactAccess::DateMonth | OPimContactAccess::DateDay | OPimContactAccess::RegExp | OPimContactAccess::ExactMatch ) ) != querySettings ) return false; // Step 2: Check whether the given combinations are ok.. // IngoreCase alone is invalid if ( querySettings == OPimContactAccess::IgnoreCase ) return false; // WildCards, RegExp and ExactMatch should never used at the same time switch ( querySettings & ~( OPimContactAccess::IgnoreCase | OPimContactAccess::DateDiff | OPimContactAccess::DateYear | OPimContactAccess::DateMonth | OPimContactAccess::DateDay ) ){ case OPimContactAccess::RegExp: return ( true ); case OPimContactAccess::WildCards: return ( true ); case OPimContactAccess::ExactMatch: return ( true ); case 0: // one of the upper removed bits were set.. return ( true ); default: return ( false ); } } UIDArray OPimContactAccessBackend::sorted( const UIDArray& ar, bool asc, int sortOrder, - int filter, const QArray<int>& categories)const { + int filter, const QArray<int>& categories )const { odebug << "Using Unaccelerated OPimContactAccessBackend sorted Implementation" << oendl; Internal::OPimContactSortVector vector(ar.count(), asc, sortOrder ); int item = 0; uint cat_count = categories.count(); uint eve_count = ar.count(); bool bCat = filter & OPimContactAccess::FilterCategory ? true : false; bool catPassed = false; int cat; for ( uint i = 0; i < eve_count; ++i ) { OPimContact contact = find( ar[i], ar, i, Frontend::Forward ); if ( contact.isEmpty() ) continue; /* show category */ /* -1 == unfiled */ catPassed = false; for ( uint cat_nu = 0; cat_nu < cat_count; ++cat_nu ) { cat = categories[cat_nu]; if ( bCat && cat == -1 ) { if(!contact.categories().isEmpty() ) continue; } else if ( bCat && cat != 0) if (!contact.categories().contains( cat ) ) continue; catPassed = true; break; } /* * If none of the Categories matched * continue */ if ( !catPassed ) continue; vector.insert(item++, contact ); } vector.resize( item ); /* sort it now */ vector.sort(); /* now get the uids */ UIDArray array( vector.count() ); for (uint i= 0; i < vector.count(); i++ ) array[i] = vector.uidAt( i ); return array; } OPimBackendOccurrence::List OPimContactAccessBackend::occurrences( const QDate& start, const QDate& end)const { OPimBackendOccurrence::List lst; UIDArray records = allRecords(); const uint count = records.count(); int uid; for ( uint i = 0; i < count; ++i ) { uid = records[i]; OPimContact contact = find(uid, records, i, Frontend::Forward ); QDate date = contact.anniversary(); date = QDate( start.year(), date.month(),date.day() ); // if ( date.isValid() && date.) { // } } return lst; } } diff --git a/libopie2/opiepim/backend/ocontactaccessbackend.h b/libopie2/opiepim/backend/ocontactaccessbackend.h index 27d70ab..d5c463b 100644 --- a/libopie2/opiepim/backend/ocontactaccessbackend.h +++ b/libopie2/opiepim/backend/ocontactaccessbackend.h @@ -1,99 +1,100 @@ /* This file is part of the Opie Project - Copyright (C) The Main Author <main-author@whereever.org> + Copyright (C) Holger Freyther <freyther@handhelds.org> + Copyright (C) Stefan Eilers <stefan@eilers-online.net> =. Copyright (C) The Opie Team <opie-devel@handhelds.org> .=l. .>+-= _;:, .> :=|. This program is free software; you can .> <`_, > . <= redistribute it and/or modify it under :`=1 )Y*s>-.-- : the terms of the GNU Library General Public .="- .-=="i, .._ License as published by the Free Software - . .-<_> .<> Foundation; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+i> _;_. .i_,=:_. -<s. This program is distributed in the hope that + . -:. = it will be useful, but WITHOUT ANY WARRANTY; : .. .:, . . . without even the implied warranty of =_ + =;=|` MERCHANTABILITY or FITNESS FOR A _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU ..}^=.= = ; Library General Public License for more ++= -. .` .: details. : = ...= . :.=- -. .:....=;==+<; You should have received a copy of the GNU -_. . . )=. = Library General Public License along with -- :-=` this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /** * The class responsible for managing a backend. * The implementation of this abstract class contains * the complete database handling. * * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) * Copyright (c) 2002 by Holger Freyther (zecke@handhelds.org) * */ #ifndef _OCONTACTACCESSBACKEND_H_ #define _OCONTACTACCESSBACKEND_H_ #include <opie2/opimcontact.h> #include <opie2/opimaccessbackend.h> #include <qregexp.h> namespace Opie { /** * This class represents the interface of all Contact Backends. * Derivates of this class will be used to access the contacts. * As implementation currently XML and vCard exist. This class needs to be implemented * if you want to provide your own storage. * In all queries a list of uids is passed on instead of loading the actual record! * * @see OPimContactAccessBackend_VCard * @see OPimContactAccessBackend_XML */ class OPimContactAccessBackend: public OPimAccessBackend<OPimContact> { public: OPimContactAccessBackend(); /** * Return if database was changed externally. * This may just make sense on file based databases like a XML-File. * It is used to prevent to overwrite the current database content * if the file was already changed by something else ! * If this happens, we have to reload before save our data. * If we use real databases, this should be handled by the database * management system themselve, therefore this function should always return false in * this case. It is not our problem to handle this conflict ... * @return <i>true</i> if the database was changed and if save without reload will * be dangerous. <i>false</i> if the database was not changed or it is save to write * in this situation. */ virtual bool wasChangedExternally() = 0; /** * Return all possible settings. * @return All settings provided by the current backend * (i.e.: query_WildCards & query_IgnoreCase) */ const uint querySettings() const; /** * Check whether settings are correct. * @return <i>true</i> if the given settings are correct and possible. */ bool hasQuerySettings (uint querySettings) const; /** * Advanced search mechanism. */ UIDArray queryByExample( const UIDArray& uidlist, const OPimContact&, int settings, const QDateTime &d = QDateTime() ) const; /** * Slow and inefficent default implementation */ //@{ UIDArray sorted( const UIDArray&, bool asc, int, int, const QArray<int>& )const; diff --git a/libopie2/opiepim/backend/odatebookaccessbackend.cpp b/libopie2/opiepim/backend/odatebookaccessbackend.cpp index e44912a..6da0170 100644 --- a/libopie2/opiepim/backend/odatebookaccessbackend.cpp +++ b/libopie2/opiepim/backend/odatebookaccessbackend.cpp @@ -1,181 +1,233 @@ /* This file is part of the Opie Project Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) =. Copyright (C) The Opie Team <opie-devel@handhelds.org> .=l. .>+-= _;:, .> :=|. This program is free software; you can .> <`_, > . <= redistribute it and/or modify it under :`=1 )Y*s>-.-- : the terms of the GNU Library General Public .="- .-=="i, .._ License as published by the Free Software - . .-<_> .<> Foundation; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+i> _;_. .i_,=:_. -<s. This program is distributed in the hope that + . -:. = it will be useful, but WITHOUT ANY WARRANTY; : .. .:, . . . without even the implied warranty of =_ + =;=|` MERCHANTABILITY or FITNESS FOR A _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU ..}^=.= = ; Library General Public License for more ++= -. .` .: details. : = ...= . :.=- -. .:....=;==+<; You should have received a copy of the GNU -_. . . )=. = Library General Public License along with -- :-=` this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include <qtl.h> +#include <opie2/odebug.h> #include <opie2/opimrecurrence.h> - +#include <opie2/odatebookaccess.h> #include <opie2/odatebookaccessbackend.h> +#include <opie2/private/opimeventsortvector.h> using namespace Opie; namespace { /* a small helper to get all NonRepeating events for a range of time */ void events( OPimBackendOccurrence::List& tmpList, const OPimEvent::ValueList& events, const QDate& from, const QDate& to ) { QDateTime dtStart, dtEnd; for ( OPimEvent::ValueList::ConstIterator it = events.begin(); it != events.end(); ++it ) { dtStart = (*it).startDateTime(); dtEnd = (*it).endDateTime(); /* * If in range */ if (dtStart.date() >= from && dtEnd.date() <= to ) { OPimBackendOccurrence eff( dtStart, dtEnd, (*it).uid() );; tmpList.append( eff ); } } } void repeat( OPimBackendOccurrence::List& tmpList, const OPimEvent::ValueList& list, const QDate& from, const QDate& to ) { QDate repeat; for ( OPimEvent::ValueList::ConstIterator it = list.begin(); it != list.end(); ++it ) { int dur = (*it).startDateTime().date().daysTo( (*it).endDateTime().date() ); QDate itDate = from.addDays(-dur ); OPimRecurrence rec = (*it).recurrence(); if ( !rec.hasEndDate() || rec.endDate() > to ) { rec.setEndDate( to ); rec.setHasEndDate( true ); } QDateTime start, end; while (rec.nextOcurrence(itDate, repeat ) ) { if (repeat > to ) break; OPimEvent event = *it; start = QDateTime( repeat, event.startDateTime().time() ); end = QDateTime( repeat.addDays(dur), event.endDateTime().time() ); OPimBackendOccurrence eff(start, end, event.uid() ); tmpList.append( eff ); } } } } namespace Opie { ODateBookAccessBackend::ODateBookAccessBackend() : OPimAccessBackend<OPimEvent>() { } ODateBookAccessBackend::~ODateBookAccessBackend() { } OPimBackendOccurrence::List ODateBookAccessBackend::occurrences( const QDate& from, const QDate& to )const { OPimBackendOccurrence::List tmpList; events( tmpList, directNonRepeats(), from, to ); repeat( tmpList, directRawRepeats(),from,to ); return tmpList; } OPimBackendOccurrence::List ODateBookAccessBackend::occurrences( const QDateTime& dt )const { OPimBackendOccurrence::List day = occurrences( dt.date(), dt.date() ); return filterOccurrences( day, dt ); } OPimBackendOccurrence::List ODateBookAccessBackend::effectiveNonRepeatingEvents( const QDate& from, const QDate& to )const { OPimBackendOccurrence::List tmpList; OPimEvent::ValueList list = directNonRepeats(); events( tmpList, list, from, to ); return tmpList; } OPimBackendOccurrence::List ODateBookAccessBackend::effectiveNonRepeatingEvents( const QDateTime& dt )const { OPimBackendOccurrence::List day = effectiveNonRepeatingEvents( dt.date(), dt.date() ); return filterOccurrences( day,dt ); } const uint ODateBookAccessBackend::querySettings() const { return 0; } bool ODateBookAccessBackend::hasQuerySettings (uint querySettings) const { return false; } UIDArray ODateBookAccessBackend::queryByExample( const UIDArray& uidlist, const OPimEvent&, int settings, const QDateTime& d )const { qDebug( "Accessing ODateBookAccessBackend::queryByExample() which is not implemented!" ); return UIDArray(); } -UIDArray ODateBookAccessBackend::sorted( const UIDArray&, bool asc, int, int, const QArray<int>& )const { - return UIDArray(); +UIDArray ODateBookAccessBackend::sorted( const UIDArray& ar, bool asc, int sortOrder, int filter, const QArray<int>& categories )const { + odebug << "Using Unaccelerated ODateBookAccessBackend sorted Implementation" << oendl; + + Internal::OPimEventSortVector vector( ar.count(), asc, sortOrder ); + int item = 0; + + for ( uint i = 0; i < ar.count(); ++i ){ + OPimEvent event = find( ar[i], ar, i, Frontend::Forward ); + if ( event.isEmpty() ) + continue; + + bool catPassed = true; + if ( filter & ODateBookAccess::FilterCategory ){ + catPassed = false; + // Filter Categories + for ( uint cat_idx = 0; cat_idx < categories.count(); ++cat_idx ){ + int cat = categories[cat_idx]; + if ( cat == -1 || cat == 0 ){ + // Unfiled. Check next category if list is not empty. + // Else: take it as we will not filter unfiled events.. + if ( !event.categories().isEmpty() ) + continue; + else + catPassed = true; + } else { + if ( !event.categories().contains( cat ) ) + continue; + else{ + catPassed = true; + break; + } + } + } + } + + // Continue to next event if the category filter removed this item + if ( !catPassed ) + continue; + + vector.insert( item++, event ); + } + + // Now sort the vector and return the list of UID's + vector.resize( item ); + vector.sort(); + + UIDArray array( vector.count() ); + for ( uint i= 0; i < vector.count(); i++ ) + array[i] = vector.uidAt( i ); + + return array; + } OPimBackendOccurrence::List ODateBookAccessBackend::filterOccurrences( const OPimBackendOccurrence::List dayList, const QDateTime& dt ) { OPimBackendOccurrence::List tmpList; OPimBackendOccurrence::List::ConstIterator it; for ( it = dayList.begin(); it != dayList.end(); ++it ) { OPimBackendOccurrence occ = *it; /* * Let us find occurrences that are 'now'! * If the dt.date() is on the same day as start or end of the Occurrence * check how near start/end are. * If it is in the middle of a multiday occurrence list it. * * We might want to 'lose' the sixty second offset and list * all Events which are active at that time. */ if ( dt.date() == occ.startDateTime().date() ) { if ( QABS( dt.time().secsTo( occ.startDateTime().time() ) ) < 60 ) tmpList.append( occ ); }else if ( dt.date() == occ.endDateTime().date() ) { if ( QABS( dt.time().secsTo( occ.endDateTime().time() ) ) < 60 ) tmpList.append( occ ); }else if ( dt.date() >= occ.startDateTime().date() && dt.date() >= occ.endDateTime().date() ) tmpList.append( occ ); } return tmpList; } } diff --git a/libopie2/opiepim/core/odatebookaccess.h b/libopie2/opiepim/core/odatebookaccess.h index 0be8606..d2e3925 100644 --- a/libopie2/opiepim/core/odatebookaccess.h +++ b/libopie2/opiepim/core/odatebookaccess.h @@ -1,76 +1,101 @@ /* This file is part of the Opie Project Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) =. Copyright (C) The Opie Team <opie-devel@handhelds.org> .=l. .>+-= _;:, .> :=|. This program is free software; you can .> <`_, > . <= redistribute it and/or modify it under :`=1 )Y*s>-.-- : the terms of the GNU Library General Public .="- .-=="i, .._ License as published by the Free Software - . .-<_> .<> Foundation; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+i> _;_. .i_,=:_. -<s. This program is distributed in the hope that + . -:. = it will be useful, but WITHOUT ANY WARRANTY; : .. .:, . . . without even the implied warranty of =_ + =;=|` MERCHANTABILITY or FITNESS FOR A _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU ..}^=.= = ; Library General Public License for more ++= -. .` .: details. : = ...= . :.=- -. .:....=;==+<; You should have received a copy of the GNU -_. . . )=. = Library General Public License along with -- :-=` this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef OPIE_DATE_BOOK_ACCESS_H #define OPIE_DATE_BOOK_ACCESS_H #include "odatebookaccessbackend.h" #include "opimaccesstemplate.h" #include <opie2/opimevent.h> namespace Opie { /** * This is the object orientated datebook database. It'll use OBackendFactory * to query for a backend. * All access to the datebook should be done via this class. * Make sure to load and save the datebook this is not part of * destructing and creating the object * * @author Holger Freyther, Stefan Eilers */ class ODateBookAccess : public OPimAccessTemplate<OPimEvent> { public: + /** + * Filter for sorted() + * @see SortFilterBase in OPimBase + */ + enum SortFilter { + + }; + + /** + * Sort order for sorted() + * @see SortOrderBase in OPimBase + */ + enum SortOrder { + SortDescription = SortCustom, + SortLocation, + SortNote, + SortStartTime, + SortEndTime, + SortStartDate, + SortEndDate, + SortStartDateTime, + SortEndDateTime, + SortAlarmDateTime, + }; + ODateBookAccess( ODateBookAccessBackend* = 0l, enum Access acc = Random ); ~ODateBookAccess(); /* return repeating events */ List rawRepeats()const; /* return non repeating events */ List nonRepeats()const; /* return non repeating events (from,to) */ OPimOccurrence::List effectiveNonRepeatingEvents( const QDate& from, const QDate& to ) const; OPimOccurrence::List effectiveNonRepeatingEvents( const QDateTime& start ) const; /** * Return identification of used records */ int rtti() const; private: ODateBookAccessBackend* m_backEnd; class Private; Private* d; }; } #endif diff --git a/libopie2/opiepim/private/opimeventsortvector.cpp b/libopie2/opiepim/private/opimeventsortvector.cpp new file mode 100644 index 0000000..4220c63 --- a/dev/null +++ b/libopie2/opiepim/private/opimeventsortvector.cpp @@ -0,0 +1,134 @@ +/* + This file is part of the Opie Project + Copyright (C) 2004 Stefan Eilers <stefan@eilers-online.net> + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include "opimeventsortvector.h" +#include <opie2/ocontactaccess.h> +#include <opie2/opimnotifymanager.h> +#include <opie2/odatebookaccess.h> + +#include <qvaluelist.h> + +namespace Opie { +namespace Internal { + +namespace{ + +inline int testAlarmNotifiers( const OPimNotifyManager& leftnotifiers, const OPimNotifyManager& rightnotifiers ){ + OPimNotifyManager::Alarms left_alarms = leftnotifiers.alarms(); + OPimNotifyManager::Alarms right_alarms = rightnotifiers.alarms(); + + // Well.. How could we compare two lists of alarms? I think we should find the most early datetimes + // and compare them.. (se) + // Find the first alarm of the left list + OPimNotifyManager::Alarms::Iterator it; + QDateTime left_earliest; // This datetime is initialized as invalid!! + for ( it = left_alarms.begin(); it != left_alarms.end(); ++it ){ + if ( !left_earliest.isValid() || left_earliest > (*it).dateTime() ){ + left_earliest = (*it).dateTime(); + } + } + QDateTime right_earliest; // This datetime is initialized as invalid!! + for ( it = right_alarms.begin(); it != right_alarms.end(); ++it ){ + if ( !right_earliest.isValid() || right_earliest > (*it).dateTime() ){ + right_earliest = (*it).dateTime(); + } + } + + int ret; + + // Now compare this found alarms + if ( !left_earliest .isValid() ) ret++; + if ( !right_earliest.isValid() ) ret--; + + if ( left_earliest.isValid() && right_earliest.isValid() ){ + ret += left_earliest < right_earliest ? -1 : 1; + } + + return ret; + +} +} + +OPimEventSortVector::OPimEventSortVector( uint size, bool asc, int sort ) + : OPimSortVector<OPimEvent>( size, asc, sort ) {} + +int OPimEventSortVector::compareItems( const OPimEvent& left, + const OPimEvent& right ) { + if ( left.uid() == right.uid() ) + return 0; + + int ret = 0; + bool asc = sortAscending(); + + switch( sortOrder() ) { + case ODateBookAccess::SortDescription: + ret = testString( left.description(), right.description() ); + break; + case ODateBookAccess::SortLocation: + ret = testString( left.location(), right.location() ); + break; + case ODateBookAccess::SortNote: + ret = testString( left.note(),right.note() ); + break; + case ODateBookAccess::SortStartTime: + ret = testTime( left.startDateTime().time(), right.startDateTime().time() ); + break; + case ODateBookAccess::SortEndTime: + ret = testTime( left.endDateTime().time(), right.endDateTime().time() ); + break; + case ODateBookAccess::SortStartDate: + ret = testDate( left.startDateTime().date(), right.startDateTime().date() ); + break; + case ODateBookAccess::SortEndDate: + ret = testDate( left.endDateTime().date(), right.endDateTime().date() ); + break; + case ODateBookAccess::SortStartDateTime: + ret = testDateTime( left.startDateTime(), right.startDateTime() ); + break; + case ODateBookAccess::SortEndDateTime: + ret = testDateTime( left.endDateTime(), right.endDateTime() ); + break; + case ODateBookAccess::SortAlarmDateTime: + ret = testAlarmNotifiers( left.notifiers(), right.notifiers() ); + break; + default: + odebug << "OpimEventSortVector: Unknown sortOrder: " << sortOrder() << oendl; + } + + /* twist to honor ascending/descending setting as QVector only sorts ascending */ + if ( !asc ) + ret *= -1; + + // Maybe differentiate as in OPimTodoSortVector ### FIXME + // if( ret ) + return ret; +} + +} +} diff --git a/libopie2/opiepim/private/opimeventsortvector.h b/libopie2/opiepim/private/opimeventsortvector.h new file mode 100644 index 0000000..dde26df --- a/dev/null +++ b/libopie2/opiepim/private/opimeventsortvector.h @@ -0,0 +1,48 @@ +/* + This file is part of the Opie Project + Copyright (C) 2004 Stefan Eilers <stefan@eilers-online.net> + =. Copyright (C) The Opie Team <opie-devel@handhelds.org> + .=l. + .>+-= + _;:, .> :=|. This program is free software; you can +.> <`_, > . <= redistribute it and/or modify it under +:`=1 )Y*s>-.-- : the terms of the GNU Library General Public +.="- .-=="i, .._ License as published by the Free Software + - . .-<_> .<> Foundation; either version 2 of the License, + ._= =} : or (at your option) any later version. + .%`+i> _;_. + .i_,=:_. -<s. This program is distributed in the hope that + + . -:. = it will be useful, but WITHOUT ANY WARRANTY; + : .. .:, . . . without even the implied warranty of + =_ + =;=|` MERCHANTABILITY or FITNESS FOR A + _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU +..}^=.= = ; Library General Public License for more +++= -. .` .: details. + : = ...= . :.=- + -. .:....=;==+<; You should have received a copy of the GNU + -_. . . )=. = Library General Public License along with + -- :-=` this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef OPIM_CONTACT_SORT_VECTOR_H +#define OPIM_CONTACT_SORT_VECTOR_H + +#include <opie2/opimevent.h> +#include <opie2/private/opimsortvector.h> + +namespace Opie { +namespace Internal { +class OPimEventSortVector : public OPimSortVector<OPimEvent> { +public: + OPimEventSortVector( uint size, bool asc, int sort ); +private: + int compareItems( const OPimEvent&, const OPimEvent& ); +}; +} +} + + +#endif diff --git a/libopie2/opiepim/private/opimsortvector.h b/libopie2/opiepim/private/opimsortvector.h index 6c21339..11a40ac 100644 --- a/libopie2/opiepim/private/opimsortvector.h +++ b/libopie2/opiepim/private/opimsortvector.h @@ -1,138 +1,172 @@ /* This file is part of the Opie Project Copyright (C) 2004 Holger Freyther <freyther@handhelds.org> =. Copyright (C) The Opie Team <opie-devel@handhelds.org> .=l. .>+-= _;:, .> :=|. This program is free software; you can .> <`_, > . <= redistribute it and/or modify it under :`=1 )Y*s>-.-- : the terms of the GNU Library General Public .="- .-=="i, .._ License as published by the Free Software - . .-<_> .<> Foundation; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+i> _;_. .i_,=:_. -<s. This program is distributed in the hope that + . -:. = it will be useful, but WITHOUT ANY WARRANTY; : .. .:, . . . without even the implied warranty of =_ + =;=|` MERCHANTABILITY or FITNESS FOR A _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU ..}^=.= = ; Library General Public License for more ++= -. .` .: details. : = ...= . :.=- -. .:....=;==+<; You should have received a copy of the GNU -_. . . )=. = Library General Public License along with -- :-=` this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef OPIE_PIM_SORT_VECTOR_H #define OPIE_PIM_SORT_VECTOR_H #include <opie2/opimglobal.h> #include <qvector.h> namespace Opie { namespace Internal { template<class T> struct OPimSortVectorContainer { T item; }; template<class T> class OPimSortVector : public QVector<OPimSortVectorContainer<T> > { typedef OPimSortVectorContainer<T> VectorItem; public: OPimSortVector( uint size, bool asc, int sort ); int compareItems( QCollection::Item d1, QCollection::Item d2 ); bool insert( uint, const T& t ); UID uidAt( uint i )const; protected: int testString( const QString&, const QString& )const; int testDate( const QDate&, const QDate& )const; + int testTime( const QTime&, const QTime& )const; + int testDateTime( const QDateTime& left, + const QDateTime& right )const; protected: bool sortAscending()const; int sortOrder()const; private: bool m_ascending : 1; int m_sort; virtual int compareItems( const T& item1, const T& item2 ) = 0; }; template<class T> OPimSortVector<T>::OPimSortVector( uint size, bool asc, int sort ) : QVector<VectorItem>( size ), m_ascending( asc ), m_sort( sort ) { this->setAutoDelete( true ); } /** * 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 * */ template<class T> int OPimSortVector<T>::compareItems( QCollection::Item d1, QCollection::Item d2 ) { return compareItems( ((VectorItem*)d1)->item, ((VectorItem*)d2)->item ); } template<class T> bool OPimSortVector<T>::sortAscending()const { return m_ascending; } template<class T> int OPimSortVector<T>::sortOrder()const { return m_sort; } template<class T> bool OPimSortVector<T>::insert( uint i, const T& record ) { VectorItem *item = new VectorItem; item->item = record; return QVector<VectorItem>::insert( i, item ); } template<class T> UID OPimSortVector<T>::uidAt( uint index )const { return this->at( index )->item.uid(); } template<class T> inline int OPimSortVector<T>::testString( const QString& left, const QString& right )const { return QString::compare( left, right ); } + template<class T> inline int OPimSortVector<T>::testDate( const QDate& left, const QDate& right )const { int ret = 0; if ( !left .isValid() ) ret++; if ( !right.isValid() ) ret--; if ( left.isValid() && right.isValid() ) ret += left < right ? -1 : 1; return ret; } + +template<class T> +inline int OPimSortVector<T>::testTime( const QTime& left, + const QTime& right )const { + int ret = 0; + if ( !left .isValid() ) ret++; + if ( !right.isValid() ) ret--; + + if ( left.isValid() && right.isValid() ){ + ret += left < right ? -1 : 1; + } + + return ret; +} + +template<class T> +inline int OPimSortVector<T>::testDateTime( const QDateTime& left, + const QDateTime& right )const { + int ret = 0; + if ( !left .isValid() ) ret++; + if ( !right.isValid() ) ret--; + + if ( left.isValid() && right.isValid() ){ + ret += left < right ? -1 : 1; + } + + return ret; + +} + } } #endif diff --git a/libopie2/opiepim/private/opimtodosortvector.cpp b/libopie2/opiepim/private/opimtodosortvector.cpp index 8d15710..1db20df 100644 --- a/libopie2/opiepim/private/opimtodosortvector.cpp +++ b/libopie2/opiepim/private/opimtodosortvector.cpp @@ -1,163 +1,165 @@ /* This file is part of the Opie Project Copyright (C) 2004 Holger Freyther <freyther@handhelds.org> =. Copyright (C) The Opie Team <opie-devel@handhelds.org> .=l. .>+-= _;:, .> :=|. This program is free software; you can .> <`_, > . <= redistribute it and/or modify it under :`=1 )Y*s>-.-- : the terms of the GNU Library General Public .="- .-=="i, .._ License as published by the Free Software - . .-<_> .<> Foundation; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+i> _;_. .i_,=:_. -<s. This program is distributed in the hope that + . -:. = it will be useful, but WITHOUT ANY WARRANTY; : .. .:, . . . without even the implied warranty of =_ + =;=|` MERCHANTABILITY or FITNESS FOR A _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU ..}^=.= = ; Library General Public License for more ++= -. .` .: details. : = ...= . :.=- -. .:....=;==+<; You should have received a copy of the GNU -_. . . )=. = Library General Public License along with -- :-=` this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "opimtodosortvector.h" #include <opie2/otodoaccess.h> namespace Opie { namespace Internal { +namespace{ inline QString string( const OPimTodo& todo) { return todo.summary().isEmpty() ? todo.description().left(20 ) : todo.summary(); } inline int completed( const OPimTodo& todo1, const OPimTodo& todo2) { int ret = 0; if ( todo1.isCompleted() ) ret++; if ( todo2.isCompleted() ) ret--; return ret; } inline int priority( const OPimTodo& t1, const OPimTodo& t2) { return ( t1.priority() - t2.priority() ); } inline int summary( const OPimTodo& t1, const OPimTodo& t2) { return QString::compare( string(t1), string(t2) ); } inline int deadline( const OPimTodo& t1, const OPimTodo& t2) { int ret = 0; if ( t1.hasDueDate() && t2.hasDueDate() ) ret = t2.dueDate().daysTo( t1.dueDate() ); else if ( t1.hasDueDate() ) ret = -1; else if ( t2.hasDueDate() ) ret = 1; else ret = 0; return ret; } +} OPimTodoSortVector::OPimTodoSortVector( uint size, bool asc, int sort ) : OPimSortVector<OPimTodo>( size, asc, sort ) {} int OPimTodoSortVector::compareItems( const OPimTodo& con1, const OPimTodo& con2 ) { bool seComp, sePrio, seSum, seDeadline; seComp = sePrio = seDeadline = seSum = false; int ret =0; bool asc = sortAscending(); /* same item */ if ( con1.uid() == con2.uid() ) return 0; switch ( sortOrder() ) { case OPimTodoAccess::Completed: { ret = completed( con1, con2 ); seComp = TRUE; break; } case OPimTodoAccess::Priority: { ret = priority( con1, con2 ); sePrio = TRUE; break; } case OPimTodoAccess::SortSummary: { ret = summary( con1, con2 ); seSum = TRUE; break; } case OPimTodoAccess::SortByDate: case OPimTodoAccess::Deadline: { ret = deadline( con1, con2 ); seDeadline = TRUE; break; } default: ret = 0; break; }; /* * FIXME do better sorting if the first sort criteria * ret equals 0 start with complete and so on... */ /* twist it we're not ascending*/ if (!asc) ret = ret * -1; if ( ret ) return ret; // default did not gave difference let's try it other way around /* * General try if already checked if not test * and return * 1.Completed * 2.Priority * 3.Description * 4.DueDate */ if (!seComp ) { if ( (ret = completed( con1, con2 ) ) ) { if (!asc ) ret *= -1; return ret; } } if (!sePrio ) { if ( (ret = priority( con1, con2 ) ) ) { if (!asc ) ret *= -1; return ret; } } if (!seSum ) { if ( (ret = summary(con1, con2 ) ) ) { if (!asc) ret *= -1; return ret; } } if (!seDeadline) { if ( (ret = deadline( con1, con2 ) ) ) { if (!asc) ret *= -1; return ret; } } return 0; } } } diff --git a/libopie2/opiepim/private/private.pro b/libopie2/opiepim/private/private.pro index 618c2d6..92c24cb 100644 --- a/libopie2/opiepim/private/private.pro +++ b/libopie2/opiepim/private/private.pro @@ -1,9 +1,11 @@ HEADERS += private/vobject_p.h \ private/opimcontactsortvector.h \ + private/opimeventsortvector.h \ private/opimoccurrence_p.h \ private/opimsortvector.h \ private/opimtodosortvector.h SOURCES += private/opimcontactsortvector.cpp \ + private/opimeventsortvector.cpp \ private/opimtodosortvector.cpp |