39 #include "kmailicalifaceimpl.h"
41 #include "kmfoldertree.h"
42 #include "kmfolderdir.h"
43 #include "kmgroupware.h"
44 #include "kmfoldermgr.h"
45 #include "kmcommands.h"
46 #include "kmfolderindex.h"
47 #include "kmmsgdict.h"
48 #include "kmmsgpart.h"
50 #include "kmfolderimap.h"
51 #include "globalsettings.h"
52 #include "accountmanager.h"
53 #include "kmfoldercachedimap.h"
54 #include "kmacctcachedimap.h"
59 #include <mimelib/enum.h>
60 #include <mimelib/utility.h>
61 #include <mimelib/body.h>
62 #include <mimelib/mimepp.h>
66 #include <tqtextcodec.h>
69 #include <kiconloader.h>
70 #include <kinputdialog.h>
71 #include <dcopclient.h>
72 #include <tdemessagebox.h>
73 #include <tdeconfig.h>
75 #include <tdetempfile.h>
77 using namespace KMail;
79 TQMap<TQString, TQString> *KMailICalIfaceImpl::mSubResourceUINamesMap =
new TQMap<TQString, TQString>;
82 static void vPartMicroParser(
const TQString& str, TQString& s );
83 static void reloadFolderTree();
87 const char* contentsTypeStr;
89 KFolderTreeItem::Type treeItemType;
90 const char* annotation;
91 const char* translatedName;
92 } s_folderContentsType[] = {
93 {
"Mail",
"application/x-vnd.kolab.mail", KFolderTreeItem::Other,
"mail", I18N_NOOP(
"Mail" ) },
94 {
"Calendar",
"application/x-vnd.kolab.event", KFolderTreeItem::Calendar,
"event", I18N_NOOP(
"Calendar" ) },
95 {
"Contact",
"application/x-vnd.kolab.contact", KFolderTreeItem::Contacts,
"contact", I18N_NOOP(
"Contacts" ) },
96 {
"Note",
"application/x-vnd.kolab.note", KFolderTreeItem::Notes,
"note", I18N_NOOP(
"Notes" ) },
97 {
"Task",
"application/x-vnd.kolab.task", KFolderTreeItem::Tasks,
"task", I18N_NOOP(
"Tasks" ) },
98 {
"Journal",
"application/x-vnd.kolab.journal", KFolderTreeItem::Journals,
"journal", I18N_NOOP(
"Journal" ) }
101 static TQString folderContentsType( KMail::FolderContentsType type )
103 return s_folderContentsType[type].contentsTypeStr;
106 static TQString folderKolabMimeType( KMail::FolderContentsType type )
108 return s_folderContentsType[type].mimetype;
111 KMailICalIfaceImpl::StorageFormat KMailICalIfaceImpl::globalStorageFormat()
const {
112 return GlobalSettings::self()->theIMAPResourceStorageFormat()
113 == GlobalSettings::EnumTheIMAPResourceStorageFormat::XML ? StorageXML : StorageIcalVcard;
116 static KMail::FolderContentsType folderContentsType(
const TQString& type )
118 for ( uint i = 0 ; i <
sizeof s_folderContentsType /
sizeof *s_folderContentsType; ++i )
119 if ( type == s_folderContentsType[i].contentsTypeStr )
120 return static_cast<KMail::FolderContentsType
>( i );
121 return KMail::ContentsTypeMail;
124 static TQString localizedDefaultFolderName( KMail::FolderContentsType type )
126 return i18n( s_folderContentsType[type].translatedName );
129 const char* KMailICalIfaceImpl::annotationForContentsType( KMail::FolderContentsType type )
131 return s_folderContentsType[type].annotation;
134 ExtraFolder::ExtraFolder(
KMFolder* f )
137 folder->open(
"kmailicaliface::extrafolder");
140 ExtraFolder::~ExtraFolder()
143 folder->close(
"kmailicaliface::extrafolder");
157 KMailICalIfaceImpl::KMailICalIfaceImpl()
158 : DCOPObject(
"KMailICalIface" ), TQObject( 0,
"KMailICalIfaceImpl" ),
159 mContacts( 0 ), mCalendar( 0 ), mNotes( 0 ), mTasks( 0 ), mJournals( 0 ),
160 mFolderLanguage( 0 ), mFolderParentDir( 0 ), mFolderType( KMFolderTypeUnknown ),
161 mUseResourceIMAP( false ), mResourceQuiet( false ), mHideFolders( true )
164 connect( kmkernel, TQ_SIGNAL( configChanged() ),
this, TQ_SLOT( readConfig() ) );
165 connect( kmkernel, TQ_SIGNAL( folderRemoved(
KMFolder* ) ),
166 this, TQ_SLOT( slotFolderRemoved(
KMFolder* ) ) );
168 mExtraFolders.setAutoDelete(
true );
169 mAccumulators.setAutoDelete(
true );
178 static DwBodyPart* findBodyPartByMimeType(
const KMMessage& msg,
const char* sType,
const char* sSubtype,
bool startsWith =
false )
186 if ( part->hasHeaders() ) {
187 DwMediaType& contentType = part->Headers().ContentType();
189 if ( contentType.TypeStr() == sType
190 && TQString( contentType.SubtypeStr().c_str() ).startsWith( sSubtype ) )
194 if ( contentType.TypeStr() == sType
195 && contentType.SubtypeStr() == sSubtype )
204 static DwBodyPart* findBodyPart(
const KMMessage& msg,
const TQString& attachmentName )
210 if ( part->hasHeaders()
211 && attachmentName == part->Headers().ContentDisposition().Filename().c_str() )
213 if ( part->hasHeaders() && attachmentName == part->Headers().ContentType().Name().c_str() )
220 static void debugBodyParts(
const char* foo,
const KMMessage& msg )
222 kdDebug(5006) <<
"--debugBodyParts " << foo <<
"--" << endl;
224 if ( part->hasHeaders() ) {
225 kdDebug(5006) <<
" bodypart: " << part << endl;
226 kdDebug(5006) <<
" " << part->Headers().AsString().c_str() << endl;
229 kdDebug(5006) <<
" part " << part <<
" has no headers" << endl;
233 inline static void debugBodyParts(
const char*,
const KMMessage& ) {}
241 bool KMailICalIfaceImpl::updateAttachment(
KMMessage& msg,
242 const TQString& attachmentURL,
243 const TQString& attachmentName,
244 const TQString& attachmentMimetype,
247 kdDebug(5006) <<
"KMailICalIfaceImpl::updateAttachment( " << attachmentURL <<
" )" << endl;
251 KURL url( attachmentURL );
252 if ( url.isValid() && url.isLocalFile() ) {
253 const TQString fileName( url.path() );
254 TQFile file( fileName );
255 if( file.open( IO_ReadOnly ) ) {
256 TQByteArray rawData = file.readAll();
260 KMMessagePart msgPart;
261 msgPart.setName( attachmentName );
263 const int iSlash = attachmentMimetype.find(
'/');
264 const TQCString sType = attachmentMimetype.left( iSlash ).latin1();
265 const TQCString sSubtype = attachmentMimetype.mid( iSlash+1 ).latin1();
266 msgPart.setTypeStr( sType );
267 msgPart.setSubtypeStr( sSubtype );
268 TQCString ctd(
"attachment;\n filename=\"");
269 ctd.append( attachmentName.latin1() );
271 msgPart.setContentDisposition( ctd );
272 TQValueList<int> dummy;
273 msgPart.setBodyAndGuessCte( rawData, dummy );
274 msgPart.setPartSpecifier( fileName );
280 newPart->Headers().ContentDisposition().Parse();
282 DwBodyPart* part = lookupByName ? findBodyPart( msg, attachmentName )
283 : findBodyPartByMimeType( msg, sType, sSubtype );
287 newPart->SetNext( part->Next() );
293 kdDebug(5006) <<
"Attachment " << attachmentName <<
" updated." << endl;
296 kdDebug(5006) <<
"Attachment " << attachmentName <<
" added." << endl;
300 kdDebug(5006) <<
"Attachment " << attachmentURL <<
" can not be read." << endl;
303 kdDebug(5006) <<
"Attachment " << attachmentURL <<
" not a local file." << endl;
310 bool KMailICalIfaceImpl::kolabXMLFoundAndDecoded(
const KMMessage& msg,
const TQString& mimetype, TQString& s )
312 const int iSlash = mimetype.find(
'/');
313 const TQCString sType = mimetype.left( iSlash ).latin1();
314 const TQCString sSubtype = mimetype.mid( iSlash+1 ).latin1();
315 DwBodyPart* part = findBodyPartByMimeType( msg, sType, sSubtype,
true );
317 KMMessagePart msgPart;
319 s = msgPart.bodyToUnicode( TQTextCodec::codecForName(
"utf8" ) );
331 bool KMailICalIfaceImpl::deleteAttachment(
KMMessage& msg,
332 const TQString& attachmentName )
334 kdDebug(5006) <<
"KMailICalIfaceImpl::deleteAttachment( " << attachmentName <<
" )" << endl;
340 DwBodyPart* part = findBodyPart( msg, attachmentName );
342 msg.getTopLevelPart()->Body().RemoveBodyPart( part );
345 kdDebug(5006) <<
"Attachment deleted." << endl;
350 kdDebug(5006) <<
"Attachment " << attachmentName <<
" not found." << endl;
356 static void setIcalVcardContentTypeHeader(
KMMessage *msg, KMail::FolderContentsType t,
KMFolder *folder )
358 KMAcctCachedImap::GroupwareType groupwareType = KMAcctCachedImap::GroupwareKolab;
360 KMFolderCachedImap *imapFolder =
dynamic_cast<KMFolderCachedImap*
>( folder->storage() );
362 groupwareType = imapFolder->account()->groupwareType();
364 msg->setType( DwMime::kTypeText );
365 if ( t == KMail::ContentsTypeCalendar || t == KMail::ContentsTypeTask
366 || t == KMail::ContentsTypeJournal ) {
367 msg->setSubtype( DwMime::kSubtypeVCal );
369 if ( groupwareType == KMAcctCachedImap::GroupwareKolab )
371 "text/calendar; method=REQUEST; charset=\"utf-8\"");
372 else if ( groupwareType == KMAcctCachedImap::GroupwareScalix )
374 "text/calendar; method=PUBLISH; charset=\"UTF-8\"");
376 }
else if ( t == KMail::ContentsTypeContact ) {
377 msg->setSubtype( DwMime::kSubtypeXVCard );
378 if ( groupwareType == KMAcctCachedImap::GroupwareKolab )
379 msg->
setHeaderField(
"Content-Type",
"Text/X-VCard; charset=\"utf-8\"" );
380 else if ( groupwareType == KMAcctCachedImap::GroupwareScalix )
381 msg->
setHeaderField(
"Content-Type",
"application/scalix-properties; charset=\"UTF-8\"" );
383 kdWarning(5006) << k_funcinfo <<
"Attempt to write non-groupware contents to folder" << endl;
387 static void setXMLContentTypeHeader(
KMMessage *msg,
const TQString plainTextBody )
392 KMMessagePart firstPart;
393 firstPart.setType( DwMime::kTypeText );
394 firstPart.setSubtype( DwMime::kSubtypePlain );
396 msg->setType( DwMime::kTypeMultipart );
397 msg->setSubtype( DwMime::kSubtypeMixed );
398 msg->
headers().ContentType().CreateBoundary( 0 );
399 msg->
headers().ContentType().Assemble();
400 firstPart.setBodyFromUnicode( plainTextBody );
405 TQ_UINT32 KMailICalIfaceImpl::addIncidenceKolab(
KMFolder& folder,
406 const TQString& subject,
407 const TQString& plainTextBody,
408 const TQMap<TQCString, TQString>& customHeaders,
409 const TQStringList& attachmentURLs,
410 const TQStringList& attachmentNames,
411 const TQStringList& attachmentMimetypes )
413 kdDebug(5006) <<
"KMailICalIfaceImpl::addIncidenceKolab( " << attachmentNames <<
" )" << endl;
415 TQ_UINT32 sernum = 0;
416 bool bAttachOK =
true;
421 msg->setSubject( subject );
424 TQMap<TQCString, TQString>::ConstIterator ith = customHeaders.begin();
425 const TQMap<TQCString, TQString>::ConstIterator ithEnd = customHeaders.end();
426 for ( ; ith != ithEnd ; ++ith ) {
431 if ( storageFormat( &folder ) == StorageXML ) {
432 setXMLContentTypeHeader( msg, plainTextBody );
433 }
else if ( storageFormat( &folder ) == StorageIcalVcard ) {
434 const KMail::FolderContentsType t = folder.storage()->
contentsType();
435 setIcalVcardContentTypeHeader( msg, t, &folder );
438 kdWarning(5006) << k_funcinfo <<
"Attempt to write to folder with unknown storage type" << endl;
441 Q_ASSERT( attachmentMimetypes.count() == attachmentURLs.count() );
442 Q_ASSERT( attachmentNames.count() == attachmentURLs.count() );
444 TQStringList::ConstIterator itmime = attachmentMimetypes.begin();
445 TQStringList::ConstIterator iturl = attachmentURLs.begin();
446 for( TQStringList::ConstIterator itname = attachmentNames.begin();
447 itname != attachmentNames.end()
448 && itmime != attachmentMimetypes.end()
449 && iturl != attachmentURLs.end();
450 ++itname, ++iturl, ++itmime ){
451 bool byname = !(*itmime).startsWith(
"application/x-vnd.kolab." );
452 if( !updateAttachment( *msg, *iturl, *itname, *itmime, byname ) ){
453 kdWarning(5006) <<
"Attachment error, can not add Incidence." << endl;
464 if ( folder.
addMsg( msg ) == 0 )
466 sernum = msg->getMsgSerNum();
467 kdDebug(5006) <<
"addIncidenceKolab(): Message done and saved. Sernum: "
471 addFolderChange( &folder, Contents );
472 syncFolder( &folder );
474 kdError(5006) <<
"addIncidenceKolab(): Message *NOT* saved!\n";
479 bool KMailICalIfaceImpl::deleteIncidenceKolab(
const TQString& resource,
483 if( !mUseResourceIMAP )
486 kdDebug(5006) <<
"KMailICalIfaceImpl::deleteIncidenceKolab( "
487 << resource <<
", " << sernum <<
")\n";
490 KMFolder* f = findResourceFolder( resource );
492 kdError(5006) <<
"deleteIncidenceKolab(" << resource <<
") : Not an IMAP resource folder" << endl;
505 kdDebug(5006) <<
"Message not found, cannot remove serNum " << sernum << endl;
511 int KMailICalIfaceImpl::incidencesKolabCount(
const TQString& mimetype,
512 const TQString& resource )
514 Q_UNUSED( mimetype );
516 if( !mUseResourceIMAP )
519 KMFolder* f = findResourceFolder( resource );
521 kdError(5006) <<
"incidencesKolab(" << resource <<
") : Not an IMAP resource folder" << endl;
525 f->
open(
"kolabcount");
527 f->
close(
"kolabcount");
528 kdDebug(5006) <<
"KMailICalIfaceImpl::incidencesKolabCount( "
529 << resource <<
" ) returned " << n << endl;
534 const TQString& resource,
542 TQMap<TQ_UINT32, TQString> aMap;
543 if( !mUseResourceIMAP )
546 KMFolder* f = findResourceFolder( resource );
548 kdError(5006) <<
"incidencesKolab(" << resource <<
") : Not an IMAP resource folder" << endl;
552 f->
open(
"incidences" );
554 kdDebug(5006) << k_funcinfo <<
"Getting incidences (" << mimetype <<
") for folder " << f->
label()
555 <<
", starting with index " << startIndex <<
", " << nbMessages <<
" messages." << endl;
556 kdDebug(5006) <<
"The folder has " << f->
count() <<
" messages." << endl;
558 int stopIndex = nbMessages == -1 ? f->
count() :
559 TQMIN( f->
count(), startIndex + nbMessages );
561 for(
int i = startIndex; i < stopIndex; ++i) {
569 const int iSlash = mimetype.find(
'/');
570 const TQCString sType = mimetype.left( iSlash ).latin1();
571 const TQCString sSubtype = mimetype.mid( iSlash+1 ).latin1();
572 if ( sType.isEmpty() || sSubtype.isEmpty() ) {
573 kdError(5006) << mimetype <<
" not an type/subtype combination" << endl;
575 DwBodyPart* dwPart = findBodyPartByMimeType( *msg, sType, sSubtype );
577 KMMessagePart msgPart;
579 aMap.insert(msg->getMsgSerNum(), msgPart.
bodyToUnicode( TQTextCodec::codecForName(
"utf8" ) ));
584 const TQCString type( msg->
typeStr() );
586 if (type.lower() == sType && subtype.lower() == sSubtype ) {
599 kdDebug(5006) << k_funcinfo <<
" Unable to retrieve message " << i <<
" for incidence!" << endl;
602 f->
close(
"incidences" );
610 void KMailICalIfaceImpl::slotMessageRetrieved(
KMMessage* msg )
616 TQ_UINT32 sernum = msg->getMsgSerNum();
619 Accumulator *ac = mAccumulators.find( parent->
location() );
622 if ( !vPartFoundAndDecoded( msg, s ) )
return;
623 TQString uid(
"UID" );
624 vPartMicroParser( s, uid );
625 const TQ_UINT32 sernum = msg->getMsgSerNum();
626 mUIDToSerNum.insert( uid, sernum );
632 mAccumulators.remove( ac->folder );
637 slotIncidenceAdded( msg->parent(), msg->getMsgSerNum() );
640 if ( mTheUnGetMes.contains( sernum ) ) {
641 mTheUnGetMes.remove( sernum );
649 static int dimapAccountCount()
652 KMAccount *account = mgr->
first();
655 if (
dynamic_cast<KMAcctCachedImap*
>( account ) )
657 account = mgr->
next();
662 int KMailICalIfaceImpl::dimapAccounts()
664 return dimapAccountCount();
667 static TQString subresourceLabelForPresentation(
const KMFolder * folder )
669 if( KMailICalIfaceImpl::getResourceMap()->contains( folder->
location() ) ) {
670 return folder->
label();
674 TQStringList parts = TQStringList::split( TQString::fromLatin1(
"/"), label );
679 if ( parts[1] == TQString::fromLatin1(
"user") ) {
680 TQStringList remainder(parts);
681 remainder.pop_front();
682 remainder.pop_front();
683 remainder.pop_front();
684 label = i18n(
"%1's %2")
686 .arg( remainder.join( TQString::fromLatin1(
"/") ) );
691 while ( parent->parent() && parent->parent()->owner() ) {
692 parent = parent->parent()->owner();
694 TQStringList remainder(parts);
695 remainder.pop_front();
696 remainder.pop_front();
697 if ( dimapAccountCount() > 1 ) {
699 if( folder->storage() &&
static_cast<const KMFolderCachedImap*
>( folder->storage() )->account() ) {
700 label = i18n(
"My %1 (%2)")
701 .arg( remainder.join( TQString::fromLatin1(
"/") ),
702 static_cast<const KMFolderCachedImap*
>( folder->storage() )->account()->name() );
704 label = i18n(
"My %1")
705 .arg( remainder.join( TQString::fromLatin1(
"/") ) );
708 label = i18n(
"My %1")
709 .arg( remainder.join( TQString::fromLatin1(
"/") ) );
718 TQValueList<KMailICalIfaceImpl::SubResource> KMailICalIfaceImpl::subresourcesKolab(
const TQString& contentsType )
720 TQValueList<SubResource> subResources;
725 subResources.append( SubResource( f->
location(), subresourceLabelForPresentation( f ),
726 f->
isWritable(), folderIsAlarmRelevant( f ) ) );
727 kdDebug(5006) <<
"Adding(1) folder " << f->
location() <<
" " <<
728 ( !f->
isWritable() ?
"readonly" :
"" ) << endl;
732 const KMail::FolderContentsType t = folderContentsType( contentsType );
733 TQDictIterator<ExtraFolder> it( mExtraFolders );
734 for ( ; it.current(); ++it ){
735 f = it.current()->folder;
737 subResources.append( SubResource( f->
location(), subresourceLabelForPresentation( f ),
738 f->
isWritable(), folderIsAlarmRelevant( f ) ) );
739 kdDebug(5006) <<
"Adding(2) folder " << f->
location() <<
" " <<
740 ( !f->
isWritable() ?
"readonly" :
"" ) << endl;
744 if ( subResources.isEmpty() )
745 kdDebug(5006) <<
"subresourcesKolab: No folder found for " << contentsType << endl;
749 bool KMailICalIfaceImpl::triggerSync(
const TQString& contentsType )
751 kdDebug(5006) << k_funcinfo << endl;
752 TQValueList<KMailICalIfaceImpl::SubResource> folderList = subresourcesKolab( contentsType );
753 for ( TQValueList<KMailICalIfaceImpl::SubResource>::const_iterator it( folderList.begin() ),
754 end( folderList.end() );
756 KMFolder *
const f = findResourceFolder( (*it).location );
759 if ( !kmkernel->askToGoOnline() ) {
765 KMFolderImap *imap =
static_cast<KMFolderImap*
>( f->storage() );
766 imap->getAndCheckFolder();
767 }
else if ( f->
folderType() == KMFolderTypeCachedImap ) {
768 KMFolderCachedImap* cached =
static_cast<KMFolderCachedImap*
>( f->storage() );
769 if ( cached->account() ) {
770 cached->account()->processNewMailInFolder( f );
778 bool KMailICalIfaceImpl::isWritableFolder(
const TQString& type,
779 const TQString& resource )
790 KMailICalIfaceImpl::StorageFormat KMailICalIfaceImpl::storageFormat(
const TQString& resource )
792 StorageFormat format;
793 KMFolder* f = findResourceFolder( resource );
795 format = storageFormat( f );
797 format = globalStorageFormat();
817 const TQString& subject,
818 const TQString& plainTextBody,
819 const TQMap<TQCString, TQString>& customHeaders,
820 const TQStringList& attachmentURLs,
821 const TQStringList& attachmentMimetypes,
822 const TQStringList& attachmentNames,
823 const TQStringList& deletedAttachments )
827 if( !mUseResourceIMAP )
830 Q_ASSERT( !resource.isEmpty() );
832 kdDebug(5006) <<
"KMailICalIfaceImpl::update( " << resource <<
", " << sernum <<
" )\n";
833 kdDebug(5006) << attachmentURLs <<
"\n";
834 kdDebug(5006) << attachmentMimetypes <<
"\n";
835 kdDebug(5006) << attachmentNames <<
"\n";
836 kdDebug(5006) <<
"deleted attachments:" << deletedAttachments <<
"\n";
839 KMFolder* f = findResourceFolder( resource );
841 kdError(5006) <<
"update(" << resource <<
") : Not an IMAP resource folder" << endl;
845 f->
open(
"ifaceupdate" );
850 if ( !msg )
return 0;
853 newMsg->setSubject( subject );
854 TQMap<TQCString, TQString>::ConstIterator ith = customHeaders.begin();
855 const TQMap<TQCString, TQString>::ConstIterator ithEnd = customHeaders.begin();
856 for ( ; ith != ithEnd ; ++ith )
858 newMsg->setParent( 0 );
862 for( TQStringList::ConstIterator it = deletedAttachments.begin();
863 it != deletedAttachments.end();
865 if( !deleteAttachment( *newMsg, *it ) ){
870 const KMail::FolderContentsType t = f->storage()->
contentsType();
871 const TQCString type = msg->
typeStr();
873 const bool messageWasIcalVcardFormat = ( type.lower() ==
"text" &&
874 ( subtype.lower() ==
"calendar" || subtype.lower() ==
"x-vcard" ) );
876 if ( storageFormat( f ) == StorageIcalVcard ) {
878 if ( !messageWasIcalVcardFormat ) {
879 setIcalVcardContentTypeHeader( newMsg, t, f );
882 }
else if ( storageFormat( f ) == StorageXML ) {
883 if ( messageWasIcalVcardFormat ) {
886 setXMLContentTypeHeader( newMsg, plainTextBody );
890 TQStringList::ConstIterator iturl = attachmentURLs.begin();
891 TQStringList::ConstIterator itmime = attachmentMimetypes.begin();
892 TQStringList::ConstIterator itname = attachmentNames.begin();
894 iturl != attachmentURLs.end()
895 && itmime != attachmentMimetypes.end()
896 && itname != attachmentNames.end();
897 ++iturl, ++itname, ++itmime ){
898 bool byname = !(*itmime).startsWith(
"application/x-vnd.kolab." );
899 if( !updateAttachment( *newMsg, *iturl, *itname, *itmime, byname ) ){
900 kdDebug(5006) <<
"Attachment error, can not update attachment " << *iturl << endl;
914 if ( f->
addMsg( newMsg ) == 0 ) {
916 rc = newMsg->getMsgSerNum();
917 kdDebug(5006) <<
"forget about " << sernum <<
", it's " << rc <<
" now" << endl;
919 addFolderChange( f, Contents );
923 rc = addIncidenceKolab( *f, subject, plainTextBody, customHeaders,
926 attachmentMimetypes );
929 f->
close(
"ifaceupdate");
933 KURL KMailICalIfaceImpl::getAttachment(
const TQString& resource,
935 const TQString& filename )
940 if( !mUseResourceIMAP )
943 kdDebug(5006) <<
"KMailICalIfaceImpl::getAttachment( "
944 << resource <<
", " << sernum <<
", " << filename <<
" )\n";
947 KMFolder* f = findResourceFolder( resource );
949 kdError(5006) <<
"getAttachment(" << resource <<
") : Not an IMAP resource folder" << endl;
952 if ( storageFormat( f ) != StorageXML ) {
953 kdError(5006) <<
"getAttachment(" << resource <<
") : Folder has wrong storage format " << storageFormat( f ) << endl;
960 bool quiet = mResourceQuiet;
961 mResourceQuiet =
true;
967 DwBodyPart* part = findBodyPart( *msg, filename );
972 TQByteArray rawData( aPart.bodyDecodedBinary() );
975 file.file()->writeBlock( rawData.data(), rawData.size() );
977 url.setPath( file.name() );
983 kdDebug(5006) <<
"Attachment " << filename <<
" not found." << endl;
986 kdDebug(5006) <<
"Message not found." << endl;
989 mResourceQuiet = quiet;
993 TQString KMailICalIfaceImpl::attachmentMimetype(
const TQString & resource,
995 const TQString & filename )
997 if( !mUseResourceIMAP )
999 KMFolder* f = findResourceFolder( resource );
1000 if( !f || storageFormat( f ) != StorageXML ) {
1001 kdError(5006) <<
"attachmentMimetype(" << resource <<
") : Wrong folder" << endl;
1008 DwBodyPart* part = findBodyPart( *msg, filename );
1010 KMMessagePart kmPart;
1012 return TQString( kmPart.typeStr() ) +
"/" + TQString( kmPart.subtypeStr() );
1014 kdDebug(5006) <<
"Attachment " << filename <<
" not found." << endl;
1017 kdDebug(5006) <<
"Message not found." << endl;
1023 TQStringList KMailICalIfaceImpl::listAttachments(
const TQString & resource, TQ_UINT32 sernum)
1026 if( !mUseResourceIMAP )
1030 KMFolder* f = findResourceFolder( resource );
1032 kdError(5006) <<
"listAttachments(" << resource <<
") : Not an IMAP resource folder" << endl;
1035 if ( storageFormat( f ) != StorageXML ) {
1036 kdError(5006) <<
"listAttachment(" << resource <<
") : Folder has wrong storage format " << storageFormat( f ) << endl;
1043 if ( part->hasHeaders() ) {
1045 DwMediaType& contentType = part->Headers().ContentType();
1046 if ( TQString( contentType.SubtypeStr().c_str() ).startsWith(
"x-vnd.kolab." )
1047 || TQString( contentType.SubtypeStr().c_str() ).contains(
"tnef" ) )
1049 if ( !part->Headers().ContentDisposition().Filename().empty() )
1050 name = part->Headers().ContentDisposition().Filename().c_str();
1051 else if ( !contentType.Name().empty() )
1052 name = contentType.Name().c_str();
1053 if ( !name.isEmpty() )
1058 kdDebug(5006) <<
"Message not found." << endl;
1071 void KMailICalIfaceImpl::slotFolderRemoved(
KMFolder* folder )
1076 TDEConfigGroup configGroup( kmkernel->config(),
"GroupwareFolderInfo" );
1077 configGroup.deleteEntry( folder->
idString() +
"-storageFormat" );
1078 configGroup.deleteEntry( folder->
idString() +
"-changes" );
1082 void KMailICalIfaceImpl::slotIncidenceAdded(
KMFolder* folder,
1085 if( mResourceQuiet || !mUseResourceIMAP )
1089 TQString type = folderContentsType( folder->storage()->
contentsType() );
1090 if( type.isEmpty() ) {
1091 kdError(5006) <<
"Not an IMAP resource folder" << endl;
1098 assert( folder == aFolder );
1102 TQString uid(
"UID" );
1108 StorageFormat format = storageFormat( folder );
1110 case StorageIcalVcard:
1112 ok = vPartFoundAndDecoded( msg, s );
1114 vPartMicroParser( s, uid );
1118 if ( kolabXMLFoundAndDecoded( *msg,
1119 folderKolabMimeType( folder->storage()->
contentsType() ), s ) ) {
1130 const TQ_UINT32 sernum = msg->getMsgSerNum();
1131 mUIDToSerNum.insert( uid, sernum );
1134 if ( mInTransit.contains( uid ) ) {
1135 mInTransit.remove( uid );
1137 incidenceAdded( type, folder->
location(), sernum, format, s );
1141 if ( unget ) mTheUnGetMes.insert( msg->getMsgSerNum(),
true );
1142 FolderJob *job = msg->parent()->createJob( msg );
1143 connect( job, TQ_SIGNAL( messageRetrieved(
KMMessage* ) ),
1144 this, TQ_SLOT( slotMessageRetrieved(
KMMessage* ) ) );
1152 void KMailICalIfaceImpl::slotIncidenceDeleted(
KMFolder* folder,
1155 if( mResourceQuiet || !mUseResourceIMAP )
1158 TQString type = folderContentsType( folder->storage()->
contentsType() );
1160 if( !type.isEmpty() ) {
1165 assert( folder == aFolder );
1172 TQString uid(
"UID" );
1173 switch( storageFormat( folder ) ) {
1174 case StorageIcalVcard:
1175 if( vPartFoundAndDecoded( msg, s ) ) {
1176 vPartMicroParser( s, uid );
1181 if ( kolabXMLFoundAndDecoded( *msg, folderKolabMimeType( folder->storage()->
contentsType() ), s ) ) {
1188 kdDebug(5006) <<
"Emitting DCOP signal incidenceDeleted( "
1189 << type <<
", " << folder->
location() <<
", " << uid
1191 incidenceDeleted( type, folder->
location(), uid );
1195 kdError(5006) <<
"Not a groupware folder" << endl;
1199 void KMailICalIfaceImpl::slotRefresh(
const TQString& type )
1201 if( mUseResourceIMAP ) {
1202 signalRefresh( type, TQString() );
1203 kdDebug(5006) <<
"Emitting DCOP signal signalRefresh( " << type <<
" )" << endl;
1208 void KMailICalIfaceImpl::slotRefreshFolder(
KMFolder* folder)
1213 if( mUseResourceIMAP && folder ) {
1214 if( folder == mCalendar || folder == mContacts
1215 || folder == mNotes || folder == mTasks
1216 || folder == mJournals || mExtraFolders.find( folder->
location() ) ) {
1218 KMail::FolderContentsType ct = folder->storage()->
contentsType();
1219 slotRefresh( s_folderContentsType[ct].contentsTypeStr );
1229 const TQString& folder )
1231 if( mUseResourceIMAP ) {
1233 if ( !folder.isEmpty() ) {
1234 f = extraFolder( type, folder );
1239 if( type ==
"Calendar" ) f = mCalendar;
1240 else if( type ==
"Contact" ) f = mContacts;
1241 else if( type ==
"Note" ) f = mNotes;
1242 else if( type ==
"Task" || type ==
"Todo" ) f = mTasks;
1243 else if( type ==
"Journal" ) f = mJournals;
1245 if ( f && ( folder.isEmpty() || folder == f->
location() ) )
1248 kdError(5006) <<
"No folder ( " << type <<
", " << folder <<
" )\n";
1259 return mUseResourceIMAP && folder &&
1260 ( isStandardResourceFolder( folder ) || mExtraFolders.find( folder->
location() )!=0 );
1263 bool KMailICalIfaceImpl::isStandardResourceFolder(
KMFolder* folder )
const
1265 return ( folder == mCalendar || folder == mTasks || folder == mJournals ||
1266 folder == mNotes || folder == mContacts );
1276 KMFolderCachedImap *dimapFolder =
dynamic_cast<KMFolderCachedImap*
>( folder->storage() );
1277 bool hide = dimapFolder && mHideFolders
1278 && (int)dimapFolder->account()->id() == GlobalSettings::self()->theIMAPResourceAccount()
1279 && GlobalSettings::self()->showOnlyGroupwareFoldersForGroupwareAccount();
1286 if( mUseResourceIMAP && folder ) {
1287 if( folder == mCalendar || folder == mContacts
1288 || folder == mNotes || folder == mTasks
1289 || folder == mJournals || mExtraFolders.find( folder->
location() ) ) {
1290 KMail::FolderContentsType ct = folder->storage()->
contentsType();
1291 return s_folderContentsType[ct].treeItemType;
1295 return KFolderTreeItem::Other;
1300 static TQMap<KFolderTreeItem::Type,TQString> folderNames[4];
1304 if ( GlobalSettings::self()->theIMAPResourceStorageFormat() == GlobalSettings::EnumTheIMAPResourceStorageFormat::XML )
1307 static bool folderNamesSet =
false;
1308 if( !folderNamesSet ) {
1309 folderNamesSet =
true;
1314 folderNames[0][KFolderTreeItem::Calendar] = TQString::fromLatin1(
"Calendar");
1315 folderNames[0][KFolderTreeItem::Tasks] = TQString::fromLatin1(
"Tasks");
1316 folderNames[0][KFolderTreeItem::Journals] = TQString::fromLatin1(
"Journal");
1317 folderNames[0][KFolderTreeItem::Contacts] = TQString::fromLatin1(
"Contacts");
1318 folderNames[0][KFolderTreeItem::Notes] = TQString::fromLatin1(
"Notes");
1321 folderNames[1][KFolderTreeItem::Calendar] = TQString::fromLatin1(
"Kalender");
1322 folderNames[1][KFolderTreeItem::Tasks] = TQString::fromLatin1(
"Aufgaben");
1323 folderNames[1][KFolderTreeItem::Journals] = TQString::fromLatin1(
"Journal");
1324 folderNames[1][KFolderTreeItem::Contacts] = TQString::fromLatin1(
"Kontakte");
1325 folderNames[1][KFolderTreeItem::Notes] = TQString::fromLatin1(
"Notizen");
1328 folderNames[2][KFolderTreeItem::Calendar] = TQString::fromLatin1(
"Calendrier");
1330 folderNames[2][KFolderTreeItem::Tasks] = TQString::fromLatin1(
"T\342ches");
1331 folderNames[2][KFolderTreeItem::Journals] = TQString::fromLatin1(
"Journal");
1332 folderNames[2][KFolderTreeItem::Contacts] = TQString::fromLatin1(
"Contacts");
1333 folderNames[2][KFolderTreeItem::Notes] = TQString::fromLatin1(
"Notes");
1336 folderNames[3][KFolderTreeItem::Calendar] = TQString::fromLatin1(
"Agenda");
1337 folderNames[3][KFolderTreeItem::Tasks] = TQString::fromLatin1(
"Taken");
1338 folderNames[3][KFolderTreeItem::Journals] = TQString::fromLatin1(
"Logboek");
1339 folderNames[3][KFolderTreeItem::Contacts] = TQString::fromLatin1(
"Contactpersonen");
1340 folderNames[3][KFolderTreeItem::Notes] = TQString::fromLatin1(
"Notities");
1343 if( language < 0 || language > 3 ) {
1344 return folderNames[mFolderLanguage][type];
1347 return folderNames[language][type];
1355 if( !folder || !mUIDToSerNum.contains( uid ) )
return 0;
1359 Q_ASSERT( aFolder == folder );
1360 return folder->
getMsg( i );
1366 if( !folder )
return 0;
1373 if( aFolder && aFolder != folder ) {
1374 kdWarning(5006) <<
"findMessageBySerNum( " << serNum <<
" ) found it in folder " << aFolder->
location() <<
", expected " << folder->
location() << endl;
1377 message = aFolder->
getMsg( index );
1379 kdWarning(5006) <<
"findMessageBySerNum( " << serNum <<
" ) invalid serial number\n" << endl;
1389 KMFolder *srcFolder = msg->parent();
1390 int idx = srcFolder->
find(msg);
1398 kdDebug(5006) << k_funcinfo <<
"Message cannot be deleted now because it is currently in use " << msg << endl;
1401 addFolderChange( srcFolder, Contents );
1405 KMail::FolderContentsType contentsType )
1407 if ( !mUseResourceIMAP )
1413 if ( isStandardResourceFolder( folder ) )
1417 const TQString location = folder->
location();
1418 ExtraFolder* ef = mExtraFolders.find( location );
1419 if ( ef && ef->folder ) {
1421 subresourceDeleted(folderContentsType( folder->storage()->
contentsType() ), location );
1423 if ( contentsType == KMail::ContentsTypeMail ) {
1425 mExtraFolders.remove( location );
1426 folder->disconnect(
this );
1431 if ( ef && !ef->folder )
1432 mExtraFolders.remove( location );
1433 if ( contentsType == KMail::ContentsTypeMail )
1438 ef =
new ExtraFolder( folder );
1439 mExtraFolders.insert( location, ef );
1441 FolderInfo info = readFolderInfo( folder );
1442 mFolderInfoMap.insert( folder, info );
1449 if ( folder->
folderType() == KMFolderTypeCachedImap ) {
1450 TQString annotation =
static_cast<KMFolderCachedImap*
>( folder->storage() )->annotationFolderType();
1451 kdDebug(5006) <<
"folderContentsTypeChanged: " << folder->name() <<
" has annotation " << annotation << endl;
1452 if ( annotation == TQString( s_folderContentsType[contentsType].annotation ) +
".default" )
1453 folder->setLabel( localizedDefaultFolderName( contentsType ) );
1456 connectFolder( folder );
1459 subresourceAdded( folderContentsType( contentsType ), location, subresourceLabelForPresentation(folder),
1460 folder->
isWritable(), folderIsAlarmRelevant( folder ) );
1463 KMFolder* KMailICalIfaceImpl::extraFolder(
const TQString& type,
1464 const TQString& folder )
1468 int t = folderContentsType( type );
1469 if ( t < 1 || t > 5 )
1472 ExtraFolder* ef = mExtraFolders.find( folder );
1473 if ( ef && ef->folder && ef->folder->storage()->contentsType() == t )
1479 KMailICalIfaceImpl::StorageFormat KMailICalIfaceImpl::storageFormat(
KMFolder* folder )
const
1481 FolderInfoMap::ConstIterator it = mFolderInfoMap.find( folder );
1482 if ( it != mFolderInfoMap.end() )
1483 return (*it).mStorageFormat;
1484 return globalStorageFormat();
1489 FolderInfoMap::Iterator it = mFolderInfoMap.find( folder );
1490 if ( it != mFolderInfoMap.end() ) {
1491 (*it).mStorageFormat = format;
1493 FolderInfo info( format, NoChange );
1494 mFolderInfoMap.insert( folder, info );
1496 TDEConfigGroup configGroup( kmkernel->config(),
"GroupwareFolderInfo" );
1497 configGroup.writeEntry( folder->
idString() +
"-storageFormat",
1498 format == StorageXML ?
"xml" :
"icalvcard" );
1501 void KMailICalIfaceImpl::addFolderChange(
KMFolder* folder, FolderChanges changes )
1503 FolderInfoMap::Iterator it = mFolderInfoMap.find( folder );
1504 if ( it != mFolderInfoMap.end() ) {
1505 (*it).mChanges =
static_cast<FolderChanges
>( (*it).mChanges | changes );
1507 kdDebug(5006) <<
"addFolderChange: nothing known about folder " << folder->
location() << endl;
1509 TDEConfigGroup configGroup( kmkernel->config(),
"GroupwareFolderInfo" );
1510 configGroup.writeEntry( folder->
idString() +
"-changes", (*it).mChanges );
1513 KMailICalIfaceImpl::FolderInfo KMailICalIfaceImpl::readFolderInfo(
const KMFolder *
const folder )
const
1515 TDEConfigGroup configGroup( kmkernel->config(),
"GroupwareFolderInfo" );
1516 TQString str = configGroup.readEntry( folder->
idString() +
"-storageFormat",
"unset" );
1518 if ( str ==
"unset" ) {
1519 info.mStorageFormat = globalStorageFormat();
1520 configGroup.writeEntry( folder->
idString() +
"-storageFormat",
1521 info.mStorageFormat == StorageXML ?
"xml" :
"icalvcard" );
1523 info.mStorageFormat = ( str ==
"xml" ) ? StorageXML : StorageIcalVcard;
1525 info.mChanges = (FolderChanges) configGroup.readNumEntry( folder->
idString() +
"-changes" );
1530 void KMailICalIfaceImpl::folderSynced(
KMFolder* folder,
const KURL& folderURL )
1532 FolderInfoMap::Iterator it = mFolderInfoMap.find( folder );
1533 if ( it != mFolderInfoMap.end() && (*it).mChanges ) {
1534 handleFolderSynced( folder, folderURL, (*it).mChanges );
1535 (*it).mChanges = NoChange;
1539 void KMailICalIfaceImpl::handleFolderSynced(
KMFolder* folder,
1540 const KURL& folderURL,
1547 if ( ( _changes & KMailICalIface::Contents ) ||
1548 ( _changes & KMailICalIface::ACL ) ) {
1549 if ( storageFormat( folder ) == StorageXML && folder->storage()->
contentsType() == KMail::ContentsTypeCalendar )
1550 triggerKolabFreeBusy( folderURL );
1554 void KMailICalIfaceImpl::folderDeletedOnServer(
const KURL& folderURL )
1556 triggerKolabFreeBusy( folderURL );
1559 void KMailICalIfaceImpl::triggerKolabFreeBusy(
const KURL& folderURL )
1564 KURL httpURL( folderURL );
1566 httpURL.setProtocol(
"https" );
1567 httpURL.setPort( 0 );
1570 TQString path = folderURL.path( -1 );
1571 Q_ASSERT( path.startsWith(
"/" ) );
1572 int secondSlash = path.find(
'/', 1 );
1573 if ( secondSlash == -1 ) {
1574 kdWarning() <<
"KCal::ResourceKolab::fromKMailFolderSynced path is too short: " << path << endl;
1577 if ( path.startsWith(
"/INBOX/",
false ) ) {
1579 path = path.mid( secondSlash );
1580 path.prepend( folderURL.user() );
1584 path = path.mid( secondSlash );
1587 httpURL.setPath(
"/freebusy/trigger/" + path +
".pfb" );
1588 httpURL.setQuery( TQString() );
1590 httpURL = KURL( httpURL.url(0,106), 106 );
1591 kdDebug() <<
"Triggering PFB update for " << folderURL <<
" : getting " << httpURL << endl;
1594 TDEIO::get( httpURL,
false,
false );
1597 void KMailICalIfaceImpl::slotFolderPropertiesChanged(
KMFolder* folder )
1600 const TQString location = folder->
location();
1601 const TQString contentsTypeStr = folderContentsType( folder->storage()->
contentsType() );
1602 subresourceDeleted( contentsTypeStr, location );
1604 subresourceAdded( contentsTypeStr, location, subresourceLabelForPresentation( folder ),
1605 folder->
isWritable(), folderIsAlarmRelevant( folder ) );
1610 void KMailICalIfaceImpl::slotFolderRenamed()
1613 slotFolderPropertiesChanged(
const_cast<KMFolder*
>( folder ) );
1616 void KMailICalIfaceImpl::slotFolderLocationChanged(
const TQString &oldLocation,
1617 const TQString &newLocation )
1619 KMFolder *folder = findResourceFolder( oldLocation );
1620 ExtraFolder* ef = mExtraFolders.find( oldLocation );
1623 mExtraFolders.setAutoDelete(
false );
1624 mExtraFolders.remove( oldLocation );
1625 mExtraFolders.setAutoDelete(
true );
1626 mExtraFolders.insert( newLocation, ef );
1629 subresourceDeleted( folderContentsType( folder->storage()->
contentsType() ), oldLocation );
1633 KMFolder* KMailICalIfaceImpl::findResourceFolder(
const TQString& resource )
1636 if( mCalendar && mCalendar->location() == resource )
1638 if ( mContacts && mContacts->location() == resource )
1640 if ( mNotes && mNotes->location() == resource )
1642 if ( mTasks && mTasks->location() == resource )
1644 if ( mJournals && mJournals->location() == resource )
1648 ExtraFolder* ef = mExtraFolders.find( resource );
1656 void KMailICalIfaceImpl::changeResourceUIName(
const TQString &folderPath,
const TQString &newName )
1658 kdDebug() <<
"Folder path " << folderPath << endl;
1659 KMFolder *f = findResourceFolder( folderPath );
1661 KMailICalIfaceImpl::getResourceMap()->insert( folderPath, newName );
1662 kmkernel->folderMgr()->renameFolder( f, newName );
1663 TDEConfigGroup configGroup( kmkernel->config(),
"Resource UINames" );
1664 configGroup.writeEntry( folderPath, newName );
1669 static void createFolderList( TQStringList &folderNames, TQValueList<TQGuardedPtr<KMFolder> > &folderList )
1671 TQStringList dimapFolderNames;
1672 TQStringList localFolderNames;
1673 TQValueList<TQGuardedPtr<KMFolder> > dimapFolderList;
1674 TQValueList<TQGuardedPtr<KMFolder> > localFolderList;
1675 kmkernel->dimapFolderMgr()->createFolderList( &dimapFolderNames, &dimapFolderList );
1676 kmkernel->folderMgr()->createFolderList( &localFolderNames, &localFolderList );
1677 folderNames += dimapFolderNames;
1678 folderNames += localFolderNames;
1679 folderList += dimapFolderList;
1680 folderList += localFolderList;
1687 void KMailICalIfaceImpl::readConfig()
1689 bool enabled = GlobalSettings::self()->theIMAPResourceEnabled() &&
1690 ( GlobalSettings::self()->theIMAPResourceAccount() != 0 );
1693 if( mUseResourceIMAP ==
true ) {
1695 mUseResourceIMAP =
false;
1701 mUseResourceIMAP = enabled;
1704 const bool hideFolders = GlobalSettings::self()->hideGroupwareFolders();
1705 TQString parentName = GlobalSettings::self()->theIMAPResourceFolderParent();
1710 KMFolder* folderParent = kmkernel->findFolderById( parentName );
1711 if( folderParent == 0 ) {
1714 kdDebug(5006) <<
"Groupware folder " << parentName <<
" not found. Groupware functionality disabled" << endl;
1716 KMAccount* account = kmkernel->acctMgr()->find( GlobalSettings::self()->theIMAPResourceAccount() );
1717 Q_ASSERT( account );
1720 disconnect( account, TQ_SIGNAL( finishedCheck(
bool, CheckStatus ) ),
1721 this, TQ_SLOT( slotCheckDone() ) );
1722 connect( account, TQ_SIGNAL( finishedCheck(
bool, CheckStatus ) ),
1723 this, TQ_SLOT( slotCheckDone() ) );
1725 mUseResourceIMAP =
false;
1738 KMAcctCachedImap::GroupwareType groupwareType =
dynamic_cast<KMFolderCachedImap *
>( folderParent->storage() )->account()->groupwareType();
1740 if ( groupwareType == KMAcctCachedImap::GroupwareKolab ) {
1743 bool noneFound =
true;
1744 bool mustFix =
false;
1745 TQValueVector<StandardFolderSearchResult> results( KMail::ContentsTypeLast + 1 );
1746 for (
int i = 0; i < KMail::ContentsTypeLast+1; ++i ) {
1747 if ( i != KMail::ContentsTypeMail ) {
1748 results[i] = findStandardResourceFolder( folderParentDir,
static_cast<KMail::FolderContentsType
>(i) );
1749 if ( results[i].found == StandardFolderSearchResult::FoundAndStandard )
1751 else if ( results[i].found == StandardFolderSearchResult::FoundByType ||
1752 results[i].found == StandardFolderSearchResult::FoundByName ) {
1761 if( mUseResourceIMAP && !noneFound && !mustFix && mFolderParentDir == folderParentDir
1764 if ( hideFolders != mHideFolders ) {
1766 mHideFolders = hideFolders;
1772 if( noneFound || mustFix ) {
1774 TQString parentFolderName = folderParent != 0 ? folderParent->name() : folderParentDir->name();
1777 msg = i18n(
"KMail will now create the required groupware folders"
1778 " as subfolders of %1; if you do not want this, cancel"
1779 " and the IMAP resource will be disabled").arg(parentFolderName);
1782 TQString operations =
"<ul>";
1783 for (
int i = 0; i < KMail::ContentsTypeLast+1; ++i ) {
1784 if ( i != KMail::ContentsTypeMail ) {
1785 TQString typeName = localizedDefaultFolderName(
static_cast<KMail::FolderContentsType
>( i ) );
1786 if ( results[i].found == StandardFolderSearchResult::NotFound )
1787 operations +=
"<li>" + i18n(
"%1: no folder found. It will be created." ).arg( typeName ) +
"</li>";
1788 else if ( results[i].found == StandardFolderSearchResult::FoundByType || results[i].found == StandardFolderSearchResult::FoundByName )
1789 operations +=
"<li>" + i18n(
"%1: found folder %2. It will be set as the main groupware folder." ).
1790 arg( typeName ).arg( results[i].folder->
label() ) +
"</li>";
1793 operations +=
"</ul>";
1795 msg = i18n(
"<qt>KMail found the following groupware folders in %1 and needs to perform the following operations: %2"
1796 "<br>If you do not want this, cancel"
1797 " and the IMAP resource will be disabled").arg(parentFolderName, operations);
1801 if( KMessageBox::questionYesNo( 0, msg,
1802 i18n(
"Standard Groupware Folders"), KStdGuiItem::cont(), KStdGuiItem::cancel() ) == KMessageBox::No ) {
1804 GlobalSettings::self()->setTheIMAPResourceEnabled(
false );
1805 mUseResourceIMAP =
false;
1806 mFolderParentDir = 0;
1814 mUseResourceIMAP =
true;
1815 mFolderLanguage = GlobalSettings::self()->theIMAPResourceFolderLanguage();
1816 if( mFolderLanguage > 3 ) mFolderLanguage = 0;
1817 mFolderParentDir = folderParentDir;
1818 mFolderParent = folderParent;
1820 mHideFolders = hideFolders;
1826 mCalendar = initFolder( KMail::ContentsTypeCalendar );
1827 mTasks = initFolder( KMail::ContentsTypeTask );
1828 mJournals = initFolder( KMail::ContentsTypeJournal );
1829 mContacts = initFolder( KMail::ContentsTypeContact );
1830 mNotes = initFolder( KMail::ContentsTypeNote );
1833 if ( mCalendar->folderType() == KMFolderTypeCachedImap )
1834 static_cast<KMFolderCachedImap *
>( mCalendar->storage() )->updateAnnotationFolderType();
1835 if ( mTasks->folderType() == KMFolderTypeCachedImap )
1836 static_cast<KMFolderCachedImap *
>( mTasks->storage() )->updateAnnotationFolderType();
1837 if ( mJournals->folderType() == KMFolderTypeCachedImap )
1838 static_cast<KMFolderCachedImap *
>( mJournals->storage() )->updateAnnotationFolderType();
1839 if ( mContacts->folderType() == KMFolderTypeCachedImap )
1840 static_cast<KMFolderCachedImap *
>( mContacts->storage() )->updateAnnotationFolderType();
1841 if ( mNotes->folderType() == KMFolderTypeCachedImap )
1842 static_cast<KMFolderCachedImap *
>( mNotes->storage() )->updateAnnotationFolderType();
1849 TQStringList folderNames;
1850 TQValueList<TQGuardedPtr<KMFolder> > folderList;
1851 createFolderList( folderNames, folderList );
1852 for( TQValueList<TQGuardedPtr<KMFolder> >::iterator it = folderList.begin();
1853 it != folderList.end(); ++it )
1856 KMFolderCachedImap* dimapStorage =
dynamic_cast<KMFolderCachedImap*
>( storage );
1859 dimapStorage->updateAnnotationFolderType();
1866 mExtraFolders.remove( mCalendar->location() );
1867 mExtraFolders.remove( mTasks->location() );
1868 mExtraFolders.remove( mJournals->location() );
1869 mExtraFolders.remove( mContacts->location() );
1870 mExtraFolders.remove( mNotes->location() );
1872 subresourceAdded( folderContentsType( KMail::ContentsTypeCalendar ), mCalendar->location(), mCalendar->label(),
true,
true );
1873 subresourceAdded( folderContentsType( KMail::ContentsTypeTask ), mTasks->location(), mTasks->label(),
true,
true );
1874 subresourceAdded( folderContentsType( KMail::ContentsTypeJournal ), mJournals->location(), mJournals->label(),
true,
false );
1875 subresourceAdded( folderContentsType( KMail::ContentsTypeContact ), mContacts->location(), mContacts->label(),
true,
false );
1876 subresourceAdded( folderContentsType( KMail::ContentsTypeNote ), mNotes->location(), mNotes->label(),
true,
false );
1877 }
else if ( groupwareType == KMAcctCachedImap::GroupwareScalix ) {
1879 mUseResourceIMAP =
true;
1880 mFolderParentDir = folderParentDir;
1881 mFolderParent = folderParent;
1883 mHideFolders =
false;
1889 mCalendar = initScalixFolder( KMail::ContentsTypeCalendar );
1890 mTasks = initScalixFolder( KMail::ContentsTypeTask );
1892 mContacts = initScalixFolder( KMail::ContentsTypeContact );
1893 mNotes = initScalixFolder( KMail::ContentsTypeNote );
1896 if ( mCalendar->folderType() == KMFolderTypeCachedImap )
1897 static_cast<KMFolderCachedImap *
>( mCalendar->storage() )->updateAnnotationFolderType();
1898 if ( mTasks->folderType() == KMFolderTypeCachedImap )
1899 static_cast<KMFolderCachedImap *
>( mTasks->storage() )->updateAnnotationFolderType();
1900 if ( mContacts->folderType() == KMFolderTypeCachedImap )
1901 static_cast<KMFolderCachedImap *
>( mContacts->storage() )->updateAnnotationFolderType();
1902 if ( mNotes->folderType() == KMFolderTypeCachedImap )
1903 static_cast<KMFolderCachedImap *
>( mNotes->storage() )->updateAnnotationFolderType();
1908 kdDebug(5006) << k_funcinfo <<
"mCalendar=" << mCalendar <<
" " << mCalendar->location() << endl;
1909 kdDebug(5006) << k_funcinfo <<
"mContacts=" << mContacts <<
" " << mContacts->location() << endl;
1910 kdDebug(5006) << k_funcinfo <<
"mNotes=" << mNotes <<
" " << mNotes->location() << endl;
1913 TQStringList folderNames;
1914 TQValueList<TQGuardedPtr<KMFolder> > folderList;
1915 kmkernel->dimapFolderMgr()->createFolderList(&folderNames, &folderList);
1916 TQValueList<TQGuardedPtr<KMFolder> >::iterator it;
1917 for(it = folderList.begin(); it != folderList.end(); ++it)
1921 if ( (*it)->folderType() == KMFolderTypeCachedImap ) {
1922 KMFolderCachedImap *imapFolder =
static_cast<KMFolderCachedImap*
>( storage );
1924 const TQString attributes = imapFolder->folderAttributes();
1925 if ( attributes.contains(
"X-FolderClass" ) ) {
1926 if ( !attributes.contains(
"X-SpecialFolder" ) || (*it)->location().contains(
"@" ) ) {
1928 if ( !parser.folderClass().isEmpty() ) {
1929 FolderContentsType type = Scalix::Utils::scalixIdToContentsType( parser.folderClass() );
1930 imapFolder->setContentsType( type );
1940 mExtraFolders.remove( mCalendar->location() );
1941 mExtraFolders.remove( mTasks->location() );
1942 mExtraFolders.remove( mContacts->location() );
1943 mExtraFolders.remove( mNotes->location() );
1947 subresourceAdded( folderContentsType( KMail::ContentsTypeCalendar ), mCalendar->location(), mCalendar->label(),
true,
true );
1948 subresourceAdded( folderContentsType( KMail::ContentsTypeTask ), mTasks->location(), mTasks->label(),
true,
true );
1949 subresourceAdded( folderContentsType( KMail::ContentsTypeContact ), mContacts->location(), mContacts->label(),
true,
false );
1950 subresourceAdded( folderContentsType( KMail::ContentsTypeNote ), mNotes->location(), mNotes->label(),
true,
false );
1953 TDEConfig *config = kmkernel->config();
1954 config->setGroup(
"Resource UINames");
1955 *KMailICalIfaceImpl::mSubResourceUINamesMap = config->entryMap(
"Resource UINames" );
1960 void KMailICalIfaceImpl::slotCheckDone()
1962 TQString parentName = GlobalSettings::self()->theIMAPResourceFolderParent();
1963 KMFolder* folderParent = kmkernel->findFolderById( parentName );
1967 KMAccount* account = kmkernel->acctMgr()->find( GlobalSettings::self()->theIMAPResourceAccount() );
1969 disconnect( account, TQ_SIGNAL( finishedCheck(
bool, CheckStatus ) ),
1970 this, TQ_SLOT( slotCheckDone() ) );
1975 KMFolder* KMailICalIfaceImpl::initFolder( KMail::FolderContentsType contentsType )
1978 KMFolderType type = mFolderType;
1979 if( type == KMFolderTypeUnknown ) type = KMFolderTypeMaildir;
1981 KFolderTreeItem::Type itemType = s_folderContentsType[contentsType].treeItemType;
1985 StandardFolderSearchResult result = findStandardResourceFolder( mFolderParentDir, contentsType );
1988 if ( result.folders.count() > 1 && result.found == StandardFolderSearchResult::FoundAndStandard ) {
1989 TQStringList labels;
1990 for ( TQValueList<KMFolder*>::ConstIterator it = result.folders.begin(); it != result.folders.end(); ++it )
1991 labels << (*it)->prettyURL();
1992 const TQString selected = KInputDialog::getItem( i18n(
"Default folder"),
1993 i18n(
"There are multiple %1 default folders, please choose one:")
1994 .arg( localizedDefaultFolderName( contentsType ) ), labels );
1995 if ( !selected.isEmpty() )
1996 result.folder = result.folders[ labels.findIndex( selected ) ];
2004 mFolderParentDir->
createFolder( localizedDefaultFolderName( contentsType ),
false, type );
2005 if( mFolderType == KMFolderTypeImap ) {
2006 KMFolderImap* parentFolder =
static_cast<KMFolderImap*
>( mFolderParent->storage() );
2007 parentFolder->createFolder( localizedDefaultFolderName( contentsType ) );
2008 static_cast<KMFolderImap*
>( folder->storage() )->setAccount( parentFolder->account() );
2013 FolderInfo info = readFolderInfo( folder );
2014 mFolderInfoMap.insert( folder, info );
2019 KMessageBox::sorry(0, i18n(
"You do not have read/write permission to your %1 folder.")
2024 folder->setSystemFolder(
true );
2026 folder->
open(
"ifacefolder");
2027 connectFolder( folder );
2031 KMFolder* KMailICalIfaceImpl::initScalixFolder( KMail::FolderContentsType contentsType )
2034 KMFolderType type = mFolderType;
2035 if( type == KMFolderTypeUnknown ) type = KMFolderTypeMaildir;
2040 TQStringList folderNames;
2041 TQValueList<TQGuardedPtr<KMFolder> > folderList;
2042 Q_ASSERT( kmkernel );
2043 Q_ASSERT( kmkernel->dimapFolderMgr() );
2044 kmkernel->dimapFolderMgr()->createFolderList(&folderNames, &folderList);
2045 TQValueList<TQGuardedPtr<KMFolder> >::iterator it = folderList.begin();
2046 for(; it != folderList.end(); ++it)
2050 if ( (*it)->folderType() == KMFolderTypeCachedImap ) {
2051 KMFolderCachedImap *imapFolder =
static_cast<KMFolderCachedImap*
>( storage );
2053 const TQString attributes = imapFolder->folderAttributes();
2054 if ( attributes.contains(
"X-SpecialFolder" ) ) {
2056 if ( contentsType == Scalix::Utils::scalixIdToContentsType( parser.folderClass() ) ) {
2067 FolderInfo info = readFolderInfo( folder );
2068 mFolderInfoMap.insert( folder, info );
2073 KMessageBox::sorry(0, i18n(
"You do not have read/write permission to your folder.") );
2077 folder->setSystemFolder(
true );
2079 folder->
open(
"scalixfolder" );
2080 connectFolder( folder );
2084 void KMailICalIfaceImpl::connectFolder(
KMFolder* folder )
2087 disconnect( folder, TQ_SIGNAL( msgAdded(
KMFolder*, TQ_UINT32 ) ),
2088 this, TQ_SLOT( slotIncidenceAdded(
KMFolder*, TQ_UINT32 ) ) );
2089 disconnect( folder, TQ_SIGNAL( msgRemoved(
KMFolder*, TQ_UINT32 ) ),
2090 this, TQ_SLOT( slotIncidenceDeleted(
KMFolder*, TQ_UINT32 ) ) );
2091 disconnect( folder, TQ_SIGNAL( expunged(
KMFolder* ) ),
2092 this, TQ_SLOT( slotRefreshFolder(
KMFolder* ) ) );
2093 disconnect( folder->storage(), TQ_SIGNAL( readOnlyChanged(
KMFolder* ) ),
2094 this, TQ_SLOT( slotFolderPropertiesChanged(
KMFolder* ) ) );
2095 disconnect( folder, TQ_SIGNAL( nameChanged() ),
2096 this, TQ_SLOT( slotFolderRenamed() ) );
2097 disconnect( folder->storage(), TQ_SIGNAL( locationChanged(
const TQString&,
const TQString&) ),
2098 this, TQ_SLOT( slotFolderLocationChanged(
const TQString&,
const TQString&) ) );
2101 connect( folder, TQ_SIGNAL( msgAdded(
KMFolder*, TQ_UINT32 ) ),
2102 this, TQ_SLOT( slotIncidenceAdded(
KMFolder*, TQ_UINT32 ) ) );
2103 connect( folder, TQ_SIGNAL( msgRemoved(
KMFolder*, TQ_UINT32 ) ),
2104 this, TQ_SLOT( slotIncidenceDeleted(
KMFolder*, TQ_UINT32 ) ) );
2105 connect( folder, TQ_SIGNAL( expunged(
KMFolder* ) ),
2106 this, TQ_SLOT( slotRefreshFolder(
KMFolder* ) ) );
2107 connect( folder->storage(), TQ_SIGNAL( readOnlyChanged(
KMFolder* ) ),
2108 this, TQ_SLOT( slotFolderPropertiesChanged(
KMFolder* ) ) );
2109 connect( folder, TQ_SIGNAL( nameChanged() ),
2110 this, TQ_SLOT( slotFolderRenamed() ) );
2111 connect( folder->storage(), TQ_SIGNAL( locationChanged(
const TQString&,
const TQString&) ),
2112 this, TQ_SLOT( slotFolderLocationChanged(
const TQString&,
const TQString&) ) );
2119 folder->setSystemFolder(
false );
2120 folder->disconnect( _this );
2121 folder->
close(
"ifacefolder");
2127 cleanupFolder( mContacts,
this );
2128 cleanupFolder( mCalendar,
this );
2129 cleanupFolder( mNotes,
this );
2130 cleanupFolder( mTasks,
this );
2131 cleanupFolder( mJournals,
this );
2133 mContacts = mCalendar = mNotes = mTasks = mJournals = 0;
2138 if( !mUseResourceIMAP )
2141 if( type == KFolderTreeItem::Contacts )
2142 return TQString::fromLatin1(
"kmgroupware_folder_contacts" );
2143 else if( type == KFolderTreeItem::Calendar )
2144 return TQString::fromLatin1(
"kmgroupware_folder_calendar" );
2145 else if( type == KFolderTreeItem::Notes )
2146 return TQString::fromLatin1(
"kmgroupware_folder_notes" );
2147 else if( type == KFolderTreeItem::Tasks )
2148 return TQString::fromLatin1(
"kmgroupware_folder_tasks" );
2149 else if( type == KFolderTreeItem::Journals )
2150 return TQString::fromLatin1(
"kmgroupware_folder_journals" );
2155 static void reloadFolderTree()
2158 kmkernel->folderMgr()->contentsChanged();
2164 static void vPartMicroParser(
const TQString& str, TQString& s )
2167 uint len = str.length();
2169 for( uint i=0; i<len; ++i){
2170 if( str[i] ==
'\r' || str[i] ==
'\n' ){
2171 if( str[i] ==
'\r' )
2173 if( i+1 < len && str[i+1] ==
' ' ){
2178 if( line.startsWith( s ) ) {
2179 s = line.mid( s.length() + 1 );
2194 static TQValueList<KMFolder*> findFolderByAnnotation(
KMFolderDir* folderParentDir,
const TQString& annotation )
2196 TQValueList<KMFolder*> rv;
2197 TQPtrListIterator<KMFolderNode> it( *folderParentDir );
2198 for ( ; it.current(); ++it ) {
2199 if ( !it.current()->isDir() ) {
2201 if ( folder->
folderType() == KMFolderTypeCachedImap ) {
2202 TQString folderAnnotation =
static_cast<KMFolderCachedImap*
>( folder->storage() )->annotationFolderType();
2204 if ( folderAnnotation == annotation )
2205 rv.append( folder );
2212 KMailICalIfaceImpl::StandardFolderSearchResult KMailICalIfaceImpl::findStandardResourceFolder(
KMFolderDir* folderParentDir, KMail::FolderContentsType contentsType )
2214 if ( GlobalSettings::self()->theIMAPResourceStorageFormat() == GlobalSettings::EnumTheIMAPResourceStorageFormat::XML )
2217 TQValueList<KMFolder*> folders = findFolderByAnnotation( folderParentDir, TQString( s_folderContentsType[contentsType].annotation ) +
".default" );
2218 if ( !folders.isEmpty() )
2219 return StandardFolderSearchResult( folders, StandardFolderSearchResult::FoundAndStandard );
2222 folders = findFolderByAnnotation( folderParentDir, TQString( s_folderContentsType[contentsType].annotation ) );
2223 if ( !folders.isEmpty() )
2224 return StandardFolderSearchResult( folders, StandardFolderSearchResult::FoundByType );
2227 KMFolderNode* node = folderParentDir->
hasNamedFolder( localizedDefaultFolderName( contentsType ) );
2228 if ( node && !node->isDir() )
2229 return StandardFolderSearchResult(
static_cast<KMFolder *
>( node ), StandardFolderSearchResult::FoundByName );
2231 kdDebug(5006) <<
"findStandardResourceFolder: found no resource folder for " << s_folderContentsType[contentsType].annotation << endl;
2232 return StandardFolderSearchResult( 0, StandardFolderSearchResult::NotFound );
2236 KFolderTreeItem::Type itemType = s_folderContentsType[contentsType].treeItemType;
2237 unsigned int folderLanguage = GlobalSettings::self()->theIMAPResourceFolderLanguage();
2238 if( folderLanguage > 3 ) folderLanguage = 0;
2240 if ( !node || node->isDir() )
2241 return StandardFolderSearchResult( 0, StandardFolderSearchResult::NotFound );
2242 return StandardFolderSearchResult(
static_cast<KMFolder*
>( node ), StandardFolderSearchResult::FoundAndStandard );
2250 bool KMailICalIfaceImpl::folderIsAlarmRelevant(
const KMFolder *folder )
2252 bool administerRights =
true;
2253 bool relevantForOwner =
true;
2254 bool relevantForEveryone =
false;
2255 if ( folder->
folderType() == KMFolderTypeImap ) {
2256 const KMFolderImap *imapFolder =
static_cast<const KMFolderImap*
>( folder->storage() );
2259 imapFolder->userRights() & KMail::ACLJobs::Administer;
2261 if ( folder->
folderType() == KMFolderTypeCachedImap ) {
2262 const KMFolderCachedImap *dimapFolder =
static_cast<const KMFolderCachedImap*
>( folder->storage() );
2265 dimapFolder->userRights() & KMail::ACLJobs::Administer;
2266 relevantForOwner = !dimapFolder->alarmsBlocked() && ( dimapFolder->incidencesFor () == KMFolderCachedImap::IncForAdmins );
2267 relevantForEveryone = !dimapFolder->alarmsBlocked() && ( dimapFolder->incidencesFor() == KMFolderCachedImap::IncForReaders );
2270 kdDebug(5006) << k_funcinfo << endl;
2271 kdDebug(5006) <<
"Folder: " << folder->
label() <<
" has administer rights: " << administerRights << endl;
2272 kdDebug(5006) <<
"and is relevant for owner: " << relevantForOwner << endl;
2273 kdDebug(5006) <<
"and relevant for everyone: " << relevantForEveryone << endl;
2275 return ( administerRights && relevantForOwner ) || relevantForEveryone;
2278 void KMailICalIfaceImpl::setResourceQuiet(
bool q)
2283 bool KMailICalIfaceImpl::isResourceQuiet()
const
2285 return mResourceQuiet;
2289 bool KMailICalIfaceImpl::addSubresource(
const TQString& resource,
2290 const TQString& parent,
2291 const TQString& contentsType )
2293 kdDebug(5006) <<
"Adding subresource to parent: " << parent <<
" with name: " << resource << endl;
2294 kdDebug(5006) <<
"contents type: " << contentsType << endl;
2295 KMFolder *folder = findResourceFolder( parent );
2297 if ( !parentFolderDir || parentFolderDir->
hasNamedFolder( resource ) )
return false;
2301 KMessageBox::error( 0, msg );
2305 KMFolderType type = mFolderType;
2306 if( type == KMFolderTypeUnknown ) type = KMFolderTypeMaildir;
2309 if ( !newFolder )
return false;
2310 if( mFolderType == KMFolderTypeImap )
2311 static_cast<KMFolderImap*
>( folder->storage() )->createFolder( resource );
2313 StorageFormat defaultFormat = GlobalSettings::self()->theIMAPResourceStorageFormat() == GlobalSettings::EnumTheIMAPResourceStorageFormat::XML ? StorageXML : StorageIcalVcard;
2314 setStorageFormat( newFolder, folder ? storageFormat( folder ) : defaultFormat );
2315 newFolder->storage()->
setContentsType( folderContentsType( contentsType ) );
2317 newFolder->
open(
"ical_subresource" );
2318 connectFolder( newFolder );
2324 bool KMailICalIfaceImpl::removeSubresource(
const TQString& location )
2326 kdDebug(5006) << k_funcinfo << endl;
2328 KMFolder *folder = findResourceFolder( location );
2333 if ( !folder || isStandardResourceFolder( folder ) )
2338 subresourceDeleted( folderContentsType( folder->storage()->
contentsType() ), location );
2339 mExtraFolders.remove( location );
2340 folder->disconnect(
this );
2342 if ( folder->
folderType() == KMFolderTypeImap )
2343 kmkernel->imapFolderMgr()->remove( folder );
2344 else if ( folder->
folderType() == KMFolderTypeCachedImap ) {
2346 KMFolderCachedImap* storage =
static_cast<KMFolderCachedImap*
>( folder->storage() );
2347 KMAcctCachedImap* acct = storage->account();
2349 acct->addDeletedFolder( folder );
2350 kmkernel->dimapFolderMgr()->remove( folder );
2355 void KMailICalIfaceImpl::syncFolder(
KMFolder * folder)
const
2357 if ( kmkernel->isOffline() || !GlobalSettings::immediatlySyncDIMAPOnGroupwareChanges() )
2359 KMFolderCachedImap *dimapFolder =
dynamic_cast<KMFolderCachedImap*
>( folder->storage() );
2363 if ( dimapFolder->imapPath().isEmpty() ) {
2364 if ( folder->parent() && folder->parent()->owner() )
2365 syncFolder( folder->parent()->owner() );
2369 dimapFolder->account()->processNewMailInFolder( folder );
2372 #include "kmailicalifaceimpl.moc"