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