00001
00002 #ifdef HAVE_CONFIG_H
00003 #include <config.h>
00004 #endif
00005
00006 #include "config.h"
00007 #include "kmkernel.h"
00008
00009 #include <weaver.h>
00010 #include <weaverlogger.h>
00011
00012 #include "kmstartup.h"
00013 #include "kmmsgindex.h"
00014 #include "kmmainwin.h"
00015 #include "kmcomposewin.h"
00016 #include "kmfoldermgr.h"
00017 #include "kmfoldercachedimap.h"
00018 #include "kmacctcachedimap.h"
00019 #include "kmfiltermgr.h"
00020 #include "kmfilteraction.h"
00021 #include "kmsender.h"
00022 #include "undostack.h"
00023 #include "kmacctmgr.h"
00024 #include "kfileio.h"
00025 #include "kmversion.h"
00026 #include "kmreaderwin.h"
00027 #include "kmmainwidget.h"
00028 #include "recentaddresses.h"
00029 using KRecentAddress::RecentAddresses;
00030 #include "kmmsgdict.h"
00031 #include "kmidentity.h"
00032 #include "identitymanager.h"
00033 #include "configuredialog.h"
00034
00035 #include <kwin.h>
00036 #include "kmgroupware.h"
00037 #include "kmailicalifaceimpl.h"
00038 #include "mailserviceimpl.h"
00039 using KMail::MailServiceImpl;
00040 #include "folderIface.h"
00041 using KMail::FolderIface;
00042 #include "cryptplugwrapperlist.h"
00043
00044 #include <kapplication.h>
00045 #include <kaboutdata.h>
00046 #include <kmessagebox.h>
00047 #include <knotifyclient.h>
00048 #include <kstaticdeleter.h>
00049 #include <kstandarddirs.h>
00050 #include <kconfig.h>
00051 #include <kprogress.h>
00052 #include <kpassivepopup.h>
00053 #include <dcopclient.h>
00054 #include <ksystemtray.h>
00055
00056 #include <kdebug.h>
00057
00058 #include <qutf7codec.h>
00059 #include <qvbox.h>
00060 #include <qdir.h>
00061 #include <qobjectlist.h>
00062
00063 #include <sys/types.h>
00064 #include <dirent.h>
00065 #include <sys/stat.h>
00066 #include <unistd.h>
00067 #include <stdio.h>
00068 #include <stdlib.h>
00069 #include <assert.h>
00070
00071 #include <X11/Xlib.h>
00072 #include <fixx11h.h>
00073 #include <kcmdlineargs.h>
00074 #include <kstartupinfo.h>
00075
00076 KMKernel *KMKernel::mySelf = 0;
00077
00078
00079
00080
00081 KMKernel::KMKernel (QObject *parent, const char *name) :
00082 DCOPObject("KMailIface"), QObject(parent, name),
00083 mIdentityManager(0), mProgress(0), mConfigureDialog(0),
00084 mContextMenuShown( false )
00085 {
00086
00087 mySelf = this;
00088 the_startingUp = true;
00089 closed_by_user = true;
00090 the_firstInstance = true;
00091 the_msgDict = 0;
00092 the_msgIndex = 0;
00093
00094 the_inboxFolder = 0;
00095 the_outboxFolder = 0;
00096 the_sentFolder = 0;
00097 the_trashFolder = 0;
00098 the_draftsFolder = 0;
00099
00100 the_folderMgr = 0;
00101 the_imapFolderMgr = 0;
00102 the_dimapFolderMgr = 0;
00103 the_searchFolderMgr = 0;
00104 the_undoStack = 0;
00105 the_acctMgr = 0;
00106 the_filterMgr = 0;
00107 the_popFilterMgr = 0;
00108 the_filterActionDict = 0;
00109 the_msgSender = 0;
00110 mWin = 0;
00111
00112 mGroupware = new KMGroupware( this );
00113
00114
00115 mICalIface = new KMailICalIfaceImpl();
00116
00117 mXmlGuiInstance = 0;
00118 mDeadLetterTimer = 0;
00119 mDeadLetterInterval = 1000*120;
00120 allowedToExpire = false;
00121
00122 new Kpgp::Module();
00123
00124
00125
00126 if ( !QTextCodec::codecForName("utf-7") ) {
00127 kdDebug(5006) << "No Qt-native utf-7 codec found; registering QUtf7Codec from libkdenetwork" << endl;
00128 (void) new QUtf7Codec();
00129 }
00130
00131
00132
00133
00134 if ( QCString(QTextCodec::codecForLocale()->name()).lower() == "eucjp" )
00135 {
00136 netCodec = QTextCodec::codecForName("jis7");
00137
00138
00139
00140 } else {
00141 netCodec = QTextCodec::codecForLocale();
00142 }
00143 mMailService = new MailServiceImpl();
00144 }
00145
00146 KMKernel::~KMKernel ()
00147 {
00148 QMap<KIO::Job*, putData>::Iterator it = mPutJobs.begin();
00149 while ( it != mPutJobs.end() )
00150 {
00151 KIO::Job *job = it.key();
00152 mPutJobs.remove( it );
00153 job->kill();
00154 it = mPutJobs.begin();
00155 }
00156
00157 delete mICalIface;
00158 mICalIface = 0L;
00159
00160 delete mMailService;
00161 mySelf = 0;
00162 kdDebug(5006) << "KMKernel::~KMKernel" << endl;
00163 }
00164
00165 bool KMKernel::handleCommandLine( bool noArgsOpensReader )
00166 {
00167 QString to, cc, bcc, subj, body;
00168 KURL messageFile;
00169 KURL::List attachURLs;
00170 bool mailto = false;
00171 bool checkMail = false;
00172
00173
00174
00175 KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
00176 if (args->getOption("subject"))
00177 {
00178 mailto = true;
00179 subj = QString::fromLocal8Bit(args->getOption("subject"));
00180 }
00181
00182 if (args->getOption("cc"))
00183 {
00184 mailto = true;
00185 cc = QString::fromLocal8Bit(args->getOption("cc"));
00186 }
00187
00188 if (args->getOption("bcc"))
00189 {
00190 mailto = true;
00191 bcc = QString::fromLocal8Bit(args->getOption("bcc"));
00192 }
00193
00194 if (args->getOption("msg"))
00195 {
00196 mailto = true;
00197 messageFile.setPath( QString::fromLocal8Bit(args->getOption("msg")) );
00198 }
00199
00200 if (args->getOption("body"))
00201 {
00202 mailto = true;
00203 body = QString::fromLocal8Bit(args->getOption("body"));
00204 }
00205
00206 QCStringList attachList = args->getOptionList("attach");
00207 if (!attachList.isEmpty())
00208 {
00209 mailto = true;
00210 for ( QCStringList::Iterator it = attachList.begin() ; it != attachList.end() ; ++it )
00211 if ( !(*it).isEmpty() )
00212 attachURLs += KURL( QString::fromLocal8Bit( *it ) );
00213 }
00214
00215 if (args->isSet("composer"))
00216 mailto = true;
00217
00218 if (args->isSet("check"))
00219 checkMail = true;
00220
00221 for(int i= 0; i < args->count(); i++)
00222 {
00223 if (strncasecmp(args->arg(i),"mailto:",7)==0)
00224 to += args->url(i).path() + ", ";
00225 else {
00226 QString tmpArg = QString::fromLocal8Bit( args->arg(i) );
00227 KURL url( tmpArg );
00228 if ( url.isValid() )
00229 attachURLs += url;
00230 else
00231 to += tmpArg + ", ";
00232 }
00233 mailto = true;
00234 }
00235 if ( !to.isEmpty() ) {
00236
00237 to.truncate( to.length() - 2 );
00238 }
00239
00240 args->clear();
00241
00242 if (!noArgsOpensReader && !mailto && !checkMail)
00243 return false;
00244
00245 action (mailto, checkMail, to, cc, bcc, subj, body, messageFile, attachURLs);
00246 return true;
00247 }
00248
00249
00250
00251
00252 void KMKernel::checkMail ()
00253 {
00254 kmkernel->acctMgr()->checkMail(false);
00255 }
00256
00257 QStringList KMKernel::accounts()
00258 {
00259 return kmkernel->acctMgr()->getAccounts();
00260 }
00261
00262 void KMKernel::checkAccount (const QString &account)
00263 {
00264 kdDebug(5006) << "KMKernel::checkMail called" << endl;
00265
00266 KMAccount* acct = kmkernel->acctMgr()->find(account);
00267 if (acct)
00268 kmkernel->acctMgr()->singleCheckMail(acct, false);
00269 }
00270
00271 void KMKernel::openReader( bool onlyCheck )
00272 {
00273 KMMainWin *mWin = 0;
00274 KMainWindow *ktmw = 0;
00275 kdDebug(5006) << "KMKernel::openReader called" << endl;
00276
00277 if (KMainWindow::memberList)
00278 for (ktmw = KMainWindow::memberList->first(); ktmw;
00279 ktmw = KMainWindow::memberList->next())
00280 if (ktmw->isA("KMMainWin"))
00281 break;
00282
00283 bool activate;
00284 if (ktmw) {
00285 mWin = (KMMainWin *) ktmw;
00286 activate = !onlyCheck;
00287 }
00288 else {
00289 mWin = new KMMainWin;
00290 activate = true;
00291 }
00292
00293 if ( activate ) {
00294 mWin->show();
00295
00296
00297 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00298 KStartupInfo::setNewStartupId( mWin, kapp->startupId() );
00299 #endif
00300 }
00301 }
00302
00303 int KMKernel::openComposer (const QString &to, const QString &cc,
00304 const QString &bcc, const QString &subject,
00305 const QString &body, int hidden,
00306 const KURL &messageFile,
00307 const KURL::List &attachURLs)
00308 {
00309 kdDebug(5006) << "KMKernel::openComposer called" << endl;
00310
00311 KMMessage *msg = new KMMessage;
00312 msg->initHeader();
00313 msg->setCharset("utf-8");
00314 if (!cc.isEmpty()) msg->setCc(cc);
00315 if (!bcc.isEmpty()) msg->setBcc(bcc);
00316 if (!subject.isEmpty()) msg->setSubject(subject);
00317 if (!to.isEmpty()) msg->setTo(to);
00318
00319 if (!messageFile.isEmpty() && messageFile.isLocalFile()) {
00320 QCString str = kFileToString( messageFile.path(), true, false );
00321 if( !str.isEmpty() )
00322 msg->setBody( QString::fromLocal8Bit( str ).utf8() );
00323 }
00324 else if (!body.isEmpty())
00325 msg->setBody(body.utf8());
00326
00327 KMComposeWin *cWin = new KMComposeWin(msg);
00328 cWin->setCharset("", TRUE);
00329 for ( KURL::List::ConstIterator it = attachURLs.begin() ; it != attachURLs.end() ; ++it )
00330 cWin->addAttach((*it));
00331 if (hidden == 0) {
00332 cWin->show();
00333
00334
00335 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00336 KStartupInfo::setNewStartupId( cWin, kapp->startupId() );
00337 #endif
00338 }
00339 return 1;
00340 }
00341
00342
00343 int KMKernel::openComposer (const QString &to, const QString &cc,
00344 const QString &bcc, const QString &subject,
00345 const QString &body, int hidden,
00346 const QString &attachName,
00347 const QCString &attachCte,
00348 const QCString &attachData,
00349 const QCString &attachType,
00350 const QCString &attachSubType,
00351 const QCString &attachParamAttr,
00352 const QString &attachParamValue,
00353 const QCString &attachContDisp)
00354 {
00355 kdDebug(5006) << "KMKernel::openComposer called" << endl;
00356
00357 KMMessage *msg = new KMMessage;
00358 msg->initHeader();
00359 msg->setCharset("utf-8");
00360 if (!cc.isEmpty()) msg->setCc(cc);
00361 if (!bcc.isEmpty()) msg->setBcc(bcc);
00362 if (!subject.isEmpty()) msg->setSubject(subject);
00363 if (!to.isEmpty()) msg->setTo(to);
00364 if (!body.isEmpty()) msg->setBody(body.utf8());
00365
00366 KMComposeWin *cWin = new KMComposeWin(msg);
00367 cWin->setCharset("", TRUE);
00368 if (!attachData.isEmpty()) {
00369 KMMessagePart *msgPart = new KMMessagePart;
00370 msgPart->setName(attachName);
00371 msgPart->setCteStr(attachCte);
00372 msgPart->setBodyEncoded(attachData);
00373 msgPart->setTypeStr(attachType);
00374 msgPart->setSubtypeStr(attachSubType);
00375 msgPart->setParameter(attachParamAttr,attachParamValue);
00376 msgPart->setContentDisposition(attachContDisp);
00377 cWin->addAttach(msgPart);
00378 }
00379
00380 if (hidden == 0) {
00381 cWin->show();
00382
00383
00384 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00385 KStartupInfo::setNewStartupId( cWin, kapp->startupId() );
00386 #endif
00387 }
00388 return 1;
00389 }
00390
00391 DCOPRef KMKernel::openComposer(const QString &to, const QString &cc,
00392 const QString &bcc, const QString &subject,
00393 const QString &body,bool hidden)
00394 {
00395 KMMessage *msg = new KMMessage;
00396 msg->initHeader();
00397 msg->setCharset("utf-8");
00398 if (!cc.isEmpty()) msg->setCc(cc);
00399 if (!bcc.isEmpty()) msg->setBcc(bcc);
00400 if (!subject.isEmpty()) msg->setSubject(subject);
00401 if (!to.isEmpty()) msg->setTo(to);
00402 if (!body.isEmpty()) msg->setBody(body.utf8());
00403
00404 KMComposeWin *cWin = new KMComposeWin(msg);
00405 cWin->setCharset("", TRUE);
00406 if (!hidden) {
00407 cWin->show();
00408
00409
00410 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00411 KStartupInfo::setNewStartupId( cWin, kapp->startupId() );
00412 #endif
00413 }
00414
00415 return DCOPRef(cWin);
00416 }
00417
00418 int KMKernel::sendCertificate( const QString& to, const QByteArray& certData )
00419 {
00420 KMMessage *msg = new KMMessage;
00421 msg->initHeader();
00422 msg->setCharset("utf-8");
00423 msg->setSubject( i18n( "Certificate Signature Request" ) );
00424 if (!to.isEmpty()) msg->setTo(to);
00425 msg->setBody( i18n( "Please sign this certificate and return to sender." ).utf8() );
00426
00427 KMComposeWin *cWin = new KMComposeWin(msg);
00428 cWin->setCharset("", TRUE);
00429 cWin->slotSetAlwaysSend( true );
00430 if (!certData.isEmpty()) {
00431 KMMessagePart *msgPart = new KMMessagePart;
00432 msgPart->setName("smime.p10");
00433 msgPart->setCteStr("base64");
00434 msgPart->setBodyEncodedBinary(certData);
00435 msgPart->setTypeStr("application");
00436 msgPart->setSubtypeStr("pkcs10");
00437 msgPart->setContentDisposition("attachment; filename=smime.p10");
00438 cWin->addAttach(msgPart);
00439 }
00440
00441 cWin->show();
00442 return 1;
00443 }
00444
00445
00446 void KMKernel::compactAllFolders ()
00447 {
00448 kdDebug(5006) << "KMKernel::compactAllFolders called" << endl;
00449 the_folderMgr->compactAll();
00450 kdDebug(5006) << "KMKernel::compactAllFolders finished" << endl;
00451 }
00452
00453 int KMKernel::dcopAddMessage(const QString & foldername,const QString & msgUrlString)
00454 {
00455 return dcopAddMessage(foldername, KURL(msgUrlString));
00456 }
00457
00458 int KMKernel::dcopAddMessage(const QString & foldername,const KURL & msgUrl)
00459 {
00460 if ( foldername.isEmpty() )
00461 return -1;
00462
00463 int retval;
00464 QCString messageText;
00465 static QStringList *msgIds = 0;
00466 static QString lastFolder = "";
00467 bool readFolderMsgIds = false;
00468
00469
00470
00471 if ( foldername != lastFolder ) {
00472 if ( msgIds != 0 ) {
00473 delete msgIds;
00474 msgIds = 0;
00475 }
00476 msgIds = new QStringList;
00477 readFolderMsgIds = true;
00478 lastFolder = foldername;
00479 }
00480
00481 if (!msgUrl.isEmpty() && msgUrl.isLocalFile()) {
00482
00483
00484
00485
00486
00487
00488
00489
00490 messageText = kFileToString( msgUrl.path(), true, false);
00491 if ( messageText.isNull() )
00492 return -2;
00493
00494 KMMessage *msg = new KMMessage();
00495 msg->fromString( messageText );
00496
00497 KMFolder *folder = the_folderMgr->findOrCreate(foldername, false);
00498
00499 if ( folder ) {
00500 if (readFolderMsgIds) {
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510 int i;
00511
00512 folder->open();
00513 for( i=0; i<folder->count(); i++) {
00514 KMMsgBase *mb = folder->getMsgBase(i);
00515 time_t DT = mb->date();
00516 QString dt = ctime(&DT);
00517 QString id = mb->subject();
00518
00519 if (id.isEmpty())
00520 id = mb->fromStrip();
00521 if (id.isEmpty())
00522 id = mb->toStrip();
00523
00524 id+=dt;
00525
00526
00527 if (!id.isEmpty()) {
00528 msgIds->append(id);
00529 }
00530 }
00531 folder->close();
00532 }
00533
00534 time_t DT = msg->date();
00535 QString dt = ctime( &DT );
00536 QString msgId = msg->subject();
00537
00538 if ( msgId.isEmpty() )
00539 msgId = msg->fromStrip();
00540 if ( msgId.isEmpty() )
00541 msgId = msg->toStrip();
00542
00543 msgId += dt;
00544
00545 int k = msgIds->findIndex( msgId );
00546
00547
00548 if ( k == -1 ) {
00549 if ( !msgId.isEmpty() ) {
00550 msgIds->append( msgId );
00551 }
00552 if ( folder->addMsg( msg ) == 0 ) {
00553 retval = 1;
00554 } else {
00555 retval =- 2;
00556 delete msg;
00557 msg = 0;
00558 }
00559 } else {
00560 retval = -4;
00561 }
00562 } else {
00563 retval = -1;
00564 }
00565 } else {
00566 retval = -2;
00567 }
00568 return retval;
00569 }
00570
00571 void KMKernel::requestAddresses( QString filename )
00572 {
00573 mGroupware->requestAddresses( filename );
00574 }
00575
00576 bool KMKernel::storeAddresses( QString addresses, QStringList delUIDs )
00577 {
00578 return mGroupware->storeAddresses( addresses, delUIDs );
00579 }
00580
00581 QStringList KMKernel::folderList() const
00582 {
00583 QStringList folders;
00584 the_folderMgr->getFolderURLS( folders );
00585 the_imapFolderMgr->getFolderURLS( folders );
00586 the_dimapFolderMgr->getFolderURLS( folders );
00587 return folders;
00588 }
00589
00590 DCOPRef KMKernel::getFolder( const QString& vpath )
00591 {
00592 if ( the_folderMgr->getFolderByURL( vpath ) )
00593 return DCOPRef( new FolderIface( vpath ) );
00594 else if ( the_imapFolderMgr->getFolderByURL( vpath ) )
00595 return DCOPRef( new FolderIface( vpath ) );
00596 else if ( the_dimapFolderMgr->getFolderByURL( vpath ) )
00597 return DCOPRef( new FolderIface( vpath ) );
00598 return DCOPRef();
00599 }
00600
00601 bool KMKernel::showMail( Q_UINT32 serialNumber, QString )
00602 {
00603 KMMainWidget *mainWidget = 0;
00604 if (KMainWindow::memberList) {
00605 KMainWindow *win = 0;
00606 QObjectList *l;
00607
00608
00609 for (win = KMainWindow::memberList->first(); win;
00610 win = KMainWindow::memberList->next()) {
00611
00612 l = win->queryList("KMMainWidget");
00613 if (l && l->first()) {
00614 mainWidget = dynamic_cast<KMMainWidget *>(l->first());
00615 if (win->isActiveWindow())
00616 break;
00617 }
00618 }
00619 }
00620
00621 if (mainWidget) {
00622 int idx = -1;
00623 KMFolder *folder = 0;
00624 msgDict()->getLocation(serialNumber, &folder, &idx);
00625 if (!folder || (idx == -1))
00626 return false;
00627 folder->open();
00628 KMMsgBase *msgBase = folder->getMsgBase(idx);
00629 if (!msgBase)
00630 return false;
00631 bool unGet = !msgBase->isMessage();
00632 KMMessage *msg = folder->getMsg(idx);
00633 mainWidget->slotSelectFolder(folder);
00634 mainWidget->slotSelectMessage(msg);
00635 if (unGet)
00636 folder->unGetMsg(idx);
00637 folder->close();
00638 return true;
00639 }
00640
00641 return false;
00642 }
00643
00644
00645
00646
00647
00648 void KMKernel::quit()
00649 {
00650
00651
00652 }
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703 void KMKernel::testDir(const char *_name)
00704 {
00705 QString foldersPath = QDir::homeDirPath() + QString( _name );
00706 QFileInfo info( foldersPath );
00707 if ( !info.exists() ) {
00708 if ( ::mkdir( QFile::encodeName( foldersPath ) , S_IRWXU ) == -1 ) {
00709 KMessageBox::sorry(0, i18n("KMail couldn't create folder '%1'.\n"
00710 "Please make sure that you can view and "
00711 "modify the content of the folder '%2'.")
00712 .arg( foldersPath ).arg( QDir::homeDirPath() ) );
00713 ::exit(-1);
00714 }
00715 }
00716 if ( !info.isDir() || !info.isReadable() || !info.isWritable() ) {
00717 KMessageBox::sorry(0, i18n("The permissions of the folder '%1' are "
00718 "incorrect.\n"
00719 "Please make sure that you can view and modify "
00720 "the content of this folder.")
00721 .arg( foldersPath ) );
00722 ::exit(-1);
00723 }
00724 }
00725
00726
00727
00728
00729
00730 void KMKernel::recoverDeadLetters(void)
00731 {
00732 KMComposeWin* win;
00733 KMMessage* msg;
00734 QDir dir = QDir::home();
00735 QString fname = dir.path();
00736 int i, rc, num;
00737 mDeadLetterTimer = new QTimer(this);
00738 connect(mDeadLetterTimer, SIGNAL(timeout()), this, SLOT(dumpDeadLetters()));
00739
00740 if (!dir.exists("dead.letter")) {
00741 mDeadLetterTimer->start(mDeadLetterInterval);
00742 return;
00743 }
00744
00745 fname += "/dead.letter";
00746 KMFolderMbox folder(0, fname);
00747
00748 folder.setAutoCreateIndex(FALSE);
00749 rc = folder.open();
00750 if (rc)
00751 {
00752 perror(QString("cannot open file "+fname).latin1());
00753 mDeadLetterTimer->start(mDeadLetterInterval);
00754 return;
00755 }
00756
00757 folder.open();
00758
00759 num = folder.count();
00760 for (i=0; i<num; i++)
00761 {
00762 msg = folder.take(0);
00763 if (msg)
00764 {
00765 win = new KMComposeWin();
00766 win->setMsg(msg, false, false, true);
00767 win->show();
00768 }
00769 }
00770 folder.close();
00771 QFile::remove(fname);
00772 mDeadLetterTimer->start(mDeadLetterInterval);
00773 }
00774
00775 void KMKernel::initFolders(KConfig* cfg)
00776 {
00777 QString name;
00778
00779 name = cfg->readEntry("inboxFolder");
00780
00781
00782
00783
00784
00785 if (name.isEmpty()) name = I18N_NOOP("inbox");
00786
00787 the_inboxFolder = (KMFolder*)the_folderMgr->findOrCreate(name);
00788
00789 if (the_inboxFolder->canAccess() != 0) {
00790 emergencyExit( i18n("You do not have read/write permission to your inbox folder.") );
00791 }
00792
00793 the_inboxFolder->setSystemFolder(TRUE);
00794 if ( the_inboxFolder->userWhoField().isEmpty() )
00795 the_inboxFolder->setUserWhoField( QString::null );
00796
00797
00798 the_outboxFolder = the_folderMgr->findOrCreate(cfg->readEntry("outboxFolder", I18N_NOOP("outbox")));
00799 if (the_outboxFolder->canAccess() != 0) {
00800 emergencyExit( i18n("You do not have read/write permission to your outbox folder.") );
00801 }
00802
00803 the_outboxFolder->setType("Out");
00804 the_outboxFolder->setSystemFolder(TRUE);
00805 if ( the_outboxFolder->userWhoField().isEmpty() )
00806 the_outboxFolder->setUserWhoField( QString::null );
00807 the_outboxFolder->open();
00808
00809 the_sentFolder = the_folderMgr->findOrCreate(cfg->readEntry("sentFolder", I18N_NOOP("sent-mail")));
00810 if (the_sentFolder->canAccess() != 0) {
00811 emergencyExit( i18n("You do not have read/write permission to your sent-mail folder.") );
00812 }
00813 the_sentFolder->setType("St");
00814 the_sentFolder->setSystemFolder(TRUE);
00815 if ( the_sentFolder->userWhoField().isEmpty() )
00816 the_sentFolder->setUserWhoField( QString::null );
00817
00818
00819 the_trashFolder = the_folderMgr->findOrCreate(cfg->readEntry("trashFolder", I18N_NOOP("trash")));
00820 if (the_trashFolder->canAccess() != 0) {
00821 emergencyExit( i18n("You do not have read/write permission to your trash folder.") );
00822 }
00823 the_trashFolder->setType("Tr");
00824 the_trashFolder->setSystemFolder(TRUE);
00825 if ( the_trashFolder->userWhoField().isEmpty() )
00826 the_trashFolder->setUserWhoField( QString::null );
00827
00828
00829 the_draftsFolder = the_folderMgr->findOrCreate(cfg->readEntry("draftsFolder", I18N_NOOP("drafts")));
00830 if (the_draftsFolder->canAccess() != 0) {
00831 emergencyExit( i18n("You do not have read/write permission to your drafts folder.") );
00832 }
00833 the_draftsFolder->setType("Df");
00834 the_draftsFolder->setSystemFolder(TRUE);
00835 if ( the_draftsFolder->userWhoField().isEmpty() )
00836 the_draftsFolder->setUserWhoField( QString::null );
00837 the_draftsFolder->open();
00838 }
00839
00840
00841 void KMKernel::init()
00842 {
00843 QString foldersPath;
00844 KConfig* cfg;
00845
00846 the_shuttingDown = false;
00847 the_server_is_ready = false;
00848
00849 cfg = KMKernel::config();
00850
00851 mCryptPlugList = new CryptPlugWrapperList();
00852 mCryptPlugList->loadFromConfig( cfg );
00853
00854 QDir dir;
00855 QString d = locateLocal("data", "kmail/");
00856
00857 KConfigGroupSaver saver(cfg, "General");
00858 the_firstStart = cfg->readBoolEntry("first-start", true);
00859 cfg->writeEntry("first-start", false);
00860 the_previousVersion = cfg->readEntry("previous-version");
00861 cfg->writeEntry("previous-version", KMAIL_VERSION);
00862 foldersPath = cfg->readEntry("folders");
00863
00864 if (foldersPath.isEmpty())
00865 {
00866 foldersPath = QDir::homeDirPath() + QString("/Mail");
00867 transferMail();
00868 }
00869 the_undoStack = new UndoStack(20);
00870 the_folderMgr = new KMFolderMgr(foldersPath);
00871 the_imapFolderMgr = new KMFolderMgr(locateLocal("data","kmail/imap"), KMImapDir);
00872 the_dimapFolderMgr = new KMFolderMgr(locateLocal("data","kmail/dimap"), KMDImapDir);
00873 the_searchFolderMgr = new KMFolderMgr(locateLocal("data","kmail/search"), KMSearchDir);
00874 the_acctMgr = new KMAcctMgr();
00875 the_filterMgr = new KMFilterMgr();
00876 the_popFilterMgr = new KMFilterMgr(true);
00877 the_filterActionDict = new KMFilterActionDict;
00878
00879
00880 KMMessage::readConfig();
00881 initFolders(cfg);
00882 the_acctMgr->readConfig();
00883 the_filterMgr->readConfig();
00884 the_popFilterMgr->readConfig();
00885 cleanupImapFolders();
00886
00887 the_msgSender = new KMSender;
00888 the_server_is_ready = true;
00889
00890 {
00891 KConfigGroupSaver saver(cfg, "Composer");
00892 if (cfg->readListEntry("pref-charsets").isEmpty())
00893 {
00894 cfg->writeEntry("pref-charsets", "us-ascii,iso-8859-1,locale,utf-8");
00895 }
00896 }
00897 mGroupware->readConfig();
00898 mICalIface->readConfig();
00899
00900 #if 0 //disabled for now..
00901 the_msgIndex = new KMMsgIndex(this, "the_index");
00902 the_msgIndex->init();
00903 the_msgIndex->remove();
00904 delete the_msgIndex;
00905 the_msgIndex = 0;
00906 #endif
00907
00908 #if 0
00909 the_weaver = new KPIM::ThreadWeaver::Weaver( this );
00910 the_weaverLogger = new KPIM::ThreadWeaver::WeaverThreadLogger(this);
00911 the_weaverLogger->attach (the_weaver);
00912 #endif
00913
00914 }
00915
00916 void KMKernel::cleanupImapFolders()
00917 {
00918 KMAccount *acct;
00919 KMFolderNode *node = the_imapFolderMgr->dir().first();
00920 while (node)
00921 {
00922 if (node->isDir() || ((acct = the_acctMgr->find(node->name()))
00923 && ( acct->type() == "imap" )) )
00924 {
00925 node = the_imapFolderMgr->dir().next();
00926 } else {
00927 the_imapFolderMgr->remove(static_cast<KMFolderImap*>(node));
00928 node = the_imapFolderMgr->dir().first();
00929 }
00930 }
00931
00932 node = the_dimapFolderMgr->dir().first();
00933 while (node)
00934 {
00935 if (node->isDir() || ((acct = the_acctMgr->find(node->name()))
00936 && ( acct->type() == "cachedimap" )) )
00937 {
00938 node = the_dimapFolderMgr->dir().next();
00939 } else {
00940 static_cast<KMFolderCachedImap*>(node)->removeRightAway();
00941 the_dimapFolderMgr->remove(static_cast<KMFolderCachedImap*>(node));
00942 node = the_imapFolderMgr->dir().first();
00943 }
00944 }
00945
00946 the_imapFolderMgr->quiet(true);
00947 for (acct = the_acctMgr->first(); acct; acct = the_acctMgr->next())
00948 {
00949 KMFolderImap *fld;
00950 KMAcctImap *imapAcct;
00951
00952 if (acct->type() != "imap") continue;
00953 fld = static_cast<KMFolderImap*>(the_imapFolderMgr
00954 ->findOrCreate(acct->name(), false));
00955 fld->setNoContent(true);
00956 imapAcct = static_cast<KMAcctImap*>(acct);
00957 fld->setAccount(imapAcct);
00958 imapAcct->setImapFolder(fld);
00959 fld->close();
00960 }
00961 the_imapFolderMgr->quiet(false);
00962
00963 the_dimapFolderMgr->quiet( true );
00964 for (acct = the_acctMgr->first(); acct; acct = the_acctMgr->next())
00965 {
00966 KMFolderCachedImap *cfld;
00967 KMAcctCachedImap *cachedImapAcct;
00968
00969 if (acct->type() != "cachedimap" ) continue;
00970
00971 cfld = static_cast<KMFolderCachedImap*>(the_dimapFolderMgr->find(acct->name()));
00972 if (cfld == 0) {
00973
00974 cfld = static_cast<KMFolderCachedImap*>(the_dimapFolderMgr->createFolder(acct->name(), FALSE, KMFolderTypeCachedImap));
00975 if (!cfld) {
00976 KMessageBox::error(0,(i18n("Cannot create file `%1' in %2.\nKMail cannot start without it.").arg(acct->name()).arg(the_imapFolderMgr->basePath())));
00977 exit(-1);
00978 }
00979 }
00980
00981 cfld->setNoContent(true);
00982 cachedImapAcct = static_cast<KMAcctCachedImap*>(acct);
00983 cfld->setAccount(cachedImapAcct);
00984 cachedImapAcct->setImapFolder(cfld);
00985 cfld->close();
00986 }
00987 the_dimapFolderMgr->quiet( false );
00988 }
00989
00990 bool KMKernel::doSessionManagement()
00991 {
00992
00993
00994 if (kapp->isRestored()){
00995 int n = 1;
00996 while (KMMainWin::canBeRestored(n)){
00997
00998 if (KMMainWin::classNameOfToplevel(n) == "KMMainWin")
00999 (new KMMainWin)->restore(n);
01000 n++;
01001 }
01002 return true;
01003 }
01004 return false;
01005 }
01006
01007 void KMKernel::closeAllKMTopLevelWidgets()
01008 {
01009 QPtrListIterator<KMainWindow> it(*KMainWindow::memberList);
01010 KMainWindow *window = 0;
01011 while ((window = it.current()) != 0) {
01012 ++it;
01013 if (window->inherits("KMTopLevelWidget"))
01014 window->close(TRUE);
01015 }
01016 }
01017
01018 void KMKernel::notClosedByUser()
01019 {
01020 if (!closed_by_user)
01021 return;
01022 closed_by_user = false;
01023 the_shuttingDown = true;
01024 closeAllKMTopLevelWidgets();
01025
01026 delete the_acctMgr;
01027 the_acctMgr = 0;
01028 delete the_filterMgr;
01029 the_filterMgr = 0;
01030 delete the_msgSender;
01031 the_msgSender = 0;
01032 delete the_filterActionDict;
01033 the_filterActionDict = 0;
01034 delete the_undoStack;
01035 the_undoStack = 0;
01036 delete the_popFilterMgr;
01037 the_popFilterMgr = 0;
01038
01039 QStringList strList;
01040 QValueList<QGuardedPtr<KMFolder> > folders;
01041 KMFolder *folder;
01042 the_folderMgr->createFolderList(&strList, &folders);
01043 for (int i = 0; folders.at(i) != folders.end(); i++)
01044 {
01045 folder = *folders.at(i);
01046 if (!folder || folder->isDir()) continue;
01047 folder->close(TRUE);
01048 }
01049 strList.clear();
01050 folders.clear();
01051 the_searchFolderMgr->createFolderList(&strList, &folders);
01052 for (int i = 0; folders.at(i) != folders.end(); i++)
01053 {
01054 folder = *folders.at(i);
01055 if (!folder || folder->isDir()) continue;
01056 folder->close(TRUE);
01057 }
01058 folderMgr()->writeMsgDict(msgDict());
01059 imapFolderMgr()->writeMsgDict(msgDict());
01060 dimapFolderMgr()->writeMsgDict(msgDict());
01061 delete the_msgIndex;
01062 the_msgIndex = 0;
01063 delete the_folderMgr;
01064 the_folderMgr = 0;
01065 delete the_imapFolderMgr;
01066 the_imapFolderMgr = 0;
01067 delete the_dimapFolderMgr;
01068 the_dimapFolderMgr = 0;
01069 delete the_searchFolderMgr;
01070 the_searchFolderMgr = 0;
01071 delete the_msgDict;
01072 the_msgDict = 0;
01073 delete mConfigureDialog;
01074 mConfigureDialog = 0;
01075 delete mWin;
01076 mWin = 0;
01077 }
01078
01079 void KMKernel::cleanup(void)
01080 {
01081 dumpDeadLetters();
01082 mDeadLetterTimer->stop();
01083 the_shuttingDown = TRUE;
01084 closeAllKMTopLevelWidgets();
01085
01086 delete the_acctMgr;
01087 the_acctMgr = 0;
01088 delete the_filterMgr;
01089 the_filterMgr = 0;
01090 delete the_msgSender;
01091 the_msgSender = 0;
01092 delete the_filterActionDict;
01093 the_filterActionDict = 0;
01094 delete the_undoStack;
01095 the_undoStack = 0;
01096 delete the_popFilterMgr;
01097 the_popFilterMgr = 0;
01098
01099 #if 0
01100 delete the_weaver;
01101 the_weaver = 0;
01102 #endif
01103
01104
01105
01106
01107
01108
01109
01110
01111 kapp->dcopClient()->suspend();
01112
01113
01114 QTimer::singleShot(0, this, SLOT(cleanupLoop()));
01115
01116
01117 kapp->enter_loop();
01118 }
01119
01120 void KMKernel::cleanupProgress()
01121 {
01122 mProgress->advance( 1 );
01123 }
01124
01125 void KMKernel::cleanupLoop()
01126 {
01127 QStringList cleanupMsgs;
01128 cleanupMsgs << i18n("Cleaning up...")
01129 << i18n("Emptying trash...")
01130 << i18n("Expiring old messages...")
01131 << i18n("Compacting folders...");
01132 enum { CleaningUpMsgNo = 0,
01133 EmptyTrashMsgNo = 1,
01134 ExpiringOldMessagesMsgNo = 2,
01135 CompactingFoldersMsgNo = 3 };
01136 mProgress = 0;
01137 mCleanupLabel = 0;
01138 mCleanupPopup = 0;
01139 int nrFolders = the_folderMgr->folderCount();
01140 if (closed_by_user)
01141 {
01142 mCleanupPopup = new KPassivePopup();
01143 QVBox *box = mCleanupPopup->standardView( kapp->aboutData()->programName(),
01144 QString::null, kapp->miniIcon());
01145 mCleanupLabel = new QLabel( cleanupMsgs[CleaningUpMsgNo], box );
01146
01147 QFontMetrics fm = mCleanupLabel->fontMetrics();
01148 int maxTextWidth = 0;
01149 for( QStringList::ConstIterator it = cleanupMsgs.begin();
01150 it != cleanupMsgs.end();
01151 ++it ) {
01152 int w;
01153 if( maxTextWidth < ( w = fm.width( *it ) ) )
01154 maxTextWidth = w;
01155 }
01156
01157 mProgress = new KProgress( box, "kmail-cleanupProgress" );
01158 mProgress->setMinimumWidth( maxTextWidth+20 );
01159 mCleanupPopup->setView( box );
01160
01161 mProgress->setTotalSteps(nrFolders*2+2);
01162 mProgress->setProgress(1);
01163 QApplication::syncX();
01164 mCleanupPopup->adjustSize();
01165 mCleanupPopup->show();
01166 kapp->processEvents();
01167 connect(the_folderMgr, SIGNAL(progress()), this, SLOT(cleanupProgress()));
01168 }
01169
01170
01171 KConfig* config = KMKernel::config();
01172 KConfigGroupSaver saver(config, "General");
01173
01174 bool expire = false;
01175
01176 if (closed_by_user) {
01177 if (config->readNumEntry("when-to-expire")==expireAtExit) {
01178 expire = true;
01179
01180 if (config->readBoolEntry("warn-before-expire", true)) {
01181 expire = canExpire();
01182 }
01183 }
01184 }
01185
01186 if (!closed_by_user) {
01187 if (the_trashFolder)
01188 the_trashFolder->close();
01189 }
01190 else if (the_trashFolder) {
01191
01192 the_trashFolder->close(TRUE);
01193
01194 if (config->readBoolEntry("empty-trash-on-exit", true))
01195 {
01196 if (mCleanupLabel)
01197 {
01198 mCleanupLabel->setText( cleanupMsgs[EmptyTrashMsgNo] );
01199 QApplication::syncX();
01200 kapp->processEvents();
01201 }
01202 if ( the_trashFolder->count( true ) > 0 )
01203 the_trashFolder->expunge();
01204 }
01205 }
01206
01207 if (mProgress)
01208 mProgress->setProgress(2);
01209
01210 if (expire) {
01211 if (mCleanupLabel)
01212 {
01213 mCleanupLabel->setText( cleanupMsgs[ExpiringOldMessagesMsgNo] );
01214 QApplication::syncX();
01215 kapp->processEvents();
01216 }
01217 the_folderMgr->expireAllFolders(0);
01218 }
01219
01220 if (mProgress)
01221 mProgress->setProgress(2+nrFolders);
01222
01223 if (closed_by_user && the_folderMgr) {
01224 if (config->readBoolEntry("compact-all-on-exit", true))
01225 {
01226 if (mCleanupLabel)
01227 {
01228 mCleanupLabel->setText( cleanupMsgs[CompactingFoldersMsgNo] );
01229 QApplication::syncX();
01230 kapp->processEvents();
01231 }
01232 the_folderMgr->compactAll();
01233 }
01234 }
01235 if (mProgress) {
01236 mCleanupLabel->setText( cleanupMsgs[CleaningUpMsgNo] );
01237 mProgress->setProgress(2+2*nrFolders);
01238 QApplication::syncX();
01239 kapp->processEvents();
01240 }
01241
01242 if (the_inboxFolder) the_inboxFolder->close(TRUE);
01243 if (the_outboxFolder) the_outboxFolder->close(TRUE);
01244 if (the_sentFolder) the_sentFolder->close(TRUE);
01245 if (the_draftsFolder) the_draftsFolder->close(TRUE);
01246
01247 mICalIface->cleanup();
01248
01249 folderMgr()->writeMsgDict(msgDict());
01250 imapFolderMgr()->writeMsgDict(msgDict());
01251 dimapFolderMgr()->writeMsgDict(msgDict());
01252 QValueList<QGuardedPtr<KMFolder> > folders;
01253 QStringList strList;
01254 KMFolder *folder;
01255 the_searchFolderMgr->createFolderList(&strList, &folders);
01256 for (int i = 0; folders.at(i) != folders.end(); i++)
01257 {
01258 folder = *folders.at(i);
01259 if (!folder || folder->isDir()) continue;
01260 folder->close(TRUE);
01261 }
01262 delete the_msgIndex;
01263 the_msgIndex = 0;
01264 delete the_folderMgr;
01265 the_folderMgr = 0;
01266 delete the_imapFolderMgr;
01267 the_imapFolderMgr = 0;
01268 delete the_dimapFolderMgr;
01269 the_dimapFolderMgr = 0;
01270 delete the_searchFolderMgr;
01271 the_searchFolderMgr = 0;
01272 delete the_msgDict;
01273 the_msgDict = 0;
01274 delete mConfigureDialog;
01275 mConfigureDialog = 0;
01276 delete mWin;
01277 mWin = 0;
01278 mCryptPlugList->setAutoDelete(true);
01279 mCryptPlugList->clear();
01280 delete mCryptPlugList;
01281 mCryptPlugList = 0;
01282
01283
01284 RecentAddresses::self(KMKernel::config())->save( KMKernel::config() );
01285 KMKernel::config()->sync();
01286 if (mCleanupPopup)
01287 {
01288 sleep(1);
01289 delete mCleanupPopup;
01290 mCleanupPopup = 0;
01291 mCleanupLabel = 0;
01292 mProgress = 0;
01293 }
01294 kapp->exit_loop();
01295 }
01296
01297
01298 void KMKernel::transferMail(void)
01299 {
01300 QDir dir = QDir::home();
01301 int rc;
01302
01303
01304
01305
01306
01307 if (!dir.cd("KMail")) return;
01308
01309 rc = KMessageBox::questionYesNo(0,
01310 i18n(
01311 "The directory ~/KMail exists. From now on, KMail uses the "
01312 "directory ~/Mail for its messages.\n"
01313 "KMail can move the contents of the directory ~/KMail into "
01314 "~/Mail, but this will replace existing files with the same "
01315 "name in the directory ~/Mail (e.g. inbox).\n"
01316 "Should KMail move the mail folders now?"));
01317
01318 if (rc == KMessageBox::No) return;
01319
01320 dir.cd("/");
01321 testDir("/Mail");
01322 system("mv -f ~/KMail/* ~/Mail");
01323 system("mv -f ~/KMail/.??* ~/Mail");
01324 system("rmdir ~/KMail");
01325 }
01326
01327
01328 void KMKernel::ungrabPtrKb(void)
01329 {
01330 if(!KMainWindow::memberList) return;
01331 QWidget* widg = KMainWindow::memberList->first();
01332 Display* dpy;
01333
01334 if (!widg) return;
01335 dpy = widg->x11Display();
01336 XUngrabKeyboard(dpy, CurrentTime);
01337 XUngrabPointer(dpy, CurrentTime);
01338 }
01339
01340
01341
01342 void KMKernel::kmailMsgHandler(QtMsgType aType, const char* aMsg)
01343 {
01344 static int recurse=-1;
01345
01346 recurse++;
01347
01348 switch (aType)
01349 {
01350 case QtDebugMsg:
01351 case QtWarningMsg:
01352 kdDebug(5006) << aMsg << endl;
01353 break;
01354
01355 case QtFatalMsg:
01356 ungrabPtrKb();
01357 kdDebug(5006) << kapp->caption() << " fatal error "
01358 << aMsg << endl;
01359 KMessageBox::error(0, aMsg);
01360 abort();
01361 }
01362
01363 recurse--;
01364 }
01365 void KMKernel::dumpDeadLetters()
01366 {
01367 if (shuttingDown())
01368 return;
01369 mDeadLetterTimer->stop();
01370 QWidget *win;
01371 QDir dir = QDir::home();
01372 QString fname = dir.path();
01373 QFile::remove(fname + "/dead.letter.tmp");
01374 if (KMainWindow::memberList) {
01375 QPtrListIterator<KMainWindow> it(*KMainWindow::memberList);
01376
01377 while ((win = it.current()) != 0) {
01378 ++it;
01379 if (win->inherits("KMComposeWin")) ((KMComposeWin*)win)->deadLetter();
01380
01381 }
01382 }
01383 QFile::remove(fname + "/dead.letter");
01384 dir.rename("dead.letter.tmp","dead.letter");
01385 mDeadLetterTimer->start(mDeadLetterInterval);
01386 }
01387
01388
01389
01390 void KMKernel::action(bool mailto, bool check, const QString &to,
01391 const QString &cc, const QString &bcc,
01392 const QString &subj, const QString &body,
01393 const KURL &messageFile,
01394 const KURL::List &attachURLs)
01395 {
01396
01397
01398
01399
01400
01401 if (mailto)
01402 openComposer (to, cc, bcc, subj, body, 0, messageFile, attachURLs);
01403 else
01404 openReader( check );
01405
01406 if (check)
01407 checkMail();
01408
01409 }
01410
01411 void KMKernel::byteArrayToRemoteFile(const QByteArray &aData, const KURL &aURL,
01412 bool overwrite)
01413 {
01414 KIO::Job *job = KIO::put(aURL, -1, overwrite, FALSE);
01415 putData pd; pd.url = aURL; pd.data = aData; pd.offset = 0;
01416 mPutJobs.insert(job, pd);
01417 connect(job, SIGNAL(dataReq(KIO::Job*,QByteArray&)),
01418 SLOT(slotDataReq(KIO::Job*,QByteArray&)));
01419 connect(job, SIGNAL(result(KIO::Job*)),
01420 SLOT(slotResult(KIO::Job*)));
01421 }
01422
01423 void KMKernel::slotDataReq(KIO::Job *job, QByteArray &data)
01424 {
01425
01426 const int MAX_CHUNK_SIZE = 64*1024;
01427 QMap<KIO::Job*, putData>::Iterator it = mPutJobs.find(job);
01428 assert(it != mPutJobs.end());
01429 int remainingBytes = (*it).data.size() - (*it).offset;
01430 if( remainingBytes > MAX_CHUNK_SIZE )
01431 {
01432
01433 data.duplicate( (*it).data.data() + (*it).offset, MAX_CHUNK_SIZE );
01434 (*it).offset += MAX_CHUNK_SIZE;
01435
01436
01437 }
01438 else
01439 {
01440
01441 data.duplicate( (*it).data.data() + (*it).offset, remainingBytes );
01442 (*it).data = QByteArray();
01443 (*it).offset = 0;
01444
01445 }
01446 }
01447
01448 void KMKernel::slotResult(KIO::Job *job)
01449 {
01450 QMap<KIO::Job*, putData>::Iterator it = mPutJobs.find(job);
01451 assert(it != mPutJobs.end());
01452 if (job->error())
01453 {
01454 if (job->error() == KIO::ERR_FILE_ALREADY_EXIST)
01455 {
01456 if (KMessageBox::warningContinueCancel(0,
01457 i18n("File %1 exists.\nDo you want to replace it?")
01458 .arg((*it).url.prettyURL()), i18n("Save to File"), i18n("&Replace"))
01459 == KMessageBox::Continue)
01460 byteArrayToRemoteFile((*it).data, (*it).url, TRUE);
01461 }
01462 else job->showErrorDialog();
01463 }
01464 mPutJobs.remove(it);
01465 }
01466
01467 void KMKernel::slotCollectStdOut( KProcess * proc, char * buffer, int len )
01468 {
01469 QByteArray & ba = mStdOutCollection[proc];
01470
01471 int oldsize = ba.size();
01472 ba.resize( oldsize + len );
01473 qmemmove( ba.begin() + oldsize, buffer, len );
01474 }
01475
01476 void KMKernel::slotCollectStdErr( KProcess * proc, char * buffer, int len )
01477 {
01478 QByteArray & ba = mStdErrCollection[proc];
01479
01480 int oldsize = ba.size();
01481 ba.resize( oldsize + len );
01482 qmemmove( ba.begin() + oldsize, buffer, len );
01483 }
01484
01485 QByteArray KMKernel::getCollectedStdOut( KProcess * proc )
01486 {
01487 QByteArray result = mStdOutCollection[proc];
01488 mStdOutCollection.remove(proc);
01489 return result;
01490 }
01491
01492 QByteArray KMKernel::getCollectedStdErr( KProcess * proc )
01493 {
01494 QByteArray result = mStdErrCollection[proc];
01495 mStdErrCollection.remove(proc);
01496 return result;
01497 }
01498
01499 void KMKernel::slotRequestConfigSync() {
01500
01501 KMKernel::config()->sync();
01502 }
01503
01504 void KMKernel::slotShowConfigurationDialog()
01505 {
01506 if( !mConfigureDialog ) {
01507 mConfigureDialog = new ConfigureDialog( 0, "configure", false );
01508 connect( mConfigureDialog, SIGNAL( configChanged() ),
01509 this, SIGNAL( configChanged() ) );
01510 }
01511
01512 if( mConfigureDialog->isHidden() )
01513 mConfigureDialog->show();
01514 else
01515 mConfigureDialog->raise();
01516 }
01517
01518 bool KMKernel::haveSystemTrayApplet()
01519 {
01520 return !systemTrayApplets.isEmpty();
01521 }
01522
01523 bool KMKernel::registerSystemTrayApplet( const KSystemTray* applet )
01524 {
01525 if ( systemTrayApplets.findIndex( applet ) == -1 ) {
01526 systemTrayApplets.append( applet );
01527 return true;
01528 }
01529 else
01530 return false;
01531 }
01532
01533 bool KMKernel::unregisterSystemTrayApplet( const KSystemTray* applet )
01534 {
01535 QValueList<const KSystemTray*>::iterator it =
01536 systemTrayApplets.find( applet );
01537 if ( it != systemTrayApplets.end() ) {
01538 systemTrayApplets.remove( it );
01539 return true;
01540 }
01541 else
01542 return false;
01543 }
01544
01545 void KMKernel::emergencyExit( const QString& reason )
01546 {
01547 QString mesg;
01548 if ( reason.length() == 0 ) {
01549 mesg = i18n("KMail encountered a fatal error and will terminate now");
01550 }
01551 else {
01552 mesg = i18n("KMail encountered a fatal error and will "
01553 "terminate now.\nThe error was:\n%1").arg( reason );
01554 }
01555
01556 kdWarning() << mesg << endl;
01557 KNotifyClient::userEvent( 0, mesg, KNotifyClient::Messagebox, KNotifyClient::Error );
01558
01559 ::exit(1);
01560 }
01561
01569 void
01570 KMKernel::setCanExpire(bool expire) {
01571 allowedToExpire = expire;
01572 }
01573
01578 bool
01579 KMKernel::canExpire() {
01580 return allowedToExpire;
01581 }
01582
01586 bool KMKernel::folderIsDraftOrOutbox(const KMFolder * folder)
01587 {
01588 assert( folder );
01589 if ( folder == the_outboxFolder || folder == the_draftsFolder )
01590 return true;
01591
01592 QString idString = folder->idString();
01593 if ( idString.isEmpty() ) return false;
01594
01595
01596 const IdentityManager * im = identityManager();
01597 for( IdentityManager::ConstIterator it = im->begin(); it != im->end(); ++it )
01598 if ( (*it).drafts() == idString ) return true;
01599 return false;
01600 }
01601
01602 bool KMKernel::folderIsTrash(KMFolder * folder)
01603 {
01604 assert(folder);
01605 if (folder == the_trashFolder) return true;
01606 if (folder->folderType() != KMFolderTypeImap) return false;
01607 KMFolderImap *fi = static_cast<KMFolderImap*>(folder);
01608 if (fi->account() && fi->account()->trash() == fi->idString())
01609 return true;
01610 return false;
01611 }
01612
01613 bool KMKernel::folderIsSentMailFolder( const KMFolder * folder )
01614 {
01615 assert( folder );
01616 if ( folder == the_sentFolder )
01617 return true;
01618
01619 QString idString = folder->idString();
01620 if ( idString.isEmpty() ) return false;
01621
01622
01623 const IdentityManager * im = identityManager();
01624 for( IdentityManager::ConstIterator it = im->begin(); it != im->end(); ++it )
01625 if ( (*it).fcc() == idString ) return true;
01626 return false;
01627 }
01628
01629 IdentityManager * KMKernel::identityManager() {
01630 if ( !mIdentityManager ) {
01631 kdDebug(5006) << "instantating IdentityManager" << endl;
01632 mIdentityManager = new IdentityManager( this, "mIdentityManager" );
01633 }
01634 return mIdentityManager;
01635 }
01636
01637 KMMsgDict *KMKernel::msgDict()
01638 {
01639 if (the_msgDict)
01640 return the_msgDict;
01641 the_msgDict = new KMMsgDict;
01642 folderMgr()->readMsgDict(msgDict());
01643 imapFolderMgr()->readMsgDict(msgDict());
01644 dimapFolderMgr()->readMsgDict(msgDict());
01645 return the_msgDict;
01646 }
01647
01648 KMMsgIndex *KMKernel::msgIndex()
01649 {
01650 return the_msgIndex;
01651 }
01652
01653 KMainWindow* KMKernel::mainWin()
01654 {
01655 if (KMainWindow::memberList) {
01656 KMainWindow *kmWin = 0;
01657
01658
01659 for (kmWin = KMainWindow::memberList->first(); kmWin;
01660 kmWin = KMainWindow::memberList->next())
01661 if (kmWin->isA("KMMainWin"))
01662 return kmWin;
01663
01664
01665
01666
01667 kmWin = KMainWindow::memberList->first();
01668 if ( kmWin )
01669 return kmWin;
01670 }
01671
01672
01673
01674
01675
01676 mWin = new KMMainWin;
01677 return mWin;
01678 }
01679
01680
01684 void KMKernel::slotEmptyTrash()
01685 {
01686 QString title = i18n("Empty Trash");
01687 QString text = i18n("Are you sure you want to empty the trash?");
01688 if (KMessageBox::warningContinueCancel(0, text, title,
01689 KStdGuiItem::cont(), "confirm_empty_trash")
01690 != KMessageBox::Continue)
01691 {
01692 return;
01693 }
01694
01695 for (KMAccount* acct = acctMgr()->first(); acct; acct = acctMgr()->next())
01696 {
01697 KMFolder* trash = folderMgr()->findIdString(acct->trash());
01698 if (trash)
01699 {
01700 trash->expunge();
01701 }
01702 }
01703 }
01704
01705 #if KDE_IS_VERSION( 3, 1, 92 )
01706 KConfig* KMKernel::config()
01707 {
01708 assert(mySelf);
01709 if (!mySelf->mConfig)
01710 {
01711 mySelf->mConfig = KSharedConfig::openConfig( "kmailrc" );
01712
01713 KMail::checkConfigUpdates();
01714 }
01715 return mySelf->mConfig;
01716 }
01717 #else
01718 KConfig *KMKernel::myConfig = 0;
01719 static KStaticDeleter<KConfig> myConfigSD;
01720
01721 KConfig* KMKernel::config()
01722 {
01723 if (!myConfig)
01724 myConfig = myConfigSD.setObject(myConfig, new KConfig( "kmailrc"));
01725 return myConfig;
01726 }
01727 #endif
01728
01729 KMGroupware & KMKernel::groupware()
01730 {
01731 assert( mGroupware );
01732 return *mGroupware;
01733 }
01734
01735 KMailICalIfaceImpl& KMKernel::iCalIface()
01736 {
01737 assert( mICalIface );
01738 return *mICalIface;
01739 }
01740
01741
01742 #include "kmkernel.moc"