forked from qt-creator/qt-creator
QmlDesigner: Add signal list dialog
* Add signal list dialog, delegate and view * Add context menu entry on items which have a trigger signal * Add specific model node operations * Add qml Connections util class * Add utility functions to signal handler property * Fix property processing in node meta info * Fix source code in connection editor and navigator Task-number: QDS-3138 Change-Id: I362ceef230efdb14f2050995b1693937e5e73c41 Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
committed by
Henning Gründl
parent
306cadc643
commit
bebd70573e
@@ -497,6 +497,7 @@ extend_qtc_plugin(QmlDesigner
|
|||||||
include/qmlmodelnodefacade.h
|
include/qmlmodelnodefacade.h
|
||||||
include/qmlobjectnode.h
|
include/qmlobjectnode.h
|
||||||
include/qmlstate.h
|
include/qmlstate.h
|
||||||
|
include/qmlconnections.h
|
||||||
include/qmltimeline.h
|
include/qmltimeline.h
|
||||||
include/qmltimelinekeyframegroup.h
|
include/qmltimelinekeyframegroup.h
|
||||||
include/removebasestateexception.h
|
include/removebasestateexception.h
|
||||||
@@ -578,6 +579,7 @@ extend_qtc_plugin(QmlDesigner
|
|||||||
model/qmlmodelnodefacade.cpp
|
model/qmlmodelnodefacade.cpp
|
||||||
model/qmlobjectnode.cpp
|
model/qmlobjectnode.cpp
|
||||||
model/qmlstate.cpp
|
model/qmlstate.cpp
|
||||||
|
model/qmlconnections.cpp
|
||||||
model/qmltextgenerator.cpp model/qmltextgenerator.h
|
model/qmltextgenerator.cpp model/qmltextgenerator.h
|
||||||
model/qmltimeline.cpp
|
model/qmltimeline.cpp
|
||||||
model/qmltimelinekeyframegroup.cpp
|
model/qmltimelinekeyframegroup.cpp
|
||||||
@@ -620,6 +622,9 @@ extend_qtc_plugin(QmlDesigner
|
|||||||
bindingeditordialog.cpp bindingeditordialog.h
|
bindingeditordialog.cpp bindingeditordialog.h
|
||||||
bindingeditorwidget.cpp bindingeditorwidget.h
|
bindingeditorwidget.cpp bindingeditorwidget.h
|
||||||
connectionvisitor.cpp connectionvisitor.h
|
connectionvisitor.cpp connectionvisitor.h
|
||||||
|
signallist.cpp signallist.h
|
||||||
|
signallistdialog.cpp signallistdialog.h
|
||||||
|
signallistdelegate.cpp signallistdelegate.h
|
||||||
)
|
)
|
||||||
|
|
||||||
extend_qtc_plugin(QmlDesigner
|
extend_qtc_plugin(QmlDesigner
|
||||||
|
@@ -5,6 +5,9 @@ HEADERS += $$PWD/actioneditordialog.h
|
|||||||
HEADERS += $$PWD/bindingeditordialog.h
|
HEADERS += $$PWD/bindingeditordialog.h
|
||||||
HEADERS += $$PWD/bindingeditorwidget.h
|
HEADERS += $$PWD/bindingeditorwidget.h
|
||||||
HEADERS += $$PWD/connectionvisitor.h
|
HEADERS += $$PWD/connectionvisitor.h
|
||||||
|
HEADERS += $$PWD/signallist.h
|
||||||
|
HEADERS += $$PWD/signallistdialog.h
|
||||||
|
HEADERS += $$PWD/signallistdelegate.h
|
||||||
|
|
||||||
SOURCES += $$PWD/bindingeditor.cpp
|
SOURCES += $$PWD/bindingeditor.cpp
|
||||||
SOURCES += $$PWD/actioneditor.cpp
|
SOURCES += $$PWD/actioneditor.cpp
|
||||||
@@ -13,3 +16,6 @@ SOURCES += $$PWD/actioneditordialog.cpp
|
|||||||
SOURCES += $$PWD/bindingeditordialog.cpp
|
SOURCES += $$PWD/bindingeditordialog.cpp
|
||||||
SOURCES += $$PWD/bindingeditorwidget.cpp
|
SOURCES += $$PWD/bindingeditorwidget.cpp
|
||||||
SOURCES += $$PWD/connectionvisitor.cpp
|
SOURCES += $$PWD/connectionvisitor.cpp
|
||||||
|
SOURCES += $$PWD/signallist.cpp
|
||||||
|
SOURCES += $$PWD/signallistdialog.cpp
|
||||||
|
SOURCES += $$PWD/signallistdelegate.cpp
|
||||||
|
328
src/plugins/qmldesigner/components/bindingeditor/signallist.cpp
Normal file
328
src/plugins/qmldesigner/components/bindingeditor/signallist.cpp
Normal file
@@ -0,0 +1,328 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2020 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** 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 https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "signallist.h"
|
||||||
|
|
||||||
|
#include "signallistdelegate.h"
|
||||||
|
|
||||||
|
#include <qmldesignerplugin.h>
|
||||||
|
#include <coreplugin/icore.h>
|
||||||
|
|
||||||
|
#include <utils/algorithm.h>
|
||||||
|
|
||||||
|
#include <metainfo.h>
|
||||||
|
|
||||||
|
#include <variantproperty.h>
|
||||||
|
#include <bindingproperty.h>
|
||||||
|
#include <signalhandlerproperty.h>
|
||||||
|
#include <qmldesignerconstants.h>
|
||||||
|
#include <qmlitemnode.h>
|
||||||
|
#include <nodeabstractproperty.h>
|
||||||
|
|
||||||
|
#include <QStandardItemModel>
|
||||||
|
#include <QSortFilterProxyModel>
|
||||||
|
#include <QTableView>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
SignalListModel::SignalListModel(QObject *parent)
|
||||||
|
: QStandardItemModel(0, 3, parent)
|
||||||
|
{
|
||||||
|
setHeaderData(TargetColumn, Qt::Horizontal, tr("Item ID"));
|
||||||
|
setHeaderData(SignalColumn, Qt::Horizontal, tr("Signal"));
|
||||||
|
setHeaderData(ButtonColumn, Qt::Horizontal, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
void SignalListModel::setConnected(int row, bool connected)
|
||||||
|
{
|
||||||
|
for (int col = 0; col < columnCount(); ++col) {
|
||||||
|
QModelIndex idx = index(row, col);
|
||||||
|
setData(idx, connected, ConnectedRole);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SignalListFilterModel::SignalListFilterModel(QObject *parent)
|
||||||
|
: QSortFilterProxyModel(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SignalListFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
|
||||||
|
{
|
||||||
|
QModelIndex targetIndex = sourceModel()->index(sourceRow, SignalListModel::TargetColumn, sourceParent);
|
||||||
|
QModelIndex signalIndex = sourceModel()->index(sourceRow, SignalListModel::SignalColumn, sourceParent);
|
||||||
|
|
||||||
|
return (sourceModel()->data(targetIndex).toString().contains(filterRegExp())
|
||||||
|
|| sourceModel()->data(signalIndex).toString().contains(filterRegExp()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PropertyNameList SignalList::st_mouseSignals = { "clicked", "doubleClicked", "pressAndHold",
|
||||||
|
"pressed", "released", "wheel" };
|
||||||
|
|
||||||
|
SignalList::SignalList(QObject *)
|
||||||
|
: m_dialog(QPointer<SignalListDialog>())
|
||||||
|
, m_model(new SignalListModel(this))
|
||||||
|
, m_modelNode()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
SignalList::~SignalList()
|
||||||
|
{
|
||||||
|
hideWidget();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SignalList::prepareDialog()
|
||||||
|
{
|
||||||
|
m_dialog = new SignalListDialog(Core::ICore::dialogParent());
|
||||||
|
m_dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
m_dialog->initialize(m_model);
|
||||||
|
m_dialog->setWindowTitle(tr("Signal List for ") + m_modelNode.validId());
|
||||||
|
|
||||||
|
auto *delegate = static_cast<SignalListDelegate *>(m_dialog->tableView()->itemDelegate());
|
||||||
|
connect(delegate, &SignalListDelegate::connectClicked, this, &SignalList::connectClicked);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SignalList::showWidget()
|
||||||
|
{
|
||||||
|
prepareDialog();
|
||||||
|
m_dialog->show();
|
||||||
|
m_dialog->raise();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SignalList::hideWidget()
|
||||||
|
{
|
||||||
|
if (m_dialog)
|
||||||
|
m_dialog->close();
|
||||||
|
|
||||||
|
m_dialog = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
SignalList* SignalList::showWidget(const ModelNode &modelNode)
|
||||||
|
{
|
||||||
|
auto signalList = new SignalList();
|
||||||
|
signalList->setModelNode(modelNode);
|
||||||
|
signalList->prepareSignals();
|
||||||
|
signalList->showWidget();
|
||||||
|
|
||||||
|
connect(signalList->m_dialog, &QDialog::destroyed,
|
||||||
|
[signalList]() { signalList->deleteLater(); } );
|
||||||
|
|
||||||
|
return signalList;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SignalList::setModelNode(const ModelNode &modelNode)
|
||||||
|
{
|
||||||
|
if (modelNode.isValid())
|
||||||
|
m_modelNode = modelNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SignalList::prepareSignals()
|
||||||
|
{
|
||||||
|
if (!m_modelNode.isValid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
AbstractView *view = m_modelNode.view();
|
||||||
|
QList<QmlConnections> connections = getAssociatedConnections(view->allModelNodes());
|
||||||
|
|
||||||
|
for (ModelNode &node : view->allModelNodes()) {
|
||||||
|
// Collect all items which contain at least one of the specified signals
|
||||||
|
const PropertyNameList signalNames = node.metaInfo().signalNames();
|
||||||
|
// Put the signals into a QSet to avoid duplicates
|
||||||
|
auto signalNamesSet = QSet<PropertyName>(signalNames.begin(), signalNames.end());
|
||||||
|
for (const PropertyName &signal : signalNamesSet) {
|
||||||
|
if (st_mouseSignals.contains(signal))
|
||||||
|
appendSignalToModel(connections, node, signal);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gather valid properties and aliases from components
|
||||||
|
for (const PropertyName &property : node.metaInfo().propertyNames()) {
|
||||||
|
const TypeName propertyType = node.metaInfo().propertyTypeName(property);
|
||||||
|
const NodeMetaInfo info = m_modelNode.model()->metaInfo(propertyType);
|
||||||
|
// Collect all items which contain at least one of the specified signals
|
||||||
|
const PropertyNameList signalNames = info.signalNames();
|
||||||
|
// Put the signals into a QSet to avoid duplicates
|
||||||
|
auto signalNamesSet = QSet<PropertyName>(signalNames.begin(), signalNames.end());
|
||||||
|
for (const PropertyName &signal : signalNamesSet) {
|
||||||
|
if (st_mouseSignals.contains(signal))
|
||||||
|
appendSignalToModel(connections, node, signal, property);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SignalList::connectClicked(const QModelIndex &modelIndex)
|
||||||
|
{
|
||||||
|
auto proxyModel = static_cast<const SignalListFilterModel *>(modelIndex.model());
|
||||||
|
QModelIndex mappedModelIndex = proxyModel->mapToSource(modelIndex);
|
||||||
|
bool connected = mappedModelIndex.data(SignalListModel::ConnectedRole).toBool();
|
||||||
|
|
||||||
|
if (!connected)
|
||||||
|
addConnection(mappedModelIndex);
|
||||||
|
else
|
||||||
|
removeConnection(mappedModelIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SignalList::appendSignalToModel(const QList<QmlConnections> &connections,
|
||||||
|
ModelNode &node,
|
||||||
|
const PropertyName &signal,
|
||||||
|
const PropertyName &property)
|
||||||
|
{
|
||||||
|
QStandardItem *idItem = new QStandardItem();
|
||||||
|
QString id(node.validId());
|
||||||
|
if (!property.isEmpty())
|
||||||
|
id += "." + QString::fromLatin1(property);
|
||||||
|
|
||||||
|
idItem->setData(id, Qt::DisplayRole);
|
||||||
|
|
||||||
|
QStandardItem *signalItem = new QStandardItem();
|
||||||
|
signalItem->setData(signal, Qt::DisplayRole);
|
||||||
|
|
||||||
|
QStandardItem *buttonItem = new QStandardItem();
|
||||||
|
|
||||||
|
idItem->setData(false, SignalListModel::ConnectedRole);
|
||||||
|
signalItem->setData(false, SignalListModel::ConnectedRole);
|
||||||
|
buttonItem->setData(false, SignalListModel::ConnectedRole);
|
||||||
|
|
||||||
|
for (const QmlConnections &connection : connections) {
|
||||||
|
if (connection.target() == id) {
|
||||||
|
for (const SignalHandlerProperty &property : connection.signalProperties()) {
|
||||||
|
auto signalWithoutPrefix = SignalHandlerProperty::prefixRemoved(property.name());
|
||||||
|
if (signalWithoutPrefix == signal) {
|
||||||
|
buttonItem->setData(connection.modelNode().internalId(),
|
||||||
|
SignalListModel::ConnectionsInternalIdRole);
|
||||||
|
|
||||||
|
idItem->setData(true, SignalListModel::ConnectedRole);
|
||||||
|
signalItem->setData(true, SignalListModel::ConnectedRole);
|
||||||
|
buttonItem->setData(true, SignalListModel::ConnectedRole);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_model->appendRow({idItem, signalItem, buttonItem});
|
||||||
|
}
|
||||||
|
|
||||||
|
void SignalList::addConnection(const QModelIndex &modelIndex)
|
||||||
|
{
|
||||||
|
const QModelIndex targetModelIndex = modelIndex.siblingAtColumn(SignalListModel::TargetColumn);
|
||||||
|
const QModelIndex signalModelIndex = modelIndex.siblingAtColumn(SignalListModel::SignalColumn);
|
||||||
|
const QModelIndex buttonModelIndex = modelIndex.siblingAtColumn(SignalListModel::ButtonColumn);
|
||||||
|
const PropertyName signalName = m_model->data(signalModelIndex,
|
||||||
|
Qt::DisplayRole).toByteArray();
|
||||||
|
|
||||||
|
QmlDesignerPlugin::emitUsageStatistics(Constants::EVENT_CONNECTION_ADDED);
|
||||||
|
|
||||||
|
AbstractView *view = m_modelNode.view();
|
||||||
|
const ModelNode rootModelNode = view->rootModelNode();
|
||||||
|
|
||||||
|
if (rootModelNode.isValid() && rootModelNode.metaInfo().isValid()) {
|
||||||
|
NodeMetaInfo nodeMetaInfo = view->model()->metaInfo("QtQuick.Connections");
|
||||||
|
if (nodeMetaInfo.isValid()) {
|
||||||
|
view->executeInTransaction("ConnectionModel::addConnection", [=, &rootModelNode](){
|
||||||
|
ModelNode newNode = view->createModelNode("QtQuick.Connections",
|
||||||
|
nodeMetaInfo.majorVersion(),
|
||||||
|
nodeMetaInfo.minorVersion());
|
||||||
|
const QString source = m_modelNode.validId() + ".trigger()";
|
||||||
|
|
||||||
|
if (QmlItemNode::isValidQmlItemNode(m_modelNode))
|
||||||
|
m_modelNode.nodeAbstractProperty("data").reparentHere(newNode);
|
||||||
|
else
|
||||||
|
rootModelNode.nodeAbstractProperty(rootModelNode.metaInfo().defaultPropertyName()).reparentHere(newNode);
|
||||||
|
|
||||||
|
const QString expression = m_model->data(targetModelIndex, Qt::DisplayRole).toString();
|
||||||
|
newNode.bindingProperty("target").setExpression(expression);
|
||||||
|
newNode.signalHandlerProperty(SignalHandlerProperty::prefixAdded(signalName)).setSource(source);
|
||||||
|
|
||||||
|
m_model->setConnected(modelIndex.row(), true);
|
||||||
|
m_model->setData(buttonModelIndex, newNode.internalId(), SignalListModel::ConnectionsInternalIdRole);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SignalList::removeConnection(const QModelIndex &modelIndex)
|
||||||
|
{
|
||||||
|
const QModelIndex signalModelIndex = modelIndex.siblingAtColumn(SignalListModel::SignalColumn);
|
||||||
|
const QModelIndex buttonModelIndex = modelIndex.siblingAtColumn(SignalListModel::ButtonColumn);
|
||||||
|
const PropertyName signalName = m_model->data(signalModelIndex,
|
||||||
|
Qt::DisplayRole).toByteArray();
|
||||||
|
const int connectionInternalId = m_model->data(buttonModelIndex,
|
||||||
|
SignalListModel::ConnectionsInternalIdRole).toInt();
|
||||||
|
|
||||||
|
AbstractView *view = m_modelNode.view();
|
||||||
|
const ModelNode connectionModelNode = view->modelNodeForInternalId(connectionInternalId);
|
||||||
|
SignalHandlerProperty targetSignal;
|
||||||
|
|
||||||
|
if (connectionModelNode.isValid())
|
||||||
|
targetSignal = connectionModelNode.signalHandlerProperty(signalName);
|
||||||
|
|
||||||
|
ModelNode node = targetSignal.parentModelNode();
|
||||||
|
if (node.isValid()) {
|
||||||
|
view->executeInTransaction("ConnectionModel::removeConnection", [=, &node](){
|
||||||
|
QList<SignalHandlerProperty> allSignals = node.signalProperties();
|
||||||
|
if (allSignals.size() > 1) {
|
||||||
|
const auto targetSignalWithPrefix = SignalHandlerProperty::prefixAdded(targetSignal.name());
|
||||||
|
for (const SignalHandlerProperty &signal : allSignals)
|
||||||
|
if (signal.name() == targetSignalWithPrefix)
|
||||||
|
node.removeProperty(targetSignalWithPrefix);
|
||||||
|
} else {
|
||||||
|
node.destroy();
|
||||||
|
}
|
||||||
|
m_model->setConnected(modelIndex.row(), false);
|
||||||
|
m_model->setData(buttonModelIndex, QVariant(), SignalListModel::ConnectionsInternalIdRole);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QmlConnections> SignalList::getAssociatedConnections(const QList<ModelNode> &nodes)
|
||||||
|
{
|
||||||
|
return Utils::transform<QList<QmlConnections>>(Utils::filtered(nodes, [this](const ModelNode &node) {
|
||||||
|
const QmlConnections connection(node);
|
||||||
|
if (!connection.isValid())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (const SignalHandlerProperty &property : connection.signalProperties()) {
|
||||||
|
auto signalWithoutPrefix = SignalHandlerProperty::prefixRemoved(property.name());
|
||||||
|
const QStringList sourceComponents = property.source().split(".");
|
||||||
|
QString sourceId;
|
||||||
|
QString sourceProperty;
|
||||||
|
if (sourceComponents.size() > 1) {
|
||||||
|
sourceId = sourceComponents[0];
|
||||||
|
sourceProperty = sourceComponents[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (st_mouseSignals.contains(signalWithoutPrefix)
|
||||||
|
&& sourceId == m_modelNode.validId()
|
||||||
|
&& sourceProperty == "trigger()")
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}), [](const ModelNode &node) {
|
||||||
|
return QmlConnections(node);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
} // QmlDesigner namespace
|
108
src/plugins/qmldesigner/components/bindingeditor/signallist.h
Normal file
108
src/plugins/qmldesigner/components/bindingeditor/signallist.h
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2020 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** 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 https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <bindingeditor/signallistdialog.h>
|
||||||
|
#include <qmldesignercorelib_global.h>
|
||||||
|
#include <modelnode.h>
|
||||||
|
#include <qmlconnections.h>
|
||||||
|
|
||||||
|
#include <QtQml>
|
||||||
|
#include <QObject>
|
||||||
|
#include <QPointer>
|
||||||
|
#include <QStandardItemModel>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class SignalListModel : public QStandardItemModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum ColumnRoles : unsigned int {
|
||||||
|
TargetColumn = 0,
|
||||||
|
SignalColumn = 1,
|
||||||
|
ButtonColumn = 2
|
||||||
|
};
|
||||||
|
enum UserRoles : unsigned int {
|
||||||
|
ConnectionsInternalIdRole = Qt::UserRole + 1,
|
||||||
|
ConnectedRole
|
||||||
|
};
|
||||||
|
|
||||||
|
SignalListModel(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
void setConnected(int row, bool connected);
|
||||||
|
};
|
||||||
|
|
||||||
|
class SignalListFilterModel : public QSortFilterProxyModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
SignalListFilterModel(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SignalList : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit SignalList(QObject *parent = nullptr);
|
||||||
|
~SignalList();
|
||||||
|
|
||||||
|
static SignalList* showWidget(const ModelNode &modelNode);
|
||||||
|
|
||||||
|
void setModelNode(const ModelNode &modelNode);
|
||||||
|
void connectClicked(const QModelIndex &modelIndex);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void prepareDialog();
|
||||||
|
void showWidget();
|
||||||
|
void hideWidget();
|
||||||
|
|
||||||
|
void prepareSignals();
|
||||||
|
|
||||||
|
void appendSignalToModel(const QList<QmlConnections> &connections,
|
||||||
|
ModelNode &node,
|
||||||
|
const PropertyName &signal,
|
||||||
|
const PropertyName &property = "");
|
||||||
|
|
||||||
|
void addConnection(const QModelIndex &modelIndex);
|
||||||
|
void removeConnection(const QModelIndex &modelIndex);
|
||||||
|
|
||||||
|
QList<QmlConnections> getAssociatedConnections(const QList<ModelNode> &nodes);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static PropertyNameList st_mouseSignals;
|
||||||
|
|
||||||
|
QPointer<SignalListDialog> m_dialog;
|
||||||
|
SignalListModel *m_model;
|
||||||
|
ModelNode m_modelNode;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // QmlDesigner namespace
|
@@ -0,0 +1,95 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2020 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** 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 https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "signallistdelegate.h"
|
||||||
|
|
||||||
|
#include "signallist.h"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QMouseEvent>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QStyleOptionButton>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
SignalListDelegate::SignalListDelegate(QObject *parent)
|
||||||
|
: QStyledItemDelegate(parent)
|
||||||
|
{}
|
||||||
|
|
||||||
|
QWidget *SignalListDelegate::createEditor(QWidget *parent,
|
||||||
|
const QStyleOptionViewItem &option,
|
||||||
|
const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
if (index.column() == SignalListModel::ButtonColumn)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return QStyledItemDelegate::createEditor(parent, option, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
QRect connectButtonRect(const QStyleOptionViewItem &option)
|
||||||
|
{
|
||||||
|
return option.rect.adjusted(3, 3, -3, -3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SignalListDelegate::paint(QPainter *painter,
|
||||||
|
const QStyleOptionViewItem &option,
|
||||||
|
const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
const bool connected = index.data(SignalListModel::ConnectedRole).toBool();
|
||||||
|
if (connected) {
|
||||||
|
QStyleOptionViewItem opt(option);
|
||||||
|
opt.state = QStyle::State_Selected;
|
||||||
|
QStyledItemDelegate::paint(painter, opt, index);
|
||||||
|
if (index.column() != SignalListModel::ButtonColumn)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (index.column() == SignalListModel::ButtonColumn) {
|
||||||
|
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 SignalListDelegate::editorEvent(QEvent *event,
|
||||||
|
QAbstractItemModel *model,
|
||||||
|
const QStyleOptionViewItem &option,
|
||||||
|
const QModelIndex &index)
|
||||||
|
{
|
||||||
|
Q_UNUSED(model)
|
||||||
|
|
||||||
|
if (index.column() == SignalListModel::ButtonColumn
|
||||||
|
&& event->type() == QEvent::MouseButtonRelease) {
|
||||||
|
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
|
||||||
|
if (connectButtonRect(option).contains(mouseEvent->pos()))
|
||||||
|
emit connectClicked(index);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // QmlDesigner namespace
|
@@ -0,0 +1,54 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2020 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** 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 https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QStyledItemDelegate>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class SignalListDelegate : public QStyledItemDelegate
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void connectClicked(const QModelIndex &modelIndex) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SignalListDelegate(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
QWidget *createEditor(QWidget *parent,
|
||||||
|
const QStyleOptionViewItem &option,
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // QmlDesigner namespace
|
@@ -0,0 +1,132 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2020 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** 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 https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "signallistdialog.h"
|
||||||
|
|
||||||
|
#include "signallist.h"
|
||||||
|
#include "signallistdelegate.h"
|
||||||
|
|
||||||
|
#include <qmldesignerplugin.h>
|
||||||
|
|
||||||
|
#include <theme.h>
|
||||||
|
#include <utils/fancylineedit.h>
|
||||||
|
#include <utils/stylehelper.h>
|
||||||
|
#include <utils/utilsicons.h>
|
||||||
|
|
||||||
|
#include <QStandardItemModel>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QTableView>
|
||||||
|
#include <QHeaderView>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QSortFilterProxyModel>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
QWidget *createFilterWidget(Utils::FancyLineEdit *lineEdit)
|
||||||
|
{
|
||||||
|
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(24, 24)));
|
||||||
|
label->setAlignment(Qt::AlignCenter);
|
||||||
|
lineEdit->setPlaceholderText(QObject::tr("<Filter>", "Library search input hint text"));
|
||||||
|
lineEdit->setDragEnabled(false);
|
||||||
|
lineEdit->setMinimumWidth(75);
|
||||||
|
lineEdit->setTextMargins(0, 0, 20, 0);
|
||||||
|
lineEdit->setFiltering(true);
|
||||||
|
auto *box = new QHBoxLayout;
|
||||||
|
box->addWidget(label);
|
||||||
|
box->addWidget(lineEdit);
|
||||||
|
auto *widget = new QWidget;
|
||||||
|
widget->setLayout(box);
|
||||||
|
return widget;
|
||||||
|
}
|
||||||
|
|
||||||
|
void modifyPalette(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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SignalListDialog::SignalListDialog(QWidget *parent)
|
||||||
|
: QDialog(parent)
|
||||||
|
, m_table(new QTableView())
|
||||||
|
, m_searchLine(new Utils::FancyLineEdit())
|
||||||
|
{
|
||||||
|
auto *signalListDelegate = new SignalListDelegate(m_table);
|
||||||
|
m_table->setItemDelegate(signalListDelegate);
|
||||||
|
m_table->setFocusPolicy(Qt::NoFocus);
|
||||||
|
m_table->setSelectionMode(QAbstractItemView::NoSelection);
|
||||||
|
m_table->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||||
|
m_table->verticalHeader()->hide();
|
||||||
|
|
||||||
|
modifyPalette(m_table, QColor("#d87b00"));
|
||||||
|
|
||||||
|
auto *layout = new QVBoxLayout;
|
||||||
|
layout->addWidget(createFilterWidget(m_searchLine));
|
||||||
|
layout->addWidget(m_table);
|
||||||
|
setLayout(layout);
|
||||||
|
|
||||||
|
setWindowFlag(Qt::Tool, true);
|
||||||
|
setModal(true);
|
||||||
|
resize(600, 480);
|
||||||
|
}
|
||||||
|
|
||||||
|
SignalListDialog::~SignalListDialog()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SignalListDialog::initialize(QStandardItemModel *model)
|
||||||
|
{
|
||||||
|
m_searchLine->clear();
|
||||||
|
|
||||||
|
auto *proxyModel = new SignalListFilterModel(this);
|
||||||
|
proxyModel->setSourceModel(model);
|
||||||
|
m_table->setModel(proxyModel);
|
||||||
|
|
||||||
|
QHeaderView *header = m_table->horizontalHeader();
|
||||||
|
header->setSectionResizeMode(SignalListModel::TargetColumn, QHeaderView::Stretch);
|
||||||
|
header->setSectionResizeMode(SignalListModel::SignalColumn, QHeaderView::Stretch);
|
||||||
|
header->resizeSection(SignalListModel::ButtonColumn, 120);
|
||||||
|
header->setStretchLastSection(false);
|
||||||
|
|
||||||
|
auto eventFilterFun = [this](const QString &str) {
|
||||||
|
if (auto *fm = qobject_cast<SignalListFilterModel *>(m_table->model()))
|
||||||
|
fm->setFilterFixedString(str);
|
||||||
|
};
|
||||||
|
connect(m_searchLine, &Utils::FancyLineEdit::filterChanged, eventFilterFun);
|
||||||
|
}
|
||||||
|
|
||||||
|
QTableView *SignalListDialog::tableView() const
|
||||||
|
{
|
||||||
|
return m_table;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // QmlDesigner namespace
|
@@ -0,0 +1,58 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2020 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** 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 https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
class QStandardItemModel;
|
||||||
|
class QTableView;
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
namespace Utils {
|
||||||
|
class FancyLineEdit;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class SignalListDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
SignalListDialog(QWidget *parent = nullptr);
|
||||||
|
~SignalListDialog() override;
|
||||||
|
|
||||||
|
void initialize(QStandardItemModel *model);
|
||||||
|
|
||||||
|
QTableView *tableView() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QTableView *m_table;
|
||||||
|
Utils::FancyLineEdit *m_searchLine;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // QmlDesigner namespace
|
@@ -89,6 +89,8 @@ const char fitRootToScreenCommandId[] = "FitRootToScreen";
|
|||||||
const char fitSelectionToScreenCommandId[] = "FitSelectionToScreen";
|
const char fitSelectionToScreenCommandId[] = "FitSelectionToScreen";
|
||||||
const char editAnnotationCommandId[] = "EditAnnotation";
|
const char editAnnotationCommandId[] = "EditAnnotation";
|
||||||
|
|
||||||
|
const char openSignalDialogCommandId[] = "OpenSignalDialog";
|
||||||
|
|
||||||
const char selectionCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Selection");
|
const char selectionCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Selection");
|
||||||
const char flowConnectionCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Connect");
|
const char flowConnectionCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Connect");
|
||||||
const char selectEffectDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Select Effect");
|
const char selectEffectDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Select Effect");
|
||||||
@@ -128,6 +130,8 @@ const char addSignalHandlerDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContext
|
|||||||
const char moveToComponentDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Move Component into Separate File");
|
const char moveToComponentDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Move Component into Separate File");
|
||||||
const char editAnnotationDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Edit Annotation");
|
const char editAnnotationDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Edit Annotation");
|
||||||
|
|
||||||
|
const char openSignalDialogDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Open Signal Dialog");
|
||||||
|
|
||||||
const char setIdDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Set Id");
|
const char setIdDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Set Id");
|
||||||
|
|
||||||
const char resetZDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Reset z Property");
|
const char resetZDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Reset z Property");
|
||||||
|
@@ -564,6 +564,7 @@ const char yProperty[] = "y";
|
|||||||
const char zProperty[] = "z";
|
const char zProperty[] = "z";
|
||||||
const char widthProperty[] = "width";
|
const char widthProperty[] = "width";
|
||||||
const char heightProperty[] = "height";
|
const char heightProperty[] = "height";
|
||||||
|
const char triggerSlot[] = "trigger";
|
||||||
|
|
||||||
using namespace SelectionContextFunctors;
|
using namespace SelectionContextFunctors;
|
||||||
|
|
||||||
@@ -644,6 +645,14 @@ bool selectionNotEmptyAndHasXorYProperty(const SelectionContext &context)
|
|||||||
&& selectionHasProperty1or2(context, xProperty, yProperty);
|
&& selectionHasProperty1or2(context, xProperty, yProperty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool singleSelectionAndHasSlotTrigger(const SelectionContext &context)
|
||||||
|
{
|
||||||
|
if (!singleSelection(context))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return selectionHasSlot(context, triggerSlot);
|
||||||
|
}
|
||||||
|
|
||||||
bool singleSelectionAndInQtQuickLayout(const SelectionContext &context)
|
bool singleSelectionAndInQtQuickLayout(const SelectionContext &context)
|
||||||
{
|
{
|
||||||
if (!singleSelection(context))
|
if (!singleSelection(context))
|
||||||
@@ -1384,6 +1393,16 @@ void DesignerActionManager::createDefaultDesignerActions()
|
|||||||
addDesignerAction(new ChangeStyleAction());
|
addDesignerAction(new ChangeStyleAction());
|
||||||
|
|
||||||
addDesignerAction(new EditListModelAction);
|
addDesignerAction(new EditListModelAction);
|
||||||
|
|
||||||
|
addDesignerAction(new ModelNodeContextMenuAction(
|
||||||
|
openSignalDialogCommandId,
|
||||||
|
openSignalDialogDisplayName,
|
||||||
|
{},
|
||||||
|
rootCategory,
|
||||||
|
QKeySequence(),
|
||||||
|
66,
|
||||||
|
&openSignalDialog,
|
||||||
|
&singleSelectionAndHasSlotTrigger));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesignerActionManager::createDefaultAddResourceHandler()
|
void DesignerActionManager::createDefaultAddResourceHandler()
|
||||||
|
@@ -30,6 +30,7 @@
|
|||||||
#include "abstractactiongroup.h"
|
#include "abstractactiongroup.h"
|
||||||
#include "qmlitemnode.h"
|
#include "qmlitemnode.h"
|
||||||
#include <qmldesignerplugin.h>
|
#include <qmldesignerplugin.h>
|
||||||
|
#include <nodemetainfo.h>
|
||||||
|
|
||||||
#include <coreplugin/actionmanager/command.h>
|
#include <coreplugin/actionmanager/command.h>
|
||||||
|
|
||||||
@@ -80,12 +81,24 @@ inline bool singleSelectionNotRoot(const SelectionContext &selectionState)
|
|||||||
|
|
||||||
inline bool selectionHasProperty(const SelectionContext &selectionState, const char *property)
|
inline bool selectionHasProperty(const SelectionContext &selectionState, const char *property)
|
||||||
{
|
{
|
||||||
foreach (const ModelNode &modelNode, selectionState.selectedModelNodes())
|
for (const ModelNode &modelNode : selectionState.selectedModelNodes())
|
||||||
if (modelNode.hasProperty(PropertyName(property)))
|
if (modelNode.hasProperty(PropertyName(property)))
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool selectionHasSlot(const SelectionContext &selectionState, const char *property)
|
||||||
|
{
|
||||||
|
for (const ModelNode &modelNode : selectionState.selectedModelNodes()) {
|
||||||
|
for (const PropertyName &slotName : modelNode.metaInfo().slotNames()) {
|
||||||
|
if (slotName == property)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
inline bool singleSelectedItem(const SelectionContext &selectionState)
|
inline bool singleSelectedItem(const SelectionContext &selectionState)
|
||||||
{
|
{
|
||||||
QmlItemNode itemNode(selectionState.currentSingleSelectedNode());
|
QmlItemNode itemNode(selectionState.currentSingleSelectedNode());
|
||||||
@@ -94,7 +107,6 @@ inline bool singleSelectedItem(const SelectionContext &selectionState)
|
|||||||
|
|
||||||
bool selectionHasSameParent(const SelectionContext &selectionState);
|
bool selectionHasSameParent(const SelectionContext &selectionState);
|
||||||
bool selectionIsComponent(const SelectionContext &selectionState);
|
bool selectionIsComponent(const SelectionContext &selectionState);
|
||||||
bool selectionIsComponent(const SelectionContext &selectionState);
|
|
||||||
bool singleSelectionItemIsAnchored(const SelectionContext &selectionState);
|
bool singleSelectionItemIsAnchored(const SelectionContext &selectionState);
|
||||||
bool singleSelectionItemIsNotAnchored(const SelectionContext &selectionState);
|
bool singleSelectionItemIsNotAnchored(const SelectionContext &selectionState);
|
||||||
|
|
||||||
|
@@ -87,6 +87,8 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
|
#include <bindingeditor/signallist.h>
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
const PropertyName auxDataString("anchors_");
|
const PropertyName auxDataString("anchors_");
|
||||||
@@ -1550,6 +1552,14 @@ QVariant previewImageDataForImageNode(const ModelNode &modelNode)
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void openSignalDialog(const SelectionContext &selectionContext)
|
||||||
|
{
|
||||||
|
if (!selectionContext.view() || !selectionContext.hasSingleSelectedModelNode())
|
||||||
|
return;
|
||||||
|
|
||||||
|
SignalList::showWidget(selectionContext.currentSingleSelectedNode());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ModelNodeOperations
|
} // namespace ModelNodeOperations
|
||||||
|
|
||||||
} //QmlDesigner
|
} //QmlDesigner
|
||||||
|
@@ -86,6 +86,8 @@ void mergeWithTemplate(const SelectionContext &selectionContext);
|
|||||||
void removeGroup(const SelectionContext &selectionContext);
|
void removeGroup(const SelectionContext &selectionContext);
|
||||||
void editAnnotation(const SelectionContext &selectionContext);
|
void editAnnotation(const SelectionContext &selectionContext);
|
||||||
|
|
||||||
|
void openSignalDialog(const SelectionContext &selectionContext);
|
||||||
|
|
||||||
// ModelNodePreviewImageOperations
|
// ModelNodePreviewImageOperations
|
||||||
QVariant previewImageDataForGenericNode(const ModelNode &modelNode);
|
QVariant previewImageDataForGenericNode(const ModelNode &modelNode);
|
||||||
QVariant previewImageDataForImageNode(const ModelNode &modelNode);
|
QVariant previewImageDataForImageNode(const ModelNode &modelNode);
|
||||||
|
@@ -49,9 +49,9 @@ namespace {
|
|||||||
QStringList propertyNameListToStringList(const QmlDesigner::PropertyNameList &propertyNameList)
|
QStringList propertyNameListToStringList(const QmlDesigner::PropertyNameList &propertyNameList)
|
||||||
{
|
{
|
||||||
QStringList stringList;
|
QStringList stringList;
|
||||||
for (const QmlDesigner::PropertyName &propertyName : propertyNameList) {
|
for (const QmlDesigner::PropertyName &propertyName : propertyNameList)
|
||||||
stringList << QString::fromUtf8(propertyName);
|
stringList << QString::fromUtf8(propertyName);
|
||||||
}
|
|
||||||
stringList.removeDuplicates();
|
stringList.removeDuplicates();
|
||||||
return stringList;
|
return stringList;
|
||||||
}
|
}
|
||||||
|
@@ -133,8 +133,6 @@ static QRect drawText(QPainter *painter,
|
|||||||
int iconOffset)
|
int iconOffset)
|
||||||
{
|
{
|
||||||
QString displayString = modelIndex.data(Qt::DisplayRole).toString();
|
QString displayString = modelIndex.data(Qt::DisplayRole).toString();
|
||||||
QPoint displayStringOffset;
|
|
||||||
int width = 0;
|
|
||||||
|
|
||||||
// Check text length does not exceed available space
|
// Check text length does not exceed available space
|
||||||
const int extraSpace = 12 + iconOffset;
|
const int extraSpace = 12 + iconOffset;
|
||||||
@@ -142,10 +140,8 @@ static QRect drawText(QPainter *painter,
|
|||||||
displayString = styleOption.fontMetrics.elidedText(displayString,
|
displayString = styleOption.fontMetrics.elidedText(displayString,
|
||||||
Qt::ElideMiddle,
|
Qt::ElideMiddle,
|
||||||
styleOption.rect.width() - extraSpace);
|
styleOption.rect.width() - extraSpace);
|
||||||
displayStringOffset = QPoint(5 + iconOffset, -5 - delegateMargin);
|
const QPoint displayStringOffset = QPoint(5 + iconOffset, -5 - delegateMargin);
|
||||||
|
const int width = styleOption.fontMetrics.horizontalAdvance(displayString);
|
||||||
width = styleOption.fontMetrics.horizontalAdvance(displayString);
|
|
||||||
|
|
||||||
const QPoint textPosition = styleOption.rect.bottomLeft() + displayStringOffset;
|
const QPoint textPosition = styleOption.rect.bottomLeft() + displayStringOffset;
|
||||||
painter->drawText(textPosition, displayString);
|
painter->drawText(textPosition, displayString);
|
||||||
|
|
||||||
|
@@ -69,6 +69,7 @@ SOURCES += $$PWD/model/abstractview.cpp \
|
|||||||
$$PWD/model/qmlmodelnodefacade.cpp \
|
$$PWD/model/qmlmodelnodefacade.cpp \
|
||||||
$$PWD/model/qmlobjectnode.cpp \
|
$$PWD/model/qmlobjectnode.cpp \
|
||||||
$$PWD/model/qmlanchors.cpp \
|
$$PWD/model/qmlanchors.cpp \
|
||||||
|
$$PWD/model/qmlconnections.cpp \
|
||||||
$$PWD/rewritertransaction.cpp \
|
$$PWD/rewritertransaction.cpp \
|
||||||
$$PWD/model/rewriteaction.cpp \
|
$$PWD/model/rewriteaction.cpp \
|
||||||
$$PWD/model/modelnodepositionstorage.cpp \
|
$$PWD/model/modelnodepositionstorage.cpp \
|
||||||
@@ -151,6 +152,7 @@ HEADERS += $$PWD/include/qmldesignercorelib_global.h \
|
|||||||
$$PWD/include/forwardview.h \
|
$$PWD/include/forwardview.h \
|
||||||
$$PWD/include/qmlobjectnode.h \
|
$$PWD/include/qmlobjectnode.h \
|
||||||
$$PWD/include/qmlanchors.h \
|
$$PWD/include/qmlanchors.h \
|
||||||
|
$$PWD/include/qmlconnections.h \
|
||||||
$$PWD/rewritertransaction.h \
|
$$PWD/rewritertransaction.h \
|
||||||
$$PWD/model/rewriteaction.h \
|
$$PWD/model/rewriteaction.h \
|
||||||
$$PWD/include/modelnodepositionstorage.h \
|
$$PWD/include/modelnodepositionstorage.h \
|
||||||
|
@@ -0,0 +1,57 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2020 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** 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 https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <qmldesignercorelib_global.h>
|
||||||
|
#include "qmlmodelnodefacade.h"
|
||||||
|
|
||||||
|
#include <signalhandlerproperty.h>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class QMLDESIGNERCORE_EXPORT QmlConnections : public QmlModelNodeFacade
|
||||||
|
{
|
||||||
|
friend class StatesEditorView;
|
||||||
|
|
||||||
|
public:
|
||||||
|
QmlConnections();
|
||||||
|
QmlConnections(const ModelNode &modelNode);
|
||||||
|
|
||||||
|
bool isValid() const override;
|
||||||
|
static bool isValidQmlConnections(const ModelNode &modelNode);
|
||||||
|
void destroy();
|
||||||
|
|
||||||
|
QString target() const;
|
||||||
|
void setTarget(const QString &target);
|
||||||
|
|
||||||
|
ModelNode getTargetNode() const;
|
||||||
|
|
||||||
|
QList<SignalHandlerProperty> signalProperties() const;
|
||||||
|
|
||||||
|
static ModelNode createQmlConnections(AbstractView *view);
|
||||||
|
};
|
||||||
|
|
||||||
|
} //QmlDesigner
|
@@ -43,6 +43,9 @@ public:
|
|||||||
SignalHandlerProperty();
|
SignalHandlerProperty();
|
||||||
SignalHandlerProperty(const SignalHandlerProperty &property, AbstractView *view);
|
SignalHandlerProperty(const SignalHandlerProperty &property, AbstractView *view);
|
||||||
|
|
||||||
|
static PropertyName prefixAdded(const PropertyName &propertyName);
|
||||||
|
static PropertyName prefixRemoved(const PropertyName &propertyName);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
SignalHandlerProperty(const PropertyName &propertyName, const Internal::InternalNodePointer &internalNode, Model* model, AbstractView *view);
|
SignalHandlerProperty(const PropertyName &propertyName, const Internal::InternalNodePointer &internalNode, Model* model, AbstractView *view);
|
||||||
};
|
};
|
||||||
|
@@ -82,7 +82,7 @@ using PropertyInfo = QPair<PropertyName, TypeName>;
|
|||||||
|
|
||||||
QVector<PropertyInfo> getObjectTypes(const ObjectValue *ov, const ContextPtr &context, bool local = false, int rec = 0);
|
QVector<PropertyInfo> getObjectTypes(const ObjectValue *ov, const ContextPtr &context, bool local = false, int rec = 0);
|
||||||
|
|
||||||
static TypeName resolveTypeName(const ASTPropertyReference *ref, const ContextPtr &context, QVector<PropertyInfo> &dotProperties)
|
static TypeName resolveTypeName(const ASTPropertyReference *ref, const ContextPtr &context, QVector<PropertyInfo> &dotProperties)
|
||||||
{
|
{
|
||||||
TypeName type = "unknown";
|
TypeName type = "unknown";
|
||||||
|
|
||||||
@@ -295,7 +295,7 @@ public:
|
|||||||
const TypeName type = resolveTypeName(ref, m_context, dotProperties);
|
const TypeName type = resolveTypeName(ref, m_context, dotProperties);
|
||||||
m_properties.append({propertyName, type});
|
m_properties.append({propertyName, type});
|
||||||
if (!dotProperties.isEmpty()) {
|
if (!dotProperties.isEmpty()) {
|
||||||
foreach (const PropertyInfo &propertyInfo, dotProperties) {
|
for (const PropertyInfo &propertyInfo : qAsConst(dotProperties)) {
|
||||||
PropertyName dotName = propertyInfo.first;
|
PropertyName dotName = propertyInfo.first;
|
||||||
TypeName type = propertyInfo.second;
|
TypeName type = propertyInfo.second;
|
||||||
dotName = propertyName + '.' + dotName;
|
dotName = propertyName + '.' + dotName;
|
||||||
@@ -303,7 +303,6 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (const CppComponentValue * cppComponentValue = value_cast<CppComponentValue>(value)) {
|
if (const CppComponentValue * cppComponentValue = value_cast<CppComponentValue>(value)) {
|
||||||
TypeName qualifiedTypeName = qualifiedTypeNameForContext(cppComponentValue,
|
TypeName qualifiedTypeName = qualifiedTypeNameForContext(cppComponentValue,
|
||||||
m_context->viewerContext(), *m_context->snapshot().importDependencies()).toUtf8();
|
m_context->viewerContext(), *m_context->snapshot().importDependencies()).toUtf8();
|
||||||
@@ -311,13 +310,13 @@ public:
|
|||||||
} else {
|
} else {
|
||||||
TypeId typeId;
|
TypeId typeId;
|
||||||
TypeName typeName = typeId(value).toUtf8();
|
TypeName typeName = typeId(value).toUtf8();
|
||||||
if (typeName == "number") {
|
|
||||||
if (value->asIntValue()) {
|
if (typeName == "Function")
|
||||||
typeName = "int";
|
return processSlot(name, value);
|
||||||
} else {
|
|
||||||
typeName = "real";
|
if (typeName == "number")
|
||||||
}
|
typeName = value->asIntValue() ? "int" : "real";
|
||||||
}
|
|
||||||
m_properties.append({propertyName, typeName});
|
m_properties.append({propertyName, typeName});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -488,7 +487,7 @@ PropertyNameList getSignals(const ObjectValue *objectValue, const ContextPtr &co
|
|||||||
QList<const ObjectValue *> objects = prototypeIterator.all();
|
QList<const ObjectValue *> objects = prototypeIterator.all();
|
||||||
|
|
||||||
if (!local) {
|
if (!local) {
|
||||||
foreach (const ObjectValue *prototype, objects)
|
for (const ObjectValue *prototype : objects)
|
||||||
signalList.append(getSignals(prototype, context, true));
|
signalList.append(getSignals(prototype, context, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -507,6 +506,9 @@ PropertyNameList getSlots(const ObjectValue *objectValue, const ContextPtr &cont
|
|||||||
PropertyMemberProcessor processor(context);
|
PropertyMemberProcessor processor(context);
|
||||||
objectValue->processMembers(&processor);
|
objectValue->processMembers(&processor);
|
||||||
|
|
||||||
|
if (const ASTObjectValue *astObjectValue = objectValue->asAstObjectValue())
|
||||||
|
astObjectValue->processMembers(&processor);
|
||||||
|
|
||||||
slotList.append(processor.slotList());
|
slotList.append(processor.slotList());
|
||||||
|
|
||||||
PrototypeIterator prototypeIterator(objectValue, context);
|
PrototypeIterator prototypeIterator(objectValue, context);
|
||||||
@@ -534,6 +536,7 @@ QVector<PropertyInfo> getObjectTypes(const ObjectValue *objectValue, const Conte
|
|||||||
|
|
||||||
PropertyMemberProcessor processor(context);
|
PropertyMemberProcessor processor(context);
|
||||||
objectValue->processMembers(&processor);
|
objectValue->processMembers(&processor);
|
||||||
|
|
||||||
const auto props = processor.properties();
|
const auto props = processor.properties();
|
||||||
|
|
||||||
for (const PropertyInfo &property : props) {
|
for (const PropertyInfo &property : props) {
|
||||||
|
130
src/plugins/qmldesigner/designercore/model/qmlconnections.cpp
Normal file
130
src/plugins/qmldesigner/designercore/model/qmlconnections.cpp
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2020 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** 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 https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "qmlconnections.h"
|
||||||
|
|
||||||
|
#include <metainfo.h>
|
||||||
|
#include <abstractview.h>
|
||||||
|
#include <bindingproperty.h>
|
||||||
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
QmlConnections::QmlConnections()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QmlConnections::QmlConnections(const ModelNode &modelNode)
|
||||||
|
: QmlModelNodeFacade(modelNode)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QmlConnections::isValid() const
|
||||||
|
{
|
||||||
|
return isValidQmlConnections(modelNode());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QmlConnections::isValidQmlConnections(const ModelNode &modelNode)
|
||||||
|
{
|
||||||
|
return isValidQmlModelNodeFacade(modelNode)
|
||||||
|
&& modelNode.metaInfo().isValid()
|
||||||
|
&& (modelNode.type() == "Connections"
|
||||||
|
|| modelNode.type() == "QtQuick.Connections"
|
||||||
|
|| modelNode.type() == "Qt.Connections"
|
||||||
|
|| modelNode.type() == "QtQml.Connections");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Removes connections node.
|
||||||
|
*/
|
||||||
|
void QmlConnections::destroy()
|
||||||
|
{
|
||||||
|
Q_ASSERT(isValid());
|
||||||
|
modelNode().destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QmlConnections::target() const
|
||||||
|
{
|
||||||
|
if (modelNode().isValid()) {
|
||||||
|
const BindingProperty bindingproperty = modelNode().bindingProperty("target");
|
||||||
|
if (bindingproperty.isValid())
|
||||||
|
return bindingproperty.expression();
|
||||||
|
}
|
||||||
|
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlConnections::setTarget(const QString &target)
|
||||||
|
{
|
||||||
|
modelNode().bindingProperty("target").setExpression(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
ModelNode QmlConnections::getTargetNode() const
|
||||||
|
{
|
||||||
|
ModelNode result;
|
||||||
|
|
||||||
|
if (!modelNode().isValid())
|
||||||
|
return result;
|
||||||
|
|
||||||
|
const BindingProperty bindingProperty = modelNode().bindingProperty("target");
|
||||||
|
const QString bindExpression = bindingProperty.expression();
|
||||||
|
|
||||||
|
if (bindingProperty.isValid()) {
|
||||||
|
AbstractView *view = modelNode().view();
|
||||||
|
if (bindExpression.contains(".")) {
|
||||||
|
QStringList substr = bindExpression.split(".");
|
||||||
|
const QString itemId = substr.constFirst();
|
||||||
|
if (substr.size() > 1) {
|
||||||
|
const ModelNode aliasParent = view->modelNodeForId(itemId);
|
||||||
|
substr.removeFirst(); // remove id, only alias pieces left
|
||||||
|
const QString aliasBody = substr.join(".");
|
||||||
|
if (aliasParent.isValid() && aliasParent.hasBindingProperty(aliasBody.toUtf8())) {
|
||||||
|
const BindingProperty binding = aliasParent.bindingProperty(aliasBody.toUtf8());
|
||||||
|
if (binding.isValid() && view->hasId(binding.expression()))
|
||||||
|
result = view->modelNodeForId(binding.expression());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result = view->modelNodeForId(bindExpression);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<SignalHandlerProperty> QmlConnections::signalProperties() const
|
||||||
|
{
|
||||||
|
return modelNode().signalProperties();
|
||||||
|
}
|
||||||
|
|
||||||
|
ModelNode QmlConnections::createQmlConnections(AbstractView *view)
|
||||||
|
{
|
||||||
|
NodeMetaInfo nodeMetaInfo = view->model()->metaInfo("QtQuick.Connections");
|
||||||
|
return view->createModelNode("QtQuick.Connections",
|
||||||
|
nodeMetaInfo.majorVersion(),
|
||||||
|
nodeMetaInfo.minorVersion());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // QmlDesigner
|
@@ -40,13 +40,11 @@ SignalHandlerProperty::SignalHandlerProperty(const SignalHandlerProperty &proper
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SignalHandlerProperty::SignalHandlerProperty(const PropertyName &propertyName, const Internal::InternalNodePointer &internalNode, Model* model, AbstractView *view)
|
SignalHandlerProperty::SignalHandlerProperty(const PropertyName &propertyName, const Internal::InternalNodePointer &internalNode, Model* model, AbstractView *view)
|
||||||
: AbstractProperty(propertyName, internalNode, model, view)
|
: AbstractProperty(propertyName, internalNode, model, view)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SignalHandlerProperty::setSource(const QString &source)
|
void SignalHandlerProperty::setSource(const QString &source)
|
||||||
{
|
{
|
||||||
Internal::WriteLocker locker(model());
|
Internal::WriteLocker locker(model());
|
||||||
@@ -83,4 +81,30 @@ QString SignalHandlerProperty::source() const
|
|||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PropertyName SignalHandlerProperty::prefixAdded(const PropertyName &propertyName)
|
||||||
|
{
|
||||||
|
QString nameAsString = QString::fromUtf8(propertyName);
|
||||||
|
if (nameAsString.startsWith("on"))
|
||||||
|
return propertyName;
|
||||||
|
|
||||||
|
QChar firstChar = nameAsString.at(0).toUpper();
|
||||||
|
nameAsString[0] = firstChar;
|
||||||
|
nameAsString.prepend("on");
|
||||||
|
|
||||||
|
return nameAsString.toLatin1();
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyName SignalHandlerProperty::prefixRemoved(const PropertyName &propertyName)
|
||||||
|
{
|
||||||
|
QString nameAsString = QString::fromUtf8(propertyName);
|
||||||
|
if (!nameAsString.startsWith("on"))
|
||||||
|
return propertyName;
|
||||||
|
|
||||||
|
nameAsString.remove(0, 2);
|
||||||
|
QChar firstChar = nameAsString.at(0).toLower();
|
||||||
|
nameAsString[0] = firstChar;
|
||||||
|
|
||||||
|
return nameAsString.toLatin1();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -302,6 +302,7 @@ Project {
|
|||||||
"include/qmlmodelnodefacade.h",
|
"include/qmlmodelnodefacade.h",
|
||||||
"include/qmlobjectnode.h",
|
"include/qmlobjectnode.h",
|
||||||
"include/qmlstate.h",
|
"include/qmlstate.h",
|
||||||
|
"include/qmlconnections.h",
|
||||||
"include/removebasestateexception.h",
|
"include/removebasestateexception.h",
|
||||||
"include/documentmessage.h",
|
"include/documentmessage.h",
|
||||||
"include/rewriterview.h",
|
"include/rewriterview.h",
|
||||||
@@ -391,6 +392,7 @@ Project {
|
|||||||
"model/qmlmodelnodefacade.cpp",
|
"model/qmlmodelnodefacade.cpp",
|
||||||
"model/qmlobjectnode.cpp",
|
"model/qmlobjectnode.cpp",
|
||||||
"model/qmlstate.cpp",
|
"model/qmlstate.cpp",
|
||||||
|
"model/qmlconnections.cpp",
|
||||||
"model/qmltextgenerator.cpp",
|
"model/qmltextgenerator.cpp",
|
||||||
"model/qmltextgenerator.h",
|
"model/qmltextgenerator.h",
|
||||||
"model/rewriteaction.cpp",
|
"model/rewriteaction.cpp",
|
||||||
@@ -739,6 +741,12 @@ Project {
|
|||||||
"bindingeditor/bindingeditorwidget.h",
|
"bindingeditor/bindingeditorwidget.h",
|
||||||
"bindingeditor/connectionvisitor.cpp",
|
"bindingeditor/connectionvisitor.cpp",
|
||||||
"bindingeditor/connectionvisitor.h",
|
"bindingeditor/connectionvisitor.h",
|
||||||
|
"bindingeditor/signallist.cpp",
|
||||||
|
"bindingeditor/signallist.h",
|
||||||
|
"bindingeditor/signallistdialog.cpp",
|
||||||
|
"bindingeditor/signallistdialog.h",
|
||||||
|
"bindingeditor/signallistdelegate.cpp",
|
||||||
|
"bindingeditor/signallistdelegate.h",
|
||||||
"colortool/colortool.cpp",
|
"colortool/colortool.cpp",
|
||||||
"colortool/colortool.h",
|
"colortool/colortool.h",
|
||||||
"connectioneditor/addnewbackenddialog.h",
|
"connectioneditor/addnewbackenddialog.h",
|
||||||
|
Reference in New Issue
Block a user