forked from qt-creator/qt-creator
Make the eventlisplugin a part of the qmldesigner plugin
The eventlistplugin enables the user to create custom events (QDS-1760). It provides a dialog to create and remove a custom event or modify its properties (id, description, shortcut) and a dialog to connect an event to one of the flowsignals in order to trigger a transition or a state change. Task-number: QDS-4300 Change-Id: Ifffa81650d4898b34a65d7901bcb0df95cc397af Reviewed-by: Alessandro Portale <alessandro.portale@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
@@ -780,7 +780,27 @@ extend_qtc_plugin(QmlDesigner
|
||||
detail/treeitemdelegate.cpp detail/treeitemdelegate.h
|
||||
detail/treemodel.cpp detail/treemodel.h
|
||||
detail/treeview.cpp detail/treeview.h
|
||||
detail/utils.cpp detail/utils.h
|
||||
detail/curveeditorutils.cpp detail/curveeditorutils.h
|
||||
)
|
||||
|
||||
extend_qtc_plugin(QmlDesigner
|
||||
SOURCES_PREFIX components/eventlist
|
||||
SOURCES
|
||||
eventlistplugin.qrc
|
||||
eventlistpluginview.cpp eventlistpluginview.h
|
||||
assigneventdialog.cpp assigneventdialog.h
|
||||
eventlist.cpp eventlist.h
|
||||
eventlistactions.cpp eventlistactions.h
|
||||
eventlistdelegate.cpp eventlistdelegate.h
|
||||
eventlistdialog.cpp eventlistdialog.h
|
||||
eventlistview.cpp eventlistview.h
|
||||
eventlistutils.cpp eventlistutils.h
|
||||
filterlinewidget.cpp filterlinewidget.h
|
||||
nodelistdelegate.cpp nodelistdelegate.h
|
||||
nodelistview.cpp nodelistview.h
|
||||
nodeselectionmodel.cpp nodeselectionmodel.h
|
||||
connectsignaldialog.cpp connectsignaldialog.h
|
||||
shortcutwidget.cpp shortcutwidget.h
|
||||
)
|
||||
|
||||
# Do the file comparison at the end, due to all the extend_qtc_plugin calls
|
||||
|
@@ -46,6 +46,7 @@ const char flowEffectCategory[] = "FlowEffect";
|
||||
const char flowConnectionCategory[] = "FlowConnection";
|
||||
const char stackedContainerCategory[] = "StackedContainer";
|
||||
const char genericToolBarCategory[] = "GenericToolBar";
|
||||
const char eventListCategory[] = "QmlEventList";
|
||||
|
||||
const char toFrontCommandId[] = "ToFront";
|
||||
const char toBackCommandId[] = "ToBack";
|
||||
@@ -209,6 +210,7 @@ const int priorityGroupCategory = 140;
|
||||
const int priorityPositionCategory = 130;
|
||||
const int priorityLayoutCategory = 120;
|
||||
const int priorityStackedContainerCategory = priorityLayoutCategory;
|
||||
const int priorityEventListCategory = 105;
|
||||
const int priorityTopLevelSeperator = 100;
|
||||
const int priorityCustomActions = 80;
|
||||
const int priorityRefactoring = 60;
|
||||
|
@@ -25,7 +25,7 @@
|
||||
|
||||
#include "animationcurve.h"
|
||||
#include "curvesegment.h"
|
||||
#include "detail/utils.h"
|
||||
#include "detail/curveeditorutils.h"
|
||||
|
||||
#include <QEasingCurve>
|
||||
#include <QLineF>
|
||||
|
@@ -45,7 +45,7 @@ SOURCES += \
|
||||
$$PWD/detail/treeitemdelegate.cpp \
|
||||
$$PWD/detail/treemodel.cpp \
|
||||
$$PWD/detail/treeview.cpp \
|
||||
$$PWD/detail/utils.cpp \
|
||||
$$PWD/detail/curveeditorutils.cpp \
|
||||
$$PWD/detail/axis.cpp \
|
||||
$$PWD/keyframe.cpp \
|
||||
$$PWD/treeitem.cpp
|
||||
|
@@ -24,7 +24,7 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include "curvesegment.h"
|
||||
#include "detail/utils.h"
|
||||
#include "detail/curveeditorutils.h"
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
#include <QEasingCurve>
|
||||
|
@@ -26,7 +26,7 @@
|
||||
#include "animationcurve.h"
|
||||
#include "graphicsscene.h"
|
||||
#include "keyframeitem.h"
|
||||
#include "utils.h"
|
||||
#include "curveeditorutils.h"
|
||||
|
||||
#include <QEasingCurve>
|
||||
#include <QPainter>
|
||||
|
@@ -29,7 +29,7 @@
|
||||
#include "curveitem.h"
|
||||
#include "navigation2d.h"
|
||||
#include "treeitem.h"
|
||||
#include "utils.h"
|
||||
#include "curveeditorutils.h"
|
||||
|
||||
#include <theme.h>
|
||||
#include <utils/fileutils.h>
|
||||
|
@@ -27,7 +27,7 @@
|
||||
#include "curvesegment.h"
|
||||
#include "graphicsscene.h"
|
||||
#include "keyframeitem.h"
|
||||
#include "utils.h"
|
||||
#include "curveeditorutils.h"
|
||||
|
||||
#include <QPainter>
|
||||
|
||||
|
@@ -0,0 +1,184 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd
|
||||
** All rights reserved.
|
||||
** For any questions to The Qt Company, please use contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
** This file is part of the Qt Event List module.
|
||||
**
|
||||
** 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 The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please use
|
||||
** contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
******************************************************************************/
|
||||
#include "assigneventdialog.h"
|
||||
#include "eventlist.h"
|
||||
#include "eventlistdelegate.h"
|
||||
#include "eventlistview.h"
|
||||
#include "filterlinewidget.h"
|
||||
#include "nodelistdelegate.h"
|
||||
#include "nodelistview.h"
|
||||
#include "nodeselectionmodel.h"
|
||||
#include "eventlistutils.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QHeaderView>
|
||||
#include <QMessageBox>
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QSplitter>
|
||||
#include <QTableView>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
AssignEventDialog::AssignEventDialog(QWidget *parent)
|
||||
: QDialog(parent)
|
||||
, m_nodeTable(new QTableView)
|
||||
, m_eventTable(new QTableView)
|
||||
, m_nodeLine(new FilterLineWidget())
|
||||
, m_eventLine(new FilterLineWidget())
|
||||
{
|
||||
setWindowFlag(Qt::Tool, true);
|
||||
setModal(true);
|
||||
|
||||
auto *nodeFilterModel = new QSortFilterProxyModel;
|
||||
auto *nodeListDelegate = new NodeListDelegate(m_nodeTable);
|
||||
auto *nodeSelectionModel = new NodeSelectionModel(nodeFilterModel);
|
||||
m_nodeTable->installEventFilter(new TabWalker(this));
|
||||
m_nodeTable->setItemDelegate(nodeListDelegate);
|
||||
m_nodeTable->setModel(nodeFilterModel);
|
||||
m_nodeTable->setSelectionModel(nodeSelectionModel);
|
||||
m_nodeTable->setFocusPolicy(Qt::NoFocus);
|
||||
m_nodeTable->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
m_nodeTable->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
m_nodeTable->resizeColumnsToContents();
|
||||
m_nodeTable->horizontalHeader()->setStretchLastSection(true);
|
||||
m_nodeTable->verticalHeader()->hide();
|
||||
polishPalette(m_nodeTable, "#1f75cc");
|
||||
|
||||
auto *eventFilterModel = new QSortFilterProxyModel;
|
||||
auto *eventListDelegate = new EventListDelegate(m_eventTable);
|
||||
m_eventTable->installEventFilter(new TabWalker(this));
|
||||
m_eventTable->setItemDelegate(eventListDelegate);
|
||||
m_eventTable->setFocusPolicy(Qt::NoFocus);
|
||||
m_eventTable->setSelectionMode(QAbstractItemView::NoSelection);
|
||||
m_eventTable->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
m_eventTable->setModel(eventFilterModel);
|
||||
m_eventTable->verticalHeader()->hide();
|
||||
polishPalette(m_eventTable, QColor("#d87b00"));
|
||||
|
||||
auto *nodeBox = new QVBoxLayout;
|
||||
nodeBox->addWidget(m_nodeLine);
|
||||
nodeBox->addWidget(m_nodeTable);
|
||||
|
||||
QWidget *nodeWidget = new QWidget;
|
||||
nodeWidget->setLayout(nodeBox);
|
||||
|
||||
auto *eventBox = new QVBoxLayout;
|
||||
eventBox->addWidget(m_eventLine);
|
||||
eventBox->addWidget(m_eventTable);
|
||||
|
||||
auto *eventWidget = new QWidget;
|
||||
eventWidget->setLayout(eventBox);
|
||||
|
||||
auto *splitter = new QSplitter(Qt::Horizontal);
|
||||
splitter->addWidget(nodeWidget);
|
||||
splitter->addWidget(eventWidget);
|
||||
splitter->setStretchFactor(0, 1);
|
||||
splitter->setStretchFactor(1, 3);
|
||||
|
||||
auto *box = new QHBoxLayout;
|
||||
box->addWidget(splitter);
|
||||
setLayout(box);
|
||||
|
||||
connect(m_nodeLine, &FilterLineWidget::filterChanged, [this](const QString &str) {
|
||||
if (auto *sm = qobject_cast<NodeSelectionModel *>(m_nodeTable->selectionModel())) {
|
||||
sm->storeSelection();
|
||||
if (auto *fm = qobject_cast<QSortFilterProxyModel *>(m_nodeTable->model()))
|
||||
fm->setFilterFixedString(str);
|
||||
sm->reselect();
|
||||
}
|
||||
});
|
||||
|
||||
connect(m_eventLine, &FilterLineWidget::filterChanged, [this](const QString &str) {
|
||||
if (auto *fm = qobject_cast<QSortFilterProxyModel *>(m_eventTable->model()))
|
||||
fm->setFilterFixedString(str);
|
||||
});
|
||||
|
||||
connect(eventListDelegate, &EventListDelegate::connectClicked,
|
||||
[](const QString &id, bool connected) {
|
||||
if (connected)
|
||||
EventList::addEventIdToCurrent(id);
|
||||
else
|
||||
EventList::removeEventIdFromCurrent(id);
|
||||
});
|
||||
}
|
||||
|
||||
void AssignEventDialog::initialize(EventList &events)
|
||||
{
|
||||
m_nodeLine->clear();
|
||||
m_eventLine->clear();
|
||||
|
||||
if (auto *fm = qobject_cast<QSortFilterProxyModel *>(m_nodeTable->model()))
|
||||
fm->setSourceModel(events.nodeModel());
|
||||
|
||||
if (auto *fm = qobject_cast<QSortFilterProxyModel *>(m_eventTable->model()))
|
||||
fm->setSourceModel(events.view()->eventListModel());
|
||||
|
||||
if (auto *sm = qobject_cast<NodeSelectionModel *>(m_nodeTable->selectionModel())) {
|
||||
if (m_connection)
|
||||
sm->disconnect(m_connection);
|
||||
|
||||
auto updateEventListView = [this, &events](const QStringList &eventIds) {
|
||||
auto nonExistent = events.view()->eventListModel()->connectEvents(eventIds);
|
||||
|
||||
if (!nonExistent.empty()) {
|
||||
QString header(tr("Nonexistent events discovered"));
|
||||
QString msg(tr("The Node references the following nonexistent events:\n"));
|
||||
for (auto &&id : nonExistent)
|
||||
msg += id + ", ";
|
||||
msg.remove(msg.size() - 2, 2);
|
||||
msg += "\nDo you want to remove these references?";
|
||||
|
||||
if (QMessageBox::Yes == QMessageBox::question(this, header, msg)) {
|
||||
auto *view = events.nodeListView();
|
||||
view->removeEventIds(view->currentNode(), nonExistent);
|
||||
view->reset();
|
||||
if (auto *sm = qobject_cast<NodeSelectionModel *>(m_nodeTable->selectionModel()))
|
||||
sm->selectNode(view->currentNode());
|
||||
}
|
||||
}
|
||||
m_eventTable->update();
|
||||
};
|
||||
m_connection = connect(sm, &NodeSelectionModel::nodeSelected, updateEventListView);
|
||||
}
|
||||
|
||||
m_nodeTable->setColumnHidden(NodeListModel::typeColumn, true);
|
||||
m_nodeTable->setColumnHidden(NodeListModel::fromColumn, true);
|
||||
m_nodeTable->setColumnHidden(NodeListModel::toColumn, true);
|
||||
|
||||
if (QHeaderView *header = m_eventTable->horizontalHeader()) {
|
||||
header->setSectionResizeMode(EventListModel::idColumn, QHeaderView::Stretch);
|
||||
header->setSectionResizeMode(EventListModel::descriptionColumn, QHeaderView::Stretch);
|
||||
header->setSectionResizeMode(EventListModel::shortcutColumn, QHeaderView::Stretch);
|
||||
header->resizeSection(EventListModel::connectColumn, 120);
|
||||
header->setStretchLastSection(false);
|
||||
}
|
||||
}
|
||||
|
||||
void AssignEventDialog::postShow()
|
||||
{
|
||||
if (auto *sm = qobject_cast<NodeSelectionModel *>(m_nodeTable->selectionModel()))
|
||||
sm->selectNode(EventList::currentNode());
|
||||
|
||||
resize(QSize(700, 300));
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner.
|
@@ -0,0 +1,52 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd
|
||||
** All rights reserved.
|
||||
** For any questions to The Qt Company, please use contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
** This file is part of the Qt Event List module.
|
||||
**
|
||||
** 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 The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please use
|
||||
** contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QTableView)
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class EventList;
|
||||
class FilterLineWidget;
|
||||
|
||||
class AssignEventDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
AssignEventDialog(QWidget *parent = nullptr);
|
||||
void initialize(EventList &events);
|
||||
void postShow();
|
||||
|
||||
private:
|
||||
QTableView *m_nodeTable;
|
||||
QTableView *m_eventTable;
|
||||
|
||||
FilterLineWidget *m_nodeLine;
|
||||
FilterLineWidget *m_eventLine;
|
||||
|
||||
QMetaObject::Connection m_connection;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner.
|
@@ -0,0 +1,136 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd
|
||||
** All rights reserved.
|
||||
** For any questions to The Qt Company, please use contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
** This file is part of the Qt Event List module.
|
||||
**
|
||||
** 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 The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please use
|
||||
** contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
******************************************************************************/
|
||||
#include "connectsignaldialog.h"
|
||||
#include "eventlist.h"
|
||||
#include "eventlistdelegate.h"
|
||||
#include "eventlistview.h"
|
||||
#include "filterlinewidget.h"
|
||||
#include "nodelistview.h"
|
||||
#include "eventlistutils.h"
|
||||
|
||||
#include <QHeaderView>
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QTableView>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
QString eventListToSource(const QStringList &events)
|
||||
{
|
||||
if (events.empty())
|
||||
return QString("{}");
|
||||
|
||||
QString source("{\n");
|
||||
for (auto &&event : events)
|
||||
source += QString("EventSystem.triggerEvent(\"") + event + QString("\")\n");
|
||||
source += "}";
|
||||
return source;
|
||||
}
|
||||
|
||||
QStringList eventListFromSource(const QString &source)
|
||||
{
|
||||
QStringList out;
|
||||
for (auto &&substr : source.split("\n", Qt::SkipEmptyParts)) {
|
||||
auto trimmed = substr.trimmed();
|
||||
if (trimmed.startsWith("EventSystem.triggerEvent("))
|
||||
out << trimmed.section('\"', 1, 1);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
ConnectSignalDialog::ConnectSignalDialog(QWidget *parent)
|
||||
: QDialog(parent)
|
||||
, m_table(new QTableView)
|
||||
, m_filter(new FilterLineWidget())
|
||||
, m_property()
|
||||
{
|
||||
setWindowFlag(Qt::Tool, true);
|
||||
setModal(true);
|
||||
|
||||
auto *filterModel = new QSortFilterProxyModel;
|
||||
auto *delegate = new EventListDelegate(m_table);
|
||||
|
||||
m_table->installEventFilter(new TabWalker(this));
|
||||
m_table->setItemDelegate(delegate);
|
||||
m_table->setModel(filterModel);
|
||||
m_table->setFocusPolicy(Qt::NoFocus);
|
||||
m_table->setSelectionMode(QAbstractItemView::NoSelection);
|
||||
m_table->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
m_table->verticalHeader()->hide();
|
||||
polishPalette(m_table, QColor("#d87b00"));
|
||||
|
||||
auto *box = new QVBoxLayout;
|
||||
box->addWidget(m_filter);
|
||||
box->addWidget(m_table);
|
||||
|
||||
setLayout(box);
|
||||
|
||||
connect(m_filter, &FilterLineWidget::filterChanged, [this](const QString &str) {
|
||||
if (auto *fm = qobject_cast<QSortFilterProxyModel *>(m_table->model()))
|
||||
fm->setFilterFixedString(str);
|
||||
});
|
||||
|
||||
connect(delegate,
|
||||
&EventListDelegate::connectClicked,
|
||||
[this, filterModel](const QString &, bool) {
|
||||
if (m_property.isValid()) {
|
||||
if (const auto *m = qobject_cast<const EventListModel *>(
|
||||
filterModel->sourceModel())) {
|
||||
QString source = eventListToSource(m->connectedEvents());
|
||||
EventList::setSignalSource(m_property, source);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void ConnectSignalDialog::initialize(EventList &events, const SignalHandlerProperty &signal)
|
||||
{
|
||||
m_filter->clear();
|
||||
|
||||
auto *eventModel = events.view()->eventListModel();
|
||||
if (!eventModel)
|
||||
return;
|
||||
|
||||
if (auto *fm = qobject_cast<QSortFilterProxyModel *>(m_table->model()))
|
||||
fm->setSourceModel(eventModel);
|
||||
|
||||
m_property = signal;
|
||||
if (m_property.isValid()) {
|
||||
QString title = QString::fromUtf8(m_property.name());
|
||||
setWindowTitle(title);
|
||||
eventModel->connectEvents(eventListFromSource(m_property.source()));
|
||||
}
|
||||
|
||||
if (QHeaderView *header = m_table->horizontalHeader()) {
|
||||
header->setSectionResizeMode(EventListModel::idColumn, QHeaderView::Stretch);
|
||||
header->setSectionResizeMode(EventListModel::descriptionColumn, QHeaderView::Stretch);
|
||||
header->setSectionResizeMode(EventListModel::shortcutColumn, QHeaderView::Stretch);
|
||||
header->resizeSection(EventListModel::connectColumn, 120);
|
||||
header->setStretchLastSection(false);
|
||||
}
|
||||
}
|
||||
|
||||
QSize ConnectSignalDialog::sizeHint() const
|
||||
{
|
||||
return QSize(522, 270);
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner.
|
@@ -0,0 +1,51 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd
|
||||
** All rights reserved.
|
||||
** For any questions to The Qt Company, please use contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
** This file is part of the Qt Event List module.
|
||||
**
|
||||
** 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 The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please use
|
||||
** contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "signalhandlerproperty.h"
|
||||
#include <QDialog>
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QTableView)
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class EventList;
|
||||
class FilterLineWidget;
|
||||
|
||||
class ConnectSignalDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ConnectSignalDialog(QWidget *parent = nullptr);
|
||||
void initialize(EventList &events, const SignalHandlerProperty &signal);
|
||||
|
||||
protected:
|
||||
QSize sizeHint() const override;
|
||||
|
||||
private:
|
||||
QTableView *m_table;
|
||||
FilterLineWidget *m_filter;
|
||||
SignalHandlerProperty m_property;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner.
|
230
src/plugins/qmldesigner/components/eventlist/eventlist.cpp
Normal file
230
src/plugins/qmldesigner/components/eventlist/eventlist.cpp
Normal file
@@ -0,0 +1,230 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd
|
||||
** All rights reserved.
|
||||
** For any questions to The Qt Company, please use contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
** This file is part of the Qt Event List module.
|
||||
**
|
||||
** 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 The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please use
|
||||
** contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
******************************************************************************/
|
||||
#include "eventlist.h"
|
||||
#include "eventlistpluginview.h"
|
||||
#include "eventlistview.h"
|
||||
#include "nodelistview.h"
|
||||
|
||||
#include "bindingproperty.h"
|
||||
#include "metainfo.h"
|
||||
#include "projectexplorer/project.h"
|
||||
#include "projectexplorer/session.h"
|
||||
#include "qmldesignerplugin.h"
|
||||
#include "signalhandlerproperty.h"
|
||||
#include "utils/fileutils.h"
|
||||
#include "utils/qtcassert.h"
|
||||
#include "variantproperty.h"
|
||||
|
||||
#include <QDirIterator>
|
||||
#include <QStandardItemModel>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
Utils::FilePath projectFilePath()
|
||||
{
|
||||
if (auto *doc = QmlDesignerPlugin::instance()->documentManager().currentDesignDocument()) {
|
||||
if (auto *proj = ProjectExplorer::SessionManager::projectForFile(doc->fileName()))
|
||||
return proj->projectDirectory();
|
||||
}
|
||||
return Utils::FilePath();
|
||||
}
|
||||
|
||||
static Utils::FilePath findFile(const Utils::FilePath &path, const QString &fileName)
|
||||
{
|
||||
QDirIterator it(path.toString(), QDirIterator::Subdirectories);
|
||||
|
||||
while (it.hasNext()) {
|
||||
QFileInfo file(it.next());
|
||||
if (file.isDir())
|
||||
continue;
|
||||
|
||||
if (file.fileName() == fileName)
|
||||
return Utils::FilePath::fromFileInfo(file);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
NodeListView *EventList::st_nodeView = nullptr;
|
||||
|
||||
void EventList::setNodeProperties(AbstractView *view)
|
||||
{
|
||||
st_nodeView = new NodeListView(view);
|
||||
}
|
||||
|
||||
void EventList::selectNode(int internalId)
|
||||
{
|
||||
if (st_nodeView)
|
||||
st_nodeView->selectNode(internalId);
|
||||
}
|
||||
|
||||
int EventList::currentNode()
|
||||
{
|
||||
if (st_nodeView)
|
||||
return st_nodeView->currentNode();
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool EventList::hasEventListModel()
|
||||
{
|
||||
Utils::FilePath projectPath = projectFilePath();
|
||||
if (projectPath.isEmpty())
|
||||
return false;
|
||||
|
||||
Utils::FilePath path = findFile(projectPath, "EventListModel.qml");
|
||||
return path.exists();
|
||||
}
|
||||
|
||||
void EventList::addEventIdToCurrent(const QString &eventId)
|
||||
{
|
||||
int iid = currentNode();
|
||||
if (st_nodeView && iid >= 0)
|
||||
st_nodeView->addEventId(iid, eventId);
|
||||
}
|
||||
|
||||
void EventList::removeEventIdFromCurrent(const QString &eventId)
|
||||
{
|
||||
int iid = currentNode();
|
||||
if (st_nodeView && iid >= 0)
|
||||
st_nodeView->removeEventIds(iid, {eventId});
|
||||
}
|
||||
|
||||
QString EventList::setNodeId(int internalId, const QString &id)
|
||||
{
|
||||
if (st_nodeView)
|
||||
return st_nodeView->setNodeId(internalId, id);
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
QStandardItemModel *EventList::nodeModel()
|
||||
{
|
||||
if (st_nodeView)
|
||||
return st_nodeView->itemModel();
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NodeListView *EventList::nodeListView()
|
||||
{
|
||||
return st_nodeView;
|
||||
}
|
||||
|
||||
ModelNode EventList::modelNode(const QString &id)
|
||||
{
|
||||
if (st_nodeView)
|
||||
return st_nodeView->modelNodeForId(id);
|
||||
|
||||
return ModelNode();
|
||||
}
|
||||
|
||||
void EventList::setSignalSource(SignalHandlerProperty &prop, const QString &source)
|
||||
{
|
||||
if (st_nodeView) {
|
||||
QmlDesigner::Import import =
|
||||
QmlDesigner::Import::createLibraryImport("QtQuick.Studio.EventSystem", "1.0");
|
||||
|
||||
if (!st_nodeView->model()->hasImport(import, true, true)) {
|
||||
try {
|
||||
st_nodeView->model()->changeImports({import}, {});
|
||||
} catch (const QmlDesigner::Exception &) {
|
||||
QTC_ASSERT(false, return );
|
||||
}
|
||||
}
|
||||
|
||||
if (source == "{}") {
|
||||
if (ModelNode node = prop.parentModelNode(); node.isValid()) {
|
||||
st_nodeView->executeInTransaction("EventList::removeProperty",
|
||||
[&]() { node.removeProperty(prop.name()); });
|
||||
}
|
||||
}
|
||||
else {
|
||||
st_nodeView->executeInTransaction("EventList::setSource",
|
||||
[&]() { prop.setSource(source); });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EventList::EventList()
|
||||
: m_model(nullptr)
|
||||
, m_eventView(nullptr)
|
||||
, m_path()
|
||||
|
||||
{}
|
||||
|
||||
Model *EventList::model() const
|
||||
{
|
||||
return m_model;
|
||||
}
|
||||
|
||||
EventListView *EventList::view() const
|
||||
{
|
||||
return m_eventView;
|
||||
}
|
||||
|
||||
QString EventList::read() const
|
||||
{
|
||||
if (!m_path.exists())
|
||||
return QString();
|
||||
|
||||
Utils::FileReader reader;
|
||||
QTC_ASSERT(reader.fetch(m_path), return QString());
|
||||
|
||||
return QString::fromUtf8(reader.data());
|
||||
}
|
||||
|
||||
|
||||
void EventList::initialize(EventListPluginView *parent)
|
||||
{
|
||||
Utils::FilePath projectPath = projectFilePath();
|
||||
QTC_ASSERT(!projectPath.isEmpty(), return );
|
||||
m_path = findFile(projectPath, "EventListModel.qml");
|
||||
|
||||
if (!m_model) {
|
||||
QByteArray unqualifiedTypeName = "ListModel";
|
||||
auto metaInfo = parent->model()->metaInfo(unqualifiedTypeName);
|
||||
|
||||
QByteArray fullTypeName = metaInfo.typeName();
|
||||
int minorVersion = metaInfo.minorVersion();
|
||||
int majorVersion = metaInfo.majorVersion();
|
||||
|
||||
m_model = Model::create(fullTypeName, majorVersion, minorVersion);
|
||||
m_model->setParent(parent);
|
||||
}
|
||||
|
||||
if (!m_eventView) {
|
||||
m_eventView = new EventListView(m_model);
|
||||
m_model->attachView(m_eventView);
|
||||
}
|
||||
}
|
||||
|
||||
void EventList::write(const QString &text)
|
||||
{
|
||||
if (!m_path.exists())
|
||||
return;
|
||||
|
||||
Utils::FileSaver writer(m_path);
|
||||
writer.write(text.toUtf8());
|
||||
writer.finalize();
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner.
|
75
src/plugins/qmldesigner/components/eventlist/eventlist.h
Normal file
75
src/plugins/qmldesigner/components/eventlist/eventlist.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd
|
||||
** All rights reserved.
|
||||
** For any questions to The Qt Company, please use contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
** This file is part of the Qt Event List module.
|
||||
**
|
||||
** 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 The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please use
|
||||
** contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "modelnode.h"
|
||||
#include "utils/fileutils.h"
|
||||
|
||||
#include <unordered_set>
|
||||
#include <QDialog>
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QStandardItemModel)
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class Model;
|
||||
class NodeListView;
|
||||
class EventListView;
|
||||
class EventListPluginView;
|
||||
|
||||
class EventList
|
||||
{
|
||||
public:
|
||||
static int currentNode();
|
||||
static bool hasEventListModel();
|
||||
static bool connectedToCurrent(const QString &eventId);
|
||||
static void addEventIdToCurrent(const QString &eventId);
|
||||
static void removeEventIdFromCurrent(const QString &eventId);
|
||||
static void setNodeProperties(AbstractView *view);
|
||||
static void selectNode(int internalId);
|
||||
|
||||
static QString setNodeId(int internalId, const QString &id);
|
||||
static QStandardItemModel *nodeModel();
|
||||
static NodeListView *nodeListView();
|
||||
static ModelNode modelNode(const QString &id);
|
||||
|
||||
static void setSignalSource(SignalHandlerProperty &prop, const QString &source);
|
||||
|
||||
EventList();
|
||||
|
||||
Model *model() const;
|
||||
|
||||
EventListView *view() const;
|
||||
QString read() const;
|
||||
|
||||
void initialize(EventListPluginView *parent);
|
||||
void write(const QString &text);
|
||||
|
||||
private:
|
||||
static NodeListView *st_nodeView;
|
||||
|
||||
Model *m_model;
|
||||
EventListView *m_eventView;
|
||||
Utils::FilePath m_path;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner.
|
@@ -0,0 +1,110 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd
|
||||
** All rights reserved.
|
||||
** For any questions to The Qt Company, please use contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
** This file is part of the Qt Event List module.
|
||||
**
|
||||
** 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 The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please use
|
||||
** contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
******************************************************************************/
|
||||
|
||||
#include "eventlistactions.h"
|
||||
#include "eventlist.h"
|
||||
#include <theme.h>
|
||||
|
||||
#include "metainfo.h"
|
||||
#include <utils/utilsicons.h>
|
||||
|
||||
#include <utils/stylehelper.h>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
inline bool eventListEnabled(const SelectionContext &)
|
||||
{
|
||||
return EventList::hasEventListModel();
|
||||
}
|
||||
|
||||
QIcon eventListIconFromIconFont(Theme::Icon iconType)
|
||||
{
|
||||
const QColor enabledColor(Theme::getColor(Theme::IconsBaseColor));
|
||||
const QColor disabledColor(Theme::getColor(Theme::IconsDisabledColor));
|
||||
const QString unicode = Theme::getIconUnicode(iconType);
|
||||
const QString fontName = "qtds_propertyIconFont.ttf";
|
||||
|
||||
const auto enabledHelper = Utils::StyleHelper::IconFontHelper(
|
||||
unicode, enabledColor, QSize(28, 28), QIcon::Normal);
|
||||
|
||||
const auto disabledHelper = Utils::StyleHelper::IconFontHelper(
|
||||
unicode, disabledColor, QSize(28, 28), QIcon::Disabled);
|
||||
|
||||
return Utils::StyleHelper::getIconFromIconFont(fontName, {enabledHelper, disabledHelper});
|
||||
}
|
||||
|
||||
static QIcon editEventListIcon()
|
||||
{
|
||||
return eventListIconFromIconFont(Theme::Icon::edit);
|
||||
}
|
||||
|
||||
static void handleAction(const SelectionContext &) {}
|
||||
|
||||
EventListAction::EventListAction()
|
||||
: ModelNodeAction("EventList",
|
||||
QObject::tr("Show Event List"),
|
||||
editEventListIcon(),
|
||||
QObject::tr("Show Event List"),
|
||||
ComponentCoreConstants::eventListCategory,
|
||||
QKeySequence("Alt+e"),
|
||||
230,
|
||||
&handleAction,
|
||||
&eventListEnabled)
|
||||
{}
|
||||
|
||||
static QIcon assignEventListIcon()
|
||||
{
|
||||
return eventListIconFromIconFont(Theme::Icon::assign);
|
||||
}
|
||||
|
||||
static void handleAssignEventActionOperation(const SelectionContext &context)
|
||||
{
|
||||
EventList::setNodeProperties(context.view());
|
||||
}
|
||||
|
||||
AssignEventEditorAction::AssignEventEditorAction()
|
||||
: ModelNodeAction("AssignEventEditor",
|
||||
QObject::tr("Assign Events to Actions"),
|
||||
assignEventListIcon(),
|
||||
QObject::tr("Assign Events to Actions"),
|
||||
ComponentCoreConstants::eventListCategory,
|
||||
QKeySequence("Alt+a"),
|
||||
220,
|
||||
&handleAssignEventActionOperation,
|
||||
&eventListEnabled)
|
||||
{}
|
||||
|
||||
ConnectSignalAction::ConnectSignalAction()
|
||||
: ModelNodeContextMenuAction("ConnectSignalEditor",
|
||||
QObject::tr("Connect Signal to Event"),
|
||||
assignEventListIcon(),
|
||||
ComponentCoreConstants::eventListCategory,
|
||||
QKeySequence(),
|
||||
210,
|
||||
&handleAssignEventActionOperation)
|
||||
{}
|
||||
|
||||
ModelNodeContextMenuAction::TargetView ConnectSignalAction::targetView() const
|
||||
{
|
||||
return TargetView::ConnectionEditor;
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner
|
@@ -0,0 +1,47 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd
|
||||
** All rights reserved.
|
||||
** For any questions to The Qt Company, please use contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
** This file is part of the Qt Event List module.
|
||||
**
|
||||
** 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 The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please use
|
||||
** contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <modelnodecontextmenu_helper.h>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class EventListAction : public ModelNodeAction
|
||||
{
|
||||
public:
|
||||
EventListAction();
|
||||
};
|
||||
|
||||
class AssignEventEditorAction : public ModelNodeAction
|
||||
{
|
||||
public:
|
||||
AssignEventEditorAction();
|
||||
};
|
||||
|
||||
class ConnectSignalAction : public ModelNodeContextMenuAction
|
||||
{
|
||||
public:
|
||||
ConnectSignalAction();
|
||||
TargetView targetView() const override;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
@@ -0,0 +1,205 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd
|
||||
** All rights reserved.
|
||||
** For any questions to The Qt Company, please use contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
** This file is part of the Qt Event List module.
|
||||
**
|
||||
** 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 The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please use
|
||||
** contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
******************************************************************************/
|
||||
#include "eventlistdelegate.h"
|
||||
#include "eventlist.h"
|
||||
#include "eventlistview.h"
|
||||
#include "nodelistview.h"
|
||||
#include "qnamespace.h"
|
||||
#include "shortcutwidget.h"
|
||||
#include "eventlistutils.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QLineEdit>
|
||||
#include <QPainter>
|
||||
#include <QStyleOptionButton>
|
||||
#include <QTableView>
|
||||
#include <QMouseEvent>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
EventListDelegate::EventListDelegate(QObject *parent)
|
||||
: QStyledItemDelegate(parent)
|
||||
{}
|
||||
|
||||
QWidget *EventListDelegate::createEditor(QWidget *parent,
|
||||
const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
if (index.column() == EventListModel::shortcutColumn) {
|
||||
auto *editor = new ShortcutWidget(parent);
|
||||
connect(editor, &ShortcutWidget::done, this, &EventListDelegate::commitAndClose);
|
||||
connect(editor, &ShortcutWidget::cancel, this, &EventListDelegate::close);
|
||||
return editor;
|
||||
} else if (index.column() == EventListModel::connectColumn) {
|
||||
return nullptr;
|
||||
}
|
||||
return QStyledItemDelegate::createEditor(parent, option, index);
|
||||
}
|
||||
|
||||
void EventListDelegate::setModelData(QWidget *editor,
|
||||
QAbstractItemModel *model,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
if (index.column() == EventListModel::idColumn) {
|
||||
if (auto *edit = qobject_cast<QLineEdit *>(editor)) {
|
||||
QString name = edit->text();
|
||||
QString unique = uniqueName(model, name);
|
||||
if (name != unique) {
|
||||
name = unique;
|
||||
edit->setText(unique);
|
||||
}
|
||||
emit eventIdChanged(model->data(index, Qt::DisplayRole).toString(), name);
|
||||
}
|
||||
|
||||
} else if (index.column() == EventListModel::shortcutColumn) {
|
||||
if (auto *edit = qobject_cast<ShortcutWidget *>(editor)) {
|
||||
auto idIndex = model->index(index.row(), EventListModel::idColumn, index.parent());
|
||||
if (idIndex.isValid()) {
|
||||
emit shortcutChanged(model->data(idIndex, Qt::DisplayRole).toString(), edit->text());
|
||||
model->setData(index, edit->text(), Qt::DisplayRole);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else if (index.column() == EventListModel::descriptionColumn) {
|
||||
if (auto *edit = qobject_cast<QLineEdit *>(editor)) {
|
||||
auto idIndex = model->index(index.row(), EventListModel::idColumn, index.parent());
|
||||
if (idIndex.isValid()) {
|
||||
auto id = model->data(idIndex, Qt::DisplayRole).toString();
|
||||
emit descriptionChanged(id, edit->text());
|
||||
}
|
||||
}
|
||||
}
|
||||
QStyledItemDelegate::setModelData(editor, model, index);
|
||||
}
|
||||
|
||||
bool EventListDelegate::hasConnectionColumn(QObject *parent)
|
||||
{
|
||||
if (auto *table = qobject_cast<QTableView *>(parent))
|
||||
return !table->isColumnHidden(EventListModel::connectColumn);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QRect EventListDelegate::connectButtonRect(const QStyleOptionViewItem &option)
|
||||
{
|
||||
return option.rect.adjusted(3, 3, -3, -3);
|
||||
}
|
||||
|
||||
void EventListDelegate::paint(QPainter *painter,
|
||||
const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
if (hasConnectionColumn(parent())) {
|
||||
bool connected = index.data(EventListModel::connectedRole).toBool();
|
||||
if (connected) {
|
||||
QStyleOptionViewItem opt(option);
|
||||
opt.state = QStyle::State_Selected;
|
||||
QStyledItemDelegate::paint(painter, opt, index);
|
||||
|
||||
if (index.column() != EventListModel::connectColumn)
|
||||
return;
|
||||
}
|
||||
|
||||
if (index.column() == EventListModel::connectColumn) {
|
||||
QStyleOptionButton button;
|
||||
button.rect = connectButtonRect(option);
|
||||
button.text = connected ? tr("Release") : tr("Connect");
|
||||
button.state = QStyle::State_Enabled;
|
||||
QApplication::style()->drawControl(QStyle::CE_PushButton, &button, painter);
|
||||
return;
|
||||
}
|
||||
}
|
||||
QStyledItemDelegate::paint(painter, option, index);
|
||||
}
|
||||
|
||||
bool EventListDelegate::editorEvent(QEvent *event,
|
||||
QAbstractItemModel *model,
|
||||
const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index)
|
||||
{
|
||||
if (index.column() == EventListModel::connectColumn) {
|
||||
if (event->type() == QEvent::MouseButtonRelease) {
|
||||
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
|
||||
if (connectButtonRect(option).contains(mouseEvent->pos())) {
|
||||
if (QModelIndex sib = index.siblingAtColumn(EventListModel::idColumn); sib.isValid()) {
|
||||
auto id = sib.data().toString();
|
||||
bool connected = index.data(EventListModel::connectedRole).toBool();
|
||||
for (int c = 0; c < model->columnCount(); ++c) {
|
||||
auto id = model->index(index.row(), c, index.parent());
|
||||
model->setData(id, !connected, EventListModel::connectedRole);
|
||||
}
|
||||
emit connectClicked(id, !connected);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return QStyledItemDelegate::editorEvent(event, model, option, index);
|
||||
}
|
||||
|
||||
bool EventListDelegate::eventFilter(QObject *editor, QEvent *event)
|
||||
{
|
||||
if (auto *edit = qobject_cast<ShortcutWidget *>(editor)) {
|
||||
if (event->type() == QEvent::KeyPress) {
|
||||
edit->recordKeysequence(static_cast<QKeyEvent *>(event));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (event->type() == QEvent::FocusOut) {
|
||||
if (!edit->containsFocus())
|
||||
edit->reset();
|
||||
}
|
||||
} else {
|
||||
if (event->type() == QEvent::KeyPress) {
|
||||
int key = static_cast<QKeyEvent *>(event)->key();
|
||||
if (key == Qt::Key_Tab || key == Qt::Key_Backtab)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return QStyledItemDelegate::eventFilter(editor, event);
|
||||
}
|
||||
|
||||
QSize EventListDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||
{
|
||||
if (index.column() == EventListModel::connectColumn) {
|
||||
QSize size = QStyledItemDelegate::sizeHint(option, index);
|
||||
size.rwidth() = 20;
|
||||
return size;
|
||||
}
|
||||
return QStyledItemDelegate::sizeHint(option, index);
|
||||
}
|
||||
|
||||
void EventListDelegate::commitAndClose()
|
||||
{
|
||||
if (auto *editor = qobject_cast<ShortcutWidget *>(sender())) {
|
||||
emit commitData(editor);
|
||||
emit closeEditor(editor);
|
||||
}
|
||||
}
|
||||
|
||||
void EventListDelegate::close()
|
||||
{
|
||||
if (auto *editor = qobject_cast<ShortcutWidget *>(sender()))
|
||||
emit closeEditor(editor);
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner.
|
@@ -0,0 +1,67 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd
|
||||
** All rights reserved.
|
||||
** For any questions to The Qt Company, please use contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
** This file is part of the Qt Event List module.
|
||||
**
|
||||
** 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 The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please use
|
||||
** contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
******************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <QStyledItemDelegate>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class EventListDelegate : public QStyledItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
signals:
|
||||
void eventIdChanged(const QString &from, const QString &to) const;
|
||||
void shortcutChanged(const QString &from, const QString &to) const;
|
||||
void descriptionChanged(const QString &id, const QString &text) const;
|
||||
void connectClicked(const QString &id, bool connected) const;
|
||||
|
||||
public:
|
||||
EventListDelegate(QObject *parent = nullptr);
|
||||
|
||||
QWidget *createEditor(QWidget *parent,
|
||||
const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const override;
|
||||
|
||||
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override;
|
||||
|
||||
void paint(QPainter *painter,
|
||||
const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const override;
|
||||
|
||||
bool editorEvent(QEvent *event,
|
||||
QAbstractItemModel *model,
|
||||
const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) override;
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *editor, QEvent *event) override;
|
||||
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
||||
|
||||
private:
|
||||
void close();
|
||||
void commitAndClose();
|
||||
|
||||
static bool hasConnectionColumn(QObject *parent);
|
||||
static QRect connectButtonRect(const QStyleOptionViewItem &option);
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner.
|
151
src/plugins/qmldesigner/components/eventlist/eventlistdialog.cpp
Normal file
151
src/plugins/qmldesigner/components/eventlist/eventlistdialog.cpp
Normal file
@@ -0,0 +1,151 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd
|
||||
** All rights reserved.
|
||||
** For any questions to The Qt Company, please use contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
** This file is part of the Qt Event List module.
|
||||
**
|
||||
** 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 The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please use
|
||||
** contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
******************************************************************************/
|
||||
#include "eventlistdialog.h"
|
||||
#include "eventlist.h"
|
||||
#include "eventlistdelegate.h"
|
||||
#include "eventlistview.h"
|
||||
#include "filterlinewidget.h"
|
||||
#include "nodelistview.h"
|
||||
#include "qmldesignerplugin.h"
|
||||
#include "eventlistutils.h"
|
||||
#include "utils/utilsicons.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QHeaderView>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QTableView>
|
||||
#include <QToolBar>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
EventListDialog::EventListDialog(QWidget *parent)
|
||||
: QDialog(parent)
|
||||
, m_delegate(new EventListDelegate)
|
||||
, m_modifier(nullptr)
|
||||
, m_rewriter(nullptr)
|
||||
, m_table(new QTableView)
|
||||
, m_addAction(nullptr)
|
||||
, m_removeAction(nullptr)
|
||||
, m_textEdit(new QPlainTextEdit)
|
||||
{
|
||||
setModal(true);
|
||||
setWindowFlag(Qt::Tool, true);
|
||||
|
||||
m_modifier = new NotIndentingTextEditModifier(m_textEdit);
|
||||
m_textEdit->hide();
|
||||
|
||||
m_table->installEventFilter(new TabWalker(this));
|
||||
m_table->setItemDelegate(m_delegate);
|
||||
m_table->setModel(new QSortFilterProxyModel);
|
||||
m_table->setFocusPolicy(Qt::NoFocus);
|
||||
m_table->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
m_table->horizontalHeader()->setStretchLastSection(true);
|
||||
m_table->resizeColumnsToContents();
|
||||
|
||||
auto *toolbar = new QToolBar;
|
||||
m_addAction = toolbar->addAction(Utils::Icons::PLUS_TOOLBAR.icon(), tr("Add Event"));
|
||||
m_removeAction = toolbar->addAction(Utils::Icons::MINUS.icon(), tr("Remove Selected Events"));
|
||||
|
||||
auto *filterWidget = new FilterLineWidget;
|
||||
toolbar->addWidget(filterWidget);
|
||||
|
||||
auto *tableLayout = new QVBoxLayout;
|
||||
tableLayout->setSpacing(0);
|
||||
tableLayout->addWidget(toolbar);
|
||||
tableLayout->addWidget(m_table);
|
||||
|
||||
auto *box = new QHBoxLayout;
|
||||
box->addLayout(tableLayout);
|
||||
setLayout(box);
|
||||
|
||||
connect(filterWidget, &FilterLineWidget::filterChanged, [this](const QString &str) {
|
||||
if (auto *fm = qobject_cast<QSortFilterProxyModel *>(m_table->model()))
|
||||
fm->setFilterFixedString(str);
|
||||
});
|
||||
}
|
||||
|
||||
void EventListDialog::initialize(EventList &events)
|
||||
{
|
||||
m_textEdit->setPlainText(events.read());
|
||||
|
||||
if (!m_rewriter) {
|
||||
Model *model = events.model();
|
||||
m_modifier->setParent(model);
|
||||
|
||||
m_rewriter = new RewriterView(QmlDesigner::RewriterView::Validate, model);
|
||||
m_rewriter->setTextModifier(m_modifier);
|
||||
m_rewriter->setCheckSemanticErrors(false);
|
||||
model->attachView(m_rewriter);
|
||||
|
||||
if (auto *fm = qobject_cast<QSortFilterProxyModel *>(m_table->model())) {
|
||||
fm->setSourceModel(events.view()->eventListModel());
|
||||
}
|
||||
|
||||
connect(m_addAction, &QAction::triggered, [this, &events]() {
|
||||
Event event;
|
||||
event.eventId = uniqueName(events.view()->eventListModel(), "event");
|
||||
events.view()->addEvent(event);
|
||||
events.write(m_textEdit->toPlainText());
|
||||
});
|
||||
|
||||
connect(m_removeAction, &QAction::triggered, [this, &events]() {
|
||||
for (auto index : m_table->selectionModel()->selectedRows()) {
|
||||
QString eventId = index.data(Qt::DisplayRole).toString();
|
||||
events.view()->removeEvent(eventId);
|
||||
}
|
||||
events.write(m_textEdit->toPlainText());
|
||||
});
|
||||
|
||||
connect(m_delegate,
|
||||
&EventListDelegate::eventIdChanged,
|
||||
[this, &events](const QString &oldId, const QString &newId) {
|
||||
events.view()->renameEvent(oldId, newId);
|
||||
events.write(m_textEdit->toPlainText());
|
||||
});
|
||||
|
||||
connect(m_delegate,
|
||||
&EventListDelegate::shortcutChanged,
|
||||
[this, &events](const QString &id, const QString &text) {
|
||||
events.view()->setShortcut(id, text);
|
||||
events.write(m_textEdit->toPlainText());
|
||||
});
|
||||
|
||||
connect(m_delegate,
|
||||
&EventListDelegate::descriptionChanged,
|
||||
[this, &events](const QString &id, const QString &text) {
|
||||
events.view()->setDescription(id, text);
|
||||
events.write(m_textEdit->toPlainText());
|
||||
});
|
||||
}
|
||||
|
||||
m_table->setColumnHidden(EventListModel::connectColumn, true);
|
||||
}
|
||||
|
||||
void EventListDialog::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
if (auto *view = EventList::nodeListView())
|
||||
view->reset();
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner.
|
@@ -0,0 +1,57 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd
|
||||
** All rights reserved.
|
||||
** For any questions to The Qt Company, please use contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
** This file is part of the Qt Event List module.
|
||||
**
|
||||
** 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 The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please use
|
||||
** contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QPlainTextEdit)
|
||||
QT_FORWARD_DECLARE_CLASS(QTableView)
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class EventList;
|
||||
class EventListDelegate;
|
||||
class RewriterView;
|
||||
class NotIndentingTextEditModifier;
|
||||
|
||||
class EventListDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
EventListDialog(QWidget *parent = nullptr);
|
||||
void initialize(EventList &events);
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *event) override;
|
||||
|
||||
private:
|
||||
EventListDelegate *m_delegate;
|
||||
NotIndentingTextEditModifier *m_modifier;
|
||||
RewriterView *m_rewriter;
|
||||
QTableView *m_table;
|
||||
QAction *m_addAction;
|
||||
QAction *m_removeAction;
|
||||
QPlainTextEdit *m_textEdit;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner.
|
@@ -0,0 +1 @@
|
||||
MetaInfo {}
|
@@ -0,0 +1,35 @@
|
||||
QT *= qml quick core
|
||||
|
||||
VPATH += $$PWD
|
||||
|
||||
SOURCES += $$PWD/eventlist.cpp \
|
||||
$$PWD/eventlistview.cpp \
|
||||
$$PWD/eventlistpluginview.cpp \
|
||||
$$PWD/eventlistactions.cpp \
|
||||
$$PWD/eventlistdialog.cpp \
|
||||
$$PWD/eventlistdelegate.cpp \
|
||||
$$PWD/filterlinewidget.cpp \
|
||||
$$PWD/nodelistview.cpp \
|
||||
$$PWD/nodelistdelegate.cpp \
|
||||
$$PWD/nodeselectionmodel.cpp \
|
||||
$$PWD/assigneventdialog.cpp \
|
||||
$$PWD/shortcutwidget.cpp \
|
||||
$$PWD/connectsignaldialog.cpp \
|
||||
$$PWD/eventlistutils.cpp
|
||||
|
||||
HEADERS += $$PWD/eventlist.h \
|
||||
$$PWD/eventlistpluginview.h \
|
||||
$$PWD/eventlistview.h \
|
||||
$$PWD/eventlistactions.h \
|
||||
$$PWD/eventlistdialog.h \
|
||||
$$PWD/eventlistdelegate.h \
|
||||
$$PWD/filterlinewidget.h \
|
||||
$$PWD/nodelistview.h \
|
||||
$$PWD/nodelistdelegate.h \
|
||||
$$PWD/nodeselectionmodel.h \
|
||||
$$PWD/assigneventdialog.h \
|
||||
$$PWD/shortcutwidget.h \
|
||||
$$PWD/connectsignaldialog.h \
|
||||
$$PWD/eventlistutils.h
|
||||
|
||||
RESOURCES += $$PWD/eventlistplugin.qrc
|
@@ -0,0 +1,5 @@
|
||||
<RCC>
|
||||
<qresource prefix="/eventlistplugin">
|
||||
<file>eventlistplugin.metainfo</file>
|
||||
</qresource>
|
||||
</RCC>
|
@@ -0,0 +1,114 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd
|
||||
** All rights reserved.
|
||||
** For any questions to The Qt Company, please use contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
** This file is part of the Qt Event List module.
|
||||
**
|
||||
** 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 The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please use
|
||||
** contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
******************************************************************************/
|
||||
#include "eventlistpluginview.h"
|
||||
#include "assigneventdialog.h"
|
||||
#include "connectsignaldialog.h"
|
||||
#include "eventlistactions.h"
|
||||
#include "eventlistdialog.h"
|
||||
|
||||
#include "signalhandlerproperty.h"
|
||||
#include <coreplugin/icore.h>
|
||||
#include <extensionsystem/pluginmanager.h>
|
||||
#include <extensionsystem/pluginspec.h>
|
||||
#include <qmldesignerplugin.h>
|
||||
#include <componentcore/componentcore_constants.h>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
SignalHandlerProperty signalPropertyFromAction(ActionInterface *interface)
|
||||
{
|
||||
if (auto data = interface->action()->data(); data.isValid()) {
|
||||
QMap<QString, QVariant> mapping = data.value<QMap<QString, QVariant>>();
|
||||
ModelNode node = EventList::modelNode(mapping["ModelNode"].toString());
|
||||
PropertyName signal = mapping["Signal"].toString().toUtf8();
|
||||
|
||||
for (auto &&child : node.directSubModelNodes()) {
|
||||
if (auto prop = child.signalHandlerProperty(signal); prop.exists())
|
||||
return prop;
|
||||
}
|
||||
}
|
||||
return SignalHandlerProperty();
|
||||
}
|
||||
|
||||
EventListPluginView::EventListPluginView(QObject* parent)
|
||||
: AbstractView(parent)
|
||||
, m_eventlist()
|
||||
, m_eventListDialog(nullptr)
|
||||
, m_assigner(nullptr)
|
||||
, m_signalConnector(nullptr)
|
||||
{ }
|
||||
|
||||
void EventListPluginView::registerActions()
|
||||
{
|
||||
DesignerActionManager &designerActionManager = QmlDesignerPlugin::instance()->designerActionManager();
|
||||
|
||||
designerActionManager.addDesignerAction(new ActionGroup(tr("Event List"),
|
||||
ComponentCoreConstants::eventListCategory,
|
||||
ComponentCoreConstants::priorityEventListCategory,
|
||||
&SelectionContextFunctors::always,
|
||||
&SelectionContextFunctors::always));
|
||||
auto eventListAction = new EventListAction();
|
||||
connect(eventListAction->defaultAction(), &QAction::triggered, [this]() {
|
||||
if (!m_eventListDialog)
|
||||
m_eventListDialog = new EventListDialog(Core::ICore::dialogParent());
|
||||
|
||||
m_eventlist.initialize(this);
|
||||
m_eventListDialog->initialize(m_eventlist);
|
||||
m_eventListDialog->show();
|
||||
});
|
||||
designerActionManager.addDesignerAction(eventListAction);
|
||||
|
||||
auto assignEventAction = new AssignEventEditorAction();
|
||||
connect(assignEventAction->defaultAction(), &QAction::triggered, [this]() {
|
||||
if (!m_assigner)
|
||||
m_assigner = new AssignEventDialog(Core::ICore::dialogParent());
|
||||
if (!m_eventListDialog)
|
||||
m_eventListDialog = new EventListDialog(Core::ICore::dialogParent());
|
||||
|
||||
m_eventlist.initialize(this);
|
||||
m_eventListDialog->initialize(m_eventlist);
|
||||
m_assigner->initialize(m_eventlist);
|
||||
m_assigner->show();
|
||||
m_assigner->postShow();
|
||||
});
|
||||
designerActionManager.addDesignerAction(assignEventAction);
|
||||
|
||||
auto *connectSignalAction = new ConnectSignalAction();
|
||||
|
||||
connect(connectSignalAction->defaultAction(), &QAction::triggered, [this, connectSignalAction]() {
|
||||
if (!m_signalConnector)
|
||||
m_signalConnector = new ConnectSignalDialog(Core::ICore::dialogParent());
|
||||
|
||||
if (!m_eventListDialog)
|
||||
m_eventListDialog = new EventListDialog(Core::ICore::dialogParent());
|
||||
|
||||
m_eventlist.initialize(this);
|
||||
m_eventListDialog->initialize(m_eventlist);
|
||||
|
||||
if (auto signal = signalPropertyFromAction(connectSignalAction); signal.isValid()) {
|
||||
m_signalConnector->initialize(m_eventlist, signal);
|
||||
m_signalConnector->show();
|
||||
}
|
||||
});
|
||||
designerActionManager.addDesignerAction(connectSignalAction);
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner
|
@@ -0,0 +1,50 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd
|
||||
** All rights reserved.
|
||||
** For any questions to The Qt Company, please use contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
** This file is part of the Qt Event List module.
|
||||
**
|
||||
** 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 The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please use
|
||||
** contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "eventlist.h"
|
||||
#include <abstractview.h>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class EventListDialog;
|
||||
class AssignEventDialog;
|
||||
class ConnectSignalDialog;
|
||||
|
||||
class EventListPluginView : public AbstractView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
EventListPluginView(QObject* parent = nullptr);
|
||||
~EventListPluginView() override = default;
|
||||
|
||||
void registerActions();
|
||||
|
||||
private:
|
||||
EventList m_eventlist;
|
||||
EventListDialog *m_eventListDialog = nullptr;
|
||||
AssignEventDialog *m_assigner = nullptr;
|
||||
ConnectSignalDialog *m_signalConnector = nullptr;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
145
src/plugins/qmldesigner/components/eventlist/eventlistutils.cpp
Normal file
145
src/plugins/qmldesigner/components/eventlist/eventlistutils.cpp
Normal file
@@ -0,0 +1,145 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd
|
||||
** All rights reserved.
|
||||
** For any questions to The Qt Company, please use contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
** This file is part of the Qt Event List module.
|
||||
**
|
||||
** 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 The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please use
|
||||
** contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
******************************************************************************/
|
||||
|
||||
#include "eventlistutils.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QKeyEvent>
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QStandardItemModel>
|
||||
#include <QTableView>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
TabWalker::TabWalker(QObject *parent)
|
||||
: QObject(parent)
|
||||
{}
|
||||
|
||||
bool TabWalker::eventFilter(QObject *obj, QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::KeyPress) {
|
||||
auto *keyEvent = static_cast<QKeyEvent *>(event);
|
||||
if (keyEvent->key() == Qt::Key_Tab || keyEvent->key() == Qt::Key_Backtab) {
|
||||
keyEvent->accept();
|
||||
int mapped = keyEvent->key() == Qt::Key_Tab ? Qt::Key_Down : Qt::Key_Up;
|
||||
int modifiers = keyEvent->nativeModifiers() & (~Qt::ShiftModifier);
|
||||
QApplication::postEvent(obj,
|
||||
new QKeyEvent(QEvent::KeyPress,
|
||||
mapped,
|
||||
static_cast<Qt::KeyboardModifier>(modifiers),
|
||||
keyEvent->nativeScanCode(),
|
||||
keyEvent->nativeVirtualKey(),
|
||||
keyEvent->nativeModifiers(),
|
||||
keyEvent->text(),
|
||||
keyEvent->isAutoRepeat(),
|
||||
keyEvent->count()));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return QObject::eventFilter(obj, event);
|
||||
}
|
||||
|
||||
QStandardItemModel *sourceModel(QAbstractItemModel *model)
|
||||
{
|
||||
if (auto *proxy = qobject_cast<QSortFilterProxyModel *>(model))
|
||||
return sourceModel(proxy->sourceModel());
|
||||
|
||||
return qobject_cast<QStandardItemModel *>(model);
|
||||
}
|
||||
|
||||
QString uniqueName(QAbstractItemModel *model, const QString &base)
|
||||
{
|
||||
if (auto *m = sourceModel(model)) {
|
||||
QList<QStandardItem *> items = m->findItems(base);
|
||||
if (items.empty())
|
||||
return base;
|
||||
|
||||
int idx = 0;
|
||||
while (true) {
|
||||
QString tmp = base + QString::number(idx++);
|
||||
items = m->findItems(tmp);
|
||||
if (items.empty())
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
std::string toString(AbstractView::PropertyChangeFlags flags)
|
||||
{
|
||||
if (flags == 0)
|
||||
return std::string("NoAdditionalChanges");
|
||||
|
||||
std::string out;
|
||||
if ((flags & AbstractView::NoAdditionalChanges) != 0)
|
||||
out += "NoAdditionalChanges ";
|
||||
|
||||
if ((flags & AbstractView::PropertiesAdded) != 0) {
|
||||
if (!out.empty())
|
||||
out += "| ";
|
||||
|
||||
out += "PropertiesAdded ";
|
||||
}
|
||||
|
||||
if ((flags & AbstractView::EmptyPropertiesRemoved) != 0) {
|
||||
if (!out.empty())
|
||||
out += "| ";
|
||||
|
||||
out += "EmptyPropertiesRemoved ";
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
void polishPalette(QTableView *view, const QColor &selectionColor)
|
||||
{
|
||||
QPalette p = view->palette();
|
||||
p.setColor(QPalette::AlternateBase, p.color(QPalette::Base).lighter(120));
|
||||
p.setColor(QPalette::Highlight, selectionColor);
|
||||
view->setPalette(p);
|
||||
view->setAlternatingRowColors(true);
|
||||
}
|
||||
|
||||
void printPropertyType(const ModelNode &node, const PropertyName &name)
|
||||
{
|
||||
std::string sname = name.toStdString();
|
||||
|
||||
auto prop = node.property(name);
|
||||
if (prop.isNodeProperty())
|
||||
printf("Property %s is a node-property\n", sname.c_str());
|
||||
|
||||
if (prop.isVariantProperty())
|
||||
printf("Property %s is a variant-property\n", sname.c_str());
|
||||
|
||||
if (prop.isNodeListProperty())
|
||||
printf("Property %s is a node-list-property\n", sname.c_str());
|
||||
|
||||
if (prop.isNodeAbstractProperty())
|
||||
printf("Property %s is a node-abstract-property\n", sname.c_str());
|
||||
|
||||
if (prop.isBindingProperty())
|
||||
printf("Property %s is a binding-property\n", sname.c_str());
|
||||
|
||||
if (prop.isSignalHandlerProperty())
|
||||
printf("Property %s is a signal-handler-property\n", sname.c_str());
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner.
|
@@ -0,0 +1,49 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd
|
||||
** All rights reserved.
|
||||
** For any questions to The Qt Company, please use contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
** This file is part of the Qt Event List module.
|
||||
**
|
||||
** 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 The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please use
|
||||
** contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "abstractview.h"
|
||||
#include <string>
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QAbstractItemModel)
|
||||
QT_FORWARD_DECLARE_CLASS(QTableView)
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class TabWalker : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TabWalker(QObject *parent = nullptr);
|
||||
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||
};
|
||||
|
||||
QString uniqueName(QAbstractItemModel *model, const QString &base);
|
||||
|
||||
std::string toString(AbstractView::PropertyChangeFlags flags);
|
||||
|
||||
void polishPalette(QTableView *view, const QColor &selectionColor);
|
||||
|
||||
void printPropertyType(const ModelNode &node, const PropertyName &name);
|
||||
|
||||
} // namespace QmlDesigner.
|
198
src/plugins/qmldesigner/components/eventlist/eventlistview.cpp
Normal file
198
src/plugins/qmldesigner/components/eventlist/eventlistview.cpp
Normal file
@@ -0,0 +1,198 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd
|
||||
** All rights reserved.
|
||||
** For any questions to The Qt Company, please use contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
** This file is part of the Qt Event List module.
|
||||
**
|
||||
** 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 The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please use
|
||||
** contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
******************************************************************************/
|
||||
#include "eventlistview.h"
|
||||
|
||||
#include "assigneventdialog.h"
|
||||
#include "connectsignaldialog.h"
|
||||
#include "eventlistactions.h"
|
||||
#include "eventlistdialog.h"
|
||||
#include "nodelistproperty.h"
|
||||
#include "nodeproperty.h"
|
||||
#include "variantproperty.h"
|
||||
#include <coreplugin/icore.h>
|
||||
#include <componentcore/componentcore_constants.h>
|
||||
|
||||
#include <QPushButton>
|
||||
#include <QStandardItemModel>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
EventListModel::EventListModel(QObject *parent)
|
||||
: QStandardItemModel(0, 4, parent)
|
||||
{
|
||||
setHeaderData(idColumn, Qt::Horizontal, tr("Event ID"));
|
||||
setHeaderData(shortcutColumn, Qt::Horizontal, tr("Shortcut"));
|
||||
setHeaderData(descriptionColumn, Qt::Horizontal, tr("Description"));
|
||||
setHeaderData(connectColumn, Qt::Horizontal, tr(""));
|
||||
}
|
||||
|
||||
QStringList EventListModel::connectedEvents() const
|
||||
{
|
||||
QStringList out;
|
||||
for (int row = 0; row < rowCount(); ++row) {
|
||||
if (auto idx = index(row, EventListModel::idColumn); idx.isValid()) {
|
||||
if (idx.data(EventListModel::connectedRole).toBool())
|
||||
out << idx.data().toString();
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
QStringList EventListModel::connectEvents(const QStringList &eventIds)
|
||||
{
|
||||
auto out = eventIds;
|
||||
for (int row = 0; row < rowCount(); ++row) {
|
||||
auto nameIndex = index(row, EventListModel::idColumn);
|
||||
bool connected = out.removeOne(nameIndex.data().toString());
|
||||
for (int col = 0; col < columnCount(); col++)
|
||||
setData(index(row, col), connected, EventListModel::connectedRole);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
EventListView::EventListView(QObject *parent)
|
||||
: AbstractView(parent)
|
||||
, m_eventlist()
|
||||
, m_model(new EventListModel(this))
|
||||
{}
|
||||
|
||||
EventListView::~EventListView() {}
|
||||
|
||||
void EventListView::nodeRemoved(const ModelNode &removedNode,
|
||||
const NodeAbstractProperty &parentProperty,
|
||||
PropertyChangeFlags propertyChange)
|
||||
{
|
||||
AbstractView::nodeRemoved(removedNode, parentProperty, propertyChange);
|
||||
reset();
|
||||
}
|
||||
|
||||
void EventListView::nodeReparented(const ModelNode &node,
|
||||
const NodeAbstractProperty &newPropertyParent,
|
||||
const NodeAbstractProperty &oldPropertyParent,
|
||||
PropertyChangeFlags propertyChange)
|
||||
{
|
||||
AbstractView::nodeReparented(node, newPropertyParent, oldPropertyParent, propertyChange);
|
||||
reset();
|
||||
}
|
||||
|
||||
EventListModel *EventListView::eventListModel() const
|
||||
{
|
||||
return m_model;
|
||||
}
|
||||
|
||||
void EventListView::addEvent(const Event &event)
|
||||
{
|
||||
executeInTransaction("EventListView::addEvent", [=]() {
|
||||
|
||||
QByteArray unqualifiedTypeName = "ListElement";
|
||||
auto metaInfo = model()->metaInfo(unqualifiedTypeName);
|
||||
|
||||
QByteArray fullTypeName = metaInfo.typeName();
|
||||
int minorVersion = metaInfo.minorVersion();
|
||||
int majorVersion = metaInfo.majorVersion();
|
||||
|
||||
ModelNode eventNode = createModelNode(fullTypeName, majorVersion, minorVersion);
|
||||
eventNode.variantProperty("eventId").setValue(event.eventId);
|
||||
|
||||
if (!event.shortcut.isEmpty())
|
||||
eventNode.variantProperty("shortcut").setValue(event.shortcut);
|
||||
|
||||
if (!event.description.isEmpty())
|
||||
eventNode.variantProperty("eventDescription").setValue(event.description);
|
||||
|
||||
rootModelNode().defaultNodeListProperty().reparentHere(eventNode);
|
||||
});
|
||||
}
|
||||
|
||||
void EventListView::removeEvent(const QString &eventId)
|
||||
{
|
||||
executeInTransaction("EventListView::removeEvent", [=]() {
|
||||
for (auto node : rootModelNode().defaultNodeListProperty().toModelNodeList()) {
|
||||
if (node.variantProperty("eventId").value().toString() == eventId) {
|
||||
node.destroy();
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void EventListView::renameEvent(const QString &oldId, const QString &newId)
|
||||
{
|
||||
executeInTransaction("EventListView::renameEvent", [=]() {
|
||||
for (auto node : rootModelNode().defaultNodeListProperty().toModelNodeList()) {
|
||||
if (node.variantProperty("eventId").value().toString() == oldId) {
|
||||
node.variantProperty("eventId").setValue(newId);
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void EventListView::setShortcut(const QString &id, const QString &text)
|
||||
{
|
||||
executeInTransaction("EventListView::setShortcut", [=]() {
|
||||
for (auto node : rootModelNode().defaultNodeListProperty().toModelNodeList()) {
|
||||
if (node.variantProperty("eventId").value().toString() == id) {
|
||||
node.variantProperty("shortcut").setValue(text);
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void EventListView::setDescription(const QString &id, const QString &text)
|
||||
{
|
||||
executeInTransaction("EventListView::setDescription", [=]() {
|
||||
for (auto node : rootModelNode().defaultNodeListProperty().toModelNodeList()) {
|
||||
if (node.variantProperty("eventId").value().toString() == id) {
|
||||
node.variantProperty("eventDescription").setValue(text);
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void EventListView::reset()
|
||||
{
|
||||
auto setData = [this](int row, int column, const QVariant &data) {
|
||||
QModelIndex idx = m_model->index(row, column, QModelIndex());
|
||||
m_model->setData(idx, data);
|
||||
};
|
||||
|
||||
if (rootModelNode().isValid()) {
|
||||
m_model->removeRows(0, m_model->rowCount(QModelIndex()), QModelIndex());
|
||||
for (auto itemNode : rootModelNode().directSubModelNodes()) {
|
||||
int row = m_model->rowCount();
|
||||
if (m_model->insertRows(row, 1, QModelIndex())) {
|
||||
QVariant eventId = itemNode.variantProperty("eventId").value();
|
||||
QVariant eventShortcut = itemNode.variantProperty("shortcut").value();
|
||||
QVariant eventDescription = itemNode.variantProperty("eventDescription").value();
|
||||
|
||||
setData(row, EventListModel::idColumn, eventId);
|
||||
setData(row, EventListModel::shortcutColumn, eventShortcut);
|
||||
setData(row, EventListModel::descriptionColumn, eventDescription);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner.
|
98
src/plugins/qmldesigner/components/eventlist/eventlistview.h
Normal file
98
src/plugins/qmldesigner/components/eventlist/eventlistview.h
Normal file
@@ -0,0 +1,98 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd
|
||||
** All rights reserved.
|
||||
** For any questions to The Qt Company, please use contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
** This file is part of the Qt Event List module.
|
||||
**
|
||||
** 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 The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please use
|
||||
** contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "eventlist.h"
|
||||
|
||||
#include <abstractview.h>
|
||||
#include <QStandardItemModel>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
struct Event
|
||||
{
|
||||
QString eventId;
|
||||
QString shortcut;
|
||||
QString description;
|
||||
};
|
||||
|
||||
class EventListModel : public QStandardItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum Columns {
|
||||
idColumn = 0,
|
||||
descriptionColumn = 1,
|
||||
shortcutColumn = 2,
|
||||
connectColumn = 3
|
||||
};
|
||||
|
||||
enum Roles : unsigned int {
|
||||
connectedRole = Qt::UserRole + 1,
|
||||
};
|
||||
|
||||
EventListModel(QObject *parent = nullptr);
|
||||
|
||||
QStringList connectedEvents() const;
|
||||
|
||||
QStringList connectEvents(const QStringList &eventIds);
|
||||
};
|
||||
|
||||
|
||||
class EventListDialog;
|
||||
class AssignEventDialog;
|
||||
class ConnectSignalDialog;
|
||||
|
||||
class EventListView : public AbstractView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit EventListView(QObject *parent = nullptr);
|
||||
~EventListView() override;
|
||||
|
||||
void nodeRemoved(const ModelNode &removedNode,
|
||||
const NodeAbstractProperty &parentProperty,
|
||||
PropertyChangeFlags propertyChange) override;
|
||||
|
||||
void nodeReparented(const ModelNode &node,
|
||||
const NodeAbstractProperty &newPropertyParent,
|
||||
const NodeAbstractProperty &oldPropertyParent,
|
||||
PropertyChangeFlags propertyChange) override;
|
||||
|
||||
EventListModel *eventListModel() const;
|
||||
|
||||
void addEvent(const Event &event);
|
||||
void removeEvent(const QString &name);
|
||||
void renameEvent(const QString &oldId, const QString &newId);
|
||||
void setShortcut(const QString &id, const QString &text);
|
||||
void setDescription(const QString &id, const QString &text);
|
||||
|
||||
private:
|
||||
void reset();
|
||||
|
||||
EventList m_eventlist;
|
||||
EventListModel *m_model;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner.
|
@@ -0,0 +1,64 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd
|
||||
** All rights reserved.
|
||||
** For any questions to The Qt Company, please use contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
** This file is part of the Qt Event List module.
|
||||
**
|
||||
** 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 The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please use
|
||||
** contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
******************************************************************************/
|
||||
#include "filterlinewidget.h"
|
||||
|
||||
#include <theme.h>
|
||||
#include <utils/fancylineedit.h>
|
||||
#include <utils/stylehelper.h>
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QIcon>
|
||||
#include <QLabel>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
FilterLineWidget::FilterLineWidget(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_edit(new Utils::FancyLineEdit())
|
||||
{
|
||||
const QString unicode = Theme::getIconUnicode(Theme::Icon::search);
|
||||
const QString fontName = "qtds_propertyIconFont.ttf";
|
||||
QIcon icon = Utils::StyleHelper::getIconFromIconFont(fontName, unicode, 28, 28);
|
||||
|
||||
auto *label = new QLabel;
|
||||
label->setPixmap(icon.pixmap(QSize(18, 18)));
|
||||
label->setAlignment(Qt::AlignCenter);
|
||||
|
||||
m_edit->setPlaceholderText(QObject::tr("<Filter>", "Library search input hint text"));
|
||||
m_edit->setDragEnabled(false);
|
||||
m_edit->setMinimumWidth(75);
|
||||
m_edit->setTextMargins(0, 0, 20, 0);
|
||||
m_edit->setFiltering(true);
|
||||
|
||||
auto *box = new QHBoxLayout;
|
||||
box->addWidget(label);
|
||||
box->addWidget(m_edit);
|
||||
setLayout(box);
|
||||
|
||||
connect(m_edit, &Utils::FancyLineEdit::filterChanged, this, &FilterLineWidget::filterChanged);
|
||||
}
|
||||
|
||||
void FilterLineWidget::clear()
|
||||
{
|
||||
m_edit->clear();
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner.
|
@@ -0,0 +1,47 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd
|
||||
** All rights reserved.
|
||||
** For any questions to The Qt Company, please use contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
** This file is part of the Qt Event List module.
|
||||
**
|
||||
** 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 The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please use
|
||||
** contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
******************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
namespace Utils {
|
||||
class FancyLineEdit;
|
||||
}
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class FilterLineWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
signals:
|
||||
void filterChanged(const QString &filter);
|
||||
|
||||
public:
|
||||
FilterLineWidget(QWidget *parent = nullptr);
|
||||
|
||||
void clear();
|
||||
|
||||
private:
|
||||
Utils::FancyLineEdit *m_edit;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner.
|
@@ -0,0 +1,86 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd
|
||||
** All rights reserved.
|
||||
** For any questions to The Qt Company, please use contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
** This file is part of the Qt Event List module.
|
||||
**
|
||||
** 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 The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please use
|
||||
** contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
******************************************************************************/
|
||||
#include "nodelistdelegate.h"
|
||||
#include "eventlist.h"
|
||||
#include "eventlistview.h"
|
||||
#include "nodelistview.h"
|
||||
#include "qnamespace.h"
|
||||
#include "shortcutwidget.h"
|
||||
#include "eventlistutils.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QFocusEvent>
|
||||
#include <QLineEdit>
|
||||
#include <QPainter>
|
||||
#include <QPushButton>
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QStyleOptionButton>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
NodeListDelegate::NodeListDelegate(QObject *parent)
|
||||
: QStyledItemDelegate(parent)
|
||||
{}
|
||||
|
||||
void NodeListDelegate::setModelData(QWidget *editor,
|
||||
QAbstractItemModel *model,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
if (index.column() == NodeListModel::idColumn) {
|
||||
if (auto *edit = qobject_cast<QLineEdit *>(editor)) {
|
||||
QVariant iidVariant = index.data(NodeListModel::internalIdRole);
|
||||
if (iidVariant.isValid()) {
|
||||
QString verifiedId = EventList::setNodeId(iidVariant.toInt(), edit->text());
|
||||
if (!verifiedId.isNull())
|
||||
edit->setText(verifiedId);
|
||||
else
|
||||
edit->setText("");
|
||||
}
|
||||
}
|
||||
}
|
||||
QStyledItemDelegate::setModelData(editor, model, index);
|
||||
}
|
||||
|
||||
bool NodeListDelegate::eventFilter(QObject *editor, QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::KeyPress) {
|
||||
int key = static_cast<QKeyEvent *>(event)->key();
|
||||
if (key == Qt::Key_Tab || key == Qt::Key_Backtab)
|
||||
return false;
|
||||
}
|
||||
return QStyledItemDelegate::eventFilter(editor, event);
|
||||
}
|
||||
|
||||
void NodeListDelegate::commitAndClose()
|
||||
{
|
||||
if (auto *editor = qobject_cast<ShortcutWidget *>(sender())) {
|
||||
emit commitData(editor);
|
||||
emit closeEditor(editor);
|
||||
}
|
||||
}
|
||||
|
||||
void NodeListDelegate::close()
|
||||
{
|
||||
if (auto *editor = qobject_cast<ShortcutWidget *>(sender()))
|
||||
emit closeEditor(editor);
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner.
|
@@ -0,0 +1,43 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd
|
||||
** All rights reserved.
|
||||
** For any questions to The Qt Company, please use contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
** This file is part of the Qt Event List module.
|
||||
**
|
||||
** 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 The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please use
|
||||
** contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
******************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <QStyledItemDelegate>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class NodeListDelegate : public QStyledItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
NodeListDelegate(QObject *parent = nullptr);
|
||||
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override;
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *editor, QEvent *event) override;
|
||||
|
||||
private:
|
||||
void close();
|
||||
void commitAndClose();
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner.
|
246
src/plugins/qmldesigner/components/eventlist/nodelistview.cpp
Normal file
246
src/plugins/qmldesigner/components/eventlist/nodelistview.cpp
Normal file
@@ -0,0 +1,246 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd
|
||||
** All rights reserved.
|
||||
** For any questions to The Qt Company, please use contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
** This file is part of the Qt Event List module.
|
||||
**
|
||||
** 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 The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please use
|
||||
** contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
******************************************************************************/
|
||||
#include "nodelistview.h"
|
||||
#include "eventlist.h"
|
||||
|
||||
#include "bindingproperty.h"
|
||||
#include "nodemetainfo.h"
|
||||
#include "utils/qtcassert.h"
|
||||
#include "variantproperty.h"
|
||||
|
||||
#include <QStandardItemModel>
|
||||
|
||||
#include <theme.h>
|
||||
#include <utils/stylehelper.h>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
QStringList eventIdsFromVariant(const QVariant &val)
|
||||
{
|
||||
QStringList eventIds = val.toString().split(",", Qt::SkipEmptyParts);
|
||||
for (QString &str : eventIds)
|
||||
str = str.trimmed();
|
||||
return eventIds;
|
||||
}
|
||||
|
||||
QVariant eventIdsToVariant(const QStringList &eventIds)
|
||||
{
|
||||
if (eventIds.empty())
|
||||
return QVariant();
|
||||
|
||||
return QVariant(eventIds.join(", "));
|
||||
}
|
||||
|
||||
NodeListModel::NodeListModel(QObject *parent)
|
||||
: QStandardItemModel(0, 4, parent)
|
||||
{
|
||||
setHeaderData(idColumn, Qt::Horizontal, tr("Id"));
|
||||
setHeaderData(typeColumn, Qt::Horizontal, tr("Type"));
|
||||
setHeaderData(fromColumn, Qt::Horizontal, tr("From"));
|
||||
setHeaderData(toColumn, Qt::Horizontal, tr("To"));
|
||||
setSortRole(internalIdRole);
|
||||
}
|
||||
|
||||
|
||||
NodeListView::NodeListView(AbstractView *parent)
|
||||
: AbstractView(parent)
|
||||
, m_itemModel(new NodeListModel(this))
|
||||
{
|
||||
parent->model()->attachView(this);
|
||||
reset();
|
||||
}
|
||||
|
||||
NodeListView::~NodeListView() {}
|
||||
|
||||
QStandardItemModel *NodeListView::itemModel() const
|
||||
{
|
||||
return m_itemModel;
|
||||
}
|
||||
|
||||
int NodeListView::currentNode() const
|
||||
{
|
||||
ModelNode node = firstSelectedModelNode();
|
||||
if (node.isValid())
|
||||
return node.internalId();
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void NodeListView::selectNode(int internalId)
|
||||
{
|
||||
ModelNode node = modelNodeForInternalId(internalId);
|
||||
if (node.isValid()) {
|
||||
clearSelectedModelNodes();
|
||||
selectModelNode(node);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QModelIndex indexByInternalId(QAbstractItemModel *model, int id)
|
||||
{
|
||||
constexpr int count = 1;
|
||||
auto ids = model->match(model->index(0, NodeListModel::idColumn),
|
||||
NodeListModel::internalIdRole,
|
||||
id,
|
||||
count,
|
||||
Qt::MatchExactly);
|
||||
if (ids.size() == count)
|
||||
return ids.first();
|
||||
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
bool NodeListView::addEventId(int nodeId, const QString &event)
|
||||
{
|
||||
if (auto node = compatibleModelNode(nodeId); node.isValid()) {
|
||||
QStringList events;
|
||||
if (node.hasProperty("eventIds"))
|
||||
events = eventIdsFromVariant(node.variantProperty("eventIds").value());
|
||||
events.push_back(event);
|
||||
|
||||
return setEventIds(node, events);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NodeListView::removeEventIds(int nodeId, const QStringList &eventIds)
|
||||
{
|
||||
if (auto node = compatibleModelNode(nodeId); node.isValid()) {
|
||||
QStringList events = eventIdsFromVariant(node.variantProperty("eventIds").value());
|
||||
for (auto &&remove : eventIds)
|
||||
Q_UNUSED(events.removeOne(remove));
|
||||
|
||||
return setEventIds(node, events);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QString NodeListView::setNodeId(int internalId, const QString &id)
|
||||
{
|
||||
ModelNode node = modelNodeForInternalId(internalId);
|
||||
if (node.isValid()) {
|
||||
QString newId = generateNewId(id);
|
||||
node.setIdWithRefactoring(newId);
|
||||
return newId;
|
||||
}
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
bool supported(const ModelNode &node)
|
||||
{
|
||||
if (!node.isValid())
|
||||
return false;
|
||||
|
||||
const NodeMetaInfo metaInfo = node.metaInfo();
|
||||
if (!metaInfo.isValid())
|
||||
return false;
|
||||
|
||||
return metaInfo.hasProperty("eventIds");
|
||||
}
|
||||
|
||||
static QIcon flowTypeIconFromFont(const TypeName &type)
|
||||
{
|
||||
QString unicode = Theme::getIconUnicode(Theme::Icon::edit);
|
||||
const QString fontName = "qtds_propertyIconFont.ttf";
|
||||
if (type == "FlowView.FlowTransition")
|
||||
unicode = Theme::getIconUnicode(Theme::Icon::flowTransition);
|
||||
else if (type == "FlowView.FlowActionArea")
|
||||
unicode = Theme::getIconUnicode(Theme::Icon::flowAction);
|
||||
else if (type == "FlowView.FlowWildcard")
|
||||
unicode = Theme::getIconUnicode(Theme::Icon::wildcard);
|
||||
|
||||
return Utils::StyleHelper::getIconFromIconFont(fontName, unicode, 28, 28);
|
||||
}
|
||||
|
||||
void NodeListView::reset()
|
||||
{
|
||||
auto setData = [this](int row, int column, const QVariant &data, int role = Qt::EditRole) {
|
||||
QModelIndex idx = m_itemModel->index(row, column, QModelIndex());
|
||||
m_itemModel->setData(idx, data, role);
|
||||
};
|
||||
|
||||
m_itemModel->removeRows(0, m_itemModel->rowCount(QModelIndex()), QModelIndex());
|
||||
|
||||
for (auto &&node : allModelNodes()) {
|
||||
if (supported(node)) {
|
||||
int row = m_itemModel->rowCount();
|
||||
if (m_itemModel->insertRows(row, 1, QModelIndex())) {
|
||||
int iid = node.internalId();
|
||||
auto eventIds = eventIdsFromVariant(node.variantProperty("eventIds").value());
|
||||
|
||||
setData(row, NodeListModel::idColumn, node.id());
|
||||
setData(row,
|
||||
NodeListModel::idColumn,
|
||||
flowTypeIconFromFont(node.type()),
|
||||
Qt::DecorationRole);
|
||||
setData(row, NodeListModel::idColumn, iid, NodeListModel::internalIdRole);
|
||||
setData(row, NodeListModel::idColumn, eventIds, NodeListModel::eventIdsRole);
|
||||
|
||||
setData(row, NodeListModel::typeColumn, node.type());
|
||||
setData(row, NodeListModel::fromColumn, node.bindingProperty("from").expression());
|
||||
setData(row, NodeListModel::toColumn, node.bindingProperty("to").expression());
|
||||
}
|
||||
}
|
||||
}
|
||||
m_itemModel->sort(0);
|
||||
}
|
||||
|
||||
ModelNode NodeListView::compatibleModelNode(int nodeId)
|
||||
{
|
||||
if (auto node = modelNodeForInternalId(nodeId); node.isValid()) {
|
||||
QTC_ASSERT(node.metaInfo().isValid(), return ModelNode());
|
||||
QTC_ASSERT(node.metaInfo().hasProperty("eventIds"), return ModelNode());
|
||||
return node;
|
||||
}
|
||||
return ModelNode();
|
||||
}
|
||||
|
||||
bool setEventIdsInModelNode(AbstractView *view, const ModelNode &node, const QStringList &events)
|
||||
{
|
||||
if (events.empty()) {
|
||||
if (node.hasProperty("eventIds")) {
|
||||
return view->executeInTransaction("NodeListView::setEventIds",
|
||||
[=]() { node.removeProperty("eventIds"); });
|
||||
}
|
||||
} else {
|
||||
QStringList copy(events);
|
||||
Q_UNUSED(copy.removeDuplicates());
|
||||
QString value = events.join(", ");
|
||||
return view->executeInTransaction("NodeListView::setEventIds", [=]() {
|
||||
node.variantProperty("eventIds").setValue(value);
|
||||
});
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NodeListView::setEventIds(const ModelNode &node, const QStringList &events)
|
||||
{
|
||||
bool result = setEventIdsInModelNode(this, node, events);
|
||||
auto modelIndex = indexByInternalId(m_itemModel, node.internalId());
|
||||
if (modelIndex.isValid() && result) {
|
||||
m_itemModel->setData(modelIndex, events, NodeListModel::eventIdsRole);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner.
|
74
src/plugins/qmldesigner/components/eventlist/nodelistview.h
Normal file
74
src/plugins/qmldesigner/components/eventlist/nodelistview.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd
|
||||
** All rights reserved.
|
||||
** For any questions to The Qt Company, please use contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
** This file is part of the Qt Event List module.
|
||||
**
|
||||
** 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 The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please use
|
||||
** contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <abstractview.h>
|
||||
#include <QStandardItemModel>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class NodeListModel : public QStandardItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum Columns : unsigned int {
|
||||
idColumn = 0,
|
||||
typeColumn = 1,
|
||||
fromColumn = 2,
|
||||
toColumn = 3
|
||||
};
|
||||
|
||||
enum Roles : unsigned int {
|
||||
internalIdRole = Qt::UserRole + 1,
|
||||
eventIdsRole = Qt::UserRole + 2
|
||||
};
|
||||
|
||||
NodeListModel(QObject *parent = nullptr);
|
||||
};
|
||||
|
||||
|
||||
class NodeListView : public AbstractView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit NodeListView(AbstractView *parent);
|
||||
~NodeListView() override;
|
||||
|
||||
int currentNode() const;
|
||||
QStandardItemModel *itemModel() const;
|
||||
|
||||
void reset();
|
||||
void selectNode(int internalId);
|
||||
bool addEventId(int nodeId, const QString &event);
|
||||
bool removeEventIds(int nodeId, const QStringList &events);
|
||||
QString setNodeId(int internalId, const QString &id);
|
||||
|
||||
private:
|
||||
ModelNode compatibleModelNode(int nodeId);
|
||||
bool setEventIds(const ModelNode &node, const QStringList &events);
|
||||
|
||||
QStandardItemModel *m_itemModel;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner.
|
@@ -0,0 +1,91 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd
|
||||
** All rights reserved.
|
||||
** For any questions to The Qt Company, please use contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
** This file is part of the Qt Event List module.
|
||||
**
|
||||
** 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 The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please use
|
||||
** contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
******************************************************************************/
|
||||
#include "nodeselectionmodel.h"
|
||||
#include "eventlist.h"
|
||||
#include "nodelistview.h"
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QStandardItemModel>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
NodeSelectionModel::NodeSelectionModel(QAbstractItemModel *model)
|
||||
: QItemSelectionModel(model)
|
||||
{}
|
||||
|
||||
void NodeSelectionModel::select(const QItemSelection &selection,
|
||||
QItemSelectionModel::SelectionFlags command)
|
||||
{
|
||||
QItemSelectionModel::select(selection, command);
|
||||
|
||||
for (auto &&modelIndex : selection.indexes()) {
|
||||
if (modelIndex.column() == NodeListModel::idColumn) {
|
||||
int id = modelIndex.data(NodeListModel::internalIdRole).toInt();
|
||||
EventList::selectNode(id);
|
||||
emit nodeSelected(modelIndex.data(NodeListModel::eventIdsRole).toStringList());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QList<int> NodeSelectionModel::selectedNodes() const
|
||||
{
|
||||
QList<int> out;
|
||||
for (auto index : selectedRows())
|
||||
out.push_back(index.data(NodeListModel::internalIdRole).toInt());
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
void NodeSelectionModel::selectNode(int nodeId)
|
||||
{
|
||||
if (nodeId < 0) {
|
||||
clearSelection();
|
||||
return;
|
||||
}
|
||||
|
||||
if (auto *model = qobject_cast<QAbstractItemModel *>(this->model())) {
|
||||
auto start = model->index(0, 0);
|
||||
auto indexes = model->match(start,
|
||||
NodeListModel::internalIdRole,
|
||||
QString::number(nodeId),
|
||||
1,
|
||||
Qt::MatchExactly);
|
||||
|
||||
for (auto index : indexes)
|
||||
QItemSelectionModel::select(index, QItemSelectionModel::Rows | QItemSelectionModel::ClearAndSelect);
|
||||
}
|
||||
}
|
||||
|
||||
void NodeSelectionModel::storeSelection()
|
||||
{
|
||||
if (const auto *proxyModel = qobject_cast<const QSortFilterProxyModel *>(model())) {
|
||||
if (hasSelection())
|
||||
m_stored = proxyModel->mapSelectionToSource(selection());
|
||||
}
|
||||
}
|
||||
|
||||
void NodeSelectionModel::reselect()
|
||||
{
|
||||
if (const auto *proxyModel = qobject_cast<const QSortFilterProxyModel *>(model()))
|
||||
select(proxyModel->mapSelectionFromSource(m_stored),
|
||||
QItemSelectionModel::Select | QItemSelectionModel::Rows);
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner.
|
@@ -0,0 +1,49 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd
|
||||
** All rights reserved.
|
||||
** For any questions to The Qt Company, please use contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
** This file is part of the Qt Event List module.
|
||||
**
|
||||
** 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 The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please use
|
||||
** contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
******************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <QItemSelectionModel>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class NodeSelectionModel : public QItemSelectionModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
signals:
|
||||
void nodeSelected(const QStringList &events);
|
||||
|
||||
public:
|
||||
NodeSelectionModel(QAbstractItemModel *model);
|
||||
|
||||
void select(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command) override;
|
||||
|
||||
QList<int> selectedNodes() const;
|
||||
void selectNode(int nodeId);
|
||||
|
||||
void storeSelection();
|
||||
void reselect();
|
||||
|
||||
private:
|
||||
QItemSelection m_stored;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner.
|
114
src/plugins/qmldesigner/components/eventlist/shortcutwidget.cpp
Normal file
114
src/plugins/qmldesigner/components/eventlist/shortcutwidget.cpp
Normal file
@@ -0,0 +1,114 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd
|
||||
** All rights reserved.
|
||||
** For any questions to The Qt Company, please use contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
** This file is part of the Qt Event List module.
|
||||
**
|
||||
** 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 The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please use
|
||||
** contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
******************************************************************************/
|
||||
|
||||
#include "shortcutwidget.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLineEdit>
|
||||
#include <QPushButton>
|
||||
#include <QResizeEvent>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
ShortcutWidget::ShortcutWidget(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_text(new QLineEdit)
|
||||
, m_button(new QPushButton("R"))
|
||||
, m_key({{0, 0, 0, 0}})
|
||||
, m_keyNum(0)
|
||||
{
|
||||
connect(m_button, &QPushButton::pressed, this, &ShortcutWidget::done);
|
||||
|
||||
auto *box = new QHBoxLayout;
|
||||
box->setContentsMargins(0, 0, 0, 0);
|
||||
box->setSpacing(0);
|
||||
box->addWidget(m_text);
|
||||
box->addWidget(m_button);
|
||||
setLayout(box);
|
||||
|
||||
m_text->setReadOnly(true);
|
||||
m_text->setFocusPolicy(Qt::NoFocus);
|
||||
}
|
||||
|
||||
bool ShortcutWidget::containsFocus() const
|
||||
{
|
||||
if (auto *fw = QApplication::focusWidget())
|
||||
if (fw->parentWidget() == this)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
QString ShortcutWidget::text() const
|
||||
{
|
||||
return m_text->text();
|
||||
}
|
||||
|
||||
void ShortcutWidget::reset()
|
||||
{
|
||||
emit cancel();
|
||||
}
|
||||
|
||||
void ShortcutWidget::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
QWidget::resizeEvent(event);
|
||||
int width = event->size().width();
|
||||
m_text->setFixedWidth(width * 3 / 4);
|
||||
m_button->setFixedWidth(width / 4);
|
||||
}
|
||||
|
||||
// Forked from qt-creator/shortcutsettings.cpp
|
||||
static int 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 ShortcutWidget::recordKeysequence(QKeyEvent *event)
|
||||
{
|
||||
int nextKey = event->key();
|
||||
if (m_keyNum > 3 || nextKey == Qt::Key_Control || nextKey == Qt::Key_Shift
|
||||
|| nextKey == Qt::Key_Meta || nextKey == Qt::Key_Alt) {
|
||||
return;
|
||||
}
|
||||
|
||||
nextKey |= translateModifiers(event->modifiers(), event->text());
|
||||
m_key[m_keyNum] = nextKey;
|
||||
m_keyNum++;
|
||||
event->accept();
|
||||
|
||||
auto sequence = QKeySequence(m_key[0], m_key[1], m_key[2], m_key[3]);
|
||||
m_text->setText(sequence.toString());
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner.
|
@@ -0,0 +1,57 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd
|
||||
** All rights reserved.
|
||||
** For any questions to The Qt Company, please use contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
** This file is part of the Qt Event List module.
|
||||
**
|
||||
** 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 The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please use
|
||||
** contact form at http://www.qt.io/contact-us
|
||||
**
|
||||
******************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <QWidget>
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QLineEdit)
|
||||
QT_FORWARD_DECLARE_CLASS(QPushButton)
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class ShortcutWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
signals:
|
||||
void done();
|
||||
void cancel();
|
||||
|
||||
public:
|
||||
ShortcutWidget(QWidget *parent = nullptr);
|
||||
bool containsFocus() const;
|
||||
QString text() const;
|
||||
|
||||
void reset();
|
||||
void recordKeysequence(QKeyEvent *event);
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
|
||||
private:
|
||||
QLineEdit *m_text;
|
||||
QPushButton *m_button;
|
||||
std::array<int, 4> m_key;
|
||||
int m_keyNum = 0;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner.
|
@@ -43,6 +43,7 @@
|
||||
#include <texttool/texttool.h>
|
||||
#include <timelineeditor/timelineview.h>
|
||||
#include <transitioneditor/transitioneditorview.h>
|
||||
#include <eventlist/eventlistpluginview.h>
|
||||
#include <pathtool/pathtool.h>
|
||||
|
||||
#include <qmljseditor/qmljseditor.h>
|
||||
@@ -254,6 +255,10 @@ bool QmlDesignerPlugin::delayedInitialize()
|
||||
|
||||
auto curveEditorView = new QmlDesigner::CurveEditorView;
|
||||
d->viewManager.registerViewTakingOwnership(curveEditorView);
|
||||
|
||||
auto eventlistView = new QmlDesigner::EventListPluginView;
|
||||
d->viewManager.registerViewTakingOwnership(eventlistView);
|
||||
eventlistView->registerActions();
|
||||
}
|
||||
|
||||
auto transitionEditorView = new QmlDesigner::TransitionEditorView;
|
||||
|
@@ -35,6 +35,7 @@ include(components/richtexteditor/richtexteditor.pri)
|
||||
include(components/transitioneditor/transitioneditor.pri)
|
||||
include(components/listmodeleditor/listmodeleditor.pri)
|
||||
include(components/previewtooltip/previewtooltipbackend.pri)
|
||||
include(components/eventlist/eventlistplugin.pri)
|
||||
|
||||
BUILD_PUPPET_IN_CREATOR_BINPATH = $$(BUILD_PUPPET_IN_CREATOR_BINPATH)
|
||||
!isEmpty(BUILD_PUPPET_IN_CREATOR_BINPATH) {
|
||||
|
@@ -51,6 +51,7 @@ Project {
|
||||
"components/integration",
|
||||
"components/propertyeditor",
|
||||
"components/edit3d",
|
||||
"components/eventlist",
|
||||
"components/formeditor",
|
||||
"components/itemlibrary",
|
||||
"components/navigator",
|
||||
@@ -841,8 +842,37 @@ Project {
|
||||
"curveeditor/detail/treemodel.h",
|
||||
"curveeditor/detail/treeview.cpp",
|
||||
"curveeditor/detail/treeview.h",
|
||||
"curveeditor/detail/utils.cpp",
|
||||
"curveeditor/detail/utils.h",
|
||||
"curveeditor/detail/curveeditorutils.cpp",
|
||||
"curveeditor/detail/curveeditorutils.h",
|
||||
"eventlist/assigneventdialog.cpp",
|
||||
"eventlist/assigneventdialog.h",
|
||||
"eventlist/connectsignaldialog.cpp",
|
||||
"eventlist/connectsignaldialog.h",
|
||||
"eventlist/eventlist.cpp",
|
||||
"eventlist/eventlist.h",
|
||||
"eventlist/eventlistactions.cpp",
|
||||
"eventlist/eventlistactions.h",
|
||||
"eventlist/eventlistdelegate.cpp",
|
||||
"eventlist/eventlistdelegate.h",
|
||||
"eventlist/eventlistdialog.cpp",
|
||||
"eventlist/eventlistdialog.h",
|
||||
"eventlist/eventlistplugin.qrc",
|
||||
"eventlist/eventlistpluginview.cpp",
|
||||
"eventlist/eventlistpluginview.h",
|
||||
"eventlist/eventlistutils.cpp",
|
||||
"eventlist/eventlistutils.h",
|
||||
"eventlist/eventlistview.cpp",
|
||||
"eventlist/eventlistview.h",
|
||||
"eventlist/filterlinewidget.cpp",
|
||||
"eventlist/filterlinewidget.h",
|
||||
"eventlist/nodelistdelegate.cpp",
|
||||
"eventlist/nodelistdelegate.h",
|
||||
"eventlist/nodelistview.cpp",
|
||||
"eventlist/nodelistview.h",
|
||||
"eventlist/nodeselectionmodel.cpp",
|
||||
"eventlist/nodeselectionmodel.h",
|
||||
"eventlist/shortcutwidget.cpp",
|
||||
"eventlist/shortcutwidget.h",
|
||||
"pathtool/controlpoint.cpp",
|
||||
"pathtool/controlpoint.h",
|
||||
"pathtool/cubicsegment.cpp",
|
||||
|
Reference in New Issue
Block a user