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