Messagelib

searchlinestatus.cpp
1/*
2 SPDX-FileCopyrightText: 2016-2024 Laurent Montel <montel@kde.org>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5*/
6
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>
13
14#include <KColorScheme>
15#include <KLocalizedString>
16#include <QAbstractItemView>
17#include <QAction>
18#include <QActionGroup>
19#include <QCompleter>
20#include <QContextMenuEvent>
21#include <QMenu>
22#include <QPushButton>
23#include <QStandardPaths>
24#include <QStringListModel>
25#include <QWidgetAction>
26
27static const char qLineEditclearButtonActionNameC[] = "_q_qlineeditclearaction";
28#define MAX_COMPLETION_ITEMS 20
29using namespace MessageList::Core;
30SearchLineStatus::SearchLineStatus(QWidget *parent)
31 : QLineEdit(parent)
32 , mCompleter(new QCompleter(this))
33 , mCompleterListModel(new QStringListModel(this))
34{
35 setProperty("_breeze_borders_sides", QVariant::fromValue(QFlags{Qt::BottomEdge}));
36 mCompleter->setCaseSensitivity(Qt::CaseInsensitive);
37 mCompleter->setModel(mCompleterListModel);
38 setCompleter(mCompleter);
39
40 setClearButtonEnabled(true);
41 initializeActions();
42 auto act = findChild<QAction *>(QLatin1StringView(qLineEditclearButtonActionNameC));
43 if (act) {
44 connect(act, &QAction::triggered, this, &SearchLineStatus::slotClear);
45 } else {
46 qCWarning(MESSAGELIST_LOG) << "Clear button name was changed ! Please verify qt code";
47 }
48 connect(FilterSavedManager::self(), &FilterSavedManager::activateFilter, this, &SearchLineStatus::slotActivateFilter);
49}
50
51SearchLineStatus::~SearchLineStatus() = default;
52
53void SearchLineStatus::keyPressEvent(QKeyEvent *e)
54{
55 if (e->key() == Qt::Key_Escape) {
56 if (mCompleter->popup()->isVisible()) {
58 } else {
59 Q_EMIT forceLostFocus();
60 }
61 } else if (e->key() == Qt::Key_Q && (e->modifiers().testFlag(Qt::ShiftModifier) && e->modifiers().testFlag(Qt::AltModifier))) {
62 mLockAction->trigger();
63 } else {
65 }
66}
67
68void SearchLineStatus::slotClear()
69{
70 Q_EMIT clearButtonClicked();
71}
72
73void SearchLineStatus::updateLockAction()
74{
75 if (mLocked) {
76 mLockAction->setIcon(QIcon::fromTheme(QStringLiteral("object-locked")));
77 mLockAction->setToolTip(i18nc("@info:tooltip", "Prevent the quick search field from being cleared when changing folders"));
78 } else {
79 mLockAction->setIcon(QIcon::fromTheme(QStringLiteral("object-unlocked")));
80 mLockAction->setToolTip(i18nc("@info:tooltip", "Clear the quick search field when changing folders"));
81 }
82}
83
84void SearchLineStatus::setLocked(bool b)
85{
86 if (mLocked != b) {
87 slotToggledLockAction();
88 }
89}
90
91bool SearchLineStatus::locked() const
92{
93 return mLocked;
94}
95
96void SearchLineStatus::initializeActions()
97{
98 mLockAction = addAction(QIcon::fromTheme(QStringLiteral("object-locked")), QLineEdit::TrailingPosition);
99 mLockAction->setWhatsThis(i18nc("@info:whatsthis",
100 "Toggle this button if you want to keep your quick search "
101 "locked when moving to other folders or when narrowing the search "
102 "by message status."));
103
104 connect(mLockAction, &QAction::triggered, this, &SearchLineStatus::slotToggledLockAction);
105 updateLockAction();
106
107 mSaveFilterAction = addAction(QIcon::fromTheme(QStringLiteral("edit-find")), QLineEdit::LeadingPosition);
108 mSaveFilterAction->setToolTip(i18nc("@info:tooltip", "Saved Filter"));
109 mFilterSavedMenu = new FilterSavedMenu(this);
110 mSaveFilterAction->setMenu(mFilterSavedMenu);
111 connect(mSaveFilterAction, &QAction::triggered, this, &SearchLineStatus::showSavedFiltersMenu);
112 connect(mFilterSavedMenu, &FilterSavedMenu::saveFilter, this, &SearchLineStatus::saveFilter);
113 connect(mFilterSavedMenu, &FilterSavedMenu::configureFilters, this, &SearchLineStatus::slotConfigureFilters);
114}
115
116void SearchLineStatus::slotActivateFilter(const QString &identifier)
117{
118 Filter *f = FilterSavedManager::self()->loadFilter(identifier);
119 if (f) {
120 Q_EMIT activateFilter(f);
121 } else {
122 qCWarning(MESSAGELIST_LOG) << "Impossible to load Filter from identifier :" << identifier;
123 }
124}
125
126void SearchLineStatus::slotConfigureFilters()
127{
128 ConfigureFiltersDialog dlg(this);
129 dlg.exec();
130}
131
132void SearchLineStatus::slotToggledLockAction()
133{
134 mLocked = !mLocked;
135 updateLockAction();
136}
137
138void SearchLineStatus::showSavedFiltersMenu()
139{
140 mFilterSavedMenu->exec(mapToGlobal(QPoint(0, height())));
141}
142
143void SearchLineStatus::clearFilterAction()
144{
145 mHasFilter = false;
146 updateFilterLineEditBackgroundColor();
147}
148
149void SearchLineStatus::updateFilterLineEditBackgroundColor()
150{
151 if (mColorName.isEmpty()) {
153 KStatefulBrush bgBrush(KColorScheme::View, bgColorScheme);
154 mColorName = bgBrush.brush(palette()).color().name();
155 }
156 setStyleSheet(mHasFilter ? QStringLiteral("QLineEdit{ background-color:%1 }").arg(mColorName) : QString());
157}
158
159void SearchLineStatus::clearFilterButtonClicked()
160{
161 mHasFilter = false;
162 updateFilterLineEditBackgroundColor();
163}
164
165void SearchLineStatus::filterAdded()
166{
167 mHasFilter = true;
168 updateFilterLineEditBackgroundColor();
169}
170
171void SearchLineStatus::addCompletionItem(const QString &str)
172{
173 mListCompetion.removeAll(str);
174 mListCompetion.prepend(str);
175 while (mListCompetion.size() > MAX_COMPLETION_ITEMS) {
176 mListCompetion.removeLast();
177 }
178 mCompleterListModel->setStringList(mListCompetion);
179}
180
181void SearchLineStatus::contextMenuEvent(QContextMenuEvent *e)
182{
184 if (popup) {
185 popup->addSeparator();
186 popup->addAction(QIcon::fromTheme(QStringLiteral("edit-clear-locationbar-rtl")), i18n("Clear History"), this, &SearchLineStatus::slotClearHistory);
187 popup->exec(e->globalPos());
188 delete popup;
189 }
190}
191
192void SearchLineStatus::slotClearHistory()
193{
194 mListCompetion.clear();
195 mCompleterListModel->setStringList(mListCompetion);
196}
197
198#include "moc_searchlinestatus.cpp"
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
The implementation independent part of the MessageList library.
Definition aggregation.h:22
QCA_EXPORT void setProperty(const QString &name, const QVariant &value)
void setIcon(const QIcon &icon)
void setMenu(QMenu *menu)
void setToolTip(const QString &tip)
void trigger()
void triggered(bool checked)
void setWhatsThis(const QString &what)
QAbstractItemView * popup() const const
const QPoint & globalPos() const const
QIcon fromTheme(const QString &name)
int key() const const
Qt::KeyboardModifiers modifiers() const const
QAction * addAction(const QIcon &icon, ActionPosition position)
QMenu * createStandardContextMenu()
virtual void keyPressEvent(QKeyEvent *event) override
void clear()
void prepend(parameter_type value)
qsizetype removeAll(const AT &t)
void removeLast()
qsizetype size() const const
QAction * addAction(const QIcon &icon, const QString &text, Functor functor, const QKeySequence &shortcut)
QAction * addSeparator()
QAction * exec()
Q_EMITQ_EMIT
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
bool isEmpty() const const
void setStringList(const QStringList &strings)
CaseInsensitive
BottomEdge
Key_Escape
ShiftModifier
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
QVariant fromValue(T &&value)
QPoint mapToGlobal(const QPoint &pos) const const
void setStyleSheet(const QString &styleSheet)
bool isVisible() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Jul 26 2024 11:54:19 by doxygen 1.11.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.