Mailcommon

statusrulewidgethandler.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 "statusrulewidgethandler.h"
8
9#include <KLazyLocalizedString>
10#include <QComboBox>
11#include <QIcon>
12#include <QStackedWidget>
13using namespace MailCommon;
14
15static const struct {
17 const KLazyLocalizedString displayName;
18} StatusFunctions[] = {{SearchRule::FuncContains, kli18n("is")}, {SearchRule::FuncContainsNot, kli18n("is not")}};
19static const int StatusFunctionCount = sizeof(StatusFunctions) / sizeof(*StatusFunctions);
20
21struct MessageStatusInfo {
22 const KLazyLocalizedString text;
23 const char *icon;
24};
25
26// If you change the ordering here; also do it in the enum below
27static const MessageStatusInfo StatusValues[] = {
28 {kli18nc("message status", "Important"), "emblem-important"},
29 {kli18nc("message status", "Action Item"), "mail-task"},
30 {kli18nc("message status", "Unread"), "mail-unread"},
31 {kli18nc("message status", "Read"), "mail-read"},
32 {kli18nc("message status", "Deleted"), "mail-deleted"},
33 {kli18nc("message status", "Replied"), "mail-replied"},
34 {kli18nc("message status", "Forwarded"), "mail-forwarded"},
35 {kli18nc("message status", "Queued"), "mail-queued"},
36 {kli18nc("message status", "Sent"), "mail-sent"},
37 {kli18nc("message status", "Watched"), "mail-thread-watch"},
38 {kli18nc("message status", "Ignored"), "mail-thread-ignored"},
39 {kli18nc("message status", "Spam"), "mail-mark-junk"},
40 {kli18nc("message status", "Ham"), "mail-mark-notjunk"},
41 {kli18nc("message status", "Has Attachment"), "mail-attachment"} // must be last
42};
43
44static const int StatusValueCount = sizeof(StatusValues) / sizeof(MessageStatusInfo);
45// we want to show all status entries in the quick search bar, but only the
46// ones up to attachment in the search/filter dialog, because there the
47// attachment case is handled separately.
48static const int StatusValueCountWithoutHidden = StatusValueCount - 1;
49
50//---------------------------------------------------------------------------
51
52QWidget *StatusRuleWidgetHandler::createFunctionWidget(int number, QStackedWidget *functionStack, const QObject *receiver, bool /*isBalooSearch*/) const
53{
54 if (number != 0) {
55 return nullptr;
56 }
57
58 auto funcCombo = new QComboBox(functionStack);
59 funcCombo->setMinimumWidth(50);
60 funcCombo->setObjectName(QLatin1StringView("statusRuleFuncCombo"));
61 for (int i = 0; i < StatusFunctionCount; ++i) {
62 funcCombo->addItem(StatusFunctions[i].displayName.toString());
63 }
64 funcCombo->adjustSize();
65 QObject::connect(funcCombo, SIGNAL(activated(int)), receiver, SLOT(slotFunctionChanged()));
66 return funcCombo;
67}
68
69//---------------------------------------------------------------------------
70
71QWidget *StatusRuleWidgetHandler::createValueWidget(int number, QStackedWidget *valueStack, const QObject *receiver) const
72{
73 if (number != 0) {
74 return nullptr;
75 }
76
77 auto statusCombo = new QComboBox(valueStack);
78 statusCombo->setMinimumWidth(50);
79 statusCombo->setObjectName(QLatin1StringView("statusRuleValueCombo"));
80 for (int i = 0; i < StatusValueCountWithoutHidden; ++i) {
81 if (StatusValues[i].icon != nullptr) {
82 statusCombo->addItem(QIcon::fromTheme(QLatin1StringView(StatusValues[i].icon)), StatusValues[i].text.toString());
83 } else {
84 statusCombo->addItem(StatusValues[i].text.toString());
85 }
86 }
87 statusCombo->adjustSize();
88 QObject::connect(statusCombo, SIGNAL(activated(int)), receiver, SLOT(slotValueChanged()));
89 return statusCombo;
90}
91
92//---------------------------------------------------------------------------
93
94SearchRule::Function StatusRuleWidgetHandler::currentFunction(const QStackedWidget *functionStack) const
95{
96 const auto funcCombo = functionStack->findChild<QComboBox *>(QStringLiteral("statusRuleFuncCombo"));
97
98 if (funcCombo && funcCombo->currentIndex() >= 0) {
99 return StatusFunctions[funcCombo->currentIndex()].id;
100 }
101
102 return SearchRule::FuncNone;
103}
104
105//---------------------------------------------------------------------------
106
107SearchRule::Function StatusRuleWidgetHandler::function(const QByteArray &field, const QStackedWidget *functionStack) const
108{
109 if (!handlesField(field)) {
110 return SearchRule::FuncNone;
111 }
112
113 return currentFunction(functionStack);
114}
115
116//---------------------------------------------------------------------------
117
118int StatusRuleWidgetHandler::currentStatusValue(const QStackedWidget *valueStack) const
119{
120 const auto statusCombo = valueStack->findChild<QComboBox *>(QStringLiteral("statusRuleValueCombo"));
121
122 if (statusCombo) {
123 return statusCombo->currentIndex();
124 }
125
126 return -1;
127}
128
129//---------------------------------------------------------------------------
130
131QString StatusRuleWidgetHandler::value(const QByteArray &field, const QStackedWidget *, const QStackedWidget *valueStack) const
132{
133 if (!handlesField(field)) {
134 return {};
135 }
136
137 const int status = currentStatusValue(valueStack);
138 if (status != -1) {
139 return StatusValues[status].text.untranslatedText();
140 } else {
141 return {};
142 }
143}
144
145//---------------------------------------------------------------------------
146
147QString StatusRuleWidgetHandler::prettyValue(const QByteArray &field, const QStackedWidget *, const QStackedWidget *valueStack) const
148{
149 if (!handlesField(field)) {
150 return {};
151 }
152
153 const int status = currentStatusValue(valueStack);
154 if (status != -1) {
155 return StatusValues[status].text.toString();
156 } else {
157 return {};
158 }
159}
160
161//---------------------------------------------------------------------------
162
163bool StatusRuleWidgetHandler::handlesField(const QByteArray &field) const
164{
165 return field == "<status>";
166}
167
168//---------------------------------------------------------------------------
169
170void StatusRuleWidgetHandler::reset(QStackedWidget *functionStack, QStackedWidget *valueStack) const
171{
172 // reset the function combo box
173 auto funcCombo = functionStack->findChild<QComboBox *>(QStringLiteral("statusRuleFuncCombo"));
174
175 if (funcCombo) {
176 funcCombo->blockSignals(true);
177 funcCombo->setCurrentIndex(0);
178 funcCombo->blockSignals(false);
179 }
180
181 // reset the status value combo box
182 auto statusCombo = valueStack->findChild<QComboBox *>(QStringLiteral("statusRuleValueCombo"));
183
184 if (statusCombo) {
185 statusCombo->blockSignals(true);
186 statusCombo->setCurrentIndex(0);
187 statusCombo->blockSignals(false);
188 }
189}
190
191//---------------------------------------------------------------------------
192
193bool StatusRuleWidgetHandler::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 // set the function
201 const SearchRule::Function func = rule->function();
202 int funcIndex = 0;
203 for (; funcIndex < StatusFunctionCount; ++funcIndex) {
204 if (func == StatusFunctions[funcIndex].id) {
205 break;
206 }
207 }
208
209 const auto funcCombo = functionStack->findChild<QComboBox *>(QStringLiteral("statusRuleFuncCombo"));
210
211 if (funcCombo) {
212 funcCombo->blockSignals(true);
213 if (funcIndex < StatusFunctionCount) {
214 funcCombo->setCurrentIndex(funcIndex);
215 } else {
216 funcCombo->setCurrentIndex(0);
217 }
218 funcCombo->blockSignals(false);
219 functionStack->setCurrentWidget(funcCombo);
220 }
221
222 // set the value
223 const QString value = rule->contents();
224 int valueIndex = 0;
225 for (; valueIndex < StatusValueCountWithoutHidden; ++valueIndex) {
226 if (value == StatusValues[valueIndex].text.untranslatedText()) {
227 break;
228 }
229 }
230
231 const auto statusCombo = valueStack->findChild<QComboBox *>(QStringLiteral("statusRuleValueCombo"));
232
233 if (statusCombo) {
234 statusCombo->blockSignals(true);
235 if (valueIndex < StatusValueCountWithoutHidden) {
236 statusCombo->setCurrentIndex(valueIndex);
237 } else {
238 statusCombo->setCurrentIndex(0);
239 }
240 statusCombo->blockSignals(false);
241 valueStack->setCurrentWidget(statusCombo);
242 }
243 return true;
244}
245
246//---------------------------------------------------------------------------
247
248bool StatusRuleWidgetHandler::update(const QByteArray &field, QStackedWidget *functionStack, QStackedWidget *valueStack) const
249{
250 if (!handlesField(field)) {
251 return false;
252 }
253
254 // raise the correct function widget
255 functionStack->setCurrentWidget(functionStack->findChild<QWidget *>(QStringLiteral("statusRuleFuncCombo")));
256
257 // raise the correct value widget
258 valueStack->setCurrentWidget(valueStack->findChild<QWidget *>(QStringLiteral("statusRuleValueCombo")));
259
260 return true;
261}
constexpr const char * untranslatedText() const
QString toString() const
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
Q_SCRIPTABLE CaptureState status()
The filter dialog.
QIcon fromTheme(const QString &name)
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.