-rw-r--r-- | libopie2/opiepim/backend/ocontactaccessbackend_xml.h | 35 | ||||
-rw-r--r-- | libopie2/opiepim/backend/otodoaccessxml.cpp | 2 | ||||
-rw-r--r-- | libopie2/opiepim/backend/otodoaccessxml.h | 2 | ||||
-rw-r--r-- | libopie2/opiepim/core/ocontactaccess.cpp | 4 | ||||
-rw-r--r-- | libopie2/opiepim/core/ocontactaccess.h | 49 | ||||
-rw-r--r-- | libopie2/opiepim/core/opimaccesstemplate.h | 12 |
6 files changed, 37 insertions, 67 deletions
diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_xml.h b/libopie2/opiepim/backend/ocontactaccessbackend_xml.h index 97ef40f..50ea329 100644 --- a/libopie2/opiepim/backend/ocontactaccessbackend_xml.h +++ b/libopie2/opiepim/backend/ocontactaccessbackend_xml.h @@ -1,359 +1,362 @@ /* * XML Backend for the OPIE-Contact Database. * * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) * * ===================================================================== * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * ===================================================================== * ToDo: XML-Backend: Automatic reload if something was changed... * * * ===================================================================== * Version: $Id$ * ===================================================================== * History: * $Log$ + * Revision 1.3 2002/10/14 16:21:54 eilers + * Some minor interface updates + * * Revision 1.2 2002/10/07 17:34:24 eilers * added OBackendFactory for advanced backend access * * Revision 1.1 2002/09/27 17:11:44 eilers * Added API for accessing the Contact-Database ! It is compiling, but * please do not expect that anything is working ! * I will debug that stuff in the next time .. * Please read README_COMPILE for compiling ! * * */ #ifndef _OContactAccessBackend_XML_ #define _OContactAccessBackend_XML_ #include <qasciidict.h> #include <qdatetime.h> #include <qfile.h> #include <qfileinfo.h> #include <qregexp.h> #include <qarray.h> #include <qpe/global.h> #include <opie/xmltree.h> #include "ocontactaccessbackend.h" #include "ocontactaccess.h" #include <stdlib.h> #include <errno.h> using namespace Opie; /* the default xml implementation */ class OContactAccessBackend_XML : public OContactAccessBackend { public: OContactAccessBackend_XML ( QString appname, QString filename = 0l ) { m_appName = appname; /* Set journalfile name ... */ m_journalName = getenv("HOME"); m_journalName +="/.abjournal" + appname; /* Expecting to access the default filename if nothing else is set */ if ( filename.isEmpty() ){ m_fileName = Global::applicationFileName( "addressbook","addressbook.xml" ); } else m_fileName = filename; /* Load Database now */ load (); } bool save() { QString strNewFile = m_fileName + ".new"; QFile f( strNewFile ); if ( !f.open( IO_WriteOnly|IO_Raw ) ) return false; int total_written; QString out; out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n" " <Groups>\n" " </Groups>\n" " <Contacts>\n"; //QValueList<Contact>::iterator it; QValueListConstIterator<OContact> it; for ( it = m_contactList.begin(); it != m_contactList.end(); ++it ) { out += "<Contact "; (*it).save( out ); out += "/>\n"; QCString cstr = out.utf8(); total_written = f.writeBlock( cstr.data(), cstr.length() ); if ( total_written != int(cstr.length()) ) { f.close(); QFile::remove( strNewFile ); return false; } out = ""; } out += " </Contacts>\n</AddressBook>\n"; QCString cstr = out.utf8(); total_written = f.writeBlock( cstr.data(), cstr.length() ); if ( total_written != int( cstr.length() ) ) { f.close(); QFile::remove( strNewFile ); return false; } f.close(); // move the file over, I'm just going to use the system call // because, I don't feel like using QDir. if ( ::rename( strNewFile.latin1(), m_fileName.latin1() ) < 0 ) { qWarning( "problem renaming file %s to %s, errno: %d", strNewFile.latin1(), m_journalName.latin1(), errno ); // remove the tmp file... QFile::remove( strNewFile ); } /* The journalfile should be removed now... */ removeJournal(); return true; } bool load () { m_contactList.clear(); /* Load XML-File and journal if it exists */ if ( !load ( m_fileName, false ) ) return false; /* The returncode of the journalfile is ignored due to the * fact that it does not exist when this class is instantiated ! * But there may such a file exist, if the application crashed. * Therefore we try to load it to get the changes before the # * crash happened... */ load (m_journalName, true); return true; } void clear () { m_contactList.clear(); } bool wasChangedExternally() { QFileInfo fi( m_fileName ); QDateTime lastmod = fi.lastModified (); return (lastmod != m_readtime); } QArray<int> allRecords() const { QArray<int> uid_list( m_contactList.count() ); uint counter = 0; QValueListConstIterator<OContact> it; for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ uid_list[counter++] = (*it).uid(); } return ( uid_list ); } OContact find ( int uid ) const { bool found = false; OContact foundContact; //Create empty contact QValueListConstIterator<OContact> it; for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ if ((*it).uid() == uid){ found = true; break; } } if ( found ){ foundContact = *it; } return ( foundContact ); } QArray<int> queryByExample ( const OContact &query, int settings ){ QArray<int> m_currentQuery( m_contactList.count() ); QValueListConstIterator<OContact> it; uint arraycounter = 0; for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ /* Search all fields and compare them with query object. Store them into list * if all fields matches. */ bool allcorrect = true; for ( int i = 0; i < Qtopia::rid; i++ ) { /* Just compare fields which are not empty in the query object */ if ( !query.field(i).isEmpty() ){ - switch ( settings & ~OContactAccess::query_IgnoreCase ){ - case OContactAccess::query_RegExp:{ + switch ( settings & ~OContactAccess::IgnoreCase ){ + case OContactAccess::RegExp:{ QRegExp expr ( query.field(i), - !(settings & OContactAccess::query_IgnoreCase), + !(settings & OContactAccess::IgnoreCase), false ); if ( expr.find ( (*it).field(i), 0 ) == -1 ) allcorrect = false; } break; - case OContactAccess::query_WildCards:{ + case OContactAccess::WildCards:{ QRegExp expr ( query.field(i), - !(settings & OContactAccess::query_IgnoreCase), + !(settings & OContactAccess::IgnoreCase), true ); if ( expr.find ( (*it).field(i), 0 ) == -1 ) allcorrect = false; } break; - case OContactAccess::query_ExactMatch:{ - if (settings & OContactAccess::query_IgnoreCase){ + case OContactAccess::ExactMatch:{ + if (settings & OContactAccess::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; } const uint querySettings() { - return ( OContactAccess::query_WildCards - & OContactAccess::query_IgnoreCase - & OContactAccess::query_RegExp - & OContactAccess::query_ExactMatch ); + return ( OContactAccess::WildCards + & OContactAccess::IgnoreCase + & OContactAccess::RegExp + & OContactAccess::ExactMatch ); } bool hasQuerySettings (uint querySettings) const { - /* OContactAccess::query_IgnoreCase may be added with one + /* OContactAccess::IgnoreCase may be added with one * of the other settings, but never used alone. * The other settings are just valid alone... */ - switch ( querySettings & ~OContactAccess::query_IgnoreCase ){ - case OContactAccess::query_RegExp: + switch ( querySettings & ~OContactAccess::IgnoreCase ){ + case OContactAccess::RegExp: return ( true ); - case OContactAccess::query_WildCards: + case OContactAccess::WildCards: return ( true ); - case OContactAccess::query_ExactMatch: + case OContactAccess::ExactMatch: return ( true ); default: return ( false ); } } bool add ( const OContact &newcontact ) { //qWarning("odefaultbackend: ACTION::ADD"); updateJournal (newcontact, OContact::ACTION_ADD); addContact_p( newcontact ); return true; } bool replace ( const OContact &contact ) { bool found = false; QValueListIterator<OContact> it; for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ if ( (*it).uid() == contact.uid() ){ found = true; break; } } if (found) { updateJournal (contact, OContact::ACTION_REPLACE); m_contactList.remove (it); m_contactList.append (contact); return true; } else return false; } bool remove ( int uid ) { bool found = false; QValueListIterator<OContact> it; for( it = m_contactList.begin(); it != m_contactList.end(); ++it ){ if ((*it).uid() == uid){ found = true; break; } } if (found) { updateJournal ( *it, OContact::ACTION_REMOVE); m_contactList.remove (it); return true; } else return false; } bool reload(){ /* Reload is the same as load in this implementation */ return ( load() ); } private: void addContact_p( const OContact &newcontact ){ m_contactList.append (newcontact); } /* This function loads the xml-database and the journalfile */ bool load( const QString filename, bool isJournal ) { /* We use the time of the last read to check if the file was * changed externally. */ if ( !isJournal ){ QFileInfo fi( filename ); m_readtime = fi.lastModified (); } const int JOURNALACTION = Qtopia::Notes + 1; const int JOURNALROW = JOURNALACTION + 1; bool foundAction = false; OContact::journal_action action = OContact::ACTION_ADD; int journalKey = 0; QMap<int, QString> contactMap; QMap<QString, QString> customMap; QMap<QString, QString>::Iterator customIt; QAsciiDict<int> dict( 47 ); dict.setAutoDelete( TRUE ); dict.insert( "Uid", new int(Qtopia::AddressUid) ); dict.insert( "Title", new int(Qtopia::Title) ); dict.insert( "FirstName", new int(Qtopia::FirstName) ); dict.insert( "MiddleName", new int(Qtopia::MiddleName) ); dict.insert( "LastName", new int(Qtopia::LastName) ); dict.insert( "Suffix", new int(Qtopia::Suffix) ); dict.insert( "FileAs", new int(Qtopia::FileAs) ); dict.insert( "Categories", new int(Qtopia::AddressCategory) ); dict.insert( "DefaultEmail", new int(Qtopia::DefaultEmail) ); dict.insert( "Emails", new int(Qtopia::Emails) ); dict.insert( "HomeStreet", new int(Qtopia::HomeStreet) ); diff --git a/libopie2/opiepim/backend/otodoaccessxml.cpp b/libopie2/opiepim/backend/otodoaccessxml.cpp index f3b0783..3b4cab2 100644 --- a/libopie2/opiepim/backend/otodoaccessxml.cpp +++ b/libopie2/opiepim/backend/otodoaccessxml.cpp @@ -94,193 +94,193 @@ bool OTodoAccessXML::load() { ++j; } if ( i == j ) { // empty value i = j + 1; continue; } QCString value( dt+i, j-i+1 ); i = j + 1; QString str = (haveUtf ? QString::fromUtf8( value ) : QString::fromLatin1( value ) ); if ( haveEnt ) str = Qtopia::plainString( str ); /* * add key + value */ todo( &dict, ev, attr, str ); } /* * now add it */ m_events.insert(ev.uid(), ev ); } qWarning("counts %d", m_events.count() ); return true; } bool OTodoAccessXML::reload() { return load(); } bool OTodoAccessXML::save() { // qWarning("saving"); if (!m_opened || !m_changed ) { // qWarning("not saving"); return true; } QString strNewFile = m_file + ".new"; QFile f( strNewFile ); if (!f.open( IO_WriteOnly|IO_Raw ) ) return false; int written; QString out; out = "<!DOCTYPE Tasks>\n<Tasks>\n"; // for all todos QMap<int, OTodo>::Iterator it; for (it = m_events.begin(); it != m_events.end(); ++it ) { out+= "<Task " + toString( (*it) ) + " />\n"; QCString cstr = out.utf8(); written = f.writeBlock( cstr.data(), cstr.length() ); /* less written then we wanted */ if ( written != (int)cstr.length() ) { f.close(); QFile::remove( strNewFile ); return false; } out = QString::null; } out += "</Tasks>"; QCString cstr = out.utf8(); written = f.writeBlock( cstr.data(), cstr.length() ); if ( written != (int)cstr.length() ) { f.close(); QFile::remove( strNewFile ); return false; } /* flush before renaming */ f.close(); if( ::rename( strNewFile.latin1(), m_file.latin1() ) < 0 ) { // qWarning("error renaming"); QFile::remove( strNewFile ); } m_changed = false; return true; } QArray<int> OTodoAccessXML::allRecords()const { QArray<int> ids( m_events.count() ); QMap<int, OTodo>::ConstIterator it; int i = 0; for ( it = m_events.begin(); it != m_events.end(); ++it ) { ids[i] = it.key(); i++; } return ids; } -QArray<int> OTodoAccessXML::queryByExample( const OTodo&, int sort ) { +QArray<int> OTodoAccessXML::queryByExample( const OTodo&, int ) { QArray<int> ids(0); return ids; } OTodo OTodoAccessXML::find( int uid )const { OTodo todo; todo.setUid( 0 ); // isEmpty() QMap<int, OTodo>::ConstIterator it = m_events.find( uid ); if ( it != m_events.end() ) todo = it.data(); return todo; } void OTodoAccessXML::clear() { if (m_opened ) m_changed = true; m_events.clear(); } bool OTodoAccessXML::add( const OTodo& todo ) { // qWarning("add"); m_changed = true; m_events.insert( todo.uid(), todo ); return true; } bool OTodoAccessXML::remove( int uid ) { m_changed = true; m_events.remove( uid ); return true; } bool OTodoAccessXML::replace( const OTodo& todo) { m_changed = true; m_events.replace( todo.uid(), todo ); return true; } QArray<int> OTodoAccessXML::effectiveToDos( const QDate& start, const QDate& end, bool includeNoDates ) { QArray<int> ids( m_events.count() ); QMap<int, OTodo>::Iterator it; int i = 0; for ( it = m_events.begin(); it != m_events.end(); ++it ) { if ( !it.data().hasDueDate() ) { if ( includeNoDates ) { ids[i] = it.key(); i++; } }else if ( it.data().dueDate() >= start && it.data().dueDate() <= end ) { ids[i] = it.key(); i++; } } ids.resize( i ); return ids; } QArray<int> OTodoAccessXML::overDue() { QArray<int> ids( m_events.count() ); int i = 0; QMap<int, OTodo>::Iterator it; for ( it = m_events.begin(); it != m_events.end(); ++it ) { if ( it.data().isOverdue() ) { ids[i] = it.key(); i++; } } ids.resize( i ); return ids; } /* private */ void OTodoAccessXML::todo( QAsciiDict<int>* dict, OTodo& ev, const QCString& attr, const QString& val) { // qWarning("parse to do from XMLElement" ); int *find=0; find = (*dict)[ attr.data() ]; if (!find ) { // qWarning("Unknown option" + it.key() ); ev.setCustomField( attr, val ); return; } switch( *find ) { case OTodo::Uid: ev.setUid( val.toInt() ); break; case OTodo::Category: ev.setCategories( ev.idsFromString( val ) ); break; diff --git a/libopie2/opiepim/backend/otodoaccessxml.h b/libopie2/opiepim/backend/otodoaccessxml.h index 1e7e371..dc41c32 100644 --- a/libopie2/opiepim/backend/otodoaccessxml.h +++ b/libopie2/opiepim/backend/otodoaccessxml.h @@ -1,56 +1,56 @@ #ifndef OPIE_TODO_ACCESS_XML_H #define OPIE_TODO_ACCESS_XML_H #include <qasciidict.h> #include <qmap.h> #include "otodoaccessbackend.h" namespace Opie { class XMLElement; }; class OTodoAccessXML : public OTodoAccessBackend { public: /** * fileName if Empty we will use the default path */ OTodoAccessXML( const QString& appName, const QString& fileName = QString::null ); ~OTodoAccessXML(); bool load(); bool reload(); bool save(); QArray<int> allRecords()const; - QArray<int> queryByExample( const OTodo&, int sort ); + QArray<int> queryByExample( const OTodo&, int querysettings ); OTodo find( int uid )const; void clear(); bool add( const OTodo& ); bool remove( int uid ); bool replace( const OTodo& ); /* our functions */ QArray<int> effectiveToDos( const QDate& start, const QDate& end, bool includeNoDates ); QArray<int> overDue(); QArray<int> sorted( bool asc, int sortOrder, int sortFilter, int cat ); private: void todo( QAsciiDict<int>*, OTodo&,const QCString&,const QString& ); QString toString( const OTodo& )const; QString toString( const QArray<int>& ints ) const; QMap<int, OTodo> m_events; QString m_file; QString m_app; bool m_opened : 1; bool m_changed : 1; class OTodoAccessXMLPrivate; OTodoAccessXMLPrivate* d; int m_year, m_month, m_day; }; #endif diff --git a/libopie2/opiepim/core/ocontactaccess.cpp b/libopie2/opiepim/core/ocontactaccess.cpp index b5f358b..e8c0a45 100644 --- a/libopie2/opiepim/core/ocontactaccess.cpp +++ b/libopie2/opiepim/core/ocontactaccess.cpp @@ -1,165 +1,167 @@ /* * Class to manage the Contacts. * * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) * * ===================================================================== * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * ===================================================================== * Info: This class could just work with a change in the header-file * of the Contact class ! Therefore our libopie only compiles * with our version of libqpe * ===================================================================== * ToDo: XML-Backend: Automatic reload if something was changed... * * * ===================================================================== * Version: $Id$ * ===================================================================== * History: * $Log$ + * Revision 1.4 2002/10/14 16:21:54 eilers + * Some minor interface updates + * * Revision 1.3 2002/10/07 17:34:24 eilers * added OBackendFactory for advanced backend access * * Revision 1.2 2002/10/02 16:18:11 eilers * debugged and seems to work almost perfectly .. * * Revision 1.1 2002/09/27 17:11:44 eilers * Added API for accessing the Contact-Database ! It is compiling, but * please do not expect that anything is working ! * I will debug that stuff in the next time .. * Please read README_COMPILE for compiling ! * * */ #include "ocontactaccess.h" #include "obackendfactory.h" #include <qasciidict.h> #include <qdatetime.h> #include <qfile.h> #include <qregexp.h> #include <qlist.h> #include <qcopchannel_qws.h> //#include <qpe/qcopenvelope_qws.h> #include <qpe/global.h> #include <errno.h> #include <fcntl.h> #include <unistd.h> #include <stdlib.h> #include "ocontactaccessbackend_xml.h" OContactAccess::OContactAccess ( const QString appname, const QString , OContactAccessBackend* end, bool autosync ): OPimAccessTemplate<OContact>( end ), m_changed ( false ) { /* take care of the backend. If there is no one defined, we * will use the XML-Backend as default (until we have a cute SQL-Backend..). */ if( end == 0 ) { - // __asm__("int3"); qWarning ("Using BackendFactory !"); end = OBackendFactory<OContactAccessBackend>::Default( "contact", appname ); } // Set backend locally and in template m_backEnd = end; OPimAccessTemplate<OContact>::setBackEnd (end); /* Connect signal of external db change to function */ QCopChannel *dbchannel = new QCopChannel( "QPE/PIM", this ); connect( dbchannel, SIGNAL(received(const QCString &, const QByteArray &)), this, SLOT(copMessage( const QCString &, const QByteArray &)) ); if ( autosync ){ QCopChannel *syncchannel = new QCopChannel( "QPE/Sync", this ); connect( syncchannel, SIGNAL(received(const QCString &, const QByteArray &)), this, SLOT(copMessage( const QCString &, const QByteArray &)) ); } } OContactAccess::~OContactAccess () { /* The user may forget to save the changed database, therefore try to * do it for him.. */ if ( m_changed ) save(); // delete m_backEnd; is done by template.. } bool OContactAccess::load() { return ( m_backEnd->load() ); } bool OContactAccess::save () { /* If the database was changed externally, we could not save the * Data. This will remove added items which is unacceptable ! * Therefore: Reload database and merge the data... */ if ( m_backEnd->wasChangedExternally() ) reload(); if ( m_changed ){ bool status = m_backEnd->save(); if ( !status ) return false; m_changed = false; /* Now tell everyone that new data is available. */ QCopEnvelope e( "QPE/PIM", "addressbookUpdated()" ); } return true; } const uint OContactAccess::querySettings() { return ( m_backEnd->querySettings() ); } bool OContactAccess::hasQuerySettings ( int querySettings ) const { return ( m_backEnd->hasQuerySettings ( querySettings ) ); } bool OContactAccess::add ( const OContact& newcontact ) { m_changed = true; return ( m_backEnd->add ( newcontact ) ); } bool OContactAccess::replace ( const OContact& contact ) { m_changed = true; return ( m_backEnd->replace ( contact ) ); } bool OContactAccess::remove ( const OContact& t ) { m_changed = true; return ( m_backEnd->remove ( t.uid() ) ); } bool OContactAccess::remove ( int uid ) { m_changed = true; return ( m_backEnd->remove ( uid ) ); } bool OContactAccess::wasChangedExternally()const { return ( m_backEnd->wasChangedExternally() ); } diff --git a/libopie2/opiepim/core/ocontactaccess.h b/libopie2/opiepim/core/ocontactaccess.h index 54f7f07..adc66cf 100644 --- a/libopie2/opiepim/core/ocontactaccess.h +++ b/libopie2/opiepim/core/ocontactaccess.h @@ -1,197 +1,168 @@ /* * Class to manage the Contacts. * * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) * Copyright (c) 2002 by Holger Freyther (zecke@handhelds.org) * * ===================================================================== * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; * either version 2 of the License, or (at your option) any later * version. * ===================================================================== * ToDo: Define enum for query settings * ===================================================================== * Version: $Id$ * ===================================================================== * History: * $Log$ + * Revision 1.2 2002/10/14 16:21:54 eilers + * Some minor interface updates + * * Revision 1.1 2002/09/27 17:11:44 eilers * Added API for accessing the Contact-Database ! It is compiling, but * please do not expect that anything is working ! * I will debug that stuff in the next time .. * Please read README_COMPILE for compiling ! * * ===================================================================== */ #ifndef _OCONTACTACCESS_H #define _OCONTACTACCESS_H #include <qobject.h> #include <qpe/qcopenvelope_qws.h> #include <qvaluelist.h> #include <qfileinfo.h> #include "ocontact.h" #include "ocontactaccessbackend.h" #include "opimaccesstemplate.h" /** Class to access the contacts database. * This is just a frontend for the real database handling which is * done by the backend. */ class OContactAccess: public QObject, public OPimAccessTemplate<OContact> { Q_OBJECT - - /* class Iterator{ - friend OContactAccess; - public: - Iterator(); - Iterator ( const Iterator& copy ); - - bool operator== ( const Iterator& it ); - bool operator!= ( const Iterator& it ); - Iterator& operator= ( const Iterator& it ); - Iterator& operator++ (); // prefix - Iterator operator++ ( int ); // postfix - Iterator& operator-- (); // prefix - Iterator operator-- ( int ); // postfix - Contact operator*() const; - Contact operator->() const; - - Iterator begin(); - Iterator end(); - - uint count() const; - - private: - QValueList<int> m_uids; - int m_cur_position; - bool m_end_reached; - OContactAccess *m_db; - - }; - - */ - public: /** 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 OContactBackend + * @see OContactAccessBackend */ OContactAccess (const QString appname, const QString filename = 0l, OContactAccessBackend* backend = 0l, bool handlesync = true); ~OContactAccess (); /** 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() - * - why not enum - zecke? - * -> Had some implementation problems .. Will use enum soon ! .. (se) */ - static const int query_WildCards = 0x0001; - static const int query_IgnoreCase = 0x0002; - static const int query_RegExp = 0x0004; - static const int query_ExactMatch = 0x0008; + enum QuerySettings { + WildCards = 0x0001, + IgnoreCase = 0x0002, + RegExp = 0x0004, + ExactMatch = 0x0008, + }; /** Return all possible settings. * @return All settings provided by the current backend * (i.e.: query_WildCards & query_IgnoreCase) */ const uint querySettings(); /** Check whether settings are correct. * @return <i>true</i> if the given settings are correct and possible. */ bool hasQuerySettings ( int querySettings ) const; /** Add Contact to database. * @param newcontact The contact to add. * @return <i>true</i> if added successfully. */ bool add (const OContact& newcontact); /** Replace contact. * Replaces given contact with contact with the user id <i>uid</i>. * @param uid The user ID * @param contact The new contact * @return <i>true</i> if successful. */ bool replace ( const OContact& contact ); /** Remove contact. * Removes contact with the user id <i>uid</i>. * @param The contact to remove * @return <i>true</i> if successful. */ bool remove ( const OContact& t ); /** Remove contact. * Removes contact with the user id <i>uid</i>. * @param The user id of the contact to remove * @return <i>true</i> if successful. */ bool remove ( int uid ); /** Load Database * */ bool load(); /** * if the resource was changed externally. * You should use the signal instead of polling possible changes ! */ bool wasChangedExternally()const; /** 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. */ bool reload(); /** Save contacts database. * Save is more a "commit". After calling this function, all changes are public available. * @return true if successful */ bool save(); 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 OContactAccess *which ); private: // class OContactAccessPrivate; // OContactAccessPrivate* d; OContactAccessBackend *m_backEnd; bool m_loading:1; bool m_changed; private slots: void copMessage( const QCString &msg, const QByteArray &data ); }; #endif diff --git a/libopie2/opiepim/core/opimaccesstemplate.h b/libopie2/opiepim/core/opimaccesstemplate.h index a0d8f63..3e1f393 100644 --- a/libopie2/opiepim/core/opimaccesstemplate.h +++ b/libopie2/opiepim/core/opimaccesstemplate.h @@ -1,167 +1,161 @@ #ifndef OPIE_PIM_ACCESS_TEMPLATE_H #define OPIE_PIM_ACCESS_TEMPLATE_H #include <qarray.h> #include <opie/opimrecord.h> #include <opie/opimaccessbackend.h> #include <opie/orecordlist.h> #include "opimcache.h" #include "otemplatebase.h" /** * 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 plugins */ template <class T = OPimRecord > class OPimAccessTemplate : public OTemplateBase<T> { public: typedef ORecordList<T> List; typedef OPimAccessBackend<T> BackEnd; typedef OPimCache<T> Cache; /** - * our sort order - * should be safe explaining - */ - enum SortOrder { WildCards = 0, IgnoreCase = 1, - RegExp = 2, ExactMatch = 4 }; - - /** * c'tor BackEnd */ OPimAccessTemplate( BackEnd* end); virtual ~OPimAccessTemplate(); /** * load from the backend */ virtual bool load(); /** * reload from the backend */ virtual bool reload(); /** * save to the backend */ virtual bool save(); /** * if the resource was changed externally */ bool wasChangedExternally()const; /** * return a List of records * you can iterate over them */ virtual List allRecords()const; /** - * queryByExample + * queryByExample) + * @see otodoaccess, ocontactaccess */ - virtual List queryByExample( const T& t, int sortOrder ); + virtual List queryByExample( const T& t, int querySettings ); /** * find the OPimRecord uid */ virtual T find( int uid )const; /** * read ahead cache find method ;) */ virtual T find( int uid, const QArray<int>&, uint current, CacheDirection dir = Forward )const; /* invalidate cache here */ /** * clears the backend and invalidates the backend */ virtual void clear() ; /** * add T to the backend */ virtual bool add( const T& t ) ; /* only the uid matters */ /** * remove T from the backend */ virtual bool remove( const T& t ); /** * remove the OPimRecord with uid */ virtual bool remove( int uid ); /** * replace T from backend */ virtual bool replace( const T& t) ; /** * @internal */ void cache( const T& )const; void setSaneCacheSize( int ); protected: /** * invalidate the cache */ void invalidateCache(); void setBackEnd( BackEnd* end ); /** * returns the backend */ BackEnd* backEnd(); BackEnd* m_backEnd; Cache m_cache; }; template <class T> OPimAccessTemplate<T>::OPimAccessTemplate( BackEnd* end ) : OTemplateBase<T>(), m_backEnd( end ) { if (end ) end->setFrontend( this ); } template <class T> OPimAccessTemplate<T>::~OPimAccessTemplate() { qWarning("~OPimAccessTemplate<T>"); delete m_backEnd; } template <class T> bool OPimAccessTemplate<T>::load() { invalidateCache(); return m_backEnd->load(); } template <class T> bool OPimAccessTemplate<T>::reload() { return m_backEnd->reload(); } template <class T> bool OPimAccessTemplate<T>::save() { return m_backEnd->save(); } template <class T> OPimAccessTemplate<T>::List OPimAccessTemplate<T>::allRecords()const { QArray<int> ints = m_backEnd->allRecords(); List lis(ints, this ); return lis; } template <class T> OPimAccessTemplate<T>::List OPimAccessTemplate<T>::queryByExample( const T& t, int sortOrder ) { QArray<int> ints = m_backEnd->queryByExample( t, sortOrder ); |