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