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