diff options
Diffstat (limited to 'kabc/scripts')
-rw-r--r-- | kabc/scripts/Makefile.am | 6 | ||||
-rw-r--r-- | kabc/scripts/addressee.src.cpp | 1108 | ||||
-rw-r--r-- | kabc/scripts/addressee.src.h | 394 | ||||
-rwxr-xr-x | kabc/scripts/createisomap.pl | 35 | ||||
-rw-r--r-- | kabc/scripts/entrylist | 84 | ||||
-rw-r--r-- | kabc/scripts/field.src.cpp | 530 | ||||
-rwxr-xr-x | kabc/scripts/makeaddressee | 215 |
7 files changed, 2372 insertions, 0 deletions
diff --git a/kabc/scripts/Makefile.am b/kabc/scripts/Makefile.am new file mode 100644 index 000000000..7715fba5c --- /dev/null +++ b/kabc/scripts/Makefile.am @@ -0,0 +1,6 @@ +EXTRA_DIST = $(srcdir)/makeaddressee \ + $(srcdir)/addressee.src.cpp \ + $(srcdir)/addressee.src.h \ + $(srcdir)/entrylist \ + $(srcdir)/field.src.cpp + diff --git a/kabc/scripts/addressee.src.cpp b/kabc/scripts/addressee.src.cpp new file mode 100644 index 000000000..887290c8f --- /dev/null +++ b/kabc/scripts/addressee.src.cpp @@ -0,0 +1,1108 @@ +/* + This file is part of libkabc. + Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org> + Copyright (c) 2003 Carsten Pfeiffer <pfeiffer@kde.org> + Copyright (c) 2005 Ingo Kloecker <kloecker@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include <qregexp.h> + +#include <ksharedptr.h> +#include <kdebug.h> +#include <kapplication.h> +#include <klocale.h> + +#include "addresseehelper.h" +#include "field.h" +#include "resource.h" +#include "sortmode.h" + +#include "addressee.h" + +using namespace KABC; + +static bool matchBinaryPattern( int value, int pattern ); + +template <class L> +static bool listEquals( const QValueList<L>&, const QValueList<L>& ); +static bool emailsEquals( const QStringList&, const QStringList& ); + +KABC::SortMode *Addressee::mSortMode = 0; + +struct Addressee::AddresseeData : public KShared +{ + QString uid; + --VARIABLES-- + + PhoneNumber::List phoneNumbers; + Address::List addresses; + Key::List keys; + QStringList emails; + QStringList categories; + QStringList custom; + + Resource *resource; + + bool empty :1; + bool changed :1; +}; + +Addressee::AddresseeData* Addressee::shared_null = 0; + +Addressee::AddresseeData* Addressee::makeSharedNull() +{ + Addressee::shared_null = new AddresseeData; + shared_null->_KShared_ref(); //just in case (we should add KSD) + shared_null->empty = true; + shared_null->changed = false; + shared_null->resource = 0; + return shared_null; +} + +Addressee::Addressee() +{ + mData = shared_null ? shared_null : makeSharedNull(); +} + +Addressee::~Addressee() +{ +} + +Addressee::Addressee( const Addressee &a ) +{ + mData = a.mData; +} + +Addressee &Addressee::operator=( const Addressee &a ) +{ + if ( this == &a ) + return (*this); + + mData = a.mData; + return (*this); +} + +void Addressee::detach() +{ + if ( mData.data() == shared_null ) { + mData = new AddresseeData; + mData->empty = true; + mData->changed = false; + mData->resource = 0; + mData->uid = KApplication::randomString( 10 ); + return; + } else if ( mData.count() == 1 ) return; + + AddresseeData data = *mData; + mData = new AddresseeData( data ); +} + +bool Addressee::operator==( const Addressee &a ) const +{ + if ( uid() != a.uid() ) { + kdDebug(5700) << "uid differs" << endl; + return false; + } + --EQUALSTEST-- + if ( ( mData->url.isValid() || a.mData->url.isValid() ) && + ( mData->url != a.mData->url ) ) { + kdDebug(5700) << "url differs" << endl; + return false; + } + if ( !listEquals( mData->phoneNumbers, a.mData->phoneNumbers ) ) { + kdDebug(5700) << "phoneNumbers differs" << endl; + return false; + } + if ( !listEquals( mData->addresses, a.mData->addresses ) ) { + kdDebug(5700) << "addresses differs" << endl; + return false; + } + if ( !listEquals( mData->keys, a.mData->keys ) ) { + kdDebug(5700) << "keys differs" << endl; + return false; + } + if ( !emailsEquals( mData->emails, a.mData->emails ) ) { + kdDebug(5700) << "emails differs" << endl; + return false; + } + if ( !listEquals( mData->categories, a.mData->categories ) ) { + kdDebug(5700) << "categories differs" << endl; + return false; + } + if ( !listEquals( mData->custom, a.mData->custom ) ) { + kdDebug(5700) << "custom differs" << endl; + return false; + } + + return true; +} + +bool Addressee::operator!=( const Addressee &a ) const +{ + return !( a == *this ); +} + +bool Addressee::isEmpty() const +{ + return mData->empty; +} + +void Addressee::setUid( const QString &id ) +{ + if ( id == mData->uid ) return; + detach(); + mData->empty = false; + mData->uid = id; +} + +QString Addressee::uid() const +{ + return mData->uid; +} + +QString Addressee::uidLabel() +{ + return i18n("Unique Identifier"); +} + +--DEFINITIONS-- + +void Addressee::setNameFromString( const QString &s ) +{ + QString str = s; + //remove enclosing quotes from string + if ( str.length() > 1 && s[ 0 ] == '"' && s[ s.length() - 1 ] == '"' ) + str = s.mid( 1, s.length() - 2 ); + + setFormattedName( str ); + setName( str ); + + // clear all name parts + setPrefix( QString::null ); + setGivenName( QString::null ); + setAdditionalName( QString::null ); + setFamilyName( QString::null ); + setSuffix( QString::null ); + + if ( str.isEmpty() ) + return; + + QString spaceStr = " "; + QString emptyStr = ""; + AddresseeHelper *helper = AddresseeHelper::self(); + + int i = str.find( ',' ); + if( i < 0 ) { + QStringList parts = QStringList::split( spaceStr, str ); + int leftOffset = 0; + int rightOffset = parts.count() - 1; + + QString suffix; + while ( rightOffset >= 0 ) { + if ( helper->containsSuffix( parts[ rightOffset ] ) ) { + suffix.prepend(parts[ rightOffset ] + (suffix.isEmpty() ? emptyStr : spaceStr)); + rightOffset--; + } else + break; + } + setSuffix( suffix ); + + if ( rightOffset < 0 ) + return; + + QStringList inclusionList; + for ( int n = 1; (rightOffset - n >= 0) && (n < 4); ++n ) { + if ( helper->containsPrefix( parts[ rightOffset - n ].lower() ) ) { + inclusionList.prepend( parts[ rightOffset - n ] ); + } else + break; + } + + if ( !inclusionList.isEmpty() ) { + setFamilyName( inclusionList.join( " " ) + spaceStr + parts[ rightOffset ] ); + rightOffset -= inclusionList.count(); + } else { + if ( helper->tradeAsFamilyName() ) + setFamilyName( parts[ rightOffset ] ); + else + setGivenName( parts[ rightOffset ] ); + } + + QString prefix; + while ( leftOffset < rightOffset ) { + if ( helper->containsTitle( parts[ leftOffset ] ) ) { + prefix.append( ( prefix.isEmpty() ? emptyStr : spaceStr) + parts[ leftOffset ] ); + leftOffset++; + } else + break; + } + setPrefix( prefix ); + + if ( leftOffset < rightOffset ) { + setGivenName( parts[ leftOffset ] ); + leftOffset++; + } + + QString additionalName; + while ( leftOffset < rightOffset ) { + additionalName.append( ( additionalName.isEmpty() ? emptyStr : spaceStr) + parts[ leftOffset ] ); + leftOffset++; + } + setAdditionalName( additionalName ); + } else { + QString part1 = str.left( i ); + QString part2 = str.mid( i + 1 ); + + QStringList parts = QStringList::split( spaceStr, part1 ); + int leftOffset = 0; + int rightOffset = parts.count() - 1; + + if ( parts.count() > 0 ) { + + QString suffix; + while ( rightOffset >= 0 ) { + if ( helper->containsSuffix( parts[ rightOffset ] ) ) { + suffix.prepend(parts[ rightOffset ] + (suffix.isEmpty() ? emptyStr : spaceStr)); + rightOffset--; + } else + break; + } + setSuffix( suffix ); + + if ( rightOffset - 1 >= 0 && helper->containsPrefix( parts[ rightOffset - 1 ].lower() ) ) { + setFamilyName( parts[ rightOffset - 1 ] + spaceStr + parts[ rightOffset ] ); + rightOffset--; + } else + setFamilyName( parts[ rightOffset ] ); + + QString prefix; + while ( leftOffset < rightOffset ) { + if ( helper->containsTitle( parts[ leftOffset ] ) ) { + prefix.append( ( prefix.isEmpty() ? emptyStr : spaceStr) + parts[ leftOffset ] ); + leftOffset++; + } else + break; + } + } else { + setPrefix( "" ); + setFamilyName( "" ); + setSuffix( "" ); + } + + parts = QStringList::split( spaceStr, part2 ); + + leftOffset = 0; + rightOffset = parts.count(); + + if ( parts.count() > 0 ) { + + QString prefix; + while ( leftOffset < rightOffset ) { + if ( helper->containsTitle( parts[ leftOffset ] ) ) { + prefix.append( ( prefix.isEmpty() ? emptyStr : spaceStr) + parts[ leftOffset ] ); + leftOffset++; + } else + break; + } + setPrefix( prefix ); + + if ( leftOffset < rightOffset ) { + setGivenName( parts[ leftOffset ] ); + leftOffset++; + } + + QString additionalName; + while ( leftOffset < rightOffset ) { + additionalName.append( ( additionalName.isEmpty() ? emptyStr : spaceStr) + parts[ leftOffset ] ); + leftOffset++; + } + setAdditionalName( additionalName ); + } else { + setGivenName( "" ); + setAdditionalName( "" ); + } + } +} + +QString Addressee::realName() const +{ + QString n( formattedName() ); + if ( !n.isEmpty() ) + return n; + + n = assembledName(); + if ( !n.isEmpty() ) + return n; + + n = name(); + if ( !n.isEmpty() ) + return n; + + return organization(); +} + +QString Addressee::assembledName() const +{ + QString name = prefix() + " " + givenName() + " " + additionalName() + " " + + familyName() + " " + suffix(); + + return name.simplifyWhiteSpace(); +} + +QString Addressee::fullEmail( const QString &email ) const +{ + QString e; + if ( email.isNull() ) { + e = preferredEmail(); + } else { + e = email; + } + if ( e.isEmpty() ) return QString::null; + + QString text; + if ( realName().isEmpty() ) + text = e; + else { + QRegExp needQuotes( "[^ 0-9A-Za-z\\x0080-\\xFFFF]" ); + if ( realName().find( needQuotes ) != -1 ) { + QString name = realName(); + name.replace( "\"", "\\\"" ); + text = "\"" + name + "\" <" + e + ">"; + } else + text = realName() + " <" + e + ">"; + } + + return text; +} + +void Addressee::insertEmail( const QString &email, bool preferred ) +{ + if ( email.simplifyWhiteSpace().isEmpty() ) + return; + + detach(); + mData->empty = false; + + QStringList::Iterator it = mData->emails.find( email ); + + if ( it != mData->emails.end() ) { + if ( !preferred || it == mData->emails.begin() ) return; + mData->emails.remove( it ); + mData->emails.prepend( email ); + } else { + if ( preferred ) { + mData->emails.prepend( email ); + } else { + mData->emails.append( email ); + } + } +} + +void Addressee::removeEmail( const QString &email ) +{ + detach(); + + QStringList::Iterator it = mData->emails.find( email ); + if ( it == mData->emails.end() ) return; + + mData->emails.remove( it ); +} + +QString Addressee::preferredEmail() const +{ + if ( mData->emails.count() == 0 ) return QString::null; + else return mData->emails.first(); +} + +QStringList Addressee::emails() const +{ + return mData->emails; +} +void Addressee::setEmails( const QStringList& emails ) { + detach(); + + mData->emails = emails; +} +void Addressee::insertPhoneNumber( const PhoneNumber &phoneNumber ) +{ + detach(); + mData->empty = false; + + PhoneNumber::List::Iterator it; + for( it = mData->phoneNumbers.begin(); it != mData->phoneNumbers.end(); ++it ) { + if ( (*it).id() == phoneNumber.id() ) { + *it = phoneNumber; + return; + } + } + if ( !phoneNumber.number().simplifyWhiteSpace().isEmpty() ) + mData->phoneNumbers.append( phoneNumber ); +} + +void Addressee::removePhoneNumber( const PhoneNumber &phoneNumber ) +{ + detach(); + + PhoneNumber::List::Iterator it; + for( it = mData->phoneNumbers.begin(); it != mData->phoneNumbers.end(); ++it ) { + if ( (*it).id() == phoneNumber.id() ) { + mData->phoneNumbers.remove( it ); + return; + } + } +} + +PhoneNumber Addressee::phoneNumber( int type ) const +{ + PhoneNumber phoneNumber( "", type ); + PhoneNumber::List::ConstIterator it; + for( it = mData->phoneNumbers.constBegin(); it != mData->phoneNumbers.constEnd(); ++it ) { + if ( matchBinaryPattern( (*it).type(), type ) ) { + if ( (*it).type() & PhoneNumber::Pref ) + return (*it); + else if ( phoneNumber.number().isEmpty() ) + phoneNumber = (*it); + } + } + + return phoneNumber; +} + +PhoneNumber::List Addressee::phoneNumbers() const +{ + return mData->phoneNumbers; +} + +PhoneNumber::List Addressee::phoneNumbers( int type ) const +{ + PhoneNumber::List list; + + PhoneNumber::List::ConstIterator it; + for( it = mData->phoneNumbers.constBegin(); it != mData->phoneNumbers.constEnd(); ++it ) { + if ( matchBinaryPattern( (*it).type(), type ) ) { + list.append( *it ); + } + } + return list; +} + +PhoneNumber Addressee::findPhoneNumber( const QString &id ) const +{ + PhoneNumber::List::ConstIterator it; + for( it = mData->phoneNumbers.constBegin(); it != mData->phoneNumbers.constEnd(); ++it ) { + if ( (*it).id() == id ) { + return *it; + } + } + return PhoneNumber(); +} + +void Addressee::insertKey( const Key &key ) +{ + detach(); + mData->empty = false; + + Key::List::Iterator it; + for( it = mData->keys.begin(); it != mData->keys.end(); ++it ) { + if ( (*it).id() == key.id() ) { + *it = key; + return; + } + } + mData->keys.append( key ); +} + +void Addressee::removeKey( const Key &key ) +{ + detach(); + + Key::List::Iterator it; + for( it = mData->keys.begin(); it != mData->keys.end(); ++it ) { + if ( (*it).id() == key.id() ) { + mData->keys.remove( key ); + return; + } + } +} + +Key Addressee::key( int type, QString customTypeString ) const +{ + Key::List::ConstIterator it; + for( it = mData->keys.constBegin(); it != mData->keys.constEnd(); ++it ) { + if ( (*it).type() == type ) { + if ( type == Key::Custom ) { + if ( customTypeString.isEmpty() ) { + return *it; + } else { + if ( (*it).customTypeString() == customTypeString ) + return (*it); + } + } else { + return *it; + } + } + } + return Key( QString(), type ); +} + +void Addressee::setKeys( const Key::List& list ) +{ + detach(); + mData->keys = list; +} + +Key::List Addressee::keys() const +{ + return mData->keys; +} + +Key::List Addressee::keys( int type, QString customTypeString ) const +{ + Key::List list; + + Key::List::ConstIterator it; + for( it = mData->keys.constBegin(); it != mData->keys.constEnd(); ++it ) { + if ( (*it).type() == type ) { + if ( type == Key::Custom ) { + if ( customTypeString.isEmpty() ) { + list.append( *it ); + } else { + if ( (*it).customTypeString() == customTypeString ) + list.append( *it ); + } + } else { + list.append( *it ); + } + } + } + return list; +} + +Key Addressee::findKey( const QString &id ) const +{ + Key::List::ConstIterator it; + for( it = mData->keys.constBegin(); it != mData->keys.constEnd(); ++it ) { + if ( (*it).id() == id ) { + return *it; + } + } + return Key(); +} + +QString Addressee::asString() const +{ + return "Smith, agent Smith..."; +} + +void Addressee::dump() const +{ + kdDebug(5700) << "Addressee {" << endl; + + kdDebug(5700) << " Uid: '" << uid() << "'" << endl; + + --DEBUG-- + + kdDebug(5700) << " Emails {" << endl; + const QStringList e = emails(); + QStringList::ConstIterator it; + for( it = e.begin(); it != e.end(); ++it ) { + kdDebug(5700) << " " << (*it) << endl; + } + kdDebug(5700) << " }" << endl; + + kdDebug(5700) << " PhoneNumbers {" << endl; + const PhoneNumber::List p = phoneNumbers(); + PhoneNumber::List::ConstIterator it2; + for( it2 = p.begin(); it2 != p.end(); ++it2 ) { + kdDebug(5700) << " Type: " << int((*it2).type()) << " Number: " << (*it2).number() << endl; + } + kdDebug(5700) << " }" << endl; + + const Address::List a = addresses(); + Address::List::ConstIterator it3; + for( it3 = a.begin(); it3 != a.end(); ++it3 ) { + (*it3).dump(); + } + + kdDebug(5700) << " Keys {" << endl; + const Key::List k = keys(); + Key::List::ConstIterator it4; + for( it4 = k.begin(); it4 != k.end(); ++it4 ) { + kdDebug(5700) << " Type: " << int((*it4).type()) << + " Key: " << (*it4).textData() << + " CustomString: " << (*it4).customTypeString() << endl; + } + kdDebug(5700) << " }" << endl; + + kdDebug(5700) << "}" << endl; +} + + +void Addressee::insertAddress( const Address &address ) +{ + if ( address.isEmpty() ) + return; + + detach(); + mData->empty = false; + + Address::List::Iterator it; + for( it = mData->addresses.begin(); it != mData->addresses.end(); ++it ) { + if ( (*it).id() == address.id() ) { + *it = address; + return; + } + } + + mData->addresses.append( address ); +} + +void Addressee::removeAddress( const Address &address ) +{ + detach(); + + Address::List::Iterator it; + for( it = mData->addresses.begin(); it != mData->addresses.end(); ++it ) { + if ( (*it).id() == address.id() ) { + mData->addresses.remove( it ); + return; + } + } +} + +Address Addressee::address( int type ) const +{ + Address address( type ); + Address::List::ConstIterator it; + for( it = mData->addresses.constBegin(); it != mData->addresses.constEnd(); ++it ) { + if ( matchBinaryPattern( (*it).type(), type ) ) { + if ( (*it).type() & Address::Pref ) + return (*it); + else if ( address.isEmpty() ) + address = (*it); + } + } + + return address; +} + +Address::List Addressee::addresses() const +{ + return mData->addresses; +} + +Address::List Addressee::addresses( int type ) const +{ + Address::List list; + + Address::List::ConstIterator it; + for( it = mData->addresses.constBegin(); it != mData->addresses.constEnd(); ++it ) { + if ( matchBinaryPattern( (*it).type(), type ) ) { + list.append( *it ); + } + } + + return list; +} + +Address Addressee::findAddress( const QString &id ) const +{ + Address::List::ConstIterator it; + for( it = mData->addresses.constBegin(); it != mData->addresses.constEnd(); ++it ) { + if ( (*it).id() == id ) { + return *it; + } + } + return Address(); +} + +void Addressee::insertCategory( const QString &c ) +{ + detach(); + mData->empty = false; + + if ( mData->categories.findIndex( c ) != -1 ) return; + + mData->categories.append( c ); +} + +void Addressee::removeCategory( const QString &c ) +{ + detach(); + + QStringList::Iterator it = mData->categories.find( c ); + if ( it == mData->categories.end() ) return; + + mData->categories.remove( it ); +} + +bool Addressee::hasCategory( const QString &c ) const +{ + return ( mData->categories.findIndex( c ) != -1 ); +} + +void Addressee::setCategories( const QStringList &c ) +{ + detach(); + mData->empty = false; + + mData->categories = c; +} + +QStringList Addressee::categories() const +{ + return mData->categories; +} + +void Addressee::insertCustom( const QString &app, const QString &name, + const QString &value ) +{ + if ( value.isEmpty() || name.isEmpty() || app.isEmpty() ) return; + + detach(); + mData->empty = false; + + QString qualifiedName = app + "-" + name + ":"; + + QStringList::Iterator it; + for( it = mData->custom.begin(); it != mData->custom.end(); ++it ) { + if ( (*it).startsWith( qualifiedName ) ) { + (*it) = qualifiedName + value; + return; + } + } + + mData->custom.append( qualifiedName + value ); +} + +void Addressee::removeCustom( const QString &app, const QString &name) +{ + detach(); + + QString qualifiedName = app + "-" + name + ":"; + + QStringList::Iterator it; + for( it = mData->custom.begin(); it != mData->custom.end(); ++it ) { + if ( (*it).startsWith( qualifiedName ) ) { + mData->custom.remove( it ); + return; + } + } +} + +QString Addressee::custom( const QString &app, const QString &name ) const +{ + QString qualifiedName = app + "-" + name + ":"; + QString value; + + QStringList::ConstIterator it; + for( it = mData->custom.constBegin(); it != mData->custom.constEnd(); ++it ) { + if ( (*it).startsWith( qualifiedName ) ) { + value = (*it).mid( (*it).find( ":" ) + 1 ); + break; + } + } + + return value; +} + +void Addressee::setCustoms( const QStringList &l ) +{ + detach(); + mData->empty = false; + + mData->custom = l; +} + +QStringList Addressee::customs() const +{ + return mData->custom; +} + +void Addressee::parseEmailAddress( const QString &rawEmail, QString &fullName, + QString &email) +{ + // This is a simplified version of KPIM::splitAddress(). + + fullName = ""; + email = ""; + if ( rawEmail.isEmpty() ) + return; // KPIM::AddressEmpty; + + // The code works on 8-bit strings, so convert the input to UTF-8. + QCString address = rawEmail.utf8(); + + QCString displayName; + QCString addrSpec; + QCString comment; + + // The following is a primitive parser for a mailbox-list (cf. RFC 2822). + // The purpose is to extract a displayable string from the mailboxes. + // Comments in the addr-spec are not handled. No error checking is done. + + enum { TopLevel, InComment, InAngleAddress } context = TopLevel; + bool inQuotedString = false; + int commentLevel = 0; + bool stop = false; + + for ( char* p = address.data(); *p && !stop; ++p ) { + switch ( context ) { + case TopLevel : { + switch ( *p ) { + case '"' : inQuotedString = !inQuotedString; + displayName += *p; + break; + case '(' : if ( !inQuotedString ) { + context = InComment; + commentLevel = 1; + } + else + displayName += *p; + break; + case '<' : if ( !inQuotedString ) { + context = InAngleAddress; + } + else + displayName += *p; + break; + case '\\' : // quoted character + displayName += *p; + ++p; // skip the '\' + if ( *p ) + displayName += *p; + else + //return KPIM::UnexpectedEnd; + goto ABORT_PARSING; + break; + case ',' : if ( !inQuotedString ) { + //if ( allowMultipleAddresses ) + // stop = true; + //else + // return KPIM::UnexpectedComma; + goto ABORT_PARSING; + } + else + displayName += *p; + break; + default : displayName += *p; + } + break; + } + case InComment : { + switch ( *p ) { + case '(' : ++commentLevel; + comment += *p; + break; + case ')' : --commentLevel; + if ( commentLevel == 0 ) { + context = TopLevel; + comment += ' '; // separate the text of several comments + } + else + comment += *p; + break; + case '\\' : // quoted character + comment += *p; + ++p; // skip the '\' + if ( *p ) + comment += *p; + else + //return KPIM::UnexpectedEnd; + goto ABORT_PARSING; + break; + default : comment += *p; + } + break; + } + case InAngleAddress : { + switch ( *p ) { + case '"' : inQuotedString = !inQuotedString; + addrSpec += *p; + break; + case '>' : if ( !inQuotedString ) { + context = TopLevel; + } + else + addrSpec += *p; + break; + case '\\' : // quoted character + addrSpec += *p; + ++p; // skip the '\' + if ( *p ) + addrSpec += *p; + else + //return KPIM::UnexpectedEnd; + goto ABORT_PARSING; + break; + default : addrSpec += *p; + } + break; + } + } // switch ( context ) + } + +ABORT_PARSING: + displayName = displayName.stripWhiteSpace(); + comment = comment.stripWhiteSpace(); + addrSpec = addrSpec.stripWhiteSpace(); + + fullName = QString::fromUtf8( displayName ); + email = QString::fromUtf8( addrSpec ); + + // check for errors + if ( inQuotedString ) + return; // KPIM::UnbalancedQuote; + if ( context == InComment ) + return; // KPIM::UnbalancedParens; + if ( context == InAngleAddress ) + return; // KPIM::UnclosedAngleAddr; + + if ( addrSpec.isEmpty() ) { + if ( displayName.isEmpty() ) + return; // KPIM::NoAddressSpec; + else { + //addrSpec = displayName; + //displayName.truncate( 0 ); + // Address of the form "foo@bar" or "foo@bar (Name)". + email = fullName; + fullName = QString::fromUtf8( comment ); + } + } + + // Check that we do not have any extra characters on the end of the + // strings + unsigned int len = fullName.length(); + if ( fullName[ 0 ] == '"' && fullName[ len - 1 ] == '"' ) + fullName = fullName.mid( 1, len - 2 ); +} + +void Addressee::setResource( Resource *resource ) +{ + detach(); + mData->resource = resource; +} + +Resource *Addressee::resource() const +{ + return mData->resource; +} + +void Addressee::setChanged( bool value ) +{ + detach(); + mData->changed = value; +} + +bool Addressee::changed() const +{ + return mData->changed; +} + +void Addressee::setSortMode( KABC::SortMode *mode ) +{ + mSortMode = mode; +} + +bool Addressee::operator< ( const Addressee &addr ) +{ + if ( !mSortMode ) + return false; + else + return mSortMode->lesser( *this, addr ); +} + +QDataStream &KABC::operator<<( QDataStream &s, const Addressee &a ) +{ + if (!a.mData) return s; + + s << a.uid(); + + --STREAMOUT-- + s << a.mData->phoneNumbers; + s << a.mData->addresses; + s << a.mData->emails; + s << a.mData->categories; + s << a.mData->custom; + s << a.mData->keys; + return s; +} + +QDataStream &KABC::operator>>( QDataStream &s, Addressee &a ) +{ + if (!a.mData) + return s; + + a.detach(); + + s >> a.mData->uid; + + --STREAMIN-- + s >> a.mData->phoneNumbers; + s >> a.mData->addresses; + s >> a.mData->emails; + s >> a.mData->categories; + s >> a.mData->custom; + s >> a.mData->keys; + + a.mData->empty = false; + + return s; +} + +bool matchBinaryPattern( int value, int pattern ) +{ + /** + We want to match all telephonnumbers/addresses which have the bits in the + pattern set. More are allowed. + if pattern == 0 we have a special handling, then we want only those with + exactly no bit set. + */ + if ( pattern == 0 ) + return ( value == 0 ); + else + return ( pattern == ( pattern & value ) ); +} + +template <class L> +bool listEquals( const QValueList<L> &list, const QValueList<L> &pattern ) +{ + if ( list.count() != pattern.count() ) + return false; + + for ( uint i = 0; i < list.count(); ++i ) + if ( pattern.find( list[ i ] ) == pattern.end() ) + return false; + + return true; +} + +bool emailsEquals( const QStringList &list, const QStringList &pattern ) +{ + if ( list.count() != pattern.count() ) + return false; + + if ( list.first() != pattern.first() ) + return false; + + QStringList::ConstIterator it; + for ( it = list.begin(); it != list.end(); ++it ) + if ( pattern.find( *it ) == pattern.end() ) + return false; + + return true; +} diff --git a/kabc/scripts/addressee.src.h b/kabc/scripts/addressee.src.h new file mode 100644 index 000000000..abceb052a --- /dev/null +++ b/kabc/scripts/addressee.src.h @@ -0,0 +1,394 @@ +/* + This file is part of libkabc. + Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KABC_ADDRESSEE_H +#define KABC_ADDRESSEE_H + +#include <qdatetime.h> +#include <qstring.h> +#include <qstringlist.h> +#include <qvaluelist.h> + +#include <ksharedptr.h> +#include <kurl.h> + +#include "address.h" +#include "agent.h" +#include "geo.h" +#include "key.h" +#include "phonenumber.h" +#include "picture.h" +#include "secrecy.h" +#include "sound.h" +#include "timezone.h" + +namespace KABC { + +class Resource; +class Field; +class SortMode; + +/** + @short address book entry + + This class represents an entry in the address book. + + The data of this class is implicitly shared. You can pass this class by value. + + If you need the name of a field for presenting it to the user you should use + the functions ending in Label(). They return a translated string which can be + used as label for the corresponding field. + + About the name fields: + + givenName() is the first name and familyName() the last name. In some + countries the family name comes first, that's the reason for the + naming. formattedName() is the full name with the correct formatting. + It is used as an override, when the correct formatting can't be generated + from the other name fields automatically. + + realName() returns a fully formatted name(). It uses formattedName, if set, + otherwise it constucts the name from the name fields. As fallback, if + nothing else is set it uses name(). + + name() is the NAME type of RFC2426. It can be used as internal name for the + data enty, but shouldn't be used for displaying the data to the user. + */ +class KABC_EXPORT Addressee +{ + friend KABC_EXPORT QDataStream &operator<<( QDataStream &, const Addressee & ); + friend KABC_EXPORT QDataStream &operator>>( QDataStream &, Addressee & ); + + public: + typedef QValueList<Addressee> List; + typedef QMap<QString, Addressee> Map; + + /** + Construct an empty address book entry. + */ + Addressee(); + ~Addressee(); + + Addressee( const Addressee & ); + Addressee &operator=( const Addressee & ); + + bool operator==( const Addressee & ) const; + bool operator!=( const Addressee & ) const; + + /** + Return, if the address book entry is empty. + */ + bool isEmpty() const; + + /** + Set unique identifier. + */ + void setUid( const QString &uid ); + /** + Return unique identifier. + */ + QString uid() const; + /** + Return translated label for uid field. + */ + static QString uidLabel(); + + --DECLARATIONS-- + /** + Set name fields by parsing the given string and trying to associate the + parts of the string with according fields. This function should probably + be a bit more clever. + */ + void setNameFromString( const QString & ); + + /** + Return the name of the addressee. This is calculated from all the name + fields. + */ + QString realName() const; + + /** + Return the name that consists of all name parts. + */ + QString assembledName() const; + + /** + Return email address including real name. + + @param email Email address to be used to construct the full email string. + If this is QString::null the preferred email address is used. + */ + QString fullEmail( const QString &email=QString::null ) const; + + /** + Insert an email address. If the email address already exists in this + addressee it is not duplicated. + + @param email Email address + @param preferred Set to true, if this is the preferred email address of + the addressee. + */ + void insertEmail( const QString &email, bool preferred=false ); + + /** + Remove email address. If the email address doesn't exist, nothing happens. + */ + void removeEmail( const QString &email ); + + /** + Return preferred email address. This is the first email address or the + last one added with insertEmail() with a set preferred parameter. + */ + QString preferredEmail() const; + + /** + Return list of all email addresses. + */ + QStringList emails() const; + + /** + Set the emails to @p list. + The first email address gets the preferred one! + @param list The list of email addresses. + */ + void setEmails( const QStringList& list); + + /** + Insert a phone number. If a phone number with the same id already exists + in this addressee it is not duplicated. + */ + void insertPhoneNumber( const PhoneNumber &phoneNumber ); + + /** + Remove phone number. If no phone number with the given id exists for this + addresse nothing happens. + */ + void removePhoneNumber( const PhoneNumber &phoneNumber ); + + /** + Return phone number, which matches the given type. + */ + PhoneNumber phoneNumber( int type ) const; + + /** + Return list of all phone numbers. + */ + PhoneNumber::List phoneNumbers() const; + + /** + Return list of phone numbers with a special type. + */ + PhoneNumber::List phoneNumbers( int type ) const; + + /** + Return phone number with the given id. + */ + PhoneNumber findPhoneNumber( const QString &id ) const; + + /** + Insert a key. If a key with the same id already exists + in this addressee it is not duplicated. + */ + void insertKey( const Key &key ); + + /** + Remove a key. If no key with the given id exists for this + addresse nothing happens. + */ + void removeKey( const Key &key ); + + /** + Return key, which matches the given type. + If @p type == Key::Custom you can specify a string + that should match. If you leave the string empty, the first + key with a custom value is returned. + */ + Key key( int type, QString customTypeString = QString::null ) const; + + /** + Return list of all keys. + */ + Key::List keys() const; + + /** + Set the list of keys + @param keys The keys to be set. + */ + void setKeys( const Key::List& keys); + + /** + Return list of keys with a special type. + If @p type == Key::Custom you can specify a string + that should match. If you leave the string empty, all custom + keys will be returned. + */ + Key::List keys( int type, QString customTypeString = QString::null ) const; + + /** + Return key with the given id. + */ + Key findKey( const QString &id ) const; + + /** + Insert an address. If an address with the same id already exists + in this addressee it is not duplicated. + */ + void insertAddress( const Address &address ); + + /** + Remove address. If no address with the given id exists for this + addresse nothing happens. + */ + void removeAddress( const Address &address ); + + /** + Return address, which matches the given type. + */ + Address address( int type ) const; + + /** + Return list of all addresses. + */ + Address::List addresses() const; + + /** + Return list of addresses with a special type. + */ + Address::List addresses( int type ) const; + + /** + Return address with the given id. + */ + Address findAddress( const QString &id ) const; + + /** + Insert category. If the category already exists it is not duplicated. + */ + void insertCategory( const QString & ); + + /** + Remove category. + */ + void removeCategory( const QString & ); + + /** + Return, if addressee has the given category. + */ + bool hasCategory( const QString & ) const; + + /** + Set categories to given value. + */ + void setCategories( const QStringList & ); + + /** + Return list of all set categories. + */ + QStringList categories() const; + + /** + Insert custom entry. The entry is identified by the name of the inserting + application and a unique name. If an entry with the given app and name + already exists its value is replaced with the new given value. + + An empty value isn't allowed (nothing happens if this is called with + any of the three arguments being empty) + */ + void insertCustom( const QString &app, const QString &name, + const QString &value ); + + /** + Remove custom entry. + */ + void removeCustom( const QString &app, const QString &name ); + + /** + Return value of custom entry, identified by app and entry name. + */ + QString custom( const QString &app, const QString &name ) const; + + /** + Set all custom entries. + */ + void setCustoms( const QStringList & ); + + /** + Return list of all custom entries. + */ + QStringList customs() const; + + /** + Parse full email address. The result is given back in fullName and email. + */ + static void parseEmailAddress( const QString &rawEmail, QString &fullName, + QString &email ); + + /** + Debug output. + */ + void dump() const; + + /** + Returns string representation of the addressee. + */ + QString asString() const; + + /** + Set resource where the addressee is from. + */ + void setResource( Resource *resource ); + + /** + Return pointer to resource. + */ + Resource *resource() const; + + /** + Mark addressee as changed. + */ + void setChanged( bool value ); + + /** + Return whether the addressee is changed. + */ + bool changed() const; + + static void setSortMode( KABC::SortMode *mode ); + + bool operator< ( const Addressee &addr ); + + private: + void detach(); + + struct AddresseeData; + mutable KSharedPtr<AddresseeData> mData; + + private: + static AddresseeData* shared_null; + static AddresseeData* makeSharedNull(); + static KABC::SortMode *mSortMode; +}; + +KABC_EXPORT QDataStream &operator<<( QDataStream &, const Addressee & ); +KABC_EXPORT QDataStream &operator>>( QDataStream &, Addressee & ); + +} + +#endif diff --git a/kabc/scripts/createisomap.pl b/kabc/scripts/createisomap.pl new file mode 100755 index 000000000..2734db111 --- /dev/null +++ b/kabc/scripts/createisomap.pl @@ -0,0 +1,35 @@ +#!/usr/bin/perl +# +# Create a translation table countryname->iso-code from the entry.desktop +# files in kdebase/l10n/*/ +# +# USAGE EXAMPLE: +# ./createisomap.pl $KDEDIR/share/locale/l10n > countrytransl.map +# +# Don't laugh at me. I put this together with an old perl book, perl +# being a language I've never used before. + +@entries = <$ARGV[0]/*/entry.desktop>; +chomp @entries; +foreach $entry (@entries) { + local ( $entryiso, @entryfile, @mappings ); + # print "--> $entry\n"; + $entryiso = $entry; + $entryiso =~ s/$ARGV[0]\///; + $entryiso =~ s/\/entry\.desktop//; + # print " $entryiso\n"; + open (IN, $entry); + @entryfile = <IN>; + close IN; + chomp @entryfile; + foreach $entryfileline (@entryfile) { + if ( $entryfileline =~ /^Name.*=(.*)$/ ) { + # push (@mappings, $1 . "\t" . $entryiso ); + print "$1\t$entryiso\n"; + } + } +} + +# add some convenience entries which aren't part of the entry.desktop files + +print "Czech Republic\tcz\n"; diff --git a/kabc/scripts/entrylist b/kabc/scripts/entrylist new file mode 100644 index 000000000..7b9b324eb --- /dev/null +++ b/kabc/scripts/entrylist @@ -0,0 +1,84 @@ +# This file describes the fields of an address book entry. +# +# The following comma-separated fields are used: +# +# Control: A generates accessor functions. +# L generates a static function for returning a tranlsated label +# F generates a Field id and object for generic field handling +# E generate an equality test in Addressee::operator==(). +# Field Name : A descriptive name which is shown to the user. +# Comment : A comment helping translators to understand the field name +# Type : C++ type of field. +# Identifier : A string used in code as variable name etc. +# Field Category : Categories the field belongs to (see Field::FieldCategory). +# Output function: Function used to convert type to string for debug output (optional) + +ALE,name,,QString,name + +ALFE,formatted name,,QString,formattedName,Frequent + +ALFE,family name,,QString,familyName,Frequent +ALFE,given name,,QString,givenName,Frequent +ALFE,additional names,,QString,additionalName +ALFE,honorific prefixes,,QString,prefix +ALFE,honorific suffixes,,QString,suffix + +ALFE,nick name,,QString,nickName,Personal + +ALFE,birthday,,QDateTime,birthday,Personal,.toString() + +#Address address +LF,home address street,,QString,homeAddressStreet,Address|Personal +LF,home address post office box,,QString,homeAddressPostOfficeBox,Address|Personal +LF,home address city,,QString,homeAddressLocality,Address|Personal +LF,home address state,,QString,homeAddressRegion,Address|Personal +LF,home address zip code,,QString,homeAddressPostalCode,Address|Personal +LF,home address country,,QString,homeAddressCountry,Address|Personal +LF,home address label,,QString,homeAddressLabel,Address|Personal + +LF,business address street,,QString,businessAddressStreet,Address|Organization +LF,business address post office box,,QString,businessAddressPostOfficeBox,Address|Organization +LF,business address city,,QString,businessAddressLocality,Address|Organization +LF,business address state,,QString,businessAddressRegion,Address|Organization +LF,business address zip code,,QString,businessAddressPostalCode,Address|Organization +LF,business address country,,QString,businessAddressCountry,Address|Organization +LF,business address label,,QString,businessAddressLabel,Address|Organization + +#phoneNumbers +LF,home phone,,QString,homePhone,Personal|Frequent +LF,business phone,,QString,businessPhone,Organization|Frequent +LF,mobile phone,,QString,mobilePhone,Frequent +LF,home fax,,QString,homeFax +LF,business fax,,QString,businessFax +LF,car phone,,QString,carPhone +LF,ISDN,,QString,isdn +LF,pager,,QString,pager + +#emails +LF,email address,,QString,email,Email|Frequent + +ALFE,mail client,,QString,mailer,Email + +ALE,time zone,,TimeZone,timeZone,,.asString() +ALE,geographic position,,Geo,geo,,.asString() + +ALFE,title,person,QString,title,Organization +ALFE,role,person in organization,QString,role,Organization +ALFE,organization,,QString,organization,Organization +ALFE,department,,QString,department,Organization + +ALFE,note,,QString,note + +ALE,product identifier,,QString,productId +ALE,revision date,,QDateTime,revision,,.toString() + +ALE,sort string,,QString,sortString + +ALF,homepage,,KURL,url,,.url() + +ALE,security class,,Secrecy,secrecy,,.asString() + +ALE,logo,,Picture,logo,,.asString() +ALE,photo,,Picture,photo,,.asString() +ALE,sound,,Sound,sound,,.asString() +ALE,agent,,Agent,agent,,.asString() diff --git a/kabc/scripts/field.src.cpp b/kabc/scripts/field.src.cpp new file mode 100644 index 000000000..205ddaa06 --- /dev/null +++ b/kabc/scripts/field.src.cpp @@ -0,0 +1,530 @@ +/* + This file is part of libkabc. + Copyright (c) 2002 Cornelius Schumacher <schumacher@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include <klocale.h> +#include <kconfig.h> +#include <kglobal.h> + +#include "field.h" +#include "address.h" + +using namespace KABC; + +class Field::FieldImpl +{ + public: + FieldImpl( int fieldId, int category = 0, + const QString &label = QString::null, + const QString &key = QString::null, + const QString &app = QString::null ) + : mFieldId( fieldId ), mCategory( category ), mLabel( label ), + mKey( key ), mApp( app ) {} + + enum FieldId + { + CustomField, + --ENUMS-- + }; + + int fieldId() { return mFieldId; } + int category() { return mCategory; } + + QString label() { return mLabel; } + QString key() { return mKey; } + QString app() { return mApp; } + + private: + int mFieldId; + int mCategory; + + QString mLabel; + QString mKey; + QString mApp; +}; + + +Field::List Field::mAllFields; +Field::List Field::mDefaultFields; +Field::List Field::mCustomFields; + + +Field::Field( FieldImpl *impl ) +{ + mImpl = impl; +} + +Field::~Field() +{ + delete mImpl; +} + +QString Field::label() +{ + switch ( mImpl->fieldId() ) { + --CASELABEL-- + case FieldImpl::CustomField: + return mImpl->label(); + default: + return i18n("Unknown Field"); + } +} + +int Field::category() +{ + return mImpl->category(); +} + +QString Field::categoryLabel( int category ) +{ + switch ( category ) { + case All: + return i18n("All"); + case Frequent: + return i18n("Frequent"); + case Address: + return i18n("street/postal","Address"); + case Email: + return i18n("Email"); + case Personal: + return i18n("Personal"); + case Organization: + return i18n("Organization"); + case CustomCategory: + return i18n("Custom"); + default: + return i18n("Undefined"); + } +} + +QString Field::value( const KABC::Addressee &a ) +{ + switch ( mImpl->fieldId() ) { + --CASEVALUE-- + case FieldImpl::Email: + return a.preferredEmail(); + case FieldImpl::Birthday: + if ( a.birthday().isValid() ) + return a.birthday().date().toString( Qt::ISODate ); + else + return QString::null; + case FieldImpl::Url: + return a.url().prettyURL(); + case FieldImpl::HomePhone: + { + PhoneNumber::List::ConstIterator it; + + { + // check for preferred number + const PhoneNumber::List list = a.phoneNumbers( PhoneNumber::Home | PhoneNumber::Pref ); + for ( it = list.begin(); it != list.end(); ++it ) + if ( ((*it).type() & ~(PhoneNumber::Pref)) == PhoneNumber::Home ) + return (*it).number(); + } + + { + // check for normal home number + const PhoneNumber::List list = a.phoneNumbers( PhoneNumber::Home ); + for ( it = list.begin(); it != list.end(); ++it ) + if ( ((*it).type() & ~(PhoneNumber::Pref)) == PhoneNumber::Home ) + return (*it).number(); + } + + return QString::null; + } + case FieldImpl::BusinessPhone: + { + PhoneNumber::List::ConstIterator it; + + { + // check for preferred number + const PhoneNumber::List list = a.phoneNumbers( PhoneNumber::Work | PhoneNumber::Pref ); + for ( it = list.begin(); it != list.end(); ++it ) + if ( ((*it).type() & ~(PhoneNumber::Pref)) == PhoneNumber::Work ) + return (*it).number(); + } + + { + // check for normal work number + const PhoneNumber::List list = a.phoneNumbers( PhoneNumber::Work ); + for ( it = list.begin(); it != list.end(); ++it ) + if ( ((*it).type() & ~(PhoneNumber::Pref)) == PhoneNumber::Work ) + return (*it).number(); + } + + return QString::null; + } + case FieldImpl::MobilePhone: + return a.phoneNumber( PhoneNumber::Cell ).number(); + case FieldImpl::HomeFax: + return a.phoneNumber( PhoneNumber::Home | PhoneNumber::Fax ).number(); + case FieldImpl::BusinessFax: + return a.phoneNumber( PhoneNumber::Work | PhoneNumber::Fax ).number(); + case FieldImpl::CarPhone: + return a.phoneNumber( PhoneNumber::Car ).number(); + case FieldImpl::Isdn: + return a.phoneNumber( PhoneNumber::Isdn ).number(); + case FieldImpl::Pager: + return a.phoneNumber( PhoneNumber::Pager ).number(); + case FieldImpl::HomeAddressStreet: + return a.address( Address::Home ).street(); + case FieldImpl::HomeAddressPostOfficeBox: + return a.address( Address::Home ).postOfficeBox(); + case FieldImpl::HomeAddressLocality: + return a.address( Address::Home ).locality(); + case FieldImpl::HomeAddressRegion: + return a.address( Address::Home ).region(); + case FieldImpl::HomeAddressPostalCode: + return a.address( Address::Home ).postalCode(); + case FieldImpl::HomeAddressCountry: + return a.address( Address::Home ).country(); + case FieldImpl::HomeAddressLabel: + return a.address( Address::Home ).label(); + case FieldImpl::BusinessAddressStreet: + return a.address( Address::Work ).street(); + case FieldImpl::BusinessAddressPostOfficeBox: + return a.address( Address::Work ).postOfficeBox(); + case FieldImpl::BusinessAddressLocality: + return a.address( Address::Work ).locality(); + case FieldImpl::BusinessAddressRegion: + return a.address( Address::Work ).region(); + case FieldImpl::BusinessAddressPostalCode: + return a.address( Address::Work ).postalCode(); + case FieldImpl::BusinessAddressCountry: + return a.address( Address::Work ).country(); + case FieldImpl::BusinessAddressLabel: + return a.address( Address::Work ).label(); + case FieldImpl::CustomField: + return a.custom( mImpl->app(), mImpl->key() ); + default: + return QString::null; + } +} + +bool Field::setValue( KABC::Addressee &a, const QString &value ) +{ + switch ( mImpl->fieldId() ) { + --CASESETVALUE-- + case FieldImpl::MobilePhone: + { + PhoneNumber number = a.phoneNumber( PhoneNumber::Cell ); + number.setNumber( value ); + a.insertPhoneNumber( number ); + return true; + } + case FieldImpl::HomeFax: + { + PhoneNumber number = a.phoneNumber( PhoneNumber::Home | PhoneNumber::Fax ); + number.setNumber( value ); + a.insertPhoneNumber( number ); + return true; + } + case FieldImpl::BusinessFax: + { + PhoneNumber number = a.phoneNumber( PhoneNumber::Work | PhoneNumber::Fax ); + number.setNumber( value ); + a.insertPhoneNumber( number ); + return true; + } + case FieldImpl::CarPhone: + { + PhoneNumber number = a.phoneNumber( PhoneNumber::Car ); + number.setNumber( value ); + a.insertPhoneNumber( number ); + return true; + } + case FieldImpl::Isdn: + { + PhoneNumber number = a.phoneNumber( PhoneNumber::Isdn ); + number.setNumber( value ); + a.insertPhoneNumber( number ); + return true; + } + case FieldImpl::Pager: + { + PhoneNumber number = a.phoneNumber( PhoneNumber::Pager ); + number.setNumber( value ); + a.insertPhoneNumber( number ); + return true; + } + case FieldImpl::HomeAddressStreet: + { + KABC::Address address = a.address( Address::Home ); + address.setStreet( value ); + a.insertAddress( address ); + return true; + } + case FieldImpl::HomeAddressPostOfficeBox: + { + KABC::Address address = a.address( Address::Home ); + address.setPostOfficeBox( value ); + a.insertAddress( address ); + return true; + } + case FieldImpl::HomeAddressLocality: + { + KABC::Address address = a.address( Address::Home ); + address.setLocality( value ); + a.insertAddress( address ); + return true; + } + case FieldImpl::HomeAddressRegion: + { + KABC::Address address = a.address( Address::Home ); + address.setRegion( value ); + a.insertAddress( address ); + return true; + } + case FieldImpl::HomeAddressPostalCode: + { + KABC::Address address = a.address( Address::Home ); + address.setPostalCode( value ); + a.insertAddress( address ); + return true; + } + case FieldImpl::HomeAddressCountry: + { + KABC::Address address = a.address( Address::Home ); + address.setCountry( value ); + a.insertAddress( address ); + return true; + } + case FieldImpl::HomeAddressLabel: + { + KABC::Address address = a.address( Address::Home ); + address.setLabel( value ); + a.insertAddress( address ); + return true; + } + case FieldImpl::BusinessAddressStreet: + { + KABC::Address address = a.address( Address::Work ); + address.setStreet( value ); + a.insertAddress( address ); + return true; + } + case FieldImpl::BusinessAddressPostOfficeBox: + { + KABC::Address address = a.address( Address::Work ); + address.setPostOfficeBox( value ); + a.insertAddress( address ); + return true; + } + case FieldImpl::BusinessAddressLocality: + { + KABC::Address address = a.address( Address::Work ); + address.setLocality( value ); + a.insertAddress( address ); + return true; + } + case FieldImpl::BusinessAddressRegion: + { + KABC::Address address = a.address( Address::Work ); + address.setRegion( value ); + a.insertAddress( address ); + return true; + } + case FieldImpl::BusinessAddressPostalCode: + { + KABC::Address address = a.address( Address::Work ); + address.setPostalCode( value ); + a.insertAddress( address ); + return true; + } + case FieldImpl::BusinessAddressCountry: + { + KABC::Address address = a.address( Address::Work ); + address.setCountry( value ); + a.insertAddress( address ); + return true; + } + case FieldImpl::BusinessAddressLabel: + { + KABC::Address address = a.address( Address::Work ); + address.setLabel( value ); + a.insertAddress( address ); + return true; + } + case FieldImpl::Birthday: + a.setBirthday( QDate::fromString( value, Qt::ISODate ) ); + return true; + case FieldImpl::CustomField: + a.insertCustom( mImpl->app(), mImpl->key(), value ); + return true; + default: + return false; + } +} + +QString Field::sortKey( const KABC::Addressee &a ) +{ + switch ( mImpl->fieldId() ) { + --CASEVALUE-- + case FieldImpl::Birthday: + if ( a.birthday().isValid() ) { + QDate date = a.birthday().date(); + QString key; + key.sprintf( "%02d-%02d", date.month(), date.day() ); + return key; + } else + return QString( "00-00" ); + default: + return value( a ).lower(); + } +} + +bool Field::isCustom() +{ + return mImpl->fieldId() == FieldImpl::CustomField; +} + +Field::List Field::allFields() +{ + if ( mAllFields.isEmpty() ) { + --CREATEFIELDS-- + } + + return mAllFields; +} + +Field::List Field::defaultFields() +{ + if ( mDefaultFields.isEmpty() ) { + createDefaultField( FieldImpl::FormattedName ); + createDefaultField( FieldImpl::Email ); + } + + return mDefaultFields; +} + +void Field::createField( int id, int category ) +{ + mAllFields.append( new Field( new FieldImpl( id, category ) ) ); +} + +void Field::createDefaultField( int id, int category ) +{ + mDefaultFields.append( new Field( new FieldImpl( id, category ) ) ); +} + +void Field::deleteFields() +{ + Field::List::ConstIterator it; + + for ( it = mAllFields.constBegin(); it != mAllFields.constEnd(); ++it ) { + delete (*it); + } + mAllFields.clear(); + + for ( it = mDefaultFields.constBegin(); it != mDefaultFields.constEnd(); ++it ) { + delete (*it); + } + mDefaultFields.clear(); + + for ( it = mCustomFields.constBegin(); it != mCustomFields.constEnd(); ++it ) { + delete (*it); + } + mCustomFields.clear(); +} + +void Field::saveFields( const QString &identifier, + const Field::List &fields ) +{ + KConfig *cfg = KGlobal::config(); + KConfigGroupSaver( cfg, "KABCFields" ); + + saveFields( cfg, identifier, fields ); +} + +void Field::saveFields( KConfig *cfg, const QString &identifier, + const Field::List &fields ) +{ + QValueList<int> fieldIds; + + int custom = 0; + Field::List::ConstIterator it; + for( it = fields.begin(); it != fields.end(); ++it ) { + fieldIds.append( (*it)->mImpl->fieldId() ); + if( (*it)->isCustom() ) { + QStringList customEntry; + customEntry << (*it)->mImpl->label(); + customEntry << (*it)->mImpl->key(); + customEntry << (*it)->mImpl->app(); + cfg->writeEntry( "KABC_CustomEntry_" + identifier + "_" + + QString::number( custom++ ), customEntry ); + } + } + + cfg->writeEntry( identifier, fieldIds ); +} + +Field::List Field::restoreFields( const QString &identifier ) +{ + KConfig *cfg = KGlobal::config(); + KConfigGroupSaver( cfg, "KABCFields" ); + + return restoreFields( cfg, identifier ); +} + +Field::List Field::restoreFields( KConfig *cfg, const QString &identifier ) +{ + const QValueList<int> fieldIds = cfg->readIntListEntry( identifier ); + + Field::List fields; + + int custom = 0; + QValueList<int>::ConstIterator it; + for( it = fieldIds.begin(); it != fieldIds.end(); ++it ) { + FieldImpl *f = 0; + if ( (*it) == FieldImpl::CustomField ) { + QStringList customEntry = cfg->readListEntry( "KABC_CustomEntry_" + + identifier + "_" + + QString::number( custom++ ) ); + f = new FieldImpl( *it, CustomCategory, customEntry[ 0 ], + customEntry[ 1 ], customEntry[ 2 ] ); + } else { + f = new FieldImpl( *it ); + } + fields.append( new Field( f ) ); + } + + return fields; +} + +bool Field::equals( Field *field ) +{ + bool sameId = ( mImpl->fieldId() == field->mImpl->fieldId() ); + + if ( !sameId ) return false; + + if ( mImpl->fieldId() != FieldImpl::CustomField ) return true; + + return mImpl->key() == field->mImpl->key(); +} + +Field *Field::createCustomField( const QString &label, int category, + const QString &key, const QString &app ) +{ + Field *field = new Field( new FieldImpl( FieldImpl::CustomField, + category | CustomCategory, + label, key, app ) ); + mCustomFields.append( field ); + + return field; +} diff --git a/kabc/scripts/makeaddressee b/kabc/scripts/makeaddressee new file mode 100755 index 000000000..cbc69543a --- /dev/null +++ b/kabc/scripts/makeaddressee @@ -0,0 +1,215 @@ +#!/usr/bin/perl + +my $srcdir; +$srcdir = `dirname $0` || die "Can't determine \$srcdir."; +chomp $srcdir; + +if (!open( ENTRIES, "$srcdir/entrylist" ) ) { + print "Can't open $srcdir/entrylist\n"; + exit 1; +} + + while(<ENTRIES>) { + if (/^#/) { next; } + chop; + @entries = split /,/; + if (!/^.+,(\w+),(\w+)/) { next; } + push @entryCtrl, @entries[0]; + push @entryRealNames, @entries[1]; + push @entryComments, @entries[2]; + push @entryTypes, @entries[3]; + push @entryNames, @entries[4]; + push @entryCategory, @entries[5]; + push @entryDebug, @entries[6]; + } + +close ENTRIES; + +if (!open( H_IN, "$srcdir/addressee.src.h" ) ) { + print "Can't open $srcdir/addressee.src.h\n"; + exit 1; +} +if (!open( H_OUT, ">../addressee.h" ) ) { + print "Can't open addressee.h\n"; + exit 1; +} + print H_OUT "/*** Warning! This file has been generated by the script makeaddressee ***/\n"; + + while( <H_IN> ) { + if (/--DECLARATIONS--/) { + for( $i=0; $i<@entryNames; ++$i ) { + if ( $entryCtrl[$i] =~ /A/ ) { + print H_OUT " /**\n"; + print H_OUT " Set $entryRealNames[$i].\n"; + print H_OUT " */\n"; + print H_OUT " void set" . ucfirst($entryNames[$i]); + print H_OUT "( const $entryTypes[$i] &$entryNames[$i] );\n"; + + print H_OUT " /**\n"; + print H_OUT " Return $entryRealNames[$i].\n"; + print H_OUT " */\n"; + print H_OUT " $entryTypes[$i] $entryNames[$i]() const;\n"; + } + + if ( $entryCtrl[$i] !~ /L/ ) { next; } + print H_OUT " /**\n"; + print H_OUT " Return translated label for $entryNames[$i] field.\n"; + print H_OUT " */\n"; + print H_OUT " static QString $entryNames[$i]Label();\n\n"; + } + } else { + print H_OUT; + } + } + +close H_OUT; +close H_IN; + +if (!open( CPP_IN, "$srcdir/addressee.src.cpp" ) ) { + print "Can't open $srcdir/addressee.src.cpp\n"; + exit 1; +} +if (!open( CPP_OUT, ">../addressee.cpp" ) ) { + print "Can't open addressee.cpp\n"; + exit 1; +} + print CPP_OUT "/*** Warning! This file has been generated by the script makeaddressee ***/\n"; + + while( <CPP_IN> ) { + if (/--VARIABLES--/) { + for( $i=0; $i<@entryNames; ++$i ) { + if ( $entryCtrl[$i] !~ /A/ ) { next; } + print CPP_OUT " $entryTypes[$i] $entryNames[$i];\n"; + } + } elsif (/--DEFINITIONS--/) { + for( $i=0; $i<@entryNames; ++$i ) { + if ( $entryCtrl[$i] =~ /A/ ) { + print CPP_OUT "void Addressee::set" . ucfirst($entryNames[$i]); + print CPP_OUT "( const $entryTypes[$i] &$entryNames[$i] )\n{\n"; + print CPP_OUT " if ( $entryNames[$i] == mData->$entryNames[$i] ) return;\n"; + print CPP_OUT " detach();\n mData->empty = false;\n"; + print CPP_OUT " mData->$entryNames[$i] = $entryNames[$i];\n}\n\n"; + + print CPP_OUT "$entryTypes[$i] Addressee::$entryNames[$i]() const\n{\n"; + print CPP_OUT " return mData->$entryNames[$i];\n}\n\n"; + } + + if ( $entryCtrl[$i] !~ /L/ ) { next; } + @labelwords = split ' ', $entryRealNames[$i]; + for( $j=0; $j < @labelwords; ++$j ) { + $labelwords[$j] = ucfirst $labelwords[$j]; + } + $label = join ' ', @labelwords; + print CPP_OUT "QString Addressee::$entryNames[$i]Label()\n{\n"; + if ( $entryComments[$i] ) { + print CPP_OUT " return i18n(\"$entryComments[$i]\",\"$label\");\n"; + } else { + print CPP_OUT " return i18n(\"$label\");\n"; + } + print CPP_OUT "}\n\n\n"; + } + } elsif (/--EQUALSTEST--/) { + for( $i=0; $i<@entryNames; ++$i ) { + if ( $entryCtrl[$i] =~ /E/ ) { + if ( $entryNames[$i] !~ "revision" ) { + if ( $entryTypes[$i] =~ "QString" ) { + print CPP_OUT " if ( mData->$entryNames[$i] != a.mData->$entryNames[$i] &&\n"; + print CPP_OUT " !( mData->$entryNames[$i].isEmpty() && a.mData->$entryNames[$i].isEmpty() ) ) {\n"; + print CPP_OUT " kdDebug(5700) << \"$entryNames[$i] differs\" << endl;\n"; + print CPP_OUT " return false;\n"; + print CPP_OUT " }\n"; + } else { + print CPP_OUT " if ( mData->$entryNames[$i] != a.mData->$entryNames[$i] ) {\n"; + print CPP_OUT " kdDebug(5700) << \"$entryNames[$i] differs\" << endl;\n"; + print CPP_OUT " return false;\n"; + print CPP_OUT " }\n"; + } + } + } + } + } elsif (/--STREAMOUT--/) { + for( $i=0; $i<@entryNames; ++$i ) { + if ( $entryCtrl[$i] =~ /A/ ) { + print CPP_OUT " s << a.mData->$entryNames[$i];\n"; + } + } + } elsif (/--STREAMIN--/) { + for( $i=0; $i<@entryNames; ++$i ) { + if ( $entryCtrl[$i] =~ /A/ ) { + print CPP_OUT " s >> a.mData->$entryNames[$i];\n"; + } + } + } elsif (/--DEBUG--/) { + for( $i=0; $i<@entryNames; ++$i ) { + if ( $entryCtrl[$i] !~ /A/ ) { next; } + print CPP_OUT " kdDebug(5700) << \" " . ucfirst($entryNames[$i]); + print CPP_OUT ": '\" << $entryNames[$i]()$entryDebug[$i] << \"'\" << endl;\n"; + } + } else { + print CPP_OUT; + } + } + +close CPP_OUT; +close CPP_IN; + +if (!open( CPP_IN, "$srcdir/field.src.cpp" ) ) { + print "Can't open $srcdir/field.src.cpp\n"; + exit 1; +} +if (!open( CPP_OUT, ">../field.cpp" ) ) { + print "Can't open field.cpp\n"; + exit 1; +} + print CPP_OUT "/*** Warning! This file has been generated by the script makeaddressee ***/\n"; + + while( <CPP_IN> ) { + if (/--ENUMS--/) { + $first = 1; + for( $i=0; $i<@entryNames; ++$i ) { + if ( $entryCtrl[$i] !~ /F/ ) { next; } + if ( $first ) { $first = 0; } + else { print CPP_OUT ",\n"; } + print CPP_OUT " " . ucfirst($entryNames[$i]); + } + print CPP_OUT "\n"; + } elsif (/--CASELABEL--/) { + for( $i=0; $i<@entryNames; ++$i ) { + if ( $entryCtrl[$i] !~ /F/ ) { next; } + if ( $entryCtrl[$i] !~ /L/ ) { next; } + print CPP_OUT " case FieldImpl::" . ucfirst($entryNames[$i]) . ":\n"; + print CPP_OUT " return Addressee::$entryNames[$i]Label();\n"; + } + } elsif (/--CASEVALUE--/) { + for( $i=0; $i<@entryNames; ++$i ) { + if ( $entryCtrl[$i] !~ /A/ ) { next; } + if ( $entryCtrl[$i] !~ /F/ ) { next; } + if ( $entryTypes[$i] ne "QString" ) { next; } + print CPP_OUT " case FieldImpl::" . ucfirst($entryNames[$i]) . ":\n"; + print CPP_OUT " return a.$entryNames[$i]();\n"; + } + } elsif (/--CASESETVALUE--/) { + for( $i=0; $i<@entryNames; ++$i ) { + if ( $entryCtrl[$i] !~ /A/ ) { next; } + if ( $entryCtrl[$i] !~ /F/ ) { next; } + if ( $entryTypes[$i] ne "QString" ) { next; } + print CPP_OUT " case FieldImpl::" . ucfirst($entryNames[$i]) . ":\n"; + print CPP_OUT " a.set" . ucfirst($entryNames[$i]) . "( value );\n"; + print CPP_OUT " return true;\n"; + } + } elsif (/--CREATEFIELDS--/) { + for( $i=0; $i<@entryNames; ++$i ) { + if ( $entryCtrl[$i] !~ /F/ ) { next; } + print CPP_OUT " createField( FieldImpl::" . ucfirst($entryNames[$i]); + if ( $entryCategory[$i] ) { + print CPP_OUT ", $entryCategory[$i]"; + } + print CPP_OUT " );\n"; + } + } else { + print CPP_OUT; + } + } + +close CPP_OUT; +close CPP_IN; |