summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorIvan Komissarov <ABBAPOH@gmail.com>2012-07-07 01:19:46 +0400
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-24 10:55:17 +0200
commitf3a723f2ec3a4fc59df21164f9ec2eaf1e50abc8 (patch)
tree2ae7def39715607b4d0c2b4469be324bb15b8dad /src
parent75abfa89821e0c64022d90bba227b947947169d4 (diff)
Add QKeySequenceEdit
Change-Id: I497309d3e6cbf38b298afb5ff3cb1ed6a0e82000 Reviewed-by: Marc Mutz <marc.mutz@kdab.com>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/global/qfeatures.h8
-rw-r--r--src/tools/uic/qclass_lib_map.h1
-rw-r--r--src/widgets/widgets/qkeysequenceedit.cpp333
-rw-r--r--src/widgets/widgets/qkeysequenceedit.h90
-rw-r--r--src/widgets/widgets/qkeysequenceedit_p.h81
-rw-r--r--src/widgets/widgets/widgets.pri3
6 files changed, 516 insertions, 0 deletions
diff --git a/src/corelib/global/qfeatures.h b/src/corelib/global/qfeatures.h
index 2cadea59c1..ba84dd109e 100644
--- a/src/corelib/global/qfeatures.h
+++ b/src/corelib/global/qfeatures.h
@@ -115,6 +115,9 @@
// Image Text
//#define QT_NO_IMAGE_TEXT
+// QKeySequenceEdit
+//#define QT_NO_KEYSEQUENCEEDIT
+
// QLCDNumber
//#define QT_NO_LCDNUMBER
@@ -306,6 +309,11 @@
#define QT_NO_IMAGEFORMATPLUGIN
#endif
+// QKeySequenceEdit
+#if !defined(QT_NO_KEYSEQUENCEEDIT) && (defined(QT_NO_SHORTCUT))
+#define QT_NO_KEYSEQUENCEEDIT
+#endif
+
// QLocalServer
#if !defined(QT_NO_LOCALSERVER) && (defined(QT_NO_TEMPORARYFILE))
#define QT_NO_LOCALSERVER
diff --git a/src/tools/uic/qclass_lib_map.h b/src/tools/uic/qclass_lib_map.h
index cedefb801a..48793e7f09 100644
--- a/src/tools/uic/qclass_lib_map.h
+++ b/src/tools/uic/qclass_lib_map.h
@@ -931,6 +931,7 @@ QT_CLASS_LIB(QFocusFrame, QtWidgets, qfocusframe.h)
QT_CLASS_LIB(QFontComboBox, QtWidgets, qfontcombobox.h)
QT_CLASS_LIB(QFrame, QtWidgets, qframe.h)
QT_CLASS_LIB(QGroupBox, QtWidgets, qgroupbox.h)
+QT_CLASS_LIB(QKeySequenceEdit, QtWidgets, qkeysequenceedit.h)
QT_CLASS_LIB(QLabel, QtWidgets, qlabel.h)
QT_CLASS_LIB(QLCDNumber, QtWidgets, qlcdnumber.h)
QT_CLASS_LIB(QLineEdit, QtWidgets, qlineedit.h)
diff --git a/src/widgets/widgets/qkeysequenceedit.cpp b/src/widgets/widgets/qkeysequenceedit.cpp
new file mode 100644
index 0000000000..a71c0ada70
--- /dev/null
+++ b/src/widgets/widgets/qkeysequenceedit.cpp
@@ -0,0 +1,333 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2013 Ivan Komissarov.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWidgets module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qkeysequenceedit.h"
+#include "qkeysequenceedit_p.h"
+
+#include "qboxlayout.h"
+#include "qlineedit.h"
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_KEYSEQUENCEEDIT
+
+void QKeySequenceEditPrivate::init()
+{
+ Q_Q(QKeySequenceEdit);
+
+ lineEdit = new QLineEdit(q);
+ keyNum = 0;
+ prevKey = -1;
+ releaseTimer = 0;
+
+ layout = new QVBoxLayout(q);
+ layout->setContentsMargins(0, 0, 0, 0);
+ layout->addWidget(lineEdit);
+
+ key[0] = key[1] = key[2] = key[3] = 0;
+
+ lineEdit->setFocusProxy(q);
+ lineEdit->installEventFilter(q);
+ resetState();
+
+ q->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+ q->setFocusPolicy(Qt::StrongFocus);
+ q->setAttribute(Qt::WA_MacShowFocusRect, true);
+ q->setAttribute(Qt::WA_InputMethodEnabled, false);
+
+ // TODO: add clear button
+}
+
+int QKeySequenceEditPrivate::translateModifiers(Qt::KeyboardModifiers state, const QString &text)
+{
+ int result = 0;
+ // The shift modifier only counts when it is not used to type a symbol
+ // that is only reachable using the shift key anyway
+ if ((state & Qt::ShiftModifier) && (text.isEmpty() ||
+ !text.at(0).isPrint() ||
+ text.at(0).isLetterOrNumber() ||
+ text.at(0).isSpace()))
+ result |= Qt::SHIFT;
+
+ if (state & Qt::ControlModifier)
+ result |= Qt::CTRL;
+ if (state & Qt::MetaModifier)
+ result |= Qt::META;
+ if (state & Qt::AltModifier)
+ result |= Qt::ALT;
+ return result;
+}
+
+void QKeySequenceEditPrivate::resetState()
+{
+ Q_Q(QKeySequenceEdit);
+
+ if (releaseTimer) {
+ q->killTimer(releaseTimer);
+ releaseTimer = 0;
+ }
+ prevKey = -1;
+ lineEdit->setText(keySequence.toString(QKeySequence::NativeText));
+ lineEdit->setPlaceholderText(QKeySequenceEdit::tr("Press shortcut"));
+}
+
+void QKeySequenceEditPrivate::finishEditing()
+{
+ Q_Q(QKeySequenceEdit);
+
+ resetState();
+ emit q->keySequenceChanged(keySequence);
+ emit q->editingFinished();
+}
+
+/*!
+ \class QKeySequenceEdit
+ \brief The QKeySequenceEdit widget allows to input a QKeySequence.
+
+ \inmodule QtWidgets
+
+ \since 5.2
+
+ This widget lets the user choose a QKeySequence, which is usually used as
+ a shortcut. The recording is initiated when the widget receives the focus
+ and ends one second after the user releases the last key.
+
+ \sa QKeySequenceEdit::keySequence
+*/
+
+/*!
+ Constructs a QKeySequenceEdit widget with the given \a parent.
+*/
+QKeySequenceEdit::QKeySequenceEdit(QWidget *parent) :
+ QWidget(*new QKeySequenceEditPrivate, parent, 0)
+{
+ Q_D(QKeySequenceEdit);
+ d->init();
+}
+
+/*!
+ Constructs a QKeySequenceEdit widget with the given \a keySequence and \a parent.
+*/
+QKeySequenceEdit::QKeySequenceEdit(const QKeySequence &keySequence, QWidget *parent) :
+ QWidget(*new QKeySequenceEditPrivate, parent, 0)
+{
+ Q_D(QKeySequenceEdit);
+ d->init();
+ setKeySequence(keySequence);
+}
+
+/*!
+ \internal
+*/
+QKeySequenceEdit::QKeySequenceEdit(QKeySequenceEditPrivate &dd, QWidget *parent, Qt::WindowFlags f) :
+ QWidget(dd, parent, f)
+{
+ Q_D(QKeySequenceEdit);
+ d->init();
+}
+
+/*!
+ Destroys the QKeySequenceEdit object.
+*/
+QKeySequenceEdit::~QKeySequenceEdit()
+{
+}
+
+/*!
+ \property QKeySequenceEdit::keySequence
+
+ \brief This property contains the currently chosen key sequence.
+
+ The shortcut can be changed by the user or via setter function.
+*/
+QKeySequence QKeySequenceEdit::keySequence() const
+{
+ Q_D(const QKeySequenceEdit);
+
+ return d->keySequence;
+}
+
+void QKeySequenceEdit::setKeySequence(const QKeySequence &keySequence)
+{
+ Q_D(QKeySequenceEdit);
+
+ d->resetState();
+
+ if (d->keySequence == keySequence)
+ return;
+
+ d->keySequence = keySequence;
+
+ d->key[0] = d->key[1] = d->key[2] = d->key[3] = 0;
+ d->keyNum = keySequence.count();
+ for (int i = 0; i < d->keyNum; ++i)
+ d->key[i] = keySequence[i];
+
+ d->lineEdit->setText(keySequence.toString(QKeySequence::NativeText));
+
+ emit keySequenceChanged(keySequence);
+}
+
+/*!
+ \fn void QKeySequenceEdit::editingFinished()
+
+ This signal is emitted when the user finishes entering the shortcut.
+
+ \note there is a one second delay before releasing the last key and
+ emitting this signal.
+*/
+
+/*!
+ \brief Clears the current key sequence.
+*/
+void QKeySequenceEdit::clear()
+{
+ Q_D(QKeySequenceEdit);
+
+ d->resetState();
+
+ d->lineEdit->clear();
+ d->keySequence = QKeySequence();
+ d->keyNum = d->key[0] = d->key[1] = d->key[2] = d->key[3] = 0;
+ d->prevKey = -1;
+ emit keySequenceChanged(d->keySequence);
+}
+
+/*!
+ \reimp
+*/
+bool QKeySequenceEdit::event(QEvent *e)
+{
+ switch (e->type()) {
+ case QEvent::Shortcut:
+ return true;
+ case QEvent::ShortcutOverride:
+ e->accept();
+ return true;
+ default :
+ break;
+ }
+
+ return QWidget::event(e);
+}
+
+/*!
+ \reimp
+*/
+void QKeySequenceEdit::keyPressEvent(QKeyEvent *e)
+{
+ Q_D(QKeySequenceEdit);
+
+ int nextKey = e->key();
+
+ if (d->prevKey == -1) {
+ clear();
+ d->prevKey = nextKey;
+ }
+
+ d->lineEdit->setPlaceholderText(QString());
+ if (nextKey == Qt::Key_Control
+ || nextKey == Qt::Key_Shift
+ || nextKey == Qt::Key_Meta
+ || nextKey == Qt::Key_Alt) {
+ return;
+ }
+
+ QString selectedText = d->lineEdit->selectedText();
+ if (!selectedText.isEmpty() && selectedText == d->lineEdit->text()) {
+ clear();
+ if (nextKey == Qt::Key_Backspace)
+ return;
+ }
+
+ if (d->keyNum >= QKeySequenceEditPrivate::MaxKeyCount)
+ return;
+
+ nextKey |= d->translateModifiers(e->modifiers(), e->text());
+
+ d->key[d->keyNum] = nextKey;
+ d->keyNum++;
+
+ QKeySequence key(d->key[0], d->key[1], d->key[2], d->key[3]);
+ d->keySequence = key;
+ QString text = key.toString(QKeySequence::NativeText);
+ if (d->keyNum < QKeySequenceEditPrivate::MaxKeyCount) {
+ //: This text is an "unfinished" shortcut, expands like "Ctrl+A, ..."
+ text = tr("%1, ...").arg(text);
+ }
+ d->lineEdit->setText(text);
+ e->accept();
+}
+
+/*!
+ \reimp
+*/
+void QKeySequenceEdit::keyReleaseEvent(QKeyEvent *e)
+{
+ Q_D(QKeySequenceEdit);
+
+ if (d->prevKey == e->key()) {
+ if (d->keyNum < QKeySequenceEditPrivate::MaxKeyCount)
+ d->releaseTimer = startTimer(1000);
+ else
+ d->finishEditing();
+ }
+ e->accept();
+}
+
+/*!
+ \reimp
+*/
+void QKeySequenceEdit::timerEvent(QTimerEvent *e)
+{
+ Q_D(QKeySequenceEdit);
+ if (e->timerId() == d->releaseTimer) {
+ d->finishEditing();
+ return;
+ }
+
+ QWidget::timerEvent(e);
+}
+
+#endif // QT_NO_KEYSEQUENCEEDIT
+
+QT_END_NAMESPACE
diff --git a/src/widgets/widgets/qkeysequenceedit.h b/src/widgets/widgets/qkeysequenceedit.h
new file mode 100644
index 0000000000..9312e98d0e
--- /dev/null
+++ b/src/widgets/widgets/qkeysequenceedit.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2013 Ivan Komissarov.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWidgets module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QKEYSEQUENCEEDIT_H
+#define QKEYSEQUENCEEDIT_H
+
+#include <QtWidgets/qwidget.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_KEYSEQUENCEEDIT
+
+class QKeySequenceEditPrivate;
+class Q_WIDGETS_EXPORT QKeySequenceEdit : public QWidget
+{
+ Q_OBJECT
+ Q_PROPERTY(QKeySequence keySequence READ keySequence WRITE setKeySequence RESET clear NOTIFY keySequenceChanged USER true)
+
+public:
+ explicit QKeySequenceEdit(QWidget *parent = 0);
+ explicit QKeySequenceEdit(const QKeySequence &keySequence, QWidget *parent = 0);
+ ~QKeySequenceEdit();
+
+ QKeySequence keySequence() const;
+ void setKeySequence(const QKeySequence &keySequence);
+
+public Q_SLOTS:
+ void clear();
+
+Q_SIGNALS:
+ void editingFinished();
+ void keySequenceChanged(const QKeySequence &keySequence);
+
+protected:
+ QKeySequenceEdit(QKeySequenceEditPrivate &d, QWidget *parent, Qt::WindowFlags f);
+
+ bool event(QEvent *) Q_DECL_OVERRIDE;
+ void keyPressEvent(QKeyEvent *) Q_DECL_OVERRIDE;
+ void keyReleaseEvent(QKeyEvent *) Q_DECL_OVERRIDE;
+ void timerEvent(QTimerEvent *) Q_DECL_OVERRIDE;
+
+private:
+ Q_DISABLE_COPY(QKeySequenceEdit)
+ Q_DECLARE_PRIVATE(QKeySequenceEdit)
+};
+
+#endif // QT_NO_KEYSEQUENCEEDIT
+
+QT_END_NAMESPACE
+
+#endif // QKEYSEQUENCEEDIT_H
diff --git a/src/widgets/widgets/qkeysequenceedit_p.h b/src/widgets/widgets/qkeysequenceedit_p.h
new file mode 100644
index 0000000000..2de86b3a05
--- /dev/null
+++ b/src/widgets/widgets/qkeysequenceedit_p.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2013 Ivan Komissarov.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWidgets module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QKEYSEQUENCEEDIT_P_H
+#define QKEYSEQUENCEEDIT_P_H
+
+#include "qkeysequenceedit.h"
+
+#include <private/qwidget_p.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_KEYSEQUENCEEDIT
+
+class QLineEdit;
+class QVBoxLayout;
+
+class QKeySequenceEditPrivate : public QWidgetPrivate
+{
+ Q_DECLARE_PUBLIC(QKeySequenceEdit)
+public:
+ enum { MaxKeyCount = 4 };
+
+ void init();
+ int translateModifiers(Qt::KeyboardModifiers state, const QString &text);
+ void resetState();
+ void finishEditing();
+
+ QLineEdit *lineEdit;
+ QVBoxLayout *layout;
+ QKeySequence keySequence;
+ int keyNum;
+ int key[MaxKeyCount];
+ int prevKey;
+ int releaseTimer;
+};
+
+#endif // QT_NO_KEYSEQUENCEEDIT
+
+QT_END_NAMESPACE
+
+#endif // QKEYSEQUENCEEDIT_P_H
diff --git a/src/widgets/widgets/widgets.pri b/src/widgets/widgets/widgets.pri
index a35e6eb3a1..efe1dd3616 100644
--- a/src/widgets/widgets/widgets.pri
+++ b/src/widgets/widgets/widgets.pri
@@ -25,6 +25,8 @@ HEADERS += \
widgets/qframe.h \
widgets/qframe_p.h \
widgets/qgroupbox.h \
+ widgets/qkeysequenceedit.h \
+ widgets/qkeysequenceedit_p.h \
widgets/qlabel.h \
widgets/qlabel_p.h \
widgets/qlcdnumber.h \
@@ -99,6 +101,7 @@ SOURCES += \
widgets/qfontcombobox.cpp \
widgets/qframe.cpp \
widgets/qgroupbox.cpp \
+ widgets/qkeysequenceedit.cpp \
widgets/qlabel.cpp \
widgets/qlcdnumber.cpp \
widgets/qlineedit_p.cpp \