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