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