forked from qt-creator/qt-creator
Improve keyboard shortcut settings
- change the line edit to accept actual text input in a form similar to QKeySequence::fromString (with special "native" form on OS X) - add a button that allows entering a key sequence by pressing keys, including support for e.g. escape key, which was broken before because it closed the dialog - add a warning label, that allows filtering the list for all potentially conflicting shortcuts Task-number: QTCREATORBUG-6 Change-Id: I94fc63525f653127e87f6ef2bffe72d8dcaa867d Reviewed-by: Leena Miettinen <riitta-leena.miettinen@theqtcompany.com>
This commit is contained in:
@@ -82,24 +82,6 @@ public:
|
|||||||
importButton = new QPushButton(CommandMappings::tr("Import..."), groupBox);
|
importButton = new QPushButton(CommandMappings::tr("Import..."), groupBox);
|
||||||
exportButton = new QPushButton(CommandMappings::tr("Export..."), groupBox);
|
exportButton = new QPushButton(CommandMappings::tr("Export..."), groupBox);
|
||||||
|
|
||||||
targetEditGroup = new QGroupBox(CommandMappings::tr("Target Identifier"), parent);
|
|
||||||
targetEditGroup->setEnabled(false);
|
|
||||||
|
|
||||||
targetEdit = new FancyLineEdit(targetEditGroup);
|
|
||||||
targetEdit->setAutoHideButton(FancyLineEdit::Right, true);
|
|
||||||
targetEdit->setPlaceholderText(QString());
|
|
||||||
targetEdit->setFiltering(true);
|
|
||||||
targetEdit->setValidationFunction([this](FancyLineEdit *, QString *) {
|
|
||||||
return !q->hasConflicts();
|
|
||||||
});
|
|
||||||
|
|
||||||
resetButton = new QPushButton(targetEditGroup);
|
|
||||||
resetButton->setToolTip(CommandMappings::tr("Reset to default."));
|
|
||||||
resetButton->setText(CommandMappings::tr("Reset"));
|
|
||||||
|
|
||||||
QLabel *infoLabel = new QLabel(targetEditGroup);
|
|
||||||
infoLabel->setTextFormat(Qt::RichText);
|
|
||||||
|
|
||||||
QHBoxLayout *hboxLayout1 = new QHBoxLayout();
|
QHBoxLayout *hboxLayout1 = new QHBoxLayout();
|
||||||
hboxLayout1->addWidget(defaultButton);
|
hboxLayout1->addWidget(defaultButton);
|
||||||
hboxLayout1->addStretch();
|
hboxLayout1->addStretch();
|
||||||
@@ -114,25 +96,9 @@ public:
|
|||||||
vboxLayout1->addWidget(commandList);
|
vboxLayout1->addWidget(commandList);
|
||||||
vboxLayout1->addLayout(hboxLayout1);
|
vboxLayout1->addLayout(hboxLayout1);
|
||||||
|
|
||||||
targetLabel = new QLabel(CommandMappings::tr("Target:"));
|
|
||||||
|
|
||||||
QHBoxLayout *hboxLayout2 = new QHBoxLayout();
|
|
||||||
hboxLayout2->addWidget(targetLabel);
|
|
||||||
hboxLayout2->addWidget(targetEdit);
|
|
||||||
hboxLayout2->addWidget(resetButton);
|
|
||||||
|
|
||||||
QVBoxLayout *vboxLayout2 = new QVBoxLayout(targetEditGroup);
|
|
||||||
vboxLayout2->addLayout(hboxLayout2);
|
|
||||||
vboxLayout2->addWidget(infoLabel);
|
|
||||||
|
|
||||||
QVBoxLayout *vboxLayout = new QVBoxLayout(parent);
|
QVBoxLayout *vboxLayout = new QVBoxLayout(parent);
|
||||||
vboxLayout->addWidget(groupBox);
|
vboxLayout->addWidget(groupBox);
|
||||||
vboxLayout->addWidget(targetEditGroup);
|
|
||||||
|
|
||||||
q->connect(targetEdit, &FancyLineEdit::buttonClicked,
|
|
||||||
q, &CommandMappings::removeTargetIdentifier);
|
|
||||||
q->connect(resetButton, &QPushButton::clicked,
|
|
||||||
q, &CommandMappings::resetTargetIdentifier);
|
|
||||||
q->connect(exportButton, &QPushButton::clicked,
|
q->connect(exportButton, &QPushButton::clicked,
|
||||||
q, &CommandMappings::exportAction);
|
q, &CommandMappings::exportAction);
|
||||||
q->connect(importButton, &QPushButton::clicked,
|
q->connect(importButton, &QPushButton::clicked,
|
||||||
@@ -145,9 +111,7 @@ public:
|
|||||||
q->connect(filterEdit, &FancyLineEdit::textChanged,
|
q->connect(filterEdit, &FancyLineEdit::textChanged,
|
||||||
q, &CommandMappings::filterChanged);
|
q, &CommandMappings::filterChanged);
|
||||||
q->connect(commandList, &QTreeWidget::currentItemChanged,
|
q->connect(commandList, &QTreeWidget::currentItemChanged,
|
||||||
q, &CommandMappings::commandChanged);
|
q, &CommandMappings::currentCommandChanged);
|
||||||
q->connect(targetEdit, &FancyLineEdit::textChanged,
|
|
||||||
q, &CommandMappings::targetIdentifierChanged);
|
|
||||||
|
|
||||||
new HeaderViewStretcher(commandList->header(), 1);
|
new HeaderViewStretcher(commandList->header(), 1);
|
||||||
}
|
}
|
||||||
@@ -160,10 +124,6 @@ public:
|
|||||||
QPushButton *defaultButton;
|
QPushButton *defaultButton;
|
||||||
QPushButton *importButton;
|
QPushButton *importButton;
|
||||||
QPushButton *exportButton;
|
QPushButton *exportButton;
|
||||||
QGroupBox *targetEditGroup;
|
|
||||||
QLabel *targetLabel;
|
|
||||||
FancyLineEdit *targetEdit;
|
|
||||||
QPushButton *resetButton;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
@@ -189,41 +149,16 @@ QTreeWidget *CommandMappings::commandList() const
|
|||||||
return d->commandList;
|
return d->commandList;
|
||||||
}
|
}
|
||||||
|
|
||||||
QLineEdit *CommandMappings::targetEdit() const
|
|
||||||
{
|
|
||||||
return d->targetEdit;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CommandMappings::setPageTitle(const QString &s)
|
void CommandMappings::setPageTitle(const QString &s)
|
||||||
{
|
{
|
||||||
d->groupBox->setTitle(s);
|
d->groupBox->setTitle(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandMappings::setTargetLabelText(const QString &s)
|
|
||||||
{
|
|
||||||
d->targetLabel->setText(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CommandMappings::setTargetEditTitle(const QString &s)
|
|
||||||
{
|
|
||||||
d->targetEditGroup->setTitle(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CommandMappings::setTargetHeader(const QString &s)
|
void CommandMappings::setTargetHeader(const QString &s)
|
||||||
{
|
{
|
||||||
d->commandList->setHeaderLabels(QStringList() << tr("Command") << tr("Label") << s);
|
d->commandList->setHeaderLabels(QStringList() << tr("Command") << tr("Label") << s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandMappings::commandChanged(QTreeWidgetItem *current)
|
|
||||||
{
|
|
||||||
if (!current || !current->data(0, Qt::UserRole).isValid()) {
|
|
||||||
d->targetEdit->clear();
|
|
||||||
d->targetEditGroup->setEnabled(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
d->targetEditGroup->setEnabled(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CommandMappings::filterChanged(const QString &f)
|
void CommandMappings::filterChanged(const QString &f)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < d->commandList->topLevelItemCount(); ++i) {
|
for (int i = 0; i < d->commandList->topLevelItemCount(); ++i) {
|
||||||
@@ -232,11 +167,6 @@ void CommandMappings::filterChanged(const QString &f)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CommandMappings::hasConflicts() const
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CommandMappings::filter(const QString &filterString, QTreeWidgetItem *item)
|
bool CommandMappings::filter(const QString &filterString, QTreeWidgetItem *item)
|
||||||
{
|
{
|
||||||
bool visible = filterString.isEmpty();
|
bool visible = filterString.isEmpty();
|
||||||
@@ -275,7 +205,12 @@ void CommandMappings::setModified(QTreeWidgetItem *item , bool modified)
|
|||||||
|
|
||||||
QString CommandMappings::filterText() const
|
QString CommandMappings::filterText() const
|
||||||
{
|
{
|
||||||
return d->filterEdit ? d->filterEdit->text() : QString();
|
return d->filterEdit->text();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CommandMappings::setFilterText(const QString &text)
|
||||||
|
{
|
||||||
|
d->filterEdit->setText(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Core
|
} // namespace Core
|
||||||
|
|||||||
@@ -54,15 +54,11 @@ class CORE_EXPORT CommandMappings : public QWidget
|
|||||||
public:
|
public:
|
||||||
CommandMappings(QWidget *parent = 0);
|
CommandMappings(QWidget *parent = 0);
|
||||||
~CommandMappings();
|
~CommandMappings();
|
||||||
virtual bool hasConflicts() const;
|
|
||||||
|
|
||||||
protected slots:
|
signals:
|
||||||
|
void currentCommandChanged(QTreeWidgetItem *current);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void removeTargetIdentifier() = 0;
|
|
||||||
virtual void resetTargetIdentifier() = 0;
|
|
||||||
virtual void targetIdentifierChanged() = 0;
|
|
||||||
|
|
||||||
virtual void defaultAction() = 0;
|
virtual void defaultAction() = 0;
|
||||||
|
|
||||||
virtual void exportAction() {}
|
virtual void exportAction() {}
|
||||||
@@ -72,16 +68,12 @@ protected:
|
|||||||
|
|
||||||
void filterChanged(const QString &f);
|
void filterChanged(const QString &f);
|
||||||
|
|
||||||
virtual void commandChanged(QTreeWidgetItem *current);
|
|
||||||
|
|
||||||
// access to m_page
|
// access to m_page
|
||||||
void setImportExportEnabled(bool enabled);
|
void setImportExportEnabled(bool enabled);
|
||||||
QTreeWidget *commandList() const;
|
QTreeWidget *commandList() const;
|
||||||
QLineEdit *targetEdit() const;
|
|
||||||
QString filterText() const;
|
QString filterText() const;
|
||||||
|
void setFilterText(const QString &text);
|
||||||
void setPageTitle(const QString &s);
|
void setPageTitle(const QString &s);
|
||||||
void setTargetLabelText(const QString &s);
|
|
||||||
void setTargetEditTitle(const QString &s);
|
|
||||||
void setTargetHeader(const QString &s);
|
void setTargetHeader(const QString &s);
|
||||||
void setModified(QTreeWidgetItem *item, bool modified);
|
void setModified(QTreeWidgetItem *item, bool modified);
|
||||||
|
|
||||||
|
|||||||
@@ -41,12 +41,16 @@
|
|||||||
#include <utils/fancylineedit.h>
|
#include <utils/fancylineedit.h>
|
||||||
#include <utils/hostosinfo.h>
|
#include <utils/hostosinfo.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
#include <utils/theme/theme.h>
|
||||||
|
|
||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
|
#include <QGroupBox>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QLabel>
|
||||||
#include <QLineEdit>
|
#include <QLineEdit>
|
||||||
#include <QTreeWidgetItem>
|
#include <QTreeWidgetItem>
|
||||||
#include <QCoreApplication>
|
#include <QApplication>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(Core::Internal::ShortcutItem*)
|
Q_DECLARE_METATYPE(Core::Internal::ShortcutItem*)
|
||||||
@@ -71,23 +75,208 @@ static int translateModifiers(Qt::KeyboardModifiers state,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static QString keySequenceToEditString(const QKeySequence &sequence)
|
||||||
|
{
|
||||||
|
QString text = sequence.toString(QKeySequence::PortableText);
|
||||||
|
if (Utils::HostOsInfo::isMacHost()) {
|
||||||
|
// adapt the modifier names
|
||||||
|
text.replace(QLatin1String("Ctrl"), QLatin1String("Cmd"), Qt::CaseInsensitive);
|
||||||
|
text.replace(QLatin1String("Alt"), QLatin1String("Opt"), Qt::CaseInsensitive);
|
||||||
|
text.replace(QLatin1String("Meta"), QLatin1String("Ctrl"), Qt::CaseInsensitive);
|
||||||
|
}
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QKeySequence keySequenceFromEditString(const QString &editString)
|
||||||
|
{
|
||||||
|
QString text = editString;
|
||||||
|
if (Utils::HostOsInfo::isMacHost()) {
|
||||||
|
// adapt the modifier names
|
||||||
|
text.replace(QLatin1String("Opt"), QLatin1String("Alt"), Qt::CaseInsensitive);
|
||||||
|
text.replace(QLatin1String("Ctrl"), QLatin1String("Meta"), Qt::CaseInsensitive);
|
||||||
|
text.replace(QLatin1String("Cmd"), QLatin1String("Ctrl"), Qt::CaseInsensitive);
|
||||||
|
}
|
||||||
|
return QKeySequence::fromString(text, QKeySequence::PortableText);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool keySequenceIsValid(const QKeySequence &sequence)
|
||||||
|
{
|
||||||
|
if (sequence.isEmpty())
|
||||||
|
return false;
|
||||||
|
for (int i = 0; i < sequence.count(); ++i) {
|
||||||
|
if (sequence[i] == Qt::Key_unknown)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
|
ShortcutButton::ShortcutButton(QWidget *parent)
|
||||||
|
: QPushButton(parent)
|
||||||
|
{
|
||||||
|
setToolTip(tr("Click and type the new key sequence."));
|
||||||
|
setCheckable(true);
|
||||||
|
m_checkedText = tr("Stop Recording");
|
||||||
|
m_uncheckedText = tr("Record");
|
||||||
|
updateText();
|
||||||
|
connect(this, &ShortcutButton::toggled, this, &ShortcutButton::handleToggleChange);
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize ShortcutButton::sizeHint() const
|
||||||
|
{
|
||||||
|
if (m_preferredWidth < 0) { // initialize size hint
|
||||||
|
const QString originalText = text();
|
||||||
|
ShortcutButton *that = const_cast<ShortcutButton *>(this);
|
||||||
|
that->setText(m_checkedText);
|
||||||
|
m_preferredWidth = QPushButton::sizeHint().width();
|
||||||
|
that->setText(m_uncheckedText);
|
||||||
|
int otherWidth = QPushButton::sizeHint().width();
|
||||||
|
if (otherWidth > m_preferredWidth)
|
||||||
|
m_preferredWidth = otherWidth;
|
||||||
|
that->setText(originalText);
|
||||||
|
}
|
||||||
|
return QSize(m_preferredWidth, QPushButton::sizeHint().height());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ShortcutButton::eventFilter(QObject *obj, QEvent *evt)
|
||||||
|
{
|
||||||
|
if (evt->type() == QEvent::ShortcutOverride) {
|
||||||
|
evt->accept();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (evt->type() == QEvent::KeyRelease
|
||||||
|
|| evt->type() == QEvent::Shortcut
|
||||||
|
|| evt->type() == QEvent::Close/*Escape tries to close dialog*/) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (evt->type() == QEvent::MouseButtonPress && isChecked()) {
|
||||||
|
setChecked(false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (evt->type() == QEvent::KeyPress) {
|
||||||
|
QKeyEvent *k = static_cast<QKeyEvent*>(evt);
|
||||||
|
int nextKey = k->key();
|
||||||
|
if (m_keyNum > 3
|
||||||
|
|| nextKey == Qt::Key_Control
|
||||||
|
|| nextKey == Qt::Key_Shift
|
||||||
|
|| nextKey == Qt::Key_Meta
|
||||||
|
|| nextKey == Qt::Key_Alt) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
nextKey |= translateModifiers(k->modifiers(), k->text());
|
||||||
|
switch (m_keyNum) {
|
||||||
|
case 0:
|
||||||
|
m_key[0] = nextKey;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
m_key[1] = nextKey;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
m_key[2] = nextKey;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
m_key[3] = nextKey;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
m_keyNum++;
|
||||||
|
k->accept();
|
||||||
|
emit keySequenceChanged(QKeySequence(m_key[0], m_key[1], m_key[2], m_key[3]));
|
||||||
|
if (m_keyNum > 3)
|
||||||
|
setChecked(false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return QPushButton::eventFilter(obj, evt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShortcutButton::updateText()
|
||||||
|
{
|
||||||
|
setText(isChecked() ? m_checkedText : m_uncheckedText);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShortcutButton::handleToggleChange(bool toogleState)
|
||||||
|
{
|
||||||
|
updateText();
|
||||||
|
m_keyNum = m_key[0] = m_key[1] = m_key[2] = m_key[3] = 0;
|
||||||
|
if (toogleState) {
|
||||||
|
if (qApp->focusWidget())
|
||||||
|
qApp->focusWidget()->clearFocus(); // funny things happen otherwise
|
||||||
|
qApp->installEventFilter(this);
|
||||||
|
} else {
|
||||||
|
qApp->removeEventFilter(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ShortcutSettingsWidget::ShortcutSettingsWidget(QWidget *parent)
|
ShortcutSettingsWidget::ShortcutSettingsWidget(QWidget *parent)
|
||||||
: CommandMappings(parent)
|
: CommandMappings(parent)
|
||||||
{
|
{
|
||||||
setPageTitle(tr("Keyboard Shortcuts"));
|
setPageTitle(tr("Keyboard Shortcuts"));
|
||||||
setTargetLabelText(tr("Key sequence:"));
|
|
||||||
setTargetEditTitle(tr("Shortcut"));
|
|
||||||
setTargetHeader(tr("Shortcut"));
|
setTargetHeader(tr("Shortcut"));
|
||||||
targetEdit()->setPlaceholderText(tr("Type to set shortcut"));
|
|
||||||
|
|
||||||
m_keyNum = m_key[0] = m_key[1] = m_key[2] = m_key[3] = 0;
|
|
||||||
|
|
||||||
connect(ActionManager::instance(), &ActionManager::commandListChanged,
|
connect(ActionManager::instance(), &ActionManager::commandListChanged,
|
||||||
this, &ShortcutSettingsWidget::initialize);
|
this, &ShortcutSettingsWidget::initialize);
|
||||||
targetEdit()->installEventFilter(this);
|
connect(this, &ShortcutSettingsWidget::currentCommandChanged,
|
||||||
|
this, &ShortcutSettingsWidget::handleCurrentCommandChanged);
|
||||||
|
|
||||||
|
m_shortcutBox = new QGroupBox(tr("Shortcut"), this);
|
||||||
|
m_shortcutBox->setEnabled(false);
|
||||||
|
auto vboxLayout = new QVBoxLayout(m_shortcutBox);
|
||||||
|
m_shortcutBox->setLayout(vboxLayout);
|
||||||
|
auto hboxLayout = new QHBoxLayout;
|
||||||
|
vboxLayout->addLayout(hboxLayout);
|
||||||
|
m_shortcutEdit = new Utils::FancyLineEdit(m_shortcutBox);
|
||||||
|
m_shortcutEdit->setFiltering(true);
|
||||||
|
m_shortcutEdit->setPlaceholderText(tr("Enter key sequence as text"));
|
||||||
|
m_shortcutEdit->setValidationFunction([this](Utils::FancyLineEdit *, QString *) {
|
||||||
|
return validateShortcutEdit();
|
||||||
|
});
|
||||||
|
auto shortcutLabel = new QLabel(tr("Key sequence:"));
|
||||||
|
shortcutLabel->setToolTip(Utils::HostOsInfo::isMacHost()
|
||||||
|
? QLatin1String("<html><body>")
|
||||||
|
+ tr("Use \"Cmd\", \"Opt\", \"Ctrl\", and \"Shift\" for modifier keys. "
|
||||||
|
"Use \"Escape\", \"Backspace\", \"Delete\", \"Insert\", \"Home\", and so on, for special keys. "
|
||||||
|
"Combine individual keys with \"+\", "
|
||||||
|
"and combine multiple shortcuts to a shortcut sequence with \",\". "
|
||||||
|
"For example, if the user must hold the Ctrl and Shift modifier keys "
|
||||||
|
"while pressing Escape, and then release and press A, "
|
||||||
|
"enter \"Ctrl+Shift+Escape,A\".")
|
||||||
|
+ QLatin1String("</body></html>")
|
||||||
|
: QLatin1String("<html><body>")
|
||||||
|
+ tr("Use \"Ctrl\", \"Alt\", \"Meta\", and \"Shift\" for modifier keys. "
|
||||||
|
"Use \"Escape\", \"Backspace\", \"Delete\", \"Insert\", \"Home\", and so on, for special keys. "
|
||||||
|
"Combine individual keys with \"+\", "
|
||||||
|
"and combine multiple shortcuts to a shortcut sequence with \",\". "
|
||||||
|
"For example, if the user must hold the Ctrl and Shift modifier keys "
|
||||||
|
"while pressing Escape, and then release and press A, "
|
||||||
|
"enter \"Ctrl+Shift+Escape,A\".")
|
||||||
|
+ QLatin1String("</body></html>"));
|
||||||
|
auto shortcutButton = new ShortcutButton(m_shortcutBox);
|
||||||
|
connect(shortcutButton, &ShortcutButton::keySequenceChanged,
|
||||||
|
this, &ShortcutSettingsWidget::setKeySequence);
|
||||||
|
auto resetButton = new QPushButton(tr("Reset"), m_shortcutBox);
|
||||||
|
resetButton->setToolTip(tr("Reset to default."));
|
||||||
|
connect(resetButton, &QPushButton::clicked,
|
||||||
|
this, &ShortcutSettingsWidget::resetToDefault);
|
||||||
|
hboxLayout->addWidget(shortcutLabel);
|
||||||
|
hboxLayout->addWidget(m_shortcutEdit);
|
||||||
|
hboxLayout->addWidget(shortcutButton);
|
||||||
|
hboxLayout->addWidget(resetButton);
|
||||||
|
|
||||||
|
m_warningLabel = new QLabel(m_shortcutBox);
|
||||||
|
m_warningLabel->setTextFormat(Qt::RichText);
|
||||||
|
QPalette palette = m_warningLabel->palette();
|
||||||
|
palette.setColor(QPalette::Active, QPalette::WindowText,
|
||||||
|
Utils::creatorTheme()->color(Utils::Theme::TextColorError));
|
||||||
|
m_warningLabel->setPalette(palette);
|
||||||
|
connect(m_warningLabel, &QLabel::linkActivated, this, &ShortcutSettingsWidget::showConflicts);
|
||||||
|
vboxLayout->addWidget(m_warningLabel);
|
||||||
|
|
||||||
|
layout()->addWidget(m_shortcutBox);
|
||||||
|
|
||||||
initialize();
|
initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,122 +319,86 @@ void ShortcutSettings::finish()
|
|||||||
delete m_widget;
|
delete m_widget;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShortcutSettingsWidget::eventFilter(QObject *o, QEvent *e)
|
void ShortcutSettingsWidget::handleCurrentCommandChanged(QTreeWidgetItem *current)
|
||||||
{
|
{
|
||||||
Q_UNUSED(o)
|
if (!current || !current->data(0, Qt::UserRole).isValid()) {
|
||||||
|
m_shortcutEdit->clear();
|
||||||
if ( e->type() == QEvent::KeyPress ) {
|
m_warningLabel->clear();
|
||||||
QKeyEvent *k = static_cast<QKeyEvent*>(e);
|
m_shortcutBox->setEnabled(false);
|
||||||
handleKeyEvent(k);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( e->type() == QEvent::Shortcut ||
|
|
||||||
e->type() == QEvent::KeyRelease ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e->type() == QEvent::ShortcutOverride) {
|
|
||||||
// for shortcut overrides, we need to accept as well
|
|
||||||
e->accept();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ShortcutSettingsWidget::commandChanged(QTreeWidgetItem *current)
|
|
||||||
{
|
|
||||||
CommandMappings::commandChanged(current);
|
|
||||||
if (!current || !current->data(0, Qt::UserRole).isValid())
|
|
||||||
return;
|
return;
|
||||||
|
} else {
|
||||||
ShortcutItem *scitem = qvariant_cast<ShortcutItem *>(current->data(0, Qt::UserRole));
|
ShortcutItem *scitem = qvariant_cast<ShortcutItem *>(current->data(0, Qt::UserRole));
|
||||||
setKeySequence(scitem->m_key);
|
setKeySequence(scitem->m_key);
|
||||||
markCollisions(scitem);
|
markCollisions(scitem);
|
||||||
}
|
m_shortcutBox->setEnabled(true);
|
||||||
|
|
||||||
void ShortcutSettingsWidget::targetIdentifierChanged()
|
|
||||||
{
|
|
||||||
QTreeWidgetItem *current = commandList()->currentItem();
|
|
||||||
if (current && current->data(0, Qt::UserRole).isValid()) {
|
|
||||||
ShortcutItem *scitem = qvariant_cast<ShortcutItem *>(current->data(0, Qt::UserRole));
|
|
||||||
scitem->m_key = QKeySequence(m_key[0], m_key[1], m_key[2], m_key[3]);
|
|
||||||
if (scitem->m_cmd->defaultKeySequence() != scitem->m_key)
|
|
||||||
setModified(current, true);
|
|
||||||
else
|
|
||||||
setModified(current, false);
|
|
||||||
current->setText(2, scitem->m_key.toString(QKeySequence::NativeText));
|
|
||||||
markCollisions(scitem);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShortcutSettingsWidget::hasConflicts() const
|
bool ShortcutSettingsWidget::validateShortcutEdit() const
|
||||||
{
|
{
|
||||||
|
m_warningLabel->clear();
|
||||||
QTreeWidgetItem *current = commandList()->currentItem();
|
QTreeWidgetItem *current = commandList()->currentItem();
|
||||||
if (!current || !current->data(0, Qt::UserRole).isValid())
|
if (!current || !current->data(0, Qt::UserRole).isValid())
|
||||||
return false;
|
return true;
|
||||||
|
|
||||||
ShortcutItem *item = qvariant_cast<ShortcutItem *>(current->data(0, Qt::UserRole));
|
ShortcutItem *item = qvariant_cast<ShortcutItem *>(current->data(0, Qt::UserRole));
|
||||||
if (!item)
|
QTC_ASSERT(item, return true);
|
||||||
return false;
|
|
||||||
|
|
||||||
const QKeySequence currentKey = QKeySequence::fromString(targetEdit()->text(), QKeySequence::NativeText);
|
bool valid = false;
|
||||||
if (currentKey.isEmpty())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const Id globalId(Constants::C_GLOBAL);
|
const QString text = m_shortcutEdit->text().trimmed();
|
||||||
const Context itemContext = item->m_cmd->context();
|
const QKeySequence currentKey = keySequenceFromEditString(text);
|
||||||
|
|
||||||
foreach (ShortcutItem *listItem, m_scitems) {
|
if (keySequenceIsValid(currentKey) || text.isEmpty()) {
|
||||||
if (item == listItem)
|
item->m_key = currentKey;
|
||||||
continue;
|
auto that = const_cast<ShortcutSettingsWidget *>(this);
|
||||||
if (listItem->m_key.isEmpty())
|
if (item->m_cmd->defaultKeySequence() != item->m_key)
|
||||||
continue;
|
that->setModified(current, true);
|
||||||
if (listItem->m_key.matches(currentKey) == QKeySequence::NoMatch)
|
else
|
||||||
continue;
|
that->setModified(current, false);
|
||||||
|
current->setText(2, item->m_key.toString(QKeySequence::NativeText));
|
||||||
const Context listContext = listItem->m_cmd->context();
|
valid = !that->markCollisions(item);
|
||||||
if (itemContext.contains(globalId) && !listContext.isEmpty())
|
if (!valid) {
|
||||||
return true;
|
m_warningLabel->setText(
|
||||||
if (listContext.contains(globalId) && !itemContext.isEmpty())
|
tr("Key sequence has potential conflicts. <a href=\"#conflicts\">Show.</a>"));
|
||||||
return true;
|
|
||||||
foreach (Id id, listContext)
|
|
||||||
if (itemContext.contains(id))
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
} else {
|
||||||
|
m_warningLabel->setText(tr("Invalid key sequence."));
|
||||||
|
}
|
||||||
|
return valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShortcutSettingsWidget::filterColumn(const QString &filterString, QTreeWidgetItem *item,
|
bool ShortcutSettingsWidget::filterColumn(const QString &filterString, QTreeWidgetItem *item,
|
||||||
int column) const
|
int column) const
|
||||||
{
|
{
|
||||||
QString text = item->text(column);
|
QString text;
|
||||||
if (Utils::HostOsInfo::isMacHost()) {
|
|
||||||
// accept e.g. Cmd+E in the filter. the text shows special fancy characters for Cmd
|
|
||||||
if (column == item->columnCount() - 1) {
|
if (column == item->columnCount() - 1) {
|
||||||
QKeySequence key = QKeySequence::fromString(text, QKeySequence::NativeText);
|
// filter on the shortcut edit text
|
||||||
if (!key.isEmpty()) {
|
if (!item->data(0, Qt::UserRole).isValid())
|
||||||
text = key.toString(QKeySequence::PortableText);
|
return true;
|
||||||
text.replace(QLatin1String("Ctrl"), QLatin1String("Cmd"));
|
ShortcutItem *scitem = qvariant_cast<ShortcutItem *>(item->data(0, Qt::UserRole));
|
||||||
text.replace(QLatin1String("Meta"), QLatin1String("Ctrl"));
|
text = keySequenceToEditString(scitem->m_key);
|
||||||
text.replace(QLatin1String("Alt"), QLatin1String("Opt"));
|
} else {
|
||||||
}
|
text = item->text(column);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return !text.contains(filterString, Qt::CaseInsensitive);
|
return !text.contains(filterString, Qt::CaseInsensitive);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShortcutSettingsWidget::setKeySequence(const QKeySequence &key)
|
void ShortcutSettingsWidget::setKeySequence(const QKeySequence &key)
|
||||||
{
|
{
|
||||||
m_key[0] = m_key[1] = m_key[2] = m_key[3] = 0;
|
m_shortcutEdit->setText(keySequenceToEditString(key));
|
||||||
m_keyNum = key.count();
|
|
||||||
for (int i = 0; i < m_keyNum; ++i) {
|
|
||||||
m_key[i] = key[i];
|
|
||||||
}
|
|
||||||
targetEdit()->setText(key.toString(QKeySequence::NativeText));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShortcutSettingsWidget::resetTargetIdentifier()
|
void ShortcutSettingsWidget::showConflicts()
|
||||||
|
{
|
||||||
|
QTreeWidgetItem *current = commandList()->currentItem();
|
||||||
|
if (current && current->data(0, Qt::UserRole).isValid()) {
|
||||||
|
ShortcutItem *scitem = qvariant_cast<ShortcutItem *>(current->data(0, Qt::UserRole));
|
||||||
|
setFilterText(keySequenceToEditString(scitem->m_key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShortcutSettingsWidget::resetToDefault()
|
||||||
{
|
{
|
||||||
QTreeWidgetItem *current = commandList()->currentItem();
|
QTreeWidgetItem *current = commandList()->currentItem();
|
||||||
if (current && current->data(0, Qt::UserRole).isValid()) {
|
if (current && current->data(0, Qt::UserRole).isValid()) {
|
||||||
@@ -256,15 +409,6 @@ void ShortcutSettingsWidget::resetTargetIdentifier()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShortcutSettingsWidget::removeTargetIdentifier()
|
|
||||||
{
|
|
||||||
m_keyNum = m_key[0] = m_key[1] = m_key[2] = m_key[3] = 0;
|
|
||||||
targetEdit()->clear();
|
|
||||||
|
|
||||||
foreach (ShortcutItem *item, m_scitems)
|
|
||||||
markCollisions(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ShortcutSettingsWidget::importAction()
|
void ShortcutSettingsWidget::importAction()
|
||||||
{
|
{
|
||||||
QString fileName = QFileDialog::getOpenFileName(ICore::dialogParent(), tr("Import Keyboard Mapping Scheme"),
|
QString fileName = QFileDialog::getOpenFileName(ICore::dialogParent(), tr("Import Keyboard Mapping Scheme"),
|
||||||
@@ -281,7 +425,7 @@ void ShortcutSettingsWidget::importAction()
|
|||||||
item->m_key = mapping.value(sid);
|
item->m_key = mapping.value(sid);
|
||||||
item->m_item->setText(2, item->m_key.toString(QKeySequence::NativeText));
|
item->m_item->setText(2, item->m_key.toString(QKeySequence::NativeText));
|
||||||
if (item->m_item == commandList()->currentItem())
|
if (item->m_item == commandList()->currentItem())
|
||||||
commandChanged(item->m_item);
|
currentCommandChanged(item->m_item);
|
||||||
|
|
||||||
if (item->m_cmd->defaultKeySequence() != item->m_key)
|
if (item->m_cmd->defaultKeySequence() != item->m_key)
|
||||||
setModified(item->m_item, true);
|
setModified(item->m_item, true);
|
||||||
@@ -302,7 +446,7 @@ void ShortcutSettingsWidget::defaultAction()
|
|||||||
item->m_item->setText(2, item->m_key.toString(QKeySequence::NativeText));
|
item->m_item->setText(2, item->m_key.toString(QKeySequence::NativeText));
|
||||||
setModified(item->m_item, false);
|
setModified(item->m_item, false);
|
||||||
if (item->m_item == commandList()->currentItem())
|
if (item->m_item == commandList()->currentItem())
|
||||||
commandChanged(item->m_item);
|
currentCommandChanged(item->m_item);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (ShortcutItem *item, m_scitems)
|
foreach (ShortcutItem *item, m_scitems)
|
||||||
@@ -377,66 +521,39 @@ void ShortcutSettingsWidget::initialize()
|
|||||||
filterChanged(filterText());
|
filterChanged(filterText());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShortcutSettingsWidget::handleKeyEvent(QKeyEvent *e)
|
bool ShortcutSettingsWidget::markCollisions(ShortcutItem *item)
|
||||||
{
|
|
||||||
int nextKey = e->key();
|
|
||||||
if ( m_keyNum > 3 ||
|
|
||||||
nextKey == Qt::Key_Control ||
|
|
||||||
nextKey == Qt::Key_Shift ||
|
|
||||||
nextKey == Qt::Key_Meta ||
|
|
||||||
nextKey == Qt::Key_Alt )
|
|
||||||
return;
|
|
||||||
|
|
||||||
nextKey |= translateModifiers(e->modifiers(), e->text());
|
|
||||||
switch (m_keyNum) {
|
|
||||||
case 0:
|
|
||||||
m_key[0] = nextKey;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
m_key[1] = nextKey;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
m_key[2] = nextKey;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
m_key[3] = nextKey;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
m_keyNum++;
|
|
||||||
QKeySequence ks(m_key[0], m_key[1], m_key[2], m_key[3]);
|
|
||||||
targetEdit()->setText(ks.toString(QKeySequence::NativeText));
|
|
||||||
e->accept();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ShortcutSettingsWidget::markCollisions(ShortcutItem *item)
|
|
||||||
{
|
{
|
||||||
bool hasCollision = false;
|
bool hasCollision = false;
|
||||||
if (!item->m_key.isEmpty()) {
|
if (!item->m_key.isEmpty()) {
|
||||||
Id globalId = Context(Constants::C_GLOBAL).at(0);
|
Id globalId(Constants::C_GLOBAL);
|
||||||
const Context itemContext = item->m_cmd->context();
|
const Context itemContext = item->m_cmd->context();
|
||||||
|
const bool itemHasGlobalContext = itemContext.contains(globalId);
|
||||||
foreach (ShortcutItem *currentItem, m_scitems) {
|
foreach (ShortcutItem *currentItem, m_scitems) {
|
||||||
|
|
||||||
if (currentItem->m_key.isEmpty() || item == currentItem
|
if (currentItem->m_key.isEmpty() || item == currentItem
|
||||||
|| item->m_key != currentItem->m_key)
|
|| item->m_key != currentItem->m_key)
|
||||||
continue;
|
continue;
|
||||||
|
const Context currentContext = currentItem->m_cmd->context();
|
||||||
foreach (Id id, currentItem->m_cmd->context()) {
|
bool currentIsConflicting = (itemHasGlobalContext && !currentContext.isEmpty());
|
||||||
// conflict if context is identical, OR if one
|
if (!currentIsConflicting) {
|
||||||
// of the contexts is the global context
|
foreach (const Id &id, currentContext) {
|
||||||
const Context thisContext = currentItem->m_cmd->context();
|
if ((id == globalId && !itemContext.isEmpty())
|
||||||
if (itemContext.contains(id)
|
|| itemContext.contains(id)) {
|
||||||
|| (itemContext.contains(globalId) && !thisContext.isEmpty())
|
currentIsConflicting = true;
|
||||||
|| (thisContext.contains(globalId) && !itemContext.isEmpty())) {
|
break;
|
||||||
currentItem->m_item->setForeground(2, Qt::red);
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (currentIsConflicting) {
|
||||||
|
currentItem->m_item->setForeground(
|
||||||
|
2, Utils::creatorTheme()->color(Utils::Theme::TextColorError));
|
||||||
hasCollision = true;
|
hasCollision = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
item->m_item->setForeground(2, hasCollision
|
||||||
item->m_item->setForeground(2, hasCollision ? Qt::red : commandList()->palette().foreground());
|
? Utils::creatorTheme()->color(Utils::Theme::TextColorError)
|
||||||
|
: commandList()->palette().foreground());
|
||||||
|
return hasCollision;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
@@ -36,9 +36,12 @@
|
|||||||
|
|
||||||
#include <QKeySequence>
|
#include <QKeySequence>
|
||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
|
#include <QPushButton>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
class QGroupBox;
|
||||||
class QKeyEvent;
|
class QKeyEvent;
|
||||||
|
class QLabel;
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
@@ -57,6 +60,31 @@ struct ShortcutItem
|
|||||||
QTreeWidgetItem *m_item;
|
QTreeWidgetItem *m_item;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ShortcutButton : public QPushButton
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
ShortcutButton(QWidget *parent = 0);
|
||||||
|
|
||||||
|
QSize sizeHint() const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void keySequenceChanged(const QKeySequence &sequence);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool eventFilter(QObject *obj, QEvent *evt);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void updateText();
|
||||||
|
void handleToggleChange(bool toggleState);
|
||||||
|
|
||||||
|
QString m_checkedText;
|
||||||
|
QString m_uncheckedText;
|
||||||
|
mutable int m_preferredWidth = -1;
|
||||||
|
int m_key[4] = { 0, 0, 0, 0 };
|
||||||
|
int m_keyNum = 0;
|
||||||
|
};
|
||||||
|
|
||||||
class ShortcutSettingsWidget : public CommandMappings
|
class ShortcutSettingsWidget : public CommandMappings
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -68,28 +96,25 @@ public:
|
|||||||
void apply();
|
void apply();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool eventFilter(QObject *o, QEvent *e) override;
|
|
||||||
|
|
||||||
void commandChanged(QTreeWidgetItem *current) override;
|
|
||||||
void targetIdentifierChanged() override;
|
|
||||||
void resetTargetIdentifier() override;
|
|
||||||
void removeTargetIdentifier() override;
|
|
||||||
void importAction() override;
|
void importAction() override;
|
||||||
void exportAction() override;
|
void exportAction() override;
|
||||||
void defaultAction() override;
|
void defaultAction() override;
|
||||||
bool hasConflicts() const override;
|
|
||||||
|
|
||||||
bool filterColumn(const QString &filterString, QTreeWidgetItem *item, int column) const override;
|
bool filterColumn(const QString &filterString, QTreeWidgetItem *item, int column) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initialize();
|
void initialize();
|
||||||
void handleKeyEvent(QKeyEvent *e);
|
void handleCurrentCommandChanged(QTreeWidgetItem *current);
|
||||||
void markCollisions(ShortcutItem *);
|
void resetToDefault();
|
||||||
|
bool validateShortcutEdit() const;
|
||||||
|
bool markCollisions(ShortcutItem *);
|
||||||
void setKeySequence(const QKeySequence &key);
|
void setKeySequence(const QKeySequence &key);
|
||||||
|
void showConflicts();
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
QList<ShortcutItem *> m_scitems;
|
QList<ShortcutItem *> m_scitems;
|
||||||
int m_key[4], m_keyNum;
|
QGroupBox *m_shortcutBox;
|
||||||
|
Utils::FancyLineEdit *m_shortcutEdit;
|
||||||
|
QLabel *m_warningLabel;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ShortcutSettings : public IOptionsPage
|
class ShortcutSettings : public IOptionsPage
|
||||||
|
|||||||
@@ -544,25 +544,14 @@ class FakeVimExCommandsWidget : public CommandMappings
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FakeVimExCommandsWidget(FakeVimPluginPrivate *q, QWidget *parent = 0)
|
FakeVimExCommandsWidget(FakeVimPluginPrivate *q, QWidget *parent = 0);
|
||||||
: CommandMappings(parent), m_q(q)
|
|
||||||
{
|
|
||||||
setPageTitle(Tr::tr("Ex Command Mapping"));
|
|
||||||
setTargetHeader(Tr::tr("Ex Trigger Expression"));
|
|
||||||
setTargetLabelText(Tr::tr("Regular expression:"));
|
|
||||||
setTargetEditTitle(Tr::tr("Ex Command"));
|
|
||||||
targetEdit()->setPlaceholderText(QString());
|
|
||||||
setImportExportEnabled(false);
|
|
||||||
initialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void targetIdentifierChanged() override;
|
void commandChanged();
|
||||||
void resetTargetIdentifier() override;
|
void resetToDefault();
|
||||||
void removeTargetIdentifier() override;
|
|
||||||
void defaultAction() override;
|
void defaultAction() override;
|
||||||
|
|
||||||
void commandChanged(QTreeWidgetItem *current) override;
|
void handleCurrentCommandChanged(QTreeWidgetItem *current);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initialize();
|
void initialize();
|
||||||
@@ -571,8 +560,41 @@ private:
|
|||||||
ExCommandMap &defaultExCommandMap();
|
ExCommandMap &defaultExCommandMap();
|
||||||
|
|
||||||
FakeVimPluginPrivate *m_q;
|
FakeVimPluginPrivate *m_q;
|
||||||
|
QGroupBox *m_commandBox;
|
||||||
|
Utils::FancyLineEdit *m_commandEdit;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
FakeVimExCommandsWidget::FakeVimExCommandsWidget(FakeVimPluginPrivate *q, QWidget *parent)
|
||||||
|
: CommandMappings(parent), m_q(q)
|
||||||
|
{
|
||||||
|
setPageTitle(Tr::tr("Ex Command Mapping"));
|
||||||
|
setTargetHeader(Tr::tr("Ex Trigger Expression"));
|
||||||
|
setImportExportEnabled(false);
|
||||||
|
|
||||||
|
connect(this, &FakeVimExCommandsWidget::currentCommandChanged,
|
||||||
|
this, &FakeVimExCommandsWidget::handleCurrentCommandChanged);
|
||||||
|
|
||||||
|
m_commandBox = new QGroupBox(Tr::tr("Ex Command"), this);
|
||||||
|
m_commandBox->setEnabled(false);
|
||||||
|
auto boxLayout = new QHBoxLayout(m_commandBox);
|
||||||
|
m_commandEdit = new Utils::FancyLineEdit(m_commandBox);
|
||||||
|
m_commandEdit->setFiltering(true);
|
||||||
|
m_commandEdit->setPlaceholderText(QString());
|
||||||
|
connect(m_commandEdit, &Utils::FancyLineEdit::textChanged,
|
||||||
|
this, &FakeVimExCommandsWidget::commandChanged);
|
||||||
|
auto resetButton = new QPushButton(Tr::tr("Reset"), m_commandBox);
|
||||||
|
resetButton->setToolTip(Tr::tr("Reset to default."));
|
||||||
|
connect(resetButton, &QPushButton::clicked,
|
||||||
|
this, &FakeVimExCommandsWidget::resetToDefault);
|
||||||
|
boxLayout->addWidget(new QLabel(Tr::tr("Regular expression:")));
|
||||||
|
boxLayout->addWidget(m_commandEdit);
|
||||||
|
boxLayout->addWidget(resetButton);
|
||||||
|
|
||||||
|
layout()->addWidget(m_commandBox);
|
||||||
|
|
||||||
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
class FakeVimExCommandsPage : public IOptionsPage
|
class FakeVimExCommandsPage : public IOptionsPage
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -647,24 +669,28 @@ void FakeVimExCommandsWidget::initialize()
|
|||||||
setModified(item, true);
|
setModified(item, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
commandChanged(0);
|
handleCurrentCommandChanged(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FakeVimExCommandsWidget::commandChanged(QTreeWidgetItem *current)
|
void FakeVimExCommandsWidget::handleCurrentCommandChanged(QTreeWidgetItem *current)
|
||||||
{
|
{
|
||||||
CommandMappings::commandChanged(current);
|
if (current) {
|
||||||
if (current)
|
m_commandEdit->setText(current->text(2));
|
||||||
targetEdit()->setText(current->text(2));
|
m_commandBox->setEnabled(true);
|
||||||
|
} else {
|
||||||
|
m_commandEdit->clear();
|
||||||
|
m_commandBox->setEnabled(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FakeVimExCommandsWidget::targetIdentifierChanged()
|
void FakeVimExCommandsWidget::commandChanged()
|
||||||
{
|
{
|
||||||
QTreeWidgetItem *current = commandList()->currentItem();
|
QTreeWidgetItem *current = commandList()->currentItem();
|
||||||
if (!current)
|
if (!current)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const QString name = current->data(0, CommandRole).toString();
|
const QString name = current->data(0, CommandRole).toString();
|
||||||
const QString regex = targetEdit()->text();
|
const QString regex = m_commandEdit->text();
|
||||||
|
|
||||||
if (current->data(0, Qt::UserRole).isValid()) {
|
if (current->data(0, Qt::UserRole).isValid()) {
|
||||||
current->setText(2, regex);
|
current->setText(2, regex);
|
||||||
@@ -674,7 +700,7 @@ void FakeVimExCommandsWidget::targetIdentifierChanged()
|
|||||||
setModified(current, regex != defaultExCommandMap()[name].pattern());
|
setModified(current, regex != defaultExCommandMap()[name].pattern());
|
||||||
}
|
}
|
||||||
|
|
||||||
void FakeVimExCommandsWidget::resetTargetIdentifier()
|
void FakeVimExCommandsWidget::resetToDefault()
|
||||||
{
|
{
|
||||||
QTreeWidgetItem *current = commandList()->currentItem();
|
QTreeWidgetItem *current = commandList()->currentItem();
|
||||||
if (!current)
|
if (!current)
|
||||||
@@ -683,12 +709,7 @@ void FakeVimExCommandsWidget::resetTargetIdentifier()
|
|||||||
QString regex;
|
QString regex;
|
||||||
if (defaultExCommandMap().contains(name))
|
if (defaultExCommandMap().contains(name))
|
||||||
regex = defaultExCommandMap()[name].pattern();
|
regex = defaultExCommandMap()[name].pattern();
|
||||||
targetEdit()->setText(regex);
|
m_commandEdit->setText(regex);
|
||||||
}
|
|
||||||
|
|
||||||
void FakeVimExCommandsWidget::removeTargetIdentifier()
|
|
||||||
{
|
|
||||||
targetEdit()->clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FakeVimExCommandsWidget::defaultAction()
|
void FakeVimExCommandsWidget::defaultAction()
|
||||||
@@ -706,7 +727,7 @@ void FakeVimExCommandsWidget::defaultAction()
|
|||||||
setModified(item, false);
|
setModified(item, false);
|
||||||
item->setText(2, regex);
|
item->setText(2, regex);
|
||||||
if (item == commandList()->currentItem())
|
if (item == commandList()->currentItem())
|
||||||
commandChanged(item);
|
currentCommandChanged(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user