author | ar <ar> | 2004-06-01 22:21:23 (UTC) |
---|---|---|
committer | ar <ar> | 2004-06-01 22:21:23 (UTC) |
commit | d4fe7d53ddf8f3e7ae046a511f0dc061f30d45ce (patch) (side-by-side diff) | |
tree | 4bab082304716df1ec924ef040161e3cf9c10366 | |
parent | baed1d5ab8589aef14440009bc4e7380bcc5a741 (diff) | |
download | opie-d4fe7d53ddf8f3e7ae046a511f0dc061f30d45ce.zip opie-d4fe7d53ddf8f3e7ae046a511f0dc061f30d45ce.tar.gz opie-d4fe7d53ddf8f3e7ae046a511f0dc061f30d45ce.tar.bz2 |
- convert to odebug framework
-rw-r--r-- | libopie2/opiepim/backend/obackendfactory.h | 24 | ||||
-rw-r--r-- | libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp | 36 | ||||
-rw-r--r-- | libopie2/opiepim/core/ocontactaccess.cpp | 25 | ||||
-rw-r--r-- | libopie2/opiepim/core/opimaccesstemplate.h | 11 | ||||
-rw-r--r-- | libopie2/opiepim/core/opimcontact.cpp | 4 | ||||
-rw-r--r-- | libopie2/opiepim/core/opimnotifymanager.cpp | 4 | ||||
-rw-r--r-- | libopie2/opiepim/core/opimrecordlist.h | 5 |
7 files changed, 60 insertions, 49 deletions
diff --git a/libopie2/opiepim/backend/obackendfactory.h b/libopie2/opiepim/backend/obackendfactory.h index 6f46652..3680ded 100644 --- a/libopie2/opiepim/backend/obackendfactory.h +++ b/libopie2/opiepim/backend/obackendfactory.h @@ -1,224 +1,230 @@ /* This file is part of the Opie Project Copyright (C) Stefan Eilers <eilers.stefan@epost.de> =. Copyright (C) The Opie Team <opie-devel@handhelds.org> .=l. .>+-= _;:, .> :=|. This program is free software; you can .> <`_, > . <= redistribute it and/or modify it under :`=1 )Y*s>-.-- : the terms of the GNU Library General Public .="- .-=="i, .._ License as published by the Free Software - . .-<_> .<> Foundation; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+i> _;_. .i_,=:_. -<s. This program is distributed in the hope that + . -:. = it will be useful, but WITHOUT ANY WARRANTY; : .. .:, . . . without even the implied warranty of =_ + =;=|` MERCHANTABILITY or FITNESS FOR A _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU ..}^=.= = ; Library General Public License for more ++= -. .` .: details. : = ...= . :.=- -. .:....=;==+<; You should have received a copy of the GNU -_. . . )=. = Library General Public License along with -- :-=` this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* * ===================================================================== * ToDo: Use plugins * ===================================================================== */ #ifndef OPIE_BACKENDFACTORY_H_ #define OPIE_BACKENDFACTORY_H_ -#include <qstring.h> -#include <qasciidict.h> -#include <qpe/config.h> - +/* OPIE */ #include <opie2/opimaccessbackend.h> #include <opie2/opimglobal.h> #include <opie2/otodoaccessxml.h> #include <opie2/otodoaccessvcal.h> #include <opie2/ocontactaccessbackend_xml.h> #include <opie2/ocontactaccessbackend_vcard.h> #include <opie2/odatebookaccessbackend_xml.h> +#include <opie2/odebug.h> #ifdef __USE_SQL #include <opie2/otodoaccesssql.h> #include <opie2/ocontactaccessbackend_sql.h> #include <opie2/odatebookaccessbackend_sql.h> #endif +#include <qpe/config.h> + +/* QT */ +#include <qstring.h> +#include <qasciidict.h> + + + using namespace Opie; using namespace Opie::Pim; namespace Opie { class OBackendPrivate; /** * This class is our factory. It will give us the default implementations * of at least Todolist, Contacts and Datebook. In the future this class will * allow users to switch the backend with ( XML->SQLite ) without the need * to recompile.# * This class - as the whole PIM Api - is making use of templates * * <pre> * OPimTodoAccessBackend* backend = OBackEndFactory<OPimTodoAccessBackend>::Default( OPimGlobal::TODOLIST, QString::null ); * backend->load(); * </pre> * * @author Stefan Eilers * @version 0.1 */ template<class T> class OBackendFactory { public: OBackendFactory() {}; /** * Returns a selected backend implementation * @param type the type of the backend * @param database the type of the used database * @param appName The name of your application. It will be passed on to the backend. * @param filename Filename of the database file if you don't want to access the default * @see OPimGlobal() */ static T* create( OPimGlobal::PimType type, OPimGlobal::DatabaseStyle database, const QString& appName, const QString& filename = QString::null ){ - qWarning("Selected backend for %d is: %d", type, database ); + owarn << "Selected backend for " << type << " is: " << database << oendl; // If we should use the dafult database style, we have to request it OPimGlobal::DatabaseStyle use_database = database; if ( use_database == OPimGlobal::DEFAULT ){ use_database = defaultDB( type ); } switch ( type ){ case OPimGlobal::TODOLIST: switch ( use_database ){ default: // Use SQL if something weird is given. // Fall through !! case OPimGlobal::SQL: #ifdef __USE_SQL return (T*) new OPimTodoAccessBackendSQL( filename ); break; #else - qWarning ("OBackendFactory:: sql Backend for TODO not implemented! Using XML instead!"); + owarn << "OBackendFactory:: sql Backend for TODO not implemented! Using XML instead!" << oendl; // Fall through !! #endif case OPimGlobal::XML: return (T*) new OPimTodoAccessXML( appName, filename ); break; case OPimGlobal::VCARD: return (T*) new OPimTodoAccessVCal( filename ); break; } case OPimGlobal::CONTACTLIST: switch ( use_database ){ default: // Use SQL if something weird is given. // Fall through !! case OPimGlobal::SQL: #ifdef __USE_SQL return (T*) new OPimContactAccessBackend_SQL( appName, filename ); break; #else - qWarning ("OBackendFactory:: sql Backend for CONTACT not implemented! Using XML instead!"); + owarn << "OBackendFactory:: sql Backend for CONTACT not implemented! Using XML instead!" << oendl; // Fall through !! #endif case OPimGlobal::XML: return (T*) new OPimContactAccessBackend_XML( appName, filename ); break; case OPimGlobal::VCARD: return (T*) new OPimContactAccessBackend_VCard( appName, filename ); break; } case OPimGlobal::DATEBOOK: switch ( use_database ){ default: // Use SQL if something weird is given. // Fall through !! case OPimGlobal::SQL: #ifdef __USE_SQL return (T*) new ODateBookAccessBackend_SQL( appName, filename ); break; #else - qWarning("OBackendFactory:: sql Backend for DATEBOOK not implemented! Using XML instead!"); + owarn << "OBackendFactory:: sql Backend for DATEBOOK not implemented! Using XML instead!" << oendl; // Fall through !! #endif case OPimGlobal::XML: return (T*) new ODateBookAccessBackend_XML( appName, filename ); break; case OPimGlobal::VCARD: - qWarning("OBackendFactory:: VCal Backend for DATEBOOK not implemented!"); + owarn << "OBackendFactory:: VCal Backend for DATEBOOK not implemented!" << oendl; return (T*) NULL; break; } default: return (T*) NULL; } } /** * Returns the style of the default database which is used to contact PIM data. * @param type the type of the backend * @see OPimGlobal() */ static OPimGlobal::DatabaseStyle defaultDB( OPimGlobal::PimType type ){ QString group_name; switch ( type ){ case OPimGlobal::TODOLIST: group_name = "todo"; break; case OPimGlobal::CONTACTLIST: group_name = "contact"; break; case OPimGlobal::DATEBOOK: group_name = "datebook"; break; default: group_name = "unknown"; } Config config( "pimaccess" ); config.setGroup ( group_name ); QString db_String = config.readEntry( "usebackend", "xml" ); QAsciiDict<int> dictDbTypes( OPimGlobal::_END_DatabaseStyle ); dictDbTypes.setAutoDelete( TRUE ); dictDbTypes.insert( "xml", new int (OPimGlobal::XML) ); dictDbTypes.insert( "sql", new int (OPimGlobal::SQL) ); dictDbTypes.insert( "vcard", new int (OPimGlobal::VCARD) ); int* db_find = dictDbTypes[ db_String ]; if ( !db_find ) return OPimGlobal::UNKNOWN; return (OPimGlobal::DatabaseStyle) *db_find; } /** * Returns the default backend implementation for backendName. Which one is used, is defined * by the configfile "pimaccess.conf". * @param type The type of the backend (@see OPimGlobal()) * @param appName The name of your application. It will be passed on to the backend * @see OPimGlobal() */ static T* defaultBackend( OPimGlobal::PimType type, const QString& appName ){ return create( type, OPimGlobal::DEFAULT, appName ); } private: OBackendPrivate* d; }; } #endif diff --git a/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp b/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp index 5ffcb11..00d62ee 100644 --- a/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp +++ b/libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp @@ -1,754 +1,750 @@ /* This file is part of the Opie Project Copyright (C) Stefan Eilers (Eilers.Stefan@epost.de) =. Copyright (C) The Opie Team <opie-devel@handhelds.org> .=l. .>+-= _;:, .> :=|. This program is free software; you can .> <`_, > . <= redistribute it and/or modify it under :`=1 )Y*s>-.-- : the terms of the GNU Library General Public .="- .-=="i, .._ License as published by the Free Software - . .-<_> .<> Foundation; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+i> _;_. .i_,=:_. -<s. This program is distributed in the hope that + . -:. = it will be useful, but WITHOUT ANY WARRANTY; : .. .:, . . . without even the implied warranty of =_ + =;=|` MERCHANTABILITY or FITNESS FOR A _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU ..}^=.= = ; Library General Public License for more ++= -. .` .: details. : = ...= . :.=- -. .:....=;==+<; You should have received a copy of the GNU -_. . . )=. = Library General Public License along with -- :-=` this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* * XML Backend for the OPIE-Contact Database. */ /* OPIE */ #include <opie2/ocontactaccessbackend_xml.h> #include <opie2/xmltree.h> #include <opie2/ocontactaccessbackend.h> #include <opie2/ocontactaccess.h> #include <opie2/odebug.h> #include <qpe/global.h> /* QT */ #include <qasciidict.h> #include <qfile.h> #include <qfileinfo.h> #include <qregexp.h> #include <qarray.h> #include <qmap.h> /* STD */ #include <stdlib.h> #include <errno.h> using namespace Opie::Core; namespace Opie { OPimContactAccessBackend_XML::OPimContactAccessBackend_XML ( const QString& appname, const QString& filename ): m_changed( false ) { // Just m_contactlist should call delete if an entry // is removed. m_contactList.setAutoDelete( true ); m_uidToContact.setAutoDelete( false ); 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 OPimContactAccessBackend_XML::save() { if ( !m_changed ) return true; QString strNewFile = m_fileName + ".new"; QFile f( strNewFile ); if ( !f.open( IO_WriteOnly|IO_Raw ) ) return false; int total_written; int idx_offset = 0; QString out; // Write Header out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n" " <Groups>\n" " </Groups>\n" " <Contacts>\n"; QCString cstr = out.utf8(); f.writeBlock( cstr.data(), cstr.length() ); idx_offset += cstr.length(); out = ""; // Write all contacts QListIterator<OPimContact> it( m_contactList ); for ( ; it.current(); ++it ) { // owarn << " Uid " << (*it)->uid() << " at Offset: " << idx_offset << "" << oendl; out += "<Contact "; (*it)->save( out ); out += "/>\n"; cstr = out.utf8(); total_written = f.writeBlock( cstr.data(), cstr.length() ); idx_offset += cstr.length(); if ( total_written != int(cstr.length()) ) { f.close(); QFile::remove( strNewFile ); return false; } out = ""; } out += " </Contacts>\n</AddressBook>\n"; // Write Footer 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 ); + owarn << "problem renaming file " << strNewFile << " to " << m_journalName + << ", errno: " << errno << oendl; // remove the tmp file... QFile::remove( strNewFile ); } /* The journalfile should be removed now... */ removeJournal(); m_changed = false; return true; } bool OPimContactAccessBackend_XML::load () { m_contactList.clear(); m_uidToContact.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 OPimContactAccessBackend_XML::clear () { m_contactList.clear(); m_uidToContact.clear(); m_changed = false; } bool OPimContactAccessBackend_XML::wasChangedExternally() { QFileInfo fi( m_fileName ); QDateTime lastmod = fi.lastModified (); return (lastmod != m_readtime); } QArray<int> OPimContactAccessBackend_XML::allRecords() const { QArray<int> uid_list( m_contactList.count() ); uint counter = 0; QListIterator<OPimContact> it( m_contactList ); for( ; it.current(); ++it ){ uid_list[counter++] = (*it)->uid(); } return ( uid_list ); } OPimContact OPimContactAccessBackend_XML::find ( int uid ) const { OPimContact foundContact; //Create empty contact OPimContact* found = m_uidToContact.find( QString().setNum( uid ) ); if ( found ){ foundContact = *found; } return ( foundContact ); } QArray<int> OPimContactAccessBackend_XML::queryByExample ( const OPimContact &query, int settings, const QDateTime& d ) { QArray<int> m_currentQuery( m_contactList.count() ); QListIterator<OPimContact> it( m_contactList ); uint arraycounter = 0; for( ; it.current(); ++it ){ /* Search all fields and compare them with query object. Store them into list * if all fields matches. */ QDate* queryDate = 0l; QDate* checkDate = 0l; bool allcorrect = true; for ( int i = 0; i < Qtopia::Groups; i++ ) { // Birthday and anniversary are special nonstring fields and should // be handled specially switch ( i ){ case Qtopia::Birthday: queryDate = new QDate( query.birthday() ); checkDate = new QDate( (*it)->birthday() ); // fall through case Qtopia::Anniversary: if ( queryDate == 0l ){ queryDate = new QDate( query.anniversary() ); checkDate = new QDate( (*it)->anniversary() ); } if ( queryDate->isValid() ){ if( checkDate->isValid() ){ if ( settings & OPimContactAccess::DateYear ){ if ( queryDate->year() != checkDate->year() ) allcorrect = false; } if ( settings & OPimContactAccess::DateMonth ){ if ( queryDate->month() != checkDate->month() ) allcorrect = false; } if ( settings & OPimContactAccess::DateDay ){ if ( queryDate->day() != checkDate->day() ) allcorrect = false; } if ( settings & OPimContactAccess::DateDiff ) { QDate current; // If we get an additional date, we // will take this date instead of // the current one.. if ( !d.date().isValid() ) current = QDate::currentDate(); else current = d.date(); // We have to equalize the year, otherwise // the search will fail.. checkDate->setYMD( current.year(), checkDate->month(), checkDate->day() ); if ( *checkDate < current ) checkDate->setYMD( current.year()+1, checkDate->month(), checkDate->day() ); // Check whether the birthday/anniversary date is between // the current/given date and the maximum date // ( maximum time range ) ! - qWarning("Checking if %s is between %s and %s ! ", - checkDate->toString().latin1(), - current.toString().latin1(), - queryDate->toString().latin1() ); + owarn << "Checking if " << checkDate->toString() << " is between " << current.toString() + << " and " << queryDate->toString() << " ! " << oendl; if ( current.daysTo( *queryDate ) >= 0 ){ if ( !( ( *checkDate >= current ) && ( *checkDate <= *queryDate ) ) ){ allcorrect = false; - qWarning (" Nope!.."); + owarn << " Nope!.." << oendl; } } } } else{ // checkDate is invalid. Therefore this entry is always rejected allcorrect = false; } } delete queryDate; queryDate = 0l; delete checkDate; checkDate = 0l; break; default: /* Just compare fields which are not empty in the query object */ if ( !query.field(i).isEmpty() ){ switch ( settings & ~( OPimContactAccess::IgnoreCase | OPimContactAccess::DateDiff | OPimContactAccess::DateYear | OPimContactAccess::DateMonth | OPimContactAccess::DateDay | OPimContactAccess::MatchOne ) ){ case OPimContactAccess::RegExp:{ QRegExp expr ( query.field(i), !(settings & OPimContactAccess::IgnoreCase), false ); if ( expr.find ( (*it)->field(i), 0 ) == -1 ) allcorrect = false; } break; case OPimContactAccess::WildCards:{ QRegExp expr ( query.field(i), !(settings & OPimContactAccess::IgnoreCase), true ); if ( expr.find ( (*it)->field(i), 0 ) == -1 ) allcorrect = false; } break; case OPimContactAccess::ExactMatch:{ if (settings & OPimContactAccess::IgnoreCase){ if ( query.field(i).upper() != (*it)->field(i).upper() ) allcorrect = false; }else{ if ( query.field(i) != (*it)->field(i) ) allcorrect = false; } } break; } } } } if ( allcorrect ){ m_currentQuery[arraycounter++] = (*it)->uid(); } } // Shrink to fit.. m_currentQuery.resize(arraycounter); return m_currentQuery; } QArray<int> OPimContactAccessBackend_XML::matchRegexp( const QRegExp &r ) const { QArray<int> m_currentQuery( m_contactList.count() ); QListIterator<OPimContact> it( m_contactList ); uint arraycounter = 0; for( ; it.current(); ++it ){ if ( (*it)->match( r ) ){ m_currentQuery[arraycounter++] = (*it)->uid(); } } // Shrink to fit.. m_currentQuery.resize(arraycounter); return m_currentQuery; } const uint OPimContactAccessBackend_XML::querySettings() { return ( OPimContactAccess::WildCards | OPimContactAccess::IgnoreCase | OPimContactAccess::RegExp | OPimContactAccess::ExactMatch | OPimContactAccess::DateDiff | OPimContactAccess::DateYear | OPimContactAccess::DateMonth | OPimContactAccess::DateDay ); } bool OPimContactAccessBackend_XML::hasQuerySettings (uint querySettings) const { /* OPimContactAccess::IgnoreCase, DateDiff, DateYear, DateMonth, DateDay * may be added with any of the other settings. IgnoreCase should never used alone. * Wildcards, RegExp, ExactMatch should never used at the same time... */ // Step 1: Check whether the given settings are supported by this backend if ( ( querySettings & ( OPimContactAccess::IgnoreCase | OPimContactAccess::WildCards | OPimContactAccess::DateDiff | OPimContactAccess::DateYear | OPimContactAccess::DateMonth | OPimContactAccess::DateDay | OPimContactAccess::RegExp | OPimContactAccess::ExactMatch ) ) != querySettings ) return false; // Step 2: Check whether the given combinations are ok.. // IngoreCase alone is invalid if ( querySettings == OPimContactAccess::IgnoreCase ) return false; // WildCards, RegExp and ExactMatch should never used at the same time switch ( querySettings & ~( OPimContactAccess::IgnoreCase | OPimContactAccess::DateDiff | OPimContactAccess::DateYear | OPimContactAccess::DateMonth | OPimContactAccess::DateDay ) ){ case OPimContactAccess::RegExp: return ( true ); case OPimContactAccess::WildCards: return ( true ); case OPimContactAccess::ExactMatch: return ( true ); case 0: // one of the upper removed bits were set.. return ( true ); default: return ( false ); } } // Currently only asc implemented.. QArray<int> OPimContactAccessBackend_XML::sorted( bool asc, int , int , int ) { QMap<QString, int> nameToUid; QStringList names; QArray<int> m_currentQuery( m_contactList.count() ); // First fill map and StringList with all Names // Afterwards sort namelist and use map to fill array to return.. QListIterator<OPimContact> it( m_contactList ); for( ; it.current(); ++it ){ names.append( (*it)->fileAs() + QString::number( (*it)->uid() ) ); nameToUid.insert( (*it)->fileAs() + QString::number( (*it)->uid() ), (*it)->uid() ); } names.sort(); int i = 0; if ( asc ){ for ( QStringList::Iterator it = names.begin(); it != names.end(); ++it ) m_currentQuery[i++] = nameToUid[ (*it) ]; }else{ for ( QStringList::Iterator it = names.end(); it != names.begin(); --it ) m_currentQuery[i++] = nameToUid[ (*it) ]; } return m_currentQuery; } bool OPimContactAccessBackend_XML::add ( const OPimContact &newcontact ) { //owarn << "odefaultbackend: ACTION::ADD" << oendl; updateJournal (newcontact, ACTION_ADD); addContact_p( newcontact ); m_changed = true; return true; } bool OPimContactAccessBackend_XML::replace ( const OPimContact &contact ) { m_changed = true; OPimContact* found = m_uidToContact.find ( QString().setNum( contact.uid() ) ); if ( found ) { OPimContact* newCont = new OPimContact( contact ); updateJournal ( *newCont, ACTION_REPLACE); m_contactList.removeRef ( found ); m_contactList.append ( newCont ); m_uidToContact.remove( QString().setNum( contact.uid() ) ); m_uidToContact.insert( QString().setNum( newCont->uid() ), newCont ); owarn << "Nur zur Sicherheit: " << contact.uid() << " == " << newCont->uid() << " ?" << oendl; return true; } else return false; } bool OPimContactAccessBackend_XML::remove ( int uid ) { m_changed = true; OPimContact* found = m_uidToContact.find ( QString().setNum( uid ) ); if ( found ) { updateJournal ( *found, ACTION_REMOVE); m_contactList.removeRef ( found ); m_uidToContact.remove( QString().setNum( uid ) ); return true; } else return false; } bool OPimContactAccessBackend_XML::reload(){ /* Reload is the same as load in this implementation */ return ( load() ); } void OPimContactAccessBackend_XML::addContact_p( const OPimContact &newcontact ) { OPimContact* contRef = new OPimContact( newcontact ); m_contactList.append ( contRef ); m_uidToContact.insert( QString().setNum( newcontact.uid() ), contRef ); } /* This function loads the xml-database and the journalfile */ bool OPimContactAccessBackend_XML::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; journal_action action = 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) ); dict.insert( "HomeCity", new int(Qtopia::HomeCity) ); dict.insert( "HomeState", new int(Qtopia::HomeState) ); dict.insert( "HomeZip", new int(Qtopia::HomeZip) ); dict.insert( "HomeCountry", new int(Qtopia::HomeCountry) ); dict.insert( "HomePhone", new int(Qtopia::HomePhone) ); dict.insert( "HomeFax", new int(Qtopia::HomeFax) ); dict.insert( "HomeMobile", new int(Qtopia::HomeMobile) ); dict.insert( "HomeWebPage", new int(Qtopia::HomeWebPage) ); dict.insert( "Company", new int(Qtopia::Company) ); dict.insert( "BusinessStreet", new int(Qtopia::BusinessStreet) ); dict.insert( "BusinessCity", new int(Qtopia::BusinessCity) ); dict.insert( "BusinessState", new int(Qtopia::BusinessState) ); dict.insert( "BusinessZip", new int(Qtopia::BusinessZip) ); dict.insert( "BusinessCountry", new int(Qtopia::BusinessCountry) ); dict.insert( "BusinessWebPage", new int(Qtopia::BusinessWebPage) ); dict.insert( "JobTitle", new int(Qtopia::JobTitle) ); dict.insert( "Department", new int(Qtopia::Department) ); dict.insert( "Office", new int(Qtopia::Office) ); dict.insert( "BusinessPhone", new int(Qtopia::BusinessPhone) ); dict.insert( "BusinessFax", new int(Qtopia::BusinessFax) ); dict.insert( "BusinessMobile", new int(Qtopia::BusinessMobile) ); dict.insert( "BusinessPager", new int(Qtopia::BusinessPager) ); dict.insert( "Profession", new int(Qtopia::Profession) ); dict.insert( "Assistant", new int(Qtopia::Assistant) ); dict.insert( "Manager", new int(Qtopia::Manager) ); dict.insert( "Spouse", new int(Qtopia::Spouse) ); dict.insert( "Children", new int(Qtopia::Children) ); dict.insert( "Gender", new int(Qtopia::Gender) ); dict.insert( "Birthday", new int(Qtopia::Birthday) ); dict.insert( "Anniversary", new int(Qtopia::Anniversary) ); dict.insert( "Nickname", new int(Qtopia::Nickname) ); dict.insert( "Notes", new int(Qtopia::Notes) ); dict.insert( "action", new int(JOURNALACTION) ); dict.insert( "actionrow", new int(JOURNALROW) ); //owarn << "OPimContactDefaultBackEnd::loading " << filename << "" << oendl; XMLElement *root = XMLElement::load( filename ); if(root != 0l ){ // start parsing /* Parse all XML-Elements and put the data into the * Contact-Class */ XMLElement *element = root->firstChild(); //owarn << "OPimContactAccess::load tagName(): " << root->tagName() << "" << oendl; element = element->firstChild(); /* Search Tag "Contacts" which is the parent of all Contacts */ while( element && !isJournal ){ if( element->tagName() != QString::fromLatin1("Contacts") ){ - //qWarning ("OPimContactDefBack::Searching for Tag \"Contacts\"! Found: %s", - // element->tagName().latin1()); + //owarn << "OPimContactDefBack::Searching for Tag \"Contacts\"! Found: " + // << element->tagName() << oendl; element = element->nextChild(); } else { element = element->firstChild(); break; } } /* Parse all Contacts and ignore unknown tags */ while( element ){ if( element->tagName() != QString::fromLatin1("Contact") ){ - //qWarning ("OPimContactDefBack::Searching for Tag \"Contact\"! Found: %s", - // element->tagName().latin1()); + //owarn << "OPimContactDefBack::Searching for Tag \"Contact\"! Found: " + // << element->tagName() << oendl; element = element->nextChild(); continue; } /* Found alement with tagname "contact", now parse and store all * attributes contained */ - //qWarning("OPimContactDefBack::load element tagName() : %s", - // element->tagName().latin1() ); + //owarn << "OPimContactDefBack::load element tagName() : " + // << element->tagName() << oendl; QString dummy; foundAction = false; XMLElement::AttributeMap aMap = element->attributes(); XMLElement::AttributeMap::Iterator it; contactMap.clear(); customMap.clear(); for( it = aMap.begin(); it != aMap.end(); ++it ){ - // qWarning ("Read Attribute: %s=%s", it.key().latin1(),it.data().latin1()); + // owarn << "Read Attribute: " << it.key() << "=" << it.data() << oendl; int *find = dict[ it.key() ]; /* Unknown attributes will be stored as "Custom" elements */ if ( !find ) { // owarn << "Attribute " << it.key() << " not known." << oendl; //contact.setCustomField(it.key(), it.data()); customMap.insert( it.key(), it.data() ); continue; } /* Check if special conversion is needed and add attribute * into Contact class */ switch( *find ) { /* case Qtopia::AddressUid: contact.setUid( it.data().toInt() ); break; case Qtopia::AddressCategory: contact.setCategories( Qtopia::Record::idsFromString( it.data( ))); break; */ case JOURNALACTION: action = journal_action(it.data().toInt()); foundAction = true; - qWarning ("ODefBack(journal)::ACTION found: %d", action); + owarn << "ODefBack(journal)::ACTION found: " << action << oendl; break; case JOURNALROW: journalKey = it.data().toInt(); break; default: // no conversion needed add them to the map contactMap.insert( *find, it.data() ); break; } } /* now generate the Contact contact */ OPimContact contact( contactMap ); for (customIt = customMap.begin(); customIt != customMap.end(); ++customIt ) { contact.setCustomField( customIt.key(), customIt.data() ); } if (foundAction){ foundAction = false; switch ( action ) { case ACTION_ADD: addContact_p (contact); break; case ACTION_REMOVE: if ( !remove (contact.uid()) ) - qWarning ("ODefBack(journal)::Unable to remove uid: %d", - contact.uid() ); + owarn << "ODefBack(journal)::Unable to remove uid: " << contact.uid() << oendl; break; case ACTION_REPLACE: if ( !replace ( contact ) ) - qWarning ("ODefBack(journal)::Unable to replace uid: %d", - contact.uid() ); + owarn << "ODefBack(journal)::Unable to replace uid: " << contact.uid() << oendl; break; default: - qWarning ("Unknown action: ignored !"); + owarn << "Unknown action: ignored !" << oendl; break; } }else{ /* Add contact to list */ addContact_p (contact); } /* Move to next element */ element = element->nextChild(); } }else { owarn << "ODefBack::could not load" << oendl; } delete root; owarn << "returning from loading" << oendl; return true; } void OPimContactAccessBackend_XML::updateJournal( const OPimContact& cnt, journal_action action ) { QFile f( m_journalName ); bool created = !f.exists(); if ( !f.open(IO_WriteOnly|IO_Append) ) return; QString buf; QCString str; // if the file was created, we have to set the Tag "<CONTACTS>" to // get a XML-File which is readable by our parser. // This is just a cheat, but better than rewrite the parser. if ( created ){ buf = "<Contacts>"; QCString cstr = buf.utf8(); f.writeBlock( cstr.data(), cstr.length() ); } buf = "<Contact "; cnt.save( buf ); buf += " action=\"" + QString::number( (int)action ) + "\" "; buf += "/>\n"; QCString cstr = buf.utf8(); f.writeBlock( cstr.data(), cstr.length() ); } void OPimContactAccessBackend_XML::removeJournal() { QFile f ( m_journalName ); if ( f.exists() ) f.remove(); } } diff --git a/libopie2/opiepim/core/ocontactaccess.cpp b/libopie2/opiepim/core/ocontactaccess.cpp index a372267..7a3d7cb 100644 --- a/libopie2/opiepim/core/ocontactaccess.cpp +++ b/libopie2/opiepim/core/ocontactaccess.cpp @@ -1,159 +1,164 @@ /* This file is part of the Opie Project Copyright (C) The Main Author <main-author@whereever.org> =. Copyright (C) The Opie Team <opie-devel@handhelds.org> .=l. .>+-= _;:, .> :=|. This program is free software; you can .> <`_, > . <= redistribute it and/or modify it under :`=1 )Y*s>-.-- : the terms of the GNU Library General Public .="- .-=="i, .._ License as published by the Free Software - . .-<_> .<> Foundation; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+i> _;_. .i_,=:_. -<s. This program is distributed in the hope that + . -:. = it will be useful, but WITHOUT ANY WARRANTY; : .. .:, . . . without even the implied warranty of =_ + =;=|` MERCHANTABILITY or FITNESS FOR A _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU ..}^=.= = ; Library General Public License for more ++= -. .` .: details. : = ...= . :.=- -. .:....=;==+<; You should have received a copy of the GNU -_. . . )=. = Library General Public License along with -- :-=` this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* * ===================================================================== * ToDo: XML-Backend: Automatic reload if something was changed... * * */ #include "ocontactaccess.h" #include "obackendfactory.h" +/* OPIE */ +#include <opie2/ocontactaccessbackend_xml.h> +#include <opie2/opimresolver.h> +#include <opie2/opimglobal.h> +#include <opie2/odebug.h> + +//#include <qpe/qcopenvelope_qws.h> +#include <qpe/global.h> + +/* QT */ #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> - +/* STD */ #include <errno.h> #include <fcntl.h> #include <unistd.h> #include <stdlib.h> -#include <opie2/ocontactaccessbackend_xml.h> -#include <opie2/opimresolver.h> -#include <opie2/opimglobal.h> namespace Opie { OPimContactAccess::OPimContactAccess ( const QString appname, const QString , OPimContactAccessBackend* end, bool autosync ): OPimAccessTemplate<OPimContact>( end ) { /* 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 ) { - qWarning ("Using BackendFactory !"); + owarn << "Using BackendFactory !" << oendl; end = OBackendFactory<OPimContactAccessBackend>::defaultBackend( OPimGlobal::CONTACTLIST, appname ); } // Set backend locally and in template m_backEnd = end; OPimAccessTemplate<OPimContact>::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&)) ); } } OPimContactAccess::~OPimContactAccess () { /* The user may forget to save the changed database, therefore try to * do it for him.. */ save(); // delete m_backEnd; is done by template.. } bool OPimContactAccess::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 ( OPimAccessTemplate<OPimContact>::wasChangedExternally() ) reload(); bool status = OPimAccessTemplate<OPimContact>::save(); if ( !status ) return false; /* Now tell everyone that new data is available. */ QCopEnvelope e( "QPE/PIM", "addressbookUpdated()" ); return true; } const uint OPimContactAccess::querySettings() { return ( m_backEnd->querySettings() ); } bool OPimContactAccess::hasQuerySettings ( int querySettings ) const { return ( m_backEnd->hasQuerySettings ( querySettings ) ); } OPimRecordList<OPimContact> OPimContactAccess::sorted( bool ascending, int sortOrder, int sortFilter, int cat ) const { QArray<int> matchingContacts = m_backEnd -> sorted( ascending, sortOrder, sortFilter, cat ); return ( OPimRecordList<OPimContact>(matchingContacts, this) ); } bool OPimContactAccess::wasChangedExternally()const { return ( m_backEnd->wasChangedExternally() ); } void OPimContactAccess::copMessage( const QCString &msg, const QByteArray & ) { if ( msg == "addressbookUpdated()" ){ - qWarning ("OPimContactAccess: Received addressbokUpdated()"); + owarn << "OPimContactAccess: Received addressbokUpdated()" << oendl; emit signalChanged ( this ); } else if ( msg == "flush()" ) { - qWarning ("OPimContactAccess: Received flush()"); + owarn << "OPimContactAccess: Received flush()" << oendl; save (); } else if ( msg == "reload()" ) { - qWarning ("OPimContactAccess: Received reload()"); + owarn << "OPimContactAccess: Received reload()" << oendl; reload (); emit signalChanged ( this ); } } int OPimContactAccess::rtti() const { return OPimResolver::AddressBook; } } diff --git a/libopie2/opiepim/core/opimaccesstemplate.h b/libopie2/opiepim/core/opimaccesstemplate.h index e438980..55d600a 100644 --- a/libopie2/opiepim/core/opimaccesstemplate.h +++ b/libopie2/opiepim/core/opimaccesstemplate.h @@ -1,357 +1,360 @@ /* 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 -#include <qarray.h> - +/* OPIE */ #include <opie2/opimrecord.h> #include <opie2/opimaccessbackend.h> #include <opie2/opimrecordlist.h> #include <opie2/opimcache.h> #include <opie2/opimtemplatebase.h> +#include <opie2/odebug.h> + +/* QT */ +#include <qarray.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; /** * c'tor BackEnd * enum Access a small hint on how to handle the backend */ OPimAccessTemplate( BackEnd* end); virtual ~OPimAccessTemplate(); /** * load from the backend */ 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. */ virtual 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(); /** * 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 ? */ bool wasChangedExternally()const; /** * return a List of records * you can iterate over them */ virtual List allRecords()const; /** * return a List of records * that match the regex */ virtual List matchRegexp( const QRegExp &r ) const; /** * queryByExample. * @see otodoaccess, ocontactaccess */ virtual List queryByExample( const T& t, int querySettings, const QDateTime& d = QDateTime() ); /** * 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, typename OTemplateBase<T>::CacheDirection dir = OTemplateBase<T>::Forward )const; /* invalidate cache here */ /** * clears the backend and invalidates the backend */ void clear() ; /** * add T to the backend * @param t The item to add. * @return <i>true</i> if added successfully. */ virtual bool add( const T& t ) ; bool add( const OPimRecord& ); // Needed for real generic access (eilers) // Info: Take this if you are working with OPimRecord, which is a generic base class, and // you need to add it into any database, you cannot generate a reference to // it and casting may be not approriate, too. // But take care that the accessing database is compatible to the real type of OPimRecord !! bool add( const OPimRecord* ); /* only the uid matters */ /** * remove T from the backend * @param t The item to remove * @return <i>true</i> if successful. */ virtual bool remove( const T& t ); /** * remove the OPimRecord with uid * @param uid The ID of the item to remove * @return <i>true</i> if successful. */ bool remove( int uid ); bool remove( const OPimRecord& ); /** * replace T from backend * @param t The item to replace * @return <i>true</i> if successful. */ virtual bool replace( const T& t) ; void setReadAhead( uint count ); /** * @internal */ void cache( const T& )const; void setSaneCacheSize( int ); QArray<int> 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; }; 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>"); + owarn << "~OPimAccessTemplate<T>" << oendl; delete m_backEnd; } template <class T> bool OPimAccessTemplate<T>::load() { invalidateCache(); return m_backEnd->load(); } template <class T> bool OPimAccessTemplate<T>::reload() { invalidateCache(); // zecke: I think this should be added (se) return m_backEnd->reload(); } template <class T> bool OPimAccessTemplate<T>::save() { return m_backEnd->save(); } 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> typename OPimAccessTemplate<T>::List OPimAccessTemplate<T>::matchRegexp( const QRegExp &r )const { QArray<int> ints = m_backEnd->matchRegexp( r ); 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 settings, const QDateTime& d ) { QArray<int> ints = m_backEnd->queryByExample( t, settings, d ); List lis(ints, this ); return lis; } template <class T> T OPimAccessTemplate<T>::find( int uid ) const{ T t = m_backEnd->find( uid ); cache( t ); return t; } template <class T> T OPimAccessTemplate<T>::find( int 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... */ - // qWarning("find it now %d", uid ); + // owarn << "find it now " << uid << oendl; if (m_cache.contains( uid ) ) { return m_cache.find( uid ); } T t = m_backEnd->find( uid, ar, current, dir ); cache( t ); return t; } template <class T> void OPimAccessTemplate<T>::clear() { invalidateCache(); m_backEnd->clear(); } 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); } return false; } 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 ); } return false; } template <class T> bool OPimAccessTemplate<T>::remove( const T& t ) { return remove( t.uid() ); } 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() { m_cache.invalidate(); } template <class T> typename OPimAccessTemplate<T>::BackEnd* OPimAccessTemplate<T>::backEnd() { return m_backEnd; } template <class T> bool OPimAccessTemplate<T>::wasChangedExternally()const { return false; } template <class T> void OPimAccessTemplate<T>::setBackEnd( BackEnd* end ) { m_backEnd = end; if (m_backEnd ) m_backEnd->setFrontend( this ); } template <class T> void OPimAccessTemplate<T>::cache( const T& t ) const{ /* hacky we need to work around the const*/ ((OPimAccessTemplate<T>*)this)->m_cache.add( t ); } template <class T> void OPimAccessTemplate<T>::setSaneCacheSize( int size ) { m_cache.setSize( size ); } template <class T> void OPimAccessTemplate<T>::setReadAhead( uint count ) { m_backEnd->setReadAhead( count ); } } #endif diff --git a/libopie2/opiepim/core/opimcontact.cpp b/libopie2/opiepim/core/opimcontact.cpp index 48a74d0..36e9a93 100644 --- a/libopie2/opiepim/core/opimcontact.cpp +++ b/libopie2/opiepim/core/opimcontact.cpp @@ -920,372 +920,372 @@ QStringList OPimContact::childrenList() const /*! \fn void OPimContact::insertEmails( const QStringList &emailList ) Appends the \a emailList to the exiting email list */ /*! Returns a list of email addresses belonging to the contact, including the default email address. */ QStringList OPimContact::emailList() const { QString emailStr = emails(); QStringList r; if ( !emailStr.isEmpty() ) { odebug << " emailstr " << oendl; QStringList l = QStringList::split( emailSeparator(), emailStr ); for ( QStringList::ConstIterator it = l.begin();it != l.end();++it ) r += ( *it ).simplifyWhiteSpace(); } return r; } /*! \overload Generates the string for the contact to be filed as from the first, middle and last name of the contact. */ void OPimContact::setFileAs() { QString lastName, firstName, middleName, fileas; lastName = find( Qtopia::LastName ); firstName = find( Qtopia::FirstName ); middleName = find( Qtopia::MiddleName ); if ( !lastName.isEmpty() && !firstName.isEmpty() && !middleName.isEmpty() ) fileas = lastName + ", " + firstName + " " + middleName; else if ( !lastName.isEmpty() && !firstName.isEmpty() ) fileas = lastName + ", " + firstName; else if ( !lastName.isEmpty() || !firstName.isEmpty() || !middleName.isEmpty() ) fileas = firstName + ( firstName.isEmpty() ? "" : " " ) + middleName + ( middleName.isEmpty() ? "" : " " ) + lastName; replace( Qtopia::FileAs, fileas ); } /*! \internal Appends the contact information to \a buf. */ void OPimContact::save( QString &buf ) const { static const QStringList SLFIELDS = fields(); // I'm expecting "<Contact " in front of this... for ( QMap<int, QString>::ConstIterator it = mMap.begin(); it != mMap.end(); ++it ) { const QString &value = it.data(); int key = it.key(); if ( !value.isEmpty() ) { if ( key == Qtopia::AddressCategory || key == Qtopia::AddressUid ) continue; key -= Qtopia::AddressCategory + 1; buf += SLFIELDS[ key ]; buf += "=\"" + Qtopia::escapeString( value ) + "\" "; } } buf += customToXml(); if ( categories().count() > 0 ) buf += "Categories=\"" + idsToString( categories() ) + "\" "; buf += "Uid=\"" + QString::number( uid() ) + "\" "; // You need to close this yourself } /*! \internal Returns the list of fields belonging to a contact Never change order of this list ! It has to be regarding enum AddressBookFields !! */ QStringList OPimContact::fields() { QStringList list; list.append( "Title" ); // Not Used! list.append( "FirstName" ); list.append( "MiddleName" ); list.append( "LastName" ); list.append( "Suffix" ); list.append( "FileAs" ); list.append( "JobTitle" ); list.append( "Department" ); list.append( "Company" ); list.append( "BusinessPhone" ); list.append( "BusinessFax" ); list.append( "BusinessMobile" ); list.append( "DefaultEmail" ); list.append( "Emails" ); list.append( "HomePhone" ); list.append( "HomeFax" ); list.append( "HomeMobile" ); list.append( "BusinessStreet" ); list.append( "BusinessCity" ); list.append( "BusinessState" ); list.append( "BusinessZip" ); list.append( "BusinessCountry" ); list.append( "BusinessPager" ); list.append( "BusinessWebPage" ); list.append( "Office" ); list.append( "Profession" ); list.append( "Assistant" ); list.append( "Manager" ); list.append( "HomeStreet" ); list.append( "HomeCity" ); list.append( "HomeState" ); list.append( "HomeZip" ); list.append( "HomeCountry" ); list.append( "HomeWebPage" ); list.append( "Spouse" ); list.append( "Gender" ); list.append( "Birthday" ); list.append( "Anniversary" ); list.append( "Nickname" ); list.append( "Children" ); list.append( "Notes" ); list.append( "Groups" ); return list; } /*! Sets the list of email address for contact to those contained in \a str. Email address should be separated by ';'s. */ void OPimContact::setEmails( const QString &str ) { replace( Qtopia::Emails, str ); if ( str.isEmpty() ) setDefaultEmail( QString::null ); } /*! Sets the list of children for the contact to those contained in \a str. */ void OPimContact::setChildren( const QString &str ) { replace( Qtopia::Children, str ); } /*! \overload Returns TRUE if the contact matches the regular expression \a regexp. Otherwise returns FALSE. */ bool OPimContact::match( const QRegExp &r ) const { setLastHitField( -1 ); bool match; match = false; QMap<int, QString>::ConstIterator it; for ( it = mMap.begin(); it != mMap.end(); ++it ) { if ( ( *it ).find( r ) > -1 ) { setLastHitField( it.key() ); match = true; break; } } return match; } QString OPimContact::toShortText() const { return ( fullName() ); } QString OPimContact::type() const { return QString::fromLatin1( "OPimContact" ); } class QString OPimContact::recordField( int pos ) const { QStringList SLFIELDS = fields(); // ?? why this ? (se) return SLFIELDS[ pos ]; } // In future releases, we should store birthday and anniversary // internally as QDate instead of QString ! // QString is always too complicate to interprete (DD.MM.YY, DD/MM/YY, MM/DD/YY, etc..)(se) /*! \fn void OPimContact::setBirthday( const QDate& date ) Sets the birthday for the contact to \a date. If date is null the current stored date will be removed. */ void OPimContact::setBirthday( const QDate &v ) { if ( v.isNull() ) { owarn << "Remove Birthday" << oendl; replace( Qtopia::Birthday, QString::null ); return ; } if ( v.isValid() ) replace( Qtopia::Birthday, OPimDateConversion::dateToString( v ) ); } /*! \fn void OPimContact::setAnniversary( const QDate &date ) Sets the anniversary of the contact to \a date. If date is null, the current stored date will be removed. */ void OPimContact::setAnniversary( const QDate &v ) { if ( v.isNull() ) { owarn << "Remove Anniversary" << oendl; replace( Qtopia::Anniversary, QString::null ); return ; } if ( v.isValid() ) replace( Qtopia::Anniversary, OPimDateConversion::dateToString( v ) ); } /*! \fn QDate OPimContact::birthday() const Returns the birthday of the contact. */ QDate OPimContact::birthday() const { QString str = find( Qtopia::Birthday ); - // qWarning ("Birthday %s", str.latin1() ); + // owarn << "Birthday " << str << oendl; if ( !str.isEmpty() ) return OPimDateConversion::dateFromString ( str ); else return QDate(); } /*! \fn QDate OPimContact::anniversary() const Returns the anniversary of the contact. */ QDate OPimContact::anniversary() const { QDate empty; QString str = find( Qtopia::Anniversary ); - // qWarning ("Anniversary %s", str.latin1() ); + // owarn << "Anniversary " << str << oendl; if ( !str.isEmpty() ) return OPimDateConversion::dateFromString ( str ); else return empty; } void OPimContact::insertEmail( const QString &v ) { //odebug << "insertEmail " << v << "" << oendl; QString e = v.simplifyWhiteSpace(); QString def = defaultEmail(); // if no default, set it as the default email and don't insert if ( def.isEmpty() ) { setDefaultEmail( e ); // will insert into the list for us return ; } // otherwise, insert assuming doesn't already exist QString emailsStr = find( Qtopia::Emails ); if ( emailsStr.contains( e ) ) return ; if ( !emailsStr.isEmpty() ) emailsStr += emailSeparator(); emailsStr += e; replace( Qtopia::Emails, emailsStr ); } void OPimContact::removeEmail( const QString &v ) { QString e = v.simplifyWhiteSpace(); QString def = defaultEmail(); QString emailsStr = find( Qtopia::Emails ); QStringList emails = emailList(); // otherwise, must first contain it if ( !emailsStr.contains( e ) ) return ; // remove it //odebug << " removing email from list " << e << "" << oendl; emails.remove( e ); // reset the string emailsStr = emails.join( emailSeparator() ); // Sharp's brain dead separator replace( Qtopia::Emails, emailsStr ); // if default, then replace the default email with the first one if ( def == e ) { //odebug << "removeEmail is default; setting new default" << oendl; if ( !emails.count() ) clearEmails(); else // setDefaultEmail will remove e from the list setDefaultEmail( emails.first() ); } } void OPimContact::clearEmails() { mMap.remove( Qtopia::DefaultEmail ); mMap.remove( Qtopia::Emails ); } void OPimContact::setDefaultEmail( const QString &v ) { QString e = v.simplifyWhiteSpace(); //odebug << "OPimContact::setDefaultEmail " << e << "" << oendl; replace( Qtopia::DefaultEmail, e ); if ( !e.isEmpty() ) insertEmail( e ); } void OPimContact::insertEmails( const QStringList &v ) { for ( QStringList::ConstIterator it = v.begin(); it != v.end(); ++it ) insertEmail( *it ); } int OPimContact::rtti() const { return OPimResolver::AddressBook; } void OPimContact::setUid( int i ) { OPimRecord::setUid( i ); replace( Qtopia::AddressUid , QString::number( i ) ); } } diff --git a/libopie2/opiepim/core/opimnotifymanager.cpp b/libopie2/opiepim/core/opimnotifymanager.cpp index 0f863aa..516dc79 100644 --- a/libopie2/opiepim/core/opimnotifymanager.cpp +++ b/libopie2/opiepim/core/opimnotifymanager.cpp @@ -1,250 +1,250 @@ /* This file is part of the Opie Project Copyright (C) The Main Author <main-author@whereever.org> =. Copyright (C) The Opie Team <opie-devel@handhelds.org> .=l. .>+-= _;:, .> :=|. This program is free software; you can .> <`_, > . <= redistribute it and/or modify it under :`=1 )Y*s>-.-- : the terms of the GNU Library General Public .="- .-=="i, .._ License as published by the Free Software - . .-<_> .<> Foundation; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+i> _;_. .i_,=:_. -<s. This program is distributed in the hope that + . -:. = it will be useful, but WITHOUT ANY WARRANTY; : .. .:, . . . without even the implied warranty of =_ + =;=|` MERCHANTABILITY or FITNESS FOR A _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU ..}^=.= = ; Library General Public License for more ++= -. .` .: details. : = ...= . :.=- -. .:....=;==+<; You should have received a copy of the GNU -_. . . )=. = Library General Public License along with -- :-=` this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "opimnotifymanager.h" /* OPIE */ #include <opie2/opimdateconversion.h> #include <opie2/odebug.h> /* QT */ #include <qstringlist.h> namespace Opie { OPimNotifyManager::OPimNotifyManager( const Reminders& rem, const Alarms& al ) : m_rem( rem ), m_al( al ) {} OPimNotifyManager::~OPimNotifyManager() {} /* use static_cast and type instead of dynamic... */ void OPimNotifyManager::add( const OPimNotify& noti ) { if ( noti.type() == QString::fromLatin1( "OPimReminder" ) ) { const OPimReminder & rem = static_cast<const OPimReminder&>( noti ); m_rem.append( rem ); } else if ( noti.type() == QString::fromLatin1( "OPimAlarm" ) ) { const OPimAlarm & al = static_cast<const OPimAlarm&>( noti ); m_al.append( al ); } } void OPimNotifyManager::remove( const OPimNotify& noti ) { if ( noti.type() == QString::fromLatin1( "OPimReminder" ) ) { const OPimReminder & rem = static_cast<const OPimReminder&>( noti ); m_rem.remove( rem ); } else if ( noti.type() == QString::fromLatin1( "OPimAlarm" ) ) { const OPimAlarm & al = static_cast<const OPimAlarm&>( noti ); m_al.remove( al ); } } void OPimNotifyManager::replace( const OPimNotify& noti ) { if ( noti.type() == QString::fromLatin1( "OPimReminder" ) ) { const OPimReminder & rem = static_cast<const OPimReminder&>( noti ); m_rem.remove( rem ); m_rem.append( rem ); } else if ( noti.type() == QString::fromLatin1( "OPimAlarm" ) ) { const OPimAlarm & al = static_cast<const OPimAlarm&>( noti ); m_al.remove( al ); m_al.append( al ); } } OPimNotifyManager::Reminders OPimNotifyManager::reminders() const { return m_rem; } OPimNotifyManager::Alarms OPimNotifyManager::alarms() const { return m_al; } OPimAlarm OPimNotifyManager::alarmAtDateTime( const QDateTime& when, bool& found ) const { Alarms::ConstIterator it; found = true; for ( it = m_al.begin(); it != m_al.end(); ++it ) { if ( ( *it ).dateTime() == when ) return ( *it ); } // Fall through if nothing could be found found = false; OPimAlarm empty; return empty; } void OPimNotifyManager::setAlarms( const Alarms& al ) { m_al = al; } void OPimNotifyManager::setReminders( const Reminders& rem ) { m_rem = rem; } /* FIXME!!! */ /** * The idea is to check if the provider for our service * is online * if it is we will use QCOP * if not the Factory to get the backend... * Qtopia1.6 services would be kewl to have here.... */ void OPimNotifyManager::registerNotify( const OPimNotify& ) { } /* FIXME!!! */ /** * same as above... * Also implement Url model * have a MainWindow.... */ void OPimNotifyManager::deregister( const OPimNotify& ) { } bool OPimNotifyManager::isEmpty() const { owarn << "is Empty called on OPimNotifyManager " << m_rem.count() << " " << m_al.count() << "" << oendl; if ( m_rem.isEmpty() && m_al.isEmpty() ) return true; else return false; } // Taken from otodoaccessxml.. code duplication bad. any alternative? QString OPimNotifyManager::alarmsToString() const { QString str; OPimNotifyManager::Alarms alarms = m_al; if ( !alarms.isEmpty() ) { QStringList als; OPimNotifyManager::Alarms::Iterator it = alarms.begin(); for ( ; it != alarms.end(); ++it ) { /* only if time is valid */ if ( ( *it ).dateTime().isValid() ) { als << OPimDateConversion::dateTimeToString( ( *it ).dateTime() ) + ":" + QString::number( ( *it ).duration() ) + ":" + QString::number( ( *it ).sound() ) + ":"; } } // now write the list owarn << "als: " << als.join( "____________" ) << "" << oendl; str = als.join( ";" ); } return str; } QString OPimNotifyManager::remindersToString() const { QString str; OPimNotifyManager::Reminders reminders = m_rem; if ( !reminders.isEmpty() ) { OPimNotifyManager::Reminders::Iterator it = reminders.begin(); QStringList records; for ( ; it != reminders.end(); ++it ) { records << QString::number( ( *it ).recordUid() ); } str = records.join( ";" ); } return str; } void OPimNotifyManager::alarmsFromString( const QString& str ) { QStringList als = QStringList::split( ";", str ); for ( QStringList::Iterator it = als.begin(); it != als.end(); ++it ) { QStringList alarm = QStringList::split( ":", ( *it ), TRUE ); // allow empty owarn << "alarm: " << alarm.join( "___" ) << "" << oendl; - qWarning( "alarm[0]: %s %s", alarm[ 0 ].latin1(), - OPimDateConversion::dateTimeFromString( alarm[ 0 ] ).toString().latin1() ); + owarn << "alarm[0]: " << alarm[ 0 ] << " " + << OPimDateConversion::dateTimeFromString( alarm[ 0 ] ).toString() << oendl; OPimAlarm al( alarm[ 2 ].toInt(), OPimDateConversion::dateTimeFromString( alarm[ 0 ] ), alarm[ 1 ].toInt() ); add( al ); } } void OPimNotifyManager::remindersFromString( const QString& str ) { QStringList rems = QStringList::split( ";", str ); for ( QStringList::Iterator it = rems.begin(); it != rems.end(); ++it ) { OPimReminder rem( ( *it ).toInt() ); add( rem ); } } } diff --git a/libopie2/opiepim/core/opimrecordlist.h b/libopie2/opiepim/core/opimrecordlist.h index b23138d..1d5027f 100644 --- a/libopie2/opiepim/core/opimrecordlist.h +++ b/libopie2/opiepim/core/opimrecordlist.h @@ -1,402 +1,403 @@ /* This file is part of the Opie Project Copyright (C) The Main Author <main-author@whereever.org> =. Copyright (C) The Opie Team <opie-devel@handhelds.org> .=l. .>+-= _;:, .> :=|. This program is free software; you can .> <`_, > . <= redistribute it and/or modify it under :`=1 )Y*s>-.-- : the terms of the GNU Library General Public .="- .-=="i, .._ License as published by the Free Software - . .-<_> .<> Foundation; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+i> _;_. .i_,=:_. -<s. This program is distributed in the hope that + . -:. = it will be useful, but WITHOUT ANY WARRANTY; : .. .:, . . . without even the implied warranty of =_ + =;=|` MERCHANTABILITY or FITNESS FOR A _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU ..}^=.= = ; Library General Public License for more ++= -. .` .: details. : = ...= . :.=- -. .:....=;==+<; You should have received a copy of the GNU -_. . . )=. = Library General Public License along with -- :-=` this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef ORECORDLIST_H #define ORECORDLIST_H /* OPIE */ #include <opie2/opimtemplatebase.h> #include <opie2/opimrecord.h> +//#include <opie2/odebug.h> /* QT */ #include <qarray.h> namespace Opie { class OPimRecordListIteratorPrivate; /** * Our List Iterator * it behaves like STL or Qt * * for(it = list.begin(); it != list.end(); ++it ) * doSomeCoolStuff( (*it) ); */ template <class T> class OPimRecordList; template <class T = OPimRecord> class OPimRecordListIterator { friend class OPimRecordList<T>; public: typedef OTemplateBase<T> Base; /** * The c'tor used internally from * OPimRecordList */ OPimRecordListIterator( const QArray<int>, const Base* ); /** * The standard c'tor */ OPimRecordListIterator(); ~OPimRecordListIterator(); OPimRecordListIterator( const OPimRecordListIterator& ); OPimRecordListIterator &operator=( const OPimRecordListIterator& ); /** * a * operator ;) * use it like this T = (*it); */ T operator*(); OPimRecordListIterator &operator++(); OPimRecordListIterator &operator--(); bool operator==( const OPimRecordListIterator& it ); bool operator!=( const OPimRecordListIterator& it ); /** * the current item */ uint current() const; /** * the number of items */ uint count() const; /** * sets the current item */ void setCurrent( uint cur ); private: QArray<int> m_uids; uint m_current; const Base* m_temp; bool m_end : 1; T m_record; bool m_direction : 1; /* d pointer for future versions */ OPimRecordListIteratorPrivate *d; }; class OPimRecordListPrivate; /** * The recordlist used as a return type * from OPimAccessTemplate */ template <class T = OPimRecord > class OPimRecordList { public: typedef OTemplateBase<T> Base; typedef OPimRecordListIterator<T> Iterator; /** * c'tor */ OPimRecordList () {} OPimRecordList( const QArray<int>& ids, const Base* ); ~OPimRecordList(); /** * the first iterator */ Iterator begin(); /** * the end */ Iterator end(); /** * the number of items in the list */ uint count() const; T operator[] ( uint i ); int uidAt( uint i ); /** * Remove the contact with given uid */ bool remove( int uid ); /* ConstIterator begin()const; ConstIterator end()const; */ private: QArray<int> m_ids; const Base* m_acc; OPimRecordListPrivate *d; }; /* ok now implement it */ template <class T> OPimRecordListIterator<T>::OPimRecordListIterator() { m_current = 0; m_temp = 0l; m_end = true; m_record = T(); /* forward */ m_direction = TRUE; } template <class T> OPimRecordListIterator<T>::~OPimRecordListIterator() { /* nothing to delete */ } template <class T> OPimRecordListIterator<T>::OPimRecordListIterator( const OPimRecordListIterator<T>& it ) { - // qWarning("OPimRecordListIterator copy c'tor"); + //owarn << "OPimRecordListIterator copy c'tor" << oendl; m_uids = it.m_uids; m_current = it.m_current; m_temp = it.m_temp; m_end = it.m_end; m_record = it.m_record; m_direction = it.m_direction; } template <class T> OPimRecordListIterator<T> &OPimRecordListIterator<T>::operator=( const OPimRecordListIterator<T>& it ) { m_uids = it.m_uids; m_current = it.m_current; m_temp = it.m_temp; m_end = it.m_end; m_record = it.m_record; return *this; } template <class T> T OPimRecordListIterator<T>::operator*() { - //qWarning("operator* %d %d", m_current, m_uids[m_current] ); + //owarn << "operator* " << m_current << " " << m_uids[m_current] << oendl; if ( !m_end ) m_record = m_temp->find( m_uids[ m_current ], m_uids, m_current, m_direction ? Base::Forward : Base::Reverse ); else m_record = T(); return m_record; } template <class T> OPimRecordListIterator<T> &OPimRecordListIterator<T>::operator++() { m_direction = true; if ( m_current < m_uids.count() ) { m_end = false; ++m_current; } else m_end = true; return *this; } template <class T> OPimRecordListIterator<T> &OPimRecordListIterator<T>::operator--() { m_direction = false; if ( m_current > 0 ) { --m_current; m_end = false; } else m_end = true; return *this; } template <class T> bool OPimRecordListIterator<T>::operator==( const OPimRecordListIterator<T>& it ) { /* if both are at we're the same.... */ if ( m_end == it.m_end ) return true; if ( m_uids != it.m_uids ) return false; if ( m_current != it.m_current ) return false; if ( m_temp != it.m_temp ) return false; return true; } template <class T> bool OPimRecordListIterator<T>::operator!=( const OPimRecordListIterator<T>& it ) { return !( *this == it ); } template <class T> OPimRecordListIterator<T>::OPimRecordListIterator( const QArray<int> uids, const Base* t ) : m_uids( uids ), m_current( 0 ), m_temp( t ), m_end( false ), m_direction( false ) { /* if the list is empty we're already at the end of the list */ if ( uids.count() == 0 ) m_end = true; } template <class T> uint OPimRecordListIterator<T>::current() const { return m_current; } template <class T> void OPimRecordListIterator<T>::setCurrent( uint cur ) { if ( cur < m_uids.count() ) { m_end = false; m_current = cur; } } template <class T> uint OPimRecordListIterator<T>::count() const { return m_uids.count(); } template <class T> OPimRecordList<T>::OPimRecordList( const QArray<int>& ids, const Base* acc ) : m_ids( ids ), m_acc( acc ) {} template <class T> OPimRecordList<T>::~OPimRecordList() { /* nothing to do here */ } template <class T> typename OPimRecordList<T>::Iterator OPimRecordList<T>::begin() { Iterator it( m_ids, m_acc ); return it; } template <class T> typename OPimRecordList<T>::Iterator OPimRecordList<T>::end() { Iterator it( m_ids, m_acc ); it.m_end = true; it.m_current = m_ids.count(); return it; } template <class T> uint OPimRecordList<T>::count() const { return m_ids.count(); } template <class T> T OPimRecordList<T>::operator[] ( uint i ) { if ( i >= m_ids.count() ) return T(); /* forward */ return m_acc->find( m_ids[ i ], m_ids, i ); } template <class T> int OPimRecordList<T>::uidAt( uint i ) { return m_ids[ i ]; } template <class T> bool OPimRecordList<T>::remove( int uid ) { QArray<int> copy( m_ids.count() ); int counter = 0; bool ret_val = false; for ( uint i = 0; i < m_ids.count(); i++ ) { if ( m_ids[ i ] != uid ) { copy[ counter++ ] = m_ids[ i ]; } else ret_val = true; } copy.resize( counter ); m_ids = copy; return ret_val; } } #endif |