00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifdef HAVE_CONFIG_H
00024 #include <config.h>
00025 #endif
00026
00027 #include "kmailicalifaceimpl.h"
00028 #include "kmfoldertree.h"
00029 #include "kmfolderdir.h"
00030 #include "kmgroupware.h"
00031 #include "kmgroupwarefuncs.h"
00032 #include "kmfoldermgr.h"
00033 #include "kmcommands.h"
00034 #include "kmfolderindex.h"
00035 #include "kmmsgdict.h"
00036
00037 #include <mimelib/enum.h>
00038
00039 #include <kdebug.h>
00040 #include <kiconloader.h>
00041 #include <dcopclient.h>
00042 #include <kmessagebox.h>
00043 #include <kconfig.h>
00044 #include <qmap.h>
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 KMailICalIfaceImpl::KMailICalIfaceImpl()
00057 : DCOPObject( "KMailICalIface" ), QObject( 0, "KMailICalIfaceImpl" ),
00058 mContacts( 0 ), mCalendar( 0 ), mNotes( 0 ), mTasks( 0 ), mJournals( 0 ),
00059 mFolderLanguage( 0 ), mUseResourceIMAP( false ), mResourceQuiet( false )
00060 {
00061 }
00062
00063
00064 bool KMailICalIfaceImpl::addIncidence( const QString& type,
00065 const QString& uid,
00066 const QString& ical )
00067 {
00068 if( !mUseResourceIMAP )
00069 return false;
00070
00071 bool rc = false;
00072 bool quiet = mResourceQuiet;
00073 mResourceQuiet = true;
00074
00075
00076 KMFolder* folder = folderFromType( type );
00077 if( folder ) {
00078
00079 KMMessage* msg = new KMMessage();
00080 msg->initHeader();
00081 msg->setType( DwMime::kTypeText );
00082 if( folder == mContacts ) {
00083 msg->setSubtype( DwMime::kSubtypeXVCard );
00084 msg->setHeaderField( "Content-Type", "Text/X-VCard; charset=\"utf-8\"" );
00085 msg->setSubject( "vCard " + uid );
00086 } else {
00087 msg->setSubtype( DwMime::kSubtypeVCal );
00088 msg->setHeaderField("Content-Type",
00089 "text/calendar; method=REQUEST; charset=\"utf-8\"");
00090 msg->setSubject( "iCal " + uid );
00091 }
00092 msg->setBodyEncoded( ical.utf8() );
00093
00094
00095 msg->touch();
00096 folder->addMsg( msg );
00097
00098 rc = true;
00099 } else
00100 kdError() << "Not an IMAP resource folder" << endl;
00101
00102 mResourceQuiet = quiet;
00103 return false;
00104 }
00105
00106
00107 bool KMailICalIfaceImpl::deleteIncidence( const QString& type,
00108 const QString& uid )
00109 {
00110 if( !mUseResourceIMAP )
00111 return false;
00112
00113 bool rc = false;
00114 bool quiet = mResourceQuiet;
00115 mResourceQuiet = true;
00116
00117
00118 KMFolder* folder = folderFromType( type );
00119 if( folder ) {
00120 KMMessage* msg = findMessageByUID( uid, folder );
00121 if( msg ) {
00122
00123 deleteMsg( msg );
00124 rc = true;
00125 } else
00126 kdDebug(5006) << type << " not found, cannot remove uid " << uid << endl;
00127 } else
00128 kdError() << "Not an IMAP resource folder" << endl;
00129
00130 mResourceQuiet = quiet;
00131 return true;
00132 }
00133
00134
00135 QStringList KMailICalIfaceImpl::incidences( const QString& type )
00136 {
00137 if( !mUseResourceIMAP )
00138 return QStringList();
00139
00140 QStringList ilist;
00141
00142 KMFolder* folder = folderFromType( type );
00143 if( folder ) {
00144 QString s;
00145 for( int i=0; i<folder->count(); ++i ) {
00146 bool unget = !folder->isMessage(i);
00147 if( KMGroupware::vPartFoundAndDecoded( folder->getMsg( i ), s ) ) {
00148 ilist << s;
00149 }
00150 if( unget ) folder->unGetMsg(i);
00151 }
00152 } else
00153 kdError() << "Not an IMAP resource folder" << endl;
00154
00155 return ilist;
00156 }
00157
00158 bool KMailICalIfaceImpl::update( const QString& type,
00159 const QStringList& entries )
00160 {
00161 if( !mUseResourceIMAP )
00162 return false;
00163
00164 if( entries.count() & 2 == 1 )
00165
00166 return false;
00167
00168 QStringList::ConstIterator it = entries.begin();
00169 while( true ) {
00170
00171 QString uid, entry;
00172 if( it == entries.end() )
00173 break;
00174 uid = *it;
00175 ++it;
00176 if( it == entries.end() )
00177 break;
00178 entry = *it;
00179 ++it;
00180
00181 if( !update( type, uid, entry ) )
00182
00183 return false;
00184 }
00185
00186 return true;
00187 }
00188
00189 bool KMailICalIfaceImpl::update( const QString& type, const QString& uid,
00190 const QString& entry )
00191 {
00192 if( !mUseResourceIMAP )
00193 return false;
00194
00195 bool rc = true;
00196 bool quiet = mResourceQuiet;
00197 mResourceQuiet = true;
00198
00199
00200 KMFolder* folder = folderFromType( type );
00201 if( folder ) {
00202 KMMessage* msg = findMessageByUID( uid, folder );
00203 if( msg ) {
00204
00205 deleteMsg( msg );
00206 addIncidence( type, uid, entry );
00207 rc = true;
00208 } else {
00209 kdDebug(5006) << type << " not found, cannot update uid " << uid << endl;
00210
00211 addIncidence( type, uid, entry );
00212 }
00213 } else {
00214 kdError() << "Not an IMAP resource folder" << endl;
00215 rc = false;
00216 }
00217
00218 mResourceQuiet = quiet;
00219 return rc;
00220 }
00221
00222
00223 void KMailICalIfaceImpl::slotIncidenceAdded( KMFolder* folder,
00224 Q_UINT32 sernum )
00225 {
00226 if( mResourceQuiet || !mUseResourceIMAP )
00227 return;
00228
00229 QString type = icalFolderType( folder );
00230 if( !type.isEmpty() ) {
00231
00232 int i = 0;
00233 KMFolder* aFolder = 0;
00234 kmkernel->msgDict()->getLocation( sernum, &aFolder, &i );
00235 assert( folder == aFolder );
00236
00237
00238 bool unget = !folder->isMessage( i );
00239 QString s;
00240 if( KMGroupware::vPartFoundAndDecoded( folder->getMsg( i ), s ) ) {
00241 QByteArray data;
00242 QDataStream arg(data, IO_WriteOnly );
00243 arg << type << s;
00244 emitDCOPSignal( "incidenceAdded(QString,QString)", data );
00245 }
00246 if( unget ) folder->unGetMsg(i);
00247 } else
00248 kdError() << "Not an IMAP resource folder" << endl;
00249 }
00250
00251
00252 void KMailICalIfaceImpl::slotIncidenceDeleted( KMFolder* folder,
00253 Q_UINT32 sernum )
00254 {
00255 if( mResourceQuiet || !mUseResourceIMAP )
00256 return;
00257
00258 QString type = icalFolderType( folder );
00259 if( !type.isEmpty() ) {
00260
00261 int i = 0;
00262 KMFolder* aFolder = 0;
00263 kmkernel->msgDict()->getLocation( sernum, &aFolder, &i );
00264 assert( folder == aFolder );
00265
00266
00267 bool unget = !folder->isMessage( i );
00268 QString s;
00269 if( KMGroupware::vPartFoundAndDecoded( folder->getMsg( i ), s ) ) {
00270 QString uid( "UID" );
00271 vPartMicroParser( s.utf8(), uid );
00272 QByteArray data;
00273 QDataStream arg(data, IO_WriteOnly );
00274 arg << type << uid;
00275 emitDCOPSignal( "incidenceDeleted(QString,QString)", data );
00276 }
00277 if( unget ) folder->unGetMsg(i);
00278 } else
00279 kdError() << "Not a groupware folder" << endl;
00280 }
00281
00282
00283 void KMailICalIfaceImpl::slotRefresh( const QString& type )
00284 {
00285 if( mUseResourceIMAP ) {
00286 QByteArray data;
00287 QDataStream arg(data, IO_WriteOnly );
00288 arg << type;
00289 emitDCOPSignal( "signalRefresh(QString)", data );
00290 }
00291 }
00292
00293
00294
00295
00296
00297
00298 KMFolder* KMailICalIfaceImpl::folderFromType( const QString& type )
00299 {
00300 if( mUseResourceIMAP ) {
00301 if( type == "Calendar" ) return mCalendar;
00302 else if( type == "Contact" ) return mContacts;
00303 else if( type == "Note" ) return mNotes;
00304 else if( type == "Task" || type == "Todo" ) return mTasks;
00305 else if( type == "Journal" ) return mJournals;
00306
00307 kdError() << "No folder type \"" << type << "\"" << endl;
00308 }
00309
00310 return 0;
00311 }
00312
00313
00314
00315
00316 bool KMailICalIfaceImpl::isResourceImapFolder( KMFolder* folder ) const
00317 {
00318 return mUseResourceIMAP && folder &&
00319 ( folder == mCalendar || folder == mTasks || folder == mJournals ||
00320 folder == mNotes || folder == mContacts );
00321 }
00322
00323
00324 KFolderTreeItem::Type KMailICalIfaceImpl::folderType( KMFolder* folder ) const
00325 {
00326 if( mUseResourceIMAP && folder ) {
00327 if( folder == mCalendar )
00328 return KFolderTreeItem::Calendar;
00329 else if( folder == mContacts )
00330 return KFolderTreeItem::Contacts;
00331 else if( folder == mNotes )
00332 return KFolderTreeItem::Notes;
00333 else if( folder == mTasks )
00334 return KFolderTreeItem::Tasks;
00335 else if( folder == mJournals )
00336 return KFolderTreeItem::Journals;
00337 }
00338
00339 return KFolderTreeItem::Other;
00340 }
00341
00342
00343 QString KMailICalIfaceImpl::icalFolderType( KMFolder* folder ) const
00344 {
00345 if( mUseResourceIMAP && folder ) {
00346 if( folder == mCalendar )
00347 return "Calendar";
00348 else if( folder == mContacts )
00349 return "Contact";
00350 else if( folder == mNotes )
00351 return "Note";
00352 else if( folder == mTasks )
00353 return "Task";
00354 else if( folder == mJournals )
00355 return "Journal";
00356 }
00357
00358 return QString::null;
00359 }
00360
00361
00362
00363
00364 static QMap<KFolderTreeItem::Type,QString> folderNames[4];
00365 QString KMailICalIfaceImpl::folderName( KFolderTreeItem::Type type, int language ) const
00366 {
00367 static bool folderNamesSet = false;
00368 if( !folderNamesSet ) {
00369 folderNamesSet = true;
00370
00371
00372
00373
00374 folderNames[0][KFolderTreeItem::Calendar] = QString::fromLatin1("Calendar");
00375 folderNames[0][KFolderTreeItem::Tasks] = QString::fromLatin1("Tasks");
00376 folderNames[0][KFolderTreeItem::Journals] = QString::fromLatin1("Journal");
00377 folderNames[0][KFolderTreeItem::Contacts] = QString::fromLatin1("Contacts");
00378 folderNames[0][KFolderTreeItem::Notes] = QString::fromLatin1("Notes");
00379
00380
00381 folderNames[1][KFolderTreeItem::Calendar] = QString::fromLatin1("Kalender");
00382 folderNames[1][KFolderTreeItem::Tasks] = QString::fromLatin1("Aufgaben");
00383 folderNames[1][KFolderTreeItem::Journals] = QString::fromLatin1("Journal");
00384 folderNames[1][KFolderTreeItem::Contacts] = QString::fromLatin1("Kontakte");
00385 folderNames[1][KFolderTreeItem::Notes] = QString::fromLatin1("Notizen");
00386
00387
00388 folderNames[2][KFolderTreeItem::Calendar] = QString::fromLatin1("Calendrier");
00389 folderNames[2][KFolderTreeItem::Tasks] = QString::fromLatin1("Tāches");
00390 folderNames[2][KFolderTreeItem::Journals] = QString::fromLatin1("Journal");
00391 folderNames[2][KFolderTreeItem::Contacts] = QString::fromLatin1("Contacts");
00392 folderNames[2][KFolderTreeItem::Notes] = QString::fromLatin1("Notes");
00393
00394
00395 folderNames[3][KFolderTreeItem::Calendar] = QString::fromLatin1("Agenda");
00396 folderNames[3][KFolderTreeItem::Tasks] = QString::fromLatin1("Taken");
00397 folderNames[3][KFolderTreeItem::Journals] = QString::fromLatin1("Logboek");
00398 folderNames[3][KFolderTreeItem::Contacts] = QString::fromLatin1("Contactpersonen");
00399 folderNames[3][KFolderTreeItem::Notes] = QString::fromLatin1("Notities");
00400 }
00401
00402 if( language < 0 || language > 3 ) {
00403 return folderNames[mFolderLanguage][type];
00404 }
00405 else {
00406 return folderNames[language][type];
00407 }
00408 }
00409
00410
00411
00412 KMMessage *KMailICalIfaceImpl::findMessageByUID( const QString& uid, KMFolder* folder )
00413 {
00414 if( !folder ) return 0;
00415
00416 for( int i=0; i<folder->count(); ++i ) {
00417 bool unget = !folder->isMessage(i);
00418 KMMessage* msg = folder->getMsg( i );
00419 if( msg ) {
00420 QString vCal;
00421 if( KMGroupware::vPartFoundAndDecoded( msg, vCal ) ) {
00422 QString msgUid( "UID" );
00423 vPartMicroParser( vCal.utf8(), msgUid );
00424 if( msgUid == uid )
00425 return msg;
00426 }
00427 }
00428 if( unget ) folder->unGetMsg(i);
00429 }
00430
00431 return 0;
00432 }
00433
00434 void KMailICalIfaceImpl::deleteMsg( KMMessage *msg )
00435 {
00436 if( !msg ) return;
00437 ( new KMDeleteMsgCommand( msg->parent(), msg ) )->start();
00438 }
00439
00440
00441
00442
00443
00444 void KMailICalIfaceImpl::readConfig()
00445 {
00446
00447 KConfigGroup options( KMKernel::config(), "IMAP Resource" );
00448 bool enabled = options.readBoolEntry( "Enabled", false );
00449
00450 if( !enabled ) {
00451 if( mUseResourceIMAP == true ) {
00452
00453 mUseResourceIMAP = false;
00454 cleanup();
00455 kmkernel->groupware().reloadFolderTree();
00456 }
00457 return;
00458 }
00459
00460
00461 unsigned int folderLanguage = options.readNumEntry( "Folder Language", 0 );
00462 if( folderLanguage > 3 ) folderLanguage = 0;
00463 QString parentName = options.readEntry("Folder Parent");
00464
00465
00466 KMFolderDir* folderParentDir;
00467 KMFolderType folderType;
00468 KMFolder* folderParent = kmkernel->folderMgr()->findIdString( parentName );
00469 if( folderParent == 0 )
00470 folderParent = kmkernel->dimapFolderMgr()->findIdString( parentName );
00471 if( folderParent == 0 )
00472 folderParent = kmkernel->imapFolderMgr()->findIdString( parentName );
00473 if( folderParent == 0 ) {
00474
00475 folderParentDir = &(kmkernel->folderMgr()->dir());
00476 folderType = KMFolderTypeMaildir;
00477 } else {
00478 folderParentDir = folderParent->createChildFolder();
00479 folderType = folderParent->folderType();
00480 }
00481
00482
00483 bool makeSubFolders = false;
00484 KMFolderNode* node;
00485 node = folderParentDir->hasNamedFolder( folderName( KFolderTreeItem::Calendar ) );
00486 if( !node || node->isDir() ) makeSubFolders = true;
00487 node = folderParentDir->hasNamedFolder( folderName( KFolderTreeItem::Tasks ) );
00488 if( !node || node->isDir() ) makeSubFolders = true;
00489 node = folderParentDir->hasNamedFolder( folderName( KFolderTreeItem::Journals ) );
00490 if( !node || node->isDir() ) makeSubFolders = true;
00491 node = folderParentDir->hasNamedFolder( folderName( KFolderTreeItem::Contacts ) );
00492 if( !node || node->isDir() ) makeSubFolders = true;
00493 node = folderParentDir->hasNamedFolder( folderName( KFolderTreeItem::Notes ) );
00494 if( !node || node->isDir() ) makeSubFolders = true;
00495 if( makeSubFolders ) {
00496
00497 if( KMessageBox::questionYesNo( 0, i18n("KMail will now create the required folders for the IMAP resource"
00498 " as subfolders of %1. If you don't want this, press \"No\","
00499 " and the IMAP resource will be disabled").arg(folderParent!=0?folderParent->name():folderParentDir->name()),
00500 i18n("IMAP Resource Folders") ) == KMessageBox::No ) {
00501 mUseResourceIMAP = false;
00502 mFolderParent = 0;
00503 kmkernel->groupware().reloadFolderTree();
00504 return;
00505 }
00506 }
00507
00508
00509 if( mUseResourceIMAP && !makeSubFolders && mFolderParent == folderParentDir && mFolderType == folderType )
00510
00511 return;
00512
00513
00514 mUseResourceIMAP = true;
00515 mFolderLanguage = folderLanguage;
00516 mFolderParent = folderParentDir;
00517 mFolderType = folderType;
00518
00519
00520 cleanup();
00521
00522
00523 mCalendar = initFolder( KFolderTreeItem::Calendar, "GCa" );
00524 mTasks = initFolder( KFolderTreeItem::Tasks, "GTa" );
00525 mJournals = initFolder( KFolderTreeItem::Journals, "GTa" );
00526 mContacts = initFolder( KFolderTreeItem::Contacts, "GCo" );
00527 mNotes = initFolder( KFolderTreeItem::Notes, "GNo" );
00528
00529
00530 connect( mCalendar, SIGNAL( expunged() ), this, SLOT( slotRefreshCalendar() ) );
00531 connect( mTasks, SIGNAL( expunged() ), this, SLOT( slotRefreshTasks() ) );
00532 connect( mJournals, SIGNAL( expunged() ), this, SLOT( slotRefreshJournals() ) );
00533 connect( mContacts, SIGNAL( expunged() ), this, SLOT( slotRefreshContacts() ) );
00534 connect( mNotes, SIGNAL( expunged() ), this, SLOT( slotRefreshNotes() ) );
00535
00536
00537 connect( mNotes, SIGNAL( changed() ), this, SLOT( slotRefreshNotes() ) );
00538
00539
00540 slotRefresh( "Calendar" );
00541 slotRefresh( "Task" );
00542 slotRefresh( "Journal" );
00543 slotRefresh( "Contact" );
00544 slotRefresh( "Notes" );
00545
00546 kmkernel->groupware().reloadFolderTree();
00547 }
00548
00549 void KMailICalIfaceImpl::slotRefreshCalendar() { slotRefresh( "Calendar" ); }
00550 void KMailICalIfaceImpl::slotRefreshTasks() { slotRefresh( "Task" ); }
00551 void KMailICalIfaceImpl::slotRefreshJournals() { slotRefresh( "Journal" ); }
00552 void KMailICalIfaceImpl::slotRefreshContacts() { slotRefresh( "Contact" ); }
00553 void KMailICalIfaceImpl::slotRefreshNotes() { slotRefresh( "Notes" ); }
00554
00555 KMFolder* KMailICalIfaceImpl::initFolder( KFolderTreeItem::Type itemType,
00556 const char* typeString )
00557 {
00558
00559 KMFolderType type = mFolderType;
00560 if( type == KMFolderTypeUnknown ) type = KMFolderTypeMaildir;
00561
00562
00563 KMFolder* folder = 0;
00564 KMFolderNode* node = mFolderParent->hasNamedFolder( folderName( itemType ) );
00565 if( node && !node->isDir() ) folder = static_cast<KMFolder*>(node);
00566
00567 if( !folder ) folder = mFolderParent->createFolder( folderName( itemType ), false, type );
00568 if( folder->canAccess() != 0 ) {
00569 KMessageBox::sorry(0, i18n("You do not have read/write permission to your %1 folder.")
00570 .arg( folderName( itemType ) ) );
00571 return 0;
00572 }
00573 folder->setType( typeString );
00574 folder->setSystemFolder( true );
00575 folder->open();
00576
00577
00578 connect( folder, SIGNAL( msgAdded( KMFolder*, Q_UINT32 ) ),
00579 this, SLOT( slotIncidenceAdded( KMFolder*, Q_UINT32 ) ) );
00580 connect( folder, SIGNAL( msgRemoved( KMFolder*, Q_UINT32 ) ),
00581 this, SLOT( slotIncidenceDeleted( KMFolder*, Q_UINT32 ) ) );
00582
00583 return folder;
00584 }
00585
00586 static void cleanupFolder( KMFolder* folder, KMailICalIfaceImpl* _this )
00587 {
00588 if( folder ) {
00589 folder->setType( "plain" );
00590 folder->setSystemFolder( false );
00591 folder->disconnect( _this );
00592 folder->close( true );
00593 }
00594 }
00595
00596 void KMailICalIfaceImpl::cleanup()
00597 {
00598 cleanupFolder( mContacts, this );
00599 cleanupFolder( mCalendar, this );
00600 cleanupFolder( mNotes, this );
00601 cleanupFolder( mTasks, this );
00602 cleanupFolder( mJournals, this );
00603
00604 mContacts = mCalendar = mNotes = mTasks = mJournals = 0;
00605 }
00606
00607 void KMailICalIfaceImpl::loadPixmaps() const
00608 {
00609 static bool pixmapsLoaded = false;
00610
00611 if( mUseResourceIMAP && !pixmapsLoaded ) {
00612 pixmapsLoaded = true;
00613 pixContacts = new QPixmap( UserIcon("kmgroupware_folder_contacts"));
00614 pixCalendar = new QPixmap( UserIcon("kmgroupware_folder_calendar"));
00615 pixNotes = new QPixmap( UserIcon("kmgroupware_folder_notes"));
00616 pixTasks = new QPixmap( UserIcon("kmgroupware_folder_tasks"));
00617
00618 }
00619 }
00620
00621 QString KMailICalIfaceImpl::folderPixmap( KFolderTreeItem::Type type ) const
00622 {
00623 if( !mUseResourceIMAP )
00624 return QString::null;
00625
00626 if( type == KFolderTreeItem::Contacts )
00627 return QString::fromLatin1( "kmgroupware_folder_contacts" );
00628 else if( type == KFolderTreeItem::Calendar )
00629 return QString::fromLatin1( "kmgroupware_folder_calendar" );
00630 else if( type == KFolderTreeItem::Notes )
00631 return QString::fromLatin1( "kmgroupware_folder_notes" );
00632 else if( type == KFolderTreeItem::Tasks )
00633 return QString::fromLatin1( "kmgroupware_folder_tasks" );
00634 else if( type == KFolderTreeItem::Journals )
00635 return QString::fromLatin1( "kmgroupware_folder_journals" );
00636
00637 return QString::null;
00638 }
00639
00640 QPixmap* KMailICalIfaceImpl::pixContacts;
00641 QPixmap* KMailICalIfaceImpl::pixCalendar;
00642 QPixmap* KMailICalIfaceImpl::pixNotes;
00643 QPixmap* KMailICalIfaceImpl::pixTasks;
00644
00645
00646 #include "kmailicalifaceimpl.moc"