Page MenuHomePhorge

resourceakonadi_p.cpp
No OneTemporary

resourceakonadi_p.cpp

/*
This file is part of libkabc.
Copyright (c) 2009 Kevin Krammer <kevin.krammer@gmx.at>
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 "resourceakonadi_p.h"
#include "resourceakonadiconfig.h"
#include "storecollectiondialog.h"
#include <akonadi/item.h>
#include <akonadi/mimetypechecker.h>
#include <kabc/addressee.h>
#include <kabc/contactgroup.h>
#include <kabc/distributionlist.h>
using namespace KABC;
ResourceAkonadi::Private::Private( ResourceAkonadi *parent )
: SharedResourcePrivate<SubResource>( new IdArbiter(), parent ),
mParent( parent ), mInternalDataChange( false )
{
}
ResourceAkonadi::Private::Private( const KConfigGroup &config, ResourceAkonadi *parent )
: SharedResourcePrivate<SubResource>( config, new IdArbiter(), parent ),
mParent( parent ), mInternalDataChange( false )
{
}
bool ResourceAkonadi::Private::insertAddressee( const KABC::Addressee &addressee )
{
const QString uid = addressee.uid();
if ( mParent->mAddrMap.constFind( uid ) != mParent->mAddrMap.constEnd() ) {
changeLocalItem( uid );
return true;
}
return addLocalItem( uid, Addressee::mimeType() );
}
void ResourceAkonadi::Private::removeAddressee( const KABC::Addressee &addressee )
{
removeLocalItem( addressee.uid() );
}
bool ResourceAkonadi::Private::insertDistributionList( KABC::DistributionList *list )
{
if ( mInternalDataChange ) {
return true;
}
const QString uid = list->identifier();
if ( mParent->mDistListMap.constFind( uid ) != mParent->mDistListMap.constEnd() ) {
changeLocalItem( uid );
return true;
}
return addLocalItem( uid, ContactGroup::mimeType() );
}
void ResourceAkonadi::Private::removeDistributionList( KABC::DistributionList *list )
{
if ( mInternalDataChange ) {
return;
}
removeLocalItem( list->identifier() );
}
QMap<QString, QString> ResourceAkonadi::Private::uidToResourceMap() const
{
return mUidToResourceMap;
}
bool ResourceAkonadi::Private::openResource()
{
kDebug( 5700 );
return true;
}
bool ResourceAkonadi::Private::closeResource()
{
kDebug( 5700 );
// clear local caches
mParent->mAddrMap.clear();
// take a copy of mDistListMap, then clear it and finally qDeleteAll
// the copy to avoid problems with removeDistributionList() called by
// ~DistributionList().
BoolGuard internalChange( mInternalDataChange, true );
DistributionListMap tempDistListMap( mParent->mDistListMap );
mParent->mDistListMap.clear();
qDeleteAll( tempDistListMap );
return true;
}
void ResourceAkonadi::Private::clearResource()
{
kDebug( 5700 );
// clear local caches
mParent->mAddrMap.clear();
// take a copy of mDistListMap, then clear it and finally qDeleteAll
// the copy to avoid problems with removeDistributionList() called by
// ~DistributionList().
BoolGuard internalChange( mInternalDataChange, true );
DistributionListMap tempDistListMap( mParent->mDistListMap );
mParent->mDistListMap.clear();
qDeleteAll( tempDistListMap );
SharedResourcePrivate<SubResource>::clearResource();
}
Akonadi::Item ResourceAkonadi::Private::createItem( const QString &kresId )
{
Akonadi::Item item;
DistributionList *list = mParent->mDistListMap.value( kresId, 0 );
if ( list != 0 ) {
item.setMimeType( ContactGroup::mimeType() );
item.setPayload<ContactGroup>( contactGroupFromDistList( list ) );
} else {
item.setMimeType( Addressee::mimeType() );
item.setPayload<Addressee>( mParent->mAddrMap.value( kresId ) );
}
return item;
}
Akonadi::Item ResourceAkonadi::Private::updateItem( const Akonadi::Item &item, const QString &kresId, const QString &originalId )
{
Akonadi::Item update( item );
DistributionList *list = mParent->mDistListMap.value( kresId, 0 );
if ( list != 0 ) {
ContactGroup contactGroup = contactGroupFromDistList( list );
contactGroup.setId( originalId );
update.setPayload<ContactGroup>( contactGroup );
} else {
Addressee addressee = mParent->mAddrMap.value( kresId );
addressee.setUid( originalId );
update.setPayload<Addressee>( addressee );
}
return update;
}
StoreConfigIface::CollectionsByMimeType ResourceAkonadi::Private::storeCollectionsFromOldDefault() const
{
Q_ASSERT( mDefaultStoreCollection.isValid() );
CollectionsByMimeType storeCollections;
if ( Akonadi::MimeTypeChecker::isWantedCollection( mDefaultStoreCollection, Addressee::mimeType() ) ) {
storeCollections[ Addressee::mimeType() ] = mDefaultStoreCollection;
}
if ( Akonadi::MimeTypeChecker::isWantedCollection( mDefaultStoreCollection, ContactGroup::mimeType() ) ) {
storeCollections[ ContactGroup::mimeType() ] = mDefaultStoreCollection;
}
return storeCollections;
}
void ResourceAkonadi::Private::subResourceAdded( SubResourceBase *subResourceBase )
{
kDebug( 5700 ) << "id=" << subResourceBase->subResourceIdentifier();
SharedResourcePrivate<SubResource>::subResourceAdded( subResourceBase );
SubResource *subResource = qobject_cast<SubResource*>( subResourceBase );
connect( subResource, SIGNAL(addresseeAdded(KABC::Addressee,QString)),
this, SLOT(addresseeAdded(KABC::Addressee,QString)) );
connect( subResource, SIGNAL(addresseeChanged(KABC::Addressee,QString)),
this, SLOT(addresseeChanged(KABC::Addressee,QString)) );
connect( subResource, SIGNAL(addresseeRemoved(QString,QString)),
this, SLOT(addresseeRemoved(QString,QString)) );
connect( subResource, SIGNAL(contactGroupAdded(KABC::ContactGroup,QString)),
this, SLOT(contactGroupAdded(KABC::ContactGroup,QString)) );
connect( subResource, SIGNAL(contactGroupChanged(KABC::ContactGroup,QString)),
this, SLOT(contactGroupChanged(KABC::ContactGroup,QString)) );
connect( subResource, SIGNAL(contactGroupRemoved(QString,QString)),
this, SLOT(contactGroupRemoved(QString,QString)) );
emit mParent->signalSubresourceAdded( mParent, QLatin1String( "contact" ), subResourceBase->subResourceIdentifier() );
}
void ResourceAkonadi::Private::subResourceRemoved( SubResourceBase *subResourceBase )
{
kDebug( 5700 ) << "id=" << subResourceBase->subResourceIdentifier();
SharedResourcePrivate<SubResource>::subResourceRemoved( subResourceBase );
SubResource *subResource = qobject_cast<SubResource*>( subResourceBase );
disconnect( subResource, SIGNAL(addresseeAdded(KABC::Addressee,QString)),
this, SLOT(addresseeAdded(KABC::Addressee,QString)) );
disconnect( subResource, SIGNAL(addresseeChanged(KABC::Addressee,QString)),
this, SLOT(addresseeChanged(KABC::Addressee,QString)) );
disconnect( subResource, SIGNAL(addresseeRemoved(QString,QString)),
this, SLOT(addresseeRemoved(QString,QString)) );
disconnect( subResource, SIGNAL(contactGroupAdded(KABC::ContactGroup,QString)),
this, SLOT(contactGroupAdded(KABC::ContactGroup,QString)) );
disconnect( subResource, SIGNAL(contactGroupChanged(KABC::ContactGroup,QString)),
this, SLOT(contactGroupChanged(KABC::ContactGroup,QString)) );
disconnect( subResource, SIGNAL(contactGroupRemoved(QString,QString)),
this, SLOT(contactGroupRemoved(QString,QString)) );
// block scope for BoolGuard
{
BoolGuard internalChange( mInternalDataChange, true );
QMap<QString, QString>::iterator it = mUidToResourceMap.begin();
while ( it != mUidToResourceMap.end() ) {
if ( it.value() == subResourceBase->subResourceIdentifier() ) {
const QString uid = it.key();
mChanges.remove( uid );
mIdArbiter->removeArbitratedId( uid );
mParent->mAddrMap.remove( uid );
DistributionList *distList = mParent->mDistListMap.value( uid, 0 );
delete distList;
it = mUidToResourceMap.erase( it );
} else {
++it;
}
}
}
emit mParent->signalSubresourceRemoved( mParent, QLatin1String( "contact" ), subResourceBase->subResourceIdentifier() );
emit mParent->addressBook()->emitAddressBookChanged();
}
void ResourceAkonadi::Private::loadingResult( bool ok, const QString &errorString )
{
SharedResourcePrivate<SubResource>::loadingResult( ok, errorString );
if ( ok ) {
emit mParent->loadingFinished( mParent );
mModel.startMonitoring();
} else {
emit mParent->loadingError( mParent, errorString );
}
}
void ResourceAkonadi::Private::savingResult( bool ok, const QString &errorString )
{
SharedResourcePrivate<SubResource>::savingResult( ok, errorString );
if ( ok ) {
mChanges.clear();
emit mParent->savingFinished( mParent );
} else {
emit mParent->savingError( mParent, errorString );
}
}
const SubResourceBase *ResourceAkonadi::Private::storeSubResourceFromUser( const QString &uid, const QString &mimeType )
{
Q_UNUSED( uid );
Q_ASSERT( mStoreCollectionDialog != 0 );
if ( mimeType == Addressee::mimeType() ) {
mStoreCollectionDialog->setLabelText( i18nc( "@label where to store a new address book entry", "Please select a storage folder for this contact:" ) );
} else if ( mimeType == ContactGroup::mimeType() ) {
mStoreCollectionDialog->setLabelText( i18nc( "@label where to store a new email distribution list", "Please select a storage folder for this distribution list:" ) );
} else {
kError( 5700 ) << "Unexpected MIME type:" << mimeType;
mStoreCollectionDialog->setLabelText( i18nc( "@label", "Please select a storage folder:" ) );
}
mStoreCollectionDialog->setMimeType( mimeType );
const SubResourceBase *resource = 0;
while ( resource == 0 ) {
if ( mStoreCollectionDialog->exec() != QDialog::Accepted ) {
return 0;
}
Akonadi::Collection collection = mStoreCollectionDialog->selectedCollection();
if ( collection.isValid() ) {
resource = mModel.subResource( collection.id() );
}
}
return resource;
}
void ResourceAkonadi::Private::subResourceChanged( const QString &subResourceIdentifier )
{
emit mParent->signalSubresourceChanged( mParent, QLatin1String( "contact" ), subResourceIdentifier );
}
void ResourceAkonadi::Private::addresseeAdded( const KABC::Addressee &addressee, const QString &subResourceIdentifier )
{
kDebug( 5700 ) << "Addressee (uid=" << addressee.uid()
<< ", name=" << addressee.formattedName()
<< "), subResource=" << subResourceIdentifier;
mChanges.remove( addressee.uid() );
// check if we already have it, i.e. if it is the result of us saving it
if ( mParent->mAddrMap.constFind( addressee.uid() ) == mParent->mAddrMap.constEnd() ) {
Addressee addr = addressee;
addr.setResource( mParent );
mParent->mAddrMap.insert( addressee.uid(), addr );
mUidToResourceMap.insert( addressee.uid(), subResourceIdentifier );
if ( !isLoading() ) {
mParent->addressBook()->emitAddressBookChanged();
}
}
}
void ResourceAkonadi::Private::addresseeChanged( const KABC::Addressee &addressee, const QString &subResourceIdentifier )
{
kDebug( 5700 ) << "Addressee (uid=" << addressee.uid()
<< ", name=" << addressee.formattedName()
<< "), subResource=" << subResourceIdentifier;
mChanges.remove( addressee.uid() );
Addressee oldAddressee = mParent->mAddrMap[ addressee.uid() ];
if ( oldAddressee == addressee ) {
kDebug( 5700 ) << "No change to addressee data";
return;
}
Addressee addr = addressee;
addr.setResource( mParent );
mParent->mAddrMap[ addressee.uid() ] = addr;
if ( !isLoading() ) {
mParent->addressBook()->emitAddressBookChanged();
}
}
void ResourceAkonadi::Private::addresseeRemoved( const QString &uid, const QString &subResourceIdentifier )
{
kDebug( 5700 ) << "Addressee (uid=" << uid
<< "), subResource=" << subResourceIdentifier;
mChanges.remove( uid );
// check if we still have it, i.e. it is not a result of us deleting it
if ( mParent->mAddrMap.constFind( uid ) != mParent->mAddrMap.constEnd() ) {
mParent->mAddrMap.remove( uid );
mUidToResourceMap.remove( uid );
if ( !isLoading() ) {
mParent->addressBook()->emitAddressBookChanged();
}
}
}
void ResourceAkonadi::Private::contactGroupAdded( const KABC::ContactGroup &contactGroup, const QString &subResourceIdentifier )
{
kDebug( 5700 ) << "ContactGroup (uid=" << contactGroup.id()
<< ", name=" << contactGroup.name()
<< "), subResource=" << subResourceIdentifier;
mChanges.remove( contactGroup.id() );
// check if we already have it, i.e. if it is the result of us saving it
if ( mParent->mDistListMap.constFind( contactGroup.id() ) == mParent->mDistListMap.constEnd() ) {
// block scope for BoolGuard
{
BoolGuard internalChange( mInternalDataChange, true );
(void)distListFromContactGroup( contactGroup );
}
mUidToResourceMap.insert( contactGroup.id(), subResourceIdentifier );
if ( !isLoading() ) {
mParent->addressBook()->emitAddressBookChanged();
}
}
}
void ResourceAkonadi::Private::contactGroupChanged( const KABC::ContactGroup &contactGroup, const QString &subResourceIdentifier )
{
kDebug( 5700 ) << "ContactGroup (uid=" << contactGroup.id()
<< ", name=" << contactGroup.name()
<< "), subResource=" << subResourceIdentifier;
mChanges.remove( contactGroup.id() );
// TODO check if we can compare distribution lists and whether we
// can do update instead of remove/add
DistributionListMap::iterator findIt = mParent->mDistListMap.find( contactGroup.id() );
if ( findIt == mParent->mDistListMap.end() ) {
kError( 5700 ) << "No distribution list for changed contactgroup";
contactGroupAdded( contactGroup, subResourceIdentifier );
return;
}
// block scope for BoolGuard
{
BoolGuard internalChange( mInternalDataChange, true );
DistributionList *distList = findIt.value();
delete distList;
distList = distListFromContactGroup( contactGroup );
}
if ( !isLoading() ) {
mParent->addressBook()->emitAddressBookChanged();
}
}
void ResourceAkonadi::Private::contactGroupRemoved( const QString &uid, const QString &subResourceIdentifier )
{
kDebug( 5700 ) << "ContactGroup (uid=" << uid
<< "), subResource=" << subResourceIdentifier;
mChanges.remove( uid );
// check if we still have it, i.e. it is not a result of us deleting it
const DistributionListMap::const_iterator findIt = mParent->mDistListMap.constFind( uid );
if ( findIt != mParent->mDistListMap.constEnd() ) {
// block scope for BoolGuard
{
BoolGuard internalChange( mInternalDataChange, true );
DistributionList *distList = findIt.value();
delete distList;
}
mUidToResourceMap.remove( uid );
if ( !isLoading() ) {
mParent->addressBook()->emitAddressBookChanged();
}
}
}
DistributionList *ResourceAkonadi::Private::distListFromContactGroup( const ContactGroup &contactGroup ) const
{
DistributionList *list = new DistributionList( mParent, contactGroup.id(), contactGroup.name() );
for ( unsigned int refIndex = 0; refIndex < contactGroup.contactReferenceCount(); ++refIndex ) {
const ContactGroup::ContactReference &reference = contactGroup.contactReference( refIndex );
Addressee addressee;
Addressee::Map::const_iterator it = mParent->mAddrMap.constFind( reference.uid() );
if ( it == mParent->mAddrMap.constEnd() ) {
addressee.setUid( reference.uid() );
// TODO any way to set a good name?
} else
addressee = it.value();
// TODO how to handle ContactGroup::Reference custom fields?
list->insertEntry( addressee, reference.preferredEmail() );
}
for ( unsigned int dataIndex = 0; dataIndex < contactGroup.dataCount(); ++dataIndex ) {
const ContactGroup::Data &data = contactGroup.data( dataIndex );
Addressee addressee;
addressee.setName( data.name() );
addressee.insertEmail( data.email() );
// TODO how to handle ContactGroup::Data custom fields?
list->insertEntry( addressee );
}
return list;
}
ContactGroup ResourceAkonadi::Private::contactGroupFromDistList( const KABC::DistributionList* list ) const
{
ContactGroup contactGroup( list->name() );
contactGroup.setId( list->identifier() );
DistributionList::Entry::List entries = list->entries();
foreach ( const DistributionList::Entry &entry, entries ) {
Addressee addressee = entry.addressee();
const QString email = entry.email();
if ( addressee.isEmpty() ) {
if ( email.isEmpty() )
continue;
ContactGroup::Data data( email, email );
contactGroup.append( data );
} else {
Addressee baseAddressee = mParent->mAddrMap.value( addressee.uid() );
if ( baseAddressee.isEmpty() ) {
ContactGroup::Data data( email, email );
// TODO: transer custom fields?
contactGroup.append( data );
} else {
ContactGroup::ContactReference reference( addressee.uid() );
reference.setPreferredEmail( email );
// TODO: transer custom fields?
contactGroup.append( reference );
}
}
}
return contactGroup;
}
// kate: space-indent on; indent-width 2; replace-tabs on;

File Metadata

Mime Type
text/x-c
Expires
Fri, Nov 1, 9:20 AM (1 d, 14 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
10075755
Default Alt Text
resourceakonadi_p.cpp (17 KB)

Event Timeline