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/treeitemdelegate.cpp detail/treeitemdelegate.h
|
||||||
detail/treemodel.cpp detail/treemodel.h
|
detail/treemodel.cpp detail/treemodel.h
|
||||||
detail/treeview.cpp detail/treeview.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
|
# 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 flowConnectionCategory[] = "FlowConnection";
|
||||||
const char stackedContainerCategory[] = "StackedContainer";
|
const char stackedContainerCategory[] = "StackedContainer";
|
||||||
const char genericToolBarCategory[] = "GenericToolBar";
|
const char genericToolBarCategory[] = "GenericToolBar";
|
||||||
|
const char eventListCategory[] = "QmlEventList";
|
||||||
|
|
||||||
const char toFrontCommandId[] = "ToFront";
|
const char toFrontCommandId[] = "ToFront";
|
||||||
const char toBackCommandId[] = "ToBack";
|
const char toBackCommandId[] = "ToBack";
|
||||||
@@ -209,6 +210,7 @@ const int priorityGroupCategory = 140;
|
|||||||
const int priorityPositionCategory = 130;
|
const int priorityPositionCategory = 130;
|
||||||
const int priorityLayoutCategory = 120;
|
const int priorityLayoutCategory = 120;
|
||||||
const int priorityStackedContainerCategory = priorityLayoutCategory;
|
const int priorityStackedContainerCategory = priorityLayoutCategory;
|
||||||
|
const int priorityEventListCategory = 105;
|
||||||
const int priorityTopLevelSeperator = 100;
|
const int priorityTopLevelSeperator = 100;
|
||||||
const int priorityCustomActions = 80;
|
const int priorityCustomActions = 80;
|
||||||
const int priorityRefactoring = 60;
|
const int priorityRefactoring = 60;
|
||||||
|
@@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
#include "animationcurve.h"
|
#include "animationcurve.h"
|
||||||
#include "curvesegment.h"
|
#include "curvesegment.h"
|
||||||
#include "detail/utils.h"
|
#include "detail/curveeditorutils.h"
|
||||||
|
|
||||||
#include <QEasingCurve>
|
#include <QEasingCurve>
|
||||||
#include <QLineF>
|
#include <QLineF>
|
||||||
|
@@ -45,7 +45,7 @@ SOURCES += \
|
|||||||
$$PWD/detail/treeitemdelegate.cpp \
|
$$PWD/detail/treeitemdelegate.cpp \
|
||||||
$$PWD/detail/treemodel.cpp \
|
$$PWD/detail/treemodel.cpp \
|
||||||
$$PWD/detail/treeview.cpp \
|
$$PWD/detail/treeview.cpp \
|
||||||
$$PWD/detail/utils.cpp \
|
$$PWD/detail/curveeditorutils.cpp \
|
||||||
$$PWD/detail/axis.cpp \
|
$$PWD/detail/axis.cpp \
|
||||||
$$PWD/keyframe.cpp \
|
$$PWD/keyframe.cpp \
|
||||||
$$PWD/treeitem.cpp
|
$$PWD/treeitem.cpp
|
||||||
|
@@ -24,7 +24,7 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "curvesegment.h"
|
#include "curvesegment.h"
|
||||||
#include "detail/utils.h"
|
#include "detail/curveeditorutils.h"
|
||||||
|
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
#include <QEasingCurve>
|
#include <QEasingCurve>
|
||||||
|
@@ -26,7 +26,7 @@
|
|||||||
#include "animationcurve.h"
|
#include "animationcurve.h"
|
||||||
#include "graphicsscene.h"
|
#include "graphicsscene.h"
|
||||||
#include "keyframeitem.h"
|
#include "keyframeitem.h"
|
||||||
#include "utils.h"
|
#include "curveeditorutils.h"
|
||||||
|
|
||||||
#include <QEasingCurve>
|
#include <QEasingCurve>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
|
@@ -29,7 +29,7 @@
|
|||||||
#include "curveitem.h"
|
#include "curveitem.h"
|
||||||
#include "navigation2d.h"
|
#include "navigation2d.h"
|
||||||
#include "treeitem.h"
|
#include "treeitem.h"
|
||||||
#include "utils.h"
|
#include "curveeditorutils.h"
|
||||||
|
|
||||||
#include <theme.h>
|
#include <theme.h>
|
||||||
#include <utils/fileutils.h>
|
#include <utils/fileutils.h>
|
||||||
|
@@ -27,7 +27,7 @@
|
|||||||
#include "curvesegment.h"
|
#include "curvesegment.h"
|
||||||
#include "graphicsscene.h"
|
#include "graphicsscene.h"
|
||||||
#include "keyframeitem.h"
|
#include "keyframeitem.h"
|
||||||
#include "utils.h"
|
#include "curveeditorutils.h"
|
||||||
|
|
||||||
#include <QPainter>
|
#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 <texttool/texttool.h>
|
||||||
#include <timelineeditor/timelineview.h>
|
#include <timelineeditor/timelineview.h>
|
||||||
#include <transitioneditor/transitioneditorview.h>
|
#include <transitioneditor/transitioneditorview.h>
|
||||||
|
#include <eventlist/eventlistpluginview.h>
|
||||||
#include <pathtool/pathtool.h>
|
#include <pathtool/pathtool.h>
|
||||||
|
|
||||||
#include <qmljseditor/qmljseditor.h>
|
#include <qmljseditor/qmljseditor.h>
|
||||||
@@ -254,6 +255,10 @@ bool QmlDesignerPlugin::delayedInitialize()
|
|||||||
|
|
||||||
auto curveEditorView = new QmlDesigner::CurveEditorView;
|
auto curveEditorView = new QmlDesigner::CurveEditorView;
|
||||||
d->viewManager.registerViewTakingOwnership(curveEditorView);
|
d->viewManager.registerViewTakingOwnership(curveEditorView);
|
||||||
|
|
||||||
|
auto eventlistView = new QmlDesigner::EventListPluginView;
|
||||||
|
d->viewManager.registerViewTakingOwnership(eventlistView);
|
||||||
|
eventlistView->registerActions();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto transitionEditorView = new QmlDesigner::TransitionEditorView;
|
auto transitionEditorView = new QmlDesigner::TransitionEditorView;
|
||||||
|
@@ -35,6 +35,7 @@ include(components/richtexteditor/richtexteditor.pri)
|
|||||||
include(components/transitioneditor/transitioneditor.pri)
|
include(components/transitioneditor/transitioneditor.pri)
|
||||||
include(components/listmodeleditor/listmodeleditor.pri)
|
include(components/listmodeleditor/listmodeleditor.pri)
|
||||||
include(components/previewtooltip/previewtooltipbackend.pri)
|
include(components/previewtooltip/previewtooltipbackend.pri)
|
||||||
|
include(components/eventlist/eventlistplugin.pri)
|
||||||
|
|
||||||
BUILD_PUPPET_IN_CREATOR_BINPATH = $$(BUILD_PUPPET_IN_CREATOR_BINPATH)
|
BUILD_PUPPET_IN_CREATOR_BINPATH = $$(BUILD_PUPPET_IN_CREATOR_BINPATH)
|
||||||
!isEmpty(BUILD_PUPPET_IN_CREATOR_BINPATH) {
|
!isEmpty(BUILD_PUPPET_IN_CREATOR_BINPATH) {
|
||||||
|
@@ -51,6 +51,7 @@ Project {
|
|||||||
"components/integration",
|
"components/integration",
|
||||||
"components/propertyeditor",
|
"components/propertyeditor",
|
||||||
"components/edit3d",
|
"components/edit3d",
|
||||||
|
"components/eventlist",
|
||||||
"components/formeditor",
|
"components/formeditor",
|
||||||
"components/itemlibrary",
|
"components/itemlibrary",
|
||||||
"components/navigator",
|
"components/navigator",
|
||||||
@@ -841,8 +842,37 @@ Project {
|
|||||||
"curveeditor/detail/treemodel.h",
|
"curveeditor/detail/treemodel.h",
|
||||||
"curveeditor/detail/treeview.cpp",
|
"curveeditor/detail/treeview.cpp",
|
||||||
"curveeditor/detail/treeview.h",
|
"curveeditor/detail/treeview.h",
|
||||||
"curveeditor/detail/utils.cpp",
|
"curveeditor/detail/curveeditorutils.cpp",
|
||||||
"curveeditor/detail/utils.h",
|
"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.cpp",
|
||||||
"pathtool/controlpoint.h",
|
"pathtool/controlpoint.h",
|
||||||
"pathtool/cubicsegment.cpp",
|
"pathtool/cubicsegment.cpp",
|
||||||
|
Reference in New Issue
Block a user