1 /* -*- mode: C++; c-file-style: "gnu" -*- */
3 #include <config-kmail.h>
6 #include "globalsettings.h"
7 #include "broadcaststatus.h"
8 using KPIM::BroadcastStatus
;
10 #include "kmmainwin.h"
12 #include "kmmsgpart.h"
13 #include "kmreadermainwin.h"
14 #include "kmfoldermgr.h"
15 #include "kmfoldercachedimap.h"
16 #include "kmacctcachedimap.h"
17 #include "kmfiltermgr.h"
18 #include "kmfilteraction.h"
19 #define REALLY_WANT_KMSENDER
21 #undef REALLY_WANT_KMSENDER
22 #include "undostack.h"
23 #include "accountmanager.h"
24 using KMail::AccountManager
;
25 #include <kpimutils/kfileio.h>
26 #include "kmversion.h"
27 #include "kmreaderwin.h"
28 #include "kmmainwidget.h"
29 #include "kmfoldertree.h"
30 #include "recentaddresses.h"
31 using KPIM::RecentAddresses
;
32 #include "kmmsgdict.h"
33 #include <kpimidentities/identity.h>
34 #include <kpimidentities/identitymanager.h>
35 #include "configuredialog.h"
36 #include "kmcommands.h"
37 #include "kmsystemtray.h"
39 #include <mailtransport/transport.h>
40 #include <mailtransport/transportmanager.h>
42 #include <kwindowsystem.h>
43 #include "kmailicalifaceimpl.h"
44 #include "mailserviceimpl.h"
45 using KMail::MailServiceImpl
;
46 #include "jobscheduler.h"
47 #include "templateparser.h"
48 using KMail::TemplateParser
;
50 #include <kmessagebox.h>
51 #include <knotification.h>
52 #include <kstandarddirs.h>
54 #include <kpassivepopup.h>
55 #include <kapplication.h>
56 #include <ksystemtrayicon.h>
57 #include <kconfiggroup.h>
58 #include <libkpgp/kpgp.h>
60 #include <kio/netaccess.h>
62 using KWallet::Wallet
;
63 #include "actionscheduler.h"
71 #include <sys/types.h>
79 #include <kcmdlineargs.h>
80 #include <kstartupinfo.h>
81 #include <kmailadaptor.h>
82 #include "kmailinterface.h"
83 KMKernel
*KMKernel::mySelf
= 0;
84 #include "folderadaptor.h"
85 #include "kmail_util.h"
87 /********************************************************************/
88 /* Constructor and destructor */
89 /********************************************************************/
90 KMKernel::KMKernel (QObject
*parent
, const char *name
) :
92 mIdentityManager(0), mConfigureDialog(0), mICalIface(0), mMailService(0),
93 mContextMenuShown( false ), mWallet( 0 )
96 setObjectName( name
);
98 the_startingUp
= true;
99 closed_by_user
= true;
100 the_firstInstance
= true;
103 the_outboxFolder
= 0;
106 the_draftsFolder
= 0;
107 the_templatesFolder
= 0;
110 the_imapFolderMgr
= 0;
111 the_dimapFolderMgr
= 0;
112 the_searchFolderMgr
= 0;
116 the_popFilterMgr
= 0;
117 the_filterActionDict
= 0;
121 mMailCheckAborted
= false;
123 // make sure that we check for config updates before doing anything else
125 // this shares the kmailrc parsing too (via KSharedConfig), and reads values from it
126 // so better do it here, than in some code where changing the group of config()
127 // would be unexpected
128 GlobalSettings::self();
130 mJobScheduler
= new JobScheduler( this );
132 mXmlGuiInstance
= KComponentData();
136 // In the case of Japan. Japanese locale name is "eucjp" but
137 // The Japanese mail systems normally used "iso-2022-jp" of locale name.
138 // We want to change locale name from eucjp to iso-2022-jp at KMail only.
139 if ( QByteArray(QTextCodec::codecForLocale()->name()).toLower() == "eucjp" )
141 netCodec
= QTextCodec::codecForName("jis7");
142 // QTextCodec *cdc = QTextCodec::codecForName("jis7");
143 // QTextCodec::setCodecForLocale(cdc);
144 // KGlobal::locale()->setEncoding(cdc->mibEnum());
146 netCodec
= QTextCodec::codecForLocale();
149 connect( MailTransport::TransportManager::self(),
150 SIGNAL(transportRemoved(int,QString
)),
151 SLOT(transportRemoved(int,QString
)) );
152 connect( MailTransport::TransportManager::self(),
153 SIGNAL(transportRenamed(int,QString
,QString
)),
154 SLOT(transportRenamed(int,QString
,QString
)) );
157 KMKernel::~KMKernel ()
159 QMap
<KIO::Job
*, putData
>::Iterator it
= mPutJobs
.begin();
160 while ( it
!= mPutJobs
.end() )
162 KIO::Job
*job
= it
.key();
163 mPutJobs
.erase( it
);
165 it
= mPutJobs
.begin();
173 GlobalSettings::self()->writeConfig();
180 void KMKernel::setupDBus()
182 (void) new KmailAdaptor( this );
183 QDBusConnection::sessionBus().registerObject("/KMail", this);
184 mICalIface
= new KMailICalIfaceImpl();
185 mICalIface
->readConfig();
186 mMailService
= new MailServiceImpl();
189 bool KMKernel::handleCommandLine( bool noArgsOpensReader
)
191 QString to
, cc
, bcc
, subj
, body
;
192 QStringList customHeaders
;
194 KUrl::List attachURLs
;
196 bool checkMail
= false;
197 bool viewOnly
= false;
198 bool calledWithSession
= false; // for ignoring '-session foo'
201 KCmdLineArgs
*args
= KCmdLineArgs::parsedArgs();
202 if (args
->isSet("subject"))
204 subj
= args
->getOption("subject");
205 // if kmail is called with 'kmail -session abc' then this doesn't mean
206 // that the user wants to send a message with subject "ession" but
207 // (most likely) that the user clicked on KMail's system tray applet
208 // which results in KMKernel::raise() calling "kmail kmail newInstance"
209 // via dcop which apparently executes the application with the original
210 // command line arguments and those include "-session ..." if
211 // kmail/kontact was restored by session management
212 if ( subj
== "ession" ) {
214 calledWithSession
= true;
220 if (args
->isSet("cc"))
223 cc
= args
->getOption("cc");
226 if (args
->isSet("bcc"))
229 bcc
= args
->getOption("bcc");
232 if (args
->isSet("msg"))
235 messageFile
.setPath( args
->getOption("msg") );
238 if (args
->isSet("body"))
241 body
= args
->getOption("body");
244 QStringList attachList
= args
->getOptionList("attach");
245 if (!attachList
.isEmpty())
248 for ( QStringList::Iterator it
= attachList
.begin() ; it
!= attachList
.end() ; ++it
)
249 if ( !(*it
).isEmpty() )
250 attachURLs
+= KUrl( *it
);
253 customHeaders
= args
->getOptionList("header");
255 if (args
->isSet("composer"))
258 if (args
->isSet("check"))
261 if ( args
->isSet( "view" ) ) {
263 const QString filename
=
264 args
->getOption( "view" );
265 messageFile
= KUrl( filename
);
266 if ( !messageFile
.isValid() ) {
267 messageFile
= KUrl();
268 messageFile
.setPath( filename
);
272 if ( !calledWithSession
) {
273 // only read additional command line arguments if kmail/kontact is
274 // not called with "-session foo"
275 for(int i
= 0; i
< args
->count(); i
++)
277 if (args
->arg(i
).startsWith("mailto:", Qt::CaseInsensitive
))
278 to
+= args
->url(i
).path() + ", ";
280 QString tmpArg
= args
->arg(i
);
289 if ( !to
.isEmpty() ) {
290 // cut off the superfluous trailing ", "
291 to
.truncate( to
.length() - 2 );
295 if ( !calledWithSession
)
298 if ( !noArgsOpensReader
&& !mailto
&& !checkMail
&& !viewOnly
)
302 viewMessage( messageFile
);
304 action( mailto
, checkMail
, to
, cc
, bcc
, subj
, body
, messageFile
,
305 attachURLs
, customHeaders
);
309 /********************************************************************/
310 /* DCOP-callable, and command line actions */
311 /********************************************************************/
312 void KMKernel::checkMail () //might create a new reader but won't show!!
314 kmkernel
->acctMgr()->checkMail(false);
317 QStringList
KMKernel::accounts()
319 return kmkernel
->acctMgr()->getAccounts();
322 void KMKernel::checkAccount (const QString
&account
) //might create a new reader but won't show!!
324 kDebug(5006) <<"KMKernel::checkMail called";
326 KMAccount
* acct
= kmkernel
->acctMgr()->findByName(account
);
328 kmkernel
->acctMgr()->singleCheckMail(acct
, false);
331 void KMKernel::openReader( bool onlyCheck
)
334 KMainWindow
*ktmw
= 0;
335 kDebug(5006) <<"KMKernel::openReader called";
337 foreach ( KMainWindow
*window
, KMainWindow::memberList() )
339 if ( ::qobject_cast
<KMMainWin
*>( window
) )
348 mWin
= (KMMainWin
*) ktmw
;
349 activate
= !onlyCheck
; // existing window: only activate if not --check
354 mWin
= new KMMainWin
;
356 activate
= false; // new window: no explicit activation (#73591)
360 // Activate window - doing this instead of KWindowSystem::activateWindow(mWin->winId());
361 // so that it also works when called from KMailApplication::newInstance()
362 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
363 KStartupInfo::setNewStartupId( mWin
, kapp
->startupId() );
368 int KMKernel::openComposer( const QString
&to
, const QString
&cc
,
369 const QString
&bcc
, const QString
&subject
,
370 const QString
&body
, int hidden
,
371 const KUrl
&messageFile
,
372 const KUrl::List
&attachURLs
,
373 const QStringList
&customHeaders
)
375 kDebug(5006) <<"KMKernel::openComposer called";
376 KMMessage
*msg
= new KMMessage
;
378 msg
->setCharset("utf-8");
379 // tentatively decode to, cc and bcc because invokeMailer calls us with
380 // RFC 2047 encoded addresses in order to protect non-ASCII email addresses
382 msg
->setTo( KMMsgBase::decodeRFC2047String( to
.toLatin1() ) );
384 msg
->setCc( KMMsgBase::decodeRFC2047String( cc
.toLatin1() ) );
386 msg
->setBcc( KMMsgBase::decodeRFC2047String( bcc
.toLatin1() ) );
387 if (!subject
.isEmpty()) msg
->setSubject(subject
);
388 if (!messageFile
.isEmpty() && messageFile
.isLocalFile()) {
389 QByteArray str
= KPIMUtils::kFileToByteArray( messageFile
.path(), true, false );
390 if( !str
.isEmpty() ) {
391 msg
->setBody( QString::fromLocal8Bit( str
.data(), str
.size() ).toUtf8() );
394 TemplateParser
parser( msg
, TemplateParser::NewMessage
,
395 QString(), false, false, false );
396 parser
.process( NULL
, NULL
);
399 else if (!body
.isEmpty()) {
400 msg
->setBody(body
.toUtf8());
403 TemplateParser
parser( msg
, TemplateParser::NewMessage
,
404 QString(), false, false, false );
405 parser
.process( NULL
, NULL
);
408 if (!customHeaders
.isEmpty())
410 for ( QStringList::ConstIterator it
= customHeaders
.begin() ; it
!= customHeaders
.end() ; ++it
)
411 if ( !(*it
).isEmpty() )
413 const int pos
= (*it
).find( ':' );
416 QString header
= (*it
).left( pos
).trimmed();
417 QString value
= (*it
).mid( pos
+1 ).trimmed();
418 if ( !header
.isEmpty() && !value
.isEmpty() )
419 msg
->setHeaderField( header
.toUtf8(), value
);
424 KMail::Composer
* cWin
= KMail::makeComposer( msg
);
425 cWin
->setCharset("", true);
426 for ( KUrl::List::ConstIterator it
= attachURLs
.begin() ; it
!= attachURLs
.end() ; ++it
)
427 cWin
->addAttach((*it
));
430 // Activate window - doing this instead of KWindowSystem::activateWindow(cWin->winId());
431 // so that it also works when called from KMailApplication::newInstance()
432 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
433 KStartupInfo::setNewStartupId( cWin
, kapp
->startupId() );
439 int KMKernel::openComposer (const QString
&to
, const QString
&cc
,
440 const QString
&bcc
, const QString
&subject
,
441 const QString
&body
, int hidden
,
442 const QString
&attachName
,
443 const QByteArray
&attachCte
,
444 const QByteArray
&attachData
,
445 const QByteArray
&attachType
,
446 const QByteArray
&attachSubType
,
447 const QByteArray
&attachParamAttr
,
448 const QString
&attachParamValue
,
449 const QByteArray
&attachContDisp
,
450 const QByteArray
&attachCharset
)
452 kDebug(5006) <<"KMKernel::openComposer()";
454 KMMessage
*msg
= new KMMessage
;
455 KMMessagePart
*msgPart
= 0;
457 msg
->setCharset( "utf-8" );
458 if ( !cc
.isEmpty() ) msg
->setCc(cc
);
459 if ( !bcc
.isEmpty() ) msg
->setBcc(bcc
);
460 if ( !subject
.isEmpty() ) msg
->setSubject(subject
);
461 if ( !to
.isEmpty() ) msg
->setTo(to
);
462 if ( !body
.isEmpty() ) {
463 msg
->setBody(body
.toUtf8());
465 TemplateParser
parser( msg
, TemplateParser::NewMessage
,
466 QString(), false, false, false );
467 parser
.process( NULL
, NULL
);
470 bool iCalAutoSend
= false;
471 bool noWordWrap
= false;
472 bool isICalInvitation
= false;
473 KConfigGroup
options( config(), "Groupware" );
474 if ( !attachData
.isEmpty() ) {
475 isICalInvitation
= attachName
== "cal.ics" &&
476 attachType
== "text" &&
477 attachSubType
== "calendar" &&
478 attachParamAttr
== "method";
479 // Remove BCC from identity on ical invitations (https://intevation.de/roundup/kolab/issue474)
480 if ( isICalInvitation
&& bcc
.isEmpty() )
482 if ( isICalInvitation
&&
483 GlobalSettings::self()->legacyBodyInvites() ) {
484 // KOrganizer invitation caught and to be sent as body instead
485 msg
->setBody( attachData
);
486 msg
->setHeaderField( "Content-Type",
487 QString( "text/calendar; method=%1; "
488 "charset=\"utf-8\"" ).
489 arg( attachParamValue
) );
491 iCalAutoSend
= true; // no point in editing raw ICAL
492 noWordWrap
= true; // we shant word wrap inline invitations
494 // Just do what we're told to do
495 msgPart
= new KMMessagePart
;
496 msgPart
->setName( attachName
);
497 msgPart
->setCteStr( attachCte
);
498 msgPart
->setBodyEncoded( attachData
);
499 msgPart
->setTypeStr( attachType
);
500 msgPart
->setSubtypeStr( attachSubType
);
501 msgPart
->setParameter( attachParamAttr
, attachParamValue
);
502 if( ! GlobalSettings::self()->exchangeCompatibleInvitations() ) {
503 msgPart
->setContentDisposition( attachContDisp
);
505 if( !attachCharset
.isEmpty() ) {
506 // kDebug(5006) <<"KMKernel::openComposer set attachCharset to"
508 msgPart
->setCharset( attachCharset
);
510 // Don't show the composer window, if the automatic sending is checked
511 KConfigGroup
options( config(), "Groupware" );
512 iCalAutoSend
= options
.readEntry( "AutomaticSending", true );
516 KMail::Composer
* cWin
= KMail::makeComposer();
517 cWin
->setMsg( msg
, !isICalInvitation
/* mayAutoSign */ );
518 cWin
->setSigningAndEncryptionDisabled( isICalInvitation
519 && GlobalSettings::self()->legacyBodyInvites() );
520 cWin
->setAutoDelete( true );
522 cWin
->slotWordWrapToggled( false );
524 cWin
->setCharset( "", true );
526 cWin
->addAttach(msgPart
);
528 if ( hidden
== 0 && !iCalAutoSend
) {
530 // Activate window - doing this instead of KWin::activateWindow(cWin->winId());
531 // so that it also works when called from KMailApplication::newInstance()
532 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
533 KStartupInfo::setNewStartupId( cWin
, kapp
->startupId() );
542 void KMKernel::setDefaultTransport( const QString
& transport
)
544 MailTransport::Transport
*t
= MailTransport::TransportManager::self()->transportByName( transport
, false );
546 kWarning(5006) <<"The transport you entered is not available";
549 MailTransport::TransportManager::self()->setDefaultTransport( t
->id() );
552 QDBusObjectPath
KMKernel::openComposer(const QString
&to
, const QString
&cc
,
553 const QString
&bcc
, const QString
&subject
,
554 const QString
&body
,bool hidden
)
556 KMMessage
*msg
= new KMMessage
;
558 msg
->setCharset("utf-8");
559 if (!cc
.isEmpty()) msg
->setCc(cc
);
560 if (!bcc
.isEmpty()) msg
->setBcc(bcc
);
561 if (!subject
.isEmpty()) msg
->setSubject(subject
);
562 if (!to
.isEmpty()) msg
->setTo(to
);
563 if ( !body
.isEmpty() ) {
564 msg
->setBody(body
.toUtf8());
566 TemplateParser
parser( msg
, TemplateParser::NewMessage
,
567 QString(), false, false, false );
568 parser
.process( NULL
, NULL
);
571 KMail::Composer
* cWin
= KMail::makeComposer( msg
);
572 cWin
->setCharset("", true);
575 // Activate window - doing this instead of KWindowSystem::activateWindow(cWin->winId());
576 // so that it also works when called from KMailApplication::newInstance()
577 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
578 KStartupInfo::setNewStartupId( cWin
, kapp
->startupId() );
582 return QDBusObjectPath(cWin
->dbusObjectPath());
585 QDBusObjectPath
KMKernel::newMessage(const QString
&to
,
590 const QString
& /*messageFile*/,
591 const QString
&_attachURL
)
593 KUrl
attachURL(_attachURL
);
594 KMail::Composer
* win
= 0;
595 KMMessage
*msg
= new KMMessage
;
596 KMFolder
*folder
= NULL
;
600 //create message with required folder identity
601 folder
= currentFolder();
602 id
= folder
? folder
->identity() : 0;
603 msg
->initHeader( id
);
604 win
= makeComposer( msg
, id
);
607 win
= makeComposer( msg
);
609 msg
->setCharset("utf-8");
611 if (!to
.isEmpty()) msg
->setTo(to
);
612 if (!cc
.isEmpty()) msg
->setCc(cc
);
613 if (!bcc
.isEmpty()) msg
->setBcc(bcc
);
616 TemplateParser
parser( msg
, TemplateParser::NewMessage
,
617 QString(), false, false, false );
618 parser
.process( NULL
, folder
);
619 win
= makeComposer( msg
, id
);
621 TemplateParser
parser( msg
, TemplateParser::NewMessage
,
622 QString(), false, false, false );
623 parser
.process( NULL
, NULL
);
624 win
= makeComposer( msg
);
627 //Add the attachment if we have one
628 if(!attachURL
.isEmpty() && attachURL
.isValid()) {
629 win
->addAttach(attachURL
);
632 //only show window when required
636 return QDBusObjectPath(win
->dbusObjectPath());
639 int KMKernel::viewMessage( const KUrl
& messageFile
)
641 KMOpenMsgCommand
*openCommand
= new KMOpenMsgCommand( 0, messageFile
);
643 openCommand
->start();
648 int KMKernel::sendCertificate( const QString
& to
, const QByteArray
& certData
)
650 KMMessage
*msg
= new KMMessage
;
652 msg
->setCharset("utf-8");
653 msg
->setSubject( i18n( "Certificate Signature Request" ) );
654 if (!to
.isEmpty()) msg
->setTo(to
);
655 // ### Make this message customizable via KIOSK
656 msg
->setBody( i18n( "Please create a certificate from attachment and return to sender." ).toUtf8() );
658 KMail::Composer
* cWin
= KMail::makeComposer( msg
);
659 cWin
->setCharset("", true);
660 cWin
->slotSetAlwaysSend( true );
661 if (!certData
.isEmpty()) {
662 KMMessagePart
*msgPart
= new KMMessagePart
;
663 msgPart
->setName("smime.p10");
664 msgPart
->setCteStr("base64");
665 msgPart
->setBodyEncodedBinary(certData
);
666 msgPart
->setTypeStr("application");
667 msgPart
->setSubtypeStr("pkcs10");
668 msgPart
->setContentDisposition("attachment; filename=smime.p10");
669 cWin
->addAttach(msgPart
);
676 int KMKernel::dbusAddMessage( const QString
& foldername
, const QString
& msgUrlString
,
677 const QString
& MsgStatusFlags
)
679 return dbusAddMessage(foldername
, KUrl(msgUrlString
), MsgStatusFlags
);
682 int KMKernel::dbusAddMessage( const QString
& foldername
,const KUrl
& msgUrl
,
683 const QString
& MsgStatusFlags
)
685 kDebug(5006) <<"KMKernel::dbusAddMessage called";
687 if ( foldername
.isEmpty() || foldername
.startsWith('.'))
691 bool readFolderMsgIds
= false;
692 QString _foldername
= foldername
.trimmed();
693 _foldername
= _foldername
.replace('\\',""); //try to prevent ESCAPE Sequences
695 if ( foldername
!= mAddMessageLastFolder
) {
696 mAddMessageMsgIds
.clear();
697 readFolderMsgIds
= true;
698 mAddMessageLastFolder
= foldername
;
701 if (!msgUrl
.isEmpty() && msgUrl
.isLocalFile()) {
703 const QByteArray messageText
=
704 KPIMUtils::kFileToByteArray( msgUrl
.path(), true, false );
705 if ( messageText
.isEmpty() )
708 KMMessage
*msg
= new KMMessage();
709 msg
->fromString( messageText
);
711 if (readFolderMsgIds
) {
712 if ( foldername
.contains("/")) {
713 QString tmp_fname
= "";
714 KMFolder
*folder
= NULL
;
715 KMFolderDir
*subfolder
;
718 QStringList subFList
= _foldername
.split("/", QString::SkipEmptyParts
);
720 for ( QStringList::Iterator it
= subFList
.begin(); it
!= subFList
.end(); ++it
) {
721 QString _newFolder
= *it
;
722 if(_newFolder
.startsWith('.')) return -1;
725 folder
= the_folderMgr
->findOrCreate(*it
, false);
728 tmp_fname
= '/' + *it
;
733 subfolder
= folder
->createChildFolder();
734 tmp_fname
+= '/' + *it
;
735 if(!the_folderMgr
->getFolderByURL( tmp_fname
)) {
736 folder
= the_folderMgr
->createFolder(*it
, false, folder
->folderType(), subfolder
);
739 if(!(folder
= the_folderMgr
->getFolderByURL( tmp_fname
))) return -1;
743 mAddMsgCurrentFolder
= the_folderMgr
->getFolderByURL( tmp_fname
);
744 if(!folder
) return -1;
748 mAddMsgCurrentFolder
= the_folderMgr
->findOrCreate(_foldername
, false);
752 if ( mAddMsgCurrentFolder
) {
753 if (readFolderMsgIds
) {
756 // Try to determine if a message already exists in
757 // the folder. The message id that is searched for, is
758 // the subject line + the date. This should be quite
759 // unique. The change that a given date with a given
760 // subject is in the folder twice is very small.
761 // If the subject is empty, the fromStrip string
764 // NEW COMMENT from Danny Kukawka (danny.kukawka@web.de):
765 // subject line + the date is only unique if the following
766 // return a correct unique value:
767 // time_t DT = mb->date();
768 // QString dt = ctime(&DT);
769 // But if the datestring in the Header isn't RFC conform
770 // subject line + the date isn't unique.
772 // The only uique headerfield is the Message-ID. In some
773 // cases this could be empty. I then I use the
774 // subject line + dateStr .
778 mAddMsgCurrentFolder
->open( "dbusadd" );
779 for( i
=0; i
<mAddMsgCurrentFolder
->count(); i
++) {
780 KMMsgBase
*mb
= mAddMsgCurrentFolder
->getMsgBase(i
);
781 QString id
= mb
->msgIdMD5();
782 if ( id
.isEmpty() ) {
785 id
= mb
->fromStrip();
792 //fprintf(stderr,"%s\n",(const char *) id);
793 if ( !id
.isEmpty() ) {
794 mAddMessageMsgIds
.append(id
);
797 mAddMsgCurrentFolder
->close( "dbusadd" );
800 QString msgId
= msg
->msgIdMD5();
801 if ( msgId
.isEmpty()) {
802 msgId
= msg
->subject();
803 if ( msgId
.isEmpty() )
804 msgId
= msg
->fromStrip();
805 if ( msgId
.isEmpty() )
806 msgId
= msg
->toStrip();
808 msgId
+= msg
->dateStr();
811 int k
= mAddMessageMsgIds
.indexOf( msgId
);
812 //fprintf(stderr,"find %s = %d\n",(const char *) msgId,k);
815 if ( !msgId
.isEmpty() ) {
816 mAddMessageMsgIds
.append( msgId
);
819 if ( !MsgStatusFlags
.isEmpty() ) {
820 msg
->status().setStatusFromStr(MsgStatusFlags
);
824 if ( mAddMsgCurrentFolder
->addMsg( msg
, &index
) == 0 ) {
825 mAddMsgCurrentFolder
->unGetMsg( index
);
833 //qDebug( "duplicate: " + msgId + "; subj: " + msg->subject() + ", from: " + msgId = msg->fromStrip());
845 void KMKernel::dbusResetAddMessage()
847 mAddMessageMsgIds
.clear();
848 mAddMessageLastFolder
.clear();
851 int KMKernel::dbusAddMessage_fastImport( const QString
& foldername
,
852 const QString
& msgUrlString
,
853 const QString
& MsgStatusFlags
)
855 return dbusAddMessage_fastImport(foldername
, KUrl(msgUrlString
), MsgStatusFlags
);
858 int KMKernel::dbusAddMessage_fastImport( const QString
& foldername
,
860 const QString
& MsgStatusFlags
)
862 // Use this function to import messages without
863 // search for already existing emails.
864 kDebug(5006) <<"KMKernel::dbusAddMessage_fastImport called";
866 if ( foldername
.isEmpty() || foldername
.startsWith('.'))
870 bool createNewFolder
= false;
872 QString _foldername
= foldername
.trimmed();
873 _foldername
= _foldername
.replace('\\',""); //try to prevent ESCAPE Sequences
875 if ( foldername
!= mAddMessageLastFolder
) {
876 createNewFolder
= true;
877 mAddMessageLastFolder
= foldername
;
881 if ( !msgUrl
.isEmpty() && msgUrl
.isLocalFile() ) {
882 const QByteArray messageText
=
883 KPIMUtils::kFileToByteArray( msgUrl
.path(), true, false );
884 if ( messageText
.isEmpty() )
887 KMMessage
*msg
= new KMMessage();
888 msg
->fromString( messageText
);
890 if (createNewFolder
) {
891 if ( foldername
.contains("/")) {
892 QString tmp_fname
= "";
893 KMFolder
*folder
= NULL
;
894 KMFolderDir
*subfolder
;
897 QStringList subFList
= _foldername
.split("/", QString::SkipEmptyParts
);
899 for ( QStringList::Iterator it
= subFList
.begin(); it
!= subFList
.end(); ++it
) {
900 QString _newFolder
= *it
;
901 if(_newFolder
.startsWith('.')) return -1;
904 folder
= the_folderMgr
->findOrCreate(*it
, false);
907 tmp_fname
= '/' + *it
;
912 subfolder
= folder
->createChildFolder();
913 tmp_fname
+= '/' + *it
;
914 if(!the_folderMgr
->getFolderByURL( tmp_fname
)) {
915 folder
= the_folderMgr
->createFolder(*it
, false, folder
->folderType(), subfolder
);
917 if(!(folder
= the_folderMgr
->getFolderByURL( tmp_fname
))) return -1;
921 mAddMsgCurrentFolder
= the_folderMgr
->getFolderByURL( tmp_fname
);
922 if(!folder
) return -1;
926 mAddMsgCurrentFolder
= the_folderMgr
->findOrCreate(_foldername
, false);
930 if ( mAddMsgCurrentFolder
) {
933 if( !MsgStatusFlags
.isEmpty() ) {
934 msg
->status().setStatusFromStr(MsgStatusFlags
);
937 if ( mAddMsgCurrentFolder
->addMsg( msg
, &index
) == 0 ) {
938 mAddMsgCurrentFolder
->unGetMsg( index
);
955 QStringList
KMKernel::folderList() const
958 const QString localPrefix
= "/Local";
959 folders
<< localPrefix
;
960 the_folderMgr
->getFolderURLS( folders
, localPrefix
);
961 the_imapFolderMgr
->getFolderURLS( folders
);
962 the_dimapFolderMgr
->getFolderURLS( folders
);
966 QString
KMKernel::getFolder( const QString
& vpath
)
969 const QString localPrefix
= "/Local";
970 if ( the_folderMgr
->getFolderByURL( vpath
) )
972 else if ( vpath
.startsWith( localPrefix
) && the_folderMgr
->getFolderByURL( vpath
.mid( localPrefix
.length() ) ) )
973 adaptorName
=vpath
.mid( localPrefix
.length() );
974 else if ( the_imapFolderMgr
->getFolderByURL( vpath
) )
976 else if (the_dimapFolderMgr
->getFolderByURL( vpath
) )
978 if( !adaptorName
.isEmpty())
982 folderAdaptor
->unregisterobject();
983 delete folderAdaptor
;
985 folderAdaptor
= new KMail::FolderAdaptor(adaptorName
);
988 kWarning(5006) << "Folder not found:" << vpath
;
992 void KMKernel::raise()
994 QDBusInterface
iface(DBUS_KMAIL
, "/MainApplication", "org.kde.KUniqueApplication", QDBusConnection::sessionBus());
995 QDBusReply
<int> reply
;
996 if (!iface
.isValid() || !(reply
= iface
.call("newInstance")).isValid())
998 QDBusError err
= iface
.lastError();
999 kError() <<"Communication problem with kmail"
1000 << "Error message was:" << err
.name() << ": \"" << err
.message() << "\"";
1005 bool KMKernel::showMail( quint32 serialNumber
, const QString
& /* messageId */ )
1007 KMMainWidget
*mainWidget
= 0;
1010 // First look for a KMainWindow.
1011 for ( QList
<KMainWindow
*>::const_iterator it
= KMainWindow::memberList().begin();
1012 it
!= KMainWindow::memberList().end(); ++it
) {
1013 // Then look for a KMMainWidget.
1014 l
= (*it
)->queryList("KMMainWidget");
1015 if (!l
.isEmpty() && l
.first()) {
1016 mainWidget
= dynamic_cast<KMMainWidget
*>(l
.first());
1017 if ( (*it
)->isActiveWindow() )
1024 KMFolder
*folder
= 0;
1025 KMMsgDict::instance()->getLocation(serialNumber
, &folder
, &idx
);
1026 if (!folder
|| (idx
== -1))
1028 KMFolderOpener
openFolder(folder
, "showmail");
1029 KMMsgBase
*msgBase
= folder
->getMsgBase(idx
);
1032 bool unGet
= !msgBase
->isMessage();
1033 KMMessage
*msg
= folder
->getMsg(idx
);
1035 KMReaderMainWin
*win
= new KMReaderMainWin( false, false );
1036 KMMessage
*newMessage
= new KMMessage( *msg
);
1037 newMessage
->setParent( msg
->parent() );
1038 newMessage
->setMsgSerNum( msg
->getMsgSerNum() );
1039 newMessage
->setReadyToShow( true );
1040 win
->showMsg( GlobalSettings::self()->overrideCharacterEncoding(), newMessage
);
1044 folder
->unGetMsg(idx
);
1051 QString
KMKernel::getFrom( quint32 serialNumber
)
1054 KMFolder
*folder
= 0;
1055 KMMsgDict::instance()->getLocation(serialNumber
, &folder
, &idx
);
1056 if (!folder
|| (idx
== -1))
1058 KMFolderOpener
openFolder(folder
, "getFrom");
1059 KMMsgBase
*msgBase
= folder
->getMsgBase(idx
);
1062 bool unGet
= !msgBase
->isMessage();
1063 KMMessage
*msg
= folder
->getMsg(idx
);
1064 QString result
= msg
->from();
1066 folder
->unGetMsg(idx
);
1070 QString
KMKernel::debugScheduler()
1072 QString res
= KMail::ActionScheduler::debug();
1076 QString
KMKernel::debugSernum( quint32 serialNumber
)
1079 if (serialNumber
!= 0) {
1081 KMFolder
*folder
= 0;
1083 KMMsgDict::instance()->getLocation( serialNumber
, &folder
, &idx
);
1084 // It's possible that the message has been deleted or moved into a
1086 if (folder
&& (idx
!= -1)) {
1088 KMFolderOpener
openFolder( folder
, "debugser" );
1089 msg
= folder
->getMsgBase( idx
);
1091 res
.append( QString( " subject %s,\n sender %s,\n date %s.\n" )
1092 .arg( msg
->subject() )
1093 .arg( msg
->fromStrip() )
1094 .arg( msg
->dateStr() ) );
1096 res
.append( QString( "Invalid serial number." ) );
1099 res
.append( QString( "Invalid serial number." ) );
1106 void KMKernel::pauseBackgroundJobs()
1108 mBackgroundTasksTimer
->stop();
1109 mJobScheduler
->pause();
1112 void KMKernel::resumeBackgroundJobs()
1114 mJobScheduler
->resume();
1115 mBackgroundTasksTimer
->start( 4 * 60 * 60 * 1000 );
1118 void KMKernel::stopNetworkJobs()
1120 if ( GlobalSettings::self()->networkState() == GlobalSettings::EnumNetworkState::Offline
)
1123 GlobalSettings::setNetworkState( GlobalSettings::EnumNetworkState::Offline
);
1124 BroadcastStatus::instance()->setStatusMsg( i18n("KMail is set to be offline; all network jobs are suspended"));
1125 emit
onlineStatusChanged( (GlobalSettings::EnumNetworkState::type
)GlobalSettings::networkState() );
1129 void KMKernel::resumeNetworkJobs()
1131 if ( GlobalSettings::self()->networkState() == GlobalSettings::EnumNetworkState::Online
)
1134 GlobalSettings::setNetworkState( GlobalSettings::EnumNetworkState::Online
);
1135 BroadcastStatus::instance()->setStatusMsg( i18n("KMail is set to be online; all network jobs resumed"));
1136 emit
onlineStatusChanged( (GlobalSettings::EnumNetworkState::type
)GlobalSettings::networkState() );
1138 if ( kmkernel
->msgSender()->sendImmediate() ) {
1139 kmkernel
->msgSender()->sendQueued();
1143 bool KMKernel::isOffline()
1145 if ( GlobalSettings::self()->networkState() == GlobalSettings::EnumNetworkState::Offline
)
1151 bool KMKernel::askToGoOnline()
1153 if ( kmkernel
->isOffline() ) {
1155 KMessageBox::questionYesNo( KMKernel::self()->mainWin(),
1156 i18n("KMail is currently in offline mode. "
1157 "How do you want to proceed?"),
1158 i18n("Online/Offline"),
1159 KGuiItem(i18n("Work Online")),
1160 KGuiItem(i18n("Work Offline")));
1162 if( rc
== KMessageBox::No
) {
1165 kmkernel
->resumeNetworkJobs();
1171 /********************************************************************/
1172 /* Kernel methods */
1173 /********************************************************************/
1175 void KMKernel::quit()
1177 // Called when all windows are closed. Will take care of compacting,
1178 // sending... should handle session management too!!
1182 - msgsender is nonblocking
1183 (our own, QSocketNotifier based. Pops up errors and sends signal
1184 senderFinished when done)
1186 o If we are getting mail, stop it (but don't lose something!)
1187 [Done already, see mailCheckAborted]
1188 o If we are sending mail, go on UNLESS this was called by SM,
1189 in which case stop ASAP that too (can we warn? should we continue
1191 o If we are compacting, or expunging, go on UNLESS this was SM call.
1192 In that case stop compacting ASAP and continue on next start, before
1193 touching any folders. [Not needed anymore with CompactionJob]
1198 if compacting, stop;
1201 Windows will take care of themselves (composer should dump
1202 its messages, if any but not in deadMail)
1203 declare us ready for the End of the Session
1205 No, normal quit call
1206 All windows are off. Anything to do, should compact or sender sends?
1207 Yes, maybe put an icon in panel as a sign of life
1208 if sender sending, connect us to his finished slot, declare us ready
1209 for quit and wait for senderFinished
1210 if not, Folder manager, go compact sent-mail and outbox
1211 } (= call slotFinished())
1213 void KMKernel::slotSenderFinished()
1215 good, Folder manager go compact sent-mail and outbox
1216 clean up stage1 (release folders and config, unregister from dcop)
1217 -- another kmail may start now ---
1223 /********************************************************************/
1224 /* Init, Exit, and handler methods */
1225 /********************************************************************/
1226 void KMKernel::testDir(const char *_name
)
1228 QString foldersPath
= QDir::homePath() + QString( _name
);
1229 QFileInfo
info( foldersPath
);
1230 if ( !info
.exists() ) {
1232 if ( ::mkdir( QFile::encodeName( foldersPath
) ) == -1 ) {
1234 if ( ::mkdir( QFile::encodeName( foldersPath
) , S_IRWXU
) == -1 ) {
1236 KMessageBox::sorry(0, i18n("KMail could not create folder '%1';\n"
1237 "please make sure that you can view and "
1238 "modify the content of the folder '%2'.",
1239 foldersPath
, QDir::homePath() ) );
1243 if ( !info
.isDir() || !info
.isReadable() || !info
.isWritable() ) {
1244 KMessageBox::sorry(0, i18n("The permissions of the folder '%1' are "
1246 "please make sure that you can view and modify "
1247 "the content of this folder.",
1254 //-----------------------------------------------------------------------------
1255 // Open a composer for each message found in the dead.letter folder
1256 void KMKernel::recoverDeadLetters()
1258 const QString pathName
= localDataPath();
1259 QDir
dir( pathName
);
1260 if ( !dir
.exists( "autosave" ) )
1263 KMFolder
folder( 0, pathName
+ "autosave", KMFolderTypeMaildir
, false /* no index */ );
1264 KMFolderOpener
openFolder( &folder
, "recover" );
1265 if ( !folder
.isOpened() ) {
1266 perror( "cannot open autosave folder" );
1270 const int num
= folder
.count();
1271 for ( int i
= 0; i
< num
; i
++ ) {
1272 KMMessage
*msg
= folder
.take( 0 );
1274 KMail::Composer
* win
= KMail::makeComposer();
1275 win
->setMsg( msg
, false, false, true );
1276 win
->setAutoSaveFilename( msg
->fileName() );
1282 //-----------------------------------------------------------------------------
1283 void KMKernel::initFolders(KConfig
* cfg
)
1286 KConfigGroup
group(cfg
,"General");
1288 name
= group
.readEntry("inboxFolder");
1290 // Currently the folder manager cannot manage folders which are not
1291 // in the base folder directory.
1292 //if (name.isEmpty()) name = getenv("MAIL");
1294 if (name
.isEmpty()) name
= I18N_NOOP("inbox");
1296 the_inboxFolder
= (KMFolder
*)the_folderMgr
->findOrCreate(name
);
1298 if (the_inboxFolder
->canAccess() != 0) {
1299 emergencyExit( i18n("You do not have read/write permission to your inbox folder.") );
1302 the_inboxFolder
->setSystemFolder(true);
1303 if ( the_inboxFolder
->userWhoField().isEmpty() )
1304 the_inboxFolder
->setUserWhoField( QString() );
1305 // inboxFolder->open();
1307 the_outboxFolder
= the_folderMgr
->findOrCreate(group
.readEntry("outboxFolder", I18N_NOOP("outbox")));
1308 if (the_outboxFolder
->canAccess() != 0) {
1309 emergencyExit( i18n("You do not have read/write permission to your outbox folder.") );
1311 the_outboxFolder
->setNoChildren(true);
1313 the_outboxFolder
->setSystemFolder(true);
1314 if ( the_outboxFolder
->userWhoField().isEmpty() )
1315 the_outboxFolder
->setUserWhoField( QString() );
1316 /* Nuke the oubox's index file, to make sure that no ghost messages are in
1317 * it from a previous crash. Ghost messages happen in the outbox because it
1318 * the only folder where messages enter and leave within 5 seconds, which is
1319 * the leniency period for index invalidation. Since the number of mails in
1320 * this folder is expected to be very small, we can live with regenerating
1321 * the index on each start to be on the save side. */
1322 //if ( the_outboxFolder->folderType() == KMFolderTypeMaildir )
1323 // unlink( QFile::encodeName( the_outboxFolder->indexLocation() ) );
1324 the_outboxFolder
->open( "kmkernel" );
1326 the_sentFolder
= the_folderMgr
->findOrCreate(group
.readEntry("sentFolder", I18N_NOOP("sent-mail")));
1327 if (the_sentFolder
->canAccess() != 0) {
1328 emergencyExit( i18n("You do not have read/write permission to your sent-mail folder.") );
1330 the_sentFolder
->setSystemFolder(true);
1331 if ( the_sentFolder
->userWhoField().isEmpty() )
1332 the_sentFolder
->setUserWhoField( QString() );
1333 // the_sentFolder->open();
1335 the_trashFolder
= the_folderMgr
->findOrCreate(group
.readEntry("trashFolder", I18N_NOOP("trash")));
1336 if (the_trashFolder
->canAccess() != 0) {
1337 emergencyExit( i18n("You do not have read/write permission to your trash folder.") );
1339 the_trashFolder
->setSystemFolder(true);
1340 if ( the_trashFolder
->userWhoField().isEmpty() )
1341 the_trashFolder
->setUserWhoField( QString() );
1342 // the_trashFolder->open();
1344 the_draftsFolder
= the_folderMgr
->findOrCreate(group
.readEntry("draftsFolder", I18N_NOOP("drafts")));
1345 if (the_draftsFolder
->canAccess() != 0) {
1346 emergencyExit( i18n("You do not have read/write permission to your drafts folder.") );
1348 the_draftsFolder
->setSystemFolder(true);
1349 if ( the_draftsFolder
->userWhoField().isEmpty() )
1350 the_draftsFolder
->setUserWhoField( QString() );
1351 the_draftsFolder
->open( "kmkernel" );
1353 the_templatesFolder
= the_folderMgr
->findOrCreate(group
.readEntry("templatesFolder", I18N_NOOP("templates")));
1354 if (the_templatesFolder
->canAccess() != 0) {
1355 emergencyExit( i18n("You do not have read/write permission to your templates folder.") );
1357 the_templatesFolder
->setSystemFolder(true);
1358 if ( the_templatesFolder
->userWhoField().isEmpty() )
1359 the_templatesFolder
->setUserWhoField( QString() );
1360 the_templatesFolder
->open( "kmkernel" );
1364 void KMKernel::init()
1366 the_shuttingDown
= false;
1367 the_server_is_ready
= false;
1369 KConfig
* cfg
= KMKernel::config();
1373 KConfigGroup
group(cfg
, "General");
1374 the_firstStart
= group
.readEntry("first-start", true );
1375 group
.writeEntry("first-start", false);
1376 the_previousVersion
= group
.readEntry("previous-version");
1377 group
.writeEntry("previous-version", KMAIL_VERSION
);
1378 QString foldersPath
= group
.readPathEntry( "folders" );
1379 kDebug(5006) <<"foldersPath (from config): '" << foldersPath
<<"'";
1381 if ( foldersPath
.isEmpty() ) {
1382 foldersPath
= localDataPath() + "mail";
1383 if ( transferMail( foldersPath
) ) {
1384 group
.writePathEntry( "folders", foldersPath
);
1386 kDebug(5006) <<"foldersPath (after transferMail): '" << foldersPath
<<"'";
1388 //Here because folderMgr's need it when they read the index and sort tags
1389 the_msgTagMgr
= new KMMessageTagMgr();
1390 the_msgTagMgr
->readConfig();
1392 // moved up here because KMMessage::stripOffPrefixes is used below
1393 KMMessage::readConfig();
1395 the_undoStack
= new UndoStack(20);
1396 the_folderMgr
= new KMFolderMgr(foldersPath
);
1397 the_imapFolderMgr
= new KMFolderMgr( KMFolderImap::cacheLocation(), KMImapDir
);
1398 the_dimapFolderMgr
= new KMFolderMgr( KMFolderCachedImap::cacheLocation(), KMDImapDir
);
1400 the_searchFolderMgr
= new KMFolderMgr(KStandardDirs::locateLocal("data","kmail/search"), KMSearchDir
);
1401 KMFolder
*lsf
= the_searchFolderMgr
->find( i18n("Last Search") );
1403 the_searchFolderMgr
->remove( lsf
);
1405 the_acctMgr
= new AccountManager();
1406 the_filterMgr
= new KMFilterMgr();
1407 the_popFilterMgr
= new KMFilterMgr(true);
1408 the_filterActionDict
= new KMFilterActionDict
;
1411 the_acctMgr
->readConfig();
1412 the_filterMgr
->readConfig();
1413 the_popFilterMgr
->readConfig();
1414 cleanupImapFolders();
1416 the_msgSender
= new KMSender
;
1417 the_server_is_ready
= true;
1418 { // area for config group "Composer"
1419 KConfigGroup
group(cfg
, "Composer");
1420 if (group
.readEntry("pref-charsets", QStringList() ).isEmpty())
1422 group
.writeEntry("pref-charsets", "us-ascii,iso-8859-1,locale,utf-8");
1426 // filterMgr->dump();
1428 the_weaver
= new ThreadWeaver::Weaver( this );
1430 connect( the_folderMgr
, SIGNAL( folderRemoved(KMFolder
*) ),
1431 this, SIGNAL( folderRemoved(KMFolder
*) ) );
1432 connect( the_dimapFolderMgr
, SIGNAL( folderRemoved(KMFolder
*) ),
1433 this, SIGNAL( folderRemoved(KMFolder
*) ) );
1434 connect( the_imapFolderMgr
, SIGNAL( folderRemoved(KMFolder
*) ),
1435 this, SIGNAL( folderRemoved(KMFolder
*) ) );
1436 connect( the_searchFolderMgr
, SIGNAL( folderRemoved(KMFolder
*) ),
1437 this, SIGNAL( folderRemoved(KMFolder
*) ) );
1439 mBackgroundTasksTimer
= new QTimer( this );
1440 mBackgroundTasksTimer
->setSingleShot( true );
1441 connect( mBackgroundTasksTimer
, SIGNAL( timeout() ), this, SLOT( slotRunBackgroundTasks() ) );
1442 #ifdef DEBUG_SCHEDULER // for debugging, see jobscheduler.h
1443 mBackgroundTasksTimer
->start( 10000 ); // 10s minute, singleshot
1445 mBackgroundTasksTimer
->start( 5 * 60000 ); // 5 minutes, singleshot
1449 void KMKernel::readConfig()
1451 //Needed here, since this function is also called when the configuration
1452 //changes, and the static variables should be updated then - IOF
1453 KMMessage::readConfig();
1456 void KMKernel::cleanupImapFolders()
1458 KMAccount
*acct
= 0;
1459 QList
<KMFolderNode
*>::iterator it
= the_imapFolderMgr
->dir().begin();
1460 while ( it
!= the_imapFolderMgr
->dir().end() )
1462 KMFolderNode
*node
= *it
;
1463 if (node
->isDir() || ((acct
= the_acctMgr
->find(node
->id()))
1464 && ( acct
->type() == KAccount::Imap
)) )
1468 KMFolder
* folder
= static_cast<KMFolder
*>(node
);
1469 // delete only local
1470 static_cast<KMFolderImap
*>( folder
->storage() )->setAlreadyRemoved( true );
1471 the_imapFolderMgr
->remove(folder
);
1472 it
= the_imapFolderMgr
->dir().begin();
1476 it
= the_dimapFolderMgr
->dir().begin();
1477 while ( it
!= the_dimapFolderMgr
->dir().end() )
1479 KMFolderNode
*node
= *it
;
1480 if (node
->isDir() || ((acct
= the_acctMgr
->find(node
->id()))
1481 && ( acct
->type() == KAccount::DImap
)) )
1485 the_dimapFolderMgr
->remove(static_cast<KMFolder
*>(node
));
1486 it
= the_dimapFolderMgr
->dir().begin();
1490 the_imapFolderMgr
->quiet(true);
1491 for (acct
= the_acctMgr
->first(); acct
; acct
= the_acctMgr
->next())
1494 KMAcctImap
*imapAcct
;
1496 if (acct
->type() != KAccount::Imap
) continue;
1497 fld
= static_cast<KMFolderImap
*>(the_imapFolderMgr
1498 ->findOrCreate(QString::number(acct
->id()), false, acct
->id())->storage());
1499 fld
->setNoContent(true);
1500 fld
->folder()->setLabel(acct
->name());
1501 imapAcct
= static_cast<KMAcctImap
*>(acct
);
1502 fld
->setAccount(imapAcct
);
1503 imapAcct
->setImapFolder(fld
);
1504 fld
->close( "kernel", true );
1506 the_imapFolderMgr
->quiet(false);
1508 the_dimapFolderMgr
->quiet( true );
1509 for (acct
= the_acctMgr
->first(); acct
; acct
= the_acctMgr
->next())
1511 KMFolderCachedImap
*cfld
= 0;
1512 KMAcctCachedImap
*cachedImapAcct
;
1514 if (acct
->type() != KAccount::DImap
) continue;
1516 KMFolder
* fld
= the_dimapFolderMgr
->find(QString::number(acct
->id()));
1518 cfld
= static_cast<KMFolderCachedImap
*>( fld
->storage() );
1520 // Folder doesn't exist yet
1521 cfld
= static_cast<KMFolderCachedImap
*>(the_dimapFolderMgr
->createFolder(QString::number(acct
->id()),
1522 false, KMFolderTypeCachedImap
)->storage());
1524 KMessageBox::error(0,(i18n("Cannot create file `%1' in %2.\nKMail cannot start without it.", acct
->name(), the_dimapFolderMgr
->basePath())));
1527 cfld
->folder()->setId( acct
->id() );
1530 cfld
->setNoContent(true);
1531 cfld
->folder()->setLabel(acct
->name());
1532 cachedImapAcct
= static_cast<KMAcctCachedImap
*>(acct
);
1533 cfld
->setAccount(cachedImapAcct
);
1534 cachedImapAcct
->setImapFolder(cfld
);
1535 cfld
->close( "kmkernel" );
1537 the_dimapFolderMgr
->quiet( false );
1540 bool KMKernel::doSessionManagement()
1543 // Do session management
1544 if (kapp
->isSessionRestored()){
1546 while (KMMainWin::canBeRestored(n
)){
1547 //only restore main windows! (Matthias);
1548 if (KMMainWin::classNameOfToplevel(n
) == "KMMainWin")
1549 (new KMMainWin
)->restore(n
);
1552 return true; // we were restored by SM
1554 return false; // no, we were not restored
1557 void KMKernel::closeAllKMailWindows()
1559 QListIterator
<KMainWindow
*> it( KMainWindow::memberList() );
1560 KMainWindow
*window
= 0;
1561 while ( it
.hasNext() ) {
1563 if ( ::qobject_cast
<KMMainWin
*>(window
) ||
1564 ::qobject_cast
<KMail::SecondaryWindow
*>(window
) )
1566 window
->setAttribute(Qt::WA_DeleteOnClose
);
1567 window
->close(); // close and delete the window
1572 void KMKernel::cleanup(void)
1575 the_shuttingDown
= true;
1576 closeAllKMailWindows();
1580 delete the_filterMgr
;
1582 delete the_msgSender
;
1584 delete the_filterActionDict
;
1585 the_filterActionDict
= 0;
1586 delete the_msgTagMgr
;
1588 delete the_undoStack
;
1590 delete the_popFilterMgr
;
1591 the_popFilterMgr
= 0;
1596 KConfig
* config
= KMKernel::config();
1597 KConfigGroup
group(config
, "General");
1599 if ( the_trashFolder
) {
1601 the_trashFolder
->close( "kmkernel", true );
1603 if ( group
.readEntry( "empty-trash-on-exit", true ) ) {
1604 if ( the_trashFolder
->count( true ) > 0 ) {
1605 the_trashFolder
->expunge();
1611 mICalIface
->cleanup();
1613 QList
<QPointer
<KMFolder
> > folders
;
1614 QStringList strList
;
1616 the_folderMgr
->createFolderList(&strList
, &folders
);
1618 QList
<QPointer
<KMFolder
> >::const_iterator it
;
1619 for ( it
= folders
.begin(); it
!= folders
.end(); it
++ ) {
1621 if ( !folder
|| folder
->isDir() ) {
1624 folder
->close( "kmkernel", true );
1628 the_searchFolderMgr
->createFolderList(&strList
, &folders
);
1629 for ( it
= folders
.begin(); it
!= folders
.end(); it
++ ) {
1631 if ( !folder
|| folder
->isDir() ) {
1634 folder
->close( "kmkernel", true );
1637 delete the_folderMgr
;
1639 delete the_imapFolderMgr
;
1640 the_imapFolderMgr
= 0;
1641 delete the_dimapFolderMgr
;
1642 the_dimapFolderMgr
= 0;
1643 delete the_searchFolderMgr
;
1644 the_searchFolderMgr
= 0;
1645 delete mConfigureDialog
;
1646 mConfigureDialog
= 0;
1647 // do not delete, because mWin may point to an existing window
1651 if ( RecentAddresses::exists() )
1652 RecentAddresses::self( config
)->save( config
);
1656 bool KMKernel::transferMail( QString
& destinationDir
)
1660 // check whether the user has a ~/KMail folder
1661 QFileInfo
fi( QDir::home(), "KMail" );
1662 if ( fi
.exists() && fi
.isDir() ) {
1663 dir
= QDir::homePath() + "/KMail";
1664 // the following two lines can be removed once moving mail is reactivated
1665 destinationDir
= dir
;
1669 if ( dir
.isEmpty() ) {
1670 // check whether the user has a ~/Mail folder
1671 fi
.setFile( QDir::home(), "Mail" );
1672 if ( fi
.exists() && fi
.isDir() &&
1673 QFile::exists( QDir::homePath() + "/Mail/.inbox.index" ) ) {
1674 // there's a ~/Mail folder which seems to be used by KMail (because of the
1676 dir
= QDir::homePath() + "/Mail";
1677 // the following two lines can be removed once moving mail is reactivated
1678 destinationDir
= dir
;
1683 if ( dir
.isEmpty() ) {
1684 return true; // there's no old mail folder
1688 // disabled for now since moving fails in certain cases (e.g. if symbolic links are involved)
1689 const QString kmailName
= KGlobal::mainComponent().aboutData()()->programName();
1691 if ( KIO::NetAccess::exists( destinationDir
, KIO::NetAccess::SourceSide
, 0 ) ) {
1692 // if destinationDir exists, we need to warn about possible
1693 // overwriting of files. otherwise, we don't have to
1694 msg
= ki18nc( "%1-%3 is the application name, %4-%7 are folder path",
1695 "<qt>The <i>%4</i> folder exists. "
1696 "%1 now uses the <i>%5</i> folder for "
1698 "%2 can move the contents of <i>%6</i> into this folder for "
1699 "you, though this may replace any existing files with "
1700 "the same name in <i>%7</i>.</p><p>"
1701 "<strong>Would you like %3 to move the mail "
1702 "files now?</strong></p></qt>" )
1703 .subs( kmailName
).subs( kmailName
).subs( kmailName
)
1704 .subs( dir
).subs( destinationDir
).subs( dir
).subs( destinationDir
)
1708 msg
= ki18nc( "%1-%3 is the application name, %4-%6 are folder path",
1709 "<qt>The <i>%4</i> folder exists. "
1710 "%1 now uses the <i>%5</i> folder for "
1711 "its messages. %2 can move the contents of <i>%6</i> into "
1712 "this folder for you.<p>"
1713 "<strong>Would you like %3 to move the mail "
1714 "files now?</strong></p></qt>" )
1715 .subs( kmailName
).subs( kmailName
).subs( kmailName
)
1716 .subs( dir
).subs( destinationDir
).subs( dir
)
1719 QString title
= i18n( "Migrate Mail Files?" );
1720 QString buttonText
= i18n( "Move" );
1722 if ( KMessageBox::questionYesNo( 0, msg
, title
, buttonText
, i18n("Do Not Move") ) ==
1724 destinationDir
= dir
;
1728 if ( !KIO::NetAccess::move( dir
, destinationDir
) ) {
1729 kDebug(5006) <<"Moving" << dir
<<" to" << destinationDir
<<" failed:" << KIO::NetAccess::lastErrorString();
1730 kDebug(5006) <<"Deleting" << destinationDir
;
1731 KIO::NetAccess::del( destinationDir
, 0 );
1732 destinationDir
= dir
;
1742 void KMKernel::dumpDeadLetters()
1744 if ( shuttingDown() )
1745 return; //All documents should be saved before shutting down is set!
1747 // make all composer windows autosave their contents
1748 QListIterator
<KMainWindow
*> it( KMainWindow::memberList() );
1749 while ( it
.hasNext() )
1750 if ( KMail::Composer
* win
= ::qobject_cast
<KMail::Composer
*>( it
.next() ) )
1751 win
->autoSaveMessage();
1756 void KMKernel::action( bool mailto
, bool check
, const QString
&to
,
1757 const QString
&cc
, const QString
&bcc
,
1758 const QString
&subj
, const QString
&body
,
1759 const KUrl
&messageFile
,
1760 const KUrl::List
&attachURLs
,
1761 const QStringList
&customHeaders
)
1764 openComposer( to
, cc
, bcc
, subj
, body
, 0, messageFile
, attachURLs
, customHeaders
);
1766 openReader( check
);
1773 void KMKernel::byteArrayToRemoteFile(const QByteArray
&aData
, const KUrl
&aURL
,
1776 // ## when KDE 3.3 is out: use KIO::storedPut to remove slotDataReq altogether
1777 KIO::Job
*job
= KIO::put(aURL
, -1, overwrite
? KIO::Overwrite
: KIO::DefaultFlags
);
1778 putData pd
; pd
.url
= aURL
; pd
.data
= aData
; pd
.offset
= 0;
1779 mPutJobs
.insert(job
, pd
);
1780 connect(job
, SIGNAL(dataReq(KIO::Job
*,QByteArray
&)),
1781 SLOT(slotDataReq(KIO::Job
*,QByteArray
&)));
1782 connect(job
, SIGNAL(result(KJob
*)),
1783 SLOT(slotResult(KJob
*)));
1786 void KMKernel::slotDataReq(KIO::Job
*job
, QByteArray
&data
)
1788 // send the data in 64 KB chunks
1789 const int MAX_CHUNK_SIZE
= 64*1024;
1790 QMap
<KIO::Job
*, putData
>::Iterator it
= mPutJobs
.find(job
);
1791 assert(it
!= mPutJobs
.end());
1792 int remainingBytes
= (*it
).data
.size() - (*it
).offset
;
1793 if( remainingBytes
> MAX_CHUNK_SIZE
)
1795 // send MAX_CHUNK_SIZE bytes to the receiver (deep copy)
1796 data
= QByteArray( (*it
).data
.data() + (*it
).offset
, MAX_CHUNK_SIZE
);
1797 (*it
).offset
+= MAX_CHUNK_SIZE
;
1798 //kDebug( 5006 ) <<"Sending" << MAX_CHUNK_SIZE <<" bytes ("
1799 // << remainingBytes - MAX_CHUNK_SIZE << " bytes remain)\n";
1803 // send the remaining bytes to the receiver (deep copy)
1804 data
= QByteArray( (*it
).data
.data() + (*it
).offset
, remainingBytes
);
1805 (*it
).data
= QByteArray();
1807 //kDebug( 5006 ) <<"Sending" << remainingBytes <<" bytes";
1811 void KMKernel::slotResult(KJob
*job
)
1813 QMap
<KIO::Job
*, putData
>::Iterator it
= mPutJobs
.find(static_cast<KIO::Job
*>(job
));
1814 assert(it
!= mPutJobs
.end());
1817 if (job
->error() == KIO::ERR_FILE_ALREADY_EXIST
)
1819 if (KMessageBox::warningContinueCancel(0,
1820 i18n("File %1 exists.\nDo you want to replace it?",
1821 (*it
).url
.prettyUrl()), i18n("Save to File"), KGuiItem(i18n("&Replace")))
1822 == KMessageBox::Continue
)
1823 byteArrayToRemoteFile((*it
).data
, (*it
).url
, true);
1825 else static_cast<KIO::Job
*>(job
)->showErrorDialog();
1830 void KMKernel::slotRequestConfigSync() {
1831 // ### FIXME: delay as promised in the kdoc of this function ;-)
1832 KMKernel::config()->sync();
1835 void KMKernel::slotShowConfigurationDialog()
1837 if( !mConfigureDialog
) {
1838 mConfigureDialog
= new ConfigureDialog( 0, false );
1839 mConfigureDialog
->setObjectName( "configure" );
1840 connect( mConfigureDialog
, SIGNAL( configCommitted() ),
1841 this, SLOT( slotConfigChanged() ) );
1844 if( KMKernel::getKMMainWidget() == 0 ) {
1845 // ensure that there is a main widget available
1846 // as parts of the configure dialog (identity) rely on this
1847 // and this slot can be called when there is only a KMComposeWin showing
1848 KMMainWin
*win
= new KMMainWin
;
1853 if( mConfigureDialog
->isHidden() ) {
1854 mConfigureDialog
->show();
1856 mConfigureDialog
->raise();
1860 void KMKernel::slotConfigChanged()
1863 emit
configChanged();
1866 //-------------------------------------------------------------------------------
1868 QString
KMKernel::localDataPath()
1870 return KStandardDirs::locateLocal( "data", "kmail/" );
1873 //-------------------------------------------------------------------------------
1875 bool KMKernel::haveSystemTrayApplet()
1877 return !systemTrayApplets
.isEmpty();
1880 bool KMKernel::registerSystemTrayApplet( const KSystemTrayIcon
* applet
)
1882 if ( !systemTrayApplets
.contains( applet
) ) {
1883 systemTrayApplets
.append( applet
);
1890 bool KMKernel::unregisterSystemTrayApplet( const KSystemTrayIcon
* applet
)
1892 return systemTrayApplets
.removeAll( applet
) > 0;
1895 void KMKernel::emergencyExit( const QString
& reason
)
1898 if ( reason
.length() == 0 ) {
1899 mesg
= i18n("KMail encountered a fatal error and will terminate now");
1902 mesg
= i18n("KMail encountered a fatal error and will "
1903 "terminate now.\nThe error was:\n%1", reason
);
1906 kWarning(5006) << mesg
;
1907 KNotification::event(KNotification::Catastrophe
, mesg
);
1913 * Returns true if the folder is either the outbox or one of the drafts-folders
1915 bool KMKernel::folderIsDraftOrOutbox(const KMFolder
* folder
)
1918 if ( folder
== the_outboxFolder
)
1920 return folderIsDrafts( folder
);
1923 bool KMKernel::folderIsDrafts(const KMFolder
* folder
)
1926 if ( folder
== the_draftsFolder
)
1929 QString idString
= folder
->idString();
1930 if ( idString
.isEmpty() ) return false;
1932 // search the identities if the folder matches the drafts-folder
1933 const KPIMIdentities::IdentityManager
* im
= identityManager();
1934 for( KPIMIdentities::IdentityManager::ConstIterator it
= im
->begin(); it
!= im
->end(); ++it
)
1935 if ( (*it
).drafts() == idString
) return true;
1939 bool KMKernel::folderIsTemplates(const KMFolder
* folder
)
1942 if ( folder
== the_templatesFolder
)
1945 QString idString
= folder
->idString();
1946 if ( idString
.isEmpty() ) return false;
1948 // search the identities if the folder matches the templates-folder
1949 const KPIMIdentities::IdentityManager
* im
= identityManager();
1950 for( KPIMIdentities::IdentityManager::ConstIterator it
= im
->begin(); it
!= im
->end(); ++it
)
1951 if ( (*it
).templates() == idString
) return true;
1955 bool KMKernel::folderIsTrash(KMFolder
* folder
)
1958 if (folder
== the_trashFolder
) return true;
1959 QStringList actList
= acctMgr()->getAccounts();
1960 QStringList::Iterator
it( actList
.begin() );
1961 for( ; it
!= actList
.end() ; ++it
) {
1962 KMAccount
* act
= acctMgr()->findByName( *it
);
1963 if ( act
&& ( act
->trash() == folder
->idString() ) )
1969 bool KMKernel::folderIsSentMailFolder( const KMFolder
* folder
)
1972 if ( folder
== the_sentFolder
)
1975 QString idString
= folder
->idString();
1976 if ( idString
.isEmpty() ) return false;
1978 // search the identities if the folder matches the sent-folder
1979 const KPIMIdentities::IdentityManager
* im
= identityManager();
1980 for( KPIMIdentities::IdentityManager::ConstIterator it
= im
->begin(); it
!= im
->end(); ++it
)
1981 if ( (*it
).fcc() == idString
) return true;
1985 KPIMIdentities::IdentityManager
* KMKernel::identityManager() {
1986 if ( !mIdentityManager
) {
1987 kDebug(5006) <<"instantating KPIMIdentities::IdentityManager";
1988 mIdentityManager
= new KPIMIdentities::IdentityManager( false, this, "mIdentityManager" );
1990 return mIdentityManager
;
1993 KMainWindow
* KMKernel::mainWin()
1995 KMainWindow
*kmWin
= 0;
1997 // First look for a KMMainWin.
1998 for ( QList
<KMainWindow
*>::const_iterator it
= KMainWindow::memberList().begin();
1999 it
!= KMainWindow::memberList().end(); ++it
)
2000 if ( ::qobject_cast
<KMMainWin
*>(*it
) )
2003 // There is no KMMainWin. Use any other KMainWindow instead (e.g. in
2004 // case we are running inside Kontact) because we anyway only need
2005 // it for modal message boxes and for KNotify events.
2006 kmWin
= KMainWindow::memberList().first();
2010 // There's not a single KMainWindow. Create a KMMainWin.
2011 // This could happen if we want to pop up an error message
2012 // while we are still doing the startup wizard and no other
2013 // KMainWindow is running.
2014 mWin
= new KMMainWin
;
2020 * Empties all trash folders
2022 void KMKernel::slotEmptyTrash()
2024 QString title
= i18n("Empty Trash");
2025 QString text
= i18n("Are you sure you want to empty the trash folders of all accounts?");
2026 if (KMessageBox::warningContinueCancel(0, text
, title
,
2027 KStandardGuiItem::cont(), KStandardGuiItem::cancel(),
2028 "confirm_empty_trash")
2029 != KMessageBox::Continue
)
2034 for (KMAccount
* acct
= acctMgr()->first(); acct
; acct
= acctMgr()->next())
2036 KMFolder
* trash
= findFolderById(acct
->trash());
2044 KConfig
* KMKernel::config()
2047 if (!mySelf
->mConfig
)
2049 mySelf
->mConfig
= KSharedConfig::openConfig( "kmailrc" );
2050 // Check that all updates have been run on the config file:
2051 KMail::checkConfigUpdates();
2053 return mySelf
->mConfig
.data();
2056 KMailICalIfaceImpl
& KMKernel::iCalIface()
2058 assert( mICalIface
);
2062 void KMKernel::selectFolder( const QString
&folderPath
)
2064 kDebug(5006)<<"Selecting a folder"<<folderPath
;
2065 const QString localPrefix
= "/Local";
2066 KMFolder
*folder
= kmkernel
->folderMgr()->getFolderByURL( folderPath
);
2067 if ( !folder
&& folderPath
.startsWith( localPrefix
) )
2068 folder
= the_folderMgr
->getFolderByURL( folderPath
.mid( localPrefix
.length() ) );
2070 folder
= kmkernel
->imapFolderMgr()->getFolderByURL( folderPath
);
2072 folder
= kmkernel
->dimapFolderMgr()->getFolderByURL( folderPath
);
2075 KMMainWidget
*widget
= getKMMainWidget();
2080 KMFolderTree
*tree
= widget
->folderTree();
2081 tree
->doFolderSelected( tree
->indexOfFolder( folder
) );
2082 tree
->ensureItemVisible( tree
->indexOfFolder( folder
) );
2085 KMMainWidget
*KMKernel::getKMMainWidget()
2087 //This could definitely use a speadup
2088 QWidgetList l
= QApplication::topLevelWidgets();
2091 Q_FOREACH( wid
, l
) {
2092 QObjectList l2
= wid
->topLevelWidget()->queryList( "KMMainWidget" );
2093 if (!l2
.isEmpty() && l2
.first()) {
2094 KMMainWidget
* kmmw
= dynamic_cast<KMMainWidget
*>( l2
.first() );
2102 void KMKernel::slotRunBackgroundTasks() // called regularly by timer
2104 // Hidden KConfig keys. Not meant to be used, but a nice fallback in case
2105 // a stable kmail release goes out with a nasty bug in CompactionJob...
2106 KConfigGroup
generalGroup( config(), "General" );
2108 if ( generalGroup
.readEntry( "auto-expiring", true ) ) {
2109 the_folderMgr
->expireAllFolders( false /*scheduled, not immediate*/ );
2110 the_imapFolderMgr
->expireAllFolders( false /*scheduled, not immediate*/ );
2111 the_dimapFolderMgr
->expireAllFolders( false /*scheduled, not immediate*/ );
2112 // the_searchFolderMgr: no expiry there
2115 if ( generalGroup
.readEntry( "auto-compaction", true ) ) {
2116 the_folderMgr
->compactAllFolders( false /*scheduled, not immediate*/ );
2117 // the_imapFolderMgr: no compaction
2118 the_dimapFolderMgr
->compactAllFolders( false /*scheduled, not immediate*/ );
2119 // the_searchFolderMgr: no compaction
2122 #ifdef DEBUG_SCHEDULER // for debugging, see jobscheduler.h
2123 mBackgroundTasksTimer
->start( 60 * 1000 ); // check again in 1 minute
2125 mBackgroundTasksTimer
->start( 4 * 60 * 60 * 1000 ); // check again in 4 hours
2130 void KMKernel::expireAllFoldersNow() // called by the GUI
2132 the_folderMgr
->expireAllFolders( true /*immediate*/ );
2133 the_imapFolderMgr
->expireAllFolders( true /*immediate*/ );
2134 the_dimapFolderMgr
->expireAllFolders( true /*immediate*/ );
2137 void KMKernel::compactAllFolders() // called by the GUI
2139 the_folderMgr
->compactAllFolders( true /*immediate*/ );
2140 //the_imapFolderMgr->compactAllFolders( true /*immediate*/ );
2141 the_dimapFolderMgr
->compactAllFolders( true /*immediate*/ );
2144 KMFolder
* KMKernel::findFolderById( const QString
& idString
)
2146 KMFolder
* folder
= the_folderMgr
->findIdString( idString
);
2148 folder
= the_imapFolderMgr
->findIdString( idString
);
2150 folder
= the_dimapFolderMgr
->findIdString( idString
);
2152 folder
= the_searchFolderMgr
->findIdString( idString
);
2156 void KMKernel::enableMailCheck()
2158 mMailCheckAborted
= false;
2161 bool KMKernel::mailCheckAborted() const
2163 return mMailCheckAborted
;
2166 void KMKernel::abortMailCheck()
2168 mMailCheckAborted
= true;
2171 bool KMKernel::canQueryClose()
2173 if ( KMMainWidget::mainWidgetList() &&
2174 KMMainWidget::mainWidgetList()->count() > 1 )
2176 KMMainWidget
*widget
= getKMMainWidget();
2179 KMSystemTray
* systray
= widget
->systray();
2180 if ( systray
&& systray
->mode() == GlobalSettings::EnumSystemTrayPolicy::ShowAlways
) {
2181 systray
->hideKMail();
2183 } else if ( systray
&& systray
->mode() == GlobalSettings::EnumSystemTrayPolicy::ShowOnUnread
) {
2185 systray
->hideKMail();
2191 void KMKernel::messageCountChanged()
2193 mTimeOfLastMessageCountChange
= ::time( 0 );
2196 int KMKernel::timeOfLastMessageCountChange() const
2198 return mTimeOfLastMessageCountChange
;
2201 Wallet
*KMKernel::wallet() {
2202 static bool walletOpenFailed
= false;
2203 if ( mWallet
&& mWallet
->isOpen() )
2206 if ( !Wallet::isEnabled() || walletOpenFailed
)
2209 // find an appropriate parent window for the wallet dialog
2211 if ( qApp
->activeWindow() )
2212 window
= qApp
->activeWindow()->winId();
2213 else if ( getKMMainWidget() )
2214 window
= getKMMainWidget()->topLevelWidget()->winId();
2217 mWallet
= Wallet::openWallet( Wallet::NetworkWallet(), window
);
2220 walletOpenFailed
= true;
2224 if ( !mWallet
->hasFolder( "kmail" ) )
2225 mWallet
->createFolder( "kmail" );
2226 mWallet
->setFolder( "kmail" );
2230 QList
< QPointer
<KMFolder
> > KMKernel::allFolders()
2233 QList
<QPointer
<KMFolder
> > folders
;
2234 folderMgr()->createFolderList(&names
, &folders
);
2235 imapFolderMgr()->createFolderList(&names
, &folders
);
2236 dimapFolderMgr()->createFolderList(&names
, &folders
);
2237 searchFolderMgr()->createFolderList(&names
, &folders
);
2242 KMFolder
*KMKernel::currentFolder() {
2243 KMMainWidget
*widget
= getKMMainWidget();
2244 KMFolder
*folder
= 0;
2245 if ( widget
&& widget
->folderTree() ) {
2246 folder
= widget
->folderTree()->currentFolder();
2251 // can't be inline, since KMSender isn't known to implement
2252 // KMail::MessageSender outside this .cpp file
2253 KMail::MessageSender
* KMKernel::msgSender() { return the_msgSender
; }
2255 void KMKernel::transportRemoved(int id
, const QString
& name
)
2259 // reset all identities using the deleted transport
2260 QStringList changedIdents
;
2261 KPIMIdentities::IdentityManager
* im
= identityManager();
2262 for ( KPIMIdentities::IdentityManager::Iterator it
= im
->modifyBegin(); it
!= im
->modifyEnd(); ++it
) {
2263 if ( name
== (*it
).transport() ) {
2264 (*it
).setTransport( QString() );
2265 changedIdents
+= (*it
).identityName();
2269 // if the deleted transport is the currently used transport reset it to default
2270 const QString
& currentTransport
= GlobalSettings::self()->currentTransport();
2271 if ( name
== currentTransport
)
2272 GlobalSettings::self()->setCurrentTransport( QString() );
2274 if ( !changedIdents
.isEmpty() ) {
2275 QString information
= i18np( "This identity has been changed to use the default transport:",
2276 "These %1 identities have been changed to use the default transport:",
2277 changedIdents
.count() );
2278 KMessageBox::informationList( mWin
, information
, changedIdents
);
2283 void KMKernel::transportRenamed(int id
, const QString
& oldName
, const QString
& newName
)
2287 QStringList changedIdents
;
2288 KPIMIdentities::IdentityManager
* im
= identityManager();
2289 for ( KPIMIdentities::IdentityManager::Iterator it
= im
->modifyBegin(); it
!= im
->modifyEnd(); ++it
) {
2290 if ( oldName
== (*it
).transport() ) {
2291 (*it
).setTransport( newName
);
2292 changedIdents
<< (*it
).identityName();
2296 if ( !changedIdents
.isEmpty() ) {
2297 QString information
=
2298 i18np( "This identity has been changed to use the modified transport:",
2299 "These %1 identities have been changed to use the modified transport:",
2300 changedIdents
.count() );
2301 KMessageBox::informationList( mWin
, information
, changedIdents
);
2306 #include "kmkernel.moc"