diff options
Diffstat (limited to 'tderesources/kolab/kabc/resourcekolab.cpp')
-rw-r--r-- | tderesources/kolab/kabc/resourcekolab.cpp | 694 |
1 files changed, 0 insertions, 694 deletions
diff --git a/tderesources/kolab/kabc/resourcekolab.cpp b/tderesources/kolab/kabc/resourcekolab.cpp deleted file mode 100644 index 226d7da89..000000000 --- a/tderesources/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 <tdeglobal.h> -#include <tdelocale.h> -#include <tdemessagebox.h> -#include <tdetempfile.h> -#include <tdeio/observer.h> -#include <tdeio/uiserver_stub.h> -#include <tdeabc/vcardconverter.h> -#include <tdemainwindow.h> -#include <tdeapplication.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(tdeabc_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 tdeio_uiserver is running - UIServer_stub uiserver( "tdeio_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" |