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