-rw-r--r-- | libopie2/opiepim/backend/obackendfactory.h | 242 | ||||
-rw-r--r-- | libopie2/opiepim/backend/ocontactaccessbackend_xml.cpp | 36 | ||||
-rw-r--r-- | libopie2/opiepim/core/ocontactaccess.cpp | 117 | ||||
-rw-r--r-- | libopie2/opiepim/core/opimaccesstemplate.h | 17 | ||||
-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, 218 insertions, 207 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() {}; + OBackendFactory() {}; /** * Returns a selected backend implementation * @param type the type of the backend - * @param database the type of the used database + * @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() + * @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 ); - // 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: + static T* create( OPimGlobal::PimType type, OPimGlobal::DatabaseStyle database, + const QString& appName, const QString& filename = QString::null ){ + 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; + return (T*) new OPimTodoAccessBackendSQL( filename ); + break; #else - qWarning ("OBackendFactory:: sql Backend for TODO not implemented! Using XML instead!"); - // Fall through !! + 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: + 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; + return (T*) new OPimContactAccessBackend_SQL( appName, filename ); + break; #else - qWarning ("OBackendFactory:: sql Backend for CONTACT not implemented! Using XML instead!"); - // Fall through !! + 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: + 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; + return (T*) new ODateBookAccessBackend_SQL( appName, filename ); + break; #else - qWarning("OBackendFactory:: sql Backend for DATEBOOK not implemented! Using XML instead!"); - // Fall through !! + 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!"); - return (T*) NULL; - break; - } - default: - return (T*) NULL; - } - - } - - /** - * Returns the style of the default database which is used to contact PIM data. + case OPimGlobal::XML: + return (T*) new ODateBookAccessBackend_XML( appName, filename ); + break; + case OPimGlobal::VCARD: + 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; - } + * @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". + * 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() + * @see OPimGlobal() */ - static T* defaultBackend( OPimGlobal::PimType type, const QString& appName ){ - return create( type, OPimGlobal::DEFAULT, appName ); - } + static T* defaultBackend( OPimGlobal::PimType type, const QString& appName ){ + return create( type, OPimGlobal::DEFAULT, appName ); + } private: - OBackendPrivate* d; + 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 ) + 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..). - */ + * will use the XML-Backend as default (until we have a cute SQL-Backend..). + */ if( end == 0 ) { - qWarning ("Using BackendFactory !"); - end = OBackendFactory<OPimContactAccessBackend>::defaultBackend( OPimGlobal::CONTACTLIST, appname ); + owarn << "Using BackendFactory !" << oendl; + end = OBackendFactory<OPimContactAccessBackend>::defaultBackend( OPimGlobal::CONTACTLIST, appname ); } - // Set backend locally and in template + // Set backend locally and in template m_backEnd = end; - OPimAccessTemplate<OPimContact>::setBackEnd (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&)), + /* 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&)) ); - } + 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.. + /* 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(); + /* 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; + bool status = OPimAccessTemplate<OPimContact>::save(); + if ( !status ) return false; - /* Now tell everyone that new data is available. - */ - QCopEnvelope e( "QPE/PIM", "addressbookUpdated()" ); + /* Now tell everyone that new data is available. + */ + QCopEnvelope e( "QPE/PIM", "addressbookUpdated()" ); - return true; + return true; } const uint OPimContactAccess::querySettings() { - return ( m_backEnd->querySettings() ); + return ( m_backEnd->querySettings() ); } bool OPimContactAccess::hasQuerySettings ( int querySettings ) const { - return ( m_backEnd->hasQuerySettings ( querySettings ) ); + 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) ); + QArray<int> matchingContacts = m_backEnd -> sorted( ascending, sortOrder, sortFilter, cat ); + return ( OPimRecordList<OPimContact>(matchingContacts, this) ); } bool OPimContactAccess::wasChangedExternally()const { - return ( m_backEnd->wasChangedExternally() ); + return ( m_backEnd->wasChangedExternally() ); } void OPimContactAccess::copMessage( const QCString &msg, const QByteArray & ) { - if ( msg == "addressbookUpdated()" ){ - qWarning ("OPimContactAccess: Received addressbokUpdated()"); - emit signalChanged ( this ); - } else if ( msg == "flush()" ) { - qWarning ("OPimContactAccess: Received flush()"); - save (); - } else if ( msg == "reload()" ) { - qWarning ("OPimContactAccess: Received reload()"); - reload (); - emit signalChanged ( this ); - } + if ( msg == "addressbookUpdated()" ){ + owarn << "OPimContactAccess: Received addressbokUpdated()" << oendl; + emit signalChanged ( this ); + } else if ( msg == "flush()" ) { + owarn << "OPimContactAccess: Received flush()" << oendl; + save (); + } else if ( msg == "reload()" ) { + owarn << "OPimContactAccess: Received reload()" << oendl; + reload (); + emit signalChanged ( this ); + } } int OPimContactAccess::rtti() const { - return OPimResolver::AddressBook; + 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) 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(); + 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 @@ -1,1291 +1,1291 @@ /* 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. */ #define QTOPIA_INTERNAL_CONTACT_MRE #include "opimcontact.h" /* OPIE */ #include <opie2/opimresolver.h> #include <opie2/opimdateconversion.h> #include <opie2/odebug.h> #include <qpe/stringutil.h> #include <qpe/timestring.h> #include <qpe/config.h> /* QT */ #include <qstylesheet.h> /* STD */ #include <stdio.h> /*! \class Contact contact.h \brief The Contact class holds the data of an address book entry. This data includes information the name of the person, contact information, and business information such as deparment and job title. \ingroup qtopiaemb \ingroup qtopiadesktop */ namespace Opie { /*! Creates a new, empty contact. */ OPimContact::OPimContact():OPimRecord(), mMap(), d( 0 ) {} /*! \internal Creates a new contact. The properties of the contact are set from \a fromMap. */ OPimContact::OPimContact( const QMap<int, QString> &fromMap ):OPimRecord(), mMap( fromMap ), d( 0 ) { QString cats = mMap[ Qtopia::AddressCategory ]; if ( !cats.isEmpty() ) setCategories( idsFromString( cats ) ); QString uidStr = find( Qtopia::AddressUid ); if ( uidStr.isEmpty() || ( uidStr.toInt() == 0 ) ) { owarn << "Invalid UID found. Generate new one.." << oendl; setUid( uidGen().generate() ); } else setUid( uidStr.toInt() ); // if ( !uidStr.isEmpty() ) // setUid( uidStr.toInt() ); } /*! Destroys a contact. */ OPimContact::~OPimContact() {} /*! \fn void OPimContact::setTitle( const QString &str ) Sets the title of the contact to \a str. */ /*! \fn void OPimContact::setFirstName( const QString &str ) Sets the first name of the contact to \a str. */ /*! \fn void OPimContact::setMiddleName( const QString &str ) Sets the middle name of the contact to \a str. */ /*! \fn void OPimContact::setLastName( const QString &str ) Sets the last name of the contact to \a str. */ /*! \fn void OPimContact::setSuffix( const QString &str ) Sets the suffix of the contact to \a str. */ /*! \fn void OPimContact::setFileAs( const QString &str ) Sets the contact to filed as \a str. */ /*! \fn void OPimContact::setDefaultEmail( const QString &str ) Sets the default email of the contact to \a str. */ /*! \fn void OPimContact::setHomeStreet( const QString &str ) Sets the home street address of the contact to \a str. */ /*! \fn void OPimContact::setHomeCity( const QString &str ) Sets the home city of the contact to \a str. */ /*! \fn void OPimContact::setHomeState( const QString &str ) Sets the home state of the contact to \a str. */ /*! \fn void OPimContact::setHomeZip( const QString &str ) Sets the home zip code of the contact to \a str. */ /*! \fn void OPimContact::setHomeCountry( const QString &str ) Sets the home country of the contact to \a str. */ /*! \fn void OPimContact::setHomePhone( const QString &str ) Sets the home phone number of the contact to \a str. */ /*! \fn void OPimContact::setHomeFax( const QString &str ) Sets the home fax number of the contact to \a str. */ /*! \fn void OPimContact::setHomeMobile( const QString &str ) Sets the home mobile phone number of the contact to \a str. */ /*! \fn void OPimContact::setHomeWebpage( const QString &str ) Sets the home webpage of the contact to \a str. */ /*! \fn void OPimContact::setCompany( const QString &str ) Sets the company for contact to \a str. */ /*! \fn void OPimContact::setJobTitle( const QString &str ) Sets the job title of the contact to \a str. */ /*! \fn void OPimContact::setDepartment( const QString &str ) Sets the department for contact to \a str. */ /*! \fn void OPimContact::setOffice( const QString &str ) Sets the office for contact to \a str. */ /*! \fn void OPimContact::setBusinessStreet( const QString &str ) Sets the business street address of the contact to \a str. */ /*! \fn void OPimContact::setBusinessCity( const QString &str ) Sets the business city of the contact to \a str. */ /*! \fn void OPimContact::setBusinessState( const QString &str ) Sets the business state of the contact to \a str. */ /*! \fn void OPimContact::setBusinessZip( const QString &str ) Sets the business zip code of the contact to \a str. */ /*! \fn void OPimContact::setBusinessCountry( const QString &str ) Sets the business country of the contact to \a str. */ /*! \fn void OPimContact::setBusinessPhone( const QString &str ) Sets the business phone number of the contact to \a str. */ /*! \fn void OPimContact::setBusinessFax( const QString &str ) Sets the business fax number of the contact to \a str. */ /*! \fn void OPimContact::setBusinessMobile( const QString &str ) Sets the business mobile phone number of the contact to \a str. */ /*! \fn void OPimContact::setBusinessPager( const QString &str ) Sets the business pager number of the contact to \a str. */ /*! \fn void OPimContact::setBusinessWebpage( const QString &str ) Sets the business webpage of the contact to \a str. */ /*! \fn void OPimContact::setProfession( const QString &str ) Sets the profession of the contact to \a str. */ /*! \fn void OPimContact::setAssistant( const QString &str ) Sets the assistant of the contact to \a str. */ /*! \fn void OPimContact::setManager( const QString &str ) Sets the manager of the contact to \a str. */ /*! \fn void OPimContact::setSpouse( const QString &str ) Sets the spouse of the contact to \a str. */ /*! \fn void OPimContact::setGender( const QString &str ) Sets the gender of the contact to \a str. */ /*! \fn void OPimContact::setNickname( const QString &str ) Sets the nickname of the contact to \a str. */ /*! \fn void OPimContact::setNotes( const QString &str ) Sets the notes about the contact to \a str. */ /*! \fn QString OPimContact::title() const Returns the title of the contact. */ /*! \fn QString OPimContact::firstName() const Returns the first name of the contact. */ /*! \fn QString OPimContact::middleName() const Returns the middle name of the contact. */ /*! \fn QString OPimContact::lastName() const Returns the last name of the contact. */ /*! \fn QString OPimContact::suffix() const Returns the suffix of the contact. */ /*! \fn QString OPimContact::fileAs() const Returns the string the contact is filed as. */ /*! \fn QString OPimContact::defaultEmail() const Returns the default email address of the contact. */ /*! \fn QString OPimContact::emails() const Returns the list of email address for a contact separated by ';'s in a single string. */ /*! \fn QString OPimContact::homeStreet() const Returns the home street address of the contact. */ /*! \fn QString OPimContact::homeCity() const Returns the home city of the contact. */ /*! \fn QString OPimContact::homeState() const Returns the home state of the contact. */ /*! \fn QString OPimContact::homeZip() const Returns the home zip of the contact. */ /*! \fn QString OPimContact::homeCountry() const Returns the home country of the contact. */ /*! \fn QString OPimContact::homePhone() const Returns the home phone number of the contact. */ /*! \fn QString OPimContact::homeFax() const Returns the home fax number of the contact. */ /*! \fn QString OPimContact::homeMobile() const Returns the home mobile number of the contact. */ /*! \fn QString OPimContact::homeWebpage() const Returns the home webpage of the contact. */ /*! \fn QString OPimContact::company() const Returns the company for the contact. */ /*! \fn QString OPimContact::department() const Returns the department for the contact. */ /*! \fn QString OPimContact::office() const Returns the office for the contact. */ /*! \fn QString OPimContact::jobTitle() const Returns the job title of the contact. */ /*! \fn QString OPimContact::profession() const Returns the profession of the contact. */ /*! \fn QString OPimContact::assistant() const Returns the assistant of the contact. */ /*! \fn QString OPimContact::manager() const Returns the manager of the contact. */ /*! \fn QString OPimContact::businessStreet() const Returns the business street address of the contact. */ /*! \fn QString OPimContact::businessCity() const Returns the business city of the contact. */ /*! \fn QString OPimContact::businessState() const Returns the business state of the contact. */ /*! \fn QString OPimContact::businessZip() const Returns the business zip of the contact. */ /*! \fn QString OPimContact::businessCountry() const Returns the business country of the contact. */ /*! \fn QString OPimContact::businessPhone() const Returns the business phone number of the contact. */ /*! \fn QString OPimContact::businessFax() const Returns the business fax number of the contact. */ /*! \fn QString OPimContact::businessMobile() const Returns the business mobile number of the contact. */ /*! \fn QString OPimContact::businessPager() const Returns the business pager number of the contact. */ /*! \fn QString OPimContact::businessWebpage() const Returns the business webpage of the contact. */ /*! \fn QString OPimContact::spouse() const Returns the spouse of the contact. */ /*! \fn QString OPimContact::gender() const Returns the gender of the contact. */ /*! \fn QString OPimContact::nickname() const Returns the nickname of the contact. */ /*! \fn QString OPimContact::children() const Returns the children of the contact. */ /*! \fn QString OPimContact::notes() const Returns the notes relating to the the contact. */ /*! \fn QString OPimContact::groups() const \internal Returns the groups for the contact. */ /*! \fn QStringList OPimContact::groupList() const \internal */ /*! \fn QString OPimContact::field(int) const \internal */ /*! \fn void OPimContact::saveJournal( journal_action, const QString & = QString::null ) \internal */ /*! \fn void OPimContact::setUid( int id ) \internal Sets the uid for this record to \a id. */ /*! \enum OPimContact::journal_action \internal */ /*! \internal */ QMap<int, QString> OPimContact::toMap() const { QMap<int, QString> map = mMap; QString cats = idsToString( categories() ); if ( !cats.isEmpty() ) map.insert( Qtopia::AddressCategory, cats ); return map; } /*! Returns a rich text formatted QString representing the contents the contact. */ QString OPimContact::toRichText() const { QString text; QString value, comp, state; QString str; bool marker = false; Config cfg( "qpe" ); cfg.setGroup( "Appearance" ); int addressformat = cfg.readNumEntry( "AddressFormat", Zip_City_State ); // name, jobtitle and company if ( !( value = fullName() ).isEmpty() ) text += "<b><h3><img src=\"addressbook/AddressBook\"> " + Qtopia::escapeString( value ) + "</h3></b>"; if ( !( value = jobTitle() ).isEmpty() ) text += Qtopia::escapeString( value ) + " "; comp = company(); if ( !( value = department() ).isEmpty() ) { text += Qtopia::escapeString( value ); if ( comp ) text += ", " + Qtopia::escapeString( comp ); } else if ( comp ) text += "<br>" + Qtopia::escapeString( comp ); text += "<br><hr>"; // defailt email QString defEmail = defaultEmail(); if ( !defEmail.isEmpty() ) { text += "<b><img src=\"addressbook/email\"> " + QObject::tr( "Default Email: " ) + "</b>" + Qtopia::escapeString( defEmail ); marker = true; } // business address if ( !businessStreet().isEmpty() || !businessCity().isEmpty() || !businessZip().isEmpty() || !businessCountry().isEmpty() ) { text += QObject::tr( "<br><b>Work Address:</b>" ); marker = true; } if ( !( value = businessStreet() ).isEmpty() ) { text += "<br>" + Qtopia::escapeString( value ); marker = true; } switch ( addressformat ) { case Zip_City_State: { // Zip_Code City, State state = businessState(); if ( !( value = businessZip() ).isEmpty() ) { text += "<br>" + Qtopia::escapeString( value ) + " "; marker = true; } if ( !( value = businessCity() ).isEmpty() ) { marker = true; if ( businessZip().isEmpty() && !businessStreet().isEmpty() ) text += "<br>"; text += Qtopia::escapeString( value ); if ( state ) text += ", " + Qtopia::escapeString( state ); } else if ( !state.isEmpty() ) { text += "<br>" + Qtopia::escapeString( state ); marker = true; } break; } case City_State_Zip: { // City, State Zip_Code state = businessState(); if ( !( value = businessCity() ).isEmpty() ) { marker = true; text += "<br>" + Qtopia::escapeString( value ); if ( state ) text += ", " + Qtopia::escapeString( state ); } else if ( !state.isEmpty() ) { text += "<br>" + Qtopia::escapeString( state ); marker = true; } if ( !( value = businessZip() ).isEmpty() ) { text += " " + Qtopia::escapeString( value ); marker = true; } break; } } if ( !( value = businessCountry() ).isEmpty() ) { text += "<br>" + Qtopia::escapeString( value ); marker = true; } // rest of Business data str = office(); if ( !str.isEmpty() ) { text += "<br><b>" + QObject::tr( "Office: " ) + "</b>" + Qtopia::escapeString( str ); marker = true; } str = businessWebpage(); if ( !str.isEmpty() ) { text += "<br><b><img src=\"addressbook/webpagework\"> " + QObject::tr( "Business Web Page: " ) + "</b>" + Qtopia::escapeString( str ); marker = true; } str = businessPhone(); if ( !str.isEmpty() ) { text += "<br><b><img src=\"addressbook/phonework\"> " + QObject::tr( "Business Phone: " ) + "</b>" + Qtopia::escapeString( str ); marker = true; } str = businessFax(); if ( !str.isEmpty() ) { text += "<br><b><img src=\"addressbook/faxwork\"> " + QObject::tr( "Business Fax: " ) + "</b>" + Qtopia::escapeString( str ); marker = true; } str = businessMobile(); if ( !str.isEmpty() ) { text += "<br><b><img src=\"addressbook/mobilework\"> " + QObject::tr( "Business Mobile: " ) + "</b>" + Qtopia::escapeString( str ); marker = true; } str = businessPager(); if ( !str.isEmpty() ) { text += "<br><b>" + QObject::tr( "Business Pager: " ) + "</b>" + Qtopia::escapeString( str ); marker = true; } // text += "<br>"; // home address if ( !homeStreet().isEmpty() || !homeCity().isEmpty() || !homeZip().isEmpty() || !homeCountry().isEmpty() ) { text += QObject::tr( "<br><b>Home Address:</b>" ); marker = true; } if ( !( value = homeStreet() ).isEmpty() ) { text += "<br>" + Qtopia::escapeString( value ); marker = true; } switch ( addressformat ) { case Zip_City_State: { // Zip_Code City, State state = homeState(); if ( !( value = homeZip() ).isEmpty() ) { text += "<br>" + Qtopia::escapeString( value ) + " "; marker = true; } if ( !( value = homeCity() ).isEmpty() ) { marker = true; if ( homeZip().isEmpty() && !homeStreet().isEmpty() ) text += "<br>"; text += Qtopia::escapeString( value ); if ( !state.isEmpty() ) text += ", " + Qtopia::escapeString( state ); } else if ( !state.isEmpty() ) { text += "<br>" + Qtopia::escapeString( state ); marker = true; } break; } case City_State_Zip: { // City, State Zip_Code state = homeState(); if ( !( value = homeCity() ).isEmpty() ) { marker = true; text += "<br>" + Qtopia::escapeString( value ); if ( state ) text += ", " + Qtopia::escapeString( state ); } else if ( !state.isEmpty() ) { text += "<br>" + Qtopia::escapeString( state ); marker = true; } if ( !( value = homeZip() ).isEmpty() ) { text += " " + Qtopia::escapeString( value ); marker = true; } break; } } if ( !( value = homeCountry() ).isEmpty() ) { text += "<br>" + Qtopia::escapeString( value ); marker = true; } // rest of Home data str = homeWebpage(); if ( !str.isEmpty() ) { text += "<br><b><img src=\"addressbook/webpagehome\"> " + QObject::tr( "Home Web Page: " ) + "</b>" + Qtopia::escapeString( str ); marker = true; } str = homePhone(); if ( !str.isEmpty() ) { text += "<br><b><img src=\"addressbook/phonehome\"> " + QObject::tr( "Home Phone: " ) + "</b>" + Qtopia::escapeString( str ); marker = true; } str = homeFax(); if ( !str.isEmpty() ) { text += "<br><b><img src=\"addressbook/faxhome\"> " + QObject::tr( "Home Fax: " ) + "</b>" + Qtopia::escapeString( str ); marker = true; } str = homeMobile(); if ( !str.isEmpty() ) { text += "<br><b><img src=\"addressbook/mobilehome\"> " + QObject::tr( "Home Mobile: " ) + "</b>" + Qtopia::escapeString( str ); marker = true; } if ( marker ) text += "<br><hr>"; // the rest... str = emails(); if ( !str.isEmpty() && ( str != defEmail ) ) text += "<br><b>" + QObject::tr( "All Emails: " ) + "</b>" + Qtopia::escapeString( str ); str = profession(); if ( !str.isEmpty() ) text += "<br><b>" + QObject::tr( "Profession: " ) + "</b>" + Qtopia::escapeString( str ); str = assistant(); if ( !str.isEmpty() ) text += "<br><b>" + QObject::tr( "Assistant: " ) + "</b>" + Qtopia::escapeString( str ); str = manager(); if ( !str.isEmpty() ) text += "<br><b>" + QObject::tr( "Manager: " ) + "</b>" + Qtopia::escapeString( str ); str = gender(); if ( !str.isEmpty() && str.toInt() != 0 ) { text += "<br>"; if ( str.toInt() == 1 ) str = QObject::tr( "Male" ); else if ( str.toInt() == 2 ) str = QObject::tr( "Female" ); text += "<b>" + QObject::tr( "Gender: " ) + "</b>" + str; } str = spouse(); if ( !str.isEmpty() ) text += "<br><b>" + QObject::tr( "Spouse: " ) + "</b>" + Qtopia::escapeString( str ); if ( birthday().isValid() ) { str = TimeString::numberDateString( birthday() ); text += "<br><b>" + QObject::tr( "Birthday: " ) + "</b>" + Qtopia::escapeString( str ); } if ( anniversary().isValid() ) { str = TimeString::numberDateString( anniversary() ); text += "<br><b>" + QObject::tr( "Anniversary: " ) + "</b>" + Qtopia::escapeString( str ); } str = children(); if ( !str.isEmpty() ) text += "<br><b>" + QObject::tr( "Children: " ) + "</b>" + Qtopia::escapeString( str ); str = nickname(); if ( !str.isEmpty() ) text += "<br><b>" + QObject::tr( "Nickname: " ) + "</b>" + Qtopia::escapeString( str ); // categories if ( categoryNames( "Contacts" ).count() ) { text += "<br><b>" + QObject::tr( "Category:" ) + "</b> "; text += categoryNames( "Contacts" ).join( ", " ); } // notes last if ( !( value = notes() ).isEmpty() ) { text += "<br><hr><b>" + QObject::tr( "Notes:" ) + "</b> "; QRegExp reg( "\n" ); //QString tmp = Qtopia::escapeString(value); QString tmp = QStyleSheet::convertFromPlainText( value ); //tmp.replace( reg, "<br>" ); text += "<br>" + tmp + "<br>"; } return text; } /*! \internal */ void OPimContact::insert( int key, const QString &v ) { QString value = v.stripWhiteSpace(); if ( value.isEmpty() ) mMap.remove( key ); else mMap.insert( key, value ); } /*! \internal */ void OPimContact::replace( int key, const QString & v ) { QString value = v.stripWhiteSpace(); if ( value.isEmpty() ) mMap.remove( key ); else mMap.replace( key, value ); } /*! \internal */ QString OPimContact::find( int key ) const { return mMap[ key ]; } /*! \internal */ QString OPimContact::displayAddress( const QString &street, const QString &city, const QString &state, const QString &zip, const QString &country ) const { QString s = street; if ( !street.isEmpty() ) s += "\n"; s += city; if ( !city.isEmpty() && !state.isEmpty() ) s += ", "; s += state; if ( !state.isEmpty() && !zip.isEmpty() ) s += " "; s += zip; if ( !country.isEmpty() && !s.isEmpty() ) s += "\n"; s += country; return s; } /*! \internal */ QString OPimContact::displayBusinessAddress() const { return displayAddress( businessStreet(), businessCity(), businessState(), businessZip(), businessCountry() ); } /*! \internal */ QString OPimContact::displayHomeAddress() const { return displayAddress( homeStreet(), homeCity(), homeState(), homeZip(), homeCountry() ); } /*! Returns the full name of the contact */ QString OPimContact::fullName() const { QString title = find( Qtopia::Title ); QString firstName = find( Qtopia::FirstName ); QString middleName = find( Qtopia::MiddleName ); QString lastName = find( Qtopia::LastName ); QString suffix = find( Qtopia::Suffix ); QString name = title; if ( !firstName.isEmpty() ) { if ( !name.isEmpty() ) name += " "; name += firstName; } if ( !middleName.isEmpty() ) { if ( !name.isEmpty() ) name += " "; name += middleName; } if ( !lastName.isEmpty() ) { if ( !name.isEmpty() ) name += " "; name += lastName; } if ( !suffix.isEmpty() ) { if ( !name.isEmpty() ) name += " "; name += suffix; } return name.simplifyWhiteSpace(); } /*! Returns a list of the names of the children of the contact. */ QStringList OPimContact::childrenList() const { return QStringList::split( " ", find( Qtopia::Children ) ); } /*! \fn void OPimContact::insertEmail( const QString &email ) Insert \a email into the email list. Ensures \a email can only be added once. If there is no default email address set, it sets it to the \a email. */ /*! \fn void OPimContact::removeEmail( const QString &email ) Removes the \a email from the email list. If the default email was \a email, then the default email address is assigned to the first email in the email list */ /*! \fn void OPimContact::clearEmails() Clears the email list. */ /*! \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 |