kmail

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