author | zecke <zecke> | 2002-12-10 17:01:18 (UTC) |
---|---|---|
committer | zecke <zecke> | 2002-12-10 17:01:18 (UTC) |
commit | 4ecbf7407c19b59fc136c334f9386c53db453930 (patch) (side-by-side diff) | |
tree | 1cba438e2533f7109af169b0b77988cec6664192 | |
parent | 36375df6ff103e52455823f7afd64c4f4ae7fcb8 (diff) | |
download | opie-4ecbf7407c19b59fc136c334f9386c53db453930.zip opie-4ecbf7407c19b59fc136c334f9386c53db453930.tar.gz opie-4ecbf7407c19b59fc136c334f9386c53db453930.tar.bz2 |
get in sync with HEAD again
-OPimBase was added to be used as a default struct inside OPimResolver
and to work with DSOs
-TodoListXML backend now uses mmap and madvise to load data
-OContact added/changed rtti
-OTodo added changed rtti
OPimAccess* added stuff necessary for the Resolver and a 'state'/'hint'
on how to load data
OPimResolver which resolves uid + services to Records, rtti to QCOPChannels
loads arbitary Service backends ( will work with DSOs soon )
-OPimMainWindow added some setDocument scripting possibility and
internal marshalling and demarshalling of Records
-OPimRecord added loadDataFromm and saveDataTo for marshalling purposes
much more :)
30 files changed, 1072 insertions, 164 deletions
diff --git a/libopie/pim/ocontact.cpp b/libopie/pim/ocontact.cpp index 6aec62e..38cba72 100644 --- a/libopie/pim/ocontact.cpp +++ b/libopie/pim/ocontact.cpp @@ -19,12 +19,13 @@ ** **********************************************************************/ #define QTOPIA_INTERNAL_CONTACT_MRE #include "ocontact.h" +#include "opimresolver.h" #include <qpe/stringutil.h> #include <qpe/timeconversion.h> #include <qpe/timestring.h> #include <qobject.h> @@ -826,13 +827,13 @@ void OContact::save( QString &buf ) const /*! \internal Returns the list of fields belonging to a contact Never change order of this list ! It has to be regarding - enum AddressBookFields !! + enum AddressBookFields !! */ QStringList OContact::fields() { QStringList list; list.append( "Title" ); // Not Used! @@ -1097,13 +1098,13 @@ void OContact::setDefaultEmail( const QString &v ) void OContact::insertEmails( const QStringList &v ) { for ( QStringList::ConstIterator it = v.begin(); it != v.end(); ++it ) insertEmail( *it ); } int OContact::rtti() { - return 2; + return OPimResolver::AddressBook; } void OContact::setUid( int i ) -{ - OPimRecord::setUid(i); - replace( Qtopia::AddressUid , QString::number(i)); +{ + OPimRecord::setUid(i); + replace( Qtopia::AddressUid , QString::number(i)); } diff --git a/libopie/pim/opimaccessbackend.h b/libopie/pim/opimaccessbackend.h index 4f00bc9..e268f4f 100644 --- a/libopie/pim/opimaccessbackend.h +++ b/libopie/pim/opimaccessbackend.h @@ -16,13 +16,15 @@ * of */ template <class T = OPimRecord> class OPimAccessBackend { public: typedef OTemplateBase<T> Frontend; - OPimAccessBackend(); + + /** The access hint from the frontend */ + OPimAccessBackend(int access = 0); virtual ~OPimAccessBackend(); /** * load the resource */ virtual bool load() = 0; @@ -85,29 +87,35 @@ public: /** * set the read ahead count */ void setReadAhead( uint count ); protected: + int access()const; void cache( const T& t )const; /** * use a prime number here! */ void setSaneCacheSize( int ); uint readAhead()const; private: + class Private; + Private* d; Frontend* m_front; uint m_read; + int m_acc; }; template <class T> -OPimAccessBackend<T>::OPimAccessBackend() { +OPimAccessBackend<T>::OPimAccessBackend(int acc) + : m_acc( acc ) +{ m_front = 0l; } template <class T> OPimAccessBackend<T>::~OPimAccessBackend() { } @@ -135,7 +143,11 @@ void OPimAccessBackend<T>::setReadAhead( uint count ) { m_read = count; } template <class T> uint OPimAccessBackend<T>::readAhead()const { return m_read; } +template <class T> +int OPimAccessBackend<T>::access()const { + return m_acc; +} #endif diff --git a/libopie/pim/opimaccesstemplate.h b/libopie/pim/opimaccesstemplate.h index 8cf81c8..259e2c1 100644 --- a/libopie/pim/opimaccesstemplate.h +++ b/libopie/pim/opimaccesstemplate.h @@ -19,26 +19,32 @@ * the plugins */ template <class T = OPimRecord > class OPimAccessTemplate : public OTemplateBase<T> { public: + enum Access { + Random = 0, + SortedAccess + }; typedef ORecordList<T> List; typedef OPimAccessBackend<T> BackEnd; typedef OPimCache<T> Cache; /** * c'tor BackEnd + * enum Access a small hint on how to handle the backend */ OPimAccessTemplate( BackEnd* end); + virtual ~OPimAccessTemplate(); /** * load from the backend */ - virtual bool load(); + bool 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. @@ -46,13 +52,13 @@ public: virtual bool reload(); /** Save contacts database. * Save is more a "commit". After calling this function, all changes are public available. * @return true if successful */ - virtual bool save(); + bool save(); /** * if the resource was changed externally * You should use the signal handling instead of polling possible changes ! * zecke: Do you implement a signal for otodoaccess ? */ @@ -82,13 +88,13 @@ public: uint current, typename OTemplateBase<T>::CacheDirection dir = OTemplateBase<T>::Forward )const; /* invalidate cache here */ /** * clears the backend and invalidates the backend */ - virtual void clear() ; + void clear() ; /** * add T to the backend * @param t The item to add. * @return <i>true</i> if added successfully. */ @@ -105,13 +111,14 @@ public: /** * remove the OPimRecord with uid * @param uid The ID of the item to remove * @return <i>true</i> if successful. */ - virtual bool remove( int uid ); + bool remove( int uid ); + bool remove( const OPimRecord& ); /** * replace T from backend * @param t The item to replace * @return <i>true</i> if successful. */ @@ -120,12 +127,14 @@ public: void setReadAhead( uint count ); /** * @internal */ void cache( const T& )const; void setSaneCacheSize( int ); + + QArray<int> records()const; protected: /** * invalidate the cache */ void invalidateCache(); @@ -169,12 +178,16 @@ template <class T> typename OPimAccessTemplate<T>::List OPimAccessTemplate<T>::allRecords()const { QArray<int> ints = m_backEnd->allRecords(); List lis(ints, this ); return lis; } template <class T> +QArray<int> OPimAccessTemplate<T>::records()const { + return m_backEnd->allRecords(); +} +template <class T> typename OPimAccessTemplate<T>::List OPimAccessTemplate<T>::queryByExample( const T& t, int sortOrder ) { QArray<int> ints = m_backEnd->queryByExample( t, sortOrder ); List lis(ints, this ); return lis; @@ -228,12 +241,16 @@ bool OPimAccessTemplate<T>::remove( const T& t ) { template <class T> bool OPimAccessTemplate<T>::remove( int uid ) { m_cache.remove( uid ); return m_backEnd->remove( uid ); } template <class T> +bool OPimAccessTemplate<T>::remove( const OPimRecord& rec) { + return remove( rec.uid() ); +} +template <class T> bool OPimAccessTemplate<T>::replace( const T& t ) { m_cache.replace( t ); return m_backEnd->replace( t ); } template <class T> void OPimAccessTemplate<T>::invalidateCache() { diff --git a/libopie/pim/opimcache.h b/libopie/pim/opimcache.h index 839550c..73414e5 100644 --- a/libopie/pim/opimcache.h +++ b/libopie/pim/opimcache.h @@ -6,14 +6,17 @@ #include "opimrecord.h" template <class T = OPimRecord> class OPimCacheItem { public: OPimCacheItem( const T& t = T() ); + OPimCacheItem( const OPimCacheItem& ); ~OPimCacheItem(); + OPimCacheItem &operator=( const OPimCacheItem& ); + T record()const; void setRecord( const T& ); private: T m_t; }; @@ -24,14 +27,17 @@ private: */ template <class T = OPimRecord> class OPimCache { public: typedef OPimCacheItem<T> Item; OPimCache(); + OPimCache( const OPimCache& ); ~OPimCache(); + OPimCache &operator=( const OPimCache& ); + bool contains(int uid)const; void invalidate(); void setSize( int size ); T find(int uid )const; void add( const T& ); diff --git a/libopie/pim/opimmainwindow.cpp b/libopie/pim/opimmainwindow.cpp index 92be2fd..7e57f3a 100644 --- a/libopie/pim/opimmainwindow.cpp +++ b/libopie/pim/opimmainwindow.cpp @@ -1,16 +1,17 @@ #include <qapplication.h> #include <qcopchannel_qws.h> #include <qpe/qcopenvelope_qws.h> +#include "opimresolver.h" #include "opimmainwindow.h" OPimMainWindow::OPimMainWindow( const QString& service, QWidget* parent, const char* name, WFlags flag ) - : QMainWindow( parent, name, flag ), m_service( service ), m_fallBack(0l) { + : QMainWindow( parent, name, flag ), m_rtti(-1), m_service( service ), m_fallBack(0l) { /* * let's generate our QCopChannel */ m_str = QString("QPE/"+m_service).local8Bit(); m_channel= new QCopChannel(m_str, this ); @@ -26,12 +27,15 @@ OPimMainWindow::OPimMainWindow( const QString& service, QWidget* parent, OPimMainWindow::~OPimMainWindow() { delete m_channel; } QCopChannel* OPimMainWindow::channel() { return m_channel; } +void OPimMainWindow::doSetDocument( const QString& ) { + +} void OPimMainWindow::appMessage( const QCString& cmd, const QByteArray& array ) { /* * create demands to create * a new record... */ QDataStream stream(array, IO_ReadOnly); @@ -66,6 +70,36 @@ void OPimMainWindow::appMessage( const QCString& cmd, const QByteArray& array ) m_fallBack = record(rtti, array ); if (!m_fallBack) return; add( *m_fallBack ); delete m_fallBack; } } +/* implement the url scripting here */ +void OPimMainWindow::setDocument( const QString& str) { + doSetDocument( str ); +} +/* + * we now try to get the array demarshalled + * check if the rtti matches this one + */ +OPimRecord* OPimMainWindow::record( int rtti, const QByteArray& array ) { + if ( service() != rtti ) + return 0l; + + OPimRecord* record = OPimResolver::self()->record( rtti ); + QDataStream str(array, IO_ReadOnly ); + if ( !record || !record->loadFromStream(str) ) { + delete record; + record = 0l; + } + + return record; +} +/* + * get the rtti for the service + */ +int OPimMainWindow::service() { + if ( m_rtti == -1 ) + m_rtti = OPimResolver::self()->serviceId( m_service ); + + return m_rtti; +} diff --git a/libopie/pim/opimmainwindow.h b/libopie/pim/opimmainwindow.h index 94100bd..34b8a71 100644 --- a/libopie/pim/opimmainwindow.h +++ b/libopie/pim/opimmainwindow.h @@ -29,12 +29,17 @@ public: OPimMainWindow( const QString& service, QWidget *parent = 0, const char* name = 0, WFlags f = WType_TopLevel); virtual ~OPimMainWindow(); protected slots: + /* + * called when a setDocument + * couldn't be handled by this window + */ + virtual void doSetDocument( const QString& ); /* for syncing */ virtual void flush() = 0; virtual void reload() = 0; /** create a new Records and return the uid */ virtual int create() = 0; @@ -48,32 +53,37 @@ protected slots: /** edit the record */ virtual void edit( int uid ) = 0; /** make a copy of it! */ virtual void add( const OPimRecord& ) = 0; - /* I would love to do this as a template - * but can't think of a right way - * because I need signal and slots -zecke - */ - /* - * the only pointer in the whole PIM API :( - */ - virtual OPimRecord* record( int rtti, const QByteArray& ) = 0; + QCopChannel* channel(); private slots: void appMessage( const QCString&, const QByteArray& ); + void setDocument( const QString& ); private: class Private; Private* d; + int m_rtti; QCopChannel* m_channel; QString m_service; QCString m_str; OPimRecord* m_fallBack; + + /* I would love to do this as a template + * but can't think of a right way + * because I need signal and slots -zecke + */ + /* + * the only pointer in the whole PIM API :( + */ + virtual OPimRecord* record( int rtti, const QByteArray& ) ; + int service(); }; #endif diff --git a/libopie/pim/opimrecord.cpp b/libopie/pim/opimrecord.cpp index 49b5bf9..ac0f4a9 100644 --- a/libopie/pim/opimrecord.cpp +++ b/libopie/pim/opimrecord.cpp @@ -1,6 +1,8 @@ +#include <qarray.h> + #include <qpe/categories.h> #include <qpe/categoryselect.h> #include "opimrecord.h" Qtopia::UidGen OPimRecord::m_uidGen( Qtopia::UidGen::Qtopia ); @@ -79,6 +81,86 @@ Qtopia::UidGen &OPimRecord::uidGen() { OPimXRefManager &OPimRecord::xrefmanager() { return m_xrefman; } int OPimRecord::rtti(){ return 0; } + +/** + * now let's put our data into the stream + */ +/* + * First read UID + * Categories + * XRef + */ +bool OPimRecord::loadFromStream( QDataStream& stream ) { + int Int; + uint UInt; + stream >> Int; + setUid(Int); + + /** Categories */ + stream >> UInt; + QArray<int> array(UInt); + for (uint i = 0; i < UInt; i++ ) { + stream >> array[i]; + } + setCategories( array ); + + /* + * now we do the X-Ref stuff + */ + OPimXRef xref; + stream >> UInt; + for ( uint i = 0; i < UInt; i++ ) { + xref.setPartner( OPimXRef::One, partner( stream ) ); + xref.setPartner( OPimXRef::Two, partner( stream ) ); + m_xrefman.add( xref ); + } + + return true; +} +bool OPimRecord::saveToStream( QDataStream& stream )const { + /** UIDs */ + + stream << uid(); + + /** Categories */ + stream << categories().count(); + for ( uint i = 0; i < categories().count(); i++ ) { + stream << categories()[i]; + } + + /* + * first the XRef count + * then the xrefs + */ + stream << m_xrefman.list().count(); + for ( OPimXRef::ValueList::ConstIterator it = m_xrefman.list().begin(); + it != m_xrefman.list().end(); ++it ) { + flush( (*it).partner( OPimXRef::One), stream ); + flush( (*it).partner( OPimXRef::Two), stream ); + } + return true; +} +void OPimRecord::flush( const OPimXRefPartner& par, QDataStream& str ) const{ + str << par.service(); + str << par.uid(); + str << par.field(); +} +OPimXRefPartner OPimRecord::partner( QDataStream& stream ) { + OPimXRefPartner par; + QString str; + int i; + + stream >> str; + par.setService( str ); + + stream >> i; + par.setUid( i ); + + stream >> i ; + par.setField( i ); + + return par; +} diff --git a/libopie/pim/opimrecord.h b/libopie/pim/opimrecord.h index ec99a13..665530f 100644 --- a/libopie/pim/opimrecord.h +++ b/libopie/pim/opimrecord.h @@ -1,9 +1,10 @@ #ifndef OPIE_PIM_RECORD_H #define OPIE_PIM_RECORD_H +#include <qdatastream.h> #include <qmap.h> #include <qstring.h> #include <qstringlist.h> #include <qpe/palmtoprecord.h> @@ -102,21 +103,32 @@ public: /* * used inside the Templates for casting * REIMPLEMENT in your .... */ static int rtti(); + /** + * some marshalling and de marshalling code + * saves the OPimRecord + * to and from a DataStream + */ + virtual bool loadFromStream(QDataStream& ); + virtual bool saveToStream( QDataStream& stream )const; + protected: Qtopia::UidGen &uidGen(); // QString crossToString()const; private: class OPimRecordPrivate; OPimRecordPrivate *d; OPimXRefManager m_xrefman; static Qtopia::UidGen m_uidGen; +private: + void flush( const OPimXRefPartner&, QDataStream& stream )const; + OPimXRefPartner partner( QDataStream& ); }; #endif diff --git a/libopie/pim/opimresolver.cpp b/libopie/pim/opimresolver.cpp new file mode 100644 index 0000000..4ebbd6e --- a/dev/null +++ b/libopie/pim/opimresolver.cpp @@ -0,0 +1,198 @@ +#include <qcopchannel_qws.h> + +#include <qpe/qcopenvelope_qws.h> + +#include "otodoaccess.h" +#include "ocontactaccess.h" + +//#include "opimfactory.h" +#include "opimresolver.h" + +OPimResolver* OPimResolver::m_self = 0l; + +OPimResolver::OPimResolver() { + /* the built in channels */ + m_builtIns << "Todolist" << "Addressbook" << "Datebook"; +} +OPimResolver* OPimResolver::self() { + if (!m_self) + m_self = new OPimResolver(); + + return m_self; +} + +/* + * FIXME use a cache here too + */ +OPimRecord* OPimResolver::record( const QString& service, int uid ) { + OPimRecord* rec = 0l; + OPimBase* base = backend( service ); + + if ( base ) + rec = base->record( uid ); + delete base; + + return rec; +} +OPimRecord* OPimResolver::record( const QString& service ) { + return record( serviceId( service ) ); +} +OPimRecord* OPimResolver::record( int rtti ) { + OPimRecord* rec = 0l; + switch( rtti ) { + case 1: /* todolist */ + rec = new OTodo(); + case 2: /* contact */ + rec = new OContact(); + default: + break; + } + /* + * FIXME resolve externally + */ + if (!rec ) { + ; + } + return 0l; +} +bool OPimResolver::isBuiltIn( const QString& str) const{ + return m_builtIns.contains( str ); +} +QCString OPimResolver::qcopChannel( enum BuiltIn& built)const { + QCString str("QPE/"); + switch( built ) { + case TodoList: + str += "Todolist"; + break; + case DateBook: + str += "Datebook"; + break; + case AddressBook: + str += "Addressbook"; + break; + default: + break; + } + + return str; +} +QCString OPimResolver::qcopChannel( const QString& service )const { + QCString str("QPE/"); + str += service.latin1(); + return str; +} +/* + * Implement services!! + * FIXME + */ +QCString OPimResolver::applicationChannel( enum BuiltIn& built)const { + QCString str("QPE/Application/"); + switch( built ) { + case TodoList: + str += "todolist"; + break; + case DateBook: + str += "datebook"; + break; + case AddressBook: + str += "addressbook"; + break; + } + + return str; +} +QCString OPimResolver::applicationChannel( const QString& service )const { + QCString str("QPE/Application/"); + + if ( isBuiltIn( service ) ) { + if ( service == "Todolist" ) + str += "todolist"; + else if ( service == "Datebook" ) + str += "datebook"; + else if ( service == "Addressbook" ) + str += "addressbook"; + }else + ; // FIXME for additional stuff + + return str; +} +QStringList OPimResolver::services()const { + return m_builtIns; +} +QString OPimResolver::serviceName( int rtti ) const{ + QString str; + switch ( rtti ) { + case TodoList: + str = "Todolist"; + break; + case DateBook: + str = "Datebook"; + break; + case AddressBook: + str = "Addressbook"; + break; + default: + break; + } + return str; + // FIXME me for 3rd party +} +int OPimResolver::serviceId( const QString& service ) { + int rtti = 0; + if ( service == "Todolist" ) + rtti = TodoList; + else if ( service == "Datebook" ) + rtti = DateBook; + else if ( service == "Addressbook" ) + rtti = AddressBook; + + return rtti; +} +/** + * check if the 'service' is registered and if so we'll + */ +bool OPimResolver::add( const QString& service, const OPimRecord& rec) { + if ( QCopChannel::isRegistered( applicationChannel( service ) ) ) { + QByteArray data; + QDataStream arg(data, IO_WriteOnly ); + if ( rec.saveToStream( arg ) ) { + QCopEnvelope env( applicationChannel( service ), "add(int,QByteArray)" ); + env << rec.rtti(); + env << data; + }else + return false; + }else{ + OPimBase* base = backend( service ); + if (!base ) return false; + + base->load(); + base->add( rec ); + base->save(); + delete base; + } + + return true; +} +OPimBase* OPimResolver::backend( const QString& service ) { + return backend( serviceId( service ) ); +} +OPimBase* OPimResolver::backend( int rtti ) { + OPimBase* base = 0l; + switch( rtti ) { + case TodoList: + base = new OTodoAccess(); + break; + case DateBook: + break; + case AddressBook: + base = new OContactAccess("Resolver"); + break; + default: + break; + } + // FIXME for 3rd party + if (!base ) + ; + + return base; +} diff --git a/libopie/pim/opimresolver.h b/libopie/pim/opimresolver.h index 86ae3eb..1ce1619 100644 --- a/libopie/pim/opimresolver.h +++ b/libopie/pim/opimresolver.h @@ -1,56 +1,90 @@ #ifndef OPIE_PIM_RESOLVER #define OPIE_PIM_RESOLVER #include <qstring.h> #include <qvaluelist.h> +#include <opie/otemplatebase.h> + /** * OPimResolver is a MetaClass to access * available backends read only. * It will be used to resolve uids + app names * to full informations * to traverse through a list of alarms, reminders * to get access to built in PIM functionality * and to more stuff * THE PERFORMANCE will depend on THE BACKEND * USING XML is a waste of memory!!!!! */ -class OPimResolver : public QObject { +class OPimResolver { public: enum BuiltIn { TodoList = 0, DateBook, AddressBook }; static OPimResolver* self(); - /* + /** * return a record for a uid - * and an app + * and an service + * You've THE OWNERSHIP NOW! */ - OPimRecord &record( const QString& service, int uid ); + OPimRecord *record( const QString& service, int uid ); /** * return the QCopChannel for service * When we will use Qtopia Services it will be used here */ - QString qcopChannel( enum BuiltIn& )const; - QString qcopChannel( const QString& service ); + QCString qcopChannel( enum BuiltIn& )const; + QCString qcopChannel( const QString& service )const; + + /** + * The Application channel (QPE/Application/name) + */ + QCString applicationChannel( enum BuiltIn& )const; + QCString applicationChannel( const QString& service )const; /** * return a list of available services */ QStringList services()const; - + inline QString serviceName(int rrti )const; + int serviceId( const QString& Service); /** * add a record to a service... ;) */ bool add( const QString& service, const OPimRecord& ); + + /** + * record returns an empty record for a given service. + * Be sure to delete it!!! + * + */ + OPimRecord* record( const QString& service ); + OPimRecord* record( int rtti ); + + /** + * you can cast to your + */ + OPimBase* backend( const QString& service ); + OPimBase* backend( int rtti ); private: OPimResolver(); - OPimRecord *m_last; + void loadData(); + inline bool isBuiltIn( const QString& )const; + OPimRecord* recordExtern( const QString&, int ); + OPimRecord* recordExtern( const QString& ); + + static OPimResolver* m_self; + struct Data; + class Private; -}: + Data* data; + Private* d; + QStringList m_builtIns; +}; #endif diff --git a/libopie/pim/otemplatebase.h b/libopie/pim/otemplatebase.h index b855919..29fb6ec 100644 --- a/libopie/pim/otemplatebase.h +++ b/libopie/pim/otemplatebase.h @@ -1,18 +1,48 @@ #ifndef OPIE_TEMPLATE_BASE_H #define OPIE_TEMPLATE_BASE_H #include <qarray.h> -#include "opimrecord.h" +#include <opie/opimrecord.h> + /** + * Templates do not have a base class, This is why + * we've this class + * this is here to give us the possibility + * to have a common base class + * You may not want to use that interface internaly + * POOR mans interface + */ +struct OPimBase { + /** + * return the rtti + */ + virtual int rtti()= 0; + virtual OPimRecord* record()const = 0; + virtual OPimRecord* record(int uid)const = 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<int> records()const = 0; + /* + * ADD editing here? + * -zecke + */ + +}; +/** * internal template base + * T needs to implement the copy c'tor!!! */ template <class T = OPimRecord> -class OTemplateBase { +class OTemplateBase : public OPimBase { public: enum CacheDirection { Forward=0, Reverse }; OTemplateBase() { }; virtual ~OTemplateBase() { } @@ -23,10 +53,39 @@ public: */ virtual T find( int uid, const QArray<int>& items, uint current, CacheDirection dir = Forward )const = 0; virtual void cache( const T& )const = 0; virtual void setSaneCacheSize( int ) = 0; + /* reimplement of OPimBase */ + int rtti(); + OPimRecord* record()const; + OPimRecord* record(int uid )const; + static T* rec(); }; +/* + * implementation + */ +template <class T> +int +OTemplateBase<T>::rtti() { + return T::rtti(); +} +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; +}; +template <class T> +T* OTemplateBase<T>::rec() { + return new T; +} #endif diff --git a/libopie/pim/otodo.cpp b/libopie/pim/otodo.cpp index ece624a..cde2b3d 100644 --- a/libopie/pim/otodo.cpp +++ b/libopie/pim/otodo.cpp @@ -13,12 +13,13 @@ #include "opimstate.h" #include "orecur.h" #include "opimmaintainer.h" #include "opimnotifymanager.h" +#include "opimresolver.h" #include "otodo.h" struct OTodo::OTodoData : public QShared { OTodoData() : QShared() { @@ -414,8 +415,8 @@ QString OTodo::type() const { } QString OTodo::recordField(int /*id*/ )const { return QString::null; } int OTodo::rtti(){ - return 1; + return OPimResolver::TodoList; } diff --git a/libopie/pim/otodoaccess.cpp b/libopie/pim/otodoaccess.cpp index d860411..5e89a1b 100644 --- a/libopie/pim/otodoaccess.cpp +++ b/libopie/pim/otodoaccess.cpp @@ -3,13 +3,13 @@ #include <qpe/alarmserver.h> // #include "otodoaccesssql.h" #include "otodoaccess.h" #include "obackendfactory.h" -OTodoAccess::OTodoAccess( OTodoAccessBackend* end ) +OTodoAccess::OTodoAccess( OTodoAccessBackend* end, enum Access ) : QObject(), OPimAccessTemplate<OTodo>( end ), m_todoBackEnd( end ) { // if (end == 0l ) // m_todoBackEnd = new OTodoAccessBackendSQL( QString::null); // Zecke: Du musst hier noch für das XML-Backend einen Appnamen übergeben ! @@ -41,42 +41,12 @@ OTodoAccess::List OTodoAccess::effectiveToDos( const QDate& start, includeNoDates ); } OTodoAccess::List OTodoAccess::overDue() { List lis( m_todoBackEnd->overDue(), this ); return lis; } -void OTodoAccess::addAlarm( const OTodo& event) { -/* FIXME use the new notifier architecture - if (!event.hasAlarmDateTime() ) - return; - - QDateTime now = QDateTime::currentDateTime(); - QDateTime schedule = event.alarmDateTime(); - - if ( schedule > now ){ - AlarmServer::addAlarm( schedule, - "QPE/Application/todolist", - "alarm(QDateTime,int)", event.uid() ); - - } -*/ -} -void OTodoAccess::delAlarm( int uid) { - - QDateTime schedule; // Create null DateTime - - // I hope this will remove all scheduled alarms - // with the given uid !? - // If not: I have to rethink how to remove already - // scheduled events... (se) - // it should be fine -zecke -// qWarning("Removing alarm for event with uid %d", uid ); - AlarmServer::deleteAlarm( schedule , - "QPE/Application/todolist", - "alarm(QDateTime,int)", uid ); -} /* sort order */ OTodoAccess::List OTodoAccess::sorted( bool ascending, int sort,int filter, int cat ) { QArray<int> ints = m_todoBackEnd->sorted( ascending, sort, filter, cat ); OTodoAccess::List list( ints, this ); return list; diff --git a/libopie/pim/otodoaccess.h b/libopie/pim/otodoaccess.h index c079155..2bb87dc 100644 --- a/libopie/pim/otodoaccess.h +++ b/libopie/pim/otodoaccess.h @@ -26,13 +26,13 @@ public: DoNotShowCompleted =4 }; /** * if you use 0l * the default resource will be * picked up */ - OTodoAccess( OTodoAccessBackend* = 0l); + OTodoAccess( OTodoAccessBackend* = 0l, enum Access acc = Random ); ~OTodoAccess(); /* our functions here */ /** * include todos from start to end @@ -75,23 +75,12 @@ public: signals: /** * if the OTodoAccess was changed */ void signalChanged( const OTodoAccess* ); private: - /** - * add an Alarm to the AlarmServer - */ - void addAlarm( const OTodo& ); - - /** - * delete an alarm with the uid from - * the alarm server - */ - void delAlarm( int uid ); - int m_cat; OTodoAccessBackend* m_todoBackEnd; class OTodoAccessPrivate; OTodoAccessPrivate* d; }; diff --git a/libopie/pim/otodoaccessxml.cpp b/libopie/pim/otodoaccessxml.cpp index b2dfe80..21f93a0 100644 --- a/libopie/pim/otodoaccessxml.cpp +++ b/libopie/pim/otodoaccessxml.cpp @@ -1,6 +1,16 @@ +#include <errno.h> +#include <fcntl.h> + +#include <sys/mman.h> +#include <sys/stat.h> +#include <sys/types.h> + +#include <unistd.h> + + #include <qfile.h> #include <qvector.h> #include <qpe/global.h> #include <qpe/stringutil.h> #include <qpe/timeconversion.h> @@ -49,26 +59,42 @@ bool OTodoAccessXML::load() { dict.insert("Reminders", new int(OTodo::Reminders) ); dict.insert("Notifiers", new int(OTodo::Notifiers) ); dict.insert("Maintainer", new int(OTodo::Maintainer) ); // here the custom XML parser from TT it's GPL // but we want to push OpiePIM... to TT..... - QFile f(m_file ); - if (!f.open(IO_ReadOnly) ) + // mmap part from zecke :) + int fd = ::open( QFile::encodeName(m_file).data(), O_RDONLY ); + struct stat attribut; + if ( fd < 0 ) return false; + + if ( fstat(fd, &attribut ) == -1 ) { + ::close( fd ); return false; + } + void* map_addr = ::mmap(NULL, attribut.st_size, PROT_READ, MAP_SHARED, fd, 0 ); + if ( map_addr == ( (caddr_t)-1) ) { + ::close(fd ); + return false; + } + /* advise the kernel who we want to read it */ + ::madvise( map_addr, attribut.st_size, MADV_SEQUENTIAL ); + /* we do not the file any more */ + ::close( fd ); - QByteArray ba = f.readAll(); - f.close(); - char* dt = ba.data(); - int len = ba.size(); + char* dt = (char*)map_addr; + int len = attribut.st_size; int i = 0; char *point; const char* collectionString = "<Task "; + int strLen = strlen(collectionString); while ( dt+i != 0 && ( point = strstr( dt+i, collectionString ) ) != 0l ) { i = point -dt; - i+= strlen(collectionString); + i+= strLen; + qWarning("Found a start at %d %d", i, (point-dt) ); + OTodo ev; m_year = m_month = m_day = 0; while ( TRUE ) { while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) ++i; @@ -117,23 +143,26 @@ bool OTodoAccessXML::load() { todo( &dict, ev, attr, str ); } /* * now add it */ + qWarning("End at %d", i ); if (m_events.contains( ev.uid() ) || ev.uid() == 0) { ev.setUid( 1 ); m_changed = true; } if ( ev.hasDueDate() ) { ev.setDueDate( QDate(m_year, m_month, m_day) ); } m_events.insert(ev.uid(), ev ); m_year = m_month = m_day = -1; } + munmap(map_addr, attribut.st_size ); + qWarning("counts %d records loaded!", m_events.count() ); return true; } bool OTodoAccessXML::reload() { return load(); } diff --git a/libopie2/opiepim/backend/opimaccessbackend.h b/libopie2/opiepim/backend/opimaccessbackend.h index 4f00bc9..e268f4f 100644 --- a/libopie2/opiepim/backend/opimaccessbackend.h +++ b/libopie2/opiepim/backend/opimaccessbackend.h @@ -16,13 +16,15 @@ * of */ template <class T = OPimRecord> class OPimAccessBackend { public: typedef OTemplateBase<T> Frontend; - OPimAccessBackend(); + + /** The access hint from the frontend */ + OPimAccessBackend(int access = 0); virtual ~OPimAccessBackend(); /** * load the resource */ virtual bool load() = 0; @@ -85,29 +87,35 @@ public: /** * set the read ahead count */ void setReadAhead( uint count ); protected: + int access()const; void cache( const T& t )const; /** * use a prime number here! */ void setSaneCacheSize( int ); uint readAhead()const; private: + class Private; + Private* d; Frontend* m_front; uint m_read; + int m_acc; }; template <class T> -OPimAccessBackend<T>::OPimAccessBackend() { +OPimAccessBackend<T>::OPimAccessBackend(int acc) + : m_acc( acc ) +{ m_front = 0l; } template <class T> OPimAccessBackend<T>::~OPimAccessBackend() { } @@ -135,7 +143,11 @@ void OPimAccessBackend<T>::setReadAhead( uint count ) { m_read = count; } template <class T> uint OPimAccessBackend<T>::readAhead()const { return m_read; } +template <class T> +int OPimAccessBackend<T>::access()const { + return m_acc; +} #endif diff --git a/libopie2/opiepim/backend/otodoaccessxml.cpp b/libopie2/opiepim/backend/otodoaccessxml.cpp index b2dfe80..21f93a0 100644 --- a/libopie2/opiepim/backend/otodoaccessxml.cpp +++ b/libopie2/opiepim/backend/otodoaccessxml.cpp @@ -1,6 +1,16 @@ +#include <errno.h> +#include <fcntl.h> + +#include <sys/mman.h> +#include <sys/stat.h> +#include <sys/types.h> + +#include <unistd.h> + + #include <qfile.h> #include <qvector.h> #include <qpe/global.h> #include <qpe/stringutil.h> #include <qpe/timeconversion.h> @@ -49,26 +59,42 @@ bool OTodoAccessXML::load() { dict.insert("Reminders", new int(OTodo::Reminders) ); dict.insert("Notifiers", new int(OTodo::Notifiers) ); dict.insert("Maintainer", new int(OTodo::Maintainer) ); // here the custom XML parser from TT it's GPL // but we want to push OpiePIM... to TT..... - QFile f(m_file ); - if (!f.open(IO_ReadOnly) ) + // mmap part from zecke :) + int fd = ::open( QFile::encodeName(m_file).data(), O_RDONLY ); + struct stat attribut; + if ( fd < 0 ) return false; + + if ( fstat(fd, &attribut ) == -1 ) { + ::close( fd ); return false; + } + void* map_addr = ::mmap(NULL, attribut.st_size, PROT_READ, MAP_SHARED, fd, 0 ); + if ( map_addr == ( (caddr_t)-1) ) { + ::close(fd ); + return false; + } + /* advise the kernel who we want to read it */ + ::madvise( map_addr, attribut.st_size, MADV_SEQUENTIAL ); + /* we do not the file any more */ + ::close( fd ); - QByteArray ba = f.readAll(); - f.close(); - char* dt = ba.data(); - int len = ba.size(); + char* dt = (char*)map_addr; + int len = attribut.st_size; int i = 0; char *point; const char* collectionString = "<Task "; + int strLen = strlen(collectionString); while ( dt+i != 0 && ( point = strstr( dt+i, collectionString ) ) != 0l ) { i = point -dt; - i+= strlen(collectionString); + i+= strLen; + qWarning("Found a start at %d %d", i, (point-dt) ); + OTodo ev; m_year = m_month = m_day = 0; while ( TRUE ) { while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) ++i; @@ -117,23 +143,26 @@ bool OTodoAccessXML::load() { todo( &dict, ev, attr, str ); } /* * now add it */ + qWarning("End at %d", i ); if (m_events.contains( ev.uid() ) || ev.uid() == 0) { ev.setUid( 1 ); m_changed = true; } if ( ev.hasDueDate() ) { ev.setDueDate( QDate(m_year, m_month, m_day) ); } m_events.insert(ev.uid(), ev ); m_year = m_month = m_day = -1; } + munmap(map_addr, attribut.st_size ); + qWarning("counts %d records loaded!", m_events.count() ); return true; } bool OTodoAccessXML::reload() { return load(); } diff --git a/libopie2/opiepim/core/opimaccesstemplate.h b/libopie2/opiepim/core/opimaccesstemplate.h index 8cf81c8..259e2c1 100644 --- a/libopie2/opiepim/core/opimaccesstemplate.h +++ b/libopie2/opiepim/core/opimaccesstemplate.h @@ -19,26 +19,32 @@ * the plugins */ template <class T = OPimRecord > class OPimAccessTemplate : public OTemplateBase<T> { public: + enum Access { + Random = 0, + SortedAccess + }; typedef ORecordList<T> List; typedef OPimAccessBackend<T> BackEnd; typedef OPimCache<T> Cache; /** * c'tor BackEnd + * enum Access a small hint on how to handle the backend */ OPimAccessTemplate( BackEnd* end); + virtual ~OPimAccessTemplate(); /** * load from the backend */ - virtual bool load(); + bool 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. @@ -46,13 +52,13 @@ public: virtual bool reload(); /** Save contacts database. * Save is more a "commit". After calling this function, all changes are public available. * @return true if successful */ - virtual bool save(); + bool save(); /** * if the resource was changed externally * You should use the signal handling instead of polling possible changes ! * zecke: Do you implement a signal for otodoaccess ? */ @@ -82,13 +88,13 @@ public: uint current, typename OTemplateBase<T>::CacheDirection dir = OTemplateBase<T>::Forward )const; /* invalidate cache here */ /** * clears the backend and invalidates the backend */ - virtual void clear() ; + void clear() ; /** * add T to the backend * @param t The item to add. * @return <i>true</i> if added successfully. */ @@ -105,13 +111,14 @@ public: /** * remove the OPimRecord with uid * @param uid The ID of the item to remove * @return <i>true</i> if successful. */ - virtual bool remove( int uid ); + bool remove( int uid ); + bool remove( const OPimRecord& ); /** * replace T from backend * @param t The item to replace * @return <i>true</i> if successful. */ @@ -120,12 +127,14 @@ public: void setReadAhead( uint count ); /** * @internal */ void cache( const T& )const; void setSaneCacheSize( int ); + + QArray<int> records()const; protected: /** * invalidate the cache */ void invalidateCache(); @@ -169,12 +178,16 @@ template <class T> typename OPimAccessTemplate<T>::List OPimAccessTemplate<T>::allRecords()const { QArray<int> ints = m_backEnd->allRecords(); List lis(ints, this ); return lis; } template <class T> +QArray<int> OPimAccessTemplate<T>::records()const { + return m_backEnd->allRecords(); +} +template <class T> typename OPimAccessTemplate<T>::List OPimAccessTemplate<T>::queryByExample( const T& t, int sortOrder ) { QArray<int> ints = m_backEnd->queryByExample( t, sortOrder ); List lis(ints, this ); return lis; @@ -228,12 +241,16 @@ bool OPimAccessTemplate<T>::remove( const T& t ) { template <class T> bool OPimAccessTemplate<T>::remove( int uid ) { m_cache.remove( uid ); return m_backEnd->remove( uid ); } template <class T> +bool OPimAccessTemplate<T>::remove( const OPimRecord& rec) { + return remove( rec.uid() ); +} +template <class T> bool OPimAccessTemplate<T>::replace( const T& t ) { m_cache.replace( t ); return m_backEnd->replace( t ); } template <class T> void OPimAccessTemplate<T>::invalidateCache() { diff --git a/libopie2/opiepim/core/opimcache.h b/libopie2/opiepim/core/opimcache.h index 839550c..73414e5 100644 --- a/libopie2/opiepim/core/opimcache.h +++ b/libopie2/opiepim/core/opimcache.h @@ -6,14 +6,17 @@ #include "opimrecord.h" template <class T = OPimRecord> class OPimCacheItem { public: OPimCacheItem( const T& t = T() ); + OPimCacheItem( const OPimCacheItem& ); ~OPimCacheItem(); + OPimCacheItem &operator=( const OPimCacheItem& ); + T record()const; void setRecord( const T& ); private: T m_t; }; @@ -24,14 +27,17 @@ private: */ template <class T = OPimRecord> class OPimCache { public: typedef OPimCacheItem<T> Item; OPimCache(); + OPimCache( const OPimCache& ); ~OPimCache(); + OPimCache &operator=( const OPimCache& ); + bool contains(int uid)const; void invalidate(); void setSize( int size ); T find(int uid )const; void add( const T& ); diff --git a/libopie2/opiepim/core/opimrecord.cpp b/libopie2/opiepim/core/opimrecord.cpp index 49b5bf9..ac0f4a9 100644 --- a/libopie2/opiepim/core/opimrecord.cpp +++ b/libopie2/opiepim/core/opimrecord.cpp @@ -1,6 +1,8 @@ +#include <qarray.h> + #include <qpe/categories.h> #include <qpe/categoryselect.h> #include "opimrecord.h" Qtopia::UidGen OPimRecord::m_uidGen( Qtopia::UidGen::Qtopia ); @@ -79,6 +81,86 @@ Qtopia::UidGen &OPimRecord::uidGen() { OPimXRefManager &OPimRecord::xrefmanager() { return m_xrefman; } int OPimRecord::rtti(){ return 0; } + +/** + * now let's put our data into the stream + */ +/* + * First read UID + * Categories + * XRef + */ +bool OPimRecord::loadFromStream( QDataStream& stream ) { + int Int; + uint UInt; + stream >> Int; + setUid(Int); + + /** Categories */ + stream >> UInt; + QArray<int> array(UInt); + for (uint i = 0; i < UInt; i++ ) { + stream >> array[i]; + } + setCategories( array ); + + /* + * now we do the X-Ref stuff + */ + OPimXRef xref; + stream >> UInt; + for ( uint i = 0; i < UInt; i++ ) { + xref.setPartner( OPimXRef::One, partner( stream ) ); + xref.setPartner( OPimXRef::Two, partner( stream ) ); + m_xrefman.add( xref ); + } + + return true; +} +bool OPimRecord::saveToStream( QDataStream& stream )const { + /** UIDs */ + + stream << uid(); + + /** Categories */ + stream << categories().count(); + for ( uint i = 0; i < categories().count(); i++ ) { + stream << categories()[i]; + } + + /* + * first the XRef count + * then the xrefs + */ + stream << m_xrefman.list().count(); + for ( OPimXRef::ValueList::ConstIterator it = m_xrefman.list().begin(); + it != m_xrefman.list().end(); ++it ) { + flush( (*it).partner( OPimXRef::One), stream ); + flush( (*it).partner( OPimXRef::Two), stream ); + } + return true; +} +void OPimRecord::flush( const OPimXRefPartner& par, QDataStream& str ) const{ + str << par.service(); + str << par.uid(); + str << par.field(); +} +OPimXRefPartner OPimRecord::partner( QDataStream& stream ) { + OPimXRefPartner par; + QString str; + int i; + + stream >> str; + par.setService( str ); + + stream >> i; + par.setUid( i ); + + stream >> i ; + par.setField( i ); + + return par; +} diff --git a/libopie2/opiepim/core/opimrecord.h b/libopie2/opiepim/core/opimrecord.h index ec99a13..665530f 100644 --- a/libopie2/opiepim/core/opimrecord.h +++ b/libopie2/opiepim/core/opimrecord.h @@ -1,9 +1,10 @@ #ifndef OPIE_PIM_RECORD_H #define OPIE_PIM_RECORD_H +#include <qdatastream.h> #include <qmap.h> #include <qstring.h> #include <qstringlist.h> #include <qpe/palmtoprecord.h> @@ -102,21 +103,32 @@ public: /* * used inside the Templates for casting * REIMPLEMENT in your .... */ static int rtti(); + /** + * some marshalling and de marshalling code + * saves the OPimRecord + * to and from a DataStream + */ + virtual bool loadFromStream(QDataStream& ); + virtual bool saveToStream( QDataStream& stream )const; + protected: Qtopia::UidGen &uidGen(); // QString crossToString()const; private: class OPimRecordPrivate; OPimRecordPrivate *d; OPimXRefManager m_xrefman; static Qtopia::UidGen m_uidGen; +private: + void flush( const OPimXRefPartner&, QDataStream& stream )const; + OPimXRefPartner partner( QDataStream& ); }; #endif diff --git a/libopie2/opiepim/core/opimresolver.cpp b/libopie2/opiepim/core/opimresolver.cpp new file mode 100644 index 0000000..4ebbd6e --- a/dev/null +++ b/libopie2/opiepim/core/opimresolver.cpp @@ -0,0 +1,198 @@ +#include <qcopchannel_qws.h> + +#include <qpe/qcopenvelope_qws.h> + +#include "otodoaccess.h" +#include "ocontactaccess.h" + +//#include "opimfactory.h" +#include "opimresolver.h" + +OPimResolver* OPimResolver::m_self = 0l; + +OPimResolver::OPimResolver() { + /* the built in channels */ + m_builtIns << "Todolist" << "Addressbook" << "Datebook"; +} +OPimResolver* OPimResolver::self() { + if (!m_self) + m_self = new OPimResolver(); + + return m_self; +} + +/* + * FIXME use a cache here too + */ +OPimRecord* OPimResolver::record( const QString& service, int uid ) { + OPimRecord* rec = 0l; + OPimBase* base = backend( service ); + + if ( base ) + rec = base->record( uid ); + delete base; + + return rec; +} +OPimRecord* OPimResolver::record( const QString& service ) { + return record( serviceId( service ) ); +} +OPimRecord* OPimResolver::record( int rtti ) { + OPimRecord* rec = 0l; + switch( rtti ) { + case 1: /* todolist */ + rec = new OTodo(); + case 2: /* contact */ + rec = new OContact(); + default: + break; + } + /* + * FIXME resolve externally + */ + if (!rec ) { + ; + } + return 0l; +} +bool OPimResolver::isBuiltIn( const QString& str) const{ + return m_builtIns.contains( str ); +} +QCString OPimResolver::qcopChannel( enum BuiltIn& built)const { + QCString str("QPE/"); + switch( built ) { + case TodoList: + str += "Todolist"; + break; + case DateBook: + str += "Datebook"; + break; + case AddressBook: + str += "Addressbook"; + break; + default: + break; + } + + return str; +} +QCString OPimResolver::qcopChannel( const QString& service )const { + QCString str("QPE/"); + str += service.latin1(); + return str; +} +/* + * Implement services!! + * FIXME + */ +QCString OPimResolver::applicationChannel( enum BuiltIn& built)const { + QCString str("QPE/Application/"); + switch( built ) { + case TodoList: + str += "todolist"; + break; + case DateBook: + str += "datebook"; + break; + case AddressBook: + str += "addressbook"; + break; + } + + return str; +} +QCString OPimResolver::applicationChannel( const QString& service )const { + QCString str("QPE/Application/"); + + if ( isBuiltIn( service ) ) { + if ( service == "Todolist" ) + str += "todolist"; + else if ( service == "Datebook" ) + str += "datebook"; + else if ( service == "Addressbook" ) + str += "addressbook"; + }else + ; // FIXME for additional stuff + + return str; +} +QStringList OPimResolver::services()const { + return m_builtIns; +} +QString OPimResolver::serviceName( int rtti ) const{ + QString str; + switch ( rtti ) { + case TodoList: + str = "Todolist"; + break; + case DateBook: + str = "Datebook"; + break; + case AddressBook: + str = "Addressbook"; + break; + default: + break; + } + return str; + // FIXME me for 3rd party +} +int OPimResolver::serviceId( const QString& service ) { + int rtti = 0; + if ( service == "Todolist" ) + rtti = TodoList; + else if ( service == "Datebook" ) + rtti = DateBook; + else if ( service == "Addressbook" ) + rtti = AddressBook; + + return rtti; +} +/** + * check if the 'service' is registered and if so we'll + */ +bool OPimResolver::add( const QString& service, const OPimRecord& rec) { + if ( QCopChannel::isRegistered( applicationChannel( service ) ) ) { + QByteArray data; + QDataStream arg(data, IO_WriteOnly ); + if ( rec.saveToStream( arg ) ) { + QCopEnvelope env( applicationChannel( service ), "add(int,QByteArray)" ); + env << rec.rtti(); + env << data; + }else + return false; + }else{ + OPimBase* base = backend( service ); + if (!base ) return false; + + base->load(); + base->add( rec ); + base->save(); + delete base; + } + + return true; +} +OPimBase* OPimResolver::backend( const QString& service ) { + return backend( serviceId( service ) ); +} +OPimBase* OPimResolver::backend( int rtti ) { + OPimBase* base = 0l; + switch( rtti ) { + case TodoList: + base = new OTodoAccess(); + break; + case DateBook: + break; + case AddressBook: + base = new OContactAccess("Resolver"); + break; + default: + break; + } + // FIXME for 3rd party + if (!base ) + ; + + return base; +} diff --git a/libopie2/opiepim/core/opimresolver.h b/libopie2/opiepim/core/opimresolver.h index 86ae3eb..1ce1619 100644 --- a/libopie2/opiepim/core/opimresolver.h +++ b/libopie2/opiepim/core/opimresolver.h @@ -1,56 +1,90 @@ #ifndef OPIE_PIM_RESOLVER #define OPIE_PIM_RESOLVER #include <qstring.h> #include <qvaluelist.h> +#include <opie/otemplatebase.h> + /** * OPimResolver is a MetaClass to access * available backends read only. * It will be used to resolve uids + app names * to full informations * to traverse through a list of alarms, reminders * to get access to built in PIM functionality * and to more stuff * THE PERFORMANCE will depend on THE BACKEND * USING XML is a waste of memory!!!!! */ -class OPimResolver : public QObject { +class OPimResolver { public: enum BuiltIn { TodoList = 0, DateBook, AddressBook }; static OPimResolver* self(); - /* + /** * return a record for a uid - * and an app + * and an service + * You've THE OWNERSHIP NOW! */ - OPimRecord &record( const QString& service, int uid ); + OPimRecord *record( const QString& service, int uid ); /** * return the QCopChannel for service * When we will use Qtopia Services it will be used here */ - QString qcopChannel( enum BuiltIn& )const; - QString qcopChannel( const QString& service ); + QCString qcopChannel( enum BuiltIn& )const; + QCString qcopChannel( const QString& service )const; + + /** + * The Application channel (QPE/Application/name) + */ + QCString applicationChannel( enum BuiltIn& )const; + QCString applicationChannel( const QString& service )const; /** * return a list of available services */ QStringList services()const; - + inline QString serviceName(int rrti )const; + int serviceId( const QString& Service); /** * add a record to a service... ;) */ bool add( const QString& service, const OPimRecord& ); + + /** + * record returns an empty record for a given service. + * Be sure to delete it!!! + * + */ + OPimRecord* record( const QString& service ); + OPimRecord* record( int rtti ); + + /** + * you can cast to your + */ + OPimBase* backend( const QString& service ); + OPimBase* backend( int rtti ); private: OPimResolver(); - OPimRecord *m_last; + void loadData(); + inline bool isBuiltIn( const QString& )const; + OPimRecord* recordExtern( const QString&, int ); + OPimRecord* recordExtern( const QString& ); + + static OPimResolver* m_self; + struct Data; + class Private; -}: + Data* data; + Private* d; + QStringList m_builtIns; +}; #endif diff --git a/libopie2/opiepim/core/otemplatebase.h b/libopie2/opiepim/core/otemplatebase.h index b855919..29fb6ec 100644 --- a/libopie2/opiepim/core/otemplatebase.h +++ b/libopie2/opiepim/core/otemplatebase.h @@ -1,18 +1,48 @@ #ifndef OPIE_TEMPLATE_BASE_H #define OPIE_TEMPLATE_BASE_H #include <qarray.h> -#include "opimrecord.h" +#include <opie/opimrecord.h> + /** + * Templates do not have a base class, This is why + * we've this class + * this is here to give us the possibility + * to have a common base class + * You may not want to use that interface internaly + * POOR mans interface + */ +struct OPimBase { + /** + * return the rtti + */ + virtual int rtti()= 0; + virtual OPimRecord* record()const = 0; + virtual OPimRecord* record(int uid)const = 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<int> records()const = 0; + /* + * ADD editing here? + * -zecke + */ + +}; +/** * internal template base + * T needs to implement the copy c'tor!!! */ template <class T = OPimRecord> -class OTemplateBase { +class OTemplateBase : public OPimBase { public: enum CacheDirection { Forward=0, Reverse }; OTemplateBase() { }; virtual ~OTemplateBase() { } @@ -23,10 +53,39 @@ public: */ virtual T find( int uid, const QArray<int>& items, uint current, CacheDirection dir = Forward )const = 0; virtual void cache( const T& )const = 0; virtual void setSaneCacheSize( int ) = 0; + /* reimplement of OPimBase */ + int rtti(); + OPimRecord* record()const; + OPimRecord* record(int uid )const; + static T* rec(); }; +/* + * implementation + */ +template <class T> +int +OTemplateBase<T>::rtti() { + return T::rtti(); +} +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; +}; +template <class T> +T* OTemplateBase<T>::rec() { + return new T; +} #endif diff --git a/libopie2/opiepim/core/otodoaccess.cpp b/libopie2/opiepim/core/otodoaccess.cpp index d860411..5e89a1b 100644 --- a/libopie2/opiepim/core/otodoaccess.cpp +++ b/libopie2/opiepim/core/otodoaccess.cpp @@ -3,13 +3,13 @@ #include <qpe/alarmserver.h> // #include "otodoaccesssql.h" #include "otodoaccess.h" #include "obackendfactory.h" -OTodoAccess::OTodoAccess( OTodoAccessBackend* end ) +OTodoAccess::OTodoAccess( OTodoAccessBackend* end, enum Access ) : QObject(), OPimAccessTemplate<OTodo>( end ), m_todoBackEnd( end ) { // if (end == 0l ) // m_todoBackEnd = new OTodoAccessBackendSQL( QString::null); // Zecke: Du musst hier noch für das XML-Backend einen Appnamen übergeben ! @@ -41,42 +41,12 @@ OTodoAccess::List OTodoAccess::effectiveToDos( const QDate& start, includeNoDates ); } OTodoAccess::List OTodoAccess::overDue() { List lis( m_todoBackEnd->overDue(), this ); return lis; } -void OTodoAccess::addAlarm( const OTodo& event) { -/* FIXME use the new notifier architecture - if (!event.hasAlarmDateTime() ) - return; - - QDateTime now = QDateTime::currentDateTime(); - QDateTime schedule = event.alarmDateTime(); - - if ( schedule > now ){ - AlarmServer::addAlarm( schedule, - "QPE/Application/todolist", - "alarm(QDateTime,int)", event.uid() ); - - } -*/ -} -void OTodoAccess::delAlarm( int uid) { - - QDateTime schedule; // Create null DateTime - - // I hope this will remove all scheduled alarms - // with the given uid !? - // If not: I have to rethink how to remove already - // scheduled events... (se) - // it should be fine -zecke -// qWarning("Removing alarm for event with uid %d", uid ); - AlarmServer::deleteAlarm( schedule , - "QPE/Application/todolist", - "alarm(QDateTime,int)", uid ); -} /* sort order */ OTodoAccess::List OTodoAccess::sorted( bool ascending, int sort,int filter, int cat ) { QArray<int> ints = m_todoBackEnd->sorted( ascending, sort, filter, cat ); OTodoAccess::List list( ints, this ); return list; diff --git a/libopie2/opiepim/core/otodoaccess.h b/libopie2/opiepim/core/otodoaccess.h index c079155..2bb87dc 100644 --- a/libopie2/opiepim/core/otodoaccess.h +++ b/libopie2/opiepim/core/otodoaccess.h @@ -26,13 +26,13 @@ public: DoNotShowCompleted =4 }; /** * if you use 0l * the default resource will be * picked up */ - OTodoAccess( OTodoAccessBackend* = 0l); + OTodoAccess( OTodoAccessBackend* = 0l, enum Access acc = Random ); ~OTodoAccess(); /* our functions here */ /** * include todos from start to end @@ -75,23 +75,12 @@ public: signals: /** * if the OTodoAccess was changed */ void signalChanged( const OTodoAccess* ); private: - /** - * add an Alarm to the AlarmServer - */ - void addAlarm( const OTodo& ); - - /** - * delete an alarm with the uid from - * the alarm server - */ - void delAlarm( int uid ); - int m_cat; OTodoAccessBackend* m_todoBackEnd; class OTodoAccessPrivate; OTodoAccessPrivate* d; }; diff --git a/libopie2/opiepim/ocontact.cpp b/libopie2/opiepim/ocontact.cpp index 6aec62e..38cba72 100644 --- a/libopie2/opiepim/ocontact.cpp +++ b/libopie2/opiepim/ocontact.cpp @@ -19,12 +19,13 @@ ** **********************************************************************/ #define QTOPIA_INTERNAL_CONTACT_MRE #include "ocontact.h" +#include "opimresolver.h" #include <qpe/stringutil.h> #include <qpe/timeconversion.h> #include <qpe/timestring.h> #include <qobject.h> @@ -826,13 +827,13 @@ void OContact::save( QString &buf ) const /*! \internal Returns the list of fields belonging to a contact Never change order of this list ! It has to be regarding - enum AddressBookFields !! + enum AddressBookFields !! */ QStringList OContact::fields() { QStringList list; list.append( "Title" ); // Not Used! @@ -1097,13 +1098,13 @@ void OContact::setDefaultEmail( const QString &v ) void OContact::insertEmails( const QStringList &v ) { for ( QStringList::ConstIterator it = v.begin(); it != v.end(); ++it ) insertEmail( *it ); } int OContact::rtti() { - return 2; + return OPimResolver::AddressBook; } void OContact::setUid( int i ) -{ - OPimRecord::setUid(i); - replace( Qtopia::AddressUid , QString::number(i)); +{ + OPimRecord::setUid(i); + replace( Qtopia::AddressUid , QString::number(i)); } diff --git a/libopie2/opiepim/otodo.cpp b/libopie2/opiepim/otodo.cpp index ece624a..cde2b3d 100644 --- a/libopie2/opiepim/otodo.cpp +++ b/libopie2/opiepim/otodo.cpp @@ -13,12 +13,13 @@ #include "opimstate.h" #include "orecur.h" #include "opimmaintainer.h" #include "opimnotifymanager.h" +#include "opimresolver.h" #include "otodo.h" struct OTodo::OTodoData : public QShared { OTodoData() : QShared() { @@ -414,8 +415,8 @@ QString OTodo::type() const { } QString OTodo::recordField(int /*id*/ )const { return QString::null; } int OTodo::rtti(){ - return 1; + return OPimResolver::TodoList; } diff --git a/libopie2/opiepim/ui/opimmainwindow.cpp b/libopie2/opiepim/ui/opimmainwindow.cpp index 92be2fd..7e57f3a 100644 --- a/libopie2/opiepim/ui/opimmainwindow.cpp +++ b/libopie2/opiepim/ui/opimmainwindow.cpp @@ -1,16 +1,17 @@ #include <qapplication.h> #include <qcopchannel_qws.h> #include <qpe/qcopenvelope_qws.h> +#include "opimresolver.h" #include "opimmainwindow.h" OPimMainWindow::OPimMainWindow( const QString& service, QWidget* parent, const char* name, WFlags flag ) - : QMainWindow( parent, name, flag ), m_service( service ), m_fallBack(0l) { + : QMainWindow( parent, name, flag ), m_rtti(-1), m_service( service ), m_fallBack(0l) { /* * let's generate our QCopChannel */ m_str = QString("QPE/"+m_service).local8Bit(); m_channel= new QCopChannel(m_str, this ); @@ -26,12 +27,15 @@ OPimMainWindow::OPimMainWindow( const QString& service, QWidget* parent, OPimMainWindow::~OPimMainWindow() { delete m_channel; } QCopChannel* OPimMainWindow::channel() { return m_channel; } +void OPimMainWindow::doSetDocument( const QString& ) { + +} void OPimMainWindow::appMessage( const QCString& cmd, const QByteArray& array ) { /* * create demands to create * a new record... */ QDataStream stream(array, IO_ReadOnly); @@ -66,6 +70,36 @@ void OPimMainWindow::appMessage( const QCString& cmd, const QByteArray& array ) m_fallBack = record(rtti, array ); if (!m_fallBack) return; add( *m_fallBack ); delete m_fallBack; } } +/* implement the url scripting here */ +void OPimMainWindow::setDocument( const QString& str) { + doSetDocument( str ); +} +/* + * we now try to get the array demarshalled + * check if the rtti matches this one + */ +OPimRecord* OPimMainWindow::record( int rtti, const QByteArray& array ) { + if ( service() != rtti ) + return 0l; + + OPimRecord* record = OPimResolver::self()->record( rtti ); + QDataStream str(array, IO_ReadOnly ); + if ( !record || !record->loadFromStream(str) ) { + delete record; + record = 0l; + } + + return record; +} +/* + * get the rtti for the service + */ +int OPimMainWindow::service() { + if ( m_rtti == -1 ) + m_rtti = OPimResolver::self()->serviceId( m_service ); + + return m_rtti; +} diff --git a/libopie2/opiepim/ui/opimmainwindow.h b/libopie2/opiepim/ui/opimmainwindow.h index 94100bd..34b8a71 100644 --- a/libopie2/opiepim/ui/opimmainwindow.h +++ b/libopie2/opiepim/ui/opimmainwindow.h @@ -29,12 +29,17 @@ public: OPimMainWindow( const QString& service, QWidget *parent = 0, const char* name = 0, WFlags f = WType_TopLevel); virtual ~OPimMainWindow(); protected slots: + /* + * called when a setDocument + * couldn't be handled by this window + */ + virtual void doSetDocument( const QString& ); /* for syncing */ virtual void flush() = 0; virtual void reload() = 0; /** create a new Records and return the uid */ virtual int create() = 0; @@ -48,32 +53,37 @@ protected slots: /** edit the record */ virtual void edit( int uid ) = 0; /** make a copy of it! */ virtual void add( const OPimRecord& ) = 0; - /* I would love to do this as a template - * but can't think of a right way - * because I need signal and slots -zecke - */ - /* - * the only pointer in the whole PIM API :( - */ - virtual OPimRecord* record( int rtti, const QByteArray& ) = 0; + QCopChannel* channel(); private slots: void appMessage( const QCString&, const QByteArray& ); + void setDocument( const QString& ); private: class Private; Private* d; + int m_rtti; QCopChannel* m_channel; QString m_service; QCString m_str; OPimRecord* m_fallBack; + + /* I would love to do this as a template + * but can't think of a right way + * because I need signal and slots -zecke + */ + /* + * the only pointer in the whole PIM API :( + */ + virtual OPimRecord* record( int rtti, const QByteArray& ) ; + int service(); }; #endif |