kmail Library API Documentation

kmfldsearch.cpp

00001 /* kmfldsearch 00002 * (c) 1999 Stefan Taferner, (c) 2001 Aaron J. Seigo 00003 * This code is under GPL 00004 */ 00005 // kmfldsearch.cpp 00006 00007 #include <config.h> 00008 #include "kmcommands.h" 00009 #include "kmfldsearch.h" 00010 #include "kmmainwidget.h" 00011 #include "kmmsgdict.h" 00012 #include "kmmsgpart.h" 00013 #include "kmfoldercombobox.h" 00014 #include "kmfolderdia.h" 00015 #include "kmfolderimap.h" 00016 #include "kmfoldermgr.h" 00017 #include "kmfoldersearch.h" 00018 #include "kmfoldertree.h" 00019 #include "kmsearchpatternedit.h" 00020 #include "kmsearchpattern.h" 00021 00022 #include <kapplication.h> 00023 #include <kdebug.h> 00024 #include <kstatusbar.h> 00025 #include <kwin.h> 00026 #include <kconfig.h> 00027 #include <kstdaction.h> 00028 00029 #include <qcheckbox.h> 00030 #include <qlayout.h> 00031 #include <klineedit.h> 00032 #include <qpushbutton.h> 00033 #include <qradiobutton.h> 00034 #include <qbuttongroup.h> 00035 #include <qobjectlist.h> //for mPatternEdit->queryList( 0, "mRuleField" )->first(); 00036 #include <qcursor.h> 00037 00038 #include <mimelib/enum.h> 00039 #include <mimelib/boyermor.h> 00040 00041 #include <assert.h> 00042 #include <stdlib.h> 00043 00044 #include <X11/Xlib.h> 00045 #include <X11/Xatom.h> 00046 00047 const int KMFldSearch::MSGID_COLUMN = 4; 00048 00049 //----------------------------------------------------------------------------- 00050 KMFldSearch::KMFldSearch(KMMainWidget* w, const char* name, 00051 KMFolder *curFolder, bool modal): 00052 KDialogBase(0, name, modal, i18n("Search in Folders"), 00053 User1 | User2 | Close, User1, false, 00054 KGuiItem( i18n("&Search"), "find" ), 00055 KGuiItem( i18n("S&top"), "cancel" )), 00056 mStopped(false), 00057 mCloseRequested(false), 00058 mSortColumn(0), 00059 mSortOrder(Ascending), 00060 mFolder(0), 00061 mTimer(new QTimer(this)), 00062 mLastFocus(0), 00063 mKMMainWidget(w) 00064 { 00065 #if !KDE_IS_VERSION( 3, 2, 91 ) 00066 // HACK - KWin keeps all dialogs on top of their mainwindows, but that's probably 00067 // wrong (#76026), and should be done only for modals. CVS HEAD should get 00068 // proper fix in KWin (l.lunak@kde.org) 00069 XDeleteProperty( qt_xdisplay(), winId(), XA_WM_TRANSIENT_FOR ); 00070 #endif 00071 KWin::setIcons(winId(), kapp->icon(), kapp->miniIcon()); 00072 00073 KConfig* config = KMKernel::config(); 00074 config->setGroup("SearchDialog"); 00075 00076 QWidget* searchWidget = new QWidget(this); 00077 QVBoxLayout *vbl = new QVBoxLayout( searchWidget, 0, spacingHint(), "kmfs_vbl" ); 00078 00079 QButtonGroup * radioGroup = new QButtonGroup( searchWidget ); 00080 radioGroup->hide(); 00081 00082 mChkbxAllFolders = new QRadioButton(i18n("Search in &all local folders"), searchWidget); 00083 vbl->addWidget( mChkbxAllFolders ); 00084 radioGroup->insert( mChkbxAllFolders ); 00085 00086 QHBoxLayout *hbl = new QHBoxLayout( vbl, spacingHint(), "kmfs_hbl" ); 00087 mChkbxSpecificFolders = new QRadioButton(i18n("Search &only in:"), searchWidget); 00088 hbl->addWidget(mChkbxSpecificFolders); 00089 mChkbxSpecificFolders->setChecked(true); 00090 radioGroup->insert( mChkbxSpecificFolders ); 00091 00092 mCbxFolders = new KMFolderComboBox(false, searchWidget); 00093 mCbxFolders->setFolder(curFolder); 00094 hbl->addWidget(mCbxFolders); 00095 00096 connect(mCbxFolders, SIGNAL(activated(int)), 00097 this, SLOT(slotFolderActivated(int))); 00098 connect(mCbxFolders, SIGNAL(activated(int)), 00099 this, SLOT(slotFilterAvailableRules())); 00100 00101 mChkSubFolders = new QCheckBox(i18n("I&nclude sub-folders"), searchWidget); 00102 mChkSubFolders->setChecked(true); 00103 hbl->addWidget(mChkSubFolders); 00104 00105 QWidget *spacer = new QWidget( searchWidget, "spacer" ); 00106 spacer->setMinimumHeight( 2 ); 00107 vbl->addWidget( spacer ); 00108 00109 mPatternEdit = new KMSearchPatternEdit( "", searchWidget , "spe", false, true ); 00110 mPatternEdit->setFrameStyle( QFrame::NoFrame | QFrame::Plain ); 00111 mPatternEdit->setInsideMargin( 0 ); 00112 mSearchPattern = new KMSearchPattern(); 00113 KMFolderSearch *searchFolder = 0; 00114 if (curFolder) 00115 searchFolder = dynamic_cast<KMFolderSearch*>(curFolder->storage()); 00116 if (searchFolder) { 00117 KConfig config(curFolder->location()); 00118 KMFolder *root = searchFolder->search()->root(); 00119 config.setGroup("Search Folder"); 00120 mSearchPattern->readConfig(&config); 00121 if (root) { 00122 mChkbxSpecificFolders->setChecked(true); 00123 mCbxFolders->setFolder(root); 00124 mChkSubFolders->setChecked(searchFolder->search()->recursive()); 00125 } else { 00126 mChkbxAllFolders->setChecked(true); 00127 } 00128 mFolder = searchFolder; 00129 } 00130 mPatternEdit->setSearchPattern( mSearchPattern ); 00131 QObjectList *list = mPatternEdit->queryList( 0, "mRuleField" ); 00132 QObject *object = 0; 00133 if ( list ) 00134 object = list->first(); 00135 delete list; 00136 if (!searchFolder && object && ::qt_cast<QComboBox*>(object)) 00137 static_cast<QComboBox*>(object)->setCurrentText("Subject"); 00138 00139 vbl->addWidget( mPatternEdit ); 00140 00141 // enable/disable widgets depending on radio buttons: 00142 connect( mChkbxSpecificFolders, SIGNAL(toggled(bool)), 00143 mCbxFolders, SLOT(setEnabled(bool)) ); 00144 connect( mChkbxSpecificFolders, SIGNAL(toggled(bool)), 00145 mChkSubFolders, SLOT(setEnabled(bool)) ); 00146 00147 mLbxMatches = new KListView(searchWidget, "Search in Folders"); 00148 00149 /* 00150 Default is to sort by date. TODO: Unfortunately this sorts *while* 00151 inserting, which looks rather strange - the user cannot read 00152 the results so far as they are constantly re-sorted --dnaber 00153 00154 Sorting is now disabled when a search is started and reenabled 00155 when it stops. Items are appended to the list. This not only 00156 solves the above problem, but speeds searches with many hits 00157 up considerably. - till 00158 00159 TODO: subclass KListViewItem and do proper (and performant) 00160 comapare functions 00161 */ 00162 mLbxMatches->setSorting(2, false); 00163 mLbxMatches->setShowSortIndicator(true); 00164 mLbxMatches->setAllColumnsShowFocus(true); 00165 mLbxMatches->setSelectionModeExt(KListView::Extended); 00166 mLbxMatches->addColumn(i18n("Subject"), 00167 config->readNumEntry("SubjectWidth", 150)); 00168 mLbxMatches->addColumn(i18n("Sender/Receiver"), 00169 config->readNumEntry("SenderWidth", 120)); 00170 mLbxMatches->addColumn(i18n("Date"), 00171 config->readNumEntry("DateWidth", 120)); 00172 mLbxMatches->addColumn(i18n("Folder"), 00173 config->readNumEntry("FolderWidth", 100)); 00174 00175 mLbxMatches->addColumn(""); // should be hidden 00176 mLbxMatches->setColumnWidthMode( MSGID_COLUMN, QListView::Manual ); 00177 mLbxMatches->setColumnWidth(MSGID_COLUMN, 0); 00178 mLbxMatches->header()->setResizeEnabled(false, MSGID_COLUMN); 00179 00180 connect(mLbxMatches, SIGNAL(doubleClicked(QListViewItem *)), 00181 this, SLOT(slotShowMsg(QListViewItem *))); 00182 connect( mLbxMatches, SIGNAL( contextMenuRequested( QListViewItem*, const QPoint &, int )), 00183 this, SLOT( slotContextMenuRequested( QListViewItem*, const QPoint &, int ))); 00184 vbl->addWidget(mLbxMatches); 00185 00186 QHBoxLayout *hbl2 = new QHBoxLayout( vbl, spacingHint(), "kmfs_hbl2" ); 00187 mSearchFolderLbl = new QLabel(i18n("Search folder &name:"), searchWidget); 00188 hbl2->addWidget(mSearchFolderLbl); 00189 mSearchFolderEdt = new KLineEdit(searchWidget); 00190 if (searchFolder) 00191 mSearchFolderEdt->setText(searchFolder->folder()->name()); 00192 else 00193 mSearchFolderEdt->setText(i18n("Last Search")); 00194 00195 mSearchFolderLbl->setBuddy(mSearchFolderEdt); 00196 hbl2->addWidget(mSearchFolderEdt); 00197 mSearchFolderBtn = new QPushButton(i18n("&Rename"), searchWidget); 00198 mSearchFolderBtn->setEnabled(false); 00199 hbl2->addWidget(mSearchFolderBtn); 00200 mSearchFolderOpenBtn = new QPushButton(i18n("Op&en"), searchWidget); 00201 mSearchFolderOpenBtn->setEnabled(false); 00202 hbl2->addWidget(mSearchFolderOpenBtn); 00203 connect( mSearchFolderEdt, SIGNAL( textChanged( const QString &)), 00204 this, SLOT( updateCreateButton( const QString & ))); 00205 connect( mSearchFolderBtn, SIGNAL( clicked() ), 00206 this, SLOT( renameSearchFolder() )); 00207 connect( mSearchFolderOpenBtn, SIGNAL( clicked() ), 00208 this, SLOT( openSearchFolder() )); 00209 mStatusBar = new KStatusBar(searchWidget); 00210 mStatusBar->insertFixedItem(i18n("AMiddleLengthText..."), 0, true); 00211 mStatusBar->changeItem(i18n("Ready."), 0); 00212 mStatusBar->setItemAlignment(0, AlignLeft | AlignVCenter); 00213 mStatusBar->insertItem(QString::null, 1, 1, true); 00214 mStatusBar->setItemAlignment(1, AlignLeft | AlignVCenter); 00215 vbl->addWidget(mStatusBar); 00216 00217 int mainWidth = config->readNumEntry("SearchWidgetWidth", 0); 00218 int mainHeight = config->readNumEntry("SearchWidgetHeight", 0); 00219 00220 if (mainWidth || mainHeight) 00221 resize(mainWidth, mainHeight); 00222 00223 setMainWidget(searchWidget); 00224 setButtonBoxOrientation(QWidget::Vertical); 00225 00226 mBtnSearch = actionButton(KDialogBase::User1); 00227 mBtnStop = actionButton(KDialogBase::User2); 00228 mBtnStop->setEnabled(false); 00229 00230 connect(this, SIGNAL(user1Clicked()), SLOT(slotSearch())); 00231 connect(this, SIGNAL(user2Clicked()), SLOT(slotStop())); 00232 connect(this, SIGNAL(finished()), this, SLOT(deleteLater())); 00233 00234 // give focus to the value field of the first search rule 00235 object = mPatternEdit->child( "regExpLineEdit" ); 00236 if ( object && object->isWidgetType() ) { 00237 static_cast<QWidget*>(object)->setFocus(); 00238 //kdDebug(5006) << "KMFldSearch: focus has been given to widget " 00239 // << object->name() << endl; 00240 } 00241 else 00242 kdDebug(5006) << "KMFldSearch: regExpLineEdit not found" << endl; 00243 00244 // Remove the <message> and <body> rule fields when searching imap folders 00245 slotFilterAvailableRules(); 00246 connect(mChkbxAllFolders, SIGNAL(toggled(bool)), 00247 this, SLOT(slotFilterAvailableRules())); 00248 00249 //set up actions 00250 KActionCollection *ac = actionCollection(); 00251 mReplyAction = new KAction( i18n("&Reply..."), "mail_reply", 0, this, 00252 SLOT(slotReplyToMsg()), ac, "search_reply" ); 00253 mReplyAllAction = new KAction( i18n("Reply to &All..."), "mail_replyall", 00254 0, this, SLOT(slotReplyAllToMsg()), 00255 ac, "search_reply_all" ); 00256 mReplyListAction = new KAction( i18n("Reply to Mailing-&List..."), 00257 "mail_replylist", 0, this, 00258 SLOT(slotReplyListToMsg()), ac, 00259 "search_reply_list" ); 00260 mForwardActionMenu = new KActionMenu( i18n("Message->","&Forward"), 00261 "mail_forward", ac, 00262 "search_message_forward" ); 00263 connect( mForwardActionMenu, SIGNAL(activated()), this, 00264 SLOT(slotForwardMsg()) ); 00265 mForwardAction = new KAction( i18n("&Inline..."), "mail_forward", 00266 0, this, SLOT(slotForwardMsg()), 00267 ac, "search_message_forward_inline" ); 00268 mForwardActionMenu->insert( mForwardAction ); 00269 mForwardAttachedAction = new KAction( i18n("Message->Forward->","As &Attachment..."), 00270 "mail_forward", 0, this, 00271 SLOT(slotForwardAttachedMsg()), ac, 00272 "search_message_forward_as_attachment" ); 00273 mForwardActionMenu->insert( mForwardAttachedAction ); 00274 mSaveAsAction = KStdAction::saveAs( this, SLOT(slotSaveMsg()), ac, "search_file_save_as" ); 00275 mSaveAtchAction = new KAction( i18n("Save Attachments..."), "attach", 0, 00276 this, SLOT(slotSaveAttachments()), ac, "search_save_attachments" ); 00277 00278 mPrintAction = KStdAction::print( this, SLOT(slotPrintMsg()), ac, "search_print" ); 00279 mClearAction = new KAction( i18n("Clear Selection"), 0, 0, this, 00280 SLOT(slotClearSelection()), ac, "search_clear_selection" ); 00281 connect(mTimer, SIGNAL(timeout()), this, SLOT(updStatus())); 00282 connect(kmkernel->searchFolderMgr(), SIGNAL(folderInvalidated(KMFolder*)), 00283 this, SLOT(folderInvalidated(KMFolder*))); 00284 } 00285 00286 //----------------------------------------------------------------------------- 00287 KMFldSearch::~KMFldSearch() 00288 { 00289 QValueListIterator<QGuardedPtr<KMFolder> > fit; 00290 for ( fit = mFolders.begin(); fit != mFolders.end(); ++fit ) { 00291 if (!(*fit)) 00292 continue; 00293 (*fit)->close(); 00294 } 00295 00296 KConfig* config = KMKernel::config(); 00297 config->setGroup("SearchDialog"); 00298 config->writeEntry("SubjectWidth", mLbxMatches->columnWidth(0)); 00299 config->writeEntry("SenderWidth", mLbxMatches->columnWidth(1)); 00300 config->writeEntry("DateWidth", mLbxMatches->columnWidth(2)); 00301 config->writeEntry("FolderWidth", mLbxMatches->columnWidth(3)); 00302 config->writeEntry("SearchWidgetWidth", width()); 00303 config->writeEntry("SearchWidgetHeight", height()); 00304 config->sync(); 00305 } 00306 00307 //----------------------------------------------------------------------------- 00308 void KMFldSearch::updStatus(void) 00309 { 00310 QString genMsg, detailMsg; 00311 int numMatches = 0, count = 0; 00312 KMSearch const *search = (mFolder) ? (mFolder->search()) : 0; 00313 QString folderName; 00314 if (search) { 00315 numMatches = search->foundCount(); 00316 count = search->searchedCount(); 00317 folderName = search->currentFolder(); 00318 } 00319 00320 if (mFolder && mFolder->search() && !mFolder->search()->running()) { 00321 if(!mStopped) { 00322 genMsg = i18n("Done"); 00323 detailMsg = i18n("%n match (%1)", "%n matches (%1)", numMatches) 00324 .arg(i18n("%n message processed", 00325 "%n messages processed", count)); 00326 } else { 00327 genMsg = i18n("Search canceled"); 00328 detailMsg = i18n("%n match so far (%1)", 00329 "%n matches so far (%1)", numMatches) 00330 .arg(i18n("%n message processed", 00331 "%n messages processed", count)); 00332 } 00333 } else { 00334 genMsg = i18n("%n match", "%n matches", numMatches); 00335 detailMsg = i18n("Searching in %1 (message %2)") 00336 .arg(folderName) 00337 .arg(count); 00338 } 00339 00340 mStatusBar->changeItem(genMsg, 0); 00341 mStatusBar->changeItem(detailMsg, 1); 00342 } 00343 00344 00345 //----------------------------------------------------------------------------- 00346 void KMFldSearch::keyPressEvent(QKeyEvent *evt) 00347 { 00348 KMSearch const *search = (mFolder) ? mFolder->search() : 0; 00349 bool searching = (search) ? search->running() : false; 00350 if (evt->key() == Key_Escape && searching) { 00351 mFolder->stopSearch(); 00352 return; 00353 } 00354 00355 KDialogBase::keyPressEvent(evt); 00356 } 00357 00358 00359 //----------------------------------------------------------------------------- 00360 void KMFldSearch::slotFolderActivated(int /*nr*/) 00361 { 00362 KMFolder* folder = mCbxFolders->getFolder(); 00363 00364 mChkbxSpecificFolders->setChecked(true); 00365 mBtnSearch->setEnabled(folder); 00366 } 00367 00368 00369 //----------------------------------------------------------------------------- 00370 void KMFldSearch::slotFilterAvailableRules() 00371 { 00372 static bool lastHeadersOnly = false; 00373 KMFolder* folder = mCbxFolders->getFolder(); 00374 bool headersOnly = folder->folderType() == KMFolderTypeImap; 00375 if (mChkbxAllFolders->isChecked()) 00376 headersOnly = false; 00377 if (headersOnly != lastHeadersOnly) 00378 mPatternEdit->setHeadersOnly( headersOnly ); 00379 lastHeadersOnly = headersOnly; 00380 } 00381 00382 00383 //----------------------------------------------------------------------------- 00384 void KMFldSearch::activateFolder(KMFolder *curFolder) 00385 { 00386 mChkbxSpecificFolders->setChecked(true); 00387 mCbxFolders->setFolder(curFolder); 00388 } 00389 00390 //----------------------------------------------------------------------------- 00391 void KMFldSearch::slotSearch() 00392 { 00393 mLastFocus = focusWidget(); 00394 mBtnSearch->setFocus(); // set focus so we don't miss key event 00395 00396 mStopped = false; 00397 mFetchingInProgress = 0; 00398 00399 mSearchFolderOpenBtn->setEnabled(true); 00400 mBtnSearch->setEnabled(false); 00401 mBtnStop->setEnabled(true); 00402 00403 mLbxMatches->clear(); 00404 00405 mSortColumn = mLbxMatches->sortColumn(); 00406 mSortOrder = mLbxMatches->sortOrder(); 00407 mLbxMatches->setSorting(-1); 00408 mLbxMatches->setShowSortIndicator(false); 00409 00410 // If we haven't openend an existing search folder, find or 00411 // create one. 00412 if (!mFolder) { 00413 KMFolderMgr *mgr = kmkernel->searchFolderMgr(); 00414 if (mSearchFolderEdt->text().isEmpty()) 00415 mSearchFolderEdt->setText(i18n("Last Search")); 00416 QString baseName = mSearchFolderEdt->text(); 00417 QString fullName = baseName; 00418 int count = 0; 00419 KMFolder *folder; 00420 while ((folder = mgr->find(fullName))) { 00421 if (folder->storage()->inherits("KMFolderSearch")) 00422 break; 00423 fullName = QString("%1 %2").arg(baseName).arg(++count); 00424 } 00425 00426 if (!folder) 00427 folder = mgr->createFolder(fullName, FALSE, KMFolderTypeSearch, 00428 &mgr->dir()); 00429 00430 mFolder = dynamic_cast<KMFolderSearch*>( folder->storage() ); 00431 } 00432 mFolder->stopSearch(); 00433 disconnect(mFolder, SIGNAL(msgAdded(int)), 00434 this, SLOT(slotAddMsg(int))); 00435 disconnect(mFolder, SIGNAL(msgRemoved(KMFolder*, Q_UINT32)), 00436 this, SLOT(slotRemoveMsg(KMFolder*, Q_UINT32))); 00437 connect(mFolder, SIGNAL(msgAdded(int)), 00438 this, SLOT(slotAddMsg(int))); 00439 connect(mFolder, SIGNAL(msgRemoved(KMFolder*, Q_UINT32)), 00440 this, SLOT(slotRemoveMsg(KMFolder*, Q_UINT32))); 00441 KMSearch *search = new KMSearch(); 00442 connect(search, SIGNAL(finished(bool)), 00443 this, SLOT(searchDone())); 00444 if (mChkbxAllFolders->isChecked()) { 00445 search->setRecursive(true); 00446 } else { 00447 search->setRoot(mCbxFolders->getFolder()); 00448 search->setRecursive(mChkSubFolders->isChecked()); 00449 } 00450 00451 mPatternEdit->updateSearchPattern(); 00452 KMSearchPattern *searchPattern = new KMSearchPattern(); 00453 *searchPattern = *mSearchPattern; //deep copy 00454 searchPattern->purify(); 00455 search->setSearchPattern(searchPattern); 00456 mFolder->setSearch(search); 00457 enableGUI(); 00458 00459 if (mFolder && !mFolders.contains(mFolder.operator->()->folder())) { 00460 mFolder->open(); 00461 mFolders.append(mFolder.operator->()->folder()); 00462 } 00463 mTimer->start(200); 00464 } 00465 00466 //----------------------------------------------------------------------------- 00467 void KMFldSearch::searchDone() 00468 { 00469 mTimer->stop(); 00470 updStatus(); 00471 00472 QTimer::singleShot(0, this, SLOT(enableGUI())); 00473 if(mLastFocus) 00474 mLastFocus->setFocus(); 00475 if (mCloseRequested) 00476 close(); 00477 00478 mLbxMatches->setSorting(mSortColumn, mSortOrder == Ascending); 00479 mLbxMatches->setShowSortIndicator(true); 00480 } 00481 00482 void KMFldSearch::slotAddMsg(int idx) 00483 { 00484 if (!mFolder) 00485 return; 00486 bool unget = !mFolder->isMessage(idx); 00487 KMMessage *msg = mFolder->getMsg(idx); 00488 QString from, fName; 00489 KMFolder *pFolder = msg->parent(); 00490 if (!mFolders.contains(pFolder)) { 00491 mFolders.append(pFolder); 00492 pFolder->open(); 00493 } 00494 if(pFolder->whoField() == "To") 00495 from = msg->to(); 00496 else 00497 from = msg->from(); 00498 if (pFolder->isSystemFolder()) 00499 fName = i18n(pFolder->name().utf8()); 00500 else 00501 fName = pFolder->name(); 00502 00503 (void)new KListViewItem(mLbxMatches, mLbxMatches->lastItem(), 00504 msg->subject(), from, msg->dateIsoStr(), 00505 fName, 00506 QString::number(mFolder->serNum(idx))); 00507 if (unget) 00508 mFolder->unGetMsg(idx); 00509 } 00510 00511 void KMFldSearch::slotRemoveMsg(KMFolder *, Q_UINT32 serNum) 00512 { 00513 if (!mFolder) 00514 return; 00515 QListViewItemIterator it(mLbxMatches); 00516 while (it.current()) { 00517 QListViewItem *item = *it; 00518 if (serNum == (*it)->text(MSGID_COLUMN).toUInt()) { 00519 delete item; 00520 return; 00521 } 00522 ++it; 00523 } 00524 } 00525 00526 //----------------------------------------------------------------------------- 00527 void KMFldSearch::slotStop() 00528 { 00529 if (mFolder) 00530 mFolder->stopSearch(); 00531 mStopped = true; 00532 mBtnStop->setEnabled(false); 00533 } 00534 00535 //----------------------------------------------------------------------------- 00536 void KMFldSearch::slotClose() 00537 { 00538 accept(); 00539 } 00540 00541 00542 //----------------------------------------------------------------------------- 00543 void KMFldSearch::closeEvent(QCloseEvent *e) 00544 { 00545 if (mFolder && mFolder->search() && mFolder->search()->running()) { 00546 mCloseRequested = true; 00547 //Cancel search in progress by setting the search folder search to 00548 //the null search 00549 mFolder->setSearch(new KMSearch()); 00550 QTimer::singleShot(0, this, SLOT(slotClose())); 00551 } else { 00552 KDialogBase::closeEvent(e); 00553 } 00554 } 00555 00556 //----------------------------------------------------------------------------- 00557 void KMFldSearch::updateCreateButton( const QString &s) 00558 { 00559 mSearchFolderBtn->setEnabled(s != i18n("Last Search") && mSearchFolderOpenBtn->isEnabled()); 00560 } 00561 00562 //----------------------------------------------------------------------------- 00563 void KMFldSearch::renameSearchFolder() 00564 { 00565 if (mFolder && (mFolder->folder()->name() != mSearchFolderEdt->text())) { 00566 int i = 1; 00567 QString name = mSearchFolderEdt->text(); 00568 while (i < 100) { 00569 if (!kmkernel->searchFolderMgr()->find( name )) { 00570 mFolder->rename( name ); 00571 kmkernel->searchFolderMgr()->contentsChanged(); 00572 break; 00573 } 00574 name.setNum( i ); 00575 name = mSearchFolderEdt->text() + " " + name; 00576 ++i; 00577 } 00578 } 00579 } 00580 00581 void KMFldSearch::openSearchFolder() 00582 { 00583 renameSearchFolder(); 00584 KMFolderTree *folderTree = mKMMainWidget->folderTree(); 00585 QListViewItem *index = folderTree->indexOfFolder(mFolder->folder()); 00586 if (index) { 00587 folderTree->ensureItemVisible(index); 00588 folderTree->doFolderSelected(index); 00589 slotClose(); 00590 } 00591 } 00592 00593 //----------------------------------------------------------------------------- 00594 void KMFldSearch::folderInvalidated(KMFolder *folder) 00595 { 00596 if (folder->storage() == mFolder) { 00597 mLbxMatches->clear(); 00598 if (mFolder->search()) 00599 connect(mFolder->search(), SIGNAL(finished(bool)), 00600 this, SLOT(searchDone())); 00601 mTimer->start(200); 00602 enableGUI(); 00603 } 00604 } 00605 00606 //----------------------------------------------------------------------------- 00607 bool KMFldSearch::slotShowMsg(QListViewItem *item) 00608 { 00609 if(!item) 00610 return false; 00611 00612 KMFolder* folder; 00613 int msgIndex; 00614 kmkernel->msgDict()->getLocation(item->text(MSGID_COLUMN).toUInt(), 00615 &folder, &msgIndex); 00616 00617 if (!folder || msgIndex < 0) 00618 return false; 00619 00620 mKMMainWidget->slotSelectFolder(folder); 00621 KMMessage* message = folder->getMsg(msgIndex); 00622 if (!message) 00623 return false; 00624 00625 mKMMainWidget->slotSelectMessage(message); 00626 return true; 00627 } 00628 00629 //----------------------------------------------------------------------------- 00630 void KMFldSearch::enableGUI() 00631 { 00632 KMSearch const *search = (mFolder) ? (mFolder->search()) : 0; 00633 bool searching = (search) ? (search->running()) : false; 00634 actionButton(KDialogBase::Close)->setEnabled(!searching); 00635 mCbxFolders->setEnabled(!searching); 00636 mChkSubFolders->setEnabled(!searching); 00637 mChkbxAllFolders->setEnabled(!searching); 00638 mChkbxSpecificFolders->setEnabled(!searching); 00639 mPatternEdit->setEnabled(!searching); 00640 mBtnSearch->setEnabled(!searching); 00641 mBtnStop->setEnabled(searching); 00642 } 00643 00644 00645 //----------------------------------------------------------------------------- 00646 KMMessageList KMFldSearch::selectedMessages() 00647 { 00648 KMMessageList msgList; 00649 KMFolder* folder = 0; 00650 int msgIndex = -1; 00651 for (QListViewItemIterator it(mLbxMatches); it.current(); it++) 00652 if (it.current()->isSelected()) { 00653 kmkernel->msgDict()->getLocation((*it)->text(MSGID_COLUMN).toUInt(), 00654 &folder, &msgIndex); 00655 if (folder && msgIndex >= 0) 00656 msgList.append(folder->getMsgBase(msgIndex)); 00657 } 00658 return msgList; 00659 } 00660 00661 //----------------------------------------------------------------------------- 00662 KMMessage* KMFldSearch::message() 00663 { 00664 QListViewItem *item = mLbxMatches->currentItem(); 00665 KMFolder* folder = 0; 00666 int msgIndex = -1; 00667 if (!item) 00668 return 0; 00669 kmkernel->msgDict()->getLocation(item->text(MSGID_COLUMN).toUInt(), 00670 &folder, &msgIndex); 00671 if (!folder || msgIndex < 0) 00672 return 0; 00673 00674 return folder->getMsg(msgIndex); 00675 } 00676 00677 //----------------------------------------------------------------------------- 00678 void KMFldSearch::moveSelectedToFolder( int menuId ) 00679 { 00680 KMFolder *dest = mMenuToFolder[menuId]; 00681 if (!dest) 00682 return; 00683 00684 KMMessageList msgList = selectedMessages(); 00685 KMCommand *command = new KMMoveCommand( dest, msgList ); 00686 command->start(); 00687 } 00688 00689 //----------------------------------------------------------------------------- 00690 void KMFldSearch::copySelectedToFolder( int menuId ) 00691 { 00692 KMFolder *dest = mMenuToFolder[menuId]; 00693 if (!dest) 00694 return; 00695 00696 KMMessageList msgList = selectedMessages(); 00697 KMCommand *command = new KMCopyCommand( dest, msgList ); 00698 command->start(); 00699 } 00700 00701 //----------------------------------------------------------------------------- 00702 void KMFldSearch::updateContextMenuActions() 00703 { 00704 int count = selectedMessages().count(); 00705 bool single_actions = count == 1; 00706 mReplyAction->setEnabled( single_actions ); 00707 mReplyAllAction->setEnabled( single_actions ); 00708 mReplyListAction->setEnabled( single_actions ); 00709 mPrintAction->setEnabled( single_actions ); 00710 } 00711 00712 //----------------------------------------------------------------------------- 00713 void KMFldSearch::slotContextMenuRequested( QListViewItem *lvi, const QPoint &, int ) 00714 { 00715 if (!lvi) 00716 return; 00717 mLbxMatches->setSelected( lvi, TRUE ); 00718 mLbxMatches->setCurrentItem( lvi ); 00719 if (!message()) 00720 return; 00721 QPopupMenu *menu = new QPopupMenu(this); 00722 updateContextMenuActions(); 00723 00724 mMenuToFolder.clear(); 00725 QPopupMenu *msgMoveMenu = new QPopupMenu(menu); 00726 KMMoveCommand::folderToPopupMenu( TRUE, this, &mMenuToFolder, msgMoveMenu ); 00727 QPopupMenu *msgCopyMenu = new QPopupMenu(menu); 00728 KMCopyCommand::folderToPopupMenu( FALSE, this, &mMenuToFolder, msgCopyMenu ); 00729 00730 // show most used actions 00731 mReplyAction->plug(menu); 00732 mReplyAllAction->plug(menu); 00733 mReplyListAction->plug(menu); 00734 mForwardActionMenu->plug(menu); 00735 menu->insertSeparator(); 00736 menu->insertItem(i18n("&Copy To"), msgCopyMenu); 00737 menu->insertItem(i18n("&Move To"), msgMoveMenu); 00738 mSaveAsAction->plug(menu); 00739 mSaveAtchAction->plug(menu); 00740 mPrintAction->plug(menu); 00741 menu->insertSeparator(); 00742 mClearAction->plug(menu); 00743 menu->exec (QCursor::pos(), 0); 00744 delete menu; 00745 } 00746 00747 //----------------------------------------------------------------------------- 00748 void KMFldSearch::slotClearSelection() 00749 { 00750 mLbxMatches->clearSelection(); 00751 } 00752 00753 //----------------------------------------------------------------------------- 00754 void KMFldSearch::slotReplyToMsg() 00755 { 00756 KMCommand *command = new KMReplyToCommand(this, message()); 00757 command->start(); 00758 } 00759 00760 //----------------------------------------------------------------------------- 00761 void KMFldSearch::slotReplyAllToMsg() 00762 { 00763 KMCommand *command = new KMReplyToAllCommand(this, message()); 00764 command->start(); 00765 } 00766 00767 //----------------------------------------------------------------------------- 00768 void KMFldSearch::slotReplyListToMsg() 00769 { 00770 KMCommand *command = new KMReplyListCommand(this, message()); 00771 command->start(); 00772 } 00773 00774 //----------------------------------------------------------------------------- 00775 void KMFldSearch::slotForwardMsg() 00776 { 00777 KMCommand *command = new KMForwardCommand(this, selectedMessages()); 00778 command->start(); 00779 } 00780 00781 //----------------------------------------------------------------------------- 00782 void KMFldSearch::slotForwardAttachedMsg() 00783 { 00784 KMCommand *command = new KMForwardAttachedCommand(this, selectedMessages()); 00785 command->start(); 00786 } 00787 00788 //----------------------------------------------------------------------------- 00789 void KMFldSearch::slotSaveMsg() 00790 { 00791 KMSaveMsgCommand *saveCommand = new KMSaveMsgCommand(this, 00792 selectedMessages()); 00793 if (saveCommand->url().isEmpty()) 00794 delete saveCommand; 00795 else 00796 saveCommand->start(); 00797 } 00798 //----------------------------------------------------------------------------- 00799 void KMFldSearch::slotSaveAttachments() 00800 { 00801 KMSaveAttachmentsCommand *saveCommand = new KMSaveAttachmentsCommand(this, 00802 selectedMessages()); 00803 saveCommand->start(); 00804 } 00805 00806 00807 //----------------------------------------------------------------------------- 00808 void KMFldSearch::slotPrintMsg() 00809 { 00810 KMCommand *command = new KMPrintCommand(this, message()); 00811 command->start(); 00812 } 00813 00814 #include "kmfldsearch.moc"
KDE Logo
This file is part of the documentation for kmail Library Version 3.3.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Fri Aug 27 12:52:31 2004 by doxygen 1.3.8 written by Dimitri van Heesch, © 1997-2003