File indexing completed on 2024-11-17 04:51:16

0001 /*
0002   SPDX-FileCopyrightText: 2013-2024 Laurent Montel <montel@kde.org>
0003 
0004   SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "textrulerwidgethandler.h"
0008 
0009 #include <KLineEdit>
0010 #include <KLocalizedString>
0011 #include <QComboBox>
0012 #include <QStackedWidget>
0013 
0014 using namespace MailCommon;
0015 
0016 #include <KLazyLocalizedString>
0017 #include <QLabel>
0018 
0019 // also see SearchRule::matches() and SearchRule::Function
0020 // if you change the following strings!
0021 static const struct {
0022     SearchRule::Function id;
0023     const KLazyLocalizedString displayName;
0024 } TextFunctions[] = {{SearchRule::FuncContains, kli18n("contains")},
0025                      {SearchRule::FuncContainsNot, kli18n("does not contain")},
0026                      {SearchRule::FuncEquals, kli18n("equals")},
0027                      {SearchRule::FuncNotEqual, kli18n("does not equal")},
0028                      {SearchRule::FuncStartWith, kli18n("starts with")},
0029                      {SearchRule::FuncNotStartWith, kli18n("does not start with")},
0030                      {SearchRule::FuncEndWith, kli18n("ends with")},
0031                      {SearchRule::FuncNotEndWith, kli18n("does not end with")},
0032 
0033                      {SearchRule::FuncRegExp, kli18n("matches regular expr.")},
0034                      {SearchRule::FuncNotRegExp, kli18n("does not match reg. expr.")}};
0035 static const int TextFunctionCount = sizeof(TextFunctions) / sizeof(*TextFunctions);
0036 
0037 //---------------------------------------------------------------------------
0038 
0039 QWidget *TextRuleWidgetHandler::createFunctionWidget(int number, QStackedWidget *functionStack, const QObject *receiver, bool /*isBalooSearch*/) const
0040 {
0041     if (number != 0) {
0042         return nullptr;
0043     }
0044 
0045     auto funcCombo = new QComboBox(functionStack);
0046     funcCombo->setMinimumWidth(50);
0047     funcCombo->setObjectName(QLatin1StringView("textRuleFuncCombo"));
0048     for (int i = 0; i < TextFunctionCount; ++i) {
0049         funcCombo->addItem(TextFunctions[i].displayName.toString());
0050     }
0051     funcCombo->adjustSize();
0052     QObject::connect(funcCombo, SIGNAL(activated(int)), receiver, SLOT(slotFunctionChanged()));
0053     return funcCombo;
0054 }
0055 
0056 //---------------------------------------------------------------------------
0057 
0058 QWidget *TextRuleWidgetHandler::createValueWidget(int number, QStackedWidget *valueStack, const QObject *receiver) const
0059 {
0060     if (number == 0) {
0061         auto lineEdit = new KLineEdit(valueStack);
0062         lineEdit->setClearButtonEnabled(true);
0063         lineEdit->setTrapReturnKey(true);
0064         lineEdit->setObjectName(QLatin1StringView("regExpLineEdit"));
0065         QObject::connect(lineEdit, SIGNAL(textChanged(QString)), receiver, SLOT(slotValueChanged()));
0066         QObject::connect(lineEdit, SIGNAL(returnPressed()), receiver, SLOT(slotReturnPressed()));
0067         return lineEdit;
0068     }
0069 
0070     // blank QLabel to hide value widget for in-address-book rule
0071     if (number == 1) {
0072         auto label = new QLabel(valueStack);
0073         label->setObjectName(QLatin1StringView("textRuleValueHider"));
0074         label->setBuddy(valueStack);
0075         return label;
0076     }
0077     return nullptr;
0078 }
0079 
0080 //---------------------------------------------------------------------------
0081 
0082 SearchRule::Function TextRuleWidgetHandler::currentFunction(const QStackedWidget *functionStack) const
0083 {
0084     const auto funcCombo = functionStack->findChild<QComboBox *>(QStringLiteral("textRuleFuncCombo"));
0085 
0086     if (funcCombo && funcCombo->currentIndex() >= 0) {
0087         return TextFunctions[funcCombo->currentIndex()].id;
0088     }
0089 
0090     return SearchRule::FuncNone;
0091 }
0092 
0093 //---------------------------------------------------------------------------
0094 
0095 SearchRule::Function TextRuleWidgetHandler::function(const QByteArray &, const QStackedWidget *functionStack) const
0096 {
0097     return currentFunction(functionStack);
0098 }
0099 
0100 //---------------------------------------------------------------------------
0101 
0102 QString TextRuleWidgetHandler::currentValue(const QStackedWidget *valueStack, SearchRule::Function) const
0103 {
0104     // in other cases of func it is a lineedit
0105     const KLineEdit *lineEdit = valueStack->findChild<KLineEdit *>(QStringLiteral("regExpLineEdit"));
0106 
0107     if (lineEdit) {
0108         return lineEdit->text();
0109     }
0110 
0111     // or anything else, like addressbook
0112     return {};
0113 }
0114 
0115 //---------------------------------------------------------------------------
0116 
0117 QString TextRuleWidgetHandler::value(const QByteArray &, const QStackedWidget *functionStack, const QStackedWidget *valueStack) const
0118 {
0119     SearchRule::Function func = currentFunction(functionStack);
0120     return currentValue(valueStack, func);
0121 }
0122 
0123 //---------------------------------------------------------------------------
0124 
0125 QString TextRuleWidgetHandler::prettyValue(const QByteArray &, const QStackedWidget *functionStack, const QStackedWidget *valueStack) const
0126 {
0127     SearchRule::Function func = currentFunction(functionStack);
0128     return currentValue(valueStack, func);
0129 }
0130 
0131 //---------------------------------------------------------------------------
0132 
0133 bool TextRuleWidgetHandler::handlesField(const QByteArray &) const
0134 {
0135     return true; // we handle all fields (as fallback)
0136 }
0137 
0138 //---------------------------------------------------------------------------
0139 
0140 void TextRuleWidgetHandler::reset(QStackedWidget *functionStack, QStackedWidget *valueStack) const
0141 {
0142     // reset the function combo box
0143     const auto funcCombo = functionStack->findChild<QComboBox *>(QStringLiteral("textRuleFuncCombo"));
0144 
0145     if (funcCombo) {
0146         funcCombo->blockSignals(true);
0147         funcCombo->setCurrentIndex(0);
0148         funcCombo->blockSignals(false);
0149     }
0150 
0151     // reset the value widget
0152     auto lineEdit = valueStack->findChild<KLineEdit *>(QStringLiteral("regExpLineEdit"));
0153     if (lineEdit) {
0154         lineEdit->blockSignals(true);
0155         lineEdit->clear();
0156         lineEdit->blockSignals(false);
0157         lineEdit->setClearButtonEnabled(false);
0158         lineEdit->setClearButtonEnabled(true);
0159         valueStack->setCurrentWidget(lineEdit);
0160     }
0161 }
0162 
0163 //---------------------------------------------------------------------------
0164 
0165 bool TextRuleWidgetHandler::setRule(QStackedWidget *functionStack, QStackedWidget *valueStack, const SearchRule::Ptr rule, bool /*isBalooSearch*/) const
0166 {
0167     if (!rule) {
0168         reset(functionStack, valueStack);
0169         return false;
0170     }
0171 
0172     const SearchRule::Function func = rule->function();
0173     int i = 0;
0174     for (; i < TextFunctionCount; ++i) {
0175         if (func == TextFunctions[i].id) {
0176             break;
0177         }
0178     }
0179 
0180     const auto funcCombo = functionStack->findChild<QComboBox *>(QStringLiteral("textRuleFuncCombo"));
0181 
0182     if (funcCombo) {
0183         funcCombo->blockSignals(true);
0184         if (i < TextFunctionCount) {
0185             funcCombo->setCurrentIndex(i);
0186         } else {
0187             funcCombo->setCurrentIndex(0);
0188         }
0189         funcCombo->blockSignals(false);
0190         functionStack->setCurrentWidget(funcCombo);
0191     }
0192     auto lineEdit = valueStack->findChild<KLineEdit *>(QStringLiteral("regExpLineEdit"));
0193 
0194     if (lineEdit) {
0195         lineEdit->blockSignals(true);
0196         lineEdit->setText(rule->contents());
0197         lineEdit->blockSignals(false);
0198         lineEdit->setClearButtonEnabled(false);
0199         lineEdit->setClearButtonEnabled(true);
0200         valueStack->setCurrentWidget(lineEdit);
0201     }
0202     return true;
0203 }
0204 
0205 //---------------------------------------------------------------------------
0206 
0207 bool TextRuleWidgetHandler::update(const QByteArray &, QStackedWidget *functionStack, QStackedWidget *valueStack) const
0208 {
0209     // raise the correct function widget
0210     functionStack->setCurrentWidget(functionStack->findChild<QWidget *>(QStringLiteral("textRuleFuncCombo")));
0211 
0212     // raise the correct value widget
0213     SearchRule::Function func = currentFunction(functionStack);
0214     if (func == SearchRule::FuncIsInAddressbook || func == SearchRule::FuncIsNotInAddressbook) {
0215         valueStack->setCurrentWidget(valueStack->findChild<QWidget *>(QStringLiteral("textRuleValueHider")));
0216     } else {
0217         auto lineEdit = valueStack->findChild<KLineEdit *>(QStringLiteral("regExpLineEdit"));
0218 
0219         if (lineEdit) {
0220             valueStack->setCurrentWidget(lineEdit);
0221         }
0222     }
0223     return true;
0224 }