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

KDE's Doxygen guidelines are available online.