File indexing completed on 2024-11-10 04:50:15
0001 /* 0002 0003 SPDX-FileCopyrightText: Marc Mutz <mutz@kde.org> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #include "searchpatternedit.h" 0009 #include "widgethandler/rulewidgethandlermanager.h" 0010 using MailCommon::RuleWidgetHandlerManager; 0011 #include "mailcommon_debug.h" 0012 0013 #include <KComboBox> 0014 #include <KLazyLocalizedString> 0015 #include <KLineEditEventHandler> 0016 #include <KLocalizedString> 0017 #include <QButtonGroup> 0018 #include <QFormLayout> 0019 #include <QHBoxLayout> 0020 #include <QIcon> 0021 #include <QLineEdit> 0022 #include <QPushButton> 0023 #include <QRadioButton> 0024 #include <QStackedWidget> 0025 // Definition of special rule field strings 0026 // Note: Also see SearchRule::matches() and ruleFieldToEnglish() if 0027 // you change the following i18n-ized strings! 0028 // Note: The index of the values in the following array has to correspond to 0029 // the value of the entries in the enum in SearchRuleWidget. 0030 0031 using namespace MailCommon; 0032 0033 static const struct { 0034 const char *internalName; 0035 const KLazyLocalizedString displayName; 0036 0037 [[nodiscard]] QString getLocalizedDisplayName() const 0038 { 0039 return displayName.toString(); 0040 } 0041 } SpecialRuleFields[] = {{"<message>", kli18n("Complete Message")}, 0042 {"<body>", kli18n("Body of Message")}, 0043 {"<any header>", kli18n("Anywhere in Headers")}, 0044 {"<recipients>", kli18n("All Recipients")}, 0045 {"<size>", kli18n("Size in Bytes")}, 0046 {"<age in days>", kli18n("Age in Days")}, 0047 {"<status>", kli18n("Message Status")}, 0048 {"<tag>", kli18n("Message Tag")}, 0049 {"Subject", kli18n("Subject")}, 0050 {"From", kli18n("From")}, 0051 {"To", kli18n("To")}, 0052 {"CC", kli18n("CC")}, 0053 {"Reply-To", kli18n("Reply To")}, 0054 {"Organization", kli18n("Organization")}, 0055 {"<date>", kli18n("Date")}, 0056 {"<encryption>", kli18n("Encryption")}}; 0057 static const int SpecialRuleFieldsCount = sizeof(SpecialRuleFields) / sizeof(*SpecialRuleFields); 0058 0059 //============================================================================= 0060 // 0061 // class SearchRuleWidget 0062 // 0063 //============================================================================= 0064 0065 SearchRuleWidget::SearchRuleWidget(QWidget *parent, 0066 SearchRule::Ptr aRule, 0067 SearchPatternEdit::SearchPatternEditOptions options, 0068 SearchPatternEdit::SearchModeType modeType) 0069 : QWidget(parent) 0070 { 0071 initFieldList(options); 0072 initWidget(modeType); 0073 0074 if (aRule) { 0075 setRule(aRule); 0076 } else { 0077 reset(); 0078 } 0079 } 0080 0081 void SearchRuleWidget::setPatternEditOptions(SearchPatternEdit::SearchPatternEditOptions options) 0082 { 0083 SearchRule::Ptr srule = rule(); 0084 QByteArray currentText = srule->field(); 0085 0086 initFieldList(options); 0087 0088 mRuleField->clear(); 0089 mRuleField->addItems(mFilterFieldList); 0090 KCompletion *comp = mRuleField->completionObject(); 0091 comp->clear(); 0092 comp->insertItems(mFilterFieldList); 0093 mRuleField->setMaxCount(mRuleField->count()); 0094 mRuleField->adjustSize(); 0095 0096 const bool headersOnly = (options & MailCommon::SearchPatternEdit::HeadersOnly); 0097 const bool notShowSize = (options & MailCommon::SearchPatternEdit::NotShowSize); 0098 const bool notShowDate = (options & MailCommon::SearchPatternEdit::NotShowDate); 0099 const bool notShowAbsoluteDates = (options & MailCommon::SearchPatternEdit::NotShowAbsoluteDate); 0100 const bool notShowTags = (options & MailCommon::SearchPatternEdit::NotShowTags); 0101 0102 if (headersOnly && (currentText != "<message>") && (currentText != "<body>")) { 0103 mRuleField->setItemText(0, QString::fromLatin1(currentText)); 0104 } else { 0105 mRuleField->setItemText(0, QString()); 0106 } 0107 0108 if (notShowSize && (currentText != "<size>")) { 0109 mRuleField->setItemText(0, QString::fromLatin1(currentText)); 0110 } else { 0111 mRuleField->setItemText(0, QString()); 0112 } 0113 0114 if (notShowDate && (currentText != "<date>")) { 0115 mRuleField->setItemText(0, QString::fromLatin1(currentText)); 0116 } else { 0117 mRuleField->setItemText(0, QString()); 0118 } 0119 0120 if (notShowAbsoluteDates && (currentText != "<age in days>")) { 0121 mRuleField->setItemText(0, QString::fromLatin1(currentText)); 0122 } else { 0123 mRuleField->setItemText(0, QString()); 0124 } 0125 if (notShowTags && (currentText != "<tag>")) { 0126 mRuleField->setItemText(0, QString::fromLatin1(currentText)); 0127 } else { 0128 mRuleField->setItemText(0, QString()); 0129 } 0130 } 0131 0132 void SearchRuleWidget::initWidget(SearchPatternEdit::SearchModeType modeType) 0133 { 0134 auto hlay = new QHBoxLayout(this); 0135 hlay->setContentsMargins({}); 0136 0137 // initialize the header field combo box 0138 mRuleField = new KComboBox(this); 0139 mRuleField->setMinimumWidth(50); 0140 mRuleField->setObjectName(QLatin1StringView("mRuleField")); 0141 mRuleField->setEditable(true); 0142 auto edit = new QLineEdit; 0143 KLineEditEventHandler::catchReturnKey(edit); 0144 edit->setPlaceholderText(i18n("Choose or type your own criteria")); 0145 mRuleField->setToolTip(i18n("Choose or type your own criteria")); 0146 edit->setClearButtonEnabled(true); 0147 mRuleField->setLineEdit(edit); 0148 0149 mRuleField->addItems(mFilterFieldList); 0150 KCompletion *comp = mRuleField->completionObject(); 0151 comp->setIgnoreCase(true); 0152 comp->insertItems(mFilterFieldList); 0153 comp->setCompletionMode(KCompletion::CompletionPopupAuto); 0154 0155 // don't show sliders when popping up this menu 0156 mRuleField->setMaxCount(mRuleField->count()); 0157 mRuleField->adjustSize(); 0158 hlay->addWidget(mRuleField); 0159 0160 // initialize the function/value widget stack 0161 mFunctionStack = new QStackedWidget(this); 0162 // Don't expand the widget in vertical direction 0163 mFunctionStack->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); 0164 0165 hlay->addWidget(mFunctionStack); 0166 0167 mValueStack = new QStackedWidget(this); 0168 hlay->addWidget(mValueStack); 0169 hlay->setStretchFactor(mValueStack, 10); 0170 0171 mAdd = new QPushButton(this); 0172 mAdd->setIcon(QIcon::fromTheme(QStringLiteral("list-add"))); 0173 mAdd->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); 0174 hlay->addWidget(mAdd); 0175 0176 mRemove = new QPushButton(this); 0177 mRemove->setIcon(QIcon::fromTheme(QStringLiteral("list-remove"))); 0178 mRemove->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); 0179 hlay->addWidget(mRemove); 0180 0181 RuleWidgetHandlerManager::instance()->setIsAkonadiSearch(modeType == SearchPatternEdit::BalooMode); 0182 0183 RuleWidgetHandlerManager::instance()->createWidgets(mFunctionStack, mValueStack, this); 0184 0185 // redirect focus to the header field combo box 0186 setFocusProxy(mRuleField); 0187 0188 connect(mRuleField, &QComboBox::textActivated, this, &SearchRuleWidget::slotRuleFieldChanged); 0189 connect(mRuleField, &QComboBox::editTextChanged, this, &SearchRuleWidget::slotRuleFieldChanged); 0190 connect(mRuleField, &QComboBox::editTextChanged, this, &SearchRuleWidget::fieldChanged); 0191 0192 connect(mAdd, &QAbstractButton::clicked, this, &SearchRuleWidget::slotAddWidget); 0193 connect(mRemove, &QAbstractButton::clicked, this, &SearchRuleWidget::slotRemoveWidget); 0194 } 0195 0196 void SearchRuleWidget::updateAddRemoveButton(bool addButtonEnabled, bool removeButtonEnabled) 0197 { 0198 mAdd->setEnabled(addButtonEnabled); 0199 mRemove->setEnabled(removeButtonEnabled); 0200 } 0201 0202 void SearchRuleWidget::slotAddWidget() 0203 { 0204 Q_EMIT addWidget(this); 0205 } 0206 0207 void SearchRuleWidget::slotRemoveWidget() 0208 { 0209 Q_EMIT removeWidget(this); 0210 } 0211 0212 void SearchRuleWidget::setRule(SearchRule::Ptr aRule) 0213 { 0214 Q_ASSERT(aRule); 0215 0216 qCDebug(MAILCOMMON_LOG) << "(" << aRule->asString() << ")"; 0217 0218 //--------------set the field 0219 int i = indexOfRuleField(aRule->field()); 0220 0221 mRuleField->blockSignals(true); 0222 0223 if (i < 0) { // not found -> user defined field 0224 mRuleField->setItemText(0, QString::fromLatin1(aRule->field())); 0225 i = 0; 0226 } else { // found in the list of predefined fields 0227 mRuleField->setItemText(0, QString()); 0228 } 0229 0230 mRuleField->setCurrentIndex(i); 0231 mRuleField->blockSignals(false); 0232 0233 RuleWidgetHandlerManager::instance()->setRule(mFunctionStack, mValueStack, aRule); 0234 } 0235 0236 SearchRule::Ptr SearchRuleWidget::rule() const 0237 { 0238 const QByteArray ruleField = ruleFieldToEnglish(mRuleField->currentText()); 0239 0240 const SearchRule::Function function = RuleWidgetHandlerManager::instance()->function(ruleField, mFunctionStack); 0241 0242 const QString value = RuleWidgetHandlerManager::instance()->value(ruleField, mFunctionStack, mValueStack); 0243 0244 return SearchRule::createInstance(ruleField, function, value); 0245 } 0246 0247 void SearchRuleWidget::reset() 0248 { 0249 mRuleField->blockSignals(true); 0250 mRuleField->setItemText(0, QString()); 0251 mRuleField->setCurrentIndex(0); 0252 mRuleField->blockSignals(false); 0253 0254 RuleWidgetHandlerManager::instance()->reset(mFunctionStack, mValueStack); 0255 } 0256 0257 void SearchRuleWidget::slotFunctionChanged() 0258 { 0259 const QByteArray ruleField = ruleFieldToEnglish(mRuleField->currentText()); 0260 RuleWidgetHandlerManager::instance()->update(ruleField, mFunctionStack, mValueStack); 0261 const QString prettyValue = RuleWidgetHandlerManager::instance()->prettyValue(ruleField, mFunctionStack, mValueStack); 0262 0263 Q_EMIT contentsChanged(prettyValue); 0264 } 0265 0266 void SearchRuleWidget::slotValueChanged() 0267 { 0268 const QByteArray ruleField = ruleFieldToEnglish(mRuleField->currentText()); 0269 0270 const QString prettyValue = RuleWidgetHandlerManager::instance()->prettyValue(ruleField, mFunctionStack, mValueStack); 0271 0272 Q_EMIT contentsChanged(prettyValue); 0273 } 0274 0275 void SearchRuleWidget::slotReturnPressed() 0276 { 0277 Q_EMIT returnPressed(); 0278 } 0279 0280 QByteArray SearchRuleWidget::ruleFieldToEnglish(const QString &i18nVal) 0281 { 0282 for (int i = 0; i < SpecialRuleFieldsCount; ++i) { 0283 if (i18nVal == SpecialRuleFields[i].getLocalizedDisplayName()) { 0284 return SpecialRuleFields[i].internalName; 0285 } 0286 } 0287 return i18nVal.toLatin1(); 0288 } 0289 0290 int SearchRuleWidget::ruleFieldToId(const QString &i18nVal) 0291 { 0292 for (int i = 0; i < SpecialRuleFieldsCount; ++i) { 0293 if (i18nVal == SpecialRuleFields[i].getLocalizedDisplayName()) { 0294 return i; 0295 } 0296 } 0297 return -1; // no pseudo header 0298 } 0299 0300 static QString displayNameFromInternalName(const QString &internal) 0301 { 0302 for (int i = 0; i < SpecialRuleFieldsCount; ++i) { 0303 if (internal == QLatin1StringView(SpecialRuleFields[i].internalName)) { 0304 return SpecialRuleFields[i].getLocalizedDisplayName(); 0305 } 0306 } 0307 return QLatin1StringView(internal.toLatin1()); 0308 } 0309 0310 int SearchRuleWidget::indexOfRuleField(const QByteArray &aName) const 0311 { 0312 if (aName.isEmpty()) { 0313 return -1; 0314 } 0315 0316 const QString i18n_aName = displayNameFromInternalName(QLatin1StringView(aName)); 0317 const int nbRuleField = mRuleField->count(); 0318 for (int i = 1; i < nbRuleField; ++i) { 0319 if (mRuleField->itemText(i) == i18n_aName) { 0320 return i; 0321 } 0322 } 0323 0324 return -1; 0325 } 0326 0327 void SearchRuleWidget::initFieldList(SearchPatternEdit::SearchPatternEditOptions options) 0328 { 0329 const bool headersOnly = (options & MailCommon::SearchPatternEdit::HeadersOnly); 0330 const bool notShowAbsoluteDates = (options & MailCommon::SearchPatternEdit::NotShowAbsoluteDate); 0331 const bool notShowSize = (options & MailCommon::SearchPatternEdit::NotShowSize); 0332 const bool notShowDate = (options & MailCommon::SearchPatternEdit::NotShowDate); 0333 const bool notShowTags = (options & MailCommon::SearchPatternEdit::NotShowTags); 0334 0335 mFilterFieldList.clear(); 0336 mFilterFieldList.append(QString()); // empty entry for user input 0337 0338 if (!headersOnly) { 0339 mFilterFieldList.append(SpecialRuleFields[Message].getLocalizedDisplayName()); 0340 mFilterFieldList.append(SpecialRuleFields[Body].getLocalizedDisplayName()); 0341 } 0342 mFilterFieldList.append(SpecialRuleFields[AnyHeader].getLocalizedDisplayName()); 0343 mFilterFieldList.append(SpecialRuleFields[Recipients].getLocalizedDisplayName()); 0344 if (!notShowSize) { 0345 mFilterFieldList.append(SpecialRuleFields[Size].getLocalizedDisplayName()); 0346 } 0347 if (!notShowAbsoluteDates) { 0348 mFilterFieldList.append(SpecialRuleFields[AgeInDays].getLocalizedDisplayName()); 0349 } 0350 0351 mFilterFieldList.append(SpecialRuleFields[Subject].getLocalizedDisplayName()); 0352 mFilterFieldList.append(SpecialRuleFields[From].getLocalizedDisplayName()); 0353 mFilterFieldList.append(SpecialRuleFields[To].getLocalizedDisplayName()); 0354 mFilterFieldList.append(SpecialRuleFields[CC].getLocalizedDisplayName()); 0355 mFilterFieldList.append(SpecialRuleFields[Status].getLocalizedDisplayName()); 0356 if (!notShowTags) { 0357 mFilterFieldList.append(SpecialRuleFields[Tag].getLocalizedDisplayName()); 0358 } 0359 mFilterFieldList.append(SpecialRuleFields[ReplyTo].getLocalizedDisplayName()); 0360 mFilterFieldList.append(SpecialRuleFields[Organization].getLocalizedDisplayName()); 0361 0362 if (!notShowDate) { 0363 mFilterFieldList.append(SpecialRuleFields[Date].getLocalizedDisplayName()); 0364 } 0365 0366 mFilterFieldList.append(SpecialRuleFields[Encryption].getLocalizedDisplayName()); 0367 0368 // these others only represent message headers and you can add to 0369 // them as you like 0370 mFilterFieldList.append(QStringLiteral("List-Id")); 0371 mFilterFieldList.append(QStringLiteral("Resent-From")); 0372 mFilterFieldList.append(QStringLiteral("X-Loop")); 0373 mFilterFieldList.append(QStringLiteral("X-Mailing-List")); 0374 mFilterFieldList.append(QStringLiteral("X-Spam-Flag")); 0375 mFilterFieldList.append(QStringLiteral("X-Spam-Status")); 0376 } 0377 0378 void SearchRuleWidget::slotRuleFieldChanged(const QString &field) 0379 { 0380 RuleWidgetHandlerManager::instance()->update(ruleFieldToEnglish(field), mFunctionStack, mValueStack); 0381 } 0382 0383 //============================================================================= 0384 // 0385 // class KMFilterActionWidgetLister (the filter action editor) 0386 // 0387 //============================================================================= 0388 0389 SearchRuleWidgetLister::SearchRuleWidgetLister(QWidget *parent, SearchPatternEdit::SearchPatternEditOptions options, SearchPatternEdit::SearchModeType modeType) 0390 : KWidgetLister(false, 1, SearchPattern::filterRulesMaximumSize(), parent) 0391 { 0392 mRuleList = nullptr; 0393 0394 mTypeMode = modeType; 0395 mOptions = options; 0396 } 0397 0398 SearchRuleWidgetLister::~SearchRuleWidgetLister() = default; 0399 0400 void SearchRuleWidgetLister::setPatternEditOptions(SearchPatternEdit::SearchPatternEditOptions options) 0401 { 0402 mOptions = options; 0403 const auto lst = widgets(); 0404 for (QWidget *w : lst) { 0405 qobject_cast<SearchRuleWidget *>(w)->setPatternEditOptions(options); 0406 } 0407 } 0408 0409 void SearchRuleWidgetLister::setRuleList(QList<SearchRule::Ptr> *aList) 0410 { 0411 Q_ASSERT(aList); 0412 0413 if (mRuleList && mRuleList != aList) { 0414 regenerateRuleListFromWidgets(); 0415 } 0416 0417 mRuleList = aList; 0418 0419 if (!widgets().isEmpty()) { // move this below next 'if'? 0420 widgets().constFirst()->blockSignals(true); 0421 } 0422 0423 if (aList->isEmpty()) { 0424 slotClear(); 0425 widgets().constFirst()->blockSignals(false); 0426 return; 0427 } 0428 0429 int superfluousItems = (int)mRuleList->count() - widgetsMaximum(); 0430 if (superfluousItems > 0) { 0431 qCDebug(MAILCOMMON_LOG) << "Clipping rule list to" << widgetsMaximum() << "items!"; 0432 0433 for (; superfluousItems; superfluousItems--) { 0434 mRuleList->removeLast(); 0435 } 0436 } 0437 0438 // set the right number of widgets 0439 setNumberOfShownWidgetsTo(qMax((int)mRuleList->count(), widgetsMinimum())); 0440 0441 // load the actions into the widgets 0442 QList<QWidget *> widgetList = widgets(); 0443 QList<SearchRule::Ptr>::const_iterator rIt; 0444 QList<SearchRule::Ptr>::const_iterator rItEnd(mRuleList->constEnd()); 0445 QList<QWidget *>::const_iterator wIt = widgetList.constBegin(); 0446 QList<QWidget *>::const_iterator wItEnd = widgetList.constEnd(); 0447 for (rIt = mRuleList->constBegin(); rIt != rItEnd && wIt != wItEnd; ++rIt, ++wIt) { 0448 qobject_cast<SearchRuleWidget *>(*wIt)->setRule((*rIt)); 0449 } 0450 for (; wIt != wItEnd; ++wIt) { 0451 qobject_cast<SearchRuleWidget *>(*wIt)->reset(); 0452 } 0453 0454 Q_ASSERT(!widgets().isEmpty()); 0455 widgets().constFirst()->blockSignals(false); 0456 updateAddRemoveButton(); 0457 } 0458 0459 void SearchRuleWidgetLister::slotAddWidget(QWidget *w) 0460 { 0461 addWidgetAfterThisWidget(w); 0462 updateAddRemoveButton(); 0463 } 0464 0465 void SearchRuleWidgetLister::slotRemoveWidget(QWidget *w) 0466 { 0467 removeWidget(w); 0468 updateAddRemoveButton(); 0469 } 0470 0471 void SearchRuleWidgetLister::reconnectWidget(SearchRuleWidget *w) 0472 { 0473 connect(w, &SearchRuleWidget::addWidget, this, &SearchRuleWidgetLister::slotAddWidget, Qt::UniqueConnection); 0474 connect(w, &SearchRuleWidget::removeWidget, this, &SearchRuleWidgetLister::slotRemoveWidget, Qt::UniqueConnection); 0475 } 0476 0477 void SearchRuleWidgetLister::updateAddRemoveButton() 0478 { 0479 QList<QWidget *> widgetList = widgets(); 0480 const int numberOfWidget(widgetList.count()); 0481 bool addButtonEnabled = false; 0482 bool removeButtonEnabled = false; 0483 if (numberOfWidget <= widgetsMinimum()) { 0484 addButtonEnabled = true; 0485 removeButtonEnabled = false; 0486 } else if (numberOfWidget >= widgetsMaximum()) { 0487 addButtonEnabled = false; 0488 removeButtonEnabled = true; 0489 } else { 0490 addButtonEnabled = true; 0491 removeButtonEnabled = true; 0492 } 0493 QList<QWidget *>::ConstIterator wIt = widgetList.constBegin(); 0494 QList<QWidget *>::ConstIterator wEnd = widgetList.constEnd(); 0495 for (; wIt != wEnd; ++wIt) { 0496 auto w = qobject_cast<SearchRuleWidget *>(*wIt); 0497 w->updateAddRemoveButton(addButtonEnabled, removeButtonEnabled); 0498 } 0499 } 0500 0501 void SearchRuleWidgetLister::reset() 0502 { 0503 if (mRuleList) { 0504 regenerateRuleListFromWidgets(); 0505 } 0506 0507 mRuleList = nullptr; 0508 slotClear(); 0509 updateAddRemoveButton(); 0510 } 0511 0512 QWidget *SearchRuleWidgetLister::createWidget(QWidget *parent) 0513 { 0514 auto w = new SearchRuleWidget(parent, SearchRule::Ptr(), mOptions, mTypeMode); 0515 reconnectWidget(w); 0516 return w; 0517 } 0518 0519 void SearchRuleWidgetLister::clearWidget(QWidget *aWidget) 0520 { 0521 if (aWidget) { 0522 auto w = static_cast<SearchRuleWidget *>(aWidget); 0523 w->reset(); 0524 reconnectWidget(w); 0525 updateAddRemoveButton(); 0526 } 0527 } 0528 0529 void SearchRuleWidgetLister::regenerateRuleListFromWidgets() 0530 { 0531 if (!mRuleList) { 0532 return; 0533 } 0534 0535 mRuleList->clear(); 0536 0537 const auto lst = widgets(); 0538 for (const QWidget *w : lst) { 0539 SearchRule::Ptr r = qobject_cast<const SearchRuleWidget *>(w)->rule(); 0540 if (r && !r->isEmpty()) { 0541 mRuleList->append(r); 0542 } 0543 } 0544 updateAddRemoveButton(); 0545 } 0546 0547 //============================================================================= 0548 // 0549 // class SearchPatternEdit 0550 // 0551 //============================================================================= 0552 0553 SearchPatternEdit::SearchPatternEdit(QWidget *parent, SearchPatternEditOptions options, SearchModeType modeType) 0554 : QWidget(parent) 0555 { 0556 setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); 0557 setObjectName(QLatin1StringView("SearchPatternEdit")); 0558 initLayout(options, modeType); 0559 } 0560 0561 SearchPatternEdit::~SearchPatternEdit() = default; 0562 0563 void SearchPatternEdit::updateSearchPattern() 0564 { 0565 mRuleLister->regenerateRuleListFromWidgets(); 0566 } 0567 0568 void SearchPatternEdit::setPatternEditOptions(SearchPatternEdit::SearchPatternEditOptions options) 0569 { 0570 mRuleLister->setPatternEditOptions(options); 0571 } 0572 0573 void SearchPatternEdit::initLayout(SearchPatternEditOptions options, SearchModeType modeType) 0574 { 0575 auto layout = new QFormLayout(this); 0576 layout->setContentsMargins({}); 0577 0578 const bool matchAllMessages = (options & MailCommon::SearchPatternEdit::MatchAllMessages); 0579 //------------the radio buttons 0580 mAllRBtn = new QRadioButton(i18n("Match a&ll of the following"), this); 0581 mAnyRBtn = new QRadioButton(i18n("Match an&y of the following"), this); 0582 if (matchAllMessages) { 0583 mAllMessageRBtn = new QRadioButton(i18n("Match all messages"), this); 0584 } 0585 0586 mAllRBtn->setObjectName(QLatin1StringView("mAllRBtn")); 0587 mAllRBtn->setChecked(true); 0588 mAnyRBtn->setObjectName(QLatin1StringView("mAnyRBtn")); 0589 mAnyRBtn->setChecked(false); 0590 if (matchAllMessages) { 0591 mAllMessageRBtn->setObjectName(QLatin1StringView("mAllMessageRBtn")); 0592 mAllMessageRBtn->setChecked(false); 0593 } 0594 layout->addRow(i18n("Filter criteria:"), mAllRBtn); 0595 layout->addRow(QString(), mAnyRBtn); 0596 if (matchAllMessages) { 0597 layout->addRow(QString(), mAllMessageRBtn); 0598 } 0599 0600 auto bg = new QButtonGroup(this); 0601 bg->addButton(mAllRBtn); 0602 bg->addButton(mAnyRBtn); 0603 if (matchAllMessages) { 0604 bg->addButton(mAllMessageRBtn); 0605 } 0606 0607 //------------connect a few signals 0608 connect(bg, &QButtonGroup::buttonClicked, this, &SearchPatternEdit::slotRadioClicked); 0609 0610 //------------the list of SearchRuleWidget's 0611 mRuleLister = new SearchRuleWidgetLister(this, options, modeType); 0612 0613 mRuleLister->slotClear(); 0614 0615 if (!mRuleLister->widgets().isEmpty()) { 0616 const int numberOfWidget(mRuleLister->widgets().count()); 0617 for (int i = 0; i < numberOfWidget; ++i) { 0618 SearchRuleWidget *srw = static_cast<SearchRuleWidget *>(mRuleLister->widgets().at(i)); 0619 connect(srw, &SearchRuleWidget::fieldChanged, this, &SearchPatternEdit::slotAutoNameHack); 0620 connect(srw, &SearchRuleWidget::contentsChanged, this, &SearchPatternEdit::slotAutoNameHack); 0621 connect(srw, &SearchRuleWidget::returnPressed, this, &SearchPatternEdit::returnPressed); 0622 } 0623 } else { 0624 qCDebug(MAILCOMMON_LOG) << "No first SearchRuleWidget, though slotClear() has been called!"; 0625 } 0626 0627 connect(mRuleLister, qOverload<QWidget *>(&SearchRuleWidgetLister::widgetAdded), this, &SearchPatternEdit::slotRuleAdded); 0628 connect(mRuleLister, qOverload<>(&SearchRuleWidgetLister::widgetRemoved), this, &SearchPatternEdit::patternChanged); 0629 connect(mRuleLister, &KPIM::KWidgetLister::clearWidgets, this, &SearchPatternEdit::patternChanged); 0630 0631 layout->addRow(mRuleLister); 0632 } 0633 0634 void SearchPatternEdit::setSearchPattern(SearchPattern *aPattern) 0635 { 0636 Q_ASSERT(aPattern); 0637 0638 mRuleLister->setRuleList(aPattern); 0639 0640 mPattern = aPattern; 0641 0642 blockSignals(true); 0643 if (mPattern->op() == SearchPattern::OpOr) { 0644 mAnyRBtn->setChecked(true); 0645 } else if (mPattern->op() == SearchPattern::OpAnd) { 0646 mAllRBtn->setChecked(true); 0647 } else if (mAllMessageRBtn && (mPattern->op() == SearchPattern::OpAll)) { 0648 mAllMessageRBtn->setChecked(true); 0649 } 0650 mRuleLister->setEnabled(mPattern->op() != SearchPattern::OpAll); 0651 blockSignals(false); 0652 0653 setEnabled(true); 0654 Q_EMIT patternChanged(); 0655 } 0656 0657 void SearchPatternEdit::reset() 0658 { 0659 mRuleLister->reset(); 0660 0661 blockSignals(true); 0662 mAllRBtn->setChecked(true); 0663 blockSignals(false); 0664 0665 setEnabled(false); 0666 Q_EMIT patternChanged(); 0667 } 0668 0669 void SearchPatternEdit::slotRadioClicked(QAbstractButton *aRBtn) 0670 { 0671 if (mPattern) { 0672 if (aRBtn == mAllRBtn) { 0673 mPattern->setOp(SearchPattern::OpAnd); 0674 } else if (aRBtn == mAnyRBtn) { 0675 mPattern->setOp(SearchPattern::OpOr); 0676 } else if (aRBtn == mAllMessageRBtn) { 0677 mPattern->setOp(SearchPattern::OpAll); 0678 } 0679 mRuleLister->setEnabled(mPattern->op() != SearchPattern::OpAll); 0680 Q_EMIT patternChanged(); 0681 } 0682 } 0683 0684 void SearchPatternEdit::slotAutoNameHack() 0685 { 0686 mRuleLister->regenerateRuleListFromWidgets(); 0687 Q_EMIT maybeNameChanged(); 0688 Q_EMIT patternChanged(); 0689 } 0690 0691 void SearchPatternEdit::slotRuleAdded(QWidget *newRuleWidget) 0692 { 0693 auto srw = static_cast<SearchRuleWidget *>(newRuleWidget); 0694 connect(srw, &SearchRuleWidget::fieldChanged, this, &SearchPatternEdit::slotAutoNameHack); 0695 connect(srw, &SearchRuleWidget::contentsChanged, this, &SearchPatternEdit::slotAutoNameHack); 0696 connect(srw, &SearchRuleWidget::returnPressed, this, &SearchPatternEdit::returnPressed); 0697 Q_EMIT patternChanged(); 0698 } 0699 0700 #include "moc_searchpatternedit.cpp"