You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
793 lines
21 KiB
793 lines
21 KiB
/* kmfldsearch |
|
* (c) 1999 Stefan Taferner, (c) 2001 Aaron J. Seigo |
|
* This code is under GPL |
|
*/ |
|
// kmfldsearch.cpp |
|
|
|
#include "kbusyptr.h" |
|
#include "kmcomposewin.h" |
|
#include "kmfldsearch.h" |
|
#include "kmmainwin.h" |
|
#include "kmmsgdict.h" |
|
#include "kmmsgpart.h" |
|
#include "kmfiltermgr.h" |
|
#include "kmfoldercombobox.h" |
|
#include "kmfolderdir.h" |
|
#include "kmfolderimap.h" |
|
#include "kmfoldermgr.h" |
|
#include "kmfoldertree.h" |
|
#include "kmsender.h" |
|
#include "kmundostack.h" |
|
#include "mailinglist-magic.h" |
|
|
|
#include <assert.h> |
|
#include <qcheckbox.h> |
|
#include <qcursor.h> |
|
#include <qheader.h> |
|
#include <qlabel.h> |
|
#include <qlayout.h> |
|
#include <qlineedit.h> |
|
#include <qpopupmenu.h> |
|
#include <qpushbutton.h> |
|
#include <qradiobutton.h> |
|
#include <qregexp.h> |
|
#include <qtextcodec.h> |
|
|
|
#include <kaction.h> |
|
#include <kapplication.h> |
|
#include <kconfig.h> |
|
#include <kdebug.h> |
|
#include <kglobal.h> |
|
#include <kiconloader.h> |
|
#include <kfiledialog.h> |
|
#include <kstatusbar.h> |
|
#include <kstdaction.h> |
|
#include <kwin.h> |
|
|
|
#include <mimelib/enum.h> |
|
|
|
#include <stdlib.h> |
|
|
|
const int KMFldSearch::FOLDER_COLUMN = 3; |
|
const int KMFldSearch::MSGID_COLUMN = 4; |
|
|
|
//----------------------------------------------------------------------------- |
|
KMFldSearch::KMFldSearch(KMMainWin* w, const char* name, |
|
KMFolder *curFolder, bool modal): |
|
KDialogBase(NULL, name, modal, i18n("Search in Folders"), |
|
KDialogBase::User1 | KDialogBase::User2 | KDialogBase::Close, |
|
KDialogBase::User1, false, i18n("&Search"), i18n("S&top")), |
|
mSearchAllFolders(false), |
|
mSearching(false), |
|
mStopped(false), |
|
mCloseRequested(false), |
|
mNumRules(2), |
|
mNumMatches(0), |
|
mCount(0), |
|
mLastFocus(0), |
|
mMainWin(w) |
|
{ |
|
KWin::setIcons(winId(), kapp->icon(), kapp->miniIcon()); |
|
|
|
KConfig* config = KGlobal::config(); |
|
config->setGroup("SearchDialog"); |
|
|
|
QWidget* searchWidget = new QWidget(this); |
|
mGrid = new QGridLayout(searchWidget, mNumRules+5, 5, spacingHint()); |
|
|
|
mChkbxAllFolders = new QRadioButton(i18n("Search in &all local folders"), searchWidget); |
|
mGrid->addMultiCellWidget(mChkbxAllFolders, 0, 0, 0, 3); |
|
connect(mChkbxAllFolders, SIGNAL(toggled(bool)), |
|
this, SLOT(slotSearchAllFolders(bool))); |
|
|
|
mChkbxSpecificFolders = new QRadioButton(i18n("Search &only in:"), searchWidget); |
|
mGrid->addWidget(mChkbxSpecificFolders, 1, 0); |
|
mChkbxSpecificFolders->setChecked(true); |
|
connect(mChkbxSpecificFolders, SIGNAL(toggled(bool)), |
|
this, SLOT(slotSearchSpecificFolder(bool))); |
|
|
|
mCbxFolders = new KMFolderComboBox(false, searchWidget); |
|
mCbxFolders->setMinimumSize(mCbxFolders->sizeHint()); |
|
mCbxFolders->setMaximumSize(1024, mCbxFolders->sizeHint().height()); |
|
mCbxFolders->setFolder(curFolder); |
|
mGrid->addMultiCellWidget(mCbxFolders, 1, 1, 1, 2); |
|
|
|
connect(mCbxFolders, SIGNAL(activated(int)), |
|
this, SLOT(slotFolderActivated(int))); |
|
|
|
mRules = new KMFldSearchRule*[mNumRules]; |
|
|
|
KMFldSearchRule* rule = 0; |
|
for (int i=0; i<mNumRules; ++i) |
|
{ |
|
rule = new KMFldSearchRule(searchWidget, mGrid, i+2, 0); |
|
rule->updateFunctions(mCbxFolders->getFolder()); |
|
mRules[i] = rule; |
|
} |
|
|
|
mChkSubFolders = new QCheckBox(i18n("I&nclude sub-folders"), searchWidget); |
|
mChkSubFolders->setChecked(true); |
|
mGrid->addWidget(mChkSubFolders, 1, 3); |
|
|
|
mLbxMatches = new QListView(searchWidget, "Search in Folders"); |
|
/* Default is to sort by date. TODO: Unfortunately this sorts *while* |
|
inserting, which looks rather strange - the user cannot read |
|
the results so far as they are constantly re-sorted --dnaber |
|
*/ |
|
mLbxMatches->setSorting(2, false); |
|
mLbxMatches->setShowSortIndicator(true); |
|
mLbxMatches->setAllColumnsShowFocus(true); |
|
mLbxMatches->addColumn(i18n("Subject"), |
|
config->readNumEntry("SubjectWidth", 150)); |
|
mLbxMatches->addColumn(i18n("Sender/Receiver"), |
|
config->readNumEntry("SenderWidth", 120)); |
|
mLbxMatches->addColumn(i18n("Date"), |
|
config->readNumEntry("DateWidth", 120)); |
|
mLbxMatches->addColumn(i18n("Folder"), |
|
config->readNumEntry("FolderWidth", 100)); |
|
|
|
mLbxMatches->addColumn(""); // should be hidden |
|
mLbxMatches->setColumnWidthMode( MSGID_COLUMN, QListView::Manual ); |
|
mLbxMatches->setColumnWidth(MSGID_COLUMN, 0); |
|
mLbxMatches->header()->setResizeEnabled(false, MSGID_COLUMN); |
|
|
|
connect(mLbxMatches, SIGNAL(doubleClicked(QListViewItem *)), |
|
this, SLOT(slotShowMsg(QListViewItem *))); |
|
mGrid->addMultiCellWidget(mLbxMatches, mNumRules+2, mNumRules+2, 0, 3); |
|
|
|
mStatusBar = new KStatusBar(searchWidget); |
|
mStatusBar->insertFixedItem(i18n("AMiddleLengthText..."), 0, true); |
|
mStatusBar->changeItem(i18n("Ready."), 0); |
|
mStatusBar->setItemAlignment(0, AlignLeft | AlignVCenter); |
|
mStatusBar->insertItem(QString::null, 1, 1, true); |
|
mStatusBar->setItemAlignment(1, AlignLeft | AlignVCenter); |
|
mGrid->addMultiCellWidget(mStatusBar, mNumRules+4, mNumRules+4, 0, 3); |
|
|
|
mGrid->setColStretch(0, 0); |
|
mGrid->setColStretch(1, 2); |
|
mGrid->setColStretch(2, 1); |
|
mGrid->setColStretch(3, 100); |
|
mGrid->setColStretch(4, 0); |
|
|
|
mGrid->setRowStretch(mNumRules+2, 100); |
|
mGrid->setRowStretch(mNumRules+3, 0); |
|
|
|
mGrid->activate(); |
|
mRules[0]->setFocus(); |
|
|
|
int mainWidth = config->readNumEntry("SearchWidgetWidth", 0); |
|
int mainHeight = config->readNumEntry("SearchWidgetHeight", 0); |
|
|
|
if (mainWidth || mainHeight) |
|
{ |
|
resize(mainWidth, mainHeight); |
|
} |
|
|
|
setMainWidget(searchWidget); |
|
setButtonBoxOrientation(QWidget::Vertical); |
|
|
|
mBtnSearch = actionButton(KDialogBase::User1); |
|
mBtnStop = actionButton(KDialogBase::User2); |
|
mBtnStop->setEnabled(false); |
|
|
|
connect(this, SIGNAL(user1Clicked()), SLOT(slotSearch())); |
|
connect(this, SIGNAL(user2Clicked()), SLOT(slotStop())); |
|
connect(this, SIGNAL(finished()), this, SLOT(slotDelayedDestruct())); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
KMFldSearch::~KMFldSearch() |
|
{ |
|
KConfig* config = KGlobal::config(); |
|
config->setGroup("SearchDialog"); |
|
config->writeEntry("SubjectWidth", mLbxMatches->columnWidth(0)); |
|
config->writeEntry("SenderWidth", mLbxMatches->columnWidth(1)); |
|
config->writeEntry("DateWidth", mLbxMatches->columnWidth(2)); |
|
config->writeEntry("FolderWidth", mLbxMatches->columnWidth(3)); |
|
config->writeEntry("SearchWidgetWidth", width()); |
|
config->writeEntry("SearchWidgetHeight", height()); |
|
config->sync(); |
|
delete [] mRules; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
void KMFldSearch::updStatus(void) |
|
{ |
|
QString genMsg, detailMsg; |
|
|
|
if (!mSearching) |
|
{ |
|
if(!mStopped) |
|
{ |
|
genMsg = i18n("Done"); |
|
detailMsg = i18n("%n match (%1)", "%n matches (%1)", mNumMatches) |
|
.arg(i18n("%n message processed", |
|
"%n messages processed", mCount)); |
|
} |
|
else |
|
{ |
|
genMsg = i18n("Search canceled"); |
|
detailMsg = i18n("%n match so far (%1)", |
|
"%n matches so far (%1)", mNumMatches) |
|
.arg(i18n("%n message processed", |
|
"%n messages processed", mCount)); |
|
} |
|
} |
|
else |
|
{ |
|
genMsg = i18n("%n match", "%n matches", mNumMatches); |
|
detailMsg = i18n("Searching in %1 (message %2)") |
|
.arg(mSearchFolder) |
|
.arg(mCount); |
|
} |
|
|
|
mStatusBar->changeItem(genMsg, 0); |
|
mStatusBar->changeItem(detailMsg, 1); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
void KMFldSearch::keyPressEvent(QKeyEvent *evt) |
|
{ |
|
if (evt->key() == Key_Escape && mSearching) |
|
{ |
|
mSearching = false; |
|
return; |
|
} |
|
|
|
KDialogBase::keyPressEvent(evt); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
bool KMFldSearch::searchInMessage(KMMessage* aMsg, const QCString& aMsgStr) |
|
{ |
|
int i; |
|
bool matches = true; |
|
|
|
mCount++; |
|
if (mCount % 100 == 0) updStatus(); |
|
for(i=0; matches && i<mNumRules; i++) |
|
if (!mRules[i]->matches(aMsg, aMsgStr)) |
|
matches = false; |
|
|
|
return matches; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
void KMFldSearch::slotFolderComplete(KMFolderImap *folder, bool success) |
|
{ |
|
disconnect(folder, SIGNAL(folderComplete(KMFolderImap*, bool)), |
|
this, SLOT(slotFolderComplete(KMFolderImap*, bool))); |
|
mFetchingInProgress--; |
|
|
|
if (success) |
|
{ |
|
searchInFolder(folder, mChkSubFolders->isChecked(), FALSE); |
|
if (mFetchingInProgress == 0) searchDone(); |
|
} |
|
else |
|
{ |
|
searchDone(); |
|
} |
|
|
|
folder->close(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
void KMFldSearch::searchInFolder(QGuardedPtr<KMFolder> aFld, bool recursive, |
|
bool fetchHeaders) |
|
{ |
|
if (fetchHeaders && aFld->protocol() == "imap") |
|
{ |
|
KMFolder *fld = aFld; |
|
KMFolderImap *imap_folder = static_cast<KMFolderImap*>(fld); |
|
if (imap_folder && |
|
imap_folder->getContentState() == KMFolderImap::imapNoInformation) |
|
{ |
|
mFetchingInProgress++; |
|
imap_folder->open(); |
|
connect(imap_folder, |
|
SIGNAL(folderComplete(KMFolderImap *, bool)), |
|
SLOT(slotFolderComplete(KMFolderImap *, bool))); |
|
imap_folder->getFolder(); |
|
return; |
|
} |
|
} |
|
|
|
KMMessage* msg=0; |
|
int i, num, upd; |
|
QString str; |
|
QCString cStr; |
|
bool unget = false, fastMode = true, found; |
|
|
|
assert(!aFld.isNull()); |
|
|
|
if (aFld->isSystemFolder()) |
|
mSearchFolder = i18n(aFld->name().utf8()); |
|
else |
|
mSearchFolder = aFld->name(); |
|
|
|
kapp->processEvents(); |
|
if (aFld->open() != 0) |
|
{ |
|
kdDebug(5006) << "Cannot open folder '" << aFld->name() << "'" << endl; |
|
return; |
|
} |
|
|
|
for(i=0; i<mNumRules; i++) |
|
if (!mRules[i]->isHeaderField()) fastMode = false; |
|
|
|
num = aFld->count(); |
|
for (i=0, upd=0; i<num && mSearching; i++, upd++) |
|
{ |
|
if (fastMode) |
|
{ |
|
found = searchInMessage(NULL, aFld->getMsgString(i, cStr)); |
|
if (found) |
|
{ |
|
unget = !aFld->isMessage(i); |
|
msg = aFld->getMsg(i); |
|
} else unget = false; |
|
} |
|
else |
|
{ |
|
unget = !aFld->isMessage(i); |
|
msg = aFld->getMsg(i); |
|
found = msg && searchInMessage(msg, QCString()); |
|
} |
|
if (found) |
|
{ |
|
QString from; |
|
if(mSearchFolder == i18n("sent-mail")) |
|
from = msg->to(); |
|
else |
|
from = msg->from(); |
|
|
|
(void)new QListViewItem(mLbxMatches, |
|
msg->subject(), from, msg->dateIsoStr(), |
|
mSearchFolder, |
|
QString::number(kernel->msgDict()->getMsgSerNum(aFld, i))); |
|
mNumMatches++; |
|
} |
|
if (upd > 10) |
|
{ |
|
kapp->processEvents(); |
|
upd = 0; |
|
if (!aFld) // Folder deleted while searching! |
|
break; |
|
num = aFld->count(); |
|
} |
|
if (unget) aFld->unGetMsg(i); |
|
} |
|
|
|
if(!mSearching) |
|
// was stopped |
|
mStopped = true; |
|
|
|
updStatus(); |
|
|
|
aFld->close(); |
|
|
|
if (!recursive) |
|
return; |
|
|
|
KMFolderDir *dir = aFld->child(); |
|
if (dir) |
|
{ |
|
KMFolder *folder; |
|
QPtrListIterator<KMFolderNode> it(*dir); |
|
for ( ; it.current(); ++it ) |
|
{ |
|
KMFolderNode *node = (*it); |
|
if (!node->isDir()) |
|
{ |
|
folder = static_cast<KMFolder*>(node); |
|
searchInFolder(folder, recursive); |
|
} |
|
} |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
void KMFldSearch::searchInAllFolders(void) |
|
{ |
|
QValueList<QGuardedPtr<KMFolder> > folders; |
|
QGuardedPtr<KMFolder> folder; |
|
QStringList str; |
|
int i = 0; |
|
|
|
mMainWin->folderTree()->createFolderList( &str, &folders ); |
|
for (; folders.at(i) != folders.end(); ++i) |
|
{ |
|
folder = *folders.at(i); |
|
// Stop pressed? |
|
if(!mSearching) |
|
{ |
|
break; |
|
} |
|
|
|
if (folder && (folder->protocol() != "imap")) |
|
{ |
|
searchInFolder(folder); |
|
} |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
void KMFldSearch::slotFolderActivated(int /*nr*/) |
|
{ |
|
KMFolder* folder = mCbxFolders->getFolder(); |
|
|
|
mChkbxSpecificFolders->setChecked(true); |
|
mBtnSearch->setEnabled(folder); |
|
|
|
for (int i = 0; i < mNumRules; i++) |
|
{ |
|
mRules[i]->updateFunctions(folder); |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
void KMFldSearch::activateFolder(KMFolder *curFolder) |
|
{ |
|
mChkbxSpecificFolders->setChecked(true); |
|
mCbxFolders->setFolder(curFolder); |
|
mRules[0]->setFocus(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
void KMFldSearch::slotSearch() |
|
{ |
|
mLastFocus = focusWidget(); |
|
mBtnSearch->setFocus(); // set focus so we don't miss key event |
|
|
|
mCount = 0; |
|
mStopped = false; |
|
mNumMatches = 0; |
|
mSearching = true; |
|
mFetchingInProgress = 0; |
|
|
|
mBtnSearch->setEnabled(false); |
|
mBtnStop->setEnabled(true); |
|
|
|
enableGUI(); |
|
mLbxMatches->clear(); |
|
kapp->processEvents(); |
|
|
|
for (int i = 0; i < mNumRules; ++i) |
|
mRules[i]->prepare(); |
|
|
|
if (mSearchAllFolders) |
|
{ |
|
searchInAllFolders(); |
|
} |
|
else |
|
{ |
|
KMFolder *folder = mCbxFolders->getFolder(); |
|
|
|
if (!folder) |
|
{ |
|
return; |
|
} |
|
|
|
searchInFolder(folder, mChkSubFolders->isChecked()); |
|
} |
|
|
|
if (!mFetchingInProgress) searchDone(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
void KMFldSearch::searchDone() |
|
{ |
|
mSearching=false; |
|
updStatus(); |
|
|
|
mBtnSearch->setEnabled(true); |
|
mBtnStop->setEnabled(false); |
|
|
|
enableGUI(); |
|
if( mLastFocus ) |
|
mLastFocus->setFocus(); |
|
if (mCloseRequested) close(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
void KMFldSearch::slotStop() |
|
{ |
|
mSearching = false; |
|
mBtnStop->setEnabled(false); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
void KMFldSearch::slotClose() |
|
{ |
|
accept(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
void KMFldSearch::closeEvent(QCloseEvent *e) |
|
{ |
|
if (mSearching) |
|
{ |
|
mSearching = false; |
|
mCloseRequested = true; |
|
e->ignore(); |
|
} |
|
else |
|
{ |
|
KDialogBase::closeEvent(e); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
void KMFldSearch::slotSearchAllFolders(bool on) |
|
{ |
|
if (on) |
|
{ |
|
mChkbxSpecificFolders->setChecked(false); |
|
mCbxFolders->setEnabled(false); |
|
mChkSubFolders->setEnabled(false); |
|
mSearchAllFolders = true; |
|
} |
|
else if (!mChkbxSpecificFolders->isChecked()) |
|
{ |
|
mChkbxAllFolders->setChecked(true); |
|
// mChkbxSpecificFolders->setChecked(true); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
void KMFldSearch::slotSearchSpecificFolder(bool on) |
|
{ |
|
if (on) |
|
{ |
|
mChkbxAllFolders->setChecked(false); |
|
mCbxFolders->setEnabled(true); |
|
mChkSubFolders->setEnabled(true); |
|
mSearchAllFolders = false; |
|
} |
|
else if (!mChkbxAllFolders->isChecked()) |
|
{ |
|
mChkbxSpecificFolders->setChecked(true); |
|
// mChkbxAllFolders->setChecked(true); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
bool KMFldSearch::slotShowMsg(QListViewItem *item) |
|
{ |
|
if(!item) |
|
{ |
|
return false; |
|
} |
|
|
|
KMFolder* folder; |
|
int msgIndex; |
|
kernel->msgDict()->getLocation(item->text(MSGID_COLUMN).toUInt(), |
|
&folder, &msgIndex); |
|
|
|
if (!folder || msgIndex < 0) |
|
{ |
|
return false; |
|
} |
|
|
|
mMainWin->slotSelectFolder(folder); |
|
KMMessage* message = folder->getMsg(msgIndex); |
|
if (!message) |
|
{ |
|
return false; |
|
} |
|
|
|
mMainWin->slotSelectMessage(message); |
|
return true; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
void KMFldSearch::enableGUI() |
|
{ |
|
actionButton(KDialogBase::Close)->setEnabled(!mSearching); |
|
mCbxFolders->setEnabled(!mSearching); |
|
mChkSubFolders->setEnabled(!mSearching); |
|
mChkbxAllFolders->setEnabled(!mSearching); |
|
mChkbxSpecificFolders->setEnabled(!mSearching); |
|
|
|
for(int i = 0; i < mNumRules; i++) |
|
mRules[i]->setEnabled(!mSearching); |
|
} |
|
|
|
|
|
//============================================================================= |
|
KMFldSearchRule::KMFldSearchRule(QWidget* aParent, QGridLayout* aGrid, |
|
int aRow, int aCol) |
|
{ |
|
assert(aParent!=NULL); |
|
assert(aGrid!=NULL); |
|
|
|
mRow = aRow; |
|
mCbxField = new QComboBox(true, aParent); |
|
insertFieldItems(TRUE); |
|
mCbxField->setMinimumSize(mCbxField->sizeHint()); |
|
mCbxField->setMaximumSize(1024, mCbxField->sizeHint().height()); |
|
|
|
mCbxFunc = new QComboBox(false, aParent); |
|
mCbxFunc->insertItem(i18n("contains")); |
|
mCbxFunc->insertItem(i18n("doesn't contain")); |
|
mCbxFunc->insertItem(i18n("equals")); |
|
mCbxFunc->insertItem(i18n("not equal")); |
|
mCbxFunc->insertItem(i18n("matches regular expr.")); |
|
mCbxFunc->insertItem(i18n("doesn't match regular expr.")); |
|
mCbxFunc->setMinimumSize(mCbxFunc->sizeHint()); |
|
mCbxFunc->setMaximumSize(1024, mCbxFunc->sizeHint().height()); |
|
|
|
mEdtValue = new QLineEdit(aParent); |
|
mEdtValue->setMinimumSize(mCbxFunc->sizeHint()); |
|
mEdtValue->setMaximumSize(1024, mCbxFunc->sizeHint().height()); |
|
|
|
QLabel* lbl; |
|
|
|
if (mRow > 2) |
|
{ |
|
lbl = new QLabel(i18n("and"), aParent); |
|
lbl->setAlignment(QWidget::AlignRight|QWidget::AlignVCenter); |
|
} |
|
else |
|
{ |
|
lbl = new QLabel(i18n("Show messages &where"), aParent); |
|
lbl->setBuddy(mCbxField); |
|
lbl->setAlignment(QWidget::AlignVCenter); |
|
} |
|
|
|
lbl->setMinimumSize(lbl->sizeHint()); |
|
|
|
aGrid->addWidget(lbl, aRow, aCol); |
|
aGrid->addWidget(mCbxField, aRow, aCol + 1); |
|
aGrid->addWidget(mCbxFunc, aRow, aCol + 2); |
|
aGrid->addWidget(mEdtValue, aRow, aCol + 3); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
KMFldSearchRule::~KMFldSearchRule() |
|
{ |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
void KMFldSearchRule::insertFieldItems(bool all) |
|
{ |
|
int last = mCbxField->currentItem(); |
|
mCbxField->clear(); |
|
if (mRow > 2) mCbxField->insertItem(QString::null); |
|
mCbxField->insertItem("Subject"); |
|
mCbxField->insertItem("From"); |
|
mCbxField->insertItem("To"); |
|
mCbxField->insertItem("Cc"); |
|
if (all) { |
|
mCbxField->insertItem("Organization"); |
|
mCbxField->insertItem(i18n("<complete message>")); |
|
} |
|
|
|
if (last < mCbxField->count()) |
|
mCbxField->setCurrentItem(last); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
void KMFldSearchRule::updateFunctions(KMFolder* folder) |
|
{ |
|
insertFieldItems(folder && (folder->protocol() != "imap")); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
void KMFldSearchRule::prepare(void) |
|
{ |
|
mFieldIdx = mCbxField->currentItem(); |
|
mField = mCbxField->currentText(); |
|
mHeaderField = QString("\n" + mField + ": ").latin1(); |
|
mFieldLength = mField.length() + 3; |
|
mFunc = mCbxFunc->currentItem(); |
|
mValue = mEdtValue->text(); |
|
mNonLatin = mValue.utf8().length() != mValue.length(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
bool KMFldSearchRule::matches(const KMMessage* aMsg, const QCString& aMsgStr) |
|
const |
|
{ |
|
QString value; |
|
|
|
if (mField.isEmpty()) return true; |
|
if (aMsg) |
|
{ |
|
if( !isHeaderField() ) { |
|
value = aMsg->headerAsString(); |
|
QCString charset, content; |
|
if (aMsg->typeStr().lower().find("multipart/") != -1) |
|
{ |
|
KMMessagePart mp; |
|
aMsg->bodyPart(0,&mp); |
|
charset = mp.charset(); |
|
content = mp.bodyDecoded(); |
|
} else { |
|
charset = aMsg->charset(); |
|
content = aMsg->bodyDecoded(); |
|
} |
|
if (!mNonLatin || charset.isEmpty() || charset == "us-ascii" |
|
|| charset == "iso-8859-1") // Speedup |
|
value += content; |
|
else { |
|
QTextCodec *codec = KMMsgBase::codecForName(charset); |
|
if (codec) value += codec->toUnicode(content); |
|
else value += content; |
|
} |
|
} else { |
|
value = aMsg->headerField(mField.latin1()); |
|
} |
|
} else { |
|
int start, stop; |
|
char ch = '\0'; |
|
start = aMsgStr.find(mHeaderField); |
|
if (start == -1) return false; |
|
int endOfHeader = aMsgStr.find("\n\n"); |
|
if (endOfHeader == -1) endOfHeader = aMsgStr.find("\n\r\n"); |
|
if (endOfHeader < start) return false; |
|
start += mFieldLength; |
|
stop = aMsgStr.find("\n", start); |
|
while (stop != -1 && (ch = aMsgStr.at(stop + 1)) == ' ' || ch == '\t') |
|
stop = aMsgStr.find("\n", stop + 1); |
|
if (stop == -1) value = KMMsgBase::decodeRFC2047String(aMsgStr.mid(start)); |
|
else value = KMMsgBase::decodeRFC2047String(aMsgStr.mid(start, |
|
stop - start)); |
|
} |
|
// also see KMFilterRule::matches() for a similar function: |
|
switch(mFunc) |
|
{ |
|
case Equal: |
|
return (value == mValue); |
|
case NotEqual: |
|
return (value != mValue); |
|
case Contains: |
|
return value.contains(mValue, FALSE); |
|
case NotContains: |
|
return ( ! value.contains(mValue, FALSE) ); |
|
case MatchesRegExp: |
|
return (value.find(QRegExp(mValue, FALSE)) >= 0); |
|
case NotMatchesRegExp: |
|
return (value.find(QRegExp(mValue, FALSE)) < 0); |
|
default: |
|
kdDebug(5006) << "KMFldSearchRule::matches: wrong rule func #" << mFunc << endl; |
|
return false; |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
bool KMFldSearchRule::isHeaderField() const |
|
{ |
|
return mField != i18n("<complete message>"); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
void KMFldSearchRule::setEnabled(bool b) { |
|
mCbxField->setEnabled(b); |
|
mCbxFunc->setEnabled(b); |
|
mEdtValue->setEnabled(b); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
void KMFldSearchRule::setFocus() { |
|
mEdtValue->setFocus(); |
|
} |
|
//----------------------------------------------------------------------------- |
|
#include "kmfldsearch.moc"
|
|
|