// kmfilterdlg.cpp #include #include "kmfilterdlg.h" #include "kmfilter.h" #include "kmfiltermgr.h" #include "kmglobal.h" #include "kmfolder.h" #include "kmfolderdir.h" #include "kmfoldermgr.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static QStringList sFilterOpList, sFilterFuncList, sFilterFieldList, sFilterActionList; //============================================================================= KMFaComboBox::KMFaComboBox(QWidget* p, const char* n): KMFaComboBoxInherited(false, p, n) { initMetaObject(); connect(this, SIGNAL(activated(int)), SLOT(slotSelected(int))); } void KMFaComboBox::slotSelected(int idx) { emit selectType(this, idx); } //============================================================================= KMFilterDlg::KMFilterDlg(QWidget* parent, const char* name): KMFilterDlgInherited(parent, name, FALSE) { KButtonBox *buttonBox; QPushButton *btnHelp; QGridLayout *fgrid, *grid, *agrid; int h, w, i; QSize sz; updown_move_semaphore = 1; initMetaObject(); grid = new QGridLayout(this, 4, 2, 4, 4); mFilter = 0; setCaption(i18n("Filter Rules")); KWin::setIcons(winId(), kapp->icon(), kapp->miniIcon()); mFilterList = new QListBox(this); mFilterList->setMinimumSize(100, 200); grid->addMultiCellWidget(mFilterList, 0, 2, 0, 0); connect(mFilterList,SIGNAL(highlighted(int)),SLOT(slotFilterSelected(int))); initLists(); //---------- static filter fields fgrid = new QGridLayout(3, 3, 4); grid->addLayout(fgrid, 0, 1); mRuleFuncA = new QComboBox(false, this); sz = mRuleFuncA->sizeHint(); w = sz.width(); h = sz.height(); mCbxHeight = h; mRuleFuncA->setMinimumSize(110, h); mRuleFuncA->setMaximumSize(32767, h); mRuleFuncA->insertStringList(sFilterFuncList); fgrid->addWidget(mRuleFuncA, 0, 1); mRuleFuncB = new QComboBox(false, this); mRuleFuncB->setMinimumSize(110, h); mRuleFuncB->setMaximumSize(32767, h); mRuleFuncB->insertStringList(sFilterFuncList); fgrid->addWidget(mRuleFuncB, 2, 1); mRuleFieldA = new QComboBox(true, this); mRuleFieldA->insertStringList(sFilterFieldList); mRuleFieldA->setMinimumSize(100, h); mRuleFieldA->setMaximumSize(32767, h); fgrid->addWidget(mRuleFieldA, 0, 0); mRuleFieldB = new QComboBox(true, this); mRuleFieldB->insertStringList(sFilterFieldList); mRuleFieldB->setMinimumSize(100, h); mRuleFieldB->setMaximumSize(32767, h); fgrid->addWidget(mRuleFieldB, 2, 0); mRuleValueA = new QLineEdit(this); mRuleValueA->adjustSize(); mRuleValueA->setMinimumSize(80, mRuleValueA->sizeHint().height()); fgrid->addWidget(mRuleValueA, 0, 2); mRuleValueB = new QLineEdit(this); mRuleValueB->adjustSize(); mRuleValueB->setMinimumSize(80, mRuleValueB->sizeHint().height()); fgrid->addWidget(mRuleValueB, 2, 2); mRuleOp = new QComboBox(false, this); mRuleOp->insertStringList(sFilterOpList); mRuleOp->setMinimumSize(50, h); mRuleOp->setMaximumSize(32767, h); fgrid->addMultiCellWidget(mRuleOp, 1, 1, 0, 1); //---------- filter action area agrid = new QGridLayout(FILTER_MAX_ACTIONS, 3, 4); grid->addLayout(agrid, 1, 1); for (i=0; iinsertStringList(sFilterActionList); mFaType[i]->setMinimumSize(80, h); mFaType[i]->setMaximumSize(32767, h); agrid->addWidget(mFaType[i], i, 0); connect(mFaType[i], SIGNAL(selectType(KMFaComboBox*, int)), SLOT(slotActionTypeSelected(KMFaComboBox*,int))); mFaBtnDetails[i] = 0; mFaField[i] = 0; } mActLineHeight = mFaType[0]->size().height(); //---------- button area buttonBox = new KButtonBox(this, Horizontal, 0, 2); grid->addMultiCellWidget(buttonBox, 3, 3, 0, 1); mBtnUp = buttonBox->addButton(i18n("Up")); connect(mBtnUp,SIGNAL(clicked()),SLOT(slotBtnUp())); mBtnDown = buttonBox->addButton(i18n("Down")); connect(mBtnDown,SIGNAL(clicked()),SLOT(slotBtnDown())); mBtnNew = buttonBox->addButton(i18n("New")); connect(mBtnNew,SIGNAL(clicked()),SLOT(slotBtnNew())); mBtnDelete = buttonBox->addButton(i18n("Delete")); connect(mBtnDelete,SIGNAL(clicked()),SLOT(slotBtnDelete())); buttonBox->addStretch(); mBtnOk = buttonBox->addButton(i18n("OK")); connect(mBtnOk,SIGNAL(clicked()),SLOT(slotBtnOk())); mBtnCancel = buttonBox->addButton(i18n("Cancel")); connect(mBtnCancel,SIGNAL(clicked()),SLOT(slotBtnCancel())); buttonBox->addStretch(); btnHelp = buttonBox->addButton(i18n("Help")); connect(btnHelp,SIGNAL(clicked()),SLOT(slotBtnHelp())); buttonBox->layout(); buttonBox->setMaximumSize(32767, buttonBox->sizeHint().height()); buttonBox->setMinimumSize(buttonBox->sizeHint()); //---------- grid->setRowStretch(0, 2); grid->setRowStretch(1, 10); grid->setRowStretch(2, 2); grid->setColStretch(0, 10); grid->setColStretch(1, 20); grid->setRowStretch(3, 100); grid->activate(); /* enableControls(); resize(buttonBox->sizeHint().width()*1.2, sizeHint().height()); show(); */ reloadFilterList(); mCurFilterIdx = -1; if(mFilterList->count() > 0) mFilterList->setCurrentItem(0); enableControls(); resize(static_cast(buttonBox->sizeHint().width()*1.2), sizeHint().height()); show(); } //----------------------------------------------------------------------------- KMFilterDlg::~KMFilterDlg() { // // Espen 2000-05-21: Would be better to send a signal but I can't // get it to work here. // kernel->filterMgr()->dialogDestroyed(); } //----------------------------------------------------------------------------- void KMFilterDlg::reloadFilterList(void) { KMFilter* filter; int i, num; mFilterList->clear(); num = kernel->filterMgr()->count(); for (i=0; ifilterMgr()->at(i); if (!filter) continue; mFilterList->insertItem(filter->name()); } } //----------------------------------------------------------------------------- void KMFilterDlg::clear(void) { int i; for (i=0; isetCurrentItem((int)aFilter->oper()); i = indexOfRuleField(aFilter->ruleA().field()); if (i < 0) { mRuleFieldA->changeItem(aFilter->ruleA().field(),0); i = 0; } else mRuleFieldA->changeItem(" ",0); mRuleFieldA->setCurrentItem(i); mRuleFuncA->setCurrentItem((int)aFilter->ruleA().function()); mRuleValueA->setText(aFilter->ruleA().contents()); i = indexOfRuleField(aFilter->ruleB().field()); if (i < 0) { mRuleFieldB->changeItem(aFilter->ruleB().field(),0); i = 0; } else mRuleFieldB->changeItem(" ",0); mRuleFieldB->setCurrentItem(i); mRuleFuncB->setCurrentItem((int)aFilter->ruleB().function()); mRuleValueB->setText(aFilter->ruleB().contents()); for (i=0; iaction(i); if (mFaField[i]) delete mFaField[i]; mFaField[i] = 0; if (!action) mFaType[i]->setCurrentItem(0); else { mFaType[i]->setCurrentItem(1+kernel->filterActionDict()->indexOf(action->name())); pwidg = action->createParamWidget(this); mFaField[i] = pwidg; if (pwidg) { QPoint pos = mFaType[i]->pos(); pos.setX(pos.x() + mFaType[i]->width() + 4); w = width() - pos.x(); if (w > 300) w = 300; sz.setWidth(w); sz.setHeight(pwidg->height()); pwidg->resize(sz); pwidg->move(pos); pwidg->show(); } } } mFilter = aFilter; mCurFilterIdx = mFilterList->currentItem(); connect(mRuleFieldA, SIGNAL(textChanged(const QString&)), this, SLOT(updateCurFilterName(const QString&))); connect(mRuleValueA, SIGNAL(textChanged(const QString&)), this, SLOT(updateCurFilterName(const QString&))); } //----------------------------------------------------------------------------- void KMFilterDlg::resizeEvent(QResizeEvent *qre) { kdDebug() << "KMFilterDlg::resizeEvent" << endl; kdDebug() << QString( "width %1" ).arg( qre->size().width() ) << endl; int i, w; QWidget* pwidg; QSize sz; for (i=0; ipos(); pos.setX(pos.x() + mFaType[i]->width() + 4); w = qre->size().width() - pos.x(); if (w > 300) w = 300; sz.setWidth(w); sz.setHeight(pwidg->height()); pwidg->resize(sz); pwidg->move(pos); kdDebug() << QString( "posx %1" ).arg( pos.x() ) << endl; } } //----------------------------------------------------------------------------- QString KMFilterDlg::ruleFieldToEnglish(const QString & i18nVal) { if (i18nVal == i18n("")) return QString(""); if (i18nVal == i18n("")) return QString(""); if (i18nVal == i18n("")) return QString(""); if (i18nVal == i18n("")) return QString(""); return i18nVal; } //----------------------------------------------------------------------------- void KMFilterDlg::applyFilterChanges(void) { KMFilterAction* action; int i; if (!mFilter || !updown_move_semaphore) return; mFilter->ruleA().init(ruleFieldToEnglish(mRuleFieldA->currentText()), (KMFilterRule::Function)mRuleFuncA->currentItem(), mRuleValueA->text()); mFilter->ruleB().init(ruleFieldToEnglish(mRuleFieldB->currentText()), (KMFilterRule::Function)mRuleFuncB->currentItem(), mRuleValueB->text()); mFilter->setOper((KMFilter::Operator)mRuleOp->currentItem()); for (i=0; iaction(i); if (!action) continue; action->applyParamWidgetValue(mFaField[i]); } } //----------------------------------------------------------------------------- void KMFilterDlg::updateCurFilterName(const QString &/*text*/) { if (mCurFilterIdx < 0) return; mFilter->setName(QString("<") + mRuleFieldA->currentText() + ">:" + mRuleValueA->text()); QObject::disconnect(mFilterList,SIGNAL(highlighted(int)),this,SLOT(slotFilterSelected(int))); mFilterList->changeItem(mFilter->name(), mCurFilterIdx); connect(mFilterList,SIGNAL(highlighted(int)),SLOT(slotFilterSelected(int))); } //----------------------------------------------------------------------------- bool KMFilterDlg::testOpts(const QWidget* w) const { if (!w) kdDebug() << "KMFilterDlg: no widget given" << endl; return (w!=0); } //----------------------------------------------------------------------------- QPushButton* KMFilterDlg::createDetailsButton(void) { QPushButton* btn; btn = mFaBtnDetails[mGridRow]; if (!btn) { btn = new QPushButton("...", this); mFaBtnDetails[mGridRow] = btn; } return btn; } //----------------------------------------------------------------------------- QLineEdit* KMFilterDlg::createEdit(const QString aTxt) { QLineEdit* edt = new QLineEdit(this); edt->setText(aTxt); return edt; } //----------------------------------------------------------------------------- QComboBox* KMFilterDlg::createFolderCombo( QStringList *str, QValueList< QGuardedPtr > *folders, QGuardedPtr curFolder ) { QComboBox* cbx = new QComboBox(false, this); int i=0,idx=-1; cbx->setFixedHeight(mCbxHeight); QStringList::Iterator st; for( st = str->begin(); st != str->end(); ++st) cbx->insertItem(*st); QGuardedPtr folder; while (folders->at(i) != folders->end()) { folder = *folders->at(i); if (folder == curFolder) idx = i; ++i; } if (idx>=0) cbx->setCurrentItem(idx); return cbx; } //----------------------------------------------------------------------------- QComboBox* KMFilterDlg::createCombo( QStringList *str, QString curItem ) { QComboBox* cbx = new QComboBox(false, this); cbx->setFixedHeight(mCbxHeight); QStringList::Iterator st; for( st = str->begin(); st != str->end(); ++st) { cbx->insertItem(*st); if (*st == curItem) cbx->setCurrentItem( cbx->count() - 1 ); } return cbx; } //----------------------------------------------------------------------------- void KMFilterDlg::slotActionTypeSelected(KMFaComboBox* cbx, int idx) { KMFilterAction* action; QWidget* widg; QPoint pos; QSize sz; int i, w; if (!mFilter) return; for (i=FILTER_MAX_ACTIONS-1; i>0; i--) if (cbx == mFaType[i]) break; if (i < 0) return; if (mFaField[i]) delete mFaField[i]; mFaField[i] = 0; mGridRow = i; if (mFilter->action(i)) delete mFilter->action(i); action = kernel->filterActionDict()->create( kernel->filterActionDict()->nameOf(*(sFilterActionList.at(idx)))); mFilter->setAction(i, action); if (!action || idx < 0) { kdDebug() << "no action selected" << endl; return; } widg = action->createParamWidget(this); mFaField[i] = widg; if (!widg) return; pos = mFaType[i]->pos(); pos.setX(pos.x() + mFaType[idx]->width() + 4); widg->move(pos); w = width() - pos.x(); if (w > 300) w = 300; sz.setWidth(w); sz.setHeight(widg->height()); widg->resize(sz); widg->show(); } //----------------------------------------------------------------------------- void KMFilterDlg::slotFilterSelected(int idx) { KMFilter* filter; kdDebug() << QString( "mCurFilterIdx %1 idx %2" ).arg( mCurFilterIdx ).arg( idx ) << endl; if (mCurFilterIdx == idx) return; if (mFilter) applyFilterChanges(); if ((uint)idx < kernel->filterMgr()->count()) { filter = kernel->filterMgr()->at(idx); if (filter) showFilter(filter); } else { clear(); mFilter = 0; } enableControls(); } //----------------------------------------------------------------------------- void KMFilterDlg::slotBtnUp() { int idx = mFilterList->currentItem(); KMFilter* filter; if (idx < 1) return; applyFilterChanges(); mCurFilterIdx = -1; updown_move_semaphore = 0; filter = kernel->filterMgr()->take(idx); assert(filter != 0); kernel->filterMgr()->insert(idx-1, filter); // This next line is to work around a QT 2.0 CVS bug // If it is omitted the listbox is refreshed incorrectly // and looks like it contains duplicate highlighted items mFilterList->setCurrentItem(idx-1); mFilterList->removeItem(idx); mFilterList->insertItem(filter->name(), idx-1); mFilterList->setCurrentItem(idx-1); enableControls(); updown_move_semaphore = 1; } //----------------------------------------------------------------------------- void KMFilterDlg::slotBtnDown() { int idx = mFilterList->currentItem(); KMFilter* filter; if (idx < 0 || idx >= (int)mFilterList->count()-1) return; applyFilterChanges(); mCurFilterIdx = -1; updown_move_semaphore = 0; filter = kernel->filterMgr()->take(idx); assert(filter != 0); kernel->filterMgr()->insert(idx+1, filter); mFilterList->removeItem(idx); mFilterList->insertItem(filter->name(), idx+1); mFilterList->setCurrentItem(idx+1); enableControls(); updown_move_semaphore = 1; } //----------------------------------------------------------------------------- void KMFilterDlg::slotBtnNew() { int idx; KMFilter* filter = new KMFilter; filter->setName(i18n("Unnamed")); applyFilterChanges(); mCurFilterIdx = -1; idx = mFilterList->currentItem(); if (idx >= 0) kernel->filterMgr()->insert(idx, filter); else kernel->filterMgr()->append(filter); idx = kernel->filterMgr()->find(filter); mFilterList->insertItem(filter->name(), idx); mFilterList->setCurrentItem(idx); slotFilterSelected(idx); enableControls(); } //----------------------------------------------------------------------------- void KMFilterDlg::slotBtnDelete() { int idx = mFilterList->currentItem(); if (idx < 0) return; mFilter = 0; mCurFilterIdx = -1; QObject::disconnect(mFilterList,SIGNAL(highlighted(int)),this,SLOT(slotFilterSelected(int))); mFilterList->removeItem(idx); kernel->filterMgr()->remove(idx); if (idx >= (int)kernel->filterMgr()->count()) idx = (int)kernel->filterMgr()->count()-1; if (idx >= 0) { mFilterList->setCurrentItem(idx); // workaround QT bug where current item is not selected // after item is deleted mFilterList->setSelected(idx, TRUE); } else mCurFilterIdx = -1; enableControls(); connect(mFilterList,SIGNAL(highlighted(int)),SLOT(slotFilterSelected(int))); slotFilterSelected( idx ); // workaround another QT bug } //----------------------------------------------------------------------------- void KMFilterDlg::slotBtnOk() { if (mFilter) applyFilterChanges(); kernel->filterMgr()->writeConfig(); KMFilterDlgInherited::close(); } //----------------------------------------------------------------------------- void KMFilterDlg::slotBtnCancel() { kernel->filterMgr()->readConfig(); KMFilterDlgInherited::close(); } //----------------------------------------------------------------------------- void KMFilterDlg::closeEvent( QCloseEvent *e ) { kernel->filterMgr()->readConfig(); KMFilterDlgInherited::closeEvent(e); } //----------------------------------------------------------------------------- void KMFilterDlg::slotBtnHelp() { kapp->invokeHTMLHelp( QString( kapp->name() )+"/index-3.html", "ss3.5" ); } //----------------------------------------------------------------------------- int KMFilterDlg::indexOfRuleField(const QString aName) const { int i; for (i=sFilterFieldList.count()-1; i>=0; i--) { if (*(sFilterFieldList.at(i))==i18n(aName)) break; } return i; } //----------------------------------------------------------------------------- void KMFilterDlg::initLists() { QString name; //---------- initialize list of filter actions if (sFilterActionList.count() <= 0) { sFilterActionList.append(i18n("")); for (name=kernel->filterActionDict()->first(); !name.isEmpty(); name=kernel->filterActionDict()->next()) { sFilterActionList.append(kernel->filterActionDict()->currentLabel()); } } //---------- initialize list of filter functions if (sFilterOpList.count() <= 0) { sFilterOpList.append(i18n("ignore")); sFilterOpList.append(i18n("and")); sFilterOpList.append(i18n("unless")); sFilterOpList.append(i18n("or")); } //---------- initialize list of filter operators if (sFilterFuncList.count() <= 0) { sFilterFuncList.append(i18n("equals")); sFilterFuncList.append(i18n("not equal")); sFilterFuncList.append(i18n("contains")); sFilterFuncList.append(i18n("doesn't contain")); sFilterFuncList.append(i18n("regular expression")); } //---------- initialize list of filter operators if (sFilterFieldList.count() <= 0) { sFilterFieldList.append(" "); // also see KMFilterRule::matches() and KMFilterDlg::ruleFieldToEnglish() // if you change the following strings! sFilterFieldList.append(i18n("")); sFilterFieldList.append(i18n("")); sFilterFieldList.append(i18n("")); sFilterFieldList.append(i18n("")); sFilterFieldList.append("Subject"); sFilterFieldList.append("From"); sFilterFieldList.append("To"); sFilterFieldList.append("Cc"); sFilterFieldList.append("Reply-To"); sFilterFieldList.append("Organization"); sFilterFieldList.append("Resent-From"); sFilterFieldList.append("X-Loop"); } } void KMFilterDlg::enableControls() { bool upEnabled = FALSE; bool downEnabled = FALSE; bool deleteEnabled = FALSE; int i; if (mFilterList->count() > 0) deleteEnabled = TRUE; if (deleteEnabled && (mFilterList->currentItem() != 0)) upEnabled = TRUE; if (deleteEnabled && (mFilterList->currentItem() != (int)mFilterList->count() - 1)) downEnabled = TRUE; mBtnUp->setEnabled( upEnabled ); mBtnDown->setEnabled( downEnabled ); mBtnDelete->setEnabled( deleteEnabled ); for (i=0; isetEnabled( deleteEnabled ); mRuleFieldA->setEnabled( deleteEnabled ); mRuleFieldB->setEnabled( deleteEnabled ); mRuleFuncA->setEnabled( deleteEnabled ); mRuleFuncB->setEnabled( deleteEnabled ); mRuleValueA->setEnabled( deleteEnabled ); mRuleValueB->setEnabled( deleteEnabled ); mRuleOp->setEnabled( deleteEnabled ); } //----------------------------------------------------------------------------- #include "kmfilterdlg.moc"