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