author | eilers <eilers> | 2004-12-28 12:14:44 (UTC) |
---|---|---|
committer | eilers <eilers> | 2004-12-28 12:14:44 (UTC) |
commit | 4f0a67218237c83bdd02d339835f62ad064dc248 (patch) (side-by-side diff) | |
tree | 26680f7a55cb0b09f158e1bf18b4bad4117e0db0 /libopie2 | |
parent | 97a3d431ba9e33a3e256955755b23a55a9a9ea05 (diff) | |
download | opie-4f0a67218237c83bdd02d339835f62ad064dc248.zip opie-4f0a67218237c83bdd02d339835f62ad064dc248.tar.gz opie-4f0a67218237c83bdd02d339835f62ad064dc248.tar.bz2 |
* Make improved query by example accessable via frontend
* Some API improvement
-rw-r--r-- | libopie2/opiepim/ChangeLog | 3 | ||||
-rw-r--r-- | libopie2/opiepim/core/ocontactaccess.h | 2 | ||||
-rw-r--r-- | libopie2/opiepim/core/opimaccesstemplate.h | 76 | ||||
-rw-r--r-- | libopie2/opiepim/core/opimtemplatebase.h | 2 |
4 files changed, 74 insertions, 9 deletions
diff --git a/libopie2/opiepim/ChangeLog b/libopie2/opiepim/ChangeLog index dd57259..564e92a 100644 --- a/libopie2/opiepim/ChangeLog +++ b/libopie2/opiepim/ChangeLog @@ -1,18 +1,21 @@ +2004-12-28 Stefan Eilers <stefan@eilers-online.net> + * Make improved query by example accessable via frontend + * Some API improvement 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/core/ocontactaccess.h b/libopie2/opiepim/core/ocontactaccess.h index bd85b4e..5051321 100644 --- a/libopie2/opiepim/core/ocontactaccess.h +++ b/libopie2/opiepim/core/ocontactaccess.h @@ -27,151 +27,151 @@ Boston, MA 02111-1307, USA. */ /* * ===================================================================== * ToDo: Define enum for query settings * ===================================================================== */ #ifndef _OCONTACTACCESS_H #define _OCONTACTACCESS_H #include <qobject.h> #include <qpe/qcopenvelope_qws.h> #include <qvaluelist.h> #include <qfileinfo.h> #include <opie2/opimcontact.h> #include <opie2/ocontactaccessbackend.h> #include <opie2/opimaccesstemplate.h> 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 { /** 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 for queryByExample(). * @return All settings provided by the current backend * (i.e.: WildCards & IgnoreCase) - * @see QuerySettings in OPimBase for details of the parameter + * @see QuerySettings in OPimBase for details of the parameter, queryByExample() */ const uint querySettings(); /** * 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(); /** * Return identification of used records */ int rtti() const; signals: /* Signal is emitted if the database was changed. Therefore * we may need to reload to stay consistent. * @param which Pointer to the database who created this event. This pointer * is useful if an application has to handle multiple databases at the same time. * @see reload() */ void signalChanged ( const OPimContactAccess *which ); private: OPimContactAccessBackend *m_backEnd; bool m_loading:1; private slots: void copMessage( const QCString &msg, const QByteArray &data ); private: class Private; Private *d; }; } #endif diff --git a/libopie2/opiepim/core/opimaccesstemplate.h b/libopie2/opiepim/core/opimaccesstemplate.h index 073d5f9..3875f09 100644 --- a/libopie2/opiepim/core/opimaccesstemplate.h +++ b/libopie2/opiepim/core/opimaccesstemplate.h @@ -1,381 +1,443 @@ /* This file is part of the Opie Project Copyright (C) Holger Freyther <zecke@handhelds.org> 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_PIM_ACCESS_TEMPLATE_H #define OPIE_PIM_ACCESS_TEMPLATE_H /* OPIE */ #include <opie2/opimrecord.h> #include <opie2/opimaccessbackend.h> #include <opie2/opimrecordlist.h> #include <opie2/opimtemplatebase.h> #include <opie2/odebug.h> /* QT */ #include <qarray.h> #include <qdatetime.h> namespace Opie { class OPimAccessTemplatePrivate; /** * Thats the frontend to our OPIE PIM * Library. Either you want to use it's * interface or you want to implement * your own Access lib * Just create a OPimRecord and inherit from * the templates */ template <class T = OPimRecord > class OPimAccessTemplate : public OTemplateBase<T> { public: /** * */ enum Access { Random = 0, SortedAccess }; typedef OPimRecordList<T> List; typedef OPimAccessBackend<T> BackEnd; typedef OPimCache<T> Cache; //@{ OPimAccessTemplate( BackEnd* end); virtual ~OPimAccessTemplate(); //@} //@{ 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() ); + + /** + * Query by example search interface. + * "Query by Example" provides a very powerful search engine. Use the query object + * (this may be a contact, a todo or databook event) + * as a search mask which is converted into a query regarding the querySettings. If a time period is needed + * (as for OpimBase::DateDiff), you have to use the date/time in the query object and the endperiod (the last parameter). + * @see QuerySettings in class OPimBase + * @param query The object which contains the query set + * @param querySettings This parameter defines what should be searched and how the query should be interpreted + * @param endperiod Defines the end of a period for some special queries. + */ + virtual List queryByExample( const T& query, int querySettings, const QDateTime& endperiod = QDateTime() ); + + /** + * Generic query by example search interface. This is a special version which handles generic OPimRecord types. They are converted + * automatically into the right datatype. + * "Query by Example" provides a very powerful search engine. Use the query object (this may be a contact, a todo or databook event) + * as a search mask which is converted into a query regarding the querySettings. If a time period is needed + * (as for OpimBase::DateDiff), you have to use the date/time in the query object and the endperiod (the last parameter). + * @see QuerySettings in class OPimBase + * @param query The object which contains the query set + * @param querySettings This parameter defines what should be searched and how the query should be interpreted + * @param endperiod Defines the end of a period for some special queries. + */ + virtual List queryByExample( const OPimRecord* query, int querySettings, const QDateTime& endperiod = QDateTime() ); + /** + * Incremental query by example search interface. Providing incremental search, this one provides the feature + * to search in a list of records which may be returned by an other search. + * "Query by Example" provides a very powerful search engine. Use the query object (this may be a contact, a todo or databook event) + * as a search mask which is converted into a query regarding the querySettings. If a time period is needed + * (as for OpimBase::DateDiff), you have to use the date/time in the query object and the endperiod (the last parameter). + * @see QuerySettings in class OPimBase + * @param uidlist List of uid's which should be incorporated into the next search + * @param query The object which contains the query set + * @param querySettings This parameter defines what should be searched and how the query should be interpreted + * @param endperiod Defines the end of a period for some special queries. + */ + virtual List queryByExample( const OPimAccessTemplate::List& uidlist, const T& query, int querySettings, + const QDateTime& endperiod = 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; //@} /** * 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; /** * 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; /** * 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 ); 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; Cache m_cache; private: OPimAccessTemplatePrivate *d; }; /** * c'tor BackEnd * enum Access a small hint on how to handle the backend */ template <class T> OPimAccessTemplate<T>::OPimAccessTemplate( BackEnd* end ) : OTemplateBase<T>(), m_backEnd( end ) { if (end ) end->setFrontend( this ); } template <class T> OPimAccessTemplate<T>::~OPimAccessTemplate() { delete m_backEnd; } /** * load from the backend */ template <class T> bool OPimAccessTemplate<T>::load() { invalidateCache(); return m_backEnd->load(); } /** Reload database. * You should execute this function if the external database * was changed. * This function will load the external database and afterwards * rejoin the local changes. Therefore the local database will be set consistent. */ template <class T> bool OPimAccessTemplate<T>::reload() { invalidateCache(); return m_backEnd->reload(); } /** * Save contacts database. * Save is more a "commit". After calling this function, all changes are public available. * @return true if successful */ template <class T> bool OPimAccessTemplate<T>::save() { return m_backEnd->save(); } /** * return a List of records * you can iterate over them */ template <class T> typename OPimAccessTemplate<T>::List OPimAccessTemplate<T>::allRecords()const { QArray<int> ints = m_backEnd->allRecords(); List lis(ints, this ); return lis; } /** * return a List of records * that match the regex */ template <class T> typename OPimAccessTemplate<T>::List OPimAccessTemplate<T>::matchRegexp( const QRegExp &r )const { QArray<int> ints = m_backEnd->matchRegexp( r ); List lis(ints, this ); return lis; } /** * find the OPimRecord uid */ template <class T> QArray<int> OPimAccessTemplate<T>::records()const { return m_backEnd->allRecords(); } -/** - * queryByExample. - * @see otodoaccess, ocontactaccess - */ template <class T> typename OPimAccessTemplate<T>::List OPimAccessTemplate<T>::queryByExample( const T& t, int settings, const QDateTime& d ) { QArray<int> ints = m_backEnd->queryByExample( t, settings, d ); - List lis(ints, this ); - return lis; + List list(ints, this ); + return list; } template <class T> +typename OPimAccessTemplate<T>::List +OPimAccessTemplate<T>::queryByExample( const OPimRecord* t, int settings, const QDateTime& d ) { + T tempInstance; + + if ( t->rtti() == tempInstance.rtti() ) { + QArray<int> ints = m_backEnd->queryByExample( t, settings, d ); + List list( ints, this ); + return list; + } else { + owarn << "Query not possible: Objecttype mismatch" << oendl; + } + + return List(); +} + +template <class T> +typename OPimAccessTemplate<T>::List +OPimAccessTemplate<T>::queryByExample( const OPimAccessTemplate::List& uidlist, const T& t, int settings, const QDateTime& d ) { + QArray<int> ints = m_backEnd->queryByExample( uidlist.uids(), t, settings, d ); + + List list( ints, this ); + return list; +} + + +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; } /** * 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 ); T t = m_backEnd->find( uid, ar, current, dir ); cache( t ); return t; } /** * clears the backend and invalidates the backend */ template <class T> void OPimAccessTemplate<T>::clear() { invalidateCache(); m_backEnd->clear(); } /** * add T to the backend * @param t The item to add. * @return <i>true</i> if added successfully. */ template <class T> bool OPimAccessTemplate<T>::add( const T& t ) { cache( t ); return m_backEnd->add( t ); } template <class T> bool OPimAccessTemplate<T>::add( const OPimRecord& rec ) { /* same type */ T tempInstance; if ( rec.rtti() == tempInstance.rtti() ) { const T& t = static_cast<const T&>(rec); return add(t); } else { owarn << "Adding not possible: Objecttype mismatch" << oendl; } return false; } /** * Add an Opie PimRecord. * Info: Take this if you are working with OPimRecords and you need to add it into any database. * But take care that the accessing database is compatible to the real type of OPimRecord !! * Otherwise this access will be rejected ! */ template <class T> bool OPimAccessTemplate<T>::add( const OPimRecord* rec) { /* same type, but pointer */ T tempInstance; if ( rec -> rtti() == tempInstance.rtti() ) { const T* t = static_cast<const T*>(rec); return add( *t ); } else { owarn << "Adding not possible: Objecttype mismatch" << oendl; } return false; } /** * remove T from the backend * @param t The item to remove * @return <i>true</i> if successful. */ template <class T> bool OPimAccessTemplate<T>::remove( const T& t ) { return remove( t.uid() ); } /** diff --git a/libopie2/opiepim/core/opimtemplatebase.h b/libopie2/opiepim/core/opimtemplatebase.h index c8abab4..075e573 100644 --- a/libopie2/opiepim/core/opimtemplatebase.h +++ b/libopie2/opiepim/core/opimtemplatebase.h @@ -41,193 +41,193 @@ namespace Opie { class OPimBasePrivate; /** * This is the base class for all our Interfaces to the * PIM Records. It is pointer based and can be used * generically for all types of Records. * */ struct OPimBase { //@{ OPimBase(); virtual ~OPimBase(); //@} //@{ /** * return the rtti */ virtual int rtti() const = 0; virtual OPimRecord* record()const = 0; virtual OPimRecord* record(int uid)const = 0; //@} //@{ 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 { /** 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 { /** 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 a list of Items with the help of the sorted() function. * The Item you provide in SortOrder will be used * for sorting. * * @see OPimAccessTemplate<>::sorted() */ enum SortFilterBase { - /** Do not filter anything. */ + /** Do not filter anything. */ FilterOff = 0, /** Use given Categories for filter */ FilterCategory = 1, /** 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; //@} protected: OPimOccurrence::List convertOccurrenceFromBackend( const OPimBackendOccurrence::List& )const; private: OPimBasePrivate* d; }; /** * internal template base * Attention: T needs to implement the copy c'tor!!! */ class OTemplateBasePrivate; template <class T = OPimRecord> class OTemplateBase : public OPimBase { public: /** * The Direction for ReadAhead/ReadBehind which will * be used by the backends to Cache Items in * advance. * For example if you know that you will access the * next ten items you can give the backend a hint * to read ahead or read before. */ enum CacheDirection { Forward=0, /** Go forward when caching (++ to the index) */ Reverse /** Go backward when caching (-- to the index) */ }; //@{ OTemplateBase() {}; virtual ~OTemplateBase() {} //@} //@{ virtual T find( int uid )const = 0; /** * read ahead find */ virtual T find( int uid, const QArray<int>& items, uint current, CacheDirection dir = Forward )const = 0; //@} //@{ /** * Put element into Cache */ virtual void cache( const T& )const = 0; virtual void setSaneCacheSize( int ) = 0; OPimRecord* record()const; OPimRecord* record(int uid )const; static T* rec(); //@} private: OTemplateBasePrivate *d; }; template <class T> OPimRecord* OTemplateBase<T>::record()const { T* t = new T; return t; } template <class T> OPimRecord* OTemplateBase<T>::record(int uid )const { T t2 = find(uid ); T* t1 = new T(t2); return t1; |