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", 2);
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   KMMessage *newMessage = new KMMessage(*msg);
02017   newMessage->setParent( msg->parent() );
02018   newMessage->setMsgSerNum( msg->getMsgSerNum() );
02019   newMessage->setReadyToShow( true );
02020   win->showMsg( mCodec, newMessage );
02021   win->show();
02022 }
02023 
02024 //-----------------------------------------------------------------------------
02025 void KMMainWidget::slotMarkAll()
02026 {
02027   mHeaders->selectAll( TRUE );
02028 }
02029 
02030 //-----------------------------------------------------------------------------
02031 void KMMainWidget::slotMsgPopup(KMMessage&, const KURL &aUrl, const QPoint& aPoint)
02032 {
02033   KPopupMenu * menu = new KPopupMenu;
02034   updateMessageMenu();
02035   mUrlCurrent = aUrl;
02036 
02037   if (!aUrl.isEmpty())
02038   {
02039     if (aUrl.protocol() == "mailto")
02040     {
02041       // popup on a mailto URL
02042       mMsgView->mailToComposeAction()->plug( menu );
02043       mMsgView->mailToReplyAction()->plug( menu );
02044       mMsgView->mailToForwardAction()->plug( menu );
02045       menu->insertSeparator();
02046       mMsgView->addAddrBookAction()->plug( menu );
02047       mMsgView->openAddrBookAction()->plug( menu );
02048       mMsgView->copyAction()->plug( menu );
02049       mMsgView->startImChatAction()->plug( menu );
02050       // only enable if our KIMProxy is functional
02051       mMsgView->startImChatAction()->setEnabled( kmkernel->imProxy()->initialize() );
02052 
02053     } else {
02054       // popup on a not-mailto URL
02055       mMsgView->urlOpenAction()->plug( menu );
02056       mMsgView->urlSaveAsAction()->plug( menu );
02057       mMsgView->copyURLAction()->plug( menu );
02058       mMsgView->addBookmarksAction()->plug( menu );
02059     }
02060     if ( aUrl.protocol() == "im" )
02061     {
02062       // popup on an IM address
02063       // no need to check the KIMProxy is initialized, as these protocols will
02064       // only be present if it is.
02065       mMsgView->startImChatAction()->plug( menu );
02066     }
02067     kdDebug( 0 ) << k_funcinfo << " URL is: " << aUrl << endl;
02068   }
02069   else
02070   {
02071     // popup somewhere else (i.e., not a URL) on the message
02072 
02073     if (!mHeaders->currentMsg()) // no messages
02074     {
02075       delete menu;
02076       return;
02077     }
02078 
02079     bool out_folder = kmkernel->folderIsDraftOrOutbox(mFolder);
02080     if ( out_folder ) {
02081       mEditAction->plug(menu);
02082     }
02083     else {
02084       mReplyAction->plug(menu);
02085       mReplyAllAction->plug(menu);
02086       mReplyAuthorAction->plug( menu );
02087       mReplyListAction->plug( menu );
02088       mForwardActionMenu->plug(menu);
02089       mBounceAction->plug(menu);
02090     }
02091     menu->insertSeparator();
02092     if ( !out_folder ) {
02093       //   mFilterMenu()->plug( menu );
02094       mStatusMenu->plug( menu );
02095       mThreadStatusMenu->plug( menu );
02096     }
02097 
02098     mCopyActionMenu->plug( menu );
02099     mMoveActionMenu->plug( menu );
02100 
02101     menu->insertSeparator();
02102     mWatchThreadAction->plug( menu );
02103     mIgnoreThreadAction->plug( menu );
02104 
02105     menu->insertSeparator();
02106 
02107     // these two only make sense if there is a reader window.
02108     // I guess. Not sure about view source ;). Till
02109     if (mMsgView) {
02110       toggleFixFontAction()->plug(menu);
02111       viewSourceAction()->plug(menu);
02112     }
02113 
02114     menu->insertSeparator();
02115     mPrintAction->plug( menu );
02116     mSaveAsAction->plug( menu );
02117     mSaveAttachmentsAction->plug( menu );
02118     menu->insertSeparator();
02119     mTrashAction->plug( menu );
02120     mDeleteAction->plug( menu );
02121   }
02122   KAcceleratorManager::manage(menu);
02123   menu->exec(aPoint, 0);
02124   delete menu;
02125 }
02126 
02127 //-----------------------------------------------------------------------------
02128 void KMMainWidget::getAccountMenu()
02129 {
02130   QStringList actList;
02131 
02132   mActMenu->clear();
02133   actList = kmkernel->acctMgr()->getAccounts(false);
02134   QStringList::Iterator it;
02135   int id = 0;
02136   for(it = actList.begin(); it != actList.end() ; ++it, id++)
02137     mActMenu->insertItem((*it).replace("&", "&&"), id);
02138 }
02139 
02140 // little helper function
02141 KRadioAction * KMMainWidget::actionForHeaderStyle( const HeaderStyle * style, const HeaderStrategy * strategy ) {
02142   const char * actionName = 0;
02143   if ( style == HeaderStyle::fancy() )
02144     actionName = "view_headers_fancy";
02145   else if ( style == HeaderStyle::brief() )
02146     actionName = "view_headers_brief";
02147   else if ( style == HeaderStyle::plain() ) {
02148     if ( strategy == HeaderStrategy::standard() )
02149       actionName = "view_headers_standard";
02150     else if ( strategy == HeaderStrategy::rich() )
02151       actionName = "view_headers_long";
02152     else if ( strategy == HeaderStrategy::all() )
02153       actionName = "view_headers_all";
02154   }
02155   if ( actionName )
02156     return static_cast<KRadioAction*>(actionCollection()->action(actionName));
02157   else
02158     return 0;
02159 }
02160 
02161 KRadioAction * KMMainWidget::actionForAttachmentStrategy( const AttachmentStrategy * as ) {
02162   const char * actionName = 0;
02163   if ( as == AttachmentStrategy::iconic() )
02164     actionName = "view_attachments_as_icons";
02165   else if ( as == AttachmentStrategy::smart() )
02166     actionName = "view_attachments_smart";
02167   else if ( as == AttachmentStrategy::inlined() )
02168     actionName = "view_attachments_inline";
02169   else if ( as == AttachmentStrategy::hidden() )
02170     actionName = "view_attachments_hide";
02171 
02172   if ( actionName )
02173     return static_cast<KRadioAction*>(actionCollection()->action(actionName));
02174   else
02175     return 0;
02176 }
02177 
02178 
02179 //-----------------------------------------------------------------------------
02180 void KMMainWidget::setupActions()
02181 {
02182   //----- File Menu
02183   (void) new KAction( i18n("New &Window"), "window_new", 0,
02184               this, SLOT(slotNewMailReader()),
02185               actionCollection(), "new_mail_client" );
02186 
02187   mSaveAsAction = new KAction( i18n("Save &As..."), "filesave",
02188     KStdAccel::shortcut(KStdAccel::Save),
02189     this, SLOT(slotSaveMsg()), actionCollection(), "file_save_as" );
02190 
02191   mOpenAction = KStdAction::open( this, SLOT( slotOpenMsg() ),
02192                                   actionCollection() );
02193 
02194   (void) new KAction( i18n("&Compact All Folders"), 0,
02195               this, SLOT(slotCompactAll()),
02196               actionCollection(), "compact_all_folders" );
02197 
02198   (void) new KAction( i18n("&Expire All Folders"), 0,
02199               this, SLOT(slotExpireAll()),
02200               actionCollection(), "expire_all_folders" );
02201 
02202   (void) new KAction( i18n("&Refresh Local IMAP Cache"), "refresh",
02203               this, SLOT(slotInvalidateIMAPFolders()),
02204               actionCollection(), "file_invalidate_imap_cache" );
02205 
02206   (void) new KAction( i18n("Empty All &Trash Folders"), 0,
02207               KMKernel::self(), SLOT(slotEmptyTrash()),
02208               actionCollection(), "empty_trash" );
02209 
02210   (void) new KAction( i18n("Check &Mail"), "mail_get", CTRL+Key_L,
02211               this, SLOT(slotCheckMail()),
02212               actionCollection(), "check_mail" );
02213 
02214   KActionMenu *actActionMenu = new
02215     KActionMenu( i18n("Check Mail &In"), "mail_get", actionCollection(),
02216                     "check_mail_in" );
02217   actActionMenu->setDelayed(true); //needed for checking "all accounts"
02218 
02219   connect(actActionMenu,SIGNAL(activated()),this,SLOT(slotCheckMail()));
02220 
02221   mActMenu = actActionMenu->popupMenu();
02222   connect(mActMenu,SIGNAL(activated(int)),this,SLOT(slotCheckOneAccount(int)));
02223   connect(mActMenu,SIGNAL(aboutToShow()),this,SLOT(getAccountMenu()));
02224 
02225   (void) new KAction( i18n("&Send Queued Messages"), "mail_send", 0, this,
02226              SLOT(slotSendQueued()), actionCollection(), "send_queued");
02227   KAction *act;
02228   //----- Tools menu
02229   if (parent()->inherits("KMMainWin")) {
02230     act =  new KAction( i18n("&Address Book..."), "contents", 0, this,
02231             SLOT(slotAddrBook()), actionCollection(), "addressbook" );
02232     if (KStandardDirs::findExe("kaddressbook").isEmpty()) act->setEnabled(false);
02233   }
02234 
02235   act = new KAction( i18n("Certificate Manager..."), "pgp-keys", 0, this,
02236              SLOT(slotStartCertManager()), actionCollection(), "tools_start_certman");
02237   // disable action if no certman binary is around
02238   if (KStandardDirs::findExe("kleopatra").isEmpty()) act->setEnabled(false);
02239 
02240   act = new KAction( i18n("GnuPG Log Viewer..."), "pgp-keys", 0, this,
02241              SLOT(slotStartWatchGnuPG()), actionCollection(), "tools_start_kwatchgnupg");
02242   // disable action if no kwatchgnupg binary is around
02243   if (KStandardDirs::findExe("kwatchgnupg").isEmpty()) act->setEnabled(false);
02244 
02245   act = new KAction( i18n("&Import Messages..."), "fileopen", 0, this,
02246              SLOT(slotImport()), actionCollection(), "import" );
02247   if (KStandardDirs::findExe("kmailcvt").isEmpty()) act->setEnabled(false);
02248 
02249   // @TODO (marc/bo): Test
02250   (void) new KAction( i18n("Edit \"Out of Office\" Replies..."),
02251               "configure", 0, this, SLOT(slotEditVacation()),
02252               actionCollection(), "tools_edit_vacation" );
02253 
02254   (void) new KAction( i18n("Filter &Log Viewer..."), 0, this,
02255               SLOT(slotFilterLogViewer()), actionCollection(), "filter_log_viewer" );
02256 
02257   (void) new KAction( i18n("&Anti-Spam Wizard..."), 0, this,
02258               SLOT(slotAntiSpamWizard()), actionCollection(), "antiSpamWizard" );
02259   (void) new KAction( i18n("&Anti-Virus Wizard..."), 0, this,
02260               SLOT(slotAntiVirusWizard()), actionCollection(), "antiVirusWizard" );
02261 
02262   //----- Edit Menu
02263   mTrashAction = new KAction( KGuiItem( i18n("&Move to Trash"), "edittrash",
02264                                        i18n("Move message to trashcan") ),
02265                              Key_Delete, this, SLOT(slotTrashMsg()),
02266                              actionCollection(), "move_to_trash" );
02267 
02268   mDeleteAction = new KAction( i18n("&Delete"), "editdelete", SHIFT+Key_Delete, this,
02269                               SLOT(slotDeleteMsg()), actionCollection(), "delete" );
02270 
02271   (void) new KAction( i18n("&Find Messages..."), "mail_find", Key_S, this,
02272               SLOT(slotSearch()), actionCollection(), "search_messages" );
02273 
02274   mFindInMessageAction = new KAction( i18n("&Find in Message..."), "find", KStdAccel::shortcut(KStdAccel::Find), this,
02275               SLOT(slotFind()), actionCollection(), "find_in_messages" );
02276 
02277   (void) new KAction( i18n("Select &All Messages"), KStdAccel::selectAll(), this,
02278               SLOT(slotMarkAll()), actionCollection(), "mark_all_messages" );
02279 
02280   (void) new KAction( i18n("Select Message &Text"),
02281               CTRL+SHIFT+Key_A, mMsgView,
02282               SLOT(selectAll()), actionCollection(), "mark_all_text" );
02283 
02284   //----- Folder Menu
02285   (void) new KAction( i18n("&New Folder..."), "folder_new", 0, this,
02286               SLOT(slotAddFolder()), actionCollection(), "new_folder" );
02287 
02288   mModifyFolderAction = new KAction( i18n("&Properties"), "configure", 0, this,
02289               SLOT(slotModifyFolder()), actionCollection(), "modify" );
02290 
02291   mMarkAllAsReadAction = new KAction( i18n("Mark All Messages as &Read"), "goto", 0, this,
02292               SLOT(slotMarkAllAsRead()), actionCollection(), "mark_all_as_read" );
02293 
02294   mExpireFolderAction = new KAction(i18n("&Expire"), 0, this, SLOT(slotExpireFolder()),
02295                    actionCollection(), "expire");
02296 
02297   mCompactFolderAction = new KAction( i18n("&Compact"), 0, this,
02298               SLOT(slotCompactFolder()), actionCollection(), "compact" );
02299 
02300   mRefreshFolderAction = new KAction( i18n("Check Mail &in This Folder"), "reload", Key_F5 , this,
02301                      SLOT(slotRefreshFolder()), actionCollection(), "refresh_folder" );
02302 
02303   mEmptyFolderAction = new KAction( i18n("&Move All Messages to Trash"),
02304                                    "edittrash", 0, this,
02305               SLOT(slotEmptyFolder()), actionCollection(), "empty" );
02306 
02307   mRemoveFolderAction = new KAction( i18n("&Delete Folder"), "editdelete", 0, this,
02308               SLOT(slotRemoveFolder()), actionCollection(), "delete_folder" );
02309 
02310   mPreferHtmlAction = new KToggleAction( i18n("Prefer &HTML to Plain Text"), 0, this,
02311               SLOT(slotOverrideHtml()), actionCollection(), "prefer_html" );
02312 
02313   mThreadMessagesAction = new KToggleAction( i18n("&Thread Messages"), 0, this,
02314               SLOT(slotOverrideThread()), actionCollection(), "thread_messages" );
02315 
02316   mThreadBySubjectAction = new KToggleAction( i18n("Thread Messages also by &Subject"), 0, this,
02317               SLOT(slotToggleSubjectThreading()), actionCollection(), "thread_messages_by_subject" );
02318 
02319 
02320   //----- Message Menu
02321   (void) new KAction( i18n("&New Message..."), "mail_new", KStdAccel::shortcut(KStdAccel::New), this,
02322               SLOT(slotCompose()), actionCollection(), "new_message" );
02323 
02324   (void) new KAction( i18n("New Message t&o Mailing-List..."), "mail_post_to", 0, this,
02325               SLOT(slotPostToML()), actionCollection(), "post_message" );
02326 
02327   mForwardActionMenu = new KActionMenu( i18n("Message->","&Forward"),
02328                     "mail_forward", actionCollection(),
02329                     "message_forward" );
02330   connect( mForwardActionMenu, SIGNAL(activated()), this,
02331        SLOT(slotForwardMsg()) );
02332 
02333   mForwardAttachedAction = new KAction( i18n("Message->Forward->","As &Attachment..."),
02334                        "mail_forward", Key_F, this,
02335                     SLOT(slotForwardAttachedMsg()), actionCollection(),
02336                     "message_forward_as_attachment" );
02337   mForwardActionMenu->insert( forwardAttachedAction() );
02338   mForwardAction = new KAction( i18n("&Inline..."), "mail_forward",
02339                 SHIFT+Key_F, this, SLOT(slotForwardMsg()),
02340                 actionCollection(), "message_forward_inline" );
02341 
02342   mForwardActionMenu->insert( forwardAction() );
02343 
02344   mSendAgainAction = new KAction( i18n("Send A&gain..."), 0, this,
02345               SLOT(slotResendMsg()), actionCollection(), "send_again" );
02346 
02347   mReplyActionMenu = new KActionMenu( i18n("Message->","&Reply"),
02348                                       "mail_reply", actionCollection(),
02349                                       "message_reply_menu" );
02350   connect( mReplyActionMenu, SIGNAL(activated()), this,
02351        SLOT(slotReplyToMsg()) );
02352 
02353   mReplyAction = new KAction( i18n("&Reply..."), "mail_reply", Key_R, this,
02354                   SLOT(slotReplyToMsg()), actionCollection(), "reply" );
02355   mReplyActionMenu->insert( mReplyAction );
02356 
02357   mReplyAuthorAction = new KAction( i18n("Reply to A&uthor..."), "mail_reply",
02358                                     SHIFT+Key_A, this,
02359                                     SLOT(slotReplyAuthorToMsg()),
02360                                     actionCollection(), "reply_author" );
02361   mReplyActionMenu->insert( mReplyAuthorAction );
02362 
02363   mReplyAllAction = new KAction( i18n("Reply to &All..."), "mail_replyall",
02364                  Key_A, this, SLOT(slotReplyAllToMsg()),
02365                  actionCollection(), "reply_all" );
02366   mReplyActionMenu->insert( mReplyAllAction );
02367 
02368   mReplyListAction = new KAction( i18n("Reply to Mailing-&List..."),
02369                   "mail_replylist", Key_L, this,
02370                   SLOT(slotReplyListToMsg()), actionCollection(),
02371                   "reply_list" );
02372   mReplyActionMenu->insert( mReplyListAction );
02373 
02374   mRedirectAction = new KAction( i18n("Message->Forward->","&Redirect..."),
02375                  Key_E, this, SLOT(slotRedirectMsg()),
02376                  actionCollection(), "message_forward_redirect" );
02377   mForwardActionMenu->insert( redirectAction() );
02378 
02379   mNoQuoteReplyAction = new KAction( i18n("Reply Without &Quote..."), SHIFT+Key_R,
02380     this, SLOT(slotNoQuoteReplyToMsg()), actionCollection(), "noquotereply" );
02381 
02382   //---- Bounce action
02383   mBounceAction = new KAction( i18n("&Bounce..."), 0, this,
02384                   SLOT(slotBounceMsg()), actionCollection(), "bounce" );
02385 
02386   //----- Create filter actions
02387   mFilterMenu = new KActionMenu( i18n("&Create Filter"), "filter", actionCollection(), "create_filter" );
02388   connect( mFilterMenu, SIGNAL(activated()), this,
02389        SLOT(slotFilter()) );
02390   mSubjectFilterAction = new KAction( i18n("Filter on &Subject..."), 0, this,
02391                       SLOT(slotSubjectFilter()),
02392                       actionCollection(), "subject_filter");
02393   mFilterMenu->insert( mSubjectFilterAction );
02394 
02395   mFromFilterAction = new KAction( i18n("Filter on &From..."), 0, this,
02396                    SLOT(slotFromFilter()),
02397                    actionCollection(), "from_filter");
02398   mFilterMenu->insert( mFromFilterAction );
02399 
02400   mToFilterAction = new KAction( i18n("Filter on &To..."), 0, this,
02401                  SLOT(slotToFilter()),
02402                  actionCollection(), "to_filter");
02403   mFilterMenu->insert( mToFilterAction );
02404 
02405   mListFilterAction = new KAction( i18n("Filter on Mailing-&List..."), 0, this,
02406                                    SLOT(slotMailingListFilter()), actionCollection(),
02407                                    "mlist_filter");
02408   mFilterMenu->insert( mListFilterAction );
02409 
02410   mPrintAction = KStdAction::print (this, SLOT(slotPrintMsg()), actionCollection());
02411 
02412   //----- Message-Encoding Submenu
02413   mEncoding = new KSelectAction( i18n( "&Set Encoding" ), "charset", 0, this,
02414               SLOT( slotSetEncoding() ), actionCollection(), "encoding" );
02415   QStringList encodings = KMMsgBase::supportedEncodings(FALSE);
02416   encodings.prepend( i18n( "Auto" ) );
02417   mEncoding->setItems( encodings );
02418   mEncoding->setCurrentItem(0);
02419 
02420   QStringList::Iterator it;
02421   int i = 0;
02422   for( it = encodings.begin(); it != encodings.end(); ++it)
02423   {
02424     if ( KGlobal::charsets()->encodingForName(*it ) == QString(mEncodingStr) )
02425     {
02426       mEncoding->setCurrentItem( i );
02427       break;
02428     }
02429     i++;
02430   }
02431 
02432   mEditAction = new KAction( i18n("&Edit Message"), "edit", Key_T, this,
02433                             SLOT(slotEditMsg()), actionCollection(), "edit" );
02434 
02435   //----- "Mark Message" submenu
02436   mStatusMenu = new KActionMenu ( i18n( "Mar&k Message" ),
02437                                  actionCollection(), "set_status" );
02438 
02439   mStatusMenu->insert(new KAction(KGuiItem(i18n("Mark Message as &Read"), "kmmsgread",
02440                                           i18n("Mark selected messages as read")),
02441                                  0, this, SLOT(slotSetMsgStatusRead()),
02442                                  actionCollection(), "status_read"));
02443 
02444   mStatusMenu->insert(new KAction(KGuiItem(i18n("Mark Message as &New"), "kmmsgnew",
02445                                           i18n("Mark selected messages as new")),
02446                                  0, this, SLOT(slotSetMsgStatusNew()),
02447                                  actionCollection(), "status_new" ));
02448 
02449   mStatusMenu->insert(new KAction(KGuiItem(i18n("Mark Message as &Unread"), "kmmsgunseen",
02450                                           i18n("Mark selected messages as unread")),
02451                                  0, this, SLOT(slotSetMsgStatusUnread()),
02452                                  actionCollection(), "status_unread"));
02453 
02454   mStatusMenu->insert( new KActionSeparator( this ) );
02455 
02456   // -------- Toggle Actions
02457   mToggleFlagAction = new KToggleAction(i18n("Mark Message as &Important"), "kmmsgflag",
02458                                  0, this, SLOT(slotSetMsgStatusFlag()),
02459                                  actionCollection(), "status_flag");
02460   mStatusMenu->insert( mToggleFlagAction );
02461 
02462   mToggleRepliedAction = new KToggleAction(i18n("Mark Message as Re&plied"), "kmmsgreplied",
02463                                  0, this, SLOT(slotSetMsgStatusReplied()),
02464                                  actionCollection(), "status_replied");
02465 
02466   mStatusMenu->insert( mToggleRepliedAction );
02467   mToggleForwardedAction = new KToggleAction(i18n("Mark Message as &Forwarded"), "kmmsgforwarded",
02468                                  0, this, SLOT(slotSetMsgStatusForwarded()),
02469                                  actionCollection(), "status_forwarded");
02470   mStatusMenu->insert( mToggleForwardedAction );
02471 
02472   mToggleQueuedAction = new KToggleAction(i18n("Mark Message as &Queued"), "kmmsgqueued",
02473                                  0, this, SLOT(slotSetMsgStatusQueued()),
02474                                  actionCollection(), "status_queued");
02475   mStatusMenu->insert( mToggleQueuedAction );
02476 
02477   mToggleSentAction = new KToggleAction(i18n("Mark Message as &Sent"), "kmmsgsent",
02478                                  0, this, SLOT(slotSetMsgStatusSent()),
02479                                  actionCollection(), "status_sent");
02480   mStatusMenu->insert( mToggleSentAction );
02481 
02482 #if KDE_IS_VERSION(3,2,90)
02483   mToggleFlagAction->setCheckedState( i18n("Remove &Important Message Mark") );
02484   mToggleRepliedAction->setCheckedState( i18n("Mark Message as Not Re&plied") );
02485   mToggleForwardedAction->setCheckedState( i18n("Mark Message as Not &Forwarded") );
02486   mToggleQueuedAction->setCheckedState( i18n("Mark Message as Not &Queued") );
02487   mToggleSentAction->setCheckedState( i18n("Mark Message as Not &Sent") );
02488 #endif
02489 
02490   mStatusMenu->insert( new KActionSeparator( this ) );
02491 
02492   mMarkAsSpamAction = new KAction(i18n("Mark Message as Spa&m"), "mark_as_spam",
02493                                  0, this, SLOT(slotSetMsgStatusSpam()),
02494                                  actionCollection(), "status_spam");
02495   mStatusMenu->insert( mMarkAsSpamAction );
02496 
02497   mMarkAsHamAction = new KAction(i18n("Mark Message as &Ham"), "mark_as_ham",
02498                                  0, this, SLOT(slotSetMsgStatusHam()),
02499                                  actionCollection(), "status_ham");
02500   mStatusMenu->insert( mMarkAsHamAction );
02501 
02502   //----- "Mark Thread" submenu
02503   mThreadStatusMenu = new KActionMenu ( i18n( "Mark &Thread" ),
02504                                        actionCollection(), "thread_status" );
02505 
02506   mMarkThreadAsReadAction = new KAction(KGuiItem(i18n("Mark Thread as &Read"), "kmmsgread",
02507                                                 i18n("Mark all messages in the selected thread as read")),
02508                                                 0, this, SLOT(slotSetThreadStatusRead()),
02509                                                 actionCollection(), "thread_read");
02510   mThreadStatusMenu->insert( mMarkThreadAsReadAction );
02511 
02512   mMarkThreadAsNewAction = new KAction(KGuiItem(i18n("Mark Thread as &New"), "kmmsgnew",
02513                                                i18n("Mark all messages in the selected thread as new")),
02514                                                0, this, SLOT(slotSetThreadStatusNew()),
02515                                                actionCollection(), "thread_new");
02516   mThreadStatusMenu->insert( mMarkThreadAsNewAction );
02517 
02518   mMarkThreadAsUnreadAction = new KAction(KGuiItem(i18n("Mark Thread as &Unread"), "kmmsgunseen",
02519                                                 i18n("Mark all messages in the selected thread as unread")),
02520                                                 0, this, SLOT(slotSetThreadStatusUnread()),
02521                                                 actionCollection(), "thread_unread");
02522   mThreadStatusMenu->insert( mMarkThreadAsUnreadAction );
02523 
02524   mThreadStatusMenu->insert( new KActionSeparator( this ) );
02525 
02526   //----- "Mark Thread" toggle actions
02527   mToggleThreadFlagAction = new KToggleAction(i18n("Mark Thread as &Important"), "kmmsgflag",
02528                                        0, this, SLOT(slotSetThreadStatusFlag()),
02529                                        actionCollection(), "thread_flag");
02530   mThreadStatusMenu->insert( mToggleThreadFlagAction );
02531 
02532   mToggleThreadRepliedAction = new KToggleAction(i18n("Mark Thread as R&eplied"), "kmmsgreplied",
02533                                        0, this, SLOT(slotSetThreadStatusReplied()),
02534                                        actionCollection(), "thread_replied");
02535   mThreadStatusMenu->insert( mToggleThreadRepliedAction );
02536 
02537   mToggleThreadForwardedAction = new KToggleAction(i18n("Mark Thread as &Forwarded"), "kmmsgforwarded",
02538                                        0, this, SLOT(slotSetThreadStatusForwarded()),
02539                                        actionCollection(), "thread_forwarded");
02540   mThreadStatusMenu->insert( mToggleThreadForwardedAction );
02541 
02542   mToggleThreadQueuedAction = new KToggleAction(i18n("Mark Thread as &Queued"), "kmmsgqueued",
02543                                        0, this, SLOT(slotSetThreadStatusQueued()),
02544                                        actionCollection(), "thread_queued");
02545   mThreadStatusMenu->insert( mToggleThreadQueuedAction );
02546 
02547   mToggleThreadSentAction = new KToggleAction(i18n("Mark Thread as &Sent"), "kmmsgsent",
02548                                        0, this, SLOT(slotSetThreadStatusSent()),
02549                                        actionCollection(), "thread_sent");
02550   mThreadStatusMenu->insert( mToggleThreadSentAction );
02551 
02552   mThreadStatusMenu->insert( new KActionSeparator( this ) );
02553 
02554 #if KDE_IS_VERSION(3,2,90)
02555   mToggleThreadFlagAction->setCheckedState( i18n("Remove &Important Thread Mark") );
02556   mToggleThreadRepliedAction->setCheckedState( i18n("Mark Thread as Not R&eplied") );
02557   mToggleThreadForwardedAction->setCheckedState( i18n("Mark Thread as Not &Forwarded") );
02558   mToggleThreadQueuedAction->setCheckedState( i18n("Mark Thread as Not &Queued") );
02559   mToggleThreadSentAction->setCheckedState( i18n("Mark Thread as Not &Sent") );
02560 #endif
02561 
02562   //------- "Watch and ignore thread" actions
02563   mWatchThreadAction = new KToggleAction(i18n("&Watch Thread"), "kmmsgwatched",
02564                                        0, this, SLOT(slotSetThreadStatusWatched()),
02565                                        actionCollection(), "thread_watched");
02566 
02567   mIgnoreThreadAction = new KToggleAction(i18n("&Ignore Thread"), "kmmsgignored",
02568                                        0, this, SLOT(slotSetThreadStatusIgnored()),
02569                                        actionCollection(), "thread_ignored");
02570 
02571   //------- "Ham and spam thread" actions
02572   mMarkThreadAsSpamAction = new KAction(i18n("Mark Thread as S&pam"), "mark_as_spam",
02573                                        0, this, SLOT(slotSetThreadStatusSpam()),
02574                                        actionCollection(), "thread_spam");
02575   mThreadStatusMenu->insert( mMarkThreadAsSpamAction );
02576 
02577   mMarkThreadAsHamAction = new KAction(i18n("Mark Thread as &Ham"), "mark_as_ham",
02578                                        0, this, SLOT(slotSetThreadStatusHam()),
02579                                        actionCollection(), "thread_ham");
02580   mThreadStatusMenu->insert( mMarkThreadAsHamAction );
02581 
02582 
02583   mSaveAttachmentsAction = new KAction( i18n("Save A&ttachments..."), "attach",
02584                                 0, this, SLOT(slotSaveAttachments()),
02585                                 actionCollection(), "file_save_attachments" );
02586 
02587   mMoveActionMenu = new KActionMenu( i18n("&Move To" ),
02588                                     actionCollection(), "move_to" );
02589 
02590   mCopyActionMenu = new KActionMenu( i18n("&Copy To" ),
02591                                     actionCollection(), "copy_to" );
02592 
02593   mApplyFiltersAction = new KAction( i18n("Appl&y Filters"), "filter",
02594                     CTRL+Key_J, this,
02595                     SLOT(slotApplyFilters()),
02596                     actionCollection(), "apply_filters" );
02597 
02598   mApplyFilterActionsMenu = new KActionMenu( i18n("A&pply Filter" ),
02599                         actionCollection(),
02600                         "apply_filter_actions" );
02601 
02602   //----- View Menu
02603   KRadioAction * raction = 0;
02604 
02605   // "Headers" submenu:
02606   KActionMenu * headerMenu =
02607     new KActionMenu( i18n("View->", "&Headers"),
02608                     actionCollection(), "view_headers" );
02609   headerMenu->setToolTip( i18n("Choose display style of message headers") );
02610 
02611   connect( headerMenu, SIGNAL(activated()), SLOT(slotCycleHeaderStyles()) );
02612 
02613   raction = new KRadioAction( i18n("View->headers->", "&Fancy Headers"), 0, this,
02614       SLOT(slotFancyHeaders()),
02615       actionCollection(), "view_headers_fancy" );
02616   raction->setToolTip( i18n("Show the list of headers in a fancy format") );
02617   raction->setExclusiveGroup( "view_headers_group" );
02618   headerMenu->insert( raction );
02619 
02620   raction = new KRadioAction( i18n("View->headers->", "&Brief Headers"), 0, this,
02621       SLOT(slotBriefHeaders()),
02622       actionCollection(), "view_headers_brief" );
02623   raction->setToolTip( i18n("Show brief list of message headers") );
02624   raction->setExclusiveGroup( "view_headers_group" );
02625   headerMenu->insert( raction );
02626 
02627   raction = new KRadioAction( i18n("View->headers->", "&Standard Headers"), 0, this,
02628       SLOT(slotStandardHeaders()),
02629       actionCollection(), "view_headers_standard" );
02630   raction->setToolTip( i18n("Show standard list of message headers") );
02631   raction->setExclusiveGroup( "view_headers_group" );
02632   headerMenu->insert( raction );
02633 
02634   raction = new KRadioAction( i18n("View->headers->", "&Long Headers"), 0, this,
02635       SLOT(slotLongHeaders()),
02636       actionCollection(), "view_headers_long" );
02637   raction->setToolTip( i18n("Show long list of message headers") );
02638   raction->setExclusiveGroup( "view_headers_group" );
02639   headerMenu->insert( raction );
02640 
02641   raction = new KRadioAction( i18n("View->headers->", "&All Headers"), 0, this,
02642       SLOT(slotAllHeaders()),
02643       actionCollection(), "view_headers_all" );
02644   raction->setToolTip( i18n("Show all message headers") );
02645   raction->setExclusiveGroup( "view_headers_group" );
02646   headerMenu->insert( raction );
02647 
02648 
02649 
02650   // "Attachments" submenu:
02651   KActionMenu * attachmentMenu =
02652     new KActionMenu( i18n("View->", "&Attachments"),
02653         actionCollection(), "view_attachments" );
02654   connect( attachmentMenu, SIGNAL(activated()),
02655       SLOT(slotCycleAttachmentStrategy()) );
02656 
02657   attachmentMenu->setToolTip( i18n("Choose display style of attachments") );
02658 
02659   raction = new KRadioAction( i18n("View->attachments->", "&As Icons"), 0, this,
02660       SLOT(slotIconicAttachments()),
02661       actionCollection(), "view_attachments_as_icons" );
02662   raction->setToolTip( i18n("Show all attachments as icons. Click to see them.") );
02663   raction->setExclusiveGroup( "view_attachments_group" );
02664   attachmentMenu->insert( raction );
02665 
02666   raction = new KRadioAction( i18n("View->attachments->", "&Smart"), 0, this,
02667       SLOT(slotSmartAttachments()),
02668       actionCollection(), "view_attachments_smart" );
02669   raction->setToolTip( i18n("Show attachments as suggested by sender.") );
02670   raction->setExclusiveGroup( "view_attachments_group" );
02671   attachmentMenu->insert( raction );
02672 
02673   raction = new KRadioAction( i18n("View->attachments->", "&Inline"), 0, this,
02674       SLOT(slotInlineAttachments()),
02675       actionCollection(), "view_attachments_inline" );
02676   raction->setToolTip( i18n("Show all attachments inline (if possible)") );
02677   raction->setExclusiveGroup( "view_attachments_group" );
02678   attachmentMenu->insert( raction );
02679 
02680   raction = new KRadioAction( i18n("View->attachments->", "&Hide"), 0, this,
02681       SLOT(slotHideAttachments()),
02682       actionCollection(), "view_attachments_hide" );
02683   raction->setToolTip( i18n("Do not show attachments in the message viewer") );
02684   raction->setExclusiveGroup( "view_attachments_group" );
02685   attachmentMenu->insert( raction );
02686 
02687   // Unread Submenu
02688   KActionMenu * unreadMenu =
02689     new KActionMenu( i18n("View->", "&Unread Count"),
02690              actionCollection(), "view_unread" );
02691   unreadMenu->setToolTip( i18n("Choose how to display the count of unread messages") );
02692 
02693   mUnreadColumnToggle = new KRadioAction( i18n("View->Unread Count", "View in &Separate Column"), 0, this,
02694                    SLOT(slotToggleUnread()),
02695                    actionCollection(), "view_unread_column" );
02696   mUnreadColumnToggle->setExclusiveGroup( "view_unread_group" );
02697   unreadMenu->insert( mUnreadColumnToggle );
02698 
02699   mUnreadTextToggle = new KRadioAction( i18n("View->Unread Count", "View After &Folder Name"), 0, this,
02700                    SLOT(slotToggleUnread()),
02701                    actionCollection(), "view_unread_text" );
02702   mUnreadTextToggle->setExclusiveGroup( "view_unread_group" );
02703   unreadMenu->insert( mUnreadTextToggle );
02704 
02705   // toggle for total column
02706   mTotalColumnToggle = new KToggleAction( i18n("View->", "&Total Column"), 0, this,
02707                    SLOT(slotToggleTotalColumn()),
02708                    actionCollection(), "view_columns_total" );
02709   mTotalColumnToggle->setToolTip( i18n("Toggle display of column showing the "
02710                                       "total number of messages in folders.") );
02711 
02712   (void)new KAction( KGuiItem( i18n("View->","&Expand Thread"), QString::null,
02713                    i18n("Expand the current thread") ),
02714              Key_Period, this,
02715              SLOT(slotExpandThread()),
02716              actionCollection(), "expand_thread" );
02717 
02718   (void)new KAction( KGuiItem( i18n("View->","&Collapse Thread"), QString::null,
02719                    i18n("Collapse the current thread") ),
02720              Key_Comma, this,
02721              SLOT(slotCollapseThread()),
02722              actionCollection(), "collapse_thread" );
02723 
02724   (void)new KAction( KGuiItem( i18n("View->","Ex&pand All Threads"), QString::null,
02725                    i18n("Expand all threads in the current folder") ),
02726              CTRL+Key_Period, this,
02727              SLOT(slotExpandAllThreads()),
02728              actionCollection(), "expand_all_threads" );
02729 
02730   (void)new KAction( KGuiItem( i18n("View->","C&ollapse All Threads"), QString::null,
02731                    i18n("Collapse all threads in the current folder") ),
02732              CTRL+Key_Comma, this,
02733              SLOT(slotCollapseAllThreads()),
02734              actionCollection(), "collapse_all_threads" );
02735 
02736 
02737   //----- Go Menu
02738   new KAction( KGuiItem( i18n("&Next Message"), QString::null,
02739                          i18n("Go to the next message") ),
02740                          "N;Right", this, SLOT(slotNextMessage()),
02741                          actionCollection(), "go_next_message" );
02742 
02743   new KAction( KGuiItem( i18n("Next &Unread Message"),
02744                          QApplication::reverseLayout() ? "previous" : "next",
02745                          i18n("Go to the next unread message") ),
02746                          Key_Plus, this, SLOT(slotNextUnreadMessage()),
02747                          actionCollection(), "go_next_unread_message" );
02748 
02749   /* ### needs better support from folders:
02750   new KAction( KGuiItem( i18n("Next &Important Message"), QString::null,
02751                          i18n("Go to the next important message") ),
02752                          0, this, SLOT(slotNextImportantMessage()),
02753                          actionCollection(), "go_next_important_message" );
02754   */
02755 
02756   new KAction( KGuiItem( i18n("&Previous Message"), QString::null,
02757                          i18n("Go to the previous message") ),
02758                          "P;Left", this, SLOT(slotPrevMessage()),
02759                          actionCollection(), "go_prev_message" );
02760 
02761   new KAction( KGuiItem( i18n("Previous Unread &Message"),
02762                          QApplication::reverseLayout() ? "next" : "previous",
02763                          i18n("Go to the previous unread message") ),
02764                          Key_Minus, this, SLOT(slotPrevUnreadMessage()),
02765                          actionCollection(), "go_prev_unread_message" );
02766 
02767   /* needs better support from folders:
02768   new KAction( KGuiItem( i18n("Previous I&mportant Message"), QString::null,
02769                          i18n("Go to the previous important message") ),
02770                          0, this, SLOT(slotPrevImportantMessage()),
02771                          actionCollection(), "go_prev_important_message" );
02772   */
02773 
02774   new KAction( KGuiItem( i18n("Next Unread &Folder"), QString::null,
02775                          i18n("Go to the next folder with unread messages") ),
02776                          CTRL+Key_Plus, this, SLOT(slotNextUnreadFolder()),
02777                          actionCollection(), "go_next_unread_folder" );
02778 
02779   new KAction( KGuiItem( i18n("Previous Unread F&older"), QString::null,
02780                          i18n("Go to the previous folder with unread messages") ),
02781                          CTRL+Key_Minus, this, SLOT(slotPrevUnreadFolder()),
02782                          actionCollection(), "go_prev_unread_folder" );
02783 
02784   new KAction( KGuiItem( i18n("Go->","Next Unread &Text"), QString::null,
02785                          i18n("Go to the next unread text"),
02786                          i18n("Scroll down current message. "
02787                               "If at end of current message, "
02788                               "go to next unread message.") ),
02789                          Key_Space, this, SLOT(slotReadOn()),
02790                          actionCollection(), "go_next_unread_text" );
02791 
02792   //----- Settings Menu
02793   mToggleShowQuickSearchAction = new KToggleAction(i18n("Show Quick Search"), QString::null,
02794                                        0, this, SLOT(slotToggleShowQuickSearch()),
02795                                        actionCollection(), "show_quick_search");
02796   mToggleShowQuickSearchAction->setChecked( GlobalSettings::quickSearchActive() );
02797   mToggleShowQuickSearchAction->setWhatsThis(
02798         i18n( GlobalSettings::self()->quickSearchActiveItem()->whatsThis().utf8() ) );
02799 
02800   (void) new KAction( i18n("Configure &Filters..."), 0, this,
02801               SLOT(slotFilter()), actionCollection(), "filter" );
02802   (void) new KAction( i18n("Configure &POP Filters..."), 0, this,
02803               SLOT(slotPopFilter()), actionCollection(), "popFilter" );
02804 
02805   (void) new KAction( KGuiItem( i18n("KMail &Introduction"), 0,
02806                 i18n("Display KMail's Welcome Page") ),
02807               0, this, SLOT(slotIntro()),
02808               actionCollection(), "help_kmail_welcomepage" );
02809 
02810   // ----- Standard Actions
02811 //  KStdAction::configureNotifications(this, SLOT(slotEditNotifications()), actionCollection());
02812   (void) new KAction( i18n("Configure &Notifications..."),
02813               "knotify", 0, this,
02814               SLOT(slotEditNotifications()), actionCollection(),
02815               "kmail_configure_notifications" );
02816 //  KStdAction::preferences(this, SLOT(slotSettings()), actionCollection());
02817   (void) new KAction( i18n("&Configure KMail..."),
02818               "configure", 0, kmkernel,
02819                       SLOT(slotShowConfigurationDialog()), actionCollection(),
02820                       "kmail_configure_kmail" );
02821 
02822   KStdAction::undo(this, SLOT(slotUndo()), actionCollection(), "kmail_undo");
02823 //  (void) new KAction( i18n("&Undo"), 0, this,
02824 //            SLOT(slotUndo()), actionCollection(),
02825 //            "kmail_undo" );
02826 
02827   KStdAction::copy( messageView(), SLOT(slotCopySelectedText()), actionCollection(), "kmail_copy");
02828 //  (void) new KAction( i18n("&Copy"), CTRL+Key_C, mMsgView,
02829 //            SLOT(slotCopySelectedText()), actionCollection(),
02830 //            "kmail_copy" );
02831 
02832   KStdAction::tipOfDay( this, SLOT( slotShowTip() ), actionCollection() );
02833 
02834   menutimer = new QTimer( this, "menutimer" );
02835   connect( menutimer, SIGNAL( timeout() ), SLOT( updateMessageActions() ) );
02836   connect( kmkernel->undoStack(),
02837            SIGNAL( undoStackChanged() ), this, SLOT( slotUpdateUndo() ));
02838 
02839   initializeFilterActions();
02840   updateMessageActions();
02841 }
02842 
02843 //-----------------------------------------------------------------------------
02844 void KMMainWidget::slotEditNotifications()
02845 {
02846   if(kmkernel->xmlGuiInstance())
02847     KNotifyDialog::configure(this, 0, kmkernel->xmlGuiInstance()->aboutData());
02848   else
02849     KNotifyDialog::configure(this);
02850 }
02851 
02852 void KMMainWidget::slotEditKeys()
02853 {
02854   KKeyDialog::configure( actionCollection(),
02855              true /*allow one-letter shortcuts*/
02856              );
02857 }
02858 
02859 //-----------------------------------------------------------------------------
02860 void KMMainWidget::slotReadOn()
02861 {
02862     if ( !mMsgView )
02863         return;
02864 
02865     if ( !mMsgView->atBottom() ) {
02866         mMsgView->slotJumpDown();
02867         return;
02868     }
02869     slotNextUnreadMessage();
02870 }
02871 
02872 void KMMainWidget::slotNextUnreadFolder() {
02873   if ( !mFolderTree ) return;
02874   mFolderTree->nextUnreadFolder();
02875 }
02876 
02877 void KMMainWidget::slotPrevUnreadFolder() {
02878   if ( !mFolderTree ) return;
02879   mFolderTree->prevUnreadFolder();
02880 }
02881 
02882 void KMMainWidget::slotExpandThread()
02883 {
02884   mHeaders->slotExpandOrCollapseThread( true ); // expand
02885 }
02886 
02887 void KMMainWidget::slotCollapseThread()
02888 {
02889   mHeaders->slotExpandOrCollapseThread( false ); // collapse
02890 }
02891 
02892 void KMMainWidget::slotExpandAllThreads()
02893 {
02894   mHeaders->slotExpandOrCollapseAllThreads( true ); // expand
02895 }
02896 
02897 void KMMainWidget::slotCollapseAllThreads()
02898 {
02899   mHeaders->slotExpandOrCollapseAllThreads( false ); // collapse
02900 }
02901 
02902 
02903 //-----------------------------------------------------------------------------
02904 void KMMainWidget::moveSelectedToFolder( int menuId )
02905 {
02906   if (mMenuToFolder[menuId])
02907     mHeaders->moveMsgToFolder( mMenuToFolder[menuId] );
02908 }
02909 
02910 
02911 //-----------------------------------------------------------------------------
02912 void KMMainWidget::copySelectedToFolder(int menuId )
02913 {
02914   if (mMenuToFolder[menuId])
02915     mHeaders->copyMsgToFolder( mMenuToFolder[menuId] );
02916 }
02917 
02918 
02919 //-----------------------------------------------------------------------------
02920 void KMMainWidget::updateMessageMenu()
02921 {
02922     mMenuToFolder.clear();
02923     KMMenuCommand::folderToPopupMenu( true, this, &mMenuToFolder, mMoveActionMenu->popupMenu() );
02924     KMMenuCommand::folderToPopupMenu( false, this, &mMenuToFolder, mCopyActionMenu->popupMenu() );
02925     updateMessageActions();
02926 }
02927 
02928 void KMMainWidget::startUpdateMessageActionsTimer()
02929 {
02930     menutimer->stop();
02931     menutimer->start( 20, true );
02932 }
02933 
02934 void KMMainWidget::updateMessageActions()
02935 {
02936     int count = 0;
02937     QPtrList<QListViewItem> selectedItems;
02938 
02939     if ( mFolder ) {
02940         for (QListViewItem *item = mHeaders->firstChild(); item; item = item->itemBelow())
02941             if (item->isSelected() )
02942             selectedItems.append(item);
02943         if ( selectedItems.isEmpty() && mFolder->count() ) // there will always be one in mMsgView
02944             count = 1;
02945     else count = selectedItems.count();
02946     }
02947 
02948     updateListFilterAction();
02949 
02950     bool allSelectedInCommonThread = true;
02951     if ( count > 1 && mHeaders->isThreaded() ) {
02952       QListViewItem * curItemParent = mHeaders->currentItem();
02953       while ( curItemParent->parent() )
02954     curItemParent = curItemParent->parent();
02955       for ( QPtrListIterator<QListViewItem> it( selectedItems ) ;
02956         it.current() ; ++ it ) {
02957     QListViewItem * item = *it;
02958     while ( item->parent() )
02959       item = item->parent();
02960     if ( item != curItemParent ) {
02961       allSelectedInCommonThread = false;
02962       break;
02963     }
02964       }
02965     }
02966 
02967     bool mass_actions = count >= 1;
02968     bool thread_actions = mass_actions &&
02969            allSelectedInCommonThread &&
02970            mHeaders->isThreaded();
02971     mStatusMenu->setEnabled( mass_actions );
02972     mThreadStatusMenu->setEnabled( thread_actions );
02973     // these need to be handled individually, the user might have them
02974     // in the toolbar
02975     mWatchThreadAction->setEnabled( thread_actions );
02976     mIgnoreThreadAction->setEnabled( thread_actions );
02977     mMarkThreadAsSpamAction->setEnabled( thread_actions );
02978     mMarkThreadAsHamAction->setEnabled( thread_actions );
02979     mMarkThreadAsNewAction->setEnabled( thread_actions );
02980     mMarkThreadAsReadAction->setEnabled( thread_actions );
02981     mMarkThreadAsUnreadAction->setEnabled( thread_actions );
02982     mToggleThreadRepliedAction->setEnabled( thread_actions );
02983     mToggleThreadForwardedAction->setEnabled( thread_actions );
02984     mToggleThreadQueuedAction->setEnabled( thread_actions );
02985     mToggleThreadSentAction->setEnabled( thread_actions );
02986     mToggleThreadFlagAction->setEnabled( thread_actions );
02987 
02988     if (mFolder && mHeaders && mHeaders->currentMsg()) {
02989       mToggleRepliedAction->setChecked(mHeaders->currentMsg()->isReplied());
02990       mToggleForwardedAction->setChecked(mHeaders->currentMsg()->isForwarded());
02991       mToggleQueuedAction->setChecked(mHeaders->currentMsg()->isQueued());
02992       mToggleSentAction->setChecked(mHeaders->currentMsg()->isSent());
02993       mToggleFlagAction->setChecked(mHeaders->currentMsg()->isImportant());
02994       if (thread_actions) {
02995         mToggleThreadRepliedAction->setChecked(mHeaders->currentMsg()->isReplied());
02996         mToggleThreadForwardedAction->setChecked(mHeaders->currentMsg()->isForwarded());
02997         mToggleThreadQueuedAction->setChecked(mHeaders->currentMsg()->isQueued());
02998         mToggleThreadSentAction->setChecked(mHeaders->currentMsg()->isSent());
02999         mToggleThreadFlagAction->setChecked(mHeaders->currentMsg()->isImportant());
03000         mWatchThreadAction->setChecked( mHeaders->currentMsg()->isWatched());
03001         mIgnoreThreadAction->setChecked( mHeaders->currentMsg()->isIgnored());
03002       }
03003     }
03004 
03005     mMoveActionMenu->setEnabled( mass_actions && !mFolder->isReadOnly() );
03006     mCopyActionMenu->setEnabled( mass_actions );
03007     mTrashAction->setEnabled( mass_actions && !mFolder->isReadOnly() );
03008     mDeleteAction->setEnabled( mass_actions && !mFolder->isReadOnly() );
03009     mFindInMessageAction->setEnabled( mass_actions );
03010     mForwardAction->setEnabled( mass_actions );
03011     mForwardAttachedAction->setEnabled( mass_actions );
03012 
03013     forwardMenu()->setEnabled( mass_actions );
03014 
03015     bool single_actions = count == 1;
03016     mEditAction->setEnabled( single_actions &&
03017     kmkernel->folderIsDraftOrOutbox(mFolder));
03018     replyMenu()->setEnabled( single_actions );
03019     filterMenu()->setEnabled( single_actions );
03020     bounceAction()->setEnabled( single_actions );
03021     replyAction()->setEnabled( single_actions );
03022     noQuoteReplyAction()->setEnabled( single_actions );
03023     replyAuthorAction()->setEnabled( single_actions );
03024     replyAllAction()->setEnabled( single_actions );
03025     replyListAction()->setEnabled( single_actions );
03026     redirectAction()->setEnabled( single_actions );
03027     printAction()->setEnabled( single_actions );
03028     if (mMsgView) {
03029       viewSourceAction()->setEnabled( single_actions );
03030     }
03031 
03032     mSendAgainAction->setEnabled( single_actions &&
03033              ( mHeaders->currentMsg() && mHeaders->currentMsg()->isSent() )
03034           || ( mFolder && kmkernel->folderIsDraftOrOutbox( mFolder ) )
03035           || ( mFolder && kmkernel->folderIsSentMailFolder( mFolder ) )
03036              );
03037     mSaveAsAction->setEnabled( mass_actions );
03038     bool mails = mFolder && mFolder->count();
03039     bool enable_goto_unread = mails
03040        || (GlobalSettings::loopOnGotoUnread() == GlobalSettings::EnumLoopOnGotoUnread::LoopInAllFolders);
03041     actionCollection()->action( "go_next_message" )->setEnabled( mails );
03042     actionCollection()->action( "go_next_unread_message" )->setEnabled( enable_goto_unread );
03043     actionCollection()->action( "go_prev_message" )->setEnabled( mails );
03044     actionCollection()->action( "go_prev_unread_message" )->setEnabled( enable_goto_unread );
03045     actionCollection()->action( "send_queued" )->setEnabled( kmkernel->outboxFolder()->count() > 0 );
03046     if (action( "edit_undo" ))
03047       action( "edit_undo" )->setEnabled( mHeaders->canUndo() );
03048 
03049     if ( count == 1 ) {
03050       KMMessage *msg;
03051       int aIdx;
03052       if((aIdx = mHeaders->currentItemIndex()) <= -1)
03053         return;
03054       if(!(msg = mFolder->getMsg(aIdx)))
03055         return;
03056 
03057       if (mFolder == kmkernel->outboxFolder())
03058         mEditAction->setEnabled( !msg->transferInProgress() );
03059     }
03060 
03061     mApplyFiltersAction->setEnabled(count);
03062     mApplyFilterActionsMenu->setEnabled(count && (mApplyFilterActionsMenu->popupMenu()->count()>0));
03063 }
03064 
03065 // This needs to be updated more often, so it is in its method.
03066 void KMMainWidget::updateMarkAsReadAction()
03067 {
03068   mMarkAllAsReadAction->setEnabled( mFolder && (mFolder->countUnread() > 0) );
03069 }
03070 
03071 //-----------------------------------------------------------------------------
03072 void KMMainWidget::updateFolderMenu()
03073 {
03074   bool folderWithContent = mFolder && !mFolder->noContent();
03075   mModifyFolderAction->setEnabled( folderWithContent );
03076   mCompactFolderAction->setEnabled( folderWithContent );
03077 
03078   // This is the refresh-folder action in the menu. See kmfoldertree for the one in the RMB...
03079   bool imap = mFolder && mFolder->folderType() == KMFolderTypeImap;
03080   bool cachedImap = mFolder && mFolder->folderType() == KMFolderTypeCachedImap;
03081   // For dimap, check that the imap path is known before allowing "check mail in this folder".
03082   bool knownImapPath = cachedImap && !static_cast<KMFolderCachedImap*>( mFolder->storage() )->imapPath().isEmpty();
03083   mRefreshFolderAction->setEnabled( folderWithContent && ( imap
03084                                                            || ( cachedImap && knownImapPath ) ) );
03085   mEmptyFolderAction->setEnabled( folderWithContent && ( mFolder->count() > 0 ) && !mFolder->isReadOnly() );
03086   mEmptyFolderAction->setText( (mFolder && kmkernel->folderIsTrash(mFolder))
03087     ? i18n("E&mpty Trash") : i18n("&Move All Messages to Trash") );
03088   mRemoveFolderAction->setEnabled( (mFolder && !mFolder->isSystemFolder()) );
03089   mExpireFolderAction->setEnabled( mFolder && mFolder->isAutoExpire() );
03090   updateMarkAsReadAction();
03091   mPreferHtmlAction->setEnabled( mFolder ? true : false );
03092   mThreadMessagesAction->setEnabled( mFolder ? true : false );
03093 
03094   mPreferHtmlAction->setChecked( mHtmlPref ? !mFolderHtmlPref : mFolderHtmlPref );
03095   mThreadMessagesAction->setChecked(
03096       mThreadPref ? !mFolderThreadPref : mFolderThreadPref );
03097   mThreadBySubjectAction->setEnabled(
03098       mFolder ? ( mThreadMessagesAction->isChecked()) : false );
03099   mThreadBySubjectAction->setChecked( mFolderThreadSubjPref );
03100 }
03101 
03102 
03103 #ifdef MALLOC_DEBUG
03104 static QString fmt(long n) {
03105   char buf[32];
03106 
03107   if(n > 1024*1024*1024)
03108     sprintf(buf, "%0.2f GB", ((double)n)/1024.0/1024.0/1024.0);
03109   else if(n > 1024*1024)
03110     sprintf(buf, "%0.2f MB", ((double)n)/1024.0/1024.0);
03111   else if(n > 1024)
03112     sprintf(buf, "%0.2f KB", ((double)n)/1024.0);
03113   else
03114     sprintf(buf, "%ld Byte", n);
03115   return QString(buf);
03116 }
03117 #endif
03118 
03119 void KMMainWidget::slotMemInfo() {
03120 #ifdef MALLOC_DEBUG
03121   struct mallinfo mi;
03122 
03123   mi = mallinfo();
03124   QString s = QString("\nMALLOC - Info\n\n"
03125               "Number of mmapped regions : %1\n"
03126               "Memory allocated in use   : %2\n"
03127               "Memory allocated, not used: %3\n"
03128               "Memory total allocated    : %4\n"
03129               "Max. freeable memory      : %5\n")
03130     .arg(mi.hblks).arg(fmt(mi.uordblks)).arg(fmt(mi.fordblks))
03131     .arg(fmt(mi.arena)).arg(fmt(mi.keepcost));
03132   KMessageBox::information(0, s, "Malloc information", s);
03133 #endif
03134 }
03135 
03136 
03137 //-----------------------------------------------------------------------------
03138 void KMMainWidget::slotIntro()
03139 {
03140   if ( !mMsgView ) return;
03141 
03142   mMsgView->clear( true );
03143   // hide widgets that are in the way:
03144   if ( mSearchAndHeaders && mHeaders && mLongFolderList )
03145     mSearchAndHeaders->hide();
03146 
03147 
03148   mMsgView->displayAboutPage();
03149 
03150   mFolder = 0;
03151 }
03152 
03153 void KMMainWidget::slotShowStartupFolder()
03154 {
03155   if ( mFolderTree ) {
03156     mFolderTree->reload();
03157     mFolderTree->readConfig();
03158     // get rid of old-folders
03159     mFolderTree->cleanupConfigFile();
03160   }
03161 
03162   connect( kmkernel->filterMgr(), SIGNAL( filterListUpdated() ),
03163        this, SLOT( initializeFilterActions() ));
03164 
03165   // plug shortcut filter actions now
03166   initializeFilterActions();
03167 
03168   QString newFeaturesMD5 = KMReaderWin::newFeaturesMD5();
03169   if ( kmkernel->firstStart() ||
03170        GlobalSettings::previousNewFeaturesMD5() != newFeaturesMD5 ) {
03171     GlobalSettings::setPreviousNewFeaturesMD5( newFeaturesMD5 );
03172     slotIntro();
03173   }
03174 
03175   KMFolder* startup = 0;
03176   if ( !mStartupFolder.isEmpty() ) {
03177     // find the startup-folder
03178     startup = kmkernel->findFolderById( mStartupFolder );
03179   }
03180   if ( !startup )
03181     startup = kmkernel->inboxFolder();
03182 
03183   if ( mFolderTree ) {
03184     mFolderTree->showFolder( startup );
03185   }
03186 }
03187 
03188 void KMMainWidget::slotShowTip()
03189 {
03190   KTipDialog::showTip( this, QString::null, true );
03191 }
03192 
03193 //-----------------------------------------------------------------------------
03194 void KMMainWidget::slotChangeCaption(QListViewItem * i)
03195 {
03196   if ( !i ) return;
03197   // set the caption to the current full path
03198   QStringList names;
03199   for ( QListViewItem * item = i ; item ; item = item->parent() )
03200     names.prepend( item->text(0) );
03201   emit captionChangeRequest( names.join( "/" ) );
03202 }
03203 
03204 //-----------------------------------------------------------------------------
03205 void KMMainWidget::removeDuplicates()
03206 {
03207   if (!mFolder)
03208     return;
03209   KMFolder *oFolder = mFolder;
03210   mHeaders->setFolder(0);
03211   QMap< QString, QValueList<int> > idMD5s;
03212   QValueList<int> redundantIds;
03213   QValueList<int>::Iterator kt;
03214   mFolder->open();
03215   for (int i = mFolder->count() - 1; i >= 0; --i) {
03216     QString id = (*mFolder)[i]->msgIdMD5();
03217     if ( !id.isEmpty() ) {
03218       QString subjMD5 = (*mFolder)[i]->strippedSubjectMD5();
03219       int other = -1;
03220       if ( idMD5s.contains(id) )
03221         other = idMD5s[id].first();
03222       else
03223         idMD5s[id].append( i );
03224       if ( other != -1 ) {
03225         QString otherSubjMD5 = (*mFolder)[other]->strippedSubjectMD5();
03226         if (otherSubjMD5 == subjMD5)
03227           idMD5s[id].append( i );
03228       }
03229     }
03230   }
03231   QMap< QString, QValueList<int> >::Iterator it;
03232   for ( it = idMD5s.begin(); it != idMD5s.end() ; ++it ) {
03233     QValueList<int>::Iterator jt;
03234     bool finished = false;
03235     for ( jt = (*it).begin(); jt != (*it).end() && !finished; ++jt )
03236       if (!((*mFolder)[*jt]->isUnread())) {
03237         (*it).remove( jt );
03238         (*it).prepend( *jt );
03239         finished = true;
03240       }
03241     for ( jt = (*it).begin(), ++jt; jt != (*it).end(); ++jt )
03242       redundantIds.append( *jt );
03243   }
03244   qHeapSort( redundantIds );
03245   kt = redundantIds.end();
03246   int numDuplicates = 0;
03247   if (kt != redundantIds.begin()) do {
03248     mFolder->removeMsg( *(--kt) );
03249     ++numDuplicates;
03250   }
03251   while (kt != redundantIds.begin());
03252 
03253   mFolder->close();
03254   mHeaders->setFolder(oFolder);
03255   QString msg;
03256   if ( numDuplicates )
03257     msg = i18n("Removed %n duplicate message.",
03258                "Removed %n duplicate messages.", numDuplicates );
03259     else
03260       msg = i18n("No duplicate messages found.");
03261   BroadcastStatus::instance()->setStatusMsg( msg );
03262 }
03263 
03264 
03265 //-----------------------------------------------------------------------------
03266 void KMMainWidget::slotUpdateUndo()
03267 {
03268     if (actionCollection()->action( "edit_undo" ))
03269         actionCollection()->action( "edit_undo" )->setEnabled( mHeaders->canUndo() );
03270 }
03271 
03272 
03273 //-----------------------------------------------------------------------------
03274 void KMMainWidget::clearFilterActions()
03275 {
03276   if ( !mFilterTBarActions.isEmpty() ) {
03277     if ( mGUIClient->factory() )
03278       mGUIClient->unplugActionList( "toolbar_filter_actions" );
03279     mFilterTBarActions.clear();
03280   }
03281   if ( !mFilterMenuActions.isEmpty() ) {
03282     mApplyFilterActionsMenu->popupMenu()->clear();
03283     if ( mGUIClient->factory() )
03284       mGUIClient->unplugActionList( "menu_filter_actions" );
03285     mFilterMenuActions.clear();
03286   }
03287   mFilterCommands.clear();
03288 }
03289 
03290 
03291 //-----------------------------------------------------------------------------
03292 void KMMainWidget::initializeFilterActions()
03293 {
03294   QString filterName, normalizedName;
03295   KMMetaFilterActionCommand *filterCommand;
03296   KAction *filterAction = 0;
03297 
03298   clearFilterActions();
03299   for ( QPtrListIterator<KMFilter> it(*kmkernel->filterMgr()) ;
03300         it.current() ; ++it ) {
03301     if (!(*it)->isEmpty() && (*it)->configureShortcut()) {
03302       filterName = QString("Filter %1").arg((*it)->name());
03303       normalizedName = filterName.replace(" ", "_");
03304       if (action(normalizedName.utf8()))
03305         continue;
03306       filterCommand = new KMMetaFilterActionCommand(*it, mHeaders, this);
03307       mFilterCommands.append(filterCommand);
03308       QString as = i18n("Filter %1").arg((*it)->name());
03309       QString icon = (*it)->icon();
03310       if ( icon.isEmpty() )
03311         icon = "gear";
03312       filterAction = new KAction(as, icon, 0, filterCommand,
03313                                  SLOT(start()), actionCollection(),
03314                                  normalizedName.local8Bit());
03315       filterAction->plug( mApplyFilterActionsMenu->popupMenu() );
03316       mFilterMenuActions.append(filterAction);
03317       // FIXME
03318       // uncomment the next if statement after the filter dialog supports
03319       // separate activation of filters for the toolbar - currently
03320       // we better depend on whether an icon is defined, so the current
03321       // IF statement is intermediate
03322       // if ( (*it)->configureToolbar() )
03323       if ( !(*it)->icon().isEmpty() )
03324         mFilterTBarActions.append(filterAction);
03325     }
03326   }
03327   if ( !mFilterMenuActions.isEmpty() && mGUIClient->factory() )
03328     mGUIClient->plugActionList( "menu_filter_actions", mFilterMenuActions );
03329   if ( !mFilterTBarActions.isEmpty() && mGUIClient->factory() )
03330     mGUIClient->plugActionList( "toolbar_filter_actions", mFilterTBarActions );
03331 }
03332 
03333 
03334 //-----------------------------------------------------------------------------
03335 void KMMainWidget::slotSubscriptionDialog()
03336 {
03337   if (!mFolder) return;
03338 
03339   ImapAccountBase* account;
03340   QString startPath;
03341   if (mFolder->folderType() == KMFolderTypeImap)
03342   {
03343     startPath = static_cast<KMFolderImap*>(mFolder->storage())->imapPath();
03344     account = static_cast<KMFolderImap*>(mFolder->storage())->account();
03345   } else if (mFolder->folderType() == KMFolderTypeCachedImap)
03346   {
03347     startPath = static_cast<KMFolderCachedImap*>(mFolder->storage())->imapPath();
03348     account = static_cast<KMFolderCachedImap*>(mFolder->storage())->account();
03349   } else
03350     return;
03351 
03352   if ( !account ) return;
03353 
03354   SubscriptionDialog *dialog = new SubscriptionDialog(this,
03355       i18n("Subscription"),
03356       account, startPath);
03357   // start a new listing
03358   if ( dialog->exec() ) {
03359     if (mFolder->folderType() == KMFolderTypeImap)
03360       static_cast<KMFolderImap*>(mFolder->storage())->account()->listDirectory();
03361   }
03362 }
03363 
03364 //-----------------------------------------------------------------------------
03365 void KMMainWidget::slotFolderTreeColumnsChanged()
03366 {
03367   mTotalColumnToggle->setChecked( mFolderTree->isTotalActive() );
03368   mUnreadColumnToggle->setChecked( mFolderTree->isUnreadActive() );
03369 }
03370 
03371 void KMMainWidget::toggleSystemTray()
03372 {
03373   if ( !mSystemTray && GlobalSettings::systemTrayEnabled() ) {
03374     mSystemTray = new KMSystemTray();
03375   }
03376   else if ( mSystemTray && !GlobalSettings::systemTrayEnabled() ) {
03377     // Get rid of system tray on user's request
03378     kdDebug(5006) << "deleting systray" << endl;
03379     delete mSystemTray;
03380     mSystemTray = 0;
03381   }
03382 
03383   // Set mode of systemtray. If mode has changed, tray will handle this.
03384   if ( mSystemTray )
03385     mSystemTray->setMode( GlobalSettings::systemTrayPolicy() );
03386 }
03387 
03388 //-----------------------------------------------------------------------------
03389 void KMMainWidget::slotAntiSpamWizard()
03390 {
03391   AntiSpamWizard wiz( AntiSpamWizard::AntiSpam,
03392                       this, folderTree(), actionCollection() );
03393   wiz.exec();
03394 }
03395 
03396 //-----------------------------------------------------------------------------
03397 void KMMainWidget::slotAntiVirusWizard()
03398 {
03399   AntiSpamWizard wiz( AntiSpamWizard::AntiVirus,
03400                       this, folderTree(), actionCollection() );
03401   wiz.exec();
03402 }
03403 
03404 //-----------------------------------------------------------------------------
03405 void KMMainWidget::slotFilterLogViewer()
03406 {
03407   FilterLogDialog * dlg = new FilterLogDialog( 0 );
03408   dlg->show();
03409 }
03410 
03411 //-----------------------------------------------------------------------------
03412 void KMMainWidget::updateFileMenu()
03413 {
03414   QStringList actList = kmkernel->acctMgr()->getAccounts(false);
03415 
03416   actionCollection()->action("check_mail")->setEnabled( actList.size() > 0 );
03417   actionCollection()->action("check_mail_in")->setEnabled( actList.size() > 0 );
03418 }
03419 
03420 
03421 //-----------------------------------------------------------------------------
03422 void KMMainWidget::updateViewMenu()
03423 {
03424   bool previewPaneVisible = ( mMsgView != 0 );
03425   if ( previewPaneVisible ) {
03426     KRadioAction *raction = actionForHeaderStyle( mMsgView->headerStyle(), mMsgView->headerStrategy() );
03427     if ( raction )
03428       raction->setChecked( true );
03429     raction = actionForAttachmentStrategy( mMsgView->attachmentStrategy() );
03430     if ( raction )
03431       raction->setChecked( true );
03432   }
03433   actionCollection()->action("view_headers")->setEnabled( previewPaneVisible );
03434   actionCollection()->action("view_attachments")->setEnabled( previewPaneVisible );
03435 }
03436 
03437 //-----------------------------------------------------------------------------
03438 KMSystemTray *KMMainWidget::systray() const
03439 {
03440   return mSystemTray;
03441 }
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 Mon Apr 4 06:44:14 2005 by doxygen 1.4.2 written by Dimitri van Heesch, © 1997-2003