Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
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
107
116
121 QWidget(dd, parent, f)
122{
123 Q_D(QKeySequenceEdit);
124 d->init();
125}
126
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
220void QKeySequenceEdit::setFinishingKeyCombinations(const QList<QKeyCombination> &finishingKeyCombinations)
221{
222 Q_D(QKeySequenceEdit);
223
224 d->finishingKeyCombinations = finishingKeyCombinations;
225}
226
227QList<QKeyCombination> QKeySequenceEdit::finishingKeyCombinations() const
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
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 const QList<QKeyCombination> 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 const int key = possibleKeys.at(i).toCombined();
354 if (key - nextKey == int(e->modifiers())
355 || (key == nextKey && e->modifiers() == Qt::ShiftModifier)) {
356 nextKey = key;
357 found = true;
358 break;
359 }
360 }
361 // Use as fallback
362 if (!found)
363 nextKey = possibleKeys.first().toCombined();
364 } else {
365 nextKey |= d->translateModifiers(e->modifiers(), e->text());
366 }
367
368
369 d->key[d->keyNum] = QKeyCombination::fromCombined(nextKey);
370 d->keyNum++;
371
372 d->rebuildKeySequence();
373 QString text = d->keySequence.toString(QKeySequence::NativeText);
374 if (d->keyNum < d->maximumSequenceLength) {
375 //: This text is an "unfinished" shortcut, expands like "Ctrl+A, ..."
376 text = tr("%1, ...").arg(text);
377 }
378 d->lineEdit->setText(text);
379 e->accept();
380}
381
386{
387 Q_D(QKeySequenceEdit);
388
389 if (d->prevKey == e->key()) {
390 if (d->keyNum < d->maximumSequenceLength)
391 d->releaseTimer = startTimer(1000);
392 else
393 d->finishEditing();
394 }
395 e->accept();
396}
397
402{
403 Q_D(QKeySequenceEdit);
404 if (e->timerId() == d->releaseTimer) {
405 d->finishEditing();
406 return;
407 }
408
410}
411
416{
417 Q_D(QKeySequenceEdit);
418 if (e->reason() != Qt::PopupFocusReason)
419 d->finishEditing();
421}
422
424
425#include "moc_qkeysequenceedit.cpp"
\inmodule QtCore
Definition qcoreevent.h:45
@ ShortcutOverride
Definition qcoreevent.h:158
@ KeyPress
Definition qcoreevent.h:64
Type type() const
Returns the event type.
Definition qcoreevent.h:304
void accept()
Sets the accept flag of the event object, the equivalent of calling setAccepted(true).
Definition qcoreevent.h:310
The QFocusEvent class contains event parameters for widget focus events.
Definition qevent.h:470
Qt::FocusReason reason() const
Returns the reason for this focus event.
Definition qevent.cpp:1569
static constexpr QKeyCombination fromCombined(int combined)
The QKeyEvent class describes a key event.
Definition qevent.h:424
Qt::KeyboardModifiers modifiers() const
Returns the keyboard modifier flags that existed immediately after the event occurred.
Definition qevent.cpp:1468
QString text() const
Returns the Unicode text that this key generated.
Definition qevent.h:443
int key() const
Returns the code of the key that was pressed or released.
Definition qevent.h:434
QKeyCombination keyCombination() const
Returns a QKeyCombination object containing both the key() and the modifiers() carried by this event.
Definition qevent.h:439
static QList< QKeyCombination > possibleKeys(const 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.
static constexpr int MaxKeyCount
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 clear()
Clears the contents of the line edit.
void setPlaceholderText(const QString &)
void textChanged(const QString &)
This signal is emitted whenever the text changes.
void setText(const QString &)
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:1817
void installEventFilter(QObject *filterObj)
Installs an event filter filterObj on this object.
Definition qobject.cpp:2339
virtual void timerEvent(QTimerEvent *event)
This event handler can be reimplemented in a subclass to receive timer events for the object.
Definition qobject.cpp:1470
Q_WEAK_OVERLOAD void setObjectName(const QString &name)
Sets the object's name to name.
Definition qobject.h:127
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
\inmodule QtCore
Definition qcoreevent.h:366
int timerId() const
Returns the unique timer identifier, which is the same identifier as returned from QObject::startTime...
Definition qcoreevent.h:370
The QVBoxLayout class lines up widgets vertically.
Definition qboxlayout.h:91
QLayout * layout
Definition qwidget_p.h:651
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:6368
bool event(QEvent *event) override
This is the main event handler; it handles event event.
Definition qwidget.cpp:8866
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:9691
QString text
else opt state
[0]
Combined button and popup list for selecting options.
@ CTRL
@ META
@ ALT
@ WA_MacShowFocusRect
Definition qnamespace.h:359
@ WA_InputMethodEnabled
Definition qnamespace.h:295
@ StrongFocus
Definition qnamespace.h:110
@ Key_Tab
Definition qnamespace.h:664
@ Key_Shift
Definition qnamespace.h:683
@ Key_Backspace
Definition qnamespace.h:666
@ Key_Backtab
Definition qnamespace.h:665
@ Key_Control
Definition qnamespace.h:684
@ Key_Alt
Definition qnamespace.h:686
@ Key_Meta
Definition qnamespace.h:685
@ Key_unknown
@ ShiftModifier
@ ControlModifier
@ MetaModifier
@ AltModifier
@ PopupFocusReason
#define qWarning
Definition qlogging.h:166
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:165
qint64 qlonglong
Definition qtypes.h:63