kmail

kmmainwidget.cpp

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