00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #ifdef HAVE_CONFIG_H
00036 #include <config.h>
00037 #endif
00038
00039 #include "kmailicalifaceimpl.h"
00040 #include "kmfolder.h"
00041 #include "kmfoldertree.h"
00042 #include "kmfolderdir.h"
00043 #include "kmgroupware.h"
00044 #include "kmfoldermgr.h"
00045 #include "kmcommands.h"
00046 #include "kmfolderindex.h"
00047 #include "kmmsgdict.h"
00048 #include "kmmsgpart.h"
00049 using KMail::AccountManager;
00050 #include "kmfolderimap.h"
00051 #include "globalsettings.h"
00052 #include "accountmanager.h"
00053 #include "kmfoldercachedimap.h"
00054 #include "kmacctcachedimap.h"
00055 #include "acljobs.h"
00056
00057 #include "scalix.h"
00058
00059 #include <mimelib/enum.h>
00060 #include <mimelib/utility.h>
00061 #include <mimelib/body.h>
00062 #include <mimelib/mimepp.h>
00063
00064 #include <tqfile.h>
00065 #include <tqmap.h>
00066 #include <tqtextcodec.h>
00067
00068 #include <kdebug.h>
00069 #include <kiconloader.h>
00070 #include <kinputdialog.h>
00071 #include <dcopclient.h>
00072 #include <tdemessagebox.h>
00073 #include <tdeconfig.h>
00074 #include <kurl.h>
00075 #include <tdetempfile.h>
00076
00077 using namespace KMail;
00078
00079 TQMap<TQString, TQString> *KMailICalIfaceImpl::mSubResourceUINamesMap = new TQMap<TQString, TQString>;
00080
00081
00082 static void vPartMicroParser( const TQString& str, TQString& s );
00083 static void reloadFolderTree();
00084
00085
00086 static const struct {
00087 const char* contentsTypeStr;
00088 const char* mimetype;
00089 KFolderTreeItem::Type treeItemType;
00090 const char* annotation;
00091 const char* translatedName;
00092 } s_folderContentsType[] = {
00093 { "Mail", "application/x-vnd.kolab.mail", KFolderTreeItem::Other, "mail", I18N_NOOP( "Mail" ) },
00094 { "Calendar", "application/x-vnd.kolab.event", KFolderTreeItem::Calendar, "event", I18N_NOOP( "Calendar" ) },
00095 { "Contact", "application/x-vnd.kolab.contact", KFolderTreeItem::Contacts, "contact", I18N_NOOP( "Contacts" ) },
00096 { "Note", "application/x-vnd.kolab.note", KFolderTreeItem::Notes, "note", I18N_NOOP( "Notes" ) },
00097 { "Task", "application/x-vnd.kolab.task", KFolderTreeItem::Tasks, "task", I18N_NOOP( "Tasks" ) },
00098 { "Journal", "application/x-vnd.kolab.journal", KFolderTreeItem::Journals, "journal", I18N_NOOP( "Journal" ) }
00099 };
00100
00101 static TQString folderContentsType( KMail::FolderContentsType type )
00102 {
00103 return s_folderContentsType[type].contentsTypeStr;
00104 }
00105
00106 static TQString folderKolabMimeType( KMail::FolderContentsType type )
00107 {
00108 return s_folderContentsType[type].mimetype;
00109 }
00110
00111 KMailICalIfaceImpl::StorageFormat KMailICalIfaceImpl::globalStorageFormat() const {
00112 return GlobalSettings::self()->theIMAPResourceStorageFormat()
00113 == GlobalSettings::EnumTheIMAPResourceStorageFormat::XML ? StorageXML : StorageIcalVcard;
00114 }
00115
00116 static KMail::FolderContentsType folderContentsType( const TQString& type )
00117 {
00118 for ( uint i = 0 ; i < sizeof s_folderContentsType / sizeof *s_folderContentsType; ++i )
00119 if ( type == s_folderContentsType[i].contentsTypeStr )
00120 return static_cast<KMail::FolderContentsType>( i );
00121 return KMail::ContentsTypeMail;
00122 }
00123
00124 static TQString localizedDefaultFolderName( KMail::FolderContentsType type )
00125 {
00126 return i18n( s_folderContentsType[type].translatedName );
00127 }
00128
00129 const char* KMailICalIfaceImpl::annotationForContentsType( KMail::FolderContentsType type )
00130 {
00131 return s_folderContentsType[type].annotation;
00132 }
00133
00134 ExtraFolder::ExtraFolder( KMFolder* f )
00135 : folder( f )
00136 {
00137 folder->open("kmailicaliface::extrafolder");
00138 }
00139
00140 ExtraFolder::~ExtraFolder()
00141 {
00142 if ( folder )
00143 folder->close("kmailicaliface::extrafolder");
00144 }
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157 KMailICalIfaceImpl::KMailICalIfaceImpl()
00158 : DCOPObject( "KMailICalIface" ), TQObject( 0, "KMailICalIfaceImpl" ),
00159 mContacts( 0 ), mCalendar( 0 ), mNotes( 0 ), mTasks( 0 ), mJournals( 0 ),
00160 mFolderLanguage( 0 ), mFolderParentDir( 0 ), mFolderType( KMFolderTypeUnknown ),
00161 mUseResourceIMAP( false ), mResourceQuiet( false ), mHideFolders( true )
00162 {
00163
00164 connect( kmkernel, TQT_SIGNAL( configChanged() ), this, TQT_SLOT( readConfig() ) );
00165 connect( kmkernel, TQT_SIGNAL( folderRemoved( KMFolder* ) ),
00166 this, TQT_SLOT( slotFolderRemoved( KMFolder* ) ) );
00167
00168 mExtraFolders.setAutoDelete( true );
00169 mAccumulators.setAutoDelete( true );
00170 }
00171
00172
00173
00174
00175
00176
00177
00178 static DwBodyPart* findBodyPartByMimeType( const KMMessage& msg, const char* sType, const char* sSubtype, bool startsWith = false )
00179 {
00180
00181
00182 DwBodyPart* part = msg.getFirstDwBodyPart();
00183 while( part ){
00184
00185
00186 if ( part->hasHeaders() ) {
00187 DwMediaType& contentType = part->Headers().ContentType();
00188 if ( startsWith ) {
00189 if ( contentType.TypeStr() == sType
00190 && TQString( contentType.SubtypeStr().c_str() ).startsWith( sSubtype ) )
00191 return part;
00192 }
00193 else
00194 if ( contentType.TypeStr() == sType
00195 && contentType.SubtypeStr() == sSubtype )
00196 return part;
00197 }
00198 part = part->Next();
00199 }
00200 return 0;
00201 }
00202
00203
00204 static DwBodyPart* findBodyPart( const KMMessage& msg, const TQString& attachmentName )
00205 {
00206
00207
00208 for ( DwBodyPart* part = msg.getFirstDwBodyPart(); part; part = part->Next() ) {
00209
00210 if ( part->hasHeaders()
00211 && attachmentName == part->Headers().ContentDisposition().Filename().c_str() )
00212 return part;
00213 if ( part->hasHeaders() && attachmentName == part->Headers().ContentType().Name().c_str() )
00214 return part;
00215 }
00216 return 0;
00217 }
00218
00219 #if 0
00220 static void debugBodyParts( const char* foo, const KMMessage& msg )
00221 {
00222 kdDebug(5006) << "--debugBodyParts " << foo << "--" << endl;
00223 for ( DwBodyPart* part = msg.getFirstDwBodyPart(); part; part = part->Next() ) {
00224 if ( part->hasHeaders() ) {
00225 kdDebug(5006) << " bodypart: " << part << endl;
00226 kdDebug(5006) << " " << part->Headers().AsString().c_str() << endl;
00227 }
00228 else
00229 kdDebug(5006) << " part " << part << " has no headers" << endl;
00230 }
00231 }
00232 #else
00233 inline static void debugBodyParts( const char*, const KMMessage& ) {}
00234 #endif
00235
00236
00237
00238
00239
00240
00241 bool KMailICalIfaceImpl::updateAttachment( KMMessage& msg,
00242 const TQString& attachmentURL,
00243 const TQString& attachmentName,
00244 const TQString& attachmentMimetype,
00245 bool lookupByName )
00246 {
00247 kdDebug(5006) << "KMailICalIfaceImpl::updateAttachment( " << attachmentURL << " )" << endl;
00248
00249 bool bOK = false;
00250
00251 KURL url( attachmentURL );
00252 if ( url.isValid() && url.isLocalFile() ) {
00253 const TQString fileName( url.path() );
00254 TQFile file( fileName );
00255 if( file.open( IO_ReadOnly ) ) {
00256 TQByteArray rawData = file.readAll();
00257 file.close();
00258
00259
00260 KMMessagePart msgPart;
00261 msgPart.setName( attachmentName );
00262
00263 const int iSlash = attachmentMimetype.find('/');
00264 const TQCString sType = attachmentMimetype.left( iSlash ).latin1();
00265 const TQCString sSubtype = attachmentMimetype.mid( iSlash+1 ).latin1();
00266 msgPart.setTypeStr( sType );
00267 msgPart.setSubtypeStr( sSubtype );
00268 TQCString ctd("attachment;\n filename=\"");
00269 ctd.append( attachmentName.latin1() );
00270 ctd.append("\"");
00271 msgPart.setContentDisposition( ctd );
00272 TQValueList<int> dummy;
00273 msgPart.setBodyAndGuessCte( rawData, dummy );
00274 msgPart.setPartSpecifier( fileName );
00275
00276 DwBodyPart* newPart = msg.createDWBodyPart( &msgPart );
00277
00278
00279
00280 newPart->Headers().ContentDisposition().Parse();
00281
00282 DwBodyPart* part = lookupByName ? findBodyPart( msg, attachmentName )
00283 : findBodyPartByMimeType( msg, sType, sSubtype );
00284 if ( part ) {
00285
00286
00287 newPart->SetNext( part->Next() );
00288
00289
00290 *part = *newPart;
00291 delete newPart;
00292 msg.setNeedsAssembly();
00293 kdDebug(5006) << "Attachment " << attachmentName << " updated." << endl;
00294 } else {
00295 msg.addDwBodyPart( newPart );
00296 kdDebug(5006) << "Attachment " << attachmentName << " added." << endl;
00297 }
00298 bOK = true;
00299 }else{
00300 kdDebug(5006) << "Attachment " << attachmentURL << " can not be read." << endl;
00301 }
00302 }else{
00303 kdDebug(5006) << "Attachment " << attachmentURL << " not a local file." << endl;
00304 }
00305
00306 return bOK;
00307 }
00308
00309
00310 bool KMailICalIfaceImpl::kolabXMLFoundAndDecoded( const KMMessage& msg, const TQString& mimetype, TQString& s )
00311 {
00312 const int iSlash = mimetype.find('/');
00313 const TQCString sType = mimetype.left( iSlash ).latin1();
00314 const TQCString sSubtype = mimetype.mid( iSlash+1 ).latin1();
00315 DwBodyPart* part = findBodyPartByMimeType( msg, sType, sSubtype, true );
00316 if ( part ) {
00317 KMMessagePart msgPart;
00318 KMMessage::bodyPart(part, &msgPart);
00319 s = msgPart.bodyToUnicode( TQTextCodec::codecForName( "utf8" ) );
00320 return true;
00321 }
00322 return false;
00323 }
00324
00325
00326
00327
00328
00329
00330
00331 bool KMailICalIfaceImpl::deleteAttachment( KMMessage& msg,
00332 const TQString& attachmentName )
00333 {
00334 kdDebug(5006) << "KMailICalIfaceImpl::deleteAttachment( " << attachmentName << " )" << endl;
00335
00336 bool bOK = false;
00337
00338
00339
00340 DwBodyPart* part = findBodyPart( msg, attachmentName );
00341 if ( part ) {
00342 msg.getTopLevelPart()->Body().RemoveBodyPart( part );
00343 delete part;
00344 msg.setNeedsAssembly();
00345 kdDebug(5006) << "Attachment deleted." << endl;
00346 bOK = true;
00347 }
00348
00349 if( !bOK ){
00350 kdDebug(5006) << "Attachment " << attachmentName << " not found." << endl;
00351 }
00352
00353 return bOK;
00354 }
00355
00356 static void setIcalVcardContentTypeHeader( KMMessage *msg, KMail::FolderContentsType t, KMFolder *folder )
00357 {
00358 KMAcctCachedImap::GroupwareType groupwareType = KMAcctCachedImap::GroupwareKolab;
00359
00360 KMFolderCachedImap *imapFolder = dynamic_cast<KMFolderCachedImap*>( folder->storage() );
00361 if ( imapFolder )
00362 groupwareType = imapFolder->account()->groupwareType();
00363
00364 msg->setType( DwMime::kTypeText );
00365 if ( t == KMail::ContentsTypeCalendar || t == KMail::ContentsTypeTask
00366 || t == KMail::ContentsTypeJournal ) {
00367 msg->setSubtype( DwMime::kSubtypeVCal );
00368
00369 if ( groupwareType == KMAcctCachedImap::GroupwareKolab )
00370 msg->setHeaderField("Content-Type",
00371 "text/calendar; method=REQUEST; charset=\"utf-8\"");
00372 else if ( groupwareType == KMAcctCachedImap::GroupwareScalix )
00373 msg->setHeaderField("Content-Type",
00374 "text/calendar; method=PUBLISH; charset=\"UTF-8\"");
00375
00376 } else if ( t == KMail::ContentsTypeContact ) {
00377 msg->setSubtype( DwMime::kSubtypeXVCard );
00378 if ( groupwareType == KMAcctCachedImap::GroupwareKolab )
00379 msg->setHeaderField( "Content-Type", "Text/X-VCard; charset=\"utf-8\"" );
00380 else if ( groupwareType == KMAcctCachedImap::GroupwareScalix )
00381 msg->setHeaderField( "Content-Type", "application/scalix-properties; charset=\"UTF-8\"" );
00382 } else {
00383 kdWarning(5006) << k_funcinfo << "Attempt to write non-groupware contents to folder" << endl;
00384 }
00385 }
00386
00387 static void setXMLContentTypeHeader( KMMessage *msg, const TQString plainTextBody )
00388 {
00389
00390
00391
00392 KMMessagePart firstPart;
00393 firstPart.setType( DwMime::kTypeText );
00394 firstPart.setSubtype( DwMime::kSubtypePlain );
00395 msg->removeHeaderField( "Content-Type" );
00396 msg->setType( DwMime::kTypeMultipart );
00397 msg->setSubtype( DwMime::kSubtypeMixed );
00398 msg->headers().ContentType().CreateBoundary( 0 );
00399 msg->headers().ContentType().Assemble();
00400 firstPart.setBodyFromUnicode( plainTextBody );
00401 msg->addBodyPart( &firstPart );
00402 }
00403
00404
00405 TQ_UINT32 KMailICalIfaceImpl::addIncidenceKolab( KMFolder& folder,
00406 const TQString& subject,
00407 const TQString& plainTextBody,
00408 const TQMap<TQCString, TQString>& customHeaders,
00409 const TQStringList& attachmentURLs,
00410 const TQStringList& attachmentNames,
00411 const TQStringList& attachmentMimetypes )
00412 {
00413 kdDebug(5006) << "KMailICalIfaceImpl::addIncidenceKolab( " << attachmentNames << " )" << endl;
00414
00415 TQ_UINT32 sernum = 0;
00416 bool bAttachOK = true;
00417
00418
00419 KMMessage* msg = new KMMessage();
00420 msg->initHeader();
00421 msg->setSubject( subject );
00422 msg->setAutomaticFields( true );
00423
00424 TQMap<TQCString, TQString>::ConstIterator ith = customHeaders.begin();
00425 const TQMap<TQCString, TQString>::ConstIterator ithEnd = customHeaders.end();
00426 for ( ; ith != ithEnd ; ++ith ) {
00427 msg->setHeaderField( ith.key(), ith.data() );
00428 }
00429
00430
00431 if ( storageFormat( &folder ) == StorageXML ) {
00432 setXMLContentTypeHeader( msg, plainTextBody );
00433 } else if ( storageFormat( &folder ) == StorageIcalVcard ) {
00434 const KMail::FolderContentsType t = folder.storage()->contentsType();
00435 setIcalVcardContentTypeHeader( msg, t, &folder );
00436 msg->setBodyEncoded( plainTextBody.utf8() );
00437 } else {
00438 kdWarning(5006) << k_funcinfo << "Attempt to write to folder with unknown storage type" << endl;
00439 }
00440
00441 Q_ASSERT( attachmentMimetypes.count() == attachmentURLs.count() );
00442 Q_ASSERT( attachmentNames.count() == attachmentURLs.count() );
00443
00444 TQStringList::ConstIterator itmime = attachmentMimetypes.begin();
00445 TQStringList::ConstIterator iturl = attachmentURLs.begin();
00446 for( TQStringList::ConstIterator itname = attachmentNames.begin();
00447 itname != attachmentNames.end()
00448 && itmime != attachmentMimetypes.end()
00449 && iturl != attachmentURLs.end();
00450 ++itname, ++iturl, ++itmime ){
00451 bool byname = !(*itmime).startsWith( "application/x-vnd.kolab." );
00452 if( !updateAttachment( *msg, *iturl, *itname, *itmime, byname ) ){
00453 kdWarning(5006) << "Attachment error, can not add Incidence." << endl;
00454 bAttachOK = false;
00455 break;
00456 }
00457 }
00458
00459 if( bAttachOK ){
00460
00461 msg->cleanupHeader();
00462
00463 msg->touch();
00464 if ( folder.addMsg( msg ) == 0 )
00465
00466 sernum = msg->getMsgSerNum();
00467 kdDebug(5006) << "addIncidenceKolab(): Message done and saved. Sernum: "
00468 << sernum << endl;
00469
00470
00471 addFolderChange( &folder, Contents );
00472 syncFolder( &folder );
00473 } else
00474 kdError(5006) << "addIncidenceKolab(): Message *NOT* saved!\n";
00475
00476 return sernum;
00477 }
00478
00479 bool KMailICalIfaceImpl::deleteIncidenceKolab( const TQString& resource,
00480 TQ_UINT32 sernum )
00481 {
00482
00483 if( !mUseResourceIMAP )
00484 return false;
00485
00486 kdDebug(5006) << "KMailICalIfaceImpl::deleteIncidenceKolab( "
00487 << resource << ", " << sernum << ")\n";
00488
00489
00490 KMFolder* f = findResourceFolder( resource );
00491 if( !f ) {
00492 kdError(5006) << "deleteIncidenceKolab(" << resource << ") : Not an IMAP resource folder" << endl;
00493 return false;
00494 }
00495
00496 bool rc = false;
00497
00498 KMMessage* msg = findMessageBySerNum( sernum, f );
00499 if( msg ) {
00500
00501 deleteMsg( msg );
00502 syncFolder( f );
00503 rc = true;
00504 } else {
00505 kdDebug(5006) << "Message not found, cannot remove serNum " << sernum << endl;
00506 }
00507 return rc;
00508 }
00509
00510
00511 int KMailICalIfaceImpl::incidencesKolabCount( const TQString& mimetype,
00512 const TQString& resource )
00513 {
00514 Q_UNUSED( mimetype );
00515
00516 if( !mUseResourceIMAP )
00517 return 0;
00518
00519 KMFolder* f = findResourceFolder( resource );
00520 if( !f ) {
00521 kdError(5006) << "incidencesKolab(" << resource << ") : Not an IMAP resource folder" << endl;
00522 return 0;
00523 }
00524
00525 f->open("kolabcount");
00526 int n = f->count();
00527 f->close("kolabcount");
00528 kdDebug(5006) << "KMailICalIfaceImpl::incidencesKolabCount( "
00529 << resource << " ) returned " << n << endl;
00530 return n;
00531 }
00532
00533 TQMap<TQ_UINT32, TQString> KMailICalIfaceImpl::incidencesKolab( const TQString& mimetype,
00534 const TQString& resource,
00535 int startIndex,
00536 int nbMessages )
00537 {
00541
00542 TQMap<TQ_UINT32, TQString> aMap;
00543 if( !mUseResourceIMAP )
00544 return aMap;
00545
00546 KMFolder* f = findResourceFolder( resource );
00547 if( !f ) {
00548 kdError(5006) << "incidencesKolab(" << resource << ") : Not an IMAP resource folder" << endl;
00549 return aMap;
00550 }
00551
00552 f->open( "incidences" );
00553
00554 kdDebug(5006) << k_funcinfo << "Getting incidences (" << mimetype << ") for folder " << f->label()
00555 << ", starting with index " << startIndex << ", " << nbMessages << " messages." << endl;
00556 kdDebug(5006) << "The folder has " << f->count() << " messages." << endl;
00557
00558 int stopIndex = nbMessages == -1 ? f->count() :
00559 TQMIN( f->count(), startIndex + nbMessages );
00560
00561 for(int i = startIndex; i < stopIndex; ++i) {
00562 #if 0
00563 bool unget = !f->isMessage(i);
00564 KMMessage* msg = f->getMsg( i );
00565 #else // faster
00566 KMMessage* msg = f->storage()->readTemporaryMsg(i);
00567 #endif
00568 if ( msg ) {
00569 const int iSlash = mimetype.find('/');
00570 const TQCString sType = mimetype.left( iSlash ).latin1();
00571 const TQCString sSubtype = mimetype.mid( iSlash+1 ).latin1();
00572 if ( sType.isEmpty() || sSubtype.isEmpty() ) {
00573 kdError(5006) << mimetype << " not an type/subtype combination" << endl;
00574 } else {
00575 DwBodyPart* dwPart = findBodyPartByMimeType( *msg, sType, sSubtype );
00576 if ( dwPart ) {
00577 KMMessagePart msgPart;
00578 KMMessage::bodyPart(dwPart, &msgPart);
00579 aMap.insert(msg->getMsgSerNum(), msgPart.bodyToUnicode( TQTextCodec::codecForName( "utf8" ) ));
00580 } else {
00581
00582
00583
00584 const TQCString type( msg->typeStr() );
00585 const TQCString subtype( msg->subtypeStr() );
00586 if (type.lower() == sType && subtype.lower() == sSubtype ) {
00587 aMap.insert( msg->getMsgSerNum(), msg->bodyToUnicode() );
00588 }
00589
00590
00591 }
00592 }
00593 #if 0
00594 if( unget ) f->unGetMsg(i);
00595 #else
00596 delete msg;
00597 #endif
00598 } else {
00599 kdDebug(5006) << k_funcinfo << " Unable to retrieve message " << i << " for incidence!" << endl;
00600 }
00601 }
00602 f->close( "incidences" );
00603 return aMap;
00604 }
00605
00606
00607
00608
00609
00610 void KMailICalIfaceImpl::slotMessageRetrieved( KMMessage* msg )
00611 {
00612 if( !msg ) return;
00613
00614 KMFolder *parent = msg->parent();
00615 Q_ASSERT( parent );
00616 TQ_UINT32 sernum = msg->getMsgSerNum();
00617
00618
00619 Accumulator *ac = mAccumulators.find( parent->location() );
00620 if( ac ) {
00621 TQString s;
00622 if ( !vPartFoundAndDecoded( msg, s ) ) return;
00623 TQString uid( "UID" );
00624 vPartMicroParser( s, uid );
00625 const TQ_UINT32 sernum = msg->getMsgSerNum();
00626 mUIDToSerNum.insert( uid, sernum );
00627 ac->add( s );
00628 if( ac->isFull() ) {
00629
00630
00631
00632 mAccumulators.remove( ac->folder );
00633 }
00634 } else {
00635
00636
00637 slotIncidenceAdded( msg->parent(), msg->getMsgSerNum() );
00638 }
00639
00640 if ( mTheUnGetMes.contains( sernum ) ) {
00641 mTheUnGetMes.remove( sernum );
00642 int i = 0;
00643 KMFolder* folder = 0;
00644 KMMsgDict::instance()->getLocation( sernum, &folder, &i );
00645 folder->unGetMsg( i );
00646 }
00647 }
00648
00649 static int dimapAccountCount()
00650 {
00651 KMail::AccountManager *mgr = kmkernel->acctMgr();
00652 KMAccount *account = mgr->first();
00653 int count = 0;
00654 while ( account ) {
00655 if ( dynamic_cast<KMAcctCachedImap*>( account ) )
00656 ++count;
00657 account = mgr->next();
00658 }
00659 return count;
00660 }
00661
00662 int KMailICalIfaceImpl::dimapAccounts()
00663 {
00664 return dimapAccountCount();
00665 }
00666
00667 static TQString subresourceLabelForPresentation( const KMFolder * folder )
00668 {
00669 if( KMailICalIfaceImpl::getResourceMap()->contains( folder->location() ) ) {
00670 return folder->label();
00671 }
00672
00673 TQString label = folder->prettyURL();
00674 TQStringList parts = TQStringList::split( TQString::fromLatin1("/"), label );
00675
00676
00677
00678
00679 if ( parts[1] == TQString::fromLatin1("user") ) {
00680 TQStringList remainder(parts);
00681 remainder.pop_front();
00682 remainder.pop_front();
00683 remainder.pop_front();
00684 label = i18n("%1's %2")
00685 .arg( parts[2] )
00686 .arg( remainder.join( TQString::fromLatin1("/") ) );
00687 }
00688
00689
00690 const KMFolder *parent = folder;
00691 while ( parent->parent() && parent->parent()->owner() ) {
00692 parent = parent->parent()->owner();
00693 if ( parent->isSystemFolder() ) {
00694 TQStringList remainder(parts);
00695 remainder.pop_front();
00696 remainder.pop_front();
00697 if ( dimapAccountCount() > 1 ) {
00698
00699 if( folder->storage() && static_cast<const KMFolderCachedImap*>( folder->storage() )->account() ) {
00700 label = i18n( "My %1 (%2)")
00701 .arg( remainder.join( TQString::fromLatin1("/") ),
00702 static_cast<const KMFolderCachedImap*>( folder->storage() )->account()->name() );
00703 } else {
00704 label = i18n("My %1")
00705 .arg( remainder.join( TQString::fromLatin1("/") ) );
00706 }
00707 } else {
00708 label = i18n("My %1")
00709 .arg( remainder.join( TQString::fromLatin1("/") ) );
00710 }
00711 break;
00712 }
00713 }
00714 return label;
00715 }
00716
00717
00718 TQValueList<KMailICalIfaceImpl::SubResource> KMailICalIfaceImpl::subresourcesKolab( const TQString& contentsType )
00719 {
00720 TQValueList<SubResource> subResources;
00721
00722
00723 KMFolder* f = folderFromType( contentsType, TQString() );
00724 if ( f ) {
00725 subResources.append( SubResource( f->location(), subresourceLabelForPresentation( f ),
00726 f->isWritable(), folderIsAlarmRelevant( f ) ) );
00727 kdDebug(5006) << "Adding(1) folder " << f->location() << " " <<
00728 ( !f->isWritable() ? "readonly" : "" ) << endl;
00729 }
00730
00731
00732 const KMail::FolderContentsType t = folderContentsType( contentsType );
00733 TQDictIterator<ExtraFolder> it( mExtraFolders );
00734 for ( ; it.current(); ++it ){
00735 f = it.current()->folder;
00736 if ( f && f->storage()->contentsType() == t ) {
00737 subResources.append( SubResource( f->location(), subresourceLabelForPresentation( f ),
00738 f->isWritable(), folderIsAlarmRelevant( f ) ) );
00739 kdDebug(5006) << "Adding(2) folder " << f->location() << " " <<
00740 ( !f->isWritable() ? "readonly" : "" ) << endl;
00741 }
00742 }
00743
00744 if ( subResources.isEmpty() )
00745 kdDebug(5006) << "subresourcesKolab: No folder found for " << contentsType << endl;
00746 return subResources;
00747 }
00748
00749 bool KMailICalIfaceImpl::triggerSync( const TQString& contentsType )
00750 {
00751 kdDebug(5006) << k_funcinfo << endl;
00752 TQValueList<KMailICalIfaceImpl::SubResource> folderList = subresourcesKolab( contentsType );
00753 for ( TQValueList<KMailICalIfaceImpl::SubResource>::const_iterator it( folderList.begin() ),
00754 end( folderList.end() );
00755 it != end ; ++it ) {
00756 KMFolder * const f = findResourceFolder( (*it).location );
00757 if ( !f ) continue;
00758 if ( f->folderType() == KMFolderTypeImap || f->folderType() == KMFolderTypeCachedImap ) {
00759 if ( !kmkernel->askToGoOnline() ) {
00760 return false;
00761 }
00762 }
00763
00764 if ( f->folderType() == KMFolderTypeImap ) {
00765 KMFolderImap *imap = static_cast<KMFolderImap*>( f->storage() );
00766 imap->getAndCheckFolder();
00767 } else if ( f->folderType() == KMFolderTypeCachedImap ) {
00768 KMFolderCachedImap* cached = static_cast<KMFolderCachedImap*>( f->storage() );
00769 if ( cached->account() ) {
00770 cached->account()->processNewMailInFolder( f );
00771 }
00772 }
00773 }
00774 return true;
00775 }
00776
00777
00778 bool KMailICalIfaceImpl::isWritableFolder( const TQString& type,
00779 const TQString& resource )
00780 {
00781 KMFolder* f = folderFromType( type, resource );
00782 if ( !f )
00783
00784 return false;
00785
00786 return f->isWritable();
00787 }
00788
00789
00790 KMailICalIfaceImpl::StorageFormat KMailICalIfaceImpl::storageFormat( const TQString& resource )
00791 {
00792 StorageFormat format;
00793 KMFolder* f = findResourceFolder( resource );
00794 if ( f )
00795 format = storageFormat( f );
00796 else
00797 format = globalStorageFormat();
00798 return format;
00799 }
00800
00815 TQ_UINT32 KMailICalIfaceImpl::update( const TQString& resource,
00816 TQ_UINT32 sernum,
00817 const TQString& subject,
00818 const TQString& plainTextBody,
00819 const TQMap<TQCString, TQString>& customHeaders,
00820 const TQStringList& attachmentURLs,
00821 const TQStringList& attachmentMimetypes,
00822 const TQStringList& attachmentNames,
00823 const TQStringList& deletedAttachments )
00824 {
00825 TQ_UINT32 rc = 0;
00826
00827 if( !mUseResourceIMAP )
00828 return rc;
00829
00830 Q_ASSERT( !resource.isEmpty() );
00831
00832 kdDebug(5006) << "KMailICalIfaceImpl::update( " << resource << ", " << sernum << " )\n";
00833 kdDebug(5006) << attachmentURLs << "\n";
00834 kdDebug(5006) << attachmentMimetypes << "\n";
00835 kdDebug(5006) << attachmentNames << "\n";
00836 kdDebug(5006) << "deleted attachments:" << deletedAttachments << "\n";
00837
00838
00839 KMFolder* f = findResourceFolder( resource );
00840 if( !f ) {
00841 kdError(5006) << "update(" << resource << ") : Not an IMAP resource folder" << endl;
00842 return rc;
00843 }
00844
00845 f->open( "ifaceupdate" );
00846
00847 KMMessage* msg = 0;
00848 if ( sernum != 0 ) {
00849 msg = findMessageBySerNum( sernum, f );
00850 if ( !msg ) return 0;
00851
00852 KMMessage* newMsg = new KMMessage( *msg );
00853 newMsg->setSubject( subject );
00854 TQMap<TQCString, TQString>::ConstIterator ith = customHeaders.begin();
00855 const TQMap<TQCString, TQString>::ConstIterator ithEnd = customHeaders.begin();
00856 for ( ; ith != ithEnd ; ++ith )
00857 newMsg->setHeaderField( ith.key(), ith.data() );
00858 newMsg->setParent( 0 );
00859
00860
00861
00862 for( TQStringList::ConstIterator it = deletedAttachments.begin();
00863 it != deletedAttachments.end();
00864 ++it ){
00865 if( !deleteAttachment( *newMsg, *it ) ){
00866
00867 }
00868 }
00869
00870 const KMail::FolderContentsType t = f->storage()->contentsType();
00871 const TQCString type = msg->typeStr();
00872 const TQCString subtype = msg->subtypeStr();
00873 const bool messageWasIcalVcardFormat = ( type.lower() == "text" &&
00874 ( subtype.lower() == "calendar" || subtype.lower() == "x-vcard" ) );
00875
00876 if ( storageFormat( f ) == StorageIcalVcard ) {
00877
00878 if ( !messageWasIcalVcardFormat ) {
00879 setIcalVcardContentTypeHeader( newMsg, t, f );
00880 }
00881 newMsg->setBodyEncoded( plainTextBody.utf8() );
00882 } else if ( storageFormat( f ) == StorageXML ) {
00883 if ( messageWasIcalVcardFormat ) {
00884
00885
00886 setXMLContentTypeHeader( newMsg, plainTextBody );
00887 }
00888
00889
00890 TQStringList::ConstIterator iturl = attachmentURLs.begin();
00891 TQStringList::ConstIterator itmime = attachmentMimetypes.begin();
00892 TQStringList::ConstIterator itname = attachmentNames.begin();
00893 for( ;
00894 iturl != attachmentURLs.end()
00895 && itmime != attachmentMimetypes.end()
00896 && itname != attachmentNames.end();
00897 ++iturl, ++itname, ++itmime ){
00898 bool byname = !(*itmime).startsWith( "application/x-vnd.kolab." );
00899 if( !updateAttachment( *newMsg, *iturl, *itname, *itmime, byname ) ){
00900 kdDebug(5006) << "Attachment error, can not update attachment " << *iturl << endl;
00901 break;
00902 }
00903 }
00904 }
00905
00906
00907
00908
00909 newMsg->cleanupHeader();
00910
00911
00912
00913 deleteMsg( msg );
00914 if ( f->addMsg( newMsg ) == 0 ) {
00915
00916 rc = newMsg->getMsgSerNum();
00917 kdDebug(5006) << "forget about " << sernum << ", it's " << rc << " now" << endl;
00918 }
00919 addFolderChange( f, Contents );
00920 syncFolder( f );
00921 } else {
00922
00923 rc = addIncidenceKolab( *f, subject, plainTextBody, customHeaders,
00924 attachmentURLs,
00925 attachmentNames,
00926 attachmentMimetypes );
00927 }
00928
00929 f->close("ifaceupdate");
00930 return rc;
00931 }
00932
00933 KURL KMailICalIfaceImpl::getAttachment( const TQString& resource,
00934 TQ_UINT32 sernum,
00935 const TQString& filename )
00936 {
00937
00938
00939
00940 if( !mUseResourceIMAP )
00941 return KURL();
00942
00943 kdDebug(5006) << "KMailICalIfaceImpl::getAttachment( "
00944 << resource << ", " << sernum << ", " << filename << " )\n";
00945
00946
00947 KMFolder* f = findResourceFolder( resource );
00948 if( !f ) {
00949 kdError(5006) << "getAttachment(" << resource << ") : Not an IMAP resource folder" << endl;
00950 return KURL();
00951 }
00952 if ( storageFormat( f ) != StorageXML ) {
00953 kdError(5006) << "getAttachment(" << resource << ") : Folder has wrong storage format " << storageFormat( f ) << endl;
00954 return KURL();
00955 }
00956
00957 KURL url;
00958
00959 bool bOK = false;
00960 bool quiet = mResourceQuiet;
00961 mResourceQuiet = true;
00962
00963 KMMessage* msg = findMessageBySerNum( sernum, f );
00964 if( msg ) {
00965
00966
00967 DwBodyPart* part = findBodyPart( *msg, filename );
00968 if ( part ) {
00969
00970 KMMessagePart aPart;
00971 msg->bodyPart( part, &aPart );
00972 TQByteArray rawData( aPart.bodyDecodedBinary() );
00973
00974 KTempFile file;
00975 file.file()->writeBlock( rawData.data(), rawData.size() );
00976
00977 url.setPath( file.name() );
00978
00979 bOK = true;
00980 }
00981
00982 if( !bOK ){
00983 kdDebug(5006) << "Attachment " << filename << " not found." << endl;
00984 }
00985 }else{
00986 kdDebug(5006) << "Message not found." << endl;
00987 }
00988
00989 mResourceQuiet = quiet;
00990 return url;
00991 }
00992
00993 TQString KMailICalIfaceImpl::attachmentMimetype( const TQString & resource,
00994 TQ_UINT32 sernum,
00995 const TQString & filename )
00996 {
00997 if( !mUseResourceIMAP )
00998 return TQString();
00999 KMFolder* f = findResourceFolder( resource );
01000 if( !f || storageFormat( f ) != StorageXML ) {
01001 kdError(5006) << "attachmentMimetype(" << resource << ") : Wrong folder" << endl;
01002 return TQString();
01003 }
01004
01005 KMMessage* msg = findMessageBySerNum( sernum, f );
01006 if( msg ) {
01007
01008 DwBodyPart* part = findBodyPart( *msg, filename );
01009 if ( part ) {
01010 KMMessagePart kmPart;
01011 msg->bodyPart( part, &kmPart );
01012 return TQString( kmPart.typeStr() ) + "/" + TQString( kmPart.subtypeStr() );
01013 } else {
01014 kdDebug(5006) << "Attachment " << filename << " not found." << endl;
01015 }
01016 } else {
01017 kdDebug(5006) << "Message not found." << endl;
01018 }
01019
01020 return TQString();
01021 }
01022
01023 TQStringList KMailICalIfaceImpl::listAttachments(const TQString & resource, TQ_UINT32 sernum)
01024 {
01025 TQStringList rv;
01026 if( !mUseResourceIMAP )
01027 return rv;
01028
01029
01030 KMFolder* f = findResourceFolder( resource );
01031 if( !f ) {
01032 kdError(5006) << "listAttachments(" << resource << ") : Not an IMAP resource folder" << endl;
01033 return rv;
01034 }
01035 if ( storageFormat( f ) != StorageXML ) {
01036 kdError(5006) << "listAttachment(" << resource << ") : Folder has wrong storage format " << storageFormat( f ) << endl;
01037 return rv;
01038 }
01039
01040 KMMessage* msg = findMessageBySerNum( sernum, f );
01041 if( msg ) {
01042 for ( DwBodyPart* part = msg->getFirstDwBodyPart(); part; part = part->Next() ) {
01043 if ( part->hasHeaders() ) {
01044 TQString name;
01045 DwMediaType& contentType = part->Headers().ContentType();
01046 if ( TQString( contentType.SubtypeStr().c_str() ).startsWith( "x-vnd.kolab." )
01047 || TQString( contentType.SubtypeStr().c_str() ).contains( "tnef" ) )
01048 continue;
01049 if ( !part->Headers().ContentDisposition().Filename().empty() )
01050 name = part->Headers().ContentDisposition().Filename().c_str();
01051 else if ( !contentType.Name().empty() )
01052 name = contentType.Name().c_str();
01053 if ( !name.isEmpty() )
01054 rv.append( name );
01055 }
01056 }
01057 } else {
01058 kdDebug(5006) << "Message not found." << endl;
01059 }
01060
01061 return rv;
01062 }
01063
01064
01065
01066
01067
01068
01069
01070
01071 void KMailICalIfaceImpl::slotFolderRemoved( KMFolder* folder )
01072 {
01073
01074
01075 folderContentsTypeChanged( folder, KMail::ContentsTypeMail );
01076 TDEConfigGroup configGroup( kmkernel->config(), "GroupwareFolderInfo" );
01077 configGroup.deleteEntry( folder->idString() + "-storageFormat" );
01078 configGroup.deleteEntry( folder->idString() + "-changes" );
01079 }
01080
01081
01082 void KMailICalIfaceImpl::slotIncidenceAdded( KMFolder* folder,
01083 TQ_UINT32 sernum )
01084 {
01085 if( mResourceQuiet || !mUseResourceIMAP )
01086 return;
01087
01088
01089 TQString type = folderContentsType( folder->storage()->contentsType() );
01090 if( type.isEmpty() ) {
01091 kdError(5006) << "Not an IMAP resource folder" << endl;
01092 return;
01093 }
01094
01095 int i = 0;
01096 KMFolder* aFolder = 0;
01097 KMMsgDict::instance()->getLocation( sernum, &aFolder, &i );
01098 assert( folder == aFolder );
01099
01100 bool unget = !folder->isMessage( i );
01101 TQString s;
01102 TQString uid( "UID" );
01103 KMMessage *msg = folder->getMsg( i );
01104 if( !msg ) return;
01105 if( msg->isComplete() ) {
01106
01107 bool ok = false;
01108 StorageFormat format = storageFormat( folder );
01109 switch( format ) {
01110 case StorageIcalVcard:
01111
01112 ok = vPartFoundAndDecoded( msg, s );
01113 if ( ok )
01114 vPartMicroParser( s, uid );
01115 break;
01116 case StorageXML:
01117
01118 if ( kolabXMLFoundAndDecoded( *msg,
01119 folderKolabMimeType( folder->storage()->contentsType() ), s ) ) {
01120 uid = msg->subject();
01121 ok = true;
01122 }
01123 break;
01124 }
01125 if ( !ok ) {
01126 if ( unget )
01127 folder->unGetMsg( i );
01128 return;
01129 }
01130 const TQ_UINT32 sernum = msg->getMsgSerNum();
01131 mUIDToSerNum.insert( uid, sernum );
01132
01133
01134 if ( mInTransit.contains( uid ) ) {
01135 mInTransit.remove( uid );
01136 }
01137 incidenceAdded( type, folder->location(), sernum, format, s );
01138 } else {
01139
01140
01141 if ( unget ) mTheUnGetMes.insert( msg->getMsgSerNum(), true );
01142 FolderJob *job = msg->parent()->createJob( msg );
01143 connect( job, TQT_SIGNAL( messageRetrieved( KMMessage* ) ),
01144 this, TQT_SLOT( slotMessageRetrieved( KMMessage* ) ) );
01145 job->start();
01146 return;
01147 }
01148 if( unget ) folder->unGetMsg(i);
01149 }
01150
01151
01152 void KMailICalIfaceImpl::slotIncidenceDeleted( KMFolder* folder,
01153 TQ_UINT32 sernum )
01154 {
01155 if( mResourceQuiet || !mUseResourceIMAP )
01156 return;
01157
01158 TQString type = folderContentsType( folder->storage()->contentsType() );
01159
01160 if( !type.isEmpty() ) {
01161
01162 int i = 0;
01163 KMFolder* aFolder = 0;
01164 KMMsgDict::instance()->getLocation( sernum, &aFolder, &i );
01165 assert( folder == aFolder );
01166
01167
01168 bool unget = !folder->isMessage( i );
01169 TQString s;
01170 bool ok = false;
01171 KMMessage* msg = folder->getMsg( i );
01172 TQString uid( "UID" );
01173 switch( storageFormat( folder ) ) {
01174 case StorageIcalVcard:
01175 if( vPartFoundAndDecoded( msg, s ) ) {
01176 vPartMicroParser( s, uid );
01177 ok = true;
01178 }
01179 break;
01180 case StorageXML:
01181 if ( kolabXMLFoundAndDecoded( *msg, folderKolabMimeType( folder->storage()->contentsType() ), s ) ) {
01182 uid = msg->subject();
01183 ok = true;
01184 }
01185 break;
01186 }
01187 if ( ok ) {
01188 kdDebug(5006) << "Emitting DCOP signal incidenceDeleted( "
01189 << type << ", " << folder->location() << ", " << uid
01190 << " )" << endl;
01191 incidenceDeleted( type, folder->location(), uid );
01192 }
01193 if( unget ) folder->unGetMsg(i);
01194 } else
01195 kdError(5006) << "Not a groupware folder" << endl;
01196 }
01197
01198
01199 void KMailICalIfaceImpl::slotRefresh( const TQString& type )
01200 {
01201 if( mUseResourceIMAP ) {
01202 signalRefresh( type, TQString() );
01203 kdDebug(5006) << "Emitting DCOP signal signalRefresh( " << type << " )" << endl;
01204 }
01205 }
01206
01207
01208 void KMailICalIfaceImpl::slotRefreshFolder( KMFolder* folder)
01209 {
01210
01211
01212
01213 if( mUseResourceIMAP && folder ) {
01214 if( folder == mCalendar || folder == mContacts
01215 || folder == mNotes || folder == mTasks
01216 || folder == mJournals || mExtraFolders.find( folder->location() ) ) {
01217
01218 KMail::FolderContentsType ct = folder->storage()->contentsType();
01219 slotRefresh( s_folderContentsType[ct].contentsTypeStr );
01220 }
01221 }
01222 }
01223
01224
01225
01226
01227
01228 KMFolder* KMailICalIfaceImpl::folderFromType( const TQString& type,
01229 const TQString& folder )
01230 {
01231 if( mUseResourceIMAP ) {
01232 KMFolder* f = 0;
01233 if ( !folder.isEmpty() ) {
01234 f = extraFolder( type, folder );
01235 if ( f )
01236 return f;
01237 }
01238
01239 if( type == "Calendar" ) f = mCalendar;
01240 else if( type == "Contact" ) f = mContacts;
01241 else if( type == "Note" ) f = mNotes;
01242 else if( type == "Task" || type == "Todo" ) f = mTasks;
01243 else if( type == "Journal" ) f = mJournals;
01244
01245 if ( f && ( folder.isEmpty() || folder == f->location() ) )
01246 return f;
01247
01248 kdError(5006) << "No folder ( " << type << ", " << folder << " )\n";
01249 }
01250
01251 return 0;
01252 }
01253
01254
01255
01256
01257 bool KMailICalIfaceImpl::isResourceFolder( KMFolder* folder ) const
01258 {
01259 return mUseResourceIMAP && folder &&
01260 ( isStandardResourceFolder( folder ) || mExtraFolders.find( folder->location() )!=0 );
01261 }
01262
01263 bool KMailICalIfaceImpl::isStandardResourceFolder( KMFolder* folder ) const
01264 {
01265 return ( folder == mCalendar || folder == mTasks || folder == mJournals ||
01266 folder == mNotes || folder == mContacts );
01267 }
01268
01269 bool KMailICalIfaceImpl::hideResourceFolder( KMFolder* folder ) const
01270 {
01271 return mHideFolders && isResourceFolder( folder );
01272 }
01273
01274 bool KMailICalIfaceImpl::hideResourceAccountRoot( KMFolder* folder ) const
01275 {
01276 KMFolderCachedImap *dimapFolder = dynamic_cast<KMFolderCachedImap*>( folder->storage() );
01277 bool hide = dimapFolder && mHideFolders
01278 && (int)dimapFolder->account()->id() == GlobalSettings::self()->theIMAPResourceAccount()
01279 && GlobalSettings::self()->showOnlyGroupwareFoldersForGroupwareAccount();
01280 return hide;
01281
01282 }
01283
01284 KFolderTreeItem::Type KMailICalIfaceImpl::folderType( KMFolder* folder ) const
01285 {
01286 if( mUseResourceIMAP && folder ) {
01287 if( folder == mCalendar || folder == mContacts
01288 || folder == mNotes || folder == mTasks
01289 || folder == mJournals || mExtraFolders.find( folder->location() ) ) {
01290 KMail::FolderContentsType ct = folder->storage()->contentsType();
01291 return s_folderContentsType[ct].treeItemType;
01292 }
01293 }
01294
01295 return KFolderTreeItem::Other;
01296 }
01297
01298
01299
01300 static TQMap<KFolderTreeItem::Type,TQString> folderNames[4];
01301 TQString KMailICalIfaceImpl::folderName( KFolderTreeItem::Type type, int language ) const
01302 {
01303
01304 if ( GlobalSettings::self()->theIMAPResourceStorageFormat() == GlobalSettings::EnumTheIMAPResourceStorageFormat::XML )
01305 language = 0;
01306
01307 static bool folderNamesSet = false;
01308 if( !folderNamesSet ) {
01309 folderNamesSet = true;
01310
01311
01312
01313
01314 folderNames[0][KFolderTreeItem::Calendar] = TQString::fromLatin1("Calendar");
01315 folderNames[0][KFolderTreeItem::Tasks] = TQString::fromLatin1("Tasks");
01316 folderNames[0][KFolderTreeItem::Journals] = TQString::fromLatin1("Journal");
01317 folderNames[0][KFolderTreeItem::Contacts] = TQString::fromLatin1("Contacts");
01318 folderNames[0][KFolderTreeItem::Notes] = TQString::fromLatin1("Notes");
01319
01320
01321 folderNames[1][KFolderTreeItem::Calendar] = TQString::fromLatin1("Kalender");
01322 folderNames[1][KFolderTreeItem::Tasks] = TQString::fromLatin1("Aufgaben");
01323 folderNames[1][KFolderTreeItem::Journals] = TQString::fromLatin1("Journal");
01324 folderNames[1][KFolderTreeItem::Contacts] = TQString::fromLatin1("Kontakte");
01325 folderNames[1][KFolderTreeItem::Notes] = TQString::fromLatin1("Notizen");
01326
01327
01328 folderNames[2][KFolderTreeItem::Calendar] = TQString::fromLatin1("Calendrier");
01329
01330 folderNames[2][KFolderTreeItem::Tasks] = TQString::fromLatin1("T\342ches");
01331 folderNames[2][KFolderTreeItem::Journals] = TQString::fromLatin1("Journal");
01332 folderNames[2][KFolderTreeItem::Contacts] = TQString::fromLatin1("Contacts");
01333 folderNames[2][KFolderTreeItem::Notes] = TQString::fromLatin1("Notes");
01334
01335
01336 folderNames[3][KFolderTreeItem::Calendar] = TQString::fromLatin1("Agenda");
01337 folderNames[3][KFolderTreeItem::Tasks] = TQString::fromLatin1("Taken");
01338 folderNames[3][KFolderTreeItem::Journals] = TQString::fromLatin1("Logboek");
01339 folderNames[3][KFolderTreeItem::Contacts] = TQString::fromLatin1("Contactpersonen");
01340 folderNames[3][KFolderTreeItem::Notes] = TQString::fromLatin1("Notities");
01341 }
01342
01343 if( language < 0 || language > 3 ) {
01344 return folderNames[mFolderLanguage][type];
01345 }
01346 else {
01347 return folderNames[language][type];
01348 }
01349 }
01350
01351
01352
01353 KMMessage *KMailICalIfaceImpl::findMessageByUID( const TQString& uid, KMFolder* folder )
01354 {
01355 if( !folder || !mUIDToSerNum.contains( uid ) ) return 0;
01356 int i;
01357 KMFolder *aFolder;
01358 KMMsgDict::instance()->getLocation( mUIDToSerNum[uid], &aFolder, &i );
01359 Q_ASSERT( aFolder == folder );
01360 return folder->getMsg( i );
01361 }
01362
01363
01364 KMMessage *KMailICalIfaceImpl::findMessageBySerNum( TQ_UINT32 serNum, KMFolder* folder )
01365 {
01366 if( !folder ) return 0;
01367
01368 KMMessage *message = 0;
01369 KMFolder* aFolder = 0;
01370 int index;
01371 KMMsgDict::instance()->getLocation( serNum, &aFolder, &index );
01372
01373 if( aFolder && aFolder != folder ) {
01374 kdWarning(5006) << "findMessageBySerNum( " << serNum << " ) found it in folder " << aFolder->location() << ", expected " << folder->location() << endl;
01375 } else {
01376 if( aFolder )
01377 message = aFolder->getMsg( index );
01378 if (!message)
01379 kdWarning(5006) << "findMessageBySerNum( " << serNum << " ) invalid serial number\n" << endl;
01380 }
01381 return message;
01382 }
01383
01384 void KMailICalIfaceImpl::deleteMsg( KMMessage *msg )
01385 {
01386 if( !msg ) return;
01387
01388
01389 KMFolder *srcFolder = msg->parent();
01390 int idx = srcFolder->find(msg);
01391 assert(idx != -1);
01392
01393 srcFolder->ignoreJobsForMessage( msg );
01394 if ( !msg->transferInProgress() ) {
01395 srcFolder->removeMsg(idx);
01396 delete msg;
01397 } else {
01398 kdDebug(5006) << k_funcinfo << "Message cannot be deleted now because it is currently in use " << msg << endl;
01399 msg->deleteWhenUnused();
01400 }
01401 addFolderChange( srcFolder, Contents );
01402 }
01403
01404 void KMailICalIfaceImpl::folderContentsTypeChanged( KMFolder* folder,
01405 KMail::FolderContentsType contentsType )
01406 {
01407 if ( !mUseResourceIMAP )
01408 return;
01409
01410
01411
01412
01413 if ( isStandardResourceFolder( folder ) )
01414 return;
01415
01416
01417 const TQString location = folder->location();
01418 ExtraFolder* ef = mExtraFolders.find( location );
01419 if ( ef && ef->folder ) {
01420
01421 subresourceDeleted(folderContentsType( folder->storage()->contentsType() ), location );
01422
01423 if ( contentsType == KMail::ContentsTypeMail ) {
01424
01425 mExtraFolders.remove( location );
01426 folder->disconnect( this );
01427 return;
01428 }
01429
01430 } else {
01431 if ( ef && !ef->folder )
01432 mExtraFolders.remove( location );
01433 if ( contentsType == KMail::ContentsTypeMail )
01434 return;
01435
01436
01437
01438 ef = new ExtraFolder( folder );
01439 mExtraFolders.insert( location, ef );
01440
01441 FolderInfo info = readFolderInfo( folder );
01442 mFolderInfoMap.insert( folder, info );
01443
01444
01445
01446
01447
01448
01449 if ( folder->folderType() == KMFolderTypeCachedImap ) {
01450 TQString annotation = static_cast<KMFolderCachedImap*>( folder->storage() )->annotationFolderType();
01451 kdDebug(5006) << "folderContentsTypeChanged: " << folder->name() << " has annotation " << annotation << endl;
01452 if ( annotation == TQString( s_folderContentsType[contentsType].annotation ) + ".default" )
01453 folder->setLabel( localizedDefaultFolderName( contentsType ) );
01454 }
01455
01456 connectFolder( folder );
01457 }
01458
01459 subresourceAdded( folderContentsType( contentsType ), location, subresourceLabelForPresentation(folder),
01460 folder->isWritable(), folderIsAlarmRelevant( folder ) );
01461 }
01462
01463 KMFolder* KMailICalIfaceImpl::extraFolder( const TQString& type,
01464 const TQString& folder )
01465 {
01466
01467
01468 int t = folderContentsType( type );
01469 if ( t < 1 || t > 5 )
01470 return 0;
01471
01472 ExtraFolder* ef = mExtraFolders.find( folder );
01473 if ( ef && ef->folder && ef->folder->storage()->contentsType() == t )
01474 return ef->folder;
01475
01476 return 0;
01477 }
01478
01479 KMailICalIfaceImpl::StorageFormat KMailICalIfaceImpl::storageFormat( KMFolder* folder ) const
01480 {
01481 FolderInfoMap::ConstIterator it = mFolderInfoMap.find( folder );
01482 if ( it != mFolderInfoMap.end() )
01483 return (*it).mStorageFormat;
01484 return globalStorageFormat();
01485 }
01486
01487 void KMailICalIfaceImpl::setStorageFormat( KMFolder* folder, StorageFormat format )
01488 {
01489 FolderInfoMap::Iterator it = mFolderInfoMap.find( folder );
01490 if ( it != mFolderInfoMap.end() ) {
01491 (*it).mStorageFormat = format;
01492 } else {
01493 FolderInfo info( format, NoChange );
01494 mFolderInfoMap.insert( folder, info );
01495 }
01496 TDEConfigGroup configGroup( kmkernel->config(), "GroupwareFolderInfo" );
01497 configGroup.writeEntry( folder->idString() + "-storageFormat",
01498 format == StorageXML ? "xml" : "icalvcard" );
01499 }
01500
01501 void KMailICalIfaceImpl::addFolderChange( KMFolder* folder, FolderChanges changes )
01502 {
01503 FolderInfoMap::Iterator it = mFolderInfoMap.find( folder );
01504 if ( it != mFolderInfoMap.end() ) {
01505 (*it).mChanges = static_cast<FolderChanges>( (*it).mChanges | changes );
01506 } else {
01507 kdDebug(5006) << "addFolderChange: nothing known about folder " << folder->location() << endl;
01508 }
01509 TDEConfigGroup configGroup( kmkernel->config(), "GroupwareFolderInfo" );
01510 configGroup.writeEntry( folder->idString() + "-changes", (*it).mChanges );
01511 }
01512
01513 KMailICalIfaceImpl::FolderInfo KMailICalIfaceImpl::readFolderInfo( const KMFolder * const folder ) const
01514 {
01515 TDEConfigGroup configGroup( kmkernel->config(), "GroupwareFolderInfo" );
01516 TQString str = configGroup.readEntry( folder->idString() + "-storageFormat", "unset" );
01517 FolderInfo info;
01518 if ( str == "unset" ) {
01519 info.mStorageFormat = globalStorageFormat();
01520 configGroup.writeEntry( folder->idString() + "-storageFormat",
01521 info.mStorageFormat == StorageXML ? "xml" : "icalvcard" );
01522 } else {
01523 info.mStorageFormat = ( str == "xml" ) ? StorageXML : StorageIcalVcard;
01524 }
01525 info.mChanges = (FolderChanges) configGroup.readNumEntry( folder->idString() + "-changes" );
01526 return info;
01527 }
01528
01529
01530 void KMailICalIfaceImpl::folderSynced( KMFolder* folder, const KURL& folderURL )
01531 {
01532 FolderInfoMap::Iterator it = mFolderInfoMap.find( folder );
01533 if ( it != mFolderInfoMap.end() && (*it).mChanges ) {
01534 handleFolderSynced( folder, folderURL, (*it).mChanges );
01535 (*it).mChanges = NoChange;
01536 }
01537 }
01538
01539 void KMailICalIfaceImpl::handleFolderSynced( KMFolder* folder,
01540 const KURL& folderURL,
01541 int _changes )
01542 {
01543
01544
01545
01546
01547 if ( ( _changes & KMailICalIface::Contents ) ||
01548 ( _changes & KMailICalIface::ACL ) ) {
01549 if ( storageFormat( folder ) == StorageXML && folder->storage()->contentsType() == KMail::ContentsTypeCalendar )
01550 triggerKolabFreeBusy( folderURL );
01551 }
01552 }
01553
01554 void KMailICalIfaceImpl::folderDeletedOnServer( const KURL& folderURL )
01555 {
01556 triggerKolabFreeBusy( folderURL );
01557 }
01558
01559 void KMailICalIfaceImpl::triggerKolabFreeBusy( const KURL& folderURL )
01560 {
01561
01562
01563
01564 KURL httpURL( folderURL );
01565
01566 httpURL.setProtocol( "https" );
01567 httpURL.setPort( 0 );
01568
01569
01570 TQString path = folderURL.path( -1 );
01571 Q_ASSERT( path.startsWith( "/" ) );
01572 int secondSlash = path.find( '/', 1 );
01573 if ( secondSlash == -1 ) {
01574 kdWarning() << "KCal::ResourceKolab::fromKMailFolderSynced path is too short: " << path << endl;
01575 return;
01576 }
01577 if ( path.startsWith( "/INBOX/", false ) ) {
01578
01579 path = path.mid( secondSlash );
01580 path.prepend( folderURL.user() );
01581 } else {
01582
01583
01584 path = path.mid( secondSlash );
01585 }
01586
01587 httpURL.setPath( "/freebusy/trigger/" + path + ".pfb" );
01588 httpURL.setQuery( TQString() );
01589
01590 httpURL = KURL( httpURL.url(0,106), 106 );
01591 kdDebug() << "Triggering PFB update for " << folderURL << " : getting " << httpURL << endl;
01592
01593
01594 TDEIO::get( httpURL, false, false );
01595 }
01596
01597 void KMailICalIfaceImpl::slotFolderPropertiesChanged( KMFolder* folder )
01598 {
01599 if ( isResourceFolder( folder ) ) {
01600 const TQString location = folder->location();
01601 const TQString contentsTypeStr = folderContentsType( folder->storage()->contentsType() );
01602 subresourceDeleted( contentsTypeStr, location );
01603
01604 subresourceAdded( contentsTypeStr, location, subresourceLabelForPresentation( folder ),
01605 folder->isWritable(), folderIsAlarmRelevant( folder ) );
01606 }
01607 }
01608
01609
01610 void KMailICalIfaceImpl::slotFolderRenamed()
01611 {
01612 const KMFolder* folder = static_cast<const KMFolder *>( sender() );
01613 slotFolderPropertiesChanged( const_cast<KMFolder*>( folder ) );
01614 }
01615
01616 void KMailICalIfaceImpl::slotFolderLocationChanged( const TQString &oldLocation,
01617 const TQString &newLocation )
01618 {
01619 KMFolder *folder = findResourceFolder( oldLocation );
01620 ExtraFolder* ef = mExtraFolders.find( oldLocation );
01621 if ( ef ) {
01622
01623 mExtraFolders.setAutoDelete( false );
01624 mExtraFolders.remove( oldLocation );
01625 mExtraFolders.setAutoDelete( true );
01626 mExtraFolders.insert( newLocation, ef );
01627 }
01628 if ( folder )
01629 subresourceDeleted( folderContentsType( folder->storage()->contentsType() ), oldLocation );
01630
01631 }
01632
01633 KMFolder* KMailICalIfaceImpl::findResourceFolder( const TQString& resource )
01634 {
01635
01636 if( mCalendar && mCalendar->location() == resource )
01637 return mCalendar;
01638 if ( mContacts && mContacts->location() == resource )
01639 return mContacts;
01640 if ( mNotes && mNotes->location() == resource )
01641 return mNotes;
01642 if ( mTasks && mTasks->location() == resource )
01643 return mTasks;
01644 if ( mJournals && mJournals->location() == resource )
01645 return mJournals;
01646
01647
01648 ExtraFolder* ef = mExtraFolders.find( resource );
01649 if ( ef )
01650 return ef->folder;
01651
01652
01653 return 0;
01654 }
01655
01656 void KMailICalIfaceImpl::changeResourceUIName( const TQString &folderPath, const TQString &newName )
01657 {
01658 kdDebug() << "Folder path " << folderPath << endl;
01659 KMFolder *f = findResourceFolder( folderPath );
01660 if ( f ) {
01661 KMailICalIfaceImpl::getResourceMap()->insert( folderPath, newName );
01662 kmkernel->folderMgr()->renameFolder( f, newName );
01663 TDEConfigGroup configGroup( kmkernel->config(), "Resource UINames" );
01664 configGroup.writeEntry( folderPath, newName );
01665 }
01666 }
01667
01668
01669 static void createFolderList( TQStringList &folderNames, TQValueList<TQGuardedPtr<KMFolder> > &folderList )
01670 {
01671 TQStringList dimapFolderNames;
01672 TQStringList localFolderNames;
01673 TQValueList<TQGuardedPtr<KMFolder> > dimapFolderList;
01674 TQValueList<TQGuardedPtr<KMFolder> > localFolderList;
01675 kmkernel->dimapFolderMgr()->createFolderList( &dimapFolderNames, &dimapFolderList );
01676 kmkernel->folderMgr()->createFolderList( &localFolderNames, &localFolderList );
01677 folderNames += dimapFolderNames;
01678 folderNames += localFolderNames;
01679 folderList += dimapFolderList;
01680 folderList += localFolderList;
01681 }
01682
01683
01684
01685
01686
01687 void KMailICalIfaceImpl::readConfig()
01688 {
01689 bool enabled = GlobalSettings::self()->theIMAPResourceEnabled() &&
01690 ( GlobalSettings::self()->theIMAPResourceAccount() != 0 );
01691
01692 if( !enabled ) {
01693 if( mUseResourceIMAP == true ) {
01694
01695 mUseResourceIMAP = false;
01696 cleanup();
01697 reloadFolderTree();
01698 }
01699 return;
01700 }
01701 mUseResourceIMAP = enabled;
01702
01703
01704 const bool hideFolders = GlobalSettings::self()->hideGroupwareFolders();
01705 TQString parentName = GlobalSettings::self()->theIMAPResourceFolderParent();
01706
01707
01708 KMFolderDir* folderParentDir;
01709 KMFolderType folderType;
01710 KMFolder* folderParent = kmkernel->findFolderById( parentName );
01711 if( folderParent == 0 ) {
01712
01713
01714 kdDebug(5006) << "Groupware folder " << parentName << " not found. Groupware functionality disabled" << endl;
01715
01716 KMAccount* account = kmkernel->acctMgr()->find( GlobalSettings::self()->theIMAPResourceAccount() );
01717 Q_ASSERT( account );
01718 if ( account ) {
01719
01720 disconnect( account, TQT_SIGNAL( finishedCheck( bool, CheckStatus ) ),
01721 this, TQT_SLOT( slotCheckDone() ) );
01722 connect( account, TQT_SIGNAL( finishedCheck( bool, CheckStatus ) ),
01723 this, TQT_SLOT( slotCheckDone() ) );
01724 }
01725 mUseResourceIMAP = false;
01726
01727 mCalendar = 0;
01728 mTasks = 0;
01729 mJournals = 0;
01730 mContacts = 0;
01731 mNotes = 0;
01732 return;
01733 } else {
01734 folderParentDir = folderParent->createChildFolder();
01735 folderType = folderParent->folderType();
01736 }
01737
01738 KMAcctCachedImap::GroupwareType groupwareType = dynamic_cast<KMFolderCachedImap *>( folderParent->storage() )->account()->groupwareType();
01739
01740 if ( groupwareType == KMAcctCachedImap::GroupwareKolab ) {
01741
01742
01743 bool noneFound = true;
01744 bool mustFix = false;
01745 TQValueVector<StandardFolderSearchResult> results( KMail::ContentsTypeLast + 1 );
01746 for ( int i = 0; i < KMail::ContentsTypeLast+1; ++i ) {
01747 if ( i != KMail::ContentsTypeMail ) {
01748 results[i] = findStandardResourceFolder( folderParentDir, static_cast<KMail::FolderContentsType>(i) );
01749 if ( results[i].found == StandardFolderSearchResult::FoundAndStandard )
01750 noneFound = false;
01751 else if ( results[i].found == StandardFolderSearchResult::FoundByType ||
01752 results[i].found == StandardFolderSearchResult::FoundByName ) {
01753 mustFix = true;
01754 noneFound = false;
01755 } else
01756 mustFix = true;
01757 }
01758 }
01759
01760
01761 if( mUseResourceIMAP && !noneFound && !mustFix && mFolderParentDir == folderParentDir
01762 && mFolderType == folderType ) {
01763
01764 if ( hideFolders != mHideFolders ) {
01765
01766 mHideFolders = hideFolders;
01767 reloadFolderTree();
01768 }
01769 return;
01770 }
01771
01772 if( noneFound || mustFix ) {
01773 TQString msg;
01774 TQString parentFolderName = folderParent != 0 ? folderParent->name() : folderParentDir->name();
01775 if ( noneFound ) {
01776
01777 msg = i18n("KMail will now create the required groupware folders"
01778 " as subfolders of %1; if you do not want this, cancel"
01779 " and the IMAP resource will be disabled").arg(parentFolderName);
01780 } else {
01781
01782 TQString operations = "<ul>";
01783 for ( int i = 0; i < KMail::ContentsTypeLast+1; ++i ) {
01784 if ( i != KMail::ContentsTypeMail ) {
01785 TQString typeName = localizedDefaultFolderName( static_cast<KMail::FolderContentsType>( i ) );
01786 if ( results[i].found == StandardFolderSearchResult::NotFound )
01787 operations += "<li>" + i18n( "%1: no folder found. It will be created." ).arg( typeName ) + "</li>";
01788 else if ( results[i].found == StandardFolderSearchResult::FoundByType || results[i].found == StandardFolderSearchResult::FoundByName )
01789 operations += "<li>" + i18n( "%1: found folder %2. It will be set as the main groupware folder." ).
01790 arg( typeName ).arg( results[i].folder->label() ) + "</li>";
01791 }
01792 }
01793 operations += "</ul>";
01794
01795 msg = i18n("<qt>KMail found the following groupware folders in %1 and needs to perform the following operations: %2"
01796 "<br>If you do not want this, cancel"
01797 " and the IMAP resource will be disabled").arg(parentFolderName, operations);
01798
01799 }
01800
01801 if( KMessageBox::questionYesNo( 0, msg,
01802 i18n("Standard Groupware Folders"), KStdGuiItem::cont(), KStdGuiItem::cancel() ) == KMessageBox::No ) {
01803
01804 GlobalSettings::self()->setTheIMAPResourceEnabled( false );
01805 mUseResourceIMAP = false;
01806 mFolderParentDir = 0;
01807 mFolderParent = 0;
01808 reloadFolderTree();
01809 return;
01810 }
01811 }
01812
01813
01814 mUseResourceIMAP = true;
01815 mFolderLanguage = GlobalSettings::self()->theIMAPResourceFolderLanguage();
01816 if( mFolderLanguage > 3 ) mFolderLanguage = 0;
01817 mFolderParentDir = folderParentDir;
01818 mFolderParent = folderParent;
01819 mFolderType = folderType;
01820 mHideFolders = hideFolders;
01821
01822
01823 cleanup();
01824
01825
01826 mCalendar = initFolder( KMail::ContentsTypeCalendar );
01827 mTasks = initFolder( KMail::ContentsTypeTask );
01828 mJournals = initFolder( KMail::ContentsTypeJournal );
01829 mContacts = initFolder( KMail::ContentsTypeContact );
01830 mNotes = initFolder( KMail::ContentsTypeNote );
01831
01832
01833 if ( mCalendar->folderType() == KMFolderTypeCachedImap )
01834 static_cast<KMFolderCachedImap *>( mCalendar->storage() )->updateAnnotationFolderType();
01835 if ( mTasks->folderType() == KMFolderTypeCachedImap )
01836 static_cast<KMFolderCachedImap *>( mTasks->storage() )->updateAnnotationFolderType();
01837 if ( mJournals->folderType() == KMFolderTypeCachedImap )
01838 static_cast<KMFolderCachedImap *>( mJournals->storage() )->updateAnnotationFolderType();
01839 if ( mContacts->folderType() == KMFolderTypeCachedImap )
01840 static_cast<KMFolderCachedImap *>( mContacts->storage() )->updateAnnotationFolderType();
01841 if ( mNotes->folderType() == KMFolderTypeCachedImap )
01842 static_cast<KMFolderCachedImap *>( mNotes->storage() )->updateAnnotationFolderType();
01843
01844
01845
01846
01847
01848
01849 TQStringList folderNames;
01850 TQValueList<TQGuardedPtr<KMFolder> > folderList;
01851 createFolderList( folderNames, folderList );
01852 for( TQValueList<TQGuardedPtr<KMFolder> >::iterator it = folderList.begin();
01853 it != folderList.end(); ++it )
01854 {
01855 FolderStorage *storage = (*it)->storage();
01856 KMFolderCachedImap* dimapStorage = dynamic_cast<KMFolderCachedImap*>( storage );
01857 if ( storage && storage->contentsType() != 0 ) {
01858 if ( dimapStorage )
01859 dimapStorage->updateAnnotationFolderType();
01860 folderContentsTypeChanged( *it, storage->contentsType() );
01861 }
01862 }
01863
01864
01865
01866 mExtraFolders.remove( mCalendar->location() );
01867 mExtraFolders.remove( mTasks->location() );
01868 mExtraFolders.remove( mJournals->location() );
01869 mExtraFolders.remove( mContacts->location() );
01870 mExtraFolders.remove( mNotes->location() );
01871
01872 subresourceAdded( folderContentsType( KMail::ContentsTypeCalendar ), mCalendar->location(), mCalendar->label(), true, true );
01873 subresourceAdded( folderContentsType( KMail::ContentsTypeTask ), mTasks->location(), mTasks->label(), true, true );
01874 subresourceAdded( folderContentsType( KMail::ContentsTypeJournal ), mJournals->location(), mJournals->label(), true, false );
01875 subresourceAdded( folderContentsType( KMail::ContentsTypeContact ), mContacts->location(), mContacts->label(), true, false );
01876 subresourceAdded( folderContentsType( KMail::ContentsTypeNote ), mNotes->location(), mNotes->label(), true, false );
01877 } else if ( groupwareType == KMAcctCachedImap::GroupwareScalix ) {
01878
01879 mUseResourceIMAP = true;
01880 mFolderParentDir = folderParentDir;
01881 mFolderParent = folderParent;
01882 mFolderType = folderType;
01883 mHideFolders = false;
01884
01885
01886 cleanup();
01887
01888
01889 mCalendar = initScalixFolder( KMail::ContentsTypeCalendar );
01890 mTasks = initScalixFolder( KMail::ContentsTypeTask );
01891 mJournals = 0;
01892 mContacts = initScalixFolder( KMail::ContentsTypeContact );
01893 mNotes = initScalixFolder( KMail::ContentsTypeNote );
01894
01895
01896 if ( mCalendar->folderType() == KMFolderTypeCachedImap )
01897 static_cast<KMFolderCachedImap *>( mCalendar->storage() )->updateAnnotationFolderType();
01898 if ( mTasks->folderType() == KMFolderTypeCachedImap )
01899 static_cast<KMFolderCachedImap *>( mTasks->storage() )->updateAnnotationFolderType();
01900 if ( mContacts->folderType() == KMFolderTypeCachedImap )
01901 static_cast<KMFolderCachedImap *>( mContacts->storage() )->updateAnnotationFolderType();
01902 if ( mNotes->folderType() == KMFolderTypeCachedImap )
01903 static_cast<KMFolderCachedImap *>( mNotes->storage() )->updateAnnotationFolderType();
01904
01905
01906
01907
01908 kdDebug(5006) << k_funcinfo << "mCalendar=" << mCalendar << " " << mCalendar->location() << endl;
01909 kdDebug(5006) << k_funcinfo << "mContacts=" << mContacts << " " << mContacts->location() << endl;
01910 kdDebug(5006) << k_funcinfo << "mNotes=" << mNotes << " " << mNotes->location() << endl;
01911
01912
01913 TQStringList folderNames;
01914 TQValueList<TQGuardedPtr<KMFolder> > folderList;
01915 kmkernel->dimapFolderMgr()->createFolderList(&folderNames, &folderList);
01916 TQValueList<TQGuardedPtr<KMFolder> >::iterator it;
01917 for(it = folderList.begin(); it != folderList.end(); ++it)
01918 {
01919 FolderStorage *storage = (*it)->storage();
01920
01921 if ( (*it)->folderType() == KMFolderTypeCachedImap ) {
01922 KMFolderCachedImap *imapFolder = static_cast<KMFolderCachedImap*>( storage );
01923
01924 const TQString attributes = imapFolder->folderAttributes();
01925 if ( attributes.contains( "X-FolderClass" ) ) {
01926 if ( !attributes.contains( "X-SpecialFolder" ) || (*it)->location().contains( "@" ) ) {
01927 const Scalix::FolderAttributeParser parser( attributes );
01928 if ( !parser.folderClass().isEmpty() ) {
01929 FolderContentsType type = Scalix::Utils::scalixIdToContentsType( parser.folderClass() );
01930 imapFolder->setContentsType( type );
01931 folderContentsTypeChanged( *it, type );
01932 }
01933 }
01934 }
01935 }
01936 }
01937
01938
01939
01940 mExtraFolders.remove( mCalendar->location() );
01941 mExtraFolders.remove( mTasks->location() );
01942 mExtraFolders.remove( mContacts->location() );
01943 mExtraFolders.remove( mNotes->location() );
01944
01945
01946
01947 subresourceAdded( folderContentsType( KMail::ContentsTypeCalendar ), mCalendar->location(), mCalendar->label(), true, true );
01948 subresourceAdded( folderContentsType( KMail::ContentsTypeTask ), mTasks->location(), mTasks->label(), true, true );
01949 subresourceAdded( folderContentsType( KMail::ContentsTypeContact ), mContacts->location(), mContacts->label(), true, false );
01950 subresourceAdded( folderContentsType( KMail::ContentsTypeNote ), mNotes->location(), mNotes->label(), true, false );
01951 }
01952
01953 TDEConfig *config = kmkernel->config();
01954 config->setGroup("Resource UINames");
01955 *KMailICalIfaceImpl::mSubResourceUINamesMap = config->entryMap( "Resource UINames" );
01956
01957 reloadFolderTree();
01958 }
01959
01960 void KMailICalIfaceImpl::slotCheckDone()
01961 {
01962 TQString parentName = GlobalSettings::self()->theIMAPResourceFolderParent();
01963 KMFolder* folderParent = kmkernel->findFolderById( parentName );
01964
01965 if ( folderParent )
01966 {
01967 KMAccount* account = kmkernel->acctMgr()->find( GlobalSettings::self()->theIMAPResourceAccount() );
01968 if ( account )
01969 disconnect( account, TQT_SIGNAL( finishedCheck( bool, CheckStatus ) ),
01970 this, TQT_SLOT( slotCheckDone() ) );
01971 readConfig();
01972 }
01973 }
01974
01975 KMFolder* KMailICalIfaceImpl::initFolder( KMail::FolderContentsType contentsType )
01976 {
01977
01978 KMFolderType type = mFolderType;
01979 if( type == KMFolderTypeUnknown ) type = KMFolderTypeMaildir;
01980
01981 KFolderTreeItem::Type itemType = s_folderContentsType[contentsType].treeItemType;
01982
01983
01984
01985 StandardFolderSearchResult result = findStandardResourceFolder( mFolderParentDir, contentsType );
01986
01987
01988 if ( result.folders.count() > 1 && result.found == StandardFolderSearchResult::FoundAndStandard ) {
01989 TQStringList labels;
01990 for ( TQValueList<KMFolder*>::ConstIterator it = result.folders.begin(); it != result.folders.end(); ++it )
01991 labels << (*it)->prettyURL();
01992 const TQString selected = KInputDialog::getItem( i18n("Default folder"),
01993 i18n("There are multiple %1 default folders, please choose one:")
01994 .arg( localizedDefaultFolderName( contentsType ) ), labels );
01995 if ( !selected.isEmpty() )
01996 result.folder = result.folders[ labels.findIndex( selected ) ];
01997 }
01998
01999 KMFolder* folder = result.folder;
02000
02001 if ( !folder ) {
02002
02003 folder =
02004 mFolderParentDir->createFolder( localizedDefaultFolderName( contentsType ), false, type );
02005 if( mFolderType == KMFolderTypeImap ) {
02006 KMFolderImap* parentFolder = static_cast<KMFolderImap*>( mFolderParent->storage() );
02007 parentFolder->createFolder( localizedDefaultFolderName( contentsType ) );
02008 static_cast<KMFolderImap*>( folder->storage() )->setAccount( parentFolder->account() );
02009 }
02010
02011 setStorageFormat( folder, globalStorageFormat() );
02012 } else {
02013 FolderInfo info = readFolderInfo( folder );
02014 mFolderInfoMap.insert( folder, info );
02015
02016 }
02017
02018 if( folder->canAccess() != 0 ) {
02019 KMessageBox::sorry(0, i18n("You do not have read/write permission to your %1 folder.")
02020 .arg( folderName( itemType ) ) );
02021 return 0;
02022 }
02023 folder->storage()->setContentsType( contentsType );
02024 folder->setSystemFolder( true );
02025 folder->storage()->writeConfig();
02026 folder->open("ifacefolder");
02027 connectFolder( folder );
02028 return folder;
02029 }
02030
02031 KMFolder* KMailICalIfaceImpl::initScalixFolder( KMail::FolderContentsType contentsType )
02032 {
02033
02034 KMFolderType type = mFolderType;
02035 if( type == KMFolderTypeUnknown ) type = KMFolderTypeMaildir;
02036
02037 KMFolder* folder = 0;
02038
02039
02040 TQStringList folderNames;
02041 TQValueList<TQGuardedPtr<KMFolder> > folderList;
02042 Q_ASSERT( kmkernel );
02043 Q_ASSERT( kmkernel->dimapFolderMgr() );
02044 kmkernel->dimapFolderMgr()->createFolderList(&folderNames, &folderList);
02045 TQValueList<TQGuardedPtr<KMFolder> >::iterator it = folderList.begin();
02046 for(; it != folderList.end(); ++it)
02047 {
02048 FolderStorage *storage = (*it)->storage();
02049
02050 if ( (*it)->folderType() == KMFolderTypeCachedImap ) {
02051 KMFolderCachedImap *imapFolder = static_cast<KMFolderCachedImap*>( storage );
02052
02053 const TQString attributes = imapFolder->folderAttributes();
02054 if ( attributes.contains( "X-SpecialFolder" ) ) {
02055 const Scalix::FolderAttributeParser parser( attributes );
02056 if ( contentsType == Scalix::Utils::scalixIdToContentsType( parser.folderClass() ) ) {
02057 folder = *it;
02058 break;
02059 }
02060 }
02061 }
02062 }
02063
02064 if ( !folder ) {
02065 return 0;
02066 } else {
02067 FolderInfo info = readFolderInfo( folder );
02068 mFolderInfoMap.insert( folder, info );
02069
02070 }
02071
02072 if( folder->canAccess() != 0 ) {
02073 KMessageBox::sorry(0, i18n("You do not have read/write permission to your folder.") );
02074 return 0;
02075 }
02076 folder->storage()->setContentsType( contentsType );
02077 folder->setSystemFolder( true );
02078 folder->storage()->writeConfig();
02079 folder->open( "scalixfolder" );
02080 connectFolder( folder );
02081 return folder;
02082 }
02083
02084 void KMailICalIfaceImpl::connectFolder( KMFolder* folder )
02085 {
02086
02087 disconnect( folder, TQT_SIGNAL( msgAdded( KMFolder*, TQ_UINT32 ) ),
02088 this, TQT_SLOT( slotIncidenceAdded( KMFolder*, TQ_UINT32 ) ) );
02089 disconnect( folder, TQT_SIGNAL( msgRemoved( KMFolder*, TQ_UINT32 ) ),
02090 this, TQT_SLOT( slotIncidenceDeleted( KMFolder*, TQ_UINT32 ) ) );
02091 disconnect( folder, TQT_SIGNAL( expunged( KMFolder* ) ),
02092 this, TQT_SLOT( slotRefreshFolder( KMFolder* ) ) );
02093 disconnect( folder->storage(), TQT_SIGNAL( readOnlyChanged( KMFolder* ) ),
02094 this, TQT_SLOT( slotFolderPropertiesChanged( KMFolder* ) ) );
02095 disconnect( folder, TQT_SIGNAL( nameChanged() ),
02096 this, TQT_SLOT( slotFolderRenamed() ) );
02097 disconnect( folder->storage(), TQT_SIGNAL( locationChanged( const TQString&, const TQString&) ),
02098 this, TQT_SLOT( slotFolderLocationChanged( const TQString&, const TQString&) ) );
02099
02100
02101 connect( folder, TQT_SIGNAL( msgAdded( KMFolder*, TQ_UINT32 ) ),
02102 this, TQT_SLOT( slotIncidenceAdded( KMFolder*, TQ_UINT32 ) ) );
02103 connect( folder, TQT_SIGNAL( msgRemoved( KMFolder*, TQ_UINT32 ) ),
02104 this, TQT_SLOT( slotIncidenceDeleted( KMFolder*, TQ_UINT32 ) ) );
02105 connect( folder, TQT_SIGNAL( expunged( KMFolder* ) ),
02106 this, TQT_SLOT( slotRefreshFolder( KMFolder* ) ) );
02107 connect( folder->storage(), TQT_SIGNAL( readOnlyChanged( KMFolder* ) ),
02108 this, TQT_SLOT( slotFolderPropertiesChanged( KMFolder* ) ) );
02109 connect( folder, TQT_SIGNAL( nameChanged() ),
02110 this, TQT_SLOT( slotFolderRenamed() ) );
02111 connect( folder->storage(), TQT_SIGNAL( locationChanged( const TQString&, const TQString&) ),
02112 this, TQT_SLOT( slotFolderLocationChanged( const TQString&, const TQString&) ) );
02113
02114 }
02115
02116 static void cleanupFolder( KMFolder* folder, KMailICalIfaceImpl* _this )
02117 {
02118 if( folder ) {
02119 folder->setSystemFolder( false );
02120 folder->disconnect( _this );
02121 folder->close("ifacefolder");
02122 }
02123 }
02124
02125 void KMailICalIfaceImpl::cleanup()
02126 {
02127 cleanupFolder( mContacts, this );
02128 cleanupFolder( mCalendar, this );
02129 cleanupFolder( mNotes, this );
02130 cleanupFolder( mTasks, this );
02131 cleanupFolder( mJournals, this );
02132
02133 mContacts = mCalendar = mNotes = mTasks = mJournals = 0;
02134 }
02135
02136 TQString KMailICalIfaceImpl::folderPixmap( KFolderTreeItem::Type type ) const
02137 {
02138 if( !mUseResourceIMAP )
02139 return TQString();
02140
02141 if( type == KFolderTreeItem::Contacts )
02142 return TQString::fromLatin1( "kmgroupware_folder_contacts" );
02143 else if( type == KFolderTreeItem::Calendar )
02144 return TQString::fromLatin1( "kmgroupware_folder_calendar" );
02145 else if( type == KFolderTreeItem::Notes )
02146 return TQString::fromLatin1( "kmgroupware_folder_notes" );
02147 else if( type == KFolderTreeItem::Tasks )
02148 return TQString::fromLatin1( "kmgroupware_folder_tasks" );
02149 else if( type == KFolderTreeItem::Journals )
02150 return TQString::fromLatin1( "kmgroupware_folder_journals" );
02151
02152 return TQString();
02153 }
02154
02155 static void reloadFolderTree()
02156 {
02157
02158 kmkernel->folderMgr()->contentsChanged();
02159 }
02160
02161
02162
02163
02164 static void vPartMicroParser( const TQString& str, TQString& s )
02165 {
02166 TQString line;
02167 uint len = str.length();
02168
02169 for( uint i=0; i<len; ++i){
02170 if( str[i] == '\r' || str[i] == '\n' ){
02171 if( str[i] == '\r' )
02172 ++i;
02173 if( i+1 < len && str[i+1] == ' ' ){
02174
02175 ++i;
02176 }else{
02177
02178 if( line.startsWith( s ) ) {
02179 s = line.mid( s.length() + 1 );
02180 return;
02181 }
02182 line = "";
02183 }
02184 } else {
02185 line += str[i];
02186 }
02187 }
02188
02189
02190 s.truncate(0);
02191 }
02192
02193
02194 static TQValueList<KMFolder*> findFolderByAnnotation( KMFolderDir* folderParentDir, const TQString& annotation )
02195 {
02196 TQValueList<KMFolder*> rv;
02197 TQPtrListIterator<KMFolderNode> it( *folderParentDir );
02198 for ( ; it.current(); ++it ) {
02199 if ( !it.current()->isDir() ) {
02200 KMFolder* folder = static_cast<KMFolder *>( it.current() );
02201 if ( folder->folderType() == KMFolderTypeCachedImap ) {
02202 TQString folderAnnotation = static_cast<KMFolderCachedImap*>( folder->storage() )->annotationFolderType();
02203
02204 if ( folderAnnotation == annotation )
02205 rv.append( folder );
02206 }
02207 }
02208 }
02209 return rv;
02210 }
02211
02212 KMailICalIfaceImpl::StandardFolderSearchResult KMailICalIfaceImpl::findStandardResourceFolder( KMFolderDir* folderParentDir, KMail::FolderContentsType contentsType )
02213 {
02214 if ( GlobalSettings::self()->theIMAPResourceStorageFormat() == GlobalSettings::EnumTheIMAPResourceStorageFormat::XML )
02215 {
02216
02217 TQValueList<KMFolder*> folders = findFolderByAnnotation( folderParentDir, TQString( s_folderContentsType[contentsType].annotation ) + ".default" );
02218 if ( !folders.isEmpty() )
02219 return StandardFolderSearchResult( folders, StandardFolderSearchResult::FoundAndStandard );
02220
02221
02222 folders = findFolderByAnnotation( folderParentDir, TQString( s_folderContentsType[contentsType].annotation ) );
02223 if ( !folders.isEmpty() )
02224 return StandardFolderSearchResult( folders, StandardFolderSearchResult::FoundByType );
02225
02226
02227 KMFolderNode* node = folderParentDir->hasNamedFolder( localizedDefaultFolderName( contentsType ) );
02228 if ( node && !node->isDir() )
02229 return StandardFolderSearchResult( static_cast<KMFolder *>( node ), StandardFolderSearchResult::FoundByName );
02230
02231 kdDebug(5006) << "findStandardResourceFolder: found no resource folder for " << s_folderContentsType[contentsType].annotation << endl;
02232 return StandardFolderSearchResult( 0, StandardFolderSearchResult::NotFound );
02233 }
02234 else
02235 {
02236 KFolderTreeItem::Type itemType = s_folderContentsType[contentsType].treeItemType;
02237 unsigned int folderLanguage = GlobalSettings::self()->theIMAPResourceFolderLanguage();
02238 if( folderLanguage > 3 ) folderLanguage = 0;
02239 KMFolderNode* node = folderParentDir->hasNamedFolder( folderName( itemType, folderLanguage ) );
02240 if ( !node || node->isDir() )
02241 return StandardFolderSearchResult( 0, StandardFolderSearchResult::NotFound );
02242 return StandardFolderSearchResult( static_cast<KMFolder*>( node ), StandardFolderSearchResult::FoundAndStandard );
02243 }
02244 }
02245
02246
02247
02248
02249
02250 bool KMailICalIfaceImpl::folderIsAlarmRelevant( const KMFolder *folder )
02251 {
02252 bool administerRights = true;
02253 bool relevantForOwner = true;
02254 bool relevantForEveryone = false;
02255 if ( folder->folderType() == KMFolderTypeImap ) {
02256 const KMFolderImap *imapFolder = static_cast<const KMFolderImap*>( folder->storage() );
02257 administerRights =
02258 imapFolder->userRightsState() != KMail::ACLJobs::Ok ||
02259 imapFolder->userRights() & KMail::ACLJobs::Administer;
02260 }
02261 if ( folder->folderType() == KMFolderTypeCachedImap ) {
02262 const KMFolderCachedImap *dimapFolder = static_cast<const KMFolderCachedImap*>( folder->storage() );
02263 administerRights =
02264 dimapFolder->userRightsState() != KMail::ACLJobs::Ok ||
02265 dimapFolder->userRights() & KMail::ACLJobs::Administer;
02266 relevantForOwner = !dimapFolder->alarmsBlocked() && ( dimapFolder->incidencesFor () == KMFolderCachedImap::IncForAdmins );
02267 relevantForEveryone = !dimapFolder->alarmsBlocked() && ( dimapFolder->incidencesFor() == KMFolderCachedImap::IncForReaders );
02268 }
02269 #if 0
02270 kdDebug(5006) << k_funcinfo << endl;
02271 kdDebug(5006) << "Folder: " << folder->label() << " has administer rights: " << administerRights << endl;
02272 kdDebug(5006) << "and is relevant for owner: " << relevantForOwner << endl;
02273 kdDebug(5006) << "and relevant for everyone: " << relevantForEveryone << endl;
02274 #endif
02275 return ( administerRights && relevantForOwner ) || relevantForEveryone;
02276 }
02277
02278 void KMailICalIfaceImpl::setResourceQuiet(bool q)
02279 {
02280 mResourceQuiet = q;
02281 }
02282
02283 bool KMailICalIfaceImpl::isResourceQuiet() const
02284 {
02285 return mResourceQuiet;
02286 }
02287
02288
02289 bool KMailICalIfaceImpl::addSubresource( const TQString& resource,
02290 const TQString& parent,
02291 const TQString& contentsType )
02292 {
02293 kdDebug(5006) << "Adding subresource to parent: " << parent << " with name: " << resource << endl;
02294 kdDebug(5006) << "contents type: " << contentsType << endl;
02295 KMFolder *folder = findResourceFolder( parent );
02296 KMFolderDir *parentFolderDir = !parent.isEmpty() && folder ? folder->createChildFolder(): mFolderParentDir;
02297 if ( !parentFolderDir || parentFolderDir->hasNamedFolder( resource ) ) return false;
02298
02299 TQString msg;
02300 if ( parentFolderDir->owner() && !parentFolderDir->owner()->isValidName( resource, msg ) ) {
02301 KMessageBox::error( 0, msg );
02302 return false;
02303 }
02304
02305 KMFolderType type = mFolderType;
02306 if( type == KMFolderTypeUnknown ) type = KMFolderTypeMaildir;
02307
02308 KMFolder* newFolder = parentFolderDir->createFolder( resource, false, type );
02309 if ( !newFolder ) return false;
02310 if( mFolderType == KMFolderTypeImap )
02311 static_cast<KMFolderImap*>( folder->storage() )->createFolder( resource );
02312
02313 StorageFormat defaultFormat = GlobalSettings::self()->theIMAPResourceStorageFormat() == GlobalSettings::EnumTheIMAPResourceStorageFormat::XML ? StorageXML : StorageIcalVcard;
02314 setStorageFormat( newFolder, folder ? storageFormat( folder ) : defaultFormat );
02315 newFolder->storage()->setContentsType( folderContentsType( contentsType ) );
02316 newFolder->storage()->writeConfig();
02317 newFolder->open( "ical_subresource" );
02318 connectFolder( newFolder );
02319 reloadFolderTree();
02320
02321 return true;
02322 }
02323
02324 bool KMailICalIfaceImpl::removeSubresource( const TQString& location )
02325 {
02326 kdDebug(5006) << k_funcinfo << endl;
02327
02328 KMFolder *folder = findResourceFolder( location );
02329
02330
02331
02332
02333 if ( !folder || isStandardResourceFolder( folder ) )
02334 return false;
02335
02336
02337
02338 subresourceDeleted( folderContentsType( folder->storage()->contentsType() ), location );
02339 mExtraFolders.remove( location );
02340 folder->disconnect( this );
02341
02342 if ( folder->folderType() == KMFolderTypeImap )
02343 kmkernel->imapFolderMgr()->remove( folder );
02344 else if ( folder->folderType() == KMFolderTypeCachedImap ) {
02345
02346 KMFolderCachedImap* storage = static_cast<KMFolderCachedImap*>( folder->storage() );
02347 KMAcctCachedImap* acct = storage->account();
02348 if ( acct )
02349 acct->addDeletedFolder( folder );
02350 kmkernel->dimapFolderMgr()->remove( folder );
02351 }
02352 return true;
02353 }
02354
02355 void KMailICalIfaceImpl::syncFolder(KMFolder * folder) const
02356 {
02357 if ( kmkernel->isOffline() || !GlobalSettings::immediatlySyncDIMAPOnGroupwareChanges() )
02358 return;
02359 KMFolderCachedImap *dimapFolder = dynamic_cast<KMFolderCachedImap*>( folder->storage() );
02360 if ( !dimapFolder )
02361 return;
02362
02363 if ( dimapFolder->imapPath().isEmpty() ) {
02364 if ( folder->parent() && folder->parent()->owner() )
02365 syncFolder( folder->parent()->owner() );
02366 else
02367 return;
02368 }
02369 dimapFolder->account()->processNewMailInFolder( folder );
02370 }
02371
02372 #include "kmailicalifaceimpl.moc"