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