kmkernel.cpp
00001 /* -*- mode: C++; c-file-style: "gnu" -*- */ 00002 #ifdef HAVE_CONFIG_H 00003 #include <config.h> 00004 #endif 00005 00006 #include "config.h" 00007 #include "kmkernel.h" 00008 00009 #include <weaver.h> 00010 #include <weaverlogger.h> 00011 00012 #include "globalsettings.h" 00013 #include "broadcaststatus.h" 00014 using KPIM::BroadcastStatus; 00015 #include "kmstartup.h" 00016 #include "index.h" 00017 #include "kmmainwin.h" 00018 #include "composer.h" 00019 #include "kmmsgpart.h" 00020 #include "kmreadermainwin.h" 00021 #include "kmfoldermgr.h" 00022 #include "kmfoldercachedimap.h" 00023 #include "kmacctcachedimap.h" 00024 #include "kmfiltermgr.h" 00025 #include "kmfilteraction.h" 00026 #include "kmheaders.h" 00027 #define REALLY_WANT_KMSENDER 00028 #include "kmsender.h" 00029 #undef REALLY_WANT_KMSENDER 00030 #include "undostack.h" 00031 #include "accountmanager.h" 00032 using KMail::AccountManager; 00033 #include <libtdepim/tdefileio.h> 00034 #include "kmversion.h" 00035 #include "kmreaderwin.h" 00036 #include "kmmainwidget.h" 00037 #include "kmfoldertree.h" 00038 #include "recentaddresses.h" 00039 using TDERecentAddress::RecentAddresses; 00040 #include "kmmsgdict.h" 00041 #include <libkpimidentities/identity.h> 00042 #include <libkpimidentities/identitymanager.h> 00043 #include "configuredialog.h" 00044 #include "kmcommands.h" 00045 #include "kmsystemtray.h" 00046 #include "transportmanager.h" 00047 #include "importarchivedialog.h" 00048 #include <mimelib/enum.h> 00049 00050 #include <twin.h> 00051 #include "kmailicalifaceimpl.h" 00052 #include "mailserviceimpl.h" 00053 using KMail::MailServiceImpl; 00054 #include "mailcomposerIface.h" 00055 #include "folderIface.h" 00056 using KMail::FolderIface; 00057 #include "jobscheduler.h" 00058 #include "templateparser.h" 00059 00060 #include <tdeapplication.h> 00061 #include <tdemessagebox.h> 00062 #include <knotifyclient.h> 00063 #include <kstaticdeleter.h> 00064 #include <kstandarddirs.h> 00065 #include <tdeconfig.h> 00066 #include <kprogress.h> 00067 #include <kpassivepopup.h> 00068 #include <dcopclient.h> 00069 #include <ksystemtray.h> 00070 #include <kpgp.h> 00071 #include <kdebug.h> 00072 #include <tdeio/netaccess.h> 00073 #include <tdewallet.h> 00074 using TDEWallet::Wallet; 00075 #include "actionscheduler.h" 00076 00077 #include <qutf7codec.h> 00078 #include <tqvbox.h> 00079 #include <tqdir.h> 00080 #include <tqwidgetlist.h> 00081 #include <tqobjectlist.h> 00082 00083 #include <sys/types.h> 00084 #include <dirent.h> 00085 #include <sys/stat.h> 00086 #include <unistd.h> 00087 #include <stdio.h> 00088 #include <stdlib.h> 00089 #include <assert.h> 00090 00091 #include <X11/Xlib.h> 00092 #include <fixx11h.h> 00093 #include <tdecmdlineargs.h> 00094 #include <tdestartupinfo.h> 00095 00096 KMKernel *KMKernel::mySelf = 0; 00097 static bool s_askingToGoOnline = false; 00098 00099 /********************************************************************/ 00100 /* Constructor and destructor */ 00101 /********************************************************************/ 00102 KMKernel::KMKernel (TQObject *parent, const char *name) : 00103 DCOPObject("KMailIface"), TQObject(parent, name), 00104 mIdentityManager(0), mConfigureDialog(0), 00105 mContextMenuShown( false ), mWallet( 0 ) 00106 { 00107 kdDebug(5006) << "KMKernel::KMKernel" << endl; 00108 mySelf = this; 00109 the_startingUp = true; 00110 closed_by_user = true; 00111 the_firstInstance = true; 00112 the_msgIndex = 0; 00113 00114 the_inboxFolder = 0; 00115 the_outboxFolder = 0; 00116 the_sentFolder = 0; 00117 the_trashFolder = 0; 00118 the_draftsFolder = 0; 00119 the_templatesFolder = 0; 00120 00121 the_folderMgr = 0; 00122 the_imapFolderMgr = 0; 00123 the_dimapFolderMgr = 0; 00124 the_searchFolderMgr = 0; 00125 the_undoStack = 0; 00126 the_acctMgr = 0; 00127 the_filterMgr = 0; 00128 the_popFilterMgr = 0; 00129 the_filterActionDict = 0; 00130 the_msgSender = 0; 00131 mWin = 0; 00132 mMailCheckAborted = false; 00133 00134 // make sure that we check for config updates before doing anything else 00135 KMKernel::config(); 00136 // this shares the kmailrc parsing too (via TDESharedConfig), and reads values from it 00137 // so better do it here, than in some code where changing the group of config() 00138 // would be unexpected 00139 GlobalSettings::self(); 00140 00141 // Set up DCOP interface 00142 mICalIface = new KMailICalIfaceImpl(); 00143 00144 mJobScheduler = new JobScheduler( this ); 00145 00146 mXmlGuiInstance = 0; 00147 00148 new Kpgp::Module(); 00149 00150 // register our own (libtdenetwork) utf-7 codec as long as TQt 00151 // doesn't have it's own: 00152 if ( !TQTextCodec::codecForName("utf-7") ) { 00153 kdDebug(5006) << "No TQt-native utf-7 codec found; registering TQUtf7Codec from libtdenetwork" << endl; 00154 (void) new TQUtf7Codec(); 00155 } 00156 00157 // In the case of Japan. Japanese locale name is "eucjp" but 00158 // The Japanese mail systems normally used "iso-2022-jp" of locale name. 00159 // We want to change locale name from eucjp to iso-2022-jp at KMail only. 00160 if ( TQCString(TQTextCodec::codecForLocale()->name()).lower() == "eucjp" ) 00161 { 00162 netCodec = TQTextCodec::codecForName("jis7"); 00163 // TQTextCodec *cdc = TQTextCodec::codecForName("jis7"); 00164 // TQTextCodec::setCodecForLocale(cdc); 00165 // TDEGlobal::locale()->setEncoding(cdc->mibEnum()); 00166 } else { 00167 netCodec = TQTextCodec::codecForLocale(); 00168 } 00169 mMailService = new MailServiceImpl(); 00170 00171 connectDCOPSignal( 0, 0, "kmailSelectFolder(TQString)", 00172 "selectFolder(TQString)", false ); 00173 00174 #ifdef __TDE_HAVE_TDEHWLIB 00175 mNetworkManager = TDEGlobal::networkManager(); 00176 if (mNetworkManager) { 00177 connect( mNetworkManager, TQT_SIGNAL( networkDeviceStateChanged( TDENetworkConnectionStatus::TDENetworkConnectionStatus, TDENetworkConnectionStatus::TDENetworkConnectionStatus, TQString ) ), 00178 this, TQT_SLOT( slotNetworkStateChanged( TDENetworkConnectionStatus::TDENetworkConnectionStatus, TDENetworkConnectionStatus::TDENetworkConnectionStatus, TQString ) ) ); 00179 if (networkStateConnected()) { 00180 resumeNetworkJobs(); 00181 } 00182 else { 00183 stopNetworkJobs(); 00184 } 00185 } 00186 #endif 00187 } 00188 00189 KMKernel::~KMKernel () 00190 { 00191 TQMap<TDEIO::Job*, putData>::Iterator it = mPutJobs.begin(); 00192 while ( it != mPutJobs.end() ) 00193 { 00194 TDEIO::Job *job = it.key(); 00195 mPutJobs.remove( it ); 00196 job->kill(); 00197 it = mPutJobs.begin(); 00198 } 00199 00200 delete mICalIface; 00201 mICalIface = 0; 00202 delete mMailService; 00203 mMailService = 0; 00204 00205 GlobalSettings::self()->writeConfig(); 00206 delete mWallet; 00207 mWallet = 0; 00208 mySelf = 0; 00209 kdDebug(5006) << "KMKernel::~KMKernel" << endl; 00210 } 00211 00212 bool KMKernel::handleCommandLine( bool noArgsOpensReader ) 00213 { 00214 TQString to, cc, bcc, subj, body; 00215 QCStringList customHeaders; 00216 KURL messageFile; 00217 KURL::List attachURLs; 00218 bool mailto = false; 00219 bool checkMail = false; 00220 bool viewOnly = false; 00221 bool calledWithSession = false; // for ignoring '-session foo' 00222 00223 // process args: 00224 TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs(); 00225 if (!args->getOption("subject").isNull()) 00226 { 00227 subj = TQString::fromLocal8Bit(args->getOption("subject")); 00228 // if kmail is called with 'kmail -session abc' then this doesn't mean 00229 // that the user wants to send a message with subject "ession" but 00230 // (most likely) that the user clicked on KMail's system tray applet 00231 // which results in KMKernel::raise() calling "kmail kmail newInstance" 00232 // via dcop which apparently executes the application with the original 00233 // command line arguments and those include "-session ..." if 00234 // kmail/kontact was restored by session management 00235 if ( subj == "ession" ) { 00236 subj = TQString(); 00237 calledWithSession = true; 00238 } 00239 else 00240 mailto = true; 00241 } 00242 00243 if (!args->getOption("cc").isNull()) 00244 { 00245 mailto = true; 00246 cc = TQString::fromLocal8Bit(args->getOption("cc")); 00247 } 00248 00249 if (!args->getOption("bcc").isNull()) 00250 { 00251 mailto = true; 00252 bcc = TQString::fromLocal8Bit(args->getOption("bcc")); 00253 } 00254 00255 if (!args->getOption("msg").isNull()) 00256 { 00257 mailto = true; 00258 messageFile.setPath( TQString::fromLocal8Bit(args->getOption("msg")) ); 00259 } 00260 00261 if (!args->getOption("body").isNull()) 00262 { 00263 mailto = true; 00264 body = TQString::fromLocal8Bit(args->getOption("body")); 00265 } 00266 00267 QCStringList attachList = args->getOptionList("attach"); 00268 if (!attachList.isEmpty()) 00269 { 00270 mailto = true; 00271 for ( QCStringList::Iterator it = attachList.begin() ; it != attachList.end() ; ++it ) 00272 if ( !(*it).isEmpty() ) 00273 attachURLs += KURL( TQString::fromLocal8Bit( *it ) ); 00274 } 00275 00276 customHeaders = args->getOptionList("header"); 00277 00278 if (args->isSet("composer")) 00279 mailto = true; 00280 00281 if (args->isSet("check")) 00282 checkMail = true; 00283 00284 if ( !args->getOption( "view" ).isNull() ) { 00285 viewOnly = true; 00286 const TQString filename = 00287 TQString::fromLocal8Bit( args->getOption( "view" ) ); 00288 messageFile = KURL::fromPathOrURL( filename ); 00289 if ( !messageFile.isValid() ) { 00290 messageFile = KURL(); 00291 messageFile.setPath( filename ); 00292 } 00293 } 00294 00295 if ( !calledWithSession ) { 00296 // only read additional command line arguments if kmail/kontact is 00297 // not called with "-session foo" 00298 for(int i= 0; i < args->count(); i++) 00299 { 00300 if (strncasecmp(args->arg(i),"mailto:",7)==0) 00301 to += args->url(i).path() + ", "; 00302 else { 00303 TQString tmpArg = TQString::fromLocal8Bit( args->arg(i) ); 00304 KURL url( tmpArg ); 00305 if ( url.isValid() ) 00306 attachURLs += url; 00307 else 00308 to += tmpArg + ", "; 00309 } 00310 mailto = true; 00311 } 00312 if ( !to.isEmpty() ) { 00313 // cut off the superfluous trailing ", " 00314 to.truncate( to.length() - 2 ); 00315 } 00316 } 00317 00318 if ( !calledWithSession ) 00319 args->clear(); 00320 00321 if ( !noArgsOpensReader && !mailto && !checkMail && !viewOnly ) 00322 return false; 00323 00324 if ( viewOnly ) 00325 viewMessage( messageFile ); 00326 else 00327 action( mailto, checkMail, to, cc, bcc, subj, body, messageFile, 00328 attachURLs, customHeaders ); 00329 return true; 00330 } 00331 00332 /********************************************************************/ 00333 /* DCOP-callable, and command line actions */ 00334 /********************************************************************/ 00335 void KMKernel::checkMail () //might create a new reader but won't show!! 00336 { 00337 if ( !kmkernel->askToGoOnline() ) 00338 return; 00339 kmkernel->acctMgr()->checkMail(false); 00340 } 00341 00342 TQStringList KMKernel::accounts() 00343 { 00344 if( kmkernel->acctMgr() ) 00345 return kmkernel->acctMgr()->getAccounts(); 00346 return TQStringList(); 00347 } 00348 00349 void KMKernel::checkAccount (const TQString &account) //might create a new reader but won't show!! 00350 { 00351 kdDebug(5006) << "KMKernel::checkMail called" << endl; 00352 00353 KMAccount* acct = kmkernel->acctMgr()->findByName(account); 00354 if (acct) 00355 kmkernel->acctMgr()->singleCheckMail(acct, false); 00356 } 00357 00358 void KMKernel::loadProfile( const TQString& ) 00359 { 00360 } 00361 00362 void KMKernel::saveToProfile( const TQString& ) const 00363 { 00364 } 00365 00366 void KMKernel::openReader( bool onlyCheck ) 00367 { 00368 mWin = 0; 00369 TDEMainWindow *ktmw = 0; 00370 kdDebug(5006) << "KMKernel::openReader called" << endl; 00371 00372 if (TDEMainWindow::memberList) 00373 for (ktmw = TDEMainWindow::memberList->first(); ktmw; 00374 ktmw = TDEMainWindow::memberList->next()) 00375 if (ktmw->isA("KMMainWin")) 00376 break; 00377 00378 bool activate; 00379 if (ktmw) { 00380 mWin = (KMMainWin *) ktmw; 00381 activate = !onlyCheck; // existing window: only activate if not --check 00382 if ( activate ) 00383 mWin->show(); 00384 } else { 00385 mWin = new KMMainWin; 00386 mWin->show(); 00387 activate = false; // new window: no explicit activation (#73591) 00388 } 00389 00390 if ( activate ) { 00391 // Activate window - doing this instead of KWin::activateWindow(mWin->winId()); 00392 // so that it also works when called from KMailApplication::newInstance() 00393 #if defined TQ_WS_X11 && ! defined K_WS_TQTONLY 00394 TDEStartupInfo::setNewStartupId( mWin, kapp->startupId() ); 00395 #endif 00396 } 00397 } 00398 00399 int KMKernel::openComposer (const TQString &to, const TQString &cc, 00400 const TQString &bcc, const TQString &subject, 00401 const TQString &body, int hidden, 00402 const KURL &messageFile, 00403 const KURL::List &attachURLs, 00404 const QCStringList &customHeaders) 00405 { 00406 kdDebug(5006) << "KMKernel::openComposer called" << endl; 00407 KMMessage *msg = new KMMessage; 00408 msg->initHeader(); 00409 msg->setCharset("utf-8"); 00410 // tentatively decode to, cc and bcc because invokeMailer calls us with 00411 // RFC 2047 encoded addresses in order to protect non-ASCII email addresses 00412 if (!to.isEmpty()) 00413 msg->setTo( KMMsgBase::decodeRFC2047String( to.latin1() ) ); 00414 if (!cc.isEmpty()) 00415 msg->setCc( KMMsgBase::decodeRFC2047String( cc.latin1() ) ); 00416 if (!bcc.isEmpty()) 00417 msg->setBcc( KMMsgBase::decodeRFC2047String( bcc.latin1() ) ); 00418 if (!subject.isEmpty()) msg->setSubject(subject); 00419 if (!messageFile.isEmpty() && messageFile.isLocalFile()) { 00420 TQCString str = KPIM::kFileToString( messageFile.path(), true, false ); 00421 if( !str.isEmpty() ) { 00422 msg->setBody( TQString(TQString::fromLocal8Bit( str )).utf8() ); 00423 } else { 00424 TemplateParser parser( msg, TemplateParser::NewMessage ); 00425 parser.process( NULL, NULL ); 00426 } 00427 } 00428 else if (!body.isEmpty()) 00429 { 00430 msg->setBody(body.utf8()); 00431 } 00432 else 00433 { 00434 TemplateParser parser( msg, TemplateParser::NewMessage ); 00435 parser.process( NULL, NULL ); 00436 } 00437 00438 if (!customHeaders.isEmpty()) 00439 { 00440 for ( QCStringList::ConstIterator it = customHeaders.begin() ; it != customHeaders.end() ; ++it ) 00441 if ( !(*it).isEmpty() ) 00442 { 00443 const int pos = (*it).find( ':' ); 00444 if ( pos > 0 ) 00445 { 00446 TQCString header, value; 00447 header = (*it).left( pos ).stripWhiteSpace(); 00448 value = (*it).mid( pos+1 ).stripWhiteSpace(); 00449 if ( !header.isEmpty() && !value.isEmpty() ) 00450 msg->setHeaderField( header, value ); 00451 } 00452 } 00453 } 00454 00455 KMail::Composer * cWin = KMail::makeComposer( msg ); 00456 cWin->setCharset("", true); 00457 for ( KURL::List::ConstIterator it = attachURLs.begin() ; it != attachURLs.end() ; ++it ) 00458 cWin->addAttach((*it)); 00459 if (hidden == 0) { 00460 cWin->show(); 00461 // Activate window - doing this instead of KWin::activateWindow(cWin->winId()); 00462 // so that it also works when called from KMailApplication::newInstance() 00463 #if defined TQ_WS_X11 && ! defined K_WS_TQTONLY 00464 TDEStartupInfo::setNewStartupId( cWin, kapp->startupId() ); 00465 #endif 00466 } 00467 return 1; 00468 } 00469 00470 00471 int KMKernel::openComposer (const TQString &to, const TQString &cc, 00472 const TQString &bcc, const TQString &subject, 00473 const TQString &body, int hidden, 00474 const TQString &attachName, 00475 const TQCString &attachCte, 00476 const TQCString &attachData, 00477 const TQCString &attachType, 00478 const TQCString &attachSubType, 00479 const TQCString &attachParamAttr, 00480 const TQString &attachParamValue, 00481 const TQCString &attachContDisp ) 00482 { 00483 kdDebug(5006) << "KMKernel::openComposer called (deprecated version)" << endl; 00484 00485 return openComposer ( to, cc, bcc, subject, body, hidden, 00486 attachName, attachCte, attachData, 00487 attachType, attachSubType, attachParamAttr, 00488 attachParamValue, attachContDisp, TQCString() ); 00489 } 00490 00491 int KMKernel::openComposer (const TQString &to, const TQString &cc, 00492 const TQString &bcc, const TQString &subject, 00493 const TQString &body, int hidden, 00494 const TQString &attachName, 00495 const TQCString &attachCte, 00496 const TQCString &attachData, 00497 const TQCString &attachType, 00498 const TQCString &attachSubType, 00499 const TQCString &attachParamAttr, 00500 const TQString &attachParamValue, 00501 const TQCString &attachContDisp, 00502 const TQCString &attachCharset ) 00503 { 00504 kdDebug(5006) << "KMKernel::openComposer called (deprecated version)" << endl; 00505 return openComposer ( to, cc, bcc, subject, body, hidden, 00506 attachName, attachCte, attachData, 00507 attachType, attachSubType, attachParamAttr, 00508 attachParamValue, attachContDisp, attachCharset, 0 ); 00509 } 00510 00511 int KMKernel::openComposer (const TQString &to, const TQString &cc, 00512 const TQString &bcc, const TQString &subject, 00513 const TQString &body, int hidden, 00514 const TQString &attachName, 00515 const TQCString &attachCte, 00516 const TQCString &attachData, 00517 const TQCString &attachType, 00518 const TQCString &attachSubType, 00519 const TQCString &attachParamAttr, 00520 const TQString &attachParamValue, 00521 const TQCString &attachContDisp, 00522 const TQCString &attachCharset, 00523 unsigned int identity ) 00524 { 00525 kdDebug(5006) << "KMKernel::openComposer()" << endl; 00526 00527 KMMessage *msg = new KMMessage; 00528 KMMessagePart *msgPart = 0; 00529 msg->initHeader(); 00530 msg->setCharset( "utf-8" ); 00531 if ( !cc.isEmpty() ) msg->setCc(cc); 00532 if ( !bcc.isEmpty() ) msg->setBcc(bcc); 00533 if ( !subject.isEmpty() ) msg->setSubject(subject); 00534 if ( !to.isEmpty() ) msg->setTo(to); 00535 if ( identity > 0 ) msg->setHeaderField( "X-KMail-Identity", TQString::number( identity ) ); 00536 if ( !body.isEmpty() ) { 00537 msg->setBody(body.utf8()); 00538 } else { 00539 TemplateParser parser( msg, TemplateParser::NewMessage ); 00540 parser.process( NULL, NULL ); 00541 } 00542 00543 bool iCalAutoSend = false; 00544 bool noWordWrap = false; 00545 bool isICalInvitation = false; 00546 TDEConfigGroup options( config(), "Groupware" ); 00547 if ( !attachData.isEmpty() ) { 00548 isICalInvitation = attachName == "cal.ics" && 00549 attachType == "text" && 00550 attachSubType == "calendar" && 00551 attachParamAttr == "method"; 00552 // Remove BCC from identity on ical invitations (https://intevation.de/roundup/kolab/issue474) 00553 if ( isICalInvitation && bcc.isEmpty() ) 00554 msg->setBcc( "" ); 00555 if ( isICalInvitation && 00556 GlobalSettings::self()->legacyBodyInvites() ) { 00557 // KOrganizer invitation caught and to be sent as body instead 00558 msg->setBody( attachData ); 00559 msg->setHeaderField( "Content-Type", 00560 TQString( "text/calendar; method=%1; " 00561 "charset=\"utf-8\"" ). 00562 arg( attachParamValue ) ); 00563 00564 iCalAutoSend = true; // no point in editing raw ICAL 00565 noWordWrap = true; // we shant word wrap inline invitations 00566 } else { 00567 // Just do what we're told to do 00568 msgPart = new KMMessagePart; 00569 msgPart->setName( attachName ); 00570 msgPart->setCteStr( attachCte ); 00571 msgPart->setBodyEncoded( attachData ); 00572 msgPart->setTypeStr( attachType ); 00573 msgPart->setSubtypeStr( attachSubType ); 00574 msgPart->setParameter( attachParamAttr, attachParamValue ); 00575 if( ! GlobalSettings::self()->exchangeCompatibleInvitations() ) { 00576 msgPart->setContentDisposition( attachContDisp ); 00577 } 00578 if( !attachCharset.isEmpty() && (msgPart->type() == DwMime::kTypeText) ) { 00579 // kdDebug(5006) << "KMKernel::openComposer set attachCharset to " 00580 // << attachCharset << endl; 00581 msgPart->setCharset( attachCharset ); 00582 } 00583 // Don't show the composer window, if the automatic sending is checked 00584 TDEConfigGroup options( config(), "Groupware" ); 00585 iCalAutoSend = options.readBoolEntry( "AutomaticSending", true ); 00586 } 00587 } 00588 00589 KMail::Composer * cWin = KMail::makeComposer(); 00590 cWin->setMsg( msg, !isICalInvitation /* mayAutoSign */ ); 00591 cWin->setSigningAndEncryptionDisabled( isICalInvitation 00592 && GlobalSettings::self()->legacyBodyInvites() ); 00593 cWin->setAutoDelete( true ); 00594 if( noWordWrap ) 00595 cWin->disableWordWrap(); 00596 else 00597 cWin->setCharset( "", true ); 00598 if ( msgPart ) 00599 cWin->addAttach(msgPart); 00600 00601 if ( isICalInvitation ) { 00602 cWin->disableRecipientNumberCheck(); 00603 cWin->disableForgottenAttachmentsCheck(); 00604 } 00605 00606 if ( hidden == 0 && !iCalAutoSend ) { 00607 cWin->show(); 00608 // Activate window - doing this instead of KWin::activateWindow(cWin->winId()); 00609 // so that it also works when called from KMailApplication::newInstance() 00610 #if defined TQ_WS_X11 && ! defined K_WS_TQTONLY 00611 TDEStartupInfo::setNewStartupId( cWin, kapp->startupId() ); 00612 #endif 00613 } else { 00614 cWin->setAutoDeleteWindow( true ); 00615 cWin->slotSendNow(); 00616 } 00617 00618 return 1; 00619 } 00620 00621 void KMKernel::setDefaultTransport( const TQString & transport ) 00622 { 00623 TQStringList availTransports = KMail::TransportManager::transportNames(); 00624 TQStringList::const_iterator it = availTransports.find( transport ); 00625 if ( it == availTransports.end() ) { 00626 kdWarning() << "The transport you entered is not available" << endl; 00627 return; 00628 } 00629 GlobalSettings::self()->setDefaultTransport( transport ); 00630 } 00631 00632 DCOPRef KMKernel::openComposer(const TQString &to, const TQString &cc, 00633 const TQString &bcc, const TQString &subject, 00634 const TQString &body,bool hidden) 00635 { 00636 KMMessage *msg = new KMMessage; 00637 msg->initHeader(); 00638 msg->setCharset("utf-8"); 00639 if (!cc.isEmpty()) msg->setCc(cc); 00640 if (!bcc.isEmpty()) msg->setBcc(bcc); 00641 if (!subject.isEmpty()) msg->setSubject(subject); 00642 if (!to.isEmpty()) msg->setTo(to); 00643 if (!body.isEmpty()) { 00644 msg->setBody(body.utf8()); 00645 } else { 00646 TemplateParser parser( msg, TemplateParser::NewMessage ); 00647 parser.process( NULL, NULL ); 00648 } 00649 00650 KMail::Composer * cWin = KMail::makeComposer( msg ); 00651 cWin->setCharset("", true); 00652 if (!hidden) { 00653 cWin->show(); 00654 // Activate window - doing this instead of KWin::activateWindow(cWin->winId()); 00655 // so that it also works when called from KMailApplication::newInstance() 00656 #if defined TQ_WS_X11 && ! defined K_WS_TQTONLY 00657 TDEStartupInfo::setNewStartupId( cWin, kapp->startupId() ); 00658 #endif 00659 } 00660 00661 return DCOPRef( cWin->asMailComposerIFace() ); 00662 } 00663 00664 DCOPRef KMKernel::newMessage(const TQString &to, 00665 const TQString &cc, 00666 const TQString &bcc, 00667 bool hidden, 00668 bool useFolderId, 00669 const KURL & /*messageFile*/, 00670 const KURL &attachURL) 00671 { 00672 KMail::Composer * win = 0; 00673 KMMessage *msg = new KMMessage; 00674 KMFolder *folder = NULL; 00675 uint id; 00676 00677 if ( useFolderId ) { 00678 //create message with required folder identity 00679 folder = currentFolder(); 00680 id = folder ? folder->identity() : 0; 00681 msg->initHeader( id ); 00682 } else { 00683 msg->initHeader(); 00684 } 00685 msg->setCharset("utf-8"); 00686 //set basic headers 00687 if (!to.isEmpty()) msg->setTo(to); 00688 if (!cc.isEmpty()) msg->setCc(cc); 00689 if (!bcc.isEmpty()) msg->setBcc(bcc); 00690 00691 if ( useFolderId ) { 00692 TemplateParser parser( msg, TemplateParser::NewMessage ); 00693 parser.process( NULL, folder ); 00694 win = makeComposer( msg, id ); 00695 } else { 00696 TemplateParser parser( msg, TemplateParser::NewMessage ); 00697 parser.process( NULL, folder ); 00698 win = makeComposer( msg ); 00699 } 00700 00701 //Add the attachment if we have one 00702 if(!attachURL.isEmpty() && attachURL.isValid()) { 00703 win->addAttach(attachURL); 00704 } 00705 00706 //only show window when required 00707 if(!hidden) { 00708 win->show(); 00709 } 00710 return DCOPRef( win->asMailComposerIFace() ); 00711 } 00712 00713 int KMKernel::viewMessage( const KURL & messageFile ) 00714 { 00715 KMOpenMsgCommand *openCommand = new KMOpenMsgCommand( 0, messageFile ); 00716 00717 openCommand->start(); 00718 00719 return 1; 00720 } 00721 00722 int KMKernel::sendCertificate( const TQString& to, const TQByteArray& certData ) 00723 { 00724 KMMessage *msg = new KMMessage; 00725 msg->initHeader(); 00726 msg->setCharset("utf-8"); 00727 msg->setSubject( i18n( "Certificate Signature Request" ) ); 00728 if (!to.isEmpty()) msg->setTo(to); 00729 // ### Make this message customizable via KIOSK 00730 msg->setBody( i18n( "Please create a certificate from attachment and return to sender." ).utf8() ); 00731 00732 KMail::Composer * cWin = KMail::makeComposer( msg ); 00733 cWin->setCharset("", true); 00734 cWin->slotSetAlwaysSend( true ); 00735 if (!certData.isEmpty()) { 00736 KMMessagePart *msgPart = new KMMessagePart; 00737 msgPart->setName("smime.p10"); 00738 msgPart->setCteStr("base64"); 00739 msgPart->setBodyEncodedBinary(certData); 00740 msgPart->setTypeStr("application"); 00741 msgPart->setSubtypeStr("pkcs10"); 00742 msgPart->setContentDisposition("attachment; filename=smime.p10"); 00743 cWin->addAttach(msgPart); 00744 } 00745 00746 cWin->show(); 00747 return 1; 00748 } 00749 00750 KMMsgStatus KMKernel::strToStatus(const TQString &flags) 00751 { 00752 KMMsgStatus status = 0; 00753 if (!flags.isEmpty()) { 00754 for (uint n = 0; n < flags.length() ; n++) { 00755 switch (flags[n]) { 00756 case 'N': 00757 status |= KMMsgStatusNew; 00758 break; 00759 case 'U': 00760 status |= KMMsgStatusUnread; 00761 break; 00762 case 'O': 00763 status |= KMMsgStatusOld; 00764 break; 00765 case 'R': 00766 status |= KMMsgStatusRead; 00767 break; 00768 case 'D': 00769 status |= KMMsgStatusDeleted; 00770 break; 00771 case 'A': 00772 status |= KMMsgStatusReplied; 00773 break; 00774 case 'F': 00775 status |= KMMsgStatusForwarded; 00776 break; 00777 case 'Q': 00778 status |= KMMsgStatusQueued; 00779 break; 00780 case 'K': 00781 status |= KMMsgStatusTodo; 00782 break; 00783 case 'S': 00784 status |= KMMsgStatusSent; 00785 break; 00786 case 'G': 00787 status |= KMMsgStatusFlag; 00788 break; 00789 case 'W': 00790 status |= KMMsgStatusWatched; 00791 break; 00792 case 'I': 00793 status |= KMMsgStatusIgnored; 00794 break; 00795 case 'P': 00796 status |= KMMsgStatusSpam; 00797 break; 00798 case 'H': 00799 status |= KMMsgStatusHam; 00800 break; 00801 case 'T': 00802 status |= KMMsgStatusHasAttach; 00803 break; 00804 case 'C': 00805 status |= KMMsgStatusHasNoAttach; 00806 break; 00807 default: 00808 break; 00809 } 00810 } 00811 } 00812 return status; 00813 } 00814 00815 int KMKernel::dcopAddMessage( const TQString & foldername, const TQString & msgUrlString, 00816 const TQString & MsgStatusFlags) 00817 { 00818 return dcopAddMessage(foldername, KURL(msgUrlString), MsgStatusFlags); 00819 } 00820 00821 int KMKernel::dcopAddMessage( const TQString & foldername,const KURL & msgUrl, 00822 const TQString & MsgStatusFlags) 00823 { 00824 kdDebug(5006) << "KMKernel::dcopAddMessage called" << endl; 00825 00826 if ( foldername.isEmpty() || foldername.startsWith(".")) 00827 return -1; 00828 00829 int retval; 00830 bool readFolderMsgIds = false; 00831 TQString _foldername = foldername.stripWhiteSpace(); 00832 _foldername = _foldername.replace('\\',""); //try to prevent ESCAPE Sequences 00833 00834 if ( foldername != mAddMessageLastFolder ) { 00835 mAddMessageMsgIds.clear(); 00836 readFolderMsgIds = true; 00837 mAddMessageLastFolder = foldername; 00838 } 00839 00840 if (!msgUrl.isEmpty() && msgUrl.isLocalFile()) { 00841 00842 // This is a proposed change by Daniel Andor. 00843 // He proposed to change from the fopen(blah) 00844 // to a KPIM::kFileToString(blah). 00845 // Although it assigns a TQString to a TQString, 00846 // because of the implicit sharing this poses 00847 // no memory or performance penalty. 00848 00849 const TQCString messageText = 00850 KPIM::kFileToString( msgUrl.path(), true, false ); 00851 if ( messageText.isEmpty() ) 00852 return -2; 00853 00854 KMMessage *msg = new KMMessage(); 00855 msg->fromString( messageText ); 00856 00857 if (readFolderMsgIds) { 00858 if ( foldername.contains("/")) { 00859 TQString tmp_fname = ""; 00860 KMFolder *folder = NULL; 00861 KMFolderDir *subfolder; 00862 bool root = true; 00863 00864 TQStringList subFList = TQStringList::split("/",_foldername,false); 00865 00866 for ( TQStringList::Iterator it = subFList.begin(); it != subFList.end(); ++it ) { 00867 TQString _newFolder = *it; 00868 if(_newFolder.startsWith(".")) return -1; 00869 00870 if(root) { 00871 folder = the_folderMgr->findOrCreate(*it, false); 00872 if (folder) { 00873 root = false; 00874 tmp_fname = "/" + *it; 00875 } 00876 else return -1; 00877 } else { 00878 subfolder = folder->createChildFolder(); 00879 tmp_fname += "/" + *it; 00880 if(!the_folderMgr->getFolderByURL( tmp_fname )) { 00881 folder = the_folderMgr->createFolder(*it, false, folder->folderType(), subfolder); 00882 } 00883 00884 if(!(folder = the_folderMgr->getFolderByURL( tmp_fname ))) return -1; 00885 } 00886 } 00887 00888 mAddMsgCurrentFolder = the_folderMgr->getFolderByURL( tmp_fname ); 00889 if(!folder) return -1; 00890 00891 } else { 00892 mAddMsgCurrentFolder = the_folderMgr->findOrCreate(_foldername, false); 00893 } 00894 } 00895 00896 if ( mAddMsgCurrentFolder ) { 00897 if (readFolderMsgIds) { 00898 00899 // OLD COMMENT: 00900 // Try to determine if a message already exists in 00901 // the folder. The message id that is searched for, is 00902 // the subject line + the date. This should be quite 00903 // unique. The change that a given date with a given 00904 // subject is in the folder twice is very small. 00905 // If the subject is empty, the fromStrip string 00906 // is taken. 00907 00908 // NEW COMMENT from Danny Kukawka (danny.kukawka@web.de): 00909 // subject line + the date is only unique if the following 00910 // return a correct unique value: 00911 // time_t DT = mb->date(); 00912 // TQString dt = ctime(&DT); 00913 // But if the datestring in the Header isn't RFC conform 00914 // subject line + the date isn't unique. 00915 // 00916 // The only uique headerfield is the Message-ID. In some 00917 // cases this could be empty. I then I use the 00918 // subject line + dateStr . 00919 00920 int i; 00921 00922 mAddMsgCurrentFolder->open("dcopadd"); 00923 for( i=0; i<mAddMsgCurrentFolder->count(); i++) { 00924 KMMsgBase *mb = mAddMsgCurrentFolder->getMsgBase(i); 00925 TQString id = mb->msgIdMD5(); 00926 if ( id.isEmpty() ) { 00927 id = mb->subject(); 00928 if ( id.isEmpty() ) 00929 id = mb->fromStrip(); 00930 if ( id.isEmpty() ) 00931 id = mb->toStrip(); 00932 00933 id += mb->dateStr(); 00934 } 00935 00936 //fprintf(stderr,"%s\n",(const char *) id); 00937 if ( !id.isEmpty() ) { 00938 mAddMessageMsgIds.append(id); 00939 } 00940 } 00941 mAddMsgCurrentFolder->close("dcopadd"); 00942 } 00943 00944 TQString msgId = msg->msgIdMD5(); 00945 if ( msgId.isEmpty()) { 00946 msgId = msg->subject(); 00947 if ( msgId.isEmpty() ) 00948 msgId = msg->fromStrip(); 00949 if ( msgId.isEmpty() ) 00950 msgId = msg->toStrip(); 00951 00952 msgId += msg->dateStr(); 00953 } 00954 00955 int k = mAddMessageMsgIds.findIndex( msgId ); 00956 //fprintf(stderr,"find %s = %d\n",(const char *) msgId,k); 00957 00958 if ( k == -1 ) { 00959 if ( !msgId.isEmpty() ) { 00960 mAddMessageMsgIds.append( msgId ); 00961 } 00962 00963 if ( !MsgStatusFlags.isEmpty() ) { 00964 KMMsgStatus status = strToStatus(MsgStatusFlags); 00965 if (status) msg->setStatus(status); 00966 } 00967 00968 int index; 00969 if ( mAddMsgCurrentFolder->addMsg( msg, &index ) == 0 ) { 00970 mAddMsgCurrentFolder->unGetMsg( index ); 00971 retval = 1; 00972 } else { 00973 retval =- 2; 00974 delete msg; 00975 msg = 0; 00976 } 00977 } else { 00978 //tqDebug( "duplicate: " + msgId + "; subj: " + msg->subject() + ", from: " + msgId = msg->fromStrip()); 00979 retval = -4; 00980 } 00981 } else { 00982 retval = -1; 00983 } 00984 } else { 00985 retval = -2; 00986 } 00987 return retval; 00988 } 00989 00990 void KMKernel::dcopResetAddMessage() 00991 { 00992 mAddMessageMsgIds.clear(); 00993 mAddMessageLastFolder = TQString(); 00994 } 00995 00996 int KMKernel::dcopAddMessage_fastImport( const TQString & foldername, 00997 const TQString & msgUrlString, 00998 const TQString & MsgStatusFlags) 00999 { 01000 return dcopAddMessage_fastImport(foldername, KURL(msgUrlString), MsgStatusFlags); 01001 } 01002 01003 int KMKernel::dcopAddMessage_fastImport( const TQString & foldername, 01004 const KURL & msgUrl, 01005 const TQString & MsgStatusFlags) 01006 { 01007 // Use this function to import messages without 01008 // search for already existing emails. 01009 kdDebug(5006) << "KMKernel::dcopAddMessage_fastImport called" << endl; 01010 01011 if ( foldername.isEmpty() || foldername.startsWith(".")) 01012 return -1; 01013 01014 int retval; 01015 bool createNewFolder = false; 01016 01017 TQString _foldername = foldername.stripWhiteSpace(); 01018 _foldername = _foldername.replace('\\',""); //try to prevent ESCAPE Sequences 01019 01020 if ( foldername != mAddMessageLastFolder ) { 01021 createNewFolder = true; 01022 mAddMessageLastFolder = foldername; 01023 } 01024 01025 01026 if ( !msgUrl.isEmpty() && msgUrl.isLocalFile() ) { 01027 const TQCString messageText = 01028 KPIM::kFileToString( msgUrl.path(), true, false ); 01029 if ( messageText.isEmpty() ) 01030 return -2; 01031 01032 KMMessage *msg = new KMMessage(); 01033 msg->fromString( messageText ); 01034 01035 if (createNewFolder) { 01036 if ( foldername.contains("/")) { 01037 TQString tmp_fname = ""; 01038 KMFolder *folder = NULL; 01039 KMFolderDir *subfolder; 01040 bool root = true; 01041 01042 TQStringList subFList = TQStringList::split("/",_foldername,false); 01043 01044 for ( TQStringList::Iterator it = subFList.begin(); it != subFList.end(); ++it ) { 01045 TQString _newFolder = *it; 01046 if(_newFolder.startsWith(".")) return -1; 01047 01048 if(root) { 01049 folder = the_folderMgr->findOrCreate(*it, false); 01050 if (folder) { 01051 root = false; 01052 tmp_fname = "/" + *it; 01053 } 01054 else return -1; 01055 } else { 01056 subfolder = folder->createChildFolder(); 01057 tmp_fname += "/" + *it; 01058 if(!the_folderMgr->getFolderByURL( tmp_fname )) { 01059 folder = the_folderMgr->createFolder(*it, false, folder->folderType(), subfolder); 01060 } 01061 if(!(folder = the_folderMgr->getFolderByURL( tmp_fname ))) return -1; 01062 } 01063 } 01064 01065 mAddMsgCurrentFolder = the_folderMgr->getFolderByURL( tmp_fname ); 01066 if(!folder) return -1; 01067 01068 } else { 01069 mAddMsgCurrentFolder = the_folderMgr->findOrCreate(_foldername, false); 01070 } 01071 } 01072 01073 if ( mAddMsgCurrentFolder ) { 01074 int index; 01075 01076 if( !MsgStatusFlags.isEmpty() ) { 01077 KMMsgStatus status = strToStatus(MsgStatusFlags); 01078 if (status) msg->setStatus(status); 01079 } 01080 01081 if ( mAddMsgCurrentFolder->addMsg( msg, &index ) == 0 ) { 01082 mAddMsgCurrentFolder->unGetMsg( index ); 01083 retval = 1; 01084 } else { 01085 retval =- 2; 01086 delete msg; 01087 msg = 0; 01088 } 01089 } else { 01090 retval = -1; 01091 } 01092 } else { 01093 retval = -2; 01094 } 01095 01096 return retval; 01097 } 01098 01099 void KMKernel::showImportArchiveDialog() 01100 { 01101 KMMainWidget *mainWidget = getKMMainWidget(); 01102 KMail::ImportArchiveDialog *importDialog = new KMail::ImportArchiveDialog( mainWidget, WDestructiveClose ); 01103 importDialog->setFolder( mainWidget->folderTree()->currentFolder() ); 01104 importDialog->show(); 01105 } 01106 01107 TQStringList KMKernel::folderList() const 01108 { 01109 TQStringList folders; 01110 const TQString localPrefix = "/Local"; 01111 folders << localPrefix; 01112 the_folderMgr->getFolderURLS( folders, localPrefix ); 01113 the_imapFolderMgr->getFolderURLS( folders ); 01114 the_dimapFolderMgr->getFolderURLS( folders ); 01115 return folders; 01116 } 01117 01118 DCOPRef KMKernel::getFolder( const TQString& vpath ) 01119 { 01120 const TQString localPrefix = "/Local"; 01121 if ( the_folderMgr->getFolderByURL( vpath ) ) 01122 return DCOPRef( new FolderIface( vpath ) ); 01123 else if ( vpath.startsWith( localPrefix ) && 01124 the_folderMgr->getFolderByURL( vpath.mid( localPrefix.length() ) ) ) 01125 return DCOPRef( new FolderIface( vpath.mid( localPrefix.length() ) ) ); 01126 else if ( the_imapFolderMgr->getFolderByURL( vpath ) ) 01127 return DCOPRef( new FolderIface( vpath ) ); 01128 else if ( the_dimapFolderMgr->getFolderByURL( vpath ) ) 01129 return DCOPRef( new FolderIface( vpath ) ); 01130 return DCOPRef(); 01131 } 01132 01133 void KMKernel::raise() 01134 { 01135 DCOPRef kmail( "kmail", "kmail" ); 01136 kmail.call( "newInstance" ); 01137 } 01138 01139 bool KMKernel::showMail( TQ_UINT32 serialNumber, TQString /* messageId */ ) 01140 { 01141 KMMainWidget *mainWidget = 0; 01142 if (TDEMainWindow::memberList) { 01143 TDEMainWindow *win = 0; 01144 TQObjectList *l; 01145 01146 // First look for a TDEMainWindow. 01147 for (win = TDEMainWindow::memberList->first(); win; 01148 win = TDEMainWindow::memberList->next()) { 01149 // Then look for a KMMainWidget. 01150 l = win->queryList("KMMainWidget"); 01151 if (l && l->first()) { 01152 mainWidget = dynamic_cast<KMMainWidget *>(l->first()); 01153 if (win->isActiveWindow()) 01154 break; 01155 } 01156 } 01157 } 01158 01159 if (mainWidget) { 01160 int idx = -1; 01161 KMFolder *folder = 0; 01162 KMMsgDict::instance()->getLocation(serialNumber, &folder, &idx); 01163 if (!folder || (idx == -1)) 01164 return false; 01165 KMFolderOpener openFolder(folder, "showmail"); 01166 KMMsgBase *msgBase = folder->getMsgBase(idx); 01167 if (!msgBase) 01168 return false; 01169 bool unGet = !msgBase->isMessage(); 01170 KMMessage *msg = folder->getMsg(idx); 01171 01172 KMReaderMainWin *win = new KMReaderMainWin( false, false ); 01173 KMMessage *newMessage = new KMMessage( *msg ); 01174 newMessage->setParent( msg->parent() ); 01175 newMessage->setMsgSerNum( msg->getMsgSerNum() ); 01176 newMessage->setReadyToShow( true ); 01177 win->showMsg( GlobalSettings::self()->overrideCharacterEncoding(), newMessage ); 01178 win->show(); 01179 01180 if (unGet) 01181 folder->unGetMsg(idx); 01182 return true; 01183 } 01184 01185 return false; 01186 } 01187 01188 TQString KMKernel::getFrom( TQ_UINT32 serialNumber ) 01189 { 01190 int idx = -1; 01191 KMFolder *folder = 0; 01192 KMMsgDict::instance()->getLocation(serialNumber, &folder, &idx); 01193 if (!folder || (idx == -1)) 01194 return TQString(); 01195 KMFolderOpener openFolder(folder, "getFrom"); 01196 KMMsgBase *msgBase = folder->getMsgBase(idx); 01197 if (!msgBase) 01198 return TQString(); 01199 bool unGet = !msgBase->isMessage(); 01200 KMMessage *msg = folder->getMsg(idx); 01201 TQString result = msg->from(); 01202 if (unGet) 01203 folder->unGetMsg(idx); 01204 return result; 01205 } 01206 01207 TQString KMKernel::debugScheduler() 01208 { 01209 TQString res = KMail::ActionScheduler::debug(); 01210 return res; 01211 } 01212 01213 TQString KMKernel::debugSernum( TQ_UINT32 serialNumber ) 01214 { 01215 TQString res; 01216 if (serialNumber != 0) { 01217 int idx = -1; 01218 KMFolder *folder = 0; 01219 KMMsgBase *msg = 0; 01220 KMMsgDict::instance()->getLocation( serialNumber, &folder, &idx ); 01221 // It's possible that the message has been deleted or moved into a 01222 // different folder 01223 if (folder && (idx != -1)) { 01224 // everything is ok 01225 KMFolderOpener openFolder(folder, "debugser"); 01226 msg = folder->getMsgBase( idx ); 01227 if (msg) { 01228 res.append( TQString( " subject %s,\n sender %s,\n date %s.\n" ) 01229 .arg( msg->subject() ) 01230 .arg( msg->fromStrip() ) 01231 .arg( msg->dateStr() ) ); 01232 } else { 01233 res.append( TQString( "Invalid serial number." ) ); 01234 } 01235 } else { 01236 res.append( TQString( "Invalid serial number." ) ); 01237 } 01238 } 01239 return res; 01240 } 01241 01242 01243 void KMKernel::pauseBackgroundJobs() 01244 { 01245 mBackgroundTasksTimer->stop(); 01246 mJobScheduler->pause(); 01247 } 01248 01249 void KMKernel::resumeBackgroundJobs() 01250 { 01251 mJobScheduler->resume(); 01252 mBackgroundTasksTimer->start( 4 * 60 * 60 * 1000, true ); 01253 } 01254 01255 void KMKernel::stopNetworkJobs() 01256 { 01257 if ( GlobalSettings::self()->networkState() == GlobalSettings::EnumNetworkState::Offline ) 01258 return; 01259 01260 GlobalSettings::setNetworkState( GlobalSettings::EnumNetworkState::Offline ); 01261 BroadcastStatus::instance()->setStatusMsg( i18n("KMail is set to be offline; all network jobs are suspended")); 01262 emit onlineStatusChanged( (GlobalSettings::EnumNetworkState::type)GlobalSettings::networkState() ); 01263 } 01264 01265 void KMKernel::resumeNetworkJobs() 01266 { 01267 if ( GlobalSettings::self()->networkState() == GlobalSettings::EnumNetworkState::Online ) 01268 return; 01269 01270 GlobalSettings::setNetworkState( GlobalSettings::EnumNetworkState::Online ); 01271 BroadcastStatus::instance()->setStatusMsg( i18n("KMail is set to be online; all network jobs resumed")); 01272 emit onlineStatusChanged( (GlobalSettings::EnumNetworkState::type)GlobalSettings::networkState() ); 01273 01274 if ( kmkernel->msgSender() && kmkernel->msgSender()->sendImmediate() ) { 01275 kmkernel->msgSender()->sendQueued(); 01276 } 01277 } 01278 01279 bool KMKernel::isOffline() 01280 { 01281 if ( GlobalSettings::self()->networkState() == GlobalSettings::EnumNetworkState::Offline ) 01282 return true; 01283 else 01284 return false; 01285 } 01286 01287 bool KMKernel::askToGoOnline() 01288 { 01289 // already asking means we are offline and need to wait anyhow 01290 if ( s_askingToGoOnline ) { 01291 return false; 01292 } 01293 01294 if ( kmkernel->isOffline() ) { 01295 s_askingToGoOnline = true; 01296 int rc = 01297 KMessageBox::questionYesNo( KMKernel::self()->mainWin(), 01298 i18n("KMail is currently in offline mode. " 01299 "How do you want to proceed?"), 01300 i18n("Online/Offline"), 01301 i18n("Work Online"), 01302 i18n("Work Offline")); 01303 01304 s_askingToGoOnline = false; 01305 if( rc == KMessageBox::No ) { 01306 return false; 01307 } else { 01308 kmkernel->resumeNetworkJobs(); 01309 } 01310 } 01311 return true; 01312 } 01313 01314 /********************************************************************/ 01315 /* Kernel methods */ 01316 /********************************************************************/ 01317 01318 void KMKernel::quit() 01319 { 01320 // Called when all windows are closed. Will take care of compacting, 01321 // sending... should handle session management too!! 01322 } 01323 /* TODO later: 01324 Asuming that: 01325 - msgsender is nonblocking 01326 (our own, TQSocketNotifier based. Pops up errors and sends signal 01327 senderFinished when done) 01328 01329 o If we are getting mail, stop it (but dont lose something!) 01330 [Done already, see mailCheckAborted] 01331 o If we are sending mail, go on UNLESS this was called by SM, 01332 in which case stop ASAP that too (can we warn? should we continue 01333 on next start?) 01334 o If we are compacting, or expunging, go on UNLESS this was SM call. 01335 In that case stop compacting ASAP and continue on next start, before 01336 touching any folders. [Not needed anymore with CompactionJob] 01337 01338 KMKernel::quit () 01339 { 01340 SM call? 01341 if compacting, stop; 01342 if sending, stop; 01343 if receiving, stop; 01344 Windows will take care of themselves (composer should dump 01345 its messages, if any but not in deadMail) 01346 declare us ready for the End of the Session 01347 01348 No, normal quit call 01349 All windows are off. Anything to do, should compact or sender sends? 01350 Yes, maybe put an icon in panel as a sign of life 01351 if sender sending, connect us to his finished slot, declare us ready 01352 for quit and wait for senderFinished 01353 if not, Folder manager, go compact sent-mail and outbox 01354 } (= call slotFinished()) 01355 01356 void KMKernel::slotSenderFinished() 01357 { 01358 good, Folder manager go compact sent-mail and outbox 01359 clean up stage1 (release folders and config, unregister from dcop) 01360 -- another kmail may start now --- 01361 kapp->quit(); 01362 } 01363 */ 01364 01365 01366 /********************************************************************/ 01367 /* Init, Exit, and handler methods */ 01368 /********************************************************************/ 01369 void KMKernel::testDir(const char *_name) 01370 { 01371 TQString foldersPath = TQDir::homeDirPath() + TQString( _name ); 01372 TQFileInfo info( foldersPath ); 01373 if ( !info.exists() ) { 01374 if ( ::mkdir( TQFile::encodeName( foldersPath ) , S_IRWXU ) == -1 ) { 01375 KMessageBox::sorry(0, i18n("KMail could not create folder '%1';\n" 01376 "please make sure that you can view and " 01377 "modify the content of the folder '%2'.") 01378 .arg( foldersPath ).arg( TQDir::homeDirPath() ) ); 01379 ::exit(-1); 01380 } 01381 } 01382 if ( !info.isDir() || !info.isReadable() || !info.isWritable() ) { 01383 KMessageBox::sorry(0, i18n("The permissions of the folder '%1' are " 01384 "incorrect;\n" 01385 "please make sure that you can view and modify " 01386 "the content of this folder.") 01387 .arg( foldersPath ) ); 01388 ::exit(-1); 01389 } 01390 } 01391 01392 01393 //----------------------------------------------------------------------------- 01394 // Open a composer for each message found in the dead.letter folder 01395 void KMKernel::recoverDeadLetters() 01396 { 01397 TQDir dir( localDataPath() + "autosave/cur" ); 01398 if ( !dir.exists() ) { 01399 kdWarning(5006) << "Autosave directory " << dir.path() << " not found!" << endl; 01400 return; 01401 } 01402 01403 const TQStringList entryList = dir.entryList( TQDir::Files | TQDir::NoSymLinks, TQDir::Unsorted ); 01404 for ( unsigned int i = 0; i < entryList.size(); i++ ) { 01405 const TQString fileName = entryList[i]; 01406 TQFile file( dir.path() + '/' + fileName ); 01407 if ( !file.open( IO_ReadOnly ) ) { 01408 kdWarning(5006) << "Unable to open autosave file " << fileName << endl; 01409 continue; 01410 } 01411 const TQByteArray msgData = file.readAll(); 01412 file.close(); 01413 01414 if ( msgData.isEmpty() ) { 01415 kdWarning(5006) << "autosave file " << fileName << " is empty!" << endl; 01416 continue; 01417 } 01418 01419 KMMessage *msg = new KMMessage(); // Composer will take ownership 01420 msg->fromByteArray( msgData ); 01421 KMail::Composer * win = KMail::makeComposer(); 01422 win->setMsg( msg, false, false, true ); 01423 win->setAutoSaveFilename( fileName ); 01424 win->show(); 01425 } 01426 } 01427 01428 //----------------------------------------------------------------------------- 01429 void KMKernel::initFolders(TDEConfig* cfg) 01430 { 01431 TQString name; 01432 01433 name = cfg->readEntry("inboxFolder"); 01434 01435 // Currently the folder manager cannot manage folders which are not 01436 // in the base folder directory. 01437 //if (name.isEmpty()) name = getenv("MAIL"); 01438 01439 if (name.isEmpty()) name = I18N_NOOP("inbox"); 01440 01441 the_inboxFolder = (KMFolder*)the_folderMgr->findOrCreate(name); 01442 01443 if (the_inboxFolder->canAccess() != 0) { 01444 emergencyExit( i18n("You do not have read/write permission to your inbox folder.") ); 01445 } 01446 01447 the_inboxFolder->setSystemFolder(true); 01448 if ( the_inboxFolder->userWhoField().isEmpty() ) 01449 the_inboxFolder->setUserWhoField( TQString() ); 01450 // inboxFolder->open(); 01451 01452 the_outboxFolder = the_folderMgr->findOrCreate(cfg->readEntry("outboxFolder", I18N_NOOP("outbox"))); 01453 if (the_outboxFolder->canAccess() != 0) { 01454 emergencyExit( i18n("You do not have read/write permission to your outbox folder.") ); 01455 } 01456 the_outboxFolder->setNoChildren(true); 01457 01458 the_outboxFolder->setSystemFolder(true); 01459 if ( the_outboxFolder->userWhoField().isEmpty() ) 01460 the_outboxFolder->setUserWhoField( TQString() ); 01461 /* Nuke the oubox's index file, to make sure that no ghost messages are in 01462 * it from a previous crash. Ghost messages happen in the outbox because it 01463 * the only folder where messages enter and leave within 5 seconds, which is 01464 * the leniency period for index invalidation. Since the number of mails in 01465 * this folder is expected to be very small, we can live with regenerating 01466 * the index on each start to be on the save side. */ 01467 //if ( the_outboxFolder->folderType() == KMFolderTypeMaildir ) 01468 // unlink( TQFile::encodeName( the_outboxFolder->indexLocation() ) ); 01469 the_outboxFolder->open("kmkernel"); 01470 01471 the_sentFolder = the_folderMgr->findOrCreate(cfg->readEntry("sentFolder", I18N_NOOP("sent-mail"))); 01472 if (the_sentFolder->canAccess() != 0) { 01473 emergencyExit( i18n("You do not have read/write permission to your sent-mail folder.") ); 01474 } 01475 the_sentFolder->setSystemFolder(true); 01476 if ( the_sentFolder->userWhoField().isEmpty() ) 01477 the_sentFolder->setUserWhoField( TQString() ); 01478 // the_sentFolder->open(); 01479 01480 the_trashFolder = the_folderMgr->findOrCreate(cfg->readEntry("trashFolder", I18N_NOOP("trash"))); 01481 if (the_trashFolder->canAccess() != 0) { 01482 emergencyExit( i18n("You do not have read/write permission to your trash folder.") ); 01483 } 01484 the_trashFolder->setSystemFolder( true ); 01485 if ( the_trashFolder->userWhoField().isEmpty() ) 01486 the_trashFolder->setUserWhoField( TQString() ); 01487 // the_trashFolder->open(); 01488 01489 the_draftsFolder = the_folderMgr->findOrCreate(cfg->readEntry("draftsFolder", I18N_NOOP("drafts"))); 01490 if (the_draftsFolder->canAccess() != 0) { 01491 emergencyExit( i18n("You do not have read/write permission to your drafts folder.") ); 01492 } 01493 the_draftsFolder->setSystemFolder( true ); 01494 if ( the_draftsFolder->userWhoField().isEmpty() ) 01495 the_draftsFolder->setUserWhoField( TQString() ); 01496 the_draftsFolder->open("kmkernel"); 01497 01498 the_templatesFolder = 01499 the_folderMgr->findOrCreate( cfg->readEntry( "templatesFolder", 01500 I18N_NOOP("templates") ) ); 01501 if ( the_templatesFolder->canAccess() != 0 ) { 01502 emergencyExit( i18n("You do not have read/write permission to your templates folder.") ); 01503 } 01504 the_templatesFolder->setSystemFolder( true ); 01505 if ( the_templatesFolder->userWhoField().isEmpty() ) 01506 the_templatesFolder->setUserWhoField( TQString() ); 01507 the_templatesFolder->open("kmkernel"); 01508 } 01509 01510 01511 void KMKernel::init() 01512 { 01513 the_shuttingDown = false; 01514 the_server_is_ready = false; 01515 01516 TDEConfig* cfg = KMKernel::config(); 01517 01518 TQDir dir; 01519 01520 TDEConfigGroupSaver saver(cfg, "General"); 01521 the_firstStart = cfg->readBoolEntry("first-start", true); 01522 cfg->writeEntry("first-start", false); 01523 the_previousVersion = cfg->readEntry("previous-version"); 01524 cfg->writeEntry("previous-version", KMAIL_VERSION); 01525 TQString foldersPath = cfg->readPathEntry( "folders" ); 01526 kdDebug(5006) << k_funcinfo << "foldersPath (from config): '" << foldersPath << "'" << endl; 01527 01528 if ( foldersPath.isEmpty() ) { 01529 foldersPath = localDataPath() + "mail"; 01530 if ( transferMail( foldersPath ) ) { 01531 cfg->writePathEntry( "folders", foldersPath ); 01532 } 01533 kdDebug(5006) << k_funcinfo << "foldersPath (after transferMail): '" << foldersPath << "'" << endl; 01534 } 01535 01536 // moved up here because KMMessage::stripOffPrefixes is used below 01537 KMMessage::readConfig(); 01538 01539 the_undoStack = new UndoStack(20); 01540 the_folderMgr = new KMFolderMgr(foldersPath); 01541 the_imapFolderMgr = new KMFolderMgr( KMFolderImap::cacheLocation(), KMImapDir); 01542 the_dimapFolderMgr = new KMFolderMgr( KMFolderCachedImap::cacheLocation(), KMDImapDir); 01543 recreateCorruptIndexFiles(); 01544 01545 the_searchFolderMgr = new KMFolderMgr(locateLocal("data","kmail/search"), KMSearchDir); 01546 KMFolder *lsf = the_searchFolderMgr->find( i18n("Last Search") ); 01547 if (lsf) 01548 the_searchFolderMgr->remove( lsf ); 01549 01550 the_acctMgr = new AccountManager(); 01551 the_filterMgr = new KMFilterMgr(); 01552 the_popFilterMgr = new KMFilterMgr(true); 01553 the_filterActionDict = new KMFilterActionDict; 01554 01555 initFolders(cfg); 01556 the_acctMgr->readConfig(); 01557 the_filterMgr->readConfig(); 01558 the_popFilterMgr->readConfig(); 01559 cleanupImapFolders(); 01560 01561 the_msgSender = new KMSender; 01562 the_server_is_ready = true; 01563 imProxy()->initialize(); 01564 { // area for config group "Composer" 01565 TDEConfigGroupSaver saver(cfg, "Composer"); 01566 if (cfg->readListEntry("pref-charsets").isEmpty()) 01567 { 01568 cfg->writeEntry("pref-charsets", "us-ascii,iso-8859-1,locale,utf-8"); 01569 } 01570 } 01571 readConfig(); 01572 mICalIface->readConfig(); 01573 // filterMgr->dump(); 01574 #ifdef HAVE_INDEXLIB 01575 the_msgIndex = new KMMsgIndex(this); //create the indexer 01576 #else 01577 the_msgIndex = 0; 01578 #endif 01579 01580 //#if 0 01581 the_weaver = new KPIM::ThreadWeaver::Weaver( this ); 01582 the_weaverLogger = new KPIM::ThreadWeaver::WeaverThreadLogger(this); 01583 the_weaverLogger->attach (the_weaver); 01584 //#endif 01585 01586 connect( the_folderMgr, TQT_SIGNAL( folderRemoved(KMFolder*) ), 01587 this, TQT_SIGNAL( folderRemoved(KMFolder*) ) ); 01588 connect( the_dimapFolderMgr, TQT_SIGNAL( folderRemoved(KMFolder*) ), 01589 this, TQT_SIGNAL( folderRemoved(KMFolder*) ) ); 01590 connect( the_imapFolderMgr, TQT_SIGNAL( folderRemoved(KMFolder*) ), 01591 this, TQT_SIGNAL( folderRemoved(KMFolder*) ) ); 01592 connect( the_searchFolderMgr, TQT_SIGNAL( folderRemoved(KMFolder*) ), 01593 this, TQT_SIGNAL( folderRemoved(KMFolder*) ) ); 01594 01595 mBackgroundTasksTimer = new TQTimer( this, "mBackgroundTasksTimer" ); 01596 connect( mBackgroundTasksTimer, TQT_SIGNAL( timeout() ), this, TQT_SLOT( slotRunBackgroundTasks() ) ); 01597 #ifdef DEBUG_SCHEDULER // for debugging, see jobscheduler.h 01598 mBackgroundTasksTimer->start( 10000, true ); // 10s, singleshot 01599 #else 01600 mBackgroundTasksTimer->start( 5 * 60000, true ); // 5 minutes, singleshot 01601 #endif 01602 01603 TQTextCodec *codec; 01604 for ( int i = 0; ( codec = TQTextCodec::codecForIndex ( i ) ); i++ ) { 01605 const TQString asciiString( "azAZ19,.-#+!?=()&" ); 01606 const TQCString encodedString = codec->fromUnicode( asciiString ); 01607 if ( TQString::fromAscii( encodedString ) != asciiString ) { 01608 mNonAsciiCompatibleCodecs.append( codec ); 01609 } 01610 } 01611 } 01612 01613 bool KMKernel::isCodecAsciiCompatible( const TQTextCodec *codec ) 01614 { 01615 return !mNonAsciiCompatibleCodecs.contains( codec ); 01616 } 01617 01618 void KMKernel::readConfig() 01619 { 01620 //Needed here, since this function is also called when the configuration 01621 //changes, and the static variables should be updated then - IOF 01622 KMMessage::readConfig(); 01623 } 01624 01625 void KMKernel::cleanupImapFolders() 01626 { 01627 KMAccount *acct = 0; 01628 KMFolderNode *node = the_imapFolderMgr->dir().first(); 01629 while (node) 01630 { 01631 if (node->isDir() || ((acct = the_acctMgr->find(node->id())) 01632 && ( acct->type() == "imap" )) ) 01633 { 01634 node = the_imapFolderMgr->dir().next(); 01635 } else { 01636 KMFolder* folder = static_cast<KMFolder*>(node); 01637 // delete only local 01638 static_cast<KMFolderImap*>( folder->storage() )->setAlreadyRemoved( true ); 01639 the_imapFolderMgr->remove(folder); 01640 node = the_imapFolderMgr->dir().first(); 01641 } 01642 } 01643 01644 node = the_dimapFolderMgr->dir().first(); 01645 while (node) 01646 { 01647 if (node->isDir() || ((acct = the_acctMgr->find(node->id())) 01648 && ( acct->type() == "cachedimap" )) ) 01649 { 01650 node = the_dimapFolderMgr->dir().next(); 01651 } else { 01652 the_dimapFolderMgr->remove(static_cast<KMFolder*>(node)); 01653 node = the_dimapFolderMgr->dir().first(); 01654 } 01655 } 01656 01657 the_imapFolderMgr->quiet(true); 01658 for (acct = the_acctMgr->first(); acct; acct = the_acctMgr->next()) 01659 { 01660 KMFolderImap *fld; 01661 KMAcctImap *imapAcct; 01662 01663 if (acct->type() != "imap") continue; 01664 fld = static_cast<KMFolderImap*>(the_imapFolderMgr 01665 ->findOrCreate(TQString::number(acct->id()), false, acct->id())->storage()); 01666 fld->setNoContent(true); 01667 fld->folder()->setLabel(acct->name()); 01668 imapAcct = static_cast<KMAcctImap*>(acct); 01669 fld->setAccount(imapAcct); 01670 imapAcct->setImapFolder(fld); 01671 fld->close( "kernel", true ); 01672 } 01673 the_imapFolderMgr->quiet(false); 01674 01675 the_dimapFolderMgr->quiet( true ); 01676 for (acct = the_acctMgr->first(); acct; acct = the_acctMgr->next()) 01677 { 01678 KMFolderCachedImap *cfld = 0; 01679 KMAcctCachedImap *cachedImapAcct; 01680 01681 if (acct->type() != "cachedimap" ) continue; 01682 01683 KMFolder* fld = the_dimapFolderMgr->find(TQString::number(acct->id())); 01684 if( fld ) 01685 cfld = static_cast<KMFolderCachedImap*>( fld->storage() ); 01686 if (cfld == 0) { 01687 // Folder doesn't exist yet 01688 cfld = static_cast<KMFolderCachedImap*>(the_dimapFolderMgr->createFolder(TQString::number(acct->id()), 01689 false, KMFolderTypeCachedImap)->storage()); 01690 if (!cfld) { 01691 KMessageBox::error(0,(i18n("Cannot create file `%1' in %2.\nKMail cannot start without it.").arg(acct->name()).arg(the_dimapFolderMgr->basePath()))); 01692 exit(-1); 01693 } 01694 cfld->folder()->setId( acct->id() ); 01695 } 01696 01697 cfld->setNoContent(true); 01698 cfld->folder()->setLabel(acct->name()); 01699 cachedImapAcct = static_cast<KMAcctCachedImap*>(acct); 01700 cfld->setAccount(cachedImapAcct); 01701 cachedImapAcct->setImapFolder(cfld); 01702 cfld->close("kmkernel"); 01703 } 01704 the_dimapFolderMgr->quiet( false ); 01705 } 01706 01707 void KMKernel::recreateCorruptIndexFiles() 01708 { 01709 TQValueList<TQGuardedPtr<KMFolder> > folders; 01710 TQValueList<KMFolderIndex*> foldersWithBrokenIndex; 01711 TQStringList strList; 01712 the_folderMgr->createFolderList( &strList, &folders ); 01713 the_imapFolderMgr->createFolderList( &strList, &folders ); 01714 the_dimapFolderMgr->createFolderList( &strList, &folders ); 01715 for ( int i = 0; folders.at(i) != folders.end(); i++ ) { 01716 KMFolder * const folder = *folders.at(i); 01717 if ( !folder || folder->isDir() || folder->isOpened() ) 01718 continue; 01719 KMFolderIndex * const index = dynamic_cast<KMFolderIndex*>( folder->storage() ); 01720 if ( index && index->indexStatus() != KMFolderIndex::IndexOk ) { 01721 foldersWithBrokenIndex.append( index ); 01722 } 01723 } 01724 01725 if ( !foldersWithBrokenIndex.isEmpty() ) { 01726 TQStringList folderNames; 01727 for ( uint i = 0; i < foldersWithBrokenIndex.size(); i++ ) { 01728 folderNames << foldersWithBrokenIndex[i]->label(); 01729 } 01730 01731 KMessageBox::informationList( 0, i18n( "There is a problem with the mail index of the following " 01732 "folders, the indices will now be regenerated.\n" 01733 "This can happen because the index files are out of date, missing or corrupted.\n" 01734 "Contact your administrator if this happens frequently.\n" 01735 "Some information, like status flags, might get lost." ), 01736 folderNames, i18n( "Problem with mail indices" ) ); 01737 01738 for ( uint i = 0; i < foldersWithBrokenIndex.size(); i++ ) { 01739 foldersWithBrokenIndex[i]->silentlyRecreateIndex(); 01740 } 01741 } 01742 } 01743 01744 bool KMKernel::doSessionManagement() 01745 { 01746 01747 // Do session management 01748 if (kapp->isRestored()){ 01749 int n = 1; 01750 while (KMMainWin::canBeRestored(n)){ 01751 //only restore main windows! (Matthias); 01752 if (KMMainWin::classNameOfToplevel(n) == "KMMainWin") 01753 (new KMMainWin)->restore(n); 01754 n++; 01755 } 01756 return true; // we were restored by SM 01757 } 01758 return false; // no, we were not restored 01759 } 01760 01761 void KMKernel::closeAllKMailWindows() 01762 { 01763 if (!TDEMainWindow::memberList) return; 01764 TQPtrListIterator<TDEMainWindow> it(*TDEMainWindow::memberList); 01765 TDEMainWindow *window = 0; 01766 while ((window = it.current()) != 0) { 01767 ++it; 01768 if (window->isA("KMMainWindow") || 01769 window->inherits("KMail::SecondaryWindow")) 01770 window->close( true ); // close and delete the window 01771 } 01772 } 01773 01774 void KMKernel::cleanup(void) 01775 { 01776 dumpDeadLetters(); 01777 the_shuttingDown = true; 01778 closeAllKMailWindows(); 01779 01780 delete the_acctMgr; 01781 the_acctMgr = 0; 01782 delete the_filterMgr; 01783 the_filterMgr = 0; 01784 delete the_msgSender; 01785 the_msgSender = 0; 01786 delete the_filterActionDict; 01787 the_filterActionDict = 0; 01788 delete the_undoStack; 01789 the_undoStack = 0; 01790 delete the_popFilterMgr; 01791 the_popFilterMgr = 0; 01792 01793 #if 0 01794 delete the_weaver; 01795 the_weaver = 0; 01796 #endif 01797 01798 TDEConfig* config = KMKernel::config(); 01799 TDEConfigGroupSaver saver(config, "General"); 01800 01801 if (the_trashFolder) { 01802 01803 the_trashFolder->close("kmkernel", true); 01804 01805 if (config->readBoolEntry("empty-trash-on-exit", true)) 01806 { 01807 if ( the_trashFolder->count( true ) > 0 ) 01808 the_trashFolder->expunge(); 01809 } 01810 } 01811 01812 mICalIface->cleanup(); 01813 01814 TQValueList<TQGuardedPtr<KMFolder> > folders; 01815 TQStringList strList; 01816 KMFolder *folder; 01817 the_folderMgr->createFolderList(&strList, &folders); 01818 for (int i = 0; folders.at(i) != folders.end(); i++) 01819 { 01820 folder = *folders.at(i); 01821 if (!folder || folder->isDir()) continue; 01822 folder->close("kmkernel", true); 01823 } 01824 strList.clear(); 01825 folders.clear(); 01826 the_searchFolderMgr->createFolderList(&strList, &folders); 01827 for (int i = 0; folders.at(i) != folders.end(); i++) 01828 { 01829 folder = *folders.at(i); 01830 if (!folder || folder->isDir()) continue; 01831 folder->close("kmkernel", true); 01832 } 01833 01834 delete the_msgIndex; 01835 the_msgIndex = 0; 01836 delete the_folderMgr; 01837 the_folderMgr = 0; 01838 delete the_imapFolderMgr; 01839 the_imapFolderMgr = 0; 01840 delete the_dimapFolderMgr; 01841 the_dimapFolderMgr = 0; 01842 delete the_searchFolderMgr; 01843 the_searchFolderMgr = 0; 01844 delete mConfigureDialog; 01845 mConfigureDialog = 0; 01846 // do not delete, because mWin may point to an existing window 01847 // delete mWin; 01848 mWin = 0; 01849 01850 if ( RecentAddresses::exists() ) 01851 RecentAddresses::self( config )->save( config ); 01852 config->sync(); 01853 } 01854 01855 bool KMKernel::transferMail( TQString & destinationDir ) 01856 { 01857 TQString dir; 01858 01859 // check whether the user has a ~/KMail folder 01860 TQFileInfo fi( TQDir::home(), "KMail" ); 01861 if ( fi.exists() && fi.isDir() ) { 01862 dir = TQDir::homeDirPath() + "/KMail"; 01863 // the following two lines can be removed once moving mail is reactivated 01864 destinationDir = dir; 01865 return true; 01866 } 01867 01868 if ( dir.isEmpty() ) { 01869 // check whether the user has a ~/Mail folder 01870 fi.setFile( TQDir::home(), "Mail" ); 01871 if ( fi.exists() && fi.isDir() && 01872 TQFile::exists( TQDir::homeDirPath() + "/Mail/.inbox.index" ) ) { 01873 // there's a ~/Mail folder which seems to be used by KMail (because of the 01874 // index file) 01875 dir = TQDir::homeDirPath() + "/Mail"; 01876 // the following two lines can be removed once moving mail is reactivated 01877 destinationDir = dir; 01878 return true; 01879 } 01880 } 01881 01882 if ( dir.isEmpty() ) { 01883 return true; // there's no old mail folder 01884 } 01885 01886 #if 0 01887 // disabled for now since moving fails in certain cases (e.g. if symbolic links are involved) 01888 const TQString kmailName = kapp->aboutData()->programName(); 01889 TQString msg; 01890 if ( TDEIO::NetAccess::exists( destinationDir, true, 0 ) ) { 01891 // if destinationDir exists, we need to warn about possible 01892 // overwriting of files. otherwise, we don't have to 01893 msg = i18n( "%1-%3 is the application name, %4-%7 are folder path", 01894 "<qt>The <i>%4</i> folder exists. " 01895 "%1 now uses the <i>%5</i> folder for " 01896 "its messages.<p>" 01897 "%2 can move the contents of <i>%6<i> into this folder for " 01898 "you, though this may replace any existing files with " 01899 "the same name in <i>%7</i>.<p>" 01900 "<strong>Would you like %3 to move the mail " 01901 "files now?</strong></qt>" ) 01902 .arg( kmailName, kmailName, kmailName ) 01903 .arg( dir, destinationDir, dir, destinationDir ); 01904 } else { 01905 msg = i18n( "%1-%3 is the application name, %4-%6 are folder path", 01906 "<qt>The <i>%4</i> folder exists. " 01907 "%1 now uses the <i>%5</i> folder for " 01908 "its messages. %2 can move the contents of <i>%6</i> into " 01909 "this folder for you.<p>" 01910 "<strong>Would you like %3 to move the mail " 01911 "files now?</strong></qt>" ) 01912 .arg( kmailName, kmailName, kmailName ) 01913 .arg( dir, destinationDir, dir ); 01914 } 01915 TQString title = i18n( "Migrate Mail Files?" ); 01916 TQString buttonText = i18n( "Move" ); 01917 01918 if ( KMessageBox::questionYesNo( 0, msg, title, buttonText, i18n("Do Not Move") ) == 01919 KMessageBox::No ) { 01920 destinationDir = dir; 01921 return true; 01922 } 01923 01924 if ( !TDEIO::NetAccess::move( dir, destinationDir ) ) { 01925 kdDebug(5006) << k_funcinfo << "Moving " << dir << " to " << destinationDir << " failed: " << TDEIO::NetAccess::lastErrorString() << endl; 01926 kdDebug(5006) << k_funcinfo << "Deleting " << destinationDir << endl; 01927 TDEIO::NetAccess::del( destinationDir, 0 ); 01928 destinationDir = dir; 01929 return false; 01930 } 01931 #endif 01932 01933 return true; 01934 } 01935 01936 01937 void KMKernel::ungrabPtrKb(void) 01938 { 01939 if(!TDEMainWindow::memberList) return; 01940 TQWidget* widg = TDEMainWindow::memberList->first(); 01941 Display* dpy; 01942 01943 if (!widg) return; 01944 dpy = widg->x11Display(); 01945 XUngrabKeyboard(dpy, CurrentTime); 01946 XUngrabPointer(dpy, CurrentTime); 01947 } 01948 01949 01950 // Message handler 01951 void KMKernel::kmailMsgHandler(TQtMsgType aType, const char* aMsg) 01952 { 01953 static int recurse=-1; 01954 01955 recurse++; 01956 01957 switch (aType) 01958 { 01959 case TQtDebugMsg: 01960 case TQtWarningMsg: 01961 kdDebug(5006) << aMsg << endl; 01962 break; 01963 01964 case TQtFatalMsg: // Hm, what about using kdFatal() here? 01965 ungrabPtrKb(); 01966 kdDebug(5006) << kapp->caption() << " fatal error " 01967 << aMsg << endl; 01968 KMessageBox::error(0, aMsg); 01969 abort(); 01970 } 01971 01972 recurse--; 01973 } 01974 01975 01976 void KMKernel::dumpDeadLetters() 01977 { 01978 if ( shuttingDown() ) 01979 return; //All documents should be saved before shutting down is set! 01980 01981 // make all composer windows autosave their contents 01982 if ( !TDEMainWindow::memberList ) 01983 return; 01984 01985 for ( TQPtrListIterator<TDEMainWindow> it(*TDEMainWindow::memberList) ; it.current() != 0; ++it ) { 01986 if ( KMail::Composer * win = ::tqqt_cast<KMail::Composer*>( it.current() ) ) { 01987 win->autoSaveMessage(); 01988 // saving the message has to be finished right here, we are called from a dtor, 01989 // therefore we have no chance to finish this later 01990 // yes, this is ugly and potentially dangerous, but the alternative is losing 01991 // currently composed messages... 01992 while ( win->isComposing() ) 01993 tqApp->processEvents(); 01994 } 01995 } 01996 } 01997 01998 01999 02000 void KMKernel::action(bool mailto, bool check, const TQString &to, 02001 const TQString &cc, const TQString &bcc, 02002 const TQString &subj, const TQString &body, 02003 const KURL &messageFile, 02004 const KURL::List &attachURLs, 02005 const QCStringList &customHeaders) 02006 { 02007 if ( mailto ) 02008 openComposer( to, cc, bcc, subj, body, 0, messageFile, attachURLs, customHeaders ); 02009 else 02010 openReader( check ); 02011 02012 if ( check ) 02013 checkMail(); 02014 //Anything else? 02015 } 02016 02017 void KMKernel::byteArrayToRemoteFile(const TQByteArray &aData, const KURL &aURL, 02018 bool overwrite) 02019 { 02020 // ## when KDE 3.3 is out: use TDEIO::storedPut to remove slotDataReq altogether 02021 TDEIO::Job *job = TDEIO::put(aURL, -1, overwrite, false); 02022 putData pd; pd.url = aURL; pd.data = aData; pd.offset = 0; 02023 mPutJobs.insert(job, pd); 02024 connect(job, TQT_SIGNAL(dataReq(TDEIO::Job*,TQByteArray&)), 02025 TQT_SLOT(slotDataReq(TDEIO::Job*,TQByteArray&))); 02026 connect(job, TQT_SIGNAL(result(TDEIO::Job*)), 02027 TQT_SLOT(slotResult(TDEIO::Job*))); 02028 } 02029 02030 void KMKernel::slotDataReq(TDEIO::Job *job, TQByteArray &data) 02031 { 02032 // send the data in 64 KB chunks 02033 const int MAX_CHUNK_SIZE = 64*1024; 02034 TQMap<TDEIO::Job*, putData>::Iterator it = mPutJobs.find(job); 02035 assert(it != mPutJobs.end()); 02036 int remainingBytes = (*it).data.size() - (*it).offset; 02037 if( remainingBytes > MAX_CHUNK_SIZE ) 02038 { 02039 // send MAX_CHUNK_SIZE bytes to the receiver (deep copy) 02040 data.duplicate( (*it).data.data() + (*it).offset, MAX_CHUNK_SIZE ); 02041 (*it).offset += MAX_CHUNK_SIZE; 02042 //kdDebug( 5006 ) << "Sending " << MAX_CHUNK_SIZE << " bytes (" 02043 // << remainingBytes - MAX_CHUNK_SIZE << " bytes remain)\n"; 02044 } 02045 else 02046 { 02047 // send the remaining bytes to the receiver (deep copy) 02048 data.duplicate( (*it).data.data() + (*it).offset, remainingBytes ); 02049 (*it).data = TQByteArray(); 02050 (*it).offset = 0; 02051 //kdDebug( 5006 ) << "Sending " << remainingBytes << " bytes\n"; 02052 } 02053 } 02054 02055 void KMKernel::slotResult(TDEIO::Job *job) 02056 { 02057 TQMap<TDEIO::Job*, putData>::Iterator it = mPutJobs.find(job); 02058 assert(it != mPutJobs.end()); 02059 if (job->error()) 02060 { 02061 if (job->error() == TDEIO::ERR_FILE_ALREADY_EXIST) 02062 { 02063 if (KMessageBox::warningContinueCancel(0, 02064 i18n("File %1 exists.\nDo you want to replace it?") 02065 .arg((*it).url.prettyURL()), i18n("Save to File"), i18n("&Replace")) 02066 == KMessageBox::Continue) 02067 byteArrayToRemoteFile((*it).data, (*it).url, true); 02068 } 02069 else job->showErrorDialog(); 02070 } 02071 mPutJobs.remove(it); 02072 } 02073 02074 void KMKernel::slotRequestConfigSync() { 02075 // ### FIXME: delay as promised in the kdoc of this function ;-) 02076 KMKernel::config()->sync(); 02077 } 02078 02079 void KMKernel::slotShowConfigurationDialog() 02080 { 02081 if( !mConfigureDialog ) { 02082 mConfigureDialog = new ConfigureDialog( 0, "configure", false ); 02083 connect( mConfigureDialog, TQT_SIGNAL( configChanged() ), 02084 this, TQT_SLOT( slotConfigChanged() ) ); 02085 } 02086 02087 if( KMKernel::getKMMainWidget() == 0 ) 02088 { 02089 // ensure that there is a main widget available 02090 // as parts of the configure dialog (identity) rely on this 02091 // and this slot can be called when there is only a KMComposeWin showing 02092 KMMainWin * win = new KMMainWin; 02093 win->show(); 02094 } 02095 if( mConfigureDialog->isHidden() ) 02096 { 02097 getKMMainWidget()->headers()->writeConfig(); 02098 mConfigureDialog->show(); 02099 } 02100 else 02101 mConfigureDialog->raise(); 02102 } 02103 02104 void KMKernel::slotConfigChanged() 02105 { 02106 readConfig(); 02107 emit configChanged(); 02108 } 02109 02110 //------------------------------------------------------------------------------- 02111 //static 02112 TQString KMKernel::localDataPath() 02113 { 02114 return locateLocal( "data", "kmail/" ); 02115 } 02116 02117 //------------------------------------------------------------------------------- 02118 02119 bool KMKernel::haveSystemTrayApplet() 02120 { 02121 return !systemTrayApplets.isEmpty(); 02122 } 02123 02124 bool KMKernel::registerSystemTrayApplet( const KSystemTray* applet ) 02125 { 02126 if ( systemTrayApplets.findIndex( applet ) == -1 ) { 02127 systemTrayApplets.append( applet ); 02128 return true; 02129 } 02130 else 02131 return false; 02132 } 02133 02134 bool KMKernel::unregisterSystemTrayApplet( const KSystemTray* applet ) 02135 { 02136 TQValueList<const KSystemTray*>::iterator it = 02137 systemTrayApplets.find( applet ); 02138 if ( it != systemTrayApplets.end() ) { 02139 systemTrayApplets.remove( it ); 02140 return true; 02141 } 02142 else 02143 return false; 02144 } 02145 02146 void KMKernel::emergencyExit( const TQString& reason ) 02147 { 02148 TQString mesg; 02149 if ( reason.length() == 0 ) { 02150 mesg = i18n("KMail encountered a fatal error and will terminate now"); 02151 } else { 02152 mesg = i18n("KMail encountered a fatal error and will " 02153 "terminate now.\nThe error was:\n%1").arg( reason ); 02154 } 02155 02156 kdWarning() << mesg << endl; 02157 KNotifyClient::userEvent( 0, "<qt>"+mesg+"</qt>", KNotifyClient::Messagebox, KNotifyClient::Error ); 02158 02159 ::exit(1); 02160 } 02161 02165 bool KMKernel::folderIsDraftOrOutbox(const KMFolder * folder) 02166 { 02167 assert( folder ); 02168 if ( folder == the_outboxFolder ) 02169 return true; 02170 return folderIsDrafts( folder ); 02171 } 02172 02173 bool KMKernel::folderIsDrafts(const KMFolder * folder) 02174 { 02175 assert( folder ); 02176 if ( folder == the_draftsFolder ) 02177 return true; 02178 02179 TQString idString = folder->idString(); 02180 if ( idString.isEmpty() ) 02181 return false; 02182 02183 // search the identities if the folder matches the drafts-folder 02184 const KPIM::IdentityManager *im = identityManager(); 02185 for ( KPIM::IdentityManager::ConstIterator it=im->begin(); it != im->end(); ++it ) 02186 if ( (*it).drafts() == idString ) 02187 return true; 02188 return false; 02189 } 02190 02191 bool KMKernel::folderIsTemplates( const KMFolder *folder ) 02192 { 02193 assert( folder ); 02194 if ( folder == the_templatesFolder ) 02195 return true; 02196 02197 TQString idString = folder->idString(); 02198 if ( idString.isEmpty() ) 02199 return false; 02200 02201 // search the identities if the folder matches the templates-folder 02202 const KPIM::IdentityManager *im = identityManager(); 02203 for ( KPIM::IdentityManager::ConstIterator it=im->begin(); it != im->end(); ++it ) 02204 if ( (*it).templates() == idString ) 02205 return true; 02206 return false; 02207 } 02208 02209 bool KMKernel::folderIsTrash(KMFolder * folder) 02210 { 02211 assert(folder); 02212 if (folder == the_trashFolder) return true; 02213 TQStringList actList = acctMgr()->getAccounts(); 02214 TQStringList::Iterator it( actList.begin() ); 02215 for( ; it != actList.end() ; ++it ) { 02216 KMAccount* act = acctMgr()->findByName( *it ); 02217 if ( act && ( act->trash() == folder->idString() ) ) 02218 return true; 02219 } 02220 return false; 02221 } 02222 02223 bool KMKernel::folderIsSentMailFolder( const KMFolder * folder ) 02224 { 02225 assert( folder ); 02226 if ( folder == the_sentFolder ) 02227 return true; 02228 02229 TQString idString = folder->idString(); 02230 if ( idString.isEmpty() ) return false; 02231 02232 // search the identities if the folder matches the sent-folder 02233 const KPIM::IdentityManager * im = identityManager(); 02234 for( KPIM::IdentityManager::ConstIterator it = im->begin(); it != im->end(); ++it ) 02235 if ( (*it).fcc() == idString ) return true; 02236 return false; 02237 } 02238 02239 KPIM::IdentityManager * KMKernel::identityManager() { 02240 if ( !mIdentityManager ) { 02241 kdDebug(5006) << "instantating KPIM::IdentityManager" << endl; 02242 mIdentityManager = new KPIM::IdentityManager( false, this, "mIdentityManager" ); 02243 } 02244 return mIdentityManager; 02245 } 02246 02247 KMMsgIndex *KMKernel::msgIndex() 02248 { 02249 return the_msgIndex; 02250 } 02251 02252 TDEMainWindow* KMKernel::mainWin() 02253 { 02254 if (TDEMainWindow::memberList) { 02255 TDEMainWindow *kmWin = 0; 02256 02257 // First look for a KMMainWin. 02258 for (kmWin = TDEMainWindow::memberList->first(); kmWin; 02259 kmWin = TDEMainWindow::memberList->next()) 02260 if (kmWin->isA("KMMainWin")) 02261 return kmWin; 02262 02263 // There is no KMMainWin. Use any other TDEMainWindow instead (e.g. in 02264 // case we are running inside Kontact) because we anyway only need 02265 // it for modal message boxes and for KNotify events. 02266 kmWin = TDEMainWindow::memberList->first(); 02267 if ( kmWin ) 02268 return kmWin; 02269 } 02270 02271 // There's not a single TDEMainWindow. Create a KMMainWin. 02272 // This could happen if we want to pop up an error message 02273 // while we are still doing the startup wizard and no other 02274 // TDEMainWindow is running. 02275 mWin = new KMMainWin; 02276 return mWin; 02277 } 02278 02279 02283 void KMKernel::slotEmptyTrash() 02284 { 02285 TQString title = i18n("Empty Trash"); 02286 TQString text = i18n("Are you sure you want to empty the trash folders of all accounts?"); 02287 if (KMessageBox::warningContinueCancel(0, text, title, 02288 KStdGuiItem::cont(), "confirm_empty_trash") 02289 != KMessageBox::Continue) 02290 { 02291 return; 02292 } 02293 02294 for (KMAccount* acct = acctMgr()->first(); acct; acct = acctMgr()->next()) 02295 { 02296 KMFolder* trash = findFolderById(acct->trash()); 02297 if (trash) 02298 { 02299 trash->expunge(); 02300 } 02301 } 02302 } 02303 02304 TDEConfig* KMKernel::config() 02305 { 02306 assert(mySelf); 02307 if (!mySelf->mConfig) 02308 { 02309 mySelf->mConfig = TDESharedConfig::openConfig( "kmailrc" ); 02310 // Check that all updates have been run on the config file: 02311 KMail::checkConfigUpdates(); 02312 } 02313 return mySelf->mConfig; 02314 } 02315 02316 KMailICalIfaceImpl& KMKernel::iCalIface() 02317 { 02318 assert( mICalIface ); 02319 return *mICalIface; 02320 } 02321 02322 void KMKernel::selectFolder( TQString folderPath ) 02323 { 02324 kdDebug(5006)<<"Selecting a folder "<<folderPath<<endl; 02325 const TQString localPrefix = "/Local"; 02326 KMFolder *folder = kmkernel->folderMgr()->getFolderByURL( folderPath ); 02327 if ( !folder && folderPath.startsWith( localPrefix ) ) 02328 folder = the_folderMgr->getFolderByURL( folderPath.mid( localPrefix.length() ) ); 02329 if ( !folder ) 02330 folder = kmkernel->imapFolderMgr()->getFolderByURL( folderPath ); 02331 if ( !folder ) 02332 folder = kmkernel->dimapFolderMgr()->getFolderByURL( folderPath ); 02333 Q_ASSERT( folder ); 02334 02335 KMMainWidget *widget = getKMMainWidget(); 02336 Q_ASSERT( widget ); 02337 if ( !widget ) 02338 return; 02339 02340 KMFolderTree *tree = widget->folderTree(); 02341 tree->doFolderSelected( tree->indexOfFolder( folder ) ); 02342 tree->ensureItemVisible( tree->indexOfFolder( folder ) ); 02343 } 02344 02345 KMMainWidget *KMKernel::getKMMainWidget() 02346 { 02347 //This could definitely use a speadup 02348 TQWidgetList *l = kapp->topLevelWidgets(); 02349 TQWidgetListIt it( *l ); 02350 TQWidget *wid; 02351 02352 while ( ( wid = it.current() ) != 0 ) { 02353 ++it; 02354 TQObjectList *l2 = wid->topLevelWidget()->queryList( "KMMainWidget" ); 02355 if (l2 && l2->first()) { 02356 KMMainWidget* kmmw = dynamic_cast<KMMainWidget *>( l2->first() ); 02357 Q_ASSERT( kmmw ); 02358 delete l2; 02359 delete l; 02360 return kmmw; 02361 } 02362 delete l2; 02363 } 02364 delete l; 02365 return 0; 02366 } 02367 02368 void KMKernel::slotRunBackgroundTasks() // called regularly by timer 02369 { 02370 // Hidden TDEConfig keys. Not meant to be used, but a nice fallback in case 02371 // a stable kmail release goes out with a nasty bug in CompactionJob... 02372 TDEConfigGroup generalGroup( config(), "General" ); 02373 02374 if ( generalGroup.readBoolEntry( "auto-expiring", true ) ) { 02375 the_folderMgr->expireAllFolders( false /*scheduled, not immediate*/ ); 02376 the_imapFolderMgr->expireAllFolders( false /*scheduled, not immediate*/ ); 02377 the_dimapFolderMgr->expireAllFolders( false /*scheduled, not immediate*/ ); 02378 // the_searchFolderMgr: no expiry there 02379 } 02380 02381 if ( generalGroup.readBoolEntry( "auto-compaction", true ) ) { 02382 the_folderMgr->compactAllFolders( false /*scheduled, not immediate*/ ); 02383 // the_imapFolderMgr: no compaction 02384 the_dimapFolderMgr->compactAllFolders( false /*scheduled, not immediate*/ ); 02385 // the_searchFolderMgr: no compaction 02386 } 02387 02388 #ifdef DEBUG_SCHEDULER // for debugging, see jobscheduler.h 02389 mBackgroundTasksTimer->start( 60 * 1000, true ); // check again in 1 minute 02390 #else 02391 mBackgroundTasksTimer->start( 4 * 60 * 60 * 1000, true ); // check again in 4 hours 02392 #endif 02393 02394 } 02395 02396 void KMKernel::expireAllFoldersNow() // called by the GUI 02397 { 02398 the_folderMgr->expireAllFolders( true /*immediate*/ ); 02399 the_imapFolderMgr->expireAllFolders( true /*immediate*/ ); 02400 the_dimapFolderMgr->expireAllFolders( true /*immediate*/ ); 02401 } 02402 02403 void KMKernel::compactAllFolders() // called by the GUI 02404 { 02405 the_folderMgr->compactAllFolders( true /*immediate*/ ); 02406 //the_imapFolderMgr->compactAllFolders( true /*immediate*/ ); 02407 the_dimapFolderMgr->compactAllFolders( true /*immediate*/ ); 02408 } 02409 02410 KMFolder* KMKernel::findFolderById( const TQString& idString ) 02411 { 02412 KMFolder * folder = the_folderMgr->findIdString( idString ); 02413 if ( !folder ) 02414 folder = the_imapFolderMgr->findIdString( idString ); 02415 if ( !folder ) 02416 folder = the_dimapFolderMgr->findIdString( idString ); 02417 if ( !folder ) 02418 folder = the_searchFolderMgr->findIdString( idString ); 02419 return folder; 02420 } 02421 02422 ::KIMProxy* KMKernel::imProxy() 02423 { 02424 return KIMProxy::instance( kapp->dcopClient() ); 02425 } 02426 02427 void KMKernel::enableMailCheck() 02428 { 02429 mMailCheckAborted = false; 02430 } 02431 02432 bool KMKernel::mailCheckAborted() const 02433 { 02434 return mMailCheckAborted; 02435 } 02436 02437 void KMKernel::abortMailCheck() 02438 { 02439 mMailCheckAborted = true; 02440 } 02441 02442 bool KMKernel::canQueryClose() 02443 { 02444 if ( KMMainWidget::mainWidgetList() && 02445 KMMainWidget::mainWidgetList()->count() > 1 ) 02446 return true; 02447 KMMainWidget *widget = getKMMainWidget(); 02448 if ( !widget ) 02449 return true; 02450 KMSystemTray* systray = widget->systray(); 02451 if ( !systray || GlobalSettings::closeDespiteSystemTray() ) 02452 return true; 02453 if ( systray->mode() == GlobalSettings::EnumSystemTrayPolicy::ShowAlways ) { 02454 systray->hideKMail(); 02455 return false; 02456 } else if ( ( systray->mode() == GlobalSettings::EnumSystemTrayPolicy::ShowOnUnread ) && ( systray->hasUnreadMail() )) { 02457 systray->show(); 02458 systray->hideKMail(); 02459 return false; 02460 } 02461 return true; 02462 } 02463 02464 void KMKernel::messageCountChanged() 02465 { 02466 mTimeOfLastMessageCountChange = ::time( 0 ); 02467 } 02468 02469 int KMKernel::timeOfLastMessageCountChange() const 02470 { 02471 return mTimeOfLastMessageCountChange; 02472 } 02473 02474 bool KMKernel::networkStateConnected() 02475 { 02476 #ifdef __TDE_HAVE_TDEHWLIB 02477 if (mNetworkManager) { 02478 TDENetworkGlobalManagerFlags::TDENetworkGlobalManagerFlags networkStatus = mNetworkManager->backendStatus(); 02479 if ((networkStatus & TDENetworkGlobalManagerFlags::Connected) 02480 || (networkStatus & TDENetworkGlobalManagerFlags::BackendUnavailable) 02481 || (networkStatus == TDENetworkGlobalManagerFlags::Unknown) 02482 ){ 02483 // Connected or no backend available 02484 return true; 02485 } 02486 else { 02487 // Not connected 02488 return false; 02489 } 02490 } 02491 else { 02492 // Assume connected 02493 return true; 02494 } 02495 #endif 02496 return true; 02497 } 02498 02499 void KMKernel::slotNetworkStateChanged(TDENetworkConnectionStatus::TDENetworkConnectionStatus, TDENetworkConnectionStatus::TDENetworkConnectionStatus, TQString) 02500 { 02501 if (networkStateConnected()) { 02502 resumeNetworkJobs(); 02503 } 02504 else { 02505 stopNetworkJobs(); 02506 } 02507 } 02508 02509 Wallet *KMKernel::wallet() { 02510 static bool walletOpenFailed = false; 02511 if ( mWallet && mWallet->isOpen() ) 02512 return mWallet; 02513 02514 if ( !Wallet::isEnabled() || walletOpenFailed ) 02515 return 0; 02516 02517 // find an appropriate parent window for the wallet dialog 02518 WId window = 0; 02519 if ( tqApp->activeWindow() ) 02520 window = tqApp->activeWindow()->winId(); 02521 else if ( getKMMainWidget() ) 02522 window = getKMMainWidget()->topLevelWidget()->winId(); 02523 02524 delete mWallet; 02525 mWallet = Wallet::openWallet( Wallet::NetworkWallet(), window ); 02526 02527 if ( !mWallet ) { 02528 walletOpenFailed = true; 02529 return 0; 02530 } 02531 02532 if ( !mWallet->hasFolder( "kmail" ) ) 02533 mWallet->createFolder( "kmail" ); 02534 mWallet->setFolder( "kmail" ); 02535 return mWallet; 02536 } 02537 02538 TQValueList< TQGuardedPtr<KMFolder> > KMKernel::allFolders() 02539 { 02540 TQStringList names; 02541 TQValueList<TQGuardedPtr<KMFolder> > folders; 02542 folderMgr()->createFolderList(&names, &folders); 02543 imapFolderMgr()->createFolderList(&names, &folders); 02544 dimapFolderMgr()->createFolderList(&names, &folders); 02545 searchFolderMgr()->createFolderList(&names, &folders); 02546 02547 return folders; 02548 } 02549 02550 KMFolder *KMKernel::currentFolder() { 02551 KMMainWidget *widget = getKMMainWidget(); 02552 KMFolder *folder = 0; 02553 if ( widget && widget->folderTree() ) { 02554 folder = widget->folderTree()->currentFolder(); 02555 } 02556 return folder; 02557 } 02558 02559 // can't be inline, since KMSender isn't known to implement 02560 // KMail::MessageSender outside this .cpp file 02561 KMail::MessageSender * KMKernel::msgSender() { return the_msgSender; } 02562 02563 #include "kmkernel.moc"