Messagelib

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

KDE's Doxygen guidelines are available online.