Mailcommon

statusrulewidgethandler.cpp
1 /*
2  SPDX-FileCopyrightText: 2013-2023 Laurent Montel <[email protected]>
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>
13 using namespace MailCommon;
14 
15 static const struct {
17  const KLazyLocalizedString displayName;
18 } StatusFunctions[] = {{SearchRule::FuncContains, kli18n("is")}, {SearchRule::FuncContainsNot, kli18n("is not")}};
19 static const int StatusFunctionCount = sizeof(StatusFunctions) / sizeof(*StatusFunctions);
20 
21 struct 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
27 static 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 
44 static 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.
48 static const int StatusValueCountWithoutHidden = StatusValueCount - 1;
49 
50 //---------------------------------------------------------------------------
51 
52 QWidget *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(QStringLiteral("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 
71 QWidget *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(QStringLiteral("statusRuleValueCombo"));
80  for (int i = 0; i < StatusValueCountWithoutHidden; ++i) {
81  if (StatusValues[i].icon != nullptr) {
82  statusCombo->addItem(QIcon::fromTheme(QLatin1String(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 
94 SearchRule::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 
107 SearchRule::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 
118 int 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 
131 QString 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 
147 QString 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 
163 bool StatusRuleWidgetHandler::handlesField(const QByteArray &field) const
164 {
165  return field == "<status>";
166 }
167 
168 //---------------------------------------------------------------------------
169 
170 void 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 
193 bool 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 
248 bool 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 }
void setCurrentWidget(QWidget *widget)
std::shared_ptr< SearchRule > Ptr
Defines a pointer to a search rule.
Definition: searchrule.h:29
QIcon fromTheme(const QString &name)
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QString toString() const
bool blockSignals(bool block)
Q_SCRIPTABLE CaptureState status()
Function
Describes operators for comparison of field and contents.
Definition: searchrule.h:40
T findChild(const QString &name, Qt::FindChildOptions options) const const
KGuiItem reset()
The filter dialog.
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon May 8 2023 03:58:16 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.