diff --git a/kabc/address.cpp b/kabc/address.cpp index 2e4198349..6268b66ea 100644 --- a/kabc/address.cpp +++ b/kabc/address.cpp @@ -1,695 +1,697 @@ /* This file is part of libkabc. Copyright (c) 2001 Cornelius Schumacher 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 "address.h" #include #include #include #include #include #include #include #include #include #include using namespace KABC; // template tags for address formatting localization #define KABC_FMTTAG_realname QString::fromLatin1("%n") #define KABC_FMTTAG_REALNAME QString::fromLatin1("%N") #define KABC_FMTTAG_company QString::fromLatin1("%cm") #define KABC_FMTTAG_COMPANY QString::fromLatin1("%CM") #define KABC_FMTTAG_pobox QString::fromLatin1("%p") #define KABC_FMTTAG_street QString::fromLatin1("%s") #define KABC_FMTTAG_STREET QString::fromLatin1("%S") #define KABC_FMTTAG_zipcode QString::fromLatin1("%z") #define KABC_FMTTAG_location QString::fromLatin1("%l") #define KABC_FMTTAG_LOCATION QString::fromLatin1("%L") #define KABC_FMTTAG_region QString::fromLatin1("%r") #define KABC_FMTTAG_REGION QString::fromLatin1("%R") #define KABC_FMTTAG_newline QString::fromLatin1("\\n") #define KABC_FMTTAG_condcomma QString::fromLatin1("%,") #define KABC_FMTTAG_condwhite QString::fromLatin1("%w") #define KABC_FMTTAG_purgeempty QString::fromLatin1("%0") /** Finds the balanced closing bracket starting from the opening bracket at pos in tsection. @return position of closing bracket, -1 for unbalanced brackets */ static int findBalancedBracket( const QString &tsection, int pos ) { int balancecounter = 0; for ( int i = pos + 1; i < tsection.length(); ++i ) { if ( QLatin1Char( ')' ) == tsection[i] && 0 == balancecounter ) { // found end of brackets return i; } else { if ( QLatin1Char( '(' ) == tsection[i] ) { // nested brackets balancecounter++; } } } return -1; } /** Parses a snippet of an address template @param tsection the template string to be parsed @param result QString reference in which the result will be stored @return true if at least one tag evaluated positively, else false */ static bool parseAddressTemplateSection( const QString &tsection, QString &result, const QString &realName, const QString &orgaName, const KABC::Address &address ) { // This method first parses and substitutes any bracketed sections and // after that replaces any tags with their values. If a bracketed section // or a tag evaluate to zero, they are not just removed but replaced // with a placeholder. This is because in the last step conditionals are // resolved which depend on information about zero-evaluations. result = tsection; int stpos = 0; bool ret = false; // first check for brackets that have to be evaluated first int fpos = result.indexOf( KABC_FMTTAG_purgeempty, stpos ); while ( -1 != fpos ) { int bpos1 = fpos + KABC_FMTTAG_purgeempty.length(); int bpos2; // expect opening bracket and find next balanced closing bracket. If // next char is no opening bracket, continue parsing (no valid tag) if ( QLatin1Char( '(' ) == result[bpos1] ) { bpos2 = findBalancedBracket( result, bpos1 ); if ( -1 != bpos2 ) { // we have balanced brackets, recursively parse: QString rplstr; bool purge = !parseAddressTemplateSection( result.mid( bpos1+1, bpos2-bpos1-1 ), rplstr, realName, orgaName, address ); if ( purge ) { // purge -> remove all // replace with !_P_!, so conditional tags work later result.replace( fpos, bpos2 - fpos + 1, QLatin1String( "!_P_!" ) ); // leave stpos as it is } else { // no purge -> replace with recursively parsed string result.replace( fpos, bpos2 - fpos + 1, rplstr ); ret = true; stpos = fpos + rplstr.length(); } } else { // unbalanced brackets: keep on parsing (should not happen // and will result in bad formatting) stpos = bpos1; } } fpos = result.indexOf( KABC_FMTTAG_purgeempty, stpos ); } // after sorting out all purge tags, we just search'n'replace the rest, // keeping track of whether at least one tag evaluates to something. // The following macro needs QString for R_FIELD // It substitutes !_P_! for empty fields so conditional tags work later #define REPLTAG(R_TAG,R_FIELD) \ if ( result.indexOf( R_TAG, false ) != -1 ) { \ QString rpl = R_FIELD.isEmpty() ? QLatin1String( "!_P_!" ) : R_FIELD; \ result.replace( R_TAG, rpl ); \ if ( !R_FIELD.isEmpty() ) { \ ret = true; \ } \ } REPLTAG( KABC_FMTTAG_realname, realName ); REPLTAG( KABC_FMTTAG_REALNAME, realName.toUpper() ); REPLTAG( KABC_FMTTAG_company, orgaName ); REPLTAG( KABC_FMTTAG_COMPANY, orgaName.toUpper() ); REPLTAG( KABC_FMTTAG_pobox, address.postOfficeBox() ); REPLTAG( KABC_FMTTAG_street, address.street() ); REPLTAG( KABC_FMTTAG_STREET, address.street().toUpper() ); REPLTAG( KABC_FMTTAG_zipcode, address.postalCode() ); REPLTAG( KABC_FMTTAG_location, address.locality() ); REPLTAG( KABC_FMTTAG_LOCATION, address.locality().toUpper() ); REPLTAG( KABC_FMTTAG_region, address.region() ); REPLTAG( KABC_FMTTAG_REGION, address.region().toUpper() ); result.replace( KABC_FMTTAG_newline, QLatin1String( "\n" ) ); #undef REPLTAG // conditional comma fpos = result.indexOf( KABC_FMTTAG_condcomma, 0 ); while ( -1 != fpos ) { const QString str1 = result.mid( fpos - 5, 5 ); const QString str2 = result.mid( fpos + 2, 5 ); if ( str1 != QLatin1String( "!_P_!" ) && str2 != QLatin1String( "!_P_!" ) ) { result.replace( fpos, 2, QLatin1String( ", " ) ); } else { result.remove( fpos, 2 ); } fpos = result.indexOf( KABC_FMTTAG_condcomma, fpos ); } // conditional whitespace fpos = result.indexOf( KABC_FMTTAG_condwhite, 0 ); while ( -1 != fpos ) { const QString str1 = result.mid( fpos - 5, 5 ); const QString str2 = result.mid( fpos + 2, 5 ); if ( str1 != QLatin1String( "!_P_!" ) && str2 != QLatin1String( "!_P_!" ) ) { result.replace( fpos, 2, QLatin1String( " " ) ); } else { result.remove( fpos, 2 ); } fpos = result.indexOf( KABC_FMTTAG_condwhite, fpos ); } // remove purged: result.remove( QLatin1String( "!_P_!" ) ); return ret; } class Address::Private : public QSharedData { public: Private() : mEmpty( true ), mType( 0 ) { mId = KRandom::randomString( 10 ); } Private( const Private &other ) : QSharedData( other ) { mEmpty = other.mEmpty; mId = other.mId; mType = other.mType; mPostOfficeBox = other.mPostOfficeBox; mExtended = other.mExtended; mStreet = other.mStreet; mLocality = other.mLocality; mRegion = other.mRegion; mPostalCode = other.mPostalCode; mCountry = other.mCountry; mLabel = other.mLabel; } bool mEmpty; QString mId; Type mType; QString mPostOfficeBox; QString mExtended; QString mStreet; QString mLocality; QString mRegion; QString mPostalCode; QString mCountry; QString mLabel; }; Address::Address() : d( new Private ) { } Address::Address( Type type ) : d( new Private ) { d->mType = type; } Address::Address( const Address &other ) : d( other.d ) { } Address::~Address() { } Address &Address::operator=( const Address &other ) { if ( this != &other ) { d = other.d; } return *this; } bool Address::operator==( const Address &other ) const { if ( d->mId != other.d->mId ) { return false; } if ( d->mType != other.d->mType ) { return false; } if ( d->mPostOfficeBox != other.d->mPostOfficeBox ) { return false; } if ( d->mExtended != other.d->mExtended ) { return false; } if ( d->mStreet != other.d->mStreet ) { return false; } if ( d->mLocality != other.d->mLocality ) { return false; } if ( d->mRegion != other.d->mRegion ) { return false; } if ( d->mPostalCode != other.d->mPostalCode ) { return false; } if ( d->mCountry != other.d->mCountry ) { return false; } if ( d->mLabel != other.d->mLabel ) { return false; } return true; } bool Address::operator!=( const Address &a ) const { return !( a == *this ); } bool Address::isEmpty() const { return d->mEmpty; } void Address::clear() { *this = Address(); } void Address::setId( const QString &id ) { d->mEmpty = false; d->mId = id; } QString Address::id() const { return d->mId; } void Address::setType( Type type ) { d->mEmpty = false; d->mType = type; } Address::Type Address::type() const { return d->mType; } QString Address::typeLabel() const { QString label; bool first = true; const TypeList list = typeList(); TypeList::ConstIterator it; for ( it = list.begin(); it != list.end(); ++it ) { if ( ( type() & (*it) ) && ( (*it) != Pref ) ) { - if ( !first ) + if ( !first ) { label.append( QLatin1Char( '/' ) ); + } label.append( typeLabel( *it ) ); if ( first ) { first = false; } } } return label; } void Address::setPostOfficeBox( const QString &postOfficeBox ) { d->mEmpty = false; d->mPostOfficeBox = postOfficeBox; } QString Address::postOfficeBox() const { return d->mPostOfficeBox; } QString Address::postOfficeBoxLabel() { return i18n( "Post Office Box" ); } void Address::setExtended( const QString &extended ) { d->mEmpty = false; d->mExtended = extended; } QString Address::extended() const { return d->mExtended; } QString Address::extendedLabel() { return i18n( "Extended Address Information" ); } void Address::setStreet( const QString &street ) { d->mEmpty = false; d->mStreet = street; } QString Address::street() const { return d->mStreet; } QString Address::streetLabel() { return i18n( "Street" ); } void Address::setLocality( const QString &locality ) { d->mEmpty = false; d->mLocality = locality; } QString Address::locality() const { return d->mLocality; } QString Address::localityLabel() { return i18n( "Locality" ); } void Address::setRegion( const QString ®ion ) { d->mEmpty = false; d->mRegion = region; } QString Address::region() const { return d->mRegion; } QString Address::regionLabel() { return i18n( "Region" ); } void Address::setPostalCode( const QString &postalCode ) { d->mEmpty = false; d->mPostalCode = postalCode; } QString Address::postalCode() const { return d->mPostalCode; } QString Address::postalCodeLabel() { return i18n( "Postal Code" ); } void Address::setCountry( const QString &country ) { d->mEmpty = false; d->mCountry = country; } QString Address::country() const { return d->mCountry; } QString Address::countryLabel() { return i18n( "Country" ); } void Address::setLabel( const QString &label ) { d->mEmpty = false; d->mLabel = label; } QString Address::label() const { return d->mLabel; } QString Address::labelLabel() { return i18n( "Delivery Label" ); } Address::TypeList Address::typeList() { static TypeList list; if ( list.isEmpty() ) { list << Dom << Intl << Postal << Parcel << Home << Work << Pref; } return list; } QString Address::typeLabel( Type type ) { if ( type & Pref ) { return i18nc( "Preferred address", "Preferred" ); } switch ( type ) { case Dom: return i18nc( "Address is in home country", "Domestic" ); break; case Intl: return i18nc( "Address is not in home country", "International" ); break; case Postal: return i18nc( "Address for delivering letters", "Postal" ); break; case Parcel: return i18nc( "Address for delivering packages", "Parcel" ); break; case Home: return i18nc( "Home Address", "Home" ); break; case Work: return i18nc( "Work Address", "Work" ); break; case Pref: return i18n( "Preferred Address" ); break; default: return i18nc( "another type of address", "Other" ); break; } } QString Address::toString() const { QString str; str += QLatin1String( "Address {\n" ); - str += QString::fromLatin1( " IsEmpty: %1\n" ).arg( d->mEmpty ? QLatin1String( "true" ) : QLatin1String( "false" ) ); + str += QString::fromLatin1( " IsEmpty: %1\n" ). + arg( d->mEmpty ? QLatin1String( "true" ) : QLatin1String( "false" ) ); str += QString::fromLatin1( " Id: %1\n" ).arg( d->mId ); str += QString::fromLatin1( " Type: %1\n" ).arg( typeLabel( d->mType ) ); str += QString::fromLatin1( " Post Office Box: %1\n" ).arg( d->mPostOfficeBox ); str += QString::fromLatin1( " Extended: %1\n" ).arg( d->mExtended ); str += QString::fromLatin1( " Street: %1\n" ).arg( d->mStreet ); str += QString::fromLatin1( " Locality: %1\n" ).arg( d->mLocality ); str += QString::fromLatin1( " Region: %1\n" ).arg( d->mRegion ); str += QString::fromLatin1( " Postal Code: %1\n" ).arg( d->mPostalCode ); str += QString::fromLatin1( " Country: %1\n" ).arg( d->mCountry ); str += QString::fromLatin1( " Label: %1\n" ).arg( d->mLabel ); str += QLatin1String( "}\n" ); return str; } QString Address::formattedAddress( const QString &realName, const QString &orgaName ) const { QString ciso; QString addrTemplate; QString ret; // FIXME: first check for iso-country-field and prefer that one if ( !country().isEmpty() ) { ciso = countryToISO( country() ); } else { // fall back to our own country ciso = KGlobal::locale()->country(); } KConfig entry( KStandardDirs::locate( "locale", QLatin1String( "l10n/" ) + ciso + QLatin1String( "/entry.desktop" ) ) ); KConfigGroup group = entry.group( "KCM Locale" ); // decide whether this needs special business address formatting if ( orgaName.isEmpty() ) { addrTemplate = group.readEntry( "AddressFormat" ); } else { addrTemplate = group.readEntry( "BusinessAddressFormat" ); if ( addrTemplate.isEmpty() ) { addrTemplate = group.readEntry( "AddressFormat" ); } } // in the case there's no format found at all, default to what we've always // used: if ( addrTemplate.isEmpty() ) { kWarning(5700) << "address format database incomplete" << "(no format for locale" << ciso << "found). Using default address formatting."; addrTemplate = QLatin1String( "%0(%n\\n)%0(%cm\\n)%0(%s\\n)%0(PO BOX %p\\n)%0(%l%w%r)%,%z" ); } // scan parseAddressTemplateSection( addrTemplate, ret, realName, orgaName, *this ); // now add the country line if needed (formatting this time according to // the rules of our own system country ) if ( !country().isEmpty() ) { KConfig entry( KStandardDirs::locate( "locale", QLatin1String( "l10n/" ) + KGlobal::locale()->country() + QLatin1String( "/entry.desktop" ) ) ); KConfigGroup group = entry.group( "KCM Locale" ); QString cpos = group.readEntry( "AddressCountryPosition" ); if ( QLatin1String( "BELOW" ) == cpos || cpos.isEmpty() ) { ret = ret + QLatin1String( "\n\n" ) + country().toUpper(); } else if ( QLatin1String( "below" ) == cpos ) { ret = ret + QLatin1String( "\n\n" ) + country(); } else if ( QLatin1String( "ABOVE" ) == cpos ) { ret = country().toUpper() + QLatin1String( "\n\n" ) + ret; } else if ( QLatin1String( "above" ) == cpos ) { ret = country() + QLatin1String( "\n\n" ) + ret; } } return ret; } QString Address::countryToISO( const QString &cname ) { // we search a map file for translations from country names to // iso codes, storing caching things in a QMap for faster future // access. typedef QMap stringMap; K_GLOBAL_STATIC( stringMap, sISOMap ) QMap::ConstIterator it; it = sISOMap->constFind( cname ); if ( it != sISOMap->constEnd() ) { return it.value(); } QString mapfile = KGlobal::dirs()->findResource( "data", QLatin1String( "kabc/countrytransl.map" ) ); QFile file( mapfile ); if ( file.open( QIODevice::ReadOnly ) ) { QTextStream s( &file ); QString strbuf = s.readLine(); while ( !strbuf.isEmpty() ) { QStringList countryInfo = strbuf.split( QLatin1Char( '\t' ), QString::KeepEmptyParts ); if ( countryInfo[ 0 ] == cname ) { file.close(); sISOMap->insert( cname, countryInfo[ 1 ] ); return countryInfo[ 1 ]; } strbuf = s.readLine(); } file.close(); } // fall back to system country sISOMap->insert( cname, KGlobal::locale()->country() ); return KGlobal::locale()->country(); } QString Address::ISOtoCountry( const QString &ISOname ) { // get country name from ISO country code (e.g. "no" -> i18n("Norway")) if ( ISOname.simplified().isEmpty() ) { return QString(); } QString mapfile = KGlobal::dirs()->findResource( "data", QLatin1String( "kabc/countrytransl.map" ) ); QFile file( mapfile ); if ( file.open( QIODevice::ReadOnly ) ) { QTextStream s( &file ); QString searchStr = QLatin1Char( '\t' ) + ISOname.simplified().toLower(); QString strbuf = s.readLine(); int pos; while ( !strbuf.isEmpty() ) { if ( ( pos = strbuf.indexOf( searchStr ) ) != -1 ) { file.close(); return i18n( strbuf.left( pos ).toUtf8() ); } strbuf = s.readLine(); } file.close(); } return ISOname; } QDataStream &KABC::operator<<( QDataStream &s, const Address &addr ) { return s << addr.d->mId << (uint)addr.d->mType << addr.d->mPostOfficeBox << addr.d->mExtended << addr.d->mStreet << addr.d->mLocality << addr.d->mRegion << addr.d->mPostalCode << addr.d->mCountry << addr.d->mLabel << addr.d->mEmpty; } QDataStream &KABC::operator>>( QDataStream &s, Address &addr ) { uint type; s >> addr.d->mId >> type >> addr.d->mPostOfficeBox >> addr.d->mExtended >> addr.d->mStreet >> addr.d->mLocality >> addr.d->mRegion >> addr.d->mPostalCode >> addr.d->mCountry >> addr.d->mLabel >> addr.d->mEmpty; addr.d->mType = Address::Type( type ); return s; } diff --git a/kabc/addresseelist.cpp b/kabc/addresseelist.cpp index 89eb7d7d4..ad2fc4f81 100644 --- a/kabc/addresseelist.cpp +++ b/kabc/addresseelist.cpp @@ -1,351 +1,352 @@ /* This file is part of libkabc. Copyright (c) 2002 Jost Schenck 2003 Tobias Koenig 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 "addresseelist.h" #include "field.h" #include "sortmode.h" #include #include using namespace KABC; // // // Traits // // SortingTraits::Uid::Uid() : d( 0 ) { } SortingTraits::Uid::~Uid() { } bool SortingTraits::Uid::eq( const Addressee &a1, const Addressee &a2 ) { // locale awareness doesn't make sense sorting ids return QString::compare( a1.uid(), a2.uid() ) == 0; } bool SortingTraits::Uid::lt( const Addressee &a1, const Addressee &a2 ) { // locale awareness doesn't make sense sorting ids return QString::compare( a1.uid(), a2.uid() ) < 0; } SortingTraits::Name::Name() : d( 0 ) { } SortingTraits::Name::~Name() { } bool SortingTraits::Name::eq( const Addressee &a1, const Addressee &a2 ) { return QString::localeAwareCompare( a1.name(), a2.name() ) == 0; } bool SortingTraits::Name::lt( const Addressee &a1, const Addressee &a2 ) { return QString::localeAwareCompare( a1.name(), a2.name() ) < 0; } SortingTraits::FormattedName::FormattedName() : d( 0 ) { } SortingTraits::FormattedName::~FormattedName() { } bool SortingTraits::FormattedName::eq( const Addressee &a1, const Addressee &a2 ) { return QString::localeAwareCompare( a1.formattedName(), a2.formattedName() ) == 0; } bool SortingTraits::FormattedName::lt( const Addressee &a1, const Addressee &a2 ) { return QString::localeAwareCompare( a1.formattedName(), a2.formattedName() ) < 0; } SortingTraits::FamilyName::FamilyName() : d( 0 ) { } SortingTraits::FamilyName::~FamilyName() { } bool SortingTraits::FamilyName::eq( const Addressee &a1, const Addressee &a2 ) { return QString::localeAwareCompare( a1.familyName(), a2.familyName() ) == 0 && QString::localeAwareCompare( a1.givenName(), a2.givenName() ) == 0; } bool SortingTraits::FamilyName::lt( const Addressee &a1, const Addressee &a2 ) { int family = QString::localeAwareCompare( a1.familyName(), a2.familyName() ); if ( 0 == family ) { return QString::localeAwareCompare( a1.givenName(), a2.givenName() ) < 0; } else { return family < 0; } } SortingTraits::GivenName::GivenName() : d( 0 ) { } SortingTraits::GivenName::~GivenName() { } bool SortingTraits::GivenName::eq( const Addressee &a1, const Addressee &a2 ) { return QString::localeAwareCompare( a1.givenName(), a2.givenName() ) == 0 && QString::localeAwareCompare( a1.familyName(), a2.familyName() ) == 0; } bool SortingTraits::GivenName::lt( const Addressee &a1, const Addressee &a2 ) { int given = QString::localeAwareCompare( a1.givenName(), a2.givenName() ); if ( 0 == given ) { return QString::localeAwareCompare( a1.familyName(), a2.familyName() ) < 0; } else { return given < 0; } } // // // AddresseeList // // static Field *sActiveField=0; class AddresseeList::Private : public QSharedData { public: Private() : mReverseSorting( false ), mActiveSortingCriterion( FormattedName ) { } Private( const Private &other ) : QSharedData( other ) { mReverseSorting = other.mReverseSorting; mActiveSortingCriterion = other.mActiveSortingCriterion; } bool mReverseSorting; SortingCriterion mActiveSortingCriterion; }; AddresseeList::AddresseeList() : QList(), d( new Private ) { } AddresseeList::~AddresseeList() { } AddresseeList::AddresseeList( const AddresseeList &other ) : QList( other ), d( other.d ) { } AddresseeList::AddresseeList( const QList &l ) : QList( l ), d( new Private ) { } AddresseeList &AddresseeList::operator=( const AddresseeList &other ) { if ( this != &other ) { QList::operator=( other ); d = other.d; } return *this; } QString AddresseeList::toString() const { QString str; str += QLatin1String( "AddresseeList {\n" ); str += QString::fromLatin1( " Reverse Order: %1\n" ).arg( d->mReverseSorting ? - QLatin1String( "true" ) : QLatin1String( "false" ) ); + QLatin1String( "true" ) : + QLatin1String( "false" ) ); QString crit; if ( Uid == d->mActiveSortingCriterion ) { crit = QLatin1String( "Uid" ); } else if ( Name == d->mActiveSortingCriterion ) { crit = QLatin1String( "Name" ); } else if ( FormattedName == d->mActiveSortingCriterion ) { crit = QLatin1String( "FormattedName" ); } else if ( FamilyName == d->mActiveSortingCriterion ) { crit = QLatin1String( "FamilyName" ); } else if ( GivenName == d->mActiveSortingCriterion ) { crit = QLatin1String( "GivenName" ); } else { crit = QLatin1String( "unknown -- update dump method" ); } str += QString::fromLatin1( " Sorting criterion: %1\n" ).arg( crit ); for ( const_iterator it = begin(); it != end(); ++it ) { // str += (*it).toString(); } str += QLatin1String( "}\n" ); return str; } void AddresseeList::setReverseSorting( bool reverseSorting ) { d->mReverseSorting = reverseSorting; } bool AddresseeList::reverseSorting() const { return d->mReverseSorting; } void AddresseeList::sortBy( SortingCriterion c ) { d->mActiveSortingCriterion = c; if ( Uid == c ) { sortByTrait(); } else if ( Name == c ) { sortByTrait(); } else if ( FormattedName == c ) { sortByTrait(); } else if ( FamilyName == c ) { sortByTrait(); } else if ( GivenName == c ) { sortByTrait(); } else { kError(5700) << "AddresseeList sorting criterion passed for which a trait is not known." << "No sorting done."; } } void AddresseeList::sort() { sortBy( d->mActiveSortingCriterion ); } template void AddresseeList::sortByTrait() { // FIXME: better sorting algorithm, bubblesort is not acceptable for larger lists. // // for i := 1 to n - 1 // do for j := 1 to n - i // do if A[j] > A[j+1] // then temp := A[j] // A[j] := A[j + 1] // A[j + 1 ] := temp iterator i1 = begin(); iterator endIt = end(); --endIt; if ( i1 == endIt ) { // don't need sorting return; } iterator i2 = endIt; while ( i1 != endIt ) { iterator j1 = begin(); iterator j2 = j1; ++j2; while ( j1 != i2 ) { - if ( (!d->mReverseSorting && Trait::lt( *j2, *j1 )) || - (d->mReverseSorting && Trait::lt( *j1, *j2 )) ) { + if ( ( !d->mReverseSorting && Trait::lt( *j2, *j1 ) ) || + ( d->mReverseSorting && Trait::lt( *j1, *j2 ) ) ) { qSwap( *j1, *j2 ); } ++j1; ++j2; } ++i1; --i2; } } void AddresseeList::sortByField( Field *field ) { if ( !field ) { kWarning(5700) << "sortByField called with no active sort field"; return; } sActiveField = field; if ( count() == 0 ) { return; } KABC::FieldSortMode *mode = new KABC::FieldSortMode( sActiveField, !d->mReverseSorting ); KABC::Addressee::setSortMode( mode ); qSort( *this ); KABC::Addressee::setSortMode( 0 ); delete mode; } void AddresseeList::sortByMode( SortMode *mode ) { if ( count() == 0 ) { return; } KABC::Addressee::setSortMode( mode ); qSort( *this ); KABC::Addressee::setSortMode( 0 ); } SortingCriterion AddresseeList::sortingCriterion() const { return d->mActiveSortingCriterion; } Field *AddresseeList::sortingField() const { return sActiveField; } diff --git a/kabc/contactgroup.cpp b/kabc/contactgroup.cpp index 381ef2a73..ad6b35fdb 100644 --- a/kabc/contactgroup.cpp +++ b/kabc/contactgroup.cpp @@ -1,489 +1,496 @@ /* This file is part of libkabc. Copyright (c) 2008 Tobias Koenig 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 "contactgroup.h" #include #include #include #include using namespace KABC; class ContactGroup::ContactReference::ContactReferencePrivate : public QSharedData { public: ContactReferencePrivate() : QSharedData() { } ContactReferencePrivate( const ContactReferencePrivate &other ) : QSharedData( other ) { mUid = other.mUid; mPreferredEmail = other.mPreferredEmail; mCustoms = other.mCustoms; } QString mUid; QString mPreferredEmail; QMap mCustoms; }; ContactGroup::ContactReference::ContactReference() : d( new ContactReferencePrivate ) { } ContactGroup::ContactReference::ContactReference( const ContactReference &other ) : d( other.d ) { } ContactGroup::ContactReference::ContactReference( const QString &uid ) : d( new ContactReferencePrivate ) { d->mUid = uid; } ContactGroup::ContactReference::~ContactReference() { } void ContactGroup::ContactReference::setUid( const QString &uid ) { d->mUid = uid; } QString ContactGroup::ContactReference::uid() const { return d->mUid; } void ContactGroup::ContactReference::setPreferredEmail( const QString &email ) { d->mPreferredEmail = email; } QString ContactGroup::ContactReference::preferredEmail() const { return d->mPreferredEmail; } void ContactGroup::ContactReference::insertCustom( const QString &key, const QString &value ) { d->mCustoms.insert( key, value ); } void ContactGroup::ContactReference::removeCustom( const QString &key ) { d->mCustoms.remove( key ); } QString ContactGroup::ContactReference::custom( const QString &key ) const { return d->mCustoms.value( key ); } -ContactGroup::ContactReference &ContactGroup::ContactReference::operator=( const ContactGroup::ContactReference &other ) +ContactGroup::ContactReference &ContactGroup::ContactReference::operator=( + const ContactGroup::ContactReference &other ) { if ( this != &other ) { d = other.d; } return *this; } bool ContactGroup::ContactReference::operator==( const ContactReference &other ) const { return d->mUid == other.d->mUid && d->mPreferredEmail == other.d->mPreferredEmail && d->mCustoms == other.d->mCustoms; } class ContactGroup::ContactGroupReference::ContactGroupReferencePrivate : public QSharedData { public: ContactGroupReferencePrivate() : QSharedData() { } ContactGroupReferencePrivate( const ContactGroupReferencePrivate &other ) : QSharedData( other ) { mUid = other.mUid; mCustoms = other.mCustoms; } QString mUid; QMap mCustoms; }; ContactGroup::ContactGroupReference::ContactGroupReference() : d( new ContactGroupReferencePrivate ) { } ContactGroup::ContactGroupReference::ContactGroupReference( const ContactGroupReference &other ) : d( other.d ) { } ContactGroup::ContactGroupReference::ContactGroupReference( const QString &uid ) : d( new ContactGroupReferencePrivate ) { d->mUid = uid; } ContactGroup::ContactGroupReference::~ContactGroupReference() { } void ContactGroup::ContactGroupReference::setUid( const QString &uid ) { d->mUid = uid; } QString ContactGroup::ContactGroupReference::uid() const { return d->mUid; } void ContactGroup::ContactGroupReference::insertCustom( const QString &key, const QString &value ) { d->mCustoms.insert( key, value ); } void ContactGroup::ContactGroupReference::removeCustom( const QString &key ) { d->mCustoms.remove( key ); } QString ContactGroup::ContactGroupReference::custom( const QString &key ) const { return d->mCustoms.value( key ); } -ContactGroup::ContactGroupReference &ContactGroup::ContactGroupReference::operator=( const ContactGroup::ContactGroupReference &other ) +ContactGroup::ContactGroupReference &ContactGroup::ContactGroupReference::operator=( + const ContactGroup::ContactGroupReference &other ) { if ( this != &other ) { d = other.d; } return *this; } bool ContactGroup::ContactGroupReference::operator==( const ContactGroupReference &other ) const { return d->mUid == other.d->mUid && d->mCustoms == other.d->mCustoms; } class ContactGroup::Data::DataPrivate : public QSharedData { public: DataPrivate() : QSharedData() { } DataPrivate( const DataPrivate &other ) : QSharedData( other ) { mName = other.mName; mEmail = other.mEmail; mCustoms = other.mCustoms; } QString mName; QString mEmail; QMap mCustoms; }; ContactGroup::Data::Data() : d( new DataPrivate ) { } ContactGroup::Data::Data( const Data &other ) : d( other.d ) { } ContactGroup::Data::Data( const QString &name, const QString &email ) : d( new DataPrivate ) { d->mName = name; d->mEmail = email; } ContactGroup::Data::~Data() { } void ContactGroup::Data::setName( const QString &name ) { d->mName = name; } QString ContactGroup::Data::name() const { return d->mName; } void ContactGroup::Data::setEmail( const QString &email ) { d->mEmail = email; } QString ContactGroup::Data::email() const { return d->mEmail; } void ContactGroup::Data::insertCustom( const QString &key, const QString &value ) { d->mCustoms.insert( key, value ); } void ContactGroup::Data::removeCustom( const QString &key ) { d->mCustoms.remove( key ); } QString ContactGroup::Data::custom( const QString &key ) const { return d->mCustoms.value( key ); } ContactGroup::Data &ContactGroup::Data::operator=( const ContactGroup::Data &other ) { if ( this != &other ) { d = other.d; } return *this; } bool ContactGroup::Data::operator==( const Data &other ) const { return d->mName == other.d->mName && d->mEmail == other.d->mEmail && d->mCustoms == other.d->mCustoms; } class ContactGroup::Private : public QSharedData { public: Private() : QSharedData(), mIdentifier( QUuid::createUuid().toString() ) { } Private( const Private &other ) : QSharedData( other ) { mIdentifier = other.mIdentifier; mName = other.mName; mContactReferences = other.mContactReferences; mContactGroupReferences = other.mContactGroupReferences; mDataObjects = other.mDataObjects; } QString mIdentifier; QString mName; ContactGroup::ContactReference::List mContactReferences; ContactGroup::ContactGroupReference::List mContactGroupReferences; ContactGroup::Data::List mDataObjects; }; ContactGroup::ContactGroup() : d( new Private ) { } ContactGroup::ContactGroup( const ContactGroup &other ) : d( other.d ) { } ContactGroup::ContactGroup( const QString &name ) : d( new Private ) { d->mName = name; } ContactGroup::~ContactGroup() { } void ContactGroup::setName( const QString &name ) { d->mName = name; } QString ContactGroup::name() const { return d->mName; } void ContactGroup::setId( const QString &id ) { d->mIdentifier = id; } QString ContactGroup::id() const { return d->mIdentifier; } unsigned int ContactGroup::count() const { return d->mContactReferences.count() + d->mDataObjects.count(); } unsigned int ContactGroup::contactReferenceCount() const { return d->mContactReferences.count(); } unsigned int ContactGroup::contactGroupReferenceCount() const { return d->mContactGroupReferences.count(); } unsigned int ContactGroup::dataCount() const { return d->mDataObjects.count(); } ContactGroup::ContactReference &ContactGroup::contactReference( unsigned int index ) { - Q_ASSERT_X( index < (unsigned int)d->mContactReferences.count(), "contactReference()", "index out of range" ); + Q_ASSERT_X( index < (unsigned int)d->mContactReferences.count(), + "contactReference()", "index out of range" ); return d->mContactReferences[ index ]; } const ContactGroup::ContactReference &ContactGroup::contactReference( unsigned int index ) const { - Q_ASSERT_X( index < (unsigned int)d->mContactReferences.count(), "contactReference()", "index out of range" ); + Q_ASSERT_X( index < (unsigned int)d->mContactReferences.count(), + "contactReference()", "index out of range" ); return d->mContactReferences[ index ]; } ContactGroup::ContactGroupReference &ContactGroup::contactGroupReference( unsigned int index ) { - Q_ASSERT_X( index < (unsigned int)d->mContactGroupReferences.count(), "contactGroupReference()", "index out of range" ); + Q_ASSERT_X( index < (unsigned int)d->mContactGroupReferences.count(), + "contactGroupReference()", "index out of range" ); return d->mContactGroupReferences[ index ]; } -const ContactGroup::ContactGroupReference &ContactGroup::contactGroupReference( unsigned int index ) const +const ContactGroup::ContactGroupReference &ContactGroup::contactGroupReference( + unsigned int index ) const { - Q_ASSERT_X( index < (unsigned int)d->mContactGroupReferences.count(), "contactGroupReference()", "index out of range" ); + Q_ASSERT_X( index < (unsigned int)d->mContactGroupReferences.count(), + "contactGroupReference()", "index out of range" ); return d->mContactGroupReferences[ index ]; } ContactGroup::Data &ContactGroup::data( unsigned int index ) { Q_ASSERT_X( index < (unsigned int)d->mDataObjects.count(), "data()", "index out of range" ); return d->mDataObjects[ index ]; } const ContactGroup::Data &ContactGroup::data( unsigned int index ) const { Q_ASSERT_X( index < (unsigned int)d->mDataObjects.count(), "data()", "index out of range" ); return d->mDataObjects[ index ]; } void ContactGroup::append( const ContactReference &reference ) { d->mContactReferences.append( reference ); } void ContactGroup::append( const ContactGroupReference &reference ) { d->mContactGroupReferences.append( reference ); } void ContactGroup::append( const Data &data ) { d->mDataObjects.append( data ); } void ContactGroup::remove( const ContactReference &reference ) { d->mContactReferences.removeOne( reference ); } void ContactGroup::remove( const ContactGroupReference &reference ) { d->mContactGroupReferences.removeOne( reference ); } void ContactGroup::remove( const Data &data ) { d->mDataObjects.removeOne( data ); } void ContactGroup::removeAllContactReferences() { d->mContactReferences.clear(); } void ContactGroup::removeAllContactGroupReferences() { d->mContactGroupReferences.clear(); } void ContactGroup::removeAllContactData() { d->mDataObjects.clear(); } ContactGroup &ContactGroup::operator=( const ContactGroup &other ) { if ( this != &other ) { d = other.d; } return *this; } bool ContactGroup::operator==( const ContactGroup &other ) const { return d->mIdentifier == other.d->mIdentifier && d->mName == other.d->mName && d->mContactReferences == other.d->mContactReferences && d->mContactGroupReferences == other.d->mContactGroupReferences && d->mDataObjects == other.d->mDataObjects; } QString ContactGroup::mimeType() { return QLatin1String( "application/x-vnd.kde.contactgroup" ); } diff --git a/kabc/contactgrouptool.cpp b/kabc/contactgrouptool.cpp index 2b43d52f2..506f34a73 100644 --- a/kabc/contactgrouptool.cpp +++ b/kabc/contactgrouptool.cpp @@ -1,367 +1,369 @@ /* This file is part of libkabc. Copyright (c) 2008 Tobias Koenig Copyright (c) 2008 Kevin Krammer 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 "contactgrouptool.h" #include "contactgroup.h" #include #include #include #include #include using namespace KABC; class XmlContactGroupWriter : public QXmlStreamWriter { public: XmlContactGroupWriter(); void write( const ContactGroup &group, QIODevice *device ); void write( const QList &groupLis, QIODevice *device ); private: void writeGroup( const ContactGroup &group ); void writeContactReference( const ContactGroup::ContactReference & ); void writeContactGroupReference( const ContactGroup::ContactGroupReference & ); void writeData( const ContactGroup::Data & ); }; XmlContactGroupWriter::XmlContactGroupWriter() { setAutoFormatting( true ); } void XmlContactGroupWriter::write( const ContactGroup &group, QIODevice *device ) { setDevice( device ); writeStartDocument(); writeGroup( group ); writeEndDocument(); } void XmlContactGroupWriter::write( const QList &groupList, QIODevice *device ) { setDevice( device ); writeStartDocument(); writeStartElement( QLatin1String( "contactGroupList" ) ); foreach ( const ContactGroup & group, groupList ) { writeGroup( group ); } writeEndElement(); writeEndDocument(); } void XmlContactGroupWriter::writeGroup( const ContactGroup &group ) { writeStartElement( QLatin1String( "contactGroup" ) ); writeAttribute( QLatin1String( "uid" ), group.id() ); writeAttribute( QLatin1String( "name" ), group.name() ); for ( uint i = 0; i < group.contactReferenceCount(); ++i ) { writeContactReference( group.contactReference( i ) ); } for ( uint i = 0; i < group.contactGroupReferenceCount(); ++i ) { writeContactGroupReference( group.contactGroupReference( i ) ); } for ( uint i = 0; i < group.dataCount(); ++i ) { writeData( group.data( i ) ); } writeEndElement(); } void XmlContactGroupWriter::writeContactReference( const ContactGroup::ContactReference &reference ) { writeStartElement( QLatin1String( "contactReference" ) ); writeAttribute( QLatin1String( "uid" ), reference.uid() ); if ( !reference.preferredEmail().isEmpty() ) { writeAttribute( QLatin1String( "preferredEmail" ), reference.preferredEmail() ); } // TODO: customs writeEndElement(); } -void XmlContactGroupWriter::writeContactGroupReference( const ContactGroup::ContactGroupReference &reference ) +void XmlContactGroupWriter::writeContactGroupReference( + const ContactGroup::ContactGroupReference &reference ) { writeStartElement( QLatin1String( "contactGroupReference" ) ); writeAttribute( QLatin1String( "uid" ), reference.uid() ); // TODO: customs writeEndElement(); } void XmlContactGroupWriter::writeData( const ContactGroup::Data &data ) { writeStartElement( QLatin1String( "contactData" ) ); writeAttribute( QLatin1String( "name" ), data.name() ); writeAttribute( QLatin1String( "email" ), data.email() ); // TODO: customs writeEndElement(); } class XmlContactGroupReader : public QXmlStreamReader { public: XmlContactGroupReader(); bool read( QIODevice *device, ContactGroup &group ); bool read( QIODevice *device, QList &groupList ); private: bool readGroup( ContactGroup &group ); bool readContactReference( ContactGroup::ContactReference &reference ); bool readContactGroupReference( ContactGroup::ContactGroupReference &reference ); bool readData( ContactGroup::Data &data ); }; XmlContactGroupReader::XmlContactGroupReader() { } bool XmlContactGroupReader::read( QIODevice *device, ContactGroup &group ) { setDevice( device ); while ( !atEnd() ) { readNext(); if ( isStartElement() ) { if ( name() == QLatin1String( "contactGroup" ) ) { return readGroup( group ); } else { raiseError( QLatin1String( "The document does not describe a ContactGroup" ) ); } } } return error() == NoError; } bool XmlContactGroupReader::read( QIODevice *device, QList &groupList ) { setDevice( device ); int depth = 0; while ( !atEnd() ) { readNext(); if ( isStartElement() ) { ++depth; if ( depth == 1 ) { if ( name() == QLatin1String( "contactGroupList" ) ) { continue; } else { raiseError( QLatin1String( "The document does not describe a list of ContactGroup" ) ); } } else if ( depth == 2 ) { if ( name() == QLatin1String( "contactGroup" ) ) { ContactGroup group; if ( !readGroup( group ) ) { return false; } groupList.append( group ); } else { raiseError( QLatin1String( "The document does not describe a list of ContactGroup" ) ); } } } if ( isEndElement() ) { --depth; } } return error() == NoError; } bool XmlContactGroupReader::readGroup( ContactGroup &group ) { const QXmlStreamAttributes elementAttributes = attributes(); const QStringRef uid = elementAttributes.value( QLatin1String( "uid" ) ); if ( uid.isEmpty() ) { raiseError( QLatin1String( "ContactGroup is missing a uid" ) ); return false; } const QStringRef groupName = elementAttributes.value( QLatin1String( "name" ) ); if ( groupName.isEmpty() ) { raiseError( QLatin1String( "ContactGroup is missing a name" ) ); return false; } group.setId( uid.toString() ); group.setName( groupName.toString() ); while ( !atEnd() ) { readNext(); if ( isStartElement() ) { if ( name() == QLatin1String( "contactData" ) ) { ContactGroup::Data data; if ( !readData( data ) ) { return false; } group.append( data ); } else if ( name() == QLatin1String( "contactReference" ) ) { ContactGroup::ContactReference reference; if ( !readContactReference( reference ) ) { return false; } group.append( reference ); } else if ( name() == QLatin1String( "contactGroupReference" ) ) { ContactGroup::ContactGroupReference reference; if ( !readContactGroupReference( reference ) ) { return false; } group.append( reference ); } else { raiseError( QLatin1String( "The document does not describe a ContactGroup" ) ); } } if ( isEndElement() ) { if ( name() == QLatin1String( "contactGroup" ) ) { return true; } } } return false; } bool XmlContactGroupReader::readData( ContactGroup::Data &data ) { const QXmlStreamAttributes elementAttributes = attributes(); const QStringRef email = elementAttributes.value( QLatin1String( "email" ) ); if ( email.isEmpty() ) { raiseError( QLatin1String( "ContactData is missing an email address" ) ); return false; } const QStringRef name = elementAttributes.value( QLatin1String( "name" ) ); if ( name.isEmpty() ) { raiseError( QLatin1String( "ContactData is missing a name" ) ); return false; } data.setName( name.toString() ); data.setEmail( email.toString() ); return true; } bool XmlContactGroupReader::readContactReference( ContactGroup::ContactReference &reference ) { const QXmlStreamAttributes elementAttributes = attributes(); const QStringRef uid = elementAttributes.value( QLatin1String( "uid" ) ); if ( uid.isEmpty() ) { raiseError( QLatin1String( "ContactReference is missing a uid" ) ); return false; } reference.setUid( uid.toString() ); return true; } -bool XmlContactGroupReader::readContactGroupReference( ContactGroup::ContactGroupReference &reference ) +bool XmlContactGroupReader::readContactGroupReference( + ContactGroup::ContactGroupReference &reference ) { const QXmlStreamAttributes elementAttributes = attributes(); const QStringRef uid = elementAttributes.value( QLatin1String( "uid" ) ); if ( uid.isEmpty() ) { raiseError( QLatin1String( "ContactGroupReference is missing a uid" ) ); return false; } reference.setUid( uid.toString() ); return true; } bool ContactGroupTool::convertFromXml( QIODevice *device, ContactGroup &group, QString *errorMessage ) { Q_UNUSED( errorMessage ); XmlContactGroupReader reader; bool ok = reader.read( device, group ); if ( !ok && errorMessage != 0 ) { *errorMessage = reader.errorString(); } return ok; } bool ContactGroupTool::convertToXml( const ContactGroup &group, QIODevice *device, QString *errorMessage ) { Q_UNUSED( errorMessage ); XmlContactGroupWriter writer; writer.write( group, device ); return true; } bool ContactGroupTool::convertFromXml( QIODevice *device, QList &groupList, QString *errorMessage ) { Q_UNUSED( errorMessage ); XmlContactGroupReader reader; bool ok = reader.read( device, groupList ); if ( !ok && errorMessage != 0 ) { *errorMessage = reader.errorString(); } return ok; } bool ContactGroupTool::convertToXml( const QList &groupList, QIODevice *device, QString *errorMessage ) { Q_UNUSED( errorMessage ); XmlContactGroupWriter writer; writer.write( groupList, device ); return true; } diff --git a/kabc/distributionlistdialog.cpp b/kabc/distributionlistdialog.cpp index 328b8830c..816c575d9 100644 --- a/kabc/distributionlistdialog.cpp +++ b/kabc/distributionlistdialog.cpp @@ -1,482 +1,482 @@ /* This file is part of libkabc. Copyright (c) 2001 Cornelius Schumacher 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 "distributionlistdialog.h" #include "distributionlist.h" #include "addressbook.h" #include "addresseedialog.h" #include #include #include #include #include #include #include #include #include #include #include #include using namespace KABC; DistributionListDialog::DistributionListDialog( AddressBook *addressBook, QWidget *parent ) : KDialog( parent ), d( 0 ) { setModal( true ); setCaption( i18n( "Configure Distribution Lists" ) ); setButtons( Ok ); setDefaultButton( Ok ); showButtonSeparator( true ); DistributionListEditorWidget *editor = new DistributionListEditorWidget( addressBook, this ); setMainWidget( editor ); connect( this, SIGNAL( okClicked() ), editor, SLOT( save() ) ); } DistributionListDialog::~DistributionListDialog() { } class EmailSelector::Private { public: QButtonGroup *mButtonGroup; QMap mEmailMap; }; EmailSelector::EmailSelector( const QStringList &emails, const QString ¤t, QWidget *parent ) : KDialog( parent ), d( new Private ) { setCaption( i18n( "Select Email Address" ) ); setButtons( Ok ); setDefaultButton( Ok ); QFrame *topFrame = new QFrame( this ); setMainWidget( topFrame ); QBoxLayout *topLayout = new QVBoxLayout( topFrame ); QGroupBox *box = new QGroupBox( i18n( "Email Addresses" ) ); d->mButtonGroup = new QButtonGroup( box ); topLayout->addWidget( box ); - QVBoxLayout *layout = new QVBoxLayout; + QVBoxLayout *layout = new QVBoxLayout; QStringList::ConstIterator it; for ( it = emails.begin(); it != emails.end(); ++it ) { QRadioButton *button = new QRadioButton( *it, box ); d->mButtonGroup->addButton( button ); d->mEmailMap.insert( button, *it ); layout->addWidget( button ); if ( (*it) == current ) { button->setChecked( true ); } } layout->addStretch( 1 ); - box->setLayout( layout ); + box->setLayout( layout ); } EmailSelector::~EmailSelector() { delete d; } QString EmailSelector::selected() const { QAbstractButton *button = d->mButtonGroup->checkedButton(); if ( !button ) { return QString(); } return d->mEmailMap[button]; } QString EmailSelector::getEmail( const QStringList &emails, const QString ¤t, QWidget *parent ) { EmailSelector dlg( emails, current, parent ); dlg.exec(); return dlg.selected(); } class EntryItem : public QTreeWidgetItem { public: EntryItem( QTreeWidget *parent, const Addressee &addressee, const QString &email=QString() ) : QTreeWidgetItem( parent ), mAddressee( addressee ), mEmail( email ) { setText( 0, addressee.realName() ); if ( email.isEmpty() ) { setText( 1, addressee.preferredEmail() ); setText( 2, i18nc( "this the preferred email address", "Yes" ) ); } else { setText( 1, email ); setText( 2, i18nc( "this is not the preferred email address", "No" ) ); } } Addressee addressee() const { return mAddressee; } QString email() const { return mEmail; } private: Addressee mAddressee; QString mEmail; }; class DistributionListEditorWidget::Private { public: Private( AddressBook *addressBook, DistributionListEditorWidget *parent ) : mParent( parent ), mAddressBook( addressBook ) { } ~Private() { } void newList(); void editList(); void removeList(); void addEntry(); void removeEntry(); void changeEmail(); void updateEntryView(); void updateAddresseeView(); void updateNameCombo(); void slotSelectionEntryViewChanged(); void slotSelectionAddresseeViewChanged(); void save(); DistributionListEditorWidget *mParent; KComboBox *mNameCombo; QLabel *mListLabel; QTreeWidget *mEntryView; QTreeWidget *mAddresseeView; AddressBook *mAddressBook; QPushButton *mNewButton, *mEditButton, *mRemoveButton; QPushButton *mChangeEmailButton, *mRemoveEntryButton, *mAddEntryButton; }; DistributionListEditorWidget::DistributionListEditorWidget( AddressBook *addressBook, QWidget *parent ) : QWidget( parent ), d( new Private( addressBook, this ) ) { kDebug(); QBoxLayout *topLayout = new QVBoxLayout( this ); topLayout->setSpacing( KDialog::spacingHint() ); QBoxLayout *nameLayout = new QHBoxLayout(); topLayout->addLayout( topLayout ); d->mNameCombo = new KComboBox( this ); nameLayout->addWidget( d->mNameCombo ); connect( d->mNameCombo, SIGNAL( activated( int ) ), SLOT( updateEntryView() ) ); d->mNewButton = new QPushButton( i18n( "New List..." ), this ); nameLayout->addWidget( d->mNewButton ); connect( d->mNewButton, SIGNAL( clicked() ), SLOT( newList() ) ); d->mEditButton = new QPushButton( i18n( "Rename List..." ), this ); nameLayout->addWidget( d->mEditButton ); connect( d->mEditButton, SIGNAL( clicked() ), SLOT( editList() ) ); d->mRemoveButton = new QPushButton( i18n( "Remove List" ), this ); nameLayout->addWidget( d->mRemoveButton ); connect( d->mRemoveButton, SIGNAL( clicked() ), SLOT( removeList() ) ); QGridLayout *gridLayout = new QGridLayout(); topLayout->addLayout( gridLayout ); gridLayout->setColumnStretch( 1, 1 ); QLabel *listLabel = new QLabel( i18n( "Available addresses:" ), this ); gridLayout->addWidget( listLabel, 0, 0 ); d->mListLabel = new QLabel( this ); gridLayout->addWidget( d->mListLabel, 0, 0, 1, 2 ); d->mAddresseeView = new QTreeWidget( this ); d->mAddresseeView->setColumnCount( 2 ); QStringList labels; labels << i18nc( "@title:column addressee name", "Name" ) << i18nc( "@title:column addressee preferred email", "Preferred Email" ); d->mAddresseeView->setHeaderLabels( labels ); gridLayout->addWidget( d->mAddresseeView, 1, 0 ); connect( d->mAddresseeView, SIGNAL( itemSelectionChanged() ), SLOT( slotSelectionAddresseeViewChanged() ) ); connect( d->mAddresseeView, SIGNAL( itemDoubleClicked( QTreeWidgetItem *, int ) ), SLOT( addEntry() ) ); d->mAddEntryButton = new QPushButton( i18n( "Add Entry" ), this ); d->mAddEntryButton->setEnabled( false ); gridLayout->addWidget( d->mAddEntryButton, 2, 0 ); connect( d->mAddEntryButton, SIGNAL( clicked() ), SLOT( addEntry() ) ); d->mEntryView = new QTreeWidget( this ); QStringList entryLabels; entryLabels << i18nc( "@title:column addressee name", "Name" ) << i18nc( "@title:column addressee preferred email", "Email" ) << i18nc( "@title:column use preferred email", "Use Preferred" ); d->mEntryView->setEnabled( false ); gridLayout->addWidget( d->mEntryView, 1, 1, 1, 2 ); connect( d->mEntryView, SIGNAL( itemSelectionChanged() ), SLOT( slotSelectionEntryViewChanged() ) ); d->mChangeEmailButton = new QPushButton( i18n( "Change Email..." ), this ); gridLayout->addWidget( d->mChangeEmailButton, 2, 1 ); connect( d->mChangeEmailButton, SIGNAL( clicked() ), SLOT( changeEmail() ) ); d->mRemoveEntryButton = new QPushButton( i18n( "Remove Entry" ), this ); gridLayout->addWidget( d->mRemoveEntryButton, 2, 2 ); connect( d->mRemoveEntryButton, SIGNAL( clicked() ), SLOT( removeEntry() ) ); d->updateAddresseeView(); d->updateNameCombo(); } DistributionListEditorWidget::~DistributionListEditorWidget() { delete d; } void DistributionListEditorWidget::Private::save() { // FIXME new distribution list handling // do we need extra save? //mManager->save(); } void DistributionListEditorWidget::Private::slotSelectionEntryViewChanged() { QList selected = mEntryView->selectedItems(); bool state = selected.count() > 0; mChangeEmailButton->setEnabled( state ); mRemoveEntryButton->setEnabled( state ); } void DistributionListEditorWidget::Private::newList() { bool ok; QString name = KInputDialog::getText( i18n( "New Distribution List" ), i18n( "Please enter &name:" ), QString(), &ok ); if ( !ok ) { return; } mAddressBook->createDistributionList( name ); mNameCombo->clear(); mNameCombo->addItems( mAddressBook->allDistributionListNames() ); mNameCombo->setCurrentIndex( mNameCombo->count() - 1 ); updateEntryView(); slotSelectionAddresseeViewChanged(); } void DistributionListEditorWidget::Private::editList() { QString oldName = mNameCombo->currentText(); bool ok; QString name = KInputDialog::getText( i18n( "Distribution List" ), i18n( "Please change &name:" ), oldName, &ok ); if ( !ok ) { return; } DistributionList *list = mAddressBook->findDistributionListByName( oldName ); if ( list ) { list->setName( name ); } mNameCombo->clear(); mNameCombo->addItems( mAddressBook->allDistributionListNames() ); mNameCombo->setCurrentIndex( mNameCombo->count() - 1 ); updateEntryView(); slotSelectionAddresseeViewChanged(); } void DistributionListEditorWidget::Private::removeList() { int result = KMessageBox::warningContinueCancel( mParent, i18n( "Delete distribution list '%1'?", mNameCombo->currentText() ), QString(), KStandardGuiItem::del() ); if ( result != KMessageBox::Continue ) { return; } DistributionList *list = mAddressBook->findDistributionListByName( mNameCombo->currentText() ); if ( list ) { // FIXME new distribution list handling // list should be deleted, no? mAddressBook->removeDistributionList( list ); mNameCombo->removeItem( mNameCombo->currentIndex() ); } updateEntryView(); slotSelectionAddresseeViewChanged(); } void DistributionListEditorWidget::Private::addEntry() { QList selected = mAddresseeView->selectedItems(); if ( selected.count() == 0 ) { kDebug() << "No addressee selected."; return; } AddresseeItem *addresseeItem = static_cast( selected.at( 0 ) ); DistributionList *list = mAddressBook->findDistributionListByName( mNameCombo->currentText() ); if ( !list ) { kDebug() << "No dist list '" << mNameCombo->currentText() << "'"; return; } list->insertEntry( addresseeItem->addressee() ); updateEntryView(); slotSelectionAddresseeViewChanged(); } void DistributionListEditorWidget::Private::removeEntry() { DistributionList *list = mAddressBook->findDistributionListByName( mNameCombo->currentText() ); if ( !list ) { return; } QList selected = mEntryView->selectedItems(); if ( selected.count() == 0 ) { return; } EntryItem *entryItem = static_cast( selected.at( 0 ) ); list->removeEntry( entryItem->addressee(), entryItem->email() ); delete entryItem; } void DistributionListEditorWidget::Private::changeEmail() { DistributionList *list = mAddressBook->findDistributionListByName( mNameCombo->currentText() ); if ( !list ) { return; } QList selected = mEntryView->selectedItems(); if ( selected.count() == 0 ) { return; } EntryItem *entryItem = static_cast( selected.at( 0 ) ); QString email = EmailSelector::getEmail( entryItem->addressee().emails(), entryItem->email(), mParent ); list->removeEntry( entryItem->addressee(), entryItem->email() ); list->insertEntry( entryItem->addressee(), email ); updateEntryView(); } void DistributionListEditorWidget::Private::updateEntryView() { if ( mNameCombo->currentText().isEmpty() ) { mListLabel->setText( i18n( "Selected addressees:" ) ); } else { mListLabel->setText( i18n( "Selected addresses in '%1':", mNameCombo->currentText() ) ); } mEntryView->clear(); DistributionList *list = mAddressBook->findDistributionListByName( mNameCombo->currentText() ); if ( !list ) { mEditButton->setEnabled( false ); mRemoveButton->setEnabled( false ); mChangeEmailButton->setEnabled( false ); mRemoveEntryButton->setEnabled( false ); mAddresseeView->setEnabled( false ); mEntryView->setEnabled( false ); return; } else { mEditButton->setEnabled( true ); mRemoveButton->setEnabled( true ); mAddresseeView->setEnabled( true ); mEntryView->setEnabled( true ); } DistributionList::Entry::List entries = list->entries(); DistributionList::Entry::List::ConstIterator it; for ( it = entries.constBegin(); it != entries.constEnd(); ++it ) { new EntryItem( mEntryView, (*it).addressee(), (*it).email() ); } QList selected = mEntryView->selectedItems(); bool state = ( selected.count() != 0 ); mChangeEmailButton->setEnabled( state ); mRemoveEntryButton->setEnabled( state ); } void DistributionListEditorWidget::Private::updateAddresseeView() { mAddresseeView->clear(); AddressBook::Iterator it; for ( it = mAddressBook->begin(); it != mAddressBook->end(); ++it ) { new AddresseeItem( mAddresseeView, *it ); } } void DistributionListEditorWidget::Private::updateNameCombo() { mNameCombo->addItems( mAddressBook->allDistributionListNames() ); updateEntryView(); } void DistributionListEditorWidget::Private::slotSelectionAddresseeViewChanged() { QList selected = mAddresseeView->selectedItems(); bool state = ( selected.count() != 0 ); mAddEntryButton->setEnabled( state && !mNameCombo->currentText().isEmpty() ); } #include "distributionlistdialog.moc" diff --git a/kabc/geo.cpp b/kabc/geo.cpp index b52700a9d..3b6ae164a 100644 --- a/kabc/geo.cpp +++ b/kabc/geo.cpp @@ -1,169 +1,170 @@ /* This file is part of libkabc. Copyright (c) 2001 Cornelius Schumacher 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 "geo.h" #include #include using namespace KABC; class Geo::Private : public QSharedData { public: Private() : mLatitude( 91 ), mLongitude( 181 ), mValidLatitude( false ), mValidLongitude( false ) { } Private( const Private &other ) : QSharedData( other ) { mLatitude = other.mLatitude; mLongitude = other.mLongitude; mValid = other.mValid; mValidLatitude = other.mValidLatitude; mValidLongitude = other.mValidLongitude; } float mLatitude; float mLongitude; bool mValid; bool mValidLatitude; bool mValidLongitude; }; Geo::Geo() : d( new Private ) { } Geo::Geo( float latitude, float longitude ) : d( new Private ) { setLatitude( latitude ); setLongitude( longitude ); } Geo::Geo( const Geo &other ) : d( other.d ) { } Geo::~Geo() { } void Geo::setLatitude( float latitude ) { if ( latitude >= -90 && latitude <= 90 ) { d->mLatitude = latitude; d->mValidLatitude = true; } else { d->mLatitude = 91; d->mValidLatitude = false; } } float Geo::latitude() const { return d->mLatitude; } void Geo::setLongitude( float longitude ) { if ( longitude >= -180 && longitude <= 180 ) { d->mLongitude = longitude; d->mValidLongitude = true; } else { d->mLongitude = 181; d->mValidLongitude = false; } } float Geo::longitude() const { return d->mLongitude; } bool Geo::isValid() const { return d->mValidLatitude && d->mValidLongitude; } bool Geo::operator==( const Geo &other ) const { if ( !other.isValid() && !isValid() ) { return true; } if ( !other.isValid() || !isValid() ) { return false; } if ( other.d->mLatitude == d->mLatitude && other.d->mLongitude == d->mLongitude ) { return true; } return false; } bool Geo::operator!=( const Geo &other ) const { return !( *this == other ); } Geo &Geo::operator=( const Geo &other ) { if ( this != &other ) { d = other.d; } return *this; } QString Geo::toString() const { QString str; str += QLatin1String( "Geo {\n" ); - str += QString::fromLatin1( " Valid: %1\n" ).arg( isValid() ? QLatin1String( "true" ) : QLatin1String( "false" ) ); + str += QString::fromLatin1( " Valid: %1\n" ). + arg( isValid() ? QLatin1String( "true" ) : QLatin1String( "false" ) ); str += QString::fromLatin1( " Latitude: %1\n" ).arg( d->mLatitude ); str += QString::fromLatin1( " Longitude: %1\n" ).arg( d->mLongitude ); str += QLatin1String( "}\n" ); return str; } QDataStream &KABC::operator<<( QDataStream &s, const Geo &geo ) { return s << geo.d->mLatitude << geo.d->mValidLatitude << geo.d->mLongitude << geo.d->mValidLongitude; } QDataStream &KABC::operator>>( QDataStream &s, Geo &geo ) { s >> geo.d->mLatitude >> geo.d->mValidLatitude >> geo.d->mLongitude >> geo.d->mValidLongitude; return s; } diff --git a/kabc/key.cpp b/kabc/key.cpp index 4acd6206a..ad78071fb 100644 --- a/kabc/key.cpp +++ b/kabc/key.cpp @@ -1,243 +1,245 @@ /* This file is part of libkabc. Copyright (c) 2002 Tobias Koenig 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 "key.h" #include #include #include #include using namespace KABC; class Key::Private : public QSharedData { public: Private() : mId( KRandom::randomString( 8 ) ) { } Private( const Private &other ) : QSharedData( other ) { mId = other.mId; mBinaryData = other.mBinaryData; mTextData = other.mTextData; mCustomTypeString = other.mCustomTypeString; mIsBinary = other.mIsBinary; mType = other.mType; } QString mId; QByteArray mBinaryData; QString mTextData; QString mCustomTypeString; bool mIsBinary; Type mType; }; Key::Key( const QString &text, Type type ) : d( new Private ) { d->mTextData = text; d->mIsBinary = false; d->mType = type; } Key::Key( const Key &other ) : d( other.d ) { } Key::~Key() { } bool Key::operator==( const Key &other ) const { if ( d->mId != other.d->mId ) { return false; } if ( d->mType != other.d->mType ) { return false; } if ( d->mIsBinary != other.d->mIsBinary ) { return false; } if ( d->mIsBinary ) { if ( d->mBinaryData != other.d->mBinaryData ) { return false; } } else { if ( d->mTextData != other.d->mTextData ) { return false; } } if ( d->mCustomTypeString != other.d->mCustomTypeString ) { return false; } return true; } bool Key::operator!=( const Key &other ) const { return !( *this == other ); } Key &Key::operator=( const Key &other ) { if ( this != &other ) { d = other.d; } return *this; } void Key::setId( const QString &id ) { d->mId = id; } QString Key::id() const { return d->mId; } void Key::setBinaryData( const QByteArray &binary ) { d->mBinaryData = binary; d->mIsBinary = true; } QByteArray Key::binaryData() const { return d->mBinaryData; } void Key::setTextData( const QString &text ) { d->mTextData = text; d->mIsBinary = false; } QString Key::textData() const { return d->mTextData; } bool Key::isBinary() const { return d->mIsBinary; } void Key::setType( Type type ) { d->mType = type; } void Key::setCustomTypeString( const QString &custom ) { d->mCustomTypeString = custom; } Key::Type Key::type() const { return d->mType; } QString Key::customTypeString() const { return d->mCustomTypeString; } QString Key::toString() const { QString str; str += QLatin1String( "Key {\n" ); str += QString::fromLatin1( " Id: %1\n" ).arg( d->mId ); str += QString::fromLatin1( " Type: %1\n" ).arg( typeLabel( d->mType ) ); if ( d->mType == Custom ) { str += QString::fromLatin1( " CustomType: %1\n" ).arg( d->mCustomTypeString ); } - str += QString::fromLatin1( " IsBinary: %1\n" ).arg( d->mIsBinary ? QLatin1String( "true" ) : QLatin1String( "false" ) ); + str += QString::fromLatin1( " IsBinary: %1\n" ). + arg( d->mIsBinary ? QLatin1String( "true" ) : QLatin1String( "false" ) ); if ( d->mIsBinary ) { - str += QString::fromLatin1( " Binary: %1\n" ).arg( QString::fromLatin1( d->mBinaryData.toBase64() ) ); + str += QString::fromLatin1( " Binary: %1\n" ). + arg( QString::fromLatin1( d->mBinaryData.toBase64() ) ); } else { str += QString::fromLatin1( " Text: %1\n" ).arg( d->mTextData ); } str += QLatin1String( "}\n" ); return str; } Key::TypeList Key::typeList() { static TypeList list; if ( list.isEmpty() ) { list << X509 << PGP << Custom; } return list; } QString Key::typeLabel( Type type ) { switch ( type ) { case X509: return i18nc( "X.509 public key", "X509" ); break; case PGP: return i18nc( "Pretty Good Privacy key", "PGP" ); break; case Custom: return i18nc( "A custom key", "Custom" ); break; default: return i18nc( "another type of encryption key", "Unknown type" ); break; } } QDataStream &KABC::operator<<( QDataStream &s, const Key &key ) { return s << key.d->mId << key.d->mType << key.d->mIsBinary << key.d->mBinaryData << key.d->mTextData << key.d->mCustomTypeString; } QDataStream &KABC::operator>>( QDataStream &s, Key &key ) { uint type; s >> key.d->mId >> type >> key.d->mIsBinary >> key.d->mBinaryData >> key.d->mTextData >> key.d->mCustomTypeString; key.d->mType = Key::Type( type ); return s; } diff --git a/kabc/ldifconverter.cpp b/kabc/ldifconverter.cpp index bc6d984fb..5f7c0de97 100644 --- a/kabc/ldifconverter.cpp +++ b/kabc/ldifconverter.cpp @@ -1,515 +1,523 @@ /* This file is part of libkabc. Copyright (c) 2003 Helge Deller 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. */ /* Useful links: - http://tldp.org/HOWTO/LDAP-Implementation-HOWTO/schemas.html - http://www.faqs.org/rfcs/rfc2849.html Not yet handled items: - objectclass microsoftaddressbook - info, - initials, - otherfacsimiletelephonenumber, - otherpager, - physicaldeliveryofficename, */ #include "ldifconverter.h" #include "vcardconverter.h" #include "address.h" #include "addressee.h" #include "kldap/ldif.h" #include #include #include #include #include #include using namespace KABC; /* generate LDIF stream */ bool LDIFConverter::addresseeToLDIF( const AddresseeList &addrList, QString &str ) { AddresseeList::ConstIterator it; for ( it = addrList.begin(); it != addrList.end(); ++it ) { addresseeToLDIF( *it, str ); } return true; } static void ldif_out( QTextStream &t, const QString &formatStr, const QString &value ) { if ( value.isEmpty() ) { return; } QByteArray txt = KLDAP::Ldif::assembleLine( formatStr, value, 72 ); // write the string t << QString::fromUtf8( txt ) << "\n"; } bool LDIFConverter::addresseeToLDIF( const Addressee &addr, QString &str ) { if ( addr.isEmpty() ) { return false; } QTextStream t( &str, QIODevice::WriteOnly|QIODevice::Append ); t.setCodec( QTextCodec::codecForName( "UTF-8" ) ); const Address homeAddr = addr.address( Address::Home ); const Address workAddr = addr.address( Address::Work ); ldif_out( t, QLatin1String( "dn" ), QString::fromLatin1( "cn=%1,mail=%2" ). arg( addr.formattedName().simplified() ). arg( addr.preferredEmail() ) ); ldif_out( t, QLatin1String( "givenname" ), addr.givenName() ); ldif_out( t, QLatin1String( "sn" ), addr.familyName() ); ldif_out( t, QLatin1String( "cn" ), addr.formattedName().simplified() ); ldif_out( t, QLatin1String( "uid" ), addr.uid() ); ldif_out( t, QLatin1String( "nickname" ), addr.nickName() ); ldif_out( t, QLatin1String( "xmozillanickname" ), addr.nickName() ); ldif_out( t, QLatin1String( "mail" ), addr.preferredEmail() ); if ( addr.emails().count() > 1 ) { ldif_out( t, QLatin1String( "mozillasecondemail" ), addr.emails()[ 1 ] ); } //ldif_out( t, "mozilla_AIMScreenName: %1\n", "screen_name" ); - ldif_out( t, QLatin1String( "telephonenumber" ), addr.phoneNumber( PhoneNumber::Work ).number() ); - ldif_out( t, QLatin1String( "facsimiletelephonenumber" ), addr.phoneNumber( PhoneNumber::Fax ).number() ); - ldif_out( t, QLatin1String( "homephone" ), addr.phoneNumber( PhoneNumber::Home ).number() ); - ldif_out( t, QLatin1String( "mobile" ), addr.phoneNumber( PhoneNumber::Cell ).number() ); // Netscape 7 - ldif_out( t, QLatin1String( "cellphone" ), addr.phoneNumber( PhoneNumber::Cell ).number() ); // Netscape 4.x - ldif_out( t, QLatin1String( "pager" ), addr.phoneNumber( PhoneNumber::Pager ).number() ); - ldif_out( t, QLatin1String( "pagerphone" ), addr.phoneNumber( PhoneNumber::Pager ).number() ); + ldif_out( t, QLatin1String( "telephonenumber" ), + addr.phoneNumber( PhoneNumber::Work ).number() ); + ldif_out( t, QLatin1String( "facsimiletelephonenumber" ), + addr.phoneNumber( PhoneNumber::Fax ).number() ); + ldif_out( t, QLatin1String( "homephone" ), + addr.phoneNumber( PhoneNumber::Home ).number() ); + ldif_out( t, QLatin1String( "mobile" ), + addr.phoneNumber( PhoneNumber::Cell ).number() ); // Netscape 7 + ldif_out( t, QLatin1String( "cellphone" ), + addr.phoneNumber( PhoneNumber::Cell ).number() ); // Netscape 4.x + ldif_out( t, QLatin1String( "pager" ), + addr.phoneNumber( PhoneNumber::Pager ).number() ); + ldif_out( t, QLatin1String( "pagerphone" ), + addr.phoneNumber( PhoneNumber::Pager ).number() ); ldif_out( t, QLatin1String( "streethomeaddress" ), homeAddr.street() ); ldif_out( t, QLatin1String( "postalcode" ), workAddr.postalCode() ); ldif_out( t, QLatin1String( "postofficebox" ), workAddr.postOfficeBox() ); QStringList streets = homeAddr.street().split( QLatin1Char( '\n' ) ); if ( streets.count() > 0 ) { ldif_out( t, QLatin1String( "homepostaladdress" ), streets[ 0 ] ); // Netscape 7 } if ( streets.count() > 1 ) { ldif_out( t, QLatin1String( "mozillahomepostaladdress2" ), streets[ 1 ] ); // Netscape 7 } ldif_out( t, QLatin1String( "mozillahomelocalityname" ), homeAddr.locality() ); // Netscape 7 ldif_out( t, QLatin1String( "mozillahomestate" ), homeAddr.region() ); ldif_out( t, QLatin1String( "mozillahomepostalcode" ), homeAddr.postalCode() ); - ldif_out( t, QLatin1String( "mozillahomecountryname" ), Address::ISOtoCountry( homeAddr.country() ) ); + ldif_out( t, QLatin1String( "mozillahomecountryname" ), + Address::ISOtoCountry( homeAddr.country() ) ); ldif_out( t, QLatin1String( "locality" ), workAddr.locality() ); ldif_out( t, QLatin1String( "streetaddress" ), workAddr.street() ); // Netscape 4.x streets = workAddr.street().split( QLatin1Char( '\n' ) ); if ( streets.count() > 0 ) { ldif_out( t, QLatin1String( "postaladdress" ), streets[ 0 ] ); } if ( streets.count() > 1 ) { ldif_out( t, QLatin1String( "mozillapostaladdress2" ), streets[ 1 ] ); } ldif_out( t, QLatin1String( "countryname" ), Address::ISOtoCountry( workAddr.country() ) ); ldif_out( t, QLatin1String( "l" ), workAddr.locality() ); ldif_out( t, QLatin1String( "c" ), Address::ISOtoCountry( workAddr.country() ) ); ldif_out( t, QLatin1String( "st" ), workAddr.region() ); ldif_out( t, QLatin1String( "title" ), addr.title() ); ldif_out( t, QLatin1String( "vocation" ), addr.prefix() ); ldif_out( t, QLatin1String( "ou" ), addr.role() ); ldif_out( t, QLatin1String( "o" ), addr.organization() ); ldif_out( t, QLatin1String( "organization" ), addr.organization() ); ldif_out( t, QLatin1String( "organizationname" ), addr.organization() ); // Compatibility with older kabc versions. if ( !addr.department().isEmpty() ) { ldif_out( t, QLatin1String( "department" ), addr.department() ); } else { ldif_out( t, QLatin1String( "department" ), addr.custom( QLatin1String( "KADDRESSBOOK" ), QLatin1String( "X-Department" ) ) ); } ldif_out( t, QLatin1String( "workurl" ), addr.url().prettyUrl() ); ldif_out( t, QLatin1String( "homeurl" ), addr.url().prettyUrl() ); ldif_out( t, QLatin1String( "description" ), addr.note() ); if ( addr.revision().isValid() ) { ldif_out( t, QLatin1String( "modifytimestamp" ), dateToVCardString( addr.revision() ) ); } t << "objectclass: top\n"; t << "objectclass: person\n"; t << "objectclass: organizationalPerson\n"; t << "\n"; return true; } /* convert from LDIF stream */ bool LDIFConverter::LDIFToAddressee( const QString &str, AddresseeList &addrList, const QDateTime &dt ) { if ( str.isEmpty() ) { return true; } bool endldif = false, end = false; KLDAP::Ldif ldif; KLDAP::Ldif::ParseValue ret; Addressee a; Address homeAddr, workAddr; ldif.setLdif( str.toLatin1() ); QDateTime qdt = dt; if ( !qdt.isValid() ) { qdt = QDateTime::currentDateTime(); } a.setRevision( qdt ); homeAddr = Address( Address::Home ); workAddr = Address( Address::Work ); do { ret = ldif.nextItem(); switch ( ret ) { case KLDAP::Ldif::Item: { QString fieldname = ldif.attr().toLower(); QString value = QString::fromUtf8( ldif.value(), ldif.value().size() ); evaluatePair( a, homeAddr, workAddr, fieldname, value ); break; } case KLDAP::Ldif::EndEntry: // if the new address is not empty, append it if ( !a.formattedName().isEmpty() || !a.name().isEmpty() || !a.familyName().isEmpty() ) { if ( !homeAddr.isEmpty() ) { a.insertAddress( homeAddr ); } if ( !workAddr.isEmpty() ) { a.insertAddress( workAddr ); } addrList.append( a ); } a = Addressee(); a.setRevision( qdt ); homeAddr = Address( Address::Home ); workAddr = Address( Address::Work ); break; case KLDAP::Ldif::MoreData: { if ( endldif ) { end = true; } else { ldif.endLdif(); endldif = true; break; } } default: break; } } while ( !end ); return true; } bool LDIFConverter::evaluatePair( Addressee &a, Address &homeAddr, Address &workAddr, QString &fieldname, QString &value ) { if ( fieldname == QLatin1String( "dn" ) ) { // ignore & return false! return false; } if ( fieldname.startsWith( QLatin1Char( '#' ) ) ) { return true; } if ( fieldname.isEmpty() && !a.note().isEmpty() ) { // some LDIF export filters are borken and add additional // comments on stand-alone lines. Just add them to the notes for now. a.setNote( a.note() + QLatin1Char( '\n' ) + value ); return true; } if ( fieldname == QLatin1String( "givenname" ) ) { a.setGivenName( value ); return true; } if ( fieldname == QLatin1String( "xmozillanickname" ) || fieldname == QLatin1String( "nickname" ) ) { a.setNickName( value ); return true; } if ( fieldname == QLatin1String( "sn" ) ) { a.setFamilyName( value ); return true; } if ( fieldname == QLatin1String( "uid" ) ) { a.setUid( value ); return true; } if ( fieldname == QLatin1String( "mail" ) || fieldname == QLatin1String( "mozillasecondemail" ) ) { // mozilla if ( a.emails().indexOf( value ) == -1 ) { a.insertEmail( value ); } return true; } if ( fieldname == QLatin1String( "title" ) ) { a.setTitle( value ); return true; } if ( fieldname == QLatin1String( "vocation" ) ) { a.setPrefix( value ); return true; } if ( fieldname == QLatin1String( "cn" ) ) { a.setFormattedName( value ); return true; } if ( fieldname == QLatin1String( "o" ) || fieldname == QLatin1String( "organization" ) || // Exchange fieldname == QLatin1String( "organizationname" ) ) { // Exchange a.setOrganization( value ); return true; } if ( fieldname == QLatin1String( "description" ) ) { addComment: if ( !a.note().isEmpty() ) { a.setNote( a.note() + QLatin1Char( '\n' ) ); } a.setNote( a.note() + value ); return true; } if ( fieldname == QLatin1String( "custom1" ) || fieldname == QLatin1String( "custom2" ) || fieldname == QLatin1String( "custom3" ) || fieldname == QLatin1String( "custom4" ) ) { goto addComment; } if ( fieldname == QLatin1String( "homeurl" ) || fieldname == QLatin1String( "workurl" ) ) { if ( a.url().isEmpty() ) { a.setUrl( KUrl( value ) ); return true; } if ( a.url().prettyUrl() == KUrl( value ).prettyUrl() ) { return true; } // TODO: current version of kabc only supports one URL. // TODO: change this with KDE 4 } if ( fieldname == QLatin1String( "homephone" ) ) { a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Home ) ); return true; } if ( fieldname == QLatin1String( "telephonenumber" ) ) { a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Work ) ); return true; } if ( fieldname == QLatin1String( "mobile" ) ) { // mozilla/Netscape 7 a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Cell ) ); return true; } if ( fieldname == QLatin1String( "cellphone" ) ) { a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Cell ) ); return true; } if ( fieldname == QLatin1String( "pager" ) || // mozilla fieldname == QLatin1String( "pagerphone" ) ) { // mozilla a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Pager ) ); return true; } if ( fieldname == QLatin1String( "facsimiletelephonenumber" ) ) { a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Fax ) ); return true; } if ( fieldname == QLatin1String( "xmozillaanyphone" ) ) { // mozilla a.insertPhoneNumber( PhoneNumber( value, PhoneNumber::Work ) ); return true; } if ( fieldname == QLatin1String( "street" ) || fieldname == QLatin1String( "streethomeaddress" ) ) { homeAddr.setStreet( value ); return true; } if ( fieldname == QLatin1String( "postaladdress" ) ) { // mozilla workAddr.setStreet( value ); return true; } if ( fieldname == QLatin1String( "mozillapostaladdress2" ) ) { // mozilla workAddr.setStreet( workAddr.street() + QLatin1String( "\n" ) + value ); return true; } if ( fieldname == QLatin1String( "postalcode" ) ) { workAddr.setPostalCode( value ); return true; } if ( fieldname == QLatin1String( "postofficebox" ) ) { workAddr.setPostOfficeBox( value ); return true; } if ( fieldname == QLatin1String( "homepostaladdress" ) ) { // Netscape 7 homeAddr.setStreet( value ); return true; } if ( fieldname == QLatin1String( "mozillahomepostaladdress2" ) ) { // mozilla homeAddr.setStreet( homeAddr.street() + QLatin1String( "\n" ) + value ); return true; } if ( fieldname == QLatin1String( "mozillahomelocalityname" ) ) { // mozilla homeAddr.setLocality( value ); return true; } if ( fieldname == QLatin1String( "mozillahomestate" ) ) { // mozilla homeAddr.setRegion( value ); return true; } if ( fieldname == QLatin1String( "mozillahomepostalcode" ) ) { // mozilla homeAddr.setPostalCode( value ); return true; } if ( fieldname == QLatin1String( "mozillahomecountryname" ) ) { // mozilla if ( value.length() <= 2 ) { value = Address::ISOtoCountry( value ); } homeAddr.setCountry( value ); return true; } if ( fieldname == QLatin1String( "locality" ) ) { workAddr.setLocality( value ); return true; } if ( fieldname == QLatin1String( "streetaddress" ) ) { // Netscape 4.x workAddr.setStreet( value ); return true; } if ( fieldname == QLatin1String( "countryname" ) || fieldname == QLatin1String( "c" ) ) { // mozilla if ( value.length() <= 2 ) { value = Address::ISOtoCountry( value ); } workAddr.setCountry( value ); return true; } if ( fieldname == QLatin1String( "l" ) ) { // mozilla workAddr.setLocality( value ); return true; } if ( fieldname == QLatin1String( "st" ) ) { workAddr.setRegion( value ); return true; } if ( fieldname == QLatin1String( "ou" ) ) { a.setRole( value ); return true; } if ( fieldname == QLatin1String( "department" ) ) { a.setDepartment( value ); return true; } if ( fieldname == QLatin1String( "member" ) ) { // this is a mozilla list member (cn=xxx, mail=yyy) QStringList list = value.split( QLatin1Char( ',' ) ); QString name, email; QStringList::Iterator it; for ( it = list.begin(); it != list.end(); ++it ) { if ( (*it).startsWith( QLatin1String( "cn=" ) ) ) { name = (*it).mid( 3 ).trimmed(); } if ( (*it).startsWith( QLatin1String( "mail=" ) ) ) { email = (*it).mid( 5 ).trimmed(); } } if ( !name.isEmpty() && !email.isEmpty() ) { email = QLatin1String( " <" ) + email + QLatin1Char( '>' ); } a.insertEmail( name + email ); a.insertCategory( i18n( "List of Emails" ) ); return true; } if ( fieldname == QLatin1String( "modifytimestamp" ) ) { if ( value == QLatin1String( "0Z" ) ) { // ignore return true; } QDateTime dt = VCardStringToDate( value ); if ( dt.isValid() ) { a.setRevision( dt ); return true; } } if ( fieldname == QLatin1String( "objectclass" ) ) { // ignore return true; } kWarning(5700) << QString::fromLatin1( "LDIFConverter: Unknown field for '%1': '%2=%3'\n" ). arg( a.formattedName() ).arg( fieldname ).arg( value ); return true; } diff --git a/kabc/lock.cpp b/kabc/lock.cpp index 1792bb11d..c7233c012 100644 --- a/kabc/lock.cpp +++ b/kabc/lock.cpp @@ -1,182 +1,183 @@ /* This file is part of libkabc. Copyright (c) 2001,2003 Cornelius Schumacher 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 "lock.h" #include #include #include #include #include #include #include #include #include #include #include #include using namespace KABC; class Lock::Private { public: Private( const QString &identifier ) : mIdentifier( identifier ), mOrigIdentifier( identifier ) { mIdentifier.replace( QLatin1Char( '/' ), QLatin1Char( '_' ) ); #ifdef Q_WS_WIN mIdentifier.replace( QLatin1Char( ':' ), QLatin1Char( '_' ) ); #endif } QString mIdentifier; QString mOrigIdentifier; QString mLockUniqueName; QString mError; }; Lock::Lock( const QString &identifier ) : d( new Private( identifier ) ) { } Lock::~Lock() { unlock(); delete d; } QString Lock::locksDir() { return KStandardDirs::locateLocal( "data", QLatin1String( "kabc/lock/" ) ); } bool Lock::readLockFile( const QString &filename, int &pid, QString &app ) { QFile file( filename ); if ( !file.open( QIODevice::ReadOnly ) ) { return false; } QTextStream t( &file ); t >> pid >> ws >> app; return true; } bool Lock::writeLockFile( const QString &filename ) { QFile file( filename ); if ( !file.open( QIODevice::WriteOnly ) ) { return false; } QTextStream t( &file ); t << ::getpid() << endl << QString( KGlobal::mainComponent().componentName() ); return true; } QString Lock::lockFileName() const { return locksDir() + d->mIdentifier + QLatin1String( ".lock" ); } bool Lock::lock() { QString lockName = lockFileName(); kDebug() << "-- lock name:" << lockName; if ( QFile::exists( lockName ) ) { // check if it is a stale lock file int pid; QString app; if ( !readLockFile( lockFileName(), pid, app ) ) { d->mError = i18n( "Unable to open lock file." ); return false; } int retval = ::kill( pid, 0 ); if ( retval == -1 && errno == ESRCH ) { // process doesn't exists anymore QFile::remove( lockName ); kWarning() << "Removed stale lock file from process '" << app << "'"; } else { d->mError = i18n( "The resource '%1' is locked by application '%2'.", d->mOrigIdentifier, app ); return false; } } QString lockUniqueName; lockUniqueName = d->mIdentifier + KRandom::randomString( 8 ); - d->mLockUniqueName = KStandardDirs::locateLocal( "data", QLatin1String( "kabc/lock/" ) + lockUniqueName ); + d->mLockUniqueName = KStandardDirs::locateLocal( + "data", QLatin1String( "kabc/lock/" ) + lockUniqueName ); kDebug() << "-- lock unique name:" << d->mLockUniqueName; // Create unique file writeLockFile( d->mLockUniqueName ); // Create lock file int result = ::link( QFile::encodeName( d->mLockUniqueName ), QFile::encodeName( lockName ) ); if ( result == 0 ) { d->mError.clear(); emit locked(); return true; } // TODO: check stat d->mError = i18n( "Error" ); return false; } bool Lock::unlock() { int pid; QString app; if ( readLockFile( lockFileName(), pid, app ) ) { if ( pid == getpid() ) { QFile::remove( lockFileName() ); QFile::remove( d->mLockUniqueName ); emit unlocked(); } else { d->mError = i18n( "Unlock failed. Lock file is owned by other process: %1 (%2)", app, pid ); kDebug() << d->mError; return false; } } d->mError.clear(); return true; } QString Lock::error() const { return d->mError; } #include "lock.moc" diff --git a/kabc/phonenumber.cpp b/kabc/phonenumber.cpp index 56d09b8e3..7879633ca 100644 --- a/kabc/phonenumber.cpp +++ b/kabc/phonenumber.cpp @@ -1,262 +1,263 @@ /* This file is part of libkabc. Copyright (c) 2001 Cornelius Schumacher 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 "phonenumber.h" #include #include #include #include using namespace KABC; static QString cleanupNumber( const QString &input ) { return input.simplified(); } class PhoneNumber::Private : public QSharedData { public: Private( Type type ) : mId( KRandom::randomString( 8 ) ), mType( type ) { } Private( const Private &other ) : QSharedData( other ) { mId = other.mId; mType = other.mType; mNumber = other.mNumber; } QString mId; Type mType; QString mNumber; }; PhoneNumber::PhoneNumber() : d( new Private( Home ) ) { } PhoneNumber::PhoneNumber( const QString &number, Type type ) : d( new Private( type ) ) { d->mNumber = cleanupNumber( number ); } PhoneNumber::PhoneNumber( const PhoneNumber &other ) : d( other.d ) { } PhoneNumber::~PhoneNumber() { } bool PhoneNumber::operator==( const PhoneNumber &other ) const { if ( d->mId != other.d->mId ) { return false; } if ( d->mNumber != other.d->mNumber ) { return false; } if ( d->mType != other.d->mType ) { return false; } return true; } bool PhoneNumber::operator!=( const PhoneNumber &other ) const { return !( other == *this ); } PhoneNumber &PhoneNumber::operator=( const PhoneNumber &other ) { if ( this != &other ) { d = other.d; } return *this; } bool PhoneNumber::isEmpty() const { return d->mNumber.isEmpty(); } void PhoneNumber::setId( const QString &id ) { d->mId = id; } QString PhoneNumber::id() const { return d->mId; } void PhoneNumber::setNumber( const QString &number ) { d->mNumber = cleanupNumber( number ); } QString PhoneNumber::number() const { return d->mNumber; } void PhoneNumber::setType( Type type ) { d->mType = type; } PhoneNumber::Type PhoneNumber::type() const { return d->mType; } QString PhoneNumber::typeLabel() const { QString label; bool first = true; const TypeList list = typeList(); TypeList::ConstIterator it; for ( it = list.begin(); it != list.end(); ++it ) { if ( ( type() & (*it) ) && ( (*it) != Pref ) ) { - if ( !first ) + if ( !first ) { label.append( QLatin1Char( '/' ) ); + } label.append( typeLabel( *it ) ); if ( first ) { first = false; } } } return label; } PhoneNumber::TypeList PhoneNumber::typeList() { static TypeList list; if ( list.isEmpty() ) { list << Home << Work << Msg << Pref << Voice << Fax << Cell << Video << Bbs << Modem << Car << Isdn << Pcs << Pager; } return list; } QString PhoneNumber::typeLabel( Type type ) { if ( type & Pref ) { return i18nc( "Preferred phone", "Preferred" ); } switch ( type ) { case Home: return i18nc( "Home phone", "Home" ); break; case Work: return i18nc( "Work phone", "Work" ); break; case Msg: return i18n( "Messenger" ); break; case Pref: return i18n( "Preferred Number" ); break; case Voice: return i18n( "Voice" ); break; case Fax: return i18n( "Fax" ); break; case Cell: return i18nc( "Mobile Phone", "Mobile" ); break; case Video: return i18nc( "Video phone", "Video" ); break; case Bbs: return i18n( "Mailbox" ); break; case Modem: return i18n( "Modem" ); break; case Car: return i18nc( "Car Phone", "Car" ); break; case Isdn: return i18n( "ISDN" ); break; case Pcs: return i18n( "PCS" ); break; case Pager: return i18n( "Pager" ); break; case Home + Fax: return i18n( "Home Fax" ); break; case Work + Fax: return i18n( "Work Fax" ); break; default: return i18nc( "another type of phone", "Other" ); } } QString PhoneNumber::toString() const { QString str; str += QString::fromLatin1( "PhoneNumber {\n" ); str += QString::fromLatin1( " Id: %1\n" ).arg( d->mId ); str += QString::fromLatin1( " Type: %1\n" ).arg( typeLabel( d->mType ) ); str += QString::fromLatin1( " Number: %1\n" ).arg( d->mNumber ); str += QString::fromLatin1( "}\n" ); return str; } QDataStream &KABC::operator<<( QDataStream &s, const PhoneNumber &phone ) { return s << phone.d->mId << (uint)phone.d->mType << phone.d->mNumber; } QDataStream &KABC::operator>>( QDataStream &s, PhoneNumber &phone ) { uint type; s >> phone.d->mId >> type >> phone.d->mNumber; phone.d->mType = PhoneNumber::Type( type ); return s; } diff --git a/kabc/picture.cpp b/kabc/picture.cpp index a81a6e2a7..0a51c8b0d 100644 --- a/kabc/picture.cpp +++ b/kabc/picture.cpp @@ -1,187 +1,187 @@ /* This file is part of libkabc. Copyright (c) 2002 Tobias Koenig 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 "picture.h" #include #include using namespace KABC; class Picture::Private : public QSharedData { public: Private() : mIntern( false ) { } Private( const Private &other ) : QSharedData( other ) { mUrl = other.mUrl; mType = other.mType; mData = other.mData; mIntern = other.mIntern; } QString mUrl; QString mType; QImage mData; bool mIntern; }; Picture::Picture() : d( new Private ) { } Picture::Picture( const QString &url ) : d( new Private ) { d->mUrl = url; } Picture::Picture( const QImage &data ) : d( new Private ) { d->mIntern = true; d->mData = data; } Picture::Picture( const Picture &other ) : d( other.d ) { } Picture::~Picture() { } Picture &Picture::operator=( const Picture &other ) { if ( this != &other ) { d = other.d; } return *this; } bool Picture::operator==( const Picture &p ) const { if ( d->mIntern != p.d->mIntern ) { return false; } if ( d->mIntern ) { if ( d->mData != p.d->mData ) { return false; } } else { if ( d->mUrl != p.d->mUrl ) { return false; } } return true; } bool Picture::operator!=( const Picture &p ) const { return !( p == *this ); } bool Picture::isEmpty() const { return - ((d->mIntern == false && d->mUrl.isEmpty()) || - (d->mIntern == true && d->mData.isNull())); + ( ( d->mIntern == false && d->mUrl.isEmpty() ) || ( d->mIntern == true && d->mData.isNull() ) ); } void Picture::setUrl( const QString &url ) { d->mUrl = url; d->mIntern = false; } void Picture::setData( const QImage &data ) { d->mData = data; d->mIntern = true; } void Picture::setType( const QString &type ) { d->mType = type; } bool Picture::isIntern() const { return d->mIntern; } QString Picture::url() const { return d->mUrl; } QImage Picture::data() const { return d->mData; } QString Picture::type() const { return d->mType; } QString Picture::toString() const { QString str; str += QLatin1String( "Picture {\n" ); str += QString::fromLatin1( " Type: %1\n" ).arg( d->mType ); - str += QString::fromLatin1( " IsIntern: %1\n" ).arg( d->mIntern ? QLatin1String( "true" ) : QLatin1String( "false" ) ); + str += QString::fromLatin1( " IsIntern: %1\n" ). + arg( d->mIntern ? QLatin1String( "true" ) : QLatin1String( "false" ) ); if ( d->mIntern ) { QByteArray data; QBuffer buffer( &data ); buffer.open( QIODevice::WriteOnly ); d->mData.save( &buffer, "PNG" ); str += QString::fromLatin1( " Data: %1\n" ).arg( QString::fromLatin1( data.toBase64() ) ); } else { str += QString::fromLatin1( " Url: %1\n" ).arg( d->mUrl ); } str += QLatin1String( "}\n" ); return str; } QDataStream &KABC::operator<<( QDataStream &s, const Picture &picture ) { return s << picture.d->mIntern << picture.d->mUrl << picture.d->mType << picture.d->mData; } QDataStream &KABC::operator>>( QDataStream &s, Picture &picture ) { s >> picture.d->mIntern >> picture.d->mUrl >> picture.d->mType >> picture.d->mData; return s; } diff --git a/kabc/plugins/file/resourcefile.cpp b/kabc/plugins/file/resourcefile.cpp index 46b56b6eb..38c180a38 100644 --- a/kabc/plugins/file/resourcefile.cpp +++ b/kabc/plugins/file/resourcefile.cpp @@ -1,473 +1,478 @@ /* This file is part of libkabc. Copyright (c) 2001,2003 Cornelius Schumacher 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 "resourcefile.h" #include "resourcefileconfig.h" #include "kabc/formatfactory.h" #include "kabc/stdaddressbook.h" #include "kabc/lock.h" #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace KABC; typedef QList< QPair > MissingEntryList; class ResourceFile::ResourceFilePrivate { public: QMap< QString, MissingEntryList > mMissingEntries; }; ResourceFile::ResourceFile() : Resource(), mFormat( 0 ), mTempFile( 0 ), mAsynchronous( false ), d( new ResourceFilePrivate ) { QString fileName, formatName; fileName = StdAddressBook::fileName(); formatName = QLatin1String( "vcard" ); init( fileName, formatName ); } ResourceFile::ResourceFile( const KConfigGroup &group ) : Resource( group ), mFormat( 0 ), mTempFile( 0 ), mAsynchronous( false ), d( new ResourceFilePrivate ) { QString fileName, formatName; fileName = group.readPathEntry( "FileName", StdAddressBook::fileName() ); formatName = group.readEntry( "FileFormat", "vcard" ); init( fileName, formatName ); } ResourceFile::ResourceFile( const QString &fileName, const QString &formatName ) : Resource(), mFormat( 0 ), mTempFile( 0 ), mAsynchronous( false ), d( new ResourceFilePrivate ) { init( fileName, formatName ); } void ResourceFile::init( const QString &fileName, const QString &formatName ) { mFormatName = formatName; FormatFactory *factory = FormatFactory::self(); mFormat = factory->format( mFormatName ); if ( !mFormat ) { mFormatName = QLatin1String( "vcard" ); mFormat = factory->format( mFormatName ); } connect( &mDirWatch, SIGNAL( dirty(const QString&) ), SLOT( fileChanged(const QString&) ) ); connect( &mDirWatch, SIGNAL( created(const QString&) ), SLOT( fileChanged(const QString&) ) ); connect( &mDirWatch, SIGNAL( deleted(const QString&) ), SLOT( fileChanged(const QString&) ) ); setFileName( fileName ); mDirWatch.addFile( KStandardDirs::locateLocal( "data", QLatin1String( "kabc/distlists" ) ) ); mLock = 0; } ResourceFile::~ResourceFile() { delete d; d = 0; delete mFormat; mFormat = 0; } void ResourceFile::writeConfig( KConfigGroup &group ) { Resource::writeConfig( group ); if ( mFileName == StdAddressBook::fileName() ) { group.deleteEntry( "FileName" ); } else { group.writePathEntry( "FileName", mFileName ); } group.writeEntry( "FileFormat", mFormatName ); } Ticket *ResourceFile::requestSaveTicket() { kDebug(); if ( !addressBook() ) { return 0; } delete mLock; mLock = new Lock( mFileName ); if ( mLock->lock() ) { addressBook()->emitAddressBookLocked(); } else { addressBook()->error( mLock->error() ); kDebug() << "Unable to lock file '" << mFileName << "':" << mLock->error(); return 0; } return createTicket( this ); } void ResourceFile::releaseSaveTicket( Ticket *ticket ) { delete ticket; delete mLock; mLock = 0; addressBook()->emitAddressBookUnlocked(); } bool ResourceFile::doOpen() { QFile file( mFileName ); if ( !file.exists() ) { // try to create the file bool ok = file.open( QIODevice::WriteOnly ); if ( ok ) { file.close(); } return ok; } else { QFileInfo fileInfo( mFileName ); if ( readOnly() || !fileInfo.isWritable() ) { if ( !file.open( QIODevice::ReadOnly ) ) { return false; } } else { if ( !file.open( QIODevice::ReadWrite ) ) { return false; } } if ( file.size() == 0 ) { file.close(); return true; } bool ok = mFormat->checkFormat( &file ); file.close(); return ok; } } void ResourceFile::doClose() { } bool ResourceFile::load() { kDebug() << mFileName << "'"; mAsynchronous = false; QFile file( mFileName ); if ( !file.open( QIODevice::ReadOnly ) ) { addressBook()->error( i18n( "Unable to open file '%1'.", mFileName ) ); return false; } if ( !clearAndLoad( &file ) ) { addressBook()->error( i18n( "Problems during parsing file '%1'.", mFileName ) ); return false; } return true; } bool ResourceFile::clearAndLoad( QFile *file ) { clear(); bool addresseesOk = mFormat->loadAll( addressBook(), this, file ); bool listsOk = loadDistributionLists(); return addresseesOk && listsOk; } bool ResourceFile::asyncLoad() { mAsynchronous = true; load(); QTimer::singleShot( 0, this, SLOT( emitLoadingFinished() ) ); return true; } bool ResourceFile::save( Ticket *ticket ) { Q_UNUSED( ticket ); kDebug(); // create backup file QString extension = QLatin1Char( '_' ) + QString::number( QDate::currentDate().dayOfWeek() ); (void) KSaveFile::simpleBackupFile( mFileName, QString(), extension ); mDirWatch.stopScan(); KSaveFile saveFile( mFileName ); bool ok = false; if ( saveFile.open() ) { saveToFile( &saveFile ); ok = saveFile.finalize(); } if ( !ok ) { addressBook()->error( i18n( "Unable to save file '%1'.", mFileName ) ); } mDirWatch.startScan(); return ok; } bool ResourceFile::asyncSave( Ticket *ticket ) { kDebug(); save( ticket ); QTimer::singleShot( 0, this, SLOT( emitSavingFinished() ) ); return true; } void ResourceFile::emitLoadingFinished() { emit loadingFinished( this ); } void ResourceFile::emitSavingFinished() { emit savingFinished( this ); } bool ResourceFile::loadDistributionLists() { KConfig cfg( KStandardDirs::locateLocal( "data", QLatin1String( "kabc/distlists" ) ) ); KConfigGroup cg( &cfg, "DistributionLists" ); KConfigGroup cgId( &cfg, "DistributionLists-Identifiers" ); const QStringList entryList = cg.keyList(); d->mMissingEntries.clear(); QStringList::ConstIterator it; for ( it = entryList.constBegin(); it != entryList.constEnd(); ++it ) { const QString name = *it; const QStringList value = cg.readEntry( name, QStringList() ); kDebug() << name << QLatin1Char( ':' ) << value.join( QLatin1String( "," ) ); DistributionList *list = 0; if ( cgId.isValid() ) { const QString identifier = cgId.readEntry( name, QString() ); - if ( !identifier.isEmpty() ) + if ( !identifier.isEmpty() ) { list = new DistributionList( this, identifier, name ); + } } - if ( list == 0 ) - list = new DistributionList( this, name ); + if ( list == 0 ) { + list = new DistributionList( this, name ); + } MissingEntryList missingEntries; QStringList::ConstIterator entryIt = value.constBegin(); while ( entryIt != value.constEnd() ) { QString id = *entryIt++; QString email = entryIt != value.constEnd() ? *entryIt : QString(); if ( email.isEmpty() && !email.isNull() ) { email = QString(); } kDebug() << "----- Entry" << id; Addressee a = addressBook()->findByUid( id ); if ( !a.isEmpty() ) { list->insertEntry( a, email ); } else { missingEntries.append( qMakePair( id, email ) ); } if ( entryIt == value.constEnd() ) { break; } ++entryIt; } d->mMissingEntries.insert( name, missingEntries ); } return true; } void ResourceFile::saveDistributionLists() { kDebug(); KConfig cfg( KStandardDirs::locateLocal( "data", QLatin1String( "kabc/distlists" ) ) ); KConfigGroup cg( &cfg, "DistributionLists" ); cg.deleteGroup(); KConfigGroup cgId( &cfg, "DistributionLists-Identifiers" ); cgId.deleteGroup(); QMapIterator it( mDistListMap ); while ( it.hasNext() ) { DistributionList *list = it.next().value(); kDebug() << " Saving '" << list->name() << "'"; QStringList value; const DistributionList::Entry::List entries = list->entries(); DistributionList::Entry::List::ConstIterator it; for ( it = entries.begin(); it != entries.end(); ++it ) { value.append( (*it).addressee().uid() ); value.append( (*it).email() ); } if ( d->mMissingEntries.find( list->name() ) != d->mMissingEntries.end() ) { const MissingEntryList missList = d->mMissingEntries[ list->name() ]; MissingEntryList::ConstIterator missIt; for ( missIt = missList.begin(); missIt != missList.end(); ++missIt ) { value.append( (*missIt).first ); value.append( (*missIt).second ); } } cg.writeEntry( list->name(), value ); cgId.writeEntry( list->name(), list->identifier() ); } cfg.sync(); } void ResourceFile::saveToFile( QFile *file ) { mFormat->saveAll( addressBook(), this, file ); saveDistributionLists(); } void ResourceFile::setFileName( const QString &fileName ) { mDirWatch.stopScan(); if ( mDirWatch.contains( mFileName ) ) { mDirWatch.removeFile( mFileName ); } mFileName = fileName; mDirWatch.addFile( mFileName ); mDirWatch.startScan(); } QString ResourceFile::fileName() const { return mFileName; } void ResourceFile::setFormat( const QString &format ) { mFormatName = format; delete mFormat; FormatFactory *factory = FormatFactory::self(); mFormat = factory->format( mFormatName ); } QString ResourceFile::format() const { return mFormatName; } void ResourceFile::fileChanged( const QString &path ) { kDebug() << path; if ( !addressBook() ) { return; } if ( path == KStandardDirs::locateLocal( "data", QLatin1String( "kabc/distlists" ) ) ) { // clear old distribution lists // take a copy of mDistListMap, then clear it and finally qDeleteAll // the copy to avoid problems with removeDistributionList() called by // ~DistributionList(). DistributionListMap tempDistListMap( mDistListMap ); mDistListMap.clear(); qDeleteAll( tempDistListMap ); loadDistributionLists(); kDebug() << "addressBookChanged()"; addressBook()->emitAddressBookChanged(); return; } // clear(); // moved to clearAndLoad() if ( mAsynchronous ) { asyncLoad(); } else { load(); kDebug() << "addressBookChanged()"; addressBook()->emitAddressBookChanged(); } } void ResourceFile::removeAddressee( const Addressee &addr ) { - QFile::remove( KStandardDirs::locateLocal( "data", QLatin1String( "kabc/photos/" ) ) + addr.uid() ); - QFile::remove( KStandardDirs::locateLocal( "data", QLatin1String( "kabc/logos/" ) ) + addr.uid() ); - QFile::remove( KStandardDirs::locateLocal( "data", QLatin1String( "kabc/sounds/" ) ) + addr.uid() ); + QFile::remove( KStandardDirs::locateLocal( + "data", QLatin1String( "kabc/photos/" ) ) + addr.uid() ); + QFile::remove( KStandardDirs::locateLocal( + "data", QLatin1String( "kabc/logos/" ) ) + addr.uid() ); + QFile::remove( KStandardDirs::locateLocal( + "data", QLatin1String( "kabc/sounds/" ) ) + addr.uid() ); mAddrMap.remove( addr.uid() ); } #include "resourcefile.moc" diff --git a/kabc/plugins/ldapkio/resourceldapkio.cpp b/kabc/plugins/ldapkio/resourceldapkio.cpp index 3f1753ed2..ceea02d91 100644 --- a/kabc/plugins/ldapkio/resourceldapkio.cpp +++ b/kabc/plugins/ldapkio/resourceldapkio.cpp @@ -1,1127 +1,1142 @@ // -*- c-basic-offset: 2 -*- /* This file is part of libkabc. Copyright (c) 2003 Tobias Koenig Copyright (c) 2004 Szombathelyi György 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 "resourceldapkio.h" #include "resourceldapkioconfig.h" #include "kldap/ldif.h" #include "kldap/ldapdn.h" #include "kldap/ldapurl.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace KABC; class ResourceLDAPKIO::Private { public: Private( ResourceLDAPKIO *parent ) : mParent( parent ), mPort( 389 ), mAnonymous( true ), mTLS( false ), mSSL( false ), mSubTree( false ), mSASL( false ), mVer( 3 ), mRDNPrefix( 0 ), mTimeLimit( 0 ), mSizeLimit( 0 ), mCachePolicy( Cache_No ), mAutoCache( true ) { KGlobal::locale()->insertCatalog( QLatin1String( "libkldap" ) ); } KIO::Job *loadFromCache(); void createCache(); void activateCache(); void enter_loop(); QByteArray addEntry( const QString &attr, const QString &value, bool mod ); QString findUid( const QString &uid ); bool AddresseeToLDIF( QByteArray &ldif, const Addressee &addr, const QString &olddn ); ResourceLDAPKIO *mParent; QString mUser; QString mPassword; QString mDn; QString mHost; QString mFilter; int mPort; bool mAnonymous; QMap mAttributes; QString mErrorMsg; KLDAP::Ldif mLdif; bool mTLS, mSSL, mSubTree; QString mResultDn; Addressee mAddr; Address mAd; Resource::Iterator mSaveIt; bool mSASL; QString mMech; QString mRealm, mBindDN; KLDAP::LdapUrl mLDAPUrl; int mVer; int mRDNPrefix; int mTimeLimit; int mSizeLimit; int mError; int mCachePolicy; bool mReadOnly; bool mAutoCache; QString mCacheDst; KTemporaryFile *mTmp; }; ResourceLDAPKIO::ResourceLDAPKIO() : Resource(), d( new Private( this ) ) { d->mCacheDst = KGlobal::dirs()->saveLocation( "cache", QLatin1String( "ldapkio" ) ) + QLatin1Char( '/' ) + type() + QLatin1Char( '_' ) + identifier(); init(); } ResourceLDAPKIO::ResourceLDAPKIO( const KConfigGroup &group ) : Resource( group ), d( new Private( this ) ) { QMap attrList; QStringList attributes = group.readEntry( "LdapAttributes", QStringList() ); for ( int pos = 0; pos < attributes.count(); pos += 2 ) { d->mAttributes.insert( attributes[ pos ], attributes[ pos + 1 ] ); } d->mUser = group.readEntry( "LdapUser" ); d->mPassword = KStringHandler::obscure( group.readEntry( "LdapPassword" ) ); d->mDn = group.readEntry( "LdapDn" ); d->mHost = group.readEntry( "LdapHost" ); d->mPort = group.readEntry( "LdapPort", 389 ); d->mFilter = group.readEntry( "LdapFilter" ); d->mAnonymous = group.readEntry( "LdapAnonymous", false ); d->mTLS = group.readEntry( "LdapTLS", false ); d->mSSL = group.readEntry( "LdapSSL", false ); d->mSubTree = group.readEntry( "LdapSubTree", false ); d->mSASL = group.readEntry( "LdapSASL", false ); d->mMech = group.readEntry( "LdapMech" ); d->mRealm = group.readEntry( "LdapRealm" ); d->mBindDN = group.readEntry( "LdapBindDN" ); d->mVer = group.readEntry( "LdapVer", 3 ); d->mTimeLimit = group.readEntry( "LdapTimeLimit", 0 ); d->mSizeLimit = group.readEntry( "LdapSizeLimit", 0 ); d->mRDNPrefix = group.readEntry( "LdapRDNPrefix", 0 ); d->mCachePolicy = group.readEntry( "LdapCachePolicy", 0 ); d->mAutoCache = group.readEntry( "LdapAutoCache", true ); - d->mCacheDst = KGlobal::dirs()->saveLocation( "cache", QLatin1String( "ldapkio" ) ) + QLatin1Char( '/' ) + + d->mCacheDst = KGlobal::dirs()->saveLocation( + "cache", QLatin1String( "ldapkio" ) ) + QLatin1Char( '/' ) + type() + QLatin1Char( '_' ) + identifier(); init(); } ResourceLDAPKIO::~ResourceLDAPKIO() { delete d; } void ResourceLDAPKIO::Private::enter_loop() { QEventLoop eventLoop; mParent->connect( mParent, SIGNAL( leaveModality() ), &eventLoop, SLOT( quit() ) ); eventLoop.exec( QEventLoop::ExcludeUserInputEvents ); } void ResourceLDAPKIO::entries( KIO::Job *, const KIO::UDSEntryList &list ) { KIO::UDSEntryList::ConstIterator it = list.begin(); KIO::UDSEntryList::ConstIterator end = list.end(); for ( ; it != end; ++it ) { const QString urlStr = (*it).stringValue( KIO::UDSEntry::UDS_URL ); if ( !urlStr.isEmpty() ) { KUrl tmpurl( urlStr ); d->mResultDn = tmpurl.path(); kDebug() << "findUid():" << d->mResultDn; if ( d->mResultDn.startsWith( QLatin1Char( '/' ) ) ) { d->mResultDn.remove( 0, 1 ); } return; } } } void ResourceLDAPKIO::listResult( KJob *job ) { d->mError = job->error(); if ( d->mError && d->mError != KIO::ERR_USER_CANCELED ) { d->mErrorMsg = job->errorString(); } else { d->mErrorMsg.clear(); } emit leaveModality(); } QString ResourceLDAPKIO::Private::findUid( const QString &uid ) { KLDAP::LdapUrl url( mLDAPUrl ); KIO::UDSEntry entry; mErrorMsg.clear(); mResultDn.clear(); url.setAttributes( QStringList( QLatin1String( "dn" ) ) ); url.setFilter( QLatin1Char( '(' ) + mAttributes[ QLatin1String( "uid" ) ] + QLatin1Char( '=' ) + uid + QLatin1Char( ')' ) + mFilter ); url.setExtension( QLatin1String( "x-dir" ), QLatin1String( "one" ) ); kDebug() << uid << "url" << url.prettyUrl(); KIO::ListJob *listJob = KIO::listDir( url, KIO::HideProgressInfo ); mParent->connect( listJob, SIGNAL( entries( KIO::Job *, const KIO::UDSEntryList& ) ), SLOT( entries( KIO::Job*, const KIO::UDSEntryList& ) ) ); mParent->connect( listJob, SIGNAL( result( KJob* ) ), mParent, SLOT( listResult( KJob* ) ) ); enter_loop(); return mResultDn; } QByteArray ResourceLDAPKIO::Private::addEntry( const QString &attr, const QString &value, bool mod ) { QByteArray tmp; if ( !attr.isEmpty() ) { if ( mod ) { tmp += KLDAP::Ldif::assembleLine( QLatin1String( "replace" ), attr ) + '\n'; } tmp += KLDAP::Ldif::assembleLine( attr, value ) + '\n'; if ( mod ) { tmp += "-\n"; } } return tmp; } bool ResourceLDAPKIO::Private::AddresseeToLDIF( QByteArray &ldif, const Addressee &addr, const QString &olddn ) { QByteArray tmp; QString dn; QByteArray data; bool mod = false; if ( olddn.isEmpty() ) { //insert new entry switch ( mRDNPrefix ) { case 1: - dn = mAttributes[ QLatin1String( "uid" ) ] + QLatin1Char( '=' ) + addr.uid() + QLatin1Char( ',' ) + mDn; + dn = mAttributes[ QLatin1String( "uid" ) ] + + QLatin1Char( '=' ) + addr.uid() + QLatin1Char( ',' ) + mDn; break; case 0: default: - dn = mAttributes[ QLatin1String( "commonName" ) ] + QLatin1Char( '=' ) + addr.assembledName() + QLatin1Char( ',' ) + mDn; + dn = mAttributes[ QLatin1String( "commonName" ) ] + + QLatin1Char( '=' ) + addr.assembledName() + QLatin1Char( ',' ) + mDn; break; } } else { //modify existing entry mod = true; if ( olddn.startsWith( mAttributes[ QLatin1String( "uid" ) ] ) ) { dn = mAttributes[ QLatin1String( "uid" ) ] + QLatin1Char( '=' ) + addr.uid() + QLatin1Char( ',' ) + olddn.section( QLatin1Char( ',' ), 1 ); } else if ( olddn.startsWith( mAttributes[ QLatin1String( "commonName" ) ] ) ) { - dn = mAttributes[ QLatin1String( "commonName" ) ] + QLatin1Char( '=' ) + addr.assembledName() - + QLatin1Char( ',' ) + olddn.section( QLatin1Char( ',' ), 1 ); + dn = mAttributes[ QLatin1String( "commonName" ) ] + + QLatin1Char( '=' ) + addr.assembledName() + + QLatin1Char( ',' ) + olddn.section( QLatin1Char( ',' ), 1 ); } else { dn = olddn; } if ( olddn.toLower() != dn.toLower() ) { tmp = KLDAP::Ldif::assembleLine( QLatin1String( "dn" ), olddn ) + '\n'; tmp += "changetype: modrdn\n"; - tmp += KLDAP::Ldif::assembleLine( QLatin1String( "newrdn" ), dn.section( QLatin1Char( ',' ), 0, 0 ) ) + '\n'; + tmp += KLDAP::Ldif::assembleLine( QLatin1String( "newrdn" ), + dn.section( QLatin1Char( ',' ), 0, 0 ) ) + '\n'; tmp += "deleteoldrdn: 1\n\n"; } } tmp += KLDAP::Ldif::assembleLine( QLatin1String( "dn" ), dn ) + '\n'; if ( mod ) { tmp += "changetype: modify\n"; } if ( !mod ) { tmp += "objectClass: top\n"; - const QStringList obclass = mAttributes[ QLatin1String( "objectClass" ) ].split( QLatin1Char( ',' ), - QString::SkipEmptyParts ); + const QStringList obclass = + mAttributes[ QLatin1String( "objectClass" ) ].split( QLatin1Char( ',' ), + QString::SkipEmptyParts ); for ( QStringList::const_iterator it = obclass.constBegin(); it != obclass.constEnd(); ++it ) { tmp += KLDAP::Ldif::assembleLine( QLatin1String( "objectClass" ), *it ) + '\n'; } } tmp += addEntry( mAttributes[ QLatin1String( "commonName" ) ], addr.assembledName(), mod ); tmp += addEntry( mAttributes[ QLatin1String( "formattedName" ) ], addr.formattedName(), mod ); tmp += addEntry( mAttributes[ QLatin1String( "givenName" ) ], addr.givenName(), mod ); tmp += addEntry( mAttributes[ QLatin1String( "familyName" ) ], addr.familyName(), mod ); tmp += addEntry( mAttributes[ QLatin1String( "uid" ) ], addr.uid(), mod ); PhoneNumber number; number = addr.phoneNumber( PhoneNumber::Home ); tmp += addEntry( mAttributes[ QLatin1String( "phoneNumber" ) ], number.number(), mod ); number = addr.phoneNumber( PhoneNumber::Work ); tmp += addEntry( mAttributes[ QLatin1String( "telephoneNumber" ) ], number.number(), mod ); number = addr.phoneNumber( PhoneNumber::Fax ); - tmp += addEntry( mAttributes[ QLatin1String( "facsimileTelephoneNumber" ) ], number.number(), mod ); + tmp += addEntry( mAttributes[ QLatin1String( "facsimileTelephoneNumber" ) ], + number.number(), mod ); number = addr.phoneNumber( PhoneNumber::Cell ); tmp += addEntry( mAttributes[ QLatin1String( "mobile" ) ], number.number(), mod ); number = addr.phoneNumber( PhoneNumber::Pager ); tmp += addEntry( mAttributes[ QLatin1String( "pager" ) ], number.number(), mod ); tmp += addEntry( mAttributes[ QLatin1String( "description" ) ], addr.note(), mod ); tmp += addEntry( mAttributes[ QLatin1String( "title" ) ], addr.title(), mod ); tmp += addEntry( mAttributes[ QLatin1String( "organization" ) ], addr.organization(), mod ); Address ad = addr.address( Address::Home ); if ( !ad.isEmpty() ) { tmp += addEntry( mAttributes[ QLatin1String( "street" ) ], ad.street(), mod ); tmp += addEntry( mAttributes[ QLatin1String( "state" ) ], ad.region(), mod ); tmp += addEntry( mAttributes[ QLatin1String( "city" ) ], ad.locality(), mod ); tmp += addEntry( mAttributes[ QLatin1String( "postalcode" ) ], ad.postalCode(), mod ); } QStringList emails = addr.emails(); QStringList::ConstIterator mailIt = emails.constBegin(); if ( !mAttributes[ QLatin1String( "mail" ) ].isEmpty() ) { if ( mod ) { - tmp += KLDAP::Ldif::assembleLine( QLatin1String( "replace" ), mAttributes[ QLatin1String( "mail" ) ] ) + '\n'; + tmp += KLDAP::Ldif::assembleLine( QLatin1String( "replace" ), + mAttributes[ QLatin1String( "mail" ) ] ) + '\n'; } if ( mailIt != emails.constEnd() ) { tmp += KLDAP::Ldif::assembleLine( mAttributes[ QLatin1String( "mail" ) ], *mailIt ) + '\n'; mailIt ++; } - if ( mod && mAttributes[ QLatin1String( "mail" ) ] != mAttributes[ QLatin1String( "mailAlias" ) ] ) { + if ( mod && + mAttributes[ QLatin1String( "mail" ) ] != mAttributes[ QLatin1String( "mailAlias" ) ] ) { tmp += "-\n"; } } if ( !mAttributes[ QLatin1String( "mailAlias" ) ].isEmpty() ) { - if ( mod && mAttributes[ QLatin1String( "mail" ) ] != mAttributes[ QLatin1String( "mailAlias" ) ] ) { - tmp += KLDAP::Ldif::assembleLine( QLatin1String( "replace" ), mAttributes[ QLatin1String( "mailAlias" ) ] ) + '\n'; + if ( mod && + mAttributes[ QLatin1String( "mail" ) ] != mAttributes[ QLatin1String( "mailAlias" ) ] ) { + tmp += KLDAP::Ldif::assembleLine( QLatin1String( "replace" ), + mAttributes[ QLatin1String( "mailAlias" ) ] ) + '\n'; } for ( ; mailIt != emails.constEnd(); ++mailIt ) { - tmp += KLDAP::Ldif::assembleLine( mAttributes[ QLatin1String( "mailAlias" ) ], *mailIt ) + '\n'; + tmp += KLDAP::Ldif::assembleLine( + mAttributes[ QLatin1String( "mailAlias" ) ], *mailIt ) + '\n'; } if ( mod ) { tmp += "-\n"; } } if ( !mAttributes[ QLatin1String( "jpegPhoto" ) ].isEmpty() ) { QByteArray pic; QBuffer buffer( &pic ); buffer.open( QIODevice::WriteOnly ); addr.photo().data().save( &buffer, "JPEG" ); if ( mod ) { - tmp += KLDAP::Ldif::assembleLine( QLatin1String( "replace" ), mAttributes[ QLatin1String( "jpegPhoto" ) ] ) + '\n'; + tmp += KLDAP::Ldif::assembleLine( QLatin1String( "replace" ), + mAttributes[ QLatin1String( "jpegPhoto" ) ] ) + '\n'; } tmp += KLDAP::Ldif::assembleLine( mAttributes[ QLatin1String( "jpegPhoto" ) ], pic, 76 ) + '\n'; if ( mod ) { tmp += "-\n"; } } tmp += '\n'; kDebug() << "ldif:" << QString::fromUtf8( tmp ); ldif = tmp; return true; } void ResourceLDAPKIO::setReadOnly( bool value ) { //save the original readonly flag, because offline using disables writing d->mReadOnly = true; Resource::setReadOnly( value ); } void ResourceLDAPKIO::init() { if ( d->mPort == 0 ) { d->mPort = 389; } /** If you want to add new attributes, append them here, add a translation string in the ctor of AttributesDialog and handle them in the load() method below. These are the default values */ if ( !d->mAttributes.contains( QLatin1String( "objectClass" ) ) ) { d->mAttributes.insert( QLatin1String( "objectClass" ), QLatin1String( "inetOrgPerson" ) ); } if ( !d->mAttributes.contains( QLatin1String( "commonName" ) ) ) { d->mAttributes.insert( QLatin1String( "commonName" ), QLatin1String( "cn" ) ); } if ( !d->mAttributes.contains( QLatin1String( "formattedName" ) ) ) { d->mAttributes.insert( QLatin1String( "formattedName" ), QLatin1String( "displayName" ) ); } if ( !d->mAttributes.contains( QLatin1String( "familyName" ) ) ) { d->mAttributes.insert( QLatin1String( "familyName" ), QLatin1String( "sn" ) ); } if ( !d->mAttributes.contains( QLatin1String( "givenName" ) ) ) { d->mAttributes.insert( QLatin1String( "givenName" ), QLatin1String( "givenName" ) ); } if ( !d->mAttributes.contains( QLatin1String( "mail" ) ) ) { d->mAttributes.insert( QLatin1String( "mail" ), QLatin1String( "mail" ) ); } if ( !d->mAttributes.contains( QLatin1String( "mailAlias" ) ) ) { d->mAttributes.insert( QLatin1String( "mailAlias" ), QString() ); } if ( !d->mAttributes.contains( QLatin1String( "phoneNumber" ) ) ) { d->mAttributes.insert( QLatin1String( "phoneNumber" ), QLatin1String( "homePhone" ) ); } if ( !d->mAttributes.contains( QLatin1String( "telephoneNumber" ) ) ) { d->mAttributes.insert( QLatin1String( "telephoneNumber" ), QLatin1String( "telephoneNumber" ) ); } if ( !d->mAttributes.contains( QLatin1String( "facsimileTelephoneNumber" ) ) ) { - d->mAttributes.insert( QLatin1String( "facsimileTelephoneNumber" ), QLatin1String( "facsimileTelephoneNumber" ) ); + d->mAttributes.insert( QLatin1String( "facsimileTelephoneNumber" ), + QLatin1String( "facsimileTelephoneNumber" ) ); } if ( !d->mAttributes.contains( QLatin1String( "mobile" ) ) ) { d->mAttributes.insert( QLatin1String( "mobile" ), QLatin1String( "mobile" ) ); } if ( !d->mAttributes.contains( QLatin1String( "pager" ) ) ) { d->mAttributes.insert( QLatin1String( "pager" ), QLatin1String( "pager" ) ); } if ( !d->mAttributes.contains( QLatin1String( "description" ) ) ) { d->mAttributes.insert( QLatin1String( "description" ), QLatin1String( "description" ) ); } if ( !d->mAttributes.contains( QLatin1String( "title" ) ) ) { d->mAttributes.insert( QLatin1String( "title" ), QLatin1String( "title" ) ); } if ( !d->mAttributes.contains( QLatin1String( "street" ) ) ) { d->mAttributes.insert( QLatin1String( "street" ), QLatin1String( "street" ) ); } if ( !d->mAttributes.contains( QLatin1String( "state" ) ) ) { d->mAttributes.insert( QLatin1String( "state" ), QLatin1String( "st" ) ); } if ( !d->mAttributes.contains( QLatin1String( "city" ) ) ) { d->mAttributes.insert( QLatin1String( "city" ), QLatin1String( "l" ) ); } if ( !d->mAttributes.contains( QLatin1String( "organization" ) ) ) { d->mAttributes.insert( QLatin1String( "organization" ), QLatin1String( "o" ) ); } if ( !d->mAttributes.contains( QLatin1String( "postalcode" ) ) ) { d->mAttributes.insert( QLatin1String( "postalcode" ), QLatin1String( "postalCode" ) ); } if ( !d->mAttributes.contains( QLatin1String( "uid" ) ) ) { d->mAttributes.insert( QLatin1String( "uid" ), QLatin1String( "uid" ) ); } if ( !d->mAttributes.contains( QLatin1String( "jpegPhoto" ) ) ) { d->mAttributes.insert( QLatin1String( "jpegPhoto" ), QLatin1String( "jpegPhoto" ) ); } d->mLDAPUrl = KLDAP::LdapUrl( KUrl() ); if ( !d->mAnonymous ) { d->mLDAPUrl.setExtension( QLatin1String( "bindname" ), d->mBindDN ); d->mLDAPUrl.setUser( d->mUser ); d->mLDAPUrl.setPass( d->mPassword ); } d->mLDAPUrl.setProtocol( d->mSSL ? QLatin1String( "ldaps" ) : QLatin1String( "ldap" ) ); d->mLDAPUrl.setHost( d->mHost ); d->mLDAPUrl.setPort( d->mPort ); d->mLDAPUrl.setDn( KLDAP::LdapDN( d->mDn ) ); if ( !d->mAttributes.empty() ) { QMap::Iterator it; QStringList attr; for ( it = d->mAttributes.begin(); it != d->mAttributes.end(); ++it ) { if ( !it.value().isEmpty() && it.key() != QLatin1String( "objectClass" ) ) { attr.append( it.value() ); } } d->mLDAPUrl.setAttributes( attr ); } d->mLDAPUrl.setScope( d->mSubTree ? KLDAP::LdapUrl::Sub : KLDAP::LdapUrl::One ); if ( !d->mFilter.isEmpty() && d->mFilter != QLatin1String( "(objectClass=*)" ) ) { d->mLDAPUrl.setFilter( d->mFilter ); } d->mLDAPUrl.setExtension( QLatin1String( "x-dir" ), QLatin1String( "base" ) ); if ( d->mTLS ) { d->mLDAPUrl.setExtension( QLatin1String( "x-tls" ), QString() ); } d->mLDAPUrl.setExtension( QLatin1String( "x-ver" ), QString::number( d->mVer ) ); if ( d->mSizeLimit ) { d->mLDAPUrl.setExtension( QLatin1String( "x-sizelimit" ), QString::number( d->mSizeLimit ) ); } if ( d->mTimeLimit ) { d->mLDAPUrl.setExtension( QLatin1String( "x-timelimit" ), QString::number( d->mTimeLimit ) ); } if ( d->mSASL ) { d->mLDAPUrl.setExtension( QLatin1String( "x-sasl" ), QString() ); if ( !d->mMech.isEmpty() ) { d->mLDAPUrl.setExtension( QLatin1String( "x-mech" ), d->mMech ); } if ( !d->mRealm.isEmpty() ) { d->mLDAPUrl.setExtension( QLatin1String( "x-realm" ), d->mRealm ); } } d->mReadOnly = readOnly(); kDebug() << "resource_ldapkio url:" << d->mLDAPUrl.prettyUrl(); } void ResourceLDAPKIO::writeConfig( KConfigGroup &group ) { Resource::writeConfig( group ); group.writeEntry( "LdapUser", d->mUser ); group.writeEntry( "LdapPassword", KStringHandler::obscure( d->mPassword ) ); group.writeEntry( "LdapDn", d->mDn ); group.writeEntry( "LdapHost", d->mHost ); group.writeEntry( "LdapPort", d->mPort ); group.writeEntry( "LdapFilter", d->mFilter ); group.writeEntry( "LdapAnonymous", d->mAnonymous ); group.writeEntry( "LdapTLS", d->mTLS ); group.writeEntry( "LdapSSL", d->mSSL ); group.writeEntry( "LdapSubTree", d->mSubTree ); group.writeEntry( "LdapSASL", d->mSASL ); group.writeEntry( "LdapMech", d->mMech ); group.writeEntry( "LdapVer", d->mVer ); group.writeEntry( "LdapTimeLimit", d->mTimeLimit ); group.writeEntry( "LdapSizeLimit", d->mSizeLimit ); group.writeEntry( "LdapRDNPrefix", d->mRDNPrefix ); group.writeEntry( "LdapRealm", d->mRealm ); group.writeEntry( "LdapBindDN", d->mBindDN ); group.writeEntry( "LdapCachePolicy", d->mCachePolicy ); group.writeEntry( "LdapAutoCache", d->mAutoCache ); QStringList attributes; QMap::const_iterator it; for ( it = d->mAttributes.constBegin(); it != d->mAttributes.constEnd(); ++it ) { attributes << it.key() << it.value(); } group.writeEntry( "LdapAttributes", attributes ); } Ticket *ResourceLDAPKIO::requestSaveTicket() { if ( !addressBook() ) { kDebug() << "no addressbook"; return 0; } return createTicket( this ); } void ResourceLDAPKIO::releaseSaveTicket( Ticket *ticket ) { delete ticket; } bool ResourceLDAPKIO::doOpen() { return true; } void ResourceLDAPKIO::doClose() { } void ResourceLDAPKIO::Private::createCache() { mTmp = 0; if ( mCachePolicy == Cache_NoConnection && mAutoCache ) { mTmp = new KTemporaryFile; mTmp->setPrefix( mCacheDst ); mTmp->setSuffix( QLatin1String( "tmp" ) ); mTmp->open(); } } void ResourceLDAPKIO::Private::activateCache() { if ( mTmp && mError == 0 ) { QString filename = mTmp->fileName(); delete mTmp; mTmp = 0; KDE_rename( QFile::encodeName( filename ), QFile::encodeName( mCacheDst ) ); } } KIO::Job *ResourceLDAPKIO::Private::loadFromCache() { KIO::Job *job = 0; if ( mCachePolicy == Cache_Always || ( mCachePolicy == Cache_NoConnection && mError == KIO::ERR_COULD_NOT_CONNECT ) ) { mAddr = Addressee(); mAd = Address( Address::Home ); //initialize ldif parser mLdif.startParsing(); mParent->Resource::setReadOnly( true ); KUrl url( mCacheDst ); job = KIO::get( url, KIO::Reload, KIO::HideProgressInfo ); mParent->connect( job, SIGNAL( data( KIO::Job*, const QByteArray& ) ), mParent, SLOT( data( KIO::Job*, const QByteArray& ) ) ); } return job; } bool ResourceLDAPKIO::load() { kDebug(); KIO::Job *job; clear(); //clear the addressee d->mAddr = Addressee(); d->mAd = Address( Address::Home ); //initialize ldif parser d->mLdif.startParsing(); //set to original settings, offline use will disable writing Resource::setReadOnly( d->mReadOnly ); d->createCache(); if ( d->mCachePolicy != Cache_Always ) { job = KIO::get( d->mLDAPUrl, KIO::Reload, KIO::HideProgressInfo ); connect( job, SIGNAL( data( KIO::Job*, const QByteArray& ) ), this, SLOT( data( KIO::Job*, const QByteArray& ) ) ); connect( job, SIGNAL( result( KJob* ) ), this, SLOT( syncLoadSaveResult( KJob* ) ) ); d->enter_loop(); } job = d->loadFromCache(); if ( job ) { connect( job, SIGNAL( result( KJob* ) ), this, SLOT( syncLoadSaveResult( KJob* ) ) ); d->enter_loop(); } if ( d->mErrorMsg.isEmpty() ) { kDebug() << "ResourceLDAPKIO load ok!"; return true; } else { kDebug() << "ResourceLDAPKIO load finished with error:" << d->mErrorMsg; addressBook()->error( d->mErrorMsg ); return false; } } bool ResourceLDAPKIO::asyncLoad() { clear(); //clear the addressee d->mAddr = Addressee(); d->mAd = Address( Address::Home ); //initialize ldif parser d->mLdif.startParsing(); Resource::setReadOnly( d->mReadOnly ); d->createCache(); if ( d->mCachePolicy != Cache_Always ) { KIO::Job *job = KIO::get( d->mLDAPUrl, KIO::Reload, KIO::HideProgressInfo ); connect( job, SIGNAL( data( KIO::Job*, const QByteArray& ) ), this, SLOT( data( KIO::Job*, const QByteArray& ) ) ); connect( job, SIGNAL( result( KJob* ) ), this, SLOT( result( KJob* ) ) ); } else { result( 0 ); } return true; } void ResourceLDAPKIO::data( KIO::Job *job, const QByteArray &data ) { Q_UNUSED( job ); if ( data.size() ) { d->mLdif.setLdif( data ); if ( d->mTmp ) { d->mTmp->write( data ); } } else { d->mLdif.endLdif(); } KLDAP::Ldif::ParseValue ret; QString name; QByteArray value; do { ret = d->mLdif.nextItem(); switch ( ret ) { case KLDAP::Ldif::NewEntry: kDebug() << "new entry:" << d->mLdif.dn().toString(); break; case KLDAP::Ldif::Item: name = d->mLdif.attr().toLower(); value = d->mLdif.value(); if ( name == d->mAttributes[ QLatin1String( "commonName" ) ].toLower() ) { if ( !d->mAddr.formattedName().isEmpty() ) { QString fn = d->mAddr.formattedName(); d->mAddr.setNameFromString( QString::fromUtf8( value, value.size() ) ); d->mAddr.setFormattedName( fn ); } else { d->mAddr.setNameFromString( QString::fromUtf8( value, value.size() ) ); } } else if ( name == d->mAttributes[ QLatin1String( "formattedName" ) ].toLower() ) { d->mAddr.setFormattedName( QString::fromUtf8( value, value.size() ) ); } else if ( name == d->mAttributes[ QLatin1String( "givenName" ) ].toLower() ) { d->mAddr.setGivenName( QString::fromUtf8( value, value.size() ) ); } else if ( name == d->mAttributes[ QLatin1String( "mail" ) ].toLower() ) { d->mAddr.insertEmail( QString::fromUtf8( value, value.size() ), true ); } else if ( name == d->mAttributes[ QLatin1String( "mailAlias" ) ].toLower() ) { d->mAddr.insertEmail( QString::fromUtf8( value, value.size() ), false ); } else if ( name == d->mAttributes[ QLatin1String( "phoneNumber" ) ].toLower() ) { PhoneNumber phone; phone.setNumber( QString::fromUtf8( value, value.size() ) ); d->mAddr.insertPhoneNumber( phone ); } else if ( name == d->mAttributes[ QLatin1String( "telephoneNumber" ) ].toLower() ) { PhoneNumber phone( QString::fromUtf8( value, value.size() ), PhoneNumber::Work ); d->mAddr.insertPhoneNumber( phone ); - } else if ( name == d->mAttributes[ QLatin1String( "facsimileTelephoneNumber" ) ].toLower() ) { + } else if ( name == + d->mAttributes[ QLatin1String( "facsimileTelephoneNumber" ) ].toLower() ) { PhoneNumber phone( QString::fromUtf8( value, value.size() ), PhoneNumber::Fax ); d->mAddr.insertPhoneNumber( phone ); } else if ( name == d->mAttributes[ QLatin1String( "mobile" ) ].toLower() ) { PhoneNumber phone( QString::fromUtf8( value, value.size() ), PhoneNumber::Cell ); d->mAddr.insertPhoneNumber( phone ); } else if ( name == d->mAttributes[ QLatin1String( "pager" ) ].toLower() ) { PhoneNumber phone( QString::fromUtf8( value, value.size() ), PhoneNumber::Pager ); d->mAddr.insertPhoneNumber( phone ); } else if ( name == d->mAttributes[ QLatin1String( "description" ) ].toLower() ) { d->mAddr.setNote( QString::fromUtf8( value, value.size() ) ); } else if ( name == d->mAttributes[ QLatin1String( "title" ) ].toLower() ) { d->mAddr.setTitle( QString::fromUtf8( value, value.size() ) ); } else if ( name == d->mAttributes[ QLatin1String( "street" ) ].toLower() ) { d->mAd.setStreet( QString::fromUtf8( value, value.size() ) ); } else if ( name == d->mAttributes[ QLatin1String( "state" ) ].toLower() ) { d->mAd.setRegion( QString::fromUtf8( value, value.size() ) ); } else if ( name == d->mAttributes[ QLatin1String( "city" ) ].toLower() ) { d->mAd.setLocality( QString::fromUtf8( value, value.size() ) ); } else if ( name == d->mAttributes[ QLatin1String( "postalcode" ) ].toLower() ) { d->mAd.setPostalCode( QString::fromUtf8( value, value.size() ) ); } else if ( name == d->mAttributes[ QLatin1String( "organization" ) ].toLower() ) { d->mAddr.setOrganization( QString::fromUtf8( value, value.size() ) ); } else if ( name == d->mAttributes[ QLatin1String( "familyName" ) ].toLower() ) { d->mAddr.setFamilyName( QString::fromUtf8( value, value.size() ) ); } else if ( name == d->mAttributes[ QLatin1String( "uid" ) ].toLower() ) { d->mAddr.setUid( QString::fromUtf8( value, value.size() ) ); } else if ( name == d->mAttributes[ QLatin1String( "jpegPhoto" ) ].toLower() ) { KABC::Picture photo; QImage img = QImage::fromData( value ); if ( !img.isNull() ) { photo.setData( img ); photo.setType( QLatin1String( "image/jpeg" ) ); d->mAddr.setPhoto( photo ); } } break; case KLDAP::Ldif::EndEntry: { d->mAddr.setResource( this ); d->mAddr.insertAddress( d->mAd ); d->mAddr.setChanged( false ); insertAddressee( d->mAddr ); //clear the addressee d->mAddr = Addressee(); d->mAd = Address( Address::Home ); } break; default: break; } } while ( ret != KLDAP::Ldif::MoreData ); } void ResourceLDAPKIO::loadCacheResult( KJob *job ) { d->mErrorMsg.clear(); d->mError = job->error(); if ( d->mError && d->mError != KIO::ERR_USER_CANCELED ) { d->mErrorMsg = job->errorString(); } if ( !d->mErrorMsg.isEmpty() ) { emit loadingError( this, d->mErrorMsg ); } else { emit loadingFinished( this ); } } void ResourceLDAPKIO::result( KJob *job ) { d->mErrorMsg.clear(); if ( job ) { d->mError = job->error(); if ( d->mError && d->mError != KIO::ERR_USER_CANCELED ) { d->mErrorMsg = job->errorString(); } } else { d->mError = 0; } d->activateCache(); KIO::Job *cjob; cjob = d->loadFromCache(); if ( cjob ) { connect( cjob, SIGNAL( result( KJob* ) ), this, SLOT( loadCacheResult( KJob* ) ) ); } else { if ( !d->mErrorMsg.isEmpty() ) { emit loadingError( this, d->mErrorMsg ); } else { emit loadingFinished( this ); } } } bool ResourceLDAPKIO::save( Ticket *ticket ) { Q_UNUSED( ticket ); kDebug(); d->mSaveIt = begin(); KIO::Job *job = KIO::put( d->mLDAPUrl, -1, KIO::Overwrite | KIO::HideProgressInfo ); connect( job, SIGNAL( dataReq( KIO::Job*, QByteArray& ) ), this, SLOT( saveData( KIO::Job*, QByteArray& ) ) ); connect( job, SIGNAL( result( KJob* ) ), this, SLOT( syncLoadSaveResult( KJob* ) ) ); d->enter_loop(); if ( d->mErrorMsg.isEmpty() ) { kDebug() << "ResourceLDAPKIO save ok!"; return true; } else { kDebug() << "ResourceLDAPKIO finished with error:" << d->mErrorMsg; addressBook()->error( d->mErrorMsg ); return false; } } bool ResourceLDAPKIO::asyncSave( Ticket *ticket ) { Q_UNUSED( ticket ); kDebug(); d->mSaveIt = begin(); KIO::Job *job = KIO::put( d->mLDAPUrl, -1, KIO::Overwrite | KIO::HideProgressInfo ); connect( job, SIGNAL( dataReq( KIO::Job*, QByteArray& ) ), this, SLOT( saveData( KIO::Job*, QByteArray& ) ) ); connect( job, SIGNAL( result( KJob* ) ), this, SLOT( saveResult( KJob* ) ) ); return true; } void ResourceLDAPKIO::syncLoadSaveResult( KJob *job ) { d->mError = job->error(); if ( d->mError && d->mError != KIO::ERR_USER_CANCELED ) { d->mErrorMsg = job->errorString(); } else { d->mErrorMsg.clear(); } d->activateCache(); emit leaveModality(); } void ResourceLDAPKIO::saveResult( KJob *job ) { d->mError = job->error(); if ( d->mError && d->mError != KIO::ERR_USER_CANCELED ) { emit savingError( this, job->errorString() ); } else { emit savingFinished( this ); } } void ResourceLDAPKIO::saveData( KIO::Job *job, QByteArray &data ) { Q_UNUSED( job ); while ( d->mSaveIt != end() && !(*d->mSaveIt).changed() ) { d->mSaveIt++; } if ( d->mSaveIt == end() ) { kDebug() << "ResourceLDAPKIO endData"; data.resize( 0 ); return; } kDebug() << "ResourceLDAPKIO saveData:" << (*d->mSaveIt).assembledName(); d->AddresseeToLDIF( data, *d->mSaveIt, d->findUid( (*d->mSaveIt).uid() ) ); // kDebug() << "ResourceLDAPKIO save LDIF:" << QString::fromUtf8(data); // mark as unchanged (*d->mSaveIt).setChanged( false ); d->mSaveIt++; } void ResourceLDAPKIO::removeAddressee( const Addressee &addr ) { QString dn = d->findUid( addr.uid() ); kDebug() << dn; if ( !d->mErrorMsg.isEmpty() ) { addressBook()->error( d->mErrorMsg ); return; } if ( !dn.isEmpty() ) { kDebug() << "ResourceLDAPKIO: found uid:" << dn; KLDAP::LdapUrl url( d->mLDAPUrl ); url.setPath( QLatin1Char( '/' ) + dn ); url.setExtension( QLatin1String( "x-dir" ), QLatin1String( "base" ) ); url.setScope( KLDAP::LdapUrl::Base ); if ( KIO::NetAccess::del( url, 0 ) ) { mAddrMap.remove( addr.uid() ); } } else { //maybe it's not saved yet mAddrMap.remove( addr.uid() ); } } void ResourceLDAPKIO::setUser( const QString &user ) { d->mUser = user; } QString ResourceLDAPKIO::user() const { return d->mUser; } void ResourceLDAPKIO::setPassword( const QString &password ) { d->mPassword = password; } QString ResourceLDAPKIO::password() const { return d->mPassword; } void ResourceLDAPKIO::setDn( const QString &dn ) { d->mDn = dn; } QString ResourceLDAPKIO::dn() const { return d->mDn; } void ResourceLDAPKIO::setHost( const QString &host ) { d->mHost = host; } QString ResourceLDAPKIO::host() const { return d->mHost; } void ResourceLDAPKIO::setPort( int port ) { d->mPort = port; } int ResourceLDAPKIO::port() const { return d->mPort; } void ResourceLDAPKIO::setVer( int ver ) { d->mVer = ver; } int ResourceLDAPKIO::ver() const { return d->mVer; } void ResourceLDAPKIO::setSizeLimit( int sizelimit ) { d->mSizeLimit = sizelimit; } int ResourceLDAPKIO::sizeLimit() { return d->mSizeLimit; } void ResourceLDAPKIO::setTimeLimit( int timelimit ) { d->mTimeLimit = timelimit; } int ResourceLDAPKIO::timeLimit() { return d->mTimeLimit; } void ResourceLDAPKIO::setFilter( const QString &filter ) { d->mFilter = filter; } QString ResourceLDAPKIO::filter() const { return d->mFilter; } void ResourceLDAPKIO::setIsAnonymous( bool value ) { d->mAnonymous = value; } bool ResourceLDAPKIO::isAnonymous() const { return d->mAnonymous; } void ResourceLDAPKIO::setIsTLS( bool value ) { d->mTLS = value; } bool ResourceLDAPKIO::isTLS() const { return d->mTLS; } void ResourceLDAPKIO::setIsSSL( bool value ) { d->mSSL = value; } bool ResourceLDAPKIO::isSSL() const { return d->mSSL; } void ResourceLDAPKIO::setIsSubTree( bool value ) { d->mSubTree = value; } bool ResourceLDAPKIO::isSubTree() const { return d->mSubTree; } void ResourceLDAPKIO::setAttributes( const QMap &attributes ) { d->mAttributes = attributes; } QMap ResourceLDAPKIO::attributes() const { return d->mAttributes; } void ResourceLDAPKIO::setRDNPrefix( int value ) { d->mRDNPrefix = value; } int ResourceLDAPKIO::RDNPrefix() const { return d->mRDNPrefix; } void ResourceLDAPKIO::setIsSASL( bool value ) { d->mSASL = value; } bool ResourceLDAPKIO::isSASL() const { return d->mSASL; } void ResourceLDAPKIO::setMech( const QString &mech ) { d->mMech = mech; } QString ResourceLDAPKIO::mech() const { return d->mMech; } void ResourceLDAPKIO::setRealm( const QString &realm ) { d->mRealm = realm; } QString ResourceLDAPKIO::realm() const { return d->mRealm; } void ResourceLDAPKIO::setBindDN( const QString &binddn ) { d->mBindDN = binddn; } QString ResourceLDAPKIO::bindDN() const { return d->mBindDN; } void ResourceLDAPKIO::setCachePolicy( int pol ) { d->mCachePolicy = pol; } int ResourceLDAPKIO::cachePolicy() const { return d->mCachePolicy; } void ResourceLDAPKIO::setAutoCache( bool value ) { d->mAutoCache = value; } bool ResourceLDAPKIO::autoCache() { return d->mAutoCache; } QString ResourceLDAPKIO::cacheDst() const { return d->mCacheDst; } #include "resourceldapkio.moc" diff --git a/kabc/plugins/ldapkio/resourceldapkioconfig.cpp b/kabc/plugins/ldapkio/resourceldapkioconfig.cpp index 7b1d7b0cc..f96e5ecb8 100644 --- a/kabc/plugins/ldapkio/resourceldapkioconfig.cpp +++ b/kabc/plugins/ldapkio/resourceldapkioconfig.cpp @@ -1,464 +1,465 @@ /* This file is part of libkabc. Copyright (c) 2002 - 2003 Tobias Koenig 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 "resourceldapkioconfig.h" #include "resourceldapkio.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "resourceldapkioconfig.moc" using namespace KABC; ResourceLDAPKIOConfig::ResourceLDAPKIOConfig( QWidget *parent ) : KRES::ConfigWidget( parent ) { QBoxLayout *mainLayout = new QVBoxLayout( this ); mainLayout->setMargin( 0 ); mainLayout->setSpacing( KDialog::spacingHint() ); KPageWidget *pageWidget = new KPageWidget( this ); pageWidget->setFaceType( KPageView::Tabbed ); mCfg = new KLDAP::LdapConfigWidget( KLDAP::LdapConfigWidget::W_USER | KLDAP::LdapConfigWidget::W_PASS | KLDAP::LdapConfigWidget::W_BINDDN | KLDAP::LdapConfigWidget::W_REALM | KLDAP::LdapConfigWidget::W_HOST | KLDAP::LdapConfigWidget::W_PORT | KLDAP::LdapConfigWidget::W_VER | KLDAP::LdapConfigWidget::W_DN | KLDAP::LdapConfigWidget::W_FILTER | KLDAP::LdapConfigWidget::W_TIMELIMIT | KLDAP::LdapConfigWidget::W_SIZELIMIT, this ); mSecurityCfg = new KLDAP::LdapConfigWidget( KLDAP::LdapConfigWidget::W_SECBOX | KLDAP::LdapConfigWidget::W_AUTHBOX, this ); pageWidget->addPage( mCfg, i18nc( "@title:tab general account settings", "General" ) ); pageWidget->addPage( mSecurityCfg, i18nc( "@title:tab account security settings", "Security" ) ); mSubTree = new QCheckBox( i18n( "Sub-tree query" ), this ); KHBox *box = new KHBox( this ); box->setSpacing( KDialog::spacingHint() ); mEditButton = new QPushButton( i18n( "Edit Attributes..." ), box ); mCacheButton = new QPushButton( i18n( "Offline Use..." ), box ); mainLayout->addWidget( pageWidget ); mainLayout->addWidget( mSubTree ); mainLayout->addWidget( box ); connect( mEditButton, SIGNAL( clicked() ), SLOT( editAttributes() ) ); connect( mCacheButton, SIGNAL( clicked() ), SLOT( editCache() ) ); } void ResourceLDAPKIOConfig::loadSettings( KRES::Resource *res ) { ResourceLDAPKIO *resource = dynamic_cast( res ); if ( !resource ) { kDebug() << "cast failed"; return; } mCfg->setUser( resource->user() ); mCfg->setPassword( resource->password() ); mCfg->setRealm( resource->realm() ); mCfg->setBindDn( resource->bindDN() ); mCfg->setHost( resource->host() ); mCfg->setPort( resource->port() ); mCfg->setVersion( resource->ver() ); mCfg->setTimeLimit( resource->timeLimit() ); mCfg->setSizeLimit( resource->sizeLimit() ); mCfg->setDn( KLDAP::LdapDN( resource->dn() ) ); mCfg->setFilter( resource->filter() ); mSecurityCfg->setMech( resource->mech() ); if ( resource->isTLS() ) { mSecurityCfg->setSecurity( KLDAP::LdapConfigWidget::TLS ); } else if ( resource->isSSL() ) { mSecurityCfg->setSecurity( KLDAP::LdapConfigWidget::SSL ); } else { mSecurityCfg->setSecurity( KLDAP::LdapConfigWidget::None ); } if ( resource->isAnonymous() ) { mSecurityCfg->setAuth( KLDAP::LdapConfigWidget::Anonymous ); } else if ( resource->isSASL() ) { mSecurityCfg->setAuth( KLDAP::LdapConfigWidget::SASL ); } else { mSecurityCfg->setAuth( KLDAP::LdapConfigWidget::Simple ); } mSubTree->setChecked( resource->isSubTree() ); mAttributes = resource->attributes(); mRDNPrefix = resource->RDNPrefix(); mCachePolicy = resource->cachePolicy(); mCacheDst = resource->cacheDst(); mAutoCache = resource->autoCache(); } void ResourceLDAPKIOConfig::saveSettings( KRES::Resource *res ) { ResourceLDAPKIO *resource = dynamic_cast( res ); if ( !resource ) { kDebug() << "cast failed"; return; } resource->setUser( mCfg->user() ); resource->setPassword( mCfg->password() ); resource->setRealm( mCfg->realm() ); resource->setBindDN( mCfg->bindDn() ); resource->setHost( mCfg->host() ); resource->setPort( mCfg->port() ); resource->setVer( mCfg->version() ); resource->setTimeLimit( mCfg->timeLimit() ); resource->setSizeLimit( mCfg->sizeLimit() ); resource->setDn( mCfg->dn().toString() ); resource->setFilter( mCfg->filter() ); resource->setIsAnonymous( mSecurityCfg->auth() == KLDAP::LdapConfigWidget::Anonymous ); resource->setIsSASL( mSecurityCfg->auth() == KLDAP::LdapConfigWidget::SASL ); resource->setMech( mSecurityCfg->mech() ); resource->setIsTLS( mSecurityCfg->security() == KLDAP::LdapConfigWidget::TLS ); resource->setIsSSL( mSecurityCfg->security() == KLDAP::LdapConfigWidget::SSL ); resource->setIsSubTree( mSubTree->isChecked() ); resource->setAttributes( mAttributes ); resource->setRDNPrefix( mRDNPrefix ); resource->setCachePolicy( mCachePolicy ); resource->init(); } void ResourceLDAPKIOConfig::editAttributes() { AttributesDialog dlg( mAttributes, mRDNPrefix, this ); if ( dlg.exec() ) { mAttributes = dlg.attributes(); mRDNPrefix = dlg.rdnprefix(); } } void ResourceLDAPKIOConfig::editCache() { KLDAP::LdapUrl src; QStringList attr; src = mCfg->url(); src.setScope( mSubTree->isChecked() ? KLDAP::LdapUrl::Sub : KLDAP::LdapUrl::One ); if ( !mAttributes.empty() ) { QMap::Iterator it; QStringList attr; for ( it = mAttributes.begin(); it != mAttributes.end(); ++it ) { if ( !it.value().isEmpty() && it.key() != QLatin1String( "objectClass" ) ) { attr.append( it.value() ); } } src.setAttributes( attr ); } src.setExtension( QLatin1String( "x-dir" ), QLatin1String( "base" ) ); OfflineDialog dlg( mAutoCache, mCachePolicy, src, mCacheDst, this ); if ( dlg.exec() ) { mCachePolicy = dlg.cachePolicy(); mAutoCache = dlg.autoCache(); } } AttributesDialog::AttributesDialog( const QMap &attributes, int rdnprefix, QWidget *parent ) : KDialog( parent ) { setCaption( i18n( "Attributes Configuration" ) ); setButtons( Ok | Cancel ); setDefaultButton( Ok ); setModal( true ); showButtonSeparator( true ); mNameDict.insert( QLatin1String( "objectClass" ), i18n( "Object classes" ) ); mNameDict.insert( QLatin1String( "commonName" ), i18n( "Common name" ) ); mNameDict.insert( QLatin1String( "formattedName" ), i18n( "Formatted name" ) ); mNameDict.insert( QLatin1String( "familyName" ), i18n( "Family name" ) ); mNameDict.insert( QLatin1String( "givenName" ), i18n( "Given name" ) ); mNameDict.insert( QLatin1String( "organization" ), i18n( "Organization" ) ); mNameDict.insert( QLatin1String( "title" ), i18nc( "job title", "Title" ) ); mNameDict.insert( QLatin1String( "street" ), i18n( "Street" ) ); mNameDict.insert( QLatin1String( "state" ), i18nc( "state/province", "State" ) ); mNameDict.insert( QLatin1String( "city" ), i18n( "City" ) ); mNameDict.insert( QLatin1String( "postalcode" ), i18n( "Postal code" ) ); mNameDict.insert( QLatin1String( "mail" ), i18nc( "email address", "Email" ) ); mNameDict.insert( QLatin1String( "mailAlias" ), i18n( "Email alias" ) ); mNameDict.insert( QLatin1String( "phoneNumber" ), i18n( "Telephone number" ) ); mNameDict.insert( QLatin1String( "telephoneNumber" ), i18n( "Work telephone number" ) ); mNameDict.insert( QLatin1String( "facsimileTelephoneNumber" ), i18n( "Fax number" ) ); mNameDict.insert( QLatin1String( "mobile" ), i18n( "Cell phone number" ) ); mNameDict.insert( QLatin1String( "pager" ), i18n( "Pager" ) ); mNameDict.insert( QLatin1String( "description" ), i18n( "Note" ) ); mNameDict.insert( QLatin1String( "uid" ), i18n( "UID" ) ); mNameDict.insert( QLatin1String( "jpegPhoto" ), i18n( "Photo" ) ); // default map mDefaultMap.insert( QLatin1String( "objectClass" ), QLatin1String( "inetOrgPerson" ) ); mDefaultMap.insert( QLatin1String( "commonName" ), QLatin1String( "cn" ) ); mDefaultMap.insert( QLatin1String( "formattedName" ), QLatin1String( "displayName" ) ); mDefaultMap.insert( QLatin1String( "familyName" ), QLatin1String( "sn" ) ); mDefaultMap.insert( QLatin1String( "givenName" ), QLatin1String( "givenName" ) ); mDefaultMap.insert( QLatin1String( "title" ), QLatin1String( "title" ) ); mDefaultMap.insert( QLatin1String( "street" ), QLatin1String( "street" ) ); mDefaultMap.insert( QLatin1String( "state" ), QLatin1String( "st" ) ); mDefaultMap.insert( QLatin1String( "city" ), QLatin1String( "l" ) ); mDefaultMap.insert( QLatin1String( "organization" ), QLatin1String( "o" ) ); mDefaultMap.insert( QLatin1String( "postalcode" ), QLatin1String( "postalCode" ) ); mDefaultMap.insert( QLatin1String( "mail" ), QLatin1String( "mail" ) ); mDefaultMap.insert( QLatin1String( "mailAlias" ), QString() ); mDefaultMap.insert( QLatin1String( "phoneNumber" ), QLatin1String( "homePhone" ) ); mDefaultMap.insert( QLatin1String( "telephoneNumber" ), QLatin1String( "telephoneNumber" ) ); - mDefaultMap.insert( QLatin1String( "facsimileTelephoneNumber" ), QLatin1String( "facsimileTelephoneNumber" ) ); + mDefaultMap.insert( QLatin1String( "facsimileTelephoneNumber" ), + QLatin1String( "facsimileTelephoneNumber" ) ); mDefaultMap.insert( QLatin1String( "mobile" ), QLatin1String( "mobile" ) ); mDefaultMap.insert( QLatin1String( "pager" ), QLatin1String( "pager" ) ); mDefaultMap.insert( QLatin1String( "description" ), QLatin1String( "description" ) ); mDefaultMap.insert( QLatin1String( "uid" ), QLatin1String( "uid" ) ); mDefaultMap.insert( QLatin1String( "jpegPhoto" ), QLatin1String( "jpegPhoto" ) ); // overwrite the default values here QMap kolabMap, netscapeMap, evolutionMap, outlookMap; // kolab kolabMap.insert( QLatin1String( "formattedName" ), QLatin1String( "display-name" ) ); kolabMap.insert( QLatin1String( "mailAlias" ), QLatin1String( "mailalias" ) ); // evolution evolutionMap.insert( QLatin1String( "formattedName" ), QLatin1String( "fileAs" ) ); mMapList.append( attributes ); mMapList.append( kolabMap ); mMapList.append( netscapeMap ); mMapList.append( evolutionMap ); mMapList.append( outlookMap ); QFrame *page = new QFrame( this ); setMainWidget( page ); QGridLayout *layout = new QGridLayout( page ); QLabel *label = new QLabel( i18n( "Template:" ), page ); layout->addWidget( label, 0, 0 ); mMapCombo = new KComboBox( page ); layout->addWidget( mMapCombo, 0, 1 ); mMapCombo->addItem( i18n( "User Defined" ) ); mMapCombo->addItem( i18n( "Kolab" ) ); mMapCombo->addItem( i18n( "Netscape" ) ); mMapCombo->addItem( i18n( "Evolution" ) ); mMapCombo->addItem( i18n( "Outlook" ) ); connect( mMapCombo, SIGNAL( activated( int ) ), SLOT( mapChanged( int ) ) ); label = new QLabel( i18n( "RDN prefix attribute:" ), page ); layout->addWidget( label, 1, 0 ); mRDNCombo = new KComboBox( page ); layout->addWidget( mRDNCombo, 1, 1 ); mRDNCombo->addItem( i18n( "commonName" ) ); mRDNCombo->addItem( i18n( "UID" ) ); mRDNCombo->setCurrentIndex( rdnprefix ); QMap::ConstIterator it; int i, j = 0; for ( i = 2, it = attributes.begin(); it != attributes.end(); ++it, ++i ) { if ( mNameDict[ it.key() ].isEmpty() ) { i--; continue; } if ( ( i - 2 ) == ( mNameDict.count() >> 1 ) ) { i = 0; j = 2; } kDebug() << "itkey:" << it.key() << "i:" << i; label = new QLabel( mNameDict[ it.key() ] + QLatin1Char( ':' ), page ); KLineEdit *lineedit = new KLineEdit( page ); mLineEditDict.insert( it.key(), lineedit ); lineedit->setText( it.value() ); label->setBuddy( lineedit ); layout->addWidget( label, i, j ); layout->addWidget( lineedit, i, j+1 ); } for ( i = 1; i < mMapCombo->count(); ++i ) { QHash::const_iterator it2 = mLineEditDict.constBegin(); while ( it2 != mLineEditDict.constEnd() ) { if ( mMapList[ i ].contains( it2.key() ) ) { if ( mMapList[ i ][ it2.key() ] != it2.value()->text() ) { break; } } else { if ( mDefaultMap[ it2.key() ] != it2.value()->text() ) { break; } } ++it2; } if ( it2 != mLineEditDict.constEnd() ) { mMapCombo->setCurrentIndex( i ); break; } } KAcceleratorManager::manage( this ); } AttributesDialog::~AttributesDialog() { mNameDict.clear(); } QMap AttributesDialog::attributes() const { QMap map; QHash::const_iterator it = mLineEditDict.constBegin(); while ( it != mLineEditDict.constEnd() ) { map.insert( it.key(), it.value()->text() ); ++it; } return map; } int AttributesDialog::rdnprefix() const { return mRDNCombo->currentIndex(); } void AttributesDialog::mapChanged( int pos ) { // apply first the default and than the spezific changes QMap::Iterator it; for ( it = mDefaultMap.begin(); it != mDefaultMap.end(); ++it ) { mLineEditDict[ it.key() ]->setText( it.value() ); } for ( it = mMapList[ pos ].begin(); it != mMapList[ pos ].end(); ++it ) { if ( !it.value().isEmpty() ) { KLineEdit *le = mLineEditDict[ it.key() ]; if ( le ) { le->setText( it.value() ); } } } } OfflineDialog::OfflineDialog( bool autoCache, int cachePolicy, const KUrl &src, const QString &dst, QWidget *parent ) : KDialog( parent ) { setCaption( i18n( "Offline Configuration" ) ); setButtons( Ok | Cancel ); setDefaultButton( Ok ); setModal( true ); showButtonSeparator( true ); QFrame *page = new QFrame( this ); setMainWidget( page ); QVBoxLayout *layout = new QVBoxLayout( page ); mSrc = src; mDst = dst; mCacheBox = new QGroupBox( i18n( "Offline Cache Policy" ), page ); QVBoxLayout *cacheBoxLayout = new QVBoxLayout( mCacheBox ); mCacheGroup = new QButtonGroup( this ); QRadioButton *bt; bt = new QRadioButton( i18n( "Do not use offline cache" ), mCacheBox ); cacheBoxLayout->addWidget( bt ); bt->setDown(true); mCacheGroup->addButton( bt ); bt = new QRadioButton( i18n( "Use local copy if no connection" ), mCacheBox ); cacheBoxLayout->addWidget( bt ); mCacheGroup->addButton( bt ); bt = new QRadioButton( i18n( "Always use local copy" ), mCacheBox ); cacheBoxLayout->addWidget( bt ); mCacheGroup->addButton( bt ); if ( mCacheGroup->button( cachePolicy ) ) { mCacheGroup->button( cachePolicy )->setDown( true ); } mAutoCache = new QCheckBox( i18n( "Refresh offline cache automatically" ), page ); mAutoCache->setChecked( autoCache ); mAutoCache->setEnabled( bt->isChecked() ); connect( bt, SIGNAL(toggled(bool)), mAutoCache, SLOT(setEnabled(bool)) ); QPushButton *lcache = new QPushButton( i18n( "Load into Cache" ), page ); connect( lcache, SIGNAL( clicked() ), SLOT( loadCache() ) ); layout->addWidget( mCacheBox ); layout->addWidget( mAutoCache ); layout->addWidget( lcache ); } OfflineDialog::~OfflineDialog() { } bool OfflineDialog::autoCache() const { return mAutoCache->isChecked(); } int OfflineDialog::cachePolicy() const { return mCacheGroup->checkedId(); } void OfflineDialog::loadCache() { if ( KIO::NetAccess::download( mSrc, mDst, this ) ) { KMessageBox::information( this, i18n( "Successfully downloaded directory server contents." ) ); } else { KMessageBox::error( this, i18n( "An error occurred downloading directory server contents into file %1.", mDst ) ); } } diff --git a/kabc/sound.cpp b/kabc/sound.cpp index 872301941..fa65a06bc 100644 --- a/kabc/sound.cpp +++ b/kabc/sound.cpp @@ -1,170 +1,171 @@ /* This file is part of libkabc. Copyright (c) 2002 Tobias Koenig 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 "sound.h" #include #include using namespace KABC; class Sound::Private : public QSharedData { public: Private() : mIntern( false ) { } Private( const Private &other ) : QSharedData( other ) { mUrl = other.mUrl; mData = other.mData; mIntern = other.mIntern; } QString mUrl; QByteArray mData; bool mIntern; }; Sound::Sound() : d( new Private ) { } Sound::Sound( const QString &url ) : d( new Private ) { d->mUrl = url; } Sound::Sound( const QByteArray &data ) : d( new Private ) { d->mIntern = true; d->mData = data; } Sound::Sound( const Sound &other ) : d( other.d ) { } Sound::~Sound() { } Sound &Sound::operator=( const Sound &other ) { if ( this != &other ) { d = other.d; } return *this; } bool Sound::operator==( const Sound &other ) const { if ( d->mIntern != other.d->mIntern ) { return false; } if ( d->mIntern ) { if ( d->mData != other.d->mData ) { return false; } } else { if ( d->mUrl != other.d->mUrl ) { return false; } } return true; } bool Sound::operator!=( const Sound &other ) const { return !( other == *this ); } void Sound::setUrl( const QString &url ) { d->mIntern = false; d->mUrl = url; } void Sound::setData( const QByteArray &data ) { d->mIntern = true; d->mData = data; } bool Sound::isIntern() const { return d->mIntern; } bool Sound::isEmpty() const { return - ((d->mIntern && d->mData.isEmpty()) || - (!d->mIntern && d->mUrl.isEmpty())); + ( ( d->mIntern && d->mData.isEmpty() ) || ( !d->mIntern && d->mUrl.isEmpty() ) ); } QString Sound::url() const { return d->mUrl; } QByteArray Sound::data() const { return d->mData; } QString Sound::toString() const { QString str; str += QLatin1String( "Sound {\n" ); - str += QString::fromLatin1( " IsIntern: %1\n" ).arg( d->mIntern ? QLatin1String( "true" ) : QLatin1String( "false" ) ); + str += QString::fromLatin1( " IsIntern: %1\n" ). + arg( d->mIntern ? QLatin1String( "true" ) : QLatin1String( "false" ) ); if ( d->mIntern ) { - str += QString::fromLatin1( " Data: %1\n" ).arg( QString::fromLatin1( d->mData.toBase64() ) ); + str += QString::fromLatin1( " Data: %1\n" ). + arg( QString::fromLatin1( d->mData.toBase64() ) ); } else { str += QString::fromLatin1( " Url: %1\n" ).arg( d->mUrl ); } str += QLatin1String( "}\n" ); return str; } QDataStream &KABC::operator<<( QDataStream &s, const Sound &sound ) { return s << sound.d->mIntern << sound.d->mUrl << sound.d->mData; } QDataStream &KABC::operator>>( QDataStream &s, Sound &sound ) { s >> sound.d->mIntern >> sound.d->mUrl >> sound.d->mData; return s; } diff --git a/kabc/stdaddressbook.cpp b/kabc/stdaddressbook.cpp index 39b54d6e4..c28c4e6a4 100644 --- a/kabc/stdaddressbook.cpp +++ b/kabc/stdaddressbook.cpp @@ -1,254 +1,255 @@ /* This file is part of libkabc. Copyright (c) 2001 Cornelius Schumacher 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 "stdaddressbook.h" #include "resource.h" #include "kresources/manager.h" #include #include #include #include #include #include #include using namespace KABC; class StdAddressBook::Private { public: Private( StdAddressBook *parent ) : mParent( parent ) { } void init( bool asynchronous ); bool saveAll(); StdAddressBook *mParent; static bool mAutomaticSave; }; static StdAddressBook *s_gStdAddressBook = 0; bool StdAddressBook::Private::mAutomaticSave = true; static void deleteGlobalStdAddressBook() { if ( s_gStdAddressBook ) { delete s_gStdAddressBook; s_gStdAddressBook = 0; } } QString StdAddressBook::fileName() { return KStandardDirs::locateLocal( "data", QLatin1String( "kabc/std.vcf" ) ); } QString StdAddressBook::directoryName() { return KStandardDirs::locateLocal( "data", QLatin1String( "kabc/stdvcf" ) ); } StdAddressBook *StdAddressBook::self() { kDebug(); // delegate to other self() method since the only difference // was the constructor being used and their only difference is // what they pass to Private::init() return self( false ); } StdAddressBook *StdAddressBook::self( bool asynchronous ) { kDebug() << "asynchronous=" << asynchronous; if ( !s_gStdAddressBook ) { s_gStdAddressBook = new StdAddressBook( asynchronous, false ); kDebug() << "calling init after instance creation"; s_gStdAddressBook->d->init( asynchronous ); // We don't use a global static here for this reason: // // There are problems with the destruction order: The destructor of // StdAddressBook calls save(), which for LDAP address books, needs KIO // (more specific: KProtocolInfo) to be still alive. However, with a global // static, KProtocolInfo is already deleted, and the app will crash. // // qAddPostRoutine deletes the objects when the QApplication is destroyed, // which is earlier than the global statics, so this will work. qAddPostRoutine( deleteGlobalStdAddressBook ); } return s_gStdAddressBook; } StdAddressBook::StdAddressBook() : AddressBook( QString() ), d( new Private( this ) ) { kDebug(); d->init( false ); } StdAddressBook::StdAddressBook( bool asynchronous ) : AddressBook( QString() ), d( new Private( this ) ) { kDebug(); d->init( asynchronous ); } StdAddressBook::StdAddressBook( bool asynchronous, bool doInit ) : AddressBook( QString() ), d( new Private( this ) ) { kDebug(); if ( doInit ) { d->init( asynchronous ); } } StdAddressBook::~StdAddressBook() { if ( Private::mAutomaticSave ) { d->saveAll(); } delete d; } void StdAddressBook::Private::init( bool asynchronous ) { KRES::Manager *manager = mParent->resourceManager(); KRES::Manager::ActiveIterator it; for ( it = manager->activeBegin(); it != manager->activeEnd(); ++it ) { (*it)->setAddressBook( mParent ); if ( !(*it)->open() ) { - mParent->error( QString::fromLatin1( "Unable to open resource '%1'!" ).arg( (*it)->resourceName() ) ); + mParent->error( QString::fromLatin1( "Unable to open resource '%1'!" ). + arg( (*it)->resourceName() ) ); continue; } mParent->connect( *it, SIGNAL( loadingFinished( Resource* ) ), mParent, SLOT( resourceLoadingFinished( Resource* ) ) ); mParent->connect( *it, SIGNAL( savingFinished( Resource* ) ), mParent, SLOT( resourceSavingFinished( Resource* ) ) ); mParent->connect( *it, SIGNAL( loadingError( Resource*, const QString& ) ), mParent, SLOT( resourceLoadingError( Resource*, const QString& ) ) ); mParent->connect( *it, SIGNAL( savingError( Resource*, const QString& ) ), mParent, SLOT( resourceSavingError( Resource*, const QString& ) ) ); } Resource *res = mParent->standardResource(); if ( !res ) { res = manager->createResource( QLatin1String( "file" ) ); if ( res ) { res->setResourceName( i18n( "Default Addressbook" ) ); mParent->addResource( res ); } else { kDebug() << "No resource available!!!"; } } mParent->setStandardResource( res ); manager->writeConfig(); if ( asynchronous ) { mParent->asyncLoad(); } else { mParent->load(); } } bool StdAddressBook::Private::saveAll() { kDebug(); bool ok = true; KRES::Manager::ActiveIterator it; KRES::Manager *manager = mParent->resourceManager(); for ( it = manager->activeBegin(); it != manager->activeEnd(); ++it ) { if ( !(*it)->readOnly() && (*it)->isOpen() ) { Ticket *ticket = mParent->requestSaveTicket( *it ); if ( !ticket ) { mParent->error( i18n( "Unable to save to resource '%1'. It is locked.", (*it)->resourceName() ) ); return false; } if ( !mParent->AddressBook::save( ticket ) ) { ok = false; mParent->releaseSaveTicket( ticket ); } } } return ok; } bool StdAddressBook::save() { kDebug(); if ( s_gStdAddressBook ) { return s_gStdAddressBook->d->saveAll(); } else { return true; } } void StdAddressBook::close() { delete s_gStdAddressBook; s_gStdAddressBook = 0; } void StdAddressBook::setAutomaticSave( bool enable ) { Private::mAutomaticSave = enable; } bool StdAddressBook::automaticSave() { return Private::mAutomaticSave; } Addressee StdAddressBook::whoAmI() const { KConfig _config( QLatin1String( "kabcrc" ) ); KConfigGroup config(&_config, "General" ); return findByUid( config.readEntry( "WhoAmI" ) ); } void StdAddressBook::setWhoAmI( const Addressee &addr ) { KConfig _config( QLatin1String( "kabcrc" ) ); KConfigGroup config(&_config, "General" ); config.writeEntry( "WhoAmI", addr.uid() ); } diff --git a/kabc/vcardparser/testutils.cpp b/kabc/vcardparser/testutils.cpp index 52cae0c78..c95086155 100644 --- a/kabc/vcardparser/testutils.cpp +++ b/kabc/vcardparser/testutils.cpp @@ -1,115 +1,115 @@ /* This file is part of libkabc. Copyright (c) 2007 KDE-PIM team 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 #include #include "vcardparser.h" using namespace KABC; Addressee vcard1() { Addressee addr; addr.setName( QLatin1String( "Frank Dawson" ) ); addr.setOrganization( QLatin1String( "Lotus Development Corporation" ) ); - addr.setUrl( KUrl( QLatin1String( "http://home.earthlink.net/~fdawson") ) ); + addr.setUrl( KUrl( QLatin1String( "http://home.earthlink.net/~fdawson" ) ) ); addr.insertEmail( QLatin1String( "fdawson@earthlink.net" ) ); addr.insertEmail( QLatin1String( "Frank_Dawson@Lotus.com" ), true ); addr.insertPhoneNumber( PhoneNumber( QLatin1String( "+1-919-676-9515" ), PhoneNumber::Voice|PhoneNumber::Msg|PhoneNumber::Work ) ); addr.insertPhoneNumber( PhoneNumber( QLatin1String( "+1-919-676-9564" ), PhoneNumber::Fax |PhoneNumber::Work ) ); Address a( Address::Work | Address::Postal | Address::Parcel ); a.setStreet( QLatin1String( "6544 Battleford Drive" ) ); a.setLocality( QLatin1String( "Raleigh" ) ); a.setRegion( QLatin1String( "NC" ) ); a.setPostalCode( QLatin1String( "27613-3502" ) ); a.setCountry( QLatin1String( "U.S.A." ) ); addr.insertAddress( a ); return addr; } Addressee vcard2() { Addressee addr; addr.setName( QLatin1String( "Tim Howes" ) ); addr.setOrganization( QLatin1String( "Netscape Communications Corp." ) ); addr.insertEmail( QLatin1String( "howes@netscape.com" ) ); addr.insertPhoneNumber( PhoneNumber( QLatin1String( "+1-415-937-3419" ), PhoneNumber::Voice|PhoneNumber::Msg|PhoneNumber::Work ) ); addr.insertPhoneNumber( PhoneNumber( QLatin1String( "+1-415-528-4164" ), PhoneNumber::Fax|PhoneNumber::Work ) ); Address a( Address::Work ); a.setStreet( QLatin1String( "501 E. Middlefield Rd." ) ); a.setLocality( QLatin1String( "Mountain View" ) ); a.setRegion( QLatin1String( "CA" ) ); a.setPostalCode( QLatin1String( "94043" ) ); a.setCountry( QLatin1String( "U.S.A." ) ); addr.insertAddress( a ); return addr; } Addressee vcard3() { Addressee addr; addr.setName( QLatin1String( "ian geiser" ) ); addr.setOrganization( QLatin1String( "Source eXtreme" ) ); addr.insertEmail( QLatin1String( "geiseri@yahoo.com" ) ); addr.setTitle( QLatin1String( "VP of Engineering" ) ); return addr; } QByteArray vcardAsText( const QString &location ) { QByteArray text; QFile file( location ); if ( file.open( QIODevice::ReadOnly ) ) { text = file.readAll(); file.close(); } return text; } Addressee::List vCardsAsAddresseeList() { Addressee::List l; l.append( vcard1() ); l.append( vcard2() ); l.append( vcard3() ); return l; } QByteArray vCardsAsText() { QByteArray vcards = vcardAsText( QLatin1String( "tests/vcard1.vcf" ) ); vcards += vcardAsText( QLatin1String( "tests/vcard2.vcf" ) ); vcards += vcardAsText( QLatin1String( "tests/vcard3.vcf" ) ); return vcards; } diff --git a/kabc/vcardparser/testwrite.cpp b/kabc/vcardparser/testwrite.cpp index ba679fdf3..f725bd284 100644 --- a/kabc/vcardparser/testwrite.cpp +++ b/kabc/vcardparser/testwrite.cpp @@ -1,114 +1,119 @@ /* This file is part of libkabc. Copyright (c) 2007 KDE-PIM team 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 #include #include #include #include "kabc/addressee.h" #include "kabc/phonenumber.h" #include "kabc/address.h" #include "kabc/key.h" #include "kabc/picture.h" #include "kabc/sound.h" #include "kabc/secrecy.h" #include "kabc/vcardconverter.h" int main( int argc, char **argv ) { KAboutData aboutData( "testwrite", 0, ki18n("vCard test writer"), "0.1" ); KCmdLineArgs::init( argc, argv, &aboutData ); KApplication app( false ); KABC::Addressee addressee; addressee.setNameFromString( QLatin1String( "Mr. Tobias Koenig Jr." ) ); addressee.setNickName( QLatin1String( "tokoe" ) ); addressee.setBirthday( QDateTime( QDate( 1982, 7, 19 ) ) ); addressee.setMailer( QLatin1String( "mutt1.2" ) ); addressee.setTimeZone( KABC::TimeZone( +2 ) ); KABC::Geo geo; geo.setLatitude( 30 ); geo.setLongitude( 51 ); addressee.setGeo( geo ); addressee.setTitle( QLatin1String( "nerd" ) ); addressee.setRole( QLatin1String( "Maintainer" ) ); addressee.setOrganization( QLatin1String( "KDE" ) ); addressee.setNote( QLatin1String( "nerver\ntouch a running system" ) ); addressee.setProductId( QLatin1String( "testId" ) ); addressee.setRevision( QDateTime::currentDateTime() ); addressee.setSortString( QLatin1String( "koenig" ) ); - addressee.setUrl( KUrl( QLatin1String( "http://wgess16.dyndns.org") ) ); + addressee.setUrl( KUrl( QLatin1String( "http://wgess16.dyndns.org" ) ) ); addressee.setSecrecy( KABC::Secrecy( KABC::Secrecy::Confidential ) ); addressee.insertEmail( QLatin1String( "tokoe@kde.org" ), true ); addressee.insertEmail( QLatin1String( "tokoe82@yahoo.de" ), true ); - KABC::PhoneNumber phone1( QLatin1String( "3541523475" ), KABC::PhoneNumber::Pref | KABC::PhoneNumber::Home ); - KABC::PhoneNumber phone2( QLatin1String( "+46745673475" ), KABC::PhoneNumber::Work ); + KABC::PhoneNumber phone1( QLatin1String( "3541523475" ), + KABC::PhoneNumber::Pref | KABC::PhoneNumber::Home ); + KABC::PhoneNumber phone2( QLatin1String( "+46745673475" ), + KABC::PhoneNumber::Work ); addressee.insertPhoneNumber( phone1 ); addressee.insertPhoneNumber( phone2 ); KABC::Key key( QLatin1String( "secret key" ), KABC::Key::X509 ); addressee.insertKey( key ); QStringList categories; categories << QLatin1String( "Friends" ) << QLatin1String( "School" ) << QLatin1String( "KDE" ); addressee.setCategories( categories ); KABC::Address a( KABC::Address::Work | KABC::Address::Postal | KABC::Address::Parcel ); a.setStreet( QLatin1String( "6544 Battleford Drive" ) ); a.setLocality( QLatin1String( "Raleigh" ) ); a.setRegion( QLatin1String( "NC" ) ); a.setPostalCode( QLatin1String( "27613-3502" ) ); a.setCountry( QLatin1String( "U.S.A." ) ); addressee.insertAddress( a ); - addressee.insertCustom( QLatin1String( "1hsdf" ), QLatin1String( "ertuer" ), QLatin1String( "iurt") ); - addressee.insertCustom( QLatin1String( "2hsdf" ), QLatin1String( "ertuer" ), QLatin1String( "iurt") ); - addressee.insertCustom( QLatin1String( "3hsdf" ), QLatin1String( "ertuer" ), QLatin1String( "iurt") ); + addressee.insertCustom( QLatin1String( "1hsdf" ), QLatin1String( "ertuer" ), + QLatin1String( "iurt" ) ); + addressee.insertCustom( QLatin1String( "2hsdf" ), QLatin1String( "ertuer" ), + QLatin1String( "iurt" ) ); + addressee.insertCustom( QLatin1String( "3hsdf" ), QLatin1String( "ertuer" ), + QLatin1String( "iurt" ) ); KABC::Addressee::List list; for ( int i = 0; i < 1000; ++i ) { KABC::Addressee addr = addressee; addr.setUid( QString::number( i ) ); list.append( addr ); } KABC::VCardConverter converter; QByteArray txt = converter.createVCards( list ); QFile file( QLatin1String( "out.vcf" ) ); if ( !file.open( QIODevice::WriteOnly ) ) { qDebug( "Can't open file '%s' fro writing", qPrintable( file.fileName() ) ); return 1; } file.write( txt ); file.close(); return 0; } diff --git a/kabc/vcardparser/vcardparser.cpp b/kabc/vcardparser/vcardparser.cpp index d52c2f200..8e16ea925 100644 --- a/kabc/vcardparser/vcardparser.cpp +++ b/kabc/vcardparser/vcardparser.cpp @@ -1,304 +1,312 @@ /* This file is part of libkabc. Copyright (c) 2003 Tobias Koenig 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 "vcardparser.h" #include #include #include #define FOLD_WIDTH 75 using namespace KABC; static void addEscapes( QByteArray &str ) { str.replace( '\\', (char *)"\\\\" ); str.replace( ',', (char *)"\\," ); str.replace( '\r', (char *)"\\r" ); str.replace( '\n', (char *)"\\n" ); } static void removeEscapes( QByteArray &str ) { str.replace( (char *)"\\n", "\n" ); str.replace( (char *)"\\r", "\r" ); str.replace( (char *)"\\,", "," ); str.replace( (char *)"\\\\", "\\" ); } VCardParser::VCardParser() { } VCardParser::~VCardParser() { } VCard::List VCardParser::parseVCards( const QByteArray &text ) { VCard currentVCard; VCard::List vCardList; QByteArray currentLine; QList lines = text.split( '\n' ); bool inVCard = false; QList::Iterator it( lines.begin() ); QList::Iterator linesEnd( lines.end() ); for ( ; it != linesEnd; ++it ) { // remove the trailing \r, left from \r\n if ( (*it).endsWith( '\r' ) ) { (*it).chop( 1 ); } if ( (*it).startsWith( ' ' ) || (*it).startsWith( '\t' ) ) { //folded line => append to previous currentLine.append( (*it).mid( 1 ) ); continue; } else { if ( (*it).trimmed().isEmpty() ) { // empty line continue; } if ( inVCard && !currentLine.isEmpty() ) { // now parse the line int colon = currentLine.indexOf( ':' ); if ( colon == -1 ) { // invalid line currentLine = (*it); continue; } VCardLine vCardLine; const QByteArray key = currentLine.left( colon ).trimmed(); QByteArray value = currentLine.mid( colon + 1 ); QList params = key.split( ';' ); // check for group int groupPos = params[ 0 ].indexOf( '.' ); if ( groupPos != -1 ) { vCardLine.setGroup( QString::fromLatin1( params[ 0 ].left( groupPos ) ) ); vCardLine.setIdentifier( QString::fromLatin1( params[ 0 ].mid( groupPos + 1 ) ) ); } else { vCardLine.setIdentifier( QString::fromLatin1( params[ 0 ] ) ); } if ( params.count() > 1 ) { // find all parameters QList::ConstIterator paramIt( params.constBegin() ); for ( ++paramIt; paramIt != params.constEnd(); ++paramIt ) { QList pair = (*paramIt).split( '=' ); if ( pair.count() == 1 ) { // correct the fucking 2.1 'standard' if ( pair[ 0 ].toLower() == "quoted-printable" ) { pair[ 0 ] = "encoding"; pair.append( "quoted-printable" ); } else if ( pair[ 0 ].toLower() == "base64" ) { pair[ 0 ] = "encoding"; pair.append( "base64" ); } else { pair.prepend( "type" ); } } if ( pair[ 1 ].indexOf( ',' ) != -1 ) { // parameter in type=x,y,z format const QList args = pair[ 1 ].split( ',' ); QList::ConstIterator argIt; for ( argIt = args.constBegin(); argIt != args.constEnd(); ++argIt ) { - vCardLine.addParameter( QString::fromLatin1( pair[ 0 ].toLower() ), QString::fromLatin1( *argIt ) ); + vCardLine.addParameter( QString::fromLatin1( pair[ 0 ].toLower() ), + QString::fromLatin1( *argIt ) ); } } else { - vCardLine.addParameter( QString::fromLatin1( pair[ 0 ].toLower() ), QString::fromLatin1( pair[ 1 ] ) ); + vCardLine.addParameter( QString::fromLatin1( pair[ 0 ].toLower() ), + QString::fromLatin1( pair[ 1 ] ) ); } } } removeEscapes( value ); QByteArray output; bool wasBase64Encoded = false; - if ( vCardLine.parameterList().contains( QLatin1String( "encoding" ) ) ) { // have to decode the data - if ( vCardLine.parameter( QLatin1String( "encoding" ) ).toLower() == QLatin1String( "b" ) || - vCardLine.parameter( QLatin1String( "encoding" ) ).toLower() == QLatin1String( "base64" ) ) { + if ( vCardLine.parameterList().contains( QLatin1String( "encoding" ) ) ) { + // have to decode the data + if ( vCardLine.parameter( QLatin1String( "encoding" ) ).toLower() == + QLatin1String( "b" ) || + vCardLine.parameter( QLatin1String( "encoding" ) ).toLower() == + QLatin1String( "base64" ) ) { output = QByteArray::fromBase64( value ); wasBase64Encoded = true; } - else if ( vCardLine.parameter( QLatin1String( "encoding" ) ).toLower() == QLatin1String( "quoted-printable" ) ) { + else if ( vCardLine.parameter( QLatin1String( "encoding" ) ).toLower() == + QLatin1String( "quoted-printable" ) ) { // join any qp-folded lines while ( value.endsWith( '=' ) && it != linesEnd ) { value.chop( 1 ); // remove the '=' value.append( *it ); ++it; } KCodecs::quotedPrintableDecode( value, output ); } else { qDebug( "Unknown vcard encoding type!" ); } } else { output = value; } - if ( vCardLine.parameterList().contains( QLatin1String( "charset" ) ) ) { // have to convert the data - QTextCodec *codec = - QTextCodec::codecForName( vCardLine.parameter( QLatin1String( "charset" ) ).toLatin1() ); + if ( vCardLine.parameterList().contains( QLatin1String( "charset" ) ) ) { + // have to convert the data + QTextCodec *codec = QTextCodec::codecForName( + vCardLine.parameter( QLatin1String( "charset" ) ).toLatin1() ); if ( codec ) { vCardLine.setValue( codec->toUnicode( output ) ); } else { vCardLine.setValue( QString::fromUtf8( output ) ); } } else if ( wasBase64Encoded ) { vCardLine.setValue( output ); } else { vCardLine.setValue( QString::fromUtf8( output ) ); } currentVCard.addLine( vCardLine ); } // we do not save the start and end tag as vcardline if ( (*it).toLower().startsWith( "begin:vcard" ) ) { inVCard = true; currentLine.clear(); currentVCard.clear(); // flush vcard continue; } if ( (*it).toLower().startsWith( "end:vcard" ) ) { inVCard = false; vCardList.append( currentVCard ); currentLine.clear(); currentVCard.clear(); // flush vcard continue; } currentLine = (*it); } } return vCardList; } QByteArray VCardParser::createVCards( const VCard::List &list ) { QByteArray text; QByteArray textLine; QString encodingType; QStringList idents; QStringList params; QStringList values; QStringList::ConstIterator identIt; QStringList::Iterator paramIt; QStringList::ConstIterator valueIt; VCardLine::List lines; VCardLine::List::ConstIterator lineIt; VCard::List::ConstIterator cardIt; bool hasEncoding; text.reserve( list.size() * 300 ); // reserve memory to be more efficient // iterate over the cards VCard::List::ConstIterator listEnd( list.end() ); for ( cardIt = list.begin(); cardIt != listEnd; ++cardIt ) { text.append( "BEGIN:VCARD\r\n" ); idents = (*cardIt).identifiers(); for ( identIt = idents.constBegin(); identIt != idents.constEnd(); ++identIt ) { lines = (*cardIt).lines( (*identIt) ); // iterate over the lines for ( lineIt = lines.constBegin(); lineIt != lines.constEnd(); ++lineIt ) { QVariant val = (*lineIt).value(); if ( val.isValid() ) { if ( (*lineIt).hasGroup() ) { textLine = (*lineIt).group().toLatin1() + '.' + (*lineIt).identifier().toLatin1(); } else { textLine = (*lineIt).identifier().toLatin1(); } params = (*lineIt).parameterList(); hasEncoding = false; if ( params.count() > 0 ) { // we have parameters for ( paramIt = params.begin(); paramIt != params.end(); ++paramIt ) { if ( (*paramIt) == QLatin1String( "encoding" ) ) { hasEncoding = true; encodingType = (*lineIt).parameter( QLatin1String( "encoding" ) ).toLower(); } values = (*lineIt).parameters( *paramIt ); for ( valueIt = values.constBegin(); valueIt != values.constEnd(); ++valueIt ) { textLine.append( ';' + (*paramIt).toLatin1().toUpper() ); if ( !(*valueIt).isEmpty() ) { textLine.append( '=' + (*valueIt).toLatin1() ); } } } } QByteArray input, output; // handle charset - if ( (*lineIt).parameterList().contains( QLatin1String( "charset" ) ) ) { // have to convert the data + if ( (*lineIt).parameterList().contains( QLatin1String( "charset" ) ) ) { + // have to convert the data const QString value = (*lineIt).value().toString(); - QTextCodec *codec = - QTextCodec::codecForName( (*lineIt).parameter( QLatin1String( "charset" ) ).toLatin1() ); + QTextCodec *codec = QTextCodec::codecForName( + (*lineIt).parameter( QLatin1String( "charset" ) ).toLatin1() ); if ( codec ) { input = codec->fromUnicode( value ); } else { input = value.toUtf8(); } } else if ( (*lineIt).value().type() == QVariant::ByteArray ) { input = (*lineIt).value().toByteArray(); } else { input = (*lineIt).value().toString().toUtf8(); } // handle encoding if ( hasEncoding ) { // have to encode the data if ( encodingType == QLatin1String( "b" ) ) { output = input.toBase64(); } else if ( encodingType == QLatin1String( "quoted-printable" ) ) { KCodecs::quotedPrintableEncode( input, output, false ); } } else { output = input; } addEscapes( output ); if ( !output.isEmpty() ) { textLine.append( ':' + output ); if ( textLine.length() > FOLD_WIDTH ) { // we have to fold the line for ( int i = 0; i <= ( textLine.length() / FOLD_WIDTH ); ++i ) { text.append( ( i == 0 ? "" : " " ) + textLine.mid( i * FOLD_WIDTH, FOLD_WIDTH ) + "\r\n" ); } } else { text.append( textLine + "\r\n" ); } } } } } text.append( "END:VCARD\r\n" ); text.append( "\r\n" ); } return text; } diff --git a/kabc/vcardtool.cpp b/kabc/vcardtool.cpp index 00fa9c276..7efde6572 100644 --- a/kabc/vcardtool.cpp +++ b/kabc/vcardtool.cpp @@ -1,923 +1,927 @@ /* This file is part of libkabc. Copyright (c) 2003 Tobias Koenig 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 "vcardtool.h" #include "key.h" #include "picture.h" #include "secrecy.h" #include "sound.h" #include #include using namespace KABC; static bool needsEncoding( const QString &value ) { uint length = value.length(); for ( uint i = 0; i < length; ++i ) { char c = value.at( i ).toLatin1(); if ( ( c < 33 || c > 126 ) && c != ' ' && c != '=' ) { return true; } } return false; } VCardTool::VCardTool() { mAddressTypeMap.insert( QLatin1String( "dom" ), Address::Dom ); mAddressTypeMap.insert( QLatin1String( "intl" ), Address::Intl ); mAddressTypeMap.insert( QLatin1String( "postal" ), Address::Postal ); mAddressTypeMap.insert( QLatin1String( "parcel" ), Address::Parcel ); mAddressTypeMap.insert( QLatin1String( "home" ), Address::Home ); mAddressTypeMap.insert( QLatin1String( "work" ), Address::Work ); mAddressTypeMap.insert( QLatin1String( "pref" ), Address::Pref ); mPhoneTypeMap.insert( QLatin1String( "HOME" ), PhoneNumber::Home ); mPhoneTypeMap.insert( QLatin1String( "WORK" ), PhoneNumber::Work ); mPhoneTypeMap.insert( QLatin1String( "MSG" ), PhoneNumber::Msg ); mPhoneTypeMap.insert( QLatin1String( "PREF" ), PhoneNumber::Pref ); mPhoneTypeMap.insert( QLatin1String( "VOICE" ), PhoneNumber::Voice ); mPhoneTypeMap.insert( QLatin1String( "FAX" ), PhoneNumber::Fax ); mPhoneTypeMap.insert( QLatin1String( "CELL" ), PhoneNumber::Cell ); mPhoneTypeMap.insert( QLatin1String( "VIDEO" ), PhoneNumber::Video ); mPhoneTypeMap.insert( QLatin1String( "BBS" ), PhoneNumber::Bbs ); mPhoneTypeMap.insert( QLatin1String( "MODEM" ), PhoneNumber::Modem ); mPhoneTypeMap.insert( QLatin1String( "CAR" ), PhoneNumber::Car ); mPhoneTypeMap.insert( QLatin1String( "ISDN" ), PhoneNumber::Isdn ); mPhoneTypeMap.insert( QLatin1String( "PCS" ), PhoneNumber::Pcs ); mPhoneTypeMap.insert( QLatin1String( "PAGER" ), PhoneNumber::Pager ); } VCardTool::~VCardTool() { } QByteArray VCardTool::createVCards( const Addressee::List &list, VCard::Version version ) const { VCard::List vCardList; Addressee::List::ConstIterator addrIt; Addressee::List::ConstIterator listEnd( list.constEnd() ); for ( addrIt = list.constBegin(); addrIt != listEnd; ++addrIt ) { VCard card; QStringList::ConstIterator strIt; // ADR + LABEL const Address::List addresses = (*addrIt).addresses(); for ( Address::List::ConstIterator it = addresses.begin(); it != addresses.end(); ++it ) { QStringList address; const bool isEmpty = ( (*it).postOfficeBox().isEmpty() && (*it).extended().isEmpty() && (*it).street().isEmpty() && (*it).locality().isEmpty() && (*it).region().isEmpty() && (*it).postalCode().isEmpty() && (*it).country().isEmpty() ); address.append( (*it).postOfficeBox().replace( QLatin1Char( ';' ), QLatin1String( "\\;" ) ) ); address.append( (*it).extended().replace( QLatin1Char( ';' ), QLatin1String( "\\;" ) ) ); address.append( (*it).street().replace( QLatin1Char( ';' ), QLatin1String( "\\;" ) ) ); address.append( (*it).locality().replace( QLatin1Char( ';' ), QLatin1String( "\\;" ) ) ); address.append( (*it).region().replace( QLatin1Char( ';' ), QLatin1String( "\\;" ) ) ); address.append( (*it).postalCode().replace( QLatin1Char( ';' ), QLatin1String( "\\;" ) ) ); address.append( (*it).country().replace( QLatin1Char( ';' ), QLatin1String( "\\;" ) ) ); VCardLine adrLine( QLatin1String( "ADR" ), address.join( QLatin1String( ";" ) ) ); if ( version == VCard::v2_1 && needsEncoding( address.join( QLatin1String( ";" ) ) ) ) { adrLine.addParameter( QLatin1String( "charset" ), QLatin1String( "UTF-8" ) ); adrLine.addParameter( QLatin1String( "encoding" ), QLatin1String( "QUOTED-PRINTABLE" ) ); } VCardLine labelLine( QLatin1String( "LABEL" ), (*it).label() ); if ( version == VCard::v2_1 && needsEncoding( (*it).label() ) ) { labelLine.addParameter( QLatin1String( "charset" ), QLatin1String( "UTF-8" ) ); labelLine.addParameter( QLatin1String( "encoding" ), QLatin1String( "QUOTED-PRINTABLE" ) ); } const bool hasLabel = !(*it).label().isEmpty(); QMap::ConstIterator typeIt; for ( typeIt = mAddressTypeMap.constBegin(); typeIt != mAddressTypeMap.constEnd(); ++typeIt ) { if ( typeIt.value() & (*it).type() ) { adrLine.addParameter( QLatin1String( "TYPE" ), typeIt.key() ); if ( hasLabel ) { labelLine.addParameter( QLatin1String( "TYPE" ), typeIt.key() ); } } } if ( !isEmpty ) { card.addLine( adrLine ); } if ( hasLabel ) { card.addLine( labelLine ); } } // BDAY card.addLine( VCardLine( QLatin1String( "BDAY" ), createDateTime( (*addrIt).birthday() ) ) ); // CATEGORIES if ( version == VCard::v3_0 ) { QStringList categories = (*addrIt).categories(); QStringList::Iterator catIt; for ( catIt = categories.begin(); catIt != categories.end(); ++catIt ) { (*catIt).replace( QLatin1Char( ',' ), QLatin1String( "\\," ) ); } VCardLine catLine( QLatin1String( "CATEGORIES" ), categories.join( QLatin1String( "," ) ) ); card.addLine( catLine ); } // CLASS if ( version == VCard::v3_0 ) { card.addLine( createSecrecy( (*addrIt).secrecy() ) ); } // EMAIL const QStringList emails = (*addrIt).emails(); bool pref = true; for ( strIt = emails.begin(); strIt != emails.end(); ++strIt ) { VCardLine line( QLatin1String( "EMAIL" ), *strIt ); if ( pref == true && emails.count() > 1 ) { line.addParameter( QLatin1String( "TYPE" ), QLatin1String( "PREF" ) ); pref = false; } card.addLine( line ); } // FN VCardLine fnLine( QLatin1String( "FN" ), (*addrIt).formattedName() ); if ( version == VCard::v2_1 && needsEncoding( (*addrIt).formattedName() ) ) { fnLine.addParameter( QLatin1String( "charset" ), QLatin1String( "UTF-8" ) ); fnLine.addParameter( QLatin1String( "encoding" ), QLatin1String( "QUOTED-PRINTABLE" ) ); } card.addLine( fnLine ); // GEO const Geo geo = (*addrIt).geo(); if ( geo.isValid() ) { QString str; str.sprintf( "%.6f;%.6f", geo.latitude(), geo.longitude() ); card.addLine( VCardLine( QLatin1String( "GEO" ), str ) ); } // KEY const Key::List keys = (*addrIt).keys(); Key::List::ConstIterator keyIt; for ( keyIt = keys.begin(); keyIt != keys.end(); ++keyIt ) { card.addLine( createKey( *keyIt ) ); } // LOGO card.addLine( createPicture( QLatin1String( "LOGO" ), (*addrIt).logo() ) ); // MAILER VCardLine mailerLine( QLatin1String( "MAILER" ), (*addrIt).mailer() ); if ( version == VCard::v2_1 && needsEncoding( (*addrIt).mailer() ) ) { mailerLine.addParameter( QLatin1String( "charset" ), QLatin1String( "UTF-8" ) ); mailerLine.addParameter( QLatin1String( "encoding" ), QLatin1String( "QUOTED-PRINTABLE" ) ); } card.addLine( mailerLine ); // N QStringList name; name.append( (*addrIt).familyName().replace( QLatin1Char( ';' ), QLatin1String( "\\;" ) ) ); name.append( (*addrIt).givenName().replace( QLatin1Char( ';' ), QLatin1String( "\\;" ) ) ); name.append( (*addrIt).additionalName().replace( QLatin1Char( ';' ), QLatin1String( "\\;" ) ) ); name.append( (*addrIt).prefix().replace( QLatin1Char( ';' ), QLatin1String( "\\;" ) ) ); name.append( (*addrIt).suffix().replace( QLatin1Char( ';' ), QLatin1String( "\\;" ) ) ); VCardLine nLine( QLatin1String( "N" ), name.join( QLatin1String( ";" ) ) ); if ( version == VCard::v2_1 && needsEncoding( name.join( QLatin1String( ";" ) ) ) ) { nLine.addParameter( QLatin1String( "charset" ), QLatin1String( "UTF-8" ) ); nLine.addParameter( QLatin1String( "encoding" ), QLatin1String( "QUOTED-PRINTABLE" ) ); } card.addLine( nLine ); // NAME VCardLine nameLine( QLatin1String( "NAME" ), (*addrIt).name() ); if ( version == VCard::v2_1 && needsEncoding( (*addrIt).name() ) ) { nameLine.addParameter( QLatin1String( "charset" ), QLatin1String( "UTF-8" ) ); nameLine.addParameter( QLatin1String( "encoding" ), QLatin1String( "QUOTED-PRINTABLE" ) ); } card.addLine( nameLine ); // NICKNAME if ( version == VCard::v3_0 ) { card.addLine( VCardLine( QLatin1String( "NICKNAME" ), (*addrIt).nickName() ) ); } // NOTE VCardLine noteLine( QLatin1String( "NOTE" ), (*addrIt).note() ); if ( version == VCard::v2_1 && needsEncoding( (*addrIt).note() ) ) { noteLine.addParameter( QLatin1String( "charset" ), QLatin1String( "UTF-8" ) ); noteLine.addParameter( QLatin1String( "encoding" ), QLatin1String( "QUOTED-PRINTABLE" ) ); } card.addLine( noteLine ); // ORG QStringList organization; - organization.append( ( *addrIt ).organization().replace( QLatin1Char( ';' ), QLatin1String( "\\;" ) ) ); + organization.append( ( *addrIt ).organization().replace( QLatin1Char( ';' ), + QLatin1String( "\\;" ) ) ); if ( !( *addrIt ).department().isEmpty() ) { - organization.append( ( *addrIt ).department().replace( QLatin1Char( ';' ), QLatin1String( "\\;" ) ) ); + organization.append( ( *addrIt ).department().replace( QLatin1Char( ';' ), + QLatin1String( "\\;" ) ) ); } VCardLine orgLine( QLatin1String( "ORG" ), organization.join( QLatin1String( ";" ) ) ); if ( version == VCard::v2_1 && needsEncoding( organization.join( QLatin1String( ";" ) ) ) ) { orgLine.addParameter( QLatin1String( "charset" ), QLatin1String( "UTF-8" ) ); orgLine.addParameter( QLatin1String( "encoding" ), QLatin1String( "QUOTED-PRINTABLE" ) ); } card.addLine( orgLine ); // PHOTO card.addLine( createPicture( QLatin1String( "PHOTO" ), (*addrIt).photo() ) ); // PROID if ( version == VCard::v3_0 ) { card.addLine( VCardLine( QLatin1String( "PRODID" ), (*addrIt).productId() ) ); } // REV card.addLine( VCardLine( QLatin1String( "REV" ), createDateTime( (*addrIt).revision() ) ) ); // ROLE VCardLine roleLine( QLatin1String( "ROLE" ), (*addrIt).role() ); if ( version == VCard::v2_1 && needsEncoding( (*addrIt).role() ) ) { roleLine.addParameter( QLatin1String( "charset" ), QLatin1String( "UTF-8" ) ); roleLine.addParameter( QLatin1String( "encoding" ), QLatin1String( "QUOTED-PRINTABLE" ) ); } card.addLine( roleLine ); // SORT-STRING if ( version == VCard::v3_0 ) { card.addLine( VCardLine( QLatin1String( "SORT-STRING" ), (*addrIt).sortString() ) ); } // SOUND card.addLine( createSound( (*addrIt).sound() ) ); // TEL const PhoneNumber::List phoneNumbers = (*addrIt).phoneNumbers(); PhoneNumber::List::ConstIterator phoneIt; for ( phoneIt = phoneNumbers.begin(); phoneIt != phoneNumbers.end(); ++phoneIt ) { VCardLine line( QLatin1String( "TEL" ), (*phoneIt).number() ); QMap::ConstIterator typeIt; for ( typeIt = mPhoneTypeMap.constBegin(); typeIt != mPhoneTypeMap.constEnd(); ++typeIt ) { if ( typeIt.value() & (*phoneIt).type() ) { line.addParameter( QLatin1String( "TYPE" ), typeIt.key() ); } } card.addLine( line ); } // TITLE VCardLine titleLine( QLatin1String( "TITLE" ), (*addrIt).title() ); if ( version == VCard::v2_1 && needsEncoding( (*addrIt).title() ) ) { titleLine.addParameter( QLatin1String( "charset" ), QLatin1String( "UTF-8" ) ); titleLine.addParameter( QLatin1String( "encoding" ), QLatin1String( "QUOTED-PRINTABLE" ) ); } card.addLine( titleLine ); // TZ const TimeZone timeZone = (*addrIt).timeZone(); if ( timeZone.isValid() ) { QString str; int neg = 1; if ( timeZone.offset() < 0 ) { neg = -1; } str.sprintf( "%c%02d:%02d", ( timeZone.offset() >= 0 ? '+' : '-' ), ( timeZone.offset() / 60 ) * neg, ( timeZone.offset() % 60 ) * neg ); card.addLine( VCardLine( QLatin1String( "TZ" ), str ) ); } // UID card.addLine( VCardLine( QLatin1String( "UID" ), (*addrIt).uid() ) ); // URL card.addLine( VCardLine( QLatin1String( "URL" ), (*addrIt).url().url() ) ); // VERSION if ( version == VCard::v2_1 ) { - card.addLine( VCardLine( QLatin1String( "VERSION" ), QLatin1String( "2.1" ) ) ); + card.addLine( VCardLine( QLatin1String( "VERSION" ), QLatin1String( "2.1" ) ) ); } if ( version == VCard::v3_0 ) { card.addLine( VCardLine( QLatin1String( "VERSION" ), QLatin1String( "3.0" ) ) ); } // X- const QStringList customs = (*addrIt).customs(); for ( strIt = customs.begin(); strIt != customs.end(); ++strIt ) { - const QString identifier = QLatin1String( "X-" ) + (*strIt).left( (*strIt).indexOf( QLatin1Char( ':' ) ) ); + const QString identifier = QLatin1String( "X-" ) + + (*strIt).left( (*strIt).indexOf( QLatin1Char( ':' ) ) ); const QString value = (*strIt).mid( (*strIt).indexOf( QLatin1Char( ':' ) ) + 1 ); if ( value.isEmpty() ) { continue; } VCardLine line( identifier, value ); if ( version == VCard::v2_1 && needsEncoding( value ) ) { line.addParameter( QLatin1String( "charset" ), QLatin1String( "UTF-8" ) ); line.addParameter( QLatin1String( "encoding" ), QLatin1String( "QUOTED-PRINTABLE" ) ); } card.addLine( line ); } vCardList.append( card ); } return VCardParser::createVCards( vCardList ); } Addressee::List VCardTool::parseVCards( const QByteArray &vcard ) const { static const QLatin1Char semicolonSep( ';' ); static const QLatin1Char commaSep( ',' ); QString identifier; Addressee::List addrList; const VCard::List vCardList = VCardParser::parseVCards( vcard ); VCard::List::ConstIterator cardIt; VCard::List::ConstIterator listEnd( vCardList.end() ); for ( cardIt = vCardList.begin(); cardIt != listEnd; ++cardIt ) { Addressee addr; const QStringList idents = (*cardIt).identifiers(); QStringList::ConstIterator identIt; QStringList::ConstIterator identEnd( idents.end() ); for ( identIt = idents.begin(); identIt != identEnd; ++identIt ) { const VCardLine::List lines = (*cardIt).lines( (*identIt) ); VCardLine::List::ConstIterator lineIt; // iterate over the lines for ( lineIt = lines.begin(); lineIt != lines.end(); ++lineIt ) { identifier = (*lineIt).identifier().toLower(); // ADR if ( identifier == QLatin1String( "adr" ) ) { Address address; const QStringList addrParts = splitString( semicolonSep, (*lineIt).value().toString() ); if ( addrParts.count() > 0 ) { address.setPostOfficeBox( addrParts[ 0 ] ); } if ( addrParts.count() > 1 ) { address.setExtended( addrParts[ 1 ] ); } if ( addrParts.count() > 2 ) { address.setStreet( addrParts[ 2 ] ); } if ( addrParts.count() > 3 ) { address.setLocality( addrParts[ 3 ] ); } if ( addrParts.count() > 4 ) { address.setRegion( addrParts[ 4 ] ); } if ( addrParts.count() > 5 ) { address.setPostalCode( addrParts[ 5 ] ); } if ( addrParts.count() > 6 ) { address.setCountry( addrParts[ 6 ] ); } Address::Type type; const QStringList types = (*lineIt).parameters( QLatin1String( "type" ) ); for ( QStringList::ConstIterator it = types.begin(); it != types.end(); ++it ) { type |= mAddressTypeMap[ (*it).toLower() ]; } address.setType( type ); addr.insertAddress( address ); } // BDAY else if ( identifier == QLatin1String( "bday" ) ) { addr.setBirthday( parseDateTime( (*lineIt).value().toString() ) ); } // CATEGORIES else if ( identifier == QLatin1String( "categories" ) ) { const QStringList categories = splitString( commaSep, (*lineIt).value().toString() ); addr.setCategories( categories ); } // CLASS else if ( identifier == QLatin1String( "class" ) ) { addr.setSecrecy( parseSecrecy( *lineIt ) ); } // EMAIL else if ( identifier == QLatin1String( "email" ) ) { const QStringList types = (*lineIt).parameters( QLatin1String( "type" ) ); - addr.insertEmail( (*lineIt).value().toString(), types.contains( QLatin1String( "PREF" ) ) ); + addr.insertEmail( (*lineIt).value().toString(), + types.contains( QLatin1String( "PREF" ) ) ); } // FN else if ( identifier == QLatin1String( "fn" ) ) { addr.setFormattedName( (*lineIt).value().toString() ); } // GEO else if ( identifier == QLatin1String( "geo" ) ) { Geo geo; const QStringList geoParts = (*lineIt).value().toString().split( QLatin1Char( ';' ), QString::KeepEmptyParts ); if ( geoParts.size() >= 2 ) { geo.setLatitude( geoParts[ 0 ].toFloat() ); geo.setLongitude( geoParts[ 1 ].toFloat() ); addr.setGeo( geo ); } } // KEY else if ( identifier == QLatin1String( "key" ) ) { addr.insertKey( parseKey( *lineIt ) ); } // LABEL else if ( identifier == QLatin1String( "label" ) ) { Address::Type type; const QStringList types = (*lineIt).parameters( QLatin1String( "type" ) ); for ( QStringList::ConstIterator it = types.begin(); it != types.end(); ++it ) { type |= mAddressTypeMap[ (*it).toLower() ]; } bool available = false; KABC::Address::List addressList = addr.addresses(); for ( KABC::Address::List::Iterator it = addressList.begin(); it != addressList.end(); ++it ) { if ( (*it).type() == type ) { (*it).setLabel( (*lineIt).value().toString() ); addr.insertAddress( *it ); available = true; break; } } if ( !available ) { // a standalone LABEL tag KABC::Address address( type ); address.setLabel( (*lineIt).value().toString() ); addr.insertAddress( address ); } } // LOGO else if ( identifier == QLatin1String( "logo" ) ) { addr.setLogo( parsePicture( *lineIt ) ); } // MAILER else if ( identifier == QLatin1String( "mailer" ) ) { addr.setMailer( (*lineIt).value().toString() ); } // N else if ( identifier == QLatin1String( "n" ) ) { const QStringList nameParts = splitString( semicolonSep, (*lineIt).value().toString() ); if ( nameParts.count() > 0 ) { addr.setFamilyName( nameParts[ 0 ] ); } if ( nameParts.count() > 1 ) { addr.setGivenName( nameParts[ 1 ] ); } if ( nameParts.count() > 2 ) { addr.setAdditionalName( nameParts[ 2 ] ); } if ( nameParts.count() > 3 ) { addr.setPrefix( nameParts[ 3 ] ); } if ( nameParts.count() > 4 ) { addr.setSuffix( nameParts[ 4 ] ); } } // NAME else if ( identifier == QLatin1String( "name" ) ) { addr.setName( (*lineIt).value().toString() ); } // NICKNAME else if ( identifier == QLatin1String( "nickname" ) ) { addr.setNickName( (*lineIt).value().toString() ); } // NOTE else if ( identifier == QLatin1String( "note" ) ) { addr.setNote( (*lineIt).value().toString() ); } // ORGANIZATION else if ( identifier == QLatin1String( "org" ) ) { const QStringList orgParts = splitString( semicolonSep, (*lineIt).value().toString() ); if ( orgParts.count() > 0 ) { addr.setOrganization( orgParts[ 0 ] ); } if ( orgParts.count() > 1 ) { addr.setDepartment( orgParts[ 1 ] ); } } // PHOTO else if ( identifier == QLatin1String( "photo" ) ) { addr.setPhoto( parsePicture( *lineIt ) ); } // PROID else if ( identifier == QLatin1String( "prodid" ) ) { addr.setProductId( (*lineIt).value().toString() ); } // REV else if ( identifier == QLatin1String( "rev" ) ) { addr.setRevision( parseDateTime( (*lineIt).value().toString() ) ); } // ROLE else if ( identifier == QLatin1String( "role" ) ) { addr.setRole( (*lineIt).value().toString() ); } // SORT-STRING else if ( identifier == QLatin1String( "sort-string" ) ) { addr.setSortString( (*lineIt).value().toString() ); } // SOUND else if ( identifier == QLatin1String( "sound" ) ) { addr.setSound( parseSound( *lineIt ) ); } // TEL else if ( identifier == QLatin1String( "tel" ) ) { PhoneNumber phone; phone.setNumber( (*lineIt).value().toString() ); PhoneNumber::Type type; const QStringList types = (*lineIt).parameters( QLatin1String( "type" ) ); for ( QStringList::ConstIterator it = types.begin(); it != types.end(); ++it ) { type |= mPhoneTypeMap[(*it).toUpper()]; } phone.setType( type ); addr.insertPhoneNumber( phone ); } // TITLE else if ( identifier == QLatin1String( "title" ) ) { addr.setTitle( (*lineIt).value().toString() ); } // TZ else if ( identifier == QLatin1String( "tz" ) ) { TimeZone tz; const QString date = (*lineIt).value().toString(); int hours = date.mid( 1, 2 ).toInt(); int minutes = date.mid( 4, 2 ).toInt(); int offset = ( hours * 60 ) + minutes; offset = offset * ( date[ 0 ] == QLatin1Char( '+' ) ? 1 : -1 ); tz.setOffset( offset ); addr.setTimeZone( tz ); } // UID else if ( identifier == QLatin1String( "uid" ) ) { addr.setUid( (*lineIt).value().toString() ); } // URL else if ( identifier == QLatin1String( "url" ) ) { addr.setUrl( KUrl( (*lineIt).value().toString() ) ); } // X- else if ( identifier.startsWith( QLatin1String( "x-" ) ) ) { const QString key = (*lineIt).identifier().mid( 2 ); int dash = key.indexOf( QLatin1Char( '-' ) ); addr.insertCustom( key.left( dash ), key.mid( dash + 1 ), (*lineIt).value().toString() ); } } } addrList.append( addr ); } return addrList; } QDateTime VCardTool::parseDateTime( const QString &str ) const { QDate date; QTime time; if ( str.indexOf( QLatin1Char( '-' ) ) == -1 ) { // is base format (yyyymmdd) date = QDate( str.left( 4 ).toInt(), str.mid( 4, 2 ).toInt(), str.mid( 6, 2 ).toInt() ); } else { // is extended format yyyy-mm-dd date = QDate( str.left( 4 ).toInt(), str.mid( 5, 2 ).toInt(), str.mid( 8, 2 ).toInt() ); } // does it also contain a time ? (Note: mm, ss are optional according ISO-8601) int timeStart = str.indexOf( QLatin1Char( 'T' ) ); if ( timeStart >= 0 ) { int hour = 0, minute = 0, second = 0; hour = str.mid( timeStart + 1, 2 ).toInt(); // hour must always be given if ( str.indexOf( QLatin1Char( ':' ), timeStart + 1 ) > 0 ) { // extended format (hh:mm:ss) if ( str.length() >= ( timeStart + 5 ) ) { minute = str.mid( timeStart + 4, 2 ).toInt(); if ( str.length() >= ( timeStart + 8 ) ) { second = str.mid( timeStart + 7, 2 ).toInt(); } } } else { // basic format (hhmmss) if ( str.length() >= ( timeStart + 4 ) ) { minute = str.mid( timeStart + 3, 2 ).toInt(); if ( str.length() >= ( timeStart + 6 ) ) { second = str.mid( timeStart + 5, 2 ).toInt(); } } } time = QTime( hour, minute, second ); } Qt::TimeSpec spec = ( str.right( 1 ) == QLatin1String( "Z" ) ) ? Qt::UTC : Qt::LocalTime; QDateTime dateTime(date); // explicitly set the time, which might be invalid, to keep the information // that the time is invalid. In createDateTime() the time/invalid flag is // checked which omits then to print the timestamp // This is needed to reproduce the given string in input // e.g. BDAY:2008-12-30 // without time shall also result in a string without a time dateTime.setTime(time); dateTime.setTimeSpec(spec); return dateTime; } QString VCardTool::createDateTime( const QDateTime &dateTime ) const { QString str; if ( dateTime.date().isValid() ) { str.sprintf( "%4d-%02d-%02d", dateTime.date().year(), dateTime.date().month(), dateTime.date().day() ); if ( dateTime.time().isValid() ) { QString tmp; tmp.sprintf( "T%02d:%02d:%02d", dateTime.time().hour(), dateTime.time().minute(), dateTime.time().second() ); str += tmp; if ( dateTime.timeSpec() == Qt::UTC ) { str += QLatin1Char( 'Z' ); } } } return str; } Picture VCardTool::parsePicture( const VCardLine &line ) const { Picture pic; const QStringList params = line.parameterList(); if ( params.contains( QLatin1String( "encoding" ) ) ) { QImage img; img.loadFromData( line.value().toByteArray() ); pic.setData( img ); } else if ( params.contains( QLatin1String( "value" ) ) ) { if ( line.parameter( QLatin1String( "value" ) ).toLower() == QLatin1String( "uri" ) ) { pic.setUrl( line.value().toString() ); } } if ( params.contains( QLatin1String( "type" ) ) ) { pic.setType( line.parameter( QLatin1String( "type" ) ) ); } return pic; } VCardLine VCardTool::createPicture( const QString &identifier, const Picture &pic ) const { VCardLine line( identifier ); if ( pic.isIntern() ) { if ( !pic.data().isNull() ) { QByteArray input; QBuffer buffer( &input ); buffer.open( QIODevice::WriteOnly ); if ( !pic.data().hasAlphaChannel() ) { pic.data().save( &buffer, "JPEG" ); line.setValue( input ); line.addParameter( QLatin1String( "encoding" ), QLatin1String( "b" ) ); line.addParameter( QLatin1String( "type" ), QLatin1String( "image/jpeg" ) ); } else { pic.data().save( &buffer, "PNG" ); line.setValue( input ); line.addParameter( QLatin1String( "encoding" ), QLatin1String( "b" ) ); line.addParameter( QLatin1String( "type" ), QLatin1String( "image/png" ) ); } } } else if ( !pic.url().isEmpty() ) { line.setValue( pic.url() ); line.addParameter( QLatin1String( "value" ), QLatin1String( "URI" ) ); } return line; } Sound VCardTool::parseSound( const VCardLine &line ) const { Sound snd; const QStringList params = line.parameterList(); if ( params.contains( QLatin1String( "encoding" ) ) ) { snd.setData( line.value().toByteArray() ); } else if ( params.contains( QLatin1String( "value" ) ) ) { if ( line.parameter( QLatin1String( "value" ) ).toLower() == QLatin1String( "uri" ) ) { snd.setUrl( line.value().toString() ); } } /* TODO: support sound types if ( params.contains( "type" ) ) snd.setType( line.parameter( "type" ) ); */ return snd; } VCardLine VCardTool::createSound( const Sound &snd ) const { VCardLine line( QLatin1String( "SOUND" ) ); if ( snd.isIntern() ) { if ( !snd.data().isEmpty() ) { line.setValue( snd.data() ); line.addParameter( QLatin1String( "encoding" ), QLatin1String( "b" ) ); // TODO: need to store sound type!!! } } else if ( !snd.url().isEmpty() ) { line.setValue( snd.url() ); line.addParameter( QLatin1String( "value" ), QLatin1String( "URI" ) ); } return line; } Key VCardTool::parseKey( const VCardLine &line ) const { Key key; const QStringList params = line.parameterList(); if ( params.contains( QLatin1String( "encoding" ) ) ) { key.setBinaryData( line.value().toByteArray() ); } else { key.setTextData( line.value().toString() ); } if ( params.contains( QLatin1String( "type" ) ) ) { if ( line.parameter( QLatin1String( "type" ) ).toLower() == QLatin1String( "x509" ) ) { key.setType( Key::X509 ); } else if ( line.parameter( QLatin1String( "type" ) ).toLower() == QLatin1String( "pgp" ) ) { key.setType( Key::PGP ); } else { key.setType( Key::Custom ); key.setCustomTypeString( line.parameter( QLatin1String( "type" ) ) ); } } return key; } VCardLine VCardTool::createKey( const Key &key ) const { VCardLine line( QLatin1String( "KEY" ) ); if ( key.isBinary() ) { if ( !key.binaryData().isEmpty() ) { line.setValue( key.binaryData() ); line.addParameter( QLatin1String( "encoding" ), QLatin1String( "b" ) ); } } else if ( !key.textData().isEmpty() ) { line.setValue( key.textData() ); } if ( key.type() == Key::X509 ) { line.addParameter( QLatin1String( "type" ), QLatin1String( "X509" ) ); } else if ( key.type() == Key::PGP ) { line.addParameter( QLatin1String( "type" ), QLatin1String( "PGP" ) ); } else if ( key.type() == Key::Custom ) { line.addParameter( QLatin1String( "type" ), key.customTypeString() ); } return line; } Secrecy VCardTool::parseSecrecy( const VCardLine &line ) const { Secrecy secrecy; const QString value = line.value().toString().toLower(); if ( value == QLatin1String( "public" ) ) { secrecy.setType( Secrecy::Public ); } else if ( value == QLatin1String( "private" ) ) { secrecy.setType( Secrecy::Private ); } else if ( value == QLatin1String( "confidential" ) ) { secrecy.setType( Secrecy::Confidential ); } return secrecy; } VCardLine VCardTool::createSecrecy( const Secrecy &secrecy ) const { VCardLine line( QLatin1String( "CLASS" ) ); int type = secrecy.type(); if ( type == Secrecy::Public ) { line.setValue( QLatin1String( "PUBLIC" ) ); } else if ( type == Secrecy::Private ) { line.setValue( QLatin1String( "PRIVATE" ) ); } else if ( type == Secrecy::Confidential ) { line.setValue( QLatin1String( "CONFIDENTIAL" ) ); } return line; } QStringList VCardTool::splitString( const QChar &sep, const QString &str ) const { QStringList list; QString value( str ); int start = 0; int pos = value.indexOf( sep, start ); while ( pos != -1 ) { if ( pos == 0 || value[ pos - 1 ] != QLatin1Char( '\\' ) ) { if ( pos > start && pos <= (int)value.length() ) { list << value.mid( start, pos - start ); } else { list << QString(); } start = pos + 1; pos = value.indexOf( sep, start ); } else { value.replace( pos - 1, 2, sep ); pos = value.indexOf( sep, pos ); } } int l = value.length() - 1; if ( value.mid( start, l - start + 1 ).length() > 0 ) { list << value.mid( start, l - start + 1 ); } else { list << QString(); } return list; }