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