QtBase  v6.3.1
tst_qkeyevent.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2017 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the test suite of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21 ** included in the packaging of this file. Please review the following
22 ** information to ensure the GNU General Public License requirements will
23 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24 **
25 ** $QT_END_LICENSE$
26 **
27 ****************************************************************************/
28 
29 #include <QTest>
30 
31 #include <QtCore/qcoreapplication.h>
32 #include <QtGui/qevent.h>
33 #include <QtGui/qwindow.h>
34 
35 class Window : public QWindow
36 {
37 public:
38  ~Window() { reset(); }
39 
40  void keyPressEvent(QKeyEvent *event) override { recordEvent(event); }
41  void keyReleaseEvent(QKeyEvent *event) override { recordEvent(event); }
42 
43  void reset() {
45  keyEvents.clear();
46  }
47 private:
48  void recordEvent(QKeyEvent *event) {
49  keyEvents.append(new QKeyEvent(event->type(), event->key(), event->modifiers(), event->nativeScanCode(),
50  event->nativeVirtualKey(), event->nativeModifiers(), event->text(),
51  event->isAutoRepeat(), event->count()));
52  }
53 
54 public:
56 };
57 
58 class tst_QKeyEvent : public QObject
59 {
60  Q_OBJECT
61 public:
62  tst_QKeyEvent();
64 
65 private slots:
66  void basicEventDelivery();
67 #if QT_CONFIG(shortcut)
68  void modifiers_data();
69  void modifiers();
70 #endif
71 };
72 
74 {
75 }
76 
78 {
79 }
80 
81 void tst_QKeyEvent::basicEventDelivery()
82 {
83  Window window;
84  window.showNormal();
86 
87  const Qt::Key key = Qt::Key_A;
88  const Qt::KeyboardModifier modifiers = Qt::NoModifier;
89 
90  QTest::keyClick(&window, key, modifiers);
91 
92  QCOMPARE(window.keyEvents.size(), 2);
93  QCOMPARE(window.keyEvents.first()->type(), QKeyEvent::KeyPress);
94  QCOMPARE(window.keyEvents.last()->type(), QKeyEvent::KeyRelease);
95  foreach (const QKeyEvent *event, window.keyEvents) {
96  QCOMPARE(Qt::Key(event->key()), key);
97  QCOMPARE(Qt::KeyboardModifiers(event->modifiers()), modifiers);
98  }
99 }
100 
101 static bool orderByModifier(const QList<int> &v1, const QList<int> &v2)
102 {
103  if (v1.size() != v2.size())
104  return v1.size() < v2.size();
105 
106  for (int i = 0; i < qMin(v1.size(), v2.size()); ++i) {
107  if (v1.at(i) == v2.at(i))
108  continue;
109 
110  return v1.at(i) < v2.at(i);
111  }
112 
113  return true;
114 }
115 
116 static QByteArray modifiersTestRowName(const QString &keySequence)
117 {
120  for (int i = 0, size = keySequence.size(); i < size; ++i) {
121  const QChar &c = keySequence.at(i);
122  const ushort uc = c.unicode();
123  if (uc > 32 && uc < 128)
124  str << '"' << c << '"';
125  else
126  str << "U+" << Qt::hex << uc << Qt::dec;
127  if (i < size - 1)
128  str << ',';
129  }
130  return result;
131 }
132 
133 #if QT_CONFIG(shortcut)
134 
135 void tst_QKeyEvent::modifiers_data()
136 {
137  struct Modifier
138  {
139  Qt::Key key;
140  Qt::KeyboardModifier modifier;
141  };
142  static const Modifier modifiers[] = {
147  };
148 
149  QList<QList<int>> modifierCombinations;
150 
151  // Generate powerset (minus the empty set) of possible modifier combinations
152  static const int kNumModifiers = sizeof(modifiers) / sizeof(Modifier);
153  for (quint64 bitmask = 1; bitmask < (1 << kNumModifiers) ; ++bitmask) {
154  QList<int> modifierCombination;
155  for (quint64 modifier = 0; modifier < kNumModifiers; ++modifier) {
156  if (bitmask & (quint64(1) << modifier))
157  modifierCombination.append(modifier);
158  }
159  modifierCombinations.append(modifierCombination);
160  }
161 
162  std::sort(modifierCombinations.begin(), modifierCombinations.end(), orderByModifier);
163 
164  QTest::addColumn<Qt::KeyboardModifiers>("modifiers");
165  foreach (const QList<int> combination, modifierCombinations) {
166  int keys[4] = {};
167  Qt::KeyboardModifiers mods;
168  for (int i = 0; i < combination.size(); ++i) {
169  Modifier modifier = modifiers[combination.at(i)];
170  keys[i] = modifier.key;
171  mods |= modifier.modifier;
172  }
173  QKeySequence keySequence(keys[0], keys[1], keys[2], keys[3]);
174  QTest::newRow(modifiersTestRowName(keySequence.toString(QKeySequence::NativeText)).constData())
175  << mods;
176  }
177 }
178 
179 void tst_QKeyEvent::modifiers()
180 {
181  Window window;
182  window.showNormal();
184 
185  const Qt::Key key = Qt::Key_A;
186  QFETCH(Qt::KeyboardModifiers, modifiers);
187 
188  QTest::keyClick(&window, key, modifiers);
189 
190  int numKeys = qPopulationCount(quint64(modifiers)) + 1;
191  QCOMPARE(window.keyEvents.size(), numKeys * 2);
192 
193  for (int i = 0; i < window.keyEvents.size(); ++i) {
194  const QKeyEvent *event = window.keyEvents.at(i);
195  QCOMPARE(event->type(), i < numKeys ? QKeyEvent::KeyPress : QKeyEvent::KeyRelease);
196  if (i == numKeys - 1 || i == numKeys) {
197  QCOMPARE(Qt::Key(event->key()), key);
198  QCOMPARE(event->modifiers(), modifiers);
199  } else {
200  QVERIFY(Qt::Key(event->key()) != key);
201  }
202  }
203 }
204 
205 #endif // QT_CONFIG(shortcut)
206 
208 #include "tst_qkeyevent.moc"
small capitals from c petite p scientific i
[1]
Definition: afcover.h:80
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:85
const char * constData() const noexcept
Definition: qbytearray.h:144
The QChar class provides a 16-bit Unicode character.
Definition: qchar.h:84
constexpr char16_t unicode() const noexcept
Definition: qchar.h:489
@ KeyRelease
Definition: qcoreevent.h:78
@ KeyPress
Definition: qcoreevent.h:77
The QKeyEvent class describes a key event.
Definition: qevent.h:471
The QKeySequence class encapsulates a key sequence as used by shortcuts.
Definition: qkeysequence.h:71
qsizetype size() const noexcept
Definition: qlist.h:414
iterator end()
Definition: qlist.h:624
const_reference at(qsizetype i) const noexcept
Definition: qlist.h:457
iterator begin()
Definition: qlist.h:623
void append(parameter_type t)
Definition: qlist.h:469
void clear()
Definition: qlist.h:445
The QObject class is the base class of all Qt objects.
Definition: qobject.h:125
The QString class provides a Unicode character string.
Definition: qstring.h:388
qsizetype size() const
Definition: qstring.h:413
const QChar at(qsizetype i) const
Definition: qstring.h:1212
The QTextStream class provides a convenient interface for reading and writing text.
Definition: qtextstream.h:62
The QWindow class represents a window in the underlying windowing system.
Definition: qwindow.h:99
[Window class definition]
Definition: window.h:64
void keyPressEvent(QKeyEvent *event) override
QList< QKeyEvent * > keyEvents
void keyReleaseEvent(QKeyEvent *event) override
QString str
[2]
qDeleteAll(list.begin(), list.end())
QCOMPARE(spy.count(), 1)
Q_TESTLIB_EXPORT QTestData & newRow(const char *dataTag)
Definition: qtestcase.cpp:2658
Q_GUI_EXPORT bool qWaitForWindowExposed(QWindow *window, int timeout=5000)
Modifier
Definition: qnamespace.h:1093
QTextStream & hex(QTextStream &stream)
@ Key_Shift
Definition: qnamespace.h:704
@ Key_A
Definition: qnamespace.h:572
@ Key_Control
Definition: qnamespace.h:705
@ Key_Alt
Definition: qnamespace.h:707
@ Key_Meta
Definition: qnamespace.h:706
QTextStream & dec(QTextStream &stream)
KeyboardModifier
Definition: qnamespace.h:1073
@ ShiftModifier
Definition: qnamespace.h:1075
@ ControlModifier
Definition: qnamespace.h:1076
@ MetaModifier
Definition: qnamespace.h:1078
@ NoModifier
Definition: qnamespace.h:1074
@ AltModifier
Definition: qnamespace.h:1077
Q_DECL_CONST_FUNCTION QT_POPCOUNT_CONSTEXPR uint qPopulationCount(quint32 v) noexcept
Definition: qalgorithms.h:244
unsigned long long quint64
Definition: qglobal.h:299
unsigned short ushort
Definition: qglobal.h:333
GLint GLfloat GLfloat GLfloat v2
GLuint64 key
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLint GLfloat GLfloat v1
struct _cl_event * event
Definition: qopenglext.h:2998
const GLubyte * c
Definition: qopenglext.h:12701
GLuint64EXT * result
[6]
Definition: qopenglext.h:10932
#define QTEST_MAIN(TestObject)
Definition: qtest.h:664
#define QFETCH(Type, name)
Definition: qtestcase.h:230
#define QVERIFY(statement)
Definition: qtestcase.h:64
#define Q_OBJECT
Definition: qtmetamacros.h:158
#define slots
Definition: qtmetamacros.h:76
QStringList keys
aWidget window() -> setWindowTitle("New Window Title")
[2]