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