kmail

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