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