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