Mailcommon

searchpatternedit.cpp
1 /*
2 
3  SPDX-FileCopyrightText: Marc Mutz <[email protected]>
4 
5  SPDX-License-Identifier: GPL-2.0-or-later
6 */
7 
8 #include "searchpatternedit.h"
9 #include "widgethandler/rulewidgethandlermanager.h"
11 #include "mailcommon_debug.h"
12 
13 #include <KComboBox>
14 #include <KLazyLocalizedString>
15 #include <KLocalizedString>
16 #include <Libkdepim/LineEditCatchReturnKey>
17 #include <QButtonGroup>
18 #include <QFormLayout>
19 #include <QHBoxLayout>
20 #include <QIcon>
21 #include <QLineEdit>
22 #include <QPushButton>
23 #include <QRadioButton>
24 #include <QStackedWidget>
25 // Definition of special rule field strings
26 // Note: Also see SearchRule::matches() and ruleFieldToEnglish() if
27 // you change the following i18n-ized strings!
28 // Note: The index of the values in the following array has to correspond to
29 // the value of the entries in the enum in SearchRuleWidget.
30 
31 using namespace MailCommon;
32 
33 static const struct {
34  const char *internalName;
35  const KLazyLocalizedString displayName;
36 
37  Q_REQUIRED_RESULT QString getLocalizedDisplayName() const
38  {
39  return displayName.toString();
40  }
41 } SpecialRuleFields[] = {{"<message>", kli18n("Complete Message")},
42  {"<body>", kli18n("Body of Message")},
43  {"<any header>", kli18n("Anywhere in Headers")},
44  {"<recipients>", kli18n("All Recipients")},
45  {"<size>", kli18n("Size in Bytes")},
46  {"<age in days>", kli18n("Age in Days")},
47  {"<status>", kli18n("Message Status")},
48  {"<tag>", kli18n("Message Tag")},
49  {"Subject", kli18n("Subject")},
50  {"From", kli18n("From")},
51  {"To", kli18n("To")},
52  {"CC", kli18n("CC")},
53  {"Reply-To", kli18n("Reply To")},
54  {"Organization", kli18n("Organization")},
55  {"<date>", kli18n("Date")},
56  {"<encryption>", kli18n("Encryption")}};
57 static const int SpecialRuleFieldsCount = sizeof(SpecialRuleFields) / sizeof(*SpecialRuleFields);
58 
59 //=============================================================================
60 //
61 // class SearchRuleWidget
62 //
63 //=============================================================================
64 
66  SearchRule::Ptr aRule,
68  SearchPatternEdit::SearchModeType modeType)
69  : QWidget(parent)
70 {
71  initFieldList(options);
72  initWidget(modeType);
73 
74  if (aRule) {
75  setRule(aRule);
76  } else {
77  reset();
78  }
79 }
80 
81 void SearchRuleWidget::setPatternEditOptions(SearchPatternEdit::SearchPatternEditOptions options)
82 {
83  SearchRule::Ptr srule = rule();
84  QByteArray currentText = srule->field();
85 
86  initFieldList(options);
87 
88  mRuleField->clear();
89  mRuleField->addItems(mFilterFieldList);
90  KCompletion *comp = mRuleField->completionObject();
91  comp->clear();
92  comp->insertItems(mFilterFieldList);
93  mRuleField->setMaxCount(mRuleField->count());
94  mRuleField->adjustSize();
95 
96  const bool headersOnly = (options & MailCommon::SearchPatternEdit::HeadersOnly);
97  const bool notShowSize = (options & MailCommon::SearchPatternEdit::NotShowSize);
98  const bool notShowDate = (options & MailCommon::SearchPatternEdit::NotShowDate);
99  const bool notShowAbsoluteDates = (options & MailCommon::SearchPatternEdit::NotShowAbsoluteDate);
100  const bool notShowTags = (options & MailCommon::SearchPatternEdit::NotShowTags);
101 
102  if (headersOnly && (currentText != "<message>") && (currentText != "<body>")) {
103  mRuleField->setItemText(0, QString::fromLatin1(currentText));
104  } else {
105  mRuleField->setItemText(0, QString());
106  }
107 
108  if (notShowSize && (currentText != "<size>")) {
109  mRuleField->setItemText(0, QString::fromLatin1(currentText));
110  } else {
111  mRuleField->setItemText(0, QString());
112  }
113 
114  if (notShowDate && (currentText != "<date>")) {
115  mRuleField->setItemText(0, QString::fromLatin1(currentText));
116  } else {
117  mRuleField->setItemText(0, QString());
118  }
119 
120  if (notShowAbsoluteDates && (currentText != "<age in days>")) {
121  mRuleField->setItemText(0, QString::fromLatin1(currentText));
122  } else {
123  mRuleField->setItemText(0, QString());
124  }
125  if (notShowTags && (currentText != "<tag>")) {
126  mRuleField->setItemText(0, QString::fromLatin1(currentText));
127  } else {
128  mRuleField->setItemText(0, QString());
129  }
130 }
131 
132 void SearchRuleWidget::initWidget(SearchPatternEdit::SearchModeType modeType)
133 {
134  auto hlay = new QHBoxLayout(this);
135  hlay->setContentsMargins({});
136 
137  // initialize the header field combo box
138  mRuleField = new KComboBox(this);
139  mRuleField->setMinimumWidth(50);
140  mRuleField->setObjectName(QStringLiteral("mRuleField"));
141  mRuleField->setEditable(true);
142  auto edit = new QLineEdit;
143  new KPIM::LineEditCatchReturnKey(edit, this);
144  edit->setPlaceholderText(i18n("Choose or type your own criteria"));
145  mRuleField->setToolTip(i18n("Choose or type your own criteria"));
146  edit->setClearButtonEnabled(true);
147  mRuleField->setLineEdit(edit);
148 
149  mRuleField->addItems(mFilterFieldList);
150  KCompletion *comp = mRuleField->completionObject();
151  comp->setIgnoreCase(true);
152  comp->insertItems(mFilterFieldList);
154 
155  // don't show sliders when popping up this menu
156  mRuleField->setMaxCount(mRuleField->count());
157  mRuleField->adjustSize();
158  hlay->addWidget(mRuleField);
159 
160  // initialize the function/value widget stack
161  mFunctionStack = new QStackedWidget(this);
162  // Don't expand the widget in vertical direction
164 
165  hlay->addWidget(mFunctionStack);
166 
167  mValueStack = new QStackedWidget(this);
168  hlay->addWidget(mValueStack);
169  hlay->setStretchFactor(mValueStack, 10);
170 
171  mAdd = new QPushButton(this);
172  mAdd->setIcon(QIcon::fromTheme(QStringLiteral("list-add")));
174  hlay->addWidget(mAdd);
175 
176  mRemove = new QPushButton(this);
177  mRemove->setIcon(QIcon::fromTheme(QStringLiteral("list-remove")));
179  hlay->addWidget(mRemove);
180 
181  RuleWidgetHandlerManager::instance()->setIsAkonadiSearch(modeType == SearchPatternEdit::BalooMode);
182 
183  RuleWidgetHandlerManager::instance()->createWidgets(mFunctionStack, mValueStack, this);
184 
185  // redirect focus to the header field combo box
186  setFocusProxy(mRuleField);
187 
188  connect(mRuleField, &QComboBox::textActivated, this, &SearchRuleWidget::slotRuleFieldChanged);
189  connect(mRuleField, &QComboBox::editTextChanged, this, &SearchRuleWidget::slotRuleFieldChanged);
191 
192  connect(mAdd, &QAbstractButton::clicked, this, &SearchRuleWidget::slotAddWidget);
193  connect(mRemove, &QAbstractButton::clicked, this, &SearchRuleWidget::slotRemoveWidget);
194 }
195 
196 void SearchRuleWidget::updateAddRemoveButton(bool addButtonEnabled, bool removeButtonEnabled)
197 {
198  mAdd->setEnabled(addButtonEnabled);
199  mRemove->setEnabled(removeButtonEnabled);
200 }
201 
202 void SearchRuleWidget::slotAddWidget()
203 {
204  Q_EMIT addWidget(this);
205 }
206 
207 void SearchRuleWidget::slotRemoveWidget()
208 {
209  Q_EMIT removeWidget(this);
210 }
211 
213 {
214  Q_ASSERT(aRule);
215 
216  qCDebug(MAILCOMMON_LOG) << "(" << aRule->asString() << ")";
217 
218  //--------------set the field
219  int i = indexOfRuleField(aRule->field());
220 
221  mRuleField->blockSignals(true);
222 
223  if (i < 0) { // not found -> user defined field
224  mRuleField->setItemText(0, QString::fromLatin1(aRule->field()));
225  i = 0;
226  } else { // found in the list of predefined fields
227  mRuleField->setItemText(0, QString());
228  }
229 
230  mRuleField->setCurrentIndex(i);
231  mRuleField->blockSignals(false);
232 
233  RuleWidgetHandlerManager::instance()->setRule(mFunctionStack, mValueStack, aRule);
234 }
235 
237 {
238  const QByteArray ruleField = ruleFieldToEnglish(mRuleField->currentText());
239 
240  const SearchRule::Function function = RuleWidgetHandlerManager::instance()->function(ruleField, mFunctionStack);
241 
242  const QString value = RuleWidgetHandlerManager::instance()->value(ruleField, mFunctionStack, mValueStack);
243 
244  return SearchRule::createInstance(ruleField, function, value);
245 }
246 
248 {
249  mRuleField->blockSignals(true);
250  mRuleField->setItemText(0, QString());
251  mRuleField->setCurrentIndex(0);
252  mRuleField->blockSignals(false);
253 
254  RuleWidgetHandlerManager::instance()->reset(mFunctionStack, mValueStack);
255 }
256 
257 void SearchRuleWidget::slotFunctionChanged()
258 {
259  const QByteArray ruleField = ruleFieldToEnglish(mRuleField->currentText());
260  RuleWidgetHandlerManager::instance()->update(ruleField, mFunctionStack, mValueStack);
261  const QString prettyValue = RuleWidgetHandlerManager::instance()->prettyValue(ruleField, mFunctionStack, mValueStack);
262 
263  Q_EMIT contentsChanged(prettyValue);
264 }
265 
266 void SearchRuleWidget::slotValueChanged()
267 {
268  const QByteArray ruleField = ruleFieldToEnglish(mRuleField->currentText());
269 
270  const QString prettyValue = RuleWidgetHandlerManager::instance()->prettyValue(ruleField, mFunctionStack, mValueStack);
271 
272  Q_EMIT contentsChanged(prettyValue);
273 }
274 
275 void SearchRuleWidget::slotReturnPressed()
276 {
277  Q_EMIT returnPressed();
278 }
279 
281 {
282  for (int i = 0; i < SpecialRuleFieldsCount; ++i) {
283  if (i18nVal == SpecialRuleFields[i].getLocalizedDisplayName()) {
284  return SpecialRuleFields[i].internalName;
285  }
286  }
287  return i18nVal.toLatin1();
288 }
289 
290 int SearchRuleWidget::ruleFieldToId(const QString &i18nVal)
291 {
292  for (int i = 0; i < SpecialRuleFieldsCount; ++i) {
293  if (i18nVal == SpecialRuleFields[i].getLocalizedDisplayName()) {
294  return i;
295  }
296  }
297  return -1; // no pseudo header
298 }
299 
300 static QString displayNameFromInternalName(const QString &internal)
301 {
302  for (int i = 0; i < SpecialRuleFieldsCount; ++i) {
303  if (internal == QLatin1String(SpecialRuleFields[i].internalName)) {
304  return SpecialRuleFields[i].getLocalizedDisplayName();
305  }
306  }
307  return QLatin1String(internal.toLatin1());
308 }
309 
311 {
312  if (aName.isEmpty()) {
313  return -1;
314  }
315 
316  const QString i18n_aName = displayNameFromInternalName(QLatin1String(aName));
317  const int nbRuleField = mRuleField->count();
318  for (int i = 1; i < nbRuleField; ++i) {
319  if (mRuleField->itemText(i) == i18n_aName) {
320  return i;
321  }
322  }
323 
324  return -1;
325 }
326 
327 void SearchRuleWidget::initFieldList(SearchPatternEdit::SearchPatternEditOptions options)
328 {
329  const bool headersOnly = (options & MailCommon::SearchPatternEdit::HeadersOnly);
330  const bool notShowAbsoluteDates = (options & MailCommon::SearchPatternEdit::NotShowAbsoluteDate);
331  const bool notShowSize = (options & MailCommon::SearchPatternEdit::NotShowSize);
332  const bool notShowDate = (options & MailCommon::SearchPatternEdit::NotShowDate);
333  const bool notShowTags = (options & MailCommon::SearchPatternEdit::NotShowTags);
334 
335  mFilterFieldList.clear();
336  mFilterFieldList.append(QString()); // empty entry for user input
337 
338  if (!headersOnly) {
339  mFilterFieldList.append(SpecialRuleFields[Message].getLocalizedDisplayName());
340  mFilterFieldList.append(SpecialRuleFields[Body].getLocalizedDisplayName());
341  }
342  mFilterFieldList.append(SpecialRuleFields[AnyHeader].getLocalizedDisplayName());
343  mFilterFieldList.append(SpecialRuleFields[Recipients].getLocalizedDisplayName());
344  if (!notShowSize) {
345  mFilterFieldList.append(SpecialRuleFields[Size].getLocalizedDisplayName());
346  }
347  if (!notShowAbsoluteDates) {
348  mFilterFieldList.append(SpecialRuleFields[AgeInDays].getLocalizedDisplayName());
349  }
350 
351  mFilterFieldList.append(SpecialRuleFields[Subject].getLocalizedDisplayName());
352  mFilterFieldList.append(SpecialRuleFields[From].getLocalizedDisplayName());
353  mFilterFieldList.append(SpecialRuleFields[To].getLocalizedDisplayName());
354  mFilterFieldList.append(SpecialRuleFields[CC].getLocalizedDisplayName());
355  mFilterFieldList.append(SpecialRuleFields[Status].getLocalizedDisplayName());
356  if (!notShowTags) {
357  mFilterFieldList.append(SpecialRuleFields[Tag].getLocalizedDisplayName());
358  }
359  mFilterFieldList.append(SpecialRuleFields[ReplyTo].getLocalizedDisplayName());
360  mFilterFieldList.append(SpecialRuleFields[Organization].getLocalizedDisplayName());
361 
362  if (!notShowDate) {
363  mFilterFieldList.append(SpecialRuleFields[Date].getLocalizedDisplayName());
364  }
365 
366  mFilterFieldList.append(SpecialRuleFields[Encryption].getLocalizedDisplayName());
367 
368  // these others only represent message headers and you can add to
369  // them as you like
370  mFilterFieldList.append(QStringLiteral("List-Id"));
371  mFilterFieldList.append(QStringLiteral("Resent-From"));
372  mFilterFieldList.append(QStringLiteral("X-Loop"));
373  mFilterFieldList.append(QStringLiteral("X-Mailing-List"));
374  mFilterFieldList.append(QStringLiteral("X-Spam-Flag"));
375  mFilterFieldList.append(QStringLiteral("X-Spam-Status"));
376 }
377 
378 void SearchRuleWidget::slotRuleFieldChanged(const QString &field)
379 {
380  RuleWidgetHandlerManager::instance()->update(ruleFieldToEnglish(field), mFunctionStack, mValueStack);
381 }
382 
383 //=============================================================================
384 //
385 // class KMFilterActionWidgetLister (the filter action editor)
386 //
387 //=============================================================================
388 
389 SearchRuleWidgetLister::SearchRuleWidgetLister(QWidget *parent, SearchPatternEdit::SearchPatternEditOptions options, SearchPatternEdit::SearchModeType modeType)
390  : KWidgetLister(false, 1, SearchPattern::filterRulesMaximumSize(), parent)
391 {
392  mRuleList = nullptr;
393 
394  mTypeMode = modeType;
395  mOptions = options;
396 }
397 
398 SearchRuleWidgetLister::~SearchRuleWidgetLister() = default;
399 
400 void SearchRuleWidgetLister::setPatternEditOptions(SearchPatternEdit::SearchPatternEditOptions options)
401 {
402  mOptions = options;
403  const auto lst = widgets();
404  for (QWidget *w : lst) {
405  qobject_cast<SearchRuleWidget *>(w)->setPatternEditOptions(options);
406  }
407 }
408 
409 void SearchRuleWidgetLister::setRuleList(QList<SearchRule::Ptr> *aList)
410 {
411  Q_ASSERT(aList);
412 
413  if (mRuleList && mRuleList != aList) {
414  regenerateRuleListFromWidgets();
415  }
416 
417  mRuleList = aList;
418 
419  if (!widgets().isEmpty()) { // move this below next 'if'?
420  widgets().constFirst()->blockSignals(true);
421  }
422 
423  if (aList->isEmpty()) {
424  slotClear();
425  widgets().constFirst()->blockSignals(false);
426  return;
427  }
428 
429  int superfluousItems = (int)mRuleList->count() - widgetsMaximum();
430  if (superfluousItems > 0) {
431  qCDebug(MAILCOMMON_LOG) << "Clipping rule list to" << widgetsMaximum() << "items!";
432 
433  for (; superfluousItems; superfluousItems--) {
434  mRuleList->removeLast();
435  }
436  }
437 
438  // set the right number of widgets
439  setNumberOfShownWidgetsTo(qMax((int)mRuleList->count(), widgetsMinimum()));
440 
441  // load the actions into the widgets
442  QList<QWidget *> widgetList = widgets();
444  QList<SearchRule::Ptr>::const_iterator rItEnd(mRuleList->constEnd());
445  QList<QWidget *>::const_iterator wIt = widgetList.constBegin();
446  QList<QWidget *>::const_iterator wItEnd = widgetList.constEnd();
447  for (rIt = mRuleList->constBegin(); rIt != rItEnd && wIt != wItEnd; ++rIt, ++wIt) {
448  qobject_cast<SearchRuleWidget *>(*wIt)->setRule((*rIt));
449  }
450  for (; wIt != wItEnd; ++wIt) {
451  qobject_cast<SearchRuleWidget *>(*wIt)->reset();
452  }
453 
454  Q_ASSERT(!widgets().isEmpty());
455  widgets().constFirst()->blockSignals(false);
456  updateAddRemoveButton();
457 }
458 
459 void SearchRuleWidgetLister::slotAddWidget(QWidget *w)
460 {
461  addWidgetAfterThisWidget(w);
462  updateAddRemoveButton();
463 }
464 
465 void SearchRuleWidgetLister::slotRemoveWidget(QWidget *w)
466 {
467  removeWidget(w);
468  updateAddRemoveButton();
469 }
470 
471 void SearchRuleWidgetLister::reconnectWidget(SearchRuleWidget *w)
472 {
473  connect(w, &SearchRuleWidget::addWidget, this, &SearchRuleWidgetLister::slotAddWidget, Qt::UniqueConnection);
474  connect(w, &SearchRuleWidget::removeWidget, this, &SearchRuleWidgetLister::slotRemoveWidget, Qt::UniqueConnection);
475 }
476 
477 void SearchRuleWidgetLister::updateAddRemoveButton()
478 {
479  QList<QWidget *> widgetList = widgets();
480  const int numberOfWidget(widgetList.count());
481  bool addButtonEnabled = false;
482  bool removeButtonEnabled = false;
483  if (numberOfWidget <= widgetsMinimum()) {
484  addButtonEnabled = true;
485  removeButtonEnabled = false;
486  } else if (numberOfWidget >= widgetsMaximum()) {
487  addButtonEnabled = false;
488  removeButtonEnabled = true;
489  } else {
490  addButtonEnabled = true;
491  removeButtonEnabled = true;
492  }
493  QList<QWidget *>::ConstIterator wIt = widgetList.constBegin();
494  QList<QWidget *>::ConstIterator wEnd = widgetList.constEnd();
495  for (; wIt != wEnd; ++wIt) {
496  auto w = qobject_cast<SearchRuleWidget *>(*wIt);
497  w->updateAddRemoveButton(addButtonEnabled, removeButtonEnabled);
498  }
499 }
500 
501 void SearchRuleWidgetLister::reset()
502 {
503  if (mRuleList) {
504  regenerateRuleListFromWidgets();
505  }
506 
507  mRuleList = nullptr;
508  slotClear();
509  updateAddRemoveButton();
510 }
511 
512 QWidget *SearchRuleWidgetLister::createWidget(QWidget *parent)
513 {
514  auto *w = new SearchRuleWidget(parent, SearchRule::Ptr(), mOptions, mTypeMode);
515  reconnectWidget(w);
516  return w;
517 }
518 
519 void SearchRuleWidgetLister::clearWidget(QWidget *aWidget)
520 {
521  if (aWidget) {
522  auto w = static_cast<SearchRuleWidget *>(aWidget);
523  w->reset();
524  reconnectWidget(w);
525  updateAddRemoveButton();
526  }
527 }
528 
529 void SearchRuleWidgetLister::regenerateRuleListFromWidgets()
530 {
531  if (!mRuleList) {
532  return;
533  }
534 
535  mRuleList->clear();
536 
537  const auto lst = widgets();
538  for (const QWidget *w : lst) {
539  SearchRule::Ptr r = qobject_cast<const SearchRuleWidget *>(w)->rule();
540  if (r && !r->isEmpty()) {
541  mRuleList->append(r);
542  }
543  }
544  updateAddRemoveButton();
545 }
546 
547 //=============================================================================
548 //
549 // class SearchPatternEdit
550 //
551 //=============================================================================
552 
553 SearchPatternEdit::SearchPatternEdit(QWidget *parent, SearchPatternEditOptions options, SearchModeType modeType)
554  : QWidget(parent)
555 {
557  setObjectName(QStringLiteral("SearchPatternEdit"));
558  initLayout(options, modeType);
559 }
560 
561 SearchPatternEdit::~SearchPatternEdit() = default;
562 
563 void SearchPatternEdit::updateSearchPattern()
564 {
565  mRuleLister->regenerateRuleListFromWidgets();
566 }
567 
568 void SearchPatternEdit::setPatternEditOptions(SearchPatternEdit::SearchPatternEditOptions options)
569 {
570  mRuleLister->setPatternEditOptions(options);
571 }
572 
573 void SearchPatternEdit::initLayout(SearchPatternEditOptions options, SearchModeType modeType)
574 {
575  auto layout = new QFormLayout(this);
576  layout->setContentsMargins({});
577 
578  const bool matchAllMessages = (options & MailCommon::SearchPatternEdit::MatchAllMessages);
579  //------------the radio buttons
580  mAllRBtn = new QRadioButton(i18n("Match a&ll of the following"), this);
581  mAnyRBtn = new QRadioButton(i18n("Match an&y of the following"), this);
582  if (matchAllMessages) {
583  mAllMessageRBtn = new QRadioButton(i18n("Match all messages"), this);
584  }
585 
586  mAllRBtn->setObjectName(QStringLiteral("mAllRBtn"));
587  mAllRBtn->setChecked(true);
588  mAnyRBtn->setObjectName(QStringLiteral("mAnyRBtn"));
589  mAnyRBtn->setChecked(false);
590  if (matchAllMessages) {
591  mAllMessageRBtn->setObjectName(QStringLiteral("mAllMessageRBtn"));
592  mAllMessageRBtn->setChecked(false);
593  }
594  layout->addRow(i18n("Filter criteria:"), mAllRBtn);
595  layout->addRow(QString(), mAnyRBtn);
596  if (matchAllMessages) {
597  layout->addRow(QString(), mAllMessageRBtn);
598  }
599 
600  auto bg = new QButtonGroup(this);
601  bg->addButton(mAllRBtn);
602  bg->addButton(mAnyRBtn);
603  if (matchAllMessages) {
604  bg->addButton(mAllMessageRBtn);
605  }
606 
607  //------------connect a few signals
608  connect(bg, &QButtonGroup::buttonClicked, this, &SearchPatternEdit::slotRadioClicked);
609 
610  //------------the list of SearchRuleWidget's
611  mRuleLister = new SearchRuleWidgetLister(this, options, modeType);
612 
613  mRuleLister->slotClear();
614 
615  if (!mRuleLister->widgets().isEmpty()) {
616  const int numberOfWidget(mRuleLister->widgets().count());
617  for (int i = 0; i < numberOfWidget; ++i) {
618  SearchRuleWidget *srw = static_cast<SearchRuleWidget *>(mRuleLister->widgets().at(i));
619  connect(srw, &SearchRuleWidget::fieldChanged, this, &SearchPatternEdit::slotAutoNameHack);
620  connect(srw, &SearchRuleWidget::contentsChanged, this, &SearchPatternEdit::slotAutoNameHack);
621  connect(srw, &SearchRuleWidget::returnPressed, this, &SearchPatternEdit::returnPressed);
622  }
623  } else {
624  qCDebug(MAILCOMMON_LOG) << "No first SearchRuleWidget, though slotClear() has been called!";
625  }
626 
627  connect(mRuleLister, qOverload<QWidget *>(&SearchRuleWidgetLister::widgetAdded), this, &SearchPatternEdit::slotRuleAdded);
628  connect(mRuleLister, qOverload<>(&SearchRuleWidgetLister::widgetRemoved), this, &SearchPatternEdit::patternChanged);
629  connect(mRuleLister, &KPIM::KWidgetLister::clearWidgets, this, &SearchPatternEdit::patternChanged);
630 
631  layout->addRow(mRuleLister);
632 }
633 
634 void SearchPatternEdit::setSearchPattern(SearchPattern *aPattern)
635 {
636  Q_ASSERT(aPattern);
637 
638  mRuleLister->setRuleList(aPattern);
639 
640  mPattern = aPattern;
641 
642  blockSignals(true);
643  if (mPattern->op() == SearchPattern::OpOr) {
644  mAnyRBtn->setChecked(true);
645  } else if (mPattern->op() == SearchPattern::OpAnd) {
646  mAllRBtn->setChecked(true);
647  } else if (mAllMessageRBtn && (mPattern->op() == SearchPattern::OpAll)) {
648  mAllMessageRBtn->setChecked(true);
649  }
650  mRuleLister->setEnabled(mPattern->op() != SearchPattern::OpAll);
651  blockSignals(false);
652 
653  setEnabled(true);
654  Q_EMIT patternChanged();
655 }
656 
657 void SearchPatternEdit::reset()
658 {
659  mRuleLister->reset();
660 
661  blockSignals(true);
662  mAllRBtn->setChecked(true);
663  blockSignals(false);
664 
665  setEnabled(false);
666  Q_EMIT patternChanged();
667 }
668 
669 void SearchPatternEdit::slotRadioClicked(QAbstractButton *aRBtn)
670 {
671  if (mPattern) {
672  if (aRBtn == mAllRBtn) {
673  mPattern->setOp(SearchPattern::OpAnd);
674  } else if (aRBtn == mAnyRBtn) {
675  mPattern->setOp(SearchPattern::OpOr);
676  } else if (aRBtn == mAllMessageRBtn) {
677  mPattern->setOp(SearchPattern::OpAll);
678  }
679  mRuleLister->setEnabled(mPattern->op() != SearchPattern::OpAll);
680  Q_EMIT patternChanged();
681  }
682 }
683 
684 void SearchPatternEdit::slotAutoNameHack()
685 {
686  mRuleLister->regenerateRuleListFromWidgets();
687  Q_EMIT maybeNameChanged();
688  Q_EMIT patternChanged();
689 }
690 
691 void SearchPatternEdit::slotRuleAdded(QWidget *newRuleWidget)
692 {
693  auto srw = static_cast<SearchRuleWidget *>(newRuleWidget);
694  connect(srw, &SearchRuleWidget::fieldChanged, this, &SearchPatternEdit::slotAutoNameHack);
695  connect(srw, &SearchRuleWidget::contentsChanged, this, &SearchPatternEdit::slotAutoNameHack);
696  connect(srw, &SearchRuleWidget::returnPressed, this, &SearchPatternEdit::returnPressed);
697  Q_EMIT patternChanged();
698 }
void append(const T &value)
void adjustSize()
std::shared_ptr< SearchRule > Ptr
Defines a pointer to a search rule.
Definition: searchrule.h:29
void setSizePolicy(QSizePolicy)
Q_EMITQ_EMIT
int count(const T &value) const const
void buttonClicked(QAbstractButton *button)
static QByteArray ruleFieldToEnglish(const QString &i18nVal)
Used internally to translate i18n-ized pseudo-headers back to English.
void clicked(bool checked)
QIcon fromTheme(const QString &name)
void setFocusProxy(QWidget *w)
void setCurrentIndex(int index)
QByteArray toLatin1() const const
QList::const_iterator constBegin() const const
void textActivated(const QString &text)
virtual void setLineEdit(QLineEdit *)
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QString itemText(int index) const const
QString toString() const
void addItems(const QStringList &texts)
void insertItems(const QStringList &items)
QString i18n(const char *text, const TYPE &arg...)
void setItemText(int index, const QString &text)
bool blockSignals(bool block)
static SearchRule::Ptr createInstance(const QByteArray &field=QByteArray(), Function function=FuncContains, const QString &contents=QString())
Creates a new search rule of a certain type by instantiating the appropriate subclass depending on th...
Definition: searchrule.cpp:75
UniqueConnection
bool isEmpty() const const
void contentsChanged(const QString &)
This signal is emitted whenever the user alters the contents/value of the rule.
virtual void setIgnoreCase(bool ignoreCase)
virtual void setCompletionMode(CompletionMode mode)
Function
Describes operators for comparison of field and contents.
Definition: searchrule.h:40
void setMaxCount(int max)
void setEnabled(bool)
void setIcon(const QIcon &icon)
void reset()
Resets the rule currently worked on and updates the widget accordingly.
bool isEmpty() const const
QList::const_iterator constEnd() const const
void clear()
KCompletion * completionObject(bool handleSignals=true)
This class is an abstraction of a search over messages.
Definition: searchpattern.h:58
void setToolTip(const QString &)
void setRule(MailCommon::SearchRule::Ptr aRule)
Sets the rule.
Singleton to manage the list of RuleWidgetHandlers.
QString fromLatin1(const char *str, int size)
void setObjectName(const QString &name)
void fieldChanged(const QString &)
This signal is emitted whenever the user alters the field.
SearchRuleWidget(QWidget *parent=nullptr, MailCommon::SearchRule::Ptr aRule=MailCommon::SearchRule::Ptr(), SearchPatternEdit::SearchPatternEditOptions options=(SearchPatternEdit::SearchPatternEditOptions)(SearchPatternEdit::None), SearchPatternEdit::SearchModeType modeType=SearchPatternEdit::StandardMode)
Constructor.
void clear()
void setMinimumWidth(int minw)
const T & constFirst() const const
virtual void clear()
MailCommon::SearchRule::Ptr rule() const
Returns a reference to the currently-worked-on MailCommon::SearchRule.
int indexOfRuleField(const QByteArray &aName) const
Used internally to find the corresponding index into the field ComboBox.
void editTextChanged(const QString &text)
A widget to edit a single MailCommon::SearchRule.
void setEditable(bool editable)
The filter dialog.
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Sat Oct 1 2022 04:00:53 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.