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

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 "numericrulewidgethandler.h"
0008 #include "search/searchpattern.h"
0009 
0010 #include <KLocalizedString>
0011 #include <KPluralHandlingSpinBox>
0012 
0013 #include <KLazyLocalizedString>
0014 #include <QComboBox>
0015 #include <QStackedWidget>
0016 using namespace MailCommon;
0017 
0018 static const struct {
0019     SearchRule::Function id;
0020     const KLazyLocalizedString displayName;
0021 } NumericFunctions[] = {{SearchRule::FuncEquals, kli18n("is equal to")},
0022                         {SearchRule::FuncNotEqual, kli18n("is not equal to")},
0023                         {SearchRule::FuncIsGreater, kli18n("is greater than")},
0024                         {SearchRule::FuncIsLessOrEqual, kli18n("is less than or equal to")},
0025                         {SearchRule::FuncIsLess, kli18n("is less than")},
0026                         {SearchRule::FuncIsGreaterOrEqual, kli18n("is greater than or equal to")}};
0027 static const int NumericFunctionCount = sizeof(NumericFunctions) / sizeof(*NumericFunctions);
0028 
0029 //---------------------------------------------------------------------------
0030 
0031 QWidget *NumericRuleWidgetHandler::createFunctionWidget(int number, QStackedWidget *functionStack, const QObject *receiver, bool /*isBalooSearch*/) const
0032 {
0033     if (number != 0) {
0034         return nullptr;
0035     }
0036 
0037     auto funcCombo = new QComboBox(functionStack);
0038     funcCombo->setMinimumWidth(50);
0039     funcCombo->setObjectName(QLatin1StringView("numericRuleFuncCombo"));
0040     for (int i = 0; i < NumericFunctionCount; ++i) {
0041         funcCombo->addItem(NumericFunctions[i].displayName.toString());
0042     }
0043     funcCombo->adjustSize();
0044     QObject::connect(funcCombo, SIGNAL(activated(int)), receiver, SLOT(slotFunctionChanged()));
0045     return funcCombo;
0046 }
0047 
0048 //---------------------------------------------------------------------------
0049 
0050 QWidget *NumericRuleWidgetHandler::createValueWidget(int number, QStackedWidget *valueStack, const QObject *receiver) const
0051 {
0052     if (number != 0) {
0053         return nullptr;
0054     }
0055 
0056     auto numInput = new KPluralHandlingSpinBox(valueStack);
0057     numInput->setObjectName(QLatin1StringView("KPluralHandlingSpinBox"));
0058     QObject::connect(numInput, SIGNAL(valueChanged(int)), receiver, SLOT(slotValueChanged()));
0059     return numInput;
0060 }
0061 
0062 //---------------------------------------------------------------------------
0063 
0064 SearchRule::Function NumericRuleWidgetHandler::currentFunction(const QStackedWidget *functionStack) const
0065 {
0066     const auto funcCombo = functionStack->findChild<QComboBox *>(QStringLiteral("numericRuleFuncCombo"));
0067 
0068     if (funcCombo && funcCombo->currentIndex() >= 0) {
0069         return NumericFunctions[funcCombo->currentIndex()].id;
0070     }
0071 
0072     return SearchRule::FuncNone;
0073 }
0074 
0075 //---------------------------------------------------------------------------
0076 
0077 SearchRule::Function NumericRuleWidgetHandler::function(const QByteArray &field, const QStackedWidget *functionStack) const
0078 {
0079     if (!handlesField(field)) {
0080         return SearchRule::FuncNone;
0081     }
0082 
0083     return currentFunction(functionStack);
0084 }
0085 
0086 //---------------------------------------------------------------------------
0087 
0088 QString NumericRuleWidgetHandler::currentValue(const QStackedWidget *valueStack) const
0089 {
0090     const KPluralHandlingSpinBox *numInput = valueStack->findChild<KPluralHandlingSpinBox *>(QStringLiteral("KPluralHandlingSpinBox"));
0091 
0092     if (numInput) {
0093         return QString::number(numInput->value());
0094     }
0095 
0096     return {};
0097 }
0098 
0099 //---------------------------------------------------------------------------
0100 
0101 QString NumericRuleWidgetHandler::value(const QByteArray &field, const QStackedWidget *, const QStackedWidget *valueStack) const
0102 {
0103     if (!handlesField(field)) {
0104         return {};
0105     }
0106 
0107     return currentValue(valueStack);
0108 }
0109 
0110 //---------------------------------------------------------------------------
0111 
0112 QString NumericRuleWidgetHandler::prettyValue(const QByteArray &field, const QStackedWidget *, const QStackedWidget *valueStack) const
0113 {
0114     if (!handlesField(field)) {
0115         return {};
0116     }
0117 
0118     return currentValue(valueStack);
0119 }
0120 
0121 //---------------------------------------------------------------------------
0122 
0123 bool NumericRuleWidgetHandler::handlesField(const QByteArray &field) const
0124 {
0125     return field == "<age in days>";
0126 }
0127 
0128 //---------------------------------------------------------------------------
0129 
0130 void NumericRuleWidgetHandler::reset(QStackedWidget *functionStack, QStackedWidget *valueStack) const
0131 {
0132     // reset the function combo box
0133     const auto funcCombo = functionStack->findChild<QComboBox *>(QStringLiteral("numericRuleFuncCombo"));
0134 
0135     if (funcCombo) {
0136         funcCombo->blockSignals(true);
0137         funcCombo->setCurrentIndex(0);
0138         funcCombo->blockSignals(false);
0139     }
0140 
0141     // reset the value widget
0142     auto numInput = valueStack->findChild<KPluralHandlingSpinBox *>(QStringLiteral("KPluralHandlingSpinBox"));
0143 
0144     if (numInput) {
0145         numInput->blockSignals(true);
0146         numInput->setValue(0);
0147         numInput->blockSignals(false);
0148     }
0149 }
0150 
0151 //---------------------------------------------------------------------------
0152 
0153 void initNumInput(KPluralHandlingSpinBox *numInput, const QByteArray &field)
0154 {
0155     if (field == "<age in days>") {
0156         numInput->setMinimum(-10000);
0157         numInput->setSuffix(ki18ncp("Unit suffix where units are days.", " day", " days"));
0158     }
0159 }
0160 
0161 //---------------------------------------------------------------------------
0162 
0163 bool NumericRuleWidgetHandler::setRule(QStackedWidget *functionStack, QStackedWidget *valueStack, const SearchRule::Ptr rule, bool /*isBalooSearch*/) const
0164 {
0165     if (!rule || !handlesField(rule->field())) {
0166         reset(functionStack, valueStack);
0167         return false;
0168     }
0169 
0170     // set the function
0171     const SearchRule::Function func = rule->function();
0172     int funcIndex = 0;
0173     for (; funcIndex < NumericFunctionCount; ++funcIndex) {
0174         if (func == NumericFunctions[funcIndex].id) {
0175             break;
0176         }
0177     }
0178 
0179     const auto funcCombo = functionStack->findChild<QComboBox *>(QStringLiteral("numericRuleFuncCombo"));
0180 
0181     if (funcCombo) {
0182         funcCombo->blockSignals(true);
0183         if (funcIndex < NumericFunctionCount) {
0184             funcCombo->setCurrentIndex(funcIndex);
0185         } else {
0186             funcCombo->setCurrentIndex(0);
0187         }
0188         funcCombo->blockSignals(false);
0189         functionStack->setCurrentWidget(funcCombo);
0190     }
0191 
0192     // set the value
0193     bool ok;
0194     int value = rule->contents().toInt(&ok);
0195     if (!ok) {
0196         value = 0;
0197     }
0198 
0199     auto numInput = valueStack->findChild<KPluralHandlingSpinBox *>(QStringLiteral("KPluralHandlingSpinBox"));
0200 
0201     if (numInput) {
0202         initNumInput(numInput, rule->field());
0203         numInput->blockSignals(true);
0204         numInput->setValue(value);
0205         numInput->blockSignals(false);
0206         valueStack->setCurrentWidget(numInput);
0207     }
0208     return true;
0209 }
0210 
0211 //---------------------------------------------------------------------------
0212 
0213 bool NumericRuleWidgetHandler::update(const QByteArray &field, QStackedWidget *functionStack, QStackedWidget *valueStack) const
0214 {
0215     if (!handlesField(field)) {
0216         return false;
0217     }
0218 
0219     // raise the correct function widget
0220     functionStack->setCurrentWidget(functionStack->findChild<QWidget *>(QStringLiteral("numericRuleFuncCombo")));
0221 
0222     // raise the correct value widget
0223     auto numInput = valueStack->findChild<KPluralHandlingSpinBox *>(QStringLiteral("KPluralHandlingSpinBox"));
0224 
0225     if (numInput) {
0226         initNumInput(numInput, field);
0227         valueStack->setCurrentWidget(numInput);
0228     }
0229     return true;
0230 }