7 #include "searchlinestatus.h"
8 #include "configurefiltersdialog.h"
9 #include "core/filtersavedmanager.h"
10 #include "filternamedialog.h"
11 #include "filtersavedmenu.h"
12 #include "messagelist_debug.h"
13 #include <kconfigwidgets_version.h>
14 #if KCONFIGWIDGETS_VERSION >= QT_VERSION_CHECK(5, 93, 0)
15 #include <KStatefulBrush>
18 #include <KColorScheme>
19 #include <KIconEngine>
20 #include <KIconLoader>
21 #include <KLocalizedString>
22 #include <QAbstractItemView>
25 #include <QContextMenuEvent>
27 #include <QPushButton>
28 #include <QStandardPaths>
29 #include <QStringListModel>
30 #include <QWidgetAction>
32 static const char qLineEditclearButtonActionNameC[] =
"_q_qlineeditclearaction";
33 #define MAX_COMPLETION_ITEMS 20
35 SearchLineStatus::SearchLineStatus(
QWidget *parent)
40 mCompleter->setModel(mCompleterListModel);
41 setCompleter(mCompleter);
43 setClearButtonEnabled(
true);
46 auto act = findChild<QAction *>(
QLatin1String(qLineEditclearButtonActionNameC));
50 qCWarning(MESSAGELIST_LOG) <<
"Clear button name was changed ! Please verify qt code";
52 connect(FilterSavedManager::self(), &FilterSavedManager::activateFilter,
this, &SearchLineStatus::slotActivateFilter);
55 SearchLineStatus::~SearchLineStatus() =
default;
57 void SearchLineStatus::keyPressEvent(
QKeyEvent *e)
60 if (mCompleter->popup()->isVisible()) {
63 Q_EMIT forceLostFocus();
66 mLockAction->trigger();
72 void SearchLineStatus::slotClear()
74 Q_EMIT clearButtonClicked();
77 void SearchLineStatus::updateLockAction()
81 mLockAction->setToolTip(
i18nc(
"@info:tooltip",
"Prevent the quick search field from being cleared when changing folders"));
84 mLockAction->setToolTip(
i18nc(
"@info:tooltip",
"Clear the quick search field when changing folders"));
88 void SearchLineStatus::setLocked(
bool b)
91 slotToggledLockAction();
95 bool SearchLineStatus::locked()
const
100 void SearchLineStatus::initializeActions()
103 mLockAction->setWhatsThis(
i18nc(
"@info:whatsthis",
104 "Toggle this button if you want to keep your quick search "
105 "locked when moving to other folders or when narrowing the search "
106 "by message status."));
108 connect(mLockAction, &
QAction::triggered,
this, &SearchLineStatus::slotToggledLockAction);
115 mFiltersAction->setToolTip(
i18n(
"Filter Mails by Status"));
119 mSaveFilterAction->setToolTip(
i18n(
"Saved Filter"));
120 mFilterSavedMenu =
new FilterSavedMenu(
this);
121 mSaveFilterAction->setMenu(mFilterSavedMenu);
122 connect(mSaveFilterAction, &
QAction::triggered,
this, &SearchLineStatus::showSavedFiltersMenu);
123 connect(mFilterSavedMenu, &FilterSavedMenu::saveFilter,
this, &SearchLineStatus::saveFilter);
124 connect(mFilterSavedMenu, &FilterSavedMenu::configureFilters,
this, &SearchLineStatus::slotConfigureFilters);
127 void SearchLineStatus::slotActivateFilter(
const QString &identifier)
129 Filter *f = FilterSavedManager::self()->loadFilter(identifier);
131 Q_EMIT activateFilter(f);
133 qCWarning(MESSAGELIST_LOG) <<
"Impossible to load Filter from identifier :" << identifier;
137 void SearchLineStatus::slotConfigureFilters()
139 ConfigureFiltersDialog dlg(
this);
143 void SearchLineStatus::slotToggledLockAction()
149 void SearchLineStatus::updateFilters()
153 for (
QAction *act : std::as_const(mFilterListActions)) {
154 if (act->isChecked()) {
156 status.fromQInt32(
static_cast<qint32
>(act->data().toInt()));
160 mHasFilter = !lstStatus.
isEmpty();
161 Q_EMIT filterActionChanged(lstStatus);
162 updateFilterActionIcon();
165 void SearchLineStatus::showSavedFiltersMenu()
167 mFilterSavedMenu->exec(mapToGlobal(
QPoint(0, height())));
170 void SearchLineStatus::showMenu()
172 if (mFilterMenu->exec(mapToGlobal(
QPoint(0, height())))) {
177 void SearchLineStatus::clearFilterAction()
179 for (
QAction *act : std::as_const(mFilterListActions)) {
180 act->setChecked(
false);
183 updateFilterActionIcon();
186 void SearchLineStatus::createFilterAction(
const QIcon &icon,
const QString &text,
int value)
188 auto act =
new QAction(icon, text,
this);
189 act->setCheckable(
true);
191 mFilterMenu->addAction(act);
192 mFilterListActions.append(act);
195 void SearchLineStatus::updateFilterActionIcon()
197 mFiltersAction->setIcon(mHasFilter ? mWithFilter : mWithoutFilter);
198 if (mColorName.isEmpty()) {
201 mColorName = bgBrush.brush(palette()).color().name();
203 setStyleSheet(mHasFilter ? QStringLiteral(
"QLineEdit{ background-color:%1 }").arg(mColorName) :
QString());
206 void SearchLineStatus::clearFilterButtonClicked()
209 clearFilterByAction();
213 void SearchLineStatus::createMenuSearch()
215 mFilterMenu =
new QMenu(
this);
216 mFilterMenu->setObjectName(QStringLiteral(
"filtermenu"));
218 auto clearFilterButton =
new QPushButton(
i18n(
"Clear Filter"), mFilterMenu);
219 connect(clearFilterButton, &
QPushButton::clicked,
this, &SearchLineStatus::clearFilterButtonClicked);
221 clearWidgetAction->setDefaultWidget(clearFilterButton);
222 mFilterMenu->addAction(clearWidgetAction);
224 i18nc(
"@action:inmenu Status of a message",
"Unread"),
228 i18nc(
"@action:inmenu Status of a message",
"Replied"),
232 i18nc(
"@action:inmenu Status of a message",
"Forwarded"),
236 i18nc(
"@action:inmenu Status of a message",
"Important"),
240 i18nc(
"@action:inmenu Status of a message",
"Action Item"),
244 i18nc(
"@action:inmenu Status of a message",
"Watched"),
248 i18nc(
"@action:inmenu Status of a message",
"Ignored"),
252 i18nc(
"@action:inmenu Status of a message",
"Has Attachment"),
256 i18nc(
"@action:inmenu Status of a message",
"Has Invitation"),
260 i18nc(
"@action:inmenu Status of a message",
"Spam"),
264 i18nc(
"@action:inmenu Status of a message",
"Ham"),
266 createFilterByAction();
269 void SearchLineStatus::createFilterByAction()
271 mFilterMenu->addSeparator();
274 mSearchEveryWhereAction =
new QAction(
i18n(
"Full Message"), mFilterMenu);
275 mSearchEveryWhereAction->setCheckable(
true);
276 mSearchEveryWhereAction->setChecked(
true);
278 mFilterMenu->addAction(mSearchEveryWhereAction);
279 grp->addAction(mSearchEveryWhereAction);
281 mSearchAgainstBodyAction =
new QAction(
i18n(
"Body"), mFilterMenu);
282 grp->addAction(mSearchAgainstBodyAction);
283 mFilterMenu->addAction(mSearchAgainstBodyAction);
284 mSearchAgainstBodyAction->setCheckable(
true);
286 mSearchAgainstSubjectAction =
new QAction(
i18n(
"Subject"), mFilterMenu);
287 grp->addAction(mSearchAgainstSubjectAction);
288 mFilterMenu->addAction(mSearchAgainstSubjectAction);
289 mSearchAgainstSubjectAction->setCheckable(
true);
291 mSearchAgainstFromOrToAction =
new QAction(mFilterMenu);
292 changeSearchAgainstFromOrToText();
293 grp->addAction(mSearchAgainstFromOrToAction);
294 mFilterMenu->addAction(mSearchAgainstFromOrToAction);
295 mSearchAgainstFromOrToAction->setCheckable(
true);
297 mSearchAgainstBccAction =
new QAction(
i18n(
"BCC"), mFilterMenu);
298 grp->addAction(mSearchAgainstBccAction);
299 mFilterMenu->addAction(mSearchAgainstBccAction);
300 mSearchAgainstBccAction->setCheckable(
true);
304 void SearchLineStatus::clearFilterByAction()
306 mSearchEveryWhereAction->setChecked(
true);
309 bool SearchLineStatus::containsOutboundMessages()
const
311 return mContainsOutboundMessages;
314 void SearchLineStatus::setContainsOutboundMessages(
bool containsOutboundMessages)
316 if (mContainsOutboundMessages != containsOutboundMessages) {
317 mContainsOutboundMessages = containsOutboundMessages;
318 changeSearchAgainstFromOrToText();
322 void SearchLineStatus::changeSearchAgainstFromOrToText()
324 if (mContainsOutboundMessages) {
325 mSearchAgainstFromOrToAction->setText(
i18n(
"To"));
327 mSearchAgainstFromOrToAction->setText(
i18n(
"From"));
334 if (mSearchEveryWhereAction->isChecked()) {
335 searchOptions |= QuickSearchLine::SearchEveryWhere;
337 if (mSearchAgainstBodyAction->isChecked()) {
338 searchOptions |= QuickSearchLine::SearchAgainstBody;
340 if (mSearchAgainstSubjectAction->isChecked()) {
341 searchOptions |= QuickSearchLine::SearchAgainstSubject;
343 if (mSearchAgainstFromOrToAction->isChecked()) {
344 if (mContainsOutboundMessages) {
345 searchOptions |= QuickSearchLine::SearchAgainstTo;
347 searchOptions |= QuickSearchLine::SearchAgainstFrom;
350 if (mSearchAgainstBccAction->isChecked()) {
351 searchOptions |= QuickSearchLine::SearchAgainstBcc;
353 return searchOptions;
358 mSearchEveryWhereAction->setChecked(opts & QuickSearchLine::SearchEveryWhere);
359 mSearchAgainstBodyAction->setChecked(opts & QuickSearchLine::SearchAgainstBody);
360 mSearchAgainstSubjectAction->setChecked(opts & QuickSearchLine::SearchAgainstSubject);
361 mSearchAgainstBccAction->setChecked(opts & QuickSearchLine::SearchAgainstBcc);
362 if (mContainsOutboundMessages) {
363 mSearchAgainstFromOrToAction->setChecked(opts & QuickSearchLine::SearchAgainstTo);
365 mSearchAgainstFromOrToAction->setChecked(opts & QuickSearchLine::SearchAgainstFrom);
372 clearFilterByAction();
375 for (
QAction *act : std::as_const(mFilterListActions)) {
376 if (
static_cast<qint32
>(act->data().toInt()) ==
status.toQInt32()) {
377 act->setChecked(
true);
383 updateFilterActionIcon();
386 void SearchLineStatus::slotFilterActionClicked(
QAction *act)
389 Q_EMIT searchOptionChanged();
392 void SearchLineStatus::addCompletionItem(
const QString &str)
394 mListCompetion.removeAll(str);
395 mListCompetion.prepend(str);
396 while (mListCompetion.size() > MAX_COMPLETION_ITEMS) {
397 mListCompetion.removeLast();
399 mCompleterListModel->setStringList(mListCompetion);
407 popup->
addAction(
QIcon::fromTheme(QStringLiteral(
"edit-clear-locationbar-rtl")),
i18n(
"Clear History"),
this, &SearchLineStatus::slotClearHistory);
413 void SearchLineStatus::slotClearHistory()
415 mListCompetion.
clear();
416 mCompleterListModel->setStringList(mListCompetion);