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 "broadcaststatus.h"
00014 using KPIM::BroadcastStatus;
00015 #include "kmstartup.h"
00016 #include "index.h"
00017 #include "kmmainwin.h"
00018 #include "composer.h"
00019 #include "kmmsgpart.h"
00020 #include "kmreadermainwin.h"
00021 #include "kmfoldermgr.h"
00022 #include "kmfoldercachedimap.h"
00023 #include "kmacctcachedimap.h"
00024 #include "kmfiltermgr.h"
00025 #include "kmfilteraction.h"
00026 #define REALLY_WANT_KMSENDER
00027 #include "kmsender.h"
00028 #undef REALLY_WANT_KMSENDER
00029 #include "undostack.h"
00030 #include "accountmanager.h"
00031 using KMail::AccountManager;
00032 #include <libkdepim/kfileio.h>
00033 #include "kmversion.h"
00034 #include "kmreaderwin.h"
00035 #include "kmmainwidget.h"
00036 #include "kmfoldertree.h"
00037 #include "recentaddresses.h"
00038 using KRecentAddress::RecentAddresses;
00039 #include "kmmsgdict.h"
00040 #include <libkpimidentities/identity.h>
00041 #include <libkpimidentities/identitymanager.h>
00042 #include "configuredialog.h"
00043 #include "kmcommands.h"
00044 #include "kmsystemtray.h"
00045 #include "transportmanager.h"
00046
00047 #include <kwin.h>
00048 #include "kmailicalifaceimpl.h"
00049 #include "mailserviceimpl.h"
00050 using KMail::MailServiceImpl;
00051 #include "mailcomposerIface.h"
00052 #include "folderIface.h"
00053 using KMail::FolderIface;
00054 #include "jobscheduler.h"
00055 #include "templateparser.h"
00056
00057 #include <kapplication.h>
00058 #include <kmessagebox.h>
00059 #include <knotifyclient.h>
00060 #include <kstaticdeleter.h>
00061 #include <kstandarddirs.h>
00062 #include <kconfig.h>
00063 #include <kprogress.h>
00064 #include <kpassivepopup.h>
00065 #include <dcopclient.h>
00066 #include <ksystemtray.h>
00067 #include <kpgp.h>
00068 #include <kdebug.h>
00069 #include <kio/netaccess.h>
00070 #include <kwallet.h>
00071 using KWallet::Wallet;
00072 #include "actionscheduler.h"
00073
00074 #include <qutf7codec.h>
00075 #include <qvbox.h>
00076 #include <qdir.h>
00077 #include <qwidgetlist.h>
00078 #include <qobjectlist.h>
00079
00080 #include <sys/types.h>
00081 #include <dirent.h>
00082 #include <sys/stat.h>
00083 #include <unistd.h>
00084 #include <stdio.h>
00085 #include <stdlib.h>
00086 #include <assert.h>
00087
00088 #include <X11/Xlib.h>
00089 #include <fixx11h.h>
00090 #include <kcmdlineargs.h>
00091 #include <kstartupinfo.h>
00092
00093 KMKernel *KMKernel::mySelf = 0;
00094
00095
00096
00097
00098 KMKernel::KMKernel (QObject *parent, const char *name) :
00099 DCOPObject("KMailIface"), QObject(parent, name),
00100 mIdentityManager(0), mConfigureDialog(0),
00101 mContextMenuShown( false ), mWallet( 0 )
00102 {
00103 kdDebug(5006) << "KMKernel::KMKernel" << endl;
00104 mySelf = this;
00105 the_startingUp = true;
00106 closed_by_user = true;
00107 the_firstInstance = true;
00108 the_msgIndex = 0;
00109
00110 the_inboxFolder = 0;
00111 the_outboxFolder = 0;
00112 the_sentFolder = 0;
00113 the_trashFolder = 0;
00114 the_draftsFolder = 0;
00115 the_templatesFolder = 0;
00116
00117 the_folderMgr = 0;
00118 the_imapFolderMgr = 0;
00119 the_dimapFolderMgr = 0;
00120 the_searchFolderMgr = 0;
00121 the_undoStack = 0;
00122 the_acctMgr = 0;
00123 the_filterMgr = 0;
00124 the_popFilterMgr = 0;
00125 the_filterActionDict = 0;
00126 the_msgSender = 0;
00127 mWin = 0;
00128 mMailCheckAborted = false;
00129
00130
00131 KMKernel::config();
00132
00133
00134
00135 GlobalSettings::self();
00136
00137
00138 mICalIface = new KMailICalIfaceImpl();
00139
00140 mJobScheduler = new JobScheduler( this );
00141
00142 mXmlGuiInstance = 0;
00143
00144 new Kpgp::Module();
00145
00146
00147
00148 if ( !QTextCodec::codecForName("utf-7") ) {
00149 kdDebug(5006) << "No Qt-native utf-7 codec found; registering QUtf7Codec from libkdenetwork" << endl;
00150 (void) new QUtf7Codec();
00151 }
00152
00153
00154
00155
00156 if ( QCString(QTextCodec::codecForLocale()->name()).lower() == "eucjp" )
00157 {
00158 netCodec = QTextCodec::codecForName("jis7");
00159
00160
00161
00162 } else {
00163 netCodec = QTextCodec::codecForLocale();
00164 }
00165 mMailService = new MailServiceImpl();
00166
00167 connectDCOPSignal( 0, 0, "kmailSelectFolder(QString)",
00168 "selectFolder(QString)", false );
00169 }
00170
00171 KMKernel::~KMKernel ()
00172 {
00173 QMap<KIO::Job*, putData>::Iterator it = mPutJobs.begin();
00174 while ( it != mPutJobs.end() )
00175 {
00176 KIO::Job *job = it.key();
00177 mPutJobs.remove( it );
00178 job->kill();
00179 it = mPutJobs.begin();
00180 }
00181
00182 delete mICalIface;
00183 mICalIface = 0;
00184 delete mMailService;
00185 mMailService = 0;
00186
00187 GlobalSettings::self()->writeConfig();
00188 delete mWallet;
00189 mWallet = 0;
00190 mySelf = 0;
00191 kdDebug(5006) << "KMKernel::~KMKernel" << endl;
00192 }
00193
00194 bool KMKernel::handleCommandLine( bool noArgsOpensReader )
00195 {
00196 QString to, cc, bcc, subj, body;
00197 QCStringList customHeaders;
00198 KURL messageFile;
00199 KURL::List attachURLs;
00200 bool mailto = false;
00201 bool checkMail = false;
00202 bool viewOnly = false;
00203 bool calledWithSession = false;
00204
00205
00206 KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
00207 if (args->getOption("subject"))
00208 {
00209 subj = QString::fromLocal8Bit(args->getOption("subject"));
00210
00211
00212
00213
00214
00215
00216
00217 if ( subj == "ession" ) {
00218 subj = QString::null;
00219 calledWithSession = true;
00220 }
00221 else
00222 mailto = true;
00223 }
00224
00225 if (args->getOption("cc"))
00226 {
00227 mailto = true;
00228 cc = QString::fromLocal8Bit(args->getOption("cc"));
00229 }
00230
00231 if (args->getOption("bcc"))
00232 {
00233 mailto = true;
00234 bcc = QString::fromLocal8Bit(args->getOption("bcc"));
00235 }
00236
00237 if (args->getOption("msg"))
00238 {
00239 mailto = true;
00240 messageFile.setPath( QString::fromLocal8Bit(args->getOption("msg")) );
00241 }
00242
00243 if (args->getOption("body"))
00244 {
00245 mailto = true;
00246 body = QString::fromLocal8Bit(args->getOption("body"));
00247 }
00248
00249 QCStringList attachList = args->getOptionList("attach");
00250 if (!attachList.isEmpty())
00251 {
00252 mailto = true;
00253 for ( QCStringList::Iterator it = attachList.begin() ; it != attachList.end() ; ++it )
00254 if ( !(*it).isEmpty() )
00255 attachURLs += KURL( QString::fromLocal8Bit( *it ) );
00256 }
00257
00258 customHeaders = args->getOptionList("header");
00259
00260 if (args->isSet("composer"))
00261 mailto = true;
00262
00263 if (args->isSet("check"))
00264 checkMail = true;
00265
00266 if ( args->getOption( "view" ) ) {
00267 viewOnly = true;
00268 const QString filename =
00269 QString::fromLocal8Bit( args->getOption( "view" ) );
00270 messageFile = KURL::fromPathOrURL( filename );
00271 if ( !messageFile.isValid() ) {
00272 messageFile = KURL();
00273 messageFile.setPath( filename );
00274 }
00275 }
00276
00277 if ( !calledWithSession ) {
00278
00279
00280 for(int i= 0; i < args->count(); i++)
00281 {
00282 if (strncasecmp(args->arg(i),"mailto:",7)==0)
00283 to += args->url(i).path() + ", ";
00284 else {
00285 QString tmpArg = QString::fromLocal8Bit( args->arg(i) );
00286 KURL url( tmpArg );
00287 if ( url.isValid() )
00288 attachURLs += url;
00289 else
00290 to += tmpArg + ", ";
00291 }
00292 mailto = true;
00293 }
00294 if ( !to.isEmpty() ) {
00295
00296 to.truncate( to.length() - 2 );
00297 }
00298 }
00299
00300 if ( !calledWithSession )
00301 args->clear();
00302
00303 if ( !noArgsOpensReader && !mailto && !checkMail && !viewOnly )
00304 return false;
00305
00306 if ( viewOnly )
00307 viewMessage( messageFile );
00308 else
00309 action( mailto, checkMail, to, cc, bcc, subj, body, messageFile,
00310 attachURLs, customHeaders );
00311 return true;
00312 }
00313
00314
00315
00316
00317 void KMKernel::checkMail ()
00318 {
00319 kmkernel->acctMgr()->checkMail(false);
00320 }
00321
00322 QStringList KMKernel::accounts()
00323 {
00324 return kmkernel->acctMgr()->getAccounts();
00325 }
00326
00327 void KMKernel::checkAccount (const QString &account)
00328 {
00329 kdDebug(5006) << "KMKernel::checkMail called" << endl;
00330
00331 KMAccount* acct = kmkernel->acctMgr()->findByName(account);
00332 if (acct)
00333 kmkernel->acctMgr()->singleCheckMail(acct, false);
00334 }
00335
00336 void KMKernel::loadProfile( const QString& )
00337 {
00338 }
00339
00340 void KMKernel::saveToProfile( const QString& ) const
00341 {
00342 }
00343
00344 void KMKernel::openReader( bool onlyCheck )
00345 {
00346 mWin = 0;
00347 KMainWindow *ktmw = 0;
00348 kdDebug(5006) << "KMKernel::openReader called" << endl;
00349
00350 if (KMainWindow::memberList)
00351 for (ktmw = KMainWindow::memberList->first(); ktmw;
00352 ktmw = KMainWindow::memberList->next())
00353 if (ktmw->isA("KMMainWin"))
00354 break;
00355
00356 bool activate;
00357 if (ktmw) {
00358 mWin = (KMMainWin *) ktmw;
00359 activate = !onlyCheck;
00360 if ( activate )
00361 mWin->show();
00362 } else {
00363 mWin = new KMMainWin;
00364 mWin->show();
00365 activate = false;
00366 }
00367
00368 if ( activate ) {
00369
00370
00371 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00372 KStartupInfo::setNewStartupId( mWin, kapp->startupId() );
00373 #endif
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 KURL &messageFile,
00381 const KURL::List &attachURLs,
00382 const QCStringList &customHeaders)
00383 {
00384 kdDebug(5006) << "KMKernel::openComposer called" << endl;
00385 KMMessage *msg = new KMMessage;
00386 msg->initHeader();
00387 msg->setCharset("utf-8");
00388
00389
00390 if (!to.isEmpty())
00391 msg->setTo( KMMsgBase::decodeRFC2047String( to.latin1() ) );
00392 if (!cc.isEmpty())
00393 msg->setCc( KMMsgBase::decodeRFC2047String( cc.latin1() ) );
00394 if (!bcc.isEmpty())
00395 msg->setBcc( KMMsgBase::decodeRFC2047String( bcc.latin1() ) );
00396 if (!subject.isEmpty()) msg->setSubject(subject);
00397 if (!messageFile.isEmpty() && messageFile.isLocalFile()) {
00398 QCString str = KPIM::kFileToString( messageFile.path(), true, false );
00399 if( !str.isEmpty() ) {
00400 msg->setBody( QString::fromLocal8Bit( str ).utf8() );
00401 } else {
00402 TemplateParser parser( msg, TemplateParser::NewMessage,
00403 "", false, false, false, false );
00404 parser.process( NULL, NULL );
00405 }
00406 }
00407 else if (!body.isEmpty())
00408 {
00409 msg->setBody(body.utf8());
00410 }
00411 else
00412 {
00413 TemplateParser parser( msg, TemplateParser::NewMessage,
00414 "", false, false, false, false );
00415 parser.process( NULL, NULL );
00416 }
00417
00418 if (!customHeaders.isEmpty())
00419 {
00420 for ( QCStringList::ConstIterator it = customHeaders.begin() ; it != customHeaders.end() ; ++it )
00421 if ( !(*it).isEmpty() )
00422 {
00423 const int pos = (*it).find( ':' );
00424 if ( pos > 0 )
00425 {
00426 QCString header, value;
00427 header = (*it).left( pos ).stripWhiteSpace();
00428 value = (*it).mid( pos+1 ).stripWhiteSpace();
00429 if ( !header.isEmpty() && !value.isEmpty() )
00430 msg->setHeaderField( header, value );
00431 }
00432 }
00433 }
00434
00435 KMail::Composer * cWin = KMail::makeComposer( msg );
00436 cWin->setCharset("", true);
00437 for ( KURL::List::ConstIterator it = attachURLs.begin() ; it != attachURLs.end() ; ++it )
00438 cWin->addAttach((*it));
00439 if (hidden == 0) {
00440 cWin->show();
00441
00442
00443 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00444 KStartupInfo::setNewStartupId( cWin, kapp->startupId() );
00445 #endif
00446 }
00447 return 1;
00448 }
00449
00450
00451 int KMKernel::openComposer (const QString &to, const QString &cc,
00452 const QString &bcc, const QString &subject,
00453 const QString &body, int hidden,
00454 const QString &attachName,
00455 const QCString &attachCte,
00456 const QCString &attachData,
00457 const QCString &attachType,
00458 const QCString &attachSubType,
00459 const QCString &attachParamAttr,
00460 const QString &attachParamValue,
00461 const QCString &attachContDisp )
00462 {
00463 kdDebug(5006) << "KMKernel::openComposer called (deprecated version)" << endl;
00464
00465 return openComposer ( to, cc, bcc, subject, body, hidden,
00466 attachName, attachCte, attachData,
00467 attachType, attachSubType, attachParamAttr,
00468 attachParamValue, attachContDisp, QCString() );
00469 }
00470
00471 int KMKernel::openComposer (const QString &to, const QString &cc,
00472 const QString &bcc, const QString &subject,
00473 const QString &body, int hidden,
00474 const QString &attachName,
00475 const QCString &attachCte,
00476 const QCString &attachData,
00477 const QCString &attachType,
00478 const QCString &attachSubType,
00479 const QCString &attachParamAttr,
00480 const QString &attachParamValue,
00481 const QCString &attachContDisp,
00482 const QCString &attachCharset )
00483 {
00484 kdDebug(5006) << "KMKernel::openComposer()" << endl;
00485
00486 KMMessage *msg = new KMMessage;
00487 KMMessagePart *msgPart = 0;
00488 msg->initHeader();
00489 msg->setCharset( "utf-8" );
00490 if ( !cc.isEmpty() ) msg->setCc(cc);
00491 if ( !bcc.isEmpty() ) msg->setBcc(bcc);
00492 if ( !subject.isEmpty() ) msg->setSubject(subject);
00493 if ( !to.isEmpty() ) msg->setTo(to);
00494 if ( !body.isEmpty() ) {
00495 msg->setBody(body.utf8());
00496 } else {
00497 TemplateParser parser( msg, TemplateParser::NewMessage,
00498 "", false, false, false, false );
00499 parser.process( NULL, NULL );
00500 }
00501
00502 bool iCalAutoSend = false;
00503 bool noWordWrap = false;
00504 bool isICalInvitation = false;
00505 KConfigGroup options( config(), "Groupware" );
00506 if ( !attachData.isEmpty() ) {
00507 isICalInvitation = attachName == "cal.ics" &&
00508 attachType == "text" &&
00509 attachSubType == "calendar" &&
00510 attachParamAttr == "method";
00511
00512 if ( isICalInvitation && bcc.isEmpty() )
00513 msg->setBcc( "" );
00514 if ( isICalInvitation &&
00515 GlobalSettings::self()->legacyBodyInvites() ) {
00516
00517 msg->setBody( attachData );
00518 msg->setHeaderField( "Content-Type",
00519 QString( "text/calendar; method=%1; "
00520 "charset=\"utf-8\"" ).
00521 arg( attachParamValue ) );
00522
00523 iCalAutoSend = true;
00524 noWordWrap = true;
00525 } else {
00526
00527 msgPart = new KMMessagePart;
00528 msgPart->setName( attachName );
00529 msgPart->setCteStr( attachCte );
00530 msgPart->setBodyEncoded( attachData );
00531 msgPart->setTypeStr( attachType );
00532 msgPart->setSubtypeStr( attachSubType );
00533 msgPart->setParameter( attachParamAttr, attachParamValue );
00534 if( ! GlobalSettings::self()->exchangeCompatibleInvitations() ) {
00535 msgPart->setContentDisposition( attachContDisp );
00536 }
00537 if( !attachCharset.isEmpty() ) {
00538
00539
00540 msgPart->setCharset( attachCharset );
00541 }
00542
00543 KConfigGroup options( config(), "Groupware" );
00544 iCalAutoSend = options.readBoolEntry( "AutomaticSending", true );
00545 }
00546 }
00547
00548 KMail::Composer * cWin = KMail::makeComposer();
00549 cWin->setMsg( msg, !isICalInvitation );
00550 cWin->setSigningAndEncryptionDisabled( isICalInvitation
00551 && GlobalSettings::self()->legacyBodyInvites() );
00552 cWin->setAutoDelete( true );
00553 if( noWordWrap )
00554 cWin->disableWordWrap();
00555 else
00556 cWin->setCharset( "", true );
00557 if ( msgPart )
00558 cWin->addAttach(msgPart);
00559
00560 if ( hidden == 0 && !iCalAutoSend ) {
00561 cWin->show();
00562
00563
00564 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00565 KStartupInfo::setNewStartupId( cWin, kapp->startupId() );
00566 #endif
00567 } else {
00568 cWin->setAutoDeleteWindow( true );
00569 cWin->slotSendNow();
00570 }
00571
00572 return 1;
00573 }
00574
00575 void KMKernel::setDefaultTransport( const QString & transport )
00576 {
00577 QStringList availTransports = KMail::TransportManager::transportNames();
00578 QStringList::const_iterator it = availTransports.find( transport );
00579 if ( it == availTransports.end() ) {
00580 kdWarning() << "The transport you entered is not available" << endl;
00581 return;
00582 }
00583 GlobalSettings::self()->setDefaultTransport( transport );
00584 }
00585
00586 DCOPRef KMKernel::openComposer(const QString &to, const QString &cc,
00587 const QString &bcc, const QString &subject,
00588 const QString &body,bool hidden)
00589 {
00590 KMMessage *msg = new KMMessage;
00591 msg->initHeader();
00592 msg->setCharset("utf-8");
00593 if (!cc.isEmpty()) msg->setCc(cc);
00594 if (!bcc.isEmpty()) msg->setBcc(bcc);
00595 if (!subject.isEmpty()) msg->setSubject(subject);
00596 if (!to.isEmpty()) msg->setTo(to);
00597 if (!body.isEmpty()) {
00598 msg->setBody(body.utf8());
00599 } else {
00600 TemplateParser parser( msg, TemplateParser::NewMessage,
00601 "", false, false, false, false );
00602 parser.process( NULL, NULL );
00603 }
00604
00605 KMail::Composer * cWin = KMail::makeComposer( msg );
00606 cWin->setCharset("", true);
00607 if (!hidden) {
00608 cWin->show();
00609
00610
00611 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00612 KStartupInfo::setNewStartupId( cWin, kapp->startupId() );
00613 #endif
00614 }
00615
00616 return DCOPRef( cWin->asMailComposerIFace() );
00617 }
00618
00619 DCOPRef KMKernel::newMessage(const QString &to,
00620 const QString &cc,
00621 const QString &bcc,
00622 bool hidden,
00623 bool useFolderId,
00624 const KURL & ,
00625 const KURL &attachURL)
00626 {
00627 KMail::Composer * win = 0;
00628 KMMessage *msg = new KMMessage;
00629 KMFolder *folder = NULL;
00630 uint id;
00631
00632 if ( useFolderId ) {
00633
00634 folder = currentFolder();
00635 id = folder ? folder->identity() : 0;
00636 msg->initHeader( id );
00637 } else {
00638 msg->initHeader();
00639 }
00640 msg->setCharset("utf-8");
00641
00642 if (!to.isEmpty()) msg->setTo(to);
00643 if (!cc.isEmpty()) msg->setCc(cc);
00644 if (!bcc.isEmpty()) msg->setBcc(bcc);
00645
00646 if ( useFolderId ) {
00647 TemplateParser parser( msg, TemplateParser::NewMessage,
00648 "", false, false, false, false );
00649 parser.process( NULL, folder );
00650 win = makeComposer( msg, id );
00651 } else {
00652 TemplateParser parser( msg, TemplateParser::NewMessage,
00653 "", false, false, false, false );
00654 parser.process( NULL, folder );
00655 win = makeComposer( msg );
00656 }
00657
00658
00659 if(!attachURL.isEmpty() && attachURL.isValid()) {
00660 win->addAttach(attachURL);
00661 }
00662
00663
00664 if(!hidden) {
00665 win->show();
00666 }
00667 return DCOPRef( win->asMailComposerIFace() );
00668 }
00669
00670 int KMKernel::viewMessage( const KURL & messageFile )
00671 {
00672 KMOpenMsgCommand *openCommand = new KMOpenMsgCommand( 0, messageFile );
00673
00674 openCommand->start();
00675
00676 return 1;
00677 }
00678
00679 int KMKernel::sendCertificate( const QString& to, const QByteArray& certData )
00680 {
00681 KMMessage *msg = new KMMessage;
00682 msg->initHeader();
00683 msg->setCharset("utf-8");
00684 msg->setSubject( i18n( "Certificate Signature Request" ) );
00685 if (!to.isEmpty()) msg->setTo(to);
00686
00687 msg->setBody( i18n( "Please create a certificate from attachment and return to sender." ).utf8() );
00688
00689 KMail::Composer * cWin = KMail::makeComposer( msg );
00690 cWin->setCharset("", true);
00691 cWin->slotSetAlwaysSend( true );
00692 if (!certData.isEmpty()) {
00693 KMMessagePart *msgPart = new KMMessagePart;
00694 msgPart->setName("smime.p10");
00695 msgPart->setCteStr("base64");
00696 msgPart->setBodyEncodedBinary(certData);
00697 msgPart->setTypeStr("application");
00698 msgPart->setSubtypeStr("pkcs10");
00699 msgPart->setContentDisposition("attachment; filename=smime.p10");
00700 cWin->addAttach(msgPart);
00701 }
00702
00703 cWin->show();
00704 return 1;
00705 }
00706
00707 KMMsgStatus KMKernel::strToStatus(const QString &flags)
00708 {
00709 KMMsgStatus status = 0;
00710 if (!flags.isEmpty()) {
00711 for (uint n = 0; n < flags.length() ; n++) {
00712 switch (flags[n]) {
00713 case 'N':
00714 status |= KMMsgStatusNew;
00715 break;
00716 case 'U':
00717 status |= KMMsgStatusUnread;
00718 break;
00719 case 'O':
00720 status |= KMMsgStatusOld;
00721 break;
00722 case 'R':
00723 status |= KMMsgStatusRead;
00724 break;
00725 case 'D':
00726 status |= KMMsgStatusDeleted;
00727 break;
00728 case 'A':
00729 status |= KMMsgStatusReplied;
00730 break;
00731 case 'F':
00732 status |= KMMsgStatusForwarded;
00733 break;
00734 case 'Q':
00735 status |= KMMsgStatusQueued;
00736 break;
00737 case 'K':
00738 status |= KMMsgStatusTodo;
00739 break;
00740 case 'S':
00741 status |= KMMsgStatusSent;
00742 break;
00743 case 'G':
00744 status |= KMMsgStatusFlag;
00745 break;
00746 case 'W':
00747 status |= KMMsgStatusWatched;
00748 break;
00749 case 'I':
00750 status |= KMMsgStatusIgnored;
00751 break;
00752 case 'P':
00753 status |= KMMsgStatusSpam;
00754 break;
00755 case 'H':
00756 status |= KMMsgStatusHam;
00757 break;
00758 case 'T':
00759 status |= KMMsgStatusHasAttach;
00760 break;
00761 case 'C':
00762 status |= KMMsgStatusHasNoAttach;
00763 break;
00764 default:
00765 break;
00766 }
00767 }
00768 }
00769 return status;
00770 }
00771
00772 int KMKernel::dcopAddMessage( const QString & foldername, const QString & msgUrlString,
00773 const QString & MsgStatusFlags)
00774 {
00775 return dcopAddMessage(foldername, KURL(msgUrlString), MsgStatusFlags);
00776 }
00777
00778 int KMKernel::dcopAddMessage( const QString & foldername,const KURL & msgUrl,
00779 const QString & MsgStatusFlags)
00780 {
00781 kdDebug(5006) << "KMKernel::dcopAddMessage called" << endl;
00782
00783 if ( foldername.isEmpty() || foldername.startsWith("."))
00784 return -1;
00785
00786 int retval;
00787 bool readFolderMsgIds = false;
00788 QString _foldername = foldername.stripWhiteSpace();
00789 _foldername = _foldername.replace('\\',"");
00790
00791 if ( foldername != mAddMessageLastFolder ) {
00792 mAddMessageMsgIds.clear();
00793 readFolderMsgIds = true;
00794 mAddMessageLastFolder = foldername;
00795 }
00796
00797 if (!msgUrl.isEmpty() && msgUrl.isLocalFile()) {
00798
00799
00800
00801
00802
00803
00804
00805
00806 const QCString messageText =
00807 KPIM::kFileToString( msgUrl.path(), true, false );
00808 if ( messageText.isEmpty() )
00809 return -2;
00810
00811 KMMessage *msg = new KMMessage();
00812 msg->fromString( messageText );
00813
00814 if (readFolderMsgIds) {
00815 if ( foldername.contains("/")) {
00816 QString tmp_fname = "";
00817 KMFolder *folder = NULL;
00818 KMFolderDir *subfolder;
00819 bool root = true;
00820
00821 QStringList subFList = QStringList::split("/",_foldername,false);
00822
00823 for ( QStringList::Iterator it = subFList.begin(); it != subFList.end(); ++it ) {
00824 QString _newFolder = *it;
00825 if(_newFolder.startsWith(".")) return -1;
00826
00827 if(root) {
00828 folder = the_folderMgr->findOrCreate(*it, false);
00829 if (folder) {
00830 root = false;
00831 tmp_fname = "/" + *it;
00832 }
00833 else return -1;
00834 } else {
00835 subfolder = folder->createChildFolder();
00836 tmp_fname += "/" + *it;
00837 if(!the_folderMgr->getFolderByURL( tmp_fname )) {
00838 folder = the_folderMgr->createFolder(*it, false, folder->folderType(), subfolder);
00839 }
00840
00841 if(!(folder = the_folderMgr->getFolderByURL( tmp_fname ))) return -1;
00842 }
00843 }
00844
00845 mAddMsgCurrentFolder = the_folderMgr->getFolderByURL( tmp_fname );
00846 if(!folder) return -1;
00847
00848 } else {
00849 mAddMsgCurrentFolder = the_folderMgr->findOrCreate(_foldername, false);
00850 }
00851 }
00852
00853 if ( mAddMsgCurrentFolder ) {
00854 if (readFolderMsgIds) {
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877 int i;
00878
00879 mAddMsgCurrentFolder->open("dcopadd");
00880 for( i=0; i<mAddMsgCurrentFolder->count(); i++) {
00881 KMMsgBase *mb = mAddMsgCurrentFolder->getMsgBase(i);
00882 QString id = mb->msgIdMD5();
00883 if ( id.isEmpty() ) {
00884 id = mb->subject();
00885 if ( id.isEmpty() )
00886 id = mb->fromStrip();
00887 if ( id.isEmpty() )
00888 id = mb->toStrip();
00889
00890 id += mb->dateStr();
00891 }
00892
00893
00894 if ( !id.isEmpty() ) {
00895 mAddMessageMsgIds.append(id);
00896 }
00897 }
00898 mAddMsgCurrentFolder->close("dcopadd");
00899 }
00900
00901 QString msgId = msg->msgIdMD5();
00902 if ( msgId.isEmpty()) {
00903 msgId = msg->subject();
00904 if ( msgId.isEmpty() )
00905 msgId = msg->fromStrip();
00906 if ( msgId.isEmpty() )
00907 msgId = msg->toStrip();
00908
00909 msgId += msg->dateStr();
00910 }
00911
00912 int k = mAddMessageMsgIds.findIndex( msgId );
00913
00914
00915 if ( k == -1 ) {
00916 if ( !msgId.isEmpty() ) {
00917 mAddMessageMsgIds.append( msgId );
00918 }
00919
00920 if ( !MsgStatusFlags.isEmpty() ) {
00921 KMMsgStatus status = strToStatus(MsgStatusFlags);
00922 if (status) msg->setStatus(status);
00923 }
00924
00925 int index;
00926 if ( mAddMsgCurrentFolder->addMsg( msg, &index ) == 0 ) {
00927 mAddMsgCurrentFolder->unGetMsg( index );
00928 retval = 1;
00929 } else {
00930 retval =- 2;
00931 delete msg;
00932 msg = 0;
00933 }
00934 } else {
00935
00936 retval = -4;
00937 }
00938 } else {
00939 retval = -1;
00940 }
00941 } else {
00942 retval = -2;
00943 }
00944 return retval;
00945 }
00946
00947 void KMKernel::dcopResetAddMessage()
00948 {
00949 mAddMessageMsgIds.clear();
00950 mAddMessageLastFolder = QString();
00951 }
00952
00953 int KMKernel::dcopAddMessage_fastImport( const QString & foldername,
00954 const QString & msgUrlString,
00955 const QString & MsgStatusFlags)
00956 {
00957 return dcopAddMessage_fastImport(foldername, KURL(msgUrlString), MsgStatusFlags);
00958 }
00959
00960 int KMKernel::dcopAddMessage_fastImport( const QString & foldername,
00961 const KURL & msgUrl,
00962 const QString & MsgStatusFlags)
00963 {
00964
00965
00966 kdDebug(5006) << "KMKernel::dcopAddMessage_fastImport called" << endl;
00967
00968 if ( foldername.isEmpty() || foldername.startsWith("."))
00969 return -1;
00970
00971 int retval;
00972 bool createNewFolder = false;
00973
00974 QString _foldername = foldername.stripWhiteSpace();
00975 _foldername = _foldername.replace('\\',"");
00976
00977 if ( foldername != mAddMessageLastFolder ) {
00978 createNewFolder = true;
00979 mAddMessageLastFolder = foldername;
00980 }
00981
00982
00983 if ( !msgUrl.isEmpty() && msgUrl.isLocalFile() ) {
00984 const QCString messageText =
00985 KPIM::kFileToString( msgUrl.path(), true, false );
00986 if ( messageText.isEmpty() )
00987 return -2;
00988
00989 KMMessage *msg = new KMMessage();
00990 msg->fromString( messageText );
00991
00992 if (createNewFolder) {
00993 if ( foldername.contains("/")) {
00994 QString tmp_fname = "";
00995 KMFolder *folder = NULL;
00996 KMFolderDir *subfolder;
00997 bool root = true;
00998
00999 QStringList subFList = QStringList::split("/",_foldername,false);
01000
01001 for ( QStringList::Iterator it = subFList.begin(); it != subFList.end(); ++it ) {
01002 QString _newFolder = *it;
01003 if(_newFolder.startsWith(".")) return -1;
01004
01005 if(root) {
01006 folder = the_folderMgr->findOrCreate(*it, false);
01007 if (folder) {
01008 root = false;
01009 tmp_fname = "/" + *it;
01010 }
01011 else return -1;
01012 } else {
01013 subfolder = folder->createChildFolder();
01014 tmp_fname += "/" + *it;
01015 if(!the_folderMgr->getFolderByURL( tmp_fname )) {
01016 folder = the_folderMgr->createFolder(*it, false, folder->folderType(), subfolder);
01017 }
01018 if(!(folder = the_folderMgr->getFolderByURL( tmp_fname ))) return -1;
01019 }
01020 }
01021
01022 mAddMsgCurrentFolder = the_folderMgr->getFolderByURL( tmp_fname );
01023 if(!folder) return -1;
01024
01025 } else {
01026 mAddMsgCurrentFolder = the_folderMgr->findOrCreate(_foldername, false);
01027 }
01028 }
01029
01030 if ( mAddMsgCurrentFolder ) {
01031 int index;
01032
01033 if( !MsgStatusFlags.isEmpty() ) {
01034 KMMsgStatus status = strToStatus(MsgStatusFlags);
01035 if (status) msg->setStatus(status);
01036 }
01037
01038 if ( mAddMsgCurrentFolder->addMsg( msg, &index ) == 0 ) {
01039 mAddMsgCurrentFolder->unGetMsg( index );
01040 retval = 1;
01041 } else {
01042 retval =- 2;
01043 delete msg;
01044 msg = 0;
01045 }
01046 } else {
01047 retval = -1;
01048 }
01049 } else {
01050 retval = -2;
01051 }
01052
01053 return retval;
01054 }
01055
01056 QStringList KMKernel::folderList() const
01057 {
01058 QStringList folders;
01059 const QString localPrefix = "/Local";
01060 folders << localPrefix;
01061 the_folderMgr->getFolderURLS( folders, localPrefix );
01062 the_imapFolderMgr->getFolderURLS( folders );
01063 the_dimapFolderMgr->getFolderURLS( folders );
01064 return folders;
01065 }
01066
01067 DCOPRef KMKernel::getFolder( const QString& vpath )
01068 {
01069 const QString localPrefix = "/Local";
01070 if ( the_folderMgr->getFolderByURL( vpath ) )
01071 return DCOPRef( new FolderIface( vpath ) );
01072 else if ( vpath.startsWith( localPrefix ) &&
01073 the_folderMgr->getFolderByURL( vpath.mid( localPrefix.length() ) ) )
01074 return DCOPRef( new FolderIface( vpath.mid( localPrefix.length() ) ) );
01075 else if ( the_imapFolderMgr->getFolderByURL( vpath ) )
01076 return DCOPRef( new FolderIface( vpath ) );
01077 else if ( the_dimapFolderMgr->getFolderByURL( vpath ) )
01078 return DCOPRef( new FolderIface( vpath ) );
01079 return DCOPRef();
01080 }
01081
01082 void KMKernel::raise()
01083 {
01084 DCOPRef kmail( "kmail", "kmail" );
01085 kmail.call( "newInstance" );
01086 }
01087
01088 bool KMKernel::showMail( Q_UINT32 serialNumber, QString )
01089 {
01090 KMMainWidget *mainWidget = 0;
01091 if (KMainWindow::memberList) {
01092 KMainWindow *win = 0;
01093 QObjectList *l;
01094
01095
01096 for (win = KMainWindow::memberList->first(); win;
01097 win = KMainWindow::memberList->next()) {
01098
01099 l = win->queryList("KMMainWidget");
01100 if (l && l->first()) {
01101 mainWidget = dynamic_cast<KMMainWidget *>(l->first());
01102 if (win->isActiveWindow())
01103 break;
01104 }
01105 }
01106 }
01107
01108 if (mainWidget) {
01109 int idx = -1;
01110 KMFolder *folder = 0;
01111 KMMsgDict::instance()->getLocation(serialNumber, &folder, &idx);
01112 if (!folder || (idx == -1))
01113 return false;
01114 KMFolderOpener openFolder(folder, "showmail");
01115 KMMsgBase *msgBase = folder->getMsgBase(idx);
01116 if (!msgBase)
01117 return false;
01118 bool unGet = !msgBase->isMessage();
01119 KMMessage *msg = folder->getMsg(idx);
01120
01121 KMReaderMainWin *win = new KMReaderMainWin( false, false );
01122 KMMessage *newMessage = new KMMessage( *msg );
01123 newMessage->setParent( msg->parent() );
01124 newMessage->setMsgSerNum( msg->getMsgSerNum() );
01125 newMessage->setReadyToShow( true );
01126 win->showMsg( GlobalSettings::self()->overrideCharacterEncoding(), newMessage );
01127 win->show();
01128
01129 if (unGet)
01130 folder->unGetMsg(idx);
01131 return true;
01132 }
01133
01134 return false;
01135 }
01136
01137 QString KMKernel::getFrom( Q_UINT32 serialNumber )
01138 {
01139 int idx = -1;
01140 KMFolder *folder = 0;
01141 KMMsgDict::instance()->getLocation(serialNumber, &folder, &idx);
01142 if (!folder || (idx == -1))
01143 return QString::null;
01144 KMFolderOpener openFolder(folder, "getFrom");
01145 KMMsgBase *msgBase = folder->getMsgBase(idx);
01146 if (!msgBase)
01147 return QString::null;
01148 bool unGet = !msgBase->isMessage();
01149 KMMessage *msg = folder->getMsg(idx);
01150 QString result = msg->from();
01151 if (unGet)
01152 folder->unGetMsg(idx);
01153 return result;
01154 }
01155
01156 QString KMKernel::debugScheduler()
01157 {
01158 QString res = KMail::ActionScheduler::debug();
01159 return res;
01160 }
01161
01162 QString KMKernel::debugSernum( Q_UINT32 serialNumber )
01163 {
01164 QString res;
01165 if (serialNumber != 0) {
01166 int idx = -1;
01167 KMFolder *folder = 0;
01168 KMMsgBase *msg = 0;
01169 KMMsgDict::instance()->getLocation( serialNumber, &folder, &idx );
01170
01171
01172 if (folder && (idx != -1)) {
01173
01174 KMFolderOpener openFolder(folder, "debugser");
01175 msg = folder->getMsgBase( idx );
01176 if (msg) {
01177 res.append( QString( " subject %s,\n sender %s,\n date %s.\n" )
01178 .arg( msg->subject() )
01179 .arg( msg->fromStrip() )
01180 .arg( msg->dateStr() ) );
01181 } else {
01182 res.append( QString( "Invalid serial number." ) );
01183 }
01184 } else {
01185 res.append( QString( "Invalid serial number." ) );
01186 }
01187 }
01188 return res;
01189 }
01190
01191
01192 void KMKernel::pauseBackgroundJobs()
01193 {
01194 mBackgroundTasksTimer->stop();
01195 mJobScheduler->pause();
01196 }
01197
01198 void KMKernel::resumeBackgroundJobs()
01199 {
01200 mJobScheduler->resume();
01201 mBackgroundTasksTimer->start( 4 * 60 * 60 * 1000, true );
01202 }
01203
01204 void KMKernel::stopNetworkJobs()
01205 {
01206 if ( GlobalSettings::self()->networkState() == GlobalSettings::EnumNetworkState::Offline )
01207 return;
01208
01209 GlobalSettings::setNetworkState( GlobalSettings::EnumNetworkState::Offline );
01210 BroadcastStatus::instance()->setStatusMsg( i18n("KMail is set to be offline; all network jobs are suspended"));
01211 emit onlineStatusChanged( (GlobalSettings::EnumNetworkState::type)GlobalSettings::networkState() );
01212 }
01213
01214 void KMKernel::resumeNetworkJobs()
01215 {
01216 if ( GlobalSettings::self()->networkState() == GlobalSettings::EnumNetworkState::Online )
01217 return;
01218
01219 GlobalSettings::setNetworkState( GlobalSettings::EnumNetworkState::Online );
01220 BroadcastStatus::instance()->setStatusMsg( i18n("KMail is set to be online; all network jobs resumed"));
01221 emit onlineStatusChanged( (GlobalSettings::EnumNetworkState::type)GlobalSettings::networkState() );
01222
01223 if ( kmkernel->msgSender()->sendImmediate() ) {
01224 kmkernel->msgSender()->sendQueued();
01225 }
01226 }
01227
01228 bool KMKernel::isOffline()
01229 {
01230 if ( GlobalSettings::self()->networkState() == GlobalSettings::EnumNetworkState::Offline )
01231 return true;
01232 else
01233 return false;
01234 }
01235
01236 bool KMKernel::askToGoOnline()
01237 {
01238 if ( kmkernel->isOffline() ) {
01239 int rc =
01240 KMessageBox::questionYesNo( KMKernel::self()->mainWin(),
01241 i18n("KMail is currently in offline mode. "
01242 "How do you want to proceed?"),
01243 i18n("Online/Offline"),
01244 i18n("Work Online"),
01245 i18n("Work Offline"));
01246
01247 if( rc == KMessageBox::No ) {
01248 return false;
01249 } else {
01250 kmkernel->resumeNetworkJobs();
01251 }
01252 }
01253 return true;
01254 }
01255
01256
01257
01258
01259
01260 void KMKernel::quit()
01261 {
01262
01263
01264 }
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311 void KMKernel::testDir(const char *_name)
01312 {
01313 QString foldersPath = QDir::homeDirPath() + QString( _name );
01314 QFileInfo info( foldersPath );
01315 if ( !info.exists() ) {
01316 if ( ::mkdir( QFile::encodeName( foldersPath ) , S_IRWXU ) == -1 ) {
01317 KMessageBox::sorry(0, i18n("KMail could not create folder '%1';\n"
01318 "please make sure that you can view and "
01319 "modify the content of the folder '%2'.")
01320 .arg( foldersPath ).arg( QDir::homeDirPath() ) );
01321 ::exit(-1);
01322 }
01323 }
01324 if ( !info.isDir() || !info.isReadable() || !info.isWritable() ) {
01325 KMessageBox::sorry(0, i18n("The permissions of the folder '%1' are "
01326 "incorrect;\n"
01327 "please make sure that you can view and modify "
01328 "the content of this folder.")
01329 .arg( foldersPath ) );
01330 ::exit(-1);
01331 }
01332 }
01333
01334
01335
01336
01337 void KMKernel::recoverDeadLetters()
01338 {
01339 const QString pathName = localDataPath();
01340 QDir dir( pathName );
01341 if ( !dir.exists( "autosave" ) )
01342 return;
01343
01344 KMFolder folder( 0, pathName + "autosave", KMFolderTypeMaildir, false );
01345 KMFolderOpener openFolder( &folder, "recover" );
01346 if ( !folder.isOpened() ) {
01347 perror( "cannot open autosave folder" );
01348 return;
01349 }
01350
01351 const int num = folder.count();
01352 for ( int i = 0; i < num; i++ ) {
01353 KMMessage *msg = folder.take( 0 );
01354 if ( msg ) {
01355 KMail::Composer * win = KMail::makeComposer();
01356 win->setMsg( msg, false, false, true );
01357 win->setAutoSaveFilename( msg->fileName() );
01358 win->show();
01359 }
01360 }
01361 }
01362
01363
01364 void KMKernel::initFolders(KConfig* cfg)
01365 {
01366 QString name;
01367
01368 name = cfg->readEntry("inboxFolder");
01369
01370
01371
01372
01373
01374 if (name.isEmpty()) name = I18N_NOOP("inbox");
01375
01376 the_inboxFolder = (KMFolder*)the_folderMgr->findOrCreate(name);
01377
01378 if (the_inboxFolder->canAccess() != 0) {
01379 emergencyExit( i18n("You do not have read/write permission to your inbox folder.") );
01380 }
01381
01382 the_inboxFolder->setSystemFolder(true);
01383 if ( the_inboxFolder->userWhoField().isEmpty() )
01384 the_inboxFolder->setUserWhoField( QString::null );
01385
01386
01387 the_outboxFolder = the_folderMgr->findOrCreate(cfg->readEntry("outboxFolder", I18N_NOOP("outbox")));
01388 if (the_outboxFolder->canAccess() != 0) {
01389 emergencyExit( i18n("You do not have read/write permission to your outbox folder.") );
01390 }
01391 the_outboxFolder->setNoChildren(true);
01392
01393 the_outboxFolder->setSystemFolder(true);
01394 if ( the_outboxFolder->userWhoField().isEmpty() )
01395 the_outboxFolder->setUserWhoField( QString::null );
01396
01397
01398
01399
01400
01401
01402
01403
01404 the_outboxFolder->open("kmkernel");
01405
01406 the_sentFolder = the_folderMgr->findOrCreate(cfg->readEntry("sentFolder", I18N_NOOP("sent-mail")));
01407 if (the_sentFolder->canAccess() != 0) {
01408 emergencyExit( i18n("You do not have read/write permission to your sent-mail folder.") );
01409 }
01410 the_sentFolder->setSystemFolder(true);
01411 if ( the_sentFolder->userWhoField().isEmpty() )
01412 the_sentFolder->setUserWhoField( QString::null );
01413
01414
01415 the_trashFolder = the_folderMgr->findOrCreate(cfg->readEntry("trashFolder", I18N_NOOP("trash")));
01416 if (the_trashFolder->canAccess() != 0) {
01417 emergencyExit( i18n("You do not have read/write permission to your trash folder.") );
01418 }
01419 the_trashFolder->setSystemFolder( true );
01420 if ( the_trashFolder->userWhoField().isEmpty() )
01421 the_trashFolder->setUserWhoField( QString::null );
01422
01423
01424 the_draftsFolder = the_folderMgr->findOrCreate(cfg->readEntry("draftsFolder", I18N_NOOP("drafts")));
01425 if (the_draftsFolder->canAccess() != 0) {
01426 emergencyExit( i18n("You do not have read/write permission to your drafts folder.") );
01427 }
01428 the_draftsFolder->setSystemFolder( true );
01429 if ( the_draftsFolder->userWhoField().isEmpty() )
01430 the_draftsFolder->setUserWhoField( QString::null );
01431 the_draftsFolder->open("kmkernel");
01432
01433 the_templatesFolder =
01434 the_folderMgr->findOrCreate( cfg->readEntry( "templatesFolder",
01435 I18N_NOOP("templates") ) );
01436 if ( the_templatesFolder->canAccess() != 0 ) {
01437 emergencyExit( i18n("You do not have read/write permission to your templates folder.") );
01438 }
01439 the_templatesFolder->setSystemFolder( true );
01440 if ( the_templatesFolder->userWhoField().isEmpty() )
01441 the_templatesFolder->setUserWhoField( QString::null );
01442 the_templatesFolder->open("kmkernel");
01443 }
01444
01445
01446 void KMKernel::init()
01447 {
01448 the_shuttingDown = false;
01449 the_server_is_ready = false;
01450
01451 KConfig* cfg = KMKernel::config();
01452
01453 QDir dir;
01454
01455 KConfigGroupSaver saver(cfg, "General");
01456 the_firstStart = cfg->readBoolEntry("first-start", true);
01457 cfg->writeEntry("first-start", false);
01458 the_previousVersion = cfg->readEntry("previous-version");
01459 cfg->writeEntry("previous-version", KMAIL_VERSION);
01460 QString foldersPath = cfg->readPathEntry( "folders" );
01461 kdDebug(5006) << k_funcinfo << "foldersPath (from config): '" << foldersPath << "'" << endl;
01462 bool migrateMail = true;
01463
01464 if ( foldersPath.isEmpty() ) {
01465 foldersPath = localDataPath() + "mail";
01466 if ( transferMail( foldersPath ) ) {
01467 cfg->writePathEntry( "folders", foldersPath );
01468 }
01469 kdDebug(5006) << k_funcinfo << "foldersPath (after transferMail): '" << foldersPath << "'" << endl;
01470 }
01471
01472
01473 KMMessage::readConfig();
01474
01475 the_undoStack = new UndoStack(20);
01476 the_folderMgr = new KMFolderMgr(foldersPath);
01477 the_imapFolderMgr = new KMFolderMgr( KMFolderImap::cacheLocation(), KMImapDir);
01478 the_dimapFolderMgr = new KMFolderMgr( KMFolderCachedImap::cacheLocation(), KMDImapDir);
01479
01480 the_searchFolderMgr = new KMFolderMgr(locateLocal("data","kmail/search"), KMSearchDir);
01481 KMFolder *lsf = the_searchFolderMgr->find( i18n("Last Search") );
01482 if (lsf)
01483 the_searchFolderMgr->remove( lsf );
01484
01485 the_acctMgr = new AccountManager();
01486 the_filterMgr = new KMFilterMgr();
01487 the_popFilterMgr = new KMFilterMgr(true);
01488 the_filterActionDict = new KMFilterActionDict;
01489
01490 initFolders(cfg);
01491 the_acctMgr->readConfig();
01492 the_filterMgr->readConfig();
01493 the_popFilterMgr->readConfig();
01494 cleanupImapFolders();
01495
01496 the_msgSender = new KMSender;
01497 the_server_is_ready = true;
01498 imProxy()->initialize();
01499 {
01500 KConfigGroupSaver saver(cfg, "Composer");
01501 if (cfg->readListEntry("pref-charsets").isEmpty())
01502 {
01503 cfg->writeEntry("pref-charsets", "us-ascii,iso-8859-1,locale,utf-8");
01504 }
01505 }
01506 readConfig();
01507 mICalIface->readConfig();
01508
01509 #ifdef HAVE_INDEXLIB
01510 the_msgIndex = new KMMsgIndex(this);
01511 #else
01512 the_msgIndex = 0;
01513 #endif
01514
01515
01516 the_weaver = new KPIM::ThreadWeaver::Weaver( this );
01517 the_weaverLogger = new KPIM::ThreadWeaver::WeaverThreadLogger(this);
01518 the_weaverLogger->attach (the_weaver);
01519
01520
01521 connect( the_folderMgr, SIGNAL( folderRemoved(KMFolder*) ),
01522 this, SIGNAL( folderRemoved(KMFolder*) ) );
01523 connect( the_dimapFolderMgr, SIGNAL( folderRemoved(KMFolder*) ),
01524 this, SIGNAL( folderRemoved(KMFolder*) ) );
01525 connect( the_imapFolderMgr, SIGNAL( folderRemoved(KMFolder*) ),
01526 this, SIGNAL( folderRemoved(KMFolder*) ) );
01527 connect( the_searchFolderMgr, SIGNAL( folderRemoved(KMFolder*) ),
01528 this, SIGNAL( folderRemoved(KMFolder*) ) );
01529
01530 mBackgroundTasksTimer = new QTimer( this, "mBackgroundTasksTimer" );
01531 connect( mBackgroundTasksTimer, SIGNAL( timeout() ), this, SLOT( slotRunBackgroundTasks() ) );
01532 #ifdef DEBUG_SCHEDULER // for debugging, see jobscheduler.h
01533 mBackgroundTasksTimer->start( 10000, true );
01534 #else
01535 mBackgroundTasksTimer->start( 5 * 60000, true );
01536 #endif
01537 }
01538
01539 void KMKernel::readConfig()
01540 {
01541
01542
01543 KMMessage::readConfig();
01544 }
01545
01546 void KMKernel::cleanupImapFolders()
01547 {
01548 KMAccount *acct = 0;
01549 KMFolderNode *node = the_imapFolderMgr->dir().first();
01550 while (node)
01551 {
01552 if (node->isDir() || ((acct = the_acctMgr->find(node->id()))
01553 && ( acct->type() == "imap" )) )
01554 {
01555 node = the_imapFolderMgr->dir().next();
01556 } else {
01557 KMFolder* folder = static_cast<KMFolder*>(node);
01558
01559 static_cast<KMFolderImap*>( folder->storage() )->setAlreadyRemoved( true );
01560 the_imapFolderMgr->remove(folder);
01561 node = the_imapFolderMgr->dir().first();
01562 }
01563 }
01564
01565 node = the_dimapFolderMgr->dir().first();
01566 while (node)
01567 {
01568 if (node->isDir() || ((acct = the_acctMgr->find(node->id()))
01569 && ( acct->type() == "cachedimap" )) )
01570 {
01571 node = the_dimapFolderMgr->dir().next();
01572 } else {
01573 the_dimapFolderMgr->remove(static_cast<KMFolder*>(node));
01574 node = the_dimapFolderMgr->dir().first();
01575 }
01576 }
01577
01578 the_imapFolderMgr->quiet(true);
01579 for (acct = the_acctMgr->first(); acct; acct = the_acctMgr->next())
01580 {
01581 KMFolderImap *fld;
01582 KMAcctImap *imapAcct;
01583
01584 if (acct->type() != "imap") continue;
01585 fld = static_cast<KMFolderImap*>(the_imapFolderMgr
01586 ->findOrCreate(QString::number(acct->id()), false, acct->id())->storage());
01587 fld->setNoContent(true);
01588 fld->folder()->setLabel(acct->name());
01589 imapAcct = static_cast<KMAcctImap*>(acct);
01590 fld->setAccount(imapAcct);
01591 imapAcct->setImapFolder(fld);
01592 fld->close( "kernel", true );
01593 }
01594 the_imapFolderMgr->quiet(false);
01595
01596 the_dimapFolderMgr->quiet( true );
01597 for (acct = the_acctMgr->first(); acct; acct = the_acctMgr->next())
01598 {
01599 KMFolderCachedImap *cfld = 0;
01600 KMAcctCachedImap *cachedImapAcct;
01601
01602 if (acct->type() != "cachedimap" ) continue;
01603
01604 KMFolder* fld = the_dimapFolderMgr->find(QString::number(acct->id()));
01605 if( fld )
01606 cfld = static_cast<KMFolderCachedImap*>( fld->storage() );
01607 if (cfld == 0) {
01608
01609 cfld = static_cast<KMFolderCachedImap*>(the_dimapFolderMgr->createFolder(QString::number(acct->id()),
01610 false, KMFolderTypeCachedImap)->storage());
01611 if (!cfld) {
01612 KMessageBox::error(0,(i18n("Cannot create file `%1' in %2.\nKMail cannot start without it.").arg(acct->name()).arg(the_dimapFolderMgr->basePath())));
01613 exit(-1);
01614 }
01615 cfld->folder()->setId( acct->id() );
01616 }
01617
01618 cfld->setNoContent(true);
01619 cfld->folder()->setLabel(acct->name());
01620 cachedImapAcct = static_cast<KMAcctCachedImap*>(acct);
01621 cfld->setAccount(cachedImapAcct);
01622 cachedImapAcct->setImapFolder(cfld);
01623 cfld->close("kmkernel");
01624 }
01625 the_dimapFolderMgr->quiet( false );
01626 }
01627
01628 bool KMKernel::doSessionManagement()
01629 {
01630
01631
01632 if (kapp->isRestored()){
01633 int n = 1;
01634 while (KMMainWin::canBeRestored(n)){
01635
01636 if (KMMainWin::classNameOfToplevel(n) == "KMMainWin")
01637 (new KMMainWin)->restore(n);
01638 n++;
01639 }
01640 return true;
01641 }
01642 return false;
01643 }
01644
01645 void KMKernel::closeAllKMailWindows()
01646 {
01647 if (!KMainWindow::memberList) return;
01648 QPtrListIterator<KMainWindow> it(*KMainWindow::memberList);
01649 KMainWindow *window = 0;
01650 while ((window = it.current()) != 0) {
01651 ++it;
01652 if (window->isA("KMMainWindow") ||
01653 window->inherits("KMail::SecondaryWindow"))
01654 window->close( true );
01655 }
01656 }
01657
01658 void KMKernel::cleanup(void)
01659 {
01660 dumpDeadLetters();
01661 the_shuttingDown = true;
01662 closeAllKMailWindows();
01663
01664 delete the_acctMgr;
01665 the_acctMgr = 0;
01666 delete the_filterMgr;
01667 the_filterMgr = 0;
01668 delete the_msgSender;
01669 the_msgSender = 0;
01670 delete the_filterActionDict;
01671 the_filterActionDict = 0;
01672 delete the_undoStack;
01673 the_undoStack = 0;
01674 delete the_popFilterMgr;
01675 the_popFilterMgr = 0;
01676
01677 #if 0
01678 delete the_weaver;
01679 the_weaver = 0;
01680 #endif
01681
01682 KConfig* config = KMKernel::config();
01683 KConfigGroupSaver saver(config, "General");
01684
01685 if (the_trashFolder) {
01686
01687 the_trashFolder->close("kmkernel", true);
01688
01689 if (config->readBoolEntry("empty-trash-on-exit", true))
01690 {
01691 if ( the_trashFolder->count( true ) > 0 )
01692 the_trashFolder->expunge();
01693 }
01694 }
01695
01696 mICalIface->cleanup();
01697
01698 QValueList<QGuardedPtr<KMFolder> > folders;
01699 QStringList strList;
01700 KMFolder *folder;
01701 the_folderMgr->createFolderList(&strList, &folders);
01702 for (int i = 0; folders.at(i) != folders.end(); i++)
01703 {
01704 folder = *folders.at(i);
01705 if (!folder || folder->isDir()) continue;
01706 folder->close("kmkernel", true);
01707 }
01708 strList.clear();
01709 folders.clear();
01710 the_searchFolderMgr->createFolderList(&strList, &folders);
01711 for (int i = 0; folders.at(i) != folders.end(); i++)
01712 {
01713 folder = *folders.at(i);
01714 if (!folder || folder->isDir()) continue;
01715 folder->close("kmkernel", true);
01716 }
01717
01718 delete the_msgIndex;
01719 the_msgIndex = 0;
01720 delete the_folderMgr;
01721 the_folderMgr = 0;
01722 delete the_imapFolderMgr;
01723 the_imapFolderMgr = 0;
01724 delete the_dimapFolderMgr;
01725 the_dimapFolderMgr = 0;
01726 delete the_searchFolderMgr;
01727 the_searchFolderMgr = 0;
01728 delete mConfigureDialog;
01729 mConfigureDialog = 0;
01730
01731
01732 mWin = 0;
01733
01734 if ( RecentAddresses::exists() )
01735 RecentAddresses::self( config )->save( config );
01736 config->sync();
01737 }
01738
01739 bool KMKernel::transferMail( QString & destinationDir )
01740 {
01741 QString dir;
01742
01743
01744 QFileInfo fi( QDir::home(), "KMail" );
01745 if ( fi.exists() && fi.isDir() ) {
01746 dir = QDir::homeDirPath() + "/KMail";
01747
01748 destinationDir = dir;
01749 return true;
01750 }
01751
01752 if ( dir.isEmpty() ) {
01753
01754 fi.setFile( QDir::home(), "Mail" );
01755 if ( fi.exists() && fi.isDir() &&
01756 QFile::exists( QDir::homeDirPath() + "/Mail/.inbox.index" ) ) {
01757
01758
01759 dir = QDir::homeDirPath() + "/Mail";
01760
01761 destinationDir = dir;
01762 return true;
01763 }
01764 }
01765
01766 if ( dir.isEmpty() ) {
01767
01768 fi.setFile( QDir::home(), ".Mail" );
01769 if ( fi.exists() && fi.isDir() &&
01770 QFile::exists( QDir::homeDirPath() + "/.Mail/.inbox.index" ) ) {
01771
01772
01773 dir = QDir::homeDirPath() + "/.Mail";
01774
01775 destinationDir = dir;
01776 return true;
01777 }
01778 }
01779
01780 if ( dir.isEmpty() ) {
01781 return true;
01782 }
01783
01784 #if 0
01785
01786 const QString kmailName = kapp->aboutData()->programName();
01787 QString msg;
01788 if ( KIO::NetAccess::exists( destinationDir, true, 0 ) ) {
01789
01790
01791 msg = i18n( "%1-%3 is the application name, %4-%7 are folder path",
01792 "<qt>The <i>%4</i> folder exists. "
01793 "%1 now uses the <i>%5</i> folder for "
01794 "its messages.<p>"
01795 "%2 can move the contents of <i>%6<i> into this folder for "
01796 "you, though this may replace any existing files with "
01797 "the same name in <i>%7</i>.<p>"
01798 "<strong>Would you like %3 to move the mail "
01799 "files now?</strong></qt>" )
01800 .arg( kmailName, kmailName, kmailName )
01801 .arg( dir, destinationDir, dir, destinationDir );
01802 } else {
01803 msg = i18n( "%1-%3 is the application name, %4-%6 are folder path",
01804 "<qt>The <i>%4</i> folder exists. "
01805 "%1 now uses the <i>%5</i> folder for "
01806 "its messages. %2 can move the contents of <i>%6</i> into "
01807 "this folder for you.<p>"
01808 "<strong>Would you like %3 to move the mail "
01809 "files now?</strong></qt>" )
01810 .arg( kmailName, kmailName, kmailName )
01811 .arg( dir, destinationDir, dir );
01812 }
01813 QString title = i18n( "Migrate Mail Files?" );
01814 QString buttonText = i18n( "Move" );
01815
01816 if ( KMessageBox::questionYesNo( 0, msg, title, buttonText, i18n("Do Not Move") ) ==
01817 KMessageBox::No ) {
01818 destinationDir = dir;
01819 return true;
01820 }
01821
01822 if ( !KIO::NetAccess::move( dir, destinationDir ) ) {
01823 kdDebug(5006) << k_funcinfo << "Moving " << dir << " to " << destinationDir << " failed: " << KIO::NetAccess::lastErrorString() << endl;
01824 kdDebug(5006) << k_funcinfo << "Deleting " << destinationDir << endl;
01825 KIO::NetAccess::del( destinationDir, 0 );
01826 destinationDir = dir;
01827 return false;
01828 }
01829 #endif
01830
01831 return true;
01832 }
01833
01834
01835 void KMKernel::ungrabPtrKb(void)
01836 {
01837 if(!KMainWindow::memberList) return;
01838 QWidget* widg = KMainWindow::memberList->first();
01839 Display* dpy;
01840
01841 if (!widg) return;
01842 dpy = widg->x11Display();
01843 XUngrabKeyboard(dpy, CurrentTime);
01844 XUngrabPointer(dpy, CurrentTime);
01845 }
01846
01847
01848
01849 void KMKernel::kmailMsgHandler(QtMsgType aType, const char* aMsg)
01850 {
01851 static int recurse=-1;
01852
01853 recurse++;
01854
01855 switch (aType)
01856 {
01857 case QtDebugMsg:
01858 case QtWarningMsg:
01859 kdDebug(5006) << aMsg << endl;
01860 break;
01861
01862 case QtFatalMsg:
01863 ungrabPtrKb();
01864 kdDebug(5006) << kapp->caption() << " fatal error "
01865 << aMsg << endl;
01866 KMessageBox::error(0, aMsg);
01867 abort();
01868 }
01869
01870 recurse--;
01871 }
01872
01873
01874 void KMKernel::dumpDeadLetters()
01875 {
01876 if ( shuttingDown() )
01877 return;
01878
01879
01880 if ( !KMainWindow::memberList )
01881 return;
01882
01883 for ( QPtrListIterator<KMainWindow> it(*KMainWindow::memberList) ; it.current() != 0; ++it )
01884 if ( KMail::Composer * win = ::qt_cast<KMail::Composer*>( it.current() ) )
01885 win->autoSaveMessage();
01886 }
01887
01888
01889
01890 void KMKernel::action(bool mailto, bool check, const QString &to,
01891 const QString &cc, const QString &bcc,
01892 const QString &subj, const QString &body,
01893 const KURL &messageFile,
01894 const KURL::List &attachURLs,
01895 const QCStringList &customHeaders)
01896 {
01897 if ( mailto )
01898 openComposer( to, cc, bcc, subj, body, 0, messageFile, attachURLs, customHeaders );
01899 else
01900 openReader( check );
01901
01902 if ( check )
01903 checkMail();
01904
01905 }
01906
01907 void KMKernel::byteArrayToRemoteFile(const QByteArray &aData, const KURL &aURL,
01908 bool overwrite)
01909 {
01910
01911 KIO::Job *job = KIO::put(aURL, -1, overwrite, false);
01912 putData pd; pd.url = aURL; pd.data = aData; pd.offset = 0;
01913 mPutJobs.insert(job, pd);
01914 connect(job, SIGNAL(dataReq(KIO::Job*,QByteArray&)),
01915 SLOT(slotDataReq(KIO::Job*,QByteArray&)));
01916 connect(job, SIGNAL(result(KIO::Job*)),
01917 SLOT(slotResult(KIO::Job*)));
01918 }
01919
01920 void KMKernel::slotDataReq(KIO::Job *job, QByteArray &data)
01921 {
01922
01923 const int MAX_CHUNK_SIZE = 64*1024;
01924 QMap<KIO::Job*, putData>::Iterator it = mPutJobs.find(job);
01925 assert(it != mPutJobs.end());
01926 int remainingBytes = (*it).data.size() - (*it).offset;
01927 if( remainingBytes > MAX_CHUNK_SIZE )
01928 {
01929
01930 data.duplicate( (*it).data.data() + (*it).offset, MAX_CHUNK_SIZE );
01931 (*it).offset += MAX_CHUNK_SIZE;
01932
01933
01934 }
01935 else
01936 {
01937
01938 data.duplicate( (*it).data.data() + (*it).offset, remainingBytes );
01939 (*it).data = QByteArray();
01940 (*it).offset = 0;
01941
01942 }
01943 }
01944
01945 void KMKernel::slotResult(KIO::Job *job)
01946 {
01947 QMap<KIO::Job*, putData>::Iterator it = mPutJobs.find(job);
01948 assert(it != mPutJobs.end());
01949 if (job->error())
01950 {
01951 if (job->error() == KIO::ERR_FILE_ALREADY_EXIST)
01952 {
01953 if (KMessageBox::warningContinueCancel(0,
01954 i18n("File %1 exists.\nDo you want to replace it?")
01955 .arg((*it).url.prettyURL()), i18n("Save to File"), i18n("&Replace"))
01956 == KMessageBox::Continue)
01957 byteArrayToRemoteFile((*it).data, (*it).url, true);
01958 }
01959 else job->showErrorDialog();
01960 }
01961 mPutJobs.remove(it);
01962 }
01963
01964 void KMKernel::slotRequestConfigSync() {
01965
01966 KMKernel::config()->sync();
01967 }
01968
01969 void KMKernel::slotShowConfigurationDialog()
01970 {
01971 if( !mConfigureDialog ) {
01972 mConfigureDialog = new ConfigureDialog( 0, "configure", false );
01973 connect( mConfigureDialog, SIGNAL( configCommitted() ),
01974 this, SLOT( slotConfigChanged() ) );
01975 }
01976
01977 if( KMKernel::getKMMainWidget() == 0 )
01978 {
01979
01980
01981
01982 KMMainWin * win = new KMMainWin;
01983 win->show();
01984 }
01985
01986 if( mConfigureDialog->isHidden() )
01987 mConfigureDialog->show();
01988 else
01989 mConfigureDialog->raise();
01990 }
01991
01992 void KMKernel::slotConfigChanged()
01993 {
01994 readConfig();
01995 emit configChanged();
01996 }
01997
01998
01999
02000 QString KMKernel::localDataPath()
02001 {
02002 return locateLocal( "data", "kmail/" );
02003 }
02004
02005
02006
02007 bool KMKernel::haveSystemTrayApplet()
02008 {
02009 return !systemTrayApplets.isEmpty();
02010 }
02011
02012 bool KMKernel::registerSystemTrayApplet( const KSystemTray* applet )
02013 {
02014 if ( systemTrayApplets.findIndex( applet ) == -1 ) {
02015 systemTrayApplets.append( applet );
02016 return true;
02017 }
02018 else
02019 return false;
02020 }
02021
02022 bool KMKernel::unregisterSystemTrayApplet( const KSystemTray* applet )
02023 {
02024 QValueList<const KSystemTray*>::iterator it =
02025 systemTrayApplets.find( applet );
02026 if ( it != systemTrayApplets.end() ) {
02027 systemTrayApplets.remove( it );
02028 return true;
02029 }
02030 else
02031 return false;
02032 }
02033
02034 void KMKernel::emergencyExit( const QString& reason )
02035 {
02036 QString mesg;
02037 if ( reason.length() == 0 ) {
02038 mesg = i18n("KMail encountered a fatal error and will terminate now");
02039 } else {
02040 mesg = i18n("KMail encountered a fatal error and will "
02041 "terminate now.\nThe error was:\n%1").arg( reason );
02042 }
02043
02044 kdWarning() << mesg << endl;
02045 KNotifyClient::userEvent( 0, "<qt>"+mesg+"</qt>", KNotifyClient::Messagebox, KNotifyClient::Error );
02046
02047 ::exit(1);
02048 }
02049
02053 bool KMKernel::folderIsDraftOrOutbox(const KMFolder * folder)
02054 {
02055 assert( folder );
02056 if ( folder == the_outboxFolder )
02057 return true;
02058 return folderIsDrafts( folder );
02059 }
02060
02061 bool KMKernel::folderIsDrafts(const KMFolder * folder)
02062 {
02063 assert( folder );
02064 if ( folder == the_draftsFolder )
02065 return true;
02066
02067 QString idString = folder->idString();
02068 if ( idString.isEmpty() )
02069 return false;
02070
02071
02072 const KPIM::IdentityManager *im = identityManager();
02073 for ( KPIM::IdentityManager::ConstIterator it=im->begin(); it != im->end(); ++it )
02074 if ( (*it).drafts() == idString )
02075 return true;
02076 return false;
02077 }
02078
02079 bool KMKernel::folderIsTemplates( const KMFolder *folder )
02080 {
02081 assert( folder );
02082 if ( folder == the_templatesFolder )
02083 return true;
02084
02085 QString idString = folder->idString();
02086 if ( idString.isEmpty() )
02087 return false;
02088
02089
02090 const KPIM::IdentityManager *im = identityManager();
02091 for ( KPIM::IdentityManager::ConstIterator it=im->begin(); it != im->end(); ++it )
02092 if ( (*it).templates() == idString )
02093 return true;
02094 return false;
02095 }
02096
02097 bool KMKernel::folderIsTrash(KMFolder * folder)
02098 {
02099 assert(folder);
02100 if (folder == the_trashFolder) return true;
02101 QStringList actList = acctMgr()->getAccounts();
02102 QStringList::Iterator it( actList.begin() );
02103 for( ; it != actList.end() ; ++it ) {
02104 KMAccount* act = acctMgr()->findByName( *it );
02105 if ( act && ( act->trash() == folder->idString() ) )
02106 return true;
02107 }
02108 return false;
02109 }
02110
02111 bool KMKernel::folderIsSentMailFolder( const KMFolder * folder )
02112 {
02113 assert( folder );
02114 if ( folder == the_sentFolder )
02115 return true;
02116
02117 QString idString = folder->idString();
02118 if ( idString.isEmpty() ) return false;
02119
02120
02121 const KPIM::IdentityManager * im = identityManager();
02122 for( KPIM::IdentityManager::ConstIterator it = im->begin(); it != im->end(); ++it )
02123 if ( (*it).fcc() == idString ) return true;
02124 return false;
02125 }
02126
02127 KPIM::IdentityManager * KMKernel::identityManager() {
02128 if ( !mIdentityManager ) {
02129 kdDebug(5006) << "instantating KPIM::IdentityManager" << endl;
02130 mIdentityManager = new KPIM::IdentityManager( false, this, "mIdentityManager" );
02131 }
02132 return mIdentityManager;
02133 }
02134
02135 KMMsgIndex *KMKernel::msgIndex()
02136 {
02137 return the_msgIndex;
02138 }
02139
02140 KMainWindow* KMKernel::mainWin()
02141 {
02142 if (KMainWindow::memberList) {
02143 KMainWindow *kmWin = 0;
02144
02145
02146 for (kmWin = KMainWindow::memberList->first(); kmWin;
02147 kmWin = KMainWindow::memberList->next())
02148 if (kmWin->isA("KMMainWin"))
02149 return kmWin;
02150
02151
02152
02153
02154 kmWin = KMainWindow::memberList->first();
02155 if ( kmWin )
02156 return kmWin;
02157 }
02158
02159
02160
02161
02162
02163 mWin = new KMMainWin;
02164 return mWin;
02165 }
02166
02167
02171 void KMKernel::slotEmptyTrash()
02172 {
02173 QString title = i18n("Empty Trash");
02174 QString text = i18n("Are you sure you want to empty the trash folders of all accounts?");
02175 if (KMessageBox::warningContinueCancel(0, text, title,
02176 KStdGuiItem::cont(), "confirm_empty_trash")
02177 != KMessageBox::Continue)
02178 {
02179 return;
02180 }
02181
02182 for (KMAccount* acct = acctMgr()->first(); acct; acct = acctMgr()->next())
02183 {
02184 KMFolder* trash = findFolderById(acct->trash());
02185 if (trash)
02186 {
02187 trash->expunge();
02188 }
02189 }
02190 }
02191
02192 KConfig* KMKernel::config()
02193 {
02194 assert(mySelf);
02195 if (!mySelf->mConfig)
02196 {
02197 mySelf->mConfig = KSharedConfig::openConfig( "kmailrc" );
02198
02199 KMail::checkConfigUpdates();
02200 }
02201 return mySelf->mConfig;
02202 }
02203
02204 KMailICalIfaceImpl& KMKernel::iCalIface()
02205 {
02206 assert( mICalIface );
02207 return *mICalIface;
02208 }
02209
02210 void KMKernel::selectFolder( QString folderPath )
02211 {
02212 kdDebug(5006)<<"Selecting a folder "<<folderPath<<endl;
02213 const QString localPrefix = "/Local";
02214 KMFolder *folder = kmkernel->folderMgr()->getFolderByURL( folderPath );
02215 if ( !folder && folderPath.startsWith( localPrefix ) )
02216 folder = the_folderMgr->getFolderByURL( folderPath.mid( localPrefix.length() ) );
02217 if ( !folder )
02218 folder = kmkernel->imapFolderMgr()->getFolderByURL( folderPath );
02219 if ( !folder )
02220 folder = kmkernel->dimapFolderMgr()->getFolderByURL( folderPath );
02221 Q_ASSERT( folder );
02222
02223 KMMainWidget *widget = getKMMainWidget();
02224 Q_ASSERT( widget );
02225 if ( !widget )
02226 return;
02227
02228 KMFolderTree *tree = widget->folderTree();
02229 tree->doFolderSelected( tree->indexOfFolder( folder ) );
02230 tree->ensureItemVisible( tree->indexOfFolder( folder ) );
02231 }
02232
02233 KMMainWidget *KMKernel::getKMMainWidget()
02234 {
02235
02236 QWidgetList *l = kapp->topLevelWidgets();
02237 QWidgetListIt it( *l );
02238 QWidget *wid;
02239
02240 while ( ( wid = it.current() ) != 0 ) {
02241 ++it;
02242 QObjectList *l2 = wid->topLevelWidget()->queryList( "KMMainWidget" );
02243 if (l2 && l2->first()) {
02244 KMMainWidget* kmmw = dynamic_cast<KMMainWidget *>( l2->first() );
02245 Q_ASSERT( kmmw );
02246 delete l2;
02247 delete l;
02248 return kmmw;
02249 }
02250 delete l2;
02251 }
02252 delete l;
02253 return 0;
02254 }
02255
02256 void KMKernel::slotRunBackgroundTasks()
02257 {
02258
02259
02260 KConfigGroup generalGroup( config(), "General" );
02261
02262 if ( generalGroup.readBoolEntry( "auto-expiring", true ) ) {
02263 the_folderMgr->expireAllFolders( false );
02264 the_imapFolderMgr->expireAllFolders( false );
02265 the_dimapFolderMgr->expireAllFolders( false );
02266
02267 }
02268
02269 if ( generalGroup.readBoolEntry( "auto-compaction", true ) ) {
02270 the_folderMgr->compactAllFolders( false );
02271
02272 the_dimapFolderMgr->compactAllFolders( false );
02273
02274 }
02275
02276 #ifdef DEBUG_SCHEDULER // for debugging, see jobscheduler.h
02277 mBackgroundTasksTimer->start( 60 * 1000, true );
02278 #else
02279 mBackgroundTasksTimer->start( 4 * 60 * 60 * 1000, true );
02280 #endif
02281
02282 }
02283
02284 void KMKernel::expireAllFoldersNow()
02285 {
02286 the_folderMgr->expireAllFolders( true );
02287 the_imapFolderMgr->expireAllFolders( true );
02288 the_dimapFolderMgr->expireAllFolders( true );
02289 }
02290
02291 void KMKernel::compactAllFolders()
02292 {
02293 the_folderMgr->compactAllFolders( true );
02294
02295 the_dimapFolderMgr->compactAllFolders( true );
02296 }
02297
02298 KMFolder* KMKernel::findFolderById( const QString& idString )
02299 {
02300 KMFolder * folder = the_folderMgr->findIdString( idString );
02301 if ( !folder )
02302 folder = the_imapFolderMgr->findIdString( idString );
02303 if ( !folder )
02304 folder = the_dimapFolderMgr->findIdString( idString );
02305 if ( !folder )
02306 folder = the_searchFolderMgr->findIdString( idString );
02307 return folder;
02308 }
02309
02310 ::KIMProxy* KMKernel::imProxy()
02311 {
02312 return KIMProxy::instance( kapp->dcopClient() );
02313 }
02314
02315 void KMKernel::enableMailCheck()
02316 {
02317 mMailCheckAborted = false;
02318 }
02319
02320 bool KMKernel::mailCheckAborted() const
02321 {
02322 return mMailCheckAborted;
02323 }
02324
02325 void KMKernel::abortMailCheck()
02326 {
02327 mMailCheckAborted = true;
02328 }
02329
02330 bool KMKernel::canQueryClose()
02331 {
02332 if ( KMMainWidget::mainWidgetList() &&
02333 KMMainWidget::mainWidgetList()->count() > 1 )
02334 return true;
02335 KMMainWidget *widget = getKMMainWidget();
02336 if ( !widget )
02337 return true;
02338 KMSystemTray* systray = widget->systray();
02339 if ( !systray || GlobalSettings::closeDespiteSystemTray() )
02340 return true;
02341 if ( systray->mode() == GlobalSettings::EnumSystemTrayPolicy::ShowAlways ) {
02342 systray->hideKMail();
02343 return false;
02344 } else if ( systray->mode() == GlobalSettings::EnumSystemTrayPolicy::ShowOnUnread ) {
02345 systray->show();
02346 systray->hideKMail();
02347 return false;
02348 }
02349 return true;
02350 }
02351
02352 void KMKernel::messageCountChanged()
02353 {
02354 mTimeOfLastMessageCountChange = ::time( 0 );
02355 }
02356
02357 int KMKernel::timeOfLastMessageCountChange() const
02358 {
02359 return mTimeOfLastMessageCountChange;
02360 }
02361
02362 Wallet *KMKernel::wallet() {
02363 static bool walletOpenFailed = false;
02364 if ( mWallet && mWallet->isOpen() )
02365 return mWallet;
02366
02367 if ( !Wallet::isEnabled() || walletOpenFailed )
02368 return 0;
02369
02370
02371 WId window = 0;
02372 if ( qApp->activeWindow() )
02373 window = qApp->activeWindow()->winId();
02374 else if ( getKMMainWidget() )
02375 window = getKMMainWidget()->topLevelWidget()->winId();
02376
02377 delete mWallet;
02378 mWallet = Wallet::openWallet( Wallet::NetworkWallet(), window );
02379
02380 if ( !mWallet ) {
02381 walletOpenFailed = true;
02382 return 0;
02383 }
02384
02385 if ( !mWallet->hasFolder( "kmail" ) )
02386 mWallet->createFolder( "kmail" );
02387 mWallet->setFolder( "kmail" );
02388 return mWallet;
02389 }
02390
02391 QValueList< QGuardedPtr<KMFolder> > KMKernel::allFolders()
02392 {
02393 QStringList names;
02394 QValueList<QGuardedPtr<KMFolder> > folders;
02395 folderMgr()->createFolderList(&names, &folders);
02396 imapFolderMgr()->createFolderList(&names, &folders);
02397 dimapFolderMgr()->createFolderList(&names, &folders);
02398 searchFolderMgr()->createFolderList(&names, &folders);
02399
02400 return folders;
02401 }
02402
02403 KMFolder *KMKernel::currentFolder() {
02404 KMMainWidget *widget = getKMMainWidget();
02405 KMFolder *folder = 0;
02406 if ( widget && widget->folderTree() ) {
02407 folder = widget->folderTree()->currentFolder();
02408 }
02409 return folder;
02410 }
02411
02412
02413
02414 KMail::MessageSender * KMKernel::msgSender() { return the_msgSender; }
02415
02416 #include "kmkernel.moc"