diff options
Diffstat (limited to 'libkdepim/distributionlist.cpp')
-rw-r--r-- | libkdepim/distributionlist.cpp | 225 |
1 files changed, 225 insertions, 0 deletions
diff --git a/libkdepim/distributionlist.cpp b/libkdepim/distributionlist.cpp new file mode 100644 index 000000000..64f56a209 --- /dev/null +++ b/libkdepim/distributionlist.cpp @@ -0,0 +1,225 @@ +#include "distributionlist.h" +#include <kabc/addressbook.h> + +static const char* s_customFieldName = "DistributionList"; + +KPIM::DistributionList::DistributionList() + : KABC::Addressee() +{ + // can't insert the custom entry here, we need to remain a null addressee +} + +KPIM::DistributionList::DistributionList( const KABC::Addressee& addr ) + : KABC::Addressee( addr ) +{ +} + +void KPIM::DistributionList::setName( const QString &name ) +{ + // We can't use Addressee::setName, the name isn't saved/loaded in the vcard (fixed in 3.4) + Addressee::setFormattedName( name ); + // Also set family name, just in case this entry appears in the normal contacts list (e.g. old kaddressbook) + Addressee::setFamilyName( name ); + // We're not an empty addressee anymore + // Set the custom field to non-empty, so that isDistributionList works + if ( custom( "KADDRESSBOOK", s_customFieldName ).isEmpty() ) + insertCustom( "KADDRESSBOOK", s_customFieldName, ";" ); +} + +// Helper function, to parse the contents of the custom field +// Returns a list of { uid, email } +typedef QValueList<QPair<QString, QString> > ParseList; +static ParseList parseCustom( const QString& str ) +{ + ParseList res; + const QStringList lst = QStringList::split( ';', str ); + for( QStringList::ConstIterator it = lst.begin(); it != lst.end(); ++it ) { + if ( (*it).isEmpty() ) + continue; + // parse "uid,email" + QStringList helpList = QStringList::split( ',', (*it) ); + Q_ASSERT( !helpList.isEmpty() ); + if ( helpList.isEmpty() ) + continue; + const QString uid = helpList.first(); + QString email; + Q_ASSERT( helpList.count() < 3 ); // 1 or 2 items, but not more + if ( helpList.count() == 2 ) + email = helpList.last(); + res.append( qMakePair( uid, email ) ); + } + return res; +} + +void KPIM::DistributionList::insertEntry( const Addressee& addr, const QString& email ) +{ + // insertEntry will removeEntry(uid), but not with formattedName + removeEntry( addr.formattedName(), email ); + insertEntry( addr.uid(), email ); +} + +void KPIM::DistributionList::insertEntry( const QString& uid, const QString& email ) +{ + Q_ASSERT( !email.isEmpty() || email.isNull() ); // hopefully never called with "", would lead to confusion + removeEntry( uid, email ); // avoid duplicates + QString str = custom( "KADDRESSBOOK", s_customFieldName ); + // Assumption: UIDs don't contain ; nor , + str += ";" + uid + "," + email; + insertCustom( "KADDRESSBOOK", s_customFieldName, str ); // replace old value +} + +void KPIM::DistributionList::removeEntry( const Addressee& addr, const QString& email ) +{ + removeEntry( addr.uid(), email ); + // Also remove entries with the full name as uid (for the kolab thing) + removeEntry( addr.formattedName(), email ); +} + +void KPIM::DistributionList::removeEntry( const QString& uid, const QString& email ) +{ + Q_ASSERT( !email.isEmpty() || email.isNull() ); // hopefully never called with "", would lead to confusion + ParseList parseList = parseCustom( custom( "KADDRESSBOOK", s_customFieldName ) ); + QString str; + for( ParseList::ConstIterator it = parseList.begin(); it != parseList.end(); ++it ) { + const QString thisUid = (*it).first; + const QString thisEmail = (*it).second; + if ( thisUid == uid && thisEmail == email ) { + continue; // remove that one + } + str += ";" + thisUid + "," + thisEmail; + } + if ( str.isEmpty() ) + str = ";"; // keep something, for isDistributionList to work + insertCustom( "KADDRESSBOOK", s_customFieldName, str ); // replace old value +} + +bool KPIM::DistributionList::isDistributionList( const KABC::Addressee& addr ) +{ + const QString str = addr.custom( "KADDRESSBOOK", s_customFieldName ); + return !str.isEmpty(); +} + +// ###### KDE4: add findByFormattedName to KABC::AddressBook +static KABC::Addressee::List findByFormattedName( KABC::AddressBook* book, + const QString& name, + bool caseSensitive = true ) +{ + KABC::Addressee::List res; + KABC::AddressBook::Iterator abIt; + for ( abIt = book->begin(); abIt != book->end(); ++abIt ) + { + if ( caseSensitive && (*abIt).formattedName() == name ) + res.append( *abIt ); + if ( !caseSensitive && (*abIt).formattedName().lower() == name.lower() ) + res.append( *abIt ); + } + return res; +} + +KPIM::DistributionList KPIM::DistributionList::findByName( KABC::AddressBook* book, + const QString& name, + bool caseSensitive ) +{ + KABC::AddressBook::Iterator abIt; + for ( abIt = book->begin(); abIt != book->end(); ++abIt ) + { + if ( isDistributionList( *abIt ) ) { + if ( caseSensitive && (*abIt).formattedName() == name ) + return *abIt; + if ( !caseSensitive && (*abIt).formattedName().lower() == name.lower() ) + return *abIt; + } + } + return DistributionList(); +} + +static KABC::Addressee findByUidOrName( KABC::AddressBook* book, const QString& uidOrName, const QString& email ) +{ + KABC::Addressee a = book->findByUid( uidOrName ); + if ( a.isEmpty() ) { + // UID not found, maybe it is a name instead. + // If we have an email, let's use that for the lookup. + // [This is used by e.g. the Kolab resource] + if ( !email.isEmpty() ) { + KABC::Addressee::List lst = book->findByEmail( email ); + KABC::Addressee::List::ConstIterator listit = lst.begin(); + for ( ; listit != lst.end(); ++listit ) + if ( (*listit).formattedName() == uidOrName ) { + a = *listit; + break; + } + if ( !lst.isEmpty() && a.isEmpty() ) { // found that email, but no match on the fullname + a = lst.first(); // probably the last name changed + } + } + // If we don't have an email, or if we didn't find any match for it, look up by full name + if ( a.isEmpty() ) { + // (But this has to be done here, since when loading we might not have the entries yet) + KABC::Addressee::List lst = findByFormattedName( book, uidOrName ); + if ( !lst.isEmpty() ) + a = lst.first(); + } + } + return a; +} + +KPIM::DistributionList::Entry::List KPIM::DistributionList::entries( KABC::AddressBook* book ) const +{ + Entry::List res; + const QString str = custom( "KADDRESSBOOK", s_customFieldName ); + const ParseList parseList = parseCustom( str ); + for( ParseList::ConstIterator it = parseList.begin(); it != parseList.end(); ++it ) { + const QString uid = (*it).first; + const QString email = (*it).second; + // look up contact + KABC::Addressee a = findByUidOrName( book, uid, email ); + if ( a.isEmpty() ) { + // ## The old DistributionListManager had a "missing entries" list... + kdWarning() << "Addressee not found: " << uid << endl; + } else { + res.append( Entry( a, email ) ); + } + } + return res; +} + +QStringList KPIM::DistributionList::emails( KABC::AddressBook* book ) const +{ + QStringList emails; + + const QString str = custom( "KADDRESSBOOK", s_customFieldName ); + ParseList parseList = parseCustom( str ); + for( ParseList::ConstIterator it = parseList.begin(); it != parseList.end(); ++it ) { + const QString thisUid = (*it).first; + const QString thisEmail = (*it).second; + + // look up contact + KABC::Addressee a = findByUidOrName( book, thisUid, thisEmail ); + if ( a.isEmpty() ) { + // ## The old DistributionListManager had a "missing entries" list... + continue; + } + + const QString email = thisEmail.isEmpty() ? a.fullEmail() : + a.fullEmail( thisEmail ); + if ( !email.isEmpty() ) { + emails.append( email ); + } + } + + return emails; +} + +QValueList<KPIM::DistributionList> + KPIM::DistributionList::allDistributionLists( KABC::AddressBook* book ) +{ + QValueList<KPIM::DistributionList> lst; + KABC::AddressBook::Iterator abIt; + for ( abIt = book->begin(); abIt != book->end(); ++abIt ) + { + if ( isDistributionList( *abIt ) ) { + lst.append( KPIM::DistributionList( *abIt ) ); + } + } + return lst; +} |