Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qkeysequenceedit.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// Copyright (C) 2013 Ivan Komissarov.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#include "qkeysequenceedit.h"
7
8#include "qboxlayout.h"
9#include "qlineedit.h"
10#include <private/qkeymapper_p.h>
11
13
14static_assert(QKeySequencePrivate::MaxKeyCount == 4); // assumed by the code around here
15
17{
19
20 lineEdit = new QLineEdit(q);
21 lineEdit->setObjectName(QStringLiteral("qt_keysequenceedit_lineedit"));
23 q->connect(lineEdit, &QLineEdit::textChanged, q, [q](const QString& text) {
24 // Clear the shortcut if the user clicked on the clear icon
25 if (text.isEmpty())
26 q->clear();
27 });
28
29 keyNum = 0;
30 prevKey = -1;
31 releaseTimer = 0;
33
35 layout->setContentsMargins(0, 0, 0, 0);
37
39
42 resetState();
43
45 q->setFocusPolicy(Qt::StrongFocus);
46 q->setAttribute(Qt::WA_MacShowFocusRect, true);
47 q->setAttribute(Qt::WA_InputMethodEnabled, false);
48}
49
51{
53 int result = 0;
59 result |= Qt::ALT;
60 return result;
61}
62
64{
66
67 if (releaseTimer) {
68 q->killTimer(releaseTimer);
69 releaseTimer = 0;
70 }
71 prevKey = -1;
73 lineEdit->setPlaceholderText(QKeySequenceEdit::tr("Press shortcut"));
74}
75
77{
79
80 resetState();
81 emit q->keySequenceChanged(keySequence);
82 emit q->editingFinished();
83}
84
105{
106}
107
113{
115}
116
121 QWidget(dd, parent, f)
122{
123 Q_D(QKeySequenceEdit);
124 d->init();
125}
126
131{
132}
133
145{
146 Q_D(const QKeySequenceEdit);
147
148 return d->keySequence;
149}
150
163{
164 Q_D(QKeySequenceEdit);
165
166 d->lineEdit->setClearButtonEnabled(enable);
167}
168
170{
171 Q_D(const QKeySequenceEdit);
172
173 return d->lineEdit->isClearButtonEnabled();
174}
175
186{
187 Q_D(const QKeySequenceEdit);
188 return d->maximumSequenceLength;
189}
190
192{
193 Q_D(QKeySequenceEdit);
194
195 if (count < 1 || count > QKeySequencePrivate::MaxKeyCount) {
196 qWarning("QKeySequenceEdit: maximumSequenceLength %lld is out of range (1..%d)",
198 return;
199 }
200 d->maximumSequenceLength = int(count);
201 if (d->keyNum > count) {
202 for (qsizetype i = d->keyNum; i < count; ++i)
204 d->keyNum = count;
205 d->rebuildKeySequence();
206 }
207}
208
221{
222 Q_D(QKeySequenceEdit);
223
224 d->finishingKeyCombinations = finishingKeyCombinations;
225}
226
228{
229 Q_D(const QKeySequenceEdit);
230
231 return d->finishingKeyCombinations;
232}
233
235{
236 Q_D(QKeySequenceEdit);
237
238 d->resetState();
239
240 if (d->keySequence == keySequence)
241 return;
242
243 const auto desiredCount = keySequence.count();
244 if (desiredCount > d->maximumSequenceLength) {
245 qWarning("QKeySequenceEdit: setting a key sequence of length %d "
246 "when maximumSequenceLength is %d, truncating.",
247 desiredCount, d->maximumSequenceLength);
248 }
249
250 d->keyNum = std::min(desiredCount, d->maximumSequenceLength);
251 for (int i = 0; i < d->keyNum; ++i)
252 d->key[i] = keySequence[i];
253 for (int i = d->keyNum; i < QKeySequencePrivate::MaxKeyCount; ++i)
255
256 d->rebuildKeySequence();
257
258 d->lineEdit->setText(d->keySequence.toString(QKeySequence::NativeText));
259
260 emit keySequenceChanged(d->keySequence);
261}
262
276{
278}
279
284{
285 Q_D(const QKeySequenceEdit);
286
287 switch (e->type()) {
288 case QEvent::Shortcut:
289 return true;
291 e->accept();
292 return true;
293 case QEvent::KeyPress: {
294 QKeyEvent *ke = static_cast<QKeyEvent *>(e);
295 if (!d->finishingKeyCombinations.contains(ke->keyCombination())) {
296 keyPressEvent(ke);
297 return true;
298 }
299 }
300 break;
301 default:
302 break;
303 }
304
305 return QWidget::event(e);
306}
307
312{
313 Q_D(QKeySequenceEdit);
314
315 if (d->finishingKeyCombinations.contains(e->keyCombination())) {
316 d->finishEditing();
317 return;
318 }
319
320 int nextKey = e->key();
321
322 if (d->prevKey == -1) {
323 clear();
324 d->prevKey = nextKey;
325 }
326
327 d->lineEdit->setPlaceholderText(QString());
328 if (nextKey == Qt::Key_Control
329 || nextKey == Qt::Key_Shift
330 || nextKey == Qt::Key_Meta
331 || nextKey == Qt::Key_Alt
332 || nextKey == Qt::Key_unknown) {
333 return;
334 }
335
336 QString selectedText = d->lineEdit->selectedText();
337 if (!selectedText.isEmpty() && selectedText == d->lineEdit->text()) {
338 clear();
339 if (nextKey == Qt::Key_Backspace)
340 return;
341 }
342
343 if (d->keyNum >= d->maximumSequenceLength)
344 return;
345
346 if (e->modifiers() & Qt::ShiftModifier) {
347 QList<int> possibleKeys = QKeyMapper::possibleKeys(e);
348 int pkTotal = possibleKeys.size();
349 if (!pkTotal)
350 return;
351 bool found = false;
352 for (int i = 0; i < possibleKeys.size(); ++i) {
353 if (possibleKeys.at(i) - nextKey == int(e->modifiers())
354 || (possibleKeys.at(i) == nextKey && e->modifiers() == Qt::ShiftModifier)) {
355 nextKey = possibleKeys.at(i);
356 found = true;
357 break;
358 }
359 }
360 // Use as fallback
361 if (!found)
362 nextKey = possibleKeys.first();
363 } else {
364 nextKey |= d->translateModifiers(e->modifiers(), e->text());
365 }
366
367
368 d->key[d->keyNum] = QKeyCombination::fromCombined(nextKey);
369 d->keyNum++;
370
371 d->rebuildKeySequence();
372 QString text = d->keySequence.toString(QKeySequence::NativeText);
373 if (d->keyNum < d->maximumSequenceLength) {
374 //: This text is an "unfinished" shortcut, expands like "Ctrl+A, ..."
375 text = tr("%1, ...").arg(text);
376 }
377 d->lineEdit->setText(text);
378 e->accept();
379}
380
385{
386 Q_D(QKeySequenceEdit);
387
388 if (d->prevKey == e->key()) {
389 if (d->keyNum < d->maximumSequenceLength)
390 d->releaseTimer = startTimer(1000);
391 else
392 d->finishEditing();
393 }
394 e->accept();
395}
396
401{
402 Q_D(QKeySequenceEdit);
403 if (e->timerId() == d->releaseTimer) {
404 d->finishEditing();
405 return;
406 }
407
409}
410
415{
416 Q_D(QKeySequenceEdit);
417 if (e->reason() != Qt::PopupFocusReason)
418 d->finishEditing();
420}
421
423
424#include "moc_qkeysequenceedit.cpp"
\inmodule QtCore
Definition qcoreevent.h:45
@ ShortcutOverride
Definition qcoreevent.h:158
@ KeyPress
Definition qcoreevent.h:64
The QFocusEvent class contains event parameters for widget focus events.
Definition qevent.h:469
static constexpr QKeyCombination fromCombined(int combined)
The QKeyEvent class describes a key event.
Definition qevent.h:423
QKeyCombination keyCombination() const
Returns a QKeyCombination object containing both the key() and the modifiers() carried by this event.
Definition qevent.h:438
static QList< int > possibleKeys(QKeyEvent *e)
QList< QKeyCombination > finishingKeyCombinations
int translateModifiers(Qt::KeyboardModifiers state, const QString &text)
The QKeySequenceEdit widget allows to input a QKeySequence.
void keyPressEvent(QKeyEvent *) override
\reimp
void timerEvent(QTimerEvent *) override
\reimp
bool isClearButtonEnabled() const
bool event(QEvent *) override
\reimp
void setMaximumSequenceLength(qsizetype count)
QKeySequenceEdit(QWidget *parent=nullptr)
Constructs a QKeySequenceEdit widget with the given parent.
void focusOutEvent(QFocusEvent *) override
\reimp
void keyReleaseEvent(QKeyEvent *) override
\reimp
void setClearButtonEnabled(bool enable)
void keySequenceChanged(const QKeySequence &keySequence)
void setKeySequence(const QKeySequence &keySequence)
qsizetype maximumSequenceLength
The maximum sequence length.
void clear()
Clears the current key sequence.
QKeySequence keySequence
This property contains the currently chosen key sequence.
void setFinishingKeyCombinations(const QList< QKeyCombination > &finishingKeyCombinations)
QList< QKeyCombination > finishingKeyCombinations
The list of key combinations that finish editing the key sequences.
~QKeySequenceEdit()
Destroys the QKeySequenceEdit object.
The QKeySequence class encapsulates a key sequence as used by shortcuts.
int count() const
Returns the number of keys in the key sequence.
QString toString(SequenceFormat format=PortableText) const
void addWidget(QWidget *w)
Adds widget w to this layout in a manner specific to the layout.
Definition qlayout.cpp:186
void setContentsMargins(int left, int top, int right, int bottom)
Definition qlayout.cpp:288
The QLineEdit widget is a one-line text editor.
Definition qlineedit.h:28
void setClearButtonEnabled(bool enable)
void setPlaceholderText(const QString &)
void textChanged(const QString &)
This signal is emitted whenever the text changes.
void setText(const QString &)
Definition qlist.h:74
qsizetype size() const noexcept
Definition qlist.h:386
T & first()
Definition qlist.h:628
const_reference at(qsizetype i) const noexcept
Definition qlist.h:429
int startTimer(int interval, Qt::TimerType timerType=Qt::CoarseTimer)
This is an overloaded function that will start a timer of type timerType and a timeout of interval mi...
Definition qobject.cpp:1792
void installEventFilter(QObject *filterObj)
Installs an event filter filterObj on this object.
Definition qobject.cpp:2269
virtual void timerEvent(QTimerEvent *event)
This event handler can be reimplemented in a subclass to receive timer events for the object.
Definition qobject.cpp:1433
Q_WEAK_OVERLOAD void setObjectName(const QString &name)
Sets the object's name to name.
Definition qobject.h:114
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:1083
\inmodule QtCore
Definition qcoreevent.h:359
The QVBoxLayout class lines up widgets vertically.
Definition qboxlayout.h:91
QLayout * layout
Definition qwidget_p.h:643
The QWidget class is the base class of all user interface objects.
Definition qwidget.h:99
void setFocusProxy(QWidget *)
Sets the widget's focus proxy to widget w.
Definition qwidget.cpp:6372
bool event(QEvent *event) override
This is the main event handler; it handles event event.
Definition qwidget.cpp:8912
virtual void focusOutEvent(QFocusEvent *event)
This event handler can be reimplemented in a subclass to receive keyboard focus events (focus lost) f...
Definition qwidget.cpp:9737
QString text
double e
else opt state
[0]
Combined button and popup list for selecting options.
@ CTRL
@ META
@ ALT
@ WA_MacShowFocusRect
Definition qnamespace.h:358
@ WA_InputMethodEnabled
Definition qnamespace.h:294
@ StrongFocus
Definition qnamespace.h:109
@ Key_Tab
Definition qnamespace.h:659
@ Key_Shift
Definition qnamespace.h:678
@ Key_Backspace
Definition qnamespace.h:661
@ Key_Backtab
Definition qnamespace.h:660
@ Key_Control
Definition qnamespace.h:679
@ Key_Alt
Definition qnamespace.h:681
@ Key_Meta
Definition qnamespace.h:680
@ Key_unknown
@ ShiftModifier
@ ControlModifier
@ MetaModifier
@ AltModifier
@ PopupFocusReason
#define qWarning
Definition qlogging.h:162
GLuint64 key
GLenum GLenum GLsizei count
GLfloat GLfloat f
GLboolean enable
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLuint64EXT * result
[6]
#define QStringLiteral(str)
#define tr(X)
#define emit
#define Q_UNUSED(x)
ptrdiff_t qsizetype
Definition qtypes.h:70
qint64 qlonglong
Definition qtypes.h:58
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent