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