-rw-r--r-- | libopie2/opiepim/ChangeLog | 4 | ||||
-rw-r--r-- | libopie2/opiepim/backend/ocontactaccessbackend.cpp | 205 | ||||
-rw-r--r-- | libopie2/opiepim/backend/ocontactaccessbackend.h | 9 | ||||
-rw-r--r-- | libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp | 144 | ||||
-rw-r--r-- | libopie2/opiepim/backend/ocontactaccessbackend_sql.h | 23 | ||||
-rw-r--r-- | libopie2/opiepim/backend/ocontactaccessbackend_vcard.cpp | 14 | ||||
-rw-r--r-- | libopie2/opiepim/backend/ocontactaccessbackend_vcard.h | 4 | ||||
-rw-r--r-- | libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp | 205 | ||||
-rw-r--r-- | libopie2/opiepim/backend/ocontactaccessbackend_xml.h | 9 | ||||
-rw-r--r-- | libopie2/opiepim/backend/opimaccessbackend.h | 40 | ||||
-rw-r--r-- | libopie2/opiepim/core/ocontactaccess.h | 37 | ||||
-rw-r--r-- | libopie2/opiepim/core/opimaccesstemplate.h | 53 | ||||
-rw-r--r-- | libopie2/opiepim/core/opimtemplatebase.h | 57 | ||||
-rw-r--r-- | libopie2/opiepim/opiepim.pro | 2 |
14 files changed, 493 insertions, 313 deletions
diff --git a/libopie2/opiepim/ChangeLog b/libopie2/opiepim/ChangeLog index 9c85e4b..dd57259 100644 --- a/libopie2/opiepim/ChangeLog +++ b/libopie2/opiepim/ChangeLog @@ -1,14 +1,18 @@ +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 6ef60eb..b4fdd46 100644 --- a/libopie2/opiepim/backend/ocontactaccessbackend.cpp +++ b/libopie2/opiepim/backend/ocontactaccessbackend.cpp @@ -20,43 +20,236 @@ ++= -. .` .: 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 OPimContact&, int, - const QDateTime& )const { - return UIDArray(); +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, + checkDate->month(), + checkDate->day() ); + + // Check whether the birthday/anniversary date is between + // the current/given date and the maximum date + // ( maximum time range ) ! + if ( current.daysTo( *queryDate ) >= 0 ){ + if ( !( ( *checkDate >= current ) && + ( *checkDate <= *queryDate ) ) ){ + allcorrect = false; + } + } + } + } else{ + // checkDate is invalid. Therefore this entry is always rejected + allcorrect = false; + } + } + + delete queryDate; + queryDate = 0l; + delete checkDate; + checkDate = 0l; + break; + default: + /* Just compare fields which are not empty in the query object */ + if ( !query.field(i).isEmpty() ){ + switch ( settings & ~( OPimContactAccess::IgnoreCase + | OPimContactAccess::DateDiff + | OPimContactAccess::DateYear + | OPimContactAccess::DateMonth + | OPimContactAccess::DateDay + | OPimContactAccess::MatchOne + ) ){ + + case OPimContactAccess::RegExp:{ + QRegExp expr ( query.field(i), + !(settings & OPimContactAccess::IgnoreCase), + false ); + if ( expr.find ( find( uid_array[it] ).field(i), 0 ) == -1 ) + allcorrect = false; + } + break; + case OPimContactAccess::WildCards:{ + 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; + } -UIDArray -OPimContactAccessBackend::sorted( const UIDArray& ar, bool asc, int sortOrder, +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 { 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; diff --git a/libopie2/opiepim/backend/ocontactaccessbackend.h b/libopie2/opiepim/backend/ocontactaccessbackend.h index efb04c7..ee6dbc2 100644 --- a/libopie2/opiepim/backend/ocontactaccessbackend.h +++ b/libopie2/opiepim/backend/ocontactaccessbackend.h @@ -67,42 +67,45 @@ class OPimContactAccessBackend: public OPimAccessBackend<OPimContact> { * 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) */ - virtual const uint querySettings() = 0; + virtual const uint querySettings() const; /** * Check whether settings are correct. * @return <i>true</i> if the given settings are correct and possible. */ - virtual bool hasQuerySettings (uint querySettings) const = 0; + virtual 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 queryByExample( const OPimContact&, int settings, const QDateTime& d = QDateTime() )const; UIDArray sorted( const UIDArray&, bool asc, int, int, const QArray<int>& )const; OPimBackendOccurrence::List occurrences( const QDate&, const QDate& )const; //@} private: class Private; Private *d; }; } #endif diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp b/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp index 3d284f7..9375f43 100644 --- a/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp +++ b/libopie2/opiepim/backend/ocontactaccessbackend_sql.cpp @@ -114,55 +114,55 @@ namespace { */ class RemoveQuery : public OSQLQuery { public: RemoveQuery(int uid ); ~RemoveQuery(); QString query()const; private: int m_uid; }; /** * a find query for noncustom elements */ class FindQuery : public OSQLQuery { public: FindQuery(int uid); - FindQuery(const QArray<int>& ); + FindQuery(const UIDArray& ); ~FindQuery(); QString query()const; private: QString single()const; QString multi()const; - QArray<int> m_uids; + UIDArray m_uids; int m_uid; }; /** * a find query for custom elements */ class FindCustomQuery : public OSQLQuery { public: FindCustomQuery(int uid); - FindCustomQuery(const QArray<int>& ); + FindCustomQuery(const UIDArray& ); ~FindCustomQuery(); QString query()const; private: QString single()const; QString multi()const; - QArray<int> m_uids; + UIDArray m_uids; int m_uid; }; // We using two tables to store the information: // 1. addressbook : It contains General information about the contact (non custom) // 2. custom_data : Not official supported entries // All tables are connected by the uid of the contact. // Maybe I should add a table for meta-information ? CreateQuery::CreateQuery() : OSQLQuery() {} CreateQuery::~CreateQuery() {} QString CreateQuery::query()const { QString qu; qu += "create table addressbook( uid PRIMARY KEY "; @@ -281,33 +281,33 @@ namespace { : OSQLQuery(), m_uid( uid ) {} RemoveQuery::~RemoveQuery() {} QString RemoveQuery::query()const { QString qu = "DELETE from addressbook where uid = " + QString::number(m_uid) + ";"; qu += "DELETE from custom_data where uid = " + QString::number(m_uid) + ";"; return qu; } FindQuery::FindQuery(int uid) : OSQLQuery(), m_uid( uid ) { } - FindQuery::FindQuery(const QArray<int>& ints) + FindQuery::FindQuery(const UIDArray& ints) : OSQLQuery(), m_uids( ints ){ } FindQuery::~FindQuery() { } QString FindQuery::query()const{ if ( m_uids.count() == 0 ) return single(); else return multi(); } QString FindQuery::multi()const { QString qu = "select * from addressbook where"; for (uint i = 0; i < m_uids.count(); i++ ) { qu += " uid = " + QString::number( m_uids[i] ) + " OR"; } @@ -316,33 +316,33 @@ namespace { odebug << "find query: " << qu << "" << oendl; return qu; } QString FindQuery::single()const{ QString qu = "select *"; qu += " from addressbook where uid = " + QString::number(m_uid); // owarn << "find query: " << qu << "" << oendl; return qu; } FindCustomQuery::FindCustomQuery(int uid) : OSQLQuery(), m_uid( uid ) { } - FindCustomQuery::FindCustomQuery(const QArray<int>& ints) + FindCustomQuery::FindCustomQuery(const UIDArray& ints) : OSQLQuery(), m_uids( ints ){ } FindCustomQuery::~FindCustomQuery() { } QString FindCustomQuery::query()const{ // if ( m_uids.count() == 0 ) return single(); } QString FindCustomQuery::single()const{ QString qu = "select uid, type, value from custom_data where uid = "; qu += QString::number(m_uid); return qu; } }; @@ -409,33 +409,33 @@ bool OPimContactAccessBackend_SQL::save() } void OPimContactAccessBackend_SQL::clear () { ClearQuery cle; OSQLResult res = m_driver->query( &cle ); reload(); } bool OPimContactAccessBackend_SQL::wasChangedExternally() { return false; } -QArray<int> OPimContactAccessBackend_SQL::allRecords() const +UIDArray OPimContactAccessBackend_SQL::allRecords() const { // FIXME: Think about cute handling of changed tables.. // Thus, we don't have to call update here... if ( m_changed ) ((OPimContactAccessBackend_SQL*)this)->update(); return m_uids; } bool OPimContactAccessBackend_SQL::add ( const OPimContact &newcontact ) { odebug << "add in contact SQL-Backend" << oendl; InsertQuery ins( newcontact ); OSQLResult res = m_driver->query( &ins ); @@ -472,33 +472,33 @@ bool OPimContactAccessBackend_SQL::replace ( const OPimContact &contact ) } OPimContact OPimContactAccessBackend_SQL::find ( int uid ) const { odebug << "OPimContactAccessBackend_SQL::find(" << uid << ")" << oendl; QTime t; t.start(); OPimContact retContact( requestNonCustom( uid ) ); retContact.setExtraMap( requestCustom( uid ) ); odebug << "OPimContactAccessBackend_SQL::find() needed: " << t.elapsed() << " ms" << oendl; return retContact; } -OPimContact OPimContactAccessBackend_SQL::find( int uid, const QArray<int>& queryUids, uint current, Frontend::CacheDirection direction ) const +OPimContact OPimContactAccessBackend_SQL::find( int uid, const UIDArray& queryUids, uint current, Frontend::CacheDirection direction ) const { odebug << "OPimContactAccessBackend_SQL::find( ..multi.. )" << oendl; odebug << "searching for " << uid << "" << oendl; QTime t; t.start(); uint numReadAhead = readAhead(); QArray<int> searchList( numReadAhead ); uint size =0; // Build an array with all elements which should be requested and cached // We will just request "numReadAhead" elements, starting from "current" position in // the list of many uids ! switch( direction ) { @@ -515,33 +515,34 @@ OPimContact OPimContactAccessBackend_SQL::find( int uid, const QArray<int>& quer searchList[size] = queryUids[i]; size++; } break; } //Shrink to real size.. searchList.resize( size ); OPimContact retContact( requestContactsAndCache( uid, searchList ) ); odebug << "OPimContactAccessBackend_SQL::find( ..multi.. ) needed: " << t.elapsed() << " ms" << oendl; return retContact; } -QArray<int> OPimContactAccessBackend_SQL::queryByExample ( const OPimContact &query, int settings, const QDateTime& qd ) +UIDArray OPimContactAccessBackend_SQL::queryByExample ( const OPimContact &query, int settings, + const QDateTime& qd ) const { QString qu = "SELECT uid FROM addressbook WHERE"; QString searchQuery =""; QDate startDate; if ( qd.isValid() ) startDate = qd.date(); else startDate = QDate::currentDate(); QMap<int, QString> queryFields = query.toMap(); QStringList fieldList = OPimContactFields::untrfields( false ); QMap<QString, int> translate = OPimContactFields::untrFieldsToId(); @@ -626,73 +627,73 @@ QArray<int> OPimContactAccessBackend_SQL::queryByExample ( const OPimContact &qu } delete endDate; } // Skip trailing "AND" // if ( isAnyFieldSelected ) // qu = qu.left( qu.length() - 4 ); qu += searchQuery; odebug << "queryByExample query: " << qu << "" << oendl; // Execute query and return the received uid's OSQLRawQuery raw( qu ); OSQLResult res = m_driver->query( &raw ); if ( res.state() != OSQLResult::Success ){ - QArray<int> empty; + UIDArray empty; return empty; } - QArray<int> list = extractUids( res ); + UIDArray list = extractUids( res ); return list; } -QArray<int> OPimContactAccessBackend_SQL::matchRegexp( const QRegExp &r ) const +UIDArray OPimContactAccessBackend_SQL::matchRegexp( const QRegExp &r ) const { #if 0 QArray<int> nix(0); return nix; #else QString qu = "SELECT uid FROM addressbook WHERE ("; QString searchlist; QStringList fieldList = OPimContactFields::untrfields( false ); // QMap<QString, int> translate = OPimContactFields::untrFieldsToId(); for ( QStringList::Iterator it = ++fieldList.begin(); it != fieldList.end(); ++it ){ if ( !searchlist.isEmpty() ) searchlist += " OR "; searchlist += " rlike(\""+ r.pattern() + "\",\"" + *it + "\") "; } qu = qu + searchlist + ")"; odebug << "query: " << qu << "" << oendl; OSQLRawQuery raw( qu ); OSQLResult res = m_driver->query( &raw ); return extractUids( res ); #endif } -const uint OPimContactAccessBackend_SQL::querySettings() +const uint OPimContactAccessBackend_SQL::querySettings() const { return OPimContactAccess::IgnoreCase | OPimContactAccess::WildCards | OPimContactAccess::DateDiff | OPimContactAccess::DateYear | OPimContactAccess::DateMonth | OPimContactAccess::DateDay ; } bool OPimContactAccessBackend_SQL::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... */ @@ -725,88 +726,183 @@ bool OPimContactAccessBackend_SQL::hasQuerySettings (uint querySettings) const ) ){ 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 ); } } -QArray<int> OPimContactAccessBackend_SQL::sorted( bool asc, int , int , int ) +UIDArray OPimContactAccessBackend_SQL::sorted( const UIDArray& ar, bool asc, int sortOrder, + int filter, const QArray<int>& categories )const { QTime t; t.start(); - QString query = "SELECT uid FROM addressbook "; - query += "ORDER BY \"Last Name\" "; + QString query = "SELECT uid FROM addressbook"; + + query += " WHERE ("; + for ( uint i = 0; i < ar.count(); i++ ) { + query += " uid = " + QString::number( ar[i] ) + " OR"; + } + query.remove( query.length()-2, 2 ); // Hmmmm.. + query += ")"; + + + if ( filter != OPimBase::FilterOff ){ + if ( filter & OPimContactAccess::DoNotShowWithCategory ){ + query += " AND ( \"Categories\" == '' )"; + } else if ( filter & OPimBase::FilterCategory ){ + query += " AND ("; + for ( uint i = 0; i < categories.count(); i++ ){ + query += "\"Categories\" LIKE"; + query += QString( " '%" ) + QString::number( categories[i] ) + "%' OR"; + } + query.remove( query.length()-2, 2 ); // Hmmmm.. + query += ")"; + } + + if ( filter & OPimContactAccess::DoNotShowWithoutChildren ){ + query += " AND ( \"Children\" != '' )"; + } + + if ( filter & OPimContactAccess::DoNotShowWithoutAnniversary ){ + query += " AND ( \"Anniversary\" != '' )"; + } + + if ( filter & OPimContactAccess::DoNotShowWithoutBirthday ){ + query += " AND ( \"Birthday\" != '' )"; + } + + if ( filter & OPimContactAccess::DoNotShowWithoutHomeAddress ){ + // Expect that no Street means no Address, too! (eilers) + query += " AND ( \"Home Street\" != '' )"; + } + + if ( filter & OPimContactAccess::DoNotShowWithoutBusinessAddress ){ + // Expect that no Street means no Address, too! (eilers) + query += " AND ( \"Business Street\" != '' )"; + } + + } + + query += " ORDER BY"; + + switch ( sortOrder ) { + case OPimContactAccess::SortSummary: + query += " \"Notes\""; + break; + case OPimContactAccess::SortByCategory: + query += " \"Categories\""; + break; + case OPimContactAccess::SortByDate: + query += " \"\""; + break; + case OPimContactAccess::SortTitle: + query += " \"Name Title\""; + break; + case OPimContactAccess::SortFirstName: + query += " \"First Name\""; + break; + case OPimContactAccess::SortMiddleName: + query += " \"Middle Name\""; + break; + case OPimContactAccess::SortLastName: + query += " \"Last Name\""; + break; + case OPimContactAccess::SortFileAsName: + query += " \"File As\""; + break; + case OPimContactAccess::SortSuffix: + query += " \"Suffix\""; + break; + case OPimContactAccess::SortEmail: + query += " \"Default Email\""; + break; + case OPimContactAccess::SortNickname: + query += " \"Nickname\""; + break; + case OPimContactAccess::SortAnniversary: + query += " \"Anniversary\""; + break; + case OPimContactAccess::SortBirthday: + query += " \"Birthday\""; + break; + case OPimContactAccess::SortGender: + query += " \"Gender\""; + break; + default: + query += " \"Last Name\""; + } if ( !asc ) - query += "DESC"; + query += " DESC"; + - // odebug << "sorted query is: " << query << "" << oendl; + odebug << "sorted query is: " << query << "" << oendl; OSQLRawQuery raw( query ); OSQLResult res = m_driver->query( &raw ); if ( res.state() != OSQLResult::Success ){ - QArray<int> empty; + UIDArray empty; return empty; } - QArray<int> list = extractUids( res ); + UIDArray list = extractUids( res ); odebug << "sorted needed " << t.elapsed() << " ms!" << oendl; return list; } void OPimContactAccessBackend_SQL::update() { odebug << "Update starts" << oendl; QTime t; t.start(); // Now load the database set and extract the uid's // which will be held locally LoadQuery lo; OSQLResult res = m_driver->query(&lo); if ( res.state() != OSQLResult::Success ) return; m_uids = extractUids( res ); m_changed = false; odebug << "Update ends " << t.elapsed() << " ms" << oendl; } -QArray<int> OPimContactAccessBackend_SQL::extractUids( OSQLResult& res ) const +UIDArray OPimContactAccessBackend_SQL::extractUids( OSQLResult& res ) const { odebug << "extractUids" << oendl; QTime t; t.start(); OSQLResultItem::ValueList list = res.results(); OSQLResultItem::ValueList::Iterator it; - QArray<int> ints(list.count() ); + UIDArray ints(list.count() ); odebug << " count = " << list.count() << "" << oendl; int i = 0; for (it = list.begin(); it != list.end(); ++it ) { ints[i] = (*it).data("uid").toInt(); i++; } odebug << "extractUids ready: count2 = " << i << " needs " << t.elapsed() << " ms" << oendl; return ints; } QMap<int, QString> OPimContactAccessBackend_SQL::requestNonCustom( int uid ) const { QTime t; @@ -824,39 +920,39 @@ QMap<int, QString> OPimContactAccessBackend_SQL::requestNonCustom( int uid ) co QMap<int, QString> nonCustomMap; QTime t3; t3.start(); nonCustomMap = fillNonCustomMap( resItem ); t3needed = t3.elapsed(); // odebug << "Adding UID: " << resItem.data( "uid" ) << "" << oendl; odebug << "RequestNonCustom needed: insg.:" << t.elapsed() << " ms, query: " << t2needed << " ms, mapping: " << t3needed << " ms" << oendl; return nonCustomMap; } /* Returns contact requested by uid and fills cache with contacts requested by uids in the cachelist */ -OPimContact OPimContactAccessBackend_SQL::requestContactsAndCache( int uid, const QArray<int>& uidlist )const +OPimContact OPimContactAccessBackend_SQL::requestContactsAndCache( int uid, const UIDArray& uidlist )const { // We want to get all contacts with one query. // We don't have to add the given uid to the uidlist, it is expected to be there already (see opimrecordlist.h). // All contacts will be stored in the cache, afterwards the contact with the user id "uid" will be returned // by using the cache.. - QArray<int> cachelist = uidlist; + UIDArray cachelist = uidlist; OPimContact retContact; odebug << "Reqest and cache" << cachelist.size() << "elements !" << oendl; QTime t; t.start(); int t2needed = 0; int t3needed = 0; QTime t2; t2.start(); FindQuery query( cachelist ); OSQLResult res_noncustom = m_driver->query( &query ); t2needed = t2.elapsed(); QMap<int, QString> nonCustomMap; diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_sql.h b/libopie2/opiepim/backend/ocontactaccessbackend_sql.h index 28d9746..299c175 100644 --- a/libopie2/opiepim/backend/ocontactaccessbackend_sql.h +++ b/libopie2/opiepim/backend/ocontactaccessbackend_sql.h @@ -57,58 +57,59 @@ namespace Opie { * @see OPimAccessBackend for more information of available methods */ class OPimContactAccessBackend_SQL : public OPimContactAccessBackend { public: OPimContactAccessBackend_SQL ( const QString& appname, const QString& filename = QString::null ); ~OPimContactAccessBackend_SQL (); bool save(); bool load (); void clear (); bool wasChangedExternally(); - QArray<int> allRecords() const; + UIDArray allRecords() const; OPimContact find( int uid ) const; - OPimContact find( int uid, const QArray<int>& items, uint cur, Frontend::CacheDirection ) const; + OPimContact find( int uid, const UIDArray& items, uint cur, Frontend::CacheDirection ) const; - QArray<int> queryByExample ( const OPimContact &query, int settings, - const QDateTime& d ); + UIDArray queryByExample ( const OPimContact &query, int settings, + const QDateTime& d ) const; - QArray<int> matchRegexp( const QRegExp &r ) const; + UIDArray matchRegexp( const QRegExp &r ) const; - const uint querySettings(); + const uint querySettings() const; bool hasQuerySettings (uint querySettings) const; - // Currently only asc implemented.. - QArray<int> sorted( bool asc, int , int , int ); - bool add ( const OPimContact &newcontact ); + UIDArray sorted( const UIDArray& ar, bool asc, int sortOrder, + int filter, const QArray<int>& categories)const; + + bool add ( const OPimContact &newcontact ); bool replace ( const OPimContact &contact ); bool remove ( int uid ); bool reload(); private: - QArray<int> extractUids( Opie::DB::OSQLResult& res ) const; + UIDArray extractUids( Opie::DB::OSQLResult& res ) const; QMap<int, QString> requestNonCustom( int uid ) const; QMap<QString, QString> requestCustom( int uid ) const; QMap<int, QString> fillNonCustomMap( const Opie::DB::OSQLResultItem& resultItem ) const; OPimContact requestContactsAndCache( int uid, const QArray<int>& cachelist ) const; void update(); protected: bool m_changed; QString m_fileName; - QArray<int> m_uids; + UIDArray m_uids; Opie::DB::OSQLDriver* m_driver; }; } #endif diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_vcard.cpp b/libopie2/opiepim/backend/ocontactaccessbackend_vcard.cpp index 5bb21c7..f3b6d56 100644 --- a/libopie2/opiepim/backend/ocontactaccessbackend_vcard.cpp +++ b/libopie2/opiepim/backend/ocontactaccessbackend_vcard.cpp @@ -144,54 +144,44 @@ bool OPimContactAccessBackend_VCard::remove ( int uid ) m_dirty = true; return true; } bool OPimContactAccessBackend_VCard::replace ( const OPimContact &contact ) { m_map.replace( contact.uid(), contact ); m_dirty = true; return true; } OPimContact OPimContactAccessBackend_VCard::find ( int uid ) const { return m_map[uid]; } -QArray<int> OPimContactAccessBackend_VCard::allRecords() const +UIDArray OPimContactAccessBackend_VCard::allRecords() const { - QArray<int> ar( m_map.count() ); + UIDArray ar( m_map.count() ); QMap<int, OPimContact>::ConstIterator it; int i = 0; for ( it = m_map.begin(); it != m_map.end(); ++it ) { ar[i] = it.key(); i++; } return ar; } -const uint OPimContactAccessBackend_VCard::querySettings() -{ - return 0; // No search possible -} - -bool OPimContactAccessBackend_VCard::hasQuerySettings (uint ) const -{ - return false; // No search possible, therefore all settings invalid ;) -} - bool OPimContactAccessBackend_VCard::wasChangedExternally() { return false; // Don't expect concurrent access } // *** Private stuff *** OPimContact OPimContactAccessBackend_VCard::parseVObject( VObject *obj ) { OPimContact c; VObjectIterator it; initPropIterator( &it, obj ); while( moreIteration( &it ) ) { VObject *o = nextVObject( &it ); QCString name = vObjectName( o ); QString value = QString::fromUtf8( vObjectStringZValue( o ) ); odebug << "(1)Read: " << name << " " << QString( value ).latin1() << oendl; diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_vcard.h b/libopie2/opiepim/backend/ocontactaccessbackend_vcard.h index b734530..3591988 100644 --- a/libopie2/opiepim/backend/ocontactaccessbackend_vcard.h +++ b/libopie2/opiepim/backend/ocontactaccessbackend_vcard.h @@ -45,36 +45,34 @@ namespace Opie { * @see OPimAccessBackend */ class OPimContactAccessBackend_VCard : public OPimContactAccessBackend { public: OPimContactAccessBackend_VCard ( const QString& appname, const QString& filename = QString::null ); bool load (); bool reload(); bool save(); void clear (); bool add ( const OPimContact& newcontact ); bool remove ( int uid ); bool replace ( const OPimContact& contact ); OPimContact find ( int uid ) const; - QArray<int> allRecords() const; + UIDArray allRecords() const; - const uint querySettings(); - bool hasQuerySettings (uint querySettings) const; bool wasChangedExternally(); private: OPimContact parseVObject( VObject* obj ); VObject* createVObject( const OPimContact& c ); QString convDateToVCardDate( const QDate& c ) const; QDate convVCardDateToDate( const QString& datestr ); VObject *safeAddPropValue( VObject *o, const char* prop, const QString& value ); VObject *safeAddProp( VObject* o, const char* prop); bool m_dirty : 1; QString m_file; QMap<int, OPimContact> m_map; /** * Version of parsed VCard diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp b/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp index 5df7253..f96f1bf 100644 --- a/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp +++ b/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp @@ -170,279 +170,86 @@ void OPimContactAccessBackend_XML::clear () { m_contactList.clear(); m_uidToContact.clear(); m_changed = false; } bool OPimContactAccessBackend_XML::wasChangedExternally() { QFileInfo fi( m_fileName ); QDateTime lastmod = fi.lastModified (); return (lastmod != m_readtime); } -QArray<int> OPimContactAccessBackend_XML::allRecords() const +UIDArray OPimContactAccessBackend_XML::allRecords() const { - QArray<int> uid_list( m_contactList.count() ); + UIDArray uid_list( m_contactList.count() ); uint counter = 0; QListIterator<OPimContact> it( m_contactList ); for( ; it.current(); ++it ){ uid_list[counter++] = (*it)->uid(); } return ( uid_list ); } OPimContact OPimContactAccessBackend_XML::find ( int uid ) const { OPimContact foundContact; //Create empty contact OPimContact* found = m_uidToContact.find( QString().setNum( uid ) ); if ( found ){ foundContact = *found; } return ( foundContact ); } -QArray<int> OPimContactAccessBackend_XML::queryByExample ( const OPimContact &query, int settings, - const QDateTime& d )const -{ - QArray<int> m_currentQuery( m_contactList.count() ); - QListIterator<OPimContact> it( m_contactList ); - uint arraycounter = 0; - - for( ; it.current(); ++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( (*it)->birthday() ); - // fall through - case Qtopia::Anniversary: - if ( queryDate == 0l ){ - queryDate = new QDate( query.anniversary() ); - checkDate = new QDate( (*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, - checkDate->month(), - checkDate->day() ); - - // Check whether the birthday/anniversary date is between - // the current/given date and the maximum date - // ( maximum time range ) ! - if ( current.daysTo( *queryDate ) >= 0 ){ - if ( !( ( *checkDate >= current ) && - ( *checkDate <= *queryDate ) ) ){ - allcorrect = false; - } - } - } - } else{ - // checkDate is invalid. Therefore this entry is always rejected - allcorrect = false; - } - } - delete queryDate; - queryDate = 0l; - delete checkDate; - checkDate = 0l; - break; - default: - /* Just compare fields which are not empty in the query object */ - if ( !query.field(i).isEmpty() ){ - switch ( settings & ~( OPimContactAccess::IgnoreCase - | OPimContactAccess::DateDiff - | OPimContactAccess::DateYear - | OPimContactAccess::DateMonth - | OPimContactAccess::DateDay - | OPimContactAccess::MatchOne - ) ){ - - case OPimContactAccess::RegExp:{ - QRegExp expr ( query.field(i), - !(settings & OPimContactAccess::IgnoreCase), - false ); - if ( expr.find ( (*it)->field(i), 0 ) == -1 ) - allcorrect = false; - } - break; - case OPimContactAccess::WildCards:{ - QRegExp expr ( query.field(i), - !(settings & OPimContactAccess::IgnoreCase), - true ); - if ( expr.find ( (*it)->field(i), 0 ) == -1 ) - allcorrect = false; - } - break; - case OPimContactAccess::ExactMatch:{ - if (settings & OPimContactAccess::IgnoreCase){ - if ( query.field(i).upper() != - (*it)->field(i).upper() ) - allcorrect = false; - }else{ - if ( query.field(i) != (*it)->field(i) ) - allcorrect = false; - } - } - break; - } - } - } - } - if ( allcorrect ){ - m_currentQuery[arraycounter++] = (*it)->uid(); - } - } - - // Shrink to fit.. - m_currentQuery.resize(arraycounter); - - return m_currentQuery; -} - -QArray<int> OPimContactAccessBackend_XML::matchRegexp( const QRegExp &r ) const +UIDArray OPimContactAccessBackend_XML::matchRegexp( const QRegExp &r ) const { - QArray<int> m_currentQuery( m_contactList.count() ); + UIDArray m_currentQuery( m_contactList.count() ); QListIterator<OPimContact> it( m_contactList ); uint arraycounter = 0; for( ; it.current(); ++it ){ if ( (*it)->match( r ) ){ m_currentQuery[arraycounter++] = (*it)->uid(); } } // Shrink to fit.. m_currentQuery.resize(arraycounter); return m_currentQuery; } -const uint OPimContactAccessBackend_XML::querySettings() -{ - return ( OPimContactAccess::WildCards - | OPimContactAccess::IgnoreCase - | OPimContactAccess::RegExp - | OPimContactAccess::ExactMatch - | OPimContactAccess::DateDiff - | OPimContactAccess::DateYear - | OPimContactAccess::DateMonth - | OPimContactAccess::DateDay - ); -} -bool OPimContactAccessBackend_XML::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 ); - } -} #if 0 // Currently only asc implemented.. -QArray<int> OPimContactAccessBackend_XML::sorted( bool asc, int , int , int ) +UIDArray OPimContactAccessBackend_XML::sorted( bool asc, int , int , int ) { QMap<QString, int> nameToUid; QStringList names; - QArray<int> m_currentQuery( m_contactList.count() ); + UIDArray m_currentQuery( m_contactList.count() ); // First fill map and StringList with all Names // Afterwards sort namelist and use map to fill array to return.. QListIterator<OPimContact> it( m_contactList ); for( ; it.current(); ++it ){ names.append( (*it)->fileAs() + QString::number( (*it)->uid() ) ); nameToUid.insert( (*it)->fileAs() + QString::number( (*it)->uid() ), (*it)->uid() ); } names.sort(); int i = 0; if ( asc ){ for ( QStringList::Iterator it = names.begin(); it != names.end(); ++it ) m_currentQuery[i++] = nameToUid[ (*it) ]; }else{ for ( QStringList::Iterator it = names.end(); it != names.begin(); --it ) diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_xml.h b/libopie2/opiepim/backend/ocontactaccessbackend_xml.h index 3e4f1e1..39378ec 100644 --- a/libopie2/opiepim/backend/ocontactaccessbackend_xml.h +++ b/libopie2/opiepim/backend/ocontactaccessbackend_xml.h @@ -45,42 +45,37 @@ namespace Opie { * This class is the XML implementation of a Contact backend * it does implement everything available for OPimContact. * @see OPimAccessBackend for more information of available methods */ class OPimContactAccessBackend_XML : public OPimContactAccessBackend { public: OPimContactAccessBackend_XML ( const QString& appname, const QString& filename = QString::null ); bool save(); bool load (); void clear (); bool wasChangedExternally(); - QArray<int> allRecords() const; + UIDArray allRecords() const; OPimContact find ( int uid ) const; - QArray<int> queryByExample ( const OPimContact &query, int settings, const QDateTime& d )const; - QArray<int> matchRegexp( const QRegExp &r ) const; - - const uint querySettings(); - - bool hasQuerySettings (uint querySettings) const; + UIDArray matchRegexp( const QRegExp &r ) const; bool add ( const OPimContact &newcontact ); bool replace ( const OPimContact &contact ); bool remove ( int uid ); bool reload(); private: enum journal_action { ACTION_ADD, ACTION_REMOVE, ACTION_REPLACE }; void addContact_p( const OPimContact &newcontact ); /* This function loads the xml-database and the journalfile */ bool load( const QString filename, bool isJournal ); diff --git a/libopie2/opiepim/backend/opimaccessbackend.h b/libopie2/opiepim/backend/opimaccessbackend.h index 0d112c9..7321758 100644 --- a/libopie2/opiepim/backend/opimaccessbackend.h +++ b/libopie2/opiepim/backend/opimaccessbackend.h @@ -53,39 +53,60 @@ template <class T = OPimRecord> class OPimAccessBackend { public: typedef OTemplateBase<T> Frontend; //@{ OPimAccessBackend(int access = 0); virtual ~OPimAccessBackend(); //@} //@{ virtual bool load() = 0; virtual bool reload() = 0; virtual bool save() = 0; virtual void clear() = 0; //@} + //@{ + // FIXME: Uncommented some of the abstract functions below. This should be removed as they are implemented in + // all typespecifc backenends (eilers) + /** + * Return all possible settings for queryByExample() + * @return All settings provided by the current backend + * (i.e.: query_WildCards & query_IgnoreCase) + * See implementation in the specific backends for contacts, todo and dates. + */ + virtual const uint querySettings() const { return 0; } /* FIXME: Make Abstrakt !! = 0; */ + + /** + * Check whether settings are correct for queryByExample() + * See implementation in the specific backends for OPimContactAccess, OPimTodoAccess and ODateBookAccess. + * @return <i>true</i> if the given settings are correct and possible. + */ + virtual bool hasQuerySettings (uint querySettings) const { return false; } /* FIXME: Make Abstrakt !! = 0; */ + //@} + //@{ virtual UIDArray allRecords()const = 0; virtual UIDArray matchRegexp(const QRegExp &r) const; - virtual UIDArray queryByExample( const T& t, int settings, const QDateTime& d = QDateTime() )const = 0; - virtual UIDArray queryByExample( const OPimRecord* rec, int, const QDateTime& d = QDateTime() )const; - virtual UIDArray sorted( const UIDArray&, bool asc, int sortOrder, int sortFilter, const QArray<int>& cats )const; + virtual UIDArray queryByExample( const UIDArray&, const T& t, + int settings, const QDateTime& d = QDateTime() )const { return UIDArray(); } /* FIXME: Make Abstrakt !! = 0; */ + virtual UIDArray queryByExample( const T& t, int settings, const QDateTime& d = QDateTime() )const; + virtual UIDArray queryByExample( const OPimRecord* rec, int settings, const QDateTime& d = QDateTime() )const; + virtual UIDArray sorted( const UIDArray&, bool asc, int sortOrder, int sortFilter, const QArray<int>& cats )const = 0; virtual UIDArray sorted( bool asc, int sortOrder, int sortFilter, const QArray<int>& cats )const; virtual OPimBackendOccurrence::List occurrences( const QDate& start, const QDate& end)const; virtual OPimBackendOccurrence::List occurrences( const QDateTime& dt )const; //@} //@{ virtual T find(UID uid )const = 0; virtual T find(UID uid, const QArray<UID>& items, uint current, typename Frontend::CacheDirection )const ; //@} //@{ virtual bool add( const T& t ) = 0; virtual bool remove( UID uid ) = 0; @@ -137,49 +158,50 @@ OPimAccessBackend<T>::~OPimAccessBackend() { template <class T> UIDArray OPimAccessBackend<T>::matchRegexp( const QRegExp& reg )const { UIDArray all_rec = allRecords(); UIDArray result( all_rec.count() ); uint used_records = 0, all_rec_count = all_rec.count(); for ( uint i = 0; i < all_rec_count; ++i ) if (find( all_rec[i], all_rec, i, Frontend::Forward ).match( reg ) ) result[used_records++] = all_rec[i]; /* shrink to fit */ result.resize( used_records ); return result; } template <class T> +UIDArray OPimAccessBackend<T>::queryByExample( const T& rec, int settings, + const QDateTime& datetime )const { + + return queryByExample( allRecords(), rec, settings, datetime ); +} + +template <class T> UIDArray OPimAccessBackend<T>::queryByExample( const OPimRecord* rec, int settings, const QDateTime& datetime )const { T* tmp_rec = T::safeCast( rec ); UIDArray ar; if ( tmp_rec ) ar = queryByExample( *tmp_rec, settings, datetime ); return ar; } template <class T> -UIDArray OPimAccessBackend<T>::sorted( const UIDArray& ids, bool, - int, int, const QArray<int>& ) const { - return ids; -} - -template <class T> UIDArray OPimAccessBackend<T>::sorted( bool asc, int order, int filter, const QArray<int>& cats )const { return sorted( allRecords(), asc, order, filter, cats ); } template<class T> OPimBackendOccurrence::List OPimAccessBackend<T>::occurrences( const QDate&, const QDate& )const { return OPimBackendOccurrence::List(); } template<class T> OPimBackendOccurrence::List OPimAccessBackend<T>::occurrences( const QDateTime& dt )const { QDate date = dt.date(); return occurrences( date, date ); } diff --git a/libopie2/opiepim/core/ocontactaccess.h b/libopie2/opiepim/core/ocontactaccess.h index 691ece2..bd85b4e 100644 --- a/libopie2/opiepim/core/ocontactaccess.h +++ b/libopie2/opiepim/core/ocontactaccess.h @@ -47,79 +47,100 @@ namespace Opie { /** * Class to access the contacts database. * This is just a frontend for the real database handling which is * done by the backend. * This class is used to access the Contacts on a system. This class as any OPIE PIM * class is backend independent. * @author Stefan Eilers, Holger Freyther * @see OPimAccessTemplate */ class OPimContactAccess: public QObject, public OPimAccessTemplate<OPimContact> { Q_OBJECT public: + /** + * Filter for sorted() + * @see SortFilterBase in OPimBase + */ enum SortFilter { - DoNotShowNoneChildren = FilterCustom<<1, - DoNotShowNoneAnniversary = FilterCustom<<2, - DoNotShowNoneBirthday = FilterCustom<<3, - DoNotShowNoHomeAddress = FilterCustom<<4, - DoNotShowNoBusinessAddress = FilterCustom<<5 + /** Don't return entries who don't have children */ + DoNotShowWithoutChildren = FilterCustom<<1, + /** Don't return entries who don't have an anniversary */ + DoNotShowWithoutAnniversary = FilterCustom<<2, + /** Don't return entries who don't have a birthday */ + DoNotShowWithoutBirthday = FilterCustom<<3, + /** Don't return entries who don't have a home address */ + DoNotShowWithoutHomeAddress = FilterCustom<<4, + /** Don't return entries who don't have a business address */ + DoNotShowWithoutBusinessAddress = FilterCustom<<5, + /** Don't return entries which hava any category */ + DoNotShowWithCategory = FilterCustom << 6 }; + /** + * Sort order for sorted() + * @see SortOrderBase in OPimBase + */ enum SortOrder { SortTitle = SortCustom, SortFirstName, SortMiddleName, + SortLastName, SortSuffix, SortEmail, SortNickname, + SortFileAsName, SortAnniversary, SortBirthday, SortGender }; /** * Create Database with contacts (addressbook). * @param appname Name of application which wants access to the database * (i.e. "todolist") * @param filename The name of the database file. If not set, the default one * is used. * @param backend Pointer to an alternative Backend. If not set, we will use * the default backend. * @param handlesync If <b>true</b> the database stores the current state * automatically if it receives the signals <i>flush()</i> and <i>reload()</i> * which are used before and after synchronisation. If the application wants * to react itself, it should be disabled by setting it to <b>false</b> * @see OPimContactAccessBackend */ OPimContactAccess (const QString appname, const QString filename = 0l, OPimContactAccessBackend* backend = 0l, bool handlesync = true); ~OPimContactAccess (); - /** Return all possible settings. + /** + * Return all possible settings for queryByExample(). * @return All settings provided by the current backend - * (i.e.: query_WildCards & query_IgnoreCase) + * (i.e.: WildCards & IgnoreCase) + * @see QuerySettings in OPimBase for details of the parameter */ const uint querySettings(); - /** Check whether settings are correct. + /** + * Check whether settings are correct for queryByExample(). * @return <i>true</i> if the given settings are correct and possible. + * @see QuerySettings in OPimBase for details of the parameter */ bool hasQuerySettings ( int querySettings ) const; /** * if the resource was changed externally. * You should use the signal instead of polling possible changes ! */ bool wasChangedExternally()const; /** Save contacts database. * Save is more a "commit". After calling this function, all changes are public available. * @return true if successful */ bool save(); diff --git a/libopie2/opiepim/core/opimaccesstemplate.h b/libopie2/opiepim/core/opimaccesstemplate.h index 2deb92a..073d5f9 100644 --- a/libopie2/opiepim/core/opimaccesstemplate.h +++ b/libopie2/opiepim/core/opimaccesstemplate.h @@ -77,72 +77,108 @@ public: bool load(); virtual bool reload(); bool save(); void clear() ; //@} bool wasChangedExternally()const; //@{ virtual List allRecords()const; virtual List matchRegexp( const QRegExp &r ) const; virtual List queryByExample( const T& t, int querySettings, const QDateTime& d = QDateTime() ); virtual T find( UID uid )const; virtual T find( UID uid, const QArray<int>&, uint current, typename OTemplateBase<T>::CacheDirection dir = OTemplateBase<T>::Forward )const; - virtual List sorted( const List&, bool ascending, int sortOrder, + //@} + + /** + * Get sorted lists.. + * @see OPimContactAccess, OPimTodoAccess and ODateBookAccess regarding more info for the following params: + * @param list of UID's received by allRecords() or others... + * @param sortOrder Setting the sort order defined by enum SortOrder + * @param ascending Sort in ascending order if true, otherwise descending + * @param sortFilter Setting the sort filter defined by enum SortFilter + * @param cat number of category. + */ + virtual List sorted( const List& list, bool ascending, int sortOrder, int sortFilter, int cat )const; - virtual List sorted( const List&, bool ascending, int sortOrder, + + /** + * Get sorted lists.. + * @see OPimContactAccess, OPimTodoAccess and ODateBookAccess regarding more info for the following params: + * @param list of UID's received by allRecords() or others... + * @param sortOrder Setting the sort order defined by enum SortOrder + * @param ascending Sort in ascending order if true, otherwise descending + * @param sortFilter Setting the sort filter defined by enum SortFilter + * @param cats List of categories. + */ + virtual List sorted( const List& list, bool ascending, int sortOrder, int sortFilter, const QArray<UID>& cats )const; + + /** + * Get sorted lists.. + * @see OPimContactAccess, OPimTodoAccess and ODateBookAccess regarding more info for the following params: + * @param ascending Sort in ascending order if true, otherwise descending + * @param sortOrder Setting the sort order defined by enum SortOrder + * @param sortFilter Setting the sort filter defined by enum SortFilter + * @param cat number of category. + */ virtual List sorted( bool ascending, int sortOrder, int sortFilter, int cat )const; - virtual List sorted( bool ascending, int sortOrder, int sortOrder, - const QArray<UID>& cats )const; - //@} + /** + * Get sorted lists.. + * @see OPimContactAccess, OPimTodoAccess and ODateBookAccess regarding more info for the following params: + * @param ascending Sort in ascending order if true, otherwise descending + * @param sortOrder Setting the sort order defined by enum SortOrder + * @param sortFilter Setting the sort filter defined by enum SortFilter + * @param cats List of categories. + */ + virtual List sorted( bool ascending, int sortOrder, int sortFilter, + const QArray<UID>& cats )const; /** * (Re)Implementation */ //@{ UIDArray matchRegexpSimple( const QRegExp& r )const; UIDArray queryByExampleSimple( const OPimRecord*, int, const QDateTime& )const; UIDArray sortedSimple( const UIDArray&, bool asc, int sortOrder, int sortFilter, int cat )const; UIDArray sortedSimple( const UIDArray&, bool asc, int sortOrder, int sortFilter, const QArray<int>& )const; UIDArray sortedSimple( bool ascending, int sortOrder, int sortFilter, int cat )const; UIDArray sortedSimple( bool ascending, int sortOrder, int sortFilter, const QArray<int>& )const; OPimOccurrence::List occurrences( const QDate& start, const QDate& end )const; OPimOccurrence::List occurrences( const QDateTime& dt )const; //@} //@{ virtual bool add( const T& t ) ; bool add( const OPimRecord& ); bool add( const OPimRecord* ); virtual bool remove( const T& t ); bool remove( UID uid ); bool remove( const OPimRecord& ); virtual bool replace( const T& t) ; //@} void setReadAhead( uint count ); - virtual T cacheFind( int uid )const; void cache( const T& )const; void setSaneCacheSize( int ); QArray<UID> records()const; protected: /** * invalidate the cache */ void invalidateCache(); void setBackEnd( BackEnd* end ); /** * returns the backend */ BackEnd* backEnd(); BackEnd* m_backEnd; @@ -245,37 +281,32 @@ OPimAccessTemplate<T>::queryByExample( const T& t, int settings, const QDateTime List lis(ints, this ); return lis; } template <class T> T OPimAccessTemplate<T>::find( UID uid ) const{ // First search in cache.. if ( m_cache.contains( uid ) ) return m_cache.find( uid ); T t = m_backEnd->find( uid ); cache( t ); return t; } -template <class T> -T OPimAccessTemplate<T>::cacheFind( int uid ) const -{ - return m_cache.find( uid ); -} /** * read ahead cache find method ;) */ template <class T> T OPimAccessTemplate<T>::find( UID uid, const QArray<int>& ar, uint current, typename OTemplateBase<T>::CacheDirection dir )const { /* * better do T.isEmpty() * after a find this way we would * avoid two finds in QCache... */ if (m_cache.contains( uid ) ) return m_cache.find( uid ); diff --git a/libopie2/opiepim/core/opimtemplatebase.h b/libopie2/opiepim/core/opimtemplatebase.h index b238a68..c8abab4 100644 --- a/libopie2/opiepim/core/opimtemplatebase.h +++ b/libopie2/opiepim/core/opimtemplatebase.h @@ -67,73 +67,92 @@ struct OPimBase { //@{ virtual bool add( const OPimRecord& ) = 0; virtual bool add( const OPimRecord* ) = 0; virtual bool remove( int uid ) = 0; virtual bool remove( const OPimRecord& ) = 0; //@} //@{ virtual void clear() = 0; virtual bool load() = 0; virtual bool save() = 0; //@} //@{ virtual QArray<UID> records()const = 0; + //@} /** Constants for query. * Use this constants to set the query parameters. * Note: <i>query_IgnoreCase</i> just make sense with one of the other attributes ! * @see queryByExample() */ enum QuerySettings { - WildCards = 0x0001, /** Use Wildcards */ - IgnoreCase = 0x0002, /** Ignore the Case */ - RegExp = 0x0004, /** Do a Regular Expression match */ - ExactMatch = 0x0008, /** It needs to exactly match */ - MatchOne = 0x0010, /** Only one Entry must match */ - DateDiff = 0x0020, /** Find all entries from today until given date */ - DateYear = 0x0040, /** The year matches */ - DateMonth = 0x0080, /** The month matches */ - DateDay = 0x0100, /** The day matches */ - LastItem = 0xffff /** the last possible name */ + /** Use Wildcards */ + WildCards = 0x0001, + /** Ignore the Case */ + IgnoreCase = 0x0002, + /** Do a Regular Expression match */ + RegExp = 0x0004, + /** It needs to exactly match */ + ExactMatch = 0x0008, + /** Only one Entry must match */ + MatchOne = 0x0010, + /** Find all entries from today until given date */ + DateDiff = 0x0020, + /** The year matches */ + DateYear = 0x0040, + /** The month matches */ + DateMonth = 0x0080, + /** The day matches */ + DateDay = 0x0100, + /** The last possible name matches */ + LastItem = 0xffff }; /** * Common Attributes for the Sort Order */ enum SortOrderBase { - SortSummary = 0, /** Sort by a Summary of the records */ - SortByCategory = 1, /** Sort by Category */ - SortByDate = 2, /** Sort by Date */ - SortCustom = 10, /** The First available sort number for the OPimAccessTemplates */ - LastSortOrderBase = 0xffff /** make this enum 16bit large */ + /** Sort by a Summary of the records */ + SortSummary = 0, + /** Sort by Category */ + SortByCategory = 1, + /** Sort by Date */ + SortByDate = 2, + /** The First available sort number for the OPimAccessTemplates */ + SortCustom = 10, + /** make this enum 16bit large */ + LastSortOrderBase = 0xffff }; /** - * Sort with the help of the \sa sorted function - * a list of Items. + * Sort a list of Items with the help of the sorted() function. * The Item you provide in SortOrder will be used * for sorting. * - * @see sorted + * @see OPimAccessTemplate<>::sorted() */ enum SortFilterBase { + /** Do not filter anything. */ + FilterOff = 0, + /** Use given Categories for filter */ FilterCategory = 1, - FilterCustom = 1024, + /** The first available custom filter defined in the specialized frontends */ + FilterCustom = 1024, LastSortFilterBase = 0xffffffff }; virtual UIDArray matchRegexpSimple( const QRegExp& r )const = 0; virtual UIDArray queryByExampleSimple( const OPimRecord*, int settings, const QDateTime& d = QDateTime() )const = 0; virtual UIDArray sortedSimple( const UIDArray& uid, bool ascending, int sortOrder, int sortFilter, int cat)const = 0; virtual UIDArray sortedSimple( const UIDArray& uid, bool ascending, int sortOrder, int sortFilter, const QArray<UID>& cats )const = 0; virtual UIDArray sortedSimple( bool ascending, int sortOrder, int sortFilter, int cat)const = 0; virtual UIDArray sortedSimple( bool ascending, int sortOrder, int sortFilter, const QArray<UID>& cats )const = 0; virtual OPimOccurrence::List occurrences( const QDate& start, const QDate& end )const = 0; virtual OPimOccurrence::List occurrences( const QDateTime& dt )const = 0; //@} diff --git a/libopie2/opiepim/opiepim.pro b/libopie2/opiepim/opiepim.pro index 47ec6da..992fb8b 100644 --- a/libopie2/opiepim/opiepim.pro +++ b/libopie2/opiepim/opiepim.pro @@ -1,23 +1,23 @@ TEMPLATE = lib CONFIG += qt warn_on DESTDIR = $(OPIEDIR)/lib INTERFACES = TARGET = opiepim2 -VERSION = 1.9.1 +VERSION = 1.8.6 INCLUDEPATH += $(OPIEDIR)/include DEPENDPATH += $(OPIEDIR)/include LIBS += -lopiecore2 include ( $(OPIEDIR)/gen.pro ) include ( core/core.pro ) include ( backend/backends.pro ) include ( ui/ui.pro ) include ( private/private.pro ) PRECOMPILED_HEADER = stable_pch.h !contains( platform, x11 ) { include ( $(OPIEDIR)/include.pro ) } |