kmail

kmmainwidget.cpp
1 // kmmainwidget.cpp
2 //#define MALLOC_DEBUG 1
3 
4 #ifdef HAVE_CONFIG_H
5 #include <config.h>
6 #endif
7 
8 #include <twin.h>
9 
10 #ifdef MALLOC_DEBUG
11 #include <malloc.h>
12 #endif
13 
14 #undef Unsorted // X headers...
15 #include <tqaccel.h>
16 #include <tqlayout.h>
17 #include <tqhbox.h>
18 #include <tqvbox.h>
19 #include <tqpopupmenu.h>
20 #include <tqptrlist.h>
21 #include <tqsignalmapper.h>
22 #include <tqvaluevector.h>
23 #include <tqstylesheet.h>
24 
25 #include <kopenwith.h>
26 #include <tdemessagebox.h>
27 #include <tdepopupmenu.h>
28 #include <tdeaccelmanager.h>
29 #include <tdeglobalsettings.h>
30 #include <tdestdaccel.h>
31 #include <kkeydialog.h>
32 #include <kcharsets.h>
33 #include <knotifyclient.h>
34 #include <kdebug.h>
35 #include <tdeapplication.h>
36 #include <tdefiledialog.h>
37 #include <ktip.h>
38 #include <knotifydialog.h>
39 #include <kstandarddirs.h>
40 #include <dcopclient.h>
41 #include <kaddrbook.h>
42 #include <tdeaccel.h>
43 #include <kstringhandler.h>
44 
45 #include "globalsettings.h"
46 #include "kcursorsaver.h"
47 #include "broadcaststatus.h"
48 using KPIM::BroadcastStatus;
49 #include "kmfoldermgr.h"
50 #include "kmfolderdia.h"
51 #include "accountmanager.h"
53 #include "kmfilter.h"
54 #include "kmfoldertree.h"
55 #include "kmreadermainwin.h"
56 #include "kmfoldercachedimap.h"
57 #include "kmfolderimap.h"
58 #include "kmacctcachedimap.h"
59 #include "composer.h"
60 #include "kmfolderseldlg.h"
61 #include "kmfiltermgr.h"
62 #include "messagesender.h"
63 #include "kmaddrbook.h"
64 #include "kmversion.h"
65 #include "searchwindow.h"
67 #include "kmacctfolder.h"
68 #include "undostack.h"
69 #include "kmcommands.h"
70 #include "kmmainwin.h"
71 #include "kmsystemtray.h"
72 #include "imapaccountbase.h"
73 #include "transportmanager.h"
74 using KMail::ImapAccountBase;
75 #include "vacation.h"
76 using KMail::Vacation;
77 #include "favoritefolderview.h"
78 #include "subscriptiondialog.h"
79 using KMail::SubscriptionDialog;
80 #include "localsubscriptiondialog.h"
81 using KMail::LocalSubscriptionDialog;
82 #include "attachmentstrategy.h"
83 using KMail::AttachmentStrategy;
84 #include "headerstrategy.h"
85 using KMail::HeaderStrategy;
86 #include "headerstyle.h"
87 using KMail::HeaderStyle;
88 #include "folderjob.h"
89 using KMail::FolderJob;
90 #include "mailinglist-magic.h"
91 #include "antispamwizard.h"
93 #include "filterlogdlg.h"
95 #include <headerlistquicksearch.h>
96 #include "tdelistviewindexedsearchline.h"
97 using KMail::HeaderListQuickSearch;
98 #include "kmheaders.h"
99 #include "mailinglistpropertiesdialog.h"
100 #include "templateparser.h"
101 #include "archivefolderdialog.h"
102 #include "folderutil.h"
103 #include "csshelper.h"
104 
105 #if !defined(NDEBUG)
106  #include "sievedebugdialog.h"
108 #endif
109 
110 #include <libkpimidentities/identity.h>
111 #include <libkpimidentities/identitymanager.h>
112 
113 #include <assert.h>
114 #include <kstatusbar.h>
115 #include <kstaticdeleter.h>
116 #include <tdeaction.h>
117 
118 #include <kmime_mdn.h>
119 #include <kmime_header_parsing.h>
120 using namespace KMime;
121 using KMime::Types::AddrSpecList;
122 
123 #include "progressmanager.h"
124 using KPIM::ProgressManager;
125 
126 #include "managesievescriptsdialog.h"
127 
128 #include "customtemplates.h"
129 #include "customtemplates_kfg.h"
130 
131 #include "kmmainwidget.moc"
132 
133 TQValueList<KMMainWidget*>* KMMainWidget::s_mainWidgetList = 0;
134 static KStaticDeleter<TQValueList<KMMainWidget*> > mwlsd;
135 
136 //-----------------------------------------------------------------------------
137 KMMainWidget::KMMainWidget(TQWidget *parent, const char *name,
138  KXMLGUIClient *aGUIClient,
139  TDEActionCollection *actionCollection, TDEConfig* config ) :
140  TQWidget(parent, name),
141  mFavoritesCheckMailAction( 0 ),
142  mFavoriteFolderView( 0 ),
143  mFolderView( 0 ),
144  mFolderViewParent( 0 ),
145  mFolderViewSplitter( 0 ),
146  mQuickSearchLine( 0 ),
147  mArchiveFolderAction( 0 ),
148  mShowBusySplashTimer( 0 ),
149  mShowingOfflineScreen( false ),
150  mMsgActions( 0 ),
151  mVacationIndicatorActive( false )
152 {
153  // must be the first line of the constructor:
154  mStartupDone = false;
155  mSearchWin = 0;
156  mIntegrated = true;
157  mFolder = 0;
158  mTemplateFolder = 0;
159  mFolderThreadPref = false;
160  mFolderThreadSubjPref = true;
161  mReaderWindowActive = true;
162  mReaderWindowBelow = true;
163  mFolderHtmlPref = false;
164  mFolderHtmlLoadExtPref = false;
165  mSystemTray = 0;
166  mDestructed = false;
167  mActionCollection = actionCollection;
168  mTopLayout = new TQVBoxLayout(this);
169  mFilterMenuActions.setAutoDelete(true);
170  mFilterTBarActions.setAutoDelete(false);
171  mFilterCommands.setAutoDelete(true);
172  mFolderShortcutCommands.setAutoDelete(true);
173  mJob = 0;
174  mConfig = config;
175  mGUIClient = aGUIClient;
176 
177  mCustomReplyActionMenu = 0;
178  mCustomReplyAllActionMenu = 0;
179  mCustomForwardActionMenu = 0;
180  mCustomReplyMapper = 0;
181  mCustomReplyAllMapper = 0;
182  mCustomForwardMapper = 0;
183 
184  // FIXME This should become a line separator as soon as the API
185  // is extended in tdelibs.
186  mToolbarActionSeparator = new TDEActionSeparator( actionCollection );
187 
188  if( !s_mainWidgetList )
189  mwlsd.setObject( s_mainWidgetList, new TQValueList<KMMainWidget*>() );
190  s_mainWidgetList->append( this );
191 
192  mPanner1Sep << 1 << 1;
193  mPanner2Sep << 1 << 1;
194 
195  setMinimumSize(400, 300);
196 
197  readPreConfig();
198  createWidgets();
199 
200  setupActions();
201 
202  readConfig();
203 
204  activatePanners();
205 
206  TQTimer::singleShot( 0, TQT_TQOBJECT(this), TQT_SLOT( slotShowStartupFolder() ));
207 
208  connect( kmkernel->acctMgr(), TQT_SIGNAL( checkedMail( bool, bool, const TQMap<TQString, int> & ) ),
209  this, TQT_SLOT( slotMailChecked( bool, bool, const TQMap<TQString, int> & ) ) );
210 
211  connect( kmkernel->acctMgr(), TQT_SIGNAL( accountAdded( KMAccount* ) ),
212  this, TQT_SLOT( initializeIMAPActions() ) );
213  connect( kmkernel->acctMgr(), TQT_SIGNAL( accountRemoved( KMAccount* ) ),
214  this, TQT_SLOT( initializeIMAPActions() ) );
215 
216  connect(kmkernel, TQT_SIGNAL( configChanged() ),
217  this, TQT_SLOT( slotConfigChanged() ));
218 
219  // display the full path to the folder in the caption
220  connect(mFolderTree, TQT_SIGNAL(currentChanged(TQListViewItem*)),
221  this, TQT_SLOT(slotChangeCaption(TQListViewItem*)));
222  connect(mFolderTree, TQT_SIGNAL(selectionChanged()),
223  TQT_SLOT(updateFolderMenu()) );
224  connect( mFolderTree, TQT_SIGNAL(syncStateChanged()),
225  TQT_SLOT(updateFolderMenu()) );
226 
227  connect(kmkernel->folderMgr(), TQT_SIGNAL(folderRemoved(KMFolder*)),
228  this, TQT_SLOT(slotFolderRemoved(KMFolder*)));
229 
230  connect(kmkernel->imapFolderMgr(), TQT_SIGNAL(folderRemoved(KMFolder*)),
231  this, TQT_SLOT(slotFolderRemoved(KMFolder*)));
232 
233  connect(kmkernel->dimapFolderMgr(), TQT_SIGNAL(folderRemoved(KMFolder*)),
234  this, TQT_SLOT(slotFolderRemoved(KMFolder*)));
235 
236  connect(kmkernel->searchFolderMgr(), TQT_SIGNAL(folderRemoved(KMFolder*)),
237  this, TQT_SLOT(slotFolderRemoved(KMFolder*)));
238 
239  connect( kmkernel, TQT_SIGNAL( onlineStatusChanged( GlobalSettings::EnumNetworkState::type ) ),
240  this, TQT_SLOT( slotUpdateOnlineStatus( GlobalSettings::EnumNetworkState::type ) ) );
241 
242  toggleSystemTray();
243 
244  // must be the last line of the constructor:
245  mStartupDone = true;
246 
247 
248  TDEMainWindow *mainWin = dynamic_cast<TDEMainWindow*>(topLevelWidget());
249  KStatusBar *sb = mainWin ? mainWin->statusBar() : 0;
250  mVacationScriptIndicator = new KStatusBarLabel( TQString(), 0, sb );
251  mVacationScriptIndicator->hide();
252  connect( mVacationScriptIndicator, TQT_SIGNAL(itemReleased(int)), TQT_SLOT(slotEditVacation()) );
253  if ( GlobalSettings::checkOutOfOfficeOnStartup() )
254  TQTimer::singleShot( 0, TQT_TQOBJECT(this), TQT_SLOT(slotCheckVacation()) );
255 }
256 
257 
258 //-----------------------------------------------------------------------------
259 //The kernel may have already been deleted when this method is called,
260 //perform all cleanup that requires the kernel in destruct()
261 KMMainWidget::~KMMainWidget()
262 {
263  s_mainWidgetList->remove( this );
264  destruct();
265 }
266 
267 
268 //-----------------------------------------------------------------------------
269 //This method performs all cleanup that requires the kernel to exist.
270 void KMMainWidget::destruct()
271 {
272  if (mDestructed)
273  return;
274  if (mSearchWin)
275  mSearchWin->close();
276  writeConfig();
277  writeFolderConfig();
278  delete mHeaders;
279  delete mFolderTree;
280  delete mSystemTray;
281  delete mMsgView;
282  mDestructed = true;
283 }
284 
285 
286 //-----------------------------------------------------------------------------
287 void KMMainWidget::readPreConfig(void)
288 {
289  const TDEConfigGroup geometry( KMKernel::config(), "Geometry" );
290  const TDEConfigGroup reader( KMKernel::config(), "Reader" );
291 
292  mLongFolderList = geometry.readEntry( "FolderList", "long" ) != "short";
293  mReaderWindowActive = geometry.readEntry( "readerWindowMode", "below" ) != "hide";
294  mReaderWindowBelow = geometry.readEntry( "readerWindowMode", "below" ) == "below";
295  mThreadPref = geometry.readBoolEntry( "nestedMessages", false );
296 
297  mHtmlPref = reader.readBoolEntry( "htmlMail", false );
298  mHtmlLoadExtPref = reader.readBoolEntry( "htmlLoadExternal", false );
299  mEnableFavoriteFolderView = GlobalSettings::self()->enableFavoriteFolderView();
300 }
301 
302 
303 //-----------------------------------------------------------------------------
304 void KMMainWidget::readFolderConfig(void)
305 {
306  if (!mFolder)
307  return;
308 
309  TDEConfig *config = KMKernel::config();
310  TDEConfigGroupSaver saver(config, "Folder-" + mFolder->idString());
311  mFolderThreadPref = config->readBoolEntry( "threadMessagesOverride", false );
312  mFolderThreadSubjPref = config->readBoolEntry( "threadMessagesBySubject", true );
313  mFolderHtmlPref = config->readBoolEntry( "htmlMailOverride", false );
314  mFolderHtmlLoadExtPref = config->readBoolEntry( "htmlLoadExternalOverride", false );
315 }
316 
317 
318 //-----------------------------------------------------------------------------
319 void KMMainWidget::writeFolderConfig(void)
320 {
321  if (!mFolder)
322  return;
323 
324  TDEConfig *config = KMKernel::config();
325  TDEConfigGroupSaver saver(config, "Folder-" + mFolder->idString());
326  config->writeEntry( "threadMessagesOverride", mFolderThreadPref );
327  config->writeEntry( "threadMessagesBySubject", mFolderThreadSubjPref );
328  config->writeEntry( "htmlMailOverride", mFolderHtmlPref );
329  config->writeEntry( "htmlLoadExternalOverride", mFolderHtmlLoadExtPref );
330 }
331 
332 
333 //-----------------------------------------------------------------------------
334 void KMMainWidget::readConfig(void)
335 {
336  TDEConfig *config = KMKernel::config();
337 
338  bool oldLongFolderList = mLongFolderList;
339  bool oldReaderWindowActive = mReaderWindowActive;
340  bool oldReaderWindowBelow = mReaderWindowBelow;
341  bool oldFavoriteFolderView = mEnableFavoriteFolderView;
342 
343  TQString str;
344  TQSize siz;
345 
346  if (mStartupDone)
347  {
348  writeConfig();
349 
350  readPreConfig();
351  mHeaders->refreshNestedState();
352 
353  bool layoutChanged = ( oldLongFolderList != mLongFolderList )
354  || ( oldReaderWindowActive != mReaderWindowActive )
355  || ( oldReaderWindowBelow != mReaderWindowBelow )
356  || ( oldFavoriteFolderView != mEnableFavoriteFolderView );
357 
358 
359  if( layoutChanged ) {
360  hide();
361  // delete all panners
362  delete mPanner1; // will always delete the others
363  createWidgets();
364  }
365 
366  }
367 
368  { // area for config group "Geometry"
369  TDEConfigGroupSaver saver(config, "Geometry");
370  // size of the mainwin
371  TQSize defaultSize(750,560);
372  siz = config->readSizeEntry("MainWin", &defaultSize);
373  if (!siz.isEmpty())
374  resize(siz);
375  // default width of the foldertree
376  static const int folderpanewidth = 250;
377 
378  const int folderW = config->readNumEntry( "FolderPaneWidth", folderpanewidth );
379  const int headerW = config->readNumEntry( "HeaderPaneWidth", width()-folderpanewidth );
380  const int headerH = config->readNumEntry( "HeaderPaneHeight", 180 );
381  const int readerH = config->readNumEntry( "ReaderPaneHeight", 280 );
382 
383  mPanner1Sep.clear();
384  mPanner2Sep.clear();
385  TQValueList<int> & widths = mLongFolderList ? mPanner1Sep : mPanner2Sep ;
386  TQValueList<int> & heights = mLongFolderList ? mPanner2Sep : mPanner1Sep ;
387 
388  widths << folderW << headerW;
389  heights << headerH << readerH;
390 
391  bool layoutChanged = ( oldLongFolderList != mLongFolderList )
392  || ( oldReaderWindowActive != mReaderWindowActive )
393  || ( oldReaderWindowBelow != mReaderWindowBelow );
394 
395  if (!mStartupDone || layoutChanged )
396  {
400  // The columns are shown by default.
401 
402  const int unreadColumn = config->readNumEntry("UnreadColumn", 1);
403  const int totalColumn = config->readNumEntry("TotalColumn", 2);
404  const int sizeColumn = config->readNumEntry("SizeColumn", 3);
405 
406  /* we need to _activate_ them in the correct order
407  * this is ugly because we can't use header()->moveSection
408  * but otherwise the restoreLayout from KMFolderTree
409  * doesn't know that to do */
410  if (unreadColumn == 1)
411  mFolderTree->addUnreadColumn( i18n("Unread"), 70 );
412  else if (totalColumn == 1)
413  mFolderTree->addTotalColumn( i18n("Total"), 70 );
414  else if (sizeColumn == 1)
415  mFolderTree->addSizeColumn( i18n("Size"), 70 );
416 
417  if (unreadColumn == 2)
418  mFolderTree->addUnreadColumn( i18n("Unread"), 70 );
419  else if (totalColumn == 2)
420  mFolderTree->addTotalColumn( i18n("Total"), 70 );
421  else if (sizeColumn == 2)
422  mFolderTree->addSizeColumn( i18n("Size"), 70 );
423 
424  if (unreadColumn == 3)
425  mFolderTree->addUnreadColumn( i18n("Unread"), 70 );
426  else if (totalColumn == 3)
427  mFolderTree->addTotalColumn( i18n("Total"), 70 );
428  else if (sizeColumn == 3)
429  mFolderTree->addSizeColumn( i18n("Size"), 70 );
430 
431  mUnreadColumnToggle->setChecked( mFolderTree->isUnreadActive() );
432  mUnreadTextToggle->setChecked( !mFolderTree->isUnreadActive() );
433  mTotalColumnToggle->setChecked( mFolderTree->isTotalActive() );
434  mSizeColumnToggle->setChecked( mFolderTree->isSizeActive() );
435 
436  mFolderTree->updatePopup();
437  }
438  }
439 
440  if (mMsgView)
441  mMsgView->readConfig();
442 
443  mHeaders->readConfig();
444  mHeaders->restoreColumnLayout( KMKernel::config(), "Header-Geometry" );
445 
446  if ( mFolderViewSplitter && !GlobalSettings::self()->folderViewSplitterPosition().isEmpty() ) {
447  mFolderViewSplitter->setSizes( GlobalSettings::self()->folderViewSplitterPosition() );
448  } else {
449  TQValueList<int> defaults;
450  defaults << (int)(height() * 0.2) << (int)(height() * 0.8);
451  mFolderViewSplitter->setSizes( defaults );
452  }
453 
454  mFolderTree->readConfig();
455  if ( mFavoriteFolderView )
456  mFavoriteFolderView->readConfig();
457  mFavoritesCheckMailAction->setEnabled( GlobalSettings::self()->enableFavoriteFolderView() );
458 
459  { // area for config group "General"
460  TDEConfigGroupSaver saver(config, "General");
461  mBeepOnNew = config->readBoolEntry("beep-on-mail", false);
462  mConfirmEmpty = config->readBoolEntry("confirm-before-empty", true);
463  // startup-Folder, defaults to system-inbox
464  mStartupFolder = config->readEntry("startupFolder", kmkernel->inboxFolder()->idString());
465  if (!mStartupDone)
466  {
467  // check mail on startup
468  bool check = config->readBoolEntry("checkmail-startup", false);
469  if (check)
470  // do it after building the kmmainwin, so that the progressdialog is available
471  TQTimer::singleShot( 0, TQT_TQOBJECT(this), TQT_SLOT( slotCheckMail() ) );
472  }
473  }
474 
475  // reload foldertree
476  mFolderTree->reload();
477 
478  // Re-activate panners
479  if (mStartupDone)
480  {
481  // Update systray
482  toggleSystemTray();
483 
484  bool layoutChanged = ( oldLongFolderList != mLongFolderList )
485  || ( oldReaderWindowActive != mReaderWindowActive )
486  || ( oldReaderWindowBelow != mReaderWindowBelow )
487  || ( oldFavoriteFolderView != mEnableFavoriteFolderView );
488  if ( layoutChanged ) {
489  activatePanners();
490  }
491 
492  mFolderTree->showFolder( mFolder );
493 
494  // sanders - New code
495  mHeaders->setFolder(mFolder);
496  if (mMsgView) {
497  int aIdx = mHeaders->currentItemIndex();
498  if (aIdx != -1)
499  mMsgView->setMsg( mFolder->getMsg(aIdx), true );
500  else
501  mMsgView->clear( true );
502  }
503  updateMessageActions();
504  show();
505  // sanders - Maybe this fixes a bug?
506 
507  }
508  updateMessageMenu();
509  updateFileMenu();
510 }
511 
512 
513 //-----------------------------------------------------------------------------
514 void KMMainWidget::writeConfig(void)
515 {
516  TQString s;
517  TDEConfig *config = KMKernel::config();
518  TDEConfigGroup geometry( config, "Geometry" );
519 
520  if (mMsgView)
521  mMsgView->writeConfig();
522 
523  if ( mFolderViewSplitter )
524  GlobalSettings::setFolderViewSplitterPosition( mFolderViewSplitter->sizes() );
525  mFolderTree->writeConfig();
526  if ( mFavoriteFolderView )
527  mFavoriteFolderView->writeConfig();
528 
529  geometry.writeEntry( "MainWin", this->geometry().size() );
530 
531  const TQValueList<int> widths = ( mLongFolderList ? mPanner1 : mPanner2 )->sizes();
532  const TQValueList<int> heights = ( mLongFolderList ? mPanner2 : mPanner1 )->sizes();
533 
534  geometry.writeEntry( "FolderPaneWidth", widths[0] );
535  geometry.writeEntry( "HeaderPaneWidth", widths[1] );
536 
537  // Only save when the widget is shown (to avoid saving a wrong value)
538  if ( mSearchAndHeaders && mSearchAndHeaders->isShown() ) {
539  geometry.writeEntry( "HeaderPaneHeight", heights[0] );
540  geometry.writeEntry( "ReaderPaneHeight", heights[1] );
541  }
542 
543  // save the state of the unread/total-columns
544  geometry.writeEntry( "UnreadColumn", mFolderTree->unreadIndex() );
545  geometry.writeEntry( "TotalColumn", mFolderTree->totalIndex() );
546  geometry.writeEntry( "SizeColumn", mFolderTree->sizeIndex() );
547 }
548 
549 
550 //-----------------------------------------------------------------------------
551 void KMMainWidget::createWidgets(void)
552 {
553  // Create the splitters according to the layout settings
554  TQWidget *headerParent = 0,
555  *mimeParent = 0, *messageParent = 0;
556 
557  const bool opaqueResize = TDEGlobalSettings::opaqueResize();
558  if ( mLongFolderList ) {
559  // superior splitter: folder tree vs. rest
560  // inferior splitter: headers vs. message vs. mime tree
561  mPanner1 = new TQSplitter( Qt::Horizontal, this, "panner 1" );
562  mPanner1->setOpaqueResize( opaqueResize );
563  Qt::Orientation orientation = mReaderWindowBelow ? Qt::Vertical : Qt::Horizontal;
564  mPanner2 = new TQSplitter( orientation, mPanner1, "panner 2" );
565  mPanner2->setOpaqueResize( opaqueResize );
566  mPanner2->setChildrenCollapsible( false );
567  mFolderViewParent = mPanner1;
568  headerParent = mimeParent = messageParent = mPanner2;
569  } else /* !mLongFolderList */ {
570  // superior splitter: ( folder tree + headers ) vs. message vs. mime
571  // inferior splitter: folder tree vs. headers
572  mPanner1 = new TQSplitter( Qt::Vertical, this, "panner 1" );
573  mPanner1->setOpaqueResize( opaqueResize );
574  mPanner1->setChildrenCollapsible( false );
575  mPanner2 = new TQSplitter( Qt::Horizontal, mPanner1, "panner 2" );
576  mPanner2->setOpaqueResize( opaqueResize );
577  headerParent = mFolderViewParent = mPanner2;
578  mimeParent = messageParent = mPanner1;
579  }
580 
581 #ifndef NDEBUG
582  if( mPanner1 ) mPanner1->dumpObjectTree();
583  if( mPanner2 ) mPanner2->dumpObjectTree();
584 #endif
585 
586  mTopLayout->add( mPanner1 );
587 
588  // BUG -sanders these accelerators stop working after switching
589  // between long/short folder layout
590  // Probably need to disconnect them first.
591 
592  // create list of messages
593 #ifndef NDEBUG
594  headerParent->dumpObjectTree();
595 #endif
596  mSearchAndHeaders = new TQVBox( headerParent );
597  mSearchToolBar = new TDEToolBar( mSearchAndHeaders, "search toolbar");
598  mSearchToolBar->setMovingEnabled(false);
599  mSearchToolBar->boxLayout()->setSpacing( KDialog::spacingHint() );
600  TQLabel *label = new TQLabel( i18n("S&earch:"), mSearchToolBar, "tde toolbar widget" );
601 
602 
603  mHeaders = new KMHeaders(this, mSearchAndHeaders, "headers");
604 #ifdef HAVE_INDEXLIB
605  mQuickSearchLine = new TDEListViewIndexedSearchLine( mSearchToolBar, mHeaders,
606  actionCollection(), "headers quick search line" );
607 #else
608  mQuickSearchLine = new HeaderListQuickSearch( mSearchToolBar, mHeaders,
609  actionCollection(), "headers quick search line" );
610 #endif
611  label->setBuddy( mQuickSearchLine );
612  connect( mQuickSearchLine, TQT_SIGNAL( requestFullSearch() ),
613  this, TQT_SLOT( slotRequestFullSearchFromQuickSearch() ) );
614  mSearchToolBar->setStretchableWidget( mQuickSearchLine );
615  connect( mHeaders, TQT_SIGNAL( messageListUpdated() ),
616  mQuickSearchLine, TQT_SLOT( updateSearch() ) );
617  if ( !GlobalSettings::self()->quickSearchActive() ) mSearchToolBar->hide();
618 
619  if (mReaderWindowActive) {
620  connect(mHeaders, TQT_SIGNAL(selected(KMMessage*)),
621  this, TQT_SLOT(slotMsgSelected(KMMessage*)));
622  }
623  connect(mHeaders, TQT_SIGNAL(activated(KMMessage*)),
624  this, TQT_SLOT(slotMsgActivated(KMMessage*)));
625  connect( mHeaders, TQT_SIGNAL( selectionChanged() ),
626  TQT_SLOT( startUpdateMessageActionsTimer() ) );
627  TQAccel *accel = actionCollection()->tdeaccel();
628  accel->connectItem(accel->insertItem(SHIFT+Key_Left),
629  mHeaders, TQT_SLOT(selectPrevMessage()));
630  accel->connectItem(accel->insertItem(SHIFT+Key_Right),
631  mHeaders, TQT_SLOT(selectNextMessage()));
632 
633  if (mReaderWindowActive) {
634  mMsgView = new KMReaderWin(messageParent, TQT_TQWIDGET(this), actionCollection(), 0 );
635  if ( mMsgActions ) {
636  mMsgActions->setMessageView( mMsgView );
637  }
638 
639  connect(mMsgView, TQT_SIGNAL(replaceMsgByUnencryptedVersion()),
640  this, TQT_SLOT(slotReplaceMsgByUnencryptedVersion()));
641  connect(mMsgView, TQT_SIGNAL(popupMenu(KMMessage&,const KURL&,const TQPoint&)),
642  this, TQT_SLOT(slotMsgPopup(KMMessage&,const KURL&,const TQPoint&)));
643  connect(mMsgView, TQT_SIGNAL(urlClicked(const KURL&,int)),
644  mMsgView, TQT_SLOT(slotUrlClicked()));
645  connect(mHeaders, TQT_SIGNAL(maybeDeleting()),
646  mMsgView, TQT_SLOT(clearCache()));
647  connect(mMsgView, TQT_SIGNAL(noDrag()),
648  mHeaders, TQT_SLOT(slotNoDrag()));
649  accel->connectItem(accel->insertItem(Key_Up),
650  mMsgView, TQT_SLOT(slotScrollUp()));
651  accel->connectItem(accel->insertItem(Key_Down),
652  mMsgView, TQT_SLOT(slotScrollDown()));
653  accel->connectItem(accel->insertItem(Key_Prior),
654  mMsgView, TQT_SLOT(slotScrollPrior()));
655  accel->connectItem(accel->insertItem(Key_Next),
656  mMsgView, TQT_SLOT(slotScrollNext()));
657  } else {
658  mMsgView = NULL;
659  }
660 
661  TDEAction *action;
662 
663  mMoveMsgToFolderAction = new TDEAction( i18n("Move Message to Folder"), Key_M, TQT_TQOBJECT(this),
664  TQT_SLOT(slotMoveMsg()), actionCollection(),
665  "move_message_to_folder" );
666  mMoveMsgToFolderAction->plugAccel( actionCollection()->tdeaccel() );
667 
668  action = new TDEAction( i18n("Copy Message to Folder"), Key_C, TQT_TQOBJECT(this),
669  TQT_SLOT(slotCopyMsg()), actionCollection(),
670  "copy_message_to_folder" );
671  action->plugAccel( actionCollection()->tdeaccel() );
672 
673  action = new TDEAction( i18n("Jump to Folder"), Key_J, TQT_TQOBJECT(this),
674  TQT_SLOT(slotJumpToFolder()), actionCollection(),
675  "jump_to_folder" );
676  action->plugAccel( actionCollection()->tdeaccel() );
677 
678  // create list of folders
679  mFolderViewSplitter = new TQSplitter( Qt::Vertical, mFolderViewParent );
680  mFolderViewSplitter->setOpaqueResize( TDEGlobalSettings::opaqueResize() );
681  mFavoriteFolderView = new KMail::FavoriteFolderView( this, mFolderViewSplitter );
682  if ( mFavoritesCheckMailAction )
683  connect( mFavoritesCheckMailAction, TQT_SIGNAL(activated()), mFavoriteFolderView, TQT_SLOT(checkMail()) );
684  TQWidget *folderTreeParent = mFolderViewParent;
685  if ( GlobalSettings::enableFavoriteFolderView() ) {
686  folderTreeParent = mFolderViewSplitter;
687  mFolderView = mFolderViewSplitter;
688  }
689  mFolderTree = new KMFolderTree(this, folderTreeParent, "folderTree");
690  if ( !GlobalSettings::enableFavoriteFolderView() ) {
691  mFolderView = mFolderTree;
692  }
693  connect( mFolderTree, TQT_SIGNAL(folderSelected(KMFolder*)),
694  mFavoriteFolderView, TQT_SLOT(folderTreeSelectionChanged(KMFolder*)) );
695 
696  connect(mFolderTree, TQT_SIGNAL(folderSelected(KMFolder*)),
697  this, TQT_SLOT(folderSelected(KMFolder*)));
698  connect( mFolderTree, TQT_SIGNAL( folderSelected( KMFolder* ) ),
699  mQuickSearchLine, TQT_SLOT( reset() ) );
700  connect(mFolderTree, TQT_SIGNAL(folderSelectedUnread(KMFolder*)),
701  this, TQT_SLOT(folderSelectedUnread(KMFolder*)));
702  connect(mFolderTree, TQT_SIGNAL(folderDrop(KMFolder*)),
703  this, TQT_SLOT(slotMoveMsgToFolder(KMFolder*)));
704  connect(mFolderTree, TQT_SIGNAL(folderDropCopy(KMFolder*)),
705  this, TQT_SLOT(slotCopyMsgToFolder(KMFolder*)));
706  connect(mFolderTree, TQT_SIGNAL(columnsChanged()),
707  this, TQT_SLOT(slotFolderTreeColumnsChanged()));
708 
709  if ( mFavoriteFolderView ) {
710  connect( mFavoriteFolderView, TQT_SIGNAL(folderDrop(KMFolder*)), TQT_SLOT(slotMoveMsgToFolder(KMFolder*)) );
711  connect( mFavoriteFolderView, TQT_SIGNAL(folderDropCopy(KMFolder*)), TQT_SLOT(slotCopyMsgToFolder(KMFolder*)) );
712  }
713 
714  //Commands not worthy of menu items, but that deserve configurable keybindings
715  mRemoveDuplicatesAction = new TDEAction(
716  i18n("Remove Duplicate Messages"), CTRL+Key_Asterisk, TQT_TQOBJECT(this),
717  TQT_SLOT(removeDuplicates()), actionCollection(), "remove_duplicate_messages");
718  action->plugAccel( actionCollection()->tdeaccel() );
719 
720  action = new TDEAction(
721  i18n("Abort Current Operation"), Key_Escape, ProgressManager::instance(),
722  TQT_SLOT(slotAbortAll()), actionCollection(), "cancel" );
723  action->plugAccel( actionCollection()->tdeaccel() );
724 
725  action = new TDEAction(
726  i18n("Focus on Next Folder"), CTRL+Key_Right, TQT_TQOBJECT(mFolderTree),
727  TQT_SLOT(incCurrentFolder()), actionCollection(), "inc_current_folder");
728  action->plugAccel( actionCollection()->tdeaccel() );
729 
730  action = new TDEAction(
731  i18n("Focus on Previous Folder"), CTRL+Key_Left, TQT_TQOBJECT(mFolderTree),
732  TQT_SLOT(decCurrentFolder()), actionCollection(), "dec_current_folder");
733  action->plugAccel( actionCollection()->tdeaccel() );
734 
735  action = new TDEAction(
736  i18n("Select Folder with Focus"), CTRL+Key_Space, TQT_TQOBJECT(mFolderTree),
737  TQT_SLOT(selectCurrentFolder()), actionCollection(), "select_current_folder");
738  action->plugAccel( actionCollection()->tdeaccel() );
739 
740  action = new TDEAction(
741  i18n("Focus on Next Message"), ALT+Key_Right, TQT_TQOBJECT(mHeaders),
742  TQT_SLOT(incCurrentMessage()), actionCollection(), "inc_current_message");
743  action->plugAccel( actionCollection()->tdeaccel() );
744 
745  action = new TDEAction(
746  i18n("Focus on Previous Message"), ALT+Key_Left, TQT_TQOBJECT(mHeaders),
747  TQT_SLOT(decCurrentMessage()), actionCollection(), "dec_current_message");
748  action->plugAccel( actionCollection()->tdeaccel() );
749 
750  action = new TDEAction(
751  i18n("Select Message with Focus"), ALT+Key_Space, TQT_TQOBJECT(mHeaders),
752  TQT_SLOT( selectCurrentMessage() ), actionCollection(), "select_current_message");
753  action->plugAccel( actionCollection()->tdeaccel() );
754 
755  connect( kmkernel->outboxFolder(), TQT_SIGNAL( msgRemoved(int, TQString) ),
756  TQT_SLOT( startUpdateMessageActionsTimer() ) );
757  connect( kmkernel->outboxFolder(), TQT_SIGNAL( msgAdded(int) ),
758  TQT_SLOT( startUpdateMessageActionsTimer() ) );
759 }
760 
761 
762 //-----------------------------------------------------------------------------
763 void KMMainWidget::activatePanners(void)
764 {
765  if (mMsgView) {
766  TQObject::disconnect( mMsgView->copyAction(),
767  TQT_SIGNAL( activated() ),
768  mMsgView, TQT_SLOT( slotCopySelectedText() ));
769  }
770 
771  setupFolderView();
772  if ( mLongFolderList ) {
773  mSearchAndHeaders->reparent( mPanner2, 0, TQPoint( 0, 0 ) );
774  if (mMsgView) {
775  mMsgView->reparent( mPanner2, 0, TQPoint( 0, 0 ) );
776  mPanner2->moveToLast( mMsgView );
777  }
778  mFolderViewParent = mPanner1;
779  mFolderView->reparent( mFolderViewParent, 0, TQPoint( 0, 0 ) );
780  mPanner1->moveToLast( mPanner2 );
781  mPanner1->setSizes( mPanner1Sep );
782  mPanner1->setResizeMode( mFolderView, TQSplitter::KeepSize );
783  mPanner2->setSizes( mPanner2Sep );
784  mPanner2->setResizeMode( mSearchAndHeaders, TQSplitter::KeepSize );
785  } else /* !mLongFolderList */ {
786  mFolderViewParent = mPanner2;
787  mFolderView->reparent( mFolderViewParent, 0, TQPoint( 0, 0 ) );
788  mSearchAndHeaders->reparent( mPanner2, 0, TQPoint( 0, 0 ) );
789  mPanner2->moveToLast( mSearchAndHeaders );
790  mPanner1->moveToFirst( mPanner2 );
791  if (mMsgView) {
792  mMsgView->reparent( mPanner1, 0, TQPoint( 0, 0 ) );
793  mPanner1->moveToLast( mMsgView );
794  }
795  mPanner1->setSizes( mPanner1Sep );
796  mPanner2->setSizes( mPanner2Sep );
797  mPanner1->setResizeMode( mPanner2, TQSplitter::KeepSize );
798  mPanner2->setResizeMode( mFolderView, TQSplitter::KeepSize );
799  }
800 
801  if (mMsgView) {
802  TQObject::connect( mMsgView->copyAction(),
803  TQT_SIGNAL( activated() ),
804  mMsgView, TQT_SLOT( slotCopySelectedText() ));
805  }
806 }
807 
808 
809 //-----------------------------------------------------------------------------
810 void KMMainWidget::hide()
811 {
812  TQWidget::hide();
813 }
814 
815 
816 //-----------------------------------------------------------------------------
817 void KMMainWidget::show()
818 {
819  TQWidget::show();
820 }
821 
822 //-------------------------------------------------------------------------
823 void KMMainWidget::slotSearch()
824 {
825  if(!mSearchWin)
826  {
827  mSearchWin = new SearchWindow(this, "Search", mFolder, false);
828  connect(mSearchWin, TQT_SIGNAL(destroyed()),
829  this, TQT_SLOT(slotSearchClosed()));
830  }
831  else
832  {
833  mSearchWin->activateFolder(mFolder);
834  }
835 
836  mSearchWin->show();
837  KWin::activateWindow( mSearchWin->winId() );
838 }
839 
840 
841 //-------------------------------------------------------------------------
842 void KMMainWidget::slotSearchClosed()
843 {
844  mSearchWin = 0;
845 }
846 
847 
848 //-------------------------------------------------------------------------
849 void KMMainWidget::slotFind()
850 {
851  if( mMsgView )
852  mMsgView->slotFind();
853 }
854 
855 
856 //-----------------------------------------------------------------------------
857 void KMMainWidget::slotHelp()
858 {
859  kapp->invokeHelp();
860 }
861 
862 
863 //-----------------------------------------------------------------------------
864 void KMMainWidget::slotFilter()
865 {
866  kmkernel->filterMgr()->openDialog( this );
867 }
868 
869 
870 //-----------------------------------------------------------------------------
871 void KMMainWidget::slotPopFilter()
872 {
873  kmkernel->popFilterMgr()->openDialog( this );
874 }
875 
876 void KMMainWidget::slotManageSieveScripts()
877 {
878  if ( !kmkernel->askToGoOnline() ) {
879  return;
880  }
881  KMail::ManageSieveScriptsDialog * dlg = new KMail::ManageSieveScriptsDialog( this );
882  dlg->show();
883 }
884 
885 
886 //-----------------------------------------------------------------------------
887 void KMMainWidget::slotAddrBook()
888 {
889  KAddrBookExternal::openAddressBook(this);
890 }
891 
892 
893 //-----------------------------------------------------------------------------
894 void KMMainWidget::slotImport()
895 {
896  KRun::runCommand("kmailcvt");
897 }
898 
899 //-----------------------------------------------------------------------------
900 void KMMainWidget::slotCheckMail()
901 {
902  if ( !kmkernel->askToGoOnline() ) {
903  return;
904  }
905  kmkernel->acctMgr()->checkMail(true);
906 }
907 
908 //-----------------------------------------------------------------------------
909 void KMMainWidget::slotCheckOneAccount(int item)
910 {
911  if ( !kmkernel->askToGoOnline() ) {
912  return;
913  }
914  kmkernel->acctMgr()->intCheckMail(item);
915 }
916 
917 //-----------------------------------------------------------------------------
918 void KMMainWidget::slotMailChecked( bool newMail, bool sendOnCheck,
919  const TQMap<TQString, int> & newInFolder )
920 {
921  const bool sendOnAll =
922  GlobalSettings::self()->sendOnCheck() == GlobalSettings::EnumSendOnCheck::SendOnAllChecks;
923  const bool sendOnManual =
924  GlobalSettings::self()->sendOnCheck() == GlobalSettings::EnumSendOnCheck::SendOnManualChecks;
925  if( !kmkernel->isOffline() && ( sendOnAll || (sendOnManual && sendOnCheck ) ) )
926  slotSendQueued();
927 
928  if ( !newMail || newInFolder.isEmpty() )
929  return;
930 
931  kapp->dcopClient()->emitDCOPSignal( "unreadCountChanged()", TQByteArray() );
932 
933  // build summary for new mail message
934  bool showNotification = false;
935  TQString summary;
936  TQStringList keys( newInFolder.keys() );
937  keys.sort();
938  for ( TQStringList::const_iterator it = keys.begin();
939  it != keys.end();
940  ++it ) {
941  kdDebug(5006) << newInFolder.find( *it ).data() << " new message(s) in "
942  << *it << endl;
943 
944  KMFolder *folder = kmkernel->findFolderById( *it );
945 
946  if ( folder && !folder->ignoreNewMail() ) {
947  showNotification = true;
948  if ( GlobalSettings::self()->verboseNewMailNotification() ) {
949  summary += "<br>" + i18n( "1 new message in %1",
950  "%n new messages in %1",
951  newInFolder.find( *it ).data() )
952  .arg( folder->prettyURL() );
953  }
954  }
955  }
956 
957  // update folder menus in case some mail got filtered to trash/current folder
958  // and we can enable "empty trash/move all to trash" action etc.
959  updateFolderMenu();
960 
961  if ( !showNotification )
962  return;
963 
964  if ( GlobalSettings::self()->verboseNewMailNotification() ) {
965  summary = i18n( "%1 is a list of the number of new messages per folder",
966  "<b>New mail arrived</b><br>%1" )
967  .arg( summary );
968  }
969  else {
970  summary = i18n( "New mail arrived" );
971  }
972 
973  if(kmkernel->xmlGuiInstance()) {
974  KNotifyClient::Instance instance(kmkernel->xmlGuiInstance());
975  KNotifyClient::event( topLevelWidget()->winId(), "new-mail-arrived",
976  summary );
977  }
978  else
979  KNotifyClient::event( topLevelWidget()->winId(), "new-mail-arrived",
980  summary );
981 
982  if (mBeepOnNew) {
983  KNotifyClient::beep();
984  }
985 }
986 
987 
988 //-----------------------------------------------------------------------------
989 void KMMainWidget::slotCompose()
990 {
991  KMail::Composer * win;
992  KMMessage* msg = new KMMessage;
993 
994  if ( mFolder ) {
995  msg->initHeader( mFolder->identity() );
996  TemplateParser parser( msg, TemplateParser::NewMessage );
997  parser.process( NULL, mFolder );
998  win = KMail::makeComposer( msg, mFolder->identity() );
999  } else {
1000  msg->initHeader();
1001  TemplateParser parser( msg, TemplateParser::NewMessage );
1002  parser.process( NULL, NULL );
1003  win = KMail::makeComposer( msg );
1004  }
1005 
1006  win->show();
1007 
1008 }
1009 
1010 //-----------------------------------------------------------------------------
1011 // TODO: do we want the list sorted alphabetically?
1012 void KMMainWidget::slotShowNewFromTemplate()
1013 {
1014  if ( mFolder ) {
1015  const KPIM::Identity & ident =
1016  kmkernel->identityManager()->identityForUoidOrDefault( mFolder->identity() );
1017  mTemplateFolder = kmkernel->folderMgr()->findIdString( ident.templates() );
1018  }
1019  else mTemplateFolder = kmkernel->templatesFolder();
1020  if ( !mTemplateFolder )
1021  return;
1022 
1023  mTemplateMenu->popupMenu()->clear();
1024  for ( int idx = 0; idx<mTemplateFolder->count(); ++idx ) {
1025  KMMsgBase *mb = mTemplateFolder->getMsgBase( idx );
1026 
1027  TQString subj = mb->subject();
1028  if ( subj.isEmpty() ) subj = i18n("No Subject");
1029  mTemplateMenu->popupMenu()->insertItem(
1030  KStringHandler::rsqueeze( subj.replace( "&", "&&" ) ), idx );
1031  }
1032 }
1033 
1034 //-----------------------------------------------------------------------------
1035 void KMMainWidget::slotNewFromTemplate( int id )
1036 {
1037  if ( !mTemplateFolder )
1038  return;
1039  newFromTemplate(mTemplateFolder->getMsg( id ) );
1040 }
1041 
1042 //-----------------------------------------------------------------------------
1043 void KMMainWidget::newFromTemplate( KMMessage *msg )
1044 {
1045  if ( !msg )
1046  return;
1047  KMCommand *command = new KMUseTemplateCommand( this, msg );
1048  command->start();
1049 }
1050 
1051 //-----------------------------------------------------------------------------
1052 void KMMainWidget::slotPostToML()
1053 {
1054  if ( mFolder && mFolder->isMailingListEnabled() ) {
1055  KMCommand *command = new KMMailingListPostCommand( this, mFolder );
1056  command->start();
1057  }
1058  else
1059  slotCompose();
1060 }
1061 
1062 //-----------------------------------------------------------------------------
1063 void KMMainWidget::slotFolderMailingListProperties()
1064 {
1065  if (!mFolderTree) return;
1066  KMFolderTreeItem *item = static_cast<KMFolderTreeItem*>( mFolderTree->currentItem() );
1067  if ( !item ) return;
1068  KMFolder* folder = item->folder();
1069  if ( folder ) {
1070  ( new KMail::MailingListFolderPropertiesDialog( this, folder ) )->show();
1071  }
1072 }
1073 
1074 //-----------------------------------------------------------------------------
1075 void KMMainWidget::slotFolderShortcutCommand()
1076 {
1077  if (!mFolderTree) return;
1078  KMFolderTreeItem *item = static_cast<KMFolderTreeItem*>( mFolderTree->currentItem() );
1079  if ( item )
1080  item->assignShortcut();
1081 }
1082 
1083 
1084 //-----------------------------------------------------------------------------
1085 void KMMainWidget::slotModifyFolder()
1086 {
1087  if (!mFolderTree) return;
1088  KMFolderTreeItem *item = static_cast<KMFolderTreeItem*>( mFolderTree->currentItem() );
1089  if ( item )
1090  modifyFolder( item );
1091 }
1092 
1093 //-----------------------------------------------------------------------------
1094 void KMMainWidget::modifyFolder( KMFolderTreeItem* folderItem )
1095 {
1096  KMFolder* folder = folderItem->folder();
1097  KMFolderTree* folderTree = static_cast<KMFolderTree *>( folderItem->listView() );
1098  KMFolderDialog props( folder, folder->parent(), folderTree,
1099  i18n("Properties of Folder %1").arg( folder->label() ) );
1100  props.exec();
1101  updateFolderMenu();
1102  //Kolab issue 2152
1103  if ( mSystemTray )
1104  mSystemTray->foldersChanged();
1105 }
1106 
1107 //-----------------------------------------------------------------------------
1108 void KMMainWidget::slotExpireFolder()
1109 {
1110  TQString str;
1111  bool canBeExpired = true;
1112 
1113  if (!mFolder) return;
1114 
1115  if (!mFolder->isAutoExpire()) {
1116  canBeExpired = false;
1117  } else if (mFolder->getUnreadExpireUnits()==expireNever &&
1118  mFolder->getReadExpireUnits()==expireNever) {
1119  canBeExpired = false;
1120  }
1121 
1122  if (!canBeExpired) {
1123  str = i18n("This folder does not have any expiry options set");
1124  KMessageBox::information(this, str);
1125  return;
1126  }
1127  TDEConfig *config = KMKernel::config();
1128  TDEConfigGroupSaver saver(config, "General");
1129 
1130  if (config->readBoolEntry("warn-before-expire", true)) {
1131  str = i18n("<qt>Are you sure you want to expire the folder <b>%1</b>?</qt>").arg(TQStyleSheet::escape( mFolder->label() ));
1132  if (KMessageBox::warningContinueCancel(this, str, i18n("Expire Folder"),
1133  i18n("&Expire"))
1134  != KMessageBox::Continue) return;
1135  }
1136 
1137  mFolder->expireOldMessages( true /*immediate*/);
1138 }
1139 
1140 //-----------------------------------------------------------------------------
1141 void KMMainWidget::slotEmptyFolder()
1142 {
1143  TQString str;
1144 
1145  if (!mFolder) return;
1146  bool isTrash = kmkernel->folderIsTrash(mFolder);
1147 
1148  if (mConfirmEmpty)
1149  {
1150  TQString title = (isTrash) ? i18n("Empty Trash") : i18n("Move to Trash");
1151  TQString text = (isTrash) ?
1152  i18n("Are you sure you want to empty the trash folder?") :
1153  i18n("<qt>Are you sure you want to move all messages from "
1154  "folder <b>%1</b> to the trash?</qt>").arg( TQStyleSheet::escape( mFolder->label() ) );
1155 
1156  if (KMessageBox::warningContinueCancel(this, text, title, KGuiItem( title, "edittrash"))
1157  != KMessageBox::Continue) return;
1158  }
1159  KCursorSaver busy(KBusyPtr::busy());
1160  slotMarkAll();
1161  if (isTrash) {
1162  /* Don't ask for confirmation again when deleting, the user has already
1163  confirmed. */
1164  slotDeleteMsg( false );
1165  }
1166  else
1167  slotTrashMsg();
1168 
1169  if (mMsgView) mMsgView->clearCache();
1170 
1171  if ( !isTrash )
1172  BroadcastStatus::instance()->setStatusMsg(i18n("Moved all messages to the trash"));
1173 
1174  updateMessageActions();
1175 
1176  // Disable empty trash/move all to trash action - we've just deleted/moved all folder
1177  // contents.
1178  mEmptyFolderAction->setEnabled( false );
1179 }
1180 
1181 //-----------------------------------------------------------------------------
1182 void KMMainWidget::slotArchiveFolder()
1183 {
1184  KMail::ArchiveFolderDialog archiveDialog;
1185  archiveDialog.setFolder( mFolder );
1186  archiveDialog.exec();
1187 }
1188 
1189 //-----------------------------------------------------------------------------
1190 void KMMainWidget::slotRemoveFolder()
1191 {
1192  TQString str;
1193  TQDir dir;
1194 
1195  if ( !mFolder ) return;
1196  if ( mFolder->isSystemFolder() ) return;
1197  if ( mFolder->isReadOnly() ) return;
1198  if ( mFolder->mailCheckInProgress() ) {
1199  KMessageBox::sorry( this, i18n( "It is not possible to delete this folder right now because it "
1200  "is being syncronized. Please wait until the syncronization of "
1201  "this folder is complete and then try again." ),
1202  i18n( "Unable to delete folder" ) );
1203  return;
1204  }
1205 
1206  TQString title;
1207  if ( mFolder->folderType() == KMFolderTypeSearch ) {
1208  title = i18n("Delete Search");
1209  str = i18n("<qt>Are you sure you want to delete the search <b>%1</b>?<br>"
1210  "Any messages it shows will still be available in their original folder.</qt>")
1211  .arg( TQStyleSheet::escape( mFolder->label() ) );
1212  } else {
1213  title = i18n("Delete Folder");
1214  if ( mFolder->count() == 0 ) {
1215  if ( !mFolder->child() || mFolder->child()->isEmpty() ) {
1216  str = i18n("<qt>Are you sure you want to delete the empty folder "
1217  "<b>%1</b>?</qt>")
1218  .arg( TQStyleSheet::escape( mFolder->label() ) );
1219  }
1220  else {
1221  str = i18n("<qt>Are you sure you want to delete the empty folder "
1222  "<b>%1</b> and all its subfolders? Those subfolders might "
1223  "not be empty and their contents will be discarded as well. "
1224  "<p><b>Beware</b> that discarded messages are not saved "
1225  "into your Trash folder and are permanently deleted.</qt>")
1226  .arg( TQStyleSheet::escape( mFolder->label() ) );
1227  }
1228  } else {
1229  if ( !mFolder->child() || mFolder->child()->isEmpty() ) {
1230  str = i18n("<qt>Are you sure you want to delete the folder "
1231  "<b>%1</b>, discarding its contents? "
1232  "<p><b>Beware</b> that discarded messages are not saved "
1233  "into your Trash folder and are permanently deleted.</qt>")
1234  .arg( TQStyleSheet::escape( mFolder->label() ) );
1235  }
1236  else {
1237  str = i18n("<qt>Are you sure you want to delete the folder <b>%1</b> "
1238  "and all its subfolders, discarding their contents? "
1239  "<p><b>Beware</b> that discarded messages are not saved "
1240  "into your Trash folder and are permanently deleted.</qt>")
1241  .arg( TQStyleSheet::escape( mFolder->label() ) );
1242  }
1243  }
1244  }
1245 
1246  if (KMessageBox::warningContinueCancel(this, str, title,
1247  KGuiItem( i18n("&Delete"), "edit-delete"))
1248  == KMessageBox::Continue)
1249  {
1250  KMail::FolderUtil::deleteFolder( mFolder, this );
1251  }
1252 }
1253 
1254 //-----------------------------------------------------------------------------
1255 void KMMainWidget::slotMarkAllAsRead()
1256 {
1257  if (!mFolder)
1258  return;
1259  mFolder->markUnreadAsRead();
1260 }
1261 
1262 //-----------------------------------------------------------------------------
1263 void KMMainWidget::slotCompactFolder()
1264 {
1265  if (mFolder) {
1266  int idx = mHeaders->currentItemIndex();
1267  KCursorSaver busy(KBusyPtr::busy());
1268  mFolder->compact( KMFolder::CompactNow );
1269  // setCurrentItemByIndex will override the statusbar message, so save/restore it
1270  TQString statusMsg = BroadcastStatus::instance()->statusMsg();
1271  mHeaders->setCurrentItemByIndex(idx);
1272  BroadcastStatus::instance()->setStatusMsg( statusMsg );
1273  }
1274 }
1275 
1276 
1277 //-----------------------------------------------------------------------------
1278 void KMMainWidget::slotRefreshFolder()
1279 {
1280  if (mFolder)
1281  {
1282  if ( mFolder->folderType() == KMFolderTypeImap || mFolder->folderType() == KMFolderTypeCachedImap ) {
1283  if ( !kmkernel->askToGoOnline() ) {
1284  return;
1285  }
1286  }
1287 
1288  if (mFolder->folderType() == KMFolderTypeImap)
1289  {
1290  KMFolderImap *imap = static_cast<KMFolderImap*>(mFolder->storage());
1291  imap->getAndCheckFolder();
1292  } else if ( mFolder->folderType() == KMFolderTypeCachedImap ) {
1293  KMFolderCachedImap* f = static_cast<KMFolderCachedImap*>( mFolder->storage() );
1294  f->account()->processNewMailInFolder( mFolder );
1295  }
1296  }
1297 }
1298 
1299 void KMMainWidget::slotTroubleshootFolder()
1300 {
1301  if (mFolder)
1302  {
1303  if ( mFolder->folderType() == KMFolderTypeCachedImap ) {
1304  KMFolderCachedImap* f = static_cast<KMFolderCachedImap*>( mFolder->storage() );
1305  f->slotTroubleshoot();
1306  }
1307  }
1308 }
1309 
1310 void KMMainWidget::slotInvalidateIMAPFolders() {
1311  if ( KMessageBox::warningContinueCancel( this,
1312  i18n("Are you sure you want to refresh the IMAP cache?\n"
1313  "This will remove all changes that you have done "
1314  "locally to your IMAP folders."),
1315  i18n("Refresh IMAP Cache"), i18n("&Refresh") ) == KMessageBox::Continue )
1316  kmkernel->acctMgr()->invalidateIMAPFolders();
1317 }
1318 
1319 //-----------------------------------------------------------------------------
1320 void KMMainWidget::slotExpireAll() {
1321  TDEConfig *config = KMKernel::config();
1322  int ret = 0;
1323 
1324  TDEConfigGroupSaver saver(config, "General");
1325 
1326  if (config->readBoolEntry("warn-before-expire", true)) {
1327  ret = KMessageBox::warningContinueCancel(TDEMainWindow::memberList->first(),
1328  i18n("Are you sure you want to expire all old messages?"),
1329  i18n("Expire Old Messages?"), i18n("Expire"));
1330  if (ret != KMessageBox::Continue) {
1331  return;
1332  }
1333  }
1334 
1335  kmkernel->expireAllFoldersNow();
1336 }
1337 
1338 //-----------------------------------------------------------------------------
1339 void KMMainWidget::slotCompactAll()
1340 {
1341  KCursorSaver busy(KBusyPtr::busy());
1342  kmkernel->compactAllFolders();
1343 }
1344 
1345 
1346 //-----------------------------------------------------------------------------
1347 void KMMainWidget::slotOverrideHtml()
1348 {
1349  if( mHtmlPref == mFolderHtmlPref ) {
1350  int result = KMessageBox::warningContinueCancel( this,
1351  // the warning text is taken from configuredialog.cpp:
1352  i18n( "Use of HTML in mail will make you more vulnerable to "
1353  "\"spam\" and may increase the likelihood that your system will be "
1354  "compromised by other present and anticipated security exploits." ),
1355  i18n( "Security Warning" ),
1356  i18n( "Use HTML" ),
1357  "OverrideHtmlWarning", false);
1358  if( result == KMessageBox::Cancel ) {
1359  mPreferHtmlAction->setChecked( false );
1360  return;
1361  }
1362  }
1363  mFolderHtmlPref = !mFolderHtmlPref;
1364  if (mMsgView) {
1365  mMsgView->setHtmlOverride(mFolderHtmlPref);
1366  mMsgView->update( true );
1367  }
1368 }
1369 
1370 //-----------------------------------------------------------------------------
1371 void KMMainWidget::slotOverrideHtmlLoadExt()
1372 {
1373  if( mHtmlLoadExtPref == mFolderHtmlLoadExtPref ) {
1374  int result = KMessageBox::warningContinueCancel( this,
1375  // the warning text is taken from configuredialog.cpp:
1376  i18n( "Loading external references in html mail will make you more vulnerable to "
1377  "\"spam\" and may increase the likelihood that your system will be "
1378  "compromised by other present and anticipated security exploits." ),
1379  i18n( "Security Warning" ),
1380  i18n( "Load External References" ),
1381  "OverrideHtmlLoadExtWarning", false);
1382  if( result == KMessageBox::Cancel ) {
1383  mPreferHtmlLoadExtAction->setChecked( false );
1384  return;
1385  }
1386  }
1387  mFolderHtmlLoadExtPref = !mFolderHtmlLoadExtPref;
1388  if (mMsgView) {
1389  mMsgView->setHtmlLoadExtOverride(mFolderHtmlLoadExtPref);
1390  mMsgView->update( true );
1391  }
1392 }
1393 
1394 //-----------------------------------------------------------------------------
1395 void KMMainWidget::slotOverrideThread()
1396 {
1397  mFolderThreadPref = !mFolderThreadPref;
1398  mHeaders->setNestedOverride(mFolderThreadPref);
1399  mThreadBySubjectAction->setEnabled(mThreadMessagesAction->isChecked());
1400 }
1401 
1402 //-----------------------------------------------------------------------------
1403 void KMMainWidget::slotToggleSubjectThreading()
1404 {
1405  mFolderThreadSubjPref = !mFolderThreadSubjPref;
1406  mHeaders->setSubjectThreading(mFolderThreadSubjPref);
1407 }
1408 
1409 //-----------------------------------------------------------------------------
1410 void KMMainWidget::slotToggleShowQuickSearch()
1411 {
1412  GlobalSettings::self()->setQuickSearchActive( !GlobalSettings::self()->quickSearchActive() );
1413  if ( GlobalSettings::self()->quickSearchActive() )
1414  mSearchToolBar->show();
1415  else {
1416  mQuickSearchLine->reset();
1417  mSearchToolBar->hide();
1418  }
1419 }
1420 
1421 //-----------------------------------------------------------------------------
1422 void KMMainWidget::slotMessageQueuedOrDrafted()
1423 {
1424  if (!kmkernel->folderIsDraftOrOutbox(mFolder))
1425  return;
1426  if (mMsgView)
1427  mMsgView->update(true);
1428 }
1429 
1430 
1431 //-----------------------------------------------------------------------------
1432 void KMMainWidget::slotForwardInlineMsg()
1433 {
1434  KMMessageList* selected = mHeaders->selectedMsgs();
1435  KMCommand *command = 0L;
1436  if(selected && !selected->isEmpty()) {
1437  command = new KMForwardInlineCommand( this, *selected,
1438  mFolder->identity() );
1439  } else {
1440  command = new KMForwardInlineCommand( this, mHeaders->currentMsg(),
1441  mFolder->identity() );
1442  }
1443 
1444  command->start();
1445 }
1446 
1447 
1448 //-----------------------------------------------------------------------------
1449 void KMMainWidget::slotForwardAttachedMsg()
1450 {
1451  KMMessageList* selected = mHeaders->selectedMsgs();
1452  KMCommand *command = 0L;
1453  if(selected && !selected->isEmpty()) {
1454  command = new KMForwardAttachedCommand( this, *selected, mFolder->identity() );
1455  } else {
1456  command = new KMForwardAttachedCommand( this, mHeaders->currentMsg(), mFolder->identity() );
1457  }
1458 
1459  command->start();
1460 }
1461 
1462 //-----------------------------------------------------------------------------
1463 void KMMainWidget::slotForwardDigestMsg()
1464 {
1465  KMMessageList* selected = mHeaders->selectedMsgs();
1466  KMCommand *command = 0L;
1467  if(selected && !selected->isEmpty()) {
1468  command = new KMForwardDigestCommand( this, *selected, mFolder->identity() );
1469  } else {
1470  command = new KMForwardDigestCommand( this, mHeaders->currentMsg(), mFolder->identity() );
1471  }
1472 
1473  command->start();
1474 }
1475 
1476 //-----------------------------------------------------------------------------
1477 void KMMainWidget::slotUseTemplate()
1478 {
1479  newFromTemplate( mHeaders->currentMsg() );
1480 }
1481 
1482 //-----------------------------------------------------------------------------
1483 void KMMainWidget::slotResendMsg()
1484 {
1485  KMCommand *command = new KMResendMessageCommand( this, mHeaders->currentMsg() );
1486  command->start();
1487 }
1488 
1489 
1490 //-----------------------------------------------------------------------------
1491 void KMMainWidget::slotTrashMsg()
1492 {
1493  mHeaders->deleteMsg();
1494 }
1495 
1496 //-----------------------------------------------------------------------------
1497 void KMMainWidget::slotDeleteMsg( bool confirmDelete )
1498 {
1499  mHeaders->moveMsgToFolder( 0, confirmDelete );
1500 }
1501 
1502 //-----------------------------------------------------------------------------
1503 void KMMainWidget::slotTrashThread()
1504 {
1505  mHeaders->highlightCurrentThread();
1506  mHeaders->deleteMsg();
1507 }
1508 
1509 //-----------------------------------------------------------------------------
1510 void KMMainWidget::slotDeleteThread( bool confirmDelete )
1511 {
1512  mHeaders->highlightCurrentThread();
1513  mHeaders->moveMsgToFolder( 0, confirmDelete );
1514 }
1515 
1516 //-----------------------------------------------------------------------------
1517 void KMMainWidget::slotRedirectMsg()
1518 {
1519  KMCommand *command = new KMRedirectCommand( this, mHeaders->currentMsg() );
1520  command->start();
1521 }
1522 
1523 
1524 //-----------------------------------------------------------------------------
1525 void KMMainWidget::slotCustomReplyToMsg( int tid )
1526 {
1527  TQString text = mMsgView? mMsgView->copyText() : "";
1528  TQString tmpl = mCustomTemplates[ tid ];
1529  kdDebug() << "Reply with template: " << tmpl << " (" << tid << ")" << endl;
1530  KMCommand *command = new KMCustomReplyToCommand( this,
1531  mHeaders->currentMsg(),
1532  text,
1533  tmpl );
1534  command->start();
1535 }
1536 
1537 
1538 //-----------------------------------------------------------------------------
1539 void KMMainWidget::slotCustomReplyAllToMsg( int tid )
1540 {
1541  TQString text = mMsgView? mMsgView->copyText() : "";
1542  TQString tmpl = mCustomTemplates[ tid ];
1543  kdDebug() << "Reply to All with template: " << tmpl << " (" << tid << ")" << endl;
1544  KMCommand *command = new KMCustomReplyAllToCommand( this,
1545  mHeaders->currentMsg(),
1546  text,
1547  tmpl );
1548  command->start();
1549 }
1550 
1551 
1552 //-----------------------------------------------------------------------------
1553 void KMMainWidget::slotCustomForwardMsg( int tid )
1554 {
1555  TQString tmpl = mCustomTemplates[ tid ];
1556  kdDebug() << "Forward with template: " << tmpl << " (" << tid << ")" << endl;
1557  KMMessageList* selected = mHeaders->selectedMsgs();
1558  KMCommand *command = 0L;
1559  if(selected && !selected->isEmpty()) {
1560  command = new KMCustomForwardCommand( this, *selected,
1561  mFolder->identity(), tmpl );
1562  } else {
1563  command = new KMCustomForwardCommand( this, mHeaders->currentMsg(),
1564  mFolder->identity(), tmpl );
1565  }
1566  command->start();
1567 }
1568 
1569 
1570 //-----------------------------------------------------------------------------
1571 void KMMainWidget::slotNoQuoteReplyToMsg()
1572 {
1573  KMCommand *command = new KMNoQuoteReplyToCommand( this, mHeaders->currentMsg() );
1574  command->start();
1575 }
1576 
1577 //-----------------------------------------------------------------------------
1578 void KMMainWidget::slotSubjectFilter()
1579 {
1580  KMMessage *msg = mHeaders->currentMsg();
1581  if (!msg)
1582  return;
1583 
1584  KMCommand *command = new KMFilterCommand( "Subject", msg->subject() );
1585  command->start();
1586 }
1587 
1588 //-----------------------------------------------------------------------------
1589 void KMMainWidget::slotMailingListFilter()
1590 {
1591  KMMessage *msg = mHeaders->currentMsg();
1592  if (!msg)
1593  return;
1594 
1595  KMCommand *command = new KMMailingListFilterCommand( this, msg );
1596  command->start();
1597 }
1598 
1599 //-----------------------------------------------------------------------------
1600 void KMMainWidget::slotFromFilter()
1601 {
1602  KMMessage *msg = mHeaders->currentMsg();
1603  if (!msg)
1604  return;
1605 
1606  AddrSpecList al = msg->extractAddrSpecs( "From" );
1607  KMCommand *command;
1608  if ( al.empty() )
1609  command = new KMFilterCommand( "From", msg->from() );
1610  else
1611  command = new KMFilterCommand( "From", al.front().asString() );
1612  command->start();
1613 }
1614 
1615 //-----------------------------------------------------------------------------
1616 void KMMainWidget::slotToFilter()
1617 {
1618  KMMessage *msg = mHeaders->currentMsg();
1619  if (!msg)
1620  return;
1621 
1622  KMCommand *command = new KMFilterCommand( "To", msg->to() );
1623  command->start();
1624 }
1625 
1626 //-----------------------------------------------------------------------------
1627 void KMMainWidget::updateListFilterAction()
1628 {
1629  //Proxy the mListFilterAction to update the action text
1630  TQCString name;
1631  TQString value;
1632  TQString lname = MailingList::name( mHeaders->currentMsg(), name, value );
1633  mListFilterAction->setText( i18n("Filter on Mailing-List...") );
1634  if ( lname.isNull() )
1635  mListFilterAction->setEnabled( false );
1636  else {
1637  mListFilterAction->setEnabled( true );
1638  mListFilterAction->setText( i18n( "Filter on Mailing-List %1..." ).arg( lname ) );
1639  }
1640 }
1641 
1642 
1643 //-----------------------------------------------------------------------------
1644 void KMMainWidget::slotUndo()
1645 {
1646  mHeaders->undo();
1647  updateMessageActions();
1648  updateFolderMenu();
1649 }
1650 
1651 //-----------------------------------------------------------------------------
1652 void KMMainWidget::slotToggleUnread()
1653 {
1654  mFolderTree->toggleColumn(KMFolderTree::unread);
1655 }
1656 
1657 //-----------------------------------------------------------------------------
1658 void KMMainWidget::slotToggleTotalColumn()
1659 {
1660  mFolderTree->toggleColumn(KMFolderTree::total, true);
1661 }
1662 
1663 //-----------------------------------------------------------------------------
1664 void KMMainWidget::slotToggleSizeColumn()
1665 {
1666  mFolderTree->toggleColumn(KMFolderTree::foldersize);
1667 }
1668 
1669 
1670 //-----------------------------------------------------------------------------
1671 void KMMainWidget::slotJumpToFolder()
1672 {
1673  KMail::KMFolderSelDlg dlg( this, i18n("Jump to Folder"), true );
1674  KMFolder* dest;
1675 
1676  if (!dlg.exec()) return;
1677  if (!(dest = dlg.folder())) return;
1678 
1679  slotSelectFolder( dest );
1680 }
1681 
1682 //-----------------------------------------------------------------------------
1683 void KMMainWidget::slotMoveMsg()
1684 {
1685  KMail::KMFolderSelDlg dlg( this, i18n("Move Message to Folder"), true );
1686  KMFolder* dest;
1687 
1688  if (!dlg.exec()) return;
1689  if (!(dest = dlg.folder())) return;
1690 
1691  mHeaders->moveMsgToFolder(dest);
1692 }
1693 
1694 //-----------------------------------------------------------------------------
1695 void KMMainWidget::slotMoveMsgToFolder( KMFolder *dest)
1696 {
1697  mHeaders->moveMsgToFolder(dest);
1698 }
1699 
1700 //-----------------------------------------------------------------------------
1701 void KMMainWidget::slotCopyMsgToFolder( KMFolder *dest)
1702 {
1703  mHeaders->copyMsgToFolder(dest);
1704 }
1705 
1706 //-----------------------------------------------------------------------------
1707 void KMMainWidget::slotApplyFilters()
1708 {
1709  mHeaders->applyFiltersOnMsg();
1710 }
1711 
1712 //-----------------------------------------------------------------------------
1713 void KMMainWidget::slotCheckVacation()
1714 {
1715  updateVactionScripStatus( false );
1716  if ( !kmkernel->askToGoOnline() )
1717  return;
1718 
1719  Vacation *vac = new Vacation( TQT_TQOBJECT(this), true /* check only */ );
1720  connect( vac, TQT_SIGNAL(scriptActive(bool)), TQT_SLOT(updateVactionScripStatus(bool)) );
1721 }
1722 
1723 void KMMainWidget::slotEditVacation()
1724 {
1725  if ( !kmkernel->askToGoOnline() ) {
1726  return;
1727  }
1728 
1729  if ( mVacation )
1730  return;
1731 
1732  mVacation = new Vacation( TQT_TQOBJECT(this) );
1733  connect( mVacation, TQT_SIGNAL(scriptActive(bool)), TQT_SLOT(updateVactionScripStatus(bool)) );
1734  if ( mVacation->isUsable() ) {
1735  connect( mVacation, TQT_SIGNAL(result(bool)), mVacation, TQT_SLOT(deleteLater()) );
1736  } else {
1737  TQString msg = i18n("KMail's Out of Office Reply functionality relies on "
1738  "server-side filtering. You have not yet configured an "
1739  "IMAP server for this.\n"
1740  "You can do this on the \"Filtering\" tab of the IMAP "
1741  "account configuration.");
1742  KMessageBox::sorry( this, msg, i18n("No Server-Side Filtering Configured") );
1743 
1744  delete mVacation; // TQGuardedPtr sets itself to 0!
1745  }
1746 }
1747 
1748 //-----------------------------------------------------------------------------
1749 void KMMainWidget::slotDebugSieve()
1750 {
1751 #if !defined(NDEBUG)
1752  if ( mSieveDebugDialog )
1753  return;
1754 
1755  mSieveDebugDialog = new SieveDebugDialog( this );
1756  mSieveDebugDialog->exec();
1757  delete mSieveDebugDialog;
1758 #endif
1759 }
1760 
1761 //-----------------------------------------------------------------------------
1762 void KMMainWidget::slotStartCertManager()
1763 {
1764  TDEProcess certManagerProc; // save to create on the heap, since
1765  // there is no parent
1766  certManagerProc << "kleopatra";
1767 
1768  if( !certManagerProc.start( TDEProcess::DontCare ) )
1769  KMessageBox::error( this, i18n( "Could not start certificate manager 'kleopatra'; "
1770  "please check your installation." ),
1771  i18n( "KMail Error" ) );
1772  else
1773  kdDebug(5006) << "\nslotStartCertManager(): certificate manager started.\n" << endl;
1774  // process continues to run even after the TDEProcess object goes
1775  // out of scope here, since it is started in DontCare run mode.
1776 
1777 }
1778 
1779 //-----------------------------------------------------------------------------
1780 void KMMainWidget::slotStartWatchGnuPG()
1781 {
1782  TDEProcess certManagerProc;
1783  certManagerProc << "kwatchgnupg";
1784 
1785  if( !certManagerProc.start( TDEProcess::DontCare ) )
1786  KMessageBox::error( this, i18n( "Could not start GnuPG LogViewer (kwatchgnupg); "
1787  "please check your installation." ),
1788  i18n( "KMail Error" ) );
1789 }
1790 
1791 //-----------------------------------------------------------------------------
1792 void KMMainWidget::slotCopyMsg()
1793 {
1794  KMail::KMFolderSelDlg dlg( this, i18n("Copy Message to Folder"), true );
1795  KMFolder* dest;
1796 
1797  if (!dlg.exec()) return;
1798  if (!(dest = dlg.folder())) return;
1799 
1800  mHeaders->copyMsgToFolder(dest);
1801 }
1802 
1803 //-----------------------------------------------------------------------------
1804 void KMMainWidget::slotPrintMsg()
1805 {
1806  KMMessage *msg = mHeaders->currentMsg();
1807  if ( !msg ) {
1808  return;
1809  }
1810 
1811  bool htmlOverride = mMsgView ? mMsgView->htmlOverride() : false;
1812  bool htmlLoadExtOverride = mMsgView ? mMsgView->htmlLoadExtOverride() : false;
1813  TDEConfigGroup reader( KMKernel::config(), "Reader" );
1814  bool useFixedFont = mMsgView ? mMsgView->isFixedFont()
1815  : reader.readBoolEntry( "useFixedFont", false );
1816 
1817  const HeaderStyle *style;
1818  const HeaderStrategy *strategy;
1819  if ( mMsgView ) {
1820  style = mMsgView->headerStyle();
1821  strategy = mMsgView->headerStrategy();
1822  } else {
1823  style = HeaderStyle::create( reader.readEntry( "header-style", "fancy" ) );
1824  strategy = HeaderStrategy::create( reader.readEntry( "header-set-displayed", "rich" ) );
1825  }
1826 
1827  KMPrintCommand *command =
1828  new KMPrintCommand( this, msg,
1829  style, strategy,
1830  htmlOverride, htmlLoadExtOverride,
1831  useFixedFont, overrideEncoding() );
1832  if ( mMsgView )
1833  command->setOverrideFont( mMsgView->cssHelper()->bodyFont( mMsgView->isFixedFont(), true /*printing*/ ) );
1834 
1835  command->start();
1836 }
1837 
1838 //-----------------------------------------------------------------------------
1839 void KMMainWidget::setupForwardActions()
1840 {
1841  disconnect( mForwardActionMenu, TQT_SIGNAL( activated() ), 0, 0 );
1842  mForwardActionMenu->remove( mForwardInlineAction );
1843  mForwardActionMenu->remove( mForwardAttachedAction );
1844 
1845  if ( GlobalSettings::self()->forwardingInlineByDefault() ) {
1846  mForwardActionMenu->insert( mForwardInlineAction, 0 );
1847  mForwardActionMenu->insert( mForwardAttachedAction, 1 );
1848  mForwardInlineAction->setShortcut( Key_F );
1849  mForwardAttachedAction->setShortcut( SHIFT+Key_F );
1850  connect( mForwardActionMenu, TQT_SIGNAL(activated()), TQT_TQOBJECT(this),
1851  TQT_SLOT(slotForwardInlineMsg()) );
1852 
1853  } else {
1854  mForwardActionMenu->insert( mForwardAttachedAction, 0 );
1855  mForwardActionMenu->insert( mForwardInlineAction, 1 );
1856  mForwardInlineAction->setShortcut( SHIFT+Key_F );
1857  mForwardAttachedAction->setShortcut( Key_F );
1858  connect( mForwardActionMenu, TQT_SIGNAL(activated()), TQT_TQOBJECT(this),
1859  TQT_SLOT(slotForwardAttachedMsg()) );
1860  }
1861 }
1862 
1863 //-----------------------------------------------------------------------------
1864 void KMMainWidget::slotConfigChanged()
1865 {
1866  readConfig();
1867  setupForwardActions();
1868  setupForwardingActionsList();
1869 }
1870 
1871 //-----------------------------------------------------------------------------
1872 void KMMainWidget::slotSaveMsg()
1873 {
1874  KMMessage *msg = mHeaders->currentMsg();
1875  if (!msg)
1876  return;
1877  KMSaveMsgCommand *saveCommand = new KMSaveMsgCommand( this,
1878  *mHeaders->selectedMsgs() );
1879 
1880  if (saveCommand->url().isEmpty())
1881  delete saveCommand;
1882  else
1883  saveCommand->start();
1884 }
1885 
1886 //-----------------------------------------------------------------------------
1887 void KMMainWidget::slotOpenMsg()
1888 {
1889  KMOpenMsgCommand *openCommand = new KMOpenMsgCommand( this, 0, overrideEncoding() );
1890 
1891  openCommand->start();
1892 }
1893 
1894 //-----------------------------------------------------------------------------
1895 void KMMainWidget::slotSaveAttachments()
1896 {
1897  KMMessage *msg = mHeaders->currentMsg();
1898  if (!msg)
1899  return;
1900  KMSaveAttachmentsCommand *saveCommand = new KMSaveAttachmentsCommand( this,
1901  *mHeaders->selectedMsgs() );
1902  saveCommand->start();
1903 }
1904 
1905 void KMMainWidget::slotOnlineStatus()
1906 {
1907  // KMKernel will emit a signal when we toggle the network state that is caught by
1908  // KMMainWidget::slotUpdateOnlineStatus to update our GUI
1909  if ( GlobalSettings::self()->networkState() == GlobalSettings::EnumNetworkState::Online ) {
1910  // if online; then toggle and set it offline.
1911  kmkernel->stopNetworkJobs();
1912  } else {
1913  kmkernel->resumeNetworkJobs();
1914  slotCheckVacation();
1915  }
1916 }
1917 
1918 void KMMainWidget::slotUpdateOnlineStatus( GlobalSettings::EnumNetworkState::type )
1919 {
1920  if ( GlobalSettings::self()->networkState() == GlobalSettings::EnumNetworkState::Online )
1921  actionCollection()->action( "online_status" )->setText( i18n("Work Offline") );
1922  else
1923  actionCollection()->action( "online_status" )->setText( i18n("Work Online") );
1924 }
1925 
1926 
1927 //-----------------------------------------------------------------------------
1928 void KMMainWidget::slotSendQueued()
1929 {
1930  if ( !kmkernel->askToGoOnline() ) {
1931  return;
1932  }
1933 
1934  kmkernel->msgSender()->sendQueued();
1935 }
1936 
1937 //-----------------------------------------------------------------------------
1938 void KMMainWidget::slotSendQueuedVia( int item )
1939 {
1940  if ( !kmkernel->askToGoOnline() ) {
1941  return;
1942  }
1943 
1944  TQStringList availTransports= KMail::TransportManager::transportNames();
1945  TQString customTransport = availTransports[ item ];
1946 
1947  kmkernel->msgSender()->sendQueued( customTransport );
1948 }
1949 
1950 //-----------------------------------------------------------------------------
1951 void KMMainWidget::slotViewChange()
1952 {
1953  if(mBodyPartsMenu->isItemChecked(mBodyPartsMenu->idAt(0)))
1954  {
1955  mBodyPartsMenu->setItemChecked(mBodyPartsMenu->idAt(0),false);
1956  mBodyPartsMenu->setItemChecked(mBodyPartsMenu->idAt(1),true);
1957  }
1958  else if(mBodyPartsMenu->isItemChecked(mBodyPartsMenu->idAt(1)))
1959  {
1960  mBodyPartsMenu->setItemChecked(mBodyPartsMenu->idAt(1),false);
1961  mBodyPartsMenu->setItemChecked(mBodyPartsMenu->idAt(0),true);
1962  }
1963 
1964  //mMsgView->setInline(!mMsgView->isInline());
1965 }
1966 
1967 
1968 //-----------------------------------------------------------------------------
1969 void KMMainWidget::folderSelectedUnread( KMFolder* aFolder )
1970 {
1971  folderSelected( aFolder, true );
1972  slotChangeCaption( mFolderTree->currentItem() );
1973 }
1974 
1975 //-----------------------------------------------------------------------------
1976 void KMMainWidget::folderSelected()
1977 {
1978  folderSelected( mFolder );
1979  updateFolderMenu();
1980  // opened() before the getAndCheckFolder() in folderSelected
1981  if ( mFolder && mFolder->folderType() == KMFolderTypeImap )
1982  mFolder->close("mainwidget");
1983 }
1984 
1985 //-----------------------------------------------------------------------------
1986 void KMMainWidget::folderSelected( KMFolder* aFolder, bool forceJumpToUnread )
1987 {
1988  KCursorSaver busy(KBusyPtr::busy());
1989 
1990  if (mMsgView)
1991  mMsgView->clear(true);
1992 
1993  if ( mFolder && mFolder->folderType() == KMFolderTypeImap && !mFolder->noContent() )
1994  {
1995  KMFolderImap *imap = static_cast<KMFolderImap*>(mFolder->storage());
1996  if ( mFolder->needsCompacting() && imap->autoExpunge() )
1997  imap->expungeFolder(imap, true);
1998  }
1999 
2000  // Re-enable the msg list and quicksearch if we're showing a splash
2001  // screen. This is true either if there's no active folder, or if we
2002  // have a timer that is no longer active (i.e. it has already fired)
2003  // To make the if() a bit more complicated, we suppress the hiding
2004  // when the new folder is also an IMAP folder, because that's an
2005  // async operation and we don't want flicker if it results in just
2006  // a new splash.
2007  bool newFolder = ( (KMFolder*)mFolder != aFolder );
2008  bool isNewImapFolder = aFolder && aFolder->folderType() == KMFolderTypeImap && newFolder;
2009  if( !mFolder
2010  || ( !isNewImapFolder && mShowBusySplashTimer )
2011  || ( newFolder && mShowingOfflineScreen && !( isNewImapFolder && kmkernel->isOffline() ) ) ) {
2012  if ( mMsgView ) {
2013  mMsgView->enableMsgDisplay();
2014  mMsgView->clear( true );
2015  }
2016  if( mSearchAndHeaders && mHeaders )
2017  mSearchAndHeaders->show();
2018  mShowingOfflineScreen = false;
2019  }
2020 
2021  // Delete any pending timer, if needed it will be recreated below
2022  delete mShowBusySplashTimer;
2023  mShowBusySplashTimer = 0;
2024 
2025  if ( newFolder )
2026  writeFolderConfig();
2027  if ( mFolder ) {
2028  disconnect( mFolder, TQT_SIGNAL( changed() ),
2029  this, TQT_SLOT( updateMarkAsReadAction() ) );
2030  disconnect( mFolder, TQT_SIGNAL( msgHeaderChanged( KMFolder*, int ) ),
2031  this, TQT_SLOT( updateMarkAsReadAction() ) );
2032  disconnect( mFolder, TQT_SIGNAL( msgAdded( int ) ),
2033  this, TQT_SLOT( updateMarkAsReadAction() ) );
2034  disconnect( mFolder, TQT_SIGNAL( msgRemoved( KMFolder * ) ),
2035  this, TQT_SLOT( updateMarkAsReadAction() ) );
2036  }
2037 
2038  mFolder = aFolder;
2039 
2040  if ( aFolder && aFolder->folderType() == KMFolderTypeImap )
2041  {
2042  if ( kmkernel->isOffline() ) {
2043  showOfflinePage();
2044  return;
2045  }
2046  KMFolderImap *imap = static_cast<KMFolderImap*>(aFolder->storage());
2047  if ( newFolder && !mFolder->noContent() )
2048  {
2049  imap->open("mainwidget"); // will be closed in the folderSelected slot
2050  // first get new headers before we select the folder
2051  imap->setSelected( true );
2052  connect( imap, TQT_SIGNAL( folderComplete( KMFolderImap*, bool ) ),
2053  this, TQT_SLOT( folderSelected() ) );
2054  imap->getAndCheckFolder();
2055  mHeaders->setFolder( 0 );
2056  updateFolderMenu();
2057  mForceJumpToUnread = forceJumpToUnread;
2058 
2059  // Set a timer to show a splash screen if fetching folder contents
2060  // takes more than the amount of seconds configured in the kmailrc (default 1000 msec)
2061  mShowBusySplashTimer = new TQTimer( this );
2062  connect( mShowBusySplashTimer, TQT_SIGNAL( timeout() ), TQT_TQOBJECT(this), TQT_SLOT( slotShowBusySplash() ) );
2063  mShowBusySplashTimer->start( GlobalSettings::self()->folderLoadingTimeout(), true );
2064  return;
2065  } else {
2066  // the folder is complete now - so go ahead
2067  disconnect( imap, TQT_SIGNAL( folderComplete( KMFolderImap*, bool ) ),
2068  this, TQT_SLOT( folderSelected() ) );
2069  forceJumpToUnread = mForceJumpToUnread;
2070  }
2071  }
2072 
2073  if ( mFolder ) { // == 0 -> pointing to toplevel ("Welcome to KMail") folder
2074  connect( mFolder, TQT_SIGNAL( changed() ),
2075  this, TQT_SLOT( updateMarkAsReadAction() ) );
2076  connect( mFolder, TQT_SIGNAL( msgHeaderChanged( KMFolder*, int ) ),
2077  this, TQT_SLOT( updateMarkAsReadAction() ) );
2078  connect( mFolder, TQT_SIGNAL( msgAdded( int ) ),
2079  this, TQT_SLOT( updateMarkAsReadAction() ) );
2080  connect( mFolder, TQT_SIGNAL( msgRemoved(KMFolder *) ),
2081  this, TQT_SLOT( updateMarkAsReadAction() ) );
2082  }
2083  readFolderConfig();
2084  if (mMsgView)
2085  {
2086  mMsgView->setHtmlOverride(mFolderHtmlPref);
2087  mMsgView->setHtmlLoadExtOverride(mFolderHtmlLoadExtPref);
2088  }
2089  mHeaders->setFolder( mFolder, forceJumpToUnread );
2090  updateMessageActions();
2091  updateFolderMenu();
2092  if (!aFolder)
2093  slotIntro();
2094 }
2095 
2096 //-----------------------------------------------------------------------------
2097 void KMMainWidget::slotShowBusySplash()
2098 {
2099  if ( mReaderWindowActive )
2100  {
2101  mMsgView->displayBusyPage();
2102  // hide widgets that are in the way:
2103  if ( mSearchAndHeaders && mHeaders && mLongFolderList )
2104  mSearchAndHeaders->hide();
2105  }
2106 }
2107 
2108 void KMMainWidget::showOfflinePage()
2109 {
2110  if ( !mReaderWindowActive ) return;
2111  mShowingOfflineScreen = true;
2112 
2113  mMsgView->displayOfflinePage();
2114  // hide widgets that are in the way:
2115  if ( mSearchAndHeaders && mHeaders && mLongFolderList )
2116  mSearchAndHeaders->hide();
2117 }
2118 
2119 //-----------------------------------------------------------------------------
2120 void KMMainWidget::slotMsgSelected(KMMessage *msg)
2121 {
2122  if ( msg && msg->parent() && !msg->isComplete() )
2123  {
2124  if ( msg->transferInProgress() )
2125  return;
2126  mMsgView->clear();
2127  mMsgView->setWaitingForSerNum( msg->getMsgSerNum() );
2128 
2129  if ( mJob ) {
2130  disconnect( mJob, 0, mMsgView, 0 );
2131  delete mJob;
2132  }
2133  mJob = msg->parent()->createJob( msg, FolderJob::tGetMessage, 0,
2134  "STRUCTURE", mMsgView->attachmentStrategy() );
2135  connect(mJob, TQT_SIGNAL(messageRetrieved(KMMessage*)),
2136  mMsgView, TQT_SLOT(slotMessageArrived(KMMessage*)));
2137  mJob->start();
2138  } else {
2139  mMsgView->setMsg(msg);
2140  }
2141  // reset HTML override to the folder setting
2142  mMsgView->setHtmlOverride(mFolderHtmlPref);
2143  mMsgView->setHtmlLoadExtOverride(mFolderHtmlLoadExtPref);
2144  mMsgView->setDecryptMessageOverwrite( false );
2145  mMsgView->setShowSignatureDetails( false );
2146 }
2147 
2148 //-----------------------------------------------------------------------------
2149 void KMMainWidget::slotMsgChanged()
2150 {
2151  mHeaders->msgChanged();
2152 }
2153 
2154 //-----------------------------------------------------------------------------
2155 void KMMainWidget::slotSelectFolder(KMFolder* folder)
2156 {
2157  TQListViewItem* item = mFolderTree->indexOfFolder(folder);
2158  if ( item ) {
2159  mFolderTree->ensureItemVisible( item );
2160  mFolderTree->doFolderSelected( item );
2161  }
2162 }
2163 
2164 //-----------------------------------------------------------------------------
2165 void KMMainWidget::slotSelectMessage(KMMessage* msg)
2166 {
2167  int idx = mFolder->find(msg);
2168  if (idx != -1) {
2169  mHeaders->setCurrentMsg(idx);
2170  if (mMsgView)
2171  mMsgView->setMsg(msg);
2172  else
2173  slotMsgActivated(msg);
2174  }
2175 }
2176 
2177 //-----------------------------------------------------------------------------
2178 void KMMainWidget::slotReplaceMsgByUnencryptedVersion()
2179 {
2180  kdDebug(5006) << "KMMainWidget::slotReplaceMsgByUnencryptedVersion()" << endl;
2181  KMMessage* oldMsg = mHeaders->currentMsg();
2182  if( oldMsg ) {
2183  kdDebug(5006) << "KMMainWidget - old message found" << endl;
2184  if( oldMsg->hasUnencryptedMsg() ) {
2185  kdDebug(5006) << "KMMainWidget - extra unencrypted message found" << endl;
2186  KMMessage* newMsg = oldMsg->unencryptedMsg();
2187  // adjust the message id
2188  {
2189  TQString msgId( oldMsg->msgId() );
2190  TQString prefix("DecryptedMsg.");
2191  int oldIdx = msgId.find(prefix, 0, false);
2192  if( -1 == oldIdx ) {
2193  int leftAngle = msgId.findRev( '<' );
2194  msgId = msgId.insert( (-1 == leftAngle) ? 0 : ++leftAngle, prefix );
2195  }
2196  else {
2197  // toggle between "DecryptedMsg." and "DeCryptedMsg."
2198  // to avoid same message id
2199  TQCharRef c = msgId[ oldIdx+2 ];
2200  if( 'C' == c )
2201  c = 'c';
2202  else
2203  c = 'C';
2204  }
2205  newMsg->setMsgId( msgId );
2206  mMsgView->setIdOfLastViewedMessage( msgId );
2207  }
2208  // insert the unencrypted message
2209  kdDebug(5006) << "KMMainWidget - adding unencrypted message to folder" << endl;
2210  mFolder->addMsg( newMsg );
2211  /* Figure out its index in the folder for selecting. This must be count()-1,
2212  * since we append. Be safe and do find, though, just in case. */
2213  int newMsgIdx = mFolder->find( newMsg );
2214  Q_ASSERT( newMsgIdx != -1 );
2215  /* we need this unget, to have the message displayed correctly initially */
2216  mFolder->unGetMsg( newMsgIdx );
2217  int idx = mFolder->find( oldMsg );
2218  Q_ASSERT( idx != -1 );
2219  /* only select here, so the old one is not un-Gotten before, which would
2220  * render the pointer we hold invalid so that find would fail */
2221  mHeaders->setCurrentItemByIndex( newMsgIdx );
2222  // remove the old one
2223  if ( idx != -1 ) {
2224  kdDebug(5006) << "KMMainWidget - deleting encrypted message" << endl;
2225  mFolder->take( idx );
2226  }
2227 
2228  kdDebug(5006) << "KMMainWidget - updating message actions" << endl;
2229  updateMessageActions();
2230 
2231  kdDebug(5006) << "KMMainWidget - done." << endl;
2232  } else
2233  kdDebug(5006) << "KMMainWidget - NO EXTRA UNENCRYPTED MESSAGE FOUND" << endl;
2234  } else
2235  kdDebug(5006) << "KMMainWidget - PANIC: NO OLD MESSAGE FOUND" << endl;
2236 }
2237 
2238 //-----------------------------------------------------------------------------
2239 void KMMainWidget::slotSetThreadStatusNew()
2240 {
2241  mHeaders->setThreadStatus(KMMsgStatusNew);
2242 }
2243 
2244 //-----------------------------------------------------------------------------
2245 void KMMainWidget::slotSetThreadStatusUnread()
2246 {
2247  mHeaders->setThreadStatus(KMMsgStatusUnread);
2248 }
2249 
2250 //-----------------------------------------------------------------------------
2251 void KMMainWidget::slotSetThreadStatusFlag()
2252 {
2253  mHeaders->setThreadStatus(KMMsgStatusFlag, true);
2254 }
2255 
2256 //-----------------------------------------------------------------------------
2257 void KMMainWidget::slotSetThreadStatusRead()
2258 {
2259  mHeaders->setThreadStatus(KMMsgStatusRead);
2260 }
2261 
2262 //-----------------------------------------------------------------------------
2263 void KMMainWidget::slotSetThreadStatusTodo()
2264 {
2265  mHeaders->setThreadStatus(KMMsgStatusTodo, true);
2266 }
2267 
2268 //-----------------------------------------------------------------------------
2269 void KMMainWidget::slotSetThreadStatusWatched()
2270 {
2271  mHeaders->setThreadStatus(KMMsgStatusWatched, true);
2272  if (mWatchThreadAction->isChecked()) {
2273  mIgnoreThreadAction->setChecked(false);
2274  }
2275 }
2276 
2277 //-----------------------------------------------------------------------------
2278 void KMMainWidget::slotSetThreadStatusIgnored()
2279 {
2280  mHeaders->setThreadStatus(KMMsgStatusIgnored, true);
2281  if (mIgnoreThreadAction->isChecked()) {
2282  mWatchThreadAction->setChecked(false);
2283  }
2284 }
2285 
2286 //-----------------------------------------------------------------------------
2287 void KMMainWidget::slotNextMessage() { mHeaders->nextMessage(); }
2288 void KMMainWidget::slotNextUnreadMessage()
2289 {
2290  if ( !mHeaders->nextUnreadMessage() )
2291  if ( GlobalSettings::self()->loopOnGotoUnread() == GlobalSettings::EnumLoopOnGotoUnread::LoopInAllFolders )
2292  mFolderTree->nextUnreadFolder(true);
2293 }
2294 void KMMainWidget::slotNextImportantMessage() {
2295  //mHeaders->nextImportantMessage();
2296 }
2297 void KMMainWidget::slotPrevMessage() { mHeaders->prevMessage(); }
2298 void KMMainWidget::slotPrevUnreadMessage()
2299 {
2300  if ( !mHeaders->prevUnreadMessage() )
2301  if ( GlobalSettings::self()->loopOnGotoUnread() == GlobalSettings::EnumLoopOnGotoUnread::LoopInAllFolders )
2302  mFolderTree->prevUnreadFolder();
2303 }
2304 void KMMainWidget::slotPrevImportantMessage() {
2305  //mHeaders->prevImportantMessage();
2306 }
2307 
2308 void KMMainWidget::slotDisplayCurrentMessage()
2309 {
2310  if ( mHeaders->currentMsg() )
2311  slotMsgActivated( mHeaders->currentMsg() );
2312 }
2313 
2314 //-----------------------------------------------------------------------------
2315 void KMMainWidget::slotMsgActivated(KMMessage *msg)
2316 {
2317  if ( !msg ) return;
2318  if ( msg->parent() && !msg->isComplete() ) {
2319  FolderJob *job = msg->parent()->createJob( msg );
2320  connect( job, TQT_SIGNAL( messageRetrieved( KMMessage* ) ),
2321  TQT_SLOT( slotMsgActivated( KMMessage* ) ) );
2322  job->start();
2323  return;
2324  }
2325 
2326  if (kmkernel->folderIsDraftOrOutbox( mFolder ) ) {
2327  mMsgActions->editCurrentMessage();
2328  return;
2329  }
2330  if ( kmkernel->folderIsTemplates( mFolder ) ) {
2331  slotUseTemplate();
2332  return;
2333  }
2334 
2335  assert( msg != 0 );
2336  KMReaderMainWin *win = new KMReaderMainWin( mFolderHtmlPref, mFolderHtmlLoadExtPref );
2337  TDEConfigGroup reader( KMKernel::config(), "Reader" );
2338  bool useFixedFont = mMsgView ? mMsgView->isFixedFont()
2339  : reader.readBoolEntry( "useFixedFont", false );
2340  win->setUseFixedFont( useFixedFont );
2341  KMMessage *newMessage = new KMMessage(*msg);
2342  newMessage->setParent( msg->parent() );
2343  newMessage->setMsgSerNum( msg->getMsgSerNum() );
2344  newMessage->setReadyToShow( true );
2345  win->showMsg( overrideEncoding(), newMessage );
2346  win->show();
2347 }
2348 
2349 //-----------------------------------------------------------------------------
2350 void KMMainWidget::slotMarkAll()
2351 {
2352  mHeaders->selectAll( true );
2353 }
2354 
2355 //-----------------------------------------------------------------------------
2356 void KMMainWidget::slotMsgPopup(KMMessage&, const KURL &aUrl, const TQPoint& aPoint)
2357 {
2358  TDEPopupMenu * menu = new TDEPopupMenu;
2359  updateMessageMenu();
2360  mUrlCurrent = aUrl;
2361 
2362  bool urlMenuAdded = false;
2363 
2364  if (!aUrl.isEmpty())
2365  {
2366  if (aUrl.protocol() == "mailto")
2367  {
2368  // popup on a mailto URL
2369  mMsgView->mailToComposeAction()->plug( menu );
2370  mMsgView->mailToReplyAction()->plug( menu );
2371  mMsgView->mailToForwardAction()->plug( menu );
2372 
2373  menu->insertSeparator();
2374  mMsgView->addAddrBookAction()->plug( menu );
2375  mMsgView->openAddrBookAction()->plug( menu );
2376  mMsgView->copyURLAction()->plug( menu );
2377  mMsgView->startImChatAction()->plug( menu );
2378  // only enable if our KIMProxy is functional
2379  mMsgView->startImChatAction()->setEnabled( kmkernel->imProxy()->initialize() );
2380 
2381  } else {
2382  // popup on a not-mailto URL
2383  mMsgView->urlOpenAction()->plug( menu );
2384  mMsgView->addBookmarksAction()->plug( menu );
2385  mMsgView->urlSaveAsAction()->plug( menu );
2386  mMsgView->copyURLAction()->plug( menu );
2387  }
2388  if ( aUrl.protocol() == "im" )
2389  {
2390  // popup on an IM address
2391  // no need to check the KIMProxy is initialized, as these protocols will
2392  // only be present if it is.
2393  mMsgView->startImChatAction()->plug( menu );
2394  }
2395 
2396  urlMenuAdded=true;
2397  kdDebug( 0 ) << k_funcinfo << " URL is: " << aUrl << endl;
2398  }
2399 
2400 
2401  if(mMsgView && !mMsgView->copyText().isEmpty()) {
2402  if ( urlMenuAdded )
2403  menu->insertSeparator();
2404  mMsgActions->replyMenu()->plug(menu);
2405  menu->insertSeparator();
2406 
2407  mMsgView->copyAction()->plug( menu );
2408  mMsgView->selectAllAction()->plug( menu );
2409  } else if ( !urlMenuAdded )
2410  {
2411  // popup somewhere else (i.e., not a URL) on the message
2412 
2413  if (!mHeaders->currentMsg()) // no messages
2414  {
2415  delete menu;
2416  return;
2417  }
2418 
2419 
2420  if ( mFolder->isTemplates() ) {
2421  mUseAction->plug( menu );
2422  } else {
2423  mMsgActions->replyMenu()->plug( menu );
2424  mForwardActionMenu->plug( menu );
2425  }
2426  editAction()->plug(menu);
2427  menu->insertSeparator();
2428 
2429  mCopyActionMenu->plug( menu );
2430  mMoveActionMenu->plug( menu );
2431 
2432  menu->insertSeparator();
2433 
2434  mMsgActions->messageStatusMenu()->plug( menu );
2435  menu->insertSeparator();
2436 
2437  viewSourceAction()->plug(menu);
2438  if(mMsgView) {
2439  mMsgView->toggleFixFontAction()->plug(menu);
2440  }
2441  menu->insertSeparator();
2442  mPrintAction->plug( menu );
2443  mSaveAsAction->plug( menu );
2444  mSaveAttachmentsAction->plug( menu );
2445 
2446  menu->insertSeparator();
2447  if( mFolder->isTrash() )
2448  mDeleteAction->plug( menu );
2449  else
2450  mTrashAction->plug( menu );
2451 
2452  menu->insertSeparator();
2453  mMsgActions->createTodoAction()->plug( menu );
2454  }
2455  TDEAcceleratorManager::manage(menu);
2456  menu->exec(aPoint, 0);
2457  delete menu;
2458 }
2459 
2460 //-----------------------------------------------------------------------------
2461 void KMMainWidget::getAccountMenu()
2462 {
2463  TQStringList actList;
2464 
2465  mActMenu->clear();
2466  actList = kmkernel->acctMgr()->getAccounts();
2467  TQStringList::Iterator it;
2468  int id = 0;
2469  for(it = actList.begin(); it != actList.end() ; ++it, id++)
2470  mActMenu->insertItem((*it).replace("&", "&&"), id);
2471 }
2472 
2473 //-----------------------------------------------------------------------------
2474 void KMMainWidget::getTransportMenu()
2475 {
2476  TQStringList availTransports;
2477 
2478  mSendMenu->clear();
2479  availTransports = KMail::TransportManager::transportNames();
2480  TQStringList::Iterator it;
2481  int id = 0;
2482  for(it = availTransports.begin(); it != availTransports.end() ; ++it, id++)
2483  mSendMenu->insertItem((*it).replace("&", "&&"), id);
2484 }
2485 
2486 //-----------------------------------------------------------------------------
2487 void KMMainWidget::updateCustomTemplateMenus()
2488 {
2489  if ( !mCustomTemplateActions.isEmpty() ) {
2490  TQPtrList<TDEAction>::iterator ait = mCustomTemplateActions.begin();
2491  for ( ; ait != mCustomTemplateActions.end() ; ++ait ) {
2492  (*ait)->unplugAll();
2493  delete (*ait);
2494  }
2495  mCustomTemplateActions.clear();
2496  }
2497 
2498  delete mCustomReplyActionMenu;
2499  delete mCustomReplyAllActionMenu;
2500  delete mCustomForwardActionMenu;
2501 
2502  delete mCustomReplyMapper;
2503  delete mCustomReplyAllMapper;
2504  delete mCustomForwardMapper;
2505 
2506  mCustomForwardActionMenu =
2507  new TDEActionMenu( i18n("Forward With Custom Template"),
2508  "mail_custom_forward",
2509  actionCollection(), "custom_forward" );
2510  TQSignalMapper *mCustomForwardMapper = new TQSignalMapper( TQT_TQOBJECT(this) );
2511  connect( mCustomForwardMapper, TQT_SIGNAL( mapped( int ) ),
2512  TQT_TQOBJECT(this), TQT_SLOT( slotCustomForwardMsg( int ) ) );
2513  mForwardActionMenu->insert( mCustomForwardActionMenu );
2514 
2515  mCustomReplyActionMenu =
2516  new TDEActionMenu( i18n("Reply With Custom Template"), "mail_custom_reply",
2517  actionCollection(), "custom_reply" );
2518  TQSignalMapper *mCustomReplyMapper = new TQSignalMapper( TQT_TQOBJECT(this) );
2519  connect( mCustomReplyMapper, TQT_SIGNAL( mapped( int ) ),
2520  TQT_TQOBJECT(this), TQT_SLOT( slotCustomReplyToMsg( int ) ) );
2521  mMsgActions->replyMenu()->insert( mCustomReplyActionMenu );
2522 
2523  mCustomReplyAllActionMenu =
2524  new TDEActionMenu( i18n("Reply to All With Custom Template"),
2525  "mail_custom_reply_all",
2526  actionCollection(), "custom_reply_all" );
2527  TQSignalMapper *mCustomReplyAllMapper = new TQSignalMapper( TQT_TQOBJECT(this) );
2528  connect( mCustomReplyAllMapper, TQT_SIGNAL( mapped( int ) ),
2529  TQT_TQOBJECT(this), TQT_SLOT( slotCustomReplyAllToMsg( int ) ) );
2530  mMsgActions->replyMenu()->insert( mCustomReplyAllActionMenu );
2531 
2532  mCustomTemplates.clear();
2533 
2534  TQStringList list = GlobalSettingsBase::self()->customTemplates();
2535  TQStringList::iterator it = list.begin();
2536  int idx = 0;
2537  int replyc = 0;
2538  int replyallc = 0;
2539  int forwardc = 0;
2540  for ( ; it != list.end(); ++it ) {
2541  CTemplates t( *it );
2542  mCustomTemplates.append( *it );
2543 
2544  TDEAction *action;
2545  switch ( t.type() ) {
2546  case CustomTemplates::TReply:
2547  action = new TDEAction( (*it).replace( "&", "&&" ),
2548  TDEShortcut( t.shortcut() ),
2549  mCustomReplyMapper,
2550  TQT_SLOT( map() ),
2551  actionCollection(),
2552  (*it).utf8() );
2553  mCustomReplyMapper->setMapping( action, idx );
2554  mCustomReplyActionMenu->insert( action, idx );
2555  mCustomTemplateActions.append( action );
2556  ++replyc;
2557  break;
2558  case CustomTemplates::TReplyAll:
2559  action = new TDEAction( (*it).replace( "&", "&&" ),
2560  TDEShortcut( t.shortcut() ),
2561  mCustomReplyAllMapper,
2562  TQT_SLOT( map() ),
2563  actionCollection(),
2564  (*it).utf8() );
2565  mCustomReplyAllMapper->setMapping( action, idx );
2566  mCustomReplyAllActionMenu->insert( action, idx );
2567  mCustomTemplateActions.append( action );
2568  ++replyallc;
2569  break;
2570  case CustomTemplates::TForward:
2571  action = new TDEAction( (*it).replace( "&", "&&" ),
2572  TDEShortcut( t.shortcut() ),
2573  mCustomForwardMapper,
2574  TQT_SLOT( map() ),
2575  actionCollection(),
2576  (*it).utf8() );
2577  mCustomForwardMapper->setMapping( action, idx );
2578  mCustomForwardActionMenu->insert( action, idx );
2579  mCustomTemplateActions.append( action );
2580  ++forwardc;
2581  break;
2582  case CustomTemplates::TUniversal:
2583  action = new TDEAction( (*it).replace( "&", "&&" ),
2584  TDEShortcut::null(),
2585  mCustomReplyMapper,
2586  TQT_SLOT( map() ),
2587  actionCollection(),
2588  (*it).utf8() );
2589  mCustomReplyMapper->setMapping( action, idx );
2590  mCustomReplyActionMenu->insert( action, idx );
2591  mCustomTemplateActions.append( action );
2592  ++replyc;
2593  action = new TDEAction( (*it).replace( "&", "&&" ),
2594  TDEShortcut::null(),
2595  mCustomReplyAllMapper,
2596  TQT_SLOT( map() ),
2597  actionCollection(),
2598  (*it).utf8() );
2599  mCustomReplyAllMapper->setMapping( action, idx );
2600  mCustomReplyAllActionMenu->insert( action, idx );
2601  mCustomTemplateActions.append( action );
2602  ++replyallc;
2603  action = new TDEAction( (*it).replace( "&", "&&" ),
2604  TDEShortcut::null(),
2605  mCustomForwardMapper,
2606  TQT_SLOT( map() ),
2607  actionCollection(),
2608  (*it).utf8() );
2609  mCustomForwardMapper->setMapping( action, idx );
2610  mCustomForwardActionMenu->insert( action, idx );
2611  mCustomTemplateActions.append( action );
2612  ++forwardc;
2613  break;
2614  }
2615 
2616  ++idx;
2617  }
2618  if ( !replyc ) {
2619  mCustomReplyActionMenu->popupMenu()->insertItem( i18n( "(no custom templates)" ), 0 );
2620  mCustomReplyActionMenu->popupMenu()->setItemEnabled( 0, false );
2621  mCustomReplyActionMenu->setEnabled(false);
2622  }
2623  if ( !replyallc ) {
2624  mCustomReplyAllActionMenu->popupMenu()->insertItem( i18n( "(no custom templates)" ), 0 );
2625  mCustomReplyAllActionMenu->popupMenu()->setItemEnabled( 0, false );
2626  mCustomReplyAllActionMenu->setEnabled(false);
2627  }
2628  if ( !forwardc ) {
2629  mCustomForwardActionMenu->popupMenu()->insertItem( i18n( "(no custom templates)" ), 0 );
2630  mCustomForwardActionMenu->popupMenu()->setItemEnabled( 0, false );
2631  mCustomForwardActionMenu->setEnabled(false);
2632  }
2633 
2634 }
2635 
2636 
2637 //-----------------------------------------------------------------------------
2638 void KMMainWidget::setupActions()
2639 {
2640  mMsgActions = new KMail::MessageActions( actionCollection(), this );
2641  mMsgActions->setMessageView( mMsgView );
2642 
2643  //----- File Menu
2644  mSaveAsAction = new TDEAction( i18n("Save &As..."), "document-save",
2645  TDEStdAccel::shortcut(TDEStdAccel::Save),
2646  TQT_TQOBJECT(this), TQT_SLOT(slotSaveMsg()), actionCollection(), "file_save_as" );
2647 
2648  mOpenAction = KStdAction::open( TQT_TQOBJECT(this), TQT_SLOT( slotOpenMsg() ),
2649  actionCollection() );
2650 
2651  (void) new TDEAction( i18n("&Compact All Folders"), 0,
2652  TQT_TQOBJECT(this), TQT_SLOT(slotCompactAll()),
2653  actionCollection(), "compact_all_folders" );
2654 
2655  (void) new TDEAction( i18n("&Expire All Folders"), 0,
2656  TQT_TQOBJECT(this), TQT_SLOT(slotExpireAll()),
2657  actionCollection(), "expire_all_folders" );
2658 
2659  (void) new TDEAction( i18n("&Refresh Local IMAP Cache"), "refresh",
2660  TQT_TQOBJECT(this), TQT_SLOT(slotInvalidateIMAPFolders()),
2661  actionCollection(), "file_invalidate_imap_cache" );
2662 
2663  (void) new TDEAction( i18n("Empty All &Trash Folders"), 0,
2664  KMKernel::self(), TQT_SLOT(slotEmptyTrash()),
2665  actionCollection(), "empty_trash" );
2666 
2667  (void) new TDEAction( i18n("Check &Mail"), "mail_get", CTRL+Key_L,
2668  TQT_TQOBJECT(this), TQT_SLOT(slotCheckMail()),
2669  actionCollection(), "check_mail" );
2670 
2671  mFavoritesCheckMailAction = new TDEAction( i18n("Check Mail in Favorite Folders"),
2672  "mail_get", CTRL+SHIFT+Key_L, 0, 0,
2673  actionCollection(), "favorite_check_mail" );
2674  if ( mFavoriteFolderView )
2675  connect( mFavoritesCheckMailAction, TQT_SIGNAL(activated()), mFavoriteFolderView, TQT_SLOT(checkMail()) );
2676 
2677  TDEActionMenu *actActionMenu = new
2678  TDEActionMenu( i18n("Check Mail &In"), "mail_get", actionCollection(),
2679  "check_mail_in" );
2680  actActionMenu->setDelayed(true); //needed for checking "all accounts"
2681 
2682  connect(actActionMenu,TQT_SIGNAL(activated()),this,TQT_SLOT(slotCheckMail()));
2683 
2684  mActMenu = actActionMenu->popupMenu();
2685  connect(mActMenu,TQT_SIGNAL(activated(int)),this,TQT_SLOT(slotCheckOneAccount(int)));
2686  connect(mActMenu,TQT_SIGNAL(aboutToShow()),this,TQT_SLOT(getAccountMenu()));
2687 
2688  (void) new TDEAction( i18n("&Send Queued Messages"), "mail-send", 0, TQT_TQOBJECT(this),
2689  TQT_SLOT(slotSendQueued()), actionCollection(), "send_queued");
2690 
2691  (void) new TDEAction( i18n("Online Status (unknown)"), "online_status", 0, TQT_TQOBJECT(this),
2692  TQT_SLOT(slotOnlineStatus()), actionCollection(), "online_status");
2693 
2694  TDEActionMenu *sendActionMenu = new
2695  TDEActionMenu( i18n("Send Queued Messages Via"), "mail_send_via", actionCollection(),
2696  "send_queued_via" );
2697  sendActionMenu->setDelayed(true);
2698 
2699  mSendMenu = sendActionMenu->popupMenu();
2700  connect(mSendMenu,TQT_SIGNAL(activated(int)), TQT_TQOBJECT(this), TQT_SLOT(slotSendQueuedVia(int)));
2701  connect(mSendMenu,TQT_SIGNAL(aboutToShow()),this,TQT_SLOT(getTransportMenu()));
2702 
2703  TDEAction *act;
2704  //----- Tools menu
2705  if (parent()->inherits("KMMainWin")) {
2706  act = new TDEAction( i18n("&Address Book..."), "contents", 0, TQT_TQOBJECT(this),
2707  TQT_SLOT(slotAddrBook()), actionCollection(), "addressbook" );
2708  if (TDEStandardDirs::findExe("kaddressbook").isEmpty()) act->setEnabled(false);
2709  }
2710 
2711  act = new TDEAction( i18n("Certificate Manager..."), "pgp-keys", 0, TQT_TQOBJECT(this),
2712  TQT_SLOT(slotStartCertManager()), actionCollection(), "tools_start_certman");
2713  // disable action if no certman binary is around
2714  if (TDEStandardDirs::findExe("kleopatra").isEmpty()) act->setEnabled(false);
2715 
2716  act = new TDEAction( i18n("GnuPG Log Viewer..."), "pgp-keys", 0, TQT_TQOBJECT(this),
2717  TQT_SLOT(slotStartWatchGnuPG()), actionCollection(), "tools_start_kwatchgnupg");
2718  // disable action if no kwatchgnupg binary is around
2719  if (TDEStandardDirs::findExe("kwatchgnupg").isEmpty()) act->setEnabled(false);
2720 
2721  act = new TDEAction( i18n("&Import Messages..."), "document-open", 0, TQT_TQOBJECT(this),
2722  TQT_SLOT(slotImport()), actionCollection(), "import" );
2723  if (TDEStandardDirs::findExe("kmailcvt").isEmpty()) act->setEnabled(false);
2724 
2725 #if !defined(NDEBUG)
2726  (void) new TDEAction( i18n("&Debug Sieve..."),
2727  "idea", 0, TQT_TQOBJECT(this), TQT_SLOT(slotDebugSieve()),
2728  actionCollection(), "tools_debug_sieve" );
2729 #endif
2730 
2731  if ( GlobalSettings::allowOutOfOfficeSettings() ) {
2732  (void) new TDEAction( i18n("Edit \"Out of Office\" Replies..."),
2733  "configure", 0, TQT_TQOBJECT(this), TQT_SLOT(slotEditVacation()),
2734  actionCollection(), "tools_edit_vacation" );
2735 
2736  }
2737 
2738  (void) new TDEAction( i18n("Filter &Log Viewer..."), 0, TQT_TQOBJECT(this),
2739  TQT_SLOT(slotFilterLogViewer()), actionCollection(), "filter_log_viewer" );
2740 
2741  (void) new TDEAction( i18n("&Anti-Spam Wizard..."), 0, TQT_TQOBJECT(this),
2742  TQT_SLOT(slotAntiSpamWizard()), actionCollection(), "antiSpamWizard" );
2743  (void) new TDEAction( i18n("&Anti-Virus Wizard..."), 0, TQT_TQOBJECT(this),
2744  TQT_SLOT(slotAntiVirusWizard()), actionCollection(), "antiVirusWizard" );
2745 
2746  //----- Edit Menu
2747  mTrashAction = new TDEAction( KGuiItem( i18n("&Move to Trash"), "edittrash",
2748  i18n("Move message to trashcan") ),
2749  Key_Delete, TQT_TQOBJECT(this), TQT_SLOT(slotTrashMsg()),
2750  actionCollection(), "move_to_trash" );
2751 
2752  /* The delete action is nowhere in the gui, by default, so we need to make
2753  * sure it is plugged into the TDEAccel now, since that won't happen on
2754  * XMLGui construction or manual ->plug(). This is only a problem when run
2755  * as a part, though. */
2756  mDeleteAction = new TDEAction( i18n("&Delete"), "edit-delete", SHIFT+Key_Delete, TQT_TQOBJECT(this),
2757  TQT_SLOT(slotDeleteMsg()), actionCollection(), "delete" );
2758  mDeleteAction->plugAccel( actionCollection()->tdeaccel() );
2759 
2760  mTrashThreadAction = new TDEAction( KGuiItem( i18n("M&ove Thread to Trash"), "edittrash",
2761  i18n("Move thread to trashcan") ),
2762  CTRL+Key_Delete, TQT_TQOBJECT(this), TQT_SLOT(slotTrashThread()),
2763  actionCollection(), "move_thread_to_trash" );
2764 
2765  mDeleteThreadAction = new TDEAction( i18n("Delete T&hread"), "edit-delete", CTRL+SHIFT+Key_Delete, TQT_TQOBJECT(this),
2766  TQT_SLOT(slotDeleteThread()), actionCollection(), "delete_thread" );
2767 
2768 
2769  (void) new TDEAction( i18n("&Find Messages..."), "mail_find", Key_S, TQT_TQOBJECT(this),
2770  TQT_SLOT(slotRequestFullSearchFromQuickSearch()), actionCollection(), "search_messages" );
2771 
2772  mFindInMessageAction = new TDEAction( i18n("&Find in Message..."), "edit-find", TDEStdAccel::shortcut(TDEStdAccel::Find), TQT_TQOBJECT(this),
2773  TQT_SLOT(slotFind()), actionCollection(), "find_in_messages" );
2774 
2775  (void) new TDEAction( i18n("Select &All Messages"), TDEStdAccel::selectAll(), TQT_TQOBJECT(this),
2776  TQT_SLOT(slotMarkAll()), actionCollection(), "mark_all_messages" );
2777 
2778  //----- Folder Menu
2779  mNewFolderAction = new TDEAction( i18n("&New Folder..."), "folder-new", 0, TQT_TQOBJECT(mFolderTree),
2780  TQT_SLOT(addChildFolder()), actionCollection(), "new_folder" );
2781 
2782  mModifyFolderAction = new TDEAction( i18n("&Properties"), "configure", 0, TQT_TQOBJECT(this),
2783  TQT_SLOT(slotModifyFolder()), actionCollection(), "modify" );
2784 
2785  mFolderMailingListPropertiesAction = new TDEAction( i18n("&Mailing List Management..."),
2786  /*"folder_mailinglist_properties",*/ 0, TQT_TQOBJECT(this), TQT_SLOT( slotFolderMailingListProperties() ),
2787  actionCollection(), "folder_mailinglist_properties" );
2788 
2789  mFolderShortCutCommandAction = new TDEAction( i18n("&Assign Shortcut..."), "configure_shortcuts",
2790  0, TQT_TQOBJECT(this), TQT_SLOT( slotFolderShortcutCommand() ), actionCollection(),
2791  "folder_shortcut_command" );
2792 
2793 
2794  mMarkAllAsReadAction = new TDEAction( i18n("Mark All Messages as &Read"), "goto", 0, TQT_TQOBJECT(this),
2795  TQT_SLOT(slotMarkAllAsRead()), actionCollection(), "mark_all_as_read" );
2796 
2797  mExpireFolderAction = new TDEAction(i18n("&Expiration Settings"), 0, TQT_TQOBJECT(this), TQT_SLOT(slotExpireFolder()),
2798  actionCollection(), "expire");
2799 
2800  mCompactFolderAction = new TDEAction( i18n("&Compact Folder"), 0, TQT_TQOBJECT(this),
2801  TQT_SLOT(slotCompactFolder()), actionCollection(), "compact" );
2802 
2803  mRefreshFolderAction = new TDEAction( i18n("Check Mail &in This Folder"), "reload",
2804  TDEStdAccel::shortcut( TDEStdAccel::Reload ), TQT_TQOBJECT(this),
2805  TQT_SLOT(slotRefreshFolder()),
2806  actionCollection(), "refresh_folder" );
2807  mTroubleshootFolderAction = 0; // set in initializeIMAPActions
2808 
2809  mEmptyFolderAction = new TDEAction( "foo" /*set in updateFolderMenu*/, "edittrash", 0, TQT_TQOBJECT(this),
2810  TQT_SLOT(slotEmptyFolder()), actionCollection(), "empty" );
2811 
2812  mRemoveFolderAction = new TDEAction( "foo" /*set in updateFolderMenu*/, "edit-delete", 0, TQT_TQOBJECT(this),
2813  TQT_SLOT(slotRemoveFolder()), actionCollection(), "delete_folder" );
2814 
2815  mArchiveFolderAction = new TDEAction( i18n( "&Archive Folder..." ), "document-save", 0, TQT_TQOBJECT(this),
2816  TQT_SLOT( slotArchiveFolder() ), actionCollection(),
2817  "archive_folder" );
2818 
2819  mPreferHtmlAction = new TDEToggleAction( i18n("Prefer &HTML to Plain Text"), 0, TQT_TQOBJECT(this),
2820  TQT_SLOT(slotOverrideHtml()), actionCollection(), "prefer_html" );
2821 
2822  mPreferHtmlLoadExtAction = new TDEToggleAction( i18n("Load E&xternal References"), 0, TQT_TQOBJECT(this),
2823  TQT_SLOT(slotOverrideHtmlLoadExt()), actionCollection(), "prefer_html_external_refs" );
2824 
2825  mThreadMessagesAction = new TDEToggleAction( i18n("&Thread Messages"), 0, TQT_TQOBJECT(this),
2826  TQT_SLOT(slotOverrideThread()), actionCollection(), "thread_messages" );
2827 
2828  mThreadBySubjectAction = new TDEToggleAction( i18n("Thread Messages also by &Subject"), 0, TQT_TQOBJECT(this),
2829  TQT_SLOT(slotToggleSubjectThreading()), actionCollection(), "thread_messages_by_subject" );
2830 
2831  new TDEAction( i18n("Copy Folder"), "edit-copy", SHIFT+CTRL+Key_C, TQT_TQOBJECT(folderTree()),
2832  TQT_SLOT(copyFolder()), actionCollection(), "copy_folder" );
2833  new TDEAction( i18n("Cut Folder"), "edit-cut", SHIFT+CTRL+Key_X, TQT_TQOBJECT(folderTree()),
2834  TQT_SLOT(cutFolder()), actionCollection(), "cut_folder" );
2835  new TDEAction( i18n("Paste Folder"), "edit-paste", SHIFT+CTRL+Key_V, TQT_TQOBJECT(folderTree()),
2836  TQT_SLOT(pasteFolder()), actionCollection(), "paste_folder" );
2837 
2838  new TDEAction( i18n("Copy Messages"), "edit-copy", ALT+CTRL+Key_C, TQT_TQOBJECT(headers()),
2839  TQT_SLOT(copyMessages()), actionCollection(), "copy_messages" );
2840  new TDEAction( i18n("Cut Messages"), "edit-cut", ALT+CTRL+Key_X, TQT_TQOBJECT(headers()),
2841  TQT_SLOT(cutMessages()), actionCollection(), "cut_messages" );
2842  new TDEAction( i18n("Paste Messages"), "edit-paste", ALT+CTRL+Key_V, TQT_TQOBJECT(headers()),
2843  TQT_SLOT(pasteMessages()), actionCollection(), "paste_messages" );
2844 
2845  //----- Message Menu
2846  (void) new TDEAction( i18n("&New Message..."), "mail-message-new", TDEStdAccel::shortcut(TDEStdAccel::New), TQT_TQOBJECT(this),
2847  TQT_SLOT(slotCompose()), actionCollection(), "new_message" );
2848  mTemplateMenu =
2849  new TDEActionMenu( i18n("New Message From &Template"), "document-new",
2850  actionCollection(), "new_from_template" );
2851  mTemplateMenu->setDelayed( true );
2852  connect( mTemplateMenu->popupMenu(), TQT_SIGNAL( aboutToShow() ), TQT_TQOBJECT(this),
2853  TQT_SLOT( slotShowNewFromTemplate() ) );
2854  connect( mTemplateMenu->popupMenu(), TQT_SIGNAL( activated(int) ), TQT_TQOBJECT(this),
2855  TQT_SLOT( slotNewFromTemplate(int) ) );
2856 
2857  TDEAction* newToML = new TDEAction( i18n("New Message t&o Mailing-List..."), "mail_post_to",
2858  CTRL+SHIFT+Key_N, TQT_TQOBJECT(this),
2859  TQT_SLOT(slotPostToML()), actionCollection(), "post_message" );
2860  newToML->plugAccel( actionCollection()->tdeaccel() );
2861 
2862  mForwardActionMenu = new TDEActionMenu( i18n("Message->","&Forward"),
2863  "mail-forward", actionCollection(),
2864  "message_forward" );
2865 
2866  mForwardInlineAction = new TDEAction( i18n("&Inline..."),
2867  "mail-forward", 0, TQT_TQOBJECT(this),
2868  TQT_SLOT(slotForwardInlineMsg()),
2869  actionCollection(),
2870  "message_forward_inline" );
2871 
2872  mForwardAttachedAction = new TDEAction( i18n("Message->Forward->","As &Attachment..."),
2873  "mail-forward", 0, TQT_TQOBJECT(this),
2874  TQT_SLOT(slotForwardAttachedMsg()),
2875  actionCollection(),
2876  "message_forward_as_attachment" );
2877 
2878  mForwardDigestAction = new TDEAction( i18n("Message->Forward->","As Di&gest..."),
2879  "mail-forward", 0, TQT_TQOBJECT(this),
2880  TQT_SLOT(slotForwardDigestMsg()),
2881  actionCollection(),
2882  "message_forward_as_digest" );
2883 
2884  mRedirectAction = new TDEAction( i18n("Message->Forward->","&Redirect..."),
2885  "mail-forward", Key_E, TQT_TQOBJECT(this),
2886  TQT_SLOT(slotRedirectMsg()),
2887  actionCollection(),
2888  "message_forward_redirect" );
2889 
2890 
2891  setupForwardActions();
2892 
2893  mForwardActionMenu->insert( mForwardDigestAction );
2894  mForwardActionMenu->insert( mRedirectAction );
2895 
2896  mSendAgainAction = new TDEAction( i18n("Send A&gain..."), 0, TQT_TQOBJECT(this),
2897  TQT_SLOT(slotResendMsg()), actionCollection(), "send_again" );
2898 
2899 
2900  //----- Create filter actions
2901  mFilterMenu = new TDEActionMenu( i18n("&Create Filter"), "filter", actionCollection(), "create_filter" );
2902  connect( mFilterMenu, TQT_SIGNAL(activated()), TQT_TQOBJECT(this),
2903  TQT_SLOT(slotFilter()) );
2904  mSubjectFilterAction = new TDEAction( i18n("Filter on &Subject..."), 0, TQT_TQOBJECT(this),
2905  TQT_SLOT(slotSubjectFilter()),
2906  actionCollection(), "subject_filter");
2907  mFilterMenu->insert( mSubjectFilterAction );
2908 
2909  mFromFilterAction = new TDEAction( i18n("Filter on &From..."), 0, TQT_TQOBJECT(this),
2910  TQT_SLOT(slotFromFilter()),
2911  actionCollection(), "from_filter");
2912  mFilterMenu->insert( mFromFilterAction );
2913 
2914  mToFilterAction = new TDEAction( i18n("Filter on &To..."), 0, TQT_TQOBJECT(this),
2915  TQT_SLOT(slotToFilter()),
2916  actionCollection(), "to_filter");
2917  mFilterMenu->insert( mToFilterAction );
2918 
2919  mListFilterAction = new TDEAction( i18n("Filter on Mailing-&List..."), 0, TQT_TQOBJECT(this),
2920  TQT_SLOT(slotMailingListFilter()), actionCollection(),
2921  "mlist_filter");
2922  mFilterMenu->insert( mListFilterAction );
2923 
2924  mPrintAction = KStdAction::print (TQT_TQOBJECT(this), TQT_SLOT(slotPrintMsg()), actionCollection());
2925 
2926  mUseAction = new TDEAction( i18n("New Message From &Template"), "document-new",
2927  Key_N, TQT_TQOBJECT(this), TQT_SLOT( slotUseTemplate() ),
2928  actionCollection(), "use_template" );
2929  mUseAction->plugAccel( actionCollection()->tdeaccel() );
2930 
2931  //----- "Mark Thread" submenu
2932  mThreadStatusMenu = new TDEActionMenu ( i18n( "Mark &Thread" ),
2933  actionCollection(), "thread_status" );
2934 
2935  mMarkThreadAsReadAction = new TDEAction(KGuiItem(i18n("Mark Thread as &Read"), "kmmsgread",
2936  i18n("Mark all messages in the selected thread as read")),
2937  0, TQT_TQOBJECT(this), TQT_SLOT(slotSetThreadStatusRead()),
2938  actionCollection(), "thread_read");
2939  mThreadStatusMenu->insert( mMarkThreadAsReadAction );
2940 
2941  mMarkThreadAsNewAction = new TDEAction(KGuiItem(i18n("Mark Thread as &New"), "kmmsgnew",
2942  i18n("Mark all messages in the selected thread as new")),
2943  0, TQT_TQOBJECT(this), TQT_SLOT(slotSetThreadStatusNew()),
2944  actionCollection(), "thread_new");
2945  mThreadStatusMenu->insert( mMarkThreadAsNewAction );
2946 
2947  mMarkThreadAsUnreadAction = new TDEAction(KGuiItem(i18n("Mark Thread as &Unread"), "kmmsgunseen",
2948  i18n("Mark all messages in the selected thread as unread")),
2949  0, TQT_TQOBJECT(this), TQT_SLOT(slotSetThreadStatusUnread()),
2950  actionCollection(), "thread_unread");
2951  mThreadStatusMenu->insert( mMarkThreadAsUnreadAction );
2952 
2953  mThreadStatusMenu->insert( new TDEActionSeparator( TQT_TQOBJECT(this) ) );
2954 
2955  //----- "Mark Thread" toggle actions
2956  mToggleThreadFlagAction = new TDEToggleAction(i18n("Mark Thread as &Important"), "mail_flag",
2957  0, TQT_TQOBJECT(this), TQT_SLOT(slotSetThreadStatusFlag()),
2958  actionCollection(), "thread_flag");
2959  mToggleThreadFlagAction->setCheckedState( i18n("Remove &Important Thread Mark") );
2960  mThreadStatusMenu->insert( mToggleThreadFlagAction );
2961 
2962  mToggleThreadTodoAction = new TDEToggleAction(i18n("Mark Thread as &Action Item"), "mail_todo",
2963  0, TQT_TQOBJECT(this), TQT_SLOT(slotSetThreadStatusTodo()),
2964  actionCollection(), "thread_todo");
2965  mToggleThreadTodoAction->setCheckedState( i18n("Remove &Action Item Thread Mark") );
2966  mThreadStatusMenu->insert( mToggleThreadTodoAction );
2967 
2968  //------- "Watch and ignore thread" actions
2969  mWatchThreadAction = new TDEToggleAction(i18n("&Watch Thread"), "kmmsgwatched",
2970  0, TQT_TQOBJECT(this), TQT_SLOT(slotSetThreadStatusWatched()),
2971  actionCollection(), "thread_watched");
2972 
2973  mIgnoreThreadAction = new TDEToggleAction(i18n("&Ignore Thread"), "mail_ignore",
2974  0, TQT_TQOBJECT(this), TQT_SLOT(slotSetThreadStatusIgnored()),
2975  actionCollection(), "thread_ignored");
2976 
2977  mThreadStatusMenu->insert( new TDEActionSeparator( TQT_TQOBJECT(this) ) );
2978  mThreadStatusMenu->insert( mWatchThreadAction );
2979  mThreadStatusMenu->insert( mIgnoreThreadAction );
2980 
2981  mSaveAttachmentsAction = new TDEAction( i18n("Save A&ttachments..."), "attach",
2982  0, TQT_TQOBJECT(this), TQT_SLOT(slotSaveAttachments()),
2983  actionCollection(), "file_save_attachments" );
2984 
2985  mMoveActionMenu = new TDEActionMenu( i18n("&Move To" ),
2986  actionCollection(), "move_to" );
2987 
2988  mCopyActionMenu = new TDEActionMenu( i18n("&Copy To" ),
2989  actionCollection(), "copy_to" );
2990 
2991  mApplyAllFiltersAction = new TDEAction( i18n("Appl&y All Filters"), "filter",
2992  CTRL+Key_J, TQT_TQOBJECT(this),
2993  TQT_SLOT(slotApplyFilters()),
2994  actionCollection(), "apply_filters" );
2995 
2996  mApplyFilterActionsMenu = new TDEActionMenu( i18n("A&pply Filter" ),
2997  actionCollection(),
2998  "apply_filter_actions" );
2999 
3000  //----- View Menu
3001  // Unread Submenu
3002  TDEActionMenu * unreadMenu =
3003  new TDEActionMenu( i18n("View->", "&Unread Count"),
3004  actionCollection(), "view_unread" );
3005  unreadMenu->setToolTip( i18n("Choose how to display the count of unread messages") );
3006 
3007  mUnreadColumnToggle = new TDERadioAction( i18n("View->Unread Count", "View in &Separate Column"), 0, TQT_TQOBJECT(this),
3008  TQT_SLOT(slotToggleUnread()),
3009  actionCollection(), "view_unread_column" );
3010  mUnreadColumnToggle->setExclusiveGroup( "view_unread_group" );
3011  unreadMenu->insert( mUnreadColumnToggle );
3012 
3013  mUnreadTextToggle = new TDERadioAction( i18n("View->Unread Count", "View After &Folder Name"), 0, TQT_TQOBJECT(this),
3014  TQT_SLOT(slotToggleUnread()),
3015  actionCollection(), "view_unread_text" );
3016  mUnreadTextToggle->setExclusiveGroup( "view_unread_group" );
3017  unreadMenu->insert( mUnreadTextToggle );
3018 
3019  // toggle for total column
3020  mTotalColumnToggle = new TDEToggleAction( i18n("View->", "&Total Column"), 0, TQT_TQOBJECT(this),
3021  TQT_SLOT(slotToggleTotalColumn()),
3022  actionCollection(), "view_columns_total" );
3023  mTotalColumnToggle->setToolTip( i18n("Toggle display of column showing the "
3024  "total number of messages in folders.") );
3025  mSizeColumnToggle = new TDEToggleAction( i18n("View->", "&Size Column"), 0, TQT_TQOBJECT(this),
3026  TQT_SLOT(slotToggleSizeColumn()),
3027  actionCollection(), "view_columns_size" );
3028  mSizeColumnToggle->setToolTip( i18n("Toggle display of column showing the "
3029  "total size of messages in folders.") );
3030 
3031  (void)new TDEAction( KGuiItem( i18n("View->","&Expand Thread"), TQString(),
3032  i18n("Expand the current thread") ),
3033  Key_Period, TQT_TQOBJECT(this),
3034  TQT_SLOT(slotExpandThread()),
3035  actionCollection(), "expand_thread" );
3036 
3037  (void)new TDEAction( KGuiItem( i18n("View->","&Collapse Thread"), TQString(),
3038  i18n("Collapse the current thread") ),
3039  Key_Comma, TQT_TQOBJECT(this),
3040  TQT_SLOT(slotCollapseThread()),
3041  actionCollection(), "collapse_thread" );
3042 
3043  (void)new TDEAction( KGuiItem( i18n("View->","Ex&pand All Threads"), TQString(),
3044  i18n("Expand all threads in the current folder") ),
3045  CTRL+Key_Period, TQT_TQOBJECT(this),
3046  TQT_SLOT(slotExpandAllThreads()),
3047  actionCollection(), "expand_all_threads" );
3048 
3049  (void)new TDEAction( KGuiItem( i18n("View->","C&ollapse All Threads"), TQString(),
3050  i18n("Collapse all threads in the current folder") ),
3051  CTRL+Key_Comma, TQT_TQOBJECT(this),
3052  TQT_SLOT(slotCollapseAllThreads()),
3053  actionCollection(), "collapse_all_threads" );
3054 
3055  mViewSourceAction = new TDEAction( i18n("&View Source"), Key_V, TQT_TQOBJECT(this),
3056  TQT_SLOT(slotShowMsgSrc()), actionCollection(),
3057  "view_source" );
3058 
3059  TDEAction* dukeOfMonmoth = new TDEAction( i18n("&Display Message"), Key_Return, TQT_TQOBJECT(this),
3060  TQT_SLOT( slotDisplayCurrentMessage() ), actionCollection(),
3061  "display_message" );
3062  dukeOfMonmoth->plugAccel( actionCollection()->tdeaccel() );
3063 
3064  //----- Go Menu
3065  new TDEAction( KGuiItem( i18n("&Next Message"), TQString(),
3066  i18n("Go to the next message") ),
3067  "N;Right", TQT_TQOBJECT(this), TQT_SLOT(slotNextMessage()),
3068  actionCollection(), "go_next_message" );
3069 
3070  new TDEAction( KGuiItem( i18n("Next &Unread Message"),
3071  TQApplication::reverseLayout() ? "go-previous" : "go-next",
3072  i18n("Go to the next unread message") ),
3073  Key_Plus, TQT_TQOBJECT(this), TQT_SLOT(slotNextUnreadMessage()),
3074  actionCollection(), "go_next_unread_message" );
3075 
3076  /* ### needs better support from folders:
3077  new TDEAction( KGuiItem( i18n("Next &Important Message"), TQString(),
3078  i18n("Go to the next important message") ),
3079  0, TQT_TQOBJECT(this), TQT_SLOT(slotNextImportantMessage()),
3080  actionCollection(), "go_next_important_message" );
3081  */
3082 
3083  new TDEAction( KGuiItem( i18n("&Previous Message"), TQString(),
3084  i18n("Go to the previous message") ),
3085  "P;Left", TQT_TQOBJECT(this), TQT_SLOT(slotPrevMessage()),
3086  actionCollection(), "go_prev_message" );
3087 
3088  new TDEAction( KGuiItem( i18n("Previous Unread &Message"),
3089  TQApplication::reverseLayout() ? "go-next" : "go-previous",
3090  i18n("Go to the previous unread message") ),
3091  Key_Minus, TQT_TQOBJECT(this), TQT_SLOT(slotPrevUnreadMessage()),
3092  actionCollection(), "go_prev_unread_message" );
3093 
3094  /* needs better support from folders:
3095  new TDEAction( KGuiItem( i18n("Previous I&mportant Message"), TQString(),
3096  i18n("Go to the previous important message") ),
3097  0, TQT_TQOBJECT(this), TQT_SLOT(slotPrevImportantMessage()),
3098  actionCollection(), "go_prev_important_message" );
3099  */
3100 
3101  TDEAction *action =
3102  new TDEAction( KGuiItem( i18n("Next Unread &Folder"), TQString(),
3103  i18n("Go to the next folder with unread messages") ),
3104  ALT+Key_Plus, TQT_TQOBJECT(this), TQT_SLOT(slotNextUnreadFolder()),
3105  actionCollection(), "go_next_unread_folder" );
3106  TDEShortcut shortcut = action->shortcut();
3107  shortcut.append( KKey( CTRL+Key_Plus ) );
3108  action->setShortcut( shortcut );
3109 
3110  action =
3111  new TDEAction( KGuiItem( i18n("Previous Unread F&older"), TQString(),
3112  i18n("Go to the previous folder with unread messages") ),
3113  ALT+Key_Minus, TQT_TQOBJECT(this), TQT_SLOT(slotPrevUnreadFolder()),
3114  actionCollection(), "go_prev_unread_folder" );
3115  shortcut = action->shortcut();
3116  shortcut.append( KKey( CTRL+Key_Minus ) );
3117  action->setShortcut( shortcut );
3118 
3119  new TDEAction( KGuiItem( i18n("Go->","Next Unread &Text"), TQString(),
3120  i18n("Go to the next unread text"),
3121  i18n("Scroll down current message. "
3122  "If at end of current message, "
3123  "go to next unread message.") ),
3124  Key_Space, TQT_TQOBJECT(this), TQT_SLOT(slotReadOn()),
3125  actionCollection(), "go_next_unread_text" );
3126 
3127  //----- Settings Menu
3128  mToggleShowQuickSearchAction = new TDEToggleAction(i18n("Show Quick Search"), TQString(),
3129  0, TQT_TQOBJECT(this), TQT_SLOT(slotToggleShowQuickSearch()),
3130  actionCollection(), "show_quick_search");
3131  mToggleShowQuickSearchAction->setChecked( GlobalSettings::self()->quickSearchActive() );
3132  mToggleShowQuickSearchAction->setWhatsThis(
3133  i18n( GlobalSettings::self()->quickSearchActiveItem()->whatsThis().utf8() ) );
3134 
3135  (void) new TDEAction( i18n("Configure &Filters..."), 0, TQT_TQOBJECT(this),
3136  TQT_SLOT(slotFilter()), actionCollection(), "filter" );
3137  (void) new TDEAction( i18n("Configure &POP Filters..."), 0, TQT_TQOBJECT(this),
3138  TQT_SLOT(slotPopFilter()), actionCollection(), "popFilter" );
3139  (void) new TDEAction( i18n("Manage &Sieve Scripts..."), 0, TQT_TQOBJECT(this),
3140  TQT_SLOT(slotManageSieveScripts()), actionCollection(), "sieveFilters" );
3141 
3142  (void) new TDEAction( KGuiItem( i18n("KMail &Introduction"), 0,
3143  i18n("Display KMail's Welcome Page") ),
3144  0, TQT_TQOBJECT(this), TQT_SLOT(slotIntro()),
3145  actionCollection(), "help_kmail_welcomepage" );
3146 
3147  // ----- Standard Actions
3148 // KStdAction::configureNotifications(this, TQT_SLOT(slotEditNotifications()), actionCollection());
3149  (void) new TDEAction( i18n("Configure &Notifications..."),
3150  "knotify", 0, TQT_TQOBJECT(this),
3151  TQT_SLOT(slotEditNotifications()), actionCollection(),
3152  "kmail_configure_notifications" );
3153 // KStdAction::preferences(this, TQT_SLOT(slotSettings()), actionCollection());
3154  (void) new TDEAction( i18n("&Configure KMail..."),
3155  "configure", 0, kmkernel,
3156  TQT_SLOT(slotShowConfigurationDialog()), actionCollection(),
3157  "kmail_configure_kmail" );
3158 
3159  KStdAction::undo(TQT_TQOBJECT(this), TQT_SLOT(slotUndo()), actionCollection(), "kmail_undo");
3160 
3161  KStdAction::tipOfDay( TQT_TQOBJECT(this), TQT_SLOT( slotShowTip() ), actionCollection() );
3162 
3163  menutimer = new TQTimer( this, "menutimer" );
3164  connect( menutimer, TQT_SIGNAL( timeout() ), TQT_SLOT( updateMessageActions() ) );
3165  connect( kmkernel->undoStack(),
3166  TQT_SIGNAL( undoStackChanged() ), TQT_TQOBJECT(this), TQT_SLOT( slotUpdateUndo() ));
3167 
3168  initializeIMAPActions( false ); // don't set state, config not read yet
3169  updateMessageActions();
3170  updateCustomTemplateMenus();
3171  updateFolderMenu();
3172 }
3173 
3174 void KMMainWidget::setupForwardingActionsList()
3175 {
3176  TQPtrList<TDEAction> mForwardActionList;
3177  if ( GlobalSettings::self()->forwardingInlineByDefault() ) {
3178  mGUIClient->unplugActionList( "forward_action_list" );
3179  mForwardActionList.append( mForwardInlineAction );
3180  mForwardActionList.append( mForwardAttachedAction );
3181  mForwardActionList.append( mForwardDigestAction );
3182  mForwardActionList.append( mRedirectAction );
3183  mGUIClient->plugActionList( "forward_action_list", mForwardActionList );
3184  } else {
3185  mGUIClient->unplugActionList( "forward_action_list" );
3186  mForwardActionList.append( mForwardAttachedAction );
3187  mForwardActionList.append( mForwardInlineAction );
3188  mForwardActionList.append( mForwardDigestAction );
3189  mForwardActionList.append( mRedirectAction );
3190  mGUIClient->plugActionList( "forward_action_list", mForwardActionList );
3191  }
3192 }
3193 
3194 //-----------------------------------------------------------------------------
3195 void KMMainWidget::slotEditNotifications()
3196 {
3197  if(kmkernel->xmlGuiInstance())
3198  KNotifyDialog::configure(this, 0, kmkernel->xmlGuiInstance()->aboutData());
3199  else
3200  KNotifyDialog::configure(this);
3201 }
3202 
3203 void KMMainWidget::slotEditKeys()
3204 {
3205  KKeyDialog::configure( actionCollection(),
3206  true /*allow one-letter shortcuts*/
3207  );
3208 }
3209 
3210 //-----------------------------------------------------------------------------
3211 void KMMainWidget::slotReadOn()
3212 {
3213  if ( !mMsgView )
3214  return;
3215 
3216  if ( !mMsgView->atBottom() ) {
3217  mMsgView->slotJumpDown();
3218  return;
3219  }
3220  slotNextUnreadMessage();
3221 }
3222 
3223 void KMMainWidget::slotNextUnreadFolder() {
3224  if ( !mFolderTree ) return;
3225  mFolderTree->nextUnreadFolder();
3226 }
3227 
3228 void KMMainWidget::slotPrevUnreadFolder() {
3229  if ( !mFolderTree ) return;
3230  mFolderTree->prevUnreadFolder();
3231 }
3232 
3233 void KMMainWidget::slotExpandThread()
3234 {
3235  mHeaders->slotExpandOrCollapseThread( true ); // expand
3236 }
3237 
3238 void KMMainWidget::slotCollapseThread()
3239 {
3240  mHeaders->slotExpandOrCollapseThread( false ); // collapse
3241 }
3242 
3243 void KMMainWidget::slotExpandAllThreads()
3244 {
3245  mHeaders->slotExpandOrCollapseAllThreads( true ); // expand
3246 }
3247 
3248 void KMMainWidget::slotCollapseAllThreads()
3249 {
3250  mHeaders->slotExpandOrCollapseAllThreads( false ); // collapse
3251 }
3252 
3253 //-----------------------------------------------------------------------------
3254 void KMMainWidget::slotShowMsgSrc()
3255 {
3256  if ( mMsgView )
3257  mMsgView->setUpdateAttachment( false );
3258  KMMessage *msg = mHeaders->currentMsg();
3259  if ( !msg )
3260  return;
3261  KMCommand *command = new KMShowMsgSrcCommand( this, msg,
3262  mMsgView
3263  ? mMsgView->isFixedFont()
3264  : false );
3265  command->start();
3266 }
3267 
3268 
3269 //-----------------------------------------------------------------------------
3270 void KMMainWidget::moveSelectedToFolder( int menuId )
3271 {
3272  if (mMenuToFolder[menuId])
3273  mHeaders->moveMsgToFolder( mMenuToFolder[menuId] );
3274 }
3275 
3276 
3277 //-----------------------------------------------------------------------------
3278 void KMMainWidget::copySelectedToFolder(int menuId )
3279 {
3280  if (mMenuToFolder[menuId])
3281  mHeaders->copyMsgToFolder( mMenuToFolder[menuId] );
3282 }
3283 
3284 
3285 //-----------------------------------------------------------------------------
3286 void KMMainWidget::updateMessageMenu()
3287 {
3288  mMenuToFolder.clear();
3289  folderTree()->folderToPopupMenu( KMFolderTree::MoveMessage, TQT_TQOBJECT(this),
3290  &mMenuToFolder, mMoveActionMenu->popupMenu() );
3291  folderTree()->folderToPopupMenu( KMFolderTree::CopyMessage, TQT_TQOBJECT(this),
3292  &mMenuToFolder, mCopyActionMenu->popupMenu() );
3293  updateMessageActions();
3294 }
3295 
3296 void KMMainWidget::startUpdateMessageActionsTimer()
3297 {
3298  menutimer->stop();
3299  menutimer->start( 20, true );
3300 }
3301 
3302 void KMMainWidget::updateMessageActions()
3303 {
3304  int count = 0;
3305  TQPtrList<TQListViewItem> selectedItems;
3306 
3307  if ( mFolder ) {
3308  for (TQListViewItem *item = mHeaders->firstChild(); item; item = item->itemBelow())
3309  if (item->isSelected() )
3310  selectedItems.append(item);
3311  if ( selectedItems.isEmpty() && mFolder->count() ) // there will always be one in mMsgView
3312  count = 1;
3313  else
3314  count = selectedItems.count();
3315  mMsgActions->setCurrentMessage( mHeaders->currentMsg() );
3316  mMsgActions->setSelectedSernums( mHeaders->selectedSernums() );
3317  mMsgActions->setSelectedVisibleSernums( mHeaders->selectedVisibleSernums() );
3318  } else {
3319  mMsgActions->setCurrentMessage( 0 );
3320  }
3321 
3322  updateListFilterAction();
3323 
3324  bool allSelectedInCommonThread = false;
3325  if ( mHeaders->isThreaded() && count > 1 ) {
3326  allSelectedInCommonThread = true;
3327  for ( TQPtrListIterator<TQListViewItem> it( selectedItems ) ;
3328  it.current() ; ++ it ) {
3329  TQListViewItem * item = *it;
3330  if ( item->parent()==0 && item->childCount()==0 ) {
3331  allSelectedInCommonThread = false;
3332  break;
3333  }
3334  }
3335  }
3336  else if ( mHeaders->isThreaded() && count == 1 ) {
3337  allSelectedInCommonThread = true;
3338  }
3339 
3340  TQListViewItem *curItemParent = mHeaders->currentItem();
3341  bool parent_thread = 0;
3342  if ( curItemParent && curItemParent->firstChild() != 0 ) parent_thread = 1;
3343 
3344  bool mass_actions = count >= 1;
3345  bool thread_actions = mass_actions && allSelectedInCommonThread &&
3346  mHeaders->isThreaded();
3347  bool flags_available = GlobalSettings::self()->allowLocalFlags() || !(mFolder ? mFolder->isReadOnly() : true);
3348  mThreadStatusMenu->setEnabled( thread_actions );
3349  // these need to be handled individually, the user might have them
3350  // in the toolbar
3351  mWatchThreadAction->setEnabled( thread_actions && flags_available );
3352  mIgnoreThreadAction->setEnabled( thread_actions && flags_available );
3353  mMarkThreadAsNewAction->setEnabled( thread_actions );
3354  mMarkThreadAsReadAction->setEnabled( thread_actions );
3355  mMarkThreadAsUnreadAction->setEnabled( thread_actions );
3356  mToggleThreadTodoAction->setEnabled( thread_actions && flags_available );
3357  mToggleThreadFlagAction->setEnabled( thread_actions && flags_available );
3358  mTrashThreadAction->setEnabled( thread_actions && mFolder->canDeleteMessages() );
3359  mDeleteThreadAction->setEnabled( thread_actions && mFolder->canDeleteMessages() );
3360 
3361  if (mFolder && mHeaders && mHeaders->currentMsg()) {
3362  if (thread_actions) {
3363  mToggleThreadTodoAction->setChecked(mHeaders->currentMsg()->isTodo());
3364  mToggleThreadFlagAction->setChecked(mHeaders->currentMsg()->isImportant());
3365  mWatchThreadAction->setChecked( mHeaders->currentMsg()->isWatched());
3366  mIgnoreThreadAction->setChecked( mHeaders->currentMsg()->isIgnored());
3367  }
3368  }
3369 
3370  mMoveActionMenu->setEnabled( mass_actions && mFolder->canDeleteMessages() );
3371  mMoveMsgToFolderAction->setEnabled( mass_actions && mFolder->canDeleteMessages() );
3372  mCopyActionMenu->setEnabled( mass_actions );
3373  mTrashAction->setEnabled( mass_actions && mFolder->canDeleteMessages() );
3374  mDeleteAction->setEnabled( mass_actions && mFolder->canDeleteMessages() );
3375  mFindInMessageAction->setEnabled( mass_actions && !kmkernel->folderIsTemplates( mFolder ) );
3376  mForwardInlineAction->setEnabled( mass_actions && !kmkernel->folderIsTemplates( mFolder ));
3377  mForwardAttachedAction->setEnabled( mass_actions && !kmkernel->folderIsTemplates( mFolder ) );
3378  mForwardDigestAction->setEnabled( ( count > 1 || parent_thread ) && !kmkernel->folderIsTemplates( mFolder ) );
3379 
3380  forwardMenu()->setEnabled( mass_actions && !kmkernel->folderIsTemplates( mFolder ));
3381 
3382  bool single_actions = count == 1;
3383  mUseAction->setEnabled( single_actions &&
3384  kmkernel->folderIsTemplates( mFolder ) );
3385  filterMenu()->setEnabled( single_actions );
3386  redirectAction()->setEnabled( single_actions && !kmkernel->folderIsTemplates( mFolder ) );
3387  printAction()->setEnabled( single_actions );
3388  viewSourceAction()->setEnabled( single_actions );
3389 
3390  mSendAgainAction->setEnabled( single_actions
3391  && ( ( mHeaders->currentMsg() && mHeaders->currentMsg()->isSent() )
3392  || ( mFolder && mHeaders->currentMsg() &&
3393  kmkernel->folderIsSentMailFolder( mFolder ) ) ) );
3394  mSaveAsAction->setEnabled( mass_actions );
3395  bool mails = mFolder && mFolder->count();
3396  bool enable_goto_unread = mails
3397  || (GlobalSettings::self()->loopOnGotoUnread() == GlobalSettings::EnumLoopOnGotoUnread::LoopInAllFolders);
3398  actionCollection()->action( "go_next_message" )->setEnabled( mails );
3399  actionCollection()->action( "go_next_unread_message" )->setEnabled( enable_goto_unread );
3400  actionCollection()->action( "go_prev_message" )->setEnabled( mails );
3401  actionCollection()->action( "go_prev_unread_message" )->setEnabled( enable_goto_unread );
3402  actionCollection()->action( "send_queued" )->setEnabled( kmkernel->outboxFolder()->count() > 0 );
3403  actionCollection()->action( "send_queued_via" )->setEnabled( kmkernel->outboxFolder()->count() > 0 );
3404  slotUpdateOnlineStatus( static_cast<GlobalSettingsBase::EnumNetworkState::type>( GlobalSettings::self()->networkState() ) );
3405  if (action( "edit_undo" ))
3406  action( "edit_undo" )->setEnabled( mHeaders->canUndo() );
3407 
3408  if ( count == 1 ) {
3409  KMMessage *msg;
3410  int aIdx;
3411  if((aIdx = mHeaders->currentItemIndex()) <= -1)
3412  return;
3413  if(!(msg = mFolder->getMsg(aIdx)))
3414  return;
3415 
3416  if ((KMFolder*)mFolder == kmkernel->outboxFolder())
3417  editAction()->setEnabled( !msg->transferInProgress() );
3418  }
3419 
3420  mApplyAllFiltersAction->setEnabled(count);
3421  mApplyFilterActionsMenu->setEnabled(count);
3422 }
3423 
3424 // This needs to be updated more often, so it is in its method.
3425 void KMMainWidget::updateMarkAsReadAction()
3426 {
3427  mMarkAllAsReadAction->setEnabled( mFolder && (mFolder->countUnread() > 0) );
3428 }
3429 
3430 //-----------------------------------------------------------------------------
3431 void KMMainWidget::updateFolderMenu()
3432 {
3433  bool folderWithContent = mFolder && !mFolder->noContent();
3434  bool multiFolder = folderTree()->selectedFolders().count() > 1;
3435  mModifyFolderAction->setEnabled( folderWithContent && !multiFolder );
3436  mFolderMailingListPropertiesAction->setEnabled( folderWithContent && !multiFolder );
3437  mCompactFolderAction->setEnabled( folderWithContent && !multiFolder );
3438 
3439  // This is the refresh-folder action in the menu. See kmfoldertree for the one in the RMB...
3440  bool imap = mFolder && mFolder->folderType() == KMFolderTypeImap;
3441  bool cachedImap = mFolder && mFolder->folderType() == KMFolderTypeCachedImap;
3442  // For dimap, check that the imap path is known before allowing "check mail in this folder".
3443  bool knownImapPath = cachedImap && !static_cast<KMFolderCachedImap*>( mFolder->storage() )->imapPath().isEmpty();
3444  mRefreshFolderAction->setEnabled( folderWithContent && ( imap
3445  || ( cachedImap && knownImapPath ) ) && !multiFolder );
3446  if ( mTroubleshootFolderAction )
3447  mTroubleshootFolderAction->setEnabled( folderWithContent && ( cachedImap && knownImapPath ) && !multiFolder );
3448 
3449  mEmptyFolderAction->setEnabled( folderWithContent &&
3450  ( mFolder->count() > 0 ) && mFolder->canDeleteMessages() &&
3451  !multiFolder );
3452  mEmptyFolderAction->setText( ( mFolder && kmkernel->folderIsTrash( mFolder ) ) ?
3453  i18n( "E&mpty Trash" ) :
3454  i18n( "&Move All Messages to Trash" ) );
3455 
3456  mRemoveFolderAction->setEnabled( mFolder &&
3457  !mFolder->isSystemFolder() &&
3458  mFolder->canDeleteMessages() &&
3459  !multiFolder && !mFolder->noContent() &&
3460  !mFolder->mailCheckInProgress() );
3461  mRemoveFolderAction->setText( mFolder &&
3462  mFolder->folderType() == KMFolderTypeSearch ?
3463  i18n( "&Delete Search" ) :
3464  i18n( "&Delete Folder" ) );
3465 
3466  if ( mArchiveFolderAction )
3467  mArchiveFolderAction->setEnabled( mFolder && !multiFolder );
3468  mExpireFolderAction->setEnabled( mFolder && mFolder->isAutoExpire() && !multiFolder && mFolder->canDeleteMessages() );
3469  updateMarkAsReadAction();
3470  // the visual ones only make sense if we are showing a message list
3471  mPreferHtmlAction->setEnabled( mHeaders->folder() ? true : false );
3472  mPreferHtmlLoadExtAction->setEnabled( mHeaders->folder() && (mHtmlPref ? !mFolderHtmlPref : mFolderHtmlPref) ? true : false );
3473  mThreadMessagesAction->setEnabled( mHeaders->folder() ? true : false );
3474 
3475  mPreferHtmlAction->setChecked( mHtmlPref ? !mFolderHtmlPref : mFolderHtmlPref );
3476  mPreferHtmlLoadExtAction->setChecked( mHtmlLoadExtPref ? !mFolderHtmlLoadExtPref : mFolderHtmlLoadExtPref );
3477  mThreadMessagesAction->setChecked(
3478  mThreadPref ? !mFolderThreadPref : mFolderThreadPref );
3479  mThreadBySubjectAction->setEnabled(
3480  mHeaders->folder() ? ( mThreadMessagesAction->isChecked()) : false );
3481  mThreadBySubjectAction->setChecked( mFolderThreadSubjPref );
3482 
3483  mNewFolderAction->setEnabled( !multiFolder && ( mFolder && mFolder->folderType() != KMFolderTypeSearch ));
3484  mRemoveDuplicatesAction->setEnabled( !multiFolder && mFolder && mFolder->canDeleteMessages() );
3485  mFolderShortCutCommandAction->setEnabled( !multiFolder );
3486 }
3487 
3488 
3489 #ifdef MALLOC_DEBUG
3490 static TQString fmt(long n) {
3491  char buf[32];
3492 
3493  if(n > 1024*1024*1024)
3494  sprintf(buf, "%0.2f GB", ((double)n)/1024.0/1024.0/1024.0);
3495  else if(n > 1024*1024)
3496  sprintf(buf, "%0.2f MB", ((double)n)/1024.0/1024.0);
3497  else if(n > 1024)
3498  sprintf(buf, "%0.2f KB", ((double)n)/1024.0);
3499  else
3500  sprintf(buf, "%ld Byte", n);
3501  return TQString(buf);
3502 }
3503 #endif
3504 
3505 void KMMainWidget::slotMemInfo() {
3506 #ifdef MALLOC_DEBUG
3507  struct mallinfo mi;
3508 
3509  mi = mallinfo();
3510  TQString s = TQString("\nMALLOC - Info\n\n"
3511  "Number of mmapped regions : %1\n"
3512  "Memory allocated in use : %2\n"
3513  "Memory allocated, not used: %3\n"
3514  "Memory total allocated : %4\n"
3515  "Max. freeable memory : %5\n")
3516  .arg(mi.hblks).arg(fmt(mi.uordblks)).arg(fmt(mi.fordblks))
3517  .arg(fmt(mi.arena)).arg(fmt(mi.keepcost));
3518  KMessageBox::information(0, s, "Malloc information", s);
3519 #endif
3520 }
3521 
3522 
3523 //-----------------------------------------------------------------------------
3524 void KMMainWidget::slotIntro()
3525 {
3526  if ( !mMsgView ) return;
3527 
3528  mMsgView->clear( true );
3529  // hide widgets that are in the way:
3530  if ( mSearchAndHeaders && mHeaders && mLongFolderList )
3531  mSearchAndHeaders->hide();
3532 
3533 
3534  mMsgView->displayAboutPage();
3535 
3536  mFolder = 0;
3537 }
3538 
3539 void KMMainWidget::slotShowStartupFolder()
3540 {
3541  if ( mFolderTree ) {
3542  mFolderTree->reload();
3543  mFolderTree->readConfig();
3544  // get rid of old-folders
3545  mFolderTree->cleanupConfigFile();
3546  }
3547 
3548  connect( kmkernel->filterMgr(), TQT_SIGNAL( filterListUpdated() ),
3549  this, TQT_SLOT( initializeFilterActions() ));
3550 
3551  // plug shortcut filter actions now
3552  initializeFilterActions();
3553 
3554  // plug folder shortcut actions
3555  initializeFolderShortcutActions();
3556 
3557  TQString newFeaturesMD5 = KMReaderWin::newFeaturesMD5();
3558  if ( kmkernel->firstStart() ||
3559  GlobalSettings::self()->previousNewFeaturesMD5() != newFeaturesMD5 ) {
3560  GlobalSettings::self()->setPreviousNewFeaturesMD5( newFeaturesMD5 );
3561  slotIntro();
3562  return;
3563  }
3564 
3565  KMFolder* startup = 0;
3566  if ( !mStartupFolder.isEmpty() ) {
3567  // find the startup-folder
3568  startup = kmkernel->findFolderById( mStartupFolder );
3569  }
3570  if ( !startup )
3571  startup = kmkernel->inboxFolder();
3572 
3573  if ( mFolderTree ) {
3574  mFolderTree->showFolder( startup );
3575  }
3576 }
3577 
3578 void KMMainWidget::slotShowTip()
3579 {
3580  KTipDialog::showTip( this, TQString(), true );
3581 }
3582 
3583 //-----------------------------------------------------------------------------
3584 void KMMainWidget::slotChangeCaption(TQListViewItem * i)
3585 {
3586  if ( !i ) return;
3587  // set the caption to the current full path
3588  TQStringList names;
3589  for ( TQListViewItem * item = i ; item ; item = item->parent() )
3590  names.prepend( item->text(0) );
3591  emit captionChangeRequest( names.join( "/" ) );
3592 }
3593 
3594 //-----------------------------------------------------------------------------
3595 void KMMainWidget::removeDuplicates()
3596 {
3597  if (!mFolder)
3598  return;
3599  KMFolder *oFolder = mFolder;
3600  mHeaders->setFolder(0);
3601  TQMap< TQString, TQValueList<int> > idMD5s;
3602  TQValueList<int> redundantIds;
3603  TQValueList<int>::Iterator kt;
3604  mFolder->open("removedups");
3605  for (int i = mFolder->count() - 1; i >= 0; --i) {
3606  TQString id = (*mFolder)[i]->msgIdMD5();
3607  if ( !id.isEmpty() ) {
3608  TQString subjMD5 = (*mFolder)[i]->strippedSubjectMD5();
3609  int other = -1;
3610  if ( idMD5s.contains(id) )
3611  other = idMD5s[id].first();
3612  else
3613  idMD5s[id].append( i );
3614  if ( other != -1 ) {
3615  TQString otherSubjMD5 = (*mFolder)[other]->strippedSubjectMD5();
3616  if (otherSubjMD5 == subjMD5)
3617  idMD5s[id].append( i );
3618  }
3619  }
3620  }
3621  TQMap< TQString, TQValueList<int> >::Iterator it;
3622  for ( it = idMD5s.begin(); it != idMD5s.end() ; ++it ) {
3623  TQValueList<int>::Iterator jt;
3624  bool finished = false;
3625  for ( jt = (*it).begin(); jt != (*it).end() && !finished; ++jt )
3626  if (!((*mFolder)[*jt]->isUnread())) {
3627  (*it).remove( jt );
3628  (*it).prepend( *jt );
3629  finished = true;
3630  }
3631  for ( jt = (*it).begin(), ++jt; jt != (*it).end(); ++jt )
3632  redundantIds.append( *jt );
3633  }
3634  qHeapSort( redundantIds );
3635  kt = redundantIds.end();
3636  int numDuplicates = 0;
3637  if (kt != redundantIds.begin()) do {
3638  mFolder->removeMsg( *(--kt) );
3639  ++numDuplicates;
3640  }
3641  while (kt != redundantIds.begin());
3642 
3643  mFolder->close("removedups");
3644  mHeaders->setFolder(oFolder);
3645  TQString msg;
3646  if ( numDuplicates )
3647  msg = i18n("Removed %n duplicate message.",
3648  "Removed %n duplicate messages.", numDuplicates );
3649  else
3650  msg = i18n("No duplicate messages found.");
3651  BroadcastStatus::instance()->setStatusMsg( msg );
3652 }
3653 
3654 
3655 //-----------------------------------------------------------------------------
3656 void KMMainWidget::slotUpdateUndo()
3657 {
3658  if (actionCollection()->action( "edit_undo" ))
3659  actionCollection()->action( "edit_undo" )->setEnabled( mHeaders->canUndo() );
3660 }
3661 
3662 
3663 //-----------------------------------------------------------------------------
3664 void KMMainWidget::clearFilterActions()
3665 {
3666  if ( !mFilterTBarActions.isEmpty() ) {
3667  if ( mGUIClient->factory() )
3668  mGUIClient->unplugActionList( "toolbar_filter_actions" );
3669  mFilterTBarActions.clear();
3670  }
3671  mApplyFilterActionsMenu->popupMenu()->clear();
3672  if ( !mFilterMenuActions.isEmpty() ) {
3673  if ( mGUIClient->factory() )
3674  mGUIClient->unplugActionList( "menu_filter_actions" );
3675  mFilterMenuActions.clear();
3676  }
3677  mFilterCommands.clear();
3678 }
3679 
3680 //-----------------------------------------------------------------------------
3681 void KMMainWidget::initializeFolderShortcutActions()
3682 {
3683 
3684  // If we are loaded as a part, this will be set to fals, since the part
3685  // does xml loading. Temporarily set to true, in that case, so the
3686  // accels are added to the collection as expected.
3687  bool old = actionCollection()->isAutoConnectShortcuts();
3688 
3689  actionCollection()->setAutoConnectShortcuts( true );
3690  TQValueList< TQGuardedPtr< KMFolder > > folders = kmkernel->allFolders();
3691  TQValueList< TQGuardedPtr< KMFolder > >::Iterator it = folders.begin();
3692  while ( it != folders.end() ) {
3693  KMFolder *folder = (*it);
3694  ++it;
3695  slotShortcutChanged( folder ); // load the initial accel
3696  }
3697  actionCollection()->setAutoConnectShortcuts( old );
3698 }
3699 
3700 
3701 //-----------------------------------------------------------------------------
3702 void KMMainWidget::initializeFilterActions()
3703 {
3704  TQString filterName, normalizedName;
3705  KMMetaFilterActionCommand *filterCommand;
3706  TDEAction *filterAction = 0;
3707 
3708  clearFilterActions();
3709  mApplyAllFiltersAction->plug(mApplyFilterActionsMenu->popupMenu());
3710  bool addedSeparator = false;
3711  TQValueListConstIterator<KMFilter*> it = kmkernel->filterMgr()->filters().constBegin();
3712  for ( ;it != kmkernel->filterMgr()->filters().constEnd(); ++it ) {
3713  if (!(*it)->isEmpty() && (*it)->configureShortcut()) {
3714  filterName = TQString("Filter %1").arg((*it)->name());
3715  normalizedName = filterName.replace(" ", "_");
3716  if (action(normalizedName.utf8()))
3717  continue;
3718  filterCommand = new KMMetaFilterActionCommand(*it, mHeaders, this);
3719  mFilterCommands.append(filterCommand);
3720  TQString as = i18n("Filter %1").arg((*it)->name());
3721  TQString icon = (*it)->icon();
3722  if ( icon.isEmpty() )
3723  icon = "gear";
3724  filterAction = new TDEAction(as, icon, (*it)->shortcut(), filterCommand,
3725  TQT_SLOT(start()), actionCollection(),
3726  normalizedName.local8Bit());
3727  if(!addedSeparator) {
3728  mApplyFilterActionsMenu->popupMenu()->insertSeparator();
3729  addedSeparator = !addedSeparator;
3730  mFilterMenuActions.append( new TDEActionSeparator());
3731  }
3732  filterAction->plug( mApplyFilterActionsMenu->popupMenu() );
3733  mFilterMenuActions.append(filterAction);
3734  if ( (*it)->configureToolbar() )
3735  mFilterTBarActions.append(filterAction);
3736  }
3737  }
3738  if ( !mFilterMenuActions.isEmpty() && mGUIClient->factory() )
3739  mGUIClient->plugActionList( "menu_filter_actions", mFilterMenuActions );
3740  if ( !mFilterTBarActions.isEmpty() && mGUIClient->factory() ) {
3741  mFilterTBarActions.prepend( mToolbarActionSeparator );
3742  mGUIClient->plugActionList( "toolbar_filter_actions", mFilterTBarActions );
3743  }
3744 }
3745 
3746 void KMMainWidget::slotFolderRemoved( KMFolder *folder )
3747 {
3748  mFolderShortcutCommands.remove( folder->idString() );
3749 }
3750 
3751 //-----------------------------------------------------------------------------
3752 void KMMainWidget::initializeIMAPActions( bool setState /* false the first time, true later on */ )
3753 {
3754  bool hasImapAccount = false;
3755  for( KMAccount *a = kmkernel->acctMgr()->first(); a;
3756  a = kmkernel->acctMgr()->next() ) {
3757  if ( a->type() == "cachedimap" ) {
3758  hasImapAccount = true;
3759  break;
3760  }
3761  }
3762  if ( hasImapAccount == ( mTroubleshootFolderAction != 0 ) )
3763  return; // nothing to do
3764 
3765  KXMLGUIFactory* factory = mGUIClient->factory();
3766  if ( factory )
3767  factory->removeClient( mGUIClient );
3768 
3769  if ( !mTroubleshootFolderAction ) {
3770  mTroubleshootFolderAction = new TDEAction( i18n("&Troubleshoot IMAP Cache..."), "wizard", 0,
3771  TQT_TQOBJECT(this), TQT_SLOT(slotTroubleshootFolder()), actionCollection(), "troubleshoot_folder" );
3772  if ( setState )
3773  updateFolderMenu(); // set initial state of the action
3774  } else {
3775  delete mTroubleshootFolderAction ;
3776  mTroubleshootFolderAction = 0;
3777  }
3778 
3779  if ( factory )
3780  factory->addClient( mGUIClient );
3781 }
3782 
3783 bool KMMainWidget::shortcutIsValid( const TDEShortcut &sc ) const
3784 {
3785  TDEActionPtrList actions = actionCollection()->actions();
3786  TDEActionPtrList::Iterator it( actions.begin() );
3787  for ( ; it != actions.end(); it++ ) {
3788  if ( (*it)->shortcut() == sc ) return false;
3789  }
3790  return true;
3791 }
3792 
3793 void KMMainWidget::slotShortcutChanged( KMFolder *folder )
3794 {
3795  // remove the old one, autodelete
3796  mFolderShortcutCommands.remove( folder->idString() );
3797  if ( folder->shortcut().isNull() )
3798  return;
3799 
3800  FolderShortcutCommand *c = new FolderShortcutCommand( this, folder );
3801  mFolderShortcutCommands.insert( folder->idString(), c );
3802 
3803  TQString actionlabel = TQString( "FolderShortcut %1").arg( folder->prettyURL() );
3804  TQString actionname = TQString( "FolderShortcut %1").arg( folder->idString() );
3805  TQString normalizedName = actionname.replace(" ", "_");
3806  TDEAction* action =
3807  new TDEAction(actionlabel, folder->shortcut(), c, TQT_SLOT(start()),
3808  actionCollection(), normalizedName.local8Bit());
3809  action->setIcon( folder->unreadIconPath() );
3810  c->setAction( action ); // will be deleted along with the command
3811 }
3812 
3813 //-----------------------------------------------------------------------------
3814 TQString KMMainWidget::findCurrentImapPath()
3815 {
3816  TQString startPath;
3817  if (!mFolder) return startPath;
3818  if (mFolder->folderType() == KMFolderTypeImap)
3819  {
3820  startPath = static_cast<KMFolderImap*>(mFolder->storage())->imapPath();
3821  } else if (mFolder->folderType() == KMFolderTypeCachedImap)
3822  {
3823  startPath = static_cast<KMFolderCachedImap*>(mFolder->storage())->imapPath();
3824  }
3825  return startPath;
3826 }
3827 
3828 //-----------------------------------------------------------------------------
3829 ImapAccountBase* KMMainWidget::findCurrentImapAccountBase()
3830 {
3831  ImapAccountBase* account = 0;
3832  if (!mFolder) return account;
3833  if (mFolder->folderType() == KMFolderTypeImap)
3834  {
3835  account = static_cast<KMFolderImap*>(mFolder->storage())->account();
3836  } else if (mFolder->folderType() == KMFolderTypeCachedImap)
3837  {
3838  account = static_cast<KMFolderCachedImap*>(mFolder->storage())->account();
3839  }
3840  return account;
3841 }
3842 
3843 //-----------------------------------------------------------------------------
3844 void KMMainWidget::slotSubscriptionDialog()
3845 {
3846  if ( !kmkernel->askToGoOnline() )
3847  return;
3848  ImapAccountBase* account = findCurrentImapAccountBase();
3849  if ( !account ) return;
3850  const TQString startPath = findCurrentImapPath();
3851 
3852  // KSubscription sets "DestruciveClose"
3853  SubscriptionDialog * dialog =
3854  new SubscriptionDialog(this, i18n("Subscription"), account, startPath);
3855  if ( dialog->exec() ) {
3856  // start a new listing
3857  if (mFolder->folderType() == KMFolderTypeImap)
3858  static_cast<KMFolderImap*>(mFolder->storage())->account()->listDirectory();
3859  }
3860 }
3861 
3862 //-----------------------------------------------------------------------------
3863 void KMMainWidget::slotLocalSubscriptionDialog()
3864 {
3865  ImapAccountBase* account = findCurrentImapAccountBase();
3866  if ( !account ) return;
3867 
3868  const TQString startPath = findCurrentImapPath();
3869  // KSubscription sets "DestruciveClose"
3870  LocalSubscriptionDialog *dialog =
3871  new LocalSubscriptionDialog(this, i18n("Local Subscription"), account, startPath);
3872  if ( dialog->exec() ) {
3873  // start a new listing
3874  if (mFolder->folderType() == KMFolderTypeImap)
3875  static_cast<KMFolderImap*>(mFolder->storage())->account()->listDirectory();
3876  }
3877 }
3878 
3879 //-----------------------------------------------------------------------------
3880 void KMMainWidget::slotFolderTreeColumnsChanged()
3881 {
3882  mTotalColumnToggle->setChecked( mFolderTree->isTotalActive() );
3883  mUnreadColumnToggle->setChecked( mFolderTree->isUnreadActive() );
3884  mSizeColumnToggle->setChecked( mFolderTree->isSizeActive() );
3885  mUnreadTextToggle->setChecked( !mFolderTree->isUnreadActive() );
3886 }
3887 
3888 void KMMainWidget::toggleSystemTray()
3889 {
3890  if ( !mSystemTray && GlobalSettings::self()->systemTrayEnabled() ) {
3891  mSystemTray = new KMSystemTray();
3892  }
3893  else if ( mSystemTray && !GlobalSettings::self()->systemTrayEnabled() ) {
3894  // Get rid of system tray on user's request
3895  kdDebug(5006) << "deleting systray" << endl;
3896  delete mSystemTray;
3897  mSystemTray = 0;
3898  }
3899 
3900  // Set mode of systemtray. If mode has changed, tray will handle this.
3901  if ( mSystemTray )
3902  mSystemTray->setMode( GlobalSettings::self()->systemTrayPolicy() );
3903 }
3904 
3905 //-----------------------------------------------------------------------------
3906 void KMMainWidget::slotAntiSpamWizard()
3907 {
3908  AntiSpamWizard wiz( AntiSpamWizard::AntiSpam, this, folderTree() );
3909  wiz.exec();
3910 }
3911 
3912 //-----------------------------------------------------------------------------
3913 void KMMainWidget::slotAntiVirusWizard()
3914 {
3915  AntiSpamWizard wiz( AntiSpamWizard::AntiVirus, this, folderTree() );
3916  wiz.exec();
3917 }
3918 
3919 //-----------------------------------------------------------------------------
3920 void KMMainWidget::slotFilterLogViewer()
3921 {
3922  FilterLogDialog * dlg = new FilterLogDialog( 0 );
3923  dlg->show();
3924 }
3925 
3926 //-----------------------------------------------------------------------------
3927 void KMMainWidget::updateFileMenu()
3928 {
3929  TQStringList actList = kmkernel->acctMgr()->getAccounts();
3930 
3931  actionCollection()->action("check_mail")->setEnabled( actList.size() > 0 );
3932  actionCollection()->action("check_mail_in")->setEnabled( actList.size() > 0 );
3933  actionCollection()->action("favorite_check_mail")->setEnabled( actList.size() > 0 );
3934 }
3935 
3936 
3937 //-----------------------------------------------------------------------------
3938 void KMMainWidget::setAccelsEnabled( bool enabled )
3939 {
3940  actionCollection()->tdeaccel()->setEnabled( enabled );
3941 }
3942 
3943 
3944 //-----------------------------------------------------------------------------
3945 KMSystemTray *KMMainWidget::systray() const
3946 {
3947  return mSystemTray;
3948 }
3949 
3950 //-----------------------------------------------------------------------------
3951 TQString KMMainWidget::overrideEncoding() const
3952 {
3953  if ( mMsgView )
3954  return mMsgView->overrideEncoding();
3955  else
3956  return GlobalSettings::self()->overrideCharacterEncoding();
3957 }
3958 
3959 void KMMainWidget::slotCreateTodo()
3960 {
3961  KMMessage *msg = mHeaders->currentMsg();
3962  if ( !msg )
3963  return;
3964  KMCommand *command = new CreateTodoCommand( this, msg );
3965  command->start();
3966 }
3967 
3968 void KMMainWidget::setupFolderView()
3969 {
3970  if ( GlobalSettings::self()->enableFavoriteFolderView() ) {
3971  mFolderView = mFolderViewSplitter;
3972  mFolderTree->reparent( mFolderViewSplitter, 0, TQPoint( 0, 0 ) );
3973  mFolderViewSplitter->show();
3974  mFavoriteFolderView->show();
3975  } else {
3976  mFolderView = mFolderTree;
3977  mFolderViewSplitter->hide();
3978  mFavoriteFolderView->hide();
3979  }
3980  mFolderView->reparent( mFolderViewParent, 0, TQPoint( 0, 0 ) );
3981  mFolderViewParent->moveToFirst( mFolderView );
3982  mFolderTree->show();
3983 }
3984 
3985 
3986 void KMMainWidget::slotRequestFullSearchFromQuickSearch()
3987 {
3988  slotSearch();
3989 #ifdef HAVE_INDEXLIB
3990  return;
3991 #endif
3992  assert( mSearchWin );
3993  KMSearchPattern pattern;
3994  pattern.append( KMSearchRule::createInstance( "<message>", KMSearchRule::FuncContains, mQuickSearchLine->currentSearchTerm() ) );
3995  int status = mQuickSearchLine->currenStatus();
3996  if ( status != 0 ) {
3997  pattern.append( new KMSearchRuleStatus( status ) );
3998  }
3999  mSearchWin->setSearchPattern( pattern );
4000 }
4001 
4002 void KMMainWidget::updateVactionScripStatus(bool active)
4003 {
4004  mVacationIndicatorActive = active;
4005  if ( active ) {
4006  mVacationScriptIndicator->setText( i18n("Out of office reply active") );
4007  mVacationScriptIndicator->setPaletteBackgroundColor( TQt::yellow );
4008  mVacationScriptIndicator->setCursor( TQCursor( TQt::PointingHandCursor ) );
4009  mVacationScriptIndicator->show();
4010  } else {
4011  mVacationScriptIndicator->hide();
4012  }
4013 }
4014 
void initHeader(uint identity=0)
Initialize header fields.
Definition: kmmessage.cpp:1717
The SearchWindow class provides a dialog for triggering a search on folders and storing that search a...
Definition: searchwindow.h:69
TQString to() const
Get or set the 'To' header field.
Definition: kmmessage.cpp:1896
bool ignoreNewMail() const
Returns true if the user doesn't want to get notified about new mail in this folder.
Definition: kmfolder.h:526
static KMKernel * self()
normal control stuff
Definition: kmkernel.h:259
static KMSearchRule * createInstance(const TQCString &field=0, Function function=FuncContains, const TQString &contents=TQString())
Create a search rule of a certain type by instantiating the appro- priate subclass depending on the f...
Dialog for handling the properties of a mail folder.
Definition: kmfolderdia.h:199
The widget that shows the contents of folders.
Definition: kmheaders.h:47
KMail anti-spam wizard.
Manages common actions that can be performed on one or more messages.
This class represents a search to be performed against the status of a messsage.
virtual TQString label() const
Returns the label of the folder for visualization.
Definition: kmfolder.cpp:581
int open(const char *owner)
Open folder for access.
Definition: kmfolder.cpp:479
TQString from() const
Get or set the 'From' header field.
Definition: kmmessage.cpp:2017
sets a cursor and makes sure it's restored on destruction Create a KCursorSaver object when you want ...
Definition: kcursorsaver.h:14
void setMsgSerNum(unsigned long newMsgSerNum=0)
Sets the message serial number.
Definition: kmmessage.cpp:225
bool isComplete() const
Return true if the complete message is available without referring to the backing store.
Definition: kmmessage.h:867
bool transferInProgress() const
Return, if the message should not be deleted.
Definition: kmmessage.cpp:238
Extends HeaderListQuickSearch to also search inside message bodies using KMMsgIndex.
static TQString newFeaturesMD5()
Returns the MD5 hash for the list of new features.
TQString idString() const
Returns a string that can be used to identify this folder.
Definition: kmfolder.cpp:705
TDEMainWindow * mainWin()
returns a reference to the first Mainwin or a temporary Mainwin
Definition: kmkernel.cpp:2251
void setReadyToShow(bool v)
Set if the message is ready to be shown.
Definition: kmmessage.h:874
bool hasUnencryptedMsg() const
Returns TRUE if the message contains an unencrypted copy of itself.
Definition: kmmessage.h:134
static TQStringList transportNames()
Returns the list for transport names.
Diagnostic info for Sieve.
KMSystemTray extends KSystemTray and handles system tray notification for KMail.
Definition: kmsystemtray.h:42
The account manager is responsible for creating accounts of various types via the factory method crea...
This is a Mime Message.
Definition: kmmessage.h:68
KMFolderType folderType() const
Returns the type of this folder.
Definition: kmfolder.cpp:233
This class implements a "reader window", that is a window used for reading or viewing messages.
Definition: kmreaderwin.h:75
TQString msgId() const
Get or set the 'Message-Id' header field.
Definition: kmmessage.cpp:2184
This class is an abstraction of a search over messages.
This class encapsulates the visual appearance of message headers.
Definition: headerstyle.h:51
KMail Filter Log Collector.
Definition: filterlogdlg.h:49
TQString subject() const
Get or set the 'Subject' header field.
Definition: kmmessage.cpp:2051
The TemplateParser transforms a message with a given template.
Mail folder.
Definition: kmfolder.h:69
KMMessage * unencryptedMsg() const
Returns an unencrypted copy of this message or 0 if none exists.
Definition: kmmessage.h:137
virtual TQString prettyURL() const
URL of the node for visualization purposes.
Definition: kmfolder.cpp:593