summaryrefslogtreecommitdiffstats
path: root/kresources/kolab/kabc/resourcekolab.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kresources/kolab/kabc/resourcekolab.cpp')
-rw-r--r--kresources/kolab/kabc/resourcekolab.cpp694
1 files changed, 0 insertions, 694 deletions
diff --git a/kresources/kolab/kabc/resourcekolab.cpp b/kresources/kolab/kabc/resourcekolab.cpp
deleted file mode 100644
index ce7c18c4..00000000
--- a/kresources/kolab/kabc/resourcekolab.cpp
+++ /dev/null
@@ -1,694 +0,0 @@
-/*
- 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 TDEConfig *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 TDEConfig *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( TDEConfig& config,
- const TQString& name,
- const TQString& label,
- bool writable )
-{
- TDEConfigGroup 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()
-{
- TDEConfig 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;
-
- TDEConfig 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 );
-
- TDEConfig 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()
-{
- TDEConfig 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"