7 #include "searchlinestatus.h"
8 #include "configurefiltersdialog.h"
9 #include "core/filtersavedmanager.h"
10 #include "filtersavedmenu.h"
11 #include "messagelist_debug.h"
12 #include <KStatefulBrush>
14 #include <KColorScheme>
15 #include <KIconEngine>
16 #include <KIconLoader>
17 #include <KLocalizedString>
18 #include <QAbstractItemView>
20 #include <QActionGroup>
22 #include <QContextMenuEvent>
24 #include <QPushButton>
25 #include <QStandardPaths>
26 #include <QStringListModel>
27 #include <QWidgetAction>
29 static const char qLineEditclearButtonActionNameC[] =
"_q_qlineeditclearaction";
30 #define MAX_COMPLETION_ITEMS 20
32 SearchLineStatus::SearchLineStatus(
QWidget *parent)
37 mCompleter->setModel(mCompleterListModel);
38 setCompleter(mCompleter);
40 setClearButtonEnabled(
true);
43 auto act = findChild<QAction *>(
QLatin1String(qLineEditclearButtonActionNameC));
47 qCWarning(MESSAGELIST_LOG) <<
"Clear button name was changed ! Please verify qt code";
49 connect(FilterSavedManager::self(), &FilterSavedManager::activateFilter,
this, &SearchLineStatus::slotActivateFilter);
52 SearchLineStatus::~SearchLineStatus() =
default;
54 void SearchLineStatus::keyPressEvent(
QKeyEvent *e)
57 if (mCompleter->popup()->isVisible()) {
60 Q_EMIT forceLostFocus();
63 mLockAction->trigger();
69 void SearchLineStatus::slotClear()
71 Q_EMIT clearButtonClicked();
74 void SearchLineStatus::updateLockAction()
78 mLockAction->setToolTip(
i18nc(
"@info:tooltip",
"Prevent the quick search field from being cleared when changing folders"));
81 mLockAction->setToolTip(
i18nc(
"@info:tooltip",
"Clear the quick search field when changing folders"));
85 void SearchLineStatus::setLocked(
bool b)
88 slotToggledLockAction();
92 bool SearchLineStatus::locked()
const
97 void SearchLineStatus::initializeActions()
100 mLockAction->setWhatsThis(
i18nc(
"@info:whatsthis",
101 "Toggle this button if you want to keep your quick search "
102 "locked when moving to other folders or when narrowing the search "
103 "by message status."));
105 connect(mLockAction, &
QAction::triggered,
this, &SearchLineStatus::slotToggledLockAction);
112 mFiltersAction->setToolTip(
i18n(
"Filter Mails by Status"));
116 mSaveFilterAction->setToolTip(
i18n(
"Saved Filter"));
117 mFilterSavedMenu =
new FilterSavedMenu(
this);
118 mSaveFilterAction->setMenu(mFilterSavedMenu);
119 connect(mSaveFilterAction, &
QAction::triggered,
this, &SearchLineStatus::showSavedFiltersMenu);
120 connect(mFilterSavedMenu, &FilterSavedMenu::saveFilter,
this, &SearchLineStatus::saveFilter);
121 connect(mFilterSavedMenu, &FilterSavedMenu::configureFilters,
this, &SearchLineStatus::slotConfigureFilters);
124 void SearchLineStatus::slotActivateFilter(
const QString &identifier)
126 Filter *f = FilterSavedManager::self()->loadFilter(identifier);
128 Q_EMIT activateFilter(f);
130 qCWarning(MESSAGELIST_LOG) <<
"Impossible to load Filter from identifier :" << identifier;
134 void SearchLineStatus::slotConfigureFilters()
136 ConfigureFiltersDialog dlg(
this);
140 void SearchLineStatus::slotToggledLockAction()
146 void SearchLineStatus::updateFilters()
150 for (
QAction *act : std::as_const(mFilterListActions)) {
151 if (act->isChecked()) {
153 status.fromQInt32(
static_cast<qint32
>(act->data().toInt()));
157 mHasFilter = !lstStatus.
isEmpty();
158 Q_EMIT filterActionChanged(lstStatus);
159 updateFilterActionIcon();
162 void SearchLineStatus::showSavedFiltersMenu()
164 mFilterSavedMenu->exec(mapToGlobal(
QPoint(0, height())));
167 void SearchLineStatus::showMenu()
169 if (mFilterMenu->exec(mapToGlobal(
QPoint(0, height())))) {
174 void SearchLineStatus::clearFilterAction()
176 for (
QAction *act : std::as_const(mFilterListActions)) {
177 act->setChecked(
false);
180 updateFilterActionIcon();
183 void SearchLineStatus::createFilterAction(
const QIcon &icon,
const QString &text,
int value)
185 auto act =
new QAction(icon, text,
this);
186 act->setCheckable(
true);
188 mFilterMenu->addAction(act);
189 mFilterListActions.append(act);
192 void SearchLineStatus::updateFilterActionIcon()
194 mFiltersAction->setIcon(mHasFilter ? mWithFilter : mWithoutFilter);
195 if (mColorName.isEmpty()) {
198 mColorName = bgBrush.brush(palette()).color().name();
200 setStyleSheet(mHasFilter ? QStringLiteral(
"QLineEdit{ background-color:%1 }").arg(mColorName) :
QString());
203 void SearchLineStatus::clearFilterButtonClicked()
206 clearFilterByAction();
210 void SearchLineStatus::createMenuSearch()
212 mFilterMenu =
new QMenu(
this);
213 mFilterMenu->setObjectName(QStringLiteral(
"filtermenu"));
215 auto clearFilterButton =
new QPushButton(
i18n(
"Clear Filter"), mFilterMenu);
216 connect(clearFilterButton, &
QPushButton::clicked,
this, &SearchLineStatus::clearFilterButtonClicked);
218 clearWidgetAction->setDefaultWidget(clearFilterButton);
219 mFilterMenu->addAction(clearWidgetAction);
221 i18nc(
"@action:inmenu Status of a message",
"Unread"),
225 i18nc(
"@action:inmenu Status of a message",
"Replied"),
229 i18nc(
"@action:inmenu Status of a message",
"Forwarded"),
233 i18nc(
"@action:inmenu Status of a message",
"Important"),
237 i18nc(
"@action:inmenu Status of a message",
"Action Item"),
241 i18nc(
"@action:inmenu Status of a message",
"Watched"),
245 i18nc(
"@action:inmenu Status of a message",
"Ignored"),
249 i18nc(
"@action:inmenu Status of a message",
"Has Attachment"),
253 i18nc(
"@action:inmenu Status of a message",
"Has Invitation"),
257 i18nc(
"@action:inmenu Status of a message",
"Spam"),
261 i18nc(
"@action:inmenu Status of a message",
"Ham"),
263 createFilterByAction();
266 void SearchLineStatus::createFilterByAction()
268 mFilterMenu->addSeparator();
271 mSearchEveryWhereAction =
new QAction(
i18n(
"Full Message"), mFilterMenu);
272 mSearchEveryWhereAction->setCheckable(
true);
273 mSearchEveryWhereAction->setChecked(
true);
275 mFilterMenu->addAction(mSearchEveryWhereAction);
276 grp->addAction(mSearchEveryWhereAction);
278 mSearchAgainstBodyAction =
new QAction(
i18n(
"Body"), mFilterMenu);
279 grp->addAction(mSearchAgainstBodyAction);
280 mFilterMenu->addAction(mSearchAgainstBodyAction);
281 mSearchAgainstBodyAction->setCheckable(
true);
283 mSearchAgainstSubjectAction =
new QAction(
i18n(
"Subject"), mFilterMenu);
284 grp->addAction(mSearchAgainstSubjectAction);
285 mFilterMenu->addAction(mSearchAgainstSubjectAction);
286 mSearchAgainstSubjectAction->setCheckable(
true);
288 mSearchAgainstFromOrToAction =
new QAction(mFilterMenu);
289 changeSearchAgainstFromOrToText();
290 grp->addAction(mSearchAgainstFromOrToAction);
291 mFilterMenu->addAction(mSearchAgainstFromOrToAction);
292 mSearchAgainstFromOrToAction->setCheckable(
true);
294 mSearchAgainstBccAction =
new QAction(
i18n(
"BCC"), mFilterMenu);
295 grp->addAction(mSearchAgainstBccAction);
296 mFilterMenu->addAction(mSearchAgainstBccAction);
297 mSearchAgainstBccAction->setCheckable(
true);
301 void SearchLineStatus::clearFilterByAction()
303 mSearchEveryWhereAction->setChecked(
true);
306 bool SearchLineStatus::containsOutboundMessages()
const
308 return mContainsOutboundMessages;
311 void SearchLineStatus::setContainsOutboundMessages(
bool containsOutboundMessages)
313 if (mContainsOutboundMessages != containsOutboundMessages) {
314 mContainsOutboundMessages = containsOutboundMessages;
315 changeSearchAgainstFromOrToText();
319 void SearchLineStatus::changeSearchAgainstFromOrToText()
321 if (mContainsOutboundMessages) {
322 mSearchAgainstFromOrToAction->setText(
i18n(
"To"));
324 mSearchAgainstFromOrToAction->setText(
i18n(
"From"));
331 if (mSearchEveryWhereAction->isChecked()) {
332 searchOptions |= QuickSearchLine::SearchEveryWhere;
334 if (mSearchAgainstBodyAction->isChecked()) {
335 searchOptions |= QuickSearchLine::SearchAgainstBody;
337 if (mSearchAgainstSubjectAction->isChecked()) {
338 searchOptions |= QuickSearchLine::SearchAgainstSubject;
340 if (mSearchAgainstFromOrToAction->isChecked()) {
341 if (mContainsOutboundMessages) {
342 searchOptions |= QuickSearchLine::SearchAgainstTo;
344 searchOptions |= QuickSearchLine::SearchAgainstFrom;
347 if (mSearchAgainstBccAction->isChecked()) {
348 searchOptions |= QuickSearchLine::SearchAgainstBcc;
350 return searchOptions;
355 mSearchEveryWhereAction->setChecked(opts & QuickSearchLine::SearchEveryWhere);
356 mSearchAgainstBodyAction->setChecked(opts & QuickSearchLine::SearchAgainstBody);
357 mSearchAgainstSubjectAction->setChecked(opts & QuickSearchLine::SearchAgainstSubject);
358 mSearchAgainstBccAction->setChecked(opts & QuickSearchLine::SearchAgainstBcc);
359 if (mContainsOutboundMessages) {
360 mSearchAgainstFromOrToAction->setChecked(opts & QuickSearchLine::SearchAgainstTo);
362 mSearchAgainstFromOrToAction->setChecked(opts & QuickSearchLine::SearchAgainstFrom);
369 clearFilterByAction();
372 for (
QAction *act : std::as_const(mFilterListActions)) {
373 if (
static_cast<qint32
>(act->data().toInt()) ==
status.toQInt32()) {
374 act->setChecked(
true);
380 updateFilterActionIcon();
383 void SearchLineStatus::slotFilterActionClicked(
QAction *act)
386 Q_EMIT searchOptionChanged();
389 void SearchLineStatus::addCompletionItem(
const QString &str)
391 mListCompetion.removeAll(str);
392 mListCompetion.prepend(str);
393 while (mListCompetion.size() > MAX_COMPLETION_ITEMS) {
394 mListCompetion.removeLast();
396 mCompleterListModel->setStringList(mListCompetion);
404 popup->
addAction(
QIcon::fromTheme(QStringLiteral(
"edit-clear-locationbar-rtl")),
i18n(
"Clear History"),
this, &SearchLineStatus::slotClearHistory);
410 void SearchLineStatus::slotClearHistory()
412 mListCompetion.
clear();
413 mCompleterListModel->setStringList(mListCompetion);