kmail Library API Documentation

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 
00021 #include <kopenwith.h>
00022 
00023 #include <kmessagebox.h>
00024 
00025 #include <kaccelmanager.h>
00026 #include <kglobalsettings.h>
00027 #include <kstdaccel.h>
00028 #include <kkeydialog.h>
00029 #include <kcharsets.h>
00030 #include <knotifyclient.h>
00031 #include <kdebug.h>
00032 #include <kapplication.h>
00033 #include <kfiledialog.h>
00034 #include <ktip.h>
00035 #include <knotifydialog.h>
00036 #include <kstandarddirs.h>
00037 #include <dcopclient.h>
00038 #include <kaddrbook.h>
00039 
00040 #include "globalsettings.h"
00041 #include "kcursorsaver.h"
00042 #include "broadcaststatus.h"
00043 using KPIM::BroadcastStatus;
00044 #include "kmfoldermgr.h"
00045 #include "kmfolderdia.h"
00046 #include "kmacctmgr.h"
00047 #include "kmfilter.h"
00048 #include "kmfoldertree.h"
00049 #include "kmreadermainwin.h"
00050 #include "kmfoldercachedimap.h"
00051 #include "kmfolderimap.h"
00052 #include "kmacctcachedimap.h"
00053 #include "kmcomposewin.h"
00054 #include "kmfolderseldlg.h"
00055 #include "kmfiltermgr.h"
00056 #include "kmsender.h"
00057 #include "kmaddrbook.h"
00058 #include "kmversion.h"
00059 #include "kmfldsearch.h"
00060 #include "kmacctfolder.h"
00061 #include "undostack.h"
00062 #include "kmcommands.h"
00063 #include "kmmainwidget.h"
00064 #include "kmmainwin.h"
00065 #include "kmsystemtray.h"
00066 #include "vacation.h"
00067 using KMail::Vacation;
00068 #include "subscriptiondialog.h"
00069 using KMail::SubscriptionDialog;
00070 #include "attachmentstrategy.h"
00071 using KMail::AttachmentStrategy;
00072 #include "headerstrategy.h"
00073 using KMail::HeaderStrategy;
00074 #include "headerstyle.h"
00075 using KMail::HeaderStyle;
00076 #include "folderjob.h"
00077 using KMail::FolderJob;
00078 #include "mailinglist-magic.h"
00079 #include "antispamwizard.h"
00080 using KMail::AntiSpamWizard;
00081 #include "filterlogdlg.h"
00082 using KMail::FilterLogDialog;
00083 #include <headerlistquicksearch.h>
00084 using KMail::HeaderListQuickSearch;
00085 
00086 #include <assert.h>
00087 #include <kstatusbar.h>
00088 #include <kstaticdeleter.h>
00089 
00090 #include <kmime_mdn.h>
00091 #include <kmime_header_parsing.h>
00092 using namespace KMime;
00093 using KMime::Types::AddrSpecList;
00094 
00095 #include "progressmanager.h"
00096 using KPIM::ProgressManager;
00097 
00098 #include "kmmainwidget.moc"
00099 
00100 QPtrList<KMMainWidget>* KMMainWidget::s_mainWidgetList = 0;
00101 static KStaticDeleter<QPtrList<KMMainWidget> > mwlsd;
00102 
00103 //-----------------------------------------------------------------------------
00104 KMMainWidget::KMMainWidget(QWidget *parent, const char *name,
00105                            KXMLGUIClient *aGUIClient,
00106                            KActionCollection *actionCollection, KConfig* config ) :
00107     QWidget(parent, name),
00108     mQuickSearchLine( 0 )
00109 {
00110   // must be the first line of the constructor:
00111   mStartupDone = FALSE;
00112   mSearchWin = 0;
00113   mIntegrated  = TRUE;
00114   mFolder = 0;
00115   mFolderThreadPref = false;
00116   mFolderThreadSubjPref = true;
00117   mReaderWindowActive = true;
00118   mReaderWindowBelow = true;
00119   mFolderHtmlPref = false;
00120   mSystemTray = 0;
00121   mDestructed = false;
00122   mActionCollection = actionCollection;
00123   mTopLayout = new QVBoxLayout(this);
00124   mFilterMenuActions.setAutoDelete(true);
00125   mFilterTBarActions.setAutoDelete(false);
00126   mFilterCommands.setAutoDelete(true);
00127   mJob = 0;
00128   mConfig = config;
00129   mGUIClient = aGUIClient;
00130 
00131   if( !s_mainWidgetList )
00132     mwlsd.setObject( s_mainWidgetList, new QPtrList<KMMainWidget>() );
00133   s_mainWidgetList->append( this );
00134 
00135   mPanner1Sep << 1 << 1;
00136   mPanner2Sep << 1 << 1;
00137 
00138   setMinimumSize(400, 300);
00139 
00140   readPreConfig();
00141   createWidgets();
00142 
00143   setupActions();
00144 
00145   readConfig();
00146 
00147   activatePanners();
00148 
00149   QTimer::singleShot( 0, this, SLOT( slotShowStartupFolder() ));
00150 
00151   connect( kmkernel->acctMgr(), SIGNAL( checkedMail( bool, bool, const QMap<QString, int> & ) ),
00152            this, SLOT( slotMailChecked( bool, bool, const QMap<QString, int> & ) ) );
00153 
00154   connect(kmkernel, SIGNAL( configChanged() ),
00155           this, SLOT( slotConfigChanged() ));
00156 
00157   // display the full path to the folder in the caption
00158   connect(mFolderTree, SIGNAL(currentChanged(QListViewItem*)),
00159       this, SLOT(slotChangeCaption(QListViewItem*)));
00160 
00161   toggleSystemTray();
00162 
00163   // must be the last line of the constructor:
00164   mStartupDone = TRUE;
00165 }
00166 
00167 
00168 //-----------------------------------------------------------------------------
00169 //The kernel may have already been deleted when this method is called,
00170 //perform all cleanup that requires the kernel in destruct()
00171 KMMainWidget::~KMMainWidget()
00172 {
00173   s_mainWidgetList->remove( this );
00174   destruct();
00175 }
00176 
00177 
00178 //-----------------------------------------------------------------------------
00179 //This method performs all cleanup that requires the kernel to exist.
00180 void KMMainWidget::destruct()
00181 {
00182   if (mDestructed)
00183     return;
00184   if (mSearchWin)
00185     mSearchWin->close();
00186   writeConfig();
00187   writeFolderConfig();
00188   delete mHeaders;
00189   delete mFolderTree;
00190   delete mSystemTray;
00191   delete mMsgView;
00192   mDestructed = true;
00193 }
00194 
00195 
00196 //-----------------------------------------------------------------------------
00197 void KMMainWidget::readPreConfig(void)
00198 {
00199   const KConfigGroup geometry( KMKernel::config(), "Geometry" );
00200   const KConfigGroup general( KMKernel::config(), "General" );
00201 
00202   mLongFolderList = geometry.readEntry( "FolderList", "long" ) != "short";
00203   mEncodingStr = general.readEntry("encoding", "").latin1();
00204   mReaderWindowActive = geometry.readEntry( "readerWindowMode", "below" ) != "hide";
00205   mReaderWindowBelow = geometry.readEntry( "readerWindowMode", "below" ) == "below";
00206 }
00207 
00208 
00209 //-----------------------------------------------------------------------------
00210 void KMMainWidget::readFolderConfig(void)
00211 {
00212   if (!mFolder)
00213     return;
00214 
00215   KConfig *config = KMKernel::config();
00216   KConfigGroupSaver saver(config, "Folder-" + mFolder->idString());
00217   mFolderThreadPref = config->readBoolEntry( "threadMessagesOverride", false );
00218   mFolderThreadSubjPref = config->readBoolEntry( "threadMessagesBySubject", true );
00219   mFolderHtmlPref = config->readBoolEntry( "htmlMailOverride", false );
00220 }
00221 
00222 
00223 //-----------------------------------------------------------------------------
00224 void KMMainWidget::writeFolderConfig(void)
00225 {
00226   if (!mFolder)
00227     return;
00228 
00229   KConfig *config = KMKernel::config();
00230   KConfigGroupSaver saver(config, "Folder-" + mFolder->idString());
00231   config->writeEntry( "threadMessagesOverride", mFolderThreadPref );
00232   config->writeEntry( "threadMessagesBySubject", mFolderThreadSubjPref );
00233   config->writeEntry( "htmlMailOverride", mFolderHtmlPref );
00234 }
00235 
00236 
00237 //-----------------------------------------------------------------------------
00238 void KMMainWidget::readConfig(void)
00239 {
00240   KConfig *config = KMKernel::config();
00241 
00242   bool oldLongFolderList =  mLongFolderList;
00243   bool oldReaderWindowActive = mReaderWindowActive;
00244   bool oldReaderWindowBelow = mReaderWindowBelow;
00245 
00246   QString str;
00247   QSize siz;
00248 
00249   if (mStartupDone)
00250   {
00251     writeConfig();
00252 
00253     readPreConfig();
00254     mHeaders->refreshNestedState();
00255 
00256     bool layoutChanged = ( oldLongFolderList != mLongFolderList )
00257                     || ( oldReaderWindowActive != mReaderWindowActive )
00258                     || ( oldReaderWindowBelow != mReaderWindowBelow );
00259 
00260 
00261     if( layoutChanged ) {
00262       hide();
00263       // delete all panners
00264       delete mPanner1; // will always delete the others
00265       createWidgets();
00266     }
00267 
00268   }
00269 
00270   // read "Reader" config options
00271   KConfigGroup readerConfig( config, "Reader" );
00272   mHtmlPref = readerConfig.readBoolEntry( "htmlMail", false );
00273   // restore the toggle action to the saved value; this is also read during
00274   // the reader initialization
00275   if (mMsgView)
00276     toggleFixFontAction()->setChecked( readerConfig.readBoolEntry( "useFixedFont",
00277                                                                false ) );
00278 
00279   { // area for config group "Geometry"
00280     KConfigGroupSaver saver(config, "Geometry");
00281     mThreadPref = config->readBoolEntry( "nestedMessages", false );
00282     // size of the mainwin
00283     QSize defaultSize(750,560);
00284     siz = config->readSizeEntry("MainWin", &defaultSize);
00285     if (!siz.isEmpty())
00286       resize(siz);
00287     // default width of the foldertree
00288     static const int folderpanewidth = 250;
00289 
00290     const int folderW = config->readNumEntry( "FolderPaneWidth", folderpanewidth );
00291     const int headerW = config->readNumEntry( "HeaderPaneWidth", width()-folderpanewidth );
00292     const int headerH = config->readNumEntry( "HeaderPaneHeight", 180 );
00293     const int readerH = config->readNumEntry( "ReaderPaneHeight", 280 );
00294 
00295     mPanner1Sep.clear();
00296     mPanner2Sep.clear();
00297     QValueList<int> & widths = mLongFolderList ? mPanner1Sep : mPanner2Sep ;
00298     QValueList<int> & heights = mLongFolderList ? mPanner2Sep : mPanner1Sep ;
00299 
00300     widths << folderW << headerW;
00301     heights << headerH << readerH;
00302 
00303     bool layoutChanged = ( oldLongFolderList != mLongFolderList )
00304                     || ( oldReaderWindowActive != mReaderWindowActive )
00305                     || ( oldReaderWindowBelow != mReaderWindowBelow );
00306 
00307     if (!mStartupDone || layoutChanged )
00308     {
00312       // The columns are shown by default.
00313 
00314       const int unreadColumn = config->readNumEntry("UnreadColumn", -1);
00315       const int totalColumn = config->readNumEntry("TotalColumn", -1);
00316 
00317       /* we need to _activate_ them in the correct order
00318       * this is ugly because we can't use header()->moveSection
00319       * but otherwise the restoreLayout from KMFolderTree
00320       * doesn't know that to do */
00321       if (unreadColumn != -1 && unreadColumn < totalColumn)
00322         mFolderTree->addUnreadColumn( i18n("Unread"), 70 );
00323       if (totalColumn != -1)
00324         mFolderTree->addTotalColumn( i18n("Total"), 70 );
00325       if (unreadColumn != -1 && unreadColumn > totalColumn)
00326         mFolderTree->addUnreadColumn( i18n("Unread"), 70 );
00327       mUnreadColumnToggle->setChecked( mFolderTree->isUnreadActive() );
00328       mUnreadTextToggle->setChecked( !mFolderTree->isUnreadActive() );
00329       mTotalColumnToggle->setChecked( mFolderTree->isTotalActive() );
00330 
00331       mFolderTree->updatePopup();
00332     }
00333   }
00334 
00335   if (mMsgView)
00336     mMsgView->readConfig();
00337   slotSetEncoding();
00338   mHeaders->readConfig();
00339   mHeaders->restoreLayout(KMKernel::config(), "Header-Geometry");
00340   mFolderTree->readConfig();
00341 
00342   { // area for config group "General"
00343     KConfigGroupSaver saver(config, "General");
00344     mBeepOnNew = config->readBoolEntry("beep-on-mail", false);
00345     mConfirmEmpty = config->readBoolEntry("confirm-before-empty", true);
00346     // startup-Folder, defaults to system-inbox
00347     mStartupFolder = config->readEntry("startupFolder", kmkernel->inboxFolder()->idString());
00348     if (!mStartupDone)
00349     {
00350       // check mail on startup
00351       bool check = config->readBoolEntry("checkmail-startup", false);
00352       if (check)
00353         // do it after building the kmmainwin, so that the progressdialog is available
00354         QTimer::singleShot( 0, this, SLOT( slotCheckMail() ) );
00355     }
00356   }
00357 
00358   // Re-activate panners
00359   if (mStartupDone)
00360   {
00361     // Update systray
00362     toggleSystemTray();
00363 
00364     bool layoutChanged = ( oldLongFolderList != mLongFolderList )
00365                     || ( oldReaderWindowActive != mReaderWindowActive )
00366                     || ( oldReaderWindowBelow != mReaderWindowBelow );
00367     if ( layoutChanged ) {
00368       activatePanners();
00369     }
00370 
00371     // reload foldertree
00372     mFolderTree->reload();
00373     mFolderTree->showFolder( mFolder );
00374 
00375     // sanders - New code
00376     mHeaders->setFolder(mFolder);
00377     if (mMsgView) {
00378       int aIdx = mHeaders->currentItemIndex();
00379       if (aIdx != -1)
00380         mMsgView->setMsg( mFolder->getMsg(aIdx), true );
00381       else
00382         mMsgView->clear( true );
00383     }
00384     updateMessageActions();
00385     show();
00386     // sanders - Maybe this fixes a bug?
00387 
00388   }
00389   updateMessageMenu();
00390   updateFileMenu();
00391   updateViewMenu();
00392 }
00393 
00394 
00395 //-----------------------------------------------------------------------------
00396 void KMMainWidget::writeConfig(void)
00397 {
00398   QString s;
00399   KConfig *config = KMKernel::config();
00400   KConfigGroup geometry( config, "Geometry" );
00401   KConfigGroup general( config, "General" );
00402 
00403   if (mMsgView)
00404     mMsgView->writeConfig();
00405 
00406   mFolderTree->writeConfig();
00407 
00408   geometry.writeEntry( "MainWin", this->geometry().size() );
00409 
00410   const QValueList<int> widths = ( mLongFolderList ? mPanner1 : mPanner2 )->sizes();
00411   const QValueList<int> heights = ( mLongFolderList ? mPanner2 : mPanner1 )->sizes();
00412 
00413   geometry.writeEntry( "FolderPaneWidth", widths[0] );
00414   geometry.writeEntry( "HeaderPaneWidth", widths[1] );
00415 
00416   // Only save when the widget is shown (to avoid saving a wrong value)
00417   if ( mSearchAndHeaders && mSearchAndHeaders->isShown() ) {
00418     geometry.writeEntry( "HeaderPaneHeight", heights[0] );
00419     geometry.writeEntry( "ReaderPaneHeight", heights[1] );
00420   }
00421 
00422   // save the state of the unread/total-columns
00423   geometry.writeEntry( "UnreadColumn", mFolderTree->unreadIndex() );
00424   geometry.writeEntry( "TotalColumn", mFolderTree->totalIndex() );
00425 
00426   general.writeEntry("encoding", QString(mEncodingStr));
00427 }
00428 
00429 
00430 //-----------------------------------------------------------------------------
00431 void KMMainWidget::createWidgets(void)
00432 {
00433   QAccel *accel = new QAccel(this, "createWidgets()");
00434 
00435   // Create the splitters according to the layout settings
00436   QWidget *headerParent = 0, *folderParent = 0,
00437             *mimeParent = 0, *messageParent = 0;
00438 
00439   const bool opaqueResize = KGlobalSettings::opaqueResize();
00440   if ( mLongFolderList ) {
00441     // superior splitter: folder tree vs. rest
00442     // inferior splitter: headers vs. message vs. mime tree
00443     mPanner1 = new QSplitter( Qt::Horizontal, this, "panner 1" );
00444     mPanner1->setOpaqueResize( opaqueResize );
00445     Qt::Orientation orientation = mReaderWindowBelow ? Qt::Vertical : Qt::Horizontal;
00446     mPanner2 = new QSplitter( orientation, mPanner1, "panner 2" );
00447     mPanner2->setOpaqueResize( opaqueResize );
00448     folderParent = mPanner1;
00449     headerParent = mimeParent = messageParent = mPanner2;
00450   } else /* !mLongFolderList */ {
00451     // superior splitter: ( folder tree + headers ) vs. message vs. mime
00452     // inferior splitter: folder tree vs. headers
00453     mPanner1 = new QSplitter( Qt::Vertical, this, "panner 1" );
00454     mPanner1->setOpaqueResize( opaqueResize );
00455     mPanner2 = new QSplitter( Qt::Horizontal, mPanner1, "panner 2" );
00456     mPanner2->setOpaqueResize( opaqueResize );
00457     headerParent = folderParent = mPanner2;
00458     mimeParent = messageParent = mPanner1;
00459   }
00460 
00461 #ifndef NDEBUG
00462   if( mPanner1 ) mPanner1->dumpObjectTree();
00463   if( mPanner2 ) mPanner2->dumpObjectTree();
00464 #endif
00465 
00466   mTopLayout->add( mPanner1 );
00467 
00468   // BUG -sanders these accelerators stop working after switching
00469   // between long/short folder layout
00470   // Probably need to disconnect them first.
00471 
00472   // create list of messages
00473 #ifndef NDEBUG
00474   headerParent->dumpObjectTree();
00475 #endif
00476   mSearchAndHeaders = new QVBox( headerParent );
00477   mSearchToolBar = new KToolBar( mSearchAndHeaders, "search toolbar");
00478   mSearchToolBar->boxLayout()->setSpacing( KDialog::spacingHint() );
00479   QLabel *label = new QLabel( i18n("S&earch:"), mSearchToolBar, "kde toolbar widget" );
00480 
00481 
00482   mHeaders = new KMHeaders(this, mSearchAndHeaders, "headers");
00483   mQuickSearchLine = new HeaderListQuickSearch( mSearchToolBar, mHeaders,
00484                                                     actionCollection(), "headers quick search line" );
00485   label->setBuddy( mQuickSearchLine );
00486   mSearchToolBar->setStretchableWidget( mQuickSearchLine );
00487     connect( mHeaders, SIGNAL( messageListUpdated() ),
00488            mQuickSearchLine, SLOT( updateSearch() ) );
00489   if ( !GlobalSettings::quickSearchActive() ) mSearchToolBar->hide();
00490 
00491   mHeaders->setFullWidth(true);
00492   if (mReaderWindowActive) {
00493     connect(mHeaders, SIGNAL(selected(KMMessage*)),
00494             this, SLOT(slotMsgSelected(KMMessage*)));
00495   }
00496   connect(mHeaders, SIGNAL(activated(KMMessage*)),
00497       this, SLOT(slotMsgActivated(KMMessage*)));
00498   connect( mHeaders, SIGNAL( selectionChanged() ),
00499            SLOT( startUpdateMessageActionsTimer() ) );
00500   accel->connectItem(accel->insertItem(SHIFT+Key_Left),
00501                      mHeaders, SLOT(selectPrevMessage()));
00502   accel->connectItem(accel->insertItem(SHIFT+Key_Right),
00503                      mHeaders, SLOT(selectNextMessage()));
00504 
00505   if (!mEncodingStr.isEmpty())
00506     mCodec = KMMsgBase::codecForName(mEncodingStr);
00507   else mCodec = 0;
00508 
00509   if (mReaderWindowActive) {
00510     mMsgView = new KMReaderWin(messageParent, this, actionCollection(), 0 );
00511 
00512     connect(mMsgView, SIGNAL(replaceMsgByUnencryptedVersion()),
00513         this, SLOT(slotReplaceMsgByUnencryptedVersion()));
00514     connect(mMsgView, SIGNAL(popupMenu(KMMessage&,const KURL&,const QPoint&)),
00515         this, SLOT(slotMsgPopup(KMMessage&,const KURL&,const QPoint&)));
00516     connect(mMsgView, SIGNAL(urlClicked(const KURL&,int)),
00517         mMsgView, SLOT(slotUrlClicked()));
00518     connect(mHeaders, SIGNAL(maybeDeleting()),
00519         mMsgView, SLOT(clearCache()));
00520     connect(mMsgView, SIGNAL(noDrag()),
00521         mHeaders, SLOT(slotNoDrag()));
00522     accel->connectItem(accel->insertItem(Key_Up),
00523         mMsgView, SLOT(slotScrollUp()));
00524     accel->connectItem(accel->insertItem(Key_Down),
00525         mMsgView, SLOT(slotScrollDown()));
00526     accel->connectItem(accel->insertItem(Key_Prior),
00527         mMsgView, SLOT(slotScrollPrior()));
00528     accel->connectItem(accel->insertItem(Key_Next),
00529         mMsgView, SLOT(slotScrollNext()));
00530   } else {
00531     mMsgView = NULL;
00532   }
00533 
00534   new KAction( i18n("Move Message to Folder"), Key_M, this,
00535                SLOT(slotMoveMsg()), actionCollection(),
00536                "move_message_to_folder" );
00537   new KAction( i18n("Copy Message to Folder"), Key_C, this,
00538                SLOT(slotCopyMsg()), actionCollection(),
00539                "copy_message_to_folder" );
00540   accel->connectItem(accel->insertItem(Key_M),
00541              this, SLOT(slotMoveMsg()) );
00542   accel->connectItem(accel->insertItem(Key_C),
00543              this, SLOT(slotCopyMsg()) );
00544 
00545   // create list of folders
00546   mFolderTree = new KMFolderTree(this, folderParent, "folderTree");
00547 
00548   connect(mFolderTree, SIGNAL(folderSelected(KMFolder*)),
00549       this, SLOT(folderSelected(KMFolder*)));
00550   connect( mFolderTree, SIGNAL( folderSelected( KMFolder* ) ),
00551            mQuickSearchLine, SLOT( reset() ) );
00552   connect(mFolderTree, SIGNAL(folderSelectedUnread(KMFolder*)),
00553       this, SLOT(folderSelectedUnread(KMFolder*)));
00554   connect(mFolderTree, SIGNAL(folderDrop(KMFolder*)),
00555       this, SLOT(slotMoveMsgToFolder(KMFolder*)));
00556   connect(mFolderTree, SIGNAL(folderDropCopy(KMFolder*)),
00557           this, SLOT(slotCopyMsgToFolder(KMFolder*)));
00558   connect(mFolderTree, SIGNAL(columnsChanged()),
00559           this, SLOT(slotFolderTreeColumnsChanged()));
00560 
00561   //Commands not worthy of menu items, but that deserve configurable keybindings
00562   new KAction(
00563     i18n("Remove Duplicate Messages"), CTRL+Key_Asterisk, this,
00564     SLOT(removeDuplicates()), actionCollection(), "remove_duplicate_messages");
00565 
00566   new KAction(
00567    i18n("Focus on Next Folder"), CTRL+Key_Right, mFolderTree,
00568    SLOT(incCurrentFolder()), actionCollection(), "inc_current_folder");
00569   accel->connectItem(accel->insertItem(CTRL+Key_Right),
00570                      mFolderTree, SLOT(incCurrentFolder()));
00571 
00572   new KAction(
00573     i18n("Abort Current Operation"), Key_Escape, ProgressManager::instance(),
00574     SLOT(slotAbortAll()), actionCollection(), "cancel" );
00575   accel->connectItem(accel->insertItem(Key_Escape),
00576                      ProgressManager::instance(), SLOT(slotAbortAll()));
00577 
00578   new KAction(
00579    i18n("Focus on Previous Folder"), CTRL+Key_Left, mFolderTree,
00580    SLOT(decCurrentFolder()), actionCollection(), "dec_current_folder");
00581   accel->connectItem(accel->insertItem(CTRL+Key_Left),
00582                      mFolderTree, SLOT(decCurrentFolder()));
00583 
00584   new KAction(
00585    i18n("Select Folder with Focus"), CTRL+Key_Space, mFolderTree,
00586    SLOT(selectCurrentFolder()), actionCollection(), "select_current_folder");
00587   accel->connectItem(accel->insertItem(CTRL+Key_Space),
00588                      mFolderTree, SLOT(selectCurrentFolder()));
00589 
00590   connect( kmkernel->outboxFolder(), SIGNAL( msgRemoved(int, QString, QString) ),
00591            SLOT( startUpdateMessageActionsTimer() ) );
00592   connect( kmkernel->outboxFolder(), SIGNAL( msgAdded(int) ),
00593            SLOT( startUpdateMessageActionsTimer() ) );
00594 }
00595 
00596 
00597 //-----------------------------------------------------------------------------
00598 void KMMainWidget::activatePanners(void)
00599 {
00600   if (mMsgView) {
00601     QObject::disconnect( actionCollection()->action( "kmail_copy" ),
00602         SIGNAL( activated() ),
00603         mMsgView, SLOT( slotCopySelectedText() ));
00604   }
00605   if ( mLongFolderList ) {
00606     mSearchAndHeaders->reparent( mPanner2, 0, QPoint( 0, 0 ) );
00607     if (mMsgView) {
00608       mMsgView->reparent( mPanner2, 0, QPoint( 0, 0 ) );
00609       mPanner2->moveToLast( mMsgView );
00610     }
00611     mFolderTree->reparent( mPanner1, 0, QPoint( 0, 0 ) );
00612     mPanner1->moveToLast( mPanner2 );
00613     mPanner1->setSizes( mPanner1Sep );
00614     mPanner1->setResizeMode( mFolderTree, QSplitter::KeepSize );
00615     mPanner2->setSizes( mPanner2Sep );
00616     mPanner2->setResizeMode( mSearchAndHeaders, QSplitter::KeepSize );
00617   } else /* !mLongFolderList */ {
00618     mFolderTree->reparent( mPanner2, 0, QPoint( 0, 0 ) );
00619     mSearchAndHeaders->reparent( mPanner2, 0, QPoint( 0, 0 ) );
00620     mPanner2->moveToLast( mSearchAndHeaders );
00621     mPanner1->moveToFirst( mPanner2 );
00622     if (mMsgView) {
00623       mMsgView->reparent( mPanner1, 0, QPoint( 0, 0 ) );
00624       mPanner1->moveToLast( mMsgView );
00625     }
00626     mPanner1->setSizes( mPanner1Sep );
00627     mPanner2->setSizes( mPanner2Sep );
00628     mPanner1->setResizeMode( mPanner2, QSplitter::KeepSize );
00629     mPanner2->setResizeMode( mFolderTree, QSplitter::KeepSize );
00630   }
00631 
00632   if (mMsgView) {
00633     QObject::connect( actionCollection()->action( "kmail_copy" ),
00634             SIGNAL( activated() ),
00635             mMsgView, SLOT( slotCopySelectedText() ));
00636   }
00637 }
00638 
00639 
00640 //-----------------------------------------------------------------------------
00641 void KMMainWidget::slotSetEncoding()
00642 {
00643     mEncodingStr = KGlobal::charsets()->encodingForName(mEncoding->currentText()).latin1();
00644     if (mEncoding->currentItem() == 0) // Auto
00645     {
00646       mCodec = 0;
00647       mEncodingStr = "";
00648     }
00649     else
00650       mCodec = KMMsgBase::codecForName( mEncodingStr );
00651     if (mMsgView)
00652       mMsgView->setOverrideCodec(mCodec);
00653     return;
00654 }
00655 
00656 //-----------------------------------------------------------------------------
00657 void KMMainWidget::hide()
00658 {
00659   QWidget::hide();
00660 }
00661 
00662 
00663 //-----------------------------------------------------------------------------
00664 void KMMainWidget::show()
00665 {
00666   QWidget::show();
00667 }
00668 
00669 //-------------------------------------------------------------------------
00670 void KMMainWidget::slotSearch()
00671 {
00672   if(!mSearchWin)
00673   {
00674     mSearchWin = new KMFldSearch(this, "Search", mFolder, false);
00675     connect(mSearchWin, SIGNAL(destroyed()),
00676         this, SLOT(slotSearchClosed()));
00677   }
00678   else
00679   {
00680     mSearchWin->activateFolder(mFolder);
00681   }
00682 
00683   mSearchWin->show();
00684   KWin::activateWindow( mSearchWin->winId() );
00685 }
00686 
00687 
00688 //-------------------------------------------------------------------------
00689 void KMMainWidget::slotSearchClosed()
00690 {
00691   mSearchWin = 0;
00692 }
00693 
00694 
00695 //-------------------------------------------------------------------------
00696 void KMMainWidget::slotFind()
00697 {
00698   if( mMsgView )
00699     mMsgView->slotFind();
00700 }
00701 
00702 
00703 //-----------------------------------------------------------------------------
00704 void KMMainWidget::slotHelp()
00705 {
00706   kapp->invokeHelp();
00707 }
00708 
00709 
00710 //-----------------------------------------------------------------------------
00711 void KMMainWidget::slotNewMailReader()
00712 {
00713   KMMainWin *d;
00714 
00715   d = new KMMainWin();
00716   d->show();
00717   d->resize(d->size());
00718 }
00719 
00720 
00721 //-----------------------------------------------------------------------------
00722 void KMMainWidget::slotFilter()
00723 {
00724   kmkernel->filterMgr()->openDialog( this );
00725 }
00726 
00727 
00728 //-----------------------------------------------------------------------------
00729 void KMMainWidget::slotPopFilter()
00730 {
00731   kmkernel->popFilterMgr()->openDialog( this );
00732 }
00733 
00734 
00735 //-----------------------------------------------------------------------------
00736 void KMMainWidget::slotAddrBook()
00737 {
00738   KAddrBookExternal::openAddressBook(this);
00739 }
00740 
00741 
00742 //-----------------------------------------------------------------------------
00743 void KMMainWidget::slotImport()
00744 {
00745   KRun::runCommand("kmailcvt");
00746 }
00747 
00748 
00749 //-----------------------------------------------------------------------------
00750 void KMMainWidget::slotAddFolder()
00751 {
00752   KMFolderDialog *d;
00753 
00754   d = new KMFolderDialog(0, &(kmkernel->folderMgr()->dir()),
00755              mFolderTree, i18n("Create Folder"));
00756   if (d->exec()) {
00757     mFolderTree->reload();
00758     QListViewItem *qlvi = mFolderTree->indexOfFolder( mFolder );
00759     if (qlvi) {
00760       qlvi->setOpen(TRUE);
00761       mFolderTree->setCurrentItem( qlvi );
00762     }
00763   }
00764   delete d;
00765 }
00766 
00767 
00768 //-----------------------------------------------------------------------------
00769 void KMMainWidget::slotCheckMail()
00770 {
00771  kmkernel->acctMgr()->checkMail(true);
00772 }
00773 
00774 
00775 //-----------------------------------------------------------------------------
00776 void KMMainWidget::slotCheckOneAccount(int item)
00777 {
00778   kmkernel->acctMgr()->intCheckMail(item);
00779 }
00780 
00781 //-----------------------------------------------------------------------------
00782 void KMMainWidget::slotMailChecked( bool newMail, bool sendOnCheck,
00783                                     const QMap<QString, int> & newInFolder )
00784 {
00785   const bool sendOnAll =
00786     GlobalSettings::sendOnCheck() == GlobalSettings::EnumSendOnCheck::SendOnAllChecks;
00787   const bool sendOnManual =
00788     GlobalSettings::sendOnCheck() == GlobalSettings::EnumSendOnCheck::SendOnManualChecks;
00789   if( sendOnAll || (sendOnManual && sendOnCheck ) )
00790     slotSendQueued();
00791 
00792   if ( !newMail || newInFolder.isEmpty() )
00793     return;
00794 
00795   kapp->dcopClient()->emitDCOPSignal( "unreadCountChanged()", QByteArray() );
00796 
00797   // build summary for new mail message
00798   bool showNotification = false;
00799   QString summary;
00800   QStringList keys( newInFolder.keys() );
00801   keys.sort();
00802   for ( QStringList::const_iterator it = keys.begin();
00803         it != keys.end();
00804         ++it ) {
00805     kdDebug(5006) << newInFolder.find( *it ).data() << " new message(s) in "
00806                   << *it << endl;
00807 
00808     KMFolder *folder = kmkernel->findFolderById( *it );
00809 
00810     if ( !folder->ignoreNewMail() ) {
00811       showNotification = true;
00812       if ( GlobalSettings::verboseNewMailNotification() ) {
00813         summary += "<br>" + i18n( "1 new message in %1",
00814                                   "%n new messages in %1",
00815                                   newInFolder.find( *it ).data() )
00816                             .arg( folder->prettyURL() );
00817       }
00818     }
00819   }
00820 
00821   if ( !showNotification )
00822     return;
00823 
00824   if ( GlobalSettings::verboseNewMailNotification() ) {
00825     summary = i18n( "%1 is a list of the number of new messages per folder",
00826                     "<b>New mail arrived</b><br>%1" )
00827               .arg( summary );
00828   }
00829   else {
00830     summary = i18n( "New mail arrived" );
00831   }
00832 
00833   if(kmkernel->xmlGuiInstance()) {
00834     KNotifyClient::Instance instance(kmkernel->xmlGuiInstance());
00835     KNotifyClient::event( topLevelWidget()->winId(), "new-mail-arrived",
00836                           summary );
00837   }
00838   else
00839     KNotifyClient::event( topLevelWidget()->winId(), "new-mail-arrived",
00840                           summary );
00841 
00842   if (mBeepOnNew) {
00843     KNotifyClient::beep();
00844   }
00845 
00846   // Todo:
00847   // scroll mHeaders to show new items if current item would
00848   // still be visible
00849   //  mHeaders->showNewMail();
00850 }
00851 
00852 
00853 //-----------------------------------------------------------------------------
00854 void KMMainWidget::slotCompose()
00855 {
00856   KMComposeWin *win;
00857   KMMessage* msg = new KMMessage;
00858 
00859   if ( mFolder ) {
00860       msg->initHeader( mFolder->identity() );
00861       win = new KMComposeWin(msg, mFolder->identity());
00862   } else {
00863       msg->initHeader();
00864       win = new KMComposeWin(msg);
00865   }
00866 
00867   win->show();
00868 
00869 }
00870 
00871 
00872 //-----------------------------------------------------------------------------
00873 void KMMainWidget::slotPostToML()
00874 {
00875   if ( mFolder && mFolder->isMailingListEnabled() ) {
00876     KMCommand *command = new KMMailingListPostCommand( this, mFolder );
00877     command->start();
00878   }
00879   else
00880     slotCompose();
00881 }
00882 
00883 
00884 //-----------------------------------------------------------------------------
00885 void KMMainWidget::slotModifyFolder()
00886 {
00887   if (!mFolderTree) return;
00888   KMFolderTreeItem *item = static_cast<KMFolderTreeItem*>( mFolderTree->currentItem() );
00889   if ( item )
00890     modifyFolder( item );
00891 }
00892 
00893 //-----------------------------------------------------------------------------
00894 void KMMainWidget::modifyFolder( KMFolderTreeItem* folderItem )
00895 {
00896   KMFolder* folder = folderItem->folder();
00897   KMFolderTree* folderTree = static_cast<KMFolderTree *>( folderItem->listView() );
00898   KMFolderDialog props( folder, folder->parent(), folderTree,
00899                         i18n("Properties of Folder %1").arg( folder->label() ) );
00900   props.exec();
00901   updateFolderMenu();
00902 }
00903 
00904 //-----------------------------------------------------------------------------
00905 void KMMainWidget::slotExpireFolder()
00906 {
00907   QString     str;
00908   bool        canBeExpired = true;
00909 
00910   if (!mFolder) return;
00911 
00912   if (!mFolder->isAutoExpire()) {
00913     canBeExpired = false;
00914   } else if (mFolder->getUnreadExpireUnits()==expireNever &&
00915          mFolder->getReadExpireUnits()==expireNever) {
00916     canBeExpired = false;
00917   }
00918 
00919   if (!canBeExpired) {
00920     str = i18n("This folder does not have any expiry options set");
00921     KMessageBox::information(this, str);
00922     return;
00923   }
00924   KConfig           *config = KMKernel::config();
00925   KConfigGroupSaver saver(config, "General");
00926 
00927   if (config->readBoolEntry("warn-before-expire", true)) {
00928     str = i18n("<qt>Are you sure you want to expire the folder <b>%1</b>?</qt>").arg(mFolder->label());
00929     if (KMessageBox::warningContinueCancel(this, str, i18n("Expire Folder"),
00930                        i18n("&Expire"))
00931     != KMessageBox::Continue) return;
00932   }
00933 
00934   mFolder->expireOldMessages( true /*immediate*/);
00935 }
00936 
00937 //-----------------------------------------------------------------------------
00938 void KMMainWidget::slotEmptyFolder()
00939 {
00940   QString str;
00941 
00942   if (!mFolder) return;
00943   bool isTrash = kmkernel->folderIsTrash(mFolder);
00944 
00945   if (mConfirmEmpty)
00946   {
00947     QString title = (isTrash) ? i18n("Empty Trash") : i18n("Move to Trash");
00948     QString text = (isTrash) ?
00949       i18n("Are you sure you want to empty the trash folder?") :
00950       i18n("<qt>Are you sure you want to move all messages from "
00951            "folder <b>%1</b> to the trash?</qt>").arg(mFolder->label());
00952 
00953     if (KMessageBox::warningContinueCancel(this, text, title, KGuiItem( title, "edittrash"))
00954       != KMessageBox::Continue) return;
00955   }
00956   KCursorSaver busy(KBusyPtr::busy());
00957   slotMarkAll();
00958   if (isTrash) {
00959     /* Don't ask for confirmation again when deleting, the user has already
00960        confirmed. */
00961     slotDeleteMsg( false );
00962   }
00963   else
00964     slotTrashMsg();
00965 
00966   if (mMsgView) mMsgView->clearCache();
00967 
00968   if ( !isTrash )
00969     BroadcastStatus::instance()->setStatusMsg(i18n("Moved all messages to the trash"));
00970 
00971   updateMessageActions();
00972 }
00973 
00974 
00975 //-----------------------------------------------------------------------------
00976 void KMMainWidget::slotRemoveFolder()
00977 {
00978   QString str;
00979   QDir dir;
00980 
00981   if (!mFolder) return;
00982   if (mFolder->isSystemFolder()) return;
00983 
00984   if ( mFolder->folderType() == KMFolderTypeSearch ) {
00985      str = i18n("<qt>Are you sure you want to delete the search folder "
00986                 "<b>%1</b>? The messages displayed in it will not be deleted "
00987                 "if you do so, as they are stored in a different folder.</qt>")
00988 
00989            .arg(mFolder->label());
00990   } else {
00991     if ( mFolder->count() == 0 ) {
00992       if ( !mFolder->child() || mFolder->child()->isEmpty() ) {
00993         str = i18n("<qt>Are you sure you want to delete the empty folder "
00994                    "<b>%1</b>?</qt>")
00995               .arg(mFolder->label());
00996       }
00997       else {
00998         str = i18n("<qt>Are you sure you want to delete the empty folder "
00999                    "<b>%1</b> and all its subfolders? Those subfolders "
01000                    "might not be empty and their  contents will be "
01001                    "discarded as well.</qt>")
01002               .arg(mFolder->label());
01003       }
01004     } else {
01005       if ( !mFolder->child() || mFolder->child()->isEmpty() ) {
01006         str = i18n("<qt>Are you sure you want to delete the folder "
01007                  "<b>%1</b>, discarding its contents?</qt>")
01008               .arg(mFolder->label());
01009       }
01010       else {
01011         str = i18n("<qt>Are you sure you want to delete the folder "
01012                  "<b>%1</b> and all its subfolders, discarding their "
01013                  "contents?</qt>")
01014             .arg(mFolder->label());
01015       }
01016     }
01017   }
01018 
01019   if (KMessageBox::warningContinueCancel(this, str, i18n("Delete Folder"),
01020                                          KGuiItem( i18n("&Delete"), "editdelete"))
01021       == KMessageBox::Continue)
01022   {
01023     if (mFolder->hasAccounts())
01024     {
01025       // this folder has an account, so we need to change that to the inbox
01026       KMAccount* acct = 0;
01027       KMAcctFolder* acctFolder = static_cast<KMAcctFolder*>(mFolder);
01028       for ( acct = acctFolder->account(); acct; acct = acctFolder->nextAccount() )
01029       {
01030         acct->setFolder(kmkernel->inboxFolder());
01031         KMessageBox::information(this,
01032             i18n("<qt>The destination folder of the account <b>%1</b> was restored to the inbox.</qt>").arg(acct->name()));
01033       }
01034     }
01035     if (mFolder->folderType() == KMFolderTypeImap)
01036       kmkernel->imapFolderMgr()->remove(mFolder);
01037     else if (mFolder->folderType() == KMFolderTypeCachedImap) {
01038       // Deleted by user -> tell the account (see KMFolderCachedImap::listDirectory2)
01039       KMFolderCachedImap* storage = static_cast<KMFolderCachedImap*>( mFolder->storage() );
01040       KMAcctCachedImap* acct = storage->account();
01041       if ( acct )
01042         acct->addDeletedFolder( storage->imapPath() );
01043 
01044       kmkernel->dimapFolderMgr()->remove(mFolder);
01045     }
01046     else if (mFolder->folderType() == KMFolderTypeSearch)
01047       kmkernel->searchFolderMgr()->remove(mFolder);
01048     else
01049       kmkernel->folderMgr()->remove(mFolder);
01050   }
01051 }
01052 
01053 //-----------------------------------------------------------------------------
01054 void KMMainWidget::slotMarkAllAsRead()
01055 {
01056   if (!mFolder)
01057     return;
01058   mFolder->markUnreadAsRead();
01059 }
01060 
01061 //-----------------------------------------------------------------------------
01062 void KMMainWidget::slotCompactFolder()
01063 {
01064   if (mFolder) {
01065     int idx = mHeaders->currentItemIndex();
01066     KCursorSaver busy(KBusyPtr::busy());
01067     mFolder->compact( KMFolder::CompactNow );
01068     // setCurrentItemByIndex will override the statusbar message, so save/restore it
01069     QString statusMsg = BroadcastStatus::instance()->statusMsg();
01070     mHeaders->setCurrentItemByIndex(idx);
01071     BroadcastStatus::instance()->setStatusMsg( statusMsg );
01072   }
01073 }
01074 
01075 
01076 //-----------------------------------------------------------------------------
01077 void KMMainWidget::slotRefreshFolder()
01078 {
01079   if (mFolder)
01080   {
01081     if (mFolder->folderType() == KMFolderTypeImap)
01082     {
01083       KMFolderImap *imap = static_cast<KMFolderImap*>(mFolder->storage());
01084       imap->getAndCheckFolder();
01085     } else if ( mFolder->folderType() == KMFolderTypeCachedImap ) {
01086       KMFolderCachedImap* f = static_cast<KMFolderCachedImap*>( mFolder->storage() );
01087       f->account()->processNewMailSingleFolder( mFolder );
01088     }
01089   }
01090 }
01091 
01092 void KMMainWidget::slotInvalidateIMAPFolders() {
01093   if ( KMessageBox::warningContinueCancel( this,
01094           i18n("Are you sure you want to refresh the IMAP cache?\n"
01095            "This will remove all changes that you have done "
01096            "locally to your IMAP folders."),
01097       i18n("Refresh IMAP Cache"), i18n("&Refresh") ) == KMessageBox::Continue )
01098     kmkernel->acctMgr()->invalidateIMAPFolders();
01099 }
01100 
01101 //-----------------------------------------------------------------------------
01102 void KMMainWidget::slotExpireAll() {
01103   KConfig    *config = KMKernel::config();
01104   int        ret = 0;
01105 
01106   KConfigGroupSaver saver(config, "General");
01107 
01108   if (config->readBoolEntry("warn-before-expire", true)) {
01109     ret = KMessageBox::warningContinueCancel(KMainWindow::memberList->first(),
01110              i18n("Are you sure you want to expire all old messages?"),
01111              i18n("Expire old Messages?"), i18n("Expire"));
01112     if (ret != KMessageBox::Continue) {
01113       return;
01114     }
01115   }
01116 
01117   kmkernel->expireAllFoldersNow();
01118 }
01119 
01120 //-----------------------------------------------------------------------------
01121 void KMMainWidget::slotCompactAll()
01122 {
01123   KCursorSaver busy(KBusyPtr::busy());
01124   kmkernel->compactAllFolders();
01125 }
01126 
01127 
01128 //-----------------------------------------------------------------------------
01129 void KMMainWidget::slotOverrideHtml()
01130 {
01131   if( mHtmlPref == mFolderHtmlPref ) {
01132     int result = KMessageBox::warningContinueCancel( this,
01133       // the warning text is taken from configuredialog.cpp:
01134       i18n( "Use of HTML in mail will make you more vulnerable to "
01135         "\"spam\" and may increase the likelihood that your system will be "
01136         "compromised by other present and anticipated security exploits." ),
01137       i18n( "Security Warning" ),
01138       i18n( "Use HTML" ),
01139       "OverrideHtmlWarning", false);
01140     if( result == KMessageBox::Cancel ) {
01141       mPreferHtmlAction->setChecked( false );
01142       return;
01143     }
01144   }
01145   mFolderHtmlPref = !mFolderHtmlPref;
01146   if (mMsgView) {
01147     mMsgView->setHtmlOverride(mFolderHtmlPref);
01148     mMsgView->update( true );
01149   }
01150 }
01151 
01152 //-----------------------------------------------------------------------------
01153 void KMMainWidget::slotOverrideThread()
01154 {
01155   mFolderThreadPref = !mFolderThreadPref;
01156   mHeaders->setNestedOverride(mFolderThreadPref);
01157   mThreadBySubjectAction->setEnabled(mThreadMessagesAction->isChecked());
01158 }
01159 
01160 //-----------------------------------------------------------------------------
01161 void KMMainWidget::slotToggleSubjectThreading()
01162 {
01163   mFolderThreadSubjPref = !mFolderThreadSubjPref;
01164   mHeaders->setSubjectThreading(mFolderThreadSubjPref);
01165 }
01166 
01167 //-----------------------------------------------------------------------------
01168 void KMMainWidget::slotToggleShowQuickSearch()
01169 {
01170   GlobalSettings::setQuickSearchActive( !GlobalSettings::quickSearchActive() );
01171   if ( GlobalSettings::quickSearchActive() )
01172     mSearchToolBar->show();
01173   else {
01174     mQuickSearchLine->reset();
01175     mSearchToolBar->hide();
01176   }
01177 }
01178 
01179 //-----------------------------------------------------------------------------
01180 void KMMainWidget::slotMessageQueuedOrDrafted()
01181 {
01182   if (!kmkernel->folderIsDraftOrOutbox(mFolder))
01183       return;
01184   if (mMsgView)
01185     mMsgView->update(true);
01186 }
01187 
01188 
01189 //-----------------------------------------------------------------------------
01190 void KMMainWidget::slotForwardMsg()
01191 {
01192   KMCommand *command =
01193     new KMForwardCommand( this, *mHeaders->selectedMsgs(), mFolder->identity() );
01194   command->start();
01195 }
01196 
01197 
01198 //-----------------------------------------------------------------------------
01199 void KMMainWidget::slotForwardAttachedMsg()
01200 {
01201   KMCommand *command =
01202     new KMForwardAttachedCommand( this, *mHeaders->selectedMsgs(), mFolder->identity() );
01203   command->start();
01204 }
01205 
01206 
01207 //-----------------------------------------------------------------------------
01208 void KMMainWidget::slotEditMsg()
01209 {
01210   KMCommand *command = new KMEditMsgCommand( this, mHeaders->currentMsg() );
01211   command->start();
01212 
01213   mHeaders->setSelected(mHeaders->currentItem(), true);
01214   mHeaders->highlightMessage(mHeaders->currentItem(), true);
01215 
01216 }
01217 
01218 //-----------------------------------------------------------------------------
01219 void KMMainWidget::slotResendMsg()
01220 {
01221   KMCommand *command = new KMResendMessageCommand( this, mHeaders->currentMsg() );
01222   command->start();
01223 }
01224 
01225 
01226 //-----------------------------------------------------------------------------
01227 void KMMainWidget::slotTrashMsg()
01228 {
01229   mHeaders->deleteMsg();
01230   updateMessageActions();
01231 }
01232 
01233 //-----------------------------------------------------------------------------
01234 void KMMainWidget::slotDeleteMsg( bool confirmDelete )
01235 {
01236   mHeaders->moveMsgToFolder( 0, confirmDelete );
01237   updateMessageActions();
01238 }
01239 
01240 
01241 //-----------------------------------------------------------------------------
01242 void KMMainWidget::slotReplyToMsg()
01243 {
01244   QString text = mMsgView? mMsgView->copyText() : "";
01245   KMCommand *command = new KMReplyToCommand( this, mHeaders->currentMsg(), text );
01246   command->start();
01247 }
01248 
01249 
01250 //-----------------------------------------------------------------------------
01251 void KMMainWidget::slotReplyAuthorToMsg()
01252 {
01253   QString text = mMsgView? mMsgView->copyText() : "";
01254   KMCommand *command = new KMReplyAuthorCommand( this, mHeaders->currentMsg(), text );
01255   command->start();
01256 }
01257 
01258 
01259 //-----------------------------------------------------------------------------
01260 void KMMainWidget::slotReplyAllToMsg()
01261 {
01262   QString text = mMsgView? mMsgView->copyText() : "";
01263   KMCommand *command = new KMReplyToAllCommand( this, mHeaders->currentMsg(), text );
01264   command->start();
01265 }
01266 
01267 
01268 //-----------------------------------------------------------------------------
01269 void KMMainWidget::slotRedirectMsg()
01270 {
01271   KMCommand *command = new KMRedirectCommand( this, mHeaders->currentMsg() );
01272   command->start();
01273 }
01274 
01275 
01276 //-----------------------------------------------------------------------------
01277 void KMMainWidget::slotBounceMsg()
01278 {
01279   KMCommand *command = new KMBounceCommand( this, mHeaders->currentMsg() );
01280   command->start();
01281 }
01282 
01283 
01284 //-----------------------------------------------------------------------------
01285 void KMMainWidget::slotReplyListToMsg()
01286 {
01287 
01288   QString text = mMsgView? mMsgView->copyText() : "";
01289   KMCommand *command = new KMReplyListCommand( this, mHeaders->currentMsg(),
01290                            text );
01291   command->start();
01292 }
01293 
01294 //-----------------------------------------------------------------------------
01295 void KMMainWidget::slotNoQuoteReplyToMsg()
01296 {
01297   KMCommand *command = new KMNoQuoteReplyToCommand( this, mHeaders->currentMsg() );
01298   command->start();
01299 }
01300 
01301 //-----------------------------------------------------------------------------
01302 void KMMainWidget::slotSubjectFilter()
01303 {
01304   KMMessage *msg = mHeaders->currentMsg();
01305   if (!msg)
01306     return;
01307 
01308   KMCommand *command = new KMFilterCommand( "Subject", msg->subject() );
01309   command->start();
01310 }
01311 
01312 //-----------------------------------------------------------------------------
01313 void KMMainWidget::slotMailingListFilter()
01314 {
01315   KMMessage *msg = mHeaders->currentMsg();
01316   if (!msg)
01317     return;
01318 
01319   KMCommand *command = new KMMailingListFilterCommand( this, msg );
01320   command->start();
01321 }
01322 
01323 //-----------------------------------------------------------------------------
01324 void KMMainWidget::slotFromFilter()
01325 {
01326   KMMessage *msg = mHeaders->currentMsg();
01327   if (!msg)
01328     return;
01329 
01330   AddrSpecList al = msg->extractAddrSpecs( "From" );
01331   if ( al.empty() )
01332     return;
01333   KMCommand *command = new KMFilterCommand( "From",  al.front().asString() );
01334   command->start();
01335 }
01336 
01337 //-----------------------------------------------------------------------------
01338 void KMMainWidget::slotToFilter()
01339 {
01340   KMMessage *msg = mHeaders->currentMsg();
01341   if (!msg)
01342     return;
01343 
01344   KMCommand *command = new KMFilterCommand( "To",  msg->to() );
01345   command->start();
01346 }
01347 
01348 //-----------------------------------------------------------------------------
01349 void KMMainWidget::updateListFilterAction()
01350 {
01351   //Proxy the mListFilterAction to update the action text
01352   QCString name;
01353   QString value;
01354   QString lname = MailingList::name( mHeaders->currentMsg(), name, value );
01355   mListFilterAction->setText( i18n("Filter on Mailing-List...") );
01356   if ( lname.isNull() )
01357     mListFilterAction->setEnabled( false );
01358   else {
01359     mListFilterAction->setEnabled( true );
01360     mListFilterAction->setText( i18n( "Filter on Mailing-List %1..." ).arg( lname ) );
01361   }
01362 }
01363 
01364 
01365 //-----------------------------------------------------------------------------
01366 void KMMainWidget::slotUndo()
01367 {
01368     mHeaders->undo();
01369     updateMessageActions();
01370 }
01371 
01372 //-----------------------------------------------------------------------------
01373 void KMMainWidget::slotToggleUnread()
01374 {
01375   mFolderTree->toggleColumn(KMFolderTree::unread);
01376 }
01377 
01378 //-----------------------------------------------------------------------------
01379 void KMMainWidget::slotToggleTotalColumn()
01380 {
01381   mFolderTree->toggleColumn(KMFolderTree::total, true);
01382 }
01383 
01384 //-----------------------------------------------------------------------------
01385 void KMMainWidget::slotMoveMsg()
01386 {
01387   KMFolderSelDlg dlg( this, i18n("Move Message to Folder"), true );
01388   KMFolder* dest;
01389 
01390   if (!dlg.exec()) return;
01391   if (!(dest = dlg.folder())) return;
01392 
01393   mHeaders->moveMsgToFolder(dest);
01394 }
01395 
01396 //-----------------------------------------------------------------------------
01397 void KMMainWidget::slotMoveMsgToFolder( KMFolder *dest)
01398 {
01399   mHeaders->moveMsgToFolder(dest);
01400 }
01401 
01402 //-----------------------------------------------------------------------------
01403 void KMMainWidget::slotCopyMsgToFolder( KMFolder *dest)
01404 {
01405   mHeaders->copyMsgToFolder(dest);
01406 }
01407 
01408 //-----------------------------------------------------------------------------
01409 void KMMainWidget::slotApplyFilters()
01410 {
01411   mHeaders->applyFiltersOnMsg();
01412 }
01413 
01414 //-----------------------------------------------------------------------------
01415 void KMMainWidget::slotEditVacation()
01416 {
01417   if ( mVacation )
01418     return;
01419 
01420   mVacation = new Vacation( this );
01421   if ( mVacation->isUsable() ) {
01422     connect( mVacation, SIGNAL(result(bool)), mVacation, SLOT(deleteLater()) );
01423   } else {
01424     QString msg = i18n("KMail's Out of Office Reply functionality relies on "
01425                       "server-side filtering. You have not yet configured an "
01426                       "IMAP server for this.\n"
01427                       "You can do this on the \"Filtering\" tab of the IMAP "
01428                       "account configuration.");
01429     KMessageBox::sorry( this, msg, i18n("No Server-Side Filtering Configured") );
01430 
01431     delete mVacation; // QGuardedPtr sets itself to 0!
01432   }
01433 }
01434 
01435 //-----------------------------------------------------------------------------
01436 void KMMainWidget::slotStartCertManager()
01437 {
01438   KProcess certManagerProc; // save to create on the heap, since
01439   // there is no parent
01440   certManagerProc << "kleopatra";
01441 
01442   if( !certManagerProc.start( KProcess::DontCare ) )
01443     KMessageBox::error( this, i18n( "Could not start certificate manager; "
01444                                     "please check your installation." ),
01445                                     i18n( "KMail Error" ) );
01446   else
01447     kdDebug(5006) << "\nslotStartCertManager(): certificate manager started.\n" << endl;
01448   // process continues to run even after the KProcess object goes
01449   // out of scope here, since it is started in DontCare run mode.
01450 
01451 }
01452 
01453 //-----------------------------------------------------------------------------
01454 void KMMainWidget::slotStartWatchGnuPG()
01455 {
01456   KProcess certManagerProc;
01457   certManagerProc << "kwatchgnupg";
01458 
01459   if( !certManagerProc.start( KProcess::DontCare ) )
01460     KMessageBox::error( this, i18n( "Could not start GnuPG LogViewer (kwatchgnupg); "
01461                                     "please check your installation." ),
01462                                     i18n( "KMail Error" ) );
01463 }
01464 
01465 //-----------------------------------------------------------------------------
01466 void KMMainWidget::slotCopyMsg()
01467 {
01468   KMFolderSelDlg dlg( this, i18n("Copy Message to Folder"), true );
01469   KMFolder* dest;
01470 
01471   if (!dlg.exec()) return;
01472   if (!(dest = dlg.folder())) return;
01473 
01474   mHeaders->copyMsgToFolder(dest);
01475 }
01476 
01477 //-----------------------------------------------------------------------------
01478 void KMMainWidget::slotPrintMsg()
01479 {
01480   bool htmlOverride = mMsgView ? mMsgView->htmlOverride() : false;
01481   KMCommand *command =
01482     new KMPrintCommand( this, mHeaders->currentMsg(),
01483                         htmlOverride, mCodec );
01484   command->start();
01485 }
01486 
01487 //-----------------------------------------------------------------------------
01488 void KMMainWidget::slotConfigChanged()
01489 {
01490   readConfig();
01491 }
01492 
01493 //-----------------------------------------------------------------------------
01494 void KMMainWidget::slotSaveMsg()
01495 {
01496   KMMessage *msg = mHeaders->currentMsg();
01497   if (!msg)
01498     return;
01499   KMSaveMsgCommand *saveCommand = new KMSaveMsgCommand( this,
01500     *mHeaders->selectedMsgs() );
01501 
01502   if (saveCommand->url().isEmpty())
01503     delete saveCommand;
01504   else
01505     saveCommand->start();
01506 }
01507 
01508 //-----------------------------------------------------------------------------
01509 void KMMainWidget::slotOpenMsg()
01510 {
01511   KMOpenMsgCommand *openCommand = new KMOpenMsgCommand( this );
01512 
01513   openCommand->start();
01514 }
01515 
01516 //-----------------------------------------------------------------------------
01517 void KMMainWidget::slotSaveAttachments()
01518 {
01519   KMMessage *msg = mHeaders->currentMsg();
01520   if (!msg)
01521     return;
01522   KMSaveAttachmentsCommand *saveCommand = new KMSaveAttachmentsCommand( this,
01523                                                                         *mHeaders->selectedMsgs() );
01524   saveCommand->start();
01525 }
01526 
01527 
01528 //-----------------------------------------------------------------------------
01529 void KMMainWidget::slotSendQueued()
01530 {
01531   kmkernel->msgSender()->sendQueued();
01532 }
01533 
01534 
01535 //-----------------------------------------------------------------------------
01536 void KMMainWidget::slotViewChange()
01537 {
01538   if(mBodyPartsMenu->isItemChecked(mBodyPartsMenu->idAt(0)))
01539   {
01540     mBodyPartsMenu->setItemChecked(mBodyPartsMenu->idAt(0),FALSE);
01541     mBodyPartsMenu->setItemChecked(mBodyPartsMenu->idAt(1),TRUE);
01542   }
01543   else if(mBodyPartsMenu->isItemChecked(mBodyPartsMenu->idAt(1)))
01544   {
01545     mBodyPartsMenu->setItemChecked(mBodyPartsMenu->idAt(1),FALSE);
01546     mBodyPartsMenu->setItemChecked(mBodyPartsMenu->idAt(0),TRUE);
01547   }
01548 
01549   //mMsgView->setInline(!mMsgView->isInline());
01550 }
01551 
01552 
01553 void KMMainWidget::slotFancyHeaders() {
01554   mMsgView->setHeaderStyleAndStrategy( HeaderStyle::fancy(),
01555                        HeaderStrategy::rich() );
01556 }
01557 
01558 void KMMainWidget::slotBriefHeaders() {
01559   mMsgView->setHeaderStyleAndStrategy( HeaderStyle::brief(),
01560                        HeaderStrategy::brief() );
01561 }
01562 
01563 void KMMainWidget::slotStandardHeaders() {
01564   mMsgView->setHeaderStyleAndStrategy( HeaderStyle::plain(),
01565                        HeaderStrategy::standard());
01566 }
01567 
01568 void KMMainWidget::slotLongHeaders() {
01569   mMsgView->setHeaderStyleAndStrategy( HeaderStyle::plain(),
01570                        HeaderStrategy::rich() );
01571 }
01572 
01573 void KMMainWidget::slotAllHeaders() {
01574   mMsgView->setHeaderStyleAndStrategy( HeaderStyle::plain(),
01575                        HeaderStrategy::all() );
01576 }
01577 
01578 void KMMainWidget::slotCycleHeaderStyles() {
01579   const HeaderStrategy * strategy = mMsgView->headerStrategy();
01580   const HeaderStyle * style = mMsgView->headerStyle();
01581 
01582   const char * actionName = 0;
01583   if ( style == HeaderStyle::fancy() ) {
01584     slotBriefHeaders();
01585     actionName = "view_headers_brief";
01586   } else if ( style == HeaderStyle::brief() ) {
01587     slotStandardHeaders();
01588     actionName = "view_headers_standard";
01589   } else if ( style == HeaderStyle::plain() ) {
01590     if ( strategy == HeaderStrategy::standard() ) {
01591       slotLongHeaders();
01592       actionName = "view_headers_long";
01593     } else if ( strategy == HeaderStrategy::rich() ) {
01594       slotAllHeaders();
01595       actionName = "view_headers_all";
01596     } else if ( strategy == HeaderStrategy::all() ) {
01597       slotFancyHeaders();
01598       actionName = "view_headers_fancy";
01599     }
01600   }
01601 
01602   if ( actionName )
01603     static_cast<KRadioAction*>( actionCollection()->action( actionName ) )->setChecked( true );
01604 }
01605 
01606 
01607 void KMMainWidget::slotIconicAttachments() {
01608   mMsgView->setAttachmentStrategy( AttachmentStrategy::iconic() );
01609 }
01610 
01611 void KMMainWidget::slotSmartAttachments() {
01612   mMsgView->setAttachmentStrategy( AttachmentStrategy::smart() );
01613 }
01614 
01615 void KMMainWidget::slotInlineAttachments() {
01616   mMsgView->setAttachmentStrategy( AttachmentStrategy::inlined() );
01617 }
01618 
01619 void KMMainWidget::slotHideAttachments() {
01620   mMsgView->setAttachmentStrategy( AttachmentStrategy::hidden() );
01621 }
01622 
01623 void KMMainWidget::slotCycleAttachmentStrategy() {
01624   mMsgView->setAttachmentStrategy( mMsgView->attachmentStrategy()->next() );
01625   KRadioAction * action = actionForAttachmentStrategy( mMsgView->attachmentStrategy() );
01626   assert( action );
01627   action->setChecked( true );
01628 }
01629 
01630 void KMMainWidget::folderSelectedUnread( KMFolder* aFolder )
01631 {
01632   folderSelected( aFolder, true );
01633   slotChangeCaption( mFolderTree->currentItem() );
01634 }
01635 
01636 //-----------------------------------------------------------------------------
01637 void KMMainWidget::folderSelected()
01638 {
01639   folderSelected( mFolder );
01640   // opened() before the getAndCheckFolder() in folderSelected
01641   if ( mFolder && mFolder->folderType() == KMFolderTypeImap )
01642     mFolder->close();
01643 }
01644 
01645 //-----------------------------------------------------------------------------
01646 void KMMainWidget::folderSelected( KMFolder* aFolder, bool forceJumpToUnread )
01647 {
01648   KCursorSaver busy(KBusyPtr::busy());
01649 
01650   if (mMsgView)
01651     mMsgView->clear(true);
01652 
01653   if( !mFolder ) {
01654     if (mMsgView) {
01655       mMsgView->enableMsgDisplay();
01656       mMsgView->clear(true);
01657     }
01658     if( mSearchAndHeaders && mHeaders )
01659       mSearchAndHeaders->show();
01660   }
01661 
01662   if ( mFolder && mFolder->folderType() == KMFolderTypeImap )
01663   {
01664     KMFolderImap *imap = static_cast<KMFolderImap*>(mFolder->storage());
01665     if ( mFolder->needsCompacting() && imap->autoExpunge() )
01666       imap->expungeFolder(imap, TRUE);
01667   }
01668 
01669   if ( mFolder != aFolder )
01670     writeFolderConfig();
01671   if ( mFolder ) {
01672     disconnect( mFolder, SIGNAL( changed() ),
01673            this, SLOT( updateMarkAsReadAction() ) );
01674     disconnect( mFolder, SIGNAL( msgHeaderChanged( KMFolder*, int ) ),
01675            this, SLOT( updateMarkAsReadAction() ) );
01676     disconnect( mFolder, SIGNAL( msgAdded( int ) ),
01677            this, SLOT( updateMarkAsReadAction() ) );
01678     disconnect( mFolder, SIGNAL( msgRemoved( KMFolder * ) ),
01679            this, SLOT( updateMarkAsReadAction() ) );
01680   }
01681 
01682   bool newFolder = ( mFolder != aFolder );
01683   mFolder = aFolder;
01684   if ( aFolder && aFolder->folderType() == KMFolderTypeImap )
01685   {
01686     KMFolderImap *imap = static_cast<KMFolderImap*>(aFolder->storage());
01687     if ( newFolder )
01688     {
01689       imap->open(); // will be closed in the folderSelected slot
01690       // first get new headers before we select the folder
01691       imap->setSelected( true );
01692       connect( imap, SIGNAL( folderComplete( KMFolderImap*, bool ) ),
01693           this, SLOT( folderSelected() ) );
01694       imap->getAndCheckFolder();
01695       mHeaders->setFolder( 0 );
01696       mForceJumpToUnread = forceJumpToUnread;
01697       return;
01698     } else {
01699       // the folder is complete now - so go ahead
01700       disconnect( imap, SIGNAL( folderComplete( KMFolderImap*, bool ) ),
01701           this, SLOT( folderSelected() ) );
01702       forceJumpToUnread = mForceJumpToUnread;
01703     }
01704   }
01705 
01706   if ( mFolder ) { // == 0 -> pointing to toplevel ("Welcome to KMail") folder
01707     connect( mFolder, SIGNAL( changed() ),
01708            this, SLOT( updateMarkAsReadAction() ) );
01709     connect( mFolder, SIGNAL( msgHeaderChanged( KMFolder*, int ) ),
01710            this, SLOT( updateMarkAsReadAction() ) );
01711     connect( mFolder, SIGNAL( msgAdded( int ) ),
01712            this, SLOT( updateMarkAsReadAction() ) );
01713     connect( mFolder, SIGNAL( msgRemoved(KMFolder *) ),
01714            this, SLOT( updateMarkAsReadAction() ) );
01715   }
01716   readFolderConfig();
01717   if (mMsgView)
01718     mMsgView->setHtmlOverride(mFolderHtmlPref);
01719   mHeaders->setFolder( mFolder, forceJumpToUnread );
01720   updateMessageActions();
01721   updateFolderMenu();
01722   if (!aFolder)
01723     slotIntro();
01724 }
01725 
01726 //-----------------------------------------------------------------------------
01727 void KMMainWidget::slotMsgSelected(KMMessage *msg)
01728 {
01729   if ( msg && msg->parent() && !msg->isComplete() )
01730   {
01731     if ( msg->transferInProgress() )
01732       return;
01733     mMsgView->clear();
01734     mMsgView->setWaitingForSerNum( msg->getMsgSerNum() );
01735 
01736     if ( mJob ) {
01737        disconnect( mJob, 0, mMsgView, 0 );
01738        delete mJob;
01739     }
01740     mJob = msg->parent()->createJob( msg, FolderJob::tGetMessage, 0,
01741           "STRUCTURE", mMsgView->attachmentStrategy() );
01742     connect(mJob, SIGNAL(messageRetrieved(KMMessage*)),
01743             mMsgView, SLOT(slotMessageArrived(KMMessage*)));
01744     mJob->start();
01745   } else {
01746     mMsgView->setMsg(msg);
01747   }
01748   // reset HTML override to the folder setting
01749   mMsgView->setHtmlOverride(mFolderHtmlPref);
01750 }
01751 
01752 //-----------------------------------------------------------------------------
01753 void KMMainWidget::slotMsgChanged()
01754 {
01755   mHeaders->msgChanged();
01756 }
01757 
01758 //-----------------------------------------------------------------------------
01759 void KMMainWidget::slotSelectFolder(KMFolder* folder)
01760 {
01761   QListViewItem* item = mFolderTree->indexOfFolder(folder);
01762   if (item)
01763     mFolderTree->doFolderSelected( item );
01764 }
01765 
01766 //-----------------------------------------------------------------------------
01767 void KMMainWidget::slotSelectMessage(KMMessage* msg)
01768 {
01769   int idx = mFolder->find(msg);
01770   if (idx != -1) {
01771     mHeaders->setCurrentMsg(idx);
01772     if (mMsgView)
01773       mMsgView->setMsg(msg);
01774   }
01775 }
01776 
01777 //-----------------------------------------------------------------------------
01778 void KMMainWidget::slotReplaceMsgByUnencryptedVersion()
01779 {
01780   kdDebug(5006) << "KMMainWidget::slotReplaceMsgByUnencryptedVersion()" << endl;
01781   KMMessage* oldMsg = mHeaders->currentMsg();
01782   if( oldMsg ) {
01783     kdDebug(5006) << "KMMainWidget  -  old message found" << endl;
01784     if( oldMsg->hasUnencryptedMsg() ) {
01785       kdDebug(5006) << "KMMainWidget  -  extra unencrypted message found" << endl;
01786       KMMessage* newMsg = oldMsg->unencryptedMsg();
01787       // adjust the message id
01788       {
01789         QString msgId( oldMsg->msgId() );
01790         QString prefix("DecryptedMsg.");
01791         int oldIdx = msgId.find(prefix, 0, false);
01792         if( -1 == oldIdx ) {
01793           int leftAngle = msgId.findRev( '<' );
01794           msgId = msgId.insert( (-1 == leftAngle) ? 0 : ++leftAngle, prefix );
01795         }
01796         else {
01797           // toggle between "DecryptedMsg." and "DeCryptedMsg."
01798           // to avoid same message id
01799           QCharRef c = msgId[ oldIdx+2 ];
01800           if( 'C' == c )
01801             c = 'c';
01802           else
01803             c = 'C';
01804         }
01805         newMsg->setMsgId( msgId );
01806         mMsgView->setIdOfLastViewedMessage( msgId );
01807       }
01808       const QString newMsgIdMD5( newMsg->msgIdMD5() );
01809       // insert the unencrypted message
01810       kdDebug(5006) << "KMMainWidget  -  copying unencrypted message to same folder" << endl;
01811       mHeaders->copyMsgToFolder(mFolder, newMsg);
01812       // delete the encrypted message - this will also delete newMsg
01813       kdDebug(5006) << "KMMainWidget  -  deleting encrypted message" << endl;
01814       mHeaders->deleteMsg();
01815       kdDebug(5006) << "KMMainWidget  -  updating message actions" << endl;
01816       updateMessageActions();
01817 
01818       // find and select and show the new message
01819       int idx = mHeaders->currentItemIndex();
01820       if( -1 != idx ) {
01821         mHeaders->setCurrentMsg( idx );
01822         mMsgView->setMsg( mHeaders->currentMsg() );
01823       } else {
01824         kdDebug(5006) << "KMMainWidget  -  SORRY, could not store unencrypted message!" << endl;
01825       }
01826 
01827       kdDebug(5006) << "KMMainWidget  -  done." << endl;
01828     } else
01829       kdDebug(5006) << "KMMainWidget  -  NO EXTRA UNENCRYPTED MESSAGE FOUND" << endl;
01830   } else
01831     kdDebug(5006) << "KMMainWidget  -  PANIC: NO OLD MESSAGE FOUND" << endl;
01832 }
01833 
01834 
01835 //-----------------------------------------------------------------------------
01836 void KMMainWidget::slotSetMsgStatusNew()
01837 {
01838   mHeaders->setMsgStatus(KMMsgStatusNew);
01839 }
01840 
01841 //-----------------------------------------------------------------------------
01842 void KMMainWidget::slotSetMsgStatusUnread()
01843 {
01844   mHeaders->setMsgStatus(KMMsgStatusUnread);
01845 }
01846 
01847 //-----------------------------------------------------------------------------
01848 void KMMainWidget::slotSetMsgStatusRead()
01849 {
01850   mHeaders->setMsgStatus(KMMsgStatusRead);
01851 }
01852 
01853 //-----------------------------------------------------------------------------
01854 void KMMainWidget::slotSetMsgStatusFlag()
01855 {
01856   mHeaders->setMsgStatus(KMMsgStatusFlag, true);
01857 }
01858 
01859 //-----------------------------------------------------------------------------
01860 void KMMainWidget::slotSetMsgStatusSpam()
01861 {
01862   mHeaders->setMsgStatus( KMMsgStatusSpam, true );
01863 }
01864 
01865 //-----------------------------------------------------------------------------
01866 void KMMainWidget::slotSetMsgStatusHam()
01867 {
01868   mHeaders->setMsgStatus( KMMsgStatusHam, true );
01869 }
01870 
01871 //-----------------------------------------------------------------------------
01872 void KMMainWidget::slotSetMsgStatusReplied()
01873 {
01874   mHeaders->setMsgStatus(KMMsgStatusReplied, true);
01875 }
01876 
01877 //-----------------------------------------------------------------------------
01878 void KMMainWidget::slotSetMsgStatusForwarded()
01879 {
01880   mHeaders->setMsgStatus(KMMsgStatusForwarded, true);
01881 }
01882 
01883 //-----------------------------------------------------------------------------
01884 void KMMainWidget::slotSetMsgStatusQueued()
01885 {
01886   mHeaders->setMsgStatus(KMMsgStatusQueued, true);
01887 }
01888 
01889 //-----------------------------------------------------------------------------
01890 void KMMainWidget::slotSetMsgStatusSent()
01891 {
01892   mHeaders->setMsgStatus(KMMsgStatusSent, true);
01893 }
01894 
01895 //-----------------------------------------------------------------------------
01896 void KMMainWidget::slotSetThreadStatusNew()
01897 {
01898   mHeaders->setThreadStatus(KMMsgStatusNew);
01899 }
01900 
01901 //-----------------------------------------------------------------------------
01902 void KMMainWidget::slotSetThreadStatusUnread()
01903 {
01904   mHeaders->setThreadStatus(KMMsgStatusUnread);
01905 }
01906 
01907 //-----------------------------------------------------------------------------
01908 void KMMainWidget::slotSetThreadStatusFlag()
01909 {
01910   mHeaders->setThreadStatus(KMMsgStatusFlag, true);
01911 }
01912 
01913 //-----------------------------------------------------------------------------
01914 void KMMainWidget::slotSetThreadStatusRead()
01915 {
01916   mHeaders->setThreadStatus(KMMsgStatusRead);
01917 }
01918 
01919 //-----------------------------------------------------------------------------
01920 void KMMainWidget::slotSetThreadStatusReplied()
01921 {
01922   mHeaders->setThreadStatus(KMMsgStatusReplied, true);
01923 }
01924 
01925 //-----------------------------------------------------------------------------
01926 void KMMainWidget::slotSetThreadStatusForwarded()
01927 {
01928   mHeaders->setThreadStatus(KMMsgStatusForwarded, true);
01929 }
01930 
01931 //-----------------------------------------------------------------------------
01932 void KMMainWidget::slotSetThreadStatusQueued()
01933 {
01934   mHeaders->setThreadStatus(KMMsgStatusQueued, true);
01935 }
01936 
01937 //-----------------------------------------------------------------------------
01938 void KMMainWidget::slotSetThreadStatusSent()
01939 {
01940   mHeaders->setThreadStatus(KMMsgStatusSent, true);
01941 }
01942 
01943 //-----------------------------------------------------------------------------
01944 void KMMainWidget::slotSetThreadStatusWatched()
01945 {
01946   mHeaders->setThreadStatus(KMMsgStatusWatched, true);
01947   if (mWatchThreadAction->isChecked()) {
01948     mIgnoreThreadAction->setChecked(false);
01949   }
01950 }
01951 
01952 //-----------------------------------------------------------------------------
01953 void KMMainWidget::slotSetThreadStatusIgnored()
01954 {
01955   mHeaders->setThreadStatus(KMMsgStatusIgnored, true);
01956   if (mIgnoreThreadAction->isChecked()) {
01957     mWatchThreadAction->setChecked(false);
01958   }
01959 }
01960 
01961 //-----------------------------------------------------------------------------
01962 void KMMainWidget::slotSetThreadStatusSpam()
01963 {
01964   mHeaders->setThreadStatus( KMMsgStatusSpam, true );
01965 }
01966 
01967 //-----------------------------------------------------------------------------
01968 void KMMainWidget::slotSetThreadStatusHam()
01969 {
01970   mHeaders->setThreadStatus( KMMsgStatusHam, true );
01971 }
01972 
01973 //-----------------------------------------------------------------------------
01974 void KMMainWidget::slotNextMessage()       { mHeaders->nextMessage(); }
01975 void KMMainWidget::slotNextUnreadMessage()
01976 {
01977   if ( !mHeaders->nextUnreadMessage() )
01978     if ( GlobalSettings::loopOnGotoUnread() == GlobalSettings::EnumLoopOnGotoUnread::LoopInAllFolders )
01979       mFolderTree->nextUnreadFolder(true);
01980 }
01981 void KMMainWidget::slotNextImportantMessage() {
01982   //mHeaders->nextImportantMessage();
01983 }
01984 void KMMainWidget::slotPrevMessage()       { mHeaders->prevMessage(); }
01985 void KMMainWidget::slotPrevUnreadMessage()
01986 {
01987   if ( !mHeaders->prevUnreadMessage() )
01988     if ( GlobalSettings::loopOnGotoUnread() == GlobalSettings::EnumLoopOnGotoUnread::LoopInAllFolders )
01989       mFolderTree->prevUnreadFolder();
01990 }
01991 void KMMainWidget::slotPrevImportantMessage() {
01992   //mHeaders->prevImportantMessage();
01993 }
01994 
01995 //-----------------------------------------------------------------------------
01996 //called from headers. Message must not be deleted on close
01997 void KMMainWidget::slotMsgActivated(KMMessage *msg)
01998 {
01999   if (msg->parent() && !msg->isComplete())
02000   {
02001     FolderJob *job = msg->parent()->createJob(msg);
02002     connect(job, SIGNAL(messageRetrieved(KMMessage*)),
02003             SLOT(slotMsgActivated(KMMessage*)));
02004     job->start();
02005     return;
02006   }
02007 
02008   if (kmkernel->folderIsDraftOrOutbox(mFolder))
02009   {
02010     slotEditMsg();
02011     return;
02012   }
02013 
02014   assert( msg != 0 );
02015   KMReaderMainWin *win = new KMReaderMainWin( mFolderHtmlPref );
02016   KConfigGroup reader( KMKernel::config(), "Reader" );
02017   bool useFixedFont = mMsgView ? mMsgView->isFixedFont()
02018                                : reader.readBoolEntry( "useFixedFont", false );
02019   win->setUseFixedFont( useFixedFont );
02020   KMMessage *newMessage = new KMMessage(*msg);
02021   newMessage->setParent( msg->parent() );
02022   newMessage->setMsgSerNum( msg->getMsgSerNum() );
02023   newMessage->setReadyToShow( true );
02024   win->showMsg( mCodec, newMessage );
02025   win->show();
02026 }
02027 
02028 //-----------------------------------------------------------------------------
02029 void KMMainWidget::slotMarkAll()
02030 {
02031   mHeaders->selectAll( TRUE );
02032 }
02033 
02034 //-----------------------------------------------------------------------------
02035 void KMMainWidget::slotMsgPopup(KMMessage&, const KURL &aUrl, const QPoint& aPoint)
02036 {
02037   KPopupMenu * menu = new KPopupMenu;
02038   updateMessageMenu();
02039   mUrlCurrent = aUrl;
02040 
02041   if (!aUrl.isEmpty())
02042   {
02043     if (aUrl.protocol() == "mailto")
02044     {
02045       // popup on a mailto URL
02046       mMsgView->mailToComposeAction()->plug( menu );
02047       mMsgView->mailToReplyAction()->plug( menu );
02048       mMsgView->mailToForwardAction()->plug( menu );
02049       menu->insertSeparator();
02050       mMsgView->addAddrBookAction()->plug( menu );
02051       mMsgView->openAddrBookAction()->plug( menu );
02052       mMsgView->copyAction()->plug( menu );
02053       mMsgView->startImChatAction()->plug( menu );
02054       // only enable if our KIMProxy is functional
02055       mMsgView->startImChatAction()->setEnabled( kmkernel->imProxy()->initialize() );
02056 
02057     } else {
02058       // popup on a not-mailto URL
02059       mMsgView->urlOpenAction()->plug( menu );
02060       mMsgView->urlSaveAsAction()->plug( menu );
02061       mMsgView->copyURLAction()->plug( menu );
02062       mMsgView->addBookmarksAction()->plug( menu );
02063     }
02064     if ( aUrl.protocol() == "im" )
02065     {
02066       // popup on an IM address
02067       // no need to check the KIMProxy is initialized, as these protocols will
02068       // only be present if it is.
02069       mMsgView->startImChatAction()->plug( menu );
02070     }
02071     kdDebug( 0 ) << k_funcinfo << " URL is: " << aUrl << endl;
02072   }
02073   else
02074   {
02075     // popup somewhere else (i.e., not a URL) on the message
02076 
02077     if (!mHeaders->currentMsg()) // no messages
02078     {
02079       delete menu;
02080       return;
02081     }
02082 
02083     bool out_folder = kmkernel->folderIsDraftOrOutbox(mFolder);
02084     if ( out_folder ) {
02085       mEditAction->plug(menu);
02086     }
02087     else {
02088       mReplyAction->plug(menu);
02089       mReplyAllAction->plug(menu);
02090       mReplyAuthorAction->plug( menu );
02091       mReplyListAction->plug( menu );
02092       mForwardActionMenu->plug(menu);
02093       mBounceAction->plug(menu);
02094     }
02095     menu->insertSeparator();
02096     if ( !out_folder ) {
02097       //   mFilterMenu()->plug( menu );
02098       mStatusMenu->plug( menu );
02099       mThreadStatusMenu->plug( menu );
02100     }
02101 
02102     mCopyActionMenu->plug( menu );
02103     mMoveActionMenu->plug( menu );
02104 
02105     menu->insertSeparator();
02106     mWatchThreadAction->plug( menu );
02107     mIgnoreThreadAction->plug( menu );
02108 
02109     menu->insertSeparator();
02110 
02111     // these two only make sense if there is a reader window.
02112     // I guess. Not sure about view source ;). Till
02113     if (mMsgView) {
02114       toggleFixFontAction()->plug(menu);
02115       viewSourceAction()->plug(menu);
02116     }
02117 
02118     menu->insertSeparator();
02119     mPrintAction->plug( menu );
02120     mSaveAsAction->plug( menu );
02121     mSaveAttachmentsAction->plug( menu );
02122     menu->insertSeparator();
02123     mTrashAction->plug( menu );
02124     mDeleteAction->plug( menu );
02125   }
02126   KAcceleratorManager::manage(menu);
02127   menu->exec(aPoint, 0);
02128   delete menu;
02129 }
02130 
02131 //-----------------------------------------------------------------------------
02132 void KMMainWidget::getAccountMenu()
02133 {
02134   QStringList actList;
02135 
02136   mActMenu->clear();
02137   actList = kmkernel->acctMgr()->getAccounts(false);
02138   QStringList::Iterator it;
02139   int id = 0;
02140   for(it = actList.begin(); it != actList.end() ; ++it, id++)
02141     mActMenu->insertItem((*it).replace("&", "&&"), id);
02142 }
02143 
02144 // little helper function
02145 KRadioAction * KMMainWidget::actionForHeaderStyle( const HeaderStyle * style, const HeaderStrategy * strategy ) {
02146   const char * actionName = 0;
02147   if ( style == HeaderStyle::fancy() )
02148     actionName = "view_headers_fancy";
02149   else if ( style == HeaderStyle::brief() )
02150     actionName = "view_headers_brief";
02151   else if ( style == HeaderStyle::plain() ) {
02152     if ( strategy == HeaderStrategy::standard() )
02153       actionName = "view_headers_standard";
02154     else if ( strategy == HeaderStrategy::rich() )
02155       actionName = "view_headers_long";
02156     else if ( strategy == HeaderStrategy::all() )
02157       actionName = "view_headers_all";
02158   }
02159   if ( actionName )
02160     return static_cast<KRadioAction*>(actionCollection()->action(actionName));
02161   else
02162     return 0;
02163 }
02164 
02165 KRadioAction * KMMainWidget::actionForAttachmentStrategy( const AttachmentStrategy * as ) {
02166   const char * actionName = 0;
02167   if ( as == AttachmentStrategy::iconic() )
02168     actionName = "view_attachments_as_icons";
02169   else if ( as == AttachmentStrategy::smart() )
02170     actionName = "view_attachments_smart";
02171   else if ( as == AttachmentStrategy::inlined() )
02172     actionName = "view_attachments_inline";
02173   else if ( as == AttachmentStrategy::hidden() )
02174     actionName = "view_attachments_hide";
02175 
02176   if ( actionName )
02177     return static_cast<KRadioAction*>(actionCollection()->action(actionName));
02178   else
02179     return 0;
02180 }
02181 
02182 
02183 //-----------------------------------------------------------------------------
02184 void KMMainWidget::setupActions()
02185 {
02186   //----- File Menu
02187   (void) new KAction( i18n("New &Window"), "window_new", 0,
02188               this, SLOT(slotNewMailReader()),
02189               actionCollection(), "new_mail_client" );
02190 
02191   mSaveAsAction = new KAction( i18n("Save &As..."), "filesave",
02192     KStdAccel::shortcut(KStdAccel::Save),
02193     this, SLOT(slotSaveMsg()), actionCollection(), "file_save_as" );
02194 
02195   mOpenAction = KStdAction::open( this, SLOT( slotOpenMsg() ),
02196                                   actionCollection() );
02197 
02198   (void) new KAction( i18n("&Compact All Folders"), 0,
02199               this, SLOT(slotCompactAll()),
02200               actionCollection(), "compact_all_folders" );
02201 
02202   (void) new KAction( i18n("&Expire All Folders"), 0,
02203               this, SLOT(slotExpireAll()),
02204               actionCollection(), "expire_all_folders" );
02205 
02206   (void) new KAction( i18n("&Refresh Local IMAP Cache"), "refresh",
02207               this, SLOT(slotInvalidateIMAPFolders()),
02208               actionCollection(), "file_invalidate_imap_cache" );
02209 
02210   (void) new KAction( i18n("Empty All &Trash Folders"), 0,
02211               KMKernel::self(), SLOT(slotEmptyTrash()),
02212               actionCollection(), "empty_trash" );
02213 
02214   (void) new KAction( i18n("Check &Mail"), "mail_get", CTRL+Key_L,
02215               this, SLOT(slotCheckMail()),
02216               actionCollection(), "check_mail" );
02217 
02218   KActionMenu *actActionMenu = new
02219     KActionMenu( i18n("Check Mail &In"), "mail_get", actionCollection(),
02220                     "check_mail_in" );
02221   actActionMenu->setDelayed(true); //needed for checking "all accounts"
02222 
02223   connect(actActionMenu,SIGNAL(activated()),this,SLOT(slotCheckMail()));
02224 
02225   mActMenu = actActionMenu->popupMenu();
02226   connect(mActMenu,SIGNAL(activated(int)),this,SLOT(slotCheckOneAccount(int)));
02227   connect(mActMenu,SIGNAL(aboutToShow()),this,SLOT(getAccountMenu()));
02228 
02229   (void) new KAction( i18n("&Send Queued Messages"), "mail_send", 0, this,
02230              SLOT(slotSendQueued()), actionCollection(), "send_queued");
02231   KAction *act;
02232   //----- Tools menu
02233   if (parent()->inherits("KMMainWin")) {
02234     act =  new KAction( i18n("&Address Book..."), "contents", 0, this,
02235             SLOT(slotAddrBook()), actionCollection(), "addressbook" );
02236     if (KStandardDirs::findExe("kaddressbook").isEmpty()) act->setEnabled(false);
02237   }
02238 
02239   act = new KAction( i18n("Certificate Manager..."), "pgp-keys", 0, this,
02240              SLOT(slotStartCertManager()), actionCollection(), "tools_start_certman");
02241   // disable action if no certman binary is around
02242   if (KStandardDirs::findExe("kleopatra").isEmpty()) act->setEnabled(false);
02243 
02244   act = new KAction( i18n("GnuPG Log Viewer..."), "pgp-keys", 0, this,
02245              SLOT(slotStartWatchGnuPG()), actionCollection(), "tools_start_kwatchgnupg");
02246   // disable action if no kwatchgnupg binary is around
02247   if (KStandardDirs::findExe("kwatchgnupg").isEmpty()) act->setEnabled(false);
02248 
02249   act = new KAction( i18n("&Import Messages..."), "fileopen", 0, this,
02250              SLOT(slotImport()), actionCollection(), "import" );
02251   if (KStandardDirs::findExe("kmailcvt").isEmpty()) act->setEnabled(false);
02252 
02253   // @TODO (marc/bo): Test
02254   (void) new KAction( i18n("Edit \"Out of Office\" Replies..."),
02255               "configure", 0, this, SLOT(slotEditVacation()),
02256               actionCollection(), "tools_edit_vacation" );
02257 
02258   (void) new KAction( i18n("Filter &Log Viewer..."), 0, this,
02259               SLOT(slotFilterLogViewer()), actionCollection(), "filter_log_viewer" );
02260 
02261   (void) new KAction( i18n("&Anti-Spam Wizard..."), 0, this,
02262               SLOT(slotAntiSpamWizard()), actionCollection(), "antiSpamWizard" );
02263   (void) new KAction( i18n("&Anti-Virus Wizard..."), 0, this,
02264               SLOT(slotAntiVirusWizard()), actionCollection(), "antiVirusWizard" );
02265 
02266   //----- Edit Menu
02267   mTrashAction = new KAction( KGuiItem( i18n("&Move to Trash"), "edittrash",
02268                                        i18n("Move message to trashcan") ),
02269                              Key_Delete, this, SLOT(slotTrashMsg()),
02270                              actionCollection(), "move_to_trash" );
02271 
02272   mDeleteAction = new KAction( i18n("&Delete"), "editdelete", SHIFT+Key_Delete, this,
02273                               SLOT(slotDeleteMsg()), actionCollection(), "delete" );
02274 
02275   (void) new KAction( i18n("&Find Messages..."), "mail_find", Key_S, this,
02276               SLOT(slotSearch()), actionCollection(), "search_messages" );
02277 
02278   mFindInMessageAction = new KAction( i18n("&Find in Message..."), "find", KStdAccel::shortcut(KStdAccel::Find), this,
02279               SLOT(slotFind()), actionCollection(), "find_in_messages" );
02280 
02281   (void) new KAction( i18n("Select &All Messages"), KStdAccel::selectAll(), this,
02282               SLOT(slotMarkAll()), actionCollection(), "mark_all_messages" );
02283 
02284   (void) new KAction( i18n("Select Message &Text"),
02285               CTRL+SHIFT+Key_A, mMsgView,
02286               SLOT(selectAll()), actionCollection(), "mark_all_text" );
02287 
02288   //----- Folder Menu
02289   (void) new KAction( i18n("&New Folder..."), "folder_new", 0, this,
02290               SLOT(slotAddFolder()), actionCollection(), "new_folder" );
02291 
02292   mModifyFolderAction = new KAction( i18n("&Properties"), "configure", 0, this,
02293               SLOT(slotModifyFolder()), actionCollection(), "modify" );
02294 
02295   mMarkAllAsReadAction = new KAction( i18n("Mark All Messages as &Read"), "goto", 0, this,
02296               SLOT(slotMarkAllAsRead()), actionCollection(), "mark_all_as_read" );
02297 
02298   mExpireFolderAction = new KAction(i18n("&Expire"), 0, this, SLOT(slotExpireFolder()),
02299                    actionCollection(), "expire");
02300 
02301   mCompactFolderAction = new KAction( i18n("&Compact"), 0, this,
02302               SLOT(slotCompactFolder()), actionCollection(), "compact" );
02303 
02304   mRefreshFolderAction = new KAction( i18n("Check Mail &in This Folder"), "reload", Key_F5 , this,
02305                      SLOT(slotRefreshFolder()), actionCollection(), "refresh_folder" );
02306 
02307   mEmptyFolderAction = new KAction( i18n("&Move All Messages to Trash"),
02308                                    "edittrash", 0, this,
02309               SLOT(slotEmptyFolder()), actionCollection(), "empty" );
02310 
02311   mRemoveFolderAction = new KAction( i18n("&Delete Folder"), "editdelete", 0, this,
02312               SLOT(slotRemoveFolder()), actionCollection(), "delete_folder" );
02313 
02314   mPreferHtmlAction = new KToggleAction( i18n("Prefer &HTML to Plain Text"), 0, this,
02315               SLOT(slotOverrideHtml()), actionCollection(), "prefer_html" );
02316 
02317   mThreadMessagesAction = new KToggleAction( i18n("&Thread Messages"), 0, this,
02318               SLOT(slotOverrideThread()), actionCollection(), "thread_messages" );
02319 
02320   mThreadBySubjectAction = new KToggleAction( i18n("Thread Messages also by &Subject"), 0, this,
02321               SLOT(slotToggleSubjectThreading()), actionCollection(), "thread_messages_by_subject" );
02322 
02323 
02324   //----- Message Menu
02325   (void) new KAction( i18n("&New Message..."), "mail_new", KStdAccel::shortcut(KStdAccel::New), this,
02326               SLOT(slotCompose()), actionCollection(), "new_message" );
02327 
02328   (void) new KAction( i18n("New Message t&o Mailing-List..."), "mail_post_to", 0, this,
02329               SLOT(slotPostToML()), actionCollection(), "post_message" );
02330 
02331   mForwardActionMenu = new KActionMenu( i18n("Message->","&Forward"),
02332                     "mail_forward", actionCollection(),
02333                     "message_forward" );
02334   connect( mForwardActionMenu, SIGNAL(activated()), this,
02335        SLOT(slotForwardMsg()) );
02336 
02337   mForwardAttachedAction = new KAction( i18n("Message->Forward->","As &Attachment..."),
02338                        "mail_forward", Key_F, this,
02339                     SLOT(slotForwardAttachedMsg()), actionCollection(),
02340                     "message_forward_as_attachment" );
02341   mForwardActionMenu->insert( forwardAttachedAction() );
02342   mForwardAction = new KAction( i18n("&Inline..."), "mail_forward",
02343                 SHIFT+Key_F, this, SLOT(slotForwardMsg()),
02344                 actionCollection(), "message_forward_inline" );
02345 
02346   mForwardActionMenu->insert( forwardAction() );
02347 
02348   mSendAgainAction = new KAction( i18n("Send A&gain..."), 0, this,
02349               SLOT(slotResendMsg()), actionCollection(), "send_again" );
02350 
02351   mReplyActionMenu = new KActionMenu( i18n("Message->","&Reply"),
02352                                       "mail_reply", actionCollection(),
02353                                       "message_reply_menu" );
02354   connect( mReplyActionMenu, SIGNAL(activated()), this,
02355        SLOT(slotReplyToMsg()) );
02356 
02357   mReplyAction = new KAction( i18n("&Reply..."), "mail_reply", Key_R, this,
02358                   SLOT(slotReplyToMsg()), actionCollection(), "reply" );
02359   mReplyActionMenu->insert( mReplyAction );
02360 
02361   mReplyAuthorAction = new KAction( i18n("Reply to A&uthor..."), "mail_reply",
02362                                     SHIFT+Key_A, this,
02363                                     SLOT(slotReplyAuthorToMsg()),
02364                                     actionCollection(), "reply_author" );
02365   mReplyActionMenu->insert( mReplyAuthorAction );
02366 
02367   mReplyAllAction = new KAction( i18n("Reply to &All..."), "mail_replyall",
02368                  Key_A, this, SLOT(slotReplyAllToMsg()),
02369                  actionCollection(), "reply_all" );
02370   mReplyActionMenu->insert( mReplyAllAction );
02371 
02372   mReplyListAction = new KAction( i18n("Reply to Mailing-&List..."),
02373                   "mail_replylist", Key_L, this,
02374                   SLOT(slotReplyListToMsg()), actionCollection(),
02375                   "reply_list" );
02376   mReplyActionMenu->insert( mReplyListAction );
02377 
02378   mRedirectAction = new KAction( i18n("Message->Forward->","&Redirect..."),
02379                  Key_E, this, SLOT(slotRedirectMsg()),
02380                  actionCollection(), "message_forward_redirect" );
02381   mForwardActionMenu->insert( redirectAction() );
02382 
02383   mNoQuoteReplyAction = new KAction( i18n("Reply Without &Quote..."), SHIFT+Key_R,
02384     this, SLOT(slotNoQuoteReplyToMsg()), actionCollection(), "noquotereply" );
02385 
02386   //---- Bounce action
02387   mBounceAction = new KAction( i18n("&Bounce..."), 0, this,
02388                   SLOT(slotBounceMsg()), actionCollection(), "bounce" );
02389 
02390   //----- Create filter actions
02391   mFilterMenu = new KActionMenu( i18n("&Create Filter"), "filter", actionCollection(), "create_filter" );
02392   connect( mFilterMenu, SIGNAL(activated()), this,
02393        SLOT(slotFilter()) );
02394   mSubjectFilterAction = new KAction( i18n("Filter on &Subject..."), 0, this,
02395                       SLOT(slotSubjectFilter()),
02396                       actionCollection(), "subject_filter");
02397   mFilterMenu->insert( mSubjectFilterAction );
02398 
02399   mFromFilterAction = new KAction( i18n("Filter on &From..."), 0, this,
02400                    SLOT(slotFromFilter()),
02401                    actionCollection(), "from_filter");
02402   mFilterMenu->insert( mFromFilterAction );
02403 
02404   mToFilterAction = new KAction( i18n("Filter on &To..."), 0, this,
02405                  SLOT(slotToFilter()),
02406                  actionCollection(), "to_filter");
02407   mFilterMenu->insert( mToFilterAction );
02408 
02409   mListFilterAction = new KAction( i18n("Filter on Mailing-&List..."), 0, this,
02410                                    SLOT(slotMailingListFilter()), actionCollection(),
02411                                    "mlist_filter");
02412   mFilterMenu->insert( mListFilterAction );
02413 
02414   mPrintAction = KStdAction::print (this, SLOT(slotPrintMsg()), actionCollection());
02415 
02416   //----- Message-Encoding Submenu
02417   mEncoding = new KSelectAction( i18n( "&Set Encoding" ), "charset", 0, this,
02418               SLOT( slotSetEncoding() ), actionCollection(), "encoding" );
02419   QStringList encodings = KMMsgBase::supportedEncodings(FALSE);
02420   encodings.prepend( i18n( "Auto" ) );
02421   mEncoding->setItems( encodings );
02422   mEncoding->setCurrentItem(0);
02423 
02424   QStringList::Iterator it;
02425   int i = 0;
02426   for( it = encodings.begin(); it != encodings.end(); ++it)
02427   {
02428     if ( KGlobal::charsets()->encodingForName(*it ) == QString(mEncodingStr) )
02429     {
02430       mEncoding->setCurrentItem( i );
02431       break;
02432     }
02433     i++;
02434   }
02435 
02436   mEditAction = new KAction( i18n("&Edit Message"), "edit", Key_T, this,
02437                             SLOT(slotEditMsg()), actionCollection(), "edit" );
02438 
02439   //----- "Mark Message" submenu
02440   mStatusMenu = new KActionMenu ( i18n( "Mar&k Message" ),
02441                                  actionCollection(), "set_status" );
02442 
02443   mStatusMenu->insert(new KAction(KGuiItem(i18n("Mark Message as &Read"), "kmmsgread",
02444                                           i18n("Mark selected messages as read")),
02445                                  0, this, SLOT(slotSetMsgStatusRead()),
02446                                  actionCollection(), "status_read"));
02447 
02448   mStatusMenu->insert(new KAction(KGuiItem(i18n("Mark Message as &New"), "kmmsgnew",
02449                                           i18n("Mark selected messages as new")),
02450                                  0, this, SLOT(slotSetMsgStatusNew()),
02451                                  actionCollection(), "status_new" ));
02452 
02453   mStatusMenu->insert(new KAction(KGuiItem(i18n("Mark Message as &Unread"), "kmmsgunseen",
02454                                           i18n("Mark selected messages as unread")),
02455                                  0, this, SLOT(slotSetMsgStatusUnread()),
02456                                  actionCollection(), "status_unread"));
02457 
02458   mStatusMenu->insert( new KActionSeparator( this ) );
02459 
02460   // -------- Toggle Actions
02461   mToggleFlagAction = new KToggleAction(i18n("Mark Message as &Important"), "kmmsgflag",
02462                                  0, this, SLOT(slotSetMsgStatusFlag()),
02463                                  actionCollection(), "status_flag");
02464   mStatusMenu->insert( mToggleFlagAction );
02465 
02466   mToggleRepliedAction = new KToggleAction(i18n("Mark Message as Re&plied"), "kmmsgreplied",
02467                                  0, this, SLOT(slotSetMsgStatusReplied()),
02468                                  actionCollection(), "status_replied");
02469 
02470   mStatusMenu->insert( mToggleRepliedAction );
02471   mToggleForwardedAction = new KToggleAction(i18n("Mark Message as &Forwarded"), "kmmsgforwarded",
02472                                  0, this, SLOT(slotSetMsgStatusForwarded()),
02473                                  actionCollection(), "status_forwarded");
02474   mStatusMenu->insert( mToggleForwardedAction );
02475 
02476   mToggleQueuedAction = new KToggleAction(i18n("Mark Message as &Queued"), "kmmsgqueued",
02477                                  0, this, SLOT(slotSetMsgStatusQueued()),
02478                                  actionCollection(), "status_queued");
02479   mStatusMenu->insert( mToggleQueuedAction );
02480 
02481   mToggleSentAction = new KToggleAction(i18n("Mark Message as &Sent"), "kmmsgsent",
02482                                  0, this, SLOT(slotSetMsgStatusSent()),
02483                                  actionCollection(), "status_sent");
02484   mStatusMenu->insert( mToggleSentAction );
02485 
02486 #if KDE_IS_VERSION(3,2,90)
02487   mToggleFlagAction->setCheckedState( i18n("Remove &Important Message Mark") );
02488   mToggleRepliedAction->setCheckedState( i18n("Mark Message as Not Re&plied") );
02489   mToggleForwardedAction->setCheckedState( i18n("Mark Message as Not &Forwarded") );
02490   mToggleQueuedAction->setCheckedState( i18n("Mark Message as Not &Queued") );
02491   mToggleSentAction->setCheckedState( i18n("Mark Message as Not &Sent") );
02492 #endif
02493 
02494   mStatusMenu->insert( new KActionSeparator( this ) );
02495 
02496   mMarkAsSpamAction = new KAction(i18n("Mark Message as Spa&m"), "mark_as_spam",
02497                                  0, this, SLOT(slotSetMsgStatusSpam()),
02498                                  actionCollection(), "status_spam");
02499   mStatusMenu->insert( mMarkAsSpamAction );
02500 
02501   mMarkAsHamAction = new KAction(i18n("Mark Message as &Ham"), "mark_as_ham",
02502                                  0, this, SLOT(slotSetMsgStatusHam()),
02503                                  actionCollection(), "status_ham");
02504   mStatusMenu->insert( mMarkAsHamAction );
02505 
02506   //----- "Mark Thread" submenu
02507   mThreadStatusMenu = new KActionMenu ( i18n( "Mark &Thread" ),
02508                                        actionCollection(), "thread_status" );
02509 
02510   mMarkThreadAsReadAction = new KAction(KGuiItem(i18n("Mark Thread as &Read"), "kmmsgread",
02511                                                 i18n("Mark all messages in the selected thread as read")),
02512                                                 0, this, SLOT(slotSetThreadStatusRead()),
02513                                                 actionCollection(), "thread_read");
02514   mThreadStatusMenu->insert( mMarkThreadAsReadAction );
02515 
02516   mMarkThreadAsNewAction = new KAction(KGuiItem(i18n("Mark Thread as &New"), "kmmsgnew",
02517                                                i18n("Mark all messages in the selected thread as new")),
02518                                                0, this, SLOT(slotSetThreadStatusNew()),
02519                                                actionCollection(), "thread_new");
02520   mThreadStatusMenu->insert( mMarkThreadAsNewAction );
02521 
02522   mMarkThreadAsUnreadAction = new KAction(KGuiItem(i18n("Mark Thread as &Unread"), "kmmsgunseen",
02523                                                 i18n("Mark all messages in the selected thread as unread")),
02524                                                 0, this, SLOT(slotSetThreadStatusUnread()),
02525                                                 actionCollection(), "thread_unread");
02526   mThreadStatusMenu->insert( mMarkThreadAsUnreadAction );
02527 
02528   mThreadStatusMenu->insert( new KActionSeparator( this ) );
02529 
02530   //----- "Mark Thread" toggle actions
02531   mToggleThreadFlagAction = new KToggleAction(i18n("Mark Thread as &Important"), "kmmsgflag",
02532                                        0, this, SLOT(slotSetThreadStatusFlag()),
02533                                        actionCollection(), "thread_flag");
02534   mThreadStatusMenu->insert( mToggleThreadFlagAction );
02535 
02536   mToggleThreadRepliedAction = new KToggleAction(i18n("Mark Thread as R&eplied"), "kmmsgreplied",
02537                                        0, this, SLOT(slotSetThreadStatusReplied()),
02538                                        actionCollection(), "thread_replied");
02539   mThreadStatusMenu->insert( mToggleThreadRepliedAction );
02540 
02541   mToggleThreadForwardedAction = new KToggleAction(i18n("Mark Thread as &Forwarded"), "kmmsgforwarded",
02542                                        0, this, SLOT(slotSetThreadStatusForwarded()),
02543                                        actionCollection(), "thread_forwarded");
02544   mThreadStatusMenu->insert( mToggleThreadForwardedAction );
02545 
02546   mToggleThreadQueuedAction = new KToggleAction(i18n("Mark Thread as &Queued"), "kmmsgqueued",
02547                                        0, this, SLOT(slotSetThreadStatusQueued()),
02548                                        actionCollection(), "thread_queued");
02549   mThreadStatusMenu->insert( mToggleThreadQueuedAction );
02550 
02551   mToggleThreadSentAction = new KToggleAction(i18n("Mark Thread as &Sent"), "kmmsgsent",
02552                                        0, this, SLOT(slotSetThreadStatusSent()),
02553                                        actionCollection(), "thread_sent");
02554   mThreadStatusMenu->insert( mToggleThreadSentAction );
02555 
02556   mThreadStatusMenu->insert( new KActionSeparator( this ) );
02557 
02558 #if KDE_IS_VERSION(3,2,90)
02559   mToggleThreadFlagAction->setCheckedState( i18n("Remove &Important Thread Mark") );
02560   mToggleThreadRepliedAction->setCheckedState( i18n("Mark Thread as Not R&eplied") );
02561   mToggleThreadForwardedAction->setCheckedState( i18n("Mark Thread as Not &Forwarded") );
02562   mToggleThreadQueuedAction->setCheckedState( i18n("Mark Thread as Not &Queued") );
02563   mToggleThreadSentAction->setCheckedState( i18n("Mark Thread as Not &Sent") );
02564 #endif
02565 
02566   //------- "Watch and ignore thread" actions
02567   mWatchThreadAction = new KToggleAction(i18n("&Watch Thread"), "kmmsgwatched",
02568                                        0, this, SLOT(slotSetThreadStatusWatched()),
02569                                        actionCollection(), "thread_watched");
02570 
02571   mIgnoreThreadAction = new KToggleAction(i18n("&Ignore Thread"), "kmmsgignored",
02572                                        0, this, SLOT(slotSetThreadStatusIgnored()),
02573                                        actionCollection(), "thread_ignored");
02574 
02575   //------- "Ham and spam thread" actions
02576   mMarkThreadAsSpamAction = new KAction(i18n("Mark Thread as S&pam"), "mark_as_spam",
02577                                        0, this, SLOT(slotSetThreadStatusSpam()),
02578                                        actionCollection(), "thread_spam");
02579   mThreadStatusMenu->insert( mMarkThreadAsSpamAction );
02580 
02581   mMarkThreadAsHamAction = new KAction(i18n("Mark Thread as &Ham"), "mark_as_ham",
02582                                        0, this, SLOT(slotSetThreadStatusHam()),
02583                                        actionCollection(), "thread_ham");
02584   mThreadStatusMenu->insert( mMarkThreadAsHamAction );
02585 
02586 
02587   mSaveAttachmentsAction = new KAction( i18n("Save A&ttachments..."), "attach",
02588                                 0, this, SLOT(slotSaveAttachments()),
02589                                 actionCollection(), "file_save_attachments" );
02590 
02591   mMoveActionMenu = new KActionMenu( i18n("&Move To" ),
02592                                     actionCollection(), "move_to" );
02593 
02594   mCopyActionMenu = new KActionMenu( i18n("&Copy To" ),
02595                                     actionCollection(), "copy_to" );
02596 
02597   mApplyFiltersAction = new KAction( i18n("Appl&y Filters"), "filter",
02598                     CTRL+Key_J, this,
02599                     SLOT(slotApplyFilters()),
02600                     actionCollection(), "apply_filters" );
02601 
02602   mApplyFilterActionsMenu = new KActionMenu( i18n("A&pply Filter" ),
02603                         actionCollection(),
02604                         "apply_filter_actions" );
02605 
02606   //----- View Menu
02607   KRadioAction * raction = 0;
02608 
02609   // "Headers" submenu:
02610   KActionMenu * headerMenu =
02611     new KActionMenu( i18n("View->", "&Headers"),
02612                     actionCollection(), "view_headers" );
02613   headerMenu->setToolTip( i18n("Choose display style of message headers") );
02614 
02615   connect( headerMenu, SIGNAL(activated()), SLOT(slotCycleHeaderStyles()) );
02616 
02617   raction = new KRadioAction( i18n("View->headers->", "&Fancy Headers"), 0, this,
02618       SLOT(slotFancyHeaders()),
02619       actionCollection(), "view_headers_fancy" );
02620   raction->setToolTip( i18n("Show the list of headers in a fancy format") );
02621   raction->setExclusiveGroup( "view_headers_group" );
02622   headerMenu->insert( raction );
02623 
02624   raction = new KRadioAction( i18n("View->headers->", "&Brief Headers"), 0, this,
02625       SLOT(slotBriefHeaders()),
02626       actionCollection(), "view_headers_brief" );
02627   raction->setToolTip( i18n("Show brief list of message headers") );
02628   raction->setExclusiveGroup( "view_headers_group" );
02629   headerMenu->insert( raction );
02630 
02631   raction = new KRadioAction( i18n("View->headers->", "&Standard Headers"), 0, this,
02632       SLOT(slotStandardHeaders()),
02633       actionCollection(), "view_headers_standard" );
02634   raction->setToolTip( i18n("Show standard list of message headers") );
02635   raction->setExclusiveGroup( "view_headers_group" );
02636   headerMenu->insert( raction );
02637 
02638   raction = new KRadioAction( i18n("View->headers->", "&Long Headers"), 0, this,
02639       SLOT(slotLongHeaders()),
02640       actionCollection(), "view_headers_long" );
02641   raction->setToolTip( i18n("Show long list of message headers") );
02642   raction->setExclusiveGroup( "view_headers_group" );
02643   headerMenu->insert( raction );
02644 
02645   raction = new KRadioAction( i18n("View->headers->", "&All Headers"), 0, this,
02646       SLOT(slotAllHeaders()),
02647       actionCollection(), "view_headers_all" );
02648   raction->setToolTip( i18n("Show all message headers") );
02649   raction->setExclusiveGroup( "view_headers_group" );
02650   headerMenu->insert( raction );
02651 
02652 
02653 
02654   // "Attachments" submenu:
02655   KActionMenu * attachmentMenu =
02656     new KActionMenu( i18n("View->", "&Attachments"),
02657         actionCollection(), "view_attachments" );
02658   connect( attachmentMenu, SIGNAL(activated()),
02659       SLOT(slotCycleAttachmentStrategy()) );
02660 
02661   attachmentMenu->setToolTip( i18n("Choose display style of attachments") );
02662 
02663   raction = new KRadioAction( i18n("View->attachments->", "&As Icons"), 0, this,
02664       SLOT(slotIconicAttachments()),
02665       actionCollection(), "view_attachments_as_icons" );
02666   raction->setToolTip( i18n("Show all attachments as icons. Click to see them.") );
02667   raction->setExclusiveGroup( "view_attachments_group" );
02668   attachmentMenu->insert( raction );
02669 
02670   raction = new KRadioAction( i18n("View->attachments->", "&Smart"), 0, this,
02671       SLOT(slotSmartAttachments()),
02672       actionCollection(), "view_attachments_smart" );
02673   raction->setToolTip( i18n("Show attachments as suggested by sender.") );
02674   raction->setExclusiveGroup( "view_attachments_group" );
02675   attachmentMenu->insert( raction );
02676 
02677   raction = new KRadioAction( i18n("View->attachments->", "&Inline"), 0, this,
02678       SLOT(slotInlineAttachments()),
02679       actionCollection(), "view_attachments_inline" );
02680   raction->setToolTip( i18n("Show all attachments inline (if possible)") );
02681   raction->setExclusiveGroup( "view_attachments_group" );
02682   attachmentMenu->insert( raction );
02683 
02684   raction = new KRadioAction( i18n("View->attachments->", "&Hide"), 0, this,
02685       SLOT(slotHideAttachments()),
02686       actionCollection(), "view_attachments_hide" );
02687   raction->setToolTip( i18n("Do not show attachments in the message viewer") );
02688   raction->setExclusiveGroup( "view_attachments_group" );
02689   attachmentMenu->insert( raction );
02690 
02691   // Unread Submenu
02692   KActionMenu * unreadMenu =
02693     new KActionMenu( i18n("View->", "&Unread Count"),
02694              actionCollection(), "view_unread" );
02695   unreadMenu->setToolTip( i18n("Choose how to display the count of unread messages") );
02696 
02697   mUnreadColumnToggle = new KRadioAction( i18n("View->Unread Count", "View in &Separate Column"), 0, this,
02698                    SLOT(slotToggleUnread()),
02699                    actionCollection(), "view_unread_column" );
02700   mUnreadColumnToggle->setExclusiveGroup( "view_unread_group" );
02701   unreadMenu->insert( mUnreadColumnToggle );
02702 
02703   mUnreadTextToggle = new KRadioAction( i18n("View->Unread Count", "View After &Folder Name"), 0, this,
02704                    SLOT(slotToggleUnread()),
02705                    actionCollection(), "view_unread_text" );
02706   mUnreadTextToggle->setExclusiveGroup( "view_unread_group" );
02707   unreadMenu->insert( mUnreadTextToggle );
02708 
02709   // toggle for total column
02710   mTotalColumnToggle = new KToggleAction( i18n("View->", "&Total Column"), 0, this,
02711                    SLOT(slotToggleTotalColumn()),
02712                    actionCollection(), "view_columns_total" );
02713   mTotalColumnToggle->setToolTip( i18n("Toggle display of column showing the "
02714                                       "total number of messages in folders.") );
02715 
02716   (void)new KAction( KGuiItem( i18n("View->","&Expand Thread"), QString::null,
02717                    i18n("Expand the current thread") ),
02718              Key_Period, this,
02719              SLOT(slotExpandThread()),
02720              actionCollection(), "expand_thread" );
02721 
02722   (void)new KAction( KGuiItem( i18n("View->","&Collapse Thread"), QString::null,
02723                    i18n("Collapse the current thread") ),
02724              Key_Comma, this,
02725              SLOT(slotCollapseThread()),
02726              actionCollection(), "collapse_thread" );
02727 
02728   (void)new KAction( KGuiItem( i18n("View->","Ex&pand All Threads"), QString::null,
02729                    i18n("Expand all threads in the current folder") ),
02730              CTRL+Key_Period, this,
02731              SLOT(slotExpandAllThreads()),
02732              actionCollection(), "expand_all_threads" );
02733 
02734   (void)new KAction( KGuiItem( i18n("View->","C&ollapse All Threads"), QString::null,
02735                    i18n("Collapse all threads in the current folder") ),
02736              CTRL+Key_Comma, this,
02737              SLOT(slotCollapseAllThreads()),
02738              actionCollection(), "collapse_all_threads" );
02739 
02740 
02741   //----- Go Menu
02742   new KAction( KGuiItem( i18n("&Next Message"), QString::null,
02743                          i18n("Go to the next message") ),
02744                          "N;Right", this, SLOT(slotNextMessage()),
02745                          actionCollection(), "go_next_message" );
02746 
02747   new KAction( KGuiItem( i18n("Next &Unread Message"),
02748                          QApplication::reverseLayout() ? "previous" : "next",
02749                          i18n("Go to the next unread message") ),
02750                          Key_Plus, this, SLOT(slotNextUnreadMessage()),
02751                          actionCollection(), "go_next_unread_message" );
02752 
02753   /* ### needs better support from folders:
02754   new KAction( KGuiItem( i18n("Next &Important Message"), QString::null,
02755                          i18n("Go to the next important message") ),
02756                          0, this, SLOT(slotNextImportantMessage()),
02757                          actionCollection(), "go_next_important_message" );
02758   */
02759 
02760   new KAction( KGuiItem( i18n("&Previous Message"), QString::null,
02761                          i18n("Go to the previous message") ),
02762                          "P;Left", this, SLOT(slotPrevMessage()),
02763                          actionCollection(), "go_prev_message" );
02764 
02765   new KAction( KGuiItem( i18n("Previous Unread &Message"),
02766                          QApplication::reverseLayout() ? "next" : "previous",
02767                          i18n("Go to the previous unread message") ),
02768                          Key_Minus, this, SLOT(slotPrevUnreadMessage()),
02769                          actionCollection(), "go_prev_unread_message" );
02770 
02771   /* needs better support from folders:
02772   new KAction( KGuiItem( i18n("Previous I&mportant Message"), QString::null,
02773                          i18n("Go to the previous important message") ),
02774                          0, this, SLOT(slotPrevImportantMessage()),
02775                          actionCollection(), "go_prev_important_message" );
02776   */
02777 
02778   new KAction( KGuiItem( i18n("Next Unread &Folder"), QString::null,
02779                          i18n("Go to the next folder with unread messages") ),
02780                          CTRL+Key_Plus, this, SLOT(slotNextUnreadFolder()),
02781                          actionCollection(), "go_next_unread_folder" );
02782 
02783   new KAction( KGuiItem( i18n("Previous Unread F&older"), QString::null,
02784                          i18n("Go to the previous folder with unread messages") ),
02785                          CTRL+Key_Minus, this, SLOT(slotPrevUnreadFolder()),
02786                          actionCollection(), "go_prev_unread_folder" );
02787 
02788   new KAction( KGuiItem( i18n("Go->","Next Unread &Text"), QString::null,
02789                          i18n("Go to the next unread text"),
02790                          i18n("Scroll down current message. "
02791                               "If at end of current message, "
02792                               "go to next unread message.") ),
02793                          Key_Space, this, SLOT(slotReadOn()),
02794                          actionCollection(), "go_next_unread_text" );
02795 
02796   //----- Settings Menu
02797   mToggleShowQuickSearchAction = new KToggleAction(i18n("Show Quick Search"), QString::null,
02798                                        0, this, SLOT(slotToggleShowQuickSearch()),
02799                                        actionCollection(), "show_quick_search");
02800   mToggleShowQuickSearchAction->setChecked( GlobalSettings::quickSearchActive() );
02801   mToggleShowQuickSearchAction->setWhatsThis(
02802         i18n( GlobalSettings::self()->quickSearchActiveItem()->whatsThis().utf8() ) );
02803 
02804   (void) new KAction( i18n("Configure &Filters..."), 0, this,
02805               SLOT(slotFilter()), actionCollection(), "filter" );
02806   (void) new KAction( i18n("Configure &POP Filters..."), 0, this,
02807               SLOT(slotPopFilter()), actionCollection(), "popFilter" );
02808 
02809   (void) new KAction( KGuiItem( i18n("KMail &Introduction"), 0,
02810                 i18n("Display KMail's Welcome Page") ),
02811               0, this, SLOT(slotIntro()),
02812               actionCollection(), "help_kmail_welcomepage" );
02813 
02814   // ----- Standard Actions
02815 //  KStdAction::configureNotifications(this, SLOT(slotEditNotifications()), actionCollection());
02816   (void) new KAction( i18n("Configure &Notifications..."),
02817               "knotify", 0, this,
02818               SLOT(slotEditNotifications()), actionCollection(),
02819               "kmail_configure_notifications" );
02820 //  KStdAction::preferences(this, SLOT(slotSettings()), actionCollection());
02821   (void) new KAction( i18n("&Configure KMail..."),
02822               "configure", 0, kmkernel,
02823                       SLOT(slotShowConfigurationDialog()), actionCollection(),
02824                       "kmail_configure_kmail" );
02825 
02826   KStdAction::undo(this, SLOT(slotUndo()), actionCollection(), "kmail_undo");
02827 //  (void) new KAction( i18n("&Undo"), 0, this,
02828 //            SLOT(slotUndo()), actionCollection(),
02829 //            "kmail_undo" );
02830 
02831   KStdAction::copy( messageView(), SLOT(slotCopySelectedText()), actionCollection(), "kmail_copy");
02832 //  (void) new KAction( i18n("&Copy"), CTRL+Key_C, mMsgView,
02833 //            SLOT(slotCopySelectedText()), actionCollection(),
02834 //            "kmail_copy" );
02835 
02836   KStdAction::tipOfDay( this, SLOT( slotShowTip() ), actionCollection() );
02837 
02838   menutimer = new QTimer( this, "menutimer" );
02839   connect( menutimer, SIGNAL( timeout() ), SLOT( updateMessageActions() ) );
02840   connect( kmkernel->undoStack(),
02841            SIGNAL( undoStackChanged() ), this, SLOT( slotUpdateUndo() ));
02842 
02843   initializeFilterActions();
02844   updateMessageActions();
02845 }
02846 
02847 //-----------------------------------------------------------------------------
02848 void KMMainWidget::slotEditNotifications()
02849 {
02850   if(kmkernel->xmlGuiInstance())
02851     KNotifyDialog::configure(this, 0, kmkernel->xmlGuiInstance()->aboutData());
02852   else
02853     KNotifyDialog::configure(this);
02854 }
02855 
02856 void KMMainWidget::slotEditKeys()
02857 {
02858   KKeyDialog::configure( actionCollection(),
02859              true /*allow one-letter shortcuts*/
02860              );
02861 }
02862 
02863 //-----------------------------------------------------------------------------
02864 void KMMainWidget::slotReadOn()
02865 {
02866     if ( !mMsgView )
02867         return;
02868 
02869     if ( !mMsgView->atBottom() ) {
02870         mMsgView->slotJumpDown();
02871         return;
02872     }
02873     slotNextUnreadMessage();
02874 }
02875 
02876 void KMMainWidget::slotNextUnreadFolder() {
02877   if ( !mFolderTree ) return;
02878   mFolderTree->nextUnreadFolder();
02879 }
02880 
02881 void KMMainWidget::slotPrevUnreadFolder() {
02882   if ( !mFolderTree ) return;
02883   mFolderTree->prevUnreadFolder();
02884 }
02885 
02886 void KMMainWidget::slotExpandThread()
02887 {
02888   mHeaders->slotExpandOrCollapseThread( true ); // expand
02889 }
02890 
02891 void KMMainWidget::slotCollapseThread()
02892 {
02893   mHeaders->slotExpandOrCollapseThread( false ); // collapse
02894 }
02895 
02896 void KMMainWidget::slotExpandAllThreads()
02897 {
02898   mHeaders->slotExpandOrCollapseAllThreads( true ); // expand
02899 }
02900 
02901 void KMMainWidget::slotCollapseAllThreads()
02902 {
02903   mHeaders->slotExpandOrCollapseAllThreads( false ); // collapse
02904 }
02905 
02906 
02907 //-----------------------------------------------------------------------------
02908 void KMMainWidget::moveSelectedToFolder( int menuId )
02909 {
02910   if (mMenuToFolder[menuId])
02911     mHeaders->moveMsgToFolder( mMenuToFolder[menuId] );
02912 }
02913 
02914 
02915 //-----------------------------------------------------------------------------
02916 void KMMainWidget::copySelectedToFolder(int menuId )
02917 {
02918   if (mMenuToFolder[menuId])
02919     mHeaders->copyMsgToFolder( mMenuToFolder[menuId] );
02920 }
02921 
02922 
02923 //-----------------------------------------------------------------------------
02924 void KMMainWidget::updateMessageMenu()
02925 {
02926     mMenuToFolder.clear();
02927     KMMenuCommand::folderToPopupMenu( true, this, &mMenuToFolder, mMoveActionMenu->popupMenu() );
02928     KMMenuCommand::folderToPopupMenu( false, this, &mMenuToFolder, mCopyActionMenu->popupMenu() );
02929     updateMessageActions();
02930 }
02931 
02932 void KMMainWidget::startUpdateMessageActionsTimer()
02933 {
02934     menutimer->stop();
02935     menutimer->start( 20, true );
02936 }
02937 
02938 void KMMainWidget::updateMessageActions()
02939 {
02940     int count = 0;
02941     QPtrList<QListViewItem> selectedItems;
02942 
02943     if ( mFolder ) {
02944         for (QListViewItem *item = mHeaders->firstChild(); item; item = item->itemBelow())
02945             if (item->isSelected() )
02946             selectedItems.append(item);
02947         if ( selectedItems.isEmpty() && mFolder->count() ) // there will always be one in mMsgView
02948             count = 1;
02949     else count = selectedItems.count();
02950     }
02951 
02952     updateListFilterAction();
02953 
02954     bool allSelectedInCommonThread = true;
02955     if ( count > 1 && mHeaders->isThreaded() ) {
02956       QListViewItem * curItemParent = mHeaders->currentItem();
02957       while ( curItemParent->parent() )
02958     curItemParent = curItemParent->parent();
02959       for ( QPtrListIterator<QListViewItem> it( selectedItems ) ;
02960         it.current() ; ++ it ) {
02961     QListViewItem * item = *it;
02962     while ( item->parent() )
02963       item = item->parent();
02964     if ( item != curItemParent ) {
02965       allSelectedInCommonThread = false;
02966       break;
02967     }
02968       }
02969     }
02970 
02971     bool mass_actions = count >= 1;
02972     bool thread_actions = mass_actions &&
02973            allSelectedInCommonThread &&
02974            mHeaders->isThreaded();
02975     mStatusMenu->setEnabled( mass_actions );
02976     mThreadStatusMenu->setEnabled( thread_actions );
02977     // these need to be handled individually, the user might have them
02978     // in the toolbar
02979     mWatchThreadAction->setEnabled( thread_actions );
02980     mIgnoreThreadAction->setEnabled( thread_actions );
02981     mMarkThreadAsSpamAction->setEnabled( thread_actions );
02982     mMarkThreadAsHamAction->setEnabled( thread_actions );
02983     mMarkThreadAsNewAction->setEnabled( thread_actions );
02984     mMarkThreadAsReadAction->setEnabled( thread_actions );
02985     mMarkThreadAsUnreadAction->setEnabled( thread_actions );
02986     mToggleThreadRepliedAction->setEnabled( thread_actions );
02987     mToggleThreadForwardedAction->setEnabled( thread_actions );
02988     mToggleThreadQueuedAction->setEnabled( thread_actions );
02989     mToggleThreadSentAction->setEnabled( thread_actions );
02990     mToggleThreadFlagAction->setEnabled( thread_actions );
02991 
02992     if (mFolder && mHeaders && mHeaders->currentMsg()) {
02993       mToggleRepliedAction->setChecked(mHeaders->currentMsg()->isReplied());
02994       mToggleForwardedAction->setChecked(mHeaders->currentMsg()->isForwarded());
02995       mToggleQueuedAction->setChecked(mHeaders->currentMsg()->isQueued());
02996       mToggleSentAction->setChecked(mHeaders->currentMsg()->isSent());
02997       mToggleFlagAction->setChecked(mHeaders->currentMsg()->isImportant());
02998       if (thread_actions) {
02999         mToggleThreadRepliedAction->setChecked(mHeaders->currentMsg()->isReplied());
03000         mToggleThreadForwardedAction->setChecked(mHeaders->currentMsg()->isForwarded());
03001         mToggleThreadQueuedAction->setChecked(mHeaders->currentMsg()->isQueued());
03002         mToggleThreadSentAction->setChecked(mHeaders->currentMsg()->isSent());
03003         mToggleThreadFlagAction->setChecked(mHeaders->currentMsg()->isImportant());
03004         mWatchThreadAction->setChecked( mHeaders->currentMsg()->isWatched());
03005         mIgnoreThreadAction->setChecked( mHeaders->currentMsg()->isIgnored());
03006       }
03007     }
03008 
03009     mMoveActionMenu->setEnabled( mass_actions && !mFolder->isReadOnly() );
03010     mCopyActionMenu->setEnabled( mass_actions );
03011     mTrashAction->setEnabled( mass_actions && !mFolder->isReadOnly() );
03012     mDeleteAction->setEnabled( mass_actions && !mFolder->isReadOnly() );
03013     mFindInMessageAction->setEnabled( mass_actions );
03014     mForwardAction->setEnabled( mass_actions );
03015     mForwardAttachedAction->setEnabled( mass_actions );
03016 
03017     forwardMenu()->setEnabled( mass_actions );
03018 
03019     bool single_actions = count == 1;
03020     mEditAction->setEnabled( single_actions &&
03021     kmkernel->folderIsDraftOrOutbox(mFolder));
03022     replyMenu()->setEnabled( single_actions );
03023     filterMenu()->setEnabled( single_actions );
03024     bounceAction()->setEnabled( single_actions );
03025     replyAction()->setEnabled( single_actions );
03026     noQuoteReplyAction()->setEnabled( single_actions );
03027     replyAuthorAction()->setEnabled( single_actions );
03028     replyAllAction()->setEnabled( single_actions );
03029     replyListAction()->setEnabled( single_actions );
03030     redirectAction()->setEnabled( single_actions );
03031     printAction()->setEnabled( single_actions );
03032     if (mMsgView) {
03033       viewSourceAction()->setEnabled( single_actions );
03034     }
03035 
03036     mSendAgainAction->setEnabled( single_actions &&
03037              ( mHeaders->currentMsg() && mHeaders->currentMsg()->isSent() )
03038           || ( mFolder && kmkernel->folderIsDraftOrOutbox( mFolder ) )
03039           || ( mFolder && kmkernel->folderIsSentMailFolder( mFolder ) )
03040              );
03041     mSaveAsAction->setEnabled( mass_actions );
03042     bool mails = mFolder && mFolder->count();
03043     bool enable_goto_unread = mails
03044        || (GlobalSettings::loopOnGotoUnread() == GlobalSettings::EnumLoopOnGotoUnread::LoopInAllFolders);
03045     actionCollection()->action( "go_next_message" )->setEnabled( mails );
03046     actionCollection()->action( "go_next_unread_message" )->setEnabled( enable_goto_unread );
03047     actionCollection()->action( "go_prev_message" )->setEnabled( mails );
03048     actionCollection()->action( "go_prev_unread_message" )->setEnabled( enable_goto_unread );
03049     actionCollection()->action( "send_queued" )->setEnabled( kmkernel->outboxFolder()->count() > 0 );
03050     if (action( "edit_undo" ))
03051       action( "edit_undo" )->setEnabled( mHeaders->canUndo() );
03052 
03053     if ( count == 1 ) {
03054       KMMessage *msg;
03055       int aIdx;
03056       if((aIdx = mHeaders->currentItemIndex()) <= -1)
03057         return;
03058       if(!(msg = mFolder->getMsg(aIdx)))
03059         return;
03060 
03061       if (mFolder == kmkernel->outboxFolder())
03062         mEditAction->setEnabled( !msg->transferInProgress() );
03063     }
03064 
03065     mApplyFiltersAction->setEnabled(count);
03066     mApplyFilterActionsMenu->setEnabled(count && (mApplyFilterActionsMenu->popupMenu()->count()>0));
03067 }
03068 
03069 // This needs to be updated more often, so it is in its method.
03070 void KMMainWidget::updateMarkAsReadAction()
03071 {
03072   mMarkAllAsReadAction->setEnabled( mFolder && (mFolder->countUnread() > 0) );
03073 }
03074 
03075 //-----------------------------------------------------------------------------
03076 void KMMainWidget::updateFolderMenu()
03077 {
03078   bool folderWithContent = mFolder && !mFolder->noContent();
03079   mModifyFolderAction->setEnabled( folderWithContent );
03080   mCompactFolderAction->setEnabled( folderWithContent );
03081 
03082   // This is the refresh-folder action in the menu. See kmfoldertree for the one in the RMB...
03083   bool imap = mFolder && mFolder->folderType() == KMFolderTypeImap;
03084   bool cachedImap = mFolder && mFolder->folderType() == KMFolderTypeCachedImap;
03085   // For dimap, check that the imap path is known before allowing "check mail in this folder".
03086   bool knownImapPath = cachedImap && !static_cast<KMFolderCachedImap*>( mFolder->storage() )->imapPath().isEmpty();
03087   mRefreshFolderAction->setEnabled( folderWithContent && ( imap
03088                                                            || ( cachedImap && knownImapPath ) ) );
03089   mEmptyFolderAction->setEnabled( folderWithContent && ( mFolder->count() > 0 ) && !mFolder->isReadOnly() );
03090   mEmptyFolderAction->setText( (mFolder && kmkernel->folderIsTrash(mFolder))
03091     ? i18n("E&mpty Trash") : i18n("&Move All Messages to Trash") );
03092   mRemoveFolderAction->setEnabled( (mFolder && !mFolder->isSystemFolder()) );
03093   mExpireFolderAction->setEnabled( mFolder && mFolder->isAutoExpire() );
03094   updateMarkAsReadAction();
03095   mPreferHtmlAction->setEnabled( mFolder ? true : false );
03096   mThreadMessagesAction->setEnabled( mFolder ? true : false );
03097 
03098   mPreferHtmlAction->setChecked( mHtmlPref ? !mFolderHtmlPref : mFolderHtmlPref );
03099   mThreadMessagesAction->setChecked(
03100       mThreadPref ? !mFolderThreadPref : mFolderThreadPref );
03101   mThreadBySubjectAction->setEnabled(
03102       mFolder ? ( mThreadMessagesAction->isChecked()) : false );
03103   mThreadBySubjectAction->setChecked( mFolderThreadSubjPref );
03104 }
03105 
03106 
03107 #ifdef MALLOC_DEBUG
03108 static QString fmt(long n) {
03109   char buf[32];
03110 
03111   if(n > 1024*1024*1024)
03112     sprintf(buf, "%0.2f GB", ((double)n)/1024.0/1024.0/1024.0);
03113   else if(n > 1024*1024)
03114     sprintf(buf, "%0.2f MB", ((double)n)/1024.0/1024.0);
03115   else if(n > 1024)
03116     sprintf(buf, "%0.2f KB", ((double)n)/1024.0);
03117   else
03118     sprintf(buf, "%ld Byte", n);
03119   return QString(buf);
03120 }
03121 #endif
03122 
03123 void KMMainWidget::slotMemInfo() {
03124 #ifdef MALLOC_DEBUG
03125   struct mallinfo mi;
03126 
03127   mi = mallinfo();
03128   QString s = QString("\nMALLOC - Info\n\n"
03129               "Number of mmapped regions : %1\n"
03130               "Memory allocated in use   : %2\n"
03131               "Memory allocated, not used: %3\n"
03132               "Memory total allocated    : %4\n"
03133               "Max. freeable memory      : %5\n")
03134     .arg(mi.hblks).arg(fmt(mi.uordblks)).arg(fmt(mi.fordblks))
03135     .arg(fmt(mi.arena)).arg(fmt(mi.keepcost));
03136   KMessageBox::information(0, s, "Malloc information", s);
03137 #endif
03138 }
03139 
03140 
03141 //-----------------------------------------------------------------------------
03142 void KMMainWidget::slotIntro()
03143 {
03144   if ( !mMsgView ) return;
03145 
03146   mMsgView->clear( true );
03147   // hide widgets that are in the way:
03148   if ( mSearchAndHeaders && mHeaders && mLongFolderList )
03149     mSearchAndHeaders->hide();
03150 
03151 
03152   mMsgView->displayAboutPage();
03153 
03154   mFolder = 0;
03155 }
03156 
03157 void KMMainWidget::slotShowStartupFolder()
03158 {
03159   if ( mFolderTree ) {
03160     mFolderTree->reload();
03161     mFolderTree->readConfig();
03162     // get rid of old-folders
03163     mFolderTree->cleanupConfigFile();
03164   }
03165 
03166   connect( kmkernel->filterMgr(), SIGNAL( filterListUpdated() ),
03167        this, SLOT( initializeFilterActions() ));
03168 
03169   // plug shortcut filter actions now
03170   initializeFilterActions();
03171 
03172   QString newFeaturesMD5 = KMReaderWin::newFeaturesMD5();
03173   if ( kmkernel->firstStart() ||
03174        GlobalSettings::previousNewFeaturesMD5() != newFeaturesMD5 ) {
03175     GlobalSettings::setPreviousNewFeaturesMD5( newFeaturesMD5 );
03176     slotIntro();
03177   }
03178 
03179   KMFolder* startup = 0;
03180   if ( !mStartupFolder.isEmpty() ) {
03181     // find the startup-folder
03182     startup = kmkernel->findFolderById( mStartupFolder );
03183   }
03184   if ( !startup )
03185     startup = kmkernel->inboxFolder();
03186 
03187   if ( mFolderTree ) {
03188     mFolderTree->showFolder( startup );
03189   }
03190 }
03191 
03192 void KMMainWidget::slotShowTip()
03193 {
03194   KTipDialog::showTip( this, QString::null, true );
03195 }
03196 
03197 //-----------------------------------------------------------------------------
03198 void KMMainWidget::slotChangeCaption(QListViewItem * i)
03199 {
03200   if ( !i ) return;
03201   // set the caption to the current full path
03202   QStringList names;
03203   for ( QListViewItem * item = i ; item ; item = item->parent() )
03204     names.prepend( item->text(0) );
03205   emit captionChangeRequest( names.join( "/" ) );
03206 }
03207 
03208 //-----------------------------------------------------------------------------
03209 void KMMainWidget::removeDuplicates()
03210 {
03211   if (!mFolder)
03212     return;
03213   KMFolder *oFolder = mFolder;
03214   mHeaders->setFolder(0);
03215   QMap< QString, QValueList<int> > idMD5s;
03216   QValueList<int> redundantIds;
03217   QValueList<int>::Iterator kt;
03218   mFolder->open();
03219   for (int i = mFolder->count() - 1; i >= 0; --i) {
03220     QString id = (*mFolder)[i]->msgIdMD5();
03221     if ( !id.isEmpty() ) {
03222       QString subjMD5 = (*mFolder)[i]->strippedSubjectMD5();
03223       int other = -1;
03224       if ( idMD5s.contains(id) )
03225         other = idMD5s[id].first();
03226       else
03227         idMD5s[id].append( i );
03228       if ( other != -1 ) {
03229         QString otherSubjMD5 = (*mFolder)[other]->strippedSubjectMD5();
03230         if (otherSubjMD5 == subjMD5)
03231           idMD5s[id].append( i );
03232       }
03233     }
03234   }
03235   QMap< QString, QValueList<int> >::Iterator it;
03236   for ( it = idMD5s.begin(); it != idMD5s.end() ; ++it ) {
03237     QValueList<int>::Iterator jt;
03238     bool finished = false;
03239     for ( jt = (*it).begin(); jt != (*it).end() && !finished; ++jt )
03240       if (!((*mFolder)[*jt]->isUnread())) {
03241         (*it).remove( jt );
03242         (*it).prepend( *jt );
03243         finished = true;
03244       }
03245     for ( jt = (*it).begin(), ++jt; jt != (*it).end(); ++jt )
03246       redundantIds.append( *jt );
03247   }
03248   qHeapSort( redundantIds );
03249   kt = redundantIds.end();
03250   int numDuplicates = 0;
03251   if (kt != redundantIds.begin()) do {
03252     mFolder->removeMsg( *(--kt) );
03253     ++numDuplicates;
03254   }
03255   while (kt != redundantIds.begin());
03256 
03257   mFolder->close();
03258   mHeaders->setFolder(oFolder);
03259   QString msg;
03260   if ( numDuplicates )
03261     msg = i18n("Removed %n duplicate message.",
03262                "Removed %n duplicate messages.", numDuplicates );
03263     else
03264       msg = i18n("No duplicate messages found.");
03265   BroadcastStatus::instance()->setStatusMsg( msg );
03266 }
03267 
03268 
03269 //-----------------------------------------------------------------------------
03270 void KMMainWidget::slotUpdateUndo()
03271 {
03272     if (actionCollection()->action( "edit_undo" ))
03273         actionCollection()->action( "edit_undo" )->setEnabled( mHeaders->canUndo() );
03274 }
03275 
03276 
03277 //-----------------------------------------------------------------------------
03278 void KMMainWidget::clearFilterActions()
03279 {
03280   if ( !mFilterTBarActions.isEmpty() ) {
03281     if ( mGUIClient->factory() )
03282       mGUIClient->unplugActionList( "toolbar_filter_actions" );
03283     mFilterTBarActions.clear();
03284   }
03285   if ( !mFilterMenuActions.isEmpty() ) {
03286     mApplyFilterActionsMenu->popupMenu()->clear();
03287     if ( mGUIClient->factory() )
03288       mGUIClient->unplugActionList( "menu_filter_actions" );
03289     mFilterMenuActions.clear();
03290   }
03291   mFilterCommands.clear();
03292 }
03293 
03294 
03295 //-----------------------------------------------------------------------------
03296 void KMMainWidget::initializeFilterActions()
03297 {
03298   QString filterName, normalizedName;
03299   KMMetaFilterActionCommand *filterCommand;
03300   KAction *filterAction = 0;
03301 
03302   clearFilterActions();
03303   for ( QPtrListIterator<KMFilter> it(*kmkernel->filterMgr()) ;
03304         it.current() ; ++it ) {
03305     if (!(*it)->isEmpty() && (*it)->configureShortcut()) {
03306       filterName = QString("Filter %1").arg((*it)->name());
03307       normalizedName = filterName.replace(" ", "_");
03308       if (action(normalizedName.utf8()))
03309         continue;
03310       filterCommand = new KMMetaFilterActionCommand(*it, mHeaders, this);
03311       mFilterCommands.append(filterCommand);
03312       QString as = i18n("Filter %1").arg((*it)->name());
03313       QString icon = (*it)->icon();
03314       if ( icon.isEmpty() )
03315         icon = "gear";
03316       filterAction = new KAction(as, icon, 0, filterCommand,
03317                                  SLOT(start()), actionCollection(),
03318                                  normalizedName.local8Bit());
03319       filterAction->plug( mApplyFilterActionsMenu->popupMenu() );
03320       mFilterMenuActions.append(filterAction);
03321       // FIXME
03322       // uncomment the next if statement after the filter dialog supports
03323       // separate activation of filters for the toolbar - currently
03324       // we better depend on whether an icon is defined, so the current
03325       // IF statement is intermediate
03326       // if ( (*it)->configureToolbar() )
03327       if ( !(*it)->icon().isEmpty() )
03328         mFilterTBarActions.append(filterAction);
03329     }
03330   }
03331   if ( !mFilterMenuActions.isEmpty() && mGUIClient->factory() )
03332     mGUIClient->plugActionList( "menu_filter_actions", mFilterMenuActions );
03333   if ( !mFilterTBarActions.isEmpty() && mGUIClient->factory() )
03334     mGUIClient->plugActionList( "toolbar_filter_actions", mFilterTBarActions );
03335 }
03336 
03337 
03338 //-----------------------------------------------------------------------------
03339 void KMMainWidget::slotSubscriptionDialog()
03340 {
03341   if (!mFolder) return;
03342 
03343   ImapAccountBase* account;
03344   QString startPath;
03345   if (mFolder->folderType() == KMFolderTypeImap)
03346   {
03347     startPath = static_cast<KMFolderImap*>(mFolder->storage())->imapPath();
03348     account = static_cast<KMFolderImap*>(mFolder->storage())->account();
03349   } else if (mFolder->folderType() == KMFolderTypeCachedImap)
03350   {
03351     startPath = static_cast<KMFolderCachedImap*>(mFolder->storage())->imapPath();
03352     account = static_cast<KMFolderCachedImap*>(mFolder->storage())->account();
03353   } else
03354     return;
03355 
03356   if ( !account ) return;
03357 
03358   SubscriptionDialog *dialog = new SubscriptionDialog(this,
03359       i18n("Subscription"),
03360       account, startPath);
03361   // start a new listing
03362   if ( dialog->exec() ) {
03363     if (mFolder->folderType() == KMFolderTypeImap)
03364       static_cast<KMFolderImap*>(mFolder->storage())->account()->listDirectory();
03365   }
03366 }
03367 
03368 //-----------------------------------------------------------------------------
03369 void KMMainWidget::slotFolderTreeColumnsChanged()
03370 {
03371   mTotalColumnToggle->setChecked( mFolderTree->isTotalActive() );
03372   mUnreadColumnToggle->setChecked( mFolderTree->isUnreadActive() );
03373 }
03374 
03375 void KMMainWidget::toggleSystemTray()
03376 {
03377   if ( !mSystemTray && GlobalSettings::systemTrayEnabled() ) {
03378     mSystemTray = new KMSystemTray();
03379   }
03380   else if ( mSystemTray && !GlobalSettings::systemTrayEnabled() ) {
03381     // Get rid of system tray on user's request
03382     kdDebug(5006) << "deleting systray" << endl;
03383     delete mSystemTray;
03384     mSystemTray = 0;
03385   }
03386 
03387   // Set mode of systemtray. If mode has changed, tray will handle this.
03388   if ( mSystemTray )
03389     mSystemTray->setMode( GlobalSettings::systemTrayPolicy() );
03390 }
03391 
03392 //-----------------------------------------------------------------------------
03393 void KMMainWidget::slotAntiSpamWizard()
03394 {
03395   AntiSpamWizard wiz( AntiSpamWizard::AntiSpam,
03396                       this, folderTree(), actionCollection() );
03397   wiz.exec();
03398 }
03399 
03400 //-----------------------------------------------------------------------------
03401 void KMMainWidget::slotAntiVirusWizard()
03402 {
03403   AntiSpamWizard wiz( AntiSpamWizard::AntiVirus,
03404                       this, folderTree(), actionCollection() );
03405   wiz.exec();
03406 }
03407 
03408 //-----------------------------------------------------------------------------
03409 void KMMainWidget::slotFilterLogViewer()
03410 {
03411   FilterLogDialog * dlg = new FilterLogDialog( 0 );
03412   dlg->show();
03413 }
03414 
03415 //-----------------------------------------------------------------------------
03416 void KMMainWidget::updateFileMenu()
03417 {
03418   QStringList actList = kmkernel->acctMgr()->getAccounts(false);
03419 
03420   actionCollection()->action("check_mail")->setEnabled( actList.size() > 0 );
03421   actionCollection()->action("check_mail_in")->setEnabled( actList.size() > 0 );
03422 }
03423 
03424 
03425 //-----------------------------------------------------------------------------
03426 void KMMainWidget::updateViewMenu()
03427 {
03428   bool previewPaneVisible = ( mMsgView != 0 );
03429   if ( previewPaneVisible ) {
03430     KRadioAction *raction = actionForHeaderStyle( mMsgView->headerStyle(), mMsgView->headerStrategy() );
03431     if ( raction )
03432       raction->setChecked( true );
03433     raction = actionForAttachmentStrategy( mMsgView->attachmentStrategy() );
03434     if ( raction )
03435       raction->setChecked( true );
03436   }
03437   actionCollection()->action("view_headers")->setEnabled( previewPaneVisible );
03438   actionCollection()->action("view_attachments")->setEnabled( previewPaneVisible );
03439 }
03440 
03441 //-----------------------------------------------------------------------------
03442 KMSystemTray *KMMainWidget::systray() const
03443 {
03444   return mSystemTray;
03445 }
KDE Logo
This file is part of the documentation for kmail Library Version 3.3.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Mar 23 22:43:51 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003