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
01463 if ( foldersPath.isEmpty() ) {
01464 foldersPath = localDataPath() + "mail";
01465 if ( transferMail( foldersPath ) ) {
01466 cfg->writePathEntry( "folders", foldersPath );
01467 }
01468 kdDebug(5006) << k_funcinfo << "foldersPath (after transferMail): '" << foldersPath << "'" << endl;
01469 }
01470
01471
01472 KMMessage::readConfig();
01473
01474 the_undoStack = new UndoStack(20);
01475 the_folderMgr = new KMFolderMgr(foldersPath);
01476 the_imapFolderMgr = new KMFolderMgr( KMFolderImap::cacheLocation(), KMImapDir);
01477 the_dimapFolderMgr = new KMFolderMgr( KMFolderCachedImap::cacheLocation(), KMDImapDir);
01478
01479 the_searchFolderMgr = new KMFolderMgr(locateLocal("data","kmail/search"), KMSearchDir);
01480 KMFolder *lsf = the_searchFolderMgr->find( i18n("Last Search") );
01481 if (lsf)
01482 the_searchFolderMgr->remove( lsf );
01483
01484 the_acctMgr = new AccountManager();
01485 the_filterMgr = new KMFilterMgr();
01486 the_popFilterMgr = new KMFilterMgr(true);
01487 the_filterActionDict = new KMFilterActionDict;
01488
01489 initFolders(cfg);
01490 the_acctMgr->readConfig();
01491 the_filterMgr->readConfig();
01492 the_popFilterMgr->readConfig();
01493 cleanupImapFolders();
01494
01495 the_msgSender = new KMSender;
01496 the_server_is_ready = true;
01497 imProxy()->initialize();
01498 {
01499 KConfigGroupSaver saver(cfg, "Composer");
01500 if (cfg->readListEntry("pref-charsets").isEmpty())
01501 {
01502 cfg->writeEntry("pref-charsets", "us-ascii,iso-8859-1,locale,utf-8");
01503 }
01504 }
01505 readConfig();
01506 mICalIface->readConfig();
01507
01508 #ifdef HAVE_INDEXLIB
01509 the_msgIndex = new KMMsgIndex(this);
01510 #else
01511 the_msgIndex = 0;
01512 #endif
01513
01514
01515 the_weaver = new KPIM::ThreadWeaver::Weaver( this );
01516 the_weaverLogger = new KPIM::ThreadWeaver::WeaverThreadLogger(this);
01517 the_weaverLogger->attach (the_weaver);
01518
01519
01520 connect( the_folderMgr, SIGNAL( folderRemoved(KMFolder*) ),
01521 this, SIGNAL( folderRemoved(KMFolder*) ) );
01522 connect( the_dimapFolderMgr, SIGNAL( folderRemoved(KMFolder*) ),
01523 this, SIGNAL( folderRemoved(KMFolder*) ) );
01524 connect( the_imapFolderMgr, SIGNAL( folderRemoved(KMFolder*) ),
01525 this, SIGNAL( folderRemoved(KMFolder*) ) );
01526 connect( the_searchFolderMgr, SIGNAL( folderRemoved(KMFolder*) ),
01527 this, SIGNAL( folderRemoved(KMFolder*) ) );
01528
01529 mBackgroundTasksTimer = new QTimer( this, "mBackgroundTasksTimer" );
01530 connect( mBackgroundTasksTimer, SIGNAL( timeout() ), this, SLOT( slotRunBackgroundTasks() ) );
01531 #ifdef DEBUG_SCHEDULER // for debugging, see jobscheduler.h
01532 mBackgroundTasksTimer->start( 10000, true );
01533 #else
01534 mBackgroundTasksTimer->start( 5 * 60000, true );
01535 #endif
01536 }
01537
01538 void KMKernel::readConfig()
01539 {
01540
01541
01542 KMMessage::readConfig();
01543 }
01544
01545 void KMKernel::cleanupImapFolders()
01546 {
01547 KMAccount *acct = 0;
01548 KMFolderNode *node = the_imapFolderMgr->dir().first();
01549 while (node)
01550 {
01551 if (node->isDir() || ((acct = the_acctMgr->find(node->id()))
01552 && ( acct->type() == "imap" )) )
01553 {
01554 node = the_imapFolderMgr->dir().next();
01555 } else {
01556 KMFolder* folder = static_cast<KMFolder*>(node);
01557
01558 static_cast<KMFolderImap*>( folder->storage() )->setAlreadyRemoved( true );
01559 the_imapFolderMgr->remove(folder);
01560 node = the_imapFolderMgr->dir().first();
01561 }
01562 }
01563
01564 node = the_dimapFolderMgr->dir().first();
01565 while (node)
01566 {
01567 if (node->isDir() || ((acct = the_acctMgr->find(node->id()))
01568 && ( acct->type() == "cachedimap" )) )
01569 {
01570 node = the_dimapFolderMgr->dir().next();
01571 } else {
01572 the_dimapFolderMgr->remove(static_cast<KMFolder*>(node));
01573 node = the_dimapFolderMgr->dir().first();
01574 }
01575 }
01576
01577 the_imapFolderMgr->quiet(true);
01578 for (acct = the_acctMgr->first(); acct; acct = the_acctMgr->next())
01579 {
01580 KMFolderImap *fld;
01581 KMAcctImap *imapAcct;
01582
01583 if (acct->type() != "imap") continue;
01584 fld = static_cast<KMFolderImap*>(the_imapFolderMgr
01585 ->findOrCreate(QString::number(acct->id()), false, acct->id())->storage());
01586 fld->setNoContent(true);
01587 fld->folder()->setLabel(acct->name());
01588 imapAcct = static_cast<KMAcctImap*>(acct);
01589 fld->setAccount(imapAcct);
01590 imapAcct->setImapFolder(fld);
01591 fld->close( "kernel", true );
01592 }
01593 the_imapFolderMgr->quiet(false);
01594
01595 the_dimapFolderMgr->quiet( true );
01596 for (acct = the_acctMgr->first(); acct; acct = the_acctMgr->next())
01597 {
01598 KMFolderCachedImap *cfld = 0;
01599 KMAcctCachedImap *cachedImapAcct;
01600
01601 if (acct->type() != "cachedimap" ) continue;
01602
01603 KMFolder* fld = the_dimapFolderMgr->find(QString::number(acct->id()));
01604 if( fld )
01605 cfld = static_cast<KMFolderCachedImap*>( fld->storage() );
01606 if (cfld == 0) {
01607
01608 cfld = static_cast<KMFolderCachedImap*>(the_dimapFolderMgr->createFolder(QString::number(acct->id()),
01609 false, KMFolderTypeCachedImap)->storage());
01610 if (!cfld) {
01611 KMessageBox::error(0,(i18n("Cannot create file `%1' in %2.\nKMail cannot start without it.").arg(acct->name()).arg(the_dimapFolderMgr->basePath())));
01612 exit(-1);
01613 }
01614 cfld->folder()->setId( acct->id() );
01615 }
01616
01617 cfld->setNoContent(true);
01618 cfld->folder()->setLabel(acct->name());
01619 cachedImapAcct = static_cast<KMAcctCachedImap*>(acct);
01620 cfld->setAccount(cachedImapAcct);
01621 cachedImapAcct->setImapFolder(cfld);
01622 cfld->close("kmkernel");
01623 }
01624 the_dimapFolderMgr->quiet( false );
01625 }
01626
01627 bool KMKernel::doSessionManagement()
01628 {
01629
01630
01631 if (kapp->isRestored()){
01632 int n = 1;
01633 while (KMMainWin::canBeRestored(n)){
01634
01635 if (KMMainWin::classNameOfToplevel(n) == "KMMainWin")
01636 (new KMMainWin)->restore(n);
01637 n++;
01638 }
01639 return true;
01640 }
01641 return false;
01642 }
01643
01644 void KMKernel::closeAllKMailWindows()
01645 {
01646 if (!KMainWindow::memberList) return;
01647 QPtrListIterator<KMainWindow> it(*KMainWindow::memberList);
01648 KMainWindow *window = 0;
01649 while ((window = it.current()) != 0) {
01650 ++it;
01651 if (window->isA("KMMainWindow") ||
01652 window->inherits("KMail::SecondaryWindow"))
01653 window->close( true );
01654 }
01655 }
01656
01657 void KMKernel::cleanup(void)
01658 {
01659 dumpDeadLetters();
01660 the_shuttingDown = true;
01661 closeAllKMailWindows();
01662
01663 delete the_acctMgr;
01664 the_acctMgr = 0;
01665 delete the_filterMgr;
01666 the_filterMgr = 0;
01667 delete the_msgSender;
01668 the_msgSender = 0;
01669 delete the_filterActionDict;
01670 the_filterActionDict = 0;
01671 delete the_undoStack;
01672 the_undoStack = 0;
01673 delete the_popFilterMgr;
01674 the_popFilterMgr = 0;
01675
01676 #if 0
01677 delete the_weaver;
01678 the_weaver = 0;
01679 #endif
01680
01681 KConfig* config = KMKernel::config();
01682 KConfigGroupSaver saver(config, "General");
01683
01684 if (the_trashFolder) {
01685
01686 the_trashFolder->close("kmkernel", true);
01687
01688 if (config->readBoolEntry("empty-trash-on-exit", true))
01689 {
01690 if ( the_trashFolder->count( true ) > 0 )
01691 the_trashFolder->expunge();
01692 }
01693 }
01694
01695 mICalIface->cleanup();
01696
01697 QValueList<QGuardedPtr<KMFolder> > folders;
01698 QStringList strList;
01699 KMFolder *folder;
01700 the_folderMgr->createFolderList(&strList, &folders);
01701 for (int i = 0; folders.at(i) != folders.end(); i++)
01702 {
01703 folder = *folders.at(i);
01704 if (!folder || folder->isDir()) continue;
01705 folder->close("kmkernel", true);
01706 }
01707 strList.clear();
01708 folders.clear();
01709 the_searchFolderMgr->createFolderList(&strList, &folders);
01710 for (int i = 0; folders.at(i) != folders.end(); i++)
01711 {
01712 folder = *folders.at(i);
01713 if (!folder || folder->isDir()) continue;
01714 folder->close("kmkernel", true);
01715 }
01716
01717 delete the_msgIndex;
01718 the_msgIndex = 0;
01719 delete the_folderMgr;
01720 the_folderMgr = 0;
01721 delete the_imapFolderMgr;
01722 the_imapFolderMgr = 0;
01723 delete the_dimapFolderMgr;
01724 the_dimapFolderMgr = 0;
01725 delete the_searchFolderMgr;
01726 the_searchFolderMgr = 0;
01727 delete mConfigureDialog;
01728 mConfigureDialog = 0;
01729
01730
01731 mWin = 0;
01732
01733 if ( RecentAddresses::exists() )
01734 RecentAddresses::self( config )->save( config );
01735 config->sync();
01736 }
01737
01738 bool KMKernel::transferMail( QString & destinationDir )
01739 {
01740 QString dir;
01741
01742
01743 QFileInfo fi( QDir::home(), "KMail" );
01744 if ( fi.exists() && fi.isDir() ) {
01745 dir = QDir::homeDirPath() + "/KMail";
01746
01747 destinationDir = dir;
01748 return true;
01749 }
01750
01751 if ( dir.isEmpty() ) {
01752
01753 fi.setFile( QDir::home(), "Mail" );
01754 if ( fi.exists() && fi.isDir() &&
01755 QFile::exists( QDir::homeDirPath() + "/Mail/.inbox.index" ) ) {
01756
01757
01758 dir = QDir::homeDirPath() + "/Mail";
01759
01760 destinationDir = dir;
01761 return true;
01762 }
01763 }
01764
01765 if ( dir.isEmpty() ) {
01766 return true;
01767 }
01768
01769 #if 0
01770
01771 const QString kmailName = kapp->aboutData()->programName();
01772 QString msg;
01773 if ( KIO::NetAccess::exists( destinationDir, true, 0 ) ) {
01774
01775
01776 msg = i18n( "%1-%3 is the application name, %4-%7 are folder path",
01777 "<qt>The <i>%4</i> folder exists. "
01778 "%1 now uses the <i>%5</i> folder for "
01779 "its messages.<p>"
01780 "%2 can move the contents of <i>%6<i> into this folder for "
01781 "you, though this may replace any existing files with "
01782 "the same name in <i>%7</i>.<p>"
01783 "<strong>Would you like %3 to move the mail "
01784 "files now?</strong></qt>" )
01785 .arg( kmailName, kmailName, kmailName )
01786 .arg( dir, destinationDir, dir, destinationDir );
01787 } else {
01788 msg = i18n( "%1-%3 is the application name, %4-%6 are folder path",
01789 "<qt>The <i>%4</i> folder exists. "
01790 "%1 now uses the <i>%5</i> folder for "
01791 "its messages. %2 can move the contents of <i>%6</i> into "
01792 "this folder for you.<p>"
01793 "<strong>Would you like %3 to move the mail "
01794 "files now?</strong></qt>" )
01795 .arg( kmailName, kmailName, kmailName )
01796 .arg( dir, destinationDir, dir );
01797 }
01798 QString title = i18n( "Migrate Mail Files?" );
01799 QString buttonText = i18n( "Move" );
01800
01801 if ( KMessageBox::questionYesNo( 0, msg, title, buttonText, i18n("Do Not Move") ) ==
01802 KMessageBox::No ) {
01803 destinationDir = dir;
01804 return true;
01805 }
01806
01807 if ( !KIO::NetAccess::move( dir, destinationDir ) ) {
01808 kdDebug(5006) << k_funcinfo << "Moving " << dir << " to " << destinationDir << " failed: " << KIO::NetAccess::lastErrorString() << endl;
01809 kdDebug(5006) << k_funcinfo << "Deleting " << destinationDir << endl;
01810 KIO::NetAccess::del( destinationDir, 0 );
01811 destinationDir = dir;
01812 return false;
01813 }
01814 #endif
01815
01816 return true;
01817 }
01818
01819
01820 void KMKernel::ungrabPtrKb(void)
01821 {
01822 if(!KMainWindow::memberList) return;
01823 QWidget* widg = KMainWindow::memberList->first();
01824 Display* dpy;
01825
01826 if (!widg) return;
01827 dpy = widg->x11Display();
01828 XUngrabKeyboard(dpy, CurrentTime);
01829 XUngrabPointer(dpy, CurrentTime);
01830 }
01831
01832
01833
01834 void KMKernel::kmailMsgHandler(QtMsgType aType, const char* aMsg)
01835 {
01836 static int recurse=-1;
01837
01838 recurse++;
01839
01840 switch (aType)
01841 {
01842 case QtDebugMsg:
01843 case QtWarningMsg:
01844 kdDebug(5006) << aMsg << endl;
01845 break;
01846
01847 case QtFatalMsg:
01848 ungrabPtrKb();
01849 kdDebug(5006) << kapp->caption() << " fatal error "
01850 << aMsg << endl;
01851 KMessageBox::error(0, aMsg);
01852 abort();
01853 }
01854
01855 recurse--;
01856 }
01857
01858
01859 void KMKernel::dumpDeadLetters()
01860 {
01861 if ( shuttingDown() )
01862 return;
01863
01864
01865 if ( !KMainWindow::memberList )
01866 return;
01867
01868 for ( QPtrListIterator<KMainWindow> it(*KMainWindow::memberList) ; it.current() != 0; ++it )
01869 if ( KMail::Composer * win = ::qt_cast<KMail::Composer*>( it.current() ) )
01870 win->autoSaveMessage();
01871 }
01872
01873
01874
01875 void KMKernel::action(bool mailto, bool check, const QString &to,
01876 const QString &cc, const QString &bcc,
01877 const QString &subj, const QString &body,
01878 const KURL &messageFile,
01879 const KURL::List &attachURLs,
01880 const QCStringList &customHeaders)
01881 {
01882 if ( mailto )
01883 openComposer( to, cc, bcc, subj, body, 0, messageFile, attachURLs, customHeaders );
01884 else
01885 openReader( check );
01886
01887 if ( check )
01888 checkMail();
01889
01890 }
01891
01892 void KMKernel::byteArrayToRemoteFile(const QByteArray &aData, const KURL &aURL,
01893 bool overwrite)
01894 {
01895
01896 KIO::Job *job = KIO::put(aURL, -1, overwrite, false);
01897 putData pd; pd.url = aURL; pd.data = aData; pd.offset = 0;
01898 mPutJobs.insert(job, pd);
01899 connect(job, SIGNAL(dataReq(KIO::Job*,QByteArray&)),
01900 SLOT(slotDataReq(KIO::Job*,QByteArray&)));
01901 connect(job, SIGNAL(result(KIO::Job*)),
01902 SLOT(slotResult(KIO::Job*)));
01903 }
01904
01905 void KMKernel::slotDataReq(KIO::Job *job, QByteArray &data)
01906 {
01907
01908 const int MAX_CHUNK_SIZE = 64*1024;
01909 QMap<KIO::Job*, putData>::Iterator it = mPutJobs.find(job);
01910 assert(it != mPutJobs.end());
01911 int remainingBytes = (*it).data.size() - (*it).offset;
01912 if( remainingBytes > MAX_CHUNK_SIZE )
01913 {
01914
01915 data.duplicate( (*it).data.data() + (*it).offset, MAX_CHUNK_SIZE );
01916 (*it).offset += MAX_CHUNK_SIZE;
01917
01918
01919 }
01920 else
01921 {
01922
01923 data.duplicate( (*it).data.data() + (*it).offset, remainingBytes );
01924 (*it).data = QByteArray();
01925 (*it).offset = 0;
01926
01927 }
01928 }
01929
01930 void KMKernel::slotResult(KIO::Job *job)
01931 {
01932 QMap<KIO::Job*, putData>::Iterator it = mPutJobs.find(job);
01933 assert(it != mPutJobs.end());
01934 if (job->error())
01935 {
01936 if (job->error() == KIO::ERR_FILE_ALREADY_EXIST)
01937 {
01938 if (KMessageBox::warningContinueCancel(0,
01939 i18n("File %1 exists.\nDo you want to replace it?")
01940 .arg((*it).url.prettyURL()), i18n("Save to File"), i18n("&Replace"))
01941 == KMessageBox::Continue)
01942 byteArrayToRemoteFile((*it).data, (*it).url, true);
01943 }
01944 else job->showErrorDialog();
01945 }
01946 mPutJobs.remove(it);
01947 }
01948
01949 void KMKernel::slotRequestConfigSync() {
01950
01951 KMKernel::config()->sync();
01952 }
01953
01954 void KMKernel::slotShowConfigurationDialog()
01955 {
01956 if( !mConfigureDialog ) {
01957 mConfigureDialog = new ConfigureDialog( 0, "configure", false );
01958 connect( mConfigureDialog, SIGNAL( configCommitted() ),
01959 this, SLOT( slotConfigChanged() ) );
01960 }
01961
01962 if( KMKernel::getKMMainWidget() == 0 )
01963 {
01964
01965
01966
01967 KMMainWin * win = new KMMainWin;
01968 win->show();
01969 }
01970
01971 if( mConfigureDialog->isHidden() )
01972 mConfigureDialog->show();
01973 else
01974 mConfigureDialog->raise();
01975 }
01976
01977 void KMKernel::slotConfigChanged()
01978 {
01979 readConfig();
01980 emit configChanged();
01981 }
01982
01983
01984
01985 QString KMKernel::localDataPath()
01986 {
01987 return locateLocal( "data", "kmail/" );
01988 }
01989
01990
01991
01992 bool KMKernel::haveSystemTrayApplet()
01993 {
01994 return !systemTrayApplets.isEmpty();
01995 }
01996
01997 bool KMKernel::registerSystemTrayApplet( const KSystemTray* applet )
01998 {
01999 if ( systemTrayApplets.findIndex( applet ) == -1 ) {
02000 systemTrayApplets.append( applet );
02001 return true;
02002 }
02003 else
02004 return false;
02005 }
02006
02007 bool KMKernel::unregisterSystemTrayApplet( const KSystemTray* applet )
02008 {
02009 QValueList<const KSystemTray*>::iterator it =
02010 systemTrayApplets.find( applet );
02011 if ( it != systemTrayApplets.end() ) {
02012 systemTrayApplets.remove( it );
02013 return true;
02014 }
02015 else
02016 return false;
02017 }
02018
02019 void KMKernel::emergencyExit( const QString& reason )
02020 {
02021 QString mesg;
02022 if ( reason.length() == 0 ) {
02023 mesg = i18n("KMail encountered a fatal error and will terminate now");
02024 } else {
02025 mesg = i18n("KMail encountered a fatal error and will "
02026 "terminate now.\nThe error was:\n%1").arg( reason );
02027 }
02028
02029 kdWarning() << mesg << endl;
02030 KNotifyClient::userEvent( 0, "<qt>"+mesg+"</qt>", KNotifyClient::Messagebox, KNotifyClient::Error );
02031
02032 ::exit(1);
02033 }
02034
02038 bool KMKernel::folderIsDraftOrOutbox(const KMFolder * folder)
02039 {
02040 assert( folder );
02041 if ( folder == the_outboxFolder )
02042 return true;
02043 return folderIsDrafts( folder );
02044 }
02045
02046 bool KMKernel::folderIsDrafts(const KMFolder * folder)
02047 {
02048 assert( folder );
02049 if ( folder == the_draftsFolder )
02050 return true;
02051
02052 QString idString = folder->idString();
02053 if ( idString.isEmpty() )
02054 return false;
02055
02056
02057 const KPIM::IdentityManager *im = identityManager();
02058 for ( KPIM::IdentityManager::ConstIterator it=im->begin(); it != im->end(); ++it )
02059 if ( (*it).drafts() == idString )
02060 return true;
02061 return false;
02062 }
02063
02064 bool KMKernel::folderIsTemplates( const KMFolder *folder )
02065 {
02066 assert( folder );
02067 if ( folder == the_templatesFolder )
02068 return true;
02069
02070 QString idString = folder->idString();
02071 if ( idString.isEmpty() )
02072 return false;
02073
02074
02075 const KPIM::IdentityManager *im = identityManager();
02076 for ( KPIM::IdentityManager::ConstIterator it=im->begin(); it != im->end(); ++it )
02077 if ( (*it).templates() == idString )
02078 return true;
02079 return false;
02080 }
02081
02082 bool KMKernel::folderIsTrash(KMFolder * folder)
02083 {
02084 assert(folder);
02085 if (folder == the_trashFolder) return true;
02086 QStringList actList = acctMgr()->getAccounts();
02087 QStringList::Iterator it( actList.begin() );
02088 for( ; it != actList.end() ; ++it ) {
02089 KMAccount* act = acctMgr()->findByName( *it );
02090 if ( act && ( act->trash() == folder->idString() ) )
02091 return true;
02092 }
02093 return false;
02094 }
02095
02096 bool KMKernel::folderIsSentMailFolder( const KMFolder * folder )
02097 {
02098 assert( folder );
02099 if ( folder == the_sentFolder )
02100 return true;
02101
02102 QString idString = folder->idString();
02103 if ( idString.isEmpty() ) return false;
02104
02105
02106 const KPIM::IdentityManager * im = identityManager();
02107 for( KPIM::IdentityManager::ConstIterator it = im->begin(); it != im->end(); ++it )
02108 if ( (*it).fcc() == idString ) return true;
02109 return false;
02110 }
02111
02112 KPIM::IdentityManager * KMKernel::identityManager() {
02113 if ( !mIdentityManager ) {
02114 kdDebug(5006) << "instantating KPIM::IdentityManager" << endl;
02115 mIdentityManager = new KPIM::IdentityManager( false, this, "mIdentityManager" );
02116 }
02117 return mIdentityManager;
02118 }
02119
02120 KMMsgIndex *KMKernel::msgIndex()
02121 {
02122 return the_msgIndex;
02123 }
02124
02125 KMainWindow* KMKernel::mainWin()
02126 {
02127 if (KMainWindow::memberList) {
02128 KMainWindow *kmWin = 0;
02129
02130
02131 for (kmWin = KMainWindow::memberList->first(); kmWin;
02132 kmWin = KMainWindow::memberList->next())
02133 if (kmWin->isA("KMMainWin"))
02134 return kmWin;
02135
02136
02137
02138
02139 kmWin = KMainWindow::memberList->first();
02140 if ( kmWin )
02141 return kmWin;
02142 }
02143
02144
02145
02146
02147
02148 mWin = new KMMainWin;
02149 return mWin;
02150 }
02151
02152
02156 void KMKernel::slotEmptyTrash()
02157 {
02158 QString title = i18n("Empty Trash");
02159 QString text = i18n("Are you sure you want to empty the trash folders of all accounts?");
02160 if (KMessageBox::warningContinueCancel(0, text, title,
02161 KStdGuiItem::cont(), "confirm_empty_trash")
02162 != KMessageBox::Continue)
02163 {
02164 return;
02165 }
02166
02167 for (KMAccount* acct = acctMgr()->first(); acct; acct = acctMgr()->next())
02168 {
02169 KMFolder* trash = findFolderById(acct->trash());
02170 if (trash)
02171 {
02172 trash->expunge();
02173 }
02174 }
02175 }
02176
02177 KConfig* KMKernel::config()
02178 {
02179 assert(mySelf);
02180 if (!mySelf->mConfig)
02181 {
02182 mySelf->mConfig = KSharedConfig::openConfig( "kmailrc" );
02183
02184 KMail::checkConfigUpdates();
02185 }
02186 return mySelf->mConfig;
02187 }
02188
02189 KMailICalIfaceImpl& KMKernel::iCalIface()
02190 {
02191 assert( mICalIface );
02192 return *mICalIface;
02193 }
02194
02195 void KMKernel::selectFolder( QString folderPath )
02196 {
02197 kdDebug(5006)<<"Selecting a folder "<<folderPath<<endl;
02198 const QString localPrefix = "/Local";
02199 KMFolder *folder = kmkernel->folderMgr()->getFolderByURL( folderPath );
02200 if ( !folder && folderPath.startsWith( localPrefix ) )
02201 folder = the_folderMgr->getFolderByURL( folderPath.mid( localPrefix.length() ) );
02202 if ( !folder )
02203 folder = kmkernel->imapFolderMgr()->getFolderByURL( folderPath );
02204 if ( !folder )
02205 folder = kmkernel->dimapFolderMgr()->getFolderByURL( folderPath );
02206 Q_ASSERT( folder );
02207
02208 KMMainWidget *widget = getKMMainWidget();
02209 Q_ASSERT( widget );
02210 if ( !widget )
02211 return;
02212
02213 KMFolderTree *tree = widget->folderTree();
02214 tree->doFolderSelected( tree->indexOfFolder( folder ) );
02215 tree->ensureItemVisible( tree->indexOfFolder( folder ) );
02216 }
02217
02218 KMMainWidget *KMKernel::getKMMainWidget()
02219 {
02220
02221 QWidgetList *l = kapp->topLevelWidgets();
02222 QWidgetListIt it( *l );
02223 QWidget *wid;
02224
02225 while ( ( wid = it.current() ) != 0 ) {
02226 ++it;
02227 QObjectList *l2 = wid->topLevelWidget()->queryList( "KMMainWidget" );
02228 if (l2 && l2->first()) {
02229 KMMainWidget* kmmw = dynamic_cast<KMMainWidget *>( l2->first() );
02230 Q_ASSERT( kmmw );
02231 delete l2;
02232 delete l;
02233 return kmmw;
02234 }
02235 delete l2;
02236 }
02237 delete l;
02238 return 0;
02239 }
02240
02241 void KMKernel::slotRunBackgroundTasks()
02242 {
02243
02244
02245 KConfigGroup generalGroup( config(), "General" );
02246
02247 if ( generalGroup.readBoolEntry( "auto-expiring", true ) ) {
02248 the_folderMgr->expireAllFolders( false );
02249 the_imapFolderMgr->expireAllFolders( false );
02250 the_dimapFolderMgr->expireAllFolders( false );
02251
02252 }
02253
02254 if ( generalGroup.readBoolEntry( "auto-compaction", true ) ) {
02255 the_folderMgr->compactAllFolders( false );
02256
02257 the_dimapFolderMgr->compactAllFolders( false );
02258
02259 }
02260
02261 #ifdef DEBUG_SCHEDULER // for debugging, see jobscheduler.h
02262 mBackgroundTasksTimer->start( 60 * 1000, true );
02263 #else
02264 mBackgroundTasksTimer->start( 4 * 60 * 60 * 1000, true );
02265 #endif
02266
02267 }
02268
02269 void KMKernel::expireAllFoldersNow()
02270 {
02271 the_folderMgr->expireAllFolders( true );
02272 the_imapFolderMgr->expireAllFolders( true );
02273 the_dimapFolderMgr->expireAllFolders( true );
02274 }
02275
02276 void KMKernel::compactAllFolders()
02277 {
02278 the_folderMgr->compactAllFolders( true );
02279
02280 the_dimapFolderMgr->compactAllFolders( true );
02281 }
02282
02283 KMFolder* KMKernel::findFolderById( const QString& idString )
02284 {
02285 KMFolder * folder = the_folderMgr->findIdString( idString );
02286 if ( !folder )
02287 folder = the_imapFolderMgr->findIdString( idString );
02288 if ( !folder )
02289 folder = the_dimapFolderMgr->findIdString( idString );
02290 if ( !folder )
02291 folder = the_searchFolderMgr->findIdString( idString );
02292 return folder;
02293 }
02294
02295 ::KIMProxy* KMKernel::imProxy()
02296 {
02297 return KIMProxy::instance( kapp->dcopClient() );
02298 }
02299
02300 void KMKernel::enableMailCheck()
02301 {
02302 mMailCheckAborted = false;
02303 }
02304
02305 bool KMKernel::mailCheckAborted() const
02306 {
02307 return mMailCheckAborted;
02308 }
02309
02310 void KMKernel::abortMailCheck()
02311 {
02312 mMailCheckAborted = true;
02313 }
02314
02315 bool KMKernel::canQueryClose()
02316 {
02317 if ( KMMainWidget::mainWidgetList() &&
02318 KMMainWidget::mainWidgetList()->count() > 1 )
02319 return true;
02320 KMMainWidget *widget = getKMMainWidget();
02321 if ( !widget )
02322 return true;
02323 KMSystemTray* systray = widget->systray();
02324 if ( !systray || GlobalSettings::closeDespiteSystemTray() )
02325 return true;
02326 if ( systray->mode() == GlobalSettings::EnumSystemTrayPolicy::ShowAlways ) {
02327 systray->hideKMail();
02328 return false;
02329 } else if ( systray->mode() == GlobalSettings::EnumSystemTrayPolicy::ShowOnUnread ) {
02330 systray->show();
02331 systray->hideKMail();
02332 return false;
02333 }
02334 return true;
02335 }
02336
02337 void KMKernel::messageCountChanged()
02338 {
02339 mTimeOfLastMessageCountChange = ::time( 0 );
02340 }
02341
02342 int KMKernel::timeOfLastMessageCountChange() const
02343 {
02344 return mTimeOfLastMessageCountChange;
02345 }
02346
02347 Wallet *KMKernel::wallet() {
02348 static bool walletOpenFailed = false;
02349 if ( mWallet && mWallet->isOpen() )
02350 return mWallet;
02351
02352 if ( !Wallet::isEnabled() || walletOpenFailed )
02353 return 0;
02354
02355
02356 WId window = 0;
02357 if ( qApp->activeWindow() )
02358 window = qApp->activeWindow()->winId();
02359 else if ( getKMMainWidget() )
02360 window = getKMMainWidget()->topLevelWidget()->winId();
02361
02362 delete mWallet;
02363 mWallet = Wallet::openWallet( Wallet::NetworkWallet(), window );
02364
02365 if ( !mWallet ) {
02366 walletOpenFailed = true;
02367 return 0;
02368 }
02369
02370 if ( !mWallet->hasFolder( "kmail" ) )
02371 mWallet->createFolder( "kmail" );
02372 mWallet->setFolder( "kmail" );
02373 return mWallet;
02374 }
02375
02376 QValueList< QGuardedPtr<KMFolder> > KMKernel::allFolders()
02377 {
02378 QStringList names;
02379 QValueList<QGuardedPtr<KMFolder> > folders;
02380 folderMgr()->createFolderList(&names, &folders);
02381 imapFolderMgr()->createFolderList(&names, &folders);
02382 dimapFolderMgr()->createFolderList(&names, &folders);
02383 searchFolderMgr()->createFolderList(&names, &folders);
02384
02385 return folders;
02386 }
02387
02388 KMFolder *KMKernel::currentFolder() {
02389 KMMainWidget *widget = getKMMainWidget();
02390 KMFolder *folder = 0;
02391 if ( widget && widget->folderTree() ) {
02392 folder = widget->folderTree()->currentFolder();
02393 }
02394 return folder;
02395 }
02396
02397
02398
02399 KMail::MessageSender * KMKernel::msgSender() { return the_msgSender; }
02400
02401 #include "kmkernel.moc"