Mailcommon

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

KDE's Doxygen guidelines are available online.