Mailcommon

headersrulerwidgethandler.cpp
1/*
2 SPDX-FileCopyrightText: 2013-2024 Laurent Montel <montel@kde.org>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5*/
6
7#include "headersrulerwidgethandler.h"
8
9#include "search/searchpattern.h"
10
11#include <KLineEdit>
12#include <KLocalizedString>
13
14#include <KLazyLocalizedString>
15#include <QComboBox>
16#include <QLabel>
17#include <QStackedWidget>
18using namespace MailCommon;
19
20// also see SearchRule::matches() and SearchRule::Function
21// if you change the following strings!
22static const struct {
24 const KLazyLocalizedString displayName;
25} HeaderFunctions[] = {{SearchRule::FuncContains, kli18n("contains")},
26 {SearchRule::FuncContainsNot, kli18n("does not contain")},
27 {SearchRule::FuncEquals, kli18n("equals")},
28 {SearchRule::FuncNotEqual, kli18n("does not equal")},
29 {SearchRule::FuncStartWith, kli18n("starts with")},
30 {SearchRule::FuncNotStartWith, kli18n("does not start with")},
31 {SearchRule::FuncEndWith, kli18n("ends with")},
32 {SearchRule::FuncNotEndWith, kli18n("does not end with")},
33
34 {SearchRule::FuncRegExp, kli18n("matches regular expr.")},
35 {SearchRule::FuncNotRegExp, kli18n("does not match reg. expr.")},
36 {SearchRule::FuncIsInAddressbook, kli18n("is in address book")},
37 {SearchRule::FuncIsNotInAddressbook, kli18n("is not in address book")}};
38static const int HeadersFunctionCount = sizeof(HeaderFunctions) / sizeof(*HeaderFunctions);
39
40//---------------------------------------------------------------------------
41
42QWidget *HeadersRuleWidgetHandler::createFunctionWidget(int number, QStackedWidget *functionStack, const QObject *receiver, bool isBalooSearch) const
43{
44 if (number != 0) {
45 return nullptr;
46 }
47
48 auto funcCombo = new QComboBox(functionStack);
49 funcCombo->setMinimumWidth(50);
50 funcCombo->setObjectName(QLatin1StringView("headerRuleFuncCombo"));
51 for (int i = 0; i < HeadersFunctionCount; ++i) {
52 if (!(isBalooSearch && (HeaderFunctions[i].id == SearchRule::FuncIsInAddressbook || HeaderFunctions[i].id == SearchRule::FuncIsNotInAddressbook))) {
53 funcCombo->addItem(HeaderFunctions[i].displayName.toString());
54 }
55 }
56 funcCombo->adjustSize();
57 QObject::connect(funcCombo, SIGNAL(activated(int)), receiver, SLOT(slotFunctionChanged()));
58 return funcCombo;
59}
60
61//---------------------------------------------------------------------------
62
63QWidget *HeadersRuleWidgetHandler::createValueWidget(int number, QStackedWidget *valueStack, const QObject *receiver) const
64{
65 if (number == 0) {
66 auto lineEdit = new KLineEdit(valueStack);
67 lineEdit->setClearButtonEnabled(true);
68 lineEdit->setTrapReturnKey(true);
69 lineEdit->setObjectName(QLatin1StringView("regExpLineEdit"));
70 QObject::connect(lineEdit, SIGNAL(textChanged(QString)), receiver, SLOT(slotValueChanged()));
71 QObject::connect(lineEdit, SIGNAL(returnPressed()), receiver, SLOT(slotReturnPressed()));
72 return lineEdit;
73 }
74
75 // blank QLabel to hide value widget for in-address-book rule
76 if (number == 1) {
77 auto label = new QLabel(valueStack);
78 label->setObjectName(QLatin1StringView("headerRuleValueHider"));
79 label->setBuddy(valueStack);
80 return label;
81 }
82 return nullptr;
83}
84
85//---------------------------------------------------------------------------
86
87SearchRule::Function HeadersRuleWidgetHandler::currentFunction(const QStackedWidget *functionStack) const
88{
89 const auto funcCombo = functionStack->findChild<QComboBox *>(QStringLiteral("headerRuleFuncCombo"));
90
91 if (funcCombo && funcCombo->currentIndex() >= 0) {
92 return HeaderFunctions[funcCombo->currentIndex()].id;
93 }
94
95 return SearchRule::FuncNone;
96}
97
98//---------------------------------------------------------------------------
99
100SearchRule::Function HeadersRuleWidgetHandler::function(const QByteArray &field, const QStackedWidget *functionStack) const
101{
102 if (!handlesField(field)) {
103 return SearchRule::FuncNone;
104 }
105 return currentFunction(functionStack);
106}
107
108//---------------------------------------------------------------------------
109QString HeadersRuleWidgetHandler::currentValue(const QStackedWidget *valueStack, SearchRule::Function func) const
110{
111 Q_UNUSED(func)
112
113 const KLineEdit *lineEdit = valueStack->findChild<KLineEdit *>(QStringLiteral("regExpLineEdit"));
114
115 if (lineEdit) {
116 return lineEdit->text();
117 }
118
119 // or anything else, like addressbook
120 return {};
121}
122
123//---------------------------------------------------------------------------
124
125QString HeadersRuleWidgetHandler::value(const QByteArray &field, const QStackedWidget *functionStack, const QStackedWidget *valueStack) const
126{
127 if (!handlesField(field)) {
128 return {};
129 }
130 SearchRule::Function func = currentFunction(functionStack);
131 if (func == SearchRule::FuncIsInAddressbook) {
132 return QStringLiteral("is in address book"); // just a non-empty dummy value
133 } else if (func == SearchRule::FuncIsNotInAddressbook) {
134 return QStringLiteral("is not in address book"); // just a non-empty dummy value
135 } else {
136 return currentValue(valueStack, func);
137 }
138}
139
140//---------------------------------------------------------------------------
141
142QString HeadersRuleWidgetHandler::prettyValue(const QByteArray &field, const QStackedWidget *functionStack, const QStackedWidget *valueStack) const
143{
144 if (!handlesField(field)) {
145 return {};
146 }
147
148 SearchRule::Function func = currentFunction(functionStack);
149
150 if (func == SearchRule::FuncIsInAddressbook) {
151 return i18n("is in address book");
152 } else if (func == SearchRule::FuncIsNotInAddressbook) {
153 return i18n("is not in address book");
154 } else {
155 return currentValue(valueStack, func);
156 }
157}
158
159//---------------------------------------------------------------------------
160
161bool HeadersRuleWidgetHandler::handlesField(const QByteArray &field) const
162{
163 return field == "To" || field == "From" || field == "CC" || field == "<recipients>";
164}
165
166//---------------------------------------------------------------------------
167
168void HeadersRuleWidgetHandler::reset(QStackedWidget *functionStack, QStackedWidget *valueStack) const
169{
170 // reset the function combo box
171 const auto funcCombo = functionStack->findChild<QComboBox *>(QStringLiteral("headerRuleFuncCombo"));
172
173 if (funcCombo) {
174 funcCombo->blockSignals(true);
175 funcCombo->setCurrentIndex(0);
176 funcCombo->blockSignals(false);
177 }
178
179 // reset the value widget
180 auto lineEdit = valueStack->findChild<KLineEdit *>(QStringLiteral("regExpLineEdit"));
181 if (lineEdit) {
182 lineEdit->blockSignals(true);
183 lineEdit->clear();
184 lineEdit->blockSignals(false);
185 lineEdit->setClearButtonEnabled(false);
186 lineEdit->setClearButtonEnabled(true);
187 valueStack->setCurrentWidget(lineEdit);
188 }
189}
190
191//---------------------------------------------------------------------------
192
193bool HeadersRuleWidgetHandler::setRule(QStackedWidget *functionStack, QStackedWidget *valueStack, const SearchRule::Ptr rule, bool isBalooSearch) const
194{
195 if (!rule || !handlesField(rule->field())) {
196 reset(functionStack, valueStack);
197 return false;
198 }
199
200 const SearchRule::Function func = rule->function();
201 if ((isBalooSearch && (func == SearchRule::FuncIsInAddressbook || func == SearchRule::FuncIsNotInAddressbook))) {
202 reset(functionStack, valueStack);
203 return false;
204 }
205
206 int i = 0;
207 for (; i < HeadersFunctionCount; ++i) {
208 if (func == HeaderFunctions[i].id) {
209 break;
210 }
211 }
212
213 const auto funcCombo = functionStack->findChild<QComboBox *>(QStringLiteral("headerRuleFuncCombo"));
214
215 if (funcCombo) {
216 funcCombo->blockSignals(true);
217 if (i < HeadersFunctionCount) {
218 funcCombo->setCurrentIndex(i);
219 } else {
220 funcCombo->setCurrentIndex(0);
221 }
222 funcCombo->blockSignals(false);
223 functionStack->setCurrentWidget(funcCombo);
224 }
225
226 if (func == SearchRule::FuncIsInAddressbook || func == SearchRule::FuncIsNotInAddressbook) {
227 auto w = valueStack->findChild<QWidget *>(QStringLiteral("headerRuleValueHider"));
228 valueStack->setCurrentWidget(w);
229 } else {
230 auto lineEdit = valueStack->findChild<KLineEdit *>(QStringLiteral("regExpLineEdit"));
231
232 if (lineEdit) {
233 lineEdit->blockSignals(true);
234 lineEdit->setText(rule->contents());
235 lineEdit->blockSignals(false);
236 lineEdit->setClearButtonEnabled(false);
237 lineEdit->setClearButtonEnabled(true);
238 valueStack->setCurrentWidget(lineEdit);
239 }
240 }
241 return true;
242}
243
244//---------------------------------------------------------------------------
245
246bool HeadersRuleWidgetHandler::update(const QByteArray &field, QStackedWidget *functionStack, QStackedWidget *valueStack) const
247{
248 if (!handlesField(field)) {
249 return false;
250 }
251
252 // raise the correct function widget
253 functionStack->setCurrentWidget(functionStack->findChild<QWidget *>(QStringLiteral("headerRuleFuncCombo")));
254
255 // raise the correct value widget
256 SearchRule::Function func = currentFunction(functionStack);
257 if (func == SearchRule::FuncIsInAddressbook || func == SearchRule::FuncIsNotInAddressbook) {
258 valueStack->setCurrentWidget(valueStack->findChild<QWidget *>(QStringLiteral("headerRuleValueHider")));
259 } else {
260 auto lineEdit = valueStack->findChild<KLineEdit *>(QStringLiteral("regExpLineEdit"));
261
262 if (lineEdit) {
263 valueStack->setCurrentWidget(lineEdit);
264 }
265 }
266 return true;
267}
QString toString() const
virtual void setText(const QString &)
std::shared_ptr< SearchRule > Ptr
Defines a pointer to a search rule.
Definition searchrule.h:29
Function
Describes operators for comparison of field and contents.
Definition searchrule.h:40
QString i18n(const char *text, const TYPE &arg...)
QString label(StandardShortcut id)
The filter dialog.
void clear()
void setClearButtonEnabled(bool enable)
bool blockSignals(bool block)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
T findChild(const QString &name, Qt::FindChildOptions options) const const
void setCurrentWidget(QWidget *widget)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:14:01 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.