kmail Library API Documentation

kmmainwidget.cpp

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