kmail

kmmainwidget.cpp

00001 // -*- mode: C++; c-file-style: "gnu" -*-
00002 // kmmainwidget.cpp
00003 //#define MALLOC_DEBUG 1
00004 
00005 #ifdef HAVE_CONFIG_H
00006 #include <config.h>
00007 #endif
00008 
00009 #include <kwin.h>
00010 
00011 #ifdef MALLOC_DEBUG
00012 #include <malloc.h>
00013 #endif
00014 
00015 #undef Unsorted // X headers...
00016 #include <qaccel.h>
00017 #include <qlayout.h>
00018 #include <qhbox.h>
00019 #include <qvbox.h>
00020 #include <qpopupmenu.h>
00021 #include <qptrlist.h>
00022 
00023 #include <kopenwith.h>
00024 
00025 #include <kmessagebox.h>
00026 
00027 #include <kpopupmenu.h>
00028 #include <kaccelmanager.h>
00029 #include <kglobalsettings.h>
00030 #include <kstdaccel.h>
00031 #include <kkeydialog.h>
00032 #include <kcharsets.h>
00033 #include <knotifyclient.h>
00034 #include <kdebug.h>
00035 #include <kapplication.h>
00036 #include <kfiledialog.h>
00037 #include <ktip.h>
00038 #include <knotifydialog.h>
00039 #include <kstandarddirs.h>
00040 #include <dcopclient.h>
00041 #include <kaddrbook.h>
00042 #include <kaccel.h>
00043 #include <kstringhandler.h>
00044 
00045 #include <qvaluevector.h>
00046 
00047 #include "globalsettings.h"
00048 #include "kcursorsaver.h"
00049 #include "broadcaststatus.h"
00050 using KPIM::BroadcastStatus;
00051 #include "kmfoldermgr.h"
00052 #include "kmfolderdia.h"
00053 #include "accountmanager.h"
00054 using KMail::AccountManager;
00055 #include "kmfilter.h"
00056 #include "kmfoldertree.h"
00057 #include "kmreadermainwin.h"
00058 #include "kmfoldercachedimap.h"
00059 #include "kmfolderimap.h"
00060 #include "kmacctcachedimap.h"
00061 #include "composer.h"
00062 #include "kmfolderseldlg.h"
00063 #include "kmfiltermgr.h"
00064 #include "messagesender.h"
00065 #include "kmaddrbook.h"
00066 #include "kmversion.h"
00067 #include "searchwindow.h"
00068 using KMail::SearchWindow;
00069 #include "kmacctfolder.h"
00070 #include "undostack.h"
00071 #include "kmcommands.h"
00072 #include "kmmainwin.h"
00073 #include "kmsystemtray.h"
00074 #include "imapaccountbase.h"
00075 #include "transportmanager.h"
00076 using KMail::ImapAccountBase;
00077 #include "vacation.h"
00078 using KMail::Vacation;
00079 #include "favoritefolderview.h"
00080 
00081 #include <qsignalmapper.h>
00082 
00083 #include "subscriptiondialog.h"
00084 using KMail::SubscriptionDialog;
00085 #include "localsubscriptiondialog.h"
00086 using KMail::LocalSubscriptionDialog;
00087 #include "attachmentstrategy.h"
00088 using KMail::AttachmentStrategy;
00089 #include "headerstrategy.h"
00090 using KMail::HeaderStrategy;
00091 #include "headerstyle.h"
00092 using KMail::HeaderStyle;
00093 #include "folderjob.h"
00094 using KMail::FolderJob;
00095 #include "mailinglist-magic.h"
00096 #include "antispamwizard.h"
00097 using KMail::AntiSpamWizard;
00098 #include "filterlogdlg.h"
00099 using KMail::FilterLogDialog;
00100 #include <headerlistquicksearch.h>
00101 #include "klistviewindexedsearchline.h"
00102 using KMail::HeaderListQuickSearch;
00103 #include "kmheaders.h"
00104 #include "mailinglistpropertiesdialog.h"
00105 #include "templateparser.h"
00106 
00107 #if !defined(NDEBUG)
00108     #include "sievedebugdialog.h"
00109     using KMail::SieveDebugDialog;
00110 #endif
00111 
00112 #include <libkpimidentities/identity.h>
00113 #include <libkpimidentities/identitymanager.h>
00114 
00115 #include <assert.h>
00116 #include <kstatusbar.h>
00117 #include <kstaticdeleter.h>
00118 #include <kaction.h>
00119 
00120 #include <kmime_mdn.h>
00121 #include <kmime_header_parsing.h>
00122 using namespace KMime;
00123 using KMime::Types::AddrSpecList;
00124 
00125 #include "progressmanager.h"
00126 using KPIM::ProgressManager;
00127 
00128 #include "managesievescriptsdialog.h"
00129 #include <qstylesheet.h>
00130 
00131 #include "customtemplates.h"
00132 #include "customtemplates_kfg.h"
00133 
00134 #include "kmmainwidget.moc"
00135 
00136 QValueList<KMMainWidget*>* KMMainWidget::s_mainWidgetList = 0;
00137 static KStaticDeleter<QValueList<KMMainWidget*> > mwlsd;
00138 
00139 //-----------------------------------------------------------------------------
00140 KMMainWidget::KMMainWidget(QWidget *parent, const char *name,
00141                            KXMLGUIClient *aGUIClient,
00142                            KActionCollection *actionCollection, KConfig* config ) :
00143     QWidget(parent, name),
00144     mFavoritesCheckMailAction( 0 ),
00145     mFavoriteFolderView( 0 ),
00146     mFolderView( 0 ),
00147     mFolderViewParent( 0 ),
00148     mFolderViewSplitter( 0 ),
00149     mQuickSearchLine( 0 ),
00150     mShowBusySplashTimer( 0 ),
00151     mShowingOfflineScreen( false ),
00152     mMsgActions( 0 ),
00153     mVacationIndicatorActive( false )
00154 {
00155   // must be the first line of the constructor:
00156   mStartupDone = false;
00157   mSearchWin = 0;
00158   mIntegrated  = true;
00159   mFolder = 0;
00160   mTemplateFolder = 0;
00161   mFolderThreadPref = false;
00162   mFolderThreadSubjPref = true;
00163   mReaderWindowActive = true;
00164   mReaderWindowBelow = true;
00165   mFolderHtmlPref = false;
00166   mFolderHtmlLoadExtPref = false;
00167   mSystemTray = 0;
00168   mDestructed = false;
00169   mActionCollection = actionCollection;
00170   mTopLayout = new QVBoxLayout(this);
00171   mFilterMenuActions.setAutoDelete(true);
00172   mFilterTBarActions.setAutoDelete(false);
00173   mFilterCommands.setAutoDelete(true);
00174   mFolderShortcutCommands.setAutoDelete(true);
00175   mJob = 0;
00176   mConfig = config;
00177   mGUIClient = aGUIClient;
00178 
00179   mCustomReplyActionMenu = 0;
00180   mCustomReplyAllActionMenu = 0;
00181   mCustomForwardActionMenu = 0;
00182   mCustomReplyMapper = 0;
00183   mCustomReplyAllMapper = 0;
00184   mCustomForwardMapper = 0;
00185 
00186   // FIXME This should become a line separator as soon as the API
00187   // is extended in kdelibs.
00188   mToolbarActionSeparator = new KActionSeparator( actionCollection );
00189 
00190   if( !s_mainWidgetList )
00191     mwlsd.setObject( s_mainWidgetList, new QValueList<KMMainWidget*>() );
00192   s_mainWidgetList->append( this );
00193 
00194   mPanner1Sep << 1 << 1;
00195   mPanner2Sep << 1 << 1;
00196 
00197   setMinimumSize(400, 300);
00198 
00199   readPreConfig();
00200   createWidgets();
00201 
00202   setupActions();
00203 
00204   readConfig();
00205 
00206   activatePanners();
00207 
00208   QTimer::singleShot( 0, this, SLOT( slotShowStartupFolder() ));
00209 
00210   connect( kmkernel->acctMgr(), SIGNAL( checkedMail( bool, bool, const QMap<QString, int> & ) ),
00211            this, SLOT( slotMailChecked( bool, bool, const QMap<QString, int> & ) ) );
00212 
00213   connect( kmkernel->acctMgr(), SIGNAL( accountAdded( KMAccount* ) ),
00214            this, SLOT( initializeIMAPActions() ) );
00215   connect( kmkernel->acctMgr(), SIGNAL( accountRemoved( KMAccount* ) ),
00216            this, SLOT( initializeIMAPActions() ) );
00217 
00218   connect(kmkernel, SIGNAL( configChanged() ),
00219           this, SLOT( slotConfigChanged() ));
00220 
00221   // display the full path to the folder in the caption
00222   connect(mFolderTree, SIGNAL(currentChanged(QListViewItem*)),
00223       this, SLOT(slotChangeCaption(QListViewItem*)));
00224   connect(mFolderTree, SIGNAL(selectionChanged()),
00225           SLOT(updateFolderMenu()) );
00226 
00227   connect(kmkernel->folderMgr(), SIGNAL(folderRemoved(KMFolder*)),
00228           this, SLOT(slotFolderRemoved(KMFolder*)));
00229 
00230   connect(kmkernel->imapFolderMgr(), SIGNAL(folderRemoved(KMFolder*)),
00231           this, SLOT(slotFolderRemoved(KMFolder*)));
00232 
00233   connect(kmkernel->dimapFolderMgr(), SIGNAL(folderRemoved(KMFolder*)),
00234           this, SLOT(slotFolderRemoved(KMFolder*)));
00235 
00236   connect(kmkernel->searchFolderMgr(), SIGNAL(folderRemoved(KMFolder*)),
00237           this, SLOT(slotFolderRemoved(KMFolder*)));
00238 
00239   connect( kmkernel, SIGNAL( onlineStatusChanged( GlobalSettings::EnumNetworkState::type ) ),
00240            this, SLOT( slotUpdateOnlineStatus( GlobalSettings::EnumNetworkState::type ) ) );
00241 
00242   toggleSystemTray();
00243 
00244   // must be the last line of the constructor:
00245   mStartupDone = true;
00246 
00247 
00248   KMainWindow *mainWin = dynamic_cast<KMainWindow*>(topLevelWidget());
00249   KStatusBar *sb =  mainWin ? mainWin->statusBar() : 0;
00250   mVacationScriptIndicator = new KStatusBarLabel( QString(), 0, sb );
00251   mVacationScriptIndicator->hide();
00252   connect( mVacationScriptIndicator, SIGNAL(itemReleased(int)), SLOT(slotEditVacation()) );
00253   if ( GlobalSettings::checkOutOfOfficeOnStartup() )
00254     QTimer::singleShot( 0, this, SLOT(slotCheckVacation()) );
00255 }
00256 
00257 
00258 //-----------------------------------------------------------------------------
00259 //The kernel may have already been deleted when this method is called,
00260 //perform all cleanup that requires the kernel in destruct()
00261 KMMainWidget::~KMMainWidget()
00262 {
00263   s_mainWidgetList->remove( this );
00264   destruct();
00265 }
00266 
00267 
00268 //-----------------------------------------------------------------------------
00269 //This method performs all cleanup that requires the kernel to exist.
00270 void KMMainWidget::destruct()
00271 {
00272   if (mDestructed)
00273     return;
00274   if (mSearchWin)
00275     mSearchWin->close();
00276   writeConfig();
00277   writeFolderConfig();
00278   delete mHeaders;
00279   delete mFolderTree;
00280   delete mSystemTray;
00281   delete mMsgView;
00282   mDestructed = true;
00283 }
00284 
00285 
00286 //-----------------------------------------------------------------------------
00287 void KMMainWidget::readPreConfig(void)
00288 {
00289   const KConfigGroup geometry( KMKernel::config(), "Geometry" );
00290   const KConfigGroup reader( KMKernel::config(), "Reader" );
00291 
00292   mLongFolderList = geometry.readEntry( "FolderList", "long" ) != "short";
00293   mReaderWindowActive = geometry.readEntry( "readerWindowMode", "below" ) != "hide";
00294   mReaderWindowBelow = geometry.readEntry( "readerWindowMode", "below" ) == "below";
00295   mThreadPref = geometry.readBoolEntry( "nestedMessages", false );
00296 
00297   mHtmlPref = reader.readBoolEntry( "htmlMail", false );
00298   mHtmlLoadExtPref = reader.readBoolEntry( "htmlLoadExternal", false );
00299   mEnableFavoriteFolderView = GlobalSettings::self()->enableFavoriteFolderView();
00300 }
00301 
00302 
00303 //-----------------------------------------------------------------------------
00304 void KMMainWidget::readFolderConfig(void)
00305 {
00306   if (!mFolder)
00307     return;
00308 
00309   KConfig *config = KMKernel::config();
00310   KConfigGroupSaver saver(config, "Folder-" + mFolder->idString());
00311   mFolderThreadPref = config->readBoolEntry( "threadMessagesOverride", false );
00312   mFolderThreadSubjPref = config->readBoolEntry( "threadMessagesBySubject", true );
00313   mFolderHtmlPref = config->readBoolEntry( "htmlMailOverride", false );
00314   mFolderHtmlLoadExtPref = config->readBoolEntry( "htmlLoadExternalOverride", false );
00315 }
00316 
00317 
00318 //-----------------------------------------------------------------------------
00319 void KMMainWidget::writeFolderConfig(void)
00320 {
00321   if (!mFolder)
00322     return;
00323 
00324   KConfig *config = KMKernel::config();
00325   KConfigGroupSaver saver(config, "Folder-" + mFolder->idString());
00326   config->writeEntry( "threadMessagesOverride", mFolderThreadPref );
00327   config->writeEntry( "threadMessagesBySubject", mFolderThreadSubjPref );
00328   config->writeEntry( "htmlMailOverride", mFolderHtmlPref );
00329   config->writeEntry( "htmlLoadExternalOverride", mFolderHtmlLoadExtPref );
00330 }
00331 
00332 
00333 //-----------------------------------------------------------------------------
00334 void KMMainWidget::readConfig(void)
00335 {
00336   KConfig *config = KMKernel::config();
00337 
00338   bool oldLongFolderList =  mLongFolderList;
00339   bool oldReaderWindowActive = mReaderWindowActive;
00340   bool oldReaderWindowBelow = mReaderWindowBelow;
00341   bool oldFavoriteFolderView = mEnableFavoriteFolderView;
00342 
00343   QString str;
00344   QSize siz;
00345 
00346   if (mStartupDone)
00347   {
00348     writeConfig();
00349 
00350     readPreConfig();
00351     mHeaders->refreshNestedState();
00352 
00353     bool layoutChanged = ( oldLongFolderList != mLongFolderList )
00354                     || ( oldReaderWindowActive != mReaderWindowActive )
00355                     || ( oldReaderWindowBelow != mReaderWindowBelow )
00356                     || ( oldFavoriteFolderView != mEnableFavoriteFolderView );
00357 
00358 
00359     if( layoutChanged ) {
00360       hide();
00361       // delete all panners
00362       delete mPanner1; // will always delete the others
00363       createWidgets();
00364     }
00365 
00366   }
00367 
00368   { // area for config group "Geometry"
00369     KConfigGroupSaver saver(config, "Geometry");
00370     // size of the mainwin
00371     QSize defaultSize(750,560);
00372     siz = config->readSizeEntry("MainWin", &defaultSize);
00373     if (!siz.isEmpty())
00374       resize(siz);
00375     // default width of the foldertree
00376     static const int folderpanewidth = 250;
00377 
00378     const int folderW = config->readNumEntry( "FolderPaneWidth", folderpanewidth );
00379     const int headerW = config->readNumEntry( "HeaderPaneWidth", width()-folderpanewidth );
00380     const int headerH = config->readNumEntry( "HeaderPaneHeight", 180 );
00381     const int readerH = config->readNumEntry( "ReaderPaneHeight", 280 );
00382 
00383     mPanner1Sep.clear();
00384     mPanner2Sep.clear();
00385     QValueList<int> & widths = mLongFolderList ? mPanner1Sep : mPanner2Sep ;
00386     QValueList<int> & heights = mLongFolderList ? mPanner2Sep : mPanner1Sep ;
00387 
00388     widths << folderW << headerW;
00389     heights << headerH << readerH;
00390 
00391     bool layoutChanged = ( oldLongFolderList != mLongFolderList )
00392                     || ( oldReaderWindowActive != mReaderWindowActive )
00393                     || ( oldReaderWindowBelow != mReaderWindowBelow );
00394 
00395     if (!mStartupDone || layoutChanged )
00396     {
00400       // The columns are shown by default.
00401 
00402       const int unreadColumn = config->readNumEntry("UnreadColumn", 1);
00403       const int totalColumn = config->readNumEntry("TotalColumn", 2);
00404       const int sizeColumn = config->readNumEntry("SizeColumn", 3);
00405 
00406       /* we need to _activate_ them in the correct order
00407       * this is ugly because we can't use header()->moveSection
00408       * but otherwise the restoreLayout from KMFolderTree
00409       * doesn't know that to do */
00410       if (unreadColumn == 1)
00411         mFolderTree->addUnreadColumn( i18n("Unread"), 70 );
00412       else if (totalColumn == 1)
00413         mFolderTree->addTotalColumn( i18n("Total"), 70 );
00414       else if (sizeColumn == 1)
00415         mFolderTree->addSizeColumn( i18n("Size"), 70 );
00416 
00417       if (unreadColumn == 2)
00418         mFolderTree->addUnreadColumn( i18n("Unread"), 70 );
00419       else if (totalColumn == 2)
00420         mFolderTree->addTotalColumn( i18n("Total"), 70 );
00421       else if (sizeColumn == 2)
00422         mFolderTree->addSizeColumn( i18n("Size"), 70 );
00423 
00424       if (unreadColumn == 3)
00425         mFolderTree->addUnreadColumn( i18n("Unread"), 70 );
00426       else if (totalColumn == 3)
00427         mFolderTree->addTotalColumn( i18n("Total"), 70 );
00428       else if (sizeColumn == 3)
00429         mFolderTree->addSizeColumn( i18n("Size"), 70 );
00430 
00431       mUnreadColumnToggle->setChecked( mFolderTree->isUnreadActive() );
00432       mUnreadTextToggle->setChecked( !mFolderTree->isUnreadActive() );
00433       mTotalColumnToggle->setChecked( mFolderTree->isTotalActive() );
00434       mSizeColumnToggle->setChecked( mFolderTree->isSizeActive() );
00435 
00436       mFolderTree->updatePopup();
00437     }
00438   }
00439 
00440   if (mMsgView)
00441     mMsgView->readConfig();
00442 
00443   mHeaders->readConfig();
00444   mHeaders->restoreLayout(KMKernel::config(), "Header-Geometry");
00445 
00446   if ( mFolderViewSplitter && !GlobalSettings::self()->folderViewSplitterPosition().isEmpty() ) {
00447     mFolderViewSplitter->setSizes( GlobalSettings::self()->folderViewSplitterPosition() );
00448   } else {
00449     QValueList<int> defaults;
00450     defaults << (int)(height() * 0.2) << (int)(height() * 0.8);
00451     mFolderViewSplitter->setSizes( defaults );
00452   }
00453 
00454   mFolderTree->readConfig();
00455   if ( mFavoriteFolderView )
00456     mFavoriteFolderView->readConfig();
00457   mFavoritesCheckMailAction->setEnabled( GlobalSettings::self()->enableFavoriteFolderView() );
00458 
00459   { // area for config group "General"
00460     KConfigGroupSaver saver(config, "General");
00461     mBeepOnNew = config->readBoolEntry("beep-on-mail", false);
00462     mConfirmEmpty = config->readBoolEntry("confirm-before-empty", true);
00463     // startup-Folder, defaults to system-inbox
00464     mStartupFolder = config->readEntry("startupFolder", kmkernel->inboxFolder()->idString());
00465     if (!mStartupDone)
00466     {
00467       // check mail on startup
00468       bool check = config->readBoolEntry("checkmail-startup", false);
00469       if (check)
00470         // do it after building the kmmainwin, so that the progressdialog is available
00471         QTimer::singleShot( 0, this, SLOT( slotCheckMail() ) );
00472     }
00473   }
00474 
00475   // reload foldertree
00476   mFolderTree->reload();
00477 
00478   // Re-activate panners
00479   if (mStartupDone)
00480   {
00481     // Update systray
00482     toggleSystemTray();
00483 
00484     bool layoutChanged = ( oldLongFolderList != mLongFolderList )
00485                     || ( oldReaderWindowActive != mReaderWindowActive )
00486                     || ( oldReaderWindowBelow != mReaderWindowBelow )
00487                     || ( oldFavoriteFolderView != mEnableFavoriteFolderView );
00488     if ( layoutChanged ) {
00489       activatePanners();
00490     }
00491 
00492     mFolderTree->showFolder( mFolder );
00493 
00494     // sanders - New code
00495     mHeaders->setFolder(mFolder);
00496     if (mMsgView) {
00497       int aIdx = mHeaders->currentItemIndex();
00498       if (aIdx != -1)
00499         mMsgView->setMsg( mFolder->getMsg(aIdx), true );
00500       else
00501         mMsgView->clear( true );
00502     }
00503     updateMessageActions();
00504     show();
00505     // sanders - Maybe this fixes a bug?
00506 
00507   }
00508   updateMessageMenu();
00509   updateFileMenu();
00510 }
00511 
00512 
00513 //-----------------------------------------------------------------------------
00514 void KMMainWidget::writeConfig(void)
00515 {
00516   QString s;
00517   KConfig *config = KMKernel::config();
00518   KConfigGroup geometry( config, "Geometry" );
00519 
00520   if (mMsgView)
00521     mMsgView->writeConfig();
00522 
00523   if ( mFolderViewSplitter )
00524     GlobalSettings::setFolderViewSplitterPosition( mFolderViewSplitter->sizes() );
00525   mFolderTree->writeConfig();
00526   if ( mFavoriteFolderView )
00527     mFavoriteFolderView->writeConfig();
00528 
00529   geometry.writeEntry( "MainWin", this->geometry().size() );
00530 
00531   const QValueList<int> widths = ( mLongFolderList ? mPanner1 : mPanner2 )->sizes();
00532   const QValueList<int> heights = ( mLongFolderList ? mPanner2 : mPanner1 )->sizes();
00533 
00534   geometry.writeEntry( "FolderPaneWidth", widths[0] );
00535   geometry.writeEntry( "HeaderPaneWidth", widths[1] );
00536 
00537   // Only save when the widget is shown (to avoid saving a wrong value)
00538   if ( mSearchAndHeaders && mSearchAndHeaders->isShown() ) {
00539     geometry.writeEntry( "HeaderPaneHeight", heights[0] );
00540     geometry.writeEntry( "ReaderPaneHeight", heights[1] );
00541   }
00542 
00543   // save the state of the unread/total-columns
00544   geometry.writeEntry( "UnreadColumn", mFolderTree->unreadIndex() );
00545   geometry.writeEntry( "TotalColumn", mFolderTree->totalIndex() );
00546   geometry.writeEntry( "SizeColumn", mFolderTree->sizeIndex() );
00547 }
00548 
00549 
00550 //-----------------------------------------------------------------------------
00551 void KMMainWidget::createWidgets(void)
00552 {
00553   // Create the splitters according to the layout settings
00554   QWidget *headerParent = 0,
00555             *mimeParent = 0, *messageParent = 0;
00556 
00557   const bool opaqueResize = KGlobalSettings::opaqueResize();
00558   if ( mLongFolderList ) {
00559     // superior splitter: folder tree vs. rest
00560     // inferior splitter: headers vs. message vs. mime tree
00561     mPanner1 = new QSplitter( Qt::Horizontal, this, "panner 1" );
00562     mPanner1->setOpaqueResize( opaqueResize );
00563     Qt::Orientation orientation = mReaderWindowBelow ? Qt::Vertical : Qt::Horizontal;
00564     mPanner2 = new QSplitter( orientation, mPanner1, "panner 2" );
00565     mPanner2->setOpaqueResize( opaqueResize );
00566     mPanner2->setChildrenCollapsible( false );
00567     mFolderViewParent = mPanner1;
00568     headerParent = mimeParent = messageParent = mPanner2;
00569   } else /* !mLongFolderList */ {
00570     // superior splitter: ( folder tree + headers ) vs. message vs. mime
00571     // inferior splitter: folder tree vs. headers
00572     mPanner1 = new QSplitter( Qt::Vertical, this, "panner 1" );
00573     mPanner1->setOpaqueResize( opaqueResize );
00574     mPanner1->setChildrenCollapsible( false );
00575     mPanner2 = new QSplitter( Qt::Horizontal, mPanner1, "panner 2" );
00576     mPanner2->setOpaqueResize( opaqueResize );
00577     headerParent = mFolderViewParent = mPanner2;
00578     mimeParent = messageParent = mPanner1;
00579   }
00580 
00581 #ifndef NDEBUG
00582   if( mPanner1 ) mPanner1->dumpObjectTree();
00583   if( mPanner2 ) mPanner2->dumpObjectTree();
00584 #endif
00585 
00586   mTopLayout->add( mPanner1 );
00587 
00588   // BUG -sanders these accelerators stop working after switching
00589   // between long/short folder layout
00590   // Probably need to disconnect them first.
00591 
00592   // create list of messages
00593 #ifndef NDEBUG
00594   headerParent->dumpObjectTree();
00595 #endif
00596   mSearchAndHeaders = new QVBox( headerParent );
00597   mSearchToolBar = new KToolBar( mSearchAndHeaders, "search toolbar");
00598   mSearchToolBar->setMovingEnabled(false);
00599   mSearchToolBar->boxLayout()->setSpacing( KDialog::spacingHint() );
00600   QLabel *label = new QLabel( i18n("S&earch:"), mSearchToolBar, "kde toolbar widget" );
00601 
00602 
00603   mHeaders = new KMHeaders(this, mSearchAndHeaders, "headers");
00604 #ifdef HAVE_INDEXLIB
00605   mQuickSearchLine = new KListViewIndexedSearchLine( mSearchToolBar, mHeaders,
00606                                                     actionCollection(), "headers quick search line" );
00607 #else
00608   mQuickSearchLine = new HeaderListQuickSearch( mSearchToolBar, mHeaders,
00609                         actionCollection(), "headers quick search line" );
00610 #endif
00611   label->setBuddy( mQuickSearchLine );
00612   connect( mQuickSearchLine, SIGNAL( requestFullSearch() ),
00613            this, SLOT( slotRequestFullSearchFromQuickSearch() ) );
00614   mSearchToolBar->setStretchableWidget( mQuickSearchLine );
00615     connect( mHeaders, SIGNAL( messageListUpdated() ),
00616            mQuickSearchLine, SLOT( updateSearch() ) );
00617   if ( !GlobalSettings::self()->quickSearchActive() ) mSearchToolBar->hide();
00618 
00619   if (mReaderWindowActive) {
00620     connect(mHeaders, SIGNAL(selected(KMMessage*)),
00621             this, SLOT(slotMsgSelected(KMMessage*)));
00622   }
00623   connect(mHeaders, SIGNAL(activated(KMMessage*)),
00624           this, SLOT(slotMsgActivated(KMMessage*)));
00625   connect( mHeaders, SIGNAL( selectionChanged() ),
00626            SLOT( startUpdateMessageActionsTimer() ) );
00627   QAccel *accel = actionCollection()->kaccel();
00628   accel->connectItem(accel->insertItem(SHIFT+Key_Left),
00629                      mHeaders, SLOT(selectPrevMessage()));
00630   accel->connectItem(accel->insertItem(SHIFT+Key_Right),
00631                      mHeaders, SLOT(selectNextMessage()));
00632 
00633   if (mReaderWindowActive) {
00634     mMsgView = new KMReaderWin(messageParent, this, actionCollection(), 0 );
00635     if ( mMsgActions ) {
00636       mMsgActions->setMessageView( mMsgView );
00637     }
00638 
00639     connect(mMsgView, SIGNAL(replaceMsgByUnencryptedVersion()),
00640         this, SLOT(slotReplaceMsgByUnencryptedVersion()));
00641     connect(mMsgView, SIGNAL(popupMenu(KMMessage&,const KURL&,const QPoint&)),
00642         this, SLOT(slotMsgPopup(KMMessage&,const KURL&,const QPoint&)));
00643     connect(mMsgView, SIGNAL(urlClicked(const KURL&,int)),
00644         mMsgView, SLOT(slotUrlClicked()));
00645     connect(mHeaders, SIGNAL(maybeDeleting()),
00646         mMsgView, SLOT(clearCache()));
00647     connect(mMsgView, SIGNAL(noDrag()),
00648         mHeaders, SLOT(slotNoDrag()));
00649     accel->connectItem(accel->insertItem(Key_Up),
00650         mMsgView, SLOT(slotScrollUp()));
00651     accel->connectItem(accel->insertItem(Key_Down),
00652         mMsgView, SLOT(slotScrollDown()));
00653     accel->connectItem(accel->insertItem(Key_Prior),
00654         mMsgView, SLOT(slotScrollPrior()));
00655     accel->connectItem(accel->insertItem(Key_Next),
00656         mMsgView, SLOT(slotScrollNext()));
00657   } else {
00658     mMsgView = NULL;
00659   }
00660 
00661   KAction *action;
00662 
00663   action = new KAction( i18n("Move Message to Folder"), Key_M, this,
00664                SLOT(slotMoveMsg()), actionCollection(),
00665                "move_message_to_folder" );
00666   action->plugAccel( actionCollection()->kaccel() );
00667 
00668   action = new KAction( i18n("Copy Message to Folder"), Key_C, this,
00669                SLOT(slotCopyMsg()), actionCollection(),
00670                "copy_message_to_folder" );
00671   action->plugAccel( actionCollection()->kaccel() );
00672 
00673   action = new KAction( i18n("Jump to Folder"), Key_J, this,
00674                SLOT(slotJumpToFolder()), actionCollection(),
00675                "jump_to_folder" );
00676   action->plugAccel( actionCollection()->kaccel() );
00677 
00678   // create list of folders
00679   mFolderViewSplitter = new QSplitter( Qt::Vertical, mFolderViewParent );
00680   mFolderViewSplitter->setOpaqueResize( KGlobalSettings::opaqueResize() );
00681   mFavoriteFolderView = new KMail::FavoriteFolderView( this, mFolderViewSplitter );
00682   if ( mFavoritesCheckMailAction )
00683   connect( mFavoritesCheckMailAction, SIGNAL(activated()), mFavoriteFolderView, SLOT(checkMail()) );
00684   QWidget *folderTreeParent = mFolderViewParent;
00685   if ( GlobalSettings::enableFavoriteFolderView() ) {
00686     folderTreeParent = mFolderViewSplitter;
00687     mFolderView = mFolderViewSplitter;
00688   }
00689   mFolderTree = new KMFolderTree(this, folderTreeParent, "folderTree");
00690   if ( !GlobalSettings::enableFavoriteFolderView() ) {
00691      mFolderView = mFolderTree;
00692   }
00693   connect( mFolderTree, SIGNAL(folderSelected(KMFolder*)),
00694             mFavoriteFolderView, SLOT(folderTreeSelectionChanged(KMFolder*)) );
00695 
00696   connect(mFolderTree, SIGNAL(folderSelected(KMFolder*)),
00697       this, SLOT(folderSelected(KMFolder*)));
00698   connect( mFolderTree, SIGNAL( folderSelected( KMFolder* ) ),
00699            mQuickSearchLine, SLOT( reset() ) );
00700   connect(mFolderTree, SIGNAL(folderSelectedUnread(KMFolder*)),
00701       this, SLOT(folderSelectedUnread(KMFolder*)));
00702   connect(mFolderTree, SIGNAL(folderDrop(KMFolder*)),
00703       this, SLOT(slotMoveMsgToFolder(KMFolder*)));
00704   connect(mFolderTree, SIGNAL(folderDropCopy(KMFolder*)),
00705           this, SLOT(slotCopyMsgToFolder(KMFolder*)));
00706   connect(mFolderTree, SIGNAL(columnsChanged()),
00707           this, SLOT(slotFolderTreeColumnsChanged()));
00708 
00709   if ( mFavoriteFolderView ) {
00710     connect( mFavoriteFolderView, SIGNAL(folderDrop(KMFolder*)), SLOT(slotMoveMsgToFolder(KMFolder*)) );
00711     connect( mFavoriteFolderView, SIGNAL(folderDropCopy(KMFolder*)), SLOT(slotCopyMsgToFolder(KMFolder*)) );
00712   }
00713 
00714   //Commands not worthy of menu items, but that deserve configurable keybindings
00715   mRemoveDuplicatesAction = new KAction(
00716     i18n("Remove Duplicate Messages"), CTRL+Key_Asterisk, this,
00717     SLOT(removeDuplicates()), actionCollection(), "remove_duplicate_messages");
00718   action->plugAccel( actionCollection()->kaccel() );
00719 
00720   action = new KAction(
00721     i18n("Abort Current Operation"), Key_Escape, ProgressManager::instance(),
00722     SLOT(slotAbortAll()), actionCollection(), "cancel" );
00723   action->plugAccel( actionCollection()->kaccel() );
00724 
00725   action = new KAction(
00726    i18n("Focus on Next Folder"), CTRL+Key_Right, mFolderTree,
00727    SLOT(incCurrentFolder()), actionCollection(), "inc_current_folder");
00728   action->plugAccel( actionCollection()->kaccel() );
00729 
00730   action = new KAction(
00731    i18n("Focus on Previous Folder"), CTRL+Key_Left, mFolderTree,
00732    SLOT(decCurrentFolder()), actionCollection(), "dec_current_folder");
00733   action->plugAccel( actionCollection()->kaccel() );
00734 
00735   action = new KAction(
00736    i18n("Select Folder with Focus"), CTRL+Key_Space, mFolderTree,
00737    SLOT(selectCurrentFolder()), actionCollection(), "select_current_folder");
00738   action->plugAccel( actionCollection()->kaccel() );
00739 
00740   action = new KAction(
00741     i18n("Focus on Next Message"), ALT+Key_Right, mHeaders,
00742     SLOT(incCurrentMessage()), actionCollection(), "inc_current_message");
00743   action->plugAccel( actionCollection()->kaccel() );
00744 
00745   action = new KAction(
00746     i18n("Focus on Previous Message"), ALT+Key_Left, mHeaders,
00747     SLOT(decCurrentMessage()), actionCollection(), "dec_current_message");
00748   action->plugAccel( actionCollection()->kaccel() );
00749 
00750   action = new KAction(
00751     i18n("Select Message with Focus"), ALT+Key_Space, mHeaders,
00752     SLOT( selectCurrentMessage() ), actionCollection(), "select_current_message");
00753   action->plugAccel( actionCollection()->kaccel() );
00754 
00755   connect( kmkernel->outboxFolder(), SIGNAL( msgRemoved(int, QString) ),
00756            SLOT( startUpdateMessageActionsTimer() ) );
00757   connect( kmkernel->outboxFolder(), SIGNAL( msgAdded(int) ),
00758            SLOT( startUpdateMessageActionsTimer() ) );
00759 }
00760 
00761 
00762 //-----------------------------------------------------------------------------
00763 void KMMainWidget::activatePanners(void)
00764 {
00765   if (mMsgView) {
00766     QObject::disconnect( mMsgView->copyAction(),
00767         SIGNAL( activated() ),
00768         mMsgView, SLOT( slotCopySelectedText() ));
00769   }
00770 
00771   setupFolderView();
00772   if ( mLongFolderList ) {
00773     mSearchAndHeaders->reparent( mPanner2, 0, QPoint( 0, 0 ) );
00774     if (mMsgView) {
00775       mMsgView->reparent( mPanner2, 0, QPoint( 0, 0 ) );
00776       mPanner2->moveToLast( mMsgView );
00777     }
00778     mFolderViewParent = mPanner1;
00779     mFolderView->reparent( mFolderViewParent, 0, QPoint( 0, 0 ) );
00780     mPanner1->moveToLast( mPanner2 );
00781     mPanner1->setSizes( mPanner1Sep );
00782     mPanner1->setResizeMode( mFolderView, QSplitter::KeepSize );
00783     mPanner2->setSizes( mPanner2Sep );
00784     mPanner2->setResizeMode( mSearchAndHeaders, QSplitter::KeepSize );
00785   } else /* !mLongFolderList */ {
00786     mFolderViewParent = mPanner2;
00787     mFolderView->reparent( mFolderViewParent, 0, QPoint( 0, 0 ) );
00788     mSearchAndHeaders->reparent( mPanner2, 0, QPoint( 0, 0 ) );
00789     mPanner2->moveToLast( mSearchAndHeaders );
00790     mPanner1->moveToFirst( mPanner2 );
00791     if (mMsgView) {
00792       mMsgView->reparent( mPanner1, 0, QPoint( 0, 0 ) );
00793       mPanner1->moveToLast( mMsgView );
00794     }
00795     mPanner1->setSizes( mPanner1Sep );
00796     mPanner2->setSizes( mPanner2Sep );
00797     mPanner1->setResizeMode( mPanner2, QSplitter::KeepSize );
00798     mPanner2->setResizeMode( mFolderView, QSplitter::KeepSize );
00799   }
00800 
00801   if (mMsgView) {
00802     QObject::connect( mMsgView->copyAction(),
00803             SIGNAL( activated() ),
00804             mMsgView, SLOT( slotCopySelectedText() ));
00805   }
00806 }
00807 
00808 
00809 //-----------------------------------------------------------------------------
00810 void KMMainWidget::hide()
00811 {
00812   QWidget::hide();
00813 }
00814 
00815 
00816 //-----------------------------------------------------------------------------
00817 void KMMainWidget::show()
00818 {
00819   QWidget::show();
00820 }
00821 
00822 //-------------------------------------------------------------------------
00823 void KMMainWidget::slotSearch()
00824 {
00825   if(!mSearchWin)
00826   {
00827     mSearchWin = new SearchWindow(this, "Search", mFolder, false);
00828     connect(mSearchWin, SIGNAL(destroyed()),
00829         this, SLOT(slotSearchClosed()));
00830   }
00831   else
00832   {
00833     mSearchWin->activateFolder(mFolder);
00834   }
00835 
00836   mSearchWin->show();
00837   KWin::activateWindow( mSearchWin->winId() );
00838 }
00839 
00840 
00841 //-------------------------------------------------------------------------
00842 void KMMainWidget::slotSearchClosed()
00843 {
00844   mSearchWin = 0;
00845 }
00846 
00847 
00848 //-------------------------------------------------------------------------
00849 void KMMainWidget::slotFind()
00850 {
00851   if( mMsgView )
00852     mMsgView->slotFind();
00853 }
00854 
00855 
00856 //-----------------------------------------------------------------------------
00857 void KMMainWidget::slotHelp()
00858 {
00859   kapp->invokeHelp();
00860 }
00861 
00862 
00863 //-----------------------------------------------------------------------------
00864 void KMMainWidget::slotFilter()
00865 {
00866   kmkernel->filterMgr()->openDialog( this );
00867 }
00868 
00869 
00870 //-----------------------------------------------------------------------------
00871 void KMMainWidget::slotPopFilter()
00872 {
00873   kmkernel->popFilterMgr()->openDialog( this );
00874 }
00875 
00876 void KMMainWidget::slotManageSieveScripts()
00877 {
00878   if ( !kmkernel->askToGoOnline() ) {
00879     return;
00880   }
00881   KMail::ManageSieveScriptsDialog * dlg = new KMail::ManageSieveScriptsDialog( this );
00882   dlg->show();
00883 }
00884 
00885 
00886 //-----------------------------------------------------------------------------
00887 void KMMainWidget::slotAddrBook()
00888 {
00889   KAddrBookExternal::openAddressBook(this);
00890 }
00891 
00892 
00893 //-----------------------------------------------------------------------------
00894 void KMMainWidget::slotImport()
00895 {
00896   KRun::runCommand("kmailcvt");
00897 }
00898 
00899 //-----------------------------------------------------------------------------
00900 void KMMainWidget::slotCheckMail()
00901 {
00902   if ( !kmkernel->askToGoOnline() ) {
00903     return;
00904   }
00905   kmkernel->acctMgr()->checkMail(true);
00906 }
00907 
00908 //-----------------------------------------------------------------------------
00909 void KMMainWidget::slotCheckOneAccount(int item)
00910 {
00911   if ( !kmkernel->askToGoOnline() ) {
00912     return;
00913   }
00914   kmkernel->acctMgr()->intCheckMail(item);
00915 }
00916 
00917 //-----------------------------------------------------------------------------
00918 void KMMainWidget::slotMailChecked( bool newMail, bool sendOnCheck,
00919                                     const QMap<QString, int> & newInFolder )
00920 {
00921   const bool sendOnAll =
00922     GlobalSettings::self()->sendOnCheck() == GlobalSettings::EnumSendOnCheck::SendOnAllChecks;
00923   const bool sendOnManual =
00924     GlobalSettings::self()->sendOnCheck() == GlobalSettings::EnumSendOnCheck::SendOnManualChecks;
00925   if( !kmkernel->isOffline() && ( sendOnAll || (sendOnManual && sendOnCheck ) ) )
00926     slotSendQueued();
00927 
00928   if ( !newMail || newInFolder.isEmpty() )
00929     return;
00930 
00931   kapp->dcopClient()->emitDCOPSignal( "unreadCountChanged()", QByteArray() );
00932 
00933   // build summary for new mail message
00934   bool showNotification = false;
00935   QString summary;
00936   QStringList keys( newInFolder.keys() );
00937   keys.sort();
00938   for ( QStringList::const_iterator it = keys.begin();
00939         it != keys.end();
00940         ++it ) {
00941     kdDebug(5006) << newInFolder.find( *it ).data() << " new message(s) in "
00942                   << *it << endl;
00943 
00944     KMFolder *folder = kmkernel->findFolderById( *it );
00945 
00946     if ( folder && !folder->ignoreNewMail() ) {
00947       showNotification = true;
00948       if ( GlobalSettings::self()->verboseNewMailNotification() ) {
00949         summary += "<br>" + i18n( "1 new message in %1",
00950                                   "%n new messages in %1",
00951                                   newInFolder.find( *it ).data() )
00952                             .arg( folder->prettyURL() );
00953       }
00954     }
00955   }
00956 
00957   // update folder menus in case some mail got filtered to trash/current folder
00958   // and we can enable "empty trash/move all to trash" action etc.
00959   updateFolderMenu();
00960 
00961   if ( !showNotification )
00962     return;
00963 
00964   if ( GlobalSettings::self()->verboseNewMailNotification() ) {
00965     summary = i18n( "%1 is a list of the number of new messages per folder",
00966                     "<b>New mail arrived</b><br>%1" )
00967               .arg( summary );
00968   }
00969   else {
00970     summary = i18n( "New mail arrived" );
00971   }
00972 
00973   if(kmkernel->xmlGuiInstance()) {
00974     KNotifyClient::Instance instance(kmkernel->xmlGuiInstance());
00975     KNotifyClient::event( topLevelWidget()->winId(), "new-mail-arrived",
00976                           summary );
00977   }
00978   else
00979     KNotifyClient::event( topLevelWidget()->winId(), "new-mail-arrived",
00980                           summary );
00981 
00982   if (mBeepOnNew) {
00983     KNotifyClient::beep();
00984   }
00985 }
00986 
00987 
00988 //-----------------------------------------------------------------------------
00989 void KMMainWidget::slotCompose()
00990 {
00991   KMail::Composer * win;
00992   KMMessage* msg = new KMMessage;
00993 
00994   if ( mFolder ) {
00995       msg->initHeader( mFolder->identity() );
00996       TemplateParser parser( msg, TemplateParser::NewMessage,
00997     "", false, false, false, false );
00998       parser.process( NULL, mFolder );
00999       win = KMail::makeComposer( msg, mFolder->identity() );
01000   } else {
01001       msg->initHeader();
01002       TemplateParser parser( msg, TemplateParser::NewMessage,
01003     "", false, false, false, false );
01004       parser.process( NULL, NULL );
01005       win = KMail::makeComposer( msg );
01006   }
01007 
01008   win->show();
01009 
01010 }
01011 
01012 //-----------------------------------------------------------------------------
01013 // TODO: do we want the list sorted alphabetically?
01014 void KMMainWidget::slotShowNewFromTemplate()
01015 {
01016   if ( mFolder ) {
01017     const KPIM::Identity & ident =
01018       kmkernel->identityManager()->identityForUoidOrDefault( mFolder->identity() );
01019     mTemplateFolder = kmkernel->folderMgr()->findIdString( ident.templates() );
01020   }
01021   else mTemplateFolder = kmkernel->templatesFolder();
01022   if ( !mTemplateFolder )
01023     return;
01024 
01025   mTemplateMenu->popupMenu()->clear();
01026   for ( int idx = 0; idx<mTemplateFolder->count(); ++idx ) {
01027     KMMsgBase *mb = mTemplateFolder->getMsgBase( idx );
01028 
01029     QString subj = mb->subject();
01030     if ( subj.isEmpty() ) subj = i18n("No Subject");
01031     mTemplateMenu->popupMenu()->insertItem(
01032       KStringHandler::rsqueeze( subj.replace( "&", "&&" ) ), idx );
01033   }
01034 }
01035 
01036 //-----------------------------------------------------------------------------
01037 void KMMainWidget::slotNewFromTemplate( int id )
01038 {
01039   if ( !mTemplateFolder )
01040     return;
01041   newFromTemplate(mTemplateFolder->getMsg( id ) );
01042 }
01043 
01044 //-----------------------------------------------------------------------------
01045 void KMMainWidget::newFromTemplate( KMMessage *msg )
01046 {
01047   if ( !msg )
01048     return;
01049   KMCommand *command = new KMUseTemplateCommand( this, msg );
01050   command->start();
01051 }
01052 
01053 //-----------------------------------------------------------------------------
01054 void KMMainWidget::slotPostToML()
01055 {
01056   if ( mFolder && mFolder->isMailingListEnabled() ) {
01057     KMCommand *command = new KMMailingListPostCommand( this, mFolder );
01058     command->start();
01059   }
01060   else
01061     slotCompose();
01062 }
01063 
01064 //-----------------------------------------------------------------------------
01065 void KMMainWidget::slotFolderMailingListProperties()
01066 {
01067   if (!mFolderTree) return;
01068   KMFolderTreeItem *item = static_cast<KMFolderTreeItem*>( mFolderTree->currentItem() );
01069   if ( !item ) return;
01070   KMFolder* folder = item->folder();
01071   if ( folder ) {
01072     ( new KMail::MailingListFolderPropertiesDialog( this, folder ) )->show();
01073   }
01074 }
01075 
01076 //-----------------------------------------------------------------------------
01077 void KMMainWidget::slotFolderShortcutCommand()
01078 {
01079   if (!mFolderTree) return;
01080   KMFolderTreeItem *item = static_cast<KMFolderTreeItem*>( mFolderTree->currentItem() );
01081   if ( item )
01082     item->assignShortcut();
01083 }
01084 
01085 
01086 //-----------------------------------------------------------------------------
01087 void KMMainWidget::slotModifyFolder()
01088 {
01089   if (!mFolderTree) return;
01090   KMFolderTreeItem *item = static_cast<KMFolderTreeItem*>( mFolderTree->currentItem() );
01091   if ( item )
01092     modifyFolder( item );
01093 }
01094 
01095 //-----------------------------------------------------------------------------
01096 void KMMainWidget::modifyFolder( KMFolderTreeItem* folderItem )
01097 {
01098   KMFolder* folder = folderItem->folder();
01099   KMFolderTree* folderTree = static_cast<KMFolderTree *>( folderItem->listView() );
01100   KMFolderDialog props( folder, folder->parent(), folderTree,
01101                         i18n("Properties of Folder %1").arg( folder->label() ) );
01102   props.exec();
01103   updateFolderMenu();
01104 }
01105 
01106 //-----------------------------------------------------------------------------
01107 void KMMainWidget::slotExpireFolder()
01108 {
01109   QString     str;
01110   bool        canBeExpired = true;
01111 
01112   if (!mFolder) return;
01113 
01114   if (!mFolder->isAutoExpire()) {
01115     canBeExpired = false;
01116   } else if (mFolder->getUnreadExpireUnits()==expireNever &&
01117          mFolder->getReadExpireUnits()==expireNever) {
01118     canBeExpired = false;
01119   }
01120 
01121   if (!canBeExpired) {
01122     str = i18n("This folder does not have any expiry options set");
01123     KMessageBox::information(this, str);
01124     return;
01125   }
01126   KConfig           *config = KMKernel::config();
01127   KConfigGroupSaver saver(config, "General");
01128 
01129   if (config->readBoolEntry("warn-before-expire", true)) {
01130     str = i18n("<qt>Are you sure you want to expire the folder <b>%1</b>?</qt>").arg(QStyleSheet::escape( mFolder->label() ));
01131     if (KMessageBox::warningContinueCancel(this, str, i18n("Expire Folder"),
01132                        i18n("&Expire"))
01133     != KMessageBox::Continue) return;
01134   }
01135 
01136   mFolder->expireOldMessages( true /*immediate*/);
01137 }
01138 
01139 //-----------------------------------------------------------------------------
01140 void KMMainWidget::slotEmptyFolder()
01141 {
01142   QString str;
01143 
01144   if (!mFolder) return;
01145   bool isTrash = kmkernel->folderIsTrash(mFolder);
01146 
01147   if (mConfirmEmpty)
01148   {
01149     QString title = (isTrash) ? i18n("Empty Trash") : i18n("Move to Trash");
01150     QString text = (isTrash) ?
01151       i18n("Are you sure you want to empty the trash folder?") :
01152       i18n("<qt>Are you sure you want to move all messages from "
01153            "folder <b>%1</b> to the trash?</qt>").arg( QStyleSheet::escape( mFolder->label() ) );
01154 
01155     if (KMessageBox::warningContinueCancel(this, text, title, KGuiItem( title, "edittrash"))
01156       != KMessageBox::Continue) return;
01157   }
01158   KCursorSaver busy(KBusyPtr::busy());
01159   slotMarkAll();
01160   if (isTrash) {
01161     /* Don't ask for confirmation again when deleting, the user has already
01162        confirmed. */
01163     slotDeleteMsg( false );
01164   }
01165   else
01166     slotTrashMsg();
01167 
01168   if (mMsgView) mMsgView->clearCache();
01169 
01170   if ( !isTrash )
01171     BroadcastStatus::instance()->setStatusMsg(i18n("Moved all messages to the trash"));
01172 
01173   updateMessageActions();
01174 
01175   // Disable empty trash/move all to trash action - we've just deleted/moved all folder
01176   // contents.
01177   mEmptyFolderAction->setEnabled( false );
01178 }
01179 
01180 
01181 //-----------------------------------------------------------------------------
01182 void KMMainWidget::slotRemoveFolder()
01183 {
01184   QString str;
01185   QDir dir;
01186 
01187   if ( !mFolder ) return;
01188   if ( mFolder->isSystemFolder() ) return;
01189   if ( mFolder->isReadOnly() ) return;
01190 
01191   QString title;
01192   if ( mFolder->folderType() == KMFolderTypeSearch ) {
01193     title = i18n("Delete Search");
01194     str = i18n("<qt>Are you sure you want to delete the search <b>%1</b>?<br>"
01195                 "Any messages it shows will still be available in their original folder.</qt>")
01196            .arg( QStyleSheet::escape( mFolder->label() ) );
01197   } else {
01198     title = i18n("Delete Folder");
01199     if ( mFolder->count() == 0 ) {
01200       if ( !mFolder->child() || mFolder->child()->isEmpty() ) {
01201         str = i18n("<qt>Are you sure you want to delete the empty folder "
01202                    "<b>%1</b>?</qt>")
01203               .arg( QStyleSheet::escape( mFolder->label() ) );
01204       }
01205       else {
01206         str = i18n("<qt>Are you sure you want to delete the empty folder "
01207                    "<b>%1</b> and all its subfolders? Those subfolders might "
01208                    "not be empty and their contents will be discarded as well. "
01209                    "<p><b>Beware</b> that discarded messages are not saved "
01210                    "into your Trash folder and are permanently deleted.</qt>")
01211               .arg( QStyleSheet::escape( mFolder->label() ) );
01212       }
01213     } else {
01214       if ( !mFolder->child() || mFolder->child()->isEmpty() ) {
01215         str = i18n("<qt>Are you sure you want to delete the folder "
01216                    "<b>%1</b>, discarding its contents? "
01217                    "<p><b>Beware</b> that discarded messages are not saved "
01218                    "into your Trash folder and are permanently deleted.</qt>")
01219               .arg( QStyleSheet::escape( mFolder->label() ) );
01220       }
01221       else {
01222         str = i18n("<qt>Are you sure you want to delete the folder <b>%1</b> "
01223                    "and all its subfolders, discarding their contents? "
01224                    "<p><b>Beware</b> that discarded messages are not saved "
01225                    "into your Trash folder and are permanently deleted.</qt>")
01226             .arg( QStyleSheet::escape( mFolder->label() ) );
01227       }
01228     }
01229   }
01230 
01231   if (KMessageBox::warningContinueCancel(this, str, title,
01232                                          KGuiItem( i18n("&Delete"), "editdelete"))
01233       == KMessageBox::Continue)
01234   {
01235     if ( mFolder->hasAccounts() ) {
01236       // this folder has an account, so we need to change that to the inbox
01237       for ( AccountList::Iterator it (mFolder->acctList()->begin() ),
01238              end( mFolder->acctList()->end() ); it != end; ++it ) {
01239         (*it)->setFolder( kmkernel->inboxFolder() );
01240         KMessageBox::information(this,
01241             i18n("<qt>The folder you deleted was associated with the account "
01242               "<b>%1</b> which delivered mail into it. The folder the account "
01243               "delivers new mail into was reset to the main Inbox folder.</qt>").arg( (*it)->name()));
01244       }
01245     }
01246     if (mFolder->folderType() == KMFolderTypeImap)
01247       kmkernel->imapFolderMgr()->remove(mFolder);
01248     else if (mFolder->folderType() == KMFolderTypeCachedImap) {
01249       // Deleted by user -> tell the account (see KMFolderCachedImap::listDirectory2)
01250       KMFolderCachedImap* storage = static_cast<KMFolderCachedImap*>( mFolder->storage() );
01251       KMAcctCachedImap* acct = storage->account();
01252       if ( acct )
01253         acct->addDeletedFolder( mFolder );
01254 
01255       kmkernel->dimapFolderMgr()->remove(mFolder);
01256     }
01257     else if (mFolder->folderType() == KMFolderTypeSearch)
01258       kmkernel->searchFolderMgr()->remove(mFolder);
01259     else
01260       kmkernel->folderMgr()->remove(mFolder);
01261   }
01262 }
01263 
01264 //-----------------------------------------------------------------------------
01265 void KMMainWidget::slotMarkAllAsRead()
01266 {
01267   if (!mFolder)
01268     return;
01269   mFolder->markUnreadAsRead();
01270 }
01271 
01272 //-----------------------------------------------------------------------------
01273 void KMMainWidget::slotCompactFolder()
01274 {
01275   if (mFolder) {
01276     int idx = mHeaders->currentItemIndex();
01277     KCursorSaver busy(KBusyPtr::busy());
01278     mFolder->compact( KMFolder::CompactNow );
01279     // setCurrentItemByIndex will override the statusbar message, so save/restore it
01280     QString statusMsg = BroadcastStatus::instance()->statusMsg();
01281     mHeaders->setCurrentItemByIndex(idx);
01282     BroadcastStatus::instance()->setStatusMsg( statusMsg );
01283   }
01284 }
01285 
01286 
01287 //-----------------------------------------------------------------------------
01288 void KMMainWidget::slotRefreshFolder()
01289 {
01290   if (mFolder)
01291   {
01292     if ( mFolder->folderType() == KMFolderTypeImap || mFolder->folderType() == KMFolderTypeCachedImap ) {
01293       if ( !kmkernel->askToGoOnline() ) {
01294         return;
01295       }
01296     }
01297 
01298     if (mFolder->folderType() == KMFolderTypeImap)
01299     {
01300       KMFolderImap *imap = static_cast<KMFolderImap*>(mFolder->storage());
01301       imap->getAndCheckFolder();
01302     } else if ( mFolder->folderType() == KMFolderTypeCachedImap ) {
01303       KMFolderCachedImap* f = static_cast<KMFolderCachedImap*>( mFolder->storage() );
01304       f->account()->processNewMailSingleFolder( mFolder );
01305     }
01306   }
01307 }
01308 
01309 void KMMainWidget::slotTroubleshootFolder()
01310 {
01311   if (mFolder)
01312   {
01313     if ( mFolder->folderType() == KMFolderTypeCachedImap ) {
01314       KMFolderCachedImap* f = static_cast<KMFolderCachedImap*>( mFolder->storage() );
01315       f->slotTroubleshoot();
01316     }
01317   }
01318 }
01319 
01320 void KMMainWidget::slotInvalidateIMAPFolders() {
01321   if ( KMessageBox::warningContinueCancel( this,
01322           i18n("Are you sure you want to refresh the IMAP cache?\n"
01323            "This will remove all changes that you have done "
01324            "locally to your IMAP folders."),
01325       i18n("Refresh IMAP Cache"), i18n("&Refresh") ) == KMessageBox::Continue )
01326     kmkernel->acctMgr()->invalidateIMAPFolders();
01327 }
01328 
01329 //-----------------------------------------------------------------------------
01330 void KMMainWidget::slotExpireAll() {
01331   KConfig    *config = KMKernel::config();
01332   int        ret = 0;
01333 
01334   KConfigGroupSaver saver(config, "General");
01335 
01336   if (config->readBoolEntry("warn-before-expire", true)) {
01337     ret = KMessageBox::warningContinueCancel(KMainWindow::memberList->first(),
01338              i18n("Are you sure you want to expire all old messages?"),
01339              i18n("Expire Old Messages?"), i18n("Expire"));
01340     if (ret != KMessageBox::Continue) {
01341       return;
01342     }
01343   }
01344 
01345   kmkernel->expireAllFoldersNow();
01346 }
01347 
01348 //-----------------------------------------------------------------------------
01349 void KMMainWidget::slotCompactAll()
01350 {
01351   KCursorSaver busy(KBusyPtr::busy());
01352   kmkernel->compactAllFolders();
01353 }
01354 
01355 
01356 //-----------------------------------------------------------------------------
01357 void KMMainWidget::slotOverrideHtml()
01358 {
01359   if( mHtmlPref == mFolderHtmlPref ) {
01360     int result = KMessageBox::warningContinueCancel( this,
01361       // the warning text is taken from configuredialog.cpp:
01362       i18n( "Use of HTML in mail will make you more vulnerable to "
01363         "\"spam\" and may increase the likelihood that your system will be "
01364         "compromised by other present and anticipated security exploits." ),
01365       i18n( "Security Warning" ),
01366       i18n( "Use HTML" ),
01367       "OverrideHtmlWarning", false);
01368     if( result == KMessageBox::Cancel ) {
01369       mPreferHtmlAction->setChecked( false );
01370       return;
01371     }
01372   }
01373   mFolderHtmlPref = !mFolderHtmlPref;
01374   if (mMsgView) {
01375     mMsgView->setHtmlOverride(mFolderHtmlPref);
01376     mMsgView->update( true );
01377   }
01378 }
01379 
01380 //-----------------------------------------------------------------------------
01381 void KMMainWidget::slotOverrideHtmlLoadExt()
01382 {
01383   if( mHtmlLoadExtPref == mFolderHtmlLoadExtPref ) {
01384     int result = KMessageBox::warningContinueCancel( this,
01385       // the warning text is taken from configuredialog.cpp:
01386       i18n( "Loading external references in html mail will make you more vulnerable to "
01387         "\"spam\" and may increase the likelihood that your system will be "
01388         "compromised by other present and anticipated security exploits." ),
01389       i18n( "Security Warning" ),
01390       i18n( "Load External References" ),
01391       "OverrideHtmlLoadExtWarning", false);
01392     if( result == KMessageBox::Cancel ) {
01393       mPreferHtmlLoadExtAction->setChecked( false );
01394       return;
01395     }
01396   }
01397   mFolderHtmlLoadExtPref = !mFolderHtmlLoadExtPref;
01398   if (mMsgView) {
01399     mMsgView->setHtmlLoadExtOverride(mFolderHtmlLoadExtPref);
01400     mMsgView->update( true );
01401   }
01402 }
01403 
01404 //-----------------------------------------------------------------------------
01405 void KMMainWidget::slotOverrideThread()
01406 {
01407   mFolderThreadPref = !mFolderThreadPref;
01408   mHeaders->setNestedOverride(mFolderThreadPref);
01409   mThreadBySubjectAction->setEnabled(mThreadMessagesAction->isChecked());
01410 }
01411 
01412 //-----------------------------------------------------------------------------
01413 void KMMainWidget::slotToggleSubjectThreading()
01414 {
01415   mFolderThreadSubjPref = !mFolderThreadSubjPref;
01416   mHeaders->setSubjectThreading(mFolderThreadSubjPref);
01417 }
01418 
01419 //-----------------------------------------------------------------------------
01420 void KMMainWidget::slotToggleShowQuickSearch()
01421 {
01422   GlobalSettings::self()->setQuickSearchActive( !GlobalSettings::self()->quickSearchActive() );
01423   if ( GlobalSettings::self()->quickSearchActive() )
01424     mSearchToolBar->show();
01425   else {
01426     mQuickSearchLine->reset();
01427     mSearchToolBar->hide();
01428   }
01429 }
01430 
01431 //-----------------------------------------------------------------------------
01432 void KMMainWidget::slotMessageQueuedOrDrafted()
01433 {
01434   if (!kmkernel->folderIsDraftOrOutbox(mFolder))
01435       return;
01436   if (mMsgView)
01437     mMsgView->update(true);
01438 }
01439 
01440 
01441 //-----------------------------------------------------------------------------
01442 void KMMainWidget::slotForwardInlineMsg()
01443 {
01444   KMMessageList* selected = mHeaders->selectedMsgs();
01445   KMCommand *command = 0L;
01446   if(selected && !selected->isEmpty()) {
01447     command = new KMForwardInlineCommand( this, *selected,
01448                                           mFolder->identity() );
01449   } else {
01450     command = new KMForwardInlineCommand( this, mHeaders->currentMsg(),
01451                                           mFolder->identity() );
01452   }
01453 
01454   command->start();
01455 }
01456 
01457 
01458 //-----------------------------------------------------------------------------
01459 void KMMainWidget::slotForwardAttachedMsg()
01460 {
01461   KMMessageList* selected = mHeaders->selectedMsgs();
01462   KMCommand *command = 0L;
01463   if(selected && !selected->isEmpty()) {
01464     command = new KMForwardAttachedCommand( this, *selected, mFolder->identity() );
01465   } else {
01466     command = new KMForwardAttachedCommand( this, mHeaders->currentMsg(), mFolder->identity() );
01467   }
01468 
01469   command->start();
01470 }
01471 
01472 //-----------------------------------------------------------------------------
01473 void KMMainWidget::slotForwardDigestMsg()
01474 {
01475   KMMessageList* selected = mHeaders->selectedMsgs();
01476   KMCommand *command = 0L;
01477   if(selected && !selected->isEmpty()) {
01478     command = new KMForwardDigestCommand( this, *selected, mFolder->identity() );
01479   } else {
01480     command = new KMForwardDigestCommand( this, mHeaders->currentMsg(), mFolder->identity() );
01481   }
01482 
01483   command->start();
01484 }
01485 
01486 //-----------------------------------------------------------------------------
01487 void KMMainWidget::slotUseTemplate()
01488 {
01489   newFromTemplate( mHeaders->currentMsg() );
01490 }
01491 
01492 //-----------------------------------------------------------------------------
01493 void KMMainWidget::slotResendMsg()
01494 {
01495   KMCommand *command = new KMResendMessageCommand( this, mHeaders->currentMsg() );
01496   command->start();
01497 }
01498 
01499 
01500 //-----------------------------------------------------------------------------
01501 void KMMainWidget::slotTrashMsg()
01502 {
01503   mHeaders->deleteMsg();
01504 }
01505 
01506 //-----------------------------------------------------------------------------
01507 void KMMainWidget::slotDeleteMsg( bool confirmDelete )
01508 {
01509   mHeaders->moveMsgToFolder( 0, confirmDelete );
01510 }
01511 
01512 //-----------------------------------------------------------------------------
01513 void KMMainWidget::slotTrashThread()
01514 {
01515   mHeaders->highlightCurrentThread();
01516   mHeaders->deleteMsg();
01517 }
01518 
01519 //-----------------------------------------------------------------------------
01520 void KMMainWidget::slotDeleteThread( bool confirmDelete )
01521 {
01522   mHeaders->highlightCurrentThread();
01523   mHeaders->moveMsgToFolder( 0, confirmDelete );
01524 }
01525 
01526 //-----------------------------------------------------------------------------
01527 void KMMainWidget::slotRedirectMsg()
01528 {
01529   KMCommand *command = new KMRedirectCommand( this, mHeaders->currentMsg() );
01530   command->start();
01531 }
01532 
01533 
01534 //-----------------------------------------------------------------------------
01535 void KMMainWidget::slotCustomReplyToMsg( int tid )
01536 {
01537   QString text = mMsgView? mMsgView->copyText() : "";
01538   QString tmpl = mCustomTemplates[ tid ];
01539   kdDebug() << "Reply with template: " << tmpl << " (" << tid << ")" << endl;
01540   KMCommand *command = new KMCustomReplyToCommand( this,
01541                                                    mHeaders->currentMsg(),
01542                                                    text,
01543                                                    tmpl );
01544   command->start();
01545 }
01546 
01547 
01548 //-----------------------------------------------------------------------------
01549 void KMMainWidget::slotCustomReplyAllToMsg( int tid )
01550 {
01551   QString text = mMsgView? mMsgView->copyText() : "";
01552   QString tmpl = mCustomTemplates[ tid ];
01553   kdDebug() << "Reply to All with template: " << tmpl << " (" << tid << ")" << endl;
01554   KMCommand *command = new KMCustomReplyAllToCommand( this,
01555                                                    mHeaders->currentMsg(),
01556                                                    text,
01557                                                    tmpl );
01558   command->start();
01559 }
01560 
01561 
01562 //-----------------------------------------------------------------------------
01563 void KMMainWidget::slotCustomForwardMsg( int tid )
01564 {
01565   QString tmpl = mCustomTemplates[ tid ];
01566   kdDebug() << "Forward with template: " << tmpl << " (" << tid << ")" << endl;
01567   KMMessageList* selected = mHeaders->selectedMsgs();
01568   KMCommand *command = 0L;
01569   if(selected && !selected->isEmpty()) {
01570     command = new KMCustomForwardCommand( this, *selected,
01571                                           mFolder->identity(), tmpl );
01572   } else {
01573     command = new KMCustomForwardCommand( this, mHeaders->currentMsg(),
01574                                           mFolder->identity(), tmpl );
01575   }
01576   command->start();
01577 }
01578 
01579 
01580 //-----------------------------------------------------------------------------
01581 void KMMainWidget::slotNoQuoteReplyToMsg()
01582 {
01583   KMCommand *command = new KMNoQuoteReplyToCommand( this, mHeaders->currentMsg() );
01584   command->start();
01585 }
01586 
01587 //-----------------------------------------------------------------------------
01588 void KMMainWidget::slotSubjectFilter()
01589 {
01590   KMMessage *msg = mHeaders->currentMsg();
01591   if (!msg)
01592     return;
01593 
01594   KMCommand *command = new KMFilterCommand( "Subject", msg->subject() );
01595   command->start();
01596 }
01597 
01598 //-----------------------------------------------------------------------------
01599 void KMMainWidget::slotMailingListFilter()
01600 {
01601   KMMessage *msg = mHeaders->currentMsg();
01602   if (!msg)
01603     return;
01604 
01605   KMCommand *command = new KMMailingListFilterCommand( this, msg );
01606   command->start();
01607 }
01608 
01609 //-----------------------------------------------------------------------------
01610 void KMMainWidget::slotFromFilter()
01611 {
01612   KMMessage *msg = mHeaders->currentMsg();
01613   if (!msg)
01614     return;
01615 
01616   AddrSpecList al = msg->extractAddrSpecs( "From" );
01617   KMCommand *command;
01618   if ( al.empty() )
01619     command = new KMFilterCommand( "From",  msg->from() );
01620   else
01621     command = new KMFilterCommand( "From",  al.front().asString() );
01622   command->start();
01623 }
01624 
01625 //-----------------------------------------------------------------------------
01626 void KMMainWidget::slotToFilter()
01627 {
01628   KMMessage *msg = mHeaders->currentMsg();
01629   if (!msg)
01630     return;
01631 
01632   KMCommand *command = new KMFilterCommand( "To",  msg->to() );
01633   command->start();
01634 }
01635 
01636 //-----------------------------------------------------------------------------
01637 void KMMainWidget::updateListFilterAction()
01638 {
01639   //Proxy the mListFilterAction to update the action text
01640   QCString name;
01641   QString value;
01642   QString lname = MailingList::name( mHeaders->currentMsg(), name, value );
01643   mListFilterAction->setText( i18n("Filter on Mailing-List...") );
01644   if ( lname.isNull() )
01645     mListFilterAction->setEnabled( false );
01646   else {
01647     mListFilterAction->setEnabled( true );
01648     mListFilterAction->setText( i18n( "Filter on Mailing-List %1..." ).arg( lname ) );
01649   }
01650 }
01651 
01652 
01653 //-----------------------------------------------------------------------------
01654 void KMMainWidget::slotUndo()
01655 {
01656     mHeaders->undo();
01657     updateMessageActions();
01658 }
01659 
01660 //-----------------------------------------------------------------------------
01661 void KMMainWidget::slotToggleUnread()
01662 {
01663   mFolderTree->toggleColumn(KMFolderTree::unread);
01664 }
01665 
01666 //-----------------------------------------------------------------------------
01667 void KMMainWidget::slotToggleTotalColumn()
01668 {
01669   mFolderTree->toggleColumn(KMFolderTree::total, true);
01670 }
01671 
01672 //-----------------------------------------------------------------------------
01673 void KMMainWidget::slotToggleSizeColumn()
01674 {
01675   mFolderTree->toggleColumn(KMFolderTree::foldersize);
01676 }
01677 
01678 
01679 //-----------------------------------------------------------------------------
01680 void KMMainWidget::slotJumpToFolder()
01681 {
01682   KMail::KMFolderSelDlg dlg( this, i18n("Jump to Folder"), true );
01683   KMFolder* dest;
01684 
01685   if (!dlg.exec()) return;
01686   if (!(dest = dlg.folder())) return;
01687 
01688   slotSelectFolder( dest );
01689 }
01690 
01691 //-----------------------------------------------------------------------------
01692 void KMMainWidget::slotMoveMsg()
01693 {
01694   KMail::KMFolderSelDlg dlg( this, i18n("Move Message to Folder"), true );
01695   KMFolder* dest;
01696 
01697   if (!dlg.exec()) return;
01698   if (!(dest = dlg.folder())) return;
01699 
01700   mHeaders->moveMsgToFolder(dest);
01701 }
01702 
01703 //-----------------------------------------------------------------------------
01704 void KMMainWidget::slotMoveMsgToFolder( KMFolder *dest)
01705 {
01706   mHeaders->moveMsgToFolder(dest);
01707 }
01708 
01709 //-----------------------------------------------------------------------------
01710 void KMMainWidget::slotCopyMsgToFolder( KMFolder *dest)
01711 {
01712   mHeaders->copyMsgToFolder(dest);
01713 }
01714 
01715 //-----------------------------------------------------------------------------
01716 void KMMainWidget::slotApplyFilters()
01717 {
01718   mHeaders->applyFiltersOnMsg();
01719 }
01720 
01721 //-----------------------------------------------------------------------------
01722 void KMMainWidget::slotCheckVacation()
01723 {
01724   updateVactionScriptStatus( false );
01725   if ( !kmkernel->askToGoOnline() )
01726     return;
01727 
01728   Vacation *vac = new Vacation( this, true /* check only */ );
01729   connect( vac, SIGNAL(scriptActive(bool)), SLOT(updateVactionScriptStatus(bool)) );
01730 }
01731 
01732 void KMMainWidget::slotEditVacation()
01733 {
01734   if ( !kmkernel->askToGoOnline() ) {
01735     return;
01736   }
01737 
01738   if ( mVacation )
01739     return;
01740 
01741   mVacation = new Vacation( this );
01742   connect( mVacation, SIGNAL(scriptActive(bool)), SLOT(updateVactionScriptStatus(bool)) );
01743   if ( mVacation->isUsable() ) {
01744     connect( mVacation, SIGNAL(result(bool)), mVacation, SLOT(deleteLater()) );
01745   } else {
01746     QString msg = i18n("KMail's Out of Office Reply functionality relies on "
01747                       "server-side filtering. You have not yet configured an "
01748                       "IMAP server for this.\n"
01749                       "You can do this on the \"Filtering\" tab of the IMAP "
01750                       "account configuration.");
01751     KMessageBox::sorry( this, msg, i18n("No Server-Side Filtering Configured") );
01752 
01753     delete mVacation; // QGuardedPtr sets itself to 0!
01754   }
01755 }
01756 
01757 //-----------------------------------------------------------------------------
01758 void KMMainWidget::slotDebugSieve()
01759 {
01760 #if !defined(NDEBUG)
01761   if ( mSieveDebugDialog )
01762     return;
01763 
01764   mSieveDebugDialog = new SieveDebugDialog( this );
01765   mSieveDebugDialog->exec();
01766   delete mSieveDebugDialog;
01767 #endif
01768 }
01769 
01770 //-----------------------------------------------------------------------------
01771 void KMMainWidget::slotStartCertManager()
01772 {
01773   KProcess certManagerProc; // save to create on the heap, since
01774   // there is no parent
01775   certManagerProc << "kleopatra";
01776 
01777   if( !certManagerProc.start( KProcess::DontCare ) )
01778     KMessageBox::error( this, i18n( "Could not start certificate manager; "
01779                                     "please check your installation." ),
01780                                     i18n( "KMail Error" ) );
01781   else
01782     kdDebug(5006) << "\nslotStartCertManager(): certificate manager started.\n" << endl;
01783   // process continues to run even after the KProcess object goes
01784   // out of scope here, since it is started in DontCare run mode.
01785 
01786 }
01787 
01788 //-----------------------------------------------------------------------------
01789 void KMMainWidget::slotStartWatchGnuPG()
01790 {
01791   KProcess certManagerProc;
01792   certManagerProc << "kwatchgnupg";
01793 
01794   if( !certManagerProc.start( KProcess::DontCare ) )
01795     KMessageBox::error( this, i18n( "Could not start GnuPG LogViewer (kwatchgnupg); "
01796                                     "please check your installation." ),
01797                                     i18n( "KMail Error" ) );
01798 }
01799 
01800 //-----------------------------------------------------------------------------
01801 void KMMainWidget::slotCopyMsg()
01802 {
01803   KMail::KMFolderSelDlg dlg( this, i18n("Copy Message to Folder"), true );
01804   KMFolder* dest;
01805 
01806   if (!dlg.exec()) return;
01807   if (!(dest = dlg.folder())) return;
01808 
01809   mHeaders->copyMsgToFolder(dest);
01810 }
01811 
01812 //-----------------------------------------------------------------------------
01813 void KMMainWidget::slotPrintMsg()
01814 {
01815   bool htmlOverride = mMsgView ? mMsgView->htmlOverride() : false;
01816   bool htmlLoadExtOverride = mMsgView ? mMsgView->htmlLoadExtOverride() : false;
01817   KConfigGroup reader( KMKernel::config(), "Reader" );
01818   bool useFixedFont = mMsgView ? mMsgView->isFixedFont()
01819                                : reader.readBoolEntry( "useFixedFont", false );
01820   KMCommand *command =
01821     new KMPrintCommand( this, mHeaders->currentMsg(),
01822                         htmlOverride, htmlLoadExtOverride,
01823                         useFixedFont, overrideEncoding() );
01824   command->start();
01825 }
01826 
01827 //-----------------------------------------------------------------------------
01828 void KMMainWidget::slotConfigChanged()
01829 {
01830   readConfig();
01831 }
01832 
01833 //-----------------------------------------------------------------------------
01834 void KMMainWidget::slotSaveMsg()
01835 {
01836   KMMessage *msg = mHeaders->currentMsg();
01837   if (!msg)
01838     return;
01839   KMSaveMsgCommand *saveCommand = new KMSaveMsgCommand( this,
01840     *mHeaders->selectedMsgs() );
01841 
01842   if (saveCommand->url().isEmpty())
01843     delete saveCommand;
01844   else
01845     saveCommand->start();
01846 }
01847 
01848 //-----------------------------------------------------------------------------
01849 void KMMainWidget::slotOpenMsg()
01850 {
01851   KMOpenMsgCommand *openCommand = new KMOpenMsgCommand( this, 0, overrideEncoding() );
01852 
01853   openCommand->start();
01854 }
01855 
01856 //-----------------------------------------------------------------------------
01857 void KMMainWidget::slotSaveAttachments()
01858 {
01859   KMMessage *msg = mHeaders->currentMsg();
01860   if (!msg)
01861     return;
01862   KMSaveAttachmentsCommand *saveCommand = new KMSaveAttachmentsCommand( this,
01863                                                                         *mHeaders->selectedMsgs() );
01864   saveCommand->start();
01865 }
01866 
01867 void KMMainWidget::slotOnlineStatus()
01868 {
01869   // KMKernel will emit a signal when we toggle the network state that is caught by
01870   // KMMainWidget::slotUpdateOnlineStatus to update our GUI
01871   if ( GlobalSettings::self()->networkState() == GlobalSettings::EnumNetworkState::Online ) {
01872     // if online; then toggle and set it offline.
01873     kmkernel->stopNetworkJobs();
01874   } else {
01875     kmkernel->resumeNetworkJobs();
01876   }
01877 }
01878 
01879 void KMMainWidget::slotUpdateOnlineStatus( GlobalSettings::EnumNetworkState::type )
01880 {
01881   if ( GlobalSettings::self()->networkState() == GlobalSettings::EnumNetworkState::Online )
01882     actionCollection()->action( "online_status" )->setText( i18n("Work Offline") );
01883   else
01884     actionCollection()->action( "online_status" )->setText( i18n("Work Online") );
01885 }
01886 
01887 
01888 //-----------------------------------------------------------------------------
01889 void KMMainWidget::slotSendQueued()
01890 {
01891   if ( !kmkernel->askToGoOnline() ) {
01892     return;
01893   }
01894 
01895   kmkernel->msgSender()->sendQueued();
01896 }
01897 
01898 //-----------------------------------------------------------------------------
01899 void KMMainWidget::slotSendQueuedVia( int item )
01900 {
01901   if ( !kmkernel->askToGoOnline() ) {
01902     return;
01903   }
01904 
01905   QStringList availTransports= KMail::TransportManager::transportNames();
01906   QString customTransport = availTransports[ item ];
01907 
01908   kmkernel->msgSender()->sendQueued( customTransport );
01909 }
01910 
01911 //-----------------------------------------------------------------------------
01912 void KMMainWidget::slotViewChange()
01913 {
01914   if(mBodyPartsMenu->isItemChecked(mBodyPartsMenu->idAt(0)))
01915   {
01916     mBodyPartsMenu->setItemChecked(mBodyPartsMenu->idAt(0),false);
01917     mBodyPartsMenu->setItemChecked(mBodyPartsMenu->idAt(1),true);
01918   }
01919   else if(mBodyPartsMenu->isItemChecked(mBodyPartsMenu->idAt(1)))
01920   {
01921     mBodyPartsMenu->setItemChecked(mBodyPartsMenu->idAt(1),false);
01922     mBodyPartsMenu->setItemChecked(mBodyPartsMenu->idAt(0),true);
01923   }
01924 
01925   //mMsgView->setInline(!mMsgView->isInline());
01926 }
01927 
01928 
01929 //-----------------------------------------------------------------------------
01930 void KMMainWidget::folderSelectedUnread( KMFolder* aFolder )
01931 {
01932   folderSelected( aFolder, true );
01933   slotChangeCaption( mFolderTree->currentItem() );
01934 }
01935 
01936 //-----------------------------------------------------------------------------
01937 void KMMainWidget::folderSelected()
01938 {
01939   folderSelected( mFolder );
01940   updateFolderMenu();
01941   // opened() before the getAndCheckFolder() in folderSelected
01942   if ( mFolder && mFolder->folderType() == KMFolderTypeImap )
01943     mFolder->close("mainwidget");
01944 }
01945 
01946 //-----------------------------------------------------------------------------
01947 void KMMainWidget::folderSelected( KMFolder* aFolder, bool forceJumpToUnread )
01948 {
01949   KCursorSaver busy(KBusyPtr::busy());
01950 
01951   if (mMsgView)
01952     mMsgView->clear(true);
01953 
01954   if ( mFolder && mFolder->folderType() == KMFolderTypeImap && !mFolder->noContent() )
01955   {
01956     KMFolderImap *imap = static_cast<KMFolderImap*>(mFolder->storage());
01957     if ( mFolder->needsCompacting() && imap->autoExpunge() )
01958       imap->expungeFolder(imap, true);
01959   }
01960 
01961   // Re-enable the msg list and quicksearch if we're showing a splash
01962   // screen. This is true either if there's no active folder, or if we
01963   // have a timer that is no longer active (i.e. it has already fired)
01964   // To make the if() a bit more complicated, we suppress the hiding
01965   // when the new folder is also an IMAP folder, because that's an
01966   // async operation and we don't want flicker if it results in just
01967   // a new splash.
01968   bool newFolder = ( (KMFolder*)mFolder != aFolder );
01969   bool isNewImapFolder = aFolder && aFolder->folderType() == KMFolderTypeImap && newFolder;
01970   if( !mFolder
01971       || ( !isNewImapFolder && mShowBusySplashTimer )
01972       || ( newFolder && mShowingOfflineScreen && !( isNewImapFolder && kmkernel->isOffline() ) ) ) {
01973     if ( mMsgView ) {
01974       mMsgView->enableMsgDisplay();
01975       mMsgView->clear( true );
01976     }
01977     if( mSearchAndHeaders && mHeaders )
01978       mSearchAndHeaders->show();
01979     mShowingOfflineScreen = false;
01980   }
01981 
01982   // Delete any pending timer, if needed it will be recreated below
01983   delete mShowBusySplashTimer;
01984   mShowBusySplashTimer = 0;
01985 
01986   if ( newFolder )
01987     writeFolderConfig();
01988   if ( mFolder ) {
01989     disconnect( mFolder, SIGNAL( changed() ),
01990            this, SLOT( updateMarkAsReadAction() ) );
01991     disconnect( mFolder, SIGNAL( msgHeaderChanged( KMFolder*, int ) ),
01992            this, SLOT( updateMarkAsReadAction() ) );
01993     disconnect( mFolder, SIGNAL( msgAdded( int ) ),
01994            this, SLOT( updateMarkAsReadAction() ) );
01995     disconnect( mFolder, SIGNAL( msgRemoved( KMFolder * ) ),
01996            this, SLOT( updateMarkAsReadAction() ) );
01997   }
01998 
01999   mFolder = aFolder;
02000 
02001   if ( aFolder && aFolder->folderType() == KMFolderTypeImap )
02002   {
02003     if ( kmkernel->isOffline() ) {
02004       showOfflinePage();
02005       return;
02006     }
02007     KMFolderImap *imap = static_cast<KMFolderImap*>(aFolder->storage());
02008     if ( newFolder && !mFolder->noContent() )
02009     {
02010       imap->open("mainwidget"); // will be closed in the folderSelected slot
02011       // first get new headers before we select the folder
02012       imap->setSelected( true );
02013       connect( imap, SIGNAL( folderComplete( KMFolderImap*, bool ) ),
02014           this, SLOT( folderSelected() ) );
02015       imap->getAndCheckFolder();
02016       mHeaders->setFolder( 0 );
02017       updateFolderMenu();
02018       mForceJumpToUnread = forceJumpToUnread;
02019 
02020       // Set a timer to show a splash screen if fetching folder contents
02021       // takes more than the amount of seconds configured in the kmailrc (default 1000 msec)
02022       mShowBusySplashTimer = new QTimer( this );
02023       connect( mShowBusySplashTimer, SIGNAL( timeout() ), this, SLOT( slotShowBusySplash() ) );
02024       mShowBusySplashTimer->start( GlobalSettings::self()->folderLoadingTimeout(), true );
02025       return;
02026     } else {
02027       // the folder is complete now - so go ahead
02028       disconnect( imap, SIGNAL( folderComplete( KMFolderImap*, bool ) ),
02029           this, SLOT( folderSelected() ) );
02030       forceJumpToUnread = mForceJumpToUnread;
02031     }
02032   }
02033 
02034   if ( mFolder ) { // == 0 -> pointing to toplevel ("Welcome to KMail") folder
02035     connect( mFolder, SIGNAL( changed() ),
02036            this, SLOT( updateMarkAsReadAction() ) );
02037     connect( mFolder, SIGNAL( msgHeaderChanged( KMFolder*, int ) ),
02038            this, SLOT( updateMarkAsReadAction() ) );
02039     connect( mFolder, SIGNAL( msgAdded( int ) ),
02040            this, SLOT( updateMarkAsReadAction() ) );
02041     connect( mFolder, SIGNAL( msgRemoved(KMFolder *) ),
02042            this, SLOT( updateMarkAsReadAction() ) );
02043   }
02044   readFolderConfig();
02045   if (mMsgView)
02046   {
02047     mMsgView->setHtmlOverride(mFolderHtmlPref);
02048     mMsgView->setHtmlLoadExtOverride(mFolderHtmlLoadExtPref);
02049   }
02050   mHeaders->setFolder( mFolder, forceJumpToUnread );
02051   updateMessageActions();
02052   updateFolderMenu();
02053   if (!aFolder)
02054     slotIntro();
02055 }
02056 
02057 //-----------------------------------------------------------------------------
02058 void KMMainWidget::slotShowBusySplash()
02059 {
02060   if ( mReaderWindowActive )
02061   {
02062     mMsgView->displayBusyPage();
02063     // hide widgets that are in the way:
02064     if ( mSearchAndHeaders && mHeaders && mLongFolderList )
02065       mSearchAndHeaders->hide();
02066   }
02067 }
02068 
02069 void KMMainWidget::showOfflinePage()
02070 {
02071   if ( !mReaderWindowActive ) return;
02072   mShowingOfflineScreen = true;
02073 
02074   mMsgView->displayOfflinePage();
02075   // hide widgets that are in the way:
02076   if ( mSearchAndHeaders && mHeaders && mLongFolderList )
02077     mSearchAndHeaders->hide();
02078 }
02079 
02080 //-----------------------------------------------------------------------------
02081 void KMMainWidget::slotMsgSelected(KMMessage *msg)
02082 {
02083   if ( msg && msg->parent() && !msg->isComplete() )
02084   {
02085     if ( msg->transferInProgress() )
02086       return;
02087     mMsgView->clear();
02088     mMsgView->setWaitingForSerNum( msg->getMsgSerNum() );
02089 
02090     if ( mJob ) {
02091        disconnect( mJob, 0, mMsgView, 0 );
02092        delete mJob;
02093     }
02094     mJob = msg->parent()->createJob( msg, FolderJob::tGetMessage, 0,
02095           "STRUCTURE", mMsgView->attachmentStrategy() );
02096     connect(mJob, SIGNAL(messageRetrieved(KMMessage*)),
02097             mMsgView, SLOT(slotMessageArrived(KMMessage*)));
02098     mJob->start();
02099   } else {
02100     mMsgView->setMsg(msg);
02101   }
02102   // reset HTML override to the folder setting
02103   mMsgView->setHtmlOverride(mFolderHtmlPref);
02104   mMsgView->setHtmlLoadExtOverride(mFolderHtmlLoadExtPref);
02105   mMsgView->setDecryptMessageOverwrite( false );
02106   mMsgView->setShowSignatureDetails( false );
02107 }
02108 
02109 //-----------------------------------------------------------------------------
02110 void KMMainWidget::slotMsgChanged()
02111 {
02112   mHeaders->msgChanged();
02113 }
02114 
02115 //-----------------------------------------------------------------------------
02116 void KMMainWidget::slotSelectFolder(KMFolder* folder)
02117 {
02118   QListViewItem* item = mFolderTree->indexOfFolder(folder);
02119   if ( item ) {
02120     mFolderTree->ensureItemVisible( item );
02121     mFolderTree->doFolderSelected( item );
02122   }
02123 }
02124 
02125 //-----------------------------------------------------------------------------
02126 void KMMainWidget::slotSelectMessage(KMMessage* msg)
02127 {
02128   int idx = mFolder->find(msg);
02129   if (idx != -1) {
02130     mHeaders->setCurrentMsg(idx);
02131     if (mMsgView)
02132       mMsgView->setMsg(msg);
02133     else
02134       slotMsgActivated(msg);
02135   }
02136 }
02137 
02138 //-----------------------------------------------------------------------------
02139 void KMMainWidget::slotReplaceMsgByUnencryptedVersion()
02140 {
02141   kdDebug(5006) << "KMMainWidget::slotReplaceMsgByUnencryptedVersion()" << endl;
02142   KMMessage* oldMsg = mHeaders->currentMsg();
02143   if( oldMsg ) {
02144     kdDebug(5006) << "KMMainWidget  -  old message found" << endl;
02145     if( oldMsg->hasUnencryptedMsg() ) {
02146       kdDebug(5006) << "KMMainWidget  -  extra unencrypted message found" << endl;
02147       KMMessage* newMsg = oldMsg->unencryptedMsg();
02148       // adjust the message id
02149       {
02150         QString msgId( oldMsg->msgId() );
02151         QString prefix("DecryptedMsg.");
02152         int oldIdx = msgId.find(prefix, 0, false);
02153         if( -1 == oldIdx ) {
02154           int leftAngle = msgId.findRev( '<' );
02155           msgId = msgId.insert( (-1 == leftAngle) ? 0 : ++leftAngle, prefix );
02156         }
02157         else {
02158           // toggle between "DecryptedMsg." and "DeCryptedMsg."
02159           // to avoid same message id
02160           QCharRef c = msgId[ oldIdx+2 ];
02161           if( 'C' == c )
02162             c = 'c';
02163           else
02164             c = 'C';
02165         }
02166         newMsg->setMsgId( msgId );
02167         mMsgView->setIdOfLastViewedMessage( msgId );
02168       }
02169       // insert the unencrypted message
02170       kdDebug(5006) << "KMMainWidget  -  adding unencrypted message to folder" << endl;
02171       mFolder->addMsg( newMsg );
02172       /* Figure out its index in the folder for selecting. This must be count()-1,
02173        * since we append. Be safe and do find, though, just in case. */
02174       int newMsgIdx = mFolder->find( newMsg );
02175       Q_ASSERT( newMsgIdx != -1 );
02176       /* we need this unget, to have the message displayed correctly initially */
02177       mFolder->unGetMsg( newMsgIdx );
02178       int idx = mFolder->find( oldMsg );
02179       Q_ASSERT( idx != -1 );
02180       /* only select here, so the old one is not un-Gotten before, which would
02181        * render the pointer we hold invalid so that find would fail */
02182       mHeaders->setCurrentItemByIndex( newMsgIdx );
02183       // remove the old one
02184       if ( idx != -1 ) {
02185         kdDebug(5006) << "KMMainWidget  -  deleting encrypted message" << endl;
02186         mFolder->take( idx );
02187       }
02188 
02189       kdDebug(5006) << "KMMainWidget  -  updating message actions" << endl;
02190       updateMessageActions();
02191 
02192       kdDebug(5006) << "KMMainWidget  -  done." << endl;
02193     } else
02194       kdDebug(5006) << "KMMainWidget  -  NO EXTRA UNENCRYPTED MESSAGE FOUND" << endl;
02195   } else
02196     kdDebug(5006) << "KMMainWidget  -  PANIC: NO OLD MESSAGE FOUND" << endl;
02197 }
02198 
02199 //-----------------------------------------------------------------------------
02200 void KMMainWidget::slotSetThreadStatusNew()
02201 {
02202   mHeaders->setThreadStatus(KMMsgStatusNew);
02203 }
02204 
02205 //-----------------------------------------------------------------------------
02206 void KMMainWidget::slotSetThreadStatusUnread()
02207 {
02208   mHeaders->setThreadStatus(KMMsgStatusUnread);
02209 }
02210 
02211 //-----------------------------------------------------------------------------
02212 void KMMainWidget::slotSetThreadStatusFlag()
02213 {
02214   mHeaders->setThreadStatus(KMMsgStatusFlag, true);
02215 }
02216 
02217 //-----------------------------------------------------------------------------
02218 void KMMainWidget::slotSetThreadStatusRead()
02219 {
02220   mHeaders->setThreadStatus(KMMsgStatusRead);
02221 }
02222 
02223 //-----------------------------------------------------------------------------
02224 void KMMainWidget::slotSetThreadStatusTodo()
02225 {
02226   mHeaders->setThreadStatus(KMMsgStatusTodo, true);
02227 }
02228 
02229 //-----------------------------------------------------------------------------
02230 void KMMainWidget::slotSetThreadStatusWatched()
02231 {
02232   mHeaders->setThreadStatus(KMMsgStatusWatched, true);
02233   if (mWatchThreadAction->isChecked()) {
02234     mIgnoreThreadAction->setChecked(false);
02235   }
02236 }
02237 
02238 //-----------------------------------------------------------------------------
02239 void KMMainWidget::slotSetThreadStatusIgnored()
02240 {
02241   mHeaders->setThreadStatus(KMMsgStatusIgnored, true);
02242   if (mIgnoreThreadAction->isChecked()) {
02243     mWatchThreadAction->setChecked(false);
02244   }
02245 }
02246 
02247 //-----------------------------------------------------------------------------
02248 void KMMainWidget::slotNextMessage()       { mHeaders->nextMessage(); }
02249 void KMMainWidget::slotNextUnreadMessage()
02250 {
02251   if ( !mHeaders->nextUnreadMessage() )
02252     if ( GlobalSettings::self()->loopOnGotoUnread() == GlobalSettings::EnumLoopOnGotoUnread::LoopInAllFolders )
02253       mFolderTree->nextUnreadFolder(true);
02254 }
02255 void KMMainWidget::slotNextImportantMessage() {
02256   //mHeaders->nextImportantMessage();
02257 }
02258 void KMMainWidget::slotPrevMessage()       { mHeaders->prevMessage(); }
02259 void KMMainWidget::slotPrevUnreadMessage()
02260 {
02261   if ( !mHeaders->prevUnreadMessage() )
02262     if ( GlobalSettings::self()->loopOnGotoUnread() == GlobalSettings::EnumLoopOnGotoUnread::LoopInAllFolders )
02263       mFolderTree->prevUnreadFolder();
02264 }
02265 void KMMainWidget::slotPrevImportantMessage() {
02266   //mHeaders->prevImportantMessage();
02267 }
02268 
02269 void KMMainWidget::slotDisplayCurrentMessage()
02270 {
02271   if ( mHeaders->currentMsg() )
02272     slotMsgActivated( mHeaders->currentMsg() );
02273 }
02274 
02275 //-----------------------------------------------------------------------------
02276 void KMMainWidget::slotMsgActivated(KMMessage *msg)
02277 {
02278   if ( !msg ) return;
02279   if ( msg->parent() && !msg->isComplete() ) {
02280     FolderJob *job = msg->parent()->createJob( msg );
02281     connect( job, SIGNAL( messageRetrieved( KMMessage* ) ),
02282              SLOT( slotMsgActivated( KMMessage* ) ) );
02283     job->start();
02284     return;
02285   }
02286 
02287   if (kmkernel->folderIsDraftOrOutbox( mFolder ) ) {
02288     mMsgActions->editCurrentMessage();
02289     return;
02290   }
02291   if ( kmkernel->folderIsTemplates( mFolder ) ) {
02292     slotUseTemplate();
02293     return;
02294   }
02295 
02296   assert( msg != 0 );
02297   KMReaderMainWin *win = new KMReaderMainWin( mFolderHtmlPref, mFolderHtmlLoadExtPref );
02298   KConfigGroup reader( KMKernel::config(), "Reader" );
02299   bool useFixedFont = mMsgView ? mMsgView->isFixedFont()
02300                                : reader.readBoolEntry( "useFixedFont", false );
02301   win->setUseFixedFont( useFixedFont );
02302   KMMessage *newMessage = new KMMessage(*msg);
02303   newMessage->setParent( msg->parent() );
02304   newMessage->setMsgSerNum( msg->getMsgSerNum() );
02305   newMessage->setReadyToShow( true );
02306   win->showMsg( overrideEncoding(), newMessage );
02307   win->show();
02308 }
02309 
02310 //-----------------------------------------------------------------------------
02311 void KMMainWidget::slotMarkAll()
02312 {
02313   mHeaders->selectAll( true );
02314 }
02315 
02316 //-----------------------------------------------------------------------------
02317 void KMMainWidget::slotMsgPopup(KMMessage&, const KURL &aUrl, const QPoint& aPoint)
02318 {
02319   KPopupMenu * menu = new KPopupMenu;
02320   updateMessageMenu();
02321   mUrlCurrent = aUrl;
02322 
02323   bool urlMenuAdded = false;
02324 
02325   if (!aUrl.isEmpty())
02326   {
02327     if (aUrl.protocol() == "mailto")
02328     {
02329       // popup on a mailto URL
02330       mMsgView->mailToComposeAction()->plug( menu );
02331       mMsgView->mailToReplyAction()->plug( menu );
02332       mMsgView->mailToForwardAction()->plug( menu );
02333 
02334       menu->insertSeparator();
02335       mMsgView->addAddrBookAction()->plug( menu );
02336       mMsgView->openAddrBookAction()->plug( menu );
02337       mMsgView->copyURLAction()->plug( menu );
02338       mMsgView->startImChatAction()->plug( menu );
02339       // only enable if our KIMProxy is functional
02340       mMsgView->startImChatAction()->setEnabled( kmkernel->imProxy()->initialize() );
02341 
02342     } else {
02343       // popup on a not-mailto URL
02344       mMsgView->urlOpenAction()->plug( menu );
02345       mMsgView->addBookmarksAction()->plug( menu );
02346       mMsgView->urlSaveAsAction()->plug( menu );
02347       mMsgView->copyURLAction()->plug( menu );
02348     }
02349     if ( aUrl.protocol() == "im" )
02350     {
02351       // popup on an IM address
02352       // no need to check the KIMProxy is initialized, as these protocols will
02353       // only be present if it is.
02354       mMsgView->startImChatAction()->plug( menu );
02355     }
02356 
02357     urlMenuAdded=true;
02358     kdDebug( 0 ) << k_funcinfo << " URL is: " << aUrl << endl;
02359   }
02360 
02361 
02362   if(mMsgView && !mMsgView->copyText().isEmpty()) {
02363     if ( urlMenuAdded )
02364       menu->insertSeparator();
02365     mMsgActions->replyMenu()->plug(menu);
02366     menu->insertSeparator();
02367 
02368     mMsgView->copyAction()->plug( menu );
02369     mMsgView->selectAllAction()->plug( menu );
02370   } else  if ( !urlMenuAdded )
02371   {
02372     // popup somewhere else (i.e., not a URL) on the message
02373 
02374     if (!mHeaders->currentMsg()) // no messages
02375     {
02376       delete menu;
02377       return;
02378     }
02379 
02380 
02381     if ( mFolder->isTemplates() ) {
02382       mUseAction->plug( menu );
02383     } else {
02384 
02385       if ( !mFolder->isSent() )
02386         mMsgActions->replyMenu()->plug( menu );
02387       mForwardActionMenu->plug( menu );
02388     }
02389     editAction()->plug(menu);
02390     menu->insertSeparator();
02391 
02392     mCopyActionMenu->plug( menu );
02393     mMoveActionMenu->plug( menu );
02394 
02395     menu->insertSeparator();
02396 
02397     mMsgActions->messageStatusMenu()->plug( menu );
02398     menu->insertSeparator();
02399 
02400     viewSourceAction()->plug(menu);
02401     if(mMsgView) {
02402       mMsgView->toggleFixFontAction()->plug(menu);
02403     }
02404     menu->insertSeparator();
02405     mPrintAction->plug( menu );
02406     mSaveAsAction->plug( menu );
02407     mSaveAttachmentsAction->plug( menu );
02408 
02409     menu->insertSeparator();
02410     if( mFolder->isTrash() )
02411       mDeleteAction->plug( menu );
02412     else
02413       mTrashAction->plug( menu );
02414 
02415     menu->insertSeparator();
02416     mMsgActions->createTodoAction()->plug( menu );
02417   }
02418   KAcceleratorManager::manage(menu);
02419   menu->exec(aPoint, 0);
02420   delete menu;
02421 }
02422 
02423 //-----------------------------------------------------------------------------
02424 void KMMainWidget::getAccountMenu()
02425 {
02426   QStringList actList;
02427 
02428   mActMenu->clear();
02429   actList = kmkernel->acctMgr()->getAccounts();
02430   QStringList::Iterator it;
02431   int id = 0;
02432   for(it = actList.begin(); it != actList.end() ; ++it, id++)
02433     mActMenu->insertItem((*it).replace("&", "&&"), id);
02434 }
02435 
02436 //-----------------------------------------------------------------------------
02437 void KMMainWidget::getTransportMenu()
02438 {
02439   QStringList availTransports;
02440 
02441   mSendMenu->clear();
02442   availTransports = KMail::TransportManager::transportNames();
02443   QStringList::Iterator it;
02444   int id = 0;
02445   for(it = availTransports.begin(); it != availTransports.end() ; ++it, id++)
02446     mSendMenu->insertItem((*it).replace("&", "&&"), id);
02447 }
02448 
02449 //-----------------------------------------------------------------------------
02450 void KMMainWidget::updateCustomTemplateMenus()
02451 {
02452   if ( !mCustomTemplateActions.isEmpty() ) {
02453     QPtrList<KAction>::iterator ait = mCustomTemplateActions.begin();
02454     for ( ; ait != mCustomTemplateActions.end() ; ++ait ) {
02455       (*ait)->unplugAll();
02456       delete (*ait);
02457     }
02458     mCustomTemplateActions.clear();
02459   }
02460 
02461   delete mCustomReplyActionMenu;
02462   delete mCustomReplyAllActionMenu;
02463   delete mCustomForwardActionMenu;
02464 
02465   delete mCustomReplyMapper;
02466   delete mCustomReplyAllMapper;
02467   delete mCustomForwardMapper;
02468 
02469   mCustomForwardActionMenu =
02470     new KActionMenu( i18n("Forward With Custom Template"),
02471                      "mail_custom_forward",
02472                      actionCollection(), "custom_forward" );
02473   QSignalMapper *mCustomForwardMapper = new QSignalMapper( this );
02474   connect( mCustomForwardMapper, SIGNAL( mapped( int ) ),
02475            this, SLOT( slotCustomForwardMsg( int ) ) );
02476   mForwardActionMenu->insert( mCustomForwardActionMenu );
02477 
02478   mCustomReplyActionMenu =
02479     new KActionMenu( i18n("Reply With Custom Template"), "mail_custom_reply",
02480                      actionCollection(), "custom_reply" );
02481   QSignalMapper *mCustomReplyMapper = new QSignalMapper( this );
02482   connect( mCustomReplyMapper, SIGNAL( mapped( int ) ),
02483            this, SLOT( slotCustomReplyToMsg( int ) ) );
02484   mMsgActions->replyMenu()->insert( mCustomReplyActionMenu );
02485 
02486   mCustomReplyAllActionMenu =
02487     new KActionMenu( i18n("Reply to All With Custom Template"),
02488                      "mail_custom_reply_all",
02489                      actionCollection(), "custom_reply_all" );
02490   QSignalMapper *mCustomReplyAllMapper = new QSignalMapper( this );
02491   connect( mCustomReplyAllMapper, SIGNAL( mapped( int ) ),
02492            this, SLOT( slotCustomReplyAllToMsg( int ) ) );
02493   mMsgActions->replyMenu()->insert( mCustomReplyAllActionMenu );
02494 
02495   mCustomTemplates.clear();
02496 
02497   QStringList list = GlobalSettingsBase::self()->customTemplates();
02498   QStringList::iterator it = list.begin();
02499   int idx = 0;
02500   int replyc = 0;
02501   int replyallc = 0;
02502   int forwardc = 0;
02503   for ( ; it != list.end(); ++it ) {
02504     CTemplates t( *it );
02505     mCustomTemplates.append( *it );
02506 
02507     KAction *action;
02508     switch ( t.type() ) {
02509     case CustomTemplates::TReply:
02510       action = new KAction( (*it).replace( "&", "&&" ),
02511                             KShortcut( t.shortcut() ),
02512                             mCustomReplyMapper,
02513                             SLOT( map() ),
02514                             actionCollection(),
02515                             (*it).utf8() );
02516       mCustomReplyMapper->setMapping( action, idx );
02517       mCustomReplyActionMenu->insert( action, idx );
02518       mCustomTemplateActions.append( action );
02519       ++replyc;
02520       break;
02521     case CustomTemplates::TReplyAll:
02522       action = new KAction( (*it).replace( "&", "&&" ),
02523                             KShortcut( t.shortcut() ),
02524                             mCustomReplyAllMapper,
02525                             SLOT( map() ),
02526                             actionCollection(),
02527                             (*it).utf8() );
02528       mCustomReplyAllMapper->setMapping( action, idx );
02529       mCustomReplyAllActionMenu->insert( action, idx );
02530       mCustomTemplateActions.append( action );
02531       ++replyallc;
02532       break;
02533     case CustomTemplates::TForward:
02534       action = new KAction( (*it).replace( "&", "&&" ),
02535                             KShortcut( t.shortcut() ),
02536                             mCustomForwardMapper,
02537                             SLOT( map() ),
02538                             actionCollection(),
02539                             (*it).utf8() );
02540       mCustomForwardMapper->setMapping( action, idx );
02541       mCustomForwardActionMenu->insert( action, idx );
02542       mCustomTemplateActions.append( action );
02543       ++forwardc;
02544       break;
02545     case CustomTemplates::TUniversal:
02546       action = new KAction( (*it).replace( "&", "&&" ),
02547                             KShortcut::null(),
02548                             mCustomReplyMapper,
02549                             SLOT( map() ),
02550                             actionCollection(),
02551                             (*it).utf8() );
02552       mCustomReplyMapper->setMapping( action, idx );
02553       mCustomReplyActionMenu->insert( action, idx );
02554       mCustomTemplateActions.append( action );
02555       ++replyc;
02556       action = new KAction( (*it).replace( "&", "&&" ),
02557                             KShortcut::null(),
02558                             mCustomReplyAllMapper,
02559                             SLOT( map() ),
02560                             actionCollection(),
02561                             (*it).utf8() );
02562       mCustomReplyAllMapper->setMapping( action, idx );
02563       mCustomReplyAllActionMenu->insert( action, idx );
02564       mCustomTemplateActions.append( action );
02565       ++replyallc;
02566       action = new KAction( (*it).replace( "&", "&&" ),
02567                             KShortcut::null(),
02568                             mCustomForwardMapper,
02569                             SLOT( map() ),
02570                             actionCollection(),
02571                             (*it).utf8() );
02572       mCustomForwardMapper->setMapping( action, idx );
02573       mCustomForwardActionMenu->insert( action, idx );
02574       mCustomTemplateActions.append( action );
02575       ++forwardc;
02576       break;
02577     }
02578 
02579     ++idx;
02580   }
02581   if ( !replyc ) {
02582       mCustomReplyActionMenu->popupMenu()->insertItem( i18n( "(no custom templates)" ), 0 );
02583       mCustomReplyActionMenu->popupMenu()->setItemEnabled( 0, false );
02584       mCustomReplyActionMenu->setEnabled(false);
02585   }
02586   if ( !replyallc ) {
02587       mCustomReplyAllActionMenu->popupMenu()->insertItem( i18n( "(no custom templates)" ), 0 );
02588       mCustomReplyAllActionMenu->popupMenu()->setItemEnabled( 0, false );
02589       mCustomReplyAllActionMenu->setEnabled(false);
02590   }
02591   if ( !forwardc ) {
02592       mCustomForwardActionMenu->popupMenu()->insertItem( i18n( "(no custom templates)" ), 0 );
02593       mCustomForwardActionMenu->popupMenu()->setItemEnabled( 0, false );
02594       mCustomForwardActionMenu->setEnabled(false);
02595   }
02596 
02597 }
02598 
02599 
02600 //-----------------------------------------------------------------------------
02601 void KMMainWidget::setupActions()
02602 {
02603   mMsgActions = new KMail::MessageActions( actionCollection(), this );
02604   mMsgActions->setMessageView( mMsgView );
02605 
02606   //----- File Menu
02607   mSaveAsAction = new KAction( i18n("Save &As..."), "filesave",
02608     KStdAccel::shortcut(KStdAccel::Save),
02609     this, SLOT(slotSaveMsg()), actionCollection(), "file_save_as" );
02610 
02611   mOpenAction = KStdAction::open( this, SLOT( slotOpenMsg() ),
02612                                   actionCollection() );
02613 
02614   (void) new KAction( i18n("&Compact All Folders"), 0,
02615               this, SLOT(slotCompactAll()),
02616               actionCollection(), "compact_all_folders" );
02617 
02618   (void) new KAction( i18n("&Expire All Folders"), 0,
02619               this, SLOT(slotExpireAll()),
02620               actionCollection(), "expire_all_folders" );
02621 
02622   (void) new KAction( i18n("&Refresh Local IMAP Cache"), "refresh",
02623               this, SLOT(slotInvalidateIMAPFolders()),
02624               actionCollection(), "file_invalidate_imap_cache" );
02625 
02626   (void) new KAction( i18n("Empty All &Trash Folders"), 0,
02627               KMKernel::self(), SLOT(slotEmptyTrash()),
02628               actionCollection(), "empty_trash" );
02629 
02630   (void) new KAction( i18n("Check &Mail"), "mail_get", CTRL+Key_L,
02631               this, SLOT(slotCheckMail()),
02632               actionCollection(), "check_mail" );
02633 
02634   mFavoritesCheckMailAction = new KAction( i18n("Check Mail in Favorite Folders"),
02635               "mail_get", CTRL+SHIFT+Key_L, 0, 0,
02636               actionCollection(), "favorite_check_mail" );
02637   if ( mFavoriteFolderView )
02638     connect( mFavoritesCheckMailAction, SIGNAL(activated()), mFavoriteFolderView, SLOT(checkMail()) );
02639 
02640   KActionMenu *actActionMenu = new
02641     KActionMenu( i18n("Check Mail &In"), "mail_get", actionCollection(),
02642                     "check_mail_in" );
02643   actActionMenu->setDelayed(true); //needed for checking "all accounts"
02644 
02645   connect(actActionMenu,SIGNAL(activated()),this,SLOT(slotCheckMail()));
02646 
02647   mActMenu = actActionMenu->popupMenu();
02648   connect(mActMenu,SIGNAL(activated(int)),this,SLOT(slotCheckOneAccount(int)));
02649   connect(mActMenu,SIGNAL(aboutToShow()),this,SLOT(getAccountMenu()));
02650 
02651   (void) new KAction( i18n("&Send Queued Messages"), "mail_send", 0, this,
02652              SLOT(slotSendQueued()), actionCollection(), "send_queued");
02653 
02654   (void) new KAction( i18n("Online Status (unknown)"), "online_status", 0, this,
02655                      SLOT(slotOnlineStatus()), actionCollection(), "online_status");
02656 
02657   KActionMenu *sendActionMenu = new
02658     KActionMenu( i18n("Send Queued Messages Via"), "mail_send_via", actionCollection(),
02659                                        "send_queued_via" );
02660   sendActionMenu->setDelayed(true);
02661 
02662   mSendMenu = sendActionMenu->popupMenu();
02663   connect(mSendMenu,SIGNAL(activated(int)), this, SLOT(slotSendQueuedVia(int)));
02664   connect(mSendMenu,SIGNAL(aboutToShow()),this,SLOT(getTransportMenu()));
02665 
02666   KAction *act;
02667   //----- Tools menu
02668   if (parent()->inherits("KMMainWin")) {
02669     act =  new KAction( i18n("&Address Book..."), "contents", 0, this,
02670             SLOT(slotAddrBook()), actionCollection(), "addressbook" );
02671     if (KStandardDirs::findExe("kaddressbook").isEmpty()) act->setEnabled(false);
02672   }
02673 
02674   act = new KAction( i18n("Certificate Manager..."), "pgp-keys", 0, this,
02675              SLOT(slotStartCertManager()), actionCollection(), "tools_start_certman");
02676   // disable action if no certman binary is around
02677   if (KStandardDirs::findExe("kleopatra").isEmpty()) act->setEnabled(false);
02678 
02679   act = new KAction( i18n("GnuPG Log Viewer..."), "pgp-keys", 0, this,
02680              SLOT(slotStartWatchGnuPG()), actionCollection(), "tools_start_kwatchgnupg");
02681   // disable action if no kwatchgnupg binary is around
02682   if (KStandardDirs::findExe("kwatchgnupg").isEmpty()) act->setEnabled(false);
02683 
02684   act = new KAction( i18n("&Import Messages..."), "fileopen", 0, this,
02685              SLOT(slotImport()), actionCollection(), "import" );
02686   if (KStandardDirs::findExe("kmailcvt").isEmpty()) act->setEnabled(false);
02687 
02688 #if !defined(NDEBUG)
02689   (void) new KAction( i18n("&Debug Sieve..."),
02690               "idea", 0, this, SLOT(slotDebugSieve()),
02691               actionCollection(), "tools_debug_sieve" );
02692 #endif
02693 
02694   if ( GlobalSettings::allowOutOfOfficeSettings() ) {
02695       (void) new KAction( i18n("Edit \"Out of Office\" Replies..."),
02696               "configure", 0, this, SLOT(slotEditVacation()),
02697               actionCollection(), "tools_edit_vacation" );
02698 
02699   }
02700 
02701   (void) new KAction( i18n("Filter &Log Viewer..."), 0, this,
02702               SLOT(slotFilterLogViewer()), actionCollection(), "filter_log_viewer" );
02703 
02704   (void) new KAction( i18n("&Anti-Spam Wizard..."), 0, this,
02705               SLOT(slotAntiSpamWizard()), actionCollection(), "antiSpamWizard" );
02706   (void) new KAction( i18n("&Anti-Virus Wizard..."), 0, this,
02707               SLOT(slotAntiVirusWizard()), actionCollection(), "antiVirusWizard" );
02708 
02709   //----- Edit Menu
02710   mTrashAction = new KAction( KGuiItem( i18n("&Move to Trash"), "edittrash",
02711                                        i18n("Move message to trashcan") ),
02712                              Key_Delete, this, SLOT(slotTrashMsg()),
02713                              actionCollection(), "move_to_trash" );
02714 
02715   /* The delete action is nowhere in the gui, by default, so we need to make
02716    * sure it is plugged into the KAccel now, since that won't happen on
02717    * XMLGui construction or manual ->plug(). This is only a problem when run
02718    * as a part, though. */
02719   mDeleteAction = new KAction( i18n("&Delete"), "editdelete", SHIFT+Key_Delete, this,
02720                               SLOT(slotDeleteMsg()), actionCollection(), "delete" );
02721   mDeleteAction->plugAccel( actionCollection()->kaccel() );
02722 
02723   mTrashThreadAction = new KAction( KGuiItem( i18n("M&ove Thread to Trash"), "edittrash",
02724                                        i18n("Move thread to trashcan") ),
02725                              CTRL+Key_Delete, this, SLOT(slotTrashThread()),
02726                              actionCollection(), "move_thread_to_trash" );
02727 
02728   mDeleteThreadAction = new KAction( i18n("Delete T&hread"), "editdelete", CTRL+SHIFT+Key_Delete, this,
02729                               SLOT(slotDeleteThread()), actionCollection(), "delete_thread" );
02730 
02731 
02732   (void) new KAction( i18n("&Find Messages..."), "mail_find", Key_S, this,
02733               SLOT(slotRequestFullSearchFromQuickSearch()), actionCollection(), "search_messages" );
02734 
02735   mFindInMessageAction = new KAction( i18n("&Find in Message..."), "find", KStdAccel::shortcut(KStdAccel::Find), this,
02736               SLOT(slotFind()), actionCollection(), "find_in_messages" );
02737 
02738   (void) new KAction( i18n("Select &All Messages"), KStdAccel::selectAll(), this,
02739               SLOT(slotMarkAll()), actionCollection(), "mark_all_messages" );
02740 
02741   //----- Folder Menu
02742   mNewFolderAction = new KAction( i18n("&New Folder..."), "folder_new", 0, mFolderTree,
02743               SLOT(addChildFolder()), actionCollection(), "new_folder" );
02744 
02745   mModifyFolderAction = new KAction( i18n("&Properties"), "configure", 0, this,
02746               SLOT(slotModifyFolder()), actionCollection(), "modify" );
02747 
02748   mFolderMailingListPropertiesAction = new KAction( i18n("&Mailing List Management..."),
02749       /*"folder_mailinglist_properties",*/ 0, this, SLOT( slotFolderMailingListProperties() ),
02750       actionCollection(), "folder_mailinglist_properties" );
02751 
02752   mFolderShortCutCommandAction = new KAction( i18n("&Assign Shortcut..."), "configure_shortcuts",
02753                       0, this, SLOT( slotFolderShortcutCommand() ), actionCollection(),
02754                       "folder_shortcut_command" );
02755 
02756 
02757   mMarkAllAsReadAction = new KAction( i18n("Mark All Messages as &Read"), "goto", 0, this,
02758               SLOT(slotMarkAllAsRead()), actionCollection(), "mark_all_as_read" );
02759 
02760   mExpireFolderAction = new KAction(i18n("&Expiration Settings"), 0, this, SLOT(slotExpireFolder()),
02761                    actionCollection(), "expire");
02762 
02763   mCompactFolderAction = new KAction( i18n("&Compact Folder"), 0, this,
02764               SLOT(slotCompactFolder()), actionCollection(), "compact" );
02765 
02766   mRefreshFolderAction = new KAction( i18n("Check Mail &in This Folder"), "reload",
02767                                       KStdAccel::shortcut( KStdAccel::Reload ), this,
02768                                       SLOT(slotRefreshFolder()),
02769                                       actionCollection(), "refresh_folder" );
02770   mTroubleshootFolderAction = 0; // set in initializeIMAPActions
02771 
02772   mEmptyFolderAction = new KAction( "foo" /*set in updateFolderMenu*/, "edittrash", 0, this,
02773               SLOT(slotEmptyFolder()), actionCollection(), "empty" );
02774 
02775   mRemoveFolderAction = new KAction( "foo" /*set in updateFolderMenu*/, "editdelete", 0, this,
02776               SLOT(slotRemoveFolder()), actionCollection(), "delete_folder" );
02777 
02778   mPreferHtmlAction = new KToggleAction( i18n("Prefer &HTML to Plain Text"), 0, this,
02779               SLOT(slotOverrideHtml()), actionCollection(), "prefer_html" );
02780 
02781   mPreferHtmlLoadExtAction = new KToggleAction( i18n("Load E&xternal References"), 0, this,
02782               SLOT(slotOverrideHtmlLoadExt()), actionCollection(), "prefer_html_external_refs" );
02783 
02784   mThreadMessagesAction = new KToggleAction( i18n("&Thread Messages"), 0, this,
02785               SLOT(slotOverrideThread()), actionCollection(), "thread_messages" );
02786 
02787   mThreadBySubjectAction = new KToggleAction( i18n("Thread Messages also by &Subject"), 0, this,
02788               SLOT(slotToggleSubjectThreading()), actionCollection(), "thread_messages_by_subject" );
02789 
02790   new KAction( i18n("Copy Folder"), "editcopy", SHIFT+CTRL+Key_C, folderTree(),
02791                SLOT(copyFolder()), actionCollection(), "copy_folder" );
02792   new KAction( i18n("Cut Folder"), "editcut", SHIFT+CTRL+Key_X, folderTree(),
02793                SLOT(cutFolder()), actionCollection(), "cut_folder" );
02794   new KAction( i18n("Paste Folder"), "editpaste", SHIFT+CTRL+Key_V, folderTree(),
02795                SLOT(pasteFolder()), actionCollection(), "paste_folder" );
02796 
02797   new KAction( i18n("Copy Messages"), "editcopy", ALT+CTRL+Key_C, headers(),
02798                SLOT(copyMessages()), actionCollection(), "copy_messages" );
02799   new KAction( i18n("Cut Messages"), "editcut", ALT+CTRL+Key_X, headers(),
02800                SLOT(cutMessages()), actionCollection(), "cut_messages" );
02801   new KAction( i18n("Paste Messages"), "editpaste", ALT+CTRL+Key_V, headers(),
02802                SLOT(pasteMessages()), actionCollection(), "paste_messages" );
02803 
02804   //----- Message Menu
02805   (void) new KAction( i18n("&New Message..."), "mail_new", KStdAccel::shortcut(KStdAccel::New), this,
02806               SLOT(slotCompose()), actionCollection(), "new_message" );
02807   mTemplateMenu =
02808     new KActionMenu( i18n("New Message From &Template"), "filenew",
02809                      actionCollection(), "new_from_template" );
02810   mTemplateMenu->setDelayed( true );
02811   connect( mTemplateMenu->popupMenu(), SIGNAL( aboutToShow() ), this,
02812            SLOT( slotShowNewFromTemplate() ) );
02813   connect( mTemplateMenu->popupMenu(), SIGNAL( activated(int) ), this,
02814            SLOT( slotNewFromTemplate(int) ) );
02815 
02816   KAction* newToML = new KAction( i18n("New Message t&o Mailing-List..."), "mail_post_to",
02817                       CTRL+SHIFT+Key_N, this,
02818               SLOT(slotPostToML()), actionCollection(), "post_message" );
02819   newToML->plugAccel( actionCollection()->kaccel() );
02820 
02821   mForwardActionMenu = new KActionMenu( i18n("Message->","&Forward"),
02822                     "mail_forward", actionCollection(),
02823                     "message_forward" );
02824 
02825       mForwardInlineAction = new KAction( i18n("&Inline..."),
02826                                       "mail_forward", 0, this,
02827                                       SLOT(slotForwardInlineMsg()),
02828                                       actionCollection(),
02829                                       "message_forward_inline" );
02830 
02831       mForwardAttachedAction = new KAction( i18n("Message->Forward->","As &Attachment..."),
02832                                         "mail_forward", 0, this,
02833                                         SLOT(slotForwardAttachedMsg()),
02834                                         actionCollection(),
02835                                         "message_forward_as_attachment" );
02836 
02837       mForwardDigestAction = new KAction( i18n("Message->Forward->","As Di&gest..."),
02838                                       "mail_forward", 0, this,
02839                                       SLOT(slotForwardDigestMsg()),
02840                                       actionCollection(),
02841                                       "message_forward_as_digest" );
02842 
02843       mRedirectAction = new KAction( i18n("Message->Forward->","&Redirect..."),
02844                                  "mail_forward", Key_E, this,
02845                                  SLOT(slotRedirectMsg()),
02846                                  actionCollection(),
02847                                  "message_forward_redirect" );
02848 
02849 
02850       if ( GlobalSettings::self()->forwardingInlineByDefault() ) {
02851           mForwardActionMenu->insert( mForwardInlineAction );
02852           mForwardActionMenu->insert( mForwardAttachedAction );
02853           mForwardInlineAction->setShortcut( Key_F );
02854           mForwardAttachedAction->setShortcut( SHIFT+Key_F );
02855           connect( mForwardActionMenu, SIGNAL(activated()), this,
02856                    SLOT(slotForwardInlineMsg()) );
02857 
02858       } else {
02859           mForwardActionMenu->insert( mForwardAttachedAction );
02860           mForwardActionMenu->insert( mForwardInlineAction );
02861           mForwardInlineAction->setShortcut( SHIFT+Key_F );
02862           mForwardAttachedAction->setShortcut( Key_F );
02863           connect( mForwardActionMenu, SIGNAL(activated()), this,
02864                    SLOT(slotForwardAttachedMsg()) );
02865       }
02866 
02867       mForwardActionMenu->insert( mForwardDigestAction );
02868       mForwardActionMenu->insert( mRedirectAction );
02869 
02870   mSendAgainAction = new KAction( i18n("Send A&gain..."), 0, this,
02871               SLOT(slotResendMsg()), actionCollection(), "send_again" );
02872 
02873 
02874   //----- Create filter actions
02875   mFilterMenu = new KActionMenu( i18n("&Create Filter"), "filter", actionCollection(), "create_filter" );
02876   connect( mFilterMenu, SIGNAL(activated()), this,
02877        SLOT(slotFilter()) );
02878   mSubjectFilterAction = new KAction( i18n("Filter on &Subject..."), 0, this,
02879                       SLOT(slotSubjectFilter()),
02880                       actionCollection(), "subject_filter");
02881   mFilterMenu->insert( mSubjectFilterAction );
02882 
02883   mFromFilterAction = new KAction( i18n("Filter on &From..."), 0, this,
02884                    SLOT(slotFromFilter()),
02885                    actionCollection(), "from_filter");
02886   mFilterMenu->insert( mFromFilterAction );
02887 
02888   mToFilterAction = new KAction( i18n("Filter on &To..."), 0, this,
02889                  SLOT(slotToFilter()),
02890                  actionCollection(), "to_filter");
02891   mFilterMenu->insert( mToFilterAction );
02892 
02893   mListFilterAction = new KAction( i18n("Filter on Mailing-&List..."), 0, this,
02894                                    SLOT(slotMailingListFilter()), actionCollection(),
02895                                    "mlist_filter");
02896   mFilterMenu->insert( mListFilterAction );
02897 
02898   mPrintAction = KStdAction::print (this, SLOT(slotPrintMsg()), actionCollection());
02899 
02900   mUseAction = new KAction( i18n("New Message From &Template"), "filenew",
02901                             Key_N, this, SLOT( slotUseTemplate() ),
02902                             actionCollection(), "use_template" );
02903   mUseAction->plugAccel( actionCollection()->kaccel() );
02904 
02905   //----- "Mark Thread" submenu
02906   mThreadStatusMenu = new KActionMenu ( i18n( "Mark &Thread" ),
02907                                        actionCollection(), "thread_status" );
02908 
02909   mMarkThreadAsReadAction = new KAction(KGuiItem(i18n("Mark Thread as &Read"), "kmmsgread",
02910                                                 i18n("Mark all messages in the selected thread as read")),
02911                                                 0, this, SLOT(slotSetThreadStatusRead()),
02912                                                 actionCollection(), "thread_read");
02913   mThreadStatusMenu->insert( mMarkThreadAsReadAction );
02914 
02915   mMarkThreadAsNewAction = new KAction(KGuiItem(i18n("Mark Thread as &New"), "kmmsgnew",
02916                                                i18n("Mark all messages in the selected thread as new")),
02917                                                0, this, SLOT(slotSetThreadStatusNew()),
02918                                                actionCollection(), "thread_new");
02919   mThreadStatusMenu->insert( mMarkThreadAsNewAction );
02920 
02921   mMarkThreadAsUnreadAction = new KAction(KGuiItem(i18n("Mark Thread as &Unread"), "kmmsgunseen",
02922                                                 i18n("Mark all messages in the selected thread as unread")),
02923                                                 0, this, SLOT(slotSetThreadStatusUnread()),
02924                                                 actionCollection(), "thread_unread");
02925   mThreadStatusMenu->insert( mMarkThreadAsUnreadAction );
02926 
02927   mThreadStatusMenu->insert( new KActionSeparator( this ) );
02928 
02929   //----- "Mark Thread" toggle actions
02930   mToggleThreadFlagAction = new KToggleAction(i18n("Mark Thread as &Important"), "mail_flag",
02931                                        0, this, SLOT(slotSetThreadStatusFlag()),
02932                                        actionCollection(), "thread_flag");
02933   mToggleThreadFlagAction->setCheckedState( i18n("Remove &Important Thread Mark") );
02934   mThreadStatusMenu->insert( mToggleThreadFlagAction );
02935 
02936   mToggleThreadTodoAction = new KToggleAction(i18n("Mark Thread as &Action Item"), "mail_todo",
02937                                        0, this, SLOT(slotSetThreadStatusTodo()),
02938                                        actionCollection(), "thread_todo");
02939   mToggleThreadTodoAction->setCheckedState( i18n("Remove &Action Item Thread Mark") );
02940   mThreadStatusMenu->insert( mToggleThreadTodoAction );
02941 
02942   //------- "Watch and ignore thread" actions
02943   mWatchThreadAction = new KToggleAction(i18n("&Watch Thread"), "kmmsgwatched",
02944                                        0, this, SLOT(slotSetThreadStatusWatched()),
02945                                        actionCollection(), "thread_watched");
02946 
02947   mIgnoreThreadAction = new KToggleAction(i18n("&Ignore Thread"), "mail_ignore",
02948                                        0, this, SLOT(slotSetThreadStatusIgnored()),
02949                                        actionCollection(), "thread_ignored");
02950 
02951   mThreadStatusMenu->insert( new KActionSeparator( this ) );
02952   mThreadStatusMenu->insert( mWatchThreadAction );
02953   mThreadStatusMenu->insert( mIgnoreThreadAction );
02954 
02955   mSaveAttachmentsAction = new KAction( i18n("Save A&ttachments..."), "attach",
02956                                 0, this, SLOT(slotSaveAttachments()),
02957                                 actionCollection(), "file_save_attachments" );
02958 
02959   mMoveActionMenu = new KActionMenu( i18n("&Move To" ),
02960                                     actionCollection(), "move_to" );
02961 
02962   mCopyActionMenu = new KActionMenu( i18n("&Copy To" ),
02963                                     actionCollection(), "copy_to" );
02964 
02965   mApplyAllFiltersAction = new KAction( i18n("Appl&y All Filters"), "filter",
02966                     CTRL+Key_J, this,
02967                     SLOT(slotApplyFilters()),
02968                     actionCollection(), "apply_filters" );
02969 
02970   mApplyFilterActionsMenu = new KActionMenu( i18n("A&pply Filter" ),
02971                         actionCollection(),
02972                         "apply_filter_actions" );
02973 
02974   //----- View Menu
02975   // Unread Submenu
02976   KActionMenu * unreadMenu =
02977     new KActionMenu( i18n("View->", "&Unread Count"),
02978              actionCollection(), "view_unread" );
02979   unreadMenu->setToolTip( i18n("Choose how to display the count of unread messages") );
02980 
02981   mUnreadColumnToggle = new KRadioAction( i18n("View->Unread Count", "View in &Separate Column"), 0, this,
02982                    SLOT(slotToggleUnread()),
02983                    actionCollection(), "view_unread_column" );
02984   mUnreadColumnToggle->setExclusiveGroup( "view_unread_group" );
02985   unreadMenu->insert( mUnreadColumnToggle );
02986 
02987   mUnreadTextToggle = new KRadioAction( i18n("View->Unread Count", "View After &Folder Name"), 0, this,
02988                    SLOT(slotToggleUnread()),
02989                    actionCollection(), "view_unread_text" );
02990   mUnreadTextToggle->setExclusiveGroup( "view_unread_group" );
02991   unreadMenu->insert( mUnreadTextToggle );
02992 
02993   // toggle for total column
02994   mTotalColumnToggle = new KToggleAction( i18n("View->", "&Total Column"), 0, this,
02995                    SLOT(slotToggleTotalColumn()),
02996                    actionCollection(), "view_columns_total" );
02997   mTotalColumnToggle->setToolTip( i18n("Toggle display of column showing the "
02998                                       "total number of messages in folders.") );
02999   mSizeColumnToggle = new KToggleAction( i18n("View->", "&Size Column"), 0, this,
03000                    SLOT(slotToggleSizeColumn()),
03001                    actionCollection(), "view_columns_size" );
03002   mSizeColumnToggle->setToolTip( i18n("Toggle display of column showing the "
03003                                       "total size of messages in folders.") );
03004 
03005   (void)new KAction( KGuiItem( i18n("View->","&Expand Thread"), QString::null,
03006                    i18n("Expand the current thread") ),
03007              Key_Period, this,
03008              SLOT(slotExpandThread()),
03009              actionCollection(), "expand_thread" );
03010 
03011   (void)new KAction( KGuiItem( i18n("View->","&Collapse Thread"), QString::null,
03012                    i18n("Collapse the current thread") ),
03013              Key_Comma, this,
03014              SLOT(slotCollapseThread()),
03015              actionCollection(), "collapse_thread" );
03016 
03017   (void)new KAction( KGuiItem( i18n("View->","Ex&pand All Threads"), QString::null,
03018                    i18n("Expand all threads in the current folder") ),
03019              CTRL+Key_Period, this,
03020              SLOT(slotExpandAllThreads()),
03021              actionCollection(), "expand_all_threads" );
03022 
03023   (void)new KAction( KGuiItem( i18n("View->","C&ollapse All Threads"), QString::null,
03024                    i18n("Collapse all threads in the current folder") ),
03025              CTRL+Key_Comma, this,
03026              SLOT(slotCollapseAllThreads()),
03027              actionCollection(), "collapse_all_threads" );
03028 
03029   mViewSourceAction = new KAction( i18n("&View Source"), Key_V, this,
03030                                    SLOT(slotShowMsgSrc()), actionCollection(),
03031                                    "view_source" );
03032 
03033   KAction* dukeOfMonmoth = new KAction( i18n("&Display Message"), Key_Return, this,
03034                         SLOT( slotDisplayCurrentMessage() ), actionCollection(),
03035                         "display_message" );
03036   dukeOfMonmoth->plugAccel( actionCollection()->kaccel() );
03037 
03038   //----- Go Menu
03039   new KAction( KGuiItem( i18n("&Next Message"), QString::null,
03040                          i18n("Go to the next message") ),
03041                          "N;Right", this, SLOT(slotNextMessage()),
03042                          actionCollection(), "go_next_message" );
03043 
03044   new KAction( KGuiItem( i18n("Next &Unread Message"),
03045                          QApplication::reverseLayout() ? "previous" : "next",
03046                          i18n("Go to the next unread message") ),
03047                          Key_Plus, this, SLOT(slotNextUnreadMessage()),
03048                          actionCollection(), "go_next_unread_message" );
03049 
03050   /* ### needs better support from folders:
03051   new KAction( KGuiItem( i18n("Next &Important Message"), QString::null,
03052                          i18n("Go to the next important message") ),
03053                          0, this, SLOT(slotNextImportantMessage()),
03054                          actionCollection(), "go_next_important_message" );
03055   */
03056 
03057   new KAction( KGuiItem( i18n("&Previous Message"), QString::null,
03058                          i18n("Go to the previous message") ),
03059                          "P;Left", this, SLOT(slotPrevMessage()),
03060                          actionCollection(), "go_prev_message" );
03061 
03062   new KAction( KGuiItem( i18n("Previous Unread &Message"),
03063                          QApplication::reverseLayout() ? "next" : "previous",
03064                          i18n("Go to the previous unread message") ),
03065                          Key_Minus, this, SLOT(slotPrevUnreadMessage()),
03066                          actionCollection(), "go_prev_unread_message" );
03067 
03068   /* needs better support from folders:
03069   new KAction( KGuiItem( i18n("Previous I&mportant Message"), QString::null,
03070                          i18n("Go to the previous important message") ),
03071                          0, this, SLOT(slotPrevImportantMessage()),
03072                          actionCollection(), "go_prev_important_message" );
03073   */
03074 
03075   KAction *action =
03076     new KAction( KGuiItem( i18n("Next Unread &Folder"), QString::null,
03077                            i18n("Go to the next folder with unread messages") ),
03078                            ALT+Key_Plus, this, SLOT(slotNextUnreadFolder()),
03079                            actionCollection(), "go_next_unread_folder" );
03080   KShortcut shortcut = action->shortcut();
03081   shortcut.append( KKey( CTRL+Key_Plus ) );
03082   action->setShortcut( shortcut );
03083 
03084   action =
03085     new KAction( KGuiItem( i18n("Previous Unread F&older"), QString::null,
03086                            i18n("Go to the previous folder with unread messages") ),
03087                            ALT+Key_Minus, this, SLOT(slotPrevUnreadFolder()),
03088                            actionCollection(), "go_prev_unread_folder" );
03089   shortcut = action->shortcut();
03090   shortcut.append( KKey( CTRL+Key_Minus ) );
03091   action->setShortcut( shortcut );
03092 
03093   new KAction( KGuiItem( i18n("Go->","Next Unread &Text"), QString::null,
03094                          i18n("Go to the next unread text"),
03095                          i18n("Scroll down current message. "
03096                               "If at end of current message, "
03097                               "go to next unread message.") ),
03098                          Key_Space, this, SLOT(slotReadOn()),
03099                          actionCollection(), "go_next_unread_text" );
03100 
03101   //----- Settings Menu
03102   mToggleShowQuickSearchAction = new KToggleAction(i18n("Show Quick Search"), QString::null,
03103                                        0, this, SLOT(slotToggleShowQuickSearch()),
03104                                        actionCollection(), "show_quick_search");
03105   mToggleShowQuickSearchAction->setChecked( GlobalSettings::self()->quickSearchActive() );
03106   mToggleShowQuickSearchAction->setWhatsThis(
03107         i18n( GlobalSettings::self()->quickSearchActiveItem()->whatsThis().utf8() ) );
03108 
03109   (void) new KAction( i18n("Configure &Filters..."), 0, this,
03110               SLOT(slotFilter()), actionCollection(), "filter" );
03111   (void) new KAction( i18n("Configure &POP Filters..."), 0, this,
03112               SLOT(slotPopFilter()), actionCollection(), "popFilter" );
03113   (void) new KAction( i18n("Manage &Sieve Scripts..."), 0, this,
03114                       SLOT(slotManageSieveScripts()), actionCollection(), "sieveFilters" );
03115 
03116   (void) new KAction( KGuiItem( i18n("KMail &Introduction"), 0,
03117                 i18n("Display KMail's Welcome Page") ),
03118               0, this, SLOT(slotIntro()),
03119               actionCollection(), "help_kmail_welcomepage" );
03120 
03121   // ----- Standard Actions
03122 //  KStdAction::configureNotifications(this, SLOT(slotEditNotifications()), actionCollection());
03123   (void) new KAction( i18n("Configure &Notifications..."),
03124               "knotify", 0, this,
03125               SLOT(slotEditNotifications()), actionCollection(),
03126               "kmail_configure_notifications" );
03127 //  KStdAction::preferences(this, SLOT(slotSettings()), actionCollection());
03128   (void) new KAction( i18n("&Configure KMail..."),
03129               "configure", 0, kmkernel,
03130                       SLOT(slotShowConfigurationDialog()), actionCollection(),
03131                       "kmail_configure_kmail" );
03132 
03133   KStdAction::undo(this, SLOT(slotUndo()), actionCollection(), "kmail_undo");
03134 
03135   KStdAction::tipOfDay( this, SLOT( slotShowTip() ), actionCollection() );
03136 
03137   menutimer = new QTimer( this, "menutimer" );
03138   connect( menutimer, SIGNAL( timeout() ), SLOT( updateMessageActions() ) );
03139   connect( kmkernel->undoStack(),
03140            SIGNAL( undoStackChanged() ), this, SLOT( slotUpdateUndo() ));
03141 
03142   initializeIMAPActions( false ); // don't set state, config not read yet
03143   updateMessageActions();
03144   updateCustomTemplateMenus();
03145   updateFolderMenu();
03146 }
03147 
03148 void KMMainWidget::setupForwardingActionsList()
03149 {
03150   QPtrList<KAction> mForwardActionList;
03151   if ( GlobalSettings::self()->forwardingInlineByDefault() ) {
03152       mGUIClient->unplugActionList( "forward_action_list" );
03153       mForwardActionList.append( mForwardInlineAction );
03154       mForwardActionList.append( mForwardAttachedAction );
03155       mForwardActionList.append( mForwardDigestAction );
03156       mForwardActionList.append( mRedirectAction );
03157       mGUIClient->plugActionList( "forward_action_list", mForwardActionList );
03158   } else {
03159       mGUIClient->unplugActionList( "forward_action_list" );
03160       mForwardActionList.append( mForwardAttachedAction );
03161       mForwardActionList.append( mForwardInlineAction );
03162       mForwardActionList.append( mForwardDigestAction );
03163       mForwardActionList.append( mRedirectAction );
03164       mGUIClient->plugActionList( "forward_action_list", mForwardActionList );
03165   }
03166 }
03167 
03168 //-----------------------------------------------------------------------------
03169 void KMMainWidget::slotEditNotifications()
03170 {
03171   if(kmkernel->xmlGuiInstance())
03172     KNotifyDialog::configure(this, 0, kmkernel->xmlGuiInstance()->aboutData());
03173   else
03174     KNotifyDialog::configure(this);
03175 }
03176 
03177 void KMMainWidget::slotEditKeys()
03178 {
03179   KKeyDialog::configure( actionCollection(),
03180              true /*allow one-letter shortcuts*/
03181              );
03182 }
03183 
03184 //-----------------------------------------------------------------------------
03185 void KMMainWidget::slotReadOn()
03186 {
03187     if ( !mMsgView )
03188         return;
03189 
03190     if ( !mMsgView->atBottom() ) {
03191         mMsgView->slotJumpDown();
03192         return;
03193     }
03194     slotNextUnreadMessage();
03195 }
03196 
03197 void KMMainWidget::slotNextUnreadFolder() {
03198   if ( !mFolderTree ) return;
03199   mFolderTree->nextUnreadFolder();
03200 }
03201 
03202 void KMMainWidget::slotPrevUnreadFolder() {
03203   if ( !mFolderTree ) return;
03204   mFolderTree->prevUnreadFolder();
03205 }
03206 
03207 void KMMainWidget::slotExpandThread()
03208 {
03209   mHeaders->slotExpandOrCollapseThread( true ); // expand
03210 }
03211 
03212 void KMMainWidget::slotCollapseThread()
03213 {
03214   mHeaders->slotExpandOrCollapseThread( false ); // collapse
03215 }
03216 
03217 void KMMainWidget::slotExpandAllThreads()
03218 {
03219   mHeaders->slotExpandOrCollapseAllThreads( true ); // expand
03220 }
03221 
03222 void KMMainWidget::slotCollapseAllThreads()
03223 {
03224   mHeaders->slotExpandOrCollapseAllThreads( false ); // collapse
03225 }
03226 
03227 //-----------------------------------------------------------------------------
03228 void KMMainWidget::slotShowMsgSrc()
03229 {
03230   if ( mMsgView )
03231     mMsgView->setUpdateAttachment( false );
03232   KMMessage *msg = mHeaders->currentMsg();
03233   if ( !msg )
03234     return;
03235   KMCommand *command = new KMShowMsgSrcCommand( this, msg,
03236                                                 mMsgView
03237                                                 ? mMsgView->isFixedFont()
03238                                                 : false );
03239   command->start();
03240 }
03241 
03242 
03243 //-----------------------------------------------------------------------------
03244 void KMMainWidget::moveSelectedToFolder( int menuId )
03245 {
03246   if (mMenuToFolder[menuId])
03247     mHeaders->moveMsgToFolder( mMenuToFolder[menuId] );
03248 }
03249 
03250 
03251 //-----------------------------------------------------------------------------
03252 void KMMainWidget::copySelectedToFolder(int menuId )
03253 {
03254   if (mMenuToFolder[menuId])
03255     mHeaders->copyMsgToFolder( mMenuToFolder[menuId] );
03256 }
03257 
03258 
03259 //-----------------------------------------------------------------------------
03260 void KMMainWidget::updateMessageMenu()
03261 {
03262   mMenuToFolder.clear();
03263   folderTree()->folderToPopupMenu( KMFolderTree::MoveMessage, this,
03264       &mMenuToFolder, mMoveActionMenu->popupMenu() );
03265   folderTree()->folderToPopupMenu( KMFolderTree::CopyMessage, this,
03266       &mMenuToFolder, mCopyActionMenu->popupMenu() );
03267   updateMessageActions();
03268 }
03269 
03270 void KMMainWidget::startUpdateMessageActionsTimer()
03271 {
03272     menutimer->stop();
03273     menutimer->start( 20, true );
03274 }
03275 
03276 void KMMainWidget::updateMessageActions()
03277 {
03278     int count = 0;
03279     QPtrList<QListViewItem> selectedItems;
03280 
03281     if ( mFolder ) {
03282       for (QListViewItem *item = mHeaders->firstChild(); item; item = item->itemBelow())
03283         if (item->isSelected() )
03284           selectedItems.append(item);
03285       if ( selectedItems.isEmpty() && mFolder->count() ) // there will always be one in mMsgView
03286         count = 1;
03287       else
03288         count = selectedItems.count();
03289       mMsgActions->setCurrentMessage( mHeaders->currentMsg() );
03290       mMsgActions->setSelectedSernums( mHeaders->selectedSernums() );
03291       mMsgActions->setSelectedVisibleSernums( mHeaders->selectedVisibleSernums() );
03292     } else {
03293       mMsgActions->setCurrentMessage( 0 );
03294     }
03295 
03296     updateListFilterAction();
03297 
03298     bool allSelectedInCommonThread = false;
03299     if ( mHeaders->isThreaded() && count > 1 ) {
03300       allSelectedInCommonThread = true;
03301       for ( QPtrListIterator<QListViewItem> it( selectedItems ) ;
03302             it.current() ; ++ it ) {
03303         QListViewItem * item = *it;
03304         if ( item->parent()==0 && item->childCount()==0 ) {
03305           allSelectedInCommonThread = false;
03306           break;
03307         }
03308       }
03309     }
03310     else if ( mHeaders->isThreaded() && count == 1 ) {
03311       allSelectedInCommonThread = true;
03312     }
03313 
03314     QListViewItem *curItemParent = mHeaders->currentItem();
03315     bool parent_thread = 0;
03316     if ( curItemParent && curItemParent->firstChild() != 0 ) parent_thread = 1;
03317 
03318     bool mass_actions = count >= 1;
03319     bool thread_actions = mass_actions && allSelectedInCommonThread &&
03320                           mHeaders->isThreaded();
03321     bool flags_available = GlobalSettings::self()->allowLocalFlags() || !(mFolder ? mFolder->isReadOnly() : true);
03322     mThreadStatusMenu->setEnabled( thread_actions );
03323     // these need to be handled individually, the user might have them
03324     // in the toolbar
03325     mWatchThreadAction->setEnabled( thread_actions && flags_available );
03326     mIgnoreThreadAction->setEnabled( thread_actions && flags_available );
03327     mMarkThreadAsNewAction->setEnabled( thread_actions );
03328     mMarkThreadAsReadAction->setEnabled( thread_actions );
03329     mMarkThreadAsUnreadAction->setEnabled( thread_actions );
03330     mToggleThreadTodoAction->setEnabled( thread_actions && flags_available );
03331     mToggleThreadFlagAction->setEnabled( thread_actions && flags_available );
03332     mTrashThreadAction->setEnabled( thread_actions && mFolder->canDeleteMessages() );
03333     mDeleteThreadAction->setEnabled( thread_actions && !mFolder->isReadOnly() );
03334 
03335     if (mFolder && mHeaders && mHeaders->currentMsg()) {
03336       if (thread_actions) {
03337         mToggleThreadTodoAction->setChecked(mHeaders->currentMsg()->isTodo());
03338         mToggleThreadFlagAction->setChecked(mHeaders->currentMsg()->isImportant());
03339         mWatchThreadAction->setChecked( mHeaders->currentMsg()->isWatched());
03340         mIgnoreThreadAction->setChecked( mHeaders->currentMsg()->isIgnored());
03341       }
03342     }
03343 
03344     mMoveActionMenu->setEnabled( mass_actions && !mFolder->isReadOnly() );
03345     mCopyActionMenu->setEnabled( mass_actions );
03346     mTrashAction->setEnabled( mass_actions && mFolder->canDeleteMessages() );
03347     mDeleteAction->setEnabled( mass_actions && mFolder->canDeleteMessages() );
03348     mFindInMessageAction->setEnabled( mass_actions );
03349     mForwardInlineAction->setEnabled( mass_actions );
03350     mForwardAttachedAction->setEnabled( mass_actions );
03351     mForwardDigestAction->setEnabled( count > 1 || parent_thread );
03352 
03353     forwardMenu()->setEnabled( mass_actions );
03354 
03355     bool single_actions = count == 1;
03356     mUseAction->setEnabled( single_actions &&
03357                             kmkernel->folderIsTemplates( mFolder ) );
03358     filterMenu()->setEnabled( single_actions );
03359     redirectAction()->setEnabled( single_actions );
03360     printAction()->setEnabled( single_actions );
03361     viewSourceAction()->setEnabled( single_actions );
03362 
03363     mSendAgainAction->setEnabled( single_actions
03364           && ( mHeaders->currentMsg() && mHeaders->currentMsg()->isSent() )
03365           || ( mFolder && mHeaders->currentMsg() &&
03366                kmkernel->folderIsSentMailFolder( mFolder ) ) );
03367     mSaveAsAction->setEnabled( mass_actions );
03368     bool mails = mFolder && mFolder->count();
03369     bool enable_goto_unread = mails
03370        || (GlobalSettings::self()->loopOnGotoUnread() == GlobalSettings::EnumLoopOnGotoUnread::LoopInAllFolders);
03371     actionCollection()->action( "go_next_message" )->setEnabled( mails );
03372     actionCollection()->action( "go_next_unread_message" )->setEnabled( enable_goto_unread );
03373     actionCollection()->action( "go_prev_message" )->setEnabled( mails );
03374     actionCollection()->action( "go_prev_unread_message" )->setEnabled( enable_goto_unread );
03375     actionCollection()->action( "send_queued" )->setEnabled( kmkernel->outboxFolder()->count() > 0 );
03376     actionCollection()->action( "send_queued_via" )->setEnabled( kmkernel->outboxFolder()->count() > 0 );
03377     slotUpdateOnlineStatus( static_cast<GlobalSettingsBase::EnumNetworkState::type>( GlobalSettings::self()->networkState() ) );
03378     if (action( "edit_undo" ))
03379       action( "edit_undo" )->setEnabled( mHeaders->canUndo() );
03380 
03381     if ( count == 1 ) {
03382       KMMessage *msg;
03383       int aIdx;
03384       if((aIdx = mHeaders->currentItemIndex()) <= -1)
03385         return;
03386       if(!(msg = mFolder->getMsg(aIdx)))
03387         return;
03388 
03389       if ((KMFolder*)mFolder == kmkernel->outboxFolder())
03390         editAction()->setEnabled( !msg->transferInProgress() );
03391     }
03392 
03393     mApplyAllFiltersAction->setEnabled(count);
03394     mApplyFilterActionsMenu->setEnabled(count);
03395 }
03396 
03397 // This needs to be updated more often, so it is in its method.
03398 void KMMainWidget::updateMarkAsReadAction()
03399 {
03400   mMarkAllAsReadAction->setEnabled( mFolder && (mFolder->countUnread() > 0) );
03401 }
03402 
03403 //-----------------------------------------------------------------------------
03404 void KMMainWidget::updateFolderMenu()
03405 {
03406   bool folderWithContent = mFolder && !mFolder->noContent();
03407   bool multiFolder = folderTree()->selectedFolders().count() > 1;
03408   mModifyFolderAction->setEnabled( folderWithContent && !multiFolder );
03409   mFolderMailingListPropertiesAction->setEnabled( folderWithContent && !multiFolder );
03410   mCompactFolderAction->setEnabled( folderWithContent && !multiFolder );
03411 
03412   // This is the refresh-folder action in the menu. See kmfoldertree for the one in the RMB...
03413   bool imap = mFolder && mFolder->folderType() == KMFolderTypeImap;
03414   bool cachedImap = mFolder && mFolder->folderType() == KMFolderTypeCachedImap;
03415   // For dimap, check that the imap path is known before allowing "check mail in this folder".
03416   bool knownImapPath = cachedImap && !static_cast<KMFolderCachedImap*>( mFolder->storage() )->imapPath().isEmpty();
03417   mRefreshFolderAction->setEnabled( folderWithContent && ( imap
03418                                                            || ( cachedImap && knownImapPath ) ) && !multiFolder );
03419   if ( mTroubleshootFolderAction )
03420     mTroubleshootFolderAction->setEnabled( folderWithContent && ( cachedImap && knownImapPath ) && !multiFolder );
03421   mEmptyFolderAction->setEnabled( folderWithContent && ( mFolder->count() > 0 ) && !mFolder->isReadOnly() && !multiFolder );
03422   mEmptyFolderAction->setText( (mFolder && kmkernel->folderIsTrash(mFolder))
03423     ? i18n("E&mpty Trash") : i18n("&Move All Messages to Trash") );
03424   mRemoveFolderAction->setEnabled( mFolder && !mFolder->isSystemFolder() && !mFolder->isReadOnly() && !multiFolder);
03425   mRemoveFolderAction->setText( mFolder && mFolder->folderType() == KMFolderTypeSearch
03426         ? i18n("&Delete Search") : i18n("&Delete Folder") );
03427   mExpireFolderAction->setEnabled( mFolder && mFolder->isAutoExpire() && !multiFolder );
03428   updateMarkAsReadAction();
03429   // the visual ones only make sense if we are showing a message list
03430   mPreferHtmlAction->setEnabled( mHeaders->folder() ? true : false );
03431   mPreferHtmlLoadExtAction->setEnabled( mHeaders->folder() && (mHtmlPref ? !mFolderHtmlPref : mFolderHtmlPref) ? true : false );
03432   mThreadMessagesAction->setEnabled( mHeaders->folder() ? true : false );
03433 
03434   mPreferHtmlAction->setChecked( mHtmlPref ? !mFolderHtmlPref : mFolderHtmlPref );
03435   mPreferHtmlLoadExtAction->setChecked( mHtmlLoadExtPref ? !mFolderHtmlLoadExtPref : mFolderHtmlLoadExtPref );
03436   mThreadMessagesAction->setChecked(
03437       mThreadPref ? !mFolderThreadPref : mFolderThreadPref );
03438   mThreadBySubjectAction->setEnabled(
03439       mHeaders->folder() ? ( mThreadMessagesAction->isChecked()) : false );
03440   mThreadBySubjectAction->setChecked( mFolderThreadSubjPref );
03441 
03442   mNewFolderAction->setEnabled( !multiFolder );
03443   mRemoveDuplicatesAction->setEnabled( !multiFolder );
03444   mFolderShortCutCommandAction->setEnabled( !multiFolder );
03445 }
03446 
03447 
03448 #ifdef MALLOC_DEBUG
03449 static QString fmt(long n) {
03450   char buf[32];
03451 
03452   if(n > 1024*1024*1024)
03453     sprintf(buf, "%0.2f GB", ((double)n)/1024.0/1024.0/1024.0);
03454   else if(n > 1024*1024)
03455     sprintf(buf, "%0.2f MB", ((double)n)/1024.0/1024.0);
03456   else if(n > 1024)
03457     sprintf(buf, "%0.2f KB", ((double)n)/1024.0);
03458   else
03459     sprintf(buf, "%ld Byte", n);
03460   return QString(buf);
03461 }
03462 #endif
03463 
03464 void KMMainWidget::slotMemInfo() {
03465 #ifdef MALLOC_DEBUG
03466   struct mallinfo mi;
03467 
03468   mi = mallinfo();
03469   QString s = QString("\nMALLOC - Info\n\n"
03470               "Number of mmapped regions : %1\n"
03471               "Memory allocated in use   : %2\n"
03472               "Memory allocated, not used: %3\n"
03473               "Memory total allocated    : %4\n"
03474               "Max. freeable memory      : %5\n")
03475     .arg(mi.hblks).arg(fmt(mi.uordblks)).arg(fmt(mi.fordblks))
03476     .arg(fmt(mi.arena)).arg(fmt(mi.keepcost));
03477   KMessageBox::information(0, s, "Malloc information", s);
03478 #endif
03479 }
03480 
03481 
03482 //-----------------------------------------------------------------------------
03483 void KMMainWidget::slotIntro()
03484 {
03485   if ( !mMsgView ) return;
03486 
03487   mMsgView->clear( true );
03488   // hide widgets that are in the way:
03489   if ( mSearchAndHeaders && mHeaders && mLongFolderList )
03490     mSearchAndHeaders->hide();
03491 
03492 
03493   mMsgView->displayAboutPage();
03494 
03495   mFolder = 0;
03496 }
03497 
03498 void KMMainWidget::slotShowStartupFolder()
03499 {
03500   if ( mFolderTree ) {
03501     mFolderTree->reload();
03502     mFolderTree->readConfig();
03503     // get rid of old-folders
03504     mFolderTree->cleanupConfigFile();
03505   }
03506 
03507   connect( kmkernel->filterMgr(), SIGNAL( filterListUpdated() ),
03508        this, SLOT( initializeFilterActions() ));
03509 
03510   // plug shortcut filter actions now
03511   initializeFilterActions();
03512 
03513   // plug folder shortcut actions
03514   initializeFolderShortcutActions();
03515 
03516   QString newFeaturesMD5 = KMReaderWin::newFeaturesMD5();
03517   if ( kmkernel->firstStart() ||
03518        GlobalSettings::self()->previousNewFeaturesMD5() != newFeaturesMD5 ) {
03519     GlobalSettings::self()->setPreviousNewFeaturesMD5( newFeaturesMD5 );
03520     slotIntro();
03521     return;
03522   }
03523 
03524   KMFolder* startup = 0;
03525   if ( !mStartupFolder.isEmpty() ) {
03526     // find the startup-folder
03527     startup = kmkernel->findFolderById( mStartupFolder );
03528   }
03529   if ( !startup )
03530     startup = kmkernel->inboxFolder();
03531 
03532   if ( mFolderTree ) {
03533     mFolderTree->showFolder( startup );
03534   }
03535 }
03536 
03537 void KMMainWidget::slotShowTip()
03538 {
03539   KTipDialog::showTip( this, QString::null, true );
03540 }
03541 
03542 //-----------------------------------------------------------------------------
03543 void KMMainWidget::slotChangeCaption(QListViewItem * i)
03544 {
03545   if ( !i ) return;
03546   // set the caption to the current full path
03547   QStringList names;
03548   for ( QListViewItem * item = i ; item ; item = item->parent() )
03549     names.prepend( item->text(0) );
03550   emit captionChangeRequest( names.join( "/" ) );
03551 }
03552 
03553 //-----------------------------------------------------------------------------
03554 void KMMainWidget::removeDuplicates()
03555 {
03556   if (!mFolder)
03557     return;
03558   KMFolder *oFolder = mFolder;
03559   mHeaders->setFolder(0);
03560   QMap< QString, QValueList<int> > idMD5s;
03561   QValueList<int> redundantIds;
03562   QValueList<int>::Iterator kt;
03563   mFolder->open("removedups");
03564   for (int i = mFolder->count() - 1; i >= 0; --i) {
03565     QString id = (*mFolder)[i]->msgIdMD5();
03566     if ( !id.isEmpty() ) {
03567       QString subjMD5 = (*mFolder)[i]->strippedSubjectMD5();
03568       int other = -1;
03569       if ( idMD5s.contains(id) )
03570         other = idMD5s[id].first();
03571       else
03572         idMD5s[id].append( i );
03573       if ( other != -1 ) {
03574         QString otherSubjMD5 = (*mFolder)[other]->strippedSubjectMD5();
03575         if (otherSubjMD5 == subjMD5)
03576           idMD5s[id].append( i );
03577       }
03578     }
03579   }
03580   QMap< QString, QValueList<int> >::Iterator it;
03581   for ( it = idMD5s.begin(); it != idMD5s.end() ; ++it ) {
03582     QValueList<int>::Iterator jt;
03583     bool finished = false;
03584     for ( jt = (*it).begin(); jt != (*it).end() && !finished; ++jt )
03585       if (!((*mFolder)[*jt]->isUnread())) {
03586         (*it).remove( jt );
03587         (*it).prepend( *jt );
03588         finished = true;
03589       }
03590     for ( jt = (*it).begin(), ++jt; jt != (*it).end(); ++jt )
03591       redundantIds.append( *jt );
03592   }
03593   qHeapSort( redundantIds );
03594   kt = redundantIds.end();
03595   int numDuplicates = 0;
03596   if (kt != redundantIds.begin()) do {
03597     mFolder->removeMsg( *(--kt) );
03598     ++numDuplicates;
03599   }
03600   while (kt != redundantIds.begin());
03601 
03602   mFolder->close("removedups");
03603   mHeaders->setFolder(oFolder);
03604   QString msg;
03605   if ( numDuplicates )
03606     msg = i18n("Removed %n duplicate message.",
03607                "Removed %n duplicate messages.", numDuplicates );
03608     else
03609       msg = i18n("No duplicate messages found.");
03610   BroadcastStatus::instance()->setStatusMsg( msg );
03611 }
03612 
03613 
03614 //-----------------------------------------------------------------------------
03615 void KMMainWidget::slotUpdateUndo()
03616 {
03617     if (actionCollection()->action( "edit_undo" ))
03618         actionCollection()->action( "edit_undo" )->setEnabled( mHeaders->canUndo() );
03619 }
03620 
03621 
03622 //-----------------------------------------------------------------------------
03623 void KMMainWidget::clearFilterActions()
03624 {
03625   if ( !mFilterTBarActions.isEmpty() ) {
03626     if ( mGUIClient->factory() )
03627       mGUIClient->unplugActionList( "toolbar_filter_actions" );
03628     mFilterTBarActions.clear();
03629   }
03630   mApplyFilterActionsMenu->popupMenu()->clear();
03631   if ( !mFilterMenuActions.isEmpty() ) {
03632     if ( mGUIClient->factory() )
03633       mGUIClient->unplugActionList( "menu_filter_actions" );
03634     mFilterMenuActions.clear();
03635   }
03636   mFilterCommands.clear();
03637 }
03638 
03639 //-----------------------------------------------------------------------------
03640 void KMMainWidget::initializeFolderShortcutActions()
03641 {
03642 
03643   // If we are loaded as a part, this will be set to fals, since the part
03644   // does xml loading. Temporarily set to true, in that case, so the
03645   // accels are added to the collection as expected.
03646   bool old = actionCollection()->isAutoConnectShortcuts();
03647 
03648   actionCollection()->setAutoConnectShortcuts( true );
03649   QValueList< QGuardedPtr< KMFolder > > folders = kmkernel->allFolders();
03650   QValueList< QGuardedPtr< KMFolder > >::Iterator it = folders.begin();
03651   while ( it != folders.end() ) {
03652     KMFolder *folder = (*it);
03653     ++it;
03654     slotShortcutChanged( folder ); // load the initial accel
03655   }
03656   actionCollection()->setAutoConnectShortcuts( old );
03657 }
03658 
03659 
03660 //-----------------------------------------------------------------------------
03661 void KMMainWidget::initializeFilterActions()
03662 {
03663   QString filterName, normalizedName;
03664   KMMetaFilterActionCommand *filterCommand;
03665   KAction *filterAction = 0;
03666 
03667   clearFilterActions();
03668   mApplyAllFiltersAction->plug(mApplyFilterActionsMenu->popupMenu());
03669   bool addedSeparator = false;
03670   QValueListConstIterator<KMFilter*> it = kmkernel->filterMgr()->filters().constBegin();
03671   for ( ;it != kmkernel->filterMgr()->filters().constEnd(); ++it ) {
03672     if (!(*it)->isEmpty() && (*it)->configureShortcut()) {
03673       filterName = QString("Filter %1").arg((*it)->name());
03674       normalizedName = filterName.replace(" ", "_");
03675       if (action(normalizedName.utf8()))
03676         continue;
03677       filterCommand = new KMMetaFilterActionCommand(*it, mHeaders, this);
03678       mFilterCommands.append(filterCommand);
03679       QString as = i18n("Filter %1").arg((*it)->name());
03680       QString icon = (*it)->icon();
03681       if ( icon.isEmpty() )
03682         icon = "gear";
03683       filterAction = new KAction(as, icon, (*it)->shortcut(), filterCommand,
03684                                  SLOT(start()), actionCollection(),
03685                                  normalizedName.local8Bit());
03686       if(!addedSeparator) {
03687         mApplyFilterActionsMenu->popupMenu()->insertSeparator();
03688         addedSeparator = !addedSeparator;
03689         mFilterMenuActions.append( new KActionSeparator());
03690       }
03691       filterAction->plug( mApplyFilterActionsMenu->popupMenu() );
03692       mFilterMenuActions.append(filterAction);
03693       if ( (*it)->configureToolbar() )
03694         mFilterTBarActions.append(filterAction);
03695     }
03696   }
03697   if ( !mFilterMenuActions.isEmpty() && mGUIClient->factory() )
03698     mGUIClient->plugActionList( "menu_filter_actions", mFilterMenuActions );
03699   if ( !mFilterTBarActions.isEmpty() && mGUIClient->factory() ) {
03700     mFilterTBarActions.prepend( mToolbarActionSeparator );
03701     mGUIClient->plugActionList( "toolbar_filter_actions", mFilterTBarActions );
03702   }
03703 }
03704 
03705 void KMMainWidget::slotFolderRemoved( KMFolder *folder )
03706 {
03707   mFolderShortcutCommands.remove( folder->idString() );
03708 }
03709 
03710 //-----------------------------------------------------------------------------
03711 void KMMainWidget::initializeIMAPActions( bool setState /* false the first time, true later on */ )
03712 {
03713   bool hasImapAccount = false;
03714   for( KMAccount *a = kmkernel->acctMgr()->first(); a;
03715        a = kmkernel->acctMgr()->next() ) {
03716     if ( a->type() == "cachedimap" ) {
03717       hasImapAccount = true;
03718       break;
03719     }
03720   }
03721   if ( hasImapAccount == ( mTroubleshootFolderAction != 0 ) )
03722     return; // nothing to do
03723 
03724   KXMLGUIFactory* factory = mGUIClient->factory();
03725   if ( factory )
03726     factory->removeClient( mGUIClient );
03727 
03728   if ( !mTroubleshootFolderAction ) {
03729     mTroubleshootFolderAction = new KAction( i18n("&Troubleshoot IMAP Cache..."), "wizard", 0,
03730      this, SLOT(slotTroubleshootFolder()), actionCollection(), "troubleshoot_folder" );
03731     if ( setState )
03732       updateFolderMenu(); // set initial state of the action
03733   } else {
03734     delete mTroubleshootFolderAction ;
03735     mTroubleshootFolderAction = 0;
03736   }
03737 
03738   if ( factory )
03739     factory->addClient( mGUIClient );
03740 }
03741 
03742 bool KMMainWidget::shortcutIsValid( const KShortcut &sc ) const
03743 {
03744   KActionPtrList actions = actionCollection()->actions();
03745   KActionPtrList::Iterator it( actions.begin() );
03746   for ( ; it != actions.end(); it++ ) {
03747     if ( (*it)->shortcut() == sc ) return false;
03748   }
03749   return true;
03750 }
03751 
03752 void KMMainWidget::slotShortcutChanged( KMFolder *folder )
03753 {
03754   // remove the old one, autodelete
03755   mFolderShortcutCommands.remove( folder->idString() );
03756   if ( folder->shortcut().isNull() )
03757     return;
03758 
03759   FolderShortcutCommand *c = new FolderShortcutCommand( this, folder );
03760   mFolderShortcutCommands.insert( folder->idString(), c );
03761 
03762   QString actionlabel = QString( "FolderShortcut %1").arg( folder->prettyURL() );
03763   QString actionname = QString( "FolderShortcut %1").arg( folder->idString() );
03764   QString normalizedName = actionname.replace(" ", "_");
03765   KAction* action =
03766     new KAction(actionlabel, folder->shortcut(), c, SLOT(start()),
03767                 actionCollection(), normalizedName.local8Bit());
03768   action->setIcon( folder->unreadIconPath() );
03769   c->setAction( action ); // will be deleted along with the command
03770 }
03771 
03772 //-----------------------------------------------------------------------------
03773 QString KMMainWidget::findCurrentImapPath()
03774 {
03775   QString startPath;
03776   if (!mFolder) return startPath;
03777   if (mFolder->folderType() == KMFolderTypeImap)
03778   {
03779     startPath = static_cast<KMFolderImap*>(mFolder->storage())->imapPath();
03780   } else if (mFolder->folderType() == KMFolderTypeCachedImap)
03781   {
03782     startPath = static_cast<KMFolderCachedImap*>(mFolder->storage())->imapPath();
03783   }
03784   return startPath;
03785 }
03786 
03787 //-----------------------------------------------------------------------------
03788 ImapAccountBase* KMMainWidget::findCurrentImapAccountBase()
03789 {
03790   ImapAccountBase* account = 0;
03791   if (!mFolder) return account;
03792   if (mFolder->folderType() == KMFolderTypeImap)
03793   {
03794     account = static_cast<KMFolderImap*>(mFolder->storage())->account();
03795   } else if (mFolder->folderType() == KMFolderTypeCachedImap)
03796   {
03797     account = static_cast<KMFolderCachedImap*>(mFolder->storage())->account();
03798   }
03799   return account;
03800 }
03801 
03802 //-----------------------------------------------------------------------------
03803 void KMMainWidget::slotSubscriptionDialog()
03804 {
03805   if ( !kmkernel->askToGoOnline() )
03806     return;
03807   ImapAccountBase* account = findCurrentImapAccountBase();
03808   if ( !account ) return;
03809   const QString startPath = findCurrentImapPath();
03810 
03811   // KSubscription sets "DestruciveClose"
03812   SubscriptionDialog * dialog =
03813       new SubscriptionDialog(this, i18n("Subscription"), account, startPath);
03814   if ( dialog->exec() ) {
03815     // start a new listing
03816     if (mFolder->folderType() == KMFolderTypeImap)
03817       static_cast<KMFolderImap*>(mFolder->storage())->account()->listDirectory();
03818   }
03819 }
03820 
03821 //-----------------------------------------------------------------------------
03822 void KMMainWidget::slotLocalSubscriptionDialog()
03823 {
03824   ImapAccountBase* account = findCurrentImapAccountBase();
03825   if ( !account ) return;
03826 
03827   const QString startPath = findCurrentImapPath();
03828   // KSubscription sets "DestruciveClose"
03829   LocalSubscriptionDialog *dialog =
03830       new LocalSubscriptionDialog(this, i18n("Local Subscription"), account, startPath);
03831   if ( dialog->exec() ) {
03832     // start a new listing
03833     if (mFolder->folderType() == KMFolderTypeImap)
03834       static_cast<KMFolderImap*>(mFolder->storage())->account()->listDirectory();
03835   }
03836 }
03837 
03838 //-----------------------------------------------------------------------------
03839 void KMMainWidget::slotFolderTreeColumnsChanged()
03840 {
03841   mTotalColumnToggle->setChecked( mFolderTree->isTotalActive() );
03842   mUnreadColumnToggle->setChecked( mFolderTree->isUnreadActive() );
03843   mSizeColumnToggle->setChecked( mFolderTree->isSizeActive() );
03844 }
03845 
03846 void KMMainWidget::toggleSystemTray()
03847 {
03848   if ( !mSystemTray && GlobalSettings::self()->systemTrayEnabled() ) {
03849     mSystemTray = new KMSystemTray();
03850   }
03851   else if ( mSystemTray && !GlobalSettings::self()->systemTrayEnabled() ) {
03852     // Get rid of system tray on user's request
03853     kdDebug(5006) << "deleting systray" << endl;
03854     delete mSystemTray;
03855     mSystemTray = 0;
03856   }
03857 
03858   // Set mode of systemtray. If mode has changed, tray will handle this.
03859   if ( mSystemTray )
03860     mSystemTray->setMode( GlobalSettings::self()->systemTrayPolicy() );
03861 }
03862 
03863 //-----------------------------------------------------------------------------
03864 void KMMainWidget::slotAntiSpamWizard()
03865 {
03866   AntiSpamWizard wiz( AntiSpamWizard::AntiSpam, this, folderTree() );
03867   wiz.exec();
03868 }
03869 
03870 //-----------------------------------------------------------------------------
03871 void KMMainWidget::slotAntiVirusWizard()
03872 {
03873   AntiSpamWizard wiz( AntiSpamWizard::AntiVirus, this, folderTree() );
03874   wiz.exec();
03875 }
03876 
03877 //-----------------------------------------------------------------------------
03878 void KMMainWidget::slotFilterLogViewer()
03879 {
03880   FilterLogDialog * dlg = new FilterLogDialog( 0 );
03881   dlg->show();
03882 }
03883 
03884 //-----------------------------------------------------------------------------
03885 void KMMainWidget::updateFileMenu()
03886 {
03887   QStringList actList = kmkernel->acctMgr()->getAccounts();
03888 
03889   actionCollection()->action("check_mail")->setEnabled( actList.size() > 0 );
03890   actionCollection()->action("check_mail_in")->setEnabled( actList.size() > 0 );
03891 }
03892 
03893 
03894 //-----------------------------------------------------------------------------
03895 void KMMainWidget::setAccelsEnabled( bool enabled )
03896 {
03897   actionCollection()->kaccel()->setEnabled( enabled );
03898 }
03899 
03900 
03901 //-----------------------------------------------------------------------------
03902 KMSystemTray *KMMainWidget::systray() const
03903 {
03904   return mSystemTray;
03905 }
03906 
03907 //-----------------------------------------------------------------------------
03908 QString KMMainWidget::overrideEncoding() const
03909 {
03910   if ( mMsgView )
03911     return mMsgView->overrideEncoding();
03912   else
03913     return GlobalSettings::self()->overrideCharacterEncoding();
03914 }
03915 
03916 void KMMainWidget::slotCreateTodo()
03917 {
03918   KMMessage *msg = mHeaders->currentMsg();
03919   if ( !msg )
03920     return;
03921   KMCommand *command = new CreateTodoCommand( this, msg );
03922   command->start();
03923 }
03924 
03925 void KMMainWidget::setupFolderView()
03926 {
03927   if ( GlobalSettings::self()->enableFavoriteFolderView() ) {
03928     mFolderView = mFolderViewSplitter;
03929     mFolderTree->reparent( mFolderViewSplitter, 0, QPoint( 0, 0 ) );
03930     mFolderViewSplitter->show();
03931     mFavoriteFolderView->show();
03932   } else {
03933     mFolderView = mFolderTree;
03934     mFolderViewSplitter->hide();
03935     mFavoriteFolderView->hide();
03936   }
03937   mFolderView->reparent( mFolderViewParent, 0, QPoint( 0, 0 ) );
03938   mFolderViewParent->moveToFirst( mFolderView );
03939   mFolderTree->show();
03940 }
03941 
03942 
03943 void KMMainWidget::slotRequestFullSearchFromQuickSearch()
03944 {
03945     slotSearch();
03946 #ifdef HAVE_INDEXLIB
03947     return;
03948 #endif
03949     assert( mSearchWin );
03950     KMSearchPattern pattern;
03951     pattern.append( KMSearchRule::createInstance( "<message>", KMSearchRule::FuncContains, mQuickSearchLine->currentSearchTerm() ) );
03952     int status = mQuickSearchLine->currentStatus();
03953     if ( status != 0 ) {
03954         pattern.append( new KMSearchRuleStatus( status ) );
03955     }
03956     mSearchWin->setSearchPattern( pattern );
03957 }
03958 
03959 void KMMainWidget::updateVactionScriptStatus(bool active)
03960 {
03961   mVacationIndicatorActive = active;
03962   if ( active ) {
03963     mVacationScriptIndicator->setText( i18n("Out of office reply active") );
03964     mVacationScriptIndicator->setPaletteBackgroundColor( Qt::yellow );
03965     mVacationScriptIndicator->setCursor( QCursor( Qt::PointingHandCursor ) );
03966     mVacationScriptIndicator->show();
03967   } else {
03968     mVacationScriptIndicator->hide();
03969   }
03970 }
03971 
KDE Home | KDE Accessibility Home | Description of Access Keys