kmail

kmkernel.cpp
1 #ifdef HAVE_CONFIG_H
2 #include <config.h>
3 #endif
4 
5 #include "config.h"
6 #include "kmkernel.h"
7 
8 #include <weaver.h>
9 #include <weaverlogger.h>
10 
11 #include "globalsettings.h"
12 #include "broadcaststatus.h"
13 using KPIM::BroadcastStatus;
14 #include "kmstartup.h"
15 #include "index.h"
16 #include "kmmainwin.h"
17 #include "composer.h"
18 #include "kmmsgpart.h"
19 #include "kmreadermainwin.h"
20 #include "kmfoldermgr.h"
21 #include "kmfoldercachedimap.h"
22 #include "kmacctcachedimap.h"
23 #include "kmfiltermgr.h"
24 #include "kmfilteraction.h"
25 #include "kmheaders.h"
26 #define REALLY_WANT_KMSENDER
27 #include "kmsender.h"
28 #undef REALLY_WANT_KMSENDER
29 #include "undostack.h"
30 #include "accountmanager.h"
32 #include <libtdepim/tdefileio.h>
33 #include "kmversion.h"
34 #include "kmreaderwin.h"
35 #include "kmmainwidget.h"
36 #include "kmfoldertree.h"
37 #include "recentaddresses.h"
38 using TDERecentAddress::RecentAddresses;
39 #include "kmmsgdict.h"
40 #include <libkpimidentities/identity.h>
41 #include <libkpimidentities/identitymanager.h>
42 #include "configuredialog.h"
43 #include "kmcommands.h"
44 #include "kmsystemtray.h"
45 #include "transportmanager.h"
46 #include "importarchivedialog.h"
47 #include <mimelib/enum.h>
48 
49 #include <twin.h>
50 #include "kmailicalifaceimpl.h"
51 #include "mailserviceimpl.h"
52 using KMail::MailServiceImpl;
53 #include "mailcomposerIface.h"
54 #include "folderIface.h"
55 using KMail::FolderIface;
56 #include "jobscheduler.h"
57 #include "templateparser.h"
58 
59 #include <tdeapplication.h>
60 #include <tdemessagebox.h>
61 #include <knotifyclient.h>
62 #include <kstaticdeleter.h>
63 #include <kstandarddirs.h>
64 #include <tdeconfig.h>
65 #include <kprogress.h>
66 #include <kpassivepopup.h>
67 #include <dcopclient.h>
68 #include <ksystemtray.h>
69 #include <kpgp.h>
70 #include <kdebug.h>
71 #include <tdeio/netaccess.h>
72 #include <tdewallet.h>
73 using TDEWallet::Wallet;
74 #include "actionscheduler.h"
75 
76 #include <qutf7codec.h>
77 #include <tqvbox.h>
78 #include <tqdir.h>
79 #include <tqwidgetlist.h>
80 #include <tqobjectlist.h>
81 
82 #include <sys/types.h>
83 #include <dirent.h>
84 #include <sys/stat.h>
85 #include <unistd.h>
86 #include <stdio.h>
87 #include <stdlib.h>
88 #include <assert.h>
89 
90 #include <X11/Xlib.h>
91 #include <fixx11h.h>
92 #include <tdecmdlineargs.h>
93 #include <tdestartupinfo.h>
94 
95 KMKernel *KMKernel::mySelf = 0;
96 static bool s_askingToGoOnline = false;
97 
98 /********************************************************************/
99 /* Constructor and destructor */
100 /********************************************************************/
101 KMKernel::KMKernel (TQObject *parent, const char *name) :
102  DCOPObject("KMailIface"), TQObject(parent, name),
103  mIdentityManager(0), mConfigureDialog(0),
104  mContextMenuShown( false ), mWallet( 0 )
105 {
106  kdDebug(5006) << "KMKernel::KMKernel" << endl;
107  mySelf = this;
108  the_startingUp = true;
109  closed_by_user = true;
110  the_firstInstance = true;
111  the_msgIndex = 0;
112 
113  the_inboxFolder = 0;
114  the_outboxFolder = 0;
115  the_sentFolder = 0;
116  the_trashFolder = 0;
117  the_draftsFolder = 0;
118  the_templatesFolder = 0;
119 
120  the_folderMgr = 0;
121  the_imapFolderMgr = 0;
122  the_dimapFolderMgr = 0;
123  the_searchFolderMgr = 0;
124  the_undoStack = 0;
125  the_acctMgr = 0;
126  the_filterMgr = 0;
127  the_popFilterMgr = 0;
128  the_filterActionDict = 0;
129  the_msgSender = 0;
130  mWin = 0;
131  mMailCheckAborted = false;
132 
133  // make sure that we check for config updates before doing anything else
134  KMKernel::config();
135  // this shares the kmailrc parsing too (via TDESharedConfig), and reads values from it
136  // so better do it here, than in some code where changing the group of config()
137  // would be unexpected
138  GlobalSettings::self();
139 
140  // Set up DCOP interface
141  mICalIface = new KMailICalIfaceImpl();
142 
143  mJobScheduler = new JobScheduler( this );
144 
145  mXmlGuiInstance = 0;
146 
147  new Kpgp::Module();
148 
149  // register our own (libtdenetwork) utf-7 codec as long as TQt
150  // doesn't have it's own:
151  if ( !TQTextCodec::codecForName("utf-7") ) {
152  kdDebug(5006) << "No TQt-native utf-7 codec found; registering TQUtf7Codec from libtdenetwork" << endl;
153  (void) new TQUtf7Codec();
154  }
155 
156  // In the case of Japan. Japanese locale name is "eucjp" but
157  // The Japanese mail systems normally used "iso-2022-jp" of locale name.
158  // We want to change locale name from eucjp to iso-2022-jp at KMail only.
159  if ( TQCString(TQTextCodec::codecForLocale()->name()).lower() == "eucjp" )
160  {
161  netCodec = TQTextCodec::codecForName("jis7");
162  // TQTextCodec *cdc = TQTextCodec::codecForName("jis7");
163  // TQTextCodec::setCodecForLocale(cdc);
164  // TDEGlobal::locale()->setEncoding(cdc->mibEnum());
165  } else {
166  netCodec = TQTextCodec::codecForLocale();
167  }
168  mMailService = new MailServiceImpl();
169 
170  connectDCOPSignal( 0, 0, "kmailSelectFolder(TQString)",
171  "selectFolder(TQString)", false );
172 
173 #ifdef __TDE_HAVE_TDEHWLIB
174  mNetworkManager = TDEGlobal::networkManager();
175  if (mNetworkManager) {
176  connect( mNetworkManager, TQ_SIGNAL( networkDeviceStateChanged( TDENetworkConnectionStatus::TDENetworkConnectionStatus, TDENetworkConnectionStatus::TDENetworkConnectionStatus, TQString ) ),
177  this, TQ_SLOT( slotNetworkStateChanged( TDENetworkConnectionStatus::TDENetworkConnectionStatus, TDENetworkConnectionStatus::TDENetworkConnectionStatus, TQString ) ) );
178  if (networkStateConnected()) {
179  resumeNetworkJobs();
180  }
181  else {
182  stopNetworkJobs();
183  }
184  }
185 #endif
186 }
187 
188 KMKernel::~KMKernel ()
189 {
190  TQMap<TDEIO::Job*, putData>::Iterator it = mPutJobs.begin();
191  while ( it != mPutJobs.end() )
192  {
193  TDEIO::Job *job = it.key();
194  mPutJobs.remove( it );
195  job->kill();
196  it = mPutJobs.begin();
197  }
198 
199  delete mICalIface;
200  mICalIface = 0;
201  delete mMailService;
202  mMailService = 0;
203 
204  GlobalSettings::self()->writeConfig();
205  delete mWallet;
206  mWallet = 0;
207  mySelf = 0;
208  kdDebug(5006) << "KMKernel::~KMKernel" << endl;
209 }
210 
211 bool KMKernel::handleCommandLine( bool noArgsOpensReader )
212 {
213  TQString to, cc, bcc, subj, body;
214  QCStringList customHeaders;
215  KURL messageFile;
216  KURL::List attachURLs;
217  bool mailto = false;
218  bool checkMail = false;
219  bool viewOnly = false;
220  bool calledWithSession = false; // for ignoring '-session foo'
221 
222  // process args:
223  TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs();
224  if (!args->getOption("subject").isNull())
225  {
226  subj = TQString::fromLocal8Bit(args->getOption("subject"));
227  // if kmail is called with 'kmail -session abc' then this doesn't mean
228  // that the user wants to send a message with subject "ession" but
229  // (most likely) that the user clicked on KMail's system tray applet
230  // which results in KMKernel::raise() calling "kmail kmail newInstance"
231  // via dcop which apparently executes the application with the original
232  // command line arguments and those include "-session ..." if
233  // kmail/kontact was restored by session management
234  if ( subj == "ession" ) {
235  subj = TQString();
236  calledWithSession = true;
237  }
238  else
239  mailto = true;
240  }
241 
242  if (!args->getOption("cc").isNull())
243  {
244  mailto = true;
245  cc = TQString::fromLocal8Bit(args->getOption("cc"));
246  }
247 
248  if (!args->getOption("bcc").isNull())
249  {
250  mailto = true;
251  bcc = TQString::fromLocal8Bit(args->getOption("bcc"));
252  }
253 
254  if (!args->getOption("msg").isNull())
255  {
256  mailto = true;
257  messageFile.setPath( TQString::fromLocal8Bit(args->getOption("msg")) );
258  }
259 
260  if (!args->getOption("body").isNull())
261  {
262  mailto = true;
263  body = TQString::fromLocal8Bit(args->getOption("body"));
264  }
265 
266  QCStringList attachList = args->getOptionList("attach");
267  if (!attachList.isEmpty())
268  {
269  mailto = true;
270  for ( QCStringList::Iterator it = attachList.begin() ; it != attachList.end() ; ++it )
271  if ( !(*it).isEmpty() )
272  attachURLs += KURL( TQString::fromLocal8Bit( *it ) );
273  }
274 
275  customHeaders = args->getOptionList("header");
276 
277  if (args->isSet("composer"))
278  mailto = true;
279 
280  if (args->isSet("check"))
281  checkMail = true;
282 
283  if ( !args->getOption( "view" ).isNull() ) {
284  viewOnly = true;
285  const TQString filename =
286  TQString::fromLocal8Bit( args->getOption( "view" ) );
287  messageFile = KURL::fromPathOrURL( filename );
288  if ( !messageFile.isValid() ) {
289  messageFile = KURL();
290  messageFile.setPath( filename );
291  }
292  }
293 
294  if ( !calledWithSession ) {
295  // only read additional command line arguments if kmail/kontact is
296  // not called with "-session foo"
297  for(int i= 0; i < args->count(); i++)
298  {
299  if (strncasecmp(args->arg(i),"mailto:",7)==0)
300  to += args->url(i).path() + ", ";
301  else {
302  TQString tmpArg = TQString::fromLocal8Bit( args->arg(i) );
303  KURL url( tmpArg );
304  if ( url.isValid() )
305  attachURLs += url;
306  else
307  to += tmpArg + ", ";
308  }
309  mailto = true;
310  }
311  if ( !to.isEmpty() ) {
312  // cut off the superfluous trailing ", "
313  to.truncate( to.length() - 2 );
314  }
315  }
316 
317  if ( !calledWithSession )
318  args->clear();
319 
320  if ( !noArgsOpensReader && !mailto && !checkMail && !viewOnly )
321  return false;
322 
323  if ( viewOnly )
324  viewMessage( messageFile );
325  else
326  action( mailto, checkMail, to, cc, bcc, subj, body, messageFile,
327  attachURLs, customHeaders );
328  return true;
329 }
330 
331 /********************************************************************/
332 /* DCOP-callable, and command line actions */
333 /********************************************************************/
334 void KMKernel::checkMail () //might create a new reader but won't show!!
335 {
336  if ( !kmkernel->askToGoOnline() )
337  return;
338  kmkernel->acctMgr()->checkMail(false);
339 }
340 
341 TQStringList KMKernel::accounts()
342 {
343  if( kmkernel->acctMgr() )
344  return kmkernel->acctMgr()->getAccounts();
345  return TQStringList();
346 }
347 
348 void KMKernel::checkAccount (const TQString &account) //might create a new reader but won't show!!
349 {
350  kdDebug(5006) << "KMKernel::checkMail called" << endl;
351 
352  KMAccount* acct = kmkernel->acctMgr()->findByName(account);
353  if (acct)
354  kmkernel->acctMgr()->singleCheckMail(acct, false);
355 }
356 
357 void KMKernel::loadProfile( const TQString& )
358 {
359 }
360 
361 void KMKernel::saveToProfile( const TQString& ) const
362 {
363 }
364 
365 void KMKernel::openReader( bool onlyCheck )
366 {
367  mWin = 0;
368  TDEMainWindow *ktmw = 0;
369  kdDebug(5006) << "KMKernel::openReader called" << endl;
370 
371  if (TDEMainWindow::memberList)
372  for (ktmw = TDEMainWindow::memberList->first(); ktmw;
373  ktmw = TDEMainWindow::memberList->next())
374  if (ktmw->isA("KMMainWin"))
375  break;
376 
377  bool activate;
378  if (ktmw) {
379  mWin = (KMMainWin *) ktmw;
380  activate = !onlyCheck; // existing window: only activate if not --check
381  if ( activate )
382  mWin->show();
383  } else {
384  mWin = new KMMainWin;
385  mWin->show();
386  activate = false; // new window: no explicit activation (#73591)
387  }
388 
389  if ( activate ) {
390  // Activate window - doing this instead of KWin::activateWindow(mWin->winId());
391  // so that it also works when called from KMailApplication::newInstance()
392 #if defined TQ_WS_X11 && ! defined K_WS_TQTONLY
393  TDEStartupInfo::setNewStartupId( mWin, kapp->startupId() );
394 #endif
395  }
396 }
397 
398 int KMKernel::openComposer (const TQString &to, const TQString &cc,
399  const TQString &bcc, const TQString &subject,
400  const TQString &body, int hidden,
401  const KURL &messageFile,
402  const KURL::List &attachURLs,
403  const QCStringList &customHeaders)
404 {
405  kdDebug(5006) << "KMKernel::openComposer called" << endl;
406  KMMessage *msg = new KMMessage;
407  msg->initHeader();
408  msg->setCharset("utf-8");
409  // tentatively decode to, cc and bcc because invokeMailer calls us with
410  // RFC 2047 encoded addresses in order to protect non-ASCII email addresses
411  if (!to.isEmpty())
412  msg->setTo( KMMsgBase::decodeRFC2047String( to.latin1() ) );
413  if (!cc.isEmpty())
414  msg->setCc( KMMsgBase::decodeRFC2047String( cc.latin1() ) );
415  if (!bcc.isEmpty())
416  msg->setBcc( KMMsgBase::decodeRFC2047String( bcc.latin1() ) );
417  if (!subject.isEmpty()) msg->setSubject(subject);
418  if (!messageFile.isEmpty() && messageFile.isLocalFile()) {
419  TQCString str = KPIM::kFileToString( messageFile.path(), true, false );
420  if( !str.isEmpty() ) {
421  msg->setBody( TQString(TQString::fromLocal8Bit( str )).utf8() );
422  } else {
423  TemplateParser parser( msg, TemplateParser::NewMessage );
424  parser.process( NULL, NULL );
425  }
426  }
427  else if (!body.isEmpty())
428  {
429  msg->setBody(body.utf8());
430  }
431  else
432  {
433  TemplateParser parser( msg, TemplateParser::NewMessage );
434  parser.process( NULL, NULL );
435  }
436 
437  if (!customHeaders.isEmpty())
438  {
439  for ( QCStringList::ConstIterator it = customHeaders.begin() ; it != customHeaders.end() ; ++it )
440  if ( !(*it).isEmpty() )
441  {
442  const int pos = (*it).find( ':' );
443  if ( pos > 0 )
444  {
445  TQCString header, value;
446  header = (*it).left( pos ).stripWhiteSpace();
447  value = (*it).mid( pos+1 ).stripWhiteSpace();
448  if ( !header.isEmpty() && !value.isEmpty() )
449  msg->setHeaderField( header, value );
450  }
451  }
452  }
453 
454  KMail::Composer * cWin = KMail::makeComposer( msg );
455  cWin->setCharset("", true);
456  for ( KURL::List::ConstIterator it = attachURLs.begin() ; it != attachURLs.end() ; ++it )
457  cWin->addAttach((*it));
458  if (hidden == 0) {
459  cWin->show();
460  // Activate window - doing this instead of KWin::activateWindow(cWin->winId());
461  // so that it also works when called from KMailApplication::newInstance()
462 #if defined TQ_WS_X11 && ! defined K_WS_TQTONLY
463  TDEStartupInfo::setNewStartupId( cWin, kapp->startupId() );
464 #endif
465  }
466  return 1;
467 }
468 
469 
470 int KMKernel::openComposer (const TQString &to, const TQString &cc,
471  const TQString &bcc, const TQString &subject,
472  const TQString &body, int hidden,
473  const TQString &attachName,
474  const TQCString &attachCte,
475  const TQCString &attachData,
476  const TQCString &attachType,
477  const TQCString &attachSubType,
478  const TQCString &attachParamAttr,
479  const TQString &attachParamValue,
480  const TQCString &attachContDisp )
481 {
482  kdDebug(5006) << "KMKernel::openComposer called (deprecated version)" << endl;
483 
484  return openComposer ( to, cc, bcc, subject, body, hidden,
485  attachName, attachCte, attachData,
486  attachType, attachSubType, attachParamAttr,
487  attachParamValue, attachContDisp, TQCString() );
488 }
489 
490 int KMKernel::openComposer (const TQString &to, const TQString &cc,
491  const TQString &bcc, const TQString &subject,
492  const TQString &body, int hidden,
493  const TQString &attachName,
494  const TQCString &attachCte,
495  const TQCString &attachData,
496  const TQCString &attachType,
497  const TQCString &attachSubType,
498  const TQCString &attachParamAttr,
499  const TQString &attachParamValue,
500  const TQCString &attachContDisp,
501  const TQCString &attachCharset )
502 {
503  kdDebug(5006) << "KMKernel::openComposer called (deprecated version)" << endl;
504  return openComposer ( to, cc, bcc, subject, body, hidden,
505  attachName, attachCte, attachData,
506  attachType, attachSubType, attachParamAttr,
507  attachParamValue, attachContDisp, attachCharset, 0 );
508 }
509 
510 int KMKernel::openComposer (const TQString &to, const TQString &cc,
511  const TQString &bcc, const TQString &subject,
512  const TQString &body, int hidden,
513  const TQString &attachName,
514  const TQCString &attachCte,
515  const TQCString &attachData,
516  const TQCString &attachType,
517  const TQCString &attachSubType,
518  const TQCString &attachParamAttr,
519  const TQString &attachParamValue,
520  const TQCString &attachContDisp,
521  const TQCString &attachCharset,
522  unsigned int identity )
523 {
524  kdDebug(5006) << "KMKernel::openComposer()" << endl;
525 
526  KMMessage *msg = new KMMessage;
527  KMMessagePart *msgPart = 0;
528  msg->initHeader();
529  msg->setCharset( "utf-8" );
530  if ( !cc.isEmpty() ) msg->setCc(cc);
531  if ( !bcc.isEmpty() ) msg->setBcc(bcc);
532  if ( !subject.isEmpty() ) msg->setSubject(subject);
533  if ( !to.isEmpty() ) msg->setTo(to);
534  if ( identity > 0 ) msg->setHeaderField( "X-KMail-Identity", TQString::number( identity ) );
535  if ( !body.isEmpty() ) {
536  msg->setBody(body.utf8());
537  } else {
538  TemplateParser parser( msg, TemplateParser::NewMessage );
539  parser.process( NULL, NULL );
540  }
541 
542  bool iCalAutoSend = false;
543  bool noWordWrap = false;
544  bool isICalInvitation = false;
545  TDEConfigGroup options( config(), "Groupware" );
546  if ( !attachData.isEmpty() ) {
547  isICalInvitation = attachName == "cal.ics" &&
548  attachType == "text" &&
549  attachSubType == "calendar" &&
550  attachParamAttr == "method";
551  // Remove BCC from identity on ical invitations (https://intevation.de/roundup/kolab/issue474)
552  if ( isICalInvitation && bcc.isEmpty() )
553  msg->setBcc( "" );
554  if ( isICalInvitation &&
555  GlobalSettings::self()->legacyBodyInvites() ) {
556  // KOrganizer invitation caught and to be sent as body instead
557  msg->setBody( attachData );
558  msg->setHeaderField( "Content-Type",
559  TQString( "text/calendar; method=%1; "
560  "charset=\"utf-8\"" ).
561  arg( attachParamValue ) );
562 
563  iCalAutoSend = true; // no point in editing raw ICAL
564  noWordWrap = true; // we shant word wrap inline invitations
565  } else {
566  // Just do what we're told to do
567  msgPart = new KMMessagePart;
568  msgPart->setName( attachName );
569  msgPart->setCteStr( attachCte );
570  msgPart->setBodyEncoded( attachData );
571  msgPart->setTypeStr( attachType );
572  msgPart->setSubtypeStr( attachSubType );
573  msgPart->setParameter( attachParamAttr, attachParamValue );
574  if( ! GlobalSettings::self()->exchangeCompatibleInvitations() ) {
575  msgPart->setContentDisposition( attachContDisp );
576  }
577  if( !attachCharset.isEmpty() && (msgPart->type() == DwMime::kTypeText) ) {
578  // kdDebug(5006) << "KMKernel::openComposer set attachCharset to "
579  // << attachCharset << endl;
580  msgPart->setCharset( attachCharset );
581  }
582  // Don't show the composer window, if the automatic sending is checked
583  TDEConfigGroup options( config(), "Groupware" );
584  iCalAutoSend = options.readBoolEntry( "AutomaticSending", true );
585  }
586  }
587 
588  KMail::Composer * cWin = KMail::makeComposer();
589  cWin->setMsg( msg, !isICalInvitation /* mayAutoSign */ );
590  cWin->setSigningAndEncryptionDisabled( isICalInvitation
591  && GlobalSettings::self()->legacyBodyInvites() );
592  cWin->setAutoDelete( true );
593  if( noWordWrap )
594  cWin->disableWordWrap();
595  else
596  cWin->setCharset( "", true );
597  if ( msgPart )
598  cWin->addAttach(msgPart);
599 
600  if ( isICalInvitation ) {
601  cWin->disableRecipientNumberCheck();
602  cWin->disableForgottenAttachmentsCheck();
603  }
604 
605  if ( hidden == 0 && !iCalAutoSend ) {
606  cWin->show();
607  // Activate window - doing this instead of KWin::activateWindow(cWin->winId());
608  // so that it also works when called from KMailApplication::newInstance()
609 #if defined TQ_WS_X11 && ! defined K_WS_TQTONLY
610  TDEStartupInfo::setNewStartupId( cWin, kapp->startupId() );
611 #endif
612  } else {
613  cWin->setAutoDeleteWindow( true );
614  cWin->slotSendNow();
615  }
616 
617  return 1;
618 }
619 
620 void KMKernel::setDefaultTransport( const TQString & transport )
621 {
622  TQStringList availTransports = KMail::TransportManager::transportNames();
623  TQStringList::const_iterator it = availTransports.find( transport );
624  if ( it == availTransports.end() ) {
625  kdWarning() << "The transport you entered is not available" << endl;
626  return;
627  }
628  GlobalSettings::self()->setDefaultTransport( transport );
629 }
630 
631 DCOPRef KMKernel::openComposer(const TQString &to, const TQString &cc,
632  const TQString &bcc, const TQString &subject,
633  const TQString &body,bool hidden)
634 {
635  KMMessage *msg = new KMMessage;
636  msg->initHeader();
637  msg->setCharset("utf-8");
638  if (!cc.isEmpty()) msg->setCc(cc);
639  if (!bcc.isEmpty()) msg->setBcc(bcc);
640  if (!subject.isEmpty()) msg->setSubject(subject);
641  if (!to.isEmpty()) msg->setTo(to);
642  if (!body.isEmpty()) {
643  msg->setBody(body.utf8());
644  } else {
645  TemplateParser parser( msg, TemplateParser::NewMessage );
646  parser.process( NULL, NULL );
647  }
648 
649  KMail::Composer * cWin = KMail::makeComposer( msg );
650  cWin->setCharset("", true);
651  if (!hidden) {
652  cWin->show();
653  // Activate window - doing this instead of KWin::activateWindow(cWin->winId());
654  // so that it also works when called from KMailApplication::newInstance()
655 #if defined TQ_WS_X11 && ! defined K_WS_TQTONLY
656  TDEStartupInfo::setNewStartupId( cWin, kapp->startupId() );
657 #endif
658  }
659 
660  return DCOPRef( cWin->asMailComposerIFace() );
661 }
662 
663 DCOPRef KMKernel::newMessage(const TQString &to,
664  const TQString &cc,
665  const TQString &bcc,
666  bool hidden,
667  bool useFolderId,
668  const KURL & /*messageFile*/,
669  const KURL &attachURL)
670 {
671  KMail::Composer * win = 0;
672  KMMessage *msg = new KMMessage;
673  KMFolder *folder = NULL;
674  uint id;
675 
676  if ( useFolderId ) {
677  //create message with required folder identity
678  folder = currentFolder();
679  id = folder ? folder->identity() : 0;
680  msg->initHeader( id );
681  } else {
682  msg->initHeader();
683  }
684  msg->setCharset("utf-8");
685  //set basic headers
686  if (!to.isEmpty()) msg->setTo(to);
687  if (!cc.isEmpty()) msg->setCc(cc);
688  if (!bcc.isEmpty()) msg->setBcc(bcc);
689 
690  if ( useFolderId ) {
691  TemplateParser parser( msg, TemplateParser::NewMessage );
692  parser.process( NULL, folder );
693  win = makeComposer( msg, id );
694  } else {
695  TemplateParser parser( msg, TemplateParser::NewMessage );
696  parser.process( NULL, folder );
697  win = makeComposer( msg );
698  }
699 
700  //Add the attachment if we have one
701  if(!attachURL.isEmpty() && attachURL.isValid()) {
702  win->addAttach(attachURL);
703  }
704 
705  //only show window when required
706  if(!hidden) {
707  win->show();
708  }
709  return DCOPRef( win->asMailComposerIFace() );
710 }
711 
712 int KMKernel::viewMessage( const KURL & messageFile )
713 {
714  KMOpenMsgCommand *openCommand = new KMOpenMsgCommand( 0, messageFile );
715 
716  openCommand->start();
717 
718  return 1;
719 }
720 
721 int KMKernel::sendCertificate( const TQString& to, const TQByteArray& certData )
722 {
723  KMMessage *msg = new KMMessage;
724  msg->initHeader();
725  msg->setCharset("utf-8");
726  msg->setSubject( i18n( "Certificate Signature Request" ) );
727  if (!to.isEmpty()) msg->setTo(to);
728  // ### Make this message customizable via KIOSK
729  msg->setBody( i18n( "Please create a certificate from attachment and return to sender." ).utf8() );
730 
731  KMail::Composer * cWin = KMail::makeComposer( msg );
732  cWin->setCharset("", true);
733  cWin->slotSetAlwaysSend( true );
734  if (!certData.isEmpty()) {
735  KMMessagePart *msgPart = new KMMessagePart;
736  msgPart->setName("smime.p10");
737  msgPart->setCteStr("base64");
738  msgPart->setBodyEncodedBinary(certData);
739  msgPart->setTypeStr("application");
740  msgPart->setSubtypeStr("pkcs10");
741  msgPart->setContentDisposition("attachment; filename=smime.p10");
742  cWin->addAttach(msgPart);
743  }
744 
745  cWin->show();
746  return 1;
747 }
748 
749 KMMsgStatus KMKernel::strToStatus(const TQString &flags)
750 {
751  KMMsgStatus status = 0;
752  if (!flags.isEmpty()) {
753  for (uint n = 0; n < flags.length() ; n++) {
754  switch (flags[n]) {
755  case 'N':
756  status |= KMMsgStatusNew;
757  break;
758  case 'U':
759  status |= KMMsgStatusUnread;
760  break;
761  case 'O':
762  status |= KMMsgStatusOld;
763  break;
764  case 'R':
765  status |= KMMsgStatusRead;
766  break;
767  case 'D':
768  status |= KMMsgStatusDeleted;
769  break;
770  case 'A':
771  status |= KMMsgStatusReplied;
772  break;
773  case 'F':
774  status |= KMMsgStatusForwarded;
775  break;
776  case 'Q':
777  status |= KMMsgStatusQueued;
778  break;
779  case 'K':
780  status |= KMMsgStatusTodo;
781  break;
782  case 'S':
783  status |= KMMsgStatusSent;
784  break;
785  case 'G':
786  status |= KMMsgStatusFlag;
787  break;
788  case 'W':
789  status |= KMMsgStatusWatched;
790  break;
791  case 'I':
792  status |= KMMsgStatusIgnored;
793  break;
794  case 'P':
795  status |= KMMsgStatusSpam;
796  break;
797  case 'H':
798  status |= KMMsgStatusHam;
799  break;
800  case 'T':
801  status |= KMMsgStatusHasAttach;
802  break;
803  case 'C':
804  status |= KMMsgStatusHasNoAttach;
805  break;
806  default:
807  break;
808  }
809  }
810  }
811  return status;
812 }
813 
814 int KMKernel::dcopAddMessage( const TQString & foldername, const TQString & msgUrlString,
815  const TQString & MsgStatusFlags)
816 {
817  return dcopAddMessage(foldername, KURL(msgUrlString), MsgStatusFlags);
818 }
819 
820 int KMKernel::dcopAddMessage( const TQString & foldername,const KURL & msgUrl,
821  const TQString & MsgStatusFlags)
822 {
823  kdDebug(5006) << "KMKernel::dcopAddMessage called" << endl;
824 
825  if ( foldername.isEmpty() || foldername.startsWith("."))
826  return -1;
827 
828  int retval;
829  bool readFolderMsgIds = false;
830  TQString _foldername = foldername.stripWhiteSpace();
831  _foldername = _foldername.replace('\\',""); //try to prevent ESCAPE Sequences
832 
833  if ( foldername != mAddMessageLastFolder ) {
834  mAddMessageMsgIds.clear();
835  readFolderMsgIds = true;
836  mAddMessageLastFolder = foldername;
837  }
838 
839  if (!msgUrl.isEmpty() && msgUrl.isLocalFile()) {
840 
841  // This is a proposed change by Daniel Andor.
842  // He proposed to change from the fopen(blah)
843  // to a KPIM::kFileToString(blah).
844  // Although it assigns a TQString to a TQString,
845  // because of the implicit sharing this poses
846  // no memory or performance penalty.
847 
848  const TQCString messageText =
849  KPIM::kFileToString( msgUrl.path(), true, false );
850  if ( messageText.isEmpty() )
851  return -2;
852 
853  KMMessage *msg = new KMMessage();
854  msg->fromString( messageText );
855 
856  if (readFolderMsgIds) {
857  if ( foldername.contains("/")) {
858  TQString tmp_fname = "";
859  KMFolder *folder = NULL;
860  KMFolderDir *subfolder;
861  bool root = true;
862 
863  TQStringList subFList = TQStringList::split("/",_foldername,false);
864 
865  for ( TQStringList::Iterator it = subFList.begin(); it != subFList.end(); ++it ) {
866  TQString _newFolder = *it;
867  if(_newFolder.startsWith(".")) return -1;
868 
869  if(root) {
870  folder = the_folderMgr->findOrCreate(*it, false);
871  if (folder) {
872  root = false;
873  tmp_fname = "/" + *it;
874  }
875  else return -1;
876  } else {
877  subfolder = folder->createChildFolder();
878  tmp_fname += "/" + *it;
879  if(!the_folderMgr->getFolderByURL( tmp_fname )) {
880  folder = the_folderMgr->createFolder(*it, false, folder->folderType(), subfolder);
881  }
882 
883  if(!(folder = the_folderMgr->getFolderByURL( tmp_fname ))) return -1;
884  }
885  }
886 
887  mAddMsgCurrentFolder = the_folderMgr->getFolderByURL( tmp_fname );
888  if(!folder) return -1;
889 
890  } else {
891  mAddMsgCurrentFolder = the_folderMgr->findOrCreate(_foldername, false);
892  }
893  }
894 
895  if ( mAddMsgCurrentFolder ) {
896  if (readFolderMsgIds) {
897 
898  // OLD COMMENT:
899  // Try to determine if a message already exists in
900  // the folder. The message id that is searched for, is
901  // the subject line + the date. This should be quite
902  // unique. The change that a given date with a given
903  // subject is in the folder twice is very small.
904  // If the subject is empty, the fromStrip string
905  // is taken.
906 
907  // NEW COMMENT from Danny Kukawka (danny.kukawka@web.de):
908  // subject line + the date is only unique if the following
909  // return a correct unique value:
910  // time_t DT = mb->date();
911  // TQString dt = ctime(&DT);
912  // But if the datestring in the Header isn't RFC conform
913  // subject line + the date isn't unique.
914  //
915  // The only uique headerfield is the Message-ID. In some
916  // cases this could be empty. I then I use the
917  // subject line + dateStr .
918 
919  int i;
920 
921  mAddMsgCurrentFolder->open("dcopadd");
922  for( i=0; i<mAddMsgCurrentFolder->count(); i++) {
923  KMMsgBase *mb = mAddMsgCurrentFolder->getMsgBase(i);
924  TQString id = mb->msgIdMD5();
925  if ( id.isEmpty() ) {
926  id = mb->subject();
927  if ( id.isEmpty() )
928  id = mb->fromStrip();
929  if ( id.isEmpty() )
930  id = mb->toStrip();
931 
932  id += mb->dateStr();
933  }
934 
935  //fprintf(stderr,"%s\n",(const char *) id);
936  if ( !id.isEmpty() ) {
937  mAddMessageMsgIds.append(id);
938  }
939  }
940  mAddMsgCurrentFolder->close("dcopadd");
941  }
942 
943  TQString msgId = msg->msgIdMD5();
944  if ( msgId.isEmpty()) {
945  msgId = msg->subject();
946  if ( msgId.isEmpty() )
947  msgId = msg->fromStrip();
948  if ( msgId.isEmpty() )
949  msgId = msg->toStrip();
950 
951  msgId += msg->dateStr();
952  }
953 
954  int k = mAddMessageMsgIds.findIndex( msgId );
955  //fprintf(stderr,"find %s = %d\n",(const char *) msgId,k);
956 
957  if ( k == -1 ) {
958  if ( !msgId.isEmpty() ) {
959  mAddMessageMsgIds.append( msgId );
960  }
961 
962  if ( !MsgStatusFlags.isEmpty() ) {
963  KMMsgStatus status = strToStatus(MsgStatusFlags);
964  if (status) msg->setStatus(status);
965  }
966 
967  int index;
968  if ( mAddMsgCurrentFolder->addMsg( msg, &index ) == 0 ) {
969  mAddMsgCurrentFolder->unGetMsg( index );
970  retval = 1;
971  } else {
972  retval =- 2;
973  delete msg;
974  msg = 0;
975  }
976  } else {
977  //tqDebug( "duplicate: " + msgId + "; subj: " + msg->subject() + ", from: " + msgId = msg->fromStrip());
978  retval = -4;
979  }
980  } else {
981  retval = -1;
982  }
983  } else {
984  retval = -2;
985  }
986  return retval;
987 }
988 
990 {
991  mAddMessageMsgIds.clear();
992  mAddMessageLastFolder = TQString();
993 }
994 
995 int KMKernel::dcopAddMessage_fastImport( const TQString & foldername,
996  const TQString & msgUrlString,
997  const TQString & MsgStatusFlags)
998 {
999  return dcopAddMessage_fastImport(foldername, KURL(msgUrlString), MsgStatusFlags);
1000 }
1001 
1002 int KMKernel::dcopAddMessage_fastImport( const TQString & foldername,
1003  const KURL & msgUrl,
1004  const TQString & MsgStatusFlags)
1005 {
1006  // Use this function to import messages without
1007  // search for already existing emails.
1008  kdDebug(5006) << "KMKernel::dcopAddMessage_fastImport called" << endl;
1009 
1010  if ( foldername.isEmpty() || foldername.startsWith("."))
1011  return -1;
1012 
1013  int retval;
1014  bool createNewFolder = false;
1015 
1016  TQString _foldername = foldername.stripWhiteSpace();
1017  _foldername = _foldername.replace('\\',""); //try to prevent ESCAPE Sequences
1018 
1019  if ( foldername != mAddMessageLastFolder ) {
1020  createNewFolder = true;
1021  mAddMessageLastFolder = foldername;
1022  }
1023 
1024 
1025  if ( !msgUrl.isEmpty() && msgUrl.isLocalFile() ) {
1026  const TQCString messageText =
1027  KPIM::kFileToString( msgUrl.path(), true, false );
1028  if ( messageText.isEmpty() )
1029  return -2;
1030 
1031  KMMessage *msg = new KMMessage();
1032  msg->fromString( messageText );
1033 
1034  if (createNewFolder) {
1035  if ( foldername.contains("/")) {
1036  TQString tmp_fname = "";
1037  KMFolder *folder = NULL;
1038  KMFolderDir *subfolder;
1039  bool root = true;
1040 
1041  TQStringList subFList = TQStringList::split("/",_foldername,false);
1042 
1043  for ( TQStringList::Iterator it = subFList.begin(); it != subFList.end(); ++it ) {
1044  TQString _newFolder = *it;
1045  if(_newFolder.startsWith(".")) return -1;
1046 
1047  if(root) {
1048  folder = the_folderMgr->findOrCreate(*it, false);
1049  if (folder) {
1050  root = false;
1051  tmp_fname = "/" + *it;
1052  }
1053  else return -1;
1054  } else {
1055  subfolder = folder->createChildFolder();
1056  tmp_fname += "/" + *it;
1057  if(!the_folderMgr->getFolderByURL( tmp_fname )) {
1058  folder = the_folderMgr->createFolder(*it, false, folder->folderType(), subfolder);
1059  }
1060  if(!(folder = the_folderMgr->getFolderByURL( tmp_fname ))) return -1;
1061  }
1062  }
1063 
1064  mAddMsgCurrentFolder = the_folderMgr->getFolderByURL( tmp_fname );
1065  if(!folder) return -1;
1066 
1067  } else {
1068  mAddMsgCurrentFolder = the_folderMgr->findOrCreate(_foldername, false);
1069  }
1070  }
1071 
1072  if ( mAddMsgCurrentFolder ) {
1073  int index;
1074 
1075  if( !MsgStatusFlags.isEmpty() ) {
1076  KMMsgStatus status = strToStatus(MsgStatusFlags);
1077  if (status) msg->setStatus(status);
1078  }
1079 
1080  if ( mAddMsgCurrentFolder->addMsg( msg, &index ) == 0 ) {
1081  mAddMsgCurrentFolder->unGetMsg( index );
1082  retval = 1;
1083  } else {
1084  retval =- 2;
1085  delete msg;
1086  msg = 0;
1087  }
1088  } else {
1089  retval = -1;
1090  }
1091  } else {
1092  retval = -2;
1093  }
1094 
1095  return retval;
1096 }
1097 
1098 void KMKernel::showImportArchiveDialog()
1099 {
1100  KMMainWidget *mainWidget = getKMMainWidget();
1101  KMail::ImportArchiveDialog *importDialog = new KMail::ImportArchiveDialog( mainWidget, WDestructiveClose );
1102  importDialog->setFolder( mainWidget->folderTree()->currentFolder() );
1103  importDialog->show();
1104 }
1105 
1106 TQStringList KMKernel::folderList() const
1107 {
1108  TQStringList folders;
1109  const TQString localPrefix = "/Local";
1110  folders << localPrefix;
1111  the_folderMgr->getFolderURLS( folders, localPrefix );
1112  the_imapFolderMgr->getFolderURLS( folders );
1113  the_dimapFolderMgr->getFolderURLS( folders );
1114  return folders;
1115 }
1116 
1117 DCOPRef KMKernel::getFolder( const TQString& vpath )
1118 {
1119  const TQString localPrefix = "/Local";
1120  if ( the_folderMgr->getFolderByURL( vpath ) )
1121  return DCOPRef( new FolderIface( vpath ) );
1122  else if ( vpath.startsWith( localPrefix ) &&
1123  the_folderMgr->getFolderByURL( vpath.mid( localPrefix.length() ) ) )
1124  return DCOPRef( new FolderIface( vpath.mid( localPrefix.length() ) ) );
1125  else if ( the_imapFolderMgr->getFolderByURL( vpath ) )
1126  return DCOPRef( new FolderIface( vpath ) );
1127  else if ( the_dimapFolderMgr->getFolderByURL( vpath ) )
1128  return DCOPRef( new FolderIface( vpath ) );
1129  return DCOPRef();
1130 }
1131 
1132 void KMKernel::raise()
1133 {
1134  DCOPRef kmail( "kmail", "kmail" );
1135  kmail.call( "newInstance" );
1136 }
1137 
1138 bool KMKernel::showMail( TQ_UINT32 serialNumber, TQString /* messageId */ )
1139 {
1140  KMMainWidget *mainWidget = 0;
1141  if (TDEMainWindow::memberList) {
1142  TDEMainWindow *win = 0;
1143  TQObjectList *l;
1144 
1145  // First look for a TDEMainWindow.
1146  for (win = TDEMainWindow::memberList->first(); win;
1147  win = TDEMainWindow::memberList->next()) {
1148  // Then look for a KMMainWidget.
1149  l = win->queryList("KMMainWidget");
1150  if (l && l->first()) {
1151  mainWidget = dynamic_cast<KMMainWidget *>(l->first());
1152  if (win->isActiveWindow())
1153  break;
1154  }
1155  }
1156  }
1157 
1158  if (mainWidget) {
1159  int idx = -1;
1160  KMFolder *folder = 0;
1161  KMMsgDict::instance()->getLocation(serialNumber, &folder, &idx);
1162  if (!folder || (idx == -1))
1163  return false;
1164  KMFolderOpener openFolder(folder, "showmail");
1165  KMMsgBase *msgBase = folder->getMsgBase(idx);
1166  if (!msgBase)
1167  return false;
1168  bool unGet = !msgBase->isMessage();
1169  KMMessage *msg = folder->getMsg(idx);
1170 
1171  KMReaderMainWin *win = new KMReaderMainWin( false, false );
1172  KMMessage *newMessage = new KMMessage( *msg );
1173  newMessage->setParent( msg->parent() );
1174  newMessage->setMsgSerNum( msg->getMsgSerNum() );
1175  newMessage->setReadyToShow( true );
1176  win->showMsg( GlobalSettings::self()->overrideCharacterEncoding(), newMessage );
1177  win->show();
1178 
1179  if (unGet)
1180  folder->unGetMsg(idx);
1181  return true;
1182  }
1183 
1184  return false;
1185 }
1186 
1187 TQString KMKernel::getFrom( TQ_UINT32 serialNumber )
1188 {
1189  int idx = -1;
1190  KMFolder *folder = 0;
1191  KMMsgDict::instance()->getLocation(serialNumber, &folder, &idx);
1192  if (!folder || (idx == -1))
1193  return TQString();
1194  KMFolderOpener openFolder(folder, "getFrom");
1195  KMMsgBase *msgBase = folder->getMsgBase(idx);
1196  if (!msgBase)
1197  return TQString();
1198  bool unGet = !msgBase->isMessage();
1199  KMMessage *msg = folder->getMsg(idx);
1200  TQString result = msg->from();
1201  if (unGet)
1202  folder->unGetMsg(idx);
1203  return result;
1204 }
1205 
1206 TQString KMKernel::debugScheduler()
1207 {
1208  TQString res = KMail::ActionScheduler::debug();
1209  return res;
1210 }
1211 
1212 TQString KMKernel::debugSernum( TQ_UINT32 serialNumber )
1213 {
1214  TQString res;
1215  if (serialNumber != 0) {
1216  int idx = -1;
1217  KMFolder *folder = 0;
1218  KMMsgBase *msg = 0;
1219  KMMsgDict::instance()->getLocation( serialNumber, &folder, &idx );
1220  // It's possible that the message has been deleted or moved into a
1221  // different folder
1222  if (folder && (idx != -1)) {
1223  // everything is ok
1224  KMFolderOpener openFolder(folder, "debugser");
1225  msg = folder->getMsgBase( idx );
1226  if (msg) {
1227  res.append( TQString( " subject %s,\n sender %s,\n date %s.\n" )
1228  .arg( msg->subject() )
1229  .arg( msg->fromStrip() )
1230  .arg( msg->dateStr() ) );
1231  } else {
1232  res.append( TQString( "Invalid serial number." ) );
1233  }
1234  } else {
1235  res.append( TQString( "Invalid serial number." ) );
1236  }
1237  }
1238  return res;
1239 }
1240 
1241 
1243 {
1244  mBackgroundTasksTimer->stop();
1245  mJobScheduler->pause();
1246 }
1247 
1249 {
1250  mJobScheduler->resume();
1251  mBackgroundTasksTimer->start( 4 * 60 * 60 * 1000, true );
1252 }
1253 
1255 {
1256  if ( GlobalSettings::self()->networkState() == GlobalSettings::EnumNetworkState::Offline )
1257  return;
1258 
1259  GlobalSettings::setNetworkState( GlobalSettings::EnumNetworkState::Offline );
1260  BroadcastStatus::instance()->setStatusMsg( i18n("KMail is set to be offline; all network jobs are suspended"));
1261  emit onlineStatusChanged( (GlobalSettings::EnumNetworkState::type)GlobalSettings::networkState() );
1262 }
1263 
1265 {
1266  if ( GlobalSettings::self()->networkState() == GlobalSettings::EnumNetworkState::Online )
1267  return;
1268 
1269  GlobalSettings::setNetworkState( GlobalSettings::EnumNetworkState::Online );
1270  BroadcastStatus::instance()->setStatusMsg( i18n("KMail is set to be online; all network jobs resumed"));
1271  emit onlineStatusChanged( (GlobalSettings::EnumNetworkState::type)GlobalSettings::networkState() );
1272 
1273  if ( kmkernel->msgSender() && kmkernel->msgSender()->sendImmediate() ) {
1274  kmkernel->msgSender()->sendQueued();
1275  }
1276 }
1277 
1279 {
1280  if ( GlobalSettings::self()->networkState() == GlobalSettings::EnumNetworkState::Offline )
1281  return true;
1282  else
1283  return false;
1284 }
1285 
1287 {
1288  // already asking means we are offline and need to wait anyhow
1289  if ( s_askingToGoOnline ) {
1290  return false;
1291  }
1292 
1293  if ( kmkernel->isOffline() ) {
1294  s_askingToGoOnline = true;
1295  int rc =
1296  KMessageBox::questionYesNo( KMKernel::self()->mainWin(),
1297  i18n("KMail is currently in offline mode. "
1298  "How do you want to proceed?"),
1299  i18n("Online/Offline"),
1300  i18n("Work Online"),
1301  i18n("Work Offline"));
1302 
1303  s_askingToGoOnline = false;
1304  if( rc == KMessageBox::No ) {
1305  return false;
1306  } else {
1307  kmkernel->resumeNetworkJobs();
1308  }
1309  }
1310  return true;
1311 }
1312 
1313 /********************************************************************/
1314 /* Kernel methods */
1315 /********************************************************************/
1316 
1317 void KMKernel::quit()
1318 {
1319  // Called when all windows are closed. Will take care of compacting,
1320  // sending... should handle session management too!!
1321 }
1322  /* TODO later:
1323  Asuming that:
1324  - msgsender is nonblocking
1325  (our own, TQSocketNotifier based. Pops up errors and sends signal
1326  senderFinished when done)
1327 
1328  o If we are getting mail, stop it (but dont lose something!)
1329  [Done already, see mailCheckAborted]
1330  o If we are sending mail, go on UNLESS this was called by SM,
1331  in which case stop ASAP that too (can we warn? should we continue
1332  on next start?)
1333  o If we are compacting, or expunging, go on UNLESS this was SM call.
1334  In that case stop compacting ASAP and continue on next start, before
1335  touching any folders. [Not needed anymore with CompactionJob]
1336 
1337  KMKernel::quit ()
1338  {
1339  SM call?
1340  if compacting, stop;
1341  if sending, stop;
1342  if receiving, stop;
1343  Windows will take care of themselves (composer should dump
1344  its messages, if any but not in deadMail)
1345  declare us ready for the End of the Session
1346 
1347  No, normal quit call
1348  All windows are off. Anything to do, should compact or sender sends?
1349  Yes, maybe put an icon in panel as a sign of life
1350  if sender sending, connect us to his finished slot, declare us ready
1351  for quit and wait for senderFinished
1352  if not, Folder manager, go compact sent-mail and outbox
1353 } (= call slotFinished())
1354 
1355 void KMKernel::slotSenderFinished()
1356 {
1357  good, Folder manager go compact sent-mail and outbox
1358  clean up stage1 (release folders and config, unregister from dcop)
1359  -- another kmail may start now ---
1360  kapp->quit();
1361 }
1362 */
1363 
1364 
1365 /********************************************************************/
1366 /* Init, Exit, and handler methods */
1367 /********************************************************************/
1368 void KMKernel::testDir(const char *_name)
1369 {
1370  TQString foldersPath = TQDir::homeDirPath() + TQString( _name );
1371  TQFileInfo info( foldersPath );
1372  if ( !info.exists() ) {
1373  if ( ::mkdir( TQFile::encodeName( foldersPath ) , S_IRWXU ) == -1 ) {
1374  KMessageBox::sorry(0, i18n("KMail could not create folder '%1';\n"
1375  "please make sure that you can view and "
1376  "modify the content of the folder '%2'.")
1377  .arg( foldersPath ).arg( TQDir::homeDirPath() ) );
1378  ::exit(-1);
1379  }
1380  }
1381  if ( !info.isDir() || !info.isReadable() || !info.isWritable() ) {
1382  KMessageBox::sorry(0, i18n("The permissions of the folder '%1' are "
1383  "incorrect;\n"
1384  "please make sure that you can view and modify "
1385  "the content of this folder.")
1386  .arg( foldersPath ) );
1387  ::exit(-1);
1388  }
1389 }
1390 
1391 
1392 //-----------------------------------------------------------------------------
1393 // Open a composer for each message found in the dead.letter folder
1394 void KMKernel::recoverDeadLetters()
1395 {
1396  TQDir dir( localDataPath() + "autosave/cur" );
1397  if ( !dir.exists() ) {
1398  kdWarning(5006) << "Autosave directory " << dir.path() << " not found!" << endl;
1399  return;
1400  }
1401 
1402  const TQStringList entryList = dir.entryList( TQDir::Files | TQDir::NoSymLinks, TQDir::Unsorted );
1403  for ( unsigned int i = 0; i < entryList.size(); i++ ) {
1404  const TQString fileName = entryList[i];
1405  TQFile file( dir.path() + '/' + fileName );
1406  if ( !file.open( IO_ReadOnly ) ) {
1407  kdWarning(5006) << "Unable to open autosave file " << fileName << endl;
1408  continue;
1409  }
1410  const TQByteArray msgData = file.readAll();
1411  file.close();
1412 
1413  if ( msgData.isEmpty() ) {
1414  kdWarning(5006) << "autosave file " << fileName << " is empty!" << endl;
1415  continue;
1416  }
1417 
1418  KMMessage *msg = new KMMessage(); // Composer will take ownership
1419  msg->fromByteArray( msgData );
1420  KMail::Composer * win = KMail::makeComposer();
1421  win->setMsg( msg, false, false, true );
1422  win->setAutoSaveFilename( fileName );
1423  win->show();
1424  }
1425 }
1426 
1427 //-----------------------------------------------------------------------------
1428 void KMKernel::initFolders(TDEConfig* cfg)
1429 {
1430  TQString name;
1431 
1432  name = cfg->readEntry("inboxFolder");
1433 
1434  // Currently the folder manager cannot manage folders which are not
1435  // in the base folder directory.
1436  //if (name.isEmpty()) name = getenv("MAIL");
1437 
1438  if (name.isEmpty()) name = I18N_NOOP("inbox");
1439 
1440  the_inboxFolder = (KMFolder*)the_folderMgr->findOrCreate(name);
1441 
1442  if (the_inboxFolder->canAccess() != 0) {
1443  emergencyExit( i18n("You do not have read/write permission to your inbox folder.") );
1444  }
1445 
1446  the_inboxFolder->setSystemFolder(true);
1447  if ( the_inboxFolder->userWhoField().isEmpty() )
1448  the_inboxFolder->setUserWhoField( TQString() );
1449  // inboxFolder->open();
1450 
1451  the_outboxFolder = the_folderMgr->findOrCreate(cfg->readEntry("outboxFolder", I18N_NOOP("outbox")));
1452  if (the_outboxFolder->canAccess() != 0) {
1453  emergencyExit( i18n("You do not have read/write permission to your outbox folder.") );
1454  }
1455  the_outboxFolder->setNoChildren(true);
1456 
1457  the_outboxFolder->setSystemFolder(true);
1458  if ( the_outboxFolder->userWhoField().isEmpty() )
1459  the_outboxFolder->setUserWhoField( TQString() );
1460  /* Nuke the oubox's index file, to make sure that no ghost messages are in
1461  * it from a previous crash. Ghost messages happen in the outbox because it
1462  * the only folder where messages enter and leave within 5 seconds, which is
1463  * the leniency period for index invalidation. Since the number of mails in
1464  * this folder is expected to be very small, we can live with regenerating
1465  * the index on each start to be on the save side. */
1466  //if ( the_outboxFolder->folderType() == KMFolderTypeMaildir )
1467  // unlink( TQFile::encodeName( the_outboxFolder->indexLocation() ) );
1468  the_outboxFolder->open("kmkernel");
1469 
1470  the_sentFolder = the_folderMgr->findOrCreate(cfg->readEntry("sentFolder", I18N_NOOP("sent-mail")));
1471  if (the_sentFolder->canAccess() != 0) {
1472  emergencyExit( i18n("You do not have read/write permission to your sent-mail folder.") );
1473  }
1474  the_sentFolder->setSystemFolder(true);
1475  if ( the_sentFolder->userWhoField().isEmpty() )
1476  the_sentFolder->setUserWhoField( TQString() );
1477  // the_sentFolder->open();
1478 
1479  the_trashFolder = the_folderMgr->findOrCreate(cfg->readEntry("trashFolder", I18N_NOOP("trash")));
1480  if (the_trashFolder->canAccess() != 0) {
1481  emergencyExit( i18n("You do not have read/write permission to your trash folder.") );
1482  }
1483  the_trashFolder->setSystemFolder( true );
1484  if ( the_trashFolder->userWhoField().isEmpty() )
1485  the_trashFolder->setUserWhoField( TQString() );
1486  // the_trashFolder->open();
1487 
1488  the_draftsFolder = the_folderMgr->findOrCreate(cfg->readEntry("draftsFolder", I18N_NOOP("drafts")));
1489  if (the_draftsFolder->canAccess() != 0) {
1490  emergencyExit( i18n("You do not have read/write permission to your drafts folder.") );
1491  }
1492  the_draftsFolder->setSystemFolder( true );
1493  if ( the_draftsFolder->userWhoField().isEmpty() )
1494  the_draftsFolder->setUserWhoField( TQString() );
1495  the_draftsFolder->open("kmkernel");
1496 
1497  the_templatesFolder =
1498  the_folderMgr->findOrCreate( cfg->readEntry( "templatesFolder",
1499  I18N_NOOP("templates") ) );
1500  if ( the_templatesFolder->canAccess() != 0 ) {
1501  emergencyExit( i18n("You do not have read/write permission to your templates folder.") );
1502  }
1503  the_templatesFolder->setSystemFolder( true );
1504  if ( the_templatesFolder->userWhoField().isEmpty() )
1505  the_templatesFolder->setUserWhoField( TQString() );
1506  the_templatesFolder->open("kmkernel");
1507 }
1508 
1509 
1510 void KMKernel::init()
1511 {
1512  the_shuttingDown = false;
1513  the_server_is_ready = false;
1514 
1515  TDEConfig* cfg = KMKernel::config();
1516 
1517  TQDir dir;
1518 
1519  TDEConfigGroupSaver saver(cfg, "General");
1520  the_firstStart = cfg->readBoolEntry("first-start", true);
1521  cfg->writeEntry("first-start", false);
1522  the_previousVersion = cfg->readEntry("previous-version");
1523  cfg->writeEntry("previous-version", KMAIL_VERSION);
1524  TQString foldersPath = cfg->readPathEntry( "folders" );
1525  kdDebug(5006) << k_funcinfo << "foldersPath (from config): '" << foldersPath << "'" << endl;
1526 
1527  if ( foldersPath.isEmpty() ) {
1528  foldersPath = localDataPath() + "mail";
1529  if ( transferMail( foldersPath ) ) {
1530  cfg->writePathEntry( "folders", foldersPath );
1531  }
1532  kdDebug(5006) << k_funcinfo << "foldersPath (after transferMail): '" << foldersPath << "'" << endl;
1533  }
1534 
1535  // moved up here because KMMessage::stripOffPrefixes is used below
1537 
1538  the_undoStack = new UndoStack(20);
1539  the_folderMgr = new KMFolderMgr(foldersPath);
1540  the_imapFolderMgr = new KMFolderMgr( KMFolderImap::cacheLocation(), KMImapDir);
1541  the_dimapFolderMgr = new KMFolderMgr( KMFolderCachedImap::cacheLocation(), KMDImapDir);
1542  recreateCorruptIndexFiles();
1543 
1544  the_searchFolderMgr = new KMFolderMgr(locateLocal("data","kmail/search"), KMSearchDir);
1545  KMFolder *lsf = the_searchFolderMgr->find( i18n("Last Search") );
1546  if (lsf)
1547  the_searchFolderMgr->remove( lsf );
1548 
1549  the_acctMgr = new AccountManager();
1550  the_filterMgr = new KMFilterMgr();
1551  the_popFilterMgr = new KMFilterMgr(true);
1552  the_filterActionDict = new KMFilterActionDict;
1553 
1554  initFolders(cfg);
1555  the_acctMgr->readConfig();
1556  the_filterMgr->readConfig();
1557  the_popFilterMgr->readConfig();
1558  cleanupImapFolders();
1559 
1560  the_msgSender = new KMSender;
1561  the_server_is_ready = true;
1562  imProxy()->initialize();
1563  { // area for config group "Composer"
1564  TDEConfigGroupSaver saver(cfg, "Composer");
1565  if (cfg->readListEntry("pref-charsets").isEmpty())
1566  {
1567  cfg->writeEntry("pref-charsets", "us-ascii,iso-8859-1,locale,utf-8");
1568  }
1569  }
1570  readConfig();
1571  mICalIface->readConfig();
1572  // filterMgr->dump();
1573 #ifdef HAVE_INDEXLIB
1574  the_msgIndex = new KMMsgIndex(this); //create the indexer
1575 #else
1576  the_msgIndex = 0;
1577 #endif
1578 
1579 //#if 0
1580  the_weaver = new KPIM::ThreadWeaver::Weaver( this );
1581  the_weaverLogger = new KPIM::ThreadWeaver::WeaverThreadLogger(this);
1582  the_weaverLogger->attach (the_weaver);
1583 //#endif
1584 
1585  connect( the_folderMgr, TQ_SIGNAL( folderRemoved(KMFolder*) ),
1586  this, TQ_SIGNAL( folderRemoved(KMFolder*) ) );
1587  connect( the_dimapFolderMgr, TQ_SIGNAL( folderRemoved(KMFolder*) ),
1588  this, TQ_SIGNAL( folderRemoved(KMFolder*) ) );
1589  connect( the_imapFolderMgr, TQ_SIGNAL( folderRemoved(KMFolder*) ),
1590  this, TQ_SIGNAL( folderRemoved(KMFolder*) ) );
1591  connect( the_searchFolderMgr, TQ_SIGNAL( folderRemoved(KMFolder*) ),
1592  this, TQ_SIGNAL( folderRemoved(KMFolder*) ) );
1593 
1594  mBackgroundTasksTimer = new TQTimer( this, "mBackgroundTasksTimer" );
1595  connect( mBackgroundTasksTimer, TQ_SIGNAL( timeout() ), this, TQ_SLOT( slotRunBackgroundTasks() ) );
1596 #ifdef DEBUG_SCHEDULER // for debugging, see jobscheduler.h
1597  mBackgroundTasksTimer->start( 10000, true ); // 10s, singleshot
1598 #else
1599  mBackgroundTasksTimer->start( 5 * 60000, true ); // 5 minutes, singleshot
1600 #endif
1601 
1602  TQTextCodec *codec;
1603  for ( int i = 0; ( codec = TQTextCodec::codecForIndex ( i ) ); i++ ) {
1604  const TQString asciiString( "azAZ19,.-#+!?=()&" );
1605  const TQCString encodedString = codec->fromUnicode( asciiString );
1606  if ( TQString::fromAscii( encodedString ) != asciiString ) {
1607  mNonAsciiCompatibleCodecs.append( codec );
1608  }
1609  }
1610 }
1611 
1612 bool KMKernel::isCodecAsciiCompatible( const TQTextCodec *codec )
1613 {
1614  return !mNonAsciiCompatibleCodecs.contains( codec );
1615 }
1616 
1617 void KMKernel::readConfig()
1618 {
1619  //Needed here, since this function is also called when the configuration
1620  //changes, and the static variables should be updated then - IOF
1622 }
1623 
1624 void KMKernel::cleanupImapFolders()
1625 {
1626  KMAccount *acct = 0;
1627  KMFolderNode *node = the_imapFolderMgr->dir().first();
1628  while (node)
1629  {
1630  if (node->isDir() || ((acct = the_acctMgr->find(node->id()))
1631  && ( acct->type() == "imap" )) )
1632  {
1633  node = the_imapFolderMgr->dir().next();
1634  } else {
1635  KMFolder* folder = static_cast<KMFolder*>(node);
1636  // delete only local
1637  static_cast<KMFolderImap*>( folder->storage() )->setAlreadyRemoved( true );
1638  the_imapFolderMgr->remove(folder);
1639  node = the_imapFolderMgr->dir().first();
1640  }
1641  }
1642 
1643  node = the_dimapFolderMgr->dir().first();
1644  while (node)
1645  {
1646  if (node->isDir() || ((acct = the_acctMgr->find(node->id()))
1647  && ( acct->type() == "cachedimap" )) )
1648  {
1649  node = the_dimapFolderMgr->dir().next();
1650  } else {
1651  the_dimapFolderMgr->remove(static_cast<KMFolder*>(node));
1652  node = the_dimapFolderMgr->dir().first();
1653  }
1654  }
1655 
1656  the_imapFolderMgr->quiet(true);
1657  for (acct = the_acctMgr->first(); acct; acct = the_acctMgr->next())
1658  {
1659  KMFolderImap *fld;
1660  KMAcctImap *imapAcct;
1661 
1662  if (acct->type() != "imap") continue;
1663  fld = static_cast<KMFolderImap*>(the_imapFolderMgr
1664  ->findOrCreate(TQString::number(acct->id()), false, acct->id())->storage());
1665  fld->setNoContent(true);
1666  fld->folder()->setLabel(acct->name());
1667  imapAcct = static_cast<KMAcctImap*>(acct);
1668  fld->setAccount(imapAcct);
1669  imapAcct->setImapFolder(fld);
1670  fld->close( "kernel", true );
1671  }
1672  the_imapFolderMgr->quiet(false);
1673 
1674  the_dimapFolderMgr->quiet( true );
1675  for (acct = the_acctMgr->first(); acct; acct = the_acctMgr->next())
1676  {
1677  KMFolderCachedImap *cfld = 0;
1678  KMAcctCachedImap *cachedImapAcct;
1679 
1680  if (acct->type() != "cachedimap" ) continue;
1681 
1682  KMFolder* fld = the_dimapFolderMgr->find(TQString::number(acct->id()));
1683  if( fld )
1684  cfld = static_cast<KMFolderCachedImap*>( fld->storage() );
1685  if (cfld == 0) {
1686  // Folder doesn't exist yet
1687  cfld = static_cast<KMFolderCachedImap*>(the_dimapFolderMgr->createFolder(TQString::number(acct->id()),
1688  false, KMFolderTypeCachedImap)->storage());
1689  if (!cfld) {
1690  KMessageBox::error(0,(i18n("Cannot create file `%1' in %2.\nKMail cannot start without it.").arg(acct->name()).arg(the_dimapFolderMgr->basePath())));
1691  exit(-1);
1692  }
1693  cfld->folder()->setId( acct->id() );
1694  }
1695 
1696  cfld->setNoContent(true);
1697  cfld->folder()->setLabel(acct->name());
1698  cachedImapAcct = static_cast<KMAcctCachedImap*>(acct);
1699  cfld->setAccount(cachedImapAcct);
1700  cachedImapAcct->setImapFolder(cfld);
1701  cfld->close("kmkernel");
1702  }
1703  the_dimapFolderMgr->quiet( false );
1704 }
1705 
1706 void KMKernel::recreateCorruptIndexFiles()
1707 {
1708  TQValueList<TQGuardedPtr<KMFolder> > folders;
1709  TQValueList<KMFolderIndex*> foldersWithBrokenIndex;
1710  TQStringList strList;
1711  the_folderMgr->createFolderList( &strList, &folders );
1712  the_imapFolderMgr->createFolderList( &strList, &folders );
1713  the_dimapFolderMgr->createFolderList( &strList, &folders );
1714  for ( int i = 0; folders.at(i) != folders.end(); i++ ) {
1715  KMFolder * const folder = *folders.at(i);
1716  if ( !folder || folder->isDir() || folder->isOpened() )
1717  continue;
1718  KMFolderIndex * const index = dynamic_cast<KMFolderIndex*>( folder->storage() );
1719  if ( index && index->indexStatus() != KMFolderIndex::IndexOk ) {
1720  foldersWithBrokenIndex.append( index );
1721  }
1722  }
1723 
1724  if ( !foldersWithBrokenIndex.isEmpty() ) {
1725  TQStringList folderNames;
1726  for ( uint i = 0; i < foldersWithBrokenIndex.size(); i++ ) {
1727  folderNames << foldersWithBrokenIndex[i]->label();
1728  }
1729 
1730  KMessageBox::informationList( 0, i18n( "There is a problem with the mail index of the following "
1731  "folders, the indices will now be regenerated.\n"
1732  "This can happen because the index files are out of date, missing or corrupted.\n"
1733  "Contact your administrator if this happens frequently.\n"
1734  "Some information, like status flags, might get lost." ),
1735  folderNames, i18n( "Problem with mail indices" ) );
1736 
1737  for ( uint i = 0; i < foldersWithBrokenIndex.size(); i++ ) {
1738  foldersWithBrokenIndex[i]->silentlyRecreateIndex();
1739  }
1740  }
1741 }
1742 
1743 bool KMKernel::doSessionManagement()
1744 {
1745 
1746  // Do session management
1747  if (kapp->isRestored()){
1748  int n = 1;
1749  while (KMMainWin::canBeRestored(n)){
1750  //only restore main windows! (Matthias);
1751  if (KMMainWin::classNameOfToplevel(n) == "KMMainWin")
1752  (new KMMainWin)->restore(n);
1753  n++;
1754  }
1755  return true; // we were restored by SM
1756  }
1757  return false; // no, we were not restored
1758 }
1759 
1760 void KMKernel::closeAllKMailWindows()
1761 {
1762  if (!TDEMainWindow::memberList) return;
1763  TQPtrListIterator<TDEMainWindow> it(*TDEMainWindow::memberList);
1764  TDEMainWindow *window = 0;
1765  while ((window = it.current()) != 0) {
1766  ++it;
1767  if (window->isA("KMMainWindow") ||
1768  window->inherits("KMail::SecondaryWindow"))
1769  window->close( true ); // close and delete the window
1770  }
1771 }
1772 
1773 void KMKernel::cleanup(void)
1774 {
1775  dumpDeadLetters();
1776  the_shuttingDown = true;
1777  closeAllKMailWindows();
1778 
1779  delete the_acctMgr;
1780  the_acctMgr = 0;
1781  delete the_filterMgr;
1782  the_filterMgr = 0;
1783  delete the_msgSender;
1784  the_msgSender = 0;
1785  delete the_filterActionDict;
1786  the_filterActionDict = 0;
1787  delete the_undoStack;
1788  the_undoStack = 0;
1789  delete the_popFilterMgr;
1790  the_popFilterMgr = 0;
1791 
1792 #if 0
1793  delete the_weaver;
1794  the_weaver = 0;
1795 #endif
1796 
1797  TDEConfig* config = KMKernel::config();
1798  TDEConfigGroupSaver saver(config, "General");
1799 
1800  if (the_trashFolder) {
1801 
1802  the_trashFolder->close("kmkernel", true);
1803 
1804  if (config->readBoolEntry("empty-trash-on-exit", true))
1805  {
1806  if ( the_trashFolder->count( true ) > 0 )
1807  the_trashFolder->expunge();
1808  }
1809  }
1810 
1811  mICalIface->cleanup();
1812 
1813  TQValueList<TQGuardedPtr<KMFolder> > folders;
1814  TQStringList strList;
1815  KMFolder *folder;
1816  the_folderMgr->createFolderList(&strList, &folders);
1817  for (int i = 0; folders.at(i) != folders.end(); i++)
1818  {
1819  folder = *folders.at(i);
1820  if (!folder || folder->isDir()) continue;
1821  folder->close("kmkernel", true);
1822  }
1823  strList.clear();
1824  folders.clear();
1825  the_searchFolderMgr->createFolderList(&strList, &folders);
1826  for (int i = 0; folders.at(i) != folders.end(); i++)
1827  {
1828  folder = *folders.at(i);
1829  if (!folder || folder->isDir()) continue;
1830  folder->close("kmkernel", true);
1831  }
1832 
1833  delete the_msgIndex;
1834  the_msgIndex = 0;
1835  delete the_folderMgr;
1836  the_folderMgr = 0;
1837  delete the_imapFolderMgr;
1838  the_imapFolderMgr = 0;
1839  delete the_dimapFolderMgr;
1840  the_dimapFolderMgr = 0;
1841  delete the_searchFolderMgr;
1842  the_searchFolderMgr = 0;
1843  delete mConfigureDialog;
1844  mConfigureDialog = 0;
1845  // do not delete, because mWin may point to an existing window
1846  // delete mWin;
1847  mWin = 0;
1848 
1849  if ( RecentAddresses::exists() )
1850  RecentAddresses::self( config )->save( config );
1851  config->sync();
1852 }
1853 
1854 bool KMKernel::transferMail( TQString & destinationDir )
1855 {
1856  TQString dir;
1857 
1858  // check whether the user has a ~/KMail folder
1859  TQFileInfo fi( TQDir::home(), "KMail" );
1860  if ( fi.exists() && fi.isDir() ) {
1861  dir = TQDir::homeDirPath() + "/KMail";
1862  // the following two lines can be removed once moving mail is reactivated
1863  destinationDir = dir;
1864  return true;
1865  }
1866 
1867  if ( dir.isEmpty() ) {
1868  // check whether the user has a ~/Mail folder
1869  fi.setFile( TQDir::home(), "Mail" );
1870  if ( fi.exists() && fi.isDir() &&
1871  TQFile::exists( TQDir::homeDirPath() + "/Mail/.inbox.index" ) ) {
1872  // there's a ~/Mail folder which seems to be used by KMail (because of the
1873  // index file)
1874  dir = TQDir::homeDirPath() + "/Mail";
1875  // the following two lines can be removed once moving mail is reactivated
1876  destinationDir = dir;
1877  return true;
1878  }
1879  }
1880 
1881  if ( dir.isEmpty() ) {
1882  return true; // there's no old mail folder
1883  }
1884 
1885 #if 0
1886  // disabled for now since moving fails in certain cases (e.g. if symbolic links are involved)
1887  const TQString kmailName = kapp->aboutData()->programName();
1888  TQString msg;
1889  if ( TDEIO::NetAccess::exists( destinationDir, true, 0 ) ) {
1890  // if destinationDir exists, we need to warn about possible
1891  // overwriting of files. otherwise, we don't have to
1892  msg = i18n( "%1-%3 is the application name, %4-%7 are folder path",
1893  "<qt>The <i>%4</i> folder exists. "
1894  "%1 now uses the <i>%5</i> folder for "
1895  "its messages.<p>"
1896  "%2 can move the contents of <i>%6<i> into this folder for "
1897  "you, though this may replace any existing files with "
1898  "the same name in <i>%7</i>.<p>"
1899  "<strong>Would you like %3 to move the mail "
1900  "files now?</strong></qt>" )
1901  .arg( kmailName, kmailName, kmailName )
1902  .arg( dir, destinationDir, dir, destinationDir );
1903  } else {
1904  msg = i18n( "%1-%3 is the application name, %4-%6 are folder path",
1905  "<qt>The <i>%4</i> folder exists. "
1906  "%1 now uses the <i>%5</i> folder for "
1907  "its messages. %2 can move the contents of <i>%6</i> into "
1908  "this folder for you.<p>"
1909  "<strong>Would you like %3 to move the mail "
1910  "files now?</strong></qt>" )
1911  .arg( kmailName, kmailName, kmailName )
1912  .arg( dir, destinationDir, dir );
1913  }
1914  TQString title = i18n( "Migrate Mail Files?" );
1915  TQString buttonText = i18n( "Move" );
1916 
1917  if ( KMessageBox::questionYesNo( 0, msg, title, buttonText, i18n("Do Not Move") ) ==
1918  KMessageBox::No ) {
1919  destinationDir = dir;
1920  return true;
1921  }
1922 
1923  if ( !TDEIO::NetAccess::move( dir, destinationDir ) ) {
1924  kdDebug(5006) << k_funcinfo << "Moving " << dir << " to " << destinationDir << " failed: " << TDEIO::NetAccess::lastErrorString() << endl;
1925  kdDebug(5006) << k_funcinfo << "Deleting " << destinationDir << endl;
1926  TDEIO::NetAccess::del( destinationDir, 0 );
1927  destinationDir = dir;
1928  return false;
1929  }
1930 #endif
1931 
1932  return true;
1933 }
1934 
1935 
1936 void KMKernel::ungrabPtrKb(void)
1937 {
1938  if(!TDEMainWindow::memberList) return;
1939  TQWidget* widg = TDEMainWindow::memberList->first();
1940  Display* dpy;
1941 
1942  if (!widg) return;
1943  dpy = widg->x11Display();
1944  XUngrabKeyboard(dpy, CurrentTime);
1945  XUngrabPointer(dpy, CurrentTime);
1946 }
1947 
1948 
1949 // Message handler
1950 void KMKernel::kmailMsgHandler(TQtMsgType aType, const char* aMsg)
1951 {
1952  static int recurse=-1;
1953 
1954  recurse++;
1955 
1956  switch (aType)
1957  {
1958  case TQtDebugMsg:
1959  case TQtWarningMsg:
1960  kdDebug(5006) << aMsg << endl;
1961  break;
1962 
1963  case TQtFatalMsg: // Hm, what about using kdFatal() here?
1964  ungrabPtrKb();
1965  kdDebug(5006) << kapp->caption() << " fatal error "
1966  << aMsg << endl;
1967  KMessageBox::error(0, aMsg);
1968  abort();
1969  }
1970 
1971  recurse--;
1972 }
1973 
1974 
1976 {
1977  if ( shuttingDown() )
1978  return; //All documents should be saved before shutting down is set!
1979 
1980  // make all composer windows autosave their contents
1981  if ( !TDEMainWindow::memberList )
1982  return;
1983 
1984  for ( TQPtrListIterator<TDEMainWindow> it(*TDEMainWindow::memberList) ; it.current() != 0; ++it ) {
1985  if ( KMail::Composer * win = ::tqt_cast<KMail::Composer*>( it.current() ) ) {
1986  win->autoSaveMessage();
1987  // saving the message has to be finished right here, we are called from a dtor,
1988  // therefore we have no chance to finish this later
1989  // yes, this is ugly and potentially dangerous, but the alternative is losing
1990  // currently composed messages...
1991  while ( win->isComposing() )
1992  tqApp->processEvents();
1993  }
1994  }
1995 }
1996 
1997 
1998 
1999 void KMKernel::action(bool mailto, bool check, const TQString &to,
2000  const TQString &cc, const TQString &bcc,
2001  const TQString &subj, const TQString &body,
2002  const KURL &messageFile,
2003  const KURL::List &attachURLs,
2004  const QCStringList &customHeaders)
2005 {
2006  if ( mailto )
2007  openComposer( to, cc, bcc, subj, body, 0, messageFile, attachURLs, customHeaders );
2008  else
2009  openReader( check );
2010 
2011  if ( check )
2012  checkMail();
2013  //Anything else?
2014 }
2015 
2016 void KMKernel::byteArrayToRemoteFile(const TQByteArray &aData, const KURL &aURL,
2017  bool overwrite)
2018 {
2019  // ## when KDE 3.3 is out: use TDEIO::storedPut to remove slotDataReq altogether
2020  TDEIO::Job *job = TDEIO::put(aURL, -1, overwrite, false);
2021  putData pd; pd.url = aURL; pd.data = aData; pd.offset = 0;
2022  mPutJobs.insert(job, pd);
2023  connect(job, TQ_SIGNAL(dataReq(TDEIO::Job*,TQByteArray&)),
2024  TQ_SLOT(slotDataReq(TDEIO::Job*,TQByteArray&)));
2025  connect(job, TQ_SIGNAL(result(TDEIO::Job*)),
2026  TQ_SLOT(slotResult(TDEIO::Job*)));
2027 }
2028 
2029 void KMKernel::slotDataReq(TDEIO::Job *job, TQByteArray &data)
2030 {
2031  // send the data in 64 KB chunks
2032  const int MAX_CHUNK_SIZE = 64*1024;
2033  TQMap<TDEIO::Job*, putData>::Iterator it = mPutJobs.find(job);
2034  assert(it != mPutJobs.end());
2035  int remainingBytes = (*it).data.size() - (*it).offset;
2036  if( remainingBytes > MAX_CHUNK_SIZE )
2037  {
2038  // send MAX_CHUNK_SIZE bytes to the receiver (deep copy)
2039  data.duplicate( (*it).data.data() + (*it).offset, MAX_CHUNK_SIZE );
2040  (*it).offset += MAX_CHUNK_SIZE;
2041  //kdDebug( 5006 ) << "Sending " << MAX_CHUNK_SIZE << " bytes ("
2042  // << remainingBytes - MAX_CHUNK_SIZE << " bytes remain)\n";
2043  }
2044  else
2045  {
2046  // send the remaining bytes to the receiver (deep copy)
2047  data.duplicate( (*it).data.data() + (*it).offset, remainingBytes );
2048  (*it).data = TQByteArray();
2049  (*it).offset = 0;
2050  //kdDebug( 5006 ) << "Sending " << remainingBytes << " bytes\n";
2051  }
2052 }
2053 
2054 void KMKernel::slotResult(TDEIO::Job *job)
2055 {
2056  TQMap<TDEIO::Job*, putData>::Iterator it = mPutJobs.find(job);
2057  assert(it != mPutJobs.end());
2058  if (job->error())
2059  {
2060  if (job->error() == TDEIO::ERR_FILE_ALREADY_EXIST)
2061  {
2062  if (KMessageBox::warningContinueCancel(0,
2063  i18n("File %1 exists.\nDo you want to replace it?")
2064  .arg((*it).url.prettyURL()), i18n("Save to File"), i18n("&Replace"))
2065  == KMessageBox::Continue)
2066  byteArrayToRemoteFile((*it).data, (*it).url, true);
2067  }
2068  else job->showErrorDialog();
2069  }
2070  mPutJobs.remove(it);
2071 }
2072 
2074  // ### FIXME: delay as promised in the kdoc of this function ;-)
2075  KMKernel::config()->sync();
2076 }
2077 
2078 void KMKernel::slotShowConfigurationDialog()
2079 {
2080  if( !mConfigureDialog ) {
2081  mConfigureDialog = new ConfigureDialog( 0, "configure", false );
2082  connect( mConfigureDialog, TQ_SIGNAL( configChanged() ),
2083  this, TQ_SLOT( slotConfigChanged() ) );
2084  }
2085 
2086  if( KMKernel::getKMMainWidget() == 0 )
2087  {
2088  // ensure that there is a main widget available
2089  // as parts of the configure dialog (identity) rely on this
2090  // and this slot can be called when there is only a KMComposeWin showing
2091  KMMainWin * win = new KMMainWin;
2092  win->show();
2093  }
2094  if( mConfigureDialog->isHidden() )
2095  {
2096  getKMMainWidget()->headers()->writeConfig();
2097  mConfigureDialog->show();
2098  }
2099  else
2100  mConfigureDialog->raise();
2101 }
2102 
2103 void KMKernel::slotConfigChanged()
2104 {
2105  readConfig();
2106  emit configChanged();
2107 }
2108 
2109 //-------------------------------------------------------------------------------
2110 //static
2112 {
2113  return locateLocal( "data", "kmail/" );
2114 }
2115 
2116 //-------------------------------------------------------------------------------
2117 
2119 {
2120  return !systemTrayApplets.isEmpty();
2121 }
2122 
2123 bool KMKernel::registerSystemTrayApplet( const KSystemTray* applet )
2124 {
2125  if ( systemTrayApplets.findIndex( applet ) == -1 ) {
2126  systemTrayApplets.append( applet );
2127  return true;
2128  }
2129  else
2130  return false;
2131 }
2132 
2133 bool KMKernel::unregisterSystemTrayApplet( const KSystemTray* applet )
2134 {
2135  TQValueList<const KSystemTray*>::iterator it =
2136  systemTrayApplets.find( applet );
2137  if ( it != systemTrayApplets.end() ) {
2138  systemTrayApplets.remove( it );
2139  return true;
2140  }
2141  else
2142  return false;
2143 }
2144 
2145 void KMKernel::emergencyExit( const TQString& reason )
2146 {
2147  TQString mesg;
2148  if ( reason.length() == 0 ) {
2149  mesg = i18n("KMail encountered a fatal error and will terminate now");
2150  } else {
2151  mesg = i18n("KMail encountered a fatal error and will "
2152  "terminate now.\nThe error was:\n%1").arg( reason );
2153  }
2154 
2155  kdWarning() << mesg << endl;
2156  KNotifyClient::userEvent( 0, "<qt>"+mesg+"</qt>", KNotifyClient::Messagebox, KNotifyClient::Error );
2157 
2158  ::exit(1);
2159 }
2160 
2165 {
2166  assert( folder );
2167  if ( folder == the_outboxFolder )
2168  return true;
2169  return folderIsDrafts( folder );
2170 }
2171 
2172 bool KMKernel::folderIsDrafts(const KMFolder * folder)
2173 {
2174  assert( folder );
2175  if ( folder == the_draftsFolder )
2176  return true;
2177 
2178  TQString idString = folder->idString();
2179  if ( idString.isEmpty() )
2180  return false;
2181 
2182  // search the identities if the folder matches the drafts-folder
2183  const KPIM::IdentityManager *im = identityManager();
2184  for ( KPIM::IdentityManager::ConstIterator it=im->begin(); it != im->end(); ++it )
2185  if ( (*it).drafts() == idString )
2186  return true;
2187  return false;
2188 }
2189 
2190 bool KMKernel::folderIsTemplates( const KMFolder *folder )
2191 {
2192  assert( folder );
2193  if ( folder == the_templatesFolder )
2194  return true;
2195 
2196  TQString idString = folder->idString();
2197  if ( idString.isEmpty() )
2198  return false;
2199 
2200  // search the identities if the folder matches the templates-folder
2201  const KPIM::IdentityManager *im = identityManager();
2202  for ( KPIM::IdentityManager::ConstIterator it=im->begin(); it != im->end(); ++it )
2203  if ( (*it).templates() == idString )
2204  return true;
2205  return false;
2206 }
2207 
2208 bool KMKernel::folderIsTrash(KMFolder * folder)
2209 {
2210  assert(folder);
2211  if (folder == the_trashFolder) return true;
2212  TQStringList actList = acctMgr()->getAccounts();
2213  TQStringList::Iterator it( actList.begin() );
2214  for( ; it != actList.end() ; ++it ) {
2215  KMAccount* act = acctMgr()->findByName( *it );
2216  if ( act && ( act->trash() == folder->idString() ) )
2217  return true;
2218  }
2219  return false;
2220 }
2221 
2223 {
2224  assert( folder );
2225  if ( folder == the_sentFolder )
2226  return true;
2227 
2228  TQString idString = folder->idString();
2229  if ( idString.isEmpty() ) return false;
2230 
2231  // search the identities if the folder matches the sent-folder
2232  const KPIM::IdentityManager * im = identityManager();
2233  for( KPIM::IdentityManager::ConstIterator it = im->begin(); it != im->end(); ++it )
2234  if ( (*it).fcc() == idString ) return true;
2235  return false;
2236 }
2237 
2238 KPIM::IdentityManager * KMKernel::identityManager() {
2239  if ( !mIdentityManager ) {
2240  kdDebug(5006) << "instantating KPIM::IdentityManager" << endl;
2241  mIdentityManager = new KPIM::IdentityManager( false, this, "mIdentityManager" );
2242  }
2243  return mIdentityManager;
2244 }
2245 
2246 KMMsgIndex *KMKernel::msgIndex()
2247 {
2248  return the_msgIndex;
2249 }
2250 
2251 TDEMainWindow* KMKernel::mainWin()
2252 {
2253  if (TDEMainWindow::memberList) {
2254  TDEMainWindow *kmWin = 0;
2255 
2256  // First look for a KMMainWin.
2257  for (kmWin = TDEMainWindow::memberList->first(); kmWin;
2258  kmWin = TDEMainWindow::memberList->next())
2259  if (kmWin->isA("KMMainWin"))
2260  return kmWin;
2261 
2262  // There is no KMMainWin. Use any other TDEMainWindow instead (e.g. in
2263  // case we are running inside Kontact) because we anyway only need
2264  // it for modal message boxes and for KNotify events.
2265  kmWin = TDEMainWindow::memberList->first();
2266  if ( kmWin )
2267  return kmWin;
2268  }
2269 
2270  // There's not a single TDEMainWindow. Create a KMMainWin.
2271  // This could happen if we want to pop up an error message
2272  // while we are still doing the startup wizard and no other
2273  // TDEMainWindow is running.
2274  mWin = new KMMainWin;
2275  return mWin;
2276 }
2277 
2278 
2283 {
2284  TQString title = i18n("Empty Trash");
2285  TQString text = i18n("Are you sure you want to empty the trash folders of all accounts?");
2286  if (KMessageBox::warningContinueCancel(0, text, title,
2287  KStdGuiItem::cont(), "confirm_empty_trash")
2288  != KMessageBox::Continue)
2289  {
2290  return;
2291  }
2292 
2293  for (KMAccount* acct = acctMgr()->first(); acct; acct = acctMgr()->next())
2294  {
2295  KMFolder* trash = findFolderById(acct->trash());
2296  if (trash)
2297  {
2298  trash->expunge();
2299  }
2300  }
2301 }
2302 
2303 TDEConfig* KMKernel::config()
2304 {
2305  assert(mySelf);
2306  if (!mySelf->mConfig)
2307  {
2308  mySelf->mConfig = TDESharedConfig::openConfig( "kmailrc" );
2309  // Check that all updates have been run on the config file:
2310  KMail::checkConfigUpdates();
2311  }
2312  return mySelf->mConfig;
2313 }
2314 
2315 KMailICalIfaceImpl& KMKernel::iCalIface()
2316 {
2317  assert( mICalIface );
2318  return *mICalIface;
2319 }
2320 
2321 void KMKernel::selectFolder( TQString folderPath )
2322 {
2323  kdDebug(5006)<<"Selecting a folder "<<folderPath<<endl;
2324  const TQString localPrefix = "/Local";
2325  KMFolder *folder = kmkernel->folderMgr()->getFolderByURL( folderPath );
2326  if ( !folder && folderPath.startsWith( localPrefix ) )
2327  folder = the_folderMgr->getFolderByURL( folderPath.mid( localPrefix.length() ) );
2328  if ( !folder )
2329  folder = kmkernel->imapFolderMgr()->getFolderByURL( folderPath );
2330  if ( !folder )
2331  folder = kmkernel->dimapFolderMgr()->getFolderByURL( folderPath );
2332  Q_ASSERT( folder );
2333 
2334  KMMainWidget *widget = getKMMainWidget();
2335  Q_ASSERT( widget );
2336  if ( !widget )
2337  return;
2338 
2339  KMFolderTree *tree = widget->folderTree();
2340  tree->doFolderSelected( tree->indexOfFolder( folder ) );
2341  tree->ensureItemVisible( tree->indexOfFolder( folder ) );
2342 }
2343 
2345 {
2346  //This could definitely use a speadup
2347  TQWidgetList *l = kapp->topLevelWidgets();
2348  TQWidgetListIt it( *l );
2349  TQWidget *wid;
2350 
2351  while ( ( wid = it.current() ) != 0 ) {
2352  ++it;
2353  TQObjectList *l2 = wid->topLevelWidget()->queryList( "KMMainWidget" );
2354  if (l2 && l2->first()) {
2355  KMMainWidget* kmmw = dynamic_cast<KMMainWidget *>( l2->first() );
2356  Q_ASSERT( kmmw );
2357  delete l2;
2358  delete l;
2359  return kmmw;
2360  }
2361  delete l2;
2362  }
2363  delete l;
2364  return 0;
2365 }
2366 
2367 void KMKernel::slotRunBackgroundTasks() // called regularly by timer
2368 {
2369  // Hidden TDEConfig keys. Not meant to be used, but a nice fallback in case
2370  // a stable kmail release goes out with a nasty bug in CompactionJob...
2371  TDEConfigGroup generalGroup( config(), "General" );
2372 
2373  if ( generalGroup.readBoolEntry( "auto-expiring", true ) ) {
2374  the_folderMgr->expireAllFolders( false /*scheduled, not immediate*/ );
2375  the_imapFolderMgr->expireAllFolders( false /*scheduled, not immediate*/ );
2376  the_dimapFolderMgr->expireAllFolders( false /*scheduled, not immediate*/ );
2377  // the_searchFolderMgr: no expiry there
2378  }
2379 
2380  if ( generalGroup.readBoolEntry( "auto-compaction", true ) ) {
2381  the_folderMgr->compactAllFolders( false /*scheduled, not immediate*/ );
2382  // the_imapFolderMgr: no compaction
2383  the_dimapFolderMgr->compactAllFolders( false /*scheduled, not immediate*/ );
2384  // the_searchFolderMgr: no compaction
2385  }
2386 
2387 #ifdef DEBUG_SCHEDULER // for debugging, see jobscheduler.h
2388  mBackgroundTasksTimer->start( 60 * 1000, true ); // check again in 1 minute
2389 #else
2390  mBackgroundTasksTimer->start( 4 * 60 * 60 * 1000, true ); // check again in 4 hours
2391 #endif
2392 
2393 }
2394 
2395 void KMKernel::expireAllFoldersNow() // called by the GUI
2396 {
2397  the_folderMgr->expireAllFolders( true /*immediate*/ );
2398  the_imapFolderMgr->expireAllFolders( true /*immediate*/ );
2399  the_dimapFolderMgr->expireAllFolders( true /*immediate*/ );
2400 }
2401 
2402 void KMKernel::compactAllFolders() // called by the GUI
2403 {
2404  the_folderMgr->compactAllFolders( true /*immediate*/ );
2405  //the_imapFolderMgr->compactAllFolders( true /*immediate*/ );
2406  the_dimapFolderMgr->compactAllFolders( true /*immediate*/ );
2407 }
2408 
2409 KMFolder* KMKernel::findFolderById( const TQString& idString )
2410 {
2411  KMFolder * folder = the_folderMgr->findIdString( idString );
2412  if ( !folder )
2413  folder = the_imapFolderMgr->findIdString( idString );
2414  if ( !folder )
2415  folder = the_dimapFolderMgr->findIdString( idString );
2416  if ( !folder )
2417  folder = the_searchFolderMgr->findIdString( idString );
2418  return folder;
2419 }
2420 
2421 ::KIMProxy* KMKernel::imProxy()
2422 {
2423  return KIMProxy::instance( kapp->dcopClient() );
2424 }
2425 
2427 {
2428  mMailCheckAborted = false;
2429 }
2430 
2432 {
2433  return mMailCheckAborted;
2434 }
2435 
2437 {
2438  mMailCheckAborted = true;
2439 }
2440 
2441 bool KMKernel::canQueryClose()
2442 {
2443  if ( KMMainWidget::mainWidgetList() &&
2444  KMMainWidget::mainWidgetList()->count() > 1 )
2445  return true;
2446  KMMainWidget *widget = getKMMainWidget();
2447  if ( !widget )
2448  return true;
2449  KMSystemTray* systray = widget->systray();
2450  if ( !systray || GlobalSettings::closeDespiteSystemTray() )
2451  return true;
2452  if ( systray->mode() == GlobalSettings::EnumSystemTrayPolicy::ShowAlways ) {
2453  systray->hideKMail();
2454  return false;
2455  } else if ( ( systray->mode() == GlobalSettings::EnumSystemTrayPolicy::ShowOnUnread ) && ( systray->hasUnreadMail() )) {
2456  systray->show();
2457  systray->hideKMail();
2458  return false;
2459  }
2460  return true;
2461 }
2462 
2464 {
2465  mTimeOfLastMessageCountChange = ::time( 0 );
2466 }
2467 
2468 int KMKernel::timeOfLastMessageCountChange() const
2469 {
2470  return mTimeOfLastMessageCountChange;
2471 }
2472 
2473 bool KMKernel::networkStateConnected()
2474 {
2475 #ifdef __TDE_HAVE_TDEHWLIB
2476  if (mNetworkManager) {
2477  TDENetworkGlobalManagerFlags::TDENetworkGlobalManagerFlags networkStatus = mNetworkManager->backendStatus();
2478  if ((networkStatus & TDENetworkGlobalManagerFlags::Connected)
2479  || (networkStatus & TDENetworkGlobalManagerFlags::BackendUnavailable)
2480  || (networkStatus == TDENetworkGlobalManagerFlags::Unknown)
2481  ){
2482  // Connected or no backend available
2483  return true;
2484  }
2485  else {
2486  // Not connected
2487  return false;
2488  }
2489  }
2490  else {
2491  // Assume connected
2492  return true;
2493  }
2494 #endif
2495  return true;
2496 }
2497 
2498 void KMKernel::slotNetworkStateChanged(TDENetworkConnectionStatus::TDENetworkConnectionStatus, TDENetworkConnectionStatus::TDENetworkConnectionStatus, TQString)
2499 {
2500  if (networkStateConnected()) {
2502  }
2503  else {
2504  stopNetworkJobs();
2505  }
2506 }
2507 
2508 Wallet *KMKernel::wallet() {
2509  static bool walletOpenFailed = false;
2510  if ( mWallet && mWallet->isOpen() )
2511  return mWallet;
2512 
2513  if ( !Wallet::isEnabled() || walletOpenFailed )
2514  return 0;
2515 
2516  // find an appropriate parent window for the wallet dialog
2517  WId window = 0;
2518  if ( tqApp->activeWindow() )
2519  window = tqApp->activeWindow()->winId();
2520  else if ( getKMMainWidget() )
2521  window = getKMMainWidget()->topLevelWidget()->winId();
2522 
2523  delete mWallet;
2524  mWallet = Wallet::openWallet( Wallet::NetworkWallet(), window );
2525 
2526  if ( !mWallet ) {
2527  walletOpenFailed = true;
2528  return 0;
2529  }
2530 
2531  if ( !mWallet->hasFolder( "kmail" ) )
2532  mWallet->createFolder( "kmail" );
2533  mWallet->setFolder( "kmail" );
2534  return mWallet;
2535 }
2536 
2537 TQValueList< TQGuardedPtr<KMFolder> > KMKernel::allFolders()
2538 {
2539  TQStringList names;
2540  TQValueList<TQGuardedPtr<KMFolder> > folders;
2541  folderMgr()->createFolderList(&names, &folders);
2542  imapFolderMgr()->createFolderList(&names, &folders);
2543  dimapFolderMgr()->createFolderList(&names, &folders);
2544  searchFolderMgr()->createFolderList(&names, &folders);
2545 
2546  return folders;
2547 }
2548 
2549 KMFolder *KMKernel::currentFolder() {
2550  KMMainWidget *widget = getKMMainWidget();
2551  KMFolder *folder = 0;
2552  if ( widget && widget->folderTree() ) {
2553  folder = widget->folderTree()->currentFolder();
2554  }
2555  return folder;
2556 }
2557 
2558 // can't be inline, since KMSender isn't known to implement
2559 // KMail::MessageSender outside this .cpp file
2560 KMail::MessageSender * KMKernel::msgSender() { return the_msgSender; }
2561 
2562 #include "kmkernel.moc"
TQString label() const
Returns the label of the folder for visualization.
Dictionary that contains a list of all registered filter actions with their creation functions.
KMail list that manages the contents of one directory that may contain folders and/or other directori...
Definition: kmfolderdir.h:16
A FolderStorage with an index for faster access to often used message properties.
Definition: kmfolderindex.h:38
virtual IndexStatus indexStatus()=0
Tests whether the contents of this folder is newer than the index.
RAII for KMFolder::open() / close().
Definition: kmfolder.h:688
Mail folder.
Definition: kmfolder.h:69
bool isOpened() const
Test if folder is opened.
Definition: kmfolder.cpp:500
void setNoChildren(bool aNoChildren)
Specify, that the folder can't have children.
Definition: kmfolder.cpp:316
TQString idString() const
Returns a string that can be used to identify this folder.
Definition: kmfolder.cpp:705
KMMsgInfo * unGetMsg(int idx)
Replace KMMessage with KMMsgInfo and delete KMMessage
Definition: kmfolder.cpp:326
int canAccess()
Check folder for permissions Returns zero if readable and writable.
Definition: kmfolder.cpp:484
int addMsg(KMMessage *msg, int *index_return=0)
Add the given message to the folder.
Definition: kmfolder.cpp:390
int expunge()
Delete entire folder.
Definition: kmfolder.cpp:526
void close(const char *owner, bool force=false)
Close folder.
Definition: kmfolder.cpp:489
KMFolderDir * createChildFolder()
Create a child folder directory and associates it with this folder.
Definition: kmfolder.cpp:264
KMMessage * getMsg(int idx)
Read message at given index.
Definition: kmfolder.cpp:321
const KMMsgBase * getMsgBase(int idx) const
Provides access to the basic message fields that are also stored in the index.
Definition: kmfolder.cpp:360
KMFolderType folderType() const
Returns the type of this folder.
Definition: kmfolder.cpp:233
int count(bool cache=false) const
Number of messages in this folder.
Definition: kmfolder.cpp:445
int open(const char *owner)
Open folder for access.
Definition: kmfolder.cpp:479
TQString userWhoField(void)
Get / set the user-settings for the WhoField (From/To/Empty)
Definition: kmfolder.h:400
Central point of coordination in KMail.
Definition: kmkernel.h:92
void expireAllFoldersNow()
Expire all folders, used for the gui action.
Definition: kmkernel.cpp:2395
virtual void pauseBackgroundJobs()
Pauses all background jobs and does not allow new background jobs to be started.
Definition: kmkernel.cpp:1242
void compactAllFolders()
Compact all folders, used for the gui action (and from DCOP)
Definition: kmkernel.cpp:2402
void dumpDeadLetters()
Save contents of all open composer widnows to ~/dead.letter.
Definition: kmkernel.cpp:1975
::KIMProxy * imProxy()
Get a reference to KMail's KIMProxy instance.
Definition: kmkernel.cpp:2421
void dcopResetAddMessage()
Clears the list of added message ids which is used to filter out duplicates.
Definition: kmkernel.cpp:989
int dcopAddMessage(const TQString &foldername, const TQString &messagefile, const TQString &MsgStatusFlags=TQString())
Definition: kmkernel.cpp:814
bool folderIsDraftOrOutbox(const KMFolder *)
Returns true if the folder is either the outbox or one of the drafts-folders.
Definition: kmkernel.cpp:2164
int openComposer(const TQString &to, const TQString &cc, const TQString &bcc, const TQString &subject, const TQString &body, int hidden, const KURL &messageFile, const KURL::List &attachURLs, const QCStringList &customHeaders)
returns id of composer if more are opened
Definition: kmkernel.cpp:398
bool mailCheckAborted() const
Returns true IFF the user has requested that the current mail checks should be aborted.
Definition: kmkernel.cpp:2431
void checkMail()
dcop callable stuff
Definition: kmkernel.cpp:334
virtual bool showMail(TQ_UINT32 serialNumber, TQString messageId)
Shows the specified message in a separate message window.
Definition: kmkernel.cpp:1138
int sendCertificate(const TQString &to, const TQByteArray &certData)
Send a certificate request to the CA specified in to.
Definition: kmkernel.cpp:721
virtual TQString getFrom(TQ_UINT32 serialNumber)
DCOP-enabled for use in kaddressbook drop.
Definition: kmkernel.cpp:1187
static bool askToGoOnline()
A static helper function that asks the user if they want to go online.
Definition: kmkernel.cpp:1286
TQValueList< TQGuardedPtr< KMFolder > > allFolders()
Definition: kmkernel.cpp:2537
static KMKernel * self()
normal control stuff
Definition: kmkernel.h:259
DCOPRef newMessage(const TQString &to, const TQString &cc, const TQString &bcc, bool hidden, bool useFolderId, const KURL &messageFile, const KURL &attachURL)
DCOP call used by the Kontact plugin to create a new message.
Definition: kmkernel.cpp:663
bool haveSystemTrayApplet()
Returns true if we have a system tray applet.
Definition: kmkernel.cpp:2118
bool folderIsSentMailFolder(const KMFolder *)
Returns true if the folder is one of the sent-mail folders.
Definition: kmkernel.cpp:2222
KMMainWidget * getKMMainWidget()
Get first mainwidget.
Definition: kmkernel.cpp:2344
void stopNetworkJobs()
Stops all network related jobs and enter offline mode New network jobs cannot be started.
Definition: kmkernel.cpp:1254
KPIM::IdentityManager * identityManager()
return the pointer to the identity manager
Definition: kmkernel.cpp:2238
TDEWallet::Wallet * wallet()
Open KDE wallet and set it to kmail folder.
Definition: kmkernel.cpp:2508
virtual void resumeBackgroundJobs()
Resumes all background jobs and allows new jobs to be started.
Definition: kmkernel.cpp:1248
TDEMainWindow * mainWin()
returns a reference to the first Mainwin or a temporary Mainwin
Definition: kmkernel.cpp:2251
bool transferMail(TQString &destinationDir)
Returns true if the transfer was successful, otherwise false.
Definition: kmkernel.cpp:1854
void abortMailCheck()
Set the state of the abort requested variable to true, (to let the current jobs run,...
Definition: kmkernel.cpp:2436
void slotRequestConfigSync()
Call this slot instead of directly TDEConfig::sync() to minimize the overall config writes.
Definition: kmkernel.cpp:2073
void setDefaultTransport(const TQString &transport)
DCOP call used to set the default transport.
Definition: kmkernel.cpp:620
static bool isOffline()
Checks if the current network state is online or offline.
Definition: kmkernel.cpp:1278
int dcopAddMessage_fastImport(const TQString &foldername, const TQString &messagefile, const TQString &MsgStatusFlags=TQString())
add messages without rejecting duplicates
Definition: kmkernel.cpp:995
bool handleCommandLine(bool noArgsOpensReader)
Reimplemented from KMailIface.
Definition: kmkernel.cpp:211
void resumeNetworkJobs()
Resumes all network related jobs and enter online mode New network jobs can be started.
Definition: kmkernel.cpp:1264
KMFolder * findFolderById(const TQString &idString)
Find a folder by ID string in all folder managers.
Definition: kmkernel.cpp:2409
static TQString localDataPath()
Returns the full path of the user's local data directory for KMail.
Definition: kmkernel.cpp:2111
void slotEmptyTrash()
empty all the trash bins
Definition: kmkernel.cpp:2282
void enableMailCheck()
Set the state of the abort requested variable to false, i.e.
Definition: kmkernel.cpp:2426
void messageCountChanged()
Called by the folder tree if the count of unread/total messages changed.
Definition: kmkernel.cpp:2463
This is a Mime Message.
Definition: kmmessage.h:68
void setBody(const TQCString &aStr)
Set the message body.
Definition: kmmessage.cpp:2774
TQString from() const
Get or set the 'From' header field.
Definition: kmmessage.cpp:2015
void setCharset(const TQCString &charset, DwEntity *entity=0)
Sets the charset of the message or a subpart of the message.
Definition: kmmessage.cpp:4114
static void readConfig()
Reads config settings from group "KMMessage" and sets all internal variables (e.g.
Definition: kmmessage.cpp:4033
void setStatus(const KMMsgStatus status, int idx=-1)
Set status and mark dirty.
Definition: kmmessage.cpp:4153
TQString subject() const
Get or set the 'Subject' header field.
Definition: kmmessage.cpp:2049
void initHeader(uint identity=0)
Initialize header fields.
Definition: kmmessage.cpp:1715
void setHeaderField(const TQCString &name, const TQString &value, HeaderFieldType type=Unstructured, bool prepend=false)
Set the header field with the given name to the given value.
Definition: kmmessage.cpp:2339
TQString dateStr() const
Get or set the 'Date' header field.
Definition: kmmessage.cpp:1797
void getLocation(unsigned long key, KMFolder **retFolder, int *retIndex) const
Returns the folder the message represented by the serial number key is in and the index in that folde...
Definition: kmmsgdict.cpp:319
static const KMMsgDict * instance()
Access the globally unique MessageDict.
Definition: kmmsgdict.cpp:167
KMSystemTray extends KSystemTray and handles system tray notification for KMail.
Definition: kmsystemtray.h:42
The implementation of the interface.
void cleanup()
Disconnect all slots and close the dirs.
The account manager is responsible for creating accounts of various types via the factory method crea...
void readConfig(void)
Completely reload accounts from config.
KMAccount * findByName(const TQString &name) const
Find account by name.
const KMAccount * first() const
First account of the list.
const KMAccount * next() const
Next account of the list.
KMAccount * find(const uint id) const
Find account by id.
The unique JobScheduler instance (owned by kmkernel) implements "background processing" of folder ope...
Definition: jobscheduler.h:97
static TQStringList transportNames()
Returns the list for transport names.
The TemplateParser transforms a message with a given template.