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                         mMsgView->headerStyle(), mMsgView->headerStrategy(),
01807                         htmlOverride, htmlLoadExtOverride,
01808                         useFixedFont, overrideEncoding() );
01809   command->start();
01810 }
01811 
01812 //-----------------------------------------------------------------------------
01813 void KMMainWidget::setupForwardActions()
01814 {
01815   disconnect( mForwardActionMenu, SIGNAL( activated() ), 0, 0 );
01816   mForwardActionMenu->remove( mForwardInlineAction );
01817   mForwardActionMenu->remove( mForwardAttachedAction );
01818 
01819   if ( GlobalSettings::self()->forwardingInlineByDefault() ) {
01820     mForwardActionMenu->insert( mForwardInlineAction, 0 );
01821     mForwardActionMenu->insert( mForwardAttachedAction, 1 );
01822     mForwardInlineAction->setShortcut( Key_F );
01823     mForwardAttachedAction->setShortcut( SHIFT+Key_F );
01824     connect( mForwardActionMenu, SIGNAL(activated()), this,
01825             SLOT(slotForwardInlineMsg()) );
01826 
01827   } else {
01828     mForwardActionMenu->insert( mForwardAttachedAction, 0 );
01829     mForwardActionMenu->insert( mForwardInlineAction, 1 );
01830     mForwardInlineAction->setShortcut( SHIFT+Key_F );
01831     mForwardAttachedAction->setShortcut( Key_F );
01832     connect( mForwardActionMenu, SIGNAL(activated()), this,
01833             SLOT(slotForwardAttachedMsg()) );
01834   }
01835 }
01836 
01837 //-----------------------------------------------------------------------------
01838 void KMMainWidget::slotConfigChanged()
01839 {
01840   readConfig();
01841   setupForwardActions();
01842   setupForwardingActionsList();
01843 }
01844 
01845 //-----------------------------------------------------------------------------
01846 void KMMainWidget::slotSaveMsg()
01847 {
01848   KMMessage *msg = mHeaders->currentMsg();
01849   if (!msg)
01850     return;
01851   KMSaveMsgCommand *saveCommand = new KMSaveMsgCommand( this,
01852     *mHeaders->selectedMsgs() );
01853 
01854   if (saveCommand->url().isEmpty())
01855     delete saveCommand;
01856   else
01857     saveCommand->start();
01858 }
01859 
01860 //-----------------------------------------------------------------------------
01861 void KMMainWidget::slotOpenMsg()
01862 {
01863   KMOpenMsgCommand *openCommand = new KMOpenMsgCommand( this, 0, overrideEncoding() );
01864 
01865   openCommand->start();
01866 }
01867 
01868 //-----------------------------------------------------------------------------
01869 void KMMainWidget::slotSaveAttachments()
01870 {
01871   KMMessage *msg = mHeaders->currentMsg();
01872   if (!msg)
01873     return;
01874   KMSaveAttachmentsCommand *saveCommand = new KMSaveAttachmentsCommand( this,
01875                                                                         *mHeaders->selectedMsgs() );
01876   saveCommand->start();
01877 }
01878 
01879 void KMMainWidget::slotOnlineStatus()
01880 {
01881   // KMKernel will emit a signal when we toggle the network state that is caught by
01882   // KMMainWidget::slotUpdateOnlineStatus to update our GUI
01883   if ( GlobalSettings::self()->networkState() == GlobalSettings::EnumNetworkState::Online ) {
01884     // if online; then toggle and set it offline.
01885     kmkernel->stopNetworkJobs();
01886   } else {
01887     kmkernel->resumeNetworkJobs();
01888     slotCheckVacation();
01889   }
01890 }
01891 
01892 void KMMainWidget::slotUpdateOnlineStatus( GlobalSettings::EnumNetworkState::type )
01893 {
01894   if ( GlobalSettings::self()->networkState() == GlobalSettings::EnumNetworkState::Online )
01895     actionCollection()->action( "online_status" )->setText( i18n("Work Offline") );
01896   else
01897     actionCollection()->action( "online_status" )->setText( i18n("Work Online") );
01898 }
01899 
01900 
01901 //-----------------------------------------------------------------------------
01902 void KMMainWidget::slotSendQueued()
01903 {
01904   if ( !kmkernel->askToGoOnline() ) {
01905     return;
01906   }
01907 
01908   kmkernel->msgSender()->sendQueued();
01909 }
01910 
01911 //-----------------------------------------------------------------------------
01912 void KMMainWidget::slotSendQueuedVia( int item )
01913 {
01914   if ( !kmkernel->askToGoOnline() ) {
01915     return;
01916   }
01917 
01918   QStringList availTransports= KMail::TransportManager::transportNames();
01919   QString customTransport = availTransports[ item ];
01920 
01921   kmkernel->msgSender()->sendQueued( customTransport );
01922 }
01923 
01924 //-----------------------------------------------------------------------------
01925 void KMMainWidget::slotViewChange()
01926 {
01927   if(mBodyPartsMenu->isItemChecked(mBodyPartsMenu->idAt(0)))
01928   {
01929     mBodyPartsMenu->setItemChecked(mBodyPartsMenu->idAt(0),false);
01930     mBodyPartsMenu->setItemChecked(mBodyPartsMenu->idAt(1),true);
01931   }
01932   else if(mBodyPartsMenu->isItemChecked(mBodyPartsMenu->idAt(1)))
01933   {
01934     mBodyPartsMenu->setItemChecked(mBodyPartsMenu->idAt(1),false);
01935     mBodyPartsMenu->setItemChecked(mBodyPartsMenu->idAt(0),true);
01936   }
01937 
01938   //mMsgView->setInline(!mMsgView->isInline());
01939 }
01940 
01941 
01942 //-----------------------------------------------------------------------------
01943 void KMMainWidget::folderSelectedUnread( KMFolder* aFolder )
01944 {
01945   folderSelected( aFolder, true );
01946   slotChangeCaption( mFolderTree->currentItem() );
01947 }
01948 
01949 //-----------------------------------------------------------------------------
01950 void KMMainWidget::folderSelected()
01951 {
01952   folderSelected( mFolder );
01953   updateFolderMenu();
01954   // opened() before the getAndCheckFolder() in folderSelected
01955   if ( mFolder && mFolder->folderType() == KMFolderTypeImap )
01956     mFolder->close("mainwidget");
01957 }
01958 
01959 //-----------------------------------------------------------------------------
01960 void KMMainWidget::folderSelected( KMFolder* aFolder, bool forceJumpToUnread )
01961 {
01962   KCursorSaver busy(KBusyPtr::busy());
01963 
01964   if (mMsgView)
01965     mMsgView->clear(true);
01966 
01967   if ( mFolder && mFolder->folderType() == KMFolderTypeImap && !mFolder->noContent() )
01968   {
01969     KMFolderImap *imap = static_cast<KMFolderImap*>(mFolder->storage());
01970     if ( mFolder->needsCompacting() && imap->autoExpunge() )
01971       imap->expungeFolder(imap, true);
01972   }
01973 
01974   // Re-enable the msg list and quicksearch if we're showing a splash
01975   // screen. This is true either if there's no active folder, or if we
01976   // have a timer that is no longer active (i.e. it has already fired)
01977   // To make the if() a bit more complicated, we suppress the hiding
01978   // when the new folder is also an IMAP folder, because that's an
01979   // async operation and we don't want flicker if it results in just
01980   // a new splash.
01981   bool newFolder = ( (KMFolder*)mFolder != aFolder );
01982   bool isNewImapFolder = aFolder && aFolder->folderType() == KMFolderTypeImap && newFolder;
01983   if( !mFolder
01984       || ( !isNewImapFolder && mShowBusySplashTimer )
01985       || ( newFolder && mShowingOfflineScreen && !( isNewImapFolder && kmkernel->isOffline() ) ) ) {
01986     if ( mMsgView ) {
01987       mMsgView->enableMsgDisplay();
01988       mMsgView->clear( true );
01989     }
01990     if( mSearchAndHeaders && mHeaders )
01991       mSearchAndHeaders->show();
01992     mShowingOfflineScreen = false;
01993   }
01994 
01995   // Delete any pending timer, if needed it will be recreated below
01996   delete mShowBusySplashTimer;
01997   mShowBusySplashTimer = 0;
01998 
01999   if ( newFolder )
02000     writeFolderConfig();
02001   if ( mFolder ) {
02002     disconnect( mFolder, SIGNAL( changed() ),
02003            this, SLOT( updateMarkAsReadAction() ) );
02004     disconnect( mFolder, SIGNAL( msgHeaderChanged( KMFolder*, int ) ),
02005            this, SLOT( updateMarkAsReadAction() ) );
02006     disconnect( mFolder, SIGNAL( msgAdded( int ) ),
02007            this, SLOT( updateMarkAsReadAction() ) );
02008     disconnect( mFolder, SIGNAL( msgRemoved( KMFolder * ) ),
02009            this, SLOT( updateMarkAsReadAction() ) );
02010   }
02011 
02012   mFolder = aFolder;
02013 
02014   if ( aFolder && aFolder->folderType() == KMFolderTypeImap )
02015   {
02016     if ( kmkernel->isOffline() ) {
02017       showOfflinePage();
02018       return;
02019     }
02020     KMFolderImap *imap = static_cast<KMFolderImap*>(aFolder->storage());
02021     if ( newFolder && !mFolder->noContent() )
02022     {
02023       imap->open("mainwidget"); // will be closed in the folderSelected slot
02024       // first get new headers before we select the folder
02025       imap->setSelected( true );
02026       connect( imap, SIGNAL( folderComplete( KMFolderImap*, bool ) ),
02027           this, SLOT( folderSelected() ) );
02028       imap->getAndCheckFolder();
02029       mHeaders->setFolder( 0 );
02030       updateFolderMenu();
02031       mForceJumpToUnread = forceJumpToUnread;
02032 
02033       // Set a timer to show a splash screen if fetching folder contents
02034       // takes more than the amount of seconds configured in the kmailrc (default 1000 msec)
02035       mShowBusySplashTimer = new QTimer( this );
02036       connect( mShowBusySplashTimer, SIGNAL( timeout() ), this, SLOT( slotShowBusySplash() ) );
02037       mShowBusySplashTimer->start( GlobalSettings::self()->folderLoadingTimeout(), true );
02038       return;
02039     } else {
02040       // the folder is complete now - so go ahead
02041       disconnect( imap, SIGNAL( folderComplete( KMFolderImap*, bool ) ),
02042           this, SLOT( folderSelected() ) );
02043       forceJumpToUnread = mForceJumpToUnread;
02044     }
02045   }
02046 
02047   if ( mFolder ) { // == 0 -> pointing to toplevel ("Welcome to KMail") folder
02048     connect( mFolder, SIGNAL( changed() ),
02049            this, SLOT( updateMarkAsReadAction() ) );
02050     connect( mFolder, SIGNAL( msgHeaderChanged( KMFolder*, int ) ),
02051            this, SLOT( updateMarkAsReadAction() ) );
02052     connect( mFolder, SIGNAL( msgAdded( int ) ),
02053            this, SLOT( updateMarkAsReadAction() ) );
02054     connect( mFolder, SIGNAL( msgRemoved(KMFolder *) ),
02055            this, SLOT( updateMarkAsReadAction() ) );
02056   }
02057   readFolderConfig();
02058   if (mMsgView)
02059   {
02060     mMsgView->setHtmlOverride(mFolderHtmlPref);
02061     mMsgView->setHtmlLoadExtOverride(mFolderHtmlLoadExtPref);
02062   }
02063   mHeaders->setFolder( mFolder, forceJumpToUnread );
02064   updateMessageActions();
02065   updateFolderMenu();
02066   if (!aFolder)
02067     slotIntro();
02068 }
02069 
02070 //-----------------------------------------------------------------------------
02071 void KMMainWidget::slotShowBusySplash()
02072 {
02073   if ( mReaderWindowActive )
02074   {
02075     mMsgView->displayBusyPage();
02076     // hide widgets that are in the way:
02077     if ( mSearchAndHeaders && mHeaders && mLongFolderList )
02078       mSearchAndHeaders->hide();
02079   }
02080 }
02081 
02082 void KMMainWidget::showOfflinePage()
02083 {
02084   if ( !mReaderWindowActive ) return;
02085   mShowingOfflineScreen = true;
02086 
02087   mMsgView->displayOfflinePage();
02088   // hide widgets that are in the way:
02089   if ( mSearchAndHeaders && mHeaders && mLongFolderList )
02090     mSearchAndHeaders->hide();
02091 }
02092 
02093 //-----------------------------------------------------------------------------
02094 void KMMainWidget::slotMsgSelected(KMMessage *msg)
02095 {
02096   if ( msg && msg->parent() && !msg->isComplete() )
02097   {
02098     if ( msg->transferInProgress() )
02099       return;
02100     mMsgView->clear();
02101     mMsgView->setWaitingForSerNum( msg->getMsgSerNum() );
02102 
02103     if ( mJob ) {
02104        disconnect( mJob, 0, mMsgView, 0 );
02105        delete mJob;
02106     }
02107     mJob = msg->parent()->createJob( msg, FolderJob::tGetMessage, 0,
02108           "STRUCTURE", mMsgView->attachmentStrategy() );
02109     connect(mJob, SIGNAL(messageRetrieved(KMMessage*)),
02110             mMsgView, SLOT(slotMessageArrived(KMMessage*)));
02111     mJob->start();
02112   } else {
02113     mMsgView->setMsg(msg);
02114   }
02115   // reset HTML override to the folder setting
02116   mMsgView->setHtmlOverride(mFolderHtmlPref);
02117   mMsgView->setHtmlLoadExtOverride(mFolderHtmlLoadExtPref);
02118   mMsgView->setDecryptMessageOverwrite( false );
02119   mMsgView->setShowSignatureDetails( false );
02120 }
02121 
02122 //-----------------------------------------------------------------------------
02123 void KMMainWidget::slotMsgChanged()
02124 {
02125   mHeaders->msgChanged();
02126 }
02127 
02128 //-----------------------------------------------------------------------------
02129 void KMMainWidget::slotSelectFolder(KMFolder* folder)
02130 {
02131   QListViewItem* item = mFolderTree->indexOfFolder(folder);
02132   if ( item ) {
02133     mFolderTree->ensureItemVisible( item );
02134     mFolderTree->doFolderSelected( item );
02135   }
02136 }
02137 
02138 //-----------------------------------------------------------------------------
02139 void KMMainWidget::slotSelectMessage(KMMessage* msg)
02140 {
02141   int idx = mFolder->find(msg);
02142   if (idx != -1) {
02143     mHeaders->setCurrentMsg(idx);
02144     if (mMsgView)
02145       mMsgView->setMsg(msg);
02146     else
02147       slotMsgActivated(msg);
02148   }
02149 }
02150 
02151 //-----------------------------------------------------------------------------
02152 void KMMainWidget::slotReplaceMsgByUnencryptedVersion()
02153 {
02154   kdDebug(5006) << "KMMainWidget::slotReplaceMsgByUnencryptedVersion()" << endl;
02155   KMMessage* oldMsg = mHeaders->currentMsg();
02156   if( oldMsg ) {
02157     kdDebug(5006) << "KMMainWidget  -  old message found" << endl;
02158     if( oldMsg->hasUnencryptedMsg() ) {
02159       kdDebug(5006) << "KMMainWidget  -  extra unencrypted message found" << endl;
02160       KMMessage* newMsg = oldMsg->unencryptedMsg();
02161       // adjust the message id
02162       {
02163         QString msgId( oldMsg->msgId() );
02164         QString prefix("DecryptedMsg.");
02165         int oldIdx = msgId.find(prefix, 0, false);
02166         if( -1 == oldIdx ) {
02167           int leftAngle = msgId.findRev( '<' );
02168           msgId = msgId.insert( (-1 == leftAngle) ? 0 : ++leftAngle, prefix );
02169         }
02170         else {
02171           // toggle between "DecryptedMsg." and "DeCryptedMsg."
02172           // to avoid same message id
02173           QCharRef c = msgId[ oldIdx+2 ];
02174           if( 'C' == c )
02175             c = 'c';
02176           else
02177             c = 'C';
02178         }
02179         newMsg->setMsgId( msgId );
02180         mMsgView->setIdOfLastViewedMessage( msgId );
02181       }
02182       // insert the unencrypted message
02183       kdDebug(5006) << "KMMainWidget  -  adding unencrypted message to folder" << endl;
02184       mFolder->addMsg( newMsg );
02185       /* Figure out its index in the folder for selecting. This must be count()-1,
02186        * since we append. Be safe and do find, though, just in case. */
02187       int newMsgIdx = mFolder->find( newMsg );
02188       Q_ASSERT( newMsgIdx != -1 );
02189       /* we need this unget, to have the message displayed correctly initially */
02190       mFolder->unGetMsg( newMsgIdx );
02191       int idx = mFolder->find( oldMsg );
02192       Q_ASSERT( idx != -1 );
02193       /* only select here, so the old one is not un-Gotten before, which would
02194        * render the pointer we hold invalid so that find would fail */
02195       mHeaders->setCurrentItemByIndex( newMsgIdx );
02196       // remove the old one
02197       if ( idx != -1 ) {
02198         kdDebug(5006) << "KMMainWidget  -  deleting encrypted message" << endl;
02199         mFolder->take( idx );
02200       }
02201 
02202       kdDebug(5006) << "KMMainWidget  -  updating message actions" << endl;
02203       updateMessageActions();
02204 
02205       kdDebug(5006) << "KMMainWidget  -  done." << endl;
02206     } else
02207       kdDebug(5006) << "KMMainWidget  -  NO EXTRA UNENCRYPTED MESSAGE FOUND" << endl;
02208   } else
02209     kdDebug(5006) << "KMMainWidget  -  PANIC: NO OLD MESSAGE FOUND" << endl;
02210 }
02211 
02212 //-----------------------------------------------------------------------------
02213 void KMMainWidget::slotSetThreadStatusNew()
02214 {
02215   mHeaders->setThreadStatus(KMMsgStatusNew);
02216 }
02217 
02218 //-----------------------------------------------------------------------------
02219 void KMMainWidget::slotSetThreadStatusUnread()
02220 {
02221   mHeaders->setThreadStatus(KMMsgStatusUnread);
02222 }
02223 
02224 //-----------------------------------------------------------------------------
02225 void KMMainWidget::slotSetThreadStatusFlag()
02226 {
02227   mHeaders->setThreadStatus(KMMsgStatusFlag, true);
02228 }
02229 
02230 //-----------------------------------------------------------------------------
02231 void KMMainWidget::slotSetThreadStatusRead()
02232 {
02233   mHeaders->setThreadStatus(KMMsgStatusRead);
02234 }
02235 
02236 //-----------------------------------------------------------------------------
02237 void KMMainWidget::slotSetThreadStatusTodo()
02238 {
02239   mHeaders->setThreadStatus(KMMsgStatusTodo, true);
02240 }
02241 
02242 //-----------------------------------------------------------------------------
02243 void KMMainWidget::slotSetThreadStatusWatched()
02244 {
02245   mHeaders->setThreadStatus(KMMsgStatusWatched, true);
02246   if (mWatchThreadAction->isChecked()) {
02247     mIgnoreThreadAction->setChecked(false);
02248   }
02249 }
02250 
02251 //-----------------------------------------------------------------------------
02252 void KMMainWidget::slotSetThreadStatusIgnored()
02253 {
02254   mHeaders->setThreadStatus(KMMsgStatusIgnored, true);
02255   if (mIgnoreThreadAction->isChecked()) {
02256     mWatchThreadAction->setChecked(false);
02257   }
02258 }
02259 
02260 //-----------------------------------------------------------------------------
02261 void KMMainWidget::slotNextMessage()       { mHeaders->nextMessage(); }
02262 void KMMainWidget::slotNextUnreadMessage()
02263 {
02264   if ( !mHeaders->nextUnreadMessage() )
02265     if ( GlobalSettings::self()->loopOnGotoUnread() == GlobalSettings::EnumLoopOnGotoUnread::LoopInAllFolders )
02266       mFolderTree->nextUnreadFolder(true);
02267 }
02268 void KMMainWidget::slotNextImportantMessage() {
02269   //mHeaders->nextImportantMessage();
02270 }
02271 void KMMainWidget::slotPrevMessage()       { mHeaders->prevMessage(); }
02272 void KMMainWidget::slotPrevUnreadMessage()
02273 {
02274   if ( !mHeaders->prevUnreadMessage() )
02275     if ( GlobalSettings::self()->loopOnGotoUnread() == GlobalSettings::EnumLoopOnGotoUnread::LoopInAllFolders )
02276       mFolderTree->prevUnreadFolder();
02277 }
02278 void KMMainWidget::slotPrevImportantMessage() {
02279   //mHeaders->prevImportantMessage();
02280 }
02281 
02282 void KMMainWidget::slotDisplayCurrentMessage()
02283 {
02284   if ( mHeaders->currentMsg() )
02285     slotMsgActivated( mHeaders->currentMsg() );
02286 }
02287 
02288 //-----------------------------------------------------------------------------
02289 void KMMainWidget::slotMsgActivated(KMMessage *msg)
02290 {
02291   if ( !msg ) return;
02292   if ( msg->parent() && !msg->isComplete() ) {
02293     FolderJob *job = msg->parent()->createJob( msg );
02294     connect( job, SIGNAL( messageRetrieved( KMMessage* ) ),
02295              SLOT( slotMsgActivated( KMMessage* ) ) );
02296     job->start();
02297     return;
02298   }
02299 
02300   if (kmkernel->folderIsDraftOrOutbox( mFolder ) ) {
02301     mMsgActions->editCurrentMessage();
02302     return;
02303   }
02304   if ( kmkernel->folderIsTemplates( mFolder ) ) {
02305     slotUseTemplate();
02306     return;
02307   }
02308 
02309   assert( msg != 0 );
02310   KMReaderMainWin *win = new KMReaderMainWin( mFolderHtmlPref, mFolderHtmlLoadExtPref );
02311   KConfigGroup reader( KMKernel::config(), "Reader" );
02312   bool useFixedFont = mMsgView ? mMsgView->isFixedFont()
02313                                : reader.readBoolEntry( "useFixedFont", false );
02314   win->setUseFixedFont( useFixedFont );
02315   KMMessage *newMessage = new KMMessage(*msg);
02316   newMessage->setParent( msg->parent() );
02317   newMessage->setMsgSerNum( msg->getMsgSerNum() );
02318   newMessage->setReadyToShow( true );
02319   win->showMsg( overrideEncoding(), newMessage );
02320   win->show();
02321 }
02322 
02323 //-----------------------------------------------------------------------------
02324 void KMMainWidget::slotMarkAll()
02325 {
02326   mHeaders->selectAll( true );
02327 }
02328 
02329 //-----------------------------------------------------------------------------
02330 void KMMainWidget::slotMsgPopup(KMMessage&, const KURL &aUrl, const QPoint& aPoint)
02331 {
02332   KPopupMenu * menu = new KPopupMenu;
02333   updateMessageMenu();
02334   mUrlCurrent = aUrl;
02335 
02336   bool urlMenuAdded = false;
02337 
02338   if (!aUrl.isEmpty())
02339   {
02340     if (aUrl.protocol() == "mailto")
02341     {
02342       // popup on a mailto URL
02343       mMsgView->mailToComposeAction()->plug( menu );
02344       mMsgView->mailToReplyAction()->plug( menu );
02345       mMsgView->mailToForwardAction()->plug( menu );
02346 
02347       menu->insertSeparator();
02348       mMsgView->addAddrBookAction()->plug( menu );
02349       mMsgView->openAddrBookAction()->plug( menu );
02350       mMsgView->copyURLAction()->plug( menu );
02351       mMsgView->startImChatAction()->plug( menu );
02352       // only enable if our KIMProxy is functional
02353       mMsgView->startImChatAction()->setEnabled( kmkernel->imProxy()->initialize() );
02354 
02355     } else {
02356       // popup on a not-mailto URL
02357       mMsgView->urlOpenAction()->plug( menu );
02358       mMsgView->addBookmarksAction()->plug( menu );
02359       mMsgView->urlSaveAsAction()->plug( menu );
02360       mMsgView->copyURLAction()->plug( menu );
02361     }
02362     if ( aUrl.protocol() == "im" )
02363     {
02364       // popup on an IM address
02365       // no need to check the KIMProxy is initialized, as these protocols will
02366       // only be present if it is.
02367       mMsgView->startImChatAction()->plug( menu );
02368     }
02369 
02370     urlMenuAdded=true;
02371     kdDebug( 0 ) << k_funcinfo << " URL is: " << aUrl << endl;
02372   }
02373 
02374 
02375   if(mMsgView && !mMsgView->copyText().isEmpty()) {
02376     if ( urlMenuAdded )
02377       menu->insertSeparator();
02378     mMsgActions->replyMenu()->plug(menu);
02379     menu->insertSeparator();
02380 
02381     mMsgView->copyAction()->plug( menu );
02382     mMsgView->selectAllAction()->plug( menu );
02383   } else  if ( !urlMenuAdded )
02384   {
02385     // popup somewhere else (i.e., not a URL) on the message
02386 
02387     if (!mHeaders->currentMsg()) // no messages
02388     {
02389       delete menu;
02390       return;
02391     }
02392 
02393 
02394     if ( mFolder->isTemplates() ) {
02395       mUseAction->plug( menu );
02396     } else {
02397       mMsgActions->replyMenu()->plug( menu );
02398       mForwardActionMenu->plug( menu );
02399     }
02400     editAction()->plug(menu);
02401     menu->insertSeparator();
02402 
02403     mCopyActionMenu->plug( menu );
02404     mMoveActionMenu->plug( menu );
02405 
02406     menu->insertSeparator();
02407 
02408     mMsgActions->messageStatusMenu()->plug( menu );
02409     menu->insertSeparator();
02410 
02411     viewSourceAction()->plug(menu);
02412     if(mMsgView) {
02413       mMsgView->toggleFixFontAction()->plug(menu);
02414     }
02415     menu->insertSeparator();
02416     mPrintAction->plug( menu );
02417     mSaveAsAction->plug( menu );
02418     mSaveAttachmentsAction->plug( menu );
02419 
02420     menu->insertSeparator();
02421     if( mFolder->isTrash() )
02422       mDeleteAction->plug( menu );
02423     else
02424       mTrashAction->plug( menu );
02425 
02426     menu->insertSeparator();
02427     mMsgActions->createTodoAction()->plug( menu );
02428   }
02429   KAcceleratorManager::manage(menu);
02430   menu->exec(aPoint, 0);
02431   delete menu;
02432 }
02433 
02434 //-----------------------------------------------------------------------------
02435 void KMMainWidget::getAccountMenu()
02436 {
02437   QStringList actList;
02438 
02439   mActMenu->clear();
02440   actList = kmkernel->acctMgr()->getAccounts();
02441   QStringList::Iterator it;
02442   int id = 0;
02443   for(it = actList.begin(); it != actList.end() ; ++it, id++)
02444     mActMenu->insertItem((*it).replace("&", "&&"), id);
02445 }
02446 
02447 //-----------------------------------------------------------------------------
02448 void KMMainWidget::getTransportMenu()
02449 {
02450   QStringList availTransports;
02451 
02452   mSendMenu->clear();
02453   availTransports = KMail::TransportManager::transportNames();
02454   QStringList::Iterator it;
02455   int id = 0;
02456   for(it = availTransports.begin(); it != availTransports.end() ; ++it, id++)
02457     mSendMenu->insertItem((*it).replace("&", "&&"), id);
02458 }
02459 
02460 //-----------------------------------------------------------------------------
02461 void KMMainWidget::updateCustomTemplateMenus()
02462 {
02463   if ( !mCustomTemplateActions.isEmpty() ) {
02464     QPtrList<KAction>::iterator ait = mCustomTemplateActions.begin();
02465     for ( ; ait != mCustomTemplateActions.end() ; ++ait ) {
02466       (*ait)->unplugAll();
02467       delete (*ait);
02468     }
02469     mCustomTemplateActions.clear();
02470   }
02471 
02472   delete mCustomReplyActionMenu;
02473   delete mCustomReplyAllActionMenu;
02474   delete mCustomForwardActionMenu;
02475 
02476   delete mCustomReplyMapper;
02477   delete mCustomReplyAllMapper;
02478   delete mCustomForwardMapper;
02479 
02480   mCustomForwardActionMenu =
02481     new KActionMenu( i18n("Forward With Custom Template"),
02482                      "mail_custom_forward",
02483                      actionCollection(), "custom_forward" );
02484   QSignalMapper *mCustomForwardMapper = new QSignalMapper( this );
02485   connect( mCustomForwardMapper, SIGNAL( mapped( int ) ),
02486            this, SLOT( slotCustomForwardMsg( int ) ) );
02487   mForwardActionMenu->insert( mCustomForwardActionMenu );
02488 
02489   mCustomReplyActionMenu =
02490     new KActionMenu( i18n("Reply With Custom Template"), "mail_custom_reply",
02491                      actionCollection(), "custom_reply" );
02492   QSignalMapper *mCustomReplyMapper = new QSignalMapper( this );
02493   connect( mCustomReplyMapper, SIGNAL( mapped( int ) ),
02494            this, SLOT( slotCustomReplyToMsg( int ) ) );
02495   mMsgActions->replyMenu()->insert( mCustomReplyActionMenu );
02496 
02497   mCustomReplyAllActionMenu =
02498     new KActionMenu( i18n("Reply to All With Custom Template"),
02499                      "mail_custom_reply_all",
02500                      actionCollection(), "custom_reply_all" );
02501   QSignalMapper *mCustomReplyAllMapper = new QSignalMapper( this );
02502   connect( mCustomReplyAllMapper, SIGNAL( mapped( int ) ),
02503            this, SLOT( slotCustomReplyAllToMsg( int ) ) );
02504   mMsgActions->replyMenu()->insert( mCustomReplyAllActionMenu );
02505 
02506   mCustomTemplates.clear();
02507 
02508   QStringList list = GlobalSettingsBase::self()->customTemplates();
02509   QStringList::iterator it = list.begin();
02510   int idx = 0;
02511   int replyc = 0;
02512   int replyallc = 0;
02513   int forwardc = 0;
02514   for ( ; it != list.end(); ++it ) {
02515     CTemplates t( *it );
02516     mCustomTemplates.append( *it );
02517 
02518     KAction *action;
02519     switch ( t.type() ) {
02520     case CustomTemplates::TReply:
02521       action = new KAction( (*it).replace( "&", "&&" ),
02522                             KShortcut( t.shortcut() ),
02523                             mCustomReplyMapper,
02524                             SLOT( map() ),
02525                             actionCollection(),
02526                             (*it).utf8() );
02527       mCustomReplyMapper->setMapping( action, idx );
02528       mCustomReplyActionMenu->insert( action, idx );
02529       mCustomTemplateActions.append( action );
02530       ++replyc;
02531       break;
02532     case CustomTemplates::TReplyAll:
02533       action = new KAction( (*it).replace( "&", "&&" ),
02534                             KShortcut( t.shortcut() ),
02535                             mCustomReplyAllMapper,
02536                             SLOT( map() ),
02537                             actionCollection(),
02538                             (*it).utf8() );
02539       mCustomReplyAllMapper->setMapping( action, idx );
02540       mCustomReplyAllActionMenu->insert( action, idx );
02541       mCustomTemplateActions.append( action );
02542       ++replyallc;
02543       break;
02544     case CustomTemplates::TForward:
02545       action = new KAction( (*it).replace( "&", "&&" ),
02546                             KShortcut( t.shortcut() ),
02547                             mCustomForwardMapper,
02548                             SLOT( map() ),
02549                             actionCollection(),
02550                             (*it).utf8() );
02551       mCustomForwardMapper->setMapping( action, idx );
02552       mCustomForwardActionMenu->insert( action, idx );
02553       mCustomTemplateActions.append( action );
02554       ++forwardc;
02555       break;
02556     case CustomTemplates::TUniversal:
02557       action = new KAction( (*it).replace( "&", "&&" ),
02558                             KShortcut::null(),
02559                             mCustomReplyMapper,
02560                             SLOT( map() ),
02561                             actionCollection(),
02562                             (*it).utf8() );
02563       mCustomReplyMapper->setMapping( action, idx );
02564       mCustomReplyActionMenu->insert( action, idx );
02565       mCustomTemplateActions.append( action );
02566       ++replyc;
02567       action = new KAction( (*it).replace( "&", "&&" ),
02568                             KShortcut::null(),
02569                             mCustomReplyAllMapper,
02570                             SLOT( map() ),
02571                             actionCollection(),
02572                             (*it).utf8() );
02573       mCustomReplyAllMapper->setMapping( action, idx );
02574       mCustomReplyAllActionMenu->insert( action, idx );
02575       mCustomTemplateActions.append( action );
02576       ++replyallc;
02577       action = new KAction( (*it).replace( "&", "&&" ),
02578                             KShortcut::null(),
02579                             mCustomForwardMapper,
02580                             SLOT( map() ),
02581                             actionCollection(),
02582                             (*it).utf8() );
02583       mCustomForwardMapper->setMapping( action, idx );
02584       mCustomForwardActionMenu->insert( action, idx );
02585       mCustomTemplateActions.append( action );
02586       ++forwardc;
02587       break;
02588     }
02589 
02590     ++idx;
02591   }
02592   if ( !replyc ) {
02593       mCustomReplyActionMenu->popupMenu()->insertItem( i18n( "(no custom templates)" ), 0 );
02594       mCustomReplyActionMenu->popupMenu()->setItemEnabled( 0, false );
02595       mCustomReplyActionMenu->setEnabled(false);
02596   }
02597   if ( !replyallc ) {
02598       mCustomReplyAllActionMenu->popupMenu()->insertItem( i18n( "(no custom templates)" ), 0 );
02599       mCustomReplyAllActionMenu->popupMenu()->setItemEnabled( 0, false );
02600       mCustomReplyAllActionMenu->setEnabled(false);
02601   }
02602   if ( !forwardc ) {
02603       mCustomForwardActionMenu->popupMenu()->insertItem( i18n( "(no custom templates)" ), 0 );
02604       mCustomForwardActionMenu->popupMenu()->setItemEnabled( 0, false );
02605       mCustomForwardActionMenu->setEnabled(false);
02606   }
02607 
02608 }
02609 
02610 
02611 //-----------------------------------------------------------------------------
02612 void KMMainWidget::setupActions()
02613 {
02614   mMsgActions = new KMail::MessageActions( actionCollection(), this );
02615   mMsgActions->setMessageView( mMsgView );
02616 
02617   //----- File Menu
02618   mSaveAsAction = new KAction( i18n("Save &As..."), "filesave",
02619     KStdAccel::shortcut(KStdAccel::Save),
02620     this, SLOT(slotSaveMsg()), actionCollection(), "file_save_as" );
02621 
02622   mOpenAction = KStdAction::open( this, SLOT( slotOpenMsg() ),
02623                                   actionCollection() );
02624 
02625   (void) new KAction( i18n("&Compact All Folders"), 0,
02626               this, SLOT(slotCompactAll()),
02627               actionCollection(), "compact_all_folders" );
02628 
02629   (void) new KAction( i18n("&Expire All Folders"), 0,
02630               this, SLOT(slotExpireAll()),
02631               actionCollection(), "expire_all_folders" );
02632 
02633   (void) new KAction( i18n("&Refresh Local IMAP Cache"), "refresh",
02634               this, SLOT(slotInvalidateIMAPFolders()),
02635               actionCollection(), "file_invalidate_imap_cache" );
02636 
02637   (void) new KAction( i18n("Empty All &Trash Folders"), 0,
02638               KMKernel::self(), SLOT(slotEmptyTrash()),
02639               actionCollection(), "empty_trash" );
02640 
02641   (void) new KAction( i18n("Check &Mail"), "mail_get", CTRL+Key_L,
02642               this, SLOT(slotCheckMail()),
02643               actionCollection(), "check_mail" );
02644 
02645   mFavoritesCheckMailAction = new KAction( i18n("Check Mail in Favorite Folders"),
02646               "mail_get", CTRL+SHIFT+Key_L, 0, 0,
02647               actionCollection(), "favorite_check_mail" );
02648   if ( mFavoriteFolderView )
02649     connect( mFavoritesCheckMailAction, SIGNAL(activated()), mFavoriteFolderView, SLOT(checkMail()) );
02650 
02651   KActionMenu *actActionMenu = new
02652     KActionMenu( i18n("Check Mail &In"), "mail_get", actionCollection(),
02653                     "check_mail_in" );
02654   actActionMenu->setDelayed(true); //needed for checking "all accounts"
02655 
02656   connect(actActionMenu,SIGNAL(activated()),this,SLOT(slotCheckMail()));
02657 
02658   mActMenu = actActionMenu->popupMenu();
02659   connect(mActMenu,SIGNAL(activated(int)),this,SLOT(slotCheckOneAccount(int)));
02660   connect(mActMenu,SIGNAL(aboutToShow()),this,SLOT(getAccountMenu()));
02661 
02662   (void) new KAction( i18n("&Send Queued Messages"), "mail_send", 0, this,
02663              SLOT(slotSendQueued()), actionCollection(), "send_queued");
02664 
02665   (void) new KAction( i18n("Online Status (unknown)"), "online_status", 0, this,
02666                      SLOT(slotOnlineStatus()), actionCollection(), "online_status");
02667 
02668   KActionMenu *sendActionMenu = new
02669     KActionMenu( i18n("Send Queued Messages Via"), "mail_send_via", actionCollection(),
02670                                        "send_queued_via" );
02671   sendActionMenu->setDelayed(true);
02672 
02673   mSendMenu = sendActionMenu->popupMenu();
02674   connect(mSendMenu,SIGNAL(activated(int)), this, SLOT(slotSendQueuedVia(int)));
02675   connect(mSendMenu,SIGNAL(aboutToShow()),this,SLOT(getTransportMenu()));
02676 
02677   KAction *act;
02678   //----- Tools menu
02679   if (parent()->inherits("KMMainWin")) {
02680     act =  new KAction( i18n("&Address Book..."), "contents", 0, this,
02681             SLOT(slotAddrBook()), actionCollection(), "addressbook" );
02682     if (KStandardDirs::findExe("kaddressbook").isEmpty()) act->setEnabled(false);
02683   }
02684 
02685   act = new KAction( i18n("Certificate Manager..."), "pgp-keys", 0, this,
02686              SLOT(slotStartCertManager()), actionCollection(), "tools_start_certman");
02687   // disable action if no certman binary is around
02688   if (KStandardDirs::findExe("kleopatra").isEmpty()) act->setEnabled(false);
02689 
02690   act = new KAction( i18n("GnuPG Log Viewer..."), "pgp-keys", 0, this,
02691              SLOT(slotStartWatchGnuPG()), actionCollection(), "tools_start_kwatchgnupg");
02692   // disable action if no kwatchgnupg binary is around
02693   if (KStandardDirs::findExe("kwatchgnupg").isEmpty()) act->setEnabled(false);
02694 
02695   act = new KAction( i18n("&Import Messages..."), "fileopen", 0, this,
02696              SLOT(slotImport()), actionCollection(), "import" );
02697   if (KStandardDirs::findExe("kmailcvt").isEmpty()) act->setEnabled(false);
02698 
02699 #if !defined(NDEBUG)
02700   (void) new KAction( i18n("&Debug Sieve..."),
02701               "idea", 0, this, SLOT(slotDebugSieve()),
02702               actionCollection(), "tools_debug_sieve" );
02703 #endif
02704 
02705   if ( GlobalSettings::allowOutOfOfficeSettings() ) {
02706       (void) new KAction( i18n("Edit \"Out of Office\" Replies..."),
02707               "configure", 0, this, SLOT(slotEditVacation()),
02708               actionCollection(), "tools_edit_vacation" );
02709 
02710   }
02711 
02712   (void) new KAction( i18n("Filter &Log Viewer..."), 0, this,
02713               SLOT(slotFilterLogViewer()), actionCollection(), "filter_log_viewer" );
02714 
02715   (void) new KAction( i18n("&Anti-Spam Wizard..."), 0, this,
02716               SLOT(slotAntiSpamWizard()), actionCollection(), "antiSpamWizard" );
02717   (void) new KAction( i18n("&Anti-Virus Wizard..."), 0, this,
02718               SLOT(slotAntiVirusWizard()), actionCollection(), "antiVirusWizard" );
02719 
02720   //----- Edit Menu
02721   mTrashAction = new KAction( KGuiItem( i18n("&Move to Trash"), "edittrash",
02722                                        i18n("Move message to trashcan") ),
02723                              Key_Delete, this, SLOT(slotTrashMsg()),
02724                              actionCollection(), "move_to_trash" );
02725 
02726   /* The delete action is nowhere in the gui, by default, so we need to make
02727    * sure it is plugged into the KAccel now, since that won't happen on
02728    * XMLGui construction or manual ->plug(). This is only a problem when run
02729    * as a part, though. */
02730   mDeleteAction = new KAction( i18n("&Delete"), "editdelete", SHIFT+Key_Delete, this,
02731                               SLOT(slotDeleteMsg()), actionCollection(), "delete" );
02732   mDeleteAction->plugAccel( actionCollection()->kaccel() );
02733 
02734   mTrashThreadAction = new KAction( KGuiItem( i18n("M&ove Thread to Trash"), "edittrash",
02735                                        i18n("Move thread to trashcan") ),
02736                              CTRL+Key_Delete, this, SLOT(slotTrashThread()),
02737                              actionCollection(), "move_thread_to_trash" );
02738 
02739   mDeleteThreadAction = new KAction( i18n("Delete T&hread"), "editdelete", CTRL+SHIFT+Key_Delete, this,
02740                               SLOT(slotDeleteThread()), actionCollection(), "delete_thread" );
02741 
02742 
02743   (void) new KAction( i18n("&Find Messages..."), "mail_find", Key_S, this,
02744               SLOT(slotRequestFullSearchFromQuickSearch()), actionCollection(), "search_messages" );
02745 
02746   mFindInMessageAction = new KAction( i18n("&Find in Message..."), "find", KStdAccel::shortcut(KStdAccel::Find), this,
02747               SLOT(slotFind()), actionCollection(), "find_in_messages" );
02748 
02749   (void) new KAction( i18n("Select &All Messages"), KStdAccel::selectAll(), this,
02750               SLOT(slotMarkAll()), actionCollection(), "mark_all_messages" );
02751 
02752   //----- Folder Menu
02753   mNewFolderAction = new KAction( i18n("&New Folder..."), "folder_new", 0, mFolderTree,
02754               SLOT(addChildFolder()), actionCollection(), "new_folder" );
02755 
02756   mModifyFolderAction = new KAction( i18n("&Properties"), "configure", 0, this,
02757               SLOT(slotModifyFolder()), actionCollection(), "modify" );
02758 
02759   mFolderMailingListPropertiesAction = new KAction( i18n("&Mailing List Management..."),
02760       /*"folder_mailinglist_properties",*/ 0, this, SLOT( slotFolderMailingListProperties() ),
02761       actionCollection(), "folder_mailinglist_properties" );
02762 
02763   mFolderShortCutCommandAction = new KAction( i18n("&Assign Shortcut..."), "configure_shortcuts",
02764                       0, this, SLOT( slotFolderShortcutCommand() ), actionCollection(),
02765                       "folder_shortcut_command" );
02766 
02767 
02768   mMarkAllAsReadAction = new KAction( i18n("Mark All Messages as &Read"), "goto", 0, this,
02769               SLOT(slotMarkAllAsRead()), actionCollection(), "mark_all_as_read" );
02770 
02771   mExpireFolderAction = new KAction(i18n("&Expiration Settings"), 0, this, SLOT(slotExpireFolder()),
02772                    actionCollection(), "expire");
02773 
02774   mCompactFolderAction = new KAction( i18n("&Compact Folder"), 0, this,
02775               SLOT(slotCompactFolder()), actionCollection(), "compact" );
02776 
02777   mRefreshFolderAction = new KAction( i18n("Check Mail &in This Folder"), "reload",
02778                                       KStdAccel::shortcut( KStdAccel::Reload ), this,
02779                                       SLOT(slotRefreshFolder()),
02780                                       actionCollection(), "refresh_folder" );
02781   mTroubleshootFolderAction = 0; // set in initializeIMAPActions
02782 
02783   mEmptyFolderAction = new KAction( "foo" /*set in updateFolderMenu*/, "edittrash", 0, this,
02784               SLOT(slotEmptyFolder()), actionCollection(), "empty" );
02785 
02786   mRemoveFolderAction = new KAction( "foo" /*set in updateFolderMenu*/, "editdelete", 0, this,
02787               SLOT(slotRemoveFolder()), actionCollection(), "delete_folder" );
02788 
02789   mArchiveFolderAction = new KAction( i18n( "&Archive Folder..." ), "filesave", 0, this,
02790                                       SLOT( slotArchiveFolder() ), actionCollection(),
02791                                       "archive_folder" );
02792 
02793   mPreferHtmlAction = new KToggleAction( i18n("Prefer &HTML to Plain Text"), 0, this,
02794               SLOT(slotOverrideHtml()), actionCollection(), "prefer_html" );
02795 
02796   mPreferHtmlLoadExtAction = new KToggleAction( i18n("Load E&xternal References"), 0, this,
02797               SLOT(slotOverrideHtmlLoadExt()), actionCollection(), "prefer_html_external_refs" );
02798 
02799   mThreadMessagesAction = new KToggleAction( i18n("&Thread Messages"), 0, this,
02800               SLOT(slotOverrideThread()), actionCollection(), "thread_messages" );
02801 
02802   mThreadBySubjectAction = new KToggleAction( i18n("Thread Messages also by &Subject"), 0, this,
02803               SLOT(slotToggleSubjectThreading()), actionCollection(), "thread_messages_by_subject" );
02804 
02805   new KAction( i18n("Copy Folder"), "editcopy", SHIFT+CTRL+Key_C, folderTree(),
02806                SLOT(copyFolder()), actionCollection(), "copy_folder" );
02807   new KAction( i18n("Cut Folder"), "editcut", SHIFT+CTRL+Key_X, folderTree(),
02808                SLOT(cutFolder()), actionCollection(), "cut_folder" );
02809   new KAction( i18n("Paste Folder"), "editpaste", SHIFT+CTRL+Key_V, folderTree(),
02810                SLOT(pasteFolder()), actionCollection(), "paste_folder" );
02811 
02812   new KAction( i18n("Copy Messages"), "editcopy", ALT+CTRL+Key_C, headers(),
02813                SLOT(copyMessages()), actionCollection(), "copy_messages" );
02814   new KAction( i18n("Cut Messages"), "editcut", ALT+CTRL+Key_X, headers(),
02815                SLOT(cutMessages()), actionCollection(), "cut_messages" );
02816   new KAction( i18n("Paste Messages"), "editpaste", ALT+CTRL+Key_V, headers(),
02817                SLOT(pasteMessages()), actionCollection(), "paste_messages" );
02818 
02819   //----- Message Menu
02820   (void) new KAction( i18n("&New Message..."), "mail_new", KStdAccel::shortcut(KStdAccel::New), this,
02821               SLOT(slotCompose()), actionCollection(), "new_message" );
02822   mTemplateMenu =
02823     new KActionMenu( i18n("New Message From &Template"), "filenew",
02824                      actionCollection(), "new_from_template" );
02825   mTemplateMenu->setDelayed( true );
02826   connect( mTemplateMenu->popupMenu(), SIGNAL( aboutToShow() ), this,
02827            SLOT( slotShowNewFromTemplate() ) );
02828   connect( mTemplateMenu->popupMenu(), SIGNAL( activated(int) ), this,
02829            SLOT( slotNewFromTemplate(int) ) );
02830 
02831   KAction* newToML = new KAction( i18n("New Message t&o Mailing-List..."), "mail_post_to",
02832                       CTRL+SHIFT+Key_N, this,
02833               SLOT(slotPostToML()), actionCollection(), "post_message" );
02834   newToML->plugAccel( actionCollection()->kaccel() );
02835 
02836   mForwardActionMenu = new KActionMenu( i18n("Message->","&Forward"),
02837                     "mail_forward", actionCollection(),
02838                     "message_forward" );
02839 
02840       mForwardInlineAction = new KAction( i18n("&Inline..."),
02841                                       "mail_forward", 0, this,
02842                                       SLOT(slotForwardInlineMsg()),
02843                                       actionCollection(),
02844                                       "message_forward_inline" );
02845 
02846       mForwardAttachedAction = new KAction( i18n("Message->Forward->","As &Attachment..."),
02847                                         "mail_forward", 0, this,
02848                                         SLOT(slotForwardAttachedMsg()),
02849                                         actionCollection(),
02850                                         "message_forward_as_attachment" );
02851 
02852       mForwardDigestAction = new KAction( i18n("Message->Forward->","As Di&gest..."),
02853                                       "mail_forward", 0, this,
02854                                       SLOT(slotForwardDigestMsg()),
02855                                       actionCollection(),
02856                                       "message_forward_as_digest" );
02857 
02858       mRedirectAction = new KAction( i18n("Message->Forward->","&Redirect..."),
02859                                  "mail_forward", Key_E, this,
02860                                  SLOT(slotRedirectMsg()),
02861                                  actionCollection(),
02862                                  "message_forward_redirect" );
02863 
02864 
02865       setupForwardActions();
02866 
02867       mForwardActionMenu->insert( mForwardDigestAction );
02868       mForwardActionMenu->insert( mRedirectAction );
02869 
02870   mSendAgainAction = new KAction( i18n("Send A&gain..."), 0, this,
02871               SLOT(slotResendMsg()), actionCollection(), "send_again" );
02872 
02873 
02874   //----- Create filter actions
02875   mFilterMenu = new KActionMenu( i18n("&Create Filter"), "filter", actionCollection(), "create_filter" );
02876   connect( mFilterMenu, SIGNAL(activated()), this,
02877        SLOT(slotFilter()) );
02878   mSubjectFilterAction = new KAction( i18n("Filter on &Subject..."), 0, this,
02879                       SLOT(slotSubjectFilter()),
02880                       actionCollection(), "subject_filter");
02881   mFilterMenu->insert( mSubjectFilterAction );
02882 
02883   mFromFilterAction = new KAction( i18n("Filter on &From..."), 0, this,
02884                    SLOT(slotFromFilter()),
02885                    actionCollection(), "from_filter");
02886   mFilterMenu->insert( mFromFilterAction );
02887 
02888   mToFilterAction = new KAction( i18n("Filter on &To..."), 0, this,
02889                  SLOT(slotToFilter()),
02890                  actionCollection(), "to_filter");
02891   mFilterMenu->insert( mToFilterAction );
02892 
02893   mListFilterAction = new KAction( i18n("Filter on Mailing-&List..."), 0, this,
02894                                    SLOT(slotMailingListFilter()), actionCollection(),
02895                                    "mlist_filter");
02896   mFilterMenu->insert( mListFilterAction );
02897 
02898   mPrintAction = KStdAction::print (this, SLOT(slotPrintMsg()), actionCollection());
02899 
02900   mUseAction = new KAction( i18n("New Message From &Template"), "filenew",
02901                             Key_N, this, SLOT( slotUseTemplate() ),
02902                             actionCollection(), "use_template" );
02903   mUseAction->plugAccel( actionCollection()->kaccel() );
02904 
02905   //----- "Mark Thread" submenu
02906   mThreadStatusMenu = new KActionMenu ( i18n( "Mark &Thread" ),
02907                                        actionCollection(), "thread_status" );
02908 
02909   mMarkThreadAsReadAction = new KAction(KGuiItem(i18n("Mark Thread as &Read"), "kmmsgread",
02910                                                 i18n("Mark all messages in the selected thread as read")),
02911                                                 0, this, SLOT(slotSetThreadStatusRead()),
02912                                                 actionCollection(), "thread_read");
02913   mThreadStatusMenu->insert( mMarkThreadAsReadAction );
02914 
02915   mMarkThreadAsNewAction = new KAction(KGuiItem(i18n("Mark Thread as &New"), "kmmsgnew",
02916                                                i18n("Mark all messages in the selected thread as new")),
02917                                                0, this, SLOT(slotSetThreadStatusNew()),
02918                                                actionCollection(), "thread_new");
02919   mThreadStatusMenu->insert( mMarkThreadAsNewAction );
02920 
02921   mMarkThreadAsUnreadAction = new KAction(KGuiItem(i18n("Mark Thread as &Unread"), "kmmsgunseen",
02922                                                 i18n("Mark all messages in the selected thread as unread")),
02923                                                 0, this, SLOT(slotSetThreadStatusUnread()),
02924                                                 actionCollection(), "thread_unread");
02925   mThreadStatusMenu->insert( mMarkThreadAsUnreadAction );
02926 
02927   mThreadStatusMenu->insert( new KActionSeparator( this ) );
02928 
02929   //----- "Mark Thread" toggle actions
02930   mToggleThreadFlagAction = new KToggleAction(i18n("Mark Thread as &Important"), "mail_flag",
02931                                        0, this, SLOT(slotSetThreadStatusFlag()),
02932                                        actionCollection(), "thread_flag");
02933   mToggleThreadFlagAction->setCheckedState( i18n("Remove &Important Thread Mark") );
02934   mThreadStatusMenu->insert( mToggleThreadFlagAction );
02935 
02936   mToggleThreadTodoAction = new KToggleAction(i18n("Mark Thread as &Action Item"), "mail_todo",
02937                                        0, this, SLOT(slotSetThreadStatusTodo()),
02938                                        actionCollection(), "thread_todo");
02939   mToggleThreadTodoAction->setCheckedState( i18n("Remove &Action Item Thread Mark") );
02940   mThreadStatusMenu->insert( mToggleThreadTodoAction );
02941 
02942   //------- "Watch and ignore thread" actions
02943   mWatchThreadAction = new KToggleAction(i18n("&Watch Thread"), "kmmsgwatched",
02944                                        0, this, SLOT(slotSetThreadStatusWatched()),
02945                                        actionCollection(), "thread_watched");
02946 
02947   mIgnoreThreadAction = new KToggleAction(i18n("&Ignore Thread"), "mail_ignore",
02948                                        0, this, SLOT(slotSetThreadStatusIgnored()),
02949                                        actionCollection(), "thread_ignored");
02950 
02951   mThreadStatusMenu->insert( new KActionSeparator( this ) );
02952   mThreadStatusMenu->insert( mWatchThreadAction );
02953   mThreadStatusMenu->insert( mIgnoreThreadAction );
02954 
02955   mSaveAttachmentsAction = new KAction( i18n("Save A&ttachments..."), "attach",
02956                                 0, this, SLOT(slotSaveAttachments()),
02957                                 actionCollection(), "file_save_attachments" );
02958 
02959   mMoveActionMenu = new KActionMenu( i18n("&Move To" ),
02960                                     actionCollection(), "move_to" );
02961 
02962   mCopyActionMenu = new KActionMenu( i18n("&Copy To" ),
02963                                     actionCollection(), "copy_to" );
02964 
02965   mApplyAllFiltersAction = new KAction( i18n("Appl&y All Filters"), "filter",
02966                     CTRL+Key_J, this,
02967                     SLOT(slotApplyFilters()),
02968                     actionCollection(), "apply_filters" );
02969 
02970   mApplyFilterActionsMenu = new KActionMenu( i18n("A&pply Filter" ),
02971                         actionCollection(),
02972                         "apply_filter_actions" );
02973 
02974   //----- View Menu
02975   // Unread Submenu
02976   KActionMenu * unreadMenu =
02977     new KActionMenu( i18n("View->", "&Unread Count"),
02978              actionCollection(), "view_unread" );
02979   unreadMenu->setToolTip( i18n("Choose how to display the count of unread messages") );
02980 
02981   mUnreadColumnToggle = new KRadioAction( i18n("View->Unread Count", "View in &Separate Column"), 0, this,
02982                    SLOT(slotToggleUnread()),
02983                    actionCollection(), "view_unread_column" );
02984   mUnreadColumnToggle->setExclusiveGroup( "view_unread_group" );
02985   unreadMenu->insert( mUnreadColumnToggle );
02986 
02987   mUnreadTextToggle = new KRadioAction( i18n("View->Unread Count", "View After &Folder Name"), 0, this,
02988                    SLOT(slotToggleUnread()),
02989                    actionCollection(), "view_unread_text" );
02990   mUnreadTextToggle->setExclusiveGroup( "view_unread_group" );
02991   unreadMenu->insert( mUnreadTextToggle );
02992 
02993   // toggle for total column
02994   mTotalColumnToggle = new KToggleAction( i18n("View->", "&Total Column"), 0, this,
02995                    SLOT(slotToggleTotalColumn()),
02996                    actionCollection(), "view_columns_total" );
02997   mTotalColumnToggle->setToolTip( i18n("Toggle display of column showing the "
02998                                       "total number of messages in folders.") );
02999   mSizeColumnToggle = new KToggleAction( i18n("View->", "&Size Column"), 0, this,
03000                    SLOT(slotToggleSizeColumn()),
03001                    actionCollection(), "view_columns_size" );
03002   mSizeColumnToggle->setToolTip( i18n("Toggle display of column showing the "
03003                                       "total size of messages in folders.") );
03004 
03005   (void)new KAction( KGuiItem( i18n("View->","&Expand Thread"), QString::null,
03006                    i18n("Expand the current thread") ),
03007              Key_Period, this,
03008              SLOT(slotExpandThread()),
03009              actionCollection(), "expand_thread" );
03010 
03011   (void)new KAction( KGuiItem( i18n("View->","&Collapse Thread"), QString::null,
03012                    i18n("Collapse the current thread") ),
03013              Key_Comma, this,
03014              SLOT(slotCollapseThread()),
03015              actionCollection(), "collapse_thread" );
03016 
03017   (void)new KAction( KGuiItem( i18n("View->","Ex&pand All Threads"), QString::null,
03018                    i18n("Expand all threads in the current folder") ),
03019              CTRL+Key_Period, this,
03020              SLOT(slotExpandAllThreads()),
03021              actionCollection(), "expand_all_threads" );
03022 
03023   (void)new KAction( KGuiItem( i18n("View->","C&ollapse All Threads"), QString::null,
03024                    i18n("Collapse all threads in the current folder") ),
03025              CTRL+Key_Comma, this,
03026              SLOT(slotCollapseAllThreads()),
03027              actionCollection(), "collapse_all_threads" );
03028 
03029   mViewSourceAction = new KAction( i18n("&View Source"), Key_V, this,
03030                                    SLOT(slotShowMsgSrc()), actionCollection(),
03031                                    "view_source" );
03032 
03033   KAction* dukeOfMonmoth = new KAction( i18n("&Display Message"), Key_Return, this,
03034                         SLOT( slotDisplayCurrentMessage() ), actionCollection(),
03035                         "display_message" );
03036   dukeOfMonmoth->plugAccel( actionCollection()->kaccel() );
03037 
03038   //----- Go Menu
03039   new KAction( KGuiItem( i18n("&Next Message"), QString::null,
03040                          i18n("Go to the next message") ),
03041                          "N;Right", this, SLOT(slotNextMessage()),
03042                          actionCollection(), "go_next_message" );
03043 
03044   new KAction( KGuiItem( i18n("Next &Unread Message"),
03045                          QApplication::reverseLayout() ? "previous" : "next",
03046                          i18n("Go to the next unread message") ),
03047                          Key_Plus, this, SLOT(slotNextUnreadMessage()),
03048                          actionCollection(), "go_next_unread_message" );
03049 
03050   /* ### needs better support from folders:
03051   new KAction( KGuiItem( i18n("Next &Important Message"), QString::null,
03052                          i18n("Go to the next important message") ),
03053                          0, this, SLOT(slotNextImportantMessage()),
03054                          actionCollection(), "go_next_important_message" );
03055   */
03056 
03057   new KAction( KGuiItem( i18n("&Previous Message"), QString::null,
03058                          i18n("Go to the previous message") ),
03059                          "P;Left", this, SLOT(slotPrevMessage()),
03060                          actionCollection(), "go_prev_message" );
03061 
03062   new KAction( KGuiItem( i18n("Previous Unread &Message"),
03063                          QApplication::reverseLayout() ? "next" : "previous",
03064                          i18n("Go to the previous unread message") ),
03065                          Key_Minus, this, SLOT(slotPrevUnreadMessage()),
03066                          actionCollection(), "go_prev_unread_message" );
03067 
03068   /* needs better support from folders:
03069   new KAction( KGuiItem( i18n("Previous I&mportant Message"), QString::null,
03070                          i18n("Go to the previous important message") ),
03071                          0, this, SLOT(slotPrevImportantMessage()),
03072                          actionCollection(), "go_prev_important_message" );
03073   */
03074 
03075   KAction *action =
03076     new KAction( KGuiItem( i18n("Next Unread &Folder"), QString::null,
03077                            i18n("Go to the next folder with unread messages") ),
03078                            ALT+Key_Plus, this, SLOT(slotNextUnreadFolder()),
03079                            actionCollection(), "go_next_unread_folder" );
03080   KShortcut shortcut = action->shortcut();
03081   shortcut.append( KKey( CTRL+Key_Plus ) );
03082   action->setShortcut( shortcut );
03083 
03084   action =
03085     new KAction( KGuiItem( i18n("Previous Unread F&older"), QString::null,
03086                            i18n("Go to the previous folder with unread messages") ),
03087                            ALT+Key_Minus, this, SLOT(slotPrevUnreadFolder()),
03088                            actionCollection(), "go_prev_unread_folder" );
03089   shortcut = action->shortcut();
03090   shortcut.append( KKey( CTRL+Key_Minus ) );
03091   action->setShortcut( shortcut );
03092 
03093   new KAction( KGuiItem( i18n("Go->","Next Unread &Text"), QString::null,
03094                          i18n("Go to the next unread text"),
03095                          i18n("Scroll down current message. "
03096                               "If at end of current message, "
03097                               "go to next unread message.") ),
03098                          Key_Space, this, SLOT(slotReadOn()),
03099                          actionCollection(), "go_next_unread_text" );
03100 
03101   //----- Settings Menu
03102   mToggleShowQuickSearchAction = new KToggleAction(i18n("Show Quick Search"), QString::null,
03103                                        0, this, SLOT(slotToggleShowQuickSearch()),
03104                                        actionCollection(), "show_quick_search");
03105   mToggleShowQuickSearchAction->setChecked( GlobalSettings::self()->quickSearchActive() );
03106   mToggleShowQuickSearchAction->setWhatsThis(
03107         i18n( GlobalSettings::self()->quickSearchActiveItem()->whatsThis().utf8() ) );
03108 
03109   (void) new KAction( i18n("Configure &Filters..."), 0, this,
03110               SLOT(slotFilter()), actionCollection(), "filter" );
03111   (void) new KAction( i18n("Configure &POP Filters..."), 0, this,
03112               SLOT(slotPopFilter()), actionCollection(), "popFilter" );
03113   (void) new KAction( i18n("Manage &Sieve Scripts..."), 0, this,
03114                       SLOT(slotManageSieveScripts()), actionCollection(), "sieveFilters" );
03115 
03116   (void) new KAction( KGuiItem( i18n("KMail &Introduction"), 0,
03117                 i18n("Display KMail's Welcome Page") ),
03118               0, this, SLOT(slotIntro()),
03119               actionCollection(), "help_kmail_welcomepage" );
03120 
03121   // ----- Standard Actions
03122 //  KStdAction::configureNotifications(this, SLOT(slotEditNotifications()), actionCollection());
03123   (void) new KAction( i18n("Configure &Notifications..."),
03124               "knotify", 0, this,
03125               SLOT(slotEditNotifications()), actionCollection(),
03126               "kmail_configure_notifications" );
03127 //  KStdAction::preferences(this, SLOT(slotSettings()), actionCollection());
03128   (void) new KAction( i18n("&Configure KMail..."),
03129               "configure", 0, kmkernel,
03130                       SLOT(slotShowConfigurationDialog()), actionCollection(),
03131                       "kmail_configure_kmail" );
03132 
03133   KStdAction::undo(this, SLOT(slotUndo()), actionCollection(), "kmail_undo");
03134 
03135   KStdAction::tipOfDay( this, SLOT( slotShowTip() ), actionCollection() );
03136 
03137   menutimer = new QTimer( this, "menutimer" );
03138   connect( menutimer, SIGNAL( timeout() ), SLOT( updateMessageActions() ) );
03139   connect( kmkernel->undoStack(),
03140            SIGNAL( undoStackChanged() ), this, SLOT( slotUpdateUndo() ));
03141 
03142   initializeIMAPActions( false ); // don't set state, config not read yet
03143   updateMessageActions();
03144   updateCustomTemplateMenus();
03145   updateFolderMenu();
03146 }
03147 
03148 void KMMainWidget::setupForwardingActionsList()
03149 {
03150   QPtrList<KAction> mForwardActionList;
03151   if ( GlobalSettings::self()->forwardingInlineByDefault() ) {
03152       mGUIClient->unplugActionList( "forward_action_list" );
03153       mForwardActionList.append( mForwardInlineAction );
03154       mForwardActionList.append( mForwardAttachedAction );
03155       mForwardActionList.append( mForwardDigestAction );
03156       mForwardActionList.append( mRedirectAction );
03157       mGUIClient->plugActionList( "forward_action_list", mForwardActionList );
03158   } else {
03159       mGUIClient->unplugActionList( "forward_action_list" );
03160       mForwardActionList.append( mForwardAttachedAction );
03161       mForwardActionList.append( mForwardInlineAction );
03162       mForwardActionList.append( mForwardDigestAction );
03163       mForwardActionList.append( mRedirectAction );
03164       mGUIClient->plugActionList( "forward_action_list", mForwardActionList );
03165   }
03166 }
03167 
03168 //-----------------------------------------------------------------------------
03169 void KMMainWidget::slotEditNotifications()
03170 {
03171   if(kmkernel->xmlGuiInstance())
03172     KNotifyDialog::configure(this, 0, kmkernel->xmlGuiInstance()->aboutData());
03173   else
03174     KNotifyDialog::configure(this);
03175 }
03176 
03177 void KMMainWidget::slotEditKeys()
03178 {
03179   KKeyDialog::configure( actionCollection(),
03180              true /*allow one-letter shortcuts*/
03181              );
03182 }
03183 
03184 //-----------------------------------------------------------------------------
03185 void KMMainWidget::slotReadOn()
03186 {
03187     if ( !mMsgView )
03188         return;
03189 
03190     if ( !mMsgView->atBottom() ) {
03191         mMsgView->slotJumpDown();
03192         return;
03193     }
03194     slotNextUnreadMessage();
03195 }
03196 
03197 void KMMainWidget::slotNextUnreadFolder() {
03198   if ( !mFolderTree ) return;
03199   mFolderTree->nextUnreadFolder();
03200 }
03201 
03202 void KMMainWidget::slotPrevUnreadFolder() {
03203   if ( !mFolderTree ) return;
03204   mFolderTree->prevUnreadFolder();
03205 }
03206 
03207 void KMMainWidget::slotExpandThread()
03208 {
03209   mHeaders->slotExpandOrCollapseThread( true ); // expand
03210 }
03211 
03212 void KMMainWidget::slotCollapseThread()
03213 {
03214   mHeaders->slotExpandOrCollapseThread( false ); // collapse
03215 }
03216 
03217 void KMMainWidget::slotExpandAllThreads()
03218 {
03219   mHeaders->slotExpandOrCollapseAllThreads( true ); // expand
03220 }
03221 
03222 void KMMainWidget::slotCollapseAllThreads()
03223 {
03224   mHeaders->slotExpandOrCollapseAllThreads( false ); // collapse
03225 }
03226 
03227 //-----------------------------------------------------------------------------
03228 void KMMainWidget::slotShowMsgSrc()
03229 {
03230   if ( mMsgView )
03231     mMsgView->setUpdateAttachment( false );
03232   KMMessage *msg = mHeaders->currentMsg();
03233   if ( !msg )
03234     return;
03235   KMCommand *command = new KMShowMsgSrcCommand( this, msg,
03236                                                 mMsgView
03237                                                 ? mMsgView->isFixedFont()
03238                                                 : false );
03239   command->start();
03240 }
03241 
03242 
03243 //-----------------------------------------------------------------------------
03244 void KMMainWidget::moveSelectedToFolder( int menuId )
03245 {
03246   if (mMenuToFolder[menuId])
03247     mHeaders->moveMsgToFolder( mMenuToFolder[menuId] );
03248 }
03249 
03250 
03251 //-----------------------------------------------------------------------------
03252 void KMMainWidget::copySelectedToFolder(int menuId )
03253 {
03254   if (mMenuToFolder[menuId])
03255     mHeaders->copyMsgToFolder( mMenuToFolder[menuId] );
03256 }
03257 
03258 
03259 //-----------------------------------------------------------------------------
03260 void KMMainWidget::updateMessageMenu()
03261 {
03262   mMenuToFolder.clear();
03263   folderTree()->folderToPopupMenu( KMFolderTree::MoveMessage, this,
03264       &mMenuToFolder, mMoveActionMenu->popupMenu() );
03265   folderTree()->folderToPopupMenu( KMFolderTree::CopyMessage, this,
03266       &mMenuToFolder, mCopyActionMenu->popupMenu() );
03267   updateMessageActions();
03268 }
03269 
03270 void KMMainWidget::startUpdateMessageActionsTimer()
03271 {
03272     menutimer->stop();
03273     menutimer->start( 20, true );
03274 }
03275 
03276 void KMMainWidget::updateMessageActions()
03277 {
03278     int count = 0;
03279     QPtrList<QListViewItem> selectedItems;
03280 
03281     if ( mFolder ) {
03282       for (QListViewItem *item = mHeaders->firstChild(); item; item = item->itemBelow())
03283         if (item->isSelected() )
03284           selectedItems.append(item);
03285       if ( selectedItems.isEmpty() && mFolder->count() ) // there will always be one in mMsgView
03286         count = 1;
03287       else
03288         count = selectedItems.count();
03289       mMsgActions->setCurrentMessage( mHeaders->currentMsg() );
03290       mMsgActions->setSelectedSernums( mHeaders->selectedSernums() );
03291       mMsgActions->setSelectedVisibleSernums( mHeaders->selectedVisibleSernums() );
03292     } else {
03293       mMsgActions->setCurrentMessage( 0 );
03294     }
03295 
03296     updateListFilterAction();
03297 
03298     bool allSelectedInCommonThread = false;
03299     if ( mHeaders->isThreaded() && count > 1 ) {
03300       allSelectedInCommonThread = true;
03301       for ( QPtrListIterator<QListViewItem> it( selectedItems ) ;
03302             it.current() ; ++ it ) {
03303         QListViewItem * item = *it;
03304         if ( item->parent()==0 && item->childCount()==0 ) {
03305           allSelectedInCommonThread = false;
03306           break;
03307         }
03308       }
03309     }
03310     else if ( mHeaders->isThreaded() && count == 1 ) {
03311       allSelectedInCommonThread = true;
03312     }
03313 
03314     QListViewItem *curItemParent = mHeaders->currentItem();
03315     bool parent_thread = 0;
03316     if ( curItemParent && curItemParent->firstChild() != 0 ) parent_thread = 1;
03317 
03318     bool mass_actions = count >= 1;
03319     bool thread_actions = mass_actions && allSelectedInCommonThread &&
03320                           mHeaders->isThreaded();
03321     bool flags_available = GlobalSettings::self()->allowLocalFlags() || !(mFolder ? mFolder->isReadOnly() : true);
03322     mThreadStatusMenu->setEnabled( thread_actions );
03323     // these need to be handled individually, the user might have them
03324     // in the toolbar
03325     mWatchThreadAction->setEnabled( thread_actions && flags_available );
03326     mIgnoreThreadAction->setEnabled( thread_actions && flags_available );
03327     mMarkThreadAsNewAction->setEnabled( thread_actions );
03328     mMarkThreadAsReadAction->setEnabled( thread_actions );
03329     mMarkThreadAsUnreadAction->setEnabled( thread_actions );
03330     mToggleThreadTodoAction->setEnabled( thread_actions && flags_available );
03331     mToggleThreadFlagAction->setEnabled( thread_actions && flags_available );
03332     mTrashThreadAction->setEnabled( thread_actions && mFolder->canDeleteMessages() );
03333     mDeleteThreadAction->setEnabled( thread_actions && mFolder->canDeleteMessages() );
03334 
03335     if (mFolder && mHeaders && mHeaders->currentMsg()) {
03336       if (thread_actions) {
03337         mToggleThreadTodoAction->setChecked(mHeaders->currentMsg()->isTodo());
03338         mToggleThreadFlagAction->setChecked(mHeaders->currentMsg()->isImportant());
03339         mWatchThreadAction->setChecked( mHeaders->currentMsg()->isWatched());
03340         mIgnoreThreadAction->setChecked( mHeaders->currentMsg()->isIgnored());
03341       }
03342     }
03343 
03344     mMoveActionMenu->setEnabled( mass_actions && mFolder->canDeleteMessages() );
03345     mMoveMsgToFolderAction->setEnabled( mass_actions && mFolder->canDeleteMessages() );
03346     mCopyActionMenu->setEnabled( mass_actions );
03347     mTrashAction->setEnabled( mass_actions && mFolder->canDeleteMessages() );
03348     mDeleteAction->setEnabled( mass_actions && mFolder->canDeleteMessages() );
03349     mFindInMessageAction->setEnabled( mass_actions && !kmkernel->folderIsTemplates( mFolder ) );
03350     mForwardInlineAction->setEnabled( mass_actions && !kmkernel->folderIsTemplates( mFolder ));
03351     mForwardAttachedAction->setEnabled( mass_actions && !kmkernel->folderIsTemplates( mFolder ) );
03352     mForwardDigestAction->setEnabled( ( count > 1 || parent_thread ) && !kmkernel->folderIsTemplates( mFolder ) );
03353 
03354     forwardMenu()->setEnabled( mass_actions && !kmkernel->folderIsTemplates( mFolder ));
03355 
03356     bool single_actions = count == 1;
03357     mUseAction->setEnabled( single_actions &&
03358                             kmkernel->folderIsTemplates( mFolder ) );
03359     filterMenu()->setEnabled( single_actions );
03360     redirectAction()->setEnabled( single_actions && !kmkernel->folderIsTemplates( mFolder ) );
03361     printAction()->setEnabled( single_actions );
03362     viewSourceAction()->setEnabled( single_actions );
03363 
03364     mSendAgainAction->setEnabled( single_actions
03365           && ( ( mHeaders->currentMsg() && mHeaders->currentMsg()->isSent() )
03366           ||   ( mFolder && mHeaders->currentMsg() &&
03367                  kmkernel->folderIsSentMailFolder( mFolder ) ) ) );
03368     mSaveAsAction->setEnabled( mass_actions );
03369     bool mails = mFolder && mFolder->count();
03370     bool enable_goto_unread = mails
03371        || (GlobalSettings::self()->loopOnGotoUnread() == GlobalSettings::EnumLoopOnGotoUnread::LoopInAllFolders);
03372     actionCollection()->action( "go_next_message" )->setEnabled( mails );
03373     actionCollection()->action( "go_next_unread_message" )->setEnabled( enable_goto_unread );
03374     actionCollection()->action( "go_prev_message" )->setEnabled( mails );
03375     actionCollection()->action( "go_prev_unread_message" )->setEnabled( enable_goto_unread );
03376     actionCollection()->action( "send_queued" )->setEnabled( kmkernel->outboxFolder()->count() > 0 );
03377     actionCollection()->action( "send_queued_via" )->setEnabled( kmkernel->outboxFolder()->count() > 0 );
03378     slotUpdateOnlineStatus( static_cast<GlobalSettingsBase::EnumNetworkState::type>( GlobalSettings::self()->networkState() ) );
03379     if (action( "edit_undo" ))
03380       action( "edit_undo" )->setEnabled( mHeaders->canUndo() );
03381 
03382     if ( count == 1 ) {
03383       KMMessage *msg;
03384       int aIdx;
03385       if((aIdx = mHeaders->currentItemIndex()) <= -1)
03386         return;
03387       if(!(msg = mFolder->getMsg(aIdx)))
03388         return;
03389 
03390       if ((KMFolder*)mFolder == kmkernel->outboxFolder())
03391         editAction()->setEnabled( !msg->transferInProgress() );
03392     }
03393 
03394     mApplyAllFiltersAction->setEnabled(count);
03395     mApplyFilterActionsMenu->setEnabled(count);
03396 }
03397 
03398 // This needs to be updated more often, so it is in its method.
03399 void KMMainWidget::updateMarkAsReadAction()
03400 {
03401   mMarkAllAsReadAction->setEnabled( mFolder && (mFolder->countUnread() > 0) );
03402 }
03403 
03404 //-----------------------------------------------------------------------------
03405 void KMMainWidget::updateFolderMenu()
03406 {
03407   bool folderWithContent = mFolder && !mFolder->noContent();
03408   bool multiFolder = folderTree()->selectedFolders().count() > 1;
03409   mModifyFolderAction->setEnabled( folderWithContent && !multiFolder );
03410   mFolderMailingListPropertiesAction->setEnabled( folderWithContent && !multiFolder );
03411   mCompactFolderAction->setEnabled( folderWithContent && !multiFolder );
03412 
03413   // This is the refresh-folder action in the menu. See kmfoldertree for the one in the RMB...
03414   bool imap = mFolder && mFolder->folderType() == KMFolderTypeImap;
03415   bool cachedImap = mFolder && mFolder->folderType() == KMFolderTypeCachedImap;
03416   // For dimap, check that the imap path is known before allowing "check mail in this folder".
03417   bool knownImapPath = cachedImap && !static_cast<KMFolderCachedImap*>( mFolder->storage() )->imapPath().isEmpty();
03418   mRefreshFolderAction->setEnabled( folderWithContent && ( imap
03419                                                            || ( cachedImap && knownImapPath ) ) && !multiFolder );
03420   if ( mTroubleshootFolderAction )
03421     mTroubleshootFolderAction->setEnabled( folderWithContent && ( cachedImap && knownImapPath ) && !multiFolder );
03422   mEmptyFolderAction->setEnabled( folderWithContent && ( mFolder->count() > 0 ) && mFolder->canDeleteMessages() && !multiFolder );
03423   mEmptyFolderAction->setText( (mFolder && kmkernel->folderIsTrash(mFolder))
03424     ? i18n("E&mpty Trash") : i18n("&Move All Messages to Trash") );
03425   mRemoveFolderAction->setEnabled( mFolder && !mFolder->isSystemFolder() && mFolder->canDeleteMessages() && !multiFolder);
03426   mRemoveFolderAction->setText( mFolder && mFolder->folderType() == KMFolderTypeSearch
03427         ? i18n("&Delete Search") : i18n("&Delete Folder") );
03428   if ( mArchiveFolderAction )
03429     mArchiveFolderAction->setEnabled( mFolder && !multiFolder );
03430   mExpireFolderAction->setEnabled( mFolder && mFolder->isAutoExpire() && !multiFolder && mFolder->canDeleteMessages() );
03431   updateMarkAsReadAction();
03432   // the visual ones only make sense if we are showing a message list
03433   mPreferHtmlAction->setEnabled( mHeaders->folder() ? true : false );
03434   mPreferHtmlLoadExtAction->setEnabled( mHeaders->folder() && (mHtmlPref ? !mFolderHtmlPref : mFolderHtmlPref) ? true : false );
03435   mThreadMessagesAction->setEnabled( mHeaders->folder() ? true : false );
03436 
03437   mPreferHtmlAction->setChecked( mHtmlPref ? !mFolderHtmlPref : mFolderHtmlPref );
03438   mPreferHtmlLoadExtAction->setChecked( mHtmlLoadExtPref ? !mFolderHtmlLoadExtPref : mFolderHtmlLoadExtPref );
03439   mThreadMessagesAction->setChecked(
03440       mThreadPref ? !mFolderThreadPref : mFolderThreadPref );
03441   mThreadBySubjectAction->setEnabled(
03442       mHeaders->folder() ? ( mThreadMessagesAction->isChecked()) : false );
03443   mThreadBySubjectAction->setChecked( mFolderThreadSubjPref );
03444 
03445   mNewFolderAction->setEnabled( !multiFolder && ( mFolder && mFolder->folderType() != KMFolderTypeSearch ));
03446   mRemoveDuplicatesAction->setEnabled( !multiFolder && mFolder && mFolder->canDeleteMessages() );
03447   mFolderShortCutCommandAction->setEnabled( !multiFolder );
03448 }
03449 
03450 
03451 #ifdef MALLOC_DEBUG
03452 static QString fmt(long n) {
03453   char buf[32];
03454 
03455   if(n > 1024*1024*1024)
03456     sprintf(buf, "%0.2f GB", ((double)n)/1024.0/1024.0/1024.0);
03457   else if(n > 1024*1024)
03458     sprintf(buf, "%0.2f MB", ((double)n)/1024.0/1024.0);
03459   else if(n > 1024)
03460     sprintf(buf, "%0.2f KB", ((double)n)/1024.0);
03461   else
03462     sprintf(buf, "%ld Byte", n);
03463   return QString(buf);
03464 }
03465 #endif
03466 
03467 void KMMainWidget::slotMemInfo() {
03468 #ifdef MALLOC_DEBUG
03469   struct mallinfo mi;
03470 
03471   mi = mallinfo();
03472   QString s = QString("\nMALLOC - Info\n\n"
03473               "Number of mmapped regions : %1\n"
03474               "Memory allocated in use   : %2\n"
03475               "Memory allocated, not used: %3\n"
03476               "Memory total allocated    : %4\n"
03477               "Max. freeable memory      : %5\n")
03478     .arg(mi.hblks).arg(fmt(mi.uordblks)).arg(fmt(mi.fordblks))
03479     .arg(fmt(mi.arena)).arg(fmt(mi.keepcost));
03480   KMessageBox::information(0, s, "Malloc information", s);
03481 #endif
03482 }
03483 
03484 
03485 //-----------------------------------------------------------------------------
03486 void KMMainWidget::slotIntro()
03487 {
03488   if ( !mMsgView ) return;
03489 
03490   mMsgView->clear( true );
03491   // hide widgets that are in the way:
03492   if ( mSearchAndHeaders && mHeaders && mLongFolderList )
03493     mSearchAndHeaders->hide();
03494 
03495 
03496   mMsgView->displayAboutPage();
03497 
03498   mFolder = 0;
03499 }
03500 
03501 void KMMainWidget::slotShowStartupFolder()
03502 {
03503   if ( mFolderTree ) {
03504     mFolderTree->reload();
03505     mFolderTree->readConfig();
03506     // get rid of old-folders
03507     mFolderTree->cleanupConfigFile();
03508   }
03509 
03510   connect( kmkernel->filterMgr(), SIGNAL( filterListUpdated() ),
03511        this, SLOT( initializeFilterActions() ));
03512 
03513   // plug shortcut filter actions now
03514   initializeFilterActions();
03515 
03516   // plug folder shortcut actions
03517   initializeFolderShortcutActions();
03518 
03519   QString newFeaturesMD5 = KMReaderWin::newFeaturesMD5();
03520   if ( kmkernel->firstStart() ||
03521        GlobalSettings::self()->previousNewFeaturesMD5() != newFeaturesMD5 ) {
03522     GlobalSettings::self()->setPreviousNewFeaturesMD5( newFeaturesMD5 );
03523     slotIntro();
03524     return;
03525   }
03526 
03527   KMFolder* startup = 0;
03528   if ( !mStartupFolder.isEmpty() ) {
03529     // find the startup-folder
03530     startup = kmkernel->findFolderById( mStartupFolder );
03531   }
03532   if ( !startup )
03533     startup = kmkernel->inboxFolder();
03534 
03535   if ( mFolderTree ) {
03536     mFolderTree->showFolder( startup );
03537   }
03538 }
03539 
03540 void KMMainWidget::slotShowTip()
03541 {
03542   KTipDialog::showTip( this, QString::null, true );
03543 }
03544 
03545 //-----------------------------------------------------------------------------
03546 void KMMainWidget::slotChangeCaption(QListViewItem * i)
03547 {
03548   if ( !i ) return;
03549   // set the caption to the current full path
03550   QStringList names;
03551   for ( QListViewItem * item = i ; item ; item = item->parent() )
03552     names.prepend( item->text(0) );
03553   emit captionChangeRequest( names.join( "/" ) );
03554 }
03555 
03556 //-----------------------------------------------------------------------------
03557 void KMMainWidget::removeDuplicates()
03558 {
03559   if (!mFolder)
03560     return;
03561   KMFolder *oFolder = mFolder;
03562   mHeaders->setFolder(0);
03563   QMap< QString, QValueList<int> > idMD5s;
03564   QValueList<int> redundantIds;
03565   QValueList<int>::Iterator kt;
03566   mFolder->open("removedups");
03567   for (int i = mFolder->count() - 1; i >= 0; --i) {
03568     QString id = (*mFolder)[i]->msgIdMD5();
03569     if ( !id.isEmpty() ) {
03570       QString subjMD5 = (*mFolder)[i]->strippedSubjectMD5();
03571       int other = -1;
03572       if ( idMD5s.contains(id) )
03573         other = idMD5s[id].first();
03574       else
03575         idMD5s[id].append( i );
03576       if ( other != -1 ) {
03577         QString otherSubjMD5 = (*mFolder)[other]->strippedSubjectMD5();
03578         if (otherSubjMD5 == subjMD5)
03579           idMD5s[id].append( i );
03580       }
03581     }
03582   }
03583   QMap< QString, QValueList<int> >::Iterator it;
03584   for ( it = idMD5s.begin(); it != idMD5s.end() ; ++it ) {
03585     QValueList<int>::Iterator jt;
03586     bool finished = false;
03587     for ( jt = (*it).begin(); jt != (*it).end() && !finished; ++jt )
03588       if (!((*mFolder)[*jt]->isUnread())) {
03589         (*it).remove( jt );
03590         (*it).prepend( *jt );
03591         finished = true;
03592       }
03593     for ( jt = (*it).begin(), ++jt; jt != (*it).end(); ++jt )
03594       redundantIds.append( *jt );
03595   }
03596   qHeapSort( redundantIds );
03597   kt = redundantIds.end();
03598   int numDuplicates = 0;
03599   if (kt != redundantIds.begin()) do {
03600     mFolder->removeMsg( *(--kt) );
03601     ++numDuplicates;
03602   }
03603   while (kt != redundantIds.begin());
03604 
03605   mFolder->close("removedups");
03606   mHeaders->setFolder(oFolder);
03607   QString msg;
03608   if ( numDuplicates )
03609     msg = i18n("Removed %n duplicate message.",
03610                "Removed %n duplicate messages.", numDuplicates );
03611     else
03612       msg = i18n("No duplicate messages found.");
03613   BroadcastStatus::instance()->setStatusMsg( msg );
03614 }
03615 
03616 
03617 //-----------------------------------------------------------------------------
03618 void KMMainWidget::slotUpdateUndo()
03619 {
03620     if (actionCollection()->action( "edit_undo" ))
03621         actionCollection()->action( "edit_undo" )->setEnabled( mHeaders->canUndo() );
03622 }
03623 
03624 
03625 //-----------------------------------------------------------------------------
03626 void KMMainWidget::clearFilterActions()
03627 {
03628   if ( !mFilterTBarActions.isEmpty() ) {
03629     if ( mGUIClient->factory() )
03630       mGUIClient->unplugActionList( "toolbar_filter_actions" );
03631     mFilterTBarActions.clear();
03632   }
03633   mApplyFilterActionsMenu->popupMenu()->clear();
03634   if ( !mFilterMenuActions.isEmpty() ) {
03635     if ( mGUIClient->factory() )
03636       mGUIClient->unplugActionList( "menu_filter_actions" );
03637     mFilterMenuActions.clear();
03638   }
03639   mFilterCommands.clear();
03640 }
03641 
03642 //-----------------------------------------------------------------------------
03643 void KMMainWidget::initializeFolderShortcutActions()
03644 {
03645 
03646   // If we are loaded as a part, this will be set to fals, since the part
03647   // does xml loading. Temporarily set to true, in that case, so the
03648   // accels are added to the collection as expected.
03649   bool old = actionCollection()->isAutoConnectShortcuts();
03650 
03651   actionCollection()->setAutoConnectShortcuts( true );
03652   QValueList< QGuardedPtr< KMFolder > > folders = kmkernel->allFolders();
03653   QValueList< QGuardedPtr< KMFolder > >::Iterator it = folders.begin();
03654   while ( it != folders.end() ) {
03655     KMFolder *folder = (*it);
03656     ++it;
03657     slotShortcutChanged( folder ); // load the initial accel
03658   }
03659   actionCollection()->setAutoConnectShortcuts( old );
03660 }
03661 
03662 
03663 //-----------------------------------------------------------------------------
03664 void KMMainWidget::initializeFilterActions()
03665 {
03666   QString filterName, normalizedName;
03667   KMMetaFilterActionCommand *filterCommand;
03668   KAction *filterAction = 0;
03669 
03670   clearFilterActions();
03671   mApplyAllFiltersAction->plug(mApplyFilterActionsMenu->popupMenu());
03672   bool addedSeparator = false;
03673   QValueListConstIterator<KMFilter*> it = kmkernel->filterMgr()->filters().constBegin();
03674   for ( ;it != kmkernel->filterMgr()->filters().constEnd(); ++it ) {
03675     if (!(*it)->isEmpty() && (*it)->configureShortcut()) {
03676       filterName = QString("Filter %1").arg((*it)->name());
03677       normalizedName = filterName.replace(" ", "_");
03678       if (action(normalizedName.utf8()))
03679         continue;
03680       filterCommand = new KMMetaFilterActionCommand(*it, mHeaders, this);
03681       mFilterCommands.append(filterCommand);
03682       QString as = i18n("Filter %1").arg((*it)->name());
03683       QString icon = (*it)->icon();
03684       if ( icon.isEmpty() )
03685         icon = "gear";
03686       filterAction = new KAction(as, icon, (*it)->shortcut(), filterCommand,
03687                                  SLOT(start()), actionCollection(),
03688                                  normalizedName.local8Bit());
03689       if(!addedSeparator) {
03690         mApplyFilterActionsMenu->popupMenu()->insertSeparator();
03691         addedSeparator = !addedSeparator;
03692         mFilterMenuActions.append( new KActionSeparator());
03693       }
03694       filterAction->plug( mApplyFilterActionsMenu->popupMenu() );
03695       mFilterMenuActions.append(filterAction);
03696       if ( (*it)->configureToolbar() )
03697         mFilterTBarActions.append(filterAction);
03698     }
03699   }
03700   if ( !mFilterMenuActions.isEmpty() && mGUIClient->factory() )
03701     mGUIClient->plugActionList( "menu_filter_actions", mFilterMenuActions );
03702   if ( !mFilterTBarActions.isEmpty() && mGUIClient->factory() ) {
03703     mFilterTBarActions.prepend( mToolbarActionSeparator );
03704     mGUIClient->plugActionList( "toolbar_filter_actions", mFilterTBarActions );
03705   }
03706 }
03707 
03708 void KMMainWidget::slotFolderRemoved( KMFolder *folder )
03709 {
03710   mFolderShortcutCommands.remove( folder->idString() );
03711 }
03712 
03713 //-----------------------------------------------------------------------------
03714 void KMMainWidget::initializeIMAPActions( bool setState /* false the first time, true later on */ )
03715 {
03716   bool hasImapAccount = false;
03717   for( KMAccount *a = kmkernel->acctMgr()->first(); a;
03718        a = kmkernel->acctMgr()->next() ) {
03719     if ( a->type() == "cachedimap" ) {
03720       hasImapAccount = true;
03721       break;
03722     }
03723   }
03724   if ( hasImapAccount == ( mTroubleshootFolderAction != 0 ) )
03725     return; // nothing to do
03726 
03727   KXMLGUIFactory* factory = mGUIClient->factory();
03728   if ( factory )
03729     factory->removeClient( mGUIClient );
03730 
03731   if ( !mTroubleshootFolderAction ) {
03732     mTroubleshootFolderAction = new KAction( i18n("&Troubleshoot IMAP Cache..."), "wizard", 0,
03733      this, SLOT(slotTroubleshootFolder()), actionCollection(), "troubleshoot_folder" );
03734     if ( setState )
03735       updateFolderMenu(); // set initial state of the action
03736   } else {
03737     delete mTroubleshootFolderAction ;
03738     mTroubleshootFolderAction = 0;
03739   }
03740 
03741   if ( factory )
03742     factory->addClient( mGUIClient );
03743 }
03744 
03745 bool KMMainWidget::shortcutIsValid( const KShortcut &sc ) const
03746 {
03747   KActionPtrList actions = actionCollection()->actions();
03748   KActionPtrList::Iterator it( actions.begin() );
03749   for ( ; it != actions.end(); it++ ) {
03750     if ( (*it)->shortcut() == sc ) return false;
03751   }
03752   return true;
03753 }
03754 
03755 void KMMainWidget::slotShortcutChanged( KMFolder *folder )
03756 {
03757   // remove the old one, autodelete
03758   mFolderShortcutCommands.remove( folder->idString() );
03759   if ( folder->shortcut().isNull() )
03760     return;
03761 
03762   FolderShortcutCommand *c = new FolderShortcutCommand( this, folder );
03763   mFolderShortcutCommands.insert( folder->idString(), c );
03764 
03765   QString actionlabel = QString( "FolderShortcut %1").arg( folder->prettyURL() );
03766   QString actionname = QString( "FolderShortcut %1").arg( folder->idString() );
03767   QString normalizedName = actionname.replace(" ", "_");
03768   KAction* action =
03769     new KAction(actionlabel, folder->shortcut(), c, SLOT(start()),
03770                 actionCollection(), normalizedName.local8Bit());
03771   action->setIcon( folder->unreadIconPath() );
03772   c->setAction( action ); // will be deleted along with the command
03773 }
03774 
03775 //-----------------------------------------------------------------------------
03776 QString KMMainWidget::findCurrentImapPath()
03777 {
03778   QString startPath;
03779   if (!mFolder) return startPath;
03780   if (mFolder->folderType() == KMFolderTypeImap)
03781   {
03782     startPath = static_cast<KMFolderImap*>(mFolder->storage())->imapPath();
03783   } else if (mFolder->folderType() == KMFolderTypeCachedImap)
03784   {
03785     startPath = static_cast<KMFolderCachedImap*>(mFolder->storage())->imapPath();
03786   }
03787   return startPath;
03788 }
03789 
03790 //-----------------------------------------------------------------------------
03791 ImapAccountBase* KMMainWidget::findCurrentImapAccountBase()
03792 {
03793   ImapAccountBase* account = 0;
03794   if (!mFolder) return account;
03795   if (mFolder->folderType() == KMFolderTypeImap)
03796   {
03797     account = static_cast<KMFolderImap*>(mFolder->storage())->account();
03798   } else if (mFolder->folderType() == KMFolderTypeCachedImap)
03799   {
03800     account = static_cast<KMFolderCachedImap*>(mFolder->storage())->account();
03801   }
03802   return account;
03803 }
03804 
03805 //-----------------------------------------------------------------------------
03806 void KMMainWidget::slotSubscriptionDialog()
03807 {
03808   if ( !kmkernel->askToGoOnline() )
03809     return;
03810   ImapAccountBase* account = findCurrentImapAccountBase();
03811   if ( !account ) return;
03812   const QString startPath = findCurrentImapPath();
03813 
03814   // KSubscription sets "DestruciveClose"
03815   SubscriptionDialog * dialog =
03816       new SubscriptionDialog(this, i18n("Subscription"), account, startPath);
03817   if ( dialog->exec() ) {
03818     // start a new listing
03819     if (mFolder->folderType() == KMFolderTypeImap)
03820       static_cast<KMFolderImap*>(mFolder->storage())->account()->listDirectory();
03821   }
03822 }
03823 
03824 //-----------------------------------------------------------------------------
03825 void KMMainWidget::slotLocalSubscriptionDialog()
03826 {
03827   ImapAccountBase* account = findCurrentImapAccountBase();
03828   if ( !account ) return;
03829 
03830   const QString startPath = findCurrentImapPath();
03831   // KSubscription sets "DestruciveClose"
03832   LocalSubscriptionDialog *dialog =
03833       new LocalSubscriptionDialog(this, i18n("Local Subscription"), account, startPath);
03834   if ( dialog->exec() ) {
03835     // start a new listing
03836     if (mFolder->folderType() == KMFolderTypeImap)
03837       static_cast<KMFolderImap*>(mFolder->storage())->account()->listDirectory();
03838   }
03839 }
03840 
03841 //-----------------------------------------------------------------------------
03842 void KMMainWidget::slotFolderTreeColumnsChanged()
03843 {
03844   mTotalColumnToggle->setChecked( mFolderTree->isTotalActive() );
03845   mUnreadColumnToggle->setChecked( mFolderTree->isUnreadActive() );
03846   mSizeColumnToggle->setChecked( mFolderTree->isSizeActive() );
03847   mUnreadTextToggle->setChecked( !mFolderTree->isUnreadActive() );
03848 }
03849 
03850 void KMMainWidget::toggleSystemTray()
03851 {
03852   if ( !mSystemTray && GlobalSettings::self()->systemTrayEnabled() ) {
03853     mSystemTray = new KMSystemTray();
03854   }
03855   else if ( mSystemTray && !GlobalSettings::self()->systemTrayEnabled() ) {
03856     // Get rid of system tray on user's request
03857     kdDebug(5006) << "deleting systray" << endl;
03858     delete mSystemTray;
03859     mSystemTray = 0;
03860   }
03861 
03862   // Set mode of systemtray. If mode has changed, tray will handle this.
03863   if ( mSystemTray )
03864     mSystemTray->setMode( GlobalSettings::self()->systemTrayPolicy() );
03865 }
03866 
03867 //-----------------------------------------------------------------------------
03868 void KMMainWidget::slotAntiSpamWizard()
03869 {
03870   AntiSpamWizard wiz( AntiSpamWizard::AntiSpam, this, folderTree() );
03871   wiz.exec();
03872 }
03873 
03874 //-----------------------------------------------------------------------------
03875 void KMMainWidget::slotAntiVirusWizard()
03876 {
03877   AntiSpamWizard wiz( AntiSpamWizard::AntiVirus, this, folderTree() );
03878   wiz.exec();
03879 }
03880 
03881 //-----------------------------------------------------------------------------
03882 void KMMainWidget::slotFilterLogViewer()
03883 {
03884   FilterLogDialog * dlg = new FilterLogDialog( 0 );
03885   dlg->show();
03886 }
03887 
03888 //-----------------------------------------------------------------------------
03889 void KMMainWidget::updateFileMenu()
03890 {
03891   QStringList actList = kmkernel->acctMgr()->getAccounts();
03892 
03893   actionCollection()->action("check_mail")->setEnabled( actList.size() > 0 );
03894   actionCollection()->action("check_mail_in")->setEnabled( actList.size() > 0 );
03895   actionCollection()->action("favorite_check_mail")->setEnabled( actList.size() > 0 );
03896 }
03897 
03898 
03899 //-----------------------------------------------------------------------------
03900 void KMMainWidget::setAccelsEnabled( bool enabled )
03901 {
03902   actionCollection()->kaccel()->setEnabled( enabled );
03903 }
03904 
03905 
03906 //-----------------------------------------------------------------------------
03907 KMSystemTray *KMMainWidget::systray() const
03908 {
03909   return mSystemTray;
03910 }
03911 
03912 //-----------------------------------------------------------------------------
03913 QString KMMainWidget::overrideEncoding() const
03914 {
03915   if ( mMsgView )
03916     return mMsgView->overrideEncoding();
03917   else
03918     return GlobalSettings::self()->overrideCharacterEncoding();
03919 }
03920 
03921 void KMMainWidget::slotCreateTodo()
03922 {
03923   KMMessage *msg = mHeaders->currentMsg();
03924   if ( !msg )
03925     return;
03926   KMCommand *command = new CreateTodoCommand( this, msg );
03927   command->start();
03928 }
03929 
03930 void KMMainWidget::setupFolderView()
03931 {
03932   if ( GlobalSettings::self()->enableFavoriteFolderView() ) {
03933     mFolderView = mFolderViewSplitter;
03934     mFolderTree->reparent( mFolderViewSplitter, 0, QPoint( 0, 0 ) );
03935     mFolderViewSplitter->show();
03936     mFavoriteFolderView->show();
03937   } else {
03938     mFolderView = mFolderTree;
03939     mFolderViewSplitter->hide();
03940     mFavoriteFolderView->hide();
03941   }
03942   mFolderView->reparent( mFolderViewParent, 0, QPoint( 0, 0 ) );
03943   mFolderViewParent->moveToFirst( mFolderView );
03944   mFolderTree->show();
03945 }
03946 
03947 
03948 void KMMainWidget::slotRequestFullSearchFromQuickSearch()
03949 {
03950     slotSearch();
03951 #ifdef HAVE_INDEXLIB
03952     return;
03953 #endif
03954     assert( mSearchWin );
03955     KMSearchPattern pattern;
03956     pattern.append( KMSearchRule::createInstance( "<message>", KMSearchRule::FuncContains, mQuickSearchLine->currentSearchTerm() ) );
03957     int status = mQuickSearchLine->currentStatus();
03958     if ( status != 0 ) {
03959         pattern.append( new KMSearchRuleStatus( status ) );
03960     }
03961     mSearchWin->setSearchPattern( pattern );
03962 }
03963 
03964 void KMMainWidget::updateVactionScriptStatus(bool active)
03965 {
03966   mVacationIndicatorActive = active;
03967   if ( active ) {
03968     mVacationScriptIndicator->setText( i18n("Out of office reply active") );
03969     mVacationScriptIndicator->setPaletteBackgroundColor( Qt::yellow );
03970     mVacationScriptIndicator->setCursor( QCursor( Qt::PointingHandCursor ) );
03971     mVacationScriptIndicator->show();
03972   } else {
03973     mVacationScriptIndicator->hide();
03974   }
03975 }
03976 
KDE Home | KDE Accessibility Home | Description of Access Keys