You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdepim/tderesources/groupwise/soap/contactconverter.cpp

633 lines
20 KiB

/*
This file is part of tdepim.
Copyright (c) 2004 Tobias Koenig <tokoe@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "contactconverter.h"
#include <kdebug.h>
#include <tdelocale.h>
ContactConverter::ContactConverter( struct soap* soap )
: GWConverter( soap )
{
}
ngwt__Contact* ContactConverter::convertToContact( const KABC::Addressee &addr )
{
if ( addr.isEmpty() )
return 0;
ngwt__Contact* contact = soap_new_ngwt__Contact( soap(), -1 );
// ngwt__Contact
contact->fullName = 0;
contact->emailList = 0;
contact->imList = 0;
contact->addressList = 0;
contact->officeInfo = 0;
contact->personalInfo = 0;
contact->referenceInfo = 0;
// ngwt__AddressBookItem
contact->uuid = 0;
contact->comment = 0;
contact->sync = 0;
contact->domain = 0;
contact->postOffice = 0;
contact->distinguishedName = 0;
contact->userid = 0;
// ngwt__ContainerItem
contact->categories = 0;
contact->created = 0;
contact->customs = 0;
// ngwt__contact
contact->id = 0;
contact->name = 0;
contact->version = 0;
contact->modified = 0;
contact->changes = 0;
// Uid
contact->id = qStringToString( addr.custom( "GWRESOURCE", "UID" ) );
// Container
if ( !addr.custom( "GWRESOURCE", "CONTAINER" ).isEmpty() ) {
std::vector<ngwt__ContainerRef*>* container = soap_new_std__vectorTemplateOfPointerTongwt__ContainerRef( soap(), -1 );
ngwt__ContainerRef* containerRef = soap_new_ngwt__ContainerRef( soap(), -1 );
containerRef->deleted = 0;
containerRef->__item = addr.custom( "GWRESOURCE", "CONTAINER" ).utf8().data();
container->push_back( containerRef );
contact->container = *container;
}
// Name parts
ngwt__FullName* fullName = soap_new_ngwt__FullName( soap(), -1 );
fullName->displayName = 0;
fullName->namePrefix = 0;
fullName->firstName = 0;
fullName->middleName = 0;
fullName->lastName = 0;
fullName->nameSuffix = 0;
if ( !addr.formattedName().isEmpty() )
fullName->displayName = qStringToString( addr.formattedName() );
if ( !addr.prefix().isEmpty() )
fullName->namePrefix = qStringToString( addr.prefix() );
if ( !addr.givenName().isEmpty() )
fullName->firstName = qStringToString( addr.givenName() );
if ( !addr.additionalName().isEmpty() )
fullName->middleName = qStringToString( addr.additionalName() );
if ( !addr.familyName().isEmpty() )
fullName->lastName = qStringToString( addr.familyName() );
if ( !addr.suffix().isEmpty() )
fullName->nameSuffix = qStringToString( addr.suffix() );
contact->fullName = fullName;
// Emails
if ( !addr.emails().isEmpty() ) {
ngwt__EmailAddressList* emailList = soap_new_ngwt__EmailAddressList( soap(), -1 );
std::vector<std::string>* list = soap_new_std__vectorTemplateOfstd__string( soap(), -1 );
TQStringList emails = addr.emails();
emailList->primary = qStringToString( emails.first() );
TQStringList::Iterator it;
for ( it = emails.begin(); it != emails.end(); ++it )
list->push_back( std::string( (*it).utf8() ) );
emailList->email = *list;
contact->emailList = emailList;
} else
contact->emailList = 0;
// Phone numbers
if ( !addr.phoneNumbers().isEmpty() ) {
ngwt__PhoneList* phoneList = soap_new_ngwt__PhoneList( soap(), -1 );
phoneList->default_ = 0;
std::vector<class ngwt__PhoneNumber*> *list = soap_new_std__vectorTemplateOfPointerTongwt__PhoneNumber( soap(), -1 );
KABC::PhoneNumber::List phones = addr.phoneNumbers();
KABC::PhoneNumber::List::Iterator it;
for ( it = phones.begin(); it != phones.end(); ++it ) {
ngwt__PhoneNumber* number = convertPhoneNumber( *it );
if ( number ) {
list->push_back( number );
// if preferred number assign it
if ( (*it).type() & KABC::PhoneNumber::Pref )
phoneList->default_ = qStringToString( (*it).number() );
}
}
phoneList->phone = *list;
contact->phoneList = phoneList;
} else
contact->phoneList = 0;
// Addresses
if ( !addr.addresses().isEmpty() ) {
ngwt__PostalAddressList* addressList = soap_new_ngwt__PostalAddressList( soap(), -1 );
std::vector<class ngwt__PostalAddress*> *list = soap_new_std__vectorTemplateOfPointerTongwt__PostalAddress( soap(), -1 );
KABC::Address::List addresses = addr.addresses();
KABC::Address::List::Iterator it;
for ( it = addresses.begin(); it != addresses.end(); ++it ) {
ngwt__PostalAddress* address = convertPostalAddress( *it );
if ( address )
list->push_back( address );
}
addressList->address = *list;
contact->addressList = addressList;
} else
contact->addressList = 0;
// IM addresses
{
contact->imList = convertImAddresses( addr );
}
// Office information
{
ngwt__OfficeInfo* info = soap_new_ngwt__OfficeInfo( soap(), -1 );
// TODO: write back organization?
if ( !addr.custom( "KADDRESSBOOK", "X-Department" ).isEmpty() )
info->department = qStringToString( addr.custom( "KADDRESSBOOK", "X-Department" ) );
else
info->department = 0;
if ( !addr.title().isEmpty() )
info->title = qStringToString( addr.title() );
else
info->title = 0;
if ( !addr.url().isEmpty() )
info->website = qStringToString( addr.url().url() );
else
info->website = 0;
info->organization = 0;
contact->officeInfo = info;
}
// Personal information
{
ngwt__PersonalInfo* info = soap_new_ngwt__PersonalInfo( soap(), -1 );
if ( addr.birthday().isValid() )
info->birthday = qDateToString( addr.birthday().date() );
else
info->birthday = 0;
// don't write back the web site here, otherwise we'll have it twice
info->website = 0;
contact->personalInfo = info;
}
return contact;
}
KABC::Addressee ContactConverter::convertFromAddressBookItem( ngwt__AddressBookItem * addrBkItem )
{
//kdDebug() << "ContactConverter::convertFromAddressBookItem()" << endl;
KABC::Addressee addr;
if ( !addrBkItem )
{
kdDebug() << "Null AddressBookItem, bailing out!" << endl;
return addr;
}
// gwt:Item
addr.insertCustom( "GWRESOURCE", "UID", stringToTQString( addrBkItem->id ) );
addr.setFormattedName( stringToTQString( addrBkItem->name ) );
// gwt::AddressBookItem
addr.insertCustom( "GWRESOURCE", "UUID", stringToTQString( addrBkItem->uuid ) );
addr.setNote( stringToTQString( addrBkItem->comment ) );
return addr;
}
KABC::Addressee ContactConverter::convertFromResource( ngwt__Resource* resource )
{
//kdDebug() << "ContactConverter::convertFromResource()" << endl;
KABC::Addressee addr = convertFromAddressBookItem( resource );
if ( !resource )
{
kdDebug() << "Null Resource, bailing out!" << endl;
return addr;
}
if ( resource->phone )
addr.insertPhoneNumber( KABC::PhoneNumber( stringToTQString( resource->phone ), KABC::PhoneNumber::Work ) );
if ( resource->email )
addr.insertEmail( stringToTQString( resource->email ), true );
if ( resource->owner )
addr.insertCustom( "KADDRESSBOOK", "X-ManagersName", stringToTQString( resource->owner->__item ) );
addr.insertCategory( i18n( "Resource" ) );
return addr;
}
KABC::Addressee ContactConverter::convertFromGroup( ngwt__Group* group)
{
// kdDebug() << "ContactConverter::convertFromGroup()" << endl;
KABC::Addressee addr = convertFromAddressBookItem( group );
if ( !group )
{
kdDebug() << "Null Resource, bailing out!" << endl;
return addr;
}
addr.insertCategory( i18n( "Group" ) );
return addr;
}
KABC::Addressee ContactConverter::convertFromContact( ngwt__Contact* contact )
{
// kdDebug() << "ContactConverter::convertFromContact()" << endl;
KABC::Addressee addr = convertFromAddressBookItem( contact );
if ( !contact )
{
kdDebug() << "Null Contact, bailing out!" << endl;
return addr;
}
// Name parts
ngwt__FullName* fullName = contact->fullName;
if ( fullName ) {
if ( fullName->displayName )
addr.setFormattedName( stringToTQString( fullName->displayName ) );
else
addr.setFormattedName( TQString() );
if ( fullName->namePrefix )
addr.setPrefix( stringToTQString( fullName->namePrefix ) );
if ( fullName->firstName )
addr.setGivenName( stringToTQString( fullName->firstName ) );
if ( fullName->middleName )
addr.setAdditionalName( stringToTQString( fullName->middleName ) );
if ( fullName->lastName )
addr.setFamilyName( stringToTQString( fullName->lastName ) );
if ( fullName->nameSuffix )
addr.setSuffix( stringToTQString( fullName->nameSuffix ) );
}
// Emails
if ( contact->emailList ) {
TQStringList emails;
if ( contact->emailList->primary )
emails.append( stringToTQString( contact->emailList->primary ) );
if ( !contact->emailList->email.empty() ) {
std::vector<std::string> list = contact->emailList->email;
std::vector<std::string>::const_iterator it;
for ( it = list.begin(); it != list.end(); ++it ) {
if ( emails.find( stringToTQString( *it ) ) == emails.end() )
emails.append( stringToTQString( *it ) );
}
}
if ( emails.count() )
addr.setEmails( emails );
}
// Phone numbers
if ( contact->phoneList && !contact->phoneList->phone.empty() ) {
TQString defaultNumber = stringToTQString( contact->phoneList->default_ );
std::vector<class ngwt__PhoneNumber*> list = contact->phoneList->phone;
std::vector<class ngwt__PhoneNumber*>::const_iterator it;
for ( it = list.begin(); it != list.end(); ++it ) {
KABC::PhoneNumber phone = convertPhoneNumber( *it );
if ( !phone.number().isEmpty() ) {
if ( phone.number() == defaultNumber )
phone.setType( phone.type() | KABC::PhoneNumber::Pref );
addr.insertPhoneNumber( phone );
}
}
}
// Addresses
if ( contact->addressList && !contact->addressList->address.empty() ) {
std::vector<class ngwt__PostalAddress*> list = contact->addressList->address;
std::vector<class ngwt__PostalAddress*>::const_iterator it;
for ( it = list.begin(); it != list.end(); ++it ) {
KABC::Address address = convertPostalAddress( *it );
if ( !address.isEmpty() )
addr.insertAddress( address );
}
}
// Office information
if ( contact->officeInfo ) {
ngwt__OfficeInfo* info = contact->officeInfo;
if ( info->organization )
addr.setOrganization( stringToTQString( info->organization->__item ) );
if ( info->department )
addr.insertCustom( "KADDRESSBOOK", "X-Department", stringToTQString( info->department ) );
if ( info->title )
addr.setTitle( stringToTQString( info->title ) );
if ( info->website )
addr.setUrl( KURL( stringToTQString( info->website ) ) );
}
// Personal information
if ( contact->personalInfo ) {
ngwt__PersonalInfo* info = contact->personalInfo;
if ( info->birthday ) {
TQDate date = stringToTQDate( info->birthday );
if ( date.isValid() )
addr.setBirthday( date );
}
if ( info->website ) // we might overwrite the office info website here... :(
addr.setUrl( KURL( stringToTQString( info->website ) ) );
}
// IM addresses
if ( contact->imList ) {
// put all the im addresses on the same service into the same qstringlist
TQMap<TQString, TQStringList> addressMap;
std::vector<ngwt__ImAddress*> list = contact->imList->im;
std::vector<ngwt__ImAddress*>::const_iterator it;
for ( it = list.begin(); it != list.end(); ++it ) {
TQStringList addressesForService = addressMap[ stringToTQString( (*it)->service ) ];
addressesForService.append( stringToTQString( (*it)->address ) );
addressMap.insert( stringToTQString( (*it)->service ), addressesForService );
}
// then construct a custom field from each qstringlist
TQMap<TQString, TQStringList>::Iterator addrIt;
for ( addrIt = addressMap.begin(); addrIt != addressMap.end(); ++addrIt )
{
TQString protocol = addrIt.key();
TQStringList addresses = addrIt.data();
//kdDebug() << "got IM addresses for '" << protocol << "' : " << addresses << endl;
// TODO: map protocol to KDE's set of known protocol names (need to know the set of services in use elsewhere)
if ( protocol == "nov" )
protocol = "groupwise";
addr.insertCustom( TQString::fromLatin1("messaging/%1").arg( protocol ),
TQString::fromLatin1( "All" ),
addresses.join( TQChar( 0xE000 ) ) );
}
}
// addressbook delta sync info
if ( contact->sync )
{
if ( *contact->sync == add )
addr.insertCustom( "GWRESOURCE", "SYNC", "ADD" );
else if ( *contact->sync == delete_ )
addr.insertCustom( "GWRESOURCE", "SYNC", "DEL" );
else if ( *contact->sync == update )
addr.insertCustom( "GWRESOURCE", "SYNC", "UPD" );
}
//kdDebug() << "Got the following addressee: " << endl;
//addr.dump();
//kdDebug() << "Customs are: " << addr.customs() << endl;
return addr;
}
KABC::PhoneNumber ContactConverter::convertPhoneNumber( ngwt__PhoneNumber *phone ) const
{
KABC::PhoneNumber phoneNumber;
if ( !phone )
return phoneNumber;
phoneNumber.setNumber( stringToTQString( phone->__item ) );
if ( phone->type == Fax ) {
phoneNumber.setType( KABC::PhoneNumber::Fax );
} else if ( phone->type == Home ) {
phoneNumber.setType( KABC::PhoneNumber::Home );
} else if ( phone->type == Mobile ) {
phoneNumber.setType( KABC::PhoneNumber::Cell );
} else if ( phone->type == Office ) {
phoneNumber.setType( KABC::PhoneNumber::Work );
} else if ( phone->type == Pager ) {
phoneNumber.setType( KABC::PhoneNumber::Pager );
} else {
// should never been reached, phone numbers have always a type set...
}
return phoneNumber;
}
ngwt__PhoneNumber* ContactConverter::convertPhoneNumber( const KABC::PhoneNumber &number ) const
{
if ( number.number().isEmpty() )
return 0;
ngwt__PhoneNumber* phoneNumber = soap_new_ngwt__PhoneNumber( soap(), -1 );
phoneNumber->__item = number.number().utf8().data();
if ( number.type() & KABC::PhoneNumber::Fax ) {
phoneNumber->type = Fax;
} else if ( number.type() == KABC::PhoneNumber::Home ) {
phoneNumber->type = Home;
} else if ( number.type() & KABC::PhoneNumber::Cell ) {
phoneNumber->type = Mobile;
} else if ( number.type() == KABC::PhoneNumber::Work ) {
phoneNumber->type = Office;
} else if ( number.type() & KABC::PhoneNumber::Pager ) {
phoneNumber->type = Pager;
} else {
// TODO: cache unsupported types
}
return phoneNumber;
}
KABC::Address ContactConverter::convertPostalAddress( ngwt__PostalAddress *addr ) const
{
KABC::Address address;
if ( !addr )
return address;
if ( addr->streetAddress )
address.setStreet( stringToTQString( addr->streetAddress ) );
if ( addr->location )
address.setExtended( stringToTQString( addr->location ) );
if ( addr->city ) // isn't city the same like location?
address.setLocality( stringToTQString( addr->city ) );
if ( addr->state )
address.setRegion( stringToTQString( addr->state ) );
if ( addr->postalCode )
address.setPostalCode( stringToTQString( addr->postalCode ) );
if ( addr->country )
address.setCountry( stringToTQString( addr->country ) );
if ( addr->type == Home_ ) {
address.setType( KABC::Address::Home );
} else if ( addr->type == Office_ ) {
address.setType( KABC::Address::Work );
} else {
// should never been reached, addresses have always a type set...
}
return address;
}
ngwt__PostalAddress* ContactConverter::convertPostalAddress( const KABC::Address &address )
{
if ( address.isEmpty() )
return 0;
ngwt__PostalAddress* postalAddress = soap_new_ngwt__PostalAddress( soap(), -1 );
postalAddress->description = 0;
if ( !address.street().isEmpty() )
postalAddress->streetAddress = qStringToString( address.street() );
else
postalAddress->streetAddress = 0;
if ( !address.extended().isEmpty() )
postalAddress->location = qStringToString( address.extended() );
else
postalAddress->location = 0;
if ( !address.locality().isEmpty() )
postalAddress->city = qStringToString( address.locality() );
else
postalAddress->city = 0;
if ( !address.region().isEmpty() )
postalAddress->state = qStringToString( address.region() );
else
postalAddress->state = 0;
if ( !address.postalCode().isEmpty() )
postalAddress->postalCode = qStringToString( address.postalCode() );
else
postalAddress->postalCode = 0;
if ( !address.country().isEmpty() )
postalAddress->country = qStringToString( address.country() );
else
postalAddress->country = 0;
if ( address.type() & KABC::Address::Home ) {
postalAddress->type = Home_;
} else if ( address.type() & KABC::Address::Work ) {
postalAddress->type = Office_;
} else {
// TODO: cache unsupported types
}
return postalAddress;
}
ngwt__ImAddressList* ContactConverter::convertImAddresses( const KABC::Addressee& addr )
{
//return 0;
/* TODO: use IM address dedicated functions in KDE 4.0.
Change semantics so that convertToContact pulls each
IM address out of the addressee and passes it to this
function, which converts one at a time. */
kdDebug() << k_funcinfo << endl;
ngwt__ImAddressList* imList = soap_new_ngwt__ImAddressList( soap(), -1 );
std::vector<class ngwt__ImAddress*> *list = soap_new_std__vectorTemplateOfPointerTongwt__ImAddress( soap(), -1 );
// for each custom
// if it contains IM addresses
// extract each one and add it to imList
const TQStringList customs = addr.customs();
TQStringList::ConstIterator it;
bool isSet = false;
for ( it = customs.begin(); it != customs.end(); ++it ) {
TQString app, name, value;
splitField( *it, app, name, value );
if ( app.startsWith( TQString::fromLatin1( "messaging/" ) ) && name == TQString::fromLatin1( "All" ) ) {
// get the protocol for this field
TQString protocol = app.section( '/', 1, 1 );
if ( !protocol.isEmpty() ) {
if ( protocol == "groupwise" )
protocol = "novell";
TQStringList addresses = TQStringList::split( TQChar( 0xE000 ), value );
TQStringList::iterator end = addresses.end();
// extract each address for this protocol, and create an ngwt__ImAddress for it, and append it to list.
for ( TQStringList::ConstIterator it = addresses.begin(); it != end; ++it ) {
ngwt__ImAddress* address = soap_new_ngwt__ImAddress( soap(), -1 );
address->service = soap_new_std__string( soap(), -1 );
address->address = soap_new_std__string( soap(), -1 );
address->type = soap_new_std__string( soap(), -1 );
address->service->append( protocol.utf8() );
address->address->append( (*it).utf8() );
address->type->append( "all" );
kdDebug() << "adding: service: " << protocol << " address: " << *it << " type: all" << endl;
list->push_back( address );
}
}
}
}
imList->im = *list;
if ( list->size() > 0 )
return imList;
else
{
delete imList;
return 0;
}
}
void ContactConverter::splitField( const TQString &str, TQString &app, TQString &name, TQString &value )
{
int colon = str.find( ':' );
if ( colon != -1 ) {
TQString tmp = str.left( colon );
value = str.mid( colon + 1 );
int dash = tmp.find( '-' );
if ( dash != -1 ) {
app = tmp.left( dash );
name = tmp.mid( dash + 1 );
}
}
}