Libksieve

findbarbase.cpp
1/* SPDX-FileCopyrightText: 2010 Torgny Nyblom <nyblom@kde.org>
2 * SPDX-FileCopyrightText: 2010-2024 Laurent Montel <montel@kde.org>
3 *
4 * SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6
7#include "findbarbase.h"
8#include <KStatefulBrush>
9
10#include <PimCommon/LineEditWithCompleterNg>
11
12#include <KColorScheme>
13#include <KLocalizedString>
14#include <QIcon>
15
16#include <QEvent>
17#include <QHBoxLayout>
18#include <QKeyEvent>
19#include <QLabel>
20#include <QMenu>
21#include <QPushButton>
22#include <QTimer>
23#include <QToolButton>
24
25using namespace KSieveUi;
26
27FindBarBase::FindBarBase(QWidget *parent)
28 : QWidget(parent)
29{
30 auto lay = new QHBoxLayout(this);
31 lay->setContentsMargins(2, 2, 2, 2);
32
33 auto closeBtn = new QToolButton(this);
34 closeBtn->setIcon(QIcon::fromTheme(QStringLiteral("dialog-close")));
35 closeBtn->setObjectName(QLatin1StringView("close"));
36 closeBtn->setIconSize(QSize(16, 16));
37 closeBtn->setToolTip(i18n("Close"));
38
39#ifndef QT_NO_ACCESSIBILITY
40 closeBtn->setAccessibleName(i18n("Close"));
41#endif
42
43 closeBtn->setAutoRaise(true);
44 lay->addWidget(closeBtn);
45
46 auto label = new QLabel(i18nc("Find text", "F&ind:"), this);
47 lay->addWidget(label);
48
49 mSearch = new PimCommon::LineEditWithCompleterNg(this);
50 mSearch->setObjectName(QLatin1StringView("searchline"));
51 mSearch->setToolTip(i18n("Text to search for"));
52 mSearch->setClearButtonEnabled(true);
53 label->setBuddy(mSearch);
54 lay->addWidget(mSearch);
55
56 mFindNextBtn = new QPushButton(QIcon::fromTheme(QStringLiteral("go-down-search")), i18nc("Find and go to the next search match", "Next"), this);
57 mFindNextBtn->setToolTip(i18n("Jump to next match"));
58 mFindNextBtn->setObjectName(QLatin1StringView("findnext"));
59 lay->addWidget(mFindNextBtn);
60 mFindNextBtn->setEnabled(false);
61
62 mFindPrevBtn = new QPushButton(QIcon::fromTheme(QStringLiteral("go-up-search")), i18nc("Find and go to the previous search match", "Previous"), this);
63 mFindPrevBtn->setToolTip(i18n("Jump to previous match"));
64 mFindPrevBtn->setObjectName(QLatin1StringView("findprevious"));
65 lay->addWidget(mFindPrevBtn);
66 mFindPrevBtn->setEnabled(false);
67
68 auto optionsBtn = new QPushButton(this);
69 optionsBtn->setText(i18n("Options"));
70 optionsBtn->setToolTip(i18n("Modify search behavior"));
71 mOptionsMenu = new QMenu(optionsBtn);
72 mCaseSensitiveAct = mOptionsMenu->addAction(i18n("Case sensitive"));
73 mCaseSensitiveAct->setCheckable(true);
74
75 optionsBtn->setMenu(mOptionsMenu);
76 lay->addWidget(optionsBtn);
77
78 connect(closeBtn, &QToolButton::clicked, this, &FindBarBase::closeBar);
79 connect(mFindNextBtn, &QPushButton::clicked, this, &FindBarBase::findNext);
80 connect(mFindPrevBtn, &QPushButton::clicked, this, &FindBarBase::findPrev);
81 connect(mCaseSensitiveAct, &QAction::toggled, this, &FindBarBase::caseSensitivityChanged);
82 connect(mSearch, &QLineEdit::textChanged, this, &FindBarBase::autoSearch);
83
84 mStatus = new QLabel(this);
85 mStatus->setObjectName(QLatin1StringView("status"));
86 mStatus->setTextFormat(Qt::PlainText);
87 QFontMetrics fm(mStatus->font());
88 mNotFoundString = i18n("Phrase not found");
89 mStatus->setFixedWidth(fm.boundingRect(mNotFoundString).width());
90 lay->addWidget(mStatus);
91
93 // lay->addStretch();
94 hide();
95}
96
97FindBarBase::~FindBarBase() = default;
98
99QMenu *FindBarBase::optionsMenu()
100{
101 return mOptionsMenu;
102}
103
104QString FindBarBase::text() const
105{
106 return mSearch->text();
107}
108
109void FindBarBase::setText(const QString &text)
110{
111 mSearch->setText(text);
112}
113
114void FindBarBase::focusAndSetCursor()
115{
116 setFocus();
117 mStatus->clear();
118 mSearch->selectAll();
119 mSearch->setFocus();
120}
121
122void FindBarBase::autoSearch(const QString &str)
123{
124 const bool isNotEmpty = (!str.isEmpty());
125 mFindPrevBtn->setEnabled(isNotEmpty);
126 mFindNextBtn->setEnabled(isNotEmpty);
127 if (isNotEmpty) {
128 QTimer::singleShot(0, this, [this]() {
129 slotSearchText();
130 });
131 } else {
132 clearSelections();
133 }
134}
135
136void FindBarBase::slotSearchText(bool backward, bool isAutoSearch)
137{
138 searchText(backward, isAutoSearch);
139}
140
141void FindBarBase::setFoundMatch(bool match)
142{
143#ifndef QT_NO_STYLE_STYLESHEET
145
146 if (!mSearch->text().isEmpty()) {
147 if (mNegativeBackground.isEmpty()) {
149 mPositiveBackground = QStringLiteral("QLineEdit{ background-color:%1 }").arg(bgBrush.brush(mSearch->palette()).color().name());
151 mNegativeBackground = QStringLiteral("QLineEdit{ background-color:%1 }").arg(bgBrush.brush(mSearch->palette()).color().name());
152 }
153 if (match) {
154 styleSheet = mPositiveBackground;
155 mStatus->clear();
156 } else {
157 styleSheet = mNegativeBackground;
158 mStatus->setText(mNotFoundString);
159 }
160 }
161 mSearch->setStyleSheet(styleSheet);
162#endif
163}
164
165void FindBarBase::searchText(bool backward, bool isAutoSearch)
166{
167 Q_UNUSED(backward)
168 Q_UNUSED(isAutoSearch)
169}
170
171void FindBarBase::addToCompletion(const QString &text)
172{
173 mSearch->addCompletionItem(text);
174}
175
176void FindBarBase::findNext()
177{
178 searchText(false, false);
179 addToCompletion(mLastSearchStr);
180}
181
182void FindBarBase::findPrev()
183{
184 searchText(true, false);
185 addToCompletion(mLastSearchStr);
186}
187
188void FindBarBase::caseSensitivityChanged(bool b)
189{
190 updateSensitivity(b);
191}
192
193void FindBarBase::updateSensitivity(bool)
194{
195}
196
197void FindBarBase::slotHighlightAllChanged(bool b)
198{
199 updateHighLight(b);
200}
201
202void FindBarBase::updateHighLight(bool)
203{
204}
205
206void FindBarBase::clearSelections()
207{
208 setFoundMatch(false);
209}
210
211void FindBarBase::closeBar()
212{
213 // Make sure that all old searches are cleared
214 mSearch->clear();
215 clearSelections();
216 mSearch->clearFocus();
217 Q_EMIT hideFindBar();
218}
219
220bool FindBarBase::event(QEvent *e)
221{
222 // Close the bar when pressing Escape.
223 // Not using a QShortcut for this because it could conflict with
224 // window-global actions (e.g. Emil Sedgh binds Esc to "close tab").
225 // With a shortcut override we can catch this before it gets to kactions.
226 const bool shortCutOverride = (e->type() == QEvent::ShortcutOverride);
227 if (shortCutOverride || e->type() == QEvent::KeyPress) {
228 auto kev = static_cast<QKeyEvent *>(e);
229 if (kev->key() == Qt::Key_Escape) {
230 if (shortCutOverride) {
231 e->accept();
232 return true;
233 }
234 e->accept();
235 closeBar();
236 return true;
237 } else if (kev->key() == Qt::Key_Enter || kev->key() == Qt::Key_Return) {
238 e->accept();
239 if (shortCutOverride) {
240 return true;
241 }
242 if (mSearch->text().isEmpty()) {
243 return true;
244 }
245 if (kev->modifiers() & Qt::ShiftModifier) {
246 findPrev();
247 } else if (kev->modifiers() == Qt::NoModifier) {
248 findNext();
249 }
250 return true;
251 }
252 }
253 return QWidget::event(e);
254}
255
256#include "moc_findbarbase.cpp"
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
QString label(StandardShortcut id)
void clicked(bool checked)
void toggled(bool checked)
ShortcutOverride
void accept()
Type type() const const
QIcon fromTheme(const QString &name)
void clear()
void setText(const QString &)
void clear()
void selectAll()
void textChanged(const QString &text)
Q_EMITQ_EMIT
QString arg(Args &&... args) const const
bool isEmpty() const const
Key_Escape
ShiftModifier
PlainText
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
void clearFocus()
void setEnabled(bool)
virtual bool event(QEvent *event) override
void setFocus()
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:17:19 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.