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