|
|
|
/*
|
|
|
|
This file is part of libkabc and/or kaddressbook.
|
|
|
|
Copyright (c) 2002 - 2004 Klarälvdalens Datakonsult AB
|
|
|
|
<info@klaralvdalens-datakonsult.se>
|
|
|
|
|
|
|
|
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.
|
|
|
|
|
|
|
|
In addition, as a special exception, the copyright holders give
|
|
|
|
permission to link the code of this program with any edition of
|
|
|
|
the TQt library by Trolltech AS, Norway (or with modified versions
|
|
|
|
of TQt that use the same license as TQt), and distribute linked
|
|
|
|
combinations including the two. You must obey the GNU General
|
|
|
|
Public License in all respects for all of the code used other than
|
|
|
|
TQt. If you modify this file, you may extend this exception to
|
|
|
|
your version of the file, but you are not obligated to do so. If
|
|
|
|
you do not wish to do so, delete this exception statement from
|
|
|
|
your version.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "resourcekolab.h"
|
|
|
|
#include "contact.h"
|
|
|
|
|
|
|
|
#include <kdebug.h>
|
|
|
|
#include <kglobal.h>
|
|
|
|
#include <klocale.h>
|
|
|
|
#include <kmessagebox.h>
|
|
|
|
#include <ktempfile.h>
|
|
|
|
#include <kio/observer.h>
|
|
|
|
#include <kio/uiserver_stub.h>
|
|
|
|
#include <kabc/vcardconverter.h>
|
|
|
|
#include <kmainwindow.h>
|
|
|
|
#include <kapplication.h>
|
|
|
|
#include <dcopclient.h>
|
|
|
|
|
|
|
|
#include <tqobject.h>
|
|
|
|
#include <tqtimer.h>
|
|
|
|
#include <tqstring.h>
|
|
|
|
#include <tqfile.h>
|
|
|
|
#include <tqapplication.h>
|
|
|
|
|
|
|
|
#include <assert.h>
|
|
|
|
|
|
|
|
using namespace Kolab;
|
|
|
|
|
|
|
|
class KolabFactory : public KRES::PluginFactoryBase
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
KRES::Resource *resource( const KConfig *config )
|
|
|
|
{
|
|
|
|
return new KABC::ResourceKolab( config );
|
|
|
|
}
|
|
|
|
|
|
|
|
KRES::ConfigWidget *configWidget( TQWidget* )
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
K_EXPORT_COMPONENT_FACTORY(kabc_kolab,KolabFactory)
|
|
|
|
|
|
|
|
static const char* s_kmailContentsType = "Contact";
|
|
|
|
static const char* s_attachmentMimeTypeContact = "application/x-vnd.kolab.contact";
|
|
|
|
static const char* s_attachmentMimeTypeDistList = "application/x-vnd.kolab.contact.distlist";
|
|
|
|
static const char* s_inlineMimeType = "text/x-vcard";
|
|
|
|
|
|
|
|
KABC::ResourceKolab::ResourceKolab( const KConfig *config )
|
|
|
|
: KPIM::ResourceABC( config ),
|
|
|
|
Kolab::ResourceKolabBase( "ResourceKolab-KABC" ),
|
|
|
|
mCachedSubresource( TQString() ), mCachedSubresourceNotFound( false ), mLocked( false )
|
|
|
|
{
|
|
|
|
setType( "imap" );
|
|
|
|
if ( !config ) {
|
|
|
|
setResourceName( i18n( "Kolab Server" ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
KABC::ResourceKolab::~ResourceKolab()
|
|
|
|
{
|
|
|
|
// The resource is deleted on exit (StdAddressBook's KStaticDeleter),
|
|
|
|
// and it wasn't closed before that, so close here to save the config.
|
|
|
|
if ( isOpen() ) {
|
|
|
|
close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void KABC::ResourceKolab::loadSubResourceConfig( KConfig& config,
|
|
|
|
const TQString& name,
|
|
|
|
const TQString& label,
|
|
|
|
bool writable )
|
|
|
|
{
|
|
|
|
KConfigGroup group( &config, name );
|
|
|
|
bool active = group.readBoolEntry( "Active", true );
|
|
|
|
int completionWeight = group.readNumEntry( "CompletionWeight", 80 );
|
|
|
|
mSubResources.insert( name, Kolab::SubResource( active, writable, label,
|
|
|
|
completionWeight ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KABC::ResourceKolab::doOpen()
|
|
|
|
{
|
|
|
|
KConfig config( configFile() );
|
|
|
|
|
|
|
|
// Read the calendar entries
|
|
|
|
TQValueList<KMailICalIface::SubResource> subResources;
|
|
|
|
if ( !kmailSubresources( subResources, s_kmailContentsType ) )
|
|
|
|
return false;
|
|
|
|
mSubResources.clear();
|
|
|
|
TQValueList<KMailICalIface::SubResource>::ConstIterator it;
|
|
|
|
for ( it = subResources.begin(); it != subResources.end(); ++it ) {
|
|
|
|
loadSubResourceConfig( config, (*it).location, (*it).label, (*it).writable );
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void KABC::ResourceKolab::doClose()
|
|
|
|
{
|
|
|
|
writeConfig();
|
|
|
|
}
|
|
|
|
|
|
|
|
KABC::Ticket * KABC::ResourceKolab::requestSaveTicket()
|
|
|
|
{
|
|
|
|
if ( !addressBook() ) {
|
|
|
|
kdError() << "no addressbook" << endl;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
mLocked = true;
|
|
|
|
|
|
|
|
return createTicket( this );
|
|
|
|
}
|
|
|
|
|
|
|
|
void KABC::ResourceKolab::releaseSaveTicket( Ticket* ticket )
|
|
|
|
{
|
|
|
|
mLocked = false;
|
|
|
|
mCachedSubresource = TQString();
|
|
|
|
mCachedSubresourceNotFound = false;
|
|
|
|
delete ticket;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString KABC::ResourceKolab::loadContact( const TQString& contactData,
|
|
|
|
const TQString& subResource,
|
|
|
|
TQ_UINT32 sernum,
|
|
|
|
KMailICalIface::StorageFormat format )
|
|
|
|
{
|
|
|
|
KABC::Addressee addr;
|
|
|
|
if ( format == KMailICalIface::StorageXML ) {
|
|
|
|
Contact contact( contactData, this, subResource, sernum ); // load
|
|
|
|
contact.saveTo( &addr );
|
|
|
|
} else {
|
|
|
|
KABC::VCardConverter converter;
|
|
|
|
#if defined(KABC_VCARD_ENCODING_FIX)
|
|
|
|
addr = converter.parseVCardRaw( contactData.utf8() );
|
|
|
|
#else
|
|
|
|
addr = converter.parseVCard( contactData );
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
addr.setResource( this );
|
|
|
|
addr.setChanged( false );
|
|
|
|
KABC::Resource::insertAddressee( addr ); // same as mAddrMap.insert( addr.uid(), addr );
|
|
|
|
mUidMap[ addr.uid() ] = StorageReference( subResource, sernum );
|
|
|
|
kdDebug(5650) << "Loaded contact uid=" << addr.uid() << " sernum=" << sernum << " fullName=" << addr.name() << endl;
|
|
|
|
return addr.uid();
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct { const char* mimetype; KMailICalIface::StorageFormat format; } s_formats[] =
|
|
|
|
{
|
|
|
|
{ s_attachmentMimeTypeContact, KMailICalIface::StorageXML },
|
|
|
|
{ s_attachmentMimeTypeDistList, KMailICalIface::StorageXML },
|
|
|
|
{ s_inlineMimeType, KMailICalIface::StorageIcalVcard }
|
|
|
|
};
|
|
|
|
|
|
|
|
bool KABC::ResourceKolab::loadSubResource( const TQString& subResource )
|
|
|
|
{
|
|
|
|
int count = 0;
|
|
|
|
if ( !kmailIncidencesCount( count, TQString(), subResource ) ) {
|
|
|
|
kdError() << "Communication problem in KABC::ResourceKolab::loadSubResource()\n";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if ( !count )
|
|
|
|
return true;
|
|
|
|
|
|
|
|
// Read that many contacts at a time.
|
|
|
|
// If this number is too small we lose time in kmail.
|
|
|
|
// If it's too big the progressbar is jumpy.
|
|
|
|
const int nbMessages = 200;
|
|
|
|
|
|
|
|
(void)Observer::self(); // ensure kio_uiserver is running
|
|
|
|
UIServer_stub uiserver( "kio_uiserver", "UIServer" );
|
|
|
|
int progressId = 0;
|
|
|
|
if ( count > 200 ) {
|
|
|
|
progressId = uiserver.newJob( kapp->dcopClient()->appId(), true );
|
|
|
|
uiserver.totalFiles( progressId, count );
|
|
|
|
uiserver.infoMessage( progressId, i18n( "Loading contacts..." ) );
|
|
|
|
uiserver.transferring( progressId, "Contacts" );
|
|
|
|
}
|
|
|
|
|
|
|
|
for ( int startIndex = 0; startIndex < count; startIndex += nbMessages ) {
|
|
|
|
|
|
|
|
// TODO it would be faster to pass the s_formats array to kmail and let it load
|
|
|
|
// all events - to avoid loading each mail 3 times. But then we need to extend the returned
|
|
|
|
// TQMap to also tell us the StorageFormat of each found contact...
|
|
|
|
for ( int indexFormat = 0; indexFormat < 3; ++indexFormat ) {
|
|
|
|
const char* mimetype = s_formats[indexFormat].mimetype;
|
|
|
|
KMailICalIface::StorageFormat format = s_formats[indexFormat].format;
|
|
|
|
TQMap<TQ_UINT32, TQString> lst;
|
|
|
|
if ( !kmailIncidences( lst, mimetype, subResource, startIndex, nbMessages ) ) {
|
|
|
|
kdError() << "Communication problem in KABC::ResourceKolab::loadSubResource()\n";
|
|
|
|
if ( progressId )
|
|
|
|
uiserver.jobFinished( progressId );
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
for( TQMap<TQ_UINT32, TQString>::ConstIterator it = lst.begin(); it != lst.end(); ++it ) {
|
|
|
|
loadContact( it.data(), subResource, it.key(), format );
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
if ( progressId ) {
|
|
|
|
uiserver.processedFiles( progressId, startIndex );
|
|
|
|
uiserver.percent( progressId, 100 * startIndex / count );
|
|
|
|
}
|
|
|
|
|
|
|
|
// if ( progress.wasCanceled() ) {
|
|
|
|
// uiserver.jobFinished( progressId );
|
|
|
|
// return false;
|
|
|
|
// }
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
kdDebug(5650) << "Contacts kolab resource: got " << count << " contacts in " << subResource << endl;
|
|
|
|
|
|
|
|
if ( progressId )
|
|
|
|
uiserver.jobFinished( progressId );
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KABC::ResourceKolab::load()
|
|
|
|
{
|
|
|
|
mUidMap.clear();
|
|
|
|
mAddrMap.clear();
|
|
|
|
|
|
|
|
bool rc = true;
|
|
|
|
Kolab::ResourceMap::ConstIterator itR;
|
|
|
|
for ( itR = mSubResources.begin(); itR != mSubResources.end(); ++itR ) {
|
|
|
|
if ( !itR.data().active() )
|
|
|
|
// This resource is disabled
|
|
|
|
continue;
|
|
|
|
|
|
|
|
rc &= loadSubResource( itR.key() );
|
|
|
|
}
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KABC::ResourceKolab::save( Ticket* )
|
|
|
|
{
|
|
|
|
bool rc = true;
|
|
|
|
|
|
|
|
for( ConstIterator it = begin(); it != end(); ++it )
|
|
|
|
if( (*it).changed() ) {
|
|
|
|
rc &= kmailUpdateAddressee( *it );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( !rc )
|
|
|
|
kdDebug(5650) << k_funcinfo << " failed." << endl;
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace Kolab {
|
|
|
|
struct AttachmentList {
|
|
|
|
TQStringList attachmentURLs;
|
|
|
|
TQStringList attachmentNames;
|
|
|
|
TQStringList attachmentMimeTypes;
|
|
|
|
TQStringList deletedAttachments;
|
|
|
|
TQValueList<KTempFile *> tempFiles;
|
|
|
|
|
|
|
|
void addAttachment( const TQString& url, const TQString& name, const TQString& mimetype ) {
|
|
|
|
attachmentURLs.append( url );
|
|
|
|
attachmentNames.append( name );
|
|
|
|
attachmentMimeTypes.append( mimetype );
|
|
|
|
}
|
|
|
|
|
|
|
|
void updatePictureAttachment( const TQImage& image, const TQString& name );
|
|
|
|
void updateAttachment( const TQByteArray& data, const TQString& name, const char* mimetype );
|
|
|
|
};
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
void AttachmentList::updatePictureAttachment( const TQImage& image, const TQString& name )
|
|
|
|
{
|
|
|
|
assert( !name.isEmpty() );
|
|
|
|
if ( !image.isNull() ) {
|
|
|
|
KTempFile tempFile;
|
|
|
|
image.save( tempFile.file(), "PNG" );
|
|
|
|
tempFile.close();
|
|
|
|
KURL url;
|
|
|
|
url.setPath( tempFile.name() );
|
|
|
|
kdDebug(5650) << "picture saved to " << url.path() << endl;
|
|
|
|
addAttachment( url.url(), name, "image/png" );
|
|
|
|
} else {
|
|
|
|
deletedAttachments.append( name );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void AttachmentList::updateAttachment( const TQByteArray& data, const TQString& name, const char* mimetype )
|
|
|
|
{
|
|
|
|
assert( !name.isEmpty() );
|
|
|
|
if ( !data.isNull() ) {
|
|
|
|
KTempFile tempFile;
|
|
|
|
tempFile.file()->writeBlock( data );
|
|
|
|
tempFile.close();
|
|
|
|
KURL url;
|
|
|
|
url.setPath( tempFile.name() );
|
|
|
|
kdDebug(5650) << "data saved to " << url.path() << endl;
|
|
|
|
addAttachment( url.url(), name, mimetype );
|
|
|
|
} else {
|
|
|
|
deletedAttachments.append( name );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KABC::ResourceKolab::kmailUpdateAddressee( const Addressee& addr )
|
|
|
|
{
|
|
|
|
const TQString uid = addr.uid();
|
|
|
|
TQString subResource;
|
|
|
|
TQ_UINT32 sernum;
|
|
|
|
if ( mUidMap.find( uid ) != mUidMap.end() ) {
|
|
|
|
subResource = mUidMap[ uid ].resource();
|
|
|
|
if ( !subresourceWritable( subResource ) ) {
|
|
|
|
kdWarning() << "Wow! Something tried to update a non-writable addressee! Fix this caller: " << kdBacktrace() << endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
sernum = mUidMap[ uid ].serialNumber();
|
|
|
|
} else {
|
|
|
|
if ( !mCachedSubresource.isNull() || mCachedSubresourceNotFound ) {
|
|
|
|
subResource = mCachedSubresource;
|
|
|
|
} else {
|
|
|
|
subResource = findWritableResource( Kolab::Contacts, mSubResources );
|
|
|
|
// We were locked, remember the subresource we are working with until
|
|
|
|
// we are unlocked
|
|
|
|
if ( mLocked ) {
|
|
|
|
mCachedSubresource = subResource;
|
|
|
|
|
|
|
|
// If the subresource is empty here, it means findWritableResource() failed, for example
|
|
|
|
// because the user cancelled the resource selection dialog. Remember that, so we avoid
|
|
|
|
// asking multiple times when locked.
|
|
|
|
mCachedSubresourceNotFound = subResource.isEmpty();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( subResource.isEmpty() )
|
|
|
|
return false;
|
|
|
|
sernum = 0;
|
|
|
|
}
|
|
|
|
TQString data;
|
|
|
|
TQString mimetype;
|
|
|
|
AttachmentList att;
|
|
|
|
bool isXMLStorageFormat = kmailStorageFormat( subResource ) == KMailICalIface::StorageXML;
|
|
|
|
TQString subject = uid; // as per kolab2 spec
|
|
|
|
if ( isXMLStorageFormat ) {
|
|
|
|
Contact contact( &addr );
|
|
|
|
// The addressee is converted to: 1) the xml 2) the optional picture 3) the optional logo 4) the optional sound
|
|
|
|
data = contact.saveXML();
|
|
|
|
att.updatePictureAttachment( contact.picture(), contact.pictureAttachmentName() );
|
|
|
|
att.updatePictureAttachment( contact.logo(), contact.logoAttachmentName() );
|
|
|
|
// no way to know the mimetype. The addressee editor allows to attach _any_ kind of file,
|
|
|
|
// and the sound system sorts it out.
|
|
|
|
att.updateAttachment( contact.sound(), contact.soundAttachmentName(), "audio/unknown" );
|
|
|
|
mimetype = contact.isDistributionList() ?
|
|
|
|
s_attachmentMimeTypeDistList : s_attachmentMimeTypeContact;
|
|
|
|
} else {
|
|
|
|
mimetype = s_inlineMimeType;
|
|
|
|
KABC::VCardConverter converter;
|
|
|
|
#if defined(KABC_VCARD_ENCODING_FIX)
|
|
|
|
data = TQString::fromUtf8( converter.createVCardRaw( addr ) );
|
|
|
|
#else
|
|
|
|
data = converter.createVCard( addr );
|
|
|
|
#endif
|
|
|
|
subject.prepend( "vCard " ); // as per kolab1 spec
|
|
|
|
}
|
|
|
|
bool rc = kmailUpdate( subResource, sernum, data, mimetype, subject,
|
|
|
|
CustomHeaderMap(),
|
|
|
|
att.attachmentURLs, att.attachmentMimeTypes, att.attachmentNames,
|
|
|
|
att.deletedAttachments );
|
|
|
|
if ( !rc )
|
|
|
|
kdDebug(5650) << "kmailUpdate returned false!" << endl;
|
|
|
|
if ( rc ) {
|
|
|
|
kdDebug(5650) << "kmailUpdate returned, now sernum=" << sernum << " for uid=" << uid << endl;
|
|
|
|
mUidMap[ uid ] = StorageReference( subResource, sernum );
|
|
|
|
// This is ugly, but it's faster than doing
|
|
|
|
// mAddrMap.find(addr.uid()), which would give the same :-(
|
|
|
|
// Reason for this: The Changed attribute of Addressee should
|
|
|
|
// be mutable
|
|
|
|
const_cast<Addressee&>(addr).setChanged( false );
|
|
|
|
}
|
|
|
|
|
|
|
|
for( TQValueList<KTempFile *>::Iterator it = att.tempFiles.begin(); it != att.tempFiles.end(); ++it ) {
|
|
|
|
(*it)->setAutoDelete( true );
|
|
|
|
delete (*it);
|
|
|
|
}
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
void KABC::ResourceKolab::insertAddressee( const Addressee& addr )
|
|
|
|
{
|
|
|
|
const TQString uid = addr.uid();
|
|
|
|
//kdDebug(5650) << k_funcinfo << uid << endl;
|
|
|
|
bool ok = false;
|
|
|
|
if ( mUidMap.contains( uid ) ) {
|
|
|
|
mUidsPendingUpdate.append( uid );
|
|
|
|
} else {
|
|
|
|
mUidsPendingAdding.append( uid );
|
|
|
|
}
|
|
|
|
|
|
|
|
ok = kmailUpdateAddressee( addr );
|
|
|
|
|
|
|
|
if ( ok )
|
|
|
|
Resource::insertAddressee( addr );
|
|
|
|
}
|
|
|
|
|
|
|
|
void KABC::ResourceKolab::removeAddressee( const Addressee& addr )
|
|
|
|
{
|
|
|
|
const TQString uid = addr.uid();
|
|
|
|
if ( mUidMap.find( uid ) == mUidMap.end() ) return;
|
|
|
|
//kdDebug(5650) << k_funcinfo << uid << endl;
|
|
|
|
const TQString resource = mUidMap[ uid ].resource();
|
|
|
|
if ( !subresourceWritable( resource ) ) {
|
|
|
|
kdWarning() << "Wow! Something tried to delete a non-writable addressee! Fix this caller: " << kdBacktrace() << endl;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
/* The user told us to delete, tell KMail */
|
|
|
|
kmailDeleteIncidence( resource,
|
|
|
|
mUidMap[ uid ].serialNumber() );
|
|
|
|
mUidsPendingDeletion.append( uid );
|
|
|
|
mUidMap.remove( uid );
|
|
|
|
|
|
|
|
Resource::removeAddressee( addr );
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* These are the DCOP slots that KMail call to notify when something
|
|
|
|
* changed.
|
|
|
|
*/
|
|
|
|
bool KABC::ResourceKolab::fromKMailAddIncidence( const TQString& type,
|
|
|
|
const TQString& subResource,
|
|
|
|
TQ_UINT32 sernum,
|
|
|
|
int format,
|
|
|
|
const TQString& contactXML )
|
|
|
|
{
|
|
|
|
// Check if this is a contact
|
|
|
|
if( type != s_kmailContentsType || !subresourceActive( subResource ) )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// Load contact to find the UID
|
|
|
|
const TQString uid = loadContact( contactXML, subResource, sernum,
|
|
|
|
( KMailICalIface::StorageFormat )format );
|
|
|
|
|
|
|
|
//kdDebug(5650) << k_funcinfo << uid << endl;
|
|
|
|
|
|
|
|
// Emit "addressbook changed" if this comes from kmail and not from the GUI
|
|
|
|
if ( !mUidsPendingAdding.contains( uid )
|
|
|
|
&& !mUidsPendingUpdate.contains( uid ) ) {
|
|
|
|
addressBook()->emitAddressBookChanged();
|
|
|
|
} else {
|
|
|
|
mUidsPendingAdding.remove( uid );
|
|
|
|
mUidsPendingUpdate.remove( uid );
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void KABC::ResourceKolab::fromKMailDelIncidence( const TQString& type,
|
|
|
|
const TQString& subResource,
|
|
|
|
const TQString& uid )
|
|
|
|
{
|
|
|
|
// Check if this is a contact
|
|
|
|
if( type != s_kmailContentsType || !subresourceActive( subResource ) )
|
|
|
|
return;
|
|
|
|
|
|
|
|
//kdDebug(5650) << k_funcinfo << uid << endl;
|
|
|
|
|
|
|
|
// Can't be in both, by contract
|
|
|
|
if ( mUidsPendingDeletion.contains( uid ) ) {
|
|
|
|
mUidsPendingDeletion.remove( uid );
|
|
|
|
} else if ( mUidsPendingUpdate.contains( uid ) ) {
|
|
|
|
// It's good to know if was deleted, but we are waiting on a new one to
|
|
|
|
// replace it, so let's just sit tight.
|
|
|
|
} else {
|
|
|
|
// We didn't trigger this, so KMail did, remove the reference to the uid
|
|
|
|
mAddrMap.remove( uid );
|
|
|
|
mUidMap.remove( uid );
|
|
|
|
addressBook()->emitAddressBookChanged();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void KABC::ResourceKolab::fromKMailRefresh( const TQString& type,
|
|
|
|
const TQString& /*subResource*/ )
|
|
|
|
{
|
|
|
|
// Check if this is a contact
|
|
|
|
if( type != s_kmailContentsType ) return;
|
|
|
|
|
|
|
|
//kdDebug(5650) << k_funcinfo << endl;
|
|
|
|
|
|
|
|
load(); // ### should call loadSubResource(subResource) probably
|
|
|
|
addressBook()->emitAddressBookChanged();
|
|
|
|
}
|
|
|
|
|
|
|
|
void KABC::ResourceKolab::fromKMailAddSubresource( const TQString& type,
|
|
|
|
const TQString& subResource,
|
|
|
|
const TQString& label,
|
|
|
|
bool writable,
|
|
|
|
bool )
|
|
|
|
{
|
|
|
|
if( type != s_kmailContentsType ) return;
|
|
|
|
|
|
|
|
if ( mSubResources.contains( subResource ) )
|
|
|
|
// Already registered
|
|
|
|
return;
|
|
|
|
|
|
|
|
KConfig config( configFile() );
|
|
|
|
config.setGroup( "Contact" );
|
|
|
|
loadSubResourceConfig( config, subResource, label, writable );
|
|
|
|
loadSubResource( subResource );
|
|
|
|
addressBook()->emitAddressBookChanged();
|
|
|
|
emit signalSubresourceAdded( this, type, subResource );
|
|
|
|
}
|
|
|
|
|
|
|
|
void KABC::ResourceKolab::fromKMailDelSubresource( const TQString& type,
|
|
|
|
const TQString& subResource )
|
|
|
|
{
|
|
|
|
if( type != s_kmailContentsType ) return;
|
|
|
|
|
|
|
|
if ( !mSubResources.contains( subResource ) )
|
|
|
|
// Not registered
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Ok, it's our job, and we have it here
|
|
|
|
mSubResources.erase( subResource );
|
|
|
|
|
|
|
|
KConfig config( configFile() );
|
|
|
|
config.deleteGroup( subResource );
|
|
|
|
config.sync();
|
|
|
|
|
|
|
|
// Make a list of all uids to remove
|
|
|
|
Kolab::UidMap::ConstIterator mapIt;
|
|
|
|
TQStringList uids;
|
|
|
|
for ( mapIt = mUidMap.begin(); mapIt != mUidMap.end(); ++mapIt )
|
|
|
|
if ( mapIt.data().resource() == subResource )
|
|
|
|
// We have a match
|
|
|
|
uids << mapIt.key();
|
|
|
|
|
|
|
|
// Finally delete all the incidences
|
|
|
|
if ( !uids.isEmpty() ) {
|
|
|
|
TQStringList::ConstIterator it;
|
|
|
|
for ( it = uids.begin(); it != uids.end(); ++it ) {
|
|
|
|
mAddrMap.remove( *it );
|
|
|
|
mUidMap.remove( *it );
|
|
|
|
}
|
|
|
|
|
|
|
|
addressBook()->emitAddressBookChanged();
|
|
|
|
}
|
|
|
|
|
|
|
|
emit signalSubresourceRemoved( this, type, subResource );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void KABC::ResourceKolab::fromKMailAsyncLoadResult( const TQMap<TQ_UINT32, TQString>& map,
|
|
|
|
const TQString& /* type */,
|
|
|
|
const TQString& folder )
|
|
|
|
{
|
|
|
|
// FIXME
|
|
|
|
KMailICalIface::StorageFormat format = KMailICalIface::StorageXML;
|
|
|
|
for( TQMap<TQ_UINT32, TQString>::ConstIterator it = map.begin(); it != map.end(); ++it ) {
|
|
|
|
loadContact( it.data(), folder, it.key(), format );
|
|
|
|
}
|
|
|
|
if ( !addressBook() ){
|
|
|
|
kdDebug(5650) << "asyncLoadResult() : addressBook() returning NULL pointer.\n";
|
|
|
|
}else
|
|
|
|
addressBook()->emitAddressBookChanged();
|
|
|
|
}
|
|
|
|
|
|
|
|
TQStringList KABC::ResourceKolab::subresources() const
|
|
|
|
{
|
|
|
|
return mSubResources.keys();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KABC::ResourceKolab::subresourceActive( const TQString& subresource ) const
|
|
|
|
{
|
|
|
|
if ( mSubResources.contains( subresource ) ) {
|
|
|
|
return mSubResources[ subresource ].active();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Safe default bet:
|
|
|
|
kdDebug(5650) << "subresourceActive( " << subresource << " ): Safe bet\n";
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KABC::ResourceKolab::subresourceWritable( const TQString& subresource ) const
|
|
|
|
{
|
|
|
|
if ( mSubResources.contains( subresource ) ) {
|
|
|
|
return mSubResources[ subresource ].writable();
|
|
|
|
}
|
|
|
|
return false; //better a safe default
|
|
|
|
}
|
|
|
|
|
|
|
|
int KABC::ResourceKolab::subresourceCompletionWeight( const TQString& subresource ) const
|
|
|
|
{
|
|
|
|
if ( mSubResources.contains( subresource ) ) {
|
|
|
|
return mSubResources[ subresource ].completionWeight();
|
|
|
|
}
|
|
|
|
|
|
|
|
kdDebug(5650) << "subresourceCompletionWeight( " << subresource << " ): not found, using default\n";
|
|
|
|
|
|
|
|
return 80;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString KABC::ResourceKolab::subresourceLabel( const TQString& subresource ) const
|
|
|
|
{
|
|
|
|
if ( mSubResources.contains( subresource ) ) {
|
|
|
|
return mSubResources[ subresource ].label();
|
|
|
|
}
|
|
|
|
|
|
|
|
kdDebug(5650) << "subresourceLabel( " << subresource << " ): not found!\n";
|
|
|
|
return TQString();
|
|
|
|
}
|
|
|
|
|
|
|
|
void KABC::ResourceKolab::setSubresourceCompletionWeight( const TQString& subresource, int completionWeight )
|
|
|
|
{
|
|
|
|
if ( mSubResources.contains( subresource ) ) {
|
|
|
|
mSubResources[ subresource ].setCompletionWeight( completionWeight );
|
|
|
|
} else {
|
|
|
|
kdDebug(5650) << "setSubresourceCompletionWeight: subresource " << subresource << " not found" << endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TQMap<TQString, TQString> KABC::ResourceKolab::uidToResourceMap() const
|
|
|
|
{
|
|
|
|
// TODO: Couldn't this be made simpler?
|
|
|
|
TQMap<TQString, TQString> map;
|
|
|
|
Kolab::UidMap::ConstIterator mapIt;
|
|
|
|
for ( mapIt = mUidMap.begin(); mapIt != mUidMap.end(); ++mapIt )
|
|
|
|
map[ mapIt.key() ] = mapIt.data().resource();
|
|
|
|
return map;
|
|
|
|
}
|
|
|
|
|
|
|
|
void KABC::ResourceKolab::setSubresourceActive( const TQString &subresource, bool active )
|
|
|
|
{
|
|
|
|
if ( mSubResources.contains( subresource ) ) {
|
|
|
|
mSubResources[ subresource ].setActive( active );
|
|
|
|
load();
|
|
|
|
} else {
|
|
|
|
kdDebug(5650) << "setSubresourceCompletionWeight: subresource " << subresource << " not found" << endl;
|
|
|
|
}
|
|
|
|
writeConfig();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*virtual*/
|
|
|
|
bool KABC::ResourceKolab::addSubresource( const TQString& label, const TQString& parent )
|
|
|
|
{
|
|
|
|
return kmailAddSubresource( label, parent, s_kmailContentsType );
|
|
|
|
}
|
|
|
|
|
|
|
|
/*virtual*/
|
|
|
|
bool KABC::ResourceKolab::removeSubresource( const TQString& id )
|
|
|
|
{
|
|
|
|
return kmailRemoveSubresource( id );
|
|
|
|
}
|
|
|
|
|
|
|
|
void KABC::ResourceKolab::writeConfig()
|
|
|
|
{
|
|
|
|
KConfig config( configFile() );
|
|
|
|
|
|
|
|
Kolab::ResourceMap::ConstIterator it;
|
|
|
|
for ( it = mSubResources.constBegin(); it != mSubResources.constEnd(); ++it ) {
|
|
|
|
config.setGroup( it.key() );
|
|
|
|
config.writeEntry( "Active", it.data().active() );
|
|
|
|
config.writeEntry( "CompletionWeight", it.data().completionWeight() );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#include "resourcekolab.moc"
|