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 "messagerulewidgethandler.h" 0008 #include "search/searchpattern.h" 0009 0010 #include <KLazyLocalizedString> 0011 #include <KLineEdit> 0012 #include <KLocalizedString> 0013 #include <QComboBox> 0014 #include <QLabel> 0015 #include <QStackedWidget> 0016 using namespace MailCommon; 0017 0018 // also see SearchRule::matches() and SearchRule::Function 0019 // if you change the following strings! 0020 static const struct { 0021 SearchRule::Function id; 0022 const KLazyLocalizedString displayName; 0023 } MessageFunctions[] = { 0024 {SearchRule::FuncContains, kli18n("contains")}, 0025 {SearchRule::FuncContainsNot, kli18n("does not contain")}, 0026 {SearchRule::FuncRegExp, kli18n("matches regular expr.")}, 0027 {SearchRule::FuncNotRegExp, kli18n("does not match reg. expr.")}, 0028 {SearchRule::FuncHasAttachment, kli18n("has an attachment")}, 0029 {SearchRule::FuncHasNoAttachment, kli18n("has no attachment")}, 0030 }; 0031 static const int MessageFunctionCount = sizeof(MessageFunctions) / sizeof(*MessageFunctions); 0032 0033 //--------------------------------------------------------------------------- 0034 0035 QWidget *MessageRuleWidgetHandler::createFunctionWidget(int number, QStackedWidget *functionStack, const QObject *receiver, bool isBalooSearch) const 0036 { 0037 if (number != 0) { 0038 return nullptr; 0039 } 0040 0041 auto funcCombo = new QComboBox(functionStack); 0042 funcCombo->setMinimumWidth(50); 0043 funcCombo->setObjectName(QLatin1StringView("messageRuleFuncCombo")); 0044 for (int i = 0; i < MessageFunctionCount; ++i) { 0045 if (!(isBalooSearch && (MessageFunctions[i].id == SearchRule::FuncHasAttachment || MessageFunctions[i].id == SearchRule::FuncHasNoAttachment))) { 0046 funcCombo->addItem(MessageFunctions[i].displayName.toString()); 0047 } 0048 } 0049 funcCombo->adjustSize(); 0050 QObject::connect(funcCombo, SIGNAL(activated(int)), receiver, SLOT(slotFunctionChanged())); 0051 return funcCombo; 0052 } 0053 0054 //--------------------------------------------------------------------------- 0055 0056 QWidget *MessageRuleWidgetHandler::createValueWidget(int number, QStackedWidget *valueStack, const QObject *receiver) const 0057 { 0058 if (number == 0) { 0059 auto lineEdit = new KLineEdit(valueStack); 0060 lineEdit->setClearButtonEnabled(true); 0061 lineEdit->setTrapReturnKey(true); 0062 0063 lineEdit->setObjectName(QLatin1StringView("regExpLineEdit")); 0064 QObject::connect(lineEdit, SIGNAL(textChanged(QString)), receiver, SLOT(slotValueChanged())); 0065 QObject::connect(lineEdit, SIGNAL(returnPressed()), receiver, SLOT(slotReturnPressed())); 0066 return lineEdit; 0067 } 0068 0069 // blank QLabel to hide value widget for has-attachment rule 0070 if (number == 1) { 0071 auto label = new QLabel(valueStack); 0072 label->setObjectName(QLatin1StringView("textRuleValueHider")); 0073 label->setBuddy(valueStack); 0074 return label; 0075 } 0076 0077 return nullptr; 0078 } 0079 0080 //--------------------------------------------------------------------------- 0081 0082 SearchRule::Function MessageRuleWidgetHandler::currentFunction(const QStackedWidget *functionStack) const 0083 { 0084 const auto funcCombo = functionStack->findChild<QComboBox *>(QStringLiteral("messageRuleFuncCombo")); 0085 0086 if (funcCombo && funcCombo->currentIndex() >= 0) { 0087 return MessageFunctions[funcCombo->currentIndex()].id; 0088 } 0089 0090 return SearchRule::FuncNone; 0091 } 0092 0093 //--------------------------------------------------------------------------- 0094 0095 SearchRule::Function MessageRuleWidgetHandler::function(const QByteArray &field, const QStackedWidget *functionStack) const 0096 { 0097 if (!handlesField(field)) { 0098 return SearchRule::FuncNone; 0099 } 0100 0101 return currentFunction(functionStack); 0102 } 0103 0104 //--------------------------------------------------------------------------- 0105 0106 QString MessageRuleWidgetHandler::currentValue(const QStackedWidget *valueStack, SearchRule::Function) const 0107 { 0108 const KLineEdit *lineEdit = valueStack->findChild<KLineEdit *>(QStringLiteral("regExpLineEdit")); 0109 0110 if (lineEdit) { 0111 return lineEdit->text(); 0112 } 0113 0114 return {}; 0115 } 0116 0117 //--------------------------------------------------------------------------- 0118 0119 QString MessageRuleWidgetHandler::value(const QByteArray &field, const QStackedWidget *functionStack, const QStackedWidget *valueStack) const 0120 { 0121 if (!handlesField(field)) { 0122 return {}; 0123 } 0124 0125 SearchRule::Function func = currentFunction(functionStack); 0126 if (func == SearchRule::FuncHasAttachment) { 0127 return QStringLiteral("has an attachment"); // just a non-empty dummy value 0128 } else if (func == SearchRule::FuncHasNoAttachment) { 0129 return QStringLiteral("has no attachment"); // just a non-empty dummy value 0130 } else { 0131 return currentValue(valueStack, func); 0132 } 0133 } 0134 0135 //--------------------------------------------------------------------------- 0136 0137 QString MessageRuleWidgetHandler::prettyValue(const QByteArray &field, const QStackedWidget *functionStack, const QStackedWidget *valueStack) const 0138 { 0139 if (!handlesField(field)) { 0140 return {}; 0141 } 0142 0143 SearchRule::Function func = currentFunction(functionStack); 0144 if (func == SearchRule::FuncHasAttachment) { 0145 return i18n("has an attachment"); 0146 } else if (func == SearchRule::FuncHasNoAttachment) { 0147 return i18n("has no attachment"); 0148 } else { 0149 return currentValue(valueStack, func); 0150 } 0151 } 0152 0153 //--------------------------------------------------------------------------- 0154 0155 bool MessageRuleWidgetHandler::handlesField(const QByteArray &field) const 0156 { 0157 return field == "<message>"; 0158 } 0159 0160 //--------------------------------------------------------------------------- 0161 0162 void MessageRuleWidgetHandler::reset(QStackedWidget *functionStack, QStackedWidget *valueStack) const 0163 { 0164 // reset the function combo box 0165 const auto funcCombo = functionStack->findChild<QComboBox *>(QStringLiteral("messageRuleFuncCombo")); 0166 0167 if (funcCombo) { 0168 funcCombo->blockSignals(true); 0169 funcCombo->setCurrentIndex(0); 0170 funcCombo->blockSignals(false); 0171 } 0172 0173 // reset the value widget 0174 auto lineEdit = valueStack->findChild<KLineEdit *>(QStringLiteral("regExpLineEdit")); 0175 0176 if (lineEdit) { 0177 lineEdit->blockSignals(true); 0178 lineEdit->clear(); 0179 lineEdit->blockSignals(false); 0180 lineEdit->setClearButtonEnabled(false); 0181 lineEdit->setClearButtonEnabled(true); 0182 valueStack->setCurrentWidget(lineEdit); 0183 } 0184 } 0185 0186 //--------------------------------------------------------------------------- 0187 0188 bool MessageRuleWidgetHandler::setRule(QStackedWidget *functionStack, QStackedWidget *valueStack, const SearchRule::Ptr rule, bool isBalooSearch) const 0189 { 0190 if (!rule || !handlesField(rule->field())) { 0191 reset(functionStack, valueStack); 0192 return false; 0193 } 0194 0195 const SearchRule::Function func = rule->function(); 0196 0197 if ((isBalooSearch && (func == SearchRule::FuncHasAttachment || func == SearchRule::FuncHasNoAttachment))) { 0198 reset(functionStack, valueStack); 0199 return false; 0200 } 0201 0202 int i = 0; 0203 for (; i < MessageFunctionCount; ++i) { 0204 if (func == MessageFunctions[i].id) { 0205 break; 0206 } 0207 } 0208 0209 const auto funcCombo = functionStack->findChild<QComboBox *>(QStringLiteral("messageRuleFuncCombo")); 0210 0211 if (funcCombo) { 0212 funcCombo->blockSignals(true); 0213 if (i < MessageFunctionCount) { 0214 funcCombo->setCurrentIndex(i); 0215 } else { 0216 funcCombo->setCurrentIndex(0); 0217 } 0218 funcCombo->blockSignals(false); 0219 functionStack->setCurrentWidget(funcCombo); 0220 } 0221 0222 if (func == SearchRule::FuncHasAttachment || func == SearchRule::FuncHasNoAttachment) { 0223 auto w = valueStack->findChild<QWidget *>(QStringLiteral("textRuleValueHider")); 0224 valueStack->setCurrentWidget(w); 0225 } else { 0226 auto lineEdit = valueStack->findChild<KLineEdit *>(QStringLiteral("regExpLineEdit")); 0227 0228 if (lineEdit) { 0229 lineEdit->blockSignals(true); 0230 lineEdit->setText(rule->contents()); 0231 lineEdit->blockSignals(false); 0232 lineEdit->setClearButtonEnabled(false); 0233 lineEdit->setClearButtonEnabled(true); 0234 valueStack->setCurrentWidget(lineEdit); 0235 } 0236 } 0237 return true; 0238 } 0239 0240 //--------------------------------------------------------------------------- 0241 0242 bool MessageRuleWidgetHandler::update(const QByteArray &field, QStackedWidget *functionStack, QStackedWidget *valueStack) const 0243 { 0244 if (!handlesField(field)) { 0245 return false; 0246 } 0247 0248 // raise the correct function widget 0249 functionStack->setCurrentWidget(functionStack->findChild<QWidget *>(QStringLiteral("messageRuleFuncCombo"))); 0250 0251 // raise the correct value widget 0252 SearchRule::Function func = currentFunction(functionStack); 0253 if (func == SearchRule::FuncHasAttachment || func == SearchRule::FuncHasNoAttachment) { 0254 auto w = valueStack->findChild<QWidget *>(QStringLiteral("textRuleValueHider")); 0255 valueStack->setCurrentWidget(w); 0256 } else { 0257 auto lineEdit = valueStack->findChild<KLineEdit *>(QStringLiteral("regExpLineEdit")); 0258 0259 if (lineEdit) { 0260 valueStack->setCurrentWidget(lineEdit); 0261 } 0262 } 0263 return true; 0264 }