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.
716 lines
24 KiB
716 lines
24 KiB
/* |
|
|
|
SPDX-FileCopyrightText: Marc Mutz <mutz@kde.org> |
|
|
|
SPDX-License-Identifier: GPL-2.0-or-later |
|
*/ |
|
|
|
#include "searchpatternedit.h" |
|
#include "widgethandler/rulewidgethandlermanager.h" |
|
using MailCommon::RuleWidgetHandlerManager; |
|
#include "mailcommon_debug.h" |
|
|
|
#include <KComboBox> |
|
#include <KLocalizedString> |
|
#include <Libkdepim/LineEditCatchReturnKey> |
|
#include <QButtonGroup> |
|
#include <QFormLayout> |
|
#include <QHBoxLayout> |
|
#include <QIcon> |
|
#include <QLineEdit> |
|
#include <QPushButton> |
|
#include <QRadioButton> |
|
#include <QStackedWidget> |
|
#include <ki18n_version.h> |
|
#if KI18N_VERSION >= QT_VERSION_CHECK(5, 89, 0) |
|
#include <KLazyLocalizedString> |
|
#undef I18N_NOOP |
|
#define I18N_NOOP kli18n |
|
#endif |
|
// Definition of special rule field strings |
|
// Note: Also see SearchRule::matches() and ruleFieldToEnglish() if |
|
// you change the following i18n-ized strings! |
|
// Note: The index of the values in the following array has to correspond to |
|
// the value of the entries in the enum in SearchRuleWidget. |
|
|
|
|
|
using namespace MailCommon; |
|
|
|
static const struct { |
|
const char *internalName; |
|
#if KI18N_VERSION < QT_VERSION_CHECK(5, 89, 0) |
|
const char *displayName; |
|
#else |
|
const KLazyLocalizedString displayName; |
|
#endif |
|
|
|
Q_REQUIRED_RESULT QString getLocalizedDisplayName() const |
|
{ |
|
#if KI18N_VERSION < QT_VERSION_CHECK(5, 89, 0) |
|
return i18n(displayName); |
|
#else |
|
return KLocalizedString(displayName).toString(); |
|
#endif |
|
} |
|
} SpecialRuleFields[] = {{"<message>", I18N_NOOP("Complete Message")}, |
|
{"<body>", I18N_NOOP("Body of Message")}, |
|
{"<any header>", I18N_NOOP("Anywhere in Headers")}, |
|
{"<recipients>", I18N_NOOP("All Recipients")}, |
|
{"<size>", I18N_NOOP("Size in Bytes")}, |
|
{"<age in days>", I18N_NOOP("Age in Days")}, |
|
{"<status>", I18N_NOOP("Message Status")}, |
|
{"<tag>", I18N_NOOP("Message Tag")}, |
|
{"Subject", I18N_NOOP("Subject")}, |
|
{"From", I18N_NOOP("From")}, |
|
{"To", I18N_NOOP("To")}, |
|
{"CC", I18N_NOOP("CC")}, |
|
{"Reply-To", I18N_NOOP("Reply To")}, |
|
{"Organization", I18N_NOOP("Organization")}, |
|
{"<date>", I18N_NOOP("Date")}, |
|
{"<encryption>", I18N_NOOP("Encryption")}}; |
|
static const int SpecialRuleFieldsCount = sizeof(SpecialRuleFields) / sizeof(*SpecialRuleFields); |
|
|
|
//============================================================================= |
|
// |
|
// class SearchRuleWidget |
|
// |
|
//============================================================================= |
|
|
|
SearchRuleWidget::SearchRuleWidget(QWidget *parent, |
|
SearchRule::Ptr aRule, |
|
SearchPatternEdit::SearchPatternEditOptions options, |
|
SearchPatternEdit::SearchModeType modeType) |
|
: QWidget(parent) |
|
{ |
|
initFieldList(options); |
|
initWidget(modeType); |
|
|
|
if (aRule) { |
|
setRule(aRule); |
|
} else { |
|
reset(); |
|
} |
|
} |
|
|
|
void SearchRuleWidget::setPatternEditOptions(SearchPatternEdit::SearchPatternEditOptions options) |
|
{ |
|
SearchRule::Ptr srule = rule(); |
|
QByteArray currentText = srule->field(); |
|
|
|
initFieldList(options); |
|
|
|
mRuleField->clear(); |
|
mRuleField->addItems(mFilterFieldList); |
|
KCompletion *comp = mRuleField->completionObject(); |
|
comp->clear(); |
|
comp->insertItems(mFilterFieldList); |
|
mRuleField->setMaxCount(mRuleField->count()); |
|
mRuleField->adjustSize(); |
|
|
|
const bool headersOnly = (options & MailCommon::SearchPatternEdit::HeadersOnly); |
|
const bool notShowSize = (options & MailCommon::SearchPatternEdit::NotShowSize); |
|
const bool notShowDate = (options & MailCommon::SearchPatternEdit::NotShowDate); |
|
const bool notShowAbsoluteDates = (options & MailCommon::SearchPatternEdit::NotShowAbsoluteDate); |
|
const bool notShowTags = (options & MailCommon::SearchPatternEdit::NotShowTags); |
|
|
|
if (headersOnly && (currentText != "<message>") && (currentText != "<body>")) { |
|
mRuleField->setItemText(0, QString::fromLatin1(currentText)); |
|
} else { |
|
mRuleField->setItemText(0, QString()); |
|
} |
|
|
|
if (notShowSize && (currentText != "<size>")) { |
|
mRuleField->setItemText(0, QString::fromLatin1(currentText)); |
|
} else { |
|
mRuleField->setItemText(0, QString()); |
|
} |
|
|
|
if (notShowDate && (currentText != "<date>")) { |
|
mRuleField->setItemText(0, QString::fromLatin1(currentText)); |
|
} else { |
|
mRuleField->setItemText(0, QString()); |
|
} |
|
|
|
if (notShowAbsoluteDates && (currentText != "<age in days>")) { |
|
mRuleField->setItemText(0, QString::fromLatin1(currentText)); |
|
} else { |
|
mRuleField->setItemText(0, QString()); |
|
} |
|
if (notShowTags && (currentText != "<tag>")) { |
|
mRuleField->setItemText(0, QString::fromLatin1(currentText)); |
|
} else { |
|
mRuleField->setItemText(0, QString()); |
|
} |
|
} |
|
|
|
void SearchRuleWidget::initWidget(SearchPatternEdit::SearchModeType modeType) |
|
{ |
|
auto hlay = new QHBoxLayout(this); |
|
hlay->setContentsMargins({}); |
|
|
|
// initialize the header field combo box |
|
mRuleField = new KComboBox(this); |
|
mRuleField->setMinimumWidth(50); |
|
mRuleField->setObjectName(QStringLiteral("mRuleField")); |
|
mRuleField->setEditable(true); |
|
auto edit = new QLineEdit; |
|
new KPIM::LineEditCatchReturnKey(edit, this); |
|
edit->setPlaceholderText(i18n("Choose or type your own criteria")); |
|
mRuleField->setToolTip(i18n("Choose or type your own criteria")); |
|
edit->setClearButtonEnabled(true); |
|
mRuleField->setLineEdit(edit); |
|
|
|
mRuleField->addItems(mFilterFieldList); |
|
KCompletion *comp = mRuleField->completionObject(); |
|
comp->setIgnoreCase(true); |
|
comp->insertItems(mFilterFieldList); |
|
comp->setCompletionMode(KCompletion::CompletionPopupAuto); |
|
|
|
// don't show sliders when popping up this menu |
|
mRuleField->setMaxCount(mRuleField->count()); |
|
mRuleField->adjustSize(); |
|
hlay->addWidget(mRuleField); |
|
|
|
// initialize the function/value widget stack |
|
mFunctionStack = new QStackedWidget(this); |
|
// Don't expand the widget in vertical direction |
|
mFunctionStack->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); |
|
|
|
hlay->addWidget(mFunctionStack); |
|
|
|
mValueStack = new QStackedWidget(this); |
|
hlay->addWidget(mValueStack); |
|
hlay->setStretchFactor(mValueStack, 10); |
|
|
|
mAdd = new QPushButton(this); |
|
mAdd->setIcon(QIcon::fromTheme(QStringLiteral("list-add"))); |
|
mAdd->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); |
|
hlay->addWidget(mAdd); |
|
|
|
mRemove = new QPushButton(this); |
|
mRemove->setIcon(QIcon::fromTheme(QStringLiteral("list-remove"))); |
|
mRemove->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); |
|
hlay->addWidget(mRemove); |
|
|
|
RuleWidgetHandlerManager::instance()->setIsAkonadiSearch(modeType == SearchPatternEdit::BalooMode); |
|
|
|
RuleWidgetHandlerManager::instance()->createWidgets(mFunctionStack, mValueStack, this); |
|
|
|
// redirect focus to the header field combo box |
|
setFocusProxy(mRuleField); |
|
|
|
connect(mRuleField, &QComboBox::textActivated, this, &SearchRuleWidget::slotRuleFieldChanged); |
|
connect(mRuleField, &QComboBox::editTextChanged, this, &SearchRuleWidget::slotRuleFieldChanged); |
|
connect(mRuleField, &QComboBox::editTextChanged, this, &SearchRuleWidget::fieldChanged); |
|
|
|
connect(mAdd, &QAbstractButton::clicked, this, &SearchRuleWidget::slotAddWidget); |
|
connect(mRemove, &QAbstractButton::clicked, this, &SearchRuleWidget::slotRemoveWidget); |
|
} |
|
|
|
void SearchRuleWidget::updateAddRemoveButton(bool addButtonEnabled, bool removeButtonEnabled) |
|
{ |
|
mAdd->setEnabled(addButtonEnabled); |
|
mRemove->setEnabled(removeButtonEnabled); |
|
} |
|
|
|
void SearchRuleWidget::slotAddWidget() |
|
{ |
|
Q_EMIT addWidget(this); |
|
} |
|
|
|
void SearchRuleWidget::slotRemoveWidget() |
|
{ |
|
Q_EMIT removeWidget(this); |
|
} |
|
|
|
void SearchRuleWidget::setRule(SearchRule::Ptr aRule) |
|
{ |
|
Q_ASSERT(aRule); |
|
|
|
qCDebug(MAILCOMMON_LOG) << "(" << aRule->asString() << ")"; |
|
|
|
//--------------set the field |
|
int i = indexOfRuleField(aRule->field()); |
|
|
|
mRuleField->blockSignals(true); |
|
|
|
if (i < 0) { // not found -> user defined field |
|
mRuleField->setItemText(0, QString::fromLatin1(aRule->field())); |
|
i = 0; |
|
} else { // found in the list of predefined fields |
|
mRuleField->setItemText(0, QString()); |
|
} |
|
|
|
mRuleField->setCurrentIndex(i); |
|
mRuleField->blockSignals(false); |
|
|
|
RuleWidgetHandlerManager::instance()->setRule(mFunctionStack, mValueStack, aRule); |
|
} |
|
|
|
SearchRule::Ptr SearchRuleWidget::rule() const |
|
{ |
|
const QByteArray ruleField = ruleFieldToEnglish(mRuleField->currentText()); |
|
|
|
const SearchRule::Function function = RuleWidgetHandlerManager::instance()->function(ruleField, mFunctionStack); |
|
|
|
const QString value = RuleWidgetHandlerManager::instance()->value(ruleField, mFunctionStack, mValueStack); |
|
|
|
return SearchRule::createInstance(ruleField, function, value); |
|
} |
|
|
|
void SearchRuleWidget::reset() |
|
{ |
|
mRuleField->blockSignals(true); |
|
mRuleField->setItemText(0, QString()); |
|
mRuleField->setCurrentIndex(0); |
|
mRuleField->blockSignals(false); |
|
|
|
RuleWidgetHandlerManager::instance()->reset(mFunctionStack, mValueStack); |
|
} |
|
|
|
void SearchRuleWidget::slotFunctionChanged() |
|
{ |
|
const QByteArray ruleField = ruleFieldToEnglish(mRuleField->currentText()); |
|
RuleWidgetHandlerManager::instance()->update(ruleField, mFunctionStack, mValueStack); |
|
const QString prettyValue = RuleWidgetHandlerManager::instance()->prettyValue(ruleField, mFunctionStack, mValueStack); |
|
|
|
Q_EMIT contentsChanged(prettyValue); |
|
} |
|
|
|
void SearchRuleWidget::slotValueChanged() |
|
{ |
|
const QByteArray ruleField = ruleFieldToEnglish(mRuleField->currentText()); |
|
|
|
const QString prettyValue = RuleWidgetHandlerManager::instance()->prettyValue(ruleField, mFunctionStack, mValueStack); |
|
|
|
Q_EMIT contentsChanged(prettyValue); |
|
} |
|
|
|
void SearchRuleWidget::slotReturnPressed() |
|
{ |
|
Q_EMIT returnPressed(); |
|
} |
|
|
|
QByteArray SearchRuleWidget::ruleFieldToEnglish(const QString &i18nVal) |
|
{ |
|
for (int i = 0; i < SpecialRuleFieldsCount; ++i) { |
|
if (i18nVal == SpecialRuleFields[i].getLocalizedDisplayName()) { |
|
return SpecialRuleFields[i].internalName; |
|
} |
|
} |
|
return i18nVal.toLatin1(); |
|
} |
|
|
|
int SearchRuleWidget::ruleFieldToId(const QString &i18nVal) |
|
{ |
|
for (int i = 0; i < SpecialRuleFieldsCount; ++i) { |
|
if (i18nVal == SpecialRuleFields[i].getLocalizedDisplayName()) { |
|
return i; |
|
} |
|
} |
|
return -1; // no pseudo header |
|
} |
|
|
|
static QString displayNameFromInternalName(const QString &internal) |
|
{ |
|
for (int i = 0; i < SpecialRuleFieldsCount; ++i) { |
|
if (internal == QLatin1String(SpecialRuleFields[i].internalName)) { |
|
return SpecialRuleFields[i].getLocalizedDisplayName(); |
|
} |
|
} |
|
return QLatin1String(internal.toLatin1()); |
|
} |
|
|
|
int SearchRuleWidget::indexOfRuleField(const QByteArray &aName) const |
|
{ |
|
if (aName.isEmpty()) { |
|
return -1; |
|
} |
|
|
|
const QString i18n_aName = displayNameFromInternalName(QLatin1String(aName)); |
|
const int nbRuleField = mRuleField->count(); |
|
for (int i = 1; i < nbRuleField; ++i) { |
|
if (mRuleField->itemText(i) == i18n_aName) { |
|
return i; |
|
} |
|
} |
|
|
|
return -1; |
|
} |
|
|
|
void SearchRuleWidget::initFieldList(SearchPatternEdit::SearchPatternEditOptions options) |
|
{ |
|
const bool headersOnly = (options & MailCommon::SearchPatternEdit::HeadersOnly); |
|
const bool notShowAbsoluteDates = (options & MailCommon::SearchPatternEdit::NotShowAbsoluteDate); |
|
const bool notShowSize = (options & MailCommon::SearchPatternEdit::NotShowSize); |
|
const bool notShowDate = (options & MailCommon::SearchPatternEdit::NotShowDate); |
|
const bool notShowTags = (options & MailCommon::SearchPatternEdit::NotShowTags); |
|
|
|
mFilterFieldList.clear(); |
|
mFilterFieldList.append(QString()); // empty entry for user input |
|
|
|
if (!headersOnly) { |
|
mFilterFieldList.append(SpecialRuleFields[Message].getLocalizedDisplayName()); |
|
mFilterFieldList.append(SpecialRuleFields[Body].getLocalizedDisplayName()); |
|
} |
|
mFilterFieldList.append(SpecialRuleFields[AnyHeader].getLocalizedDisplayName()); |
|
mFilterFieldList.append(SpecialRuleFields[Recipients].getLocalizedDisplayName()); |
|
if (!notShowSize) { |
|
mFilterFieldList.append(SpecialRuleFields[Size].getLocalizedDisplayName()); |
|
} |
|
if (!notShowAbsoluteDates) { |
|
mFilterFieldList.append(SpecialRuleFields[AgeInDays].getLocalizedDisplayName()); |
|
} |
|
|
|
mFilterFieldList.append(SpecialRuleFields[Subject].getLocalizedDisplayName()); |
|
mFilterFieldList.append(SpecialRuleFields[From].getLocalizedDisplayName()); |
|
mFilterFieldList.append(SpecialRuleFields[To].getLocalizedDisplayName()); |
|
mFilterFieldList.append(SpecialRuleFields[CC].getLocalizedDisplayName()); |
|
mFilterFieldList.append(SpecialRuleFields[Status].getLocalizedDisplayName()); |
|
if (!notShowTags) { |
|
mFilterFieldList.append(SpecialRuleFields[Tag].getLocalizedDisplayName()); |
|
} |
|
mFilterFieldList.append(SpecialRuleFields[ReplyTo].getLocalizedDisplayName()); |
|
mFilterFieldList.append(SpecialRuleFields[Organization].getLocalizedDisplayName()); |
|
|
|
if (!notShowDate) { |
|
mFilterFieldList.append(SpecialRuleFields[Date].getLocalizedDisplayName()); |
|
} |
|
|
|
mFilterFieldList.append(SpecialRuleFields[Encryption].getLocalizedDisplayName()); |
|
|
|
// these others only represent message headers and you can add to |
|
// them as you like |
|
mFilterFieldList.append(QStringLiteral("List-Id")); |
|
mFilterFieldList.append(QStringLiteral("Resent-From")); |
|
mFilterFieldList.append(QStringLiteral("X-Loop")); |
|
mFilterFieldList.append(QStringLiteral("X-Mailing-List")); |
|
mFilterFieldList.append(QStringLiteral("X-Spam-Flag")); |
|
mFilterFieldList.append(QStringLiteral("X-Spam-Status")); |
|
} |
|
|
|
void SearchRuleWidget::slotRuleFieldChanged(const QString &field) |
|
{ |
|
RuleWidgetHandlerManager::instance()->update(ruleFieldToEnglish(field), mFunctionStack, mValueStack); |
|
} |
|
|
|
//============================================================================= |
|
// |
|
// class KMFilterActionWidgetLister (the filter action editor) |
|
// |
|
//============================================================================= |
|
|
|
SearchRuleWidgetLister::SearchRuleWidgetLister(QWidget *parent, SearchPatternEdit::SearchPatternEditOptions options, SearchPatternEdit::SearchModeType modeType) |
|
: KWidgetLister(false, 1, SearchPattern::filterRulesMaximumSize(), parent) |
|
{ |
|
mRuleList = nullptr; |
|
|
|
mTypeMode = modeType; |
|
mOptions = options; |
|
} |
|
|
|
SearchRuleWidgetLister::~SearchRuleWidgetLister() |
|
{ |
|
} |
|
|
|
void SearchRuleWidgetLister::setPatternEditOptions(SearchPatternEdit::SearchPatternEditOptions options) |
|
{ |
|
mOptions = options; |
|
const auto lst = widgets(); |
|
for (QWidget *w : lst) { |
|
qobject_cast<SearchRuleWidget *>(w)->setPatternEditOptions(options); |
|
} |
|
} |
|
|
|
void SearchRuleWidgetLister::setRuleList(QList<SearchRule::Ptr> *aList) |
|
{ |
|
Q_ASSERT(aList); |
|
|
|
if (mRuleList && mRuleList != aList) { |
|
regenerateRuleListFromWidgets(); |
|
} |
|
|
|
mRuleList = aList; |
|
|
|
if (!widgets().isEmpty()) { // move this below next 'if'? |
|
widgets().constFirst()->blockSignals(true); |
|
} |
|
|
|
if (aList->isEmpty()) { |
|
slotClear(); |
|
widgets().constFirst()->blockSignals(false); |
|
return; |
|
} |
|
|
|
int superfluousItems = (int)mRuleList->count() - widgetsMaximum(); |
|
if (superfluousItems > 0) { |
|
qCDebug(MAILCOMMON_LOG) << "Clipping rule list to" << widgetsMaximum() << "items!"; |
|
|
|
for (; superfluousItems; superfluousItems--) { |
|
mRuleList->removeLast(); |
|
} |
|
} |
|
|
|
// set the right number of widgets |
|
setNumberOfShownWidgetsTo(qMax((int)mRuleList->count(), widgetsMinimum())); |
|
|
|
// load the actions into the widgets |
|
QList<QWidget *> widgetList = widgets(); |
|
QList<SearchRule::Ptr>::const_iterator rIt; |
|
QList<SearchRule::Ptr>::const_iterator rItEnd(mRuleList->constEnd()); |
|
QList<QWidget *>::const_iterator wIt = widgetList.constBegin(); |
|
QList<QWidget *>::const_iterator wItEnd = widgetList.constEnd(); |
|
for (rIt = mRuleList->constBegin(); rIt != rItEnd && wIt != wItEnd; ++rIt, ++wIt) { |
|
qobject_cast<SearchRuleWidget *>(*wIt)->setRule((*rIt)); |
|
} |
|
for (; wIt != wItEnd; ++wIt) { |
|
qobject_cast<SearchRuleWidget *>(*wIt)->reset(); |
|
} |
|
|
|
Q_ASSERT(!widgets().isEmpty()); |
|
widgets().constFirst()->blockSignals(false); |
|
updateAddRemoveButton(); |
|
} |
|
|
|
void SearchRuleWidgetLister::slotAddWidget(QWidget *w) |
|
{ |
|
addWidgetAfterThisWidget(w); |
|
updateAddRemoveButton(); |
|
} |
|
|
|
void SearchRuleWidgetLister::slotRemoveWidget(QWidget *w) |
|
{ |
|
removeWidget(w); |
|
updateAddRemoveButton(); |
|
} |
|
|
|
void SearchRuleWidgetLister::reconnectWidget(SearchRuleWidget *w) |
|
{ |
|
connect(w, &SearchRuleWidget::addWidget, this, &SearchRuleWidgetLister::slotAddWidget, Qt::UniqueConnection); |
|
connect(w, &SearchRuleWidget::removeWidget, this, &SearchRuleWidgetLister::slotRemoveWidget, Qt::UniqueConnection); |
|
} |
|
|
|
void SearchRuleWidgetLister::updateAddRemoveButton() |
|
{ |
|
QList<QWidget *> widgetList = widgets(); |
|
const int numberOfWidget(widgetList.count()); |
|
bool addButtonEnabled = false; |
|
bool removeButtonEnabled = false; |
|
if (numberOfWidget <= widgetsMinimum()) { |
|
addButtonEnabled = true; |
|
removeButtonEnabled = false; |
|
} else if (numberOfWidget >= widgetsMaximum()) { |
|
addButtonEnabled = false; |
|
removeButtonEnabled = true; |
|
} else { |
|
addButtonEnabled = true; |
|
removeButtonEnabled = true; |
|
} |
|
QList<QWidget *>::ConstIterator wIt = widgetList.constBegin(); |
|
QList<QWidget *>::ConstIterator wEnd = widgetList.constEnd(); |
|
for (; wIt != wEnd; ++wIt) { |
|
auto w = qobject_cast<SearchRuleWidget *>(*wIt); |
|
w->updateAddRemoveButton(addButtonEnabled, removeButtonEnabled); |
|
} |
|
} |
|
|
|
void SearchRuleWidgetLister::reset() |
|
{ |
|
if (mRuleList) { |
|
regenerateRuleListFromWidgets(); |
|
} |
|
|
|
mRuleList = nullptr; |
|
slotClear(); |
|
updateAddRemoveButton(); |
|
} |
|
|
|
QWidget *SearchRuleWidgetLister::createWidget(QWidget *parent) |
|
{ |
|
auto *w = new SearchRuleWidget(parent, SearchRule::Ptr(), mOptions, mTypeMode); |
|
reconnectWidget(w); |
|
return w; |
|
} |
|
|
|
void SearchRuleWidgetLister::clearWidget(QWidget *aWidget) |
|
{ |
|
if (aWidget) { |
|
auto w = static_cast<SearchRuleWidget *>(aWidget); |
|
w->reset(); |
|
reconnectWidget(w); |
|
updateAddRemoveButton(); |
|
} |
|
} |
|
|
|
void SearchRuleWidgetLister::regenerateRuleListFromWidgets() |
|
{ |
|
if (!mRuleList) { |
|
return; |
|
} |
|
|
|
mRuleList->clear(); |
|
|
|
const auto lst = widgets(); |
|
for (const QWidget *w : lst) { |
|
SearchRule::Ptr r = qobject_cast<const SearchRuleWidget *>(w)->rule(); |
|
if (r && !r->isEmpty()) { |
|
mRuleList->append(r); |
|
} |
|
} |
|
updateAddRemoveButton(); |
|
} |
|
|
|
//============================================================================= |
|
// |
|
// class SearchPatternEdit |
|
// |
|
//============================================================================= |
|
|
|
SearchPatternEdit::SearchPatternEdit(QWidget *parent, SearchPatternEditOptions options, SearchModeType modeType) |
|
: QWidget(parent) |
|
{ |
|
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); |
|
setObjectName(QStringLiteral("SearchPatternEdit")); |
|
initLayout(options, modeType); |
|
} |
|
|
|
SearchPatternEdit::~SearchPatternEdit() |
|
{ |
|
} |
|
|
|
void SearchPatternEdit::updateSearchPattern() |
|
{ |
|
mRuleLister->regenerateRuleListFromWidgets(); |
|
} |
|
|
|
void SearchPatternEdit::setPatternEditOptions(SearchPatternEdit::SearchPatternEditOptions options) |
|
{ |
|
mRuleLister->setPatternEditOptions(options); |
|
} |
|
|
|
void SearchPatternEdit::initLayout(SearchPatternEditOptions options, SearchModeType modeType) |
|
{ |
|
auto layout = new QFormLayout(this); |
|
layout->setContentsMargins({}); |
|
|
|
const bool matchAllMessages = (options & MailCommon::SearchPatternEdit::MatchAllMessages); |
|
//------------the radio buttons |
|
mAllRBtn = new QRadioButton(i18n("Match a&ll of the following"), this); |
|
mAnyRBtn = new QRadioButton(i18n("Match an&y of the following"), this); |
|
if (matchAllMessages) { |
|
mAllMessageRBtn = new QRadioButton(i18n("Match all messages"), this); |
|
} |
|
|
|
mAllRBtn->setObjectName(QStringLiteral("mAllRBtn")); |
|
mAllRBtn->setChecked(true); |
|
mAnyRBtn->setObjectName(QStringLiteral("mAnyRBtn")); |
|
mAnyRBtn->setChecked(false); |
|
if (matchAllMessages) { |
|
mAllMessageRBtn->setObjectName(QStringLiteral("mAllMessageRBtn")); |
|
mAllMessageRBtn->setChecked(false); |
|
} |
|
layout->addRow(i18n("Filter criteria:"), mAllRBtn); |
|
layout->addRow(QString(), mAnyRBtn); |
|
if (matchAllMessages) { |
|
layout->addRow(QString(), mAllMessageRBtn); |
|
} |
|
|
|
auto bg = new QButtonGroup(this); |
|
bg->addButton(mAllRBtn); |
|
bg->addButton(mAnyRBtn); |
|
if (matchAllMessages) { |
|
bg->addButton(mAllMessageRBtn); |
|
} |
|
|
|
//------------connect a few signals |
|
connect(bg, &QButtonGroup::buttonClicked, this, &SearchPatternEdit::slotRadioClicked); |
|
|
|
//------------the list of SearchRuleWidget's |
|
mRuleLister = new SearchRuleWidgetLister(this, options, modeType); |
|
|
|
mRuleLister->slotClear(); |
|
|
|
if (!mRuleLister->widgets().isEmpty()) { |
|
const int numberOfWidget(mRuleLister->widgets().count()); |
|
for (int i = 0; i < numberOfWidget; ++i) { |
|
SearchRuleWidget *srw = static_cast<SearchRuleWidget *>(mRuleLister->widgets().at(i)); |
|
connect(srw, &SearchRuleWidget::fieldChanged, this, &SearchPatternEdit::slotAutoNameHack); |
|
connect(srw, &SearchRuleWidget::contentsChanged, this, &SearchPatternEdit::slotAutoNameHack); |
|
connect(srw, &SearchRuleWidget::returnPressed, this, &SearchPatternEdit::returnPressed); |
|
} |
|
} else { |
|
qCDebug(MAILCOMMON_LOG) << "No first SearchRuleWidget, though slotClear() has been called!"; |
|
} |
|
|
|
connect(mRuleLister, qOverload<QWidget *>(&SearchRuleWidgetLister::widgetAdded), this, &SearchPatternEdit::slotRuleAdded); |
|
connect(mRuleLister, qOverload<>(&SearchRuleWidgetLister::widgetRemoved), this, &SearchPatternEdit::patternChanged); |
|
connect(mRuleLister, &KPIM::KWidgetLister::clearWidgets, this, &SearchPatternEdit::patternChanged); |
|
|
|
layout->addRow(mRuleLister); |
|
} |
|
|
|
void SearchPatternEdit::setSearchPattern(SearchPattern *aPattern) |
|
{ |
|
Q_ASSERT(aPattern); |
|
|
|
mRuleLister->setRuleList(aPattern); |
|
|
|
mPattern = aPattern; |
|
|
|
blockSignals(true); |
|
if (mPattern->op() == SearchPattern::OpOr) { |
|
mAnyRBtn->setChecked(true); |
|
} else if (mPattern->op() == SearchPattern::OpAnd) { |
|
mAllRBtn->setChecked(true); |
|
} else if (mAllMessageRBtn && (mPattern->op() == SearchPattern::OpAll)) { |
|
mAllMessageRBtn->setChecked(true); |
|
} |
|
mRuleLister->setEnabled(mPattern->op() != SearchPattern::OpAll); |
|
blockSignals(false); |
|
|
|
setEnabled(true); |
|
Q_EMIT patternChanged(); |
|
} |
|
|
|
void SearchPatternEdit::reset() |
|
{ |
|
mRuleLister->reset(); |
|
|
|
blockSignals(true); |
|
mAllRBtn->setChecked(true); |
|
blockSignals(false); |
|
|
|
setEnabled(false); |
|
Q_EMIT patternChanged(); |
|
} |
|
|
|
void SearchPatternEdit::slotRadioClicked(QAbstractButton *aRBtn) |
|
{ |
|
if (mPattern) { |
|
if (aRBtn == mAllRBtn) { |
|
mPattern->setOp(SearchPattern::OpAnd); |
|
} else if (aRBtn == mAnyRBtn) { |
|
mPattern->setOp(SearchPattern::OpOr); |
|
} else if (aRBtn == mAllMessageRBtn) { |
|
mPattern->setOp(SearchPattern::OpAll); |
|
} |
|
mRuleLister->setEnabled(mPattern->op() != SearchPattern::OpAll); |
|
Q_EMIT patternChanged(); |
|
} |
|
} |
|
|
|
void SearchPatternEdit::slotAutoNameHack() |
|
{ |
|
mRuleLister->regenerateRuleListFromWidgets(); |
|
Q_EMIT maybeNameChanged(); |
|
Q_EMIT patternChanged(); |
|
} |
|
|
|
void SearchPatternEdit::slotRuleAdded(QWidget *newRuleWidget) |
|
{ |
|
auto srw = static_cast<SearchRuleWidget *>(newRuleWidget); |
|
connect(srw, &SearchRuleWidget::fieldChanged, this, &SearchPatternEdit::slotAutoNameHack); |
|
connect(srw, &SearchRuleWidget::contentsChanged, this, &SearchPatternEdit::slotAutoNameHack); |
|
connect(srw, &SearchRuleWidget::returnPressed, this, &SearchPatternEdit::returnPressed); |
|
Q_EMIT patternChanged(); |
|
}
|
|
|