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