forked from qt-creator/qt-creator
QmlDesigner: Add lock functionality to navigator
* Update icon font and change related theme and constants files * Add locked column to Navigator * Add auxiliary property "locked" * Integrate locked feature into the following components: * Transition Editor * Connection Editor * Form Editor * Text Editor * Timeline * Navigator * State Editor Task-number: QDS-826 Change-Id: Ibf3ae96e0d5daeb1ab00279b94df5aaabe75e0bb Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io> Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
committed by
Henning Gründl
parent
15f39cf37c
commit
2860e57112
@@ -98,33 +98,37 @@ QtObject {
|
|||||||
readonly property string idAliasOff: "\u005B"
|
readonly property string idAliasOff: "\u005B"
|
||||||
readonly property string idAliasOn: "\u005C"
|
readonly property string idAliasOn: "\u005C"
|
||||||
readonly property string listView: "\u005D"
|
readonly property string listView: "\u005D"
|
||||||
readonly property string mergeCells: "\u005E"
|
readonly property string lockOff: "\u005E"
|
||||||
readonly property string minus: "\u005F"
|
readonly property string lockOn: "\u005F"
|
||||||
readonly property string plus: "\u0060"
|
readonly property string mergeCells: "\u0060"
|
||||||
readonly property string redo: "\u0061"
|
readonly property string minus: "\u0061"
|
||||||
readonly property string splitColumns: "\u0062"
|
readonly property string plus: "\u0062"
|
||||||
readonly property string splitRows: "\u0063"
|
readonly property string redo: "\u0063"
|
||||||
readonly property string startNode: "\u0064"
|
readonly property string splitColumns: "\u0064"
|
||||||
readonly property string testIcon: "\u0065"
|
readonly property string splitRows: "\u0065"
|
||||||
readonly property string textAlignBottom: "\u0066"
|
readonly property string startNode: "\u0066"
|
||||||
readonly property string textAlignCenter: "\u0067"
|
readonly property string testIcon: "\u0067"
|
||||||
readonly property string textAlignLeft: "\u0068"
|
readonly property string textAlignBottom: "\u0068"
|
||||||
readonly property string textAlignMiddle: "\u0069"
|
readonly property string textAlignCenter: "\u0069"
|
||||||
readonly property string textAlignRight: "\u006A"
|
readonly property string textAlignLeft: "\u006A"
|
||||||
readonly property string textAlignTop: "\u006B"
|
readonly property string textAlignMiddle: "\u006B"
|
||||||
readonly property string textBulletList: "\u006C"
|
readonly property string textAlignRight: "\u006C"
|
||||||
readonly property string textFullJustification: "\u006D"
|
readonly property string textAlignTop: "\u006D"
|
||||||
readonly property string textNumberedList: "\u006E"
|
readonly property string textBulletList: "\u006E"
|
||||||
readonly property string tickIcon: "\u006F"
|
readonly property string textFullJustification: "\u006F"
|
||||||
readonly property string triState: "\u0070"
|
readonly property string textNumberedList: "\u0070"
|
||||||
readonly property string undo: "\u0071"
|
readonly property string tickIcon: "\u0071"
|
||||||
readonly property string upDownIcon: "\u0072"
|
readonly property string triState: "\u0072"
|
||||||
readonly property string upDownSquare2: "\u0073"
|
readonly property string undo: "\u0073"
|
||||||
readonly property string wildcard: "\u0074"
|
readonly property string upDownIcon: "\u0074"
|
||||||
readonly property string zoomAll: "\u0075"
|
readonly property string upDownSquare2: "\u0075"
|
||||||
readonly property string zoomIn: "\u0076"
|
readonly property string visibilityOff: "\u0076"
|
||||||
readonly property string zoomOut: "\u0077"
|
readonly property string visibilityOn: "\u0077"
|
||||||
readonly property string zoomSelection: "\u0078"
|
readonly property string wildcard: "\u0078"
|
||||||
|
readonly property string zoomAll: "\u0079"
|
||||||
|
readonly property string zoomIn: "\u007A"
|
||||||
|
readonly property string zoomOut: "\u007B"
|
||||||
|
readonly property string zoomSelection: "\u007C"
|
||||||
|
|
||||||
readonly property font iconFont: Qt.font({
|
readonly property font iconFont: Qt.font({
|
||||||
"family": controlIcons.name,
|
"family": controlIcons.name,
|
||||||
|
Binary file not shown.
@@ -347,11 +347,11 @@ public:
|
|||||||
&& !selectionContext().currentSingleSelectedNode().isRootNode()
|
&& !selectionContext().currentSingleSelectedNode().isRootNode()
|
||||||
&& selectionContext().currentSingleSelectedNode().hasParentProperty()) {
|
&& selectionContext().currentSingleSelectedNode().hasParentProperty()) {
|
||||||
|
|
||||||
ActionTemplate *selectionAction = new ActionTemplate(QString(), &ModelNodeOperations::select);
|
|
||||||
selectionAction->setParent(menu());
|
|
||||||
|
|
||||||
parentNode = selectionContext().currentSingleSelectedNode().parentProperty().parentModelNode();
|
parentNode = selectionContext().currentSingleSelectedNode().parentProperty().parentModelNode();
|
||||||
|
|
||||||
|
if (!ModelNode::isThisOrAncestorLocked(parentNode)) {
|
||||||
|
ActionTemplate *selectionAction = new ActionTemplate(QString(), &ModelNodeOperations::select);
|
||||||
|
selectionAction->setParent(menu());
|
||||||
selectionAction->setText(QString(QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Select parent: %1")).arg(
|
selectionAction->setText(QString(QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Select parent: %1")).arg(
|
||||||
captionForModelNode(parentNode)));
|
captionForModelNode(parentNode)));
|
||||||
|
|
||||||
@@ -361,11 +361,13 @@ public:
|
|||||||
|
|
||||||
menu()->addAction(selectionAction);
|
menu()->addAction(selectionAction);
|
||||||
}
|
}
|
||||||
foreach (const ModelNode &node, selectionContext().view()->allModelNodes()) {
|
}
|
||||||
|
for (const ModelNode &node : selectionContext().view()->allModelNodes()) {
|
||||||
if (node != selectionContext().currentSingleSelectedNode()
|
if (node != selectionContext().currentSingleSelectedNode()
|
||||||
&& node != parentNode
|
&& node != parentNode
|
||||||
&& contains(node, selectionContext().scenePosition())
|
&& contains(node, selectionContext().scenePosition())
|
||||||
&& !node.isRootNode()) {
|
&& !node.isRootNode()
|
||||||
|
&& !ModelNode::isThisOrAncestorLocked(node)) {
|
||||||
selectionContext().setTargetNode(node);
|
selectionContext().setTargetNode(node);
|
||||||
QString what = QString(QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Select: %1")).arg(captionForModelNode(node));
|
QString what = QString(QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Select: %1")).arg(captionForModelNode(node));
|
||||||
ActionTemplate *selectionAction = new ActionTemplate(what, &ModelNodeOperations::select);
|
ActionTemplate *selectionAction = new ActionTemplate(what, &ModelNodeOperations::select);
|
||||||
@@ -377,6 +379,9 @@ public:
|
|||||||
menu()->addAction(selectionAction);
|
menu()->addAction(selectionAction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (menu()->isEmpty())
|
||||||
|
action()->setEnabled(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -107,6 +107,8 @@ public:
|
|||||||
idAliasOff,
|
idAliasOff,
|
||||||
idAliasOn,
|
idAliasOn,
|
||||||
listView,
|
listView,
|
||||||
|
lockOff,
|
||||||
|
lockOn,
|
||||||
mergeCells,
|
mergeCells,
|
||||||
minus,
|
minus,
|
||||||
plus,
|
plus,
|
||||||
@@ -129,6 +131,8 @@ public:
|
|||||||
undo,
|
undo,
|
||||||
upDownIcon,
|
upDownIcon,
|
||||||
upDownSquare2,
|
upDownSquare2,
|
||||||
|
visibilityOff,
|
||||||
|
visibilityOn,
|
||||||
wildcard,
|
wildcard,
|
||||||
zoomAll,
|
zoomAll,
|
||||||
zoomIn,
|
zoomIn,
|
||||||
|
@@ -75,6 +75,23 @@ ConnectionModel::ConnectionModel(ConnectionView *parent)
|
|||||||
connect(this, &QStandardItemModel::dataChanged, this, &ConnectionModel::handleDataChanged);
|
connect(this, &QStandardItemModel::dataChanged, this, &ConnectionModel::handleDataChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Qt::ItemFlags ConnectionModel::flags(const QModelIndex &modelIndex) const
|
||||||
|
{
|
||||||
|
if (!modelIndex.isValid())
|
||||||
|
return Qt::ItemIsEnabled;
|
||||||
|
|
||||||
|
if (!m_connectionView || !m_connectionView->model())
|
||||||
|
return Qt::ItemIsEnabled;
|
||||||
|
|
||||||
|
const int internalId = data(index(modelIndex.row(), TargetModelNodeRow), UserRoles::InternalIdRole).toInt();
|
||||||
|
ModelNode modelNode = m_connectionView->modelNodeForInternalId(internalId);
|
||||||
|
|
||||||
|
if (modelNode.isValid() && ModelNode::isThisOrAncestorLocked(modelNode))
|
||||||
|
return Qt::ItemIsEnabled;
|
||||||
|
|
||||||
|
return Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
void ConnectionModel::resetModel()
|
void ConnectionModel::resetModel()
|
||||||
{
|
{
|
||||||
beginResetModel();
|
beginResetModel();
|
||||||
@@ -82,7 +99,7 @@ void ConnectionModel::resetModel()
|
|||||||
setHorizontalHeaderLabels(QStringList({ tr("Target"), tr("Signal Handler"), tr("Action") }));
|
setHorizontalHeaderLabels(QStringList({ tr("Target"), tr("Signal Handler"), tr("Action") }));
|
||||||
|
|
||||||
if (connectionView()->isAttached()) {
|
if (connectionView()->isAttached()) {
|
||||||
for (const ModelNode modelNode : connectionView()->allModelNodes())
|
for (const ModelNode &modelNode : connectionView()->allModelNodes())
|
||||||
addModelNode(modelNode);
|
addModelNode(modelNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,8 +111,8 @@ void ConnectionModel::resetModel()
|
|||||||
|
|
||||||
SignalHandlerProperty ConnectionModel::signalHandlerPropertyForRow(int rowNumber) const
|
SignalHandlerProperty ConnectionModel::signalHandlerPropertyForRow(int rowNumber) const
|
||||||
{
|
{
|
||||||
const int internalId = data(index(rowNumber, TargetModelNodeRow), Qt::UserRole + 1).toInt();
|
const int internalId = data(index(rowNumber, TargetModelNodeRow), UserRoles::InternalIdRole).toInt();
|
||||||
const QString targetPropertyName = data(index(rowNumber, TargetModelNodeRow), Qt::UserRole + 2).toString();
|
const QString targetPropertyName = data(index(rowNumber, TargetModelNodeRow), UserRoles::TargetPropertyNameRole).toString();
|
||||||
|
|
||||||
ModelNode modelNode = connectionView()->modelNodeForInternalId(internalId);
|
ModelNode modelNode = connectionView()->modelNodeForInternalId(internalId);
|
||||||
if (modelNode.isValid())
|
if (modelNode.isValid())
|
||||||
@@ -256,8 +273,8 @@ void ConnectionModel::updateTargetNode(int rowNumber)
|
|||||||
|
|
||||||
void ConnectionModel::updateCustomData(QStandardItem *item, const SignalHandlerProperty &signalHandlerProperty)
|
void ConnectionModel::updateCustomData(QStandardItem *item, const SignalHandlerProperty &signalHandlerProperty)
|
||||||
{
|
{
|
||||||
item->setData(signalHandlerProperty.parentModelNode().internalId(), Qt::UserRole + 1);
|
item->setData(signalHandlerProperty.parentModelNode().internalId(), UserRoles::InternalIdRole);
|
||||||
item->setData(signalHandlerProperty.name(), Qt::UserRole + 2);
|
item->setData(signalHandlerProperty.name(), UserRoles::TargetPropertyNameRole);
|
||||||
}
|
}
|
||||||
|
|
||||||
ModelNode ConnectionModel::getTargetNodeForConnection(const ModelNode &connection) const
|
ModelNode ConnectionModel::getTargetNodeForConnection(const ModelNode &connection) const
|
||||||
|
@@ -48,7 +48,14 @@ public:
|
|||||||
TargetPropertyNameRow = 1,
|
TargetPropertyNameRow = 1,
|
||||||
SourceRow = 2
|
SourceRow = 2
|
||||||
};
|
};
|
||||||
|
enum UserRoles {
|
||||||
|
InternalIdRole = Qt::UserRole + 1,
|
||||||
|
TargetPropertyNameRole
|
||||||
|
};
|
||||||
ConnectionModel(ConnectionView *parent = nullptr);
|
ConnectionModel(ConnectionView *parent = nullptr);
|
||||||
|
|
||||||
|
Qt::ItemFlags flags(const QModelIndex &modelIndex) const override;
|
||||||
|
|
||||||
void resetModel();
|
void resetModel();
|
||||||
SignalHandlerProperty signalHandlerPropertyForRow(int rowNumber) const;
|
SignalHandlerProperty signalHandlerPropertyForRow(int rowNumber) const;
|
||||||
ConnectionView *connectionView() const;
|
ConnectionView *connectionView() const;
|
||||||
|
@@ -36,6 +36,8 @@
|
|||||||
#include <variantproperty.h>
|
#include <variantproperty.h>
|
||||||
#include <signalhandlerproperty.h>
|
#include <signalhandlerproperty.h>
|
||||||
|
|
||||||
|
#include <QTableView>
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
@@ -162,6 +164,33 @@ void ConnectionView::selectedNodesChanged(const QList<ModelNode> & selectedNodeL
|
|||||||
emit connectionViewWidget()->setEnabledAddButton(selectedNodeList.count() == 1);
|
emit connectionViewWidget()->setEnabledAddButton(selectedNodeList.count() == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ConnectionView::auxiliaryDataChanged(const ModelNode &node,
|
||||||
|
const PropertyName &name,
|
||||||
|
const QVariant &data)
|
||||||
|
{
|
||||||
|
Q_UNUSED(node)
|
||||||
|
|
||||||
|
// Check if the auxiliary data is actually the locked property or if it is unlocked
|
||||||
|
if (name != QmlDesigner::lockedProperty || !data.toBool())
|
||||||
|
return;
|
||||||
|
|
||||||
|
QItemSelectionModel *selectionModel = connectionTableView()->selectionModel();
|
||||||
|
if (!selectionModel->hasSelection())
|
||||||
|
return;
|
||||||
|
|
||||||
|
QModelIndex modelIndex = selectionModel->currentIndex();
|
||||||
|
if (!modelIndex.isValid() || !model())
|
||||||
|
return;
|
||||||
|
|
||||||
|
const int internalId = connectionModel()->data(connectionModel()->index(modelIndex.row(),
|
||||||
|
ConnectionModel::TargetModelNodeRow),
|
||||||
|
ConnectionModel::UserRoles::InternalIdRole).toInt();
|
||||||
|
ModelNode modelNode = modelNodeForInternalId(internalId);
|
||||||
|
|
||||||
|
if (modelNode.isValid() && ModelNode::isThisOrAncestorLocked(modelNode))
|
||||||
|
selectionModel->clearSelection();
|
||||||
|
}
|
||||||
|
|
||||||
void ConnectionView::importsChanged(const QList<Import> & /*addedImports*/, const QList<Import> & /*removedImports*/)
|
void ConnectionView::importsChanged(const QList<Import> & /*addedImports*/, const QList<Import> & /*removedImports*/)
|
||||||
{
|
{
|
||||||
backendModel()->resetModel();
|
backendModel()->resetModel();
|
||||||
|
@@ -69,6 +69,7 @@ public:
|
|||||||
|
|
||||||
void selectedNodesChanged(const QList<ModelNode> &selectedNodeList,
|
void selectedNodesChanged(const QList<ModelNode> &selectedNodeList,
|
||||||
const QList<ModelNode> &lastSelectedNodeList) override;
|
const QList<ModelNode> &lastSelectedNodeList) override;
|
||||||
|
void auxiliaryDataChanged(const ModelNode &node, const PropertyName &name, const QVariant &data) override;
|
||||||
|
|
||||||
void importsChanged(const QList<Import> &addedImports, const QList<Import> &removedImports) override;
|
void importsChanged(const QList<Import> &addedImports, const QList<Import> &removedImports) override;
|
||||||
|
|
||||||
|
@@ -189,7 +189,7 @@ FormEditorItem *AbstractFormEditorTool::topMovableFormEditorItem(const QList<QGr
|
|||||||
FormEditorItem* AbstractFormEditorTool::nearestFormEditorItem(const QPointF &point, const QList<QGraphicsItem*> &itemList)
|
FormEditorItem* AbstractFormEditorTool::nearestFormEditorItem(const QPointF &point, const QList<QGraphicsItem*> &itemList)
|
||||||
{
|
{
|
||||||
FormEditorItem* nearestItem = nullptr;
|
FormEditorItem* nearestItem = nullptr;
|
||||||
foreach (QGraphicsItem *item, itemList) {
|
for (QGraphicsItem *item : itemList) {
|
||||||
FormEditorItem *formEditorItem = FormEditorItem::fromQGraphicsItem(item);
|
FormEditorItem *formEditorItem = FormEditorItem::fromQGraphicsItem(item);
|
||||||
|
|
||||||
if (formEditorItem && formEditorItem->flowHitTest(point))
|
if (formEditorItem && formEditorItem->flowHitTest(point))
|
||||||
@@ -201,6 +201,9 @@ FormEditorItem* AbstractFormEditorTool::nearestFormEditorItem(const QPointF &poi
|
|||||||
if (formEditorItem->parentItem() && !formEditorItem->parentItem()->isContentVisible())
|
if (formEditorItem->parentItem() && !formEditorItem->parentItem()->isContentVisible())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (formEditorItem && ModelNode::isThisOrAncestorLocked(formEditorItem->qmlItemNode().modelNode()))
|
||||||
|
continue;
|
||||||
|
|
||||||
if (!nearestItem)
|
if (!nearestItem)
|
||||||
nearestItem = formEditorItem;
|
nearestItem = formEditorItem;
|
||||||
else if (formEditorItem->selectionWeigth(point, 1) < nearestItem->selectionWeigth(point, 0))
|
else if (formEditorItem->selectionWeigth(point, 1) < nearestItem->selectionWeigth(point, 0))
|
||||||
|
@@ -250,7 +250,6 @@ void DragTool::dropEvent(const QList<QGraphicsItem *> &/*itemList*/, QGraphicsSc
|
|||||||
if (m_dragNode.isValid())
|
if (m_dragNode.isValid())
|
||||||
view()->setSelectedModelNode(m_dragNode);
|
view()->setSelectedModelNode(m_dragNode);
|
||||||
|
|
||||||
|
|
||||||
m_dragNode = QmlItemNode();
|
m_dragNode = QmlItemNode();
|
||||||
|
|
||||||
view()->changeToSelectionTool();
|
view()->changeToSelectionTool();
|
||||||
|
@@ -93,7 +93,7 @@ void RubberBandSelectionManipulator::select(SelectionType selectionType)
|
|||||||
QList<QGraphicsItem *> itemList = m_editorView->scene()->items(m_selectionRectangleElement.rect(), Qt::IntersectsItemBoundingRect);
|
QList<QGraphicsItem *> itemList = m_editorView->scene()->items(m_selectionRectangleElement.rect(), Qt::IntersectsItemBoundingRect);
|
||||||
QList<QmlItemNode> newNodeList;
|
QList<QmlItemNode> newNodeList;
|
||||||
|
|
||||||
foreach (QGraphicsItem* item, itemList)
|
for (QGraphicsItem *item : itemList)
|
||||||
{
|
{
|
||||||
FormEditorItem *formEditorItem = FormEditorItem::fromQGraphicsItem(item);
|
FormEditorItem *formEditorItem = FormEditorItem::fromQGraphicsItem(item);
|
||||||
|
|
||||||
|
@@ -49,6 +49,7 @@
|
|||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
#include <coreplugin/idocument.h>
|
#include <coreplugin/idocument.h>
|
||||||
#include <coreplugin/editormanager/editormanager.h>
|
#include <coreplugin/editormanager/editormanager.h>
|
||||||
|
#include <utils/algorithm.h>
|
||||||
|
|
||||||
#include <qmljs/qmljsmodelmanagerinterface.h>
|
#include <qmljs/qmljsmodelmanagerinterface.h>
|
||||||
|
|
||||||
@@ -57,6 +58,7 @@
|
|||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
#include <QMessageBox>
|
||||||
#include <QPlainTextEdit>
|
#include <QPlainTextEdit>
|
||||||
#include <QRandomGenerator>
|
#include <QRandomGenerator>
|
||||||
|
|
||||||
@@ -375,9 +377,41 @@ void DesignDocument::deleteSelected()
|
|||||||
if (!currentModel())
|
if (!currentModel())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
QStringList lockedNodes;
|
||||||
|
for (const ModelNode &modelNode : view()->selectedModelNodes()) {
|
||||||
|
for (const ModelNode &node : modelNode.allSubModelNodesAndThisNode()) {
|
||||||
|
if (node.isValid() && !node.isRootNode() && node.locked())
|
||||||
|
lockedNodes.push_back(node.id());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!lockedNodes.empty()) {
|
||||||
|
Utils::sort(lockedNodes);
|
||||||
|
QString detailedText = QString("<b>" + tr("Locked items:") + "</b><br>");
|
||||||
|
|
||||||
|
for (const auto &id : qAsConst(lockedNodes))
|
||||||
|
detailedText.append("- " + id + "<br>");
|
||||||
|
|
||||||
|
detailedText.chop(QString("<br>").size());
|
||||||
|
|
||||||
|
QMessageBox msgBox;
|
||||||
|
msgBox.setTextFormat(Qt::RichText);
|
||||||
|
msgBox.setIcon(QMessageBox::Question);
|
||||||
|
msgBox.setWindowTitle(tr("Delete/Cut Item"));
|
||||||
|
msgBox.setText(QString(tr("Deleting or cutting this item will modify locked items.") + "<br><br>%1")
|
||||||
|
.arg(detailedText));
|
||||||
|
msgBox.setInformativeText(tr("Do you want to continue by removing the item (Delete) or removing it and copying it to the clipboard (Cut)?"));
|
||||||
|
msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
|
||||||
|
msgBox.setDefaultButton(QMessageBox::Ok);
|
||||||
|
|
||||||
|
if (msgBox.exec() == QMessageBox::Cancel)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
rewriterView()->executeInTransaction("DesignDocument::deleteSelected", [this](){
|
rewriterView()->executeInTransaction("DesignDocument::deleteSelected", [this](){
|
||||||
QList<ModelNode> toDelete = view()->selectedModelNodes();
|
QList<ModelNode> toDelete = view()->selectedModelNodes();
|
||||||
foreach (ModelNode node, toDelete) {
|
|
||||||
|
for (ModelNode node : toDelete) {
|
||||||
if (node.isValid() && !node.isRootNode() && QmlObjectNode::isValidQmlObjectNode(node))
|
if (node.isValid() && !node.isRootNode() && QmlObjectNode::isValidQmlObjectNode(node))
|
||||||
QmlObjectNode(node).destroy();
|
QmlObjectNode(node).destroy();
|
||||||
}
|
}
|
||||||
|
@@ -203,7 +203,7 @@ QVariant NavigatorTreeModel::data(const QModelIndex &index, int role) const
|
|||||||
if (role == ItemIsVisibleRole) // independent of column
|
if (role == ItemIsVisibleRole) // independent of column
|
||||||
return m_view->isNodeInvisible(modelNode) ? Qt::Unchecked : Qt::Checked;
|
return m_view->isNodeInvisible(modelNode) ? Qt::Unchecked : Qt::Checked;
|
||||||
|
|
||||||
if (index.column() == 0) {
|
if (index.column() == ColumnType::Name) {
|
||||||
if (role == Qt::DisplayRole) {
|
if (role == Qt::DisplayRole) {
|
||||||
return modelNode.displayName();
|
return modelNode.displayName();
|
||||||
} else if (role == Qt::DecorationRole) {
|
} else if (role == Qt::DecorationRole) {
|
||||||
@@ -240,18 +240,24 @@ QVariant NavigatorTreeModel::data(const QModelIndex &index, int role) const
|
|||||||
} else if (role == ModelNodeRole) {
|
} else if (role == ModelNodeRole) {
|
||||||
return QVariant::fromValue<ModelNode>(modelNode);
|
return QVariant::fromValue<ModelNode>(modelNode);
|
||||||
}
|
}
|
||||||
} else if (index.column() == 1) { //export
|
} else if (index.column() == ColumnType::Alias) { // export
|
||||||
if (role == Qt::CheckStateRole)
|
if (role == Qt::CheckStateRole)
|
||||||
return currentQmlObjectNode.isAliasExported() ? Qt::Checked : Qt::Unchecked;
|
return currentQmlObjectNode.isAliasExported() ? Qt::Checked : Qt::Unchecked;
|
||||||
else if (role == Qt::ToolTipRole)
|
else if (role == Qt::ToolTipRole)
|
||||||
return tr("Toggles whether this item is exported as an "
|
return tr("Toggles whether this item is exported as an "
|
||||||
"alias property of the root item.");
|
"alias property of the root item.");
|
||||||
} else if (index.column() == 2) { //visible
|
} else if (index.column() == ColumnType::Visibility) { // visible
|
||||||
if (role == Qt::CheckStateRole)
|
if (role == Qt::CheckStateRole)
|
||||||
return m_view->isNodeInvisible(modelNode) ? Qt::Unchecked : Qt::Checked;
|
return m_view->isNodeInvisible(modelNode) ? Qt::Unchecked : Qt::Checked;
|
||||||
else if (role == Qt::ToolTipRole)
|
else if (role == Qt::ToolTipRole)
|
||||||
return tr("Toggles the visibility of this item in the form editor.\n"
|
return tr("Toggles the visibility of this item in the form editor.\n"
|
||||||
"This is independent of the visibility property in QML.");
|
"This is independent of the visibility property in QML.");
|
||||||
|
} else if (index.column() == ColumnType::Lock) { // lock
|
||||||
|
if (role == Qt::CheckStateRole)
|
||||||
|
return modelNode.locked() ? Qt::Checked : Qt::Unchecked;
|
||||||
|
else if (role == Qt::ToolTipRole)
|
||||||
|
return tr("Toggles whether this item is locked.\n"
|
||||||
|
"Locked items can't be modified or selected.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return QVariant();
|
return QVariant();
|
||||||
@@ -259,7 +265,16 @@ QVariant NavigatorTreeModel::data(const QModelIndex &index, int role) const
|
|||||||
|
|
||||||
Qt::ItemFlags NavigatorTreeModel::flags(const QModelIndex &index) const
|
Qt::ItemFlags NavigatorTreeModel::flags(const QModelIndex &index) const
|
||||||
{
|
{
|
||||||
if (index.column() == 0)
|
if (index.column() == ColumnType::Alias
|
||||||
|
|| index.column() == ColumnType::Visibility
|
||||||
|
|| index.column() == ColumnType::Lock)
|
||||||
|
return Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemNeverHasChildren;
|
||||||
|
|
||||||
|
const ModelNode modelNode = modelNodeForIndex(index);
|
||||||
|
if (ModelNode::isThisOrAncestorLocked(modelNode))
|
||||||
|
return Qt::NoItemFlags;
|
||||||
|
|
||||||
|
if (index.column() == ColumnType::Name)
|
||||||
return Qt::ItemIsEditable | Qt::ItemIsDropEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsSelectable | Qt::ItemIsEnabled;
|
return Qt::ItemIsEditable | Qt::ItemIsDropEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsSelectable | Qt::ItemIsEnabled;
|
||||||
|
|
||||||
return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable
|
return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable
|
||||||
@@ -378,7 +393,7 @@ int NavigatorTreeModel::columnCount(const QModelIndex &parent) const
|
|||||||
if (parent.column() > 0)
|
if (parent.column() > 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return 3;
|
return ColumnType::Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
ModelNode NavigatorTreeModel::modelNodeForIndex(const QModelIndex &index) const
|
ModelNode NavigatorTreeModel::modelNodeForIndex(const QModelIndex &index) const
|
||||||
@@ -792,11 +807,13 @@ Qt::DropActions NavigatorTreeModel::supportedDragActions() const
|
|||||||
bool NavigatorTreeModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
bool NavigatorTreeModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||||
{
|
{
|
||||||
ModelNode modelNode = modelNodeForIndex(index);
|
ModelNode modelNode = modelNodeForIndex(index);
|
||||||
if (index.column() == 1 && role == Qt::CheckStateRole) {
|
if (index.column() == ColumnType::Alias && role == Qt::CheckStateRole) {
|
||||||
QTC_ASSERT(m_view, return false);
|
QTC_ASSERT(m_view, return false);
|
||||||
m_view->handleChangedExport(modelNode, value.toInt() != 0);
|
m_view->handleChangedExport(modelNode, value.toInt() != 0);
|
||||||
} else if (index.column() == 2 && role == Qt::CheckStateRole) {
|
} else if (index.column() == ColumnType::Visibility && role == Qt::CheckStateRole) {
|
||||||
QmlVisualNode(modelNode).setVisibilityOverride(value.toInt() == 0);
|
QmlVisualNode(modelNode).setVisibilityOverride(value.toInt() == 0);
|
||||||
|
} else if (index.column() == ColumnType::Lock && role == Qt::CheckStateRole) {
|
||||||
|
modelNode.setLocked(value.toInt() != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -806,7 +823,7 @@ void NavigatorTreeModel::notifyDataChanged(const ModelNode &modelNode)
|
|||||||
{
|
{
|
||||||
const QModelIndex index = indexForModelNode(modelNode);
|
const QModelIndex index = indexForModelNode(modelNode);
|
||||||
const QAbstractItemModel *model = index.model();
|
const QAbstractItemModel *model = index.model();
|
||||||
const QModelIndex sibling = model ? model->sibling(index.row(), 2, index) : QModelIndex();
|
const QModelIndex sibling = model ? model->sibling(index.row(), ColumnType::Count - 1, index) : QModelIndex();
|
||||||
emit dataChanged(index, sibling);
|
emit dataChanged(index, sibling);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -49,6 +49,14 @@ class NavigatorTreeModel : public QAbstractItemModel, public NavigatorModelInter
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
enum ColumnType {
|
||||||
|
Name = 0,
|
||||||
|
Alias,
|
||||||
|
Visibility,
|
||||||
|
Lock,
|
||||||
|
Count
|
||||||
|
};
|
||||||
|
|
||||||
explicit NavigatorTreeModel(QObject *parent = nullptr);
|
explicit NavigatorTreeModel(QObject *parent = nullptr);
|
||||||
~NavigatorTreeModel() override;
|
~NavigatorTreeModel() override;
|
||||||
|
|
||||||
|
@@ -41,6 +41,7 @@
|
|||||||
#include <qmlitemnode.h>
|
#include <qmlitemnode.h>
|
||||||
#include <rewritingexception.h>
|
#include <rewritingexception.h>
|
||||||
#include <nodeinstanceview.h>
|
#include <nodeinstanceview.h>
|
||||||
|
#include <theme.h>
|
||||||
|
|
||||||
#include <coreplugin/editormanager/editormanager.h>
|
#include <coreplugin/editormanager/editormanager.h>
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
@@ -48,6 +49,7 @@
|
|||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
#include <utils/icon.h>
|
#include <utils/icon.h>
|
||||||
#include <utils/utilsicons.h>
|
#include <utils/utilsicons.h>
|
||||||
|
#include <utils/stylehelper.h>
|
||||||
|
|
||||||
#include <QHeaderView>
|
#include <QHeaderView>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
@@ -138,13 +140,14 @@ void NavigatorView::modelAttached(Model *model)
|
|||||||
|
|
||||||
QTreeView *treeView = treeWidget();
|
QTreeView *treeView = treeWidget();
|
||||||
|
|
||||||
treeView->header()->setSectionResizeMode(0, QHeaderView::Stretch);
|
treeView->header()->setSectionResizeMode(NavigatorTreeModel::ColumnType::Name, QHeaderView::Stretch);
|
||||||
treeView->header()->resizeSection(1,26);
|
treeView->header()->resizeSection(NavigatorTreeModel::ColumnType::Alias, 26);
|
||||||
|
treeView->header()->resizeSection(NavigatorTreeModel::ColumnType::Visibility, 26);
|
||||||
|
treeView->header()->resizeSection(NavigatorTreeModel::ColumnType::Lock, 26);
|
||||||
treeView->setIndentation(20);
|
treeView->setIndentation(20);
|
||||||
|
|
||||||
m_currentModelInterface->setFilter(false);
|
m_currentModelInterface->setFilter(false);
|
||||||
|
|
||||||
|
|
||||||
QTimer::singleShot(0, this, [this, treeView]() {
|
QTimer::singleShot(0, this, [this, treeView]() {
|
||||||
m_currentModelInterface->setFilter(
|
m_currentModelInterface->setFilter(
|
||||||
DesignerSettings::getValue(DesignerSettingsKey::NAVIGATOR_SHOW_ONLY_VISIBLE_ITEMS).toBool());
|
DesignerSettings::getValue(DesignerSettingsKey::NAVIGATOR_SHOW_ONLY_VISIBLE_ITEMS).toBool());
|
||||||
@@ -166,10 +169,6 @@ void NavigatorView::modelAttached(Model *model)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
#ifdef _LOCK_ITEMS_
|
|
||||||
treeView->header()->resizeSection(2,20);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavigatorView::modelAboutToBeDetached(Model *model)
|
void NavigatorView::modelAboutToBeDetached(Model *model)
|
||||||
@@ -332,9 +331,12 @@ void NavigatorView::nodeTypeChanged(const ModelNode &modelNode, const TypeName &
|
|||||||
}
|
}
|
||||||
|
|
||||||
void NavigatorView::auxiliaryDataChanged(const ModelNode &modelNode,
|
void NavigatorView::auxiliaryDataChanged(const ModelNode &modelNode,
|
||||||
const PropertyName & /*name*/,
|
const PropertyName &name,
|
||||||
const QVariant & /*data*/)
|
const QVariant &data)
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(name)
|
||||||
|
Q_UNUSED(data)
|
||||||
|
|
||||||
m_currentModelInterface->notifyDataChanged(modelNode);
|
m_currentModelInterface->notifyDataChanged(modelNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -613,33 +615,50 @@ void NavigatorView::setupWidget()
|
|||||||
connect(m_widget.data(), &NavigatorWidget::reverseOrderToggled, this, &NavigatorView::reverseOrderToggled);
|
connect(m_widget.data(), &NavigatorWidget::reverseOrderToggled, this, &NavigatorView::reverseOrderToggled);
|
||||||
|
|
||||||
#ifndef QMLDESIGNER_TEST
|
#ifndef QMLDESIGNER_TEST
|
||||||
|
const QString fontName = "qtds_propertyIconFont.ttf";
|
||||||
|
|
||||||
|
const QIcon visibilityOnIcon =
|
||||||
|
Utils::StyleHelper::getIconFromIconFont(fontName,
|
||||||
|
Theme::getIconUnicode(Theme::Icon::visibilityOn),
|
||||||
|
28, 28, QColor(Qt::white));
|
||||||
|
const QIcon visibilityOffIcon =
|
||||||
|
Utils::StyleHelper::getIconFromIconFont(fontName,
|
||||||
|
Theme::getIconUnicode(Theme::Icon::visibilityOff),
|
||||||
|
28, 28, QColor(Qt::white));
|
||||||
|
|
||||||
|
const QIcon aliasOnIcon =
|
||||||
|
Utils::StyleHelper::getIconFromIconFont(fontName,
|
||||||
|
Theme::getIconUnicode(Theme::Icon::idAliasOn),
|
||||||
|
28, 28, QColor(Qt::red));
|
||||||
|
const QIcon aliasOffIcon =
|
||||||
|
Utils::StyleHelper::getIconFromIconFont(fontName,
|
||||||
|
Theme::getIconUnicode(Theme::Icon::idAliasOff),
|
||||||
|
28, 28, QColor(Qt::white));
|
||||||
|
|
||||||
|
const QIcon lockOnIcon =
|
||||||
|
Utils::StyleHelper::getIconFromIconFont(fontName,
|
||||||
|
Theme::getIconUnicode(Theme::Icon::lockOn),
|
||||||
|
28, 28, QColor(Qt::white));
|
||||||
|
const QIcon lockOffIcon =
|
||||||
|
Utils::StyleHelper::getIconFromIconFont(fontName,
|
||||||
|
Theme::getIconUnicode(Theme::Icon::lockOff),
|
||||||
|
28, 28, QColor(Qt::white));
|
||||||
|
|
||||||
auto idDelegate = new NameItemDelegate(this);
|
auto idDelegate = new NameItemDelegate(this);
|
||||||
IconCheckboxItemDelegate *showDelegate =
|
|
||||||
new IconCheckboxItemDelegate(this,
|
|
||||||
Utils::Icons::EYE_OPEN_TOOLBAR.icon(),
|
|
||||||
Utils::Icons::EYE_CLOSED_TOOLBAR.icon());
|
|
||||||
|
|
||||||
IconCheckboxItemDelegate *exportDelegate =
|
IconCheckboxItemDelegate *visibilityDelegate =
|
||||||
new IconCheckboxItemDelegate(this,
|
new IconCheckboxItemDelegate(this, visibilityOnIcon, visibilityOffIcon);
|
||||||
Icons::EXPORT_CHECKED.icon(),
|
|
||||||
Icons::EXPORT_UNCHECKED.icon());
|
IconCheckboxItemDelegate *aliasDelegate =
|
||||||
|
new IconCheckboxItemDelegate(this, aliasOnIcon, aliasOffIcon);
|
||||||
|
|
||||||
#ifdef _LOCK_ITEMS_
|
|
||||||
IconCheckboxItemDelegate *lockDelegate =
|
IconCheckboxItemDelegate *lockDelegate =
|
||||||
new IconCheckboxItemDelegate(this,
|
new IconCheckboxItemDelegate(this, lockOnIcon, lockOffIcon);
|
||||||
Utils::Icons::LOCKED_TOOLBAR.icon(),
|
|
||||||
Utils::Icons::UNLOCKED_TOOLBAR.icon());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
treeWidget()->setItemDelegateForColumn(NavigatorTreeModel::ColumnType::Name, idDelegate);
|
||||||
treeWidget()->setItemDelegateForColumn(0, idDelegate);
|
treeWidget()->setItemDelegateForColumn(NavigatorTreeModel::ColumnType::Alias, aliasDelegate);
|
||||||
#ifdef _LOCK_ITEMS_
|
treeWidget()->setItemDelegateForColumn(NavigatorTreeModel::ColumnType::Visibility, visibilityDelegate);
|
||||||
treeWidget()->setItemDelegateForColumn(1,lockDelegate);
|
treeWidget()->setItemDelegateForColumn(NavigatorTreeModel::ColumnType::Lock, lockDelegate);
|
||||||
treeWidget()->setItemDelegateForColumn(2,showDelegate);
|
|
||||||
#else
|
|
||||||
treeWidget()->setItemDelegateForColumn(1, exportDelegate);
|
|
||||||
treeWidget()->setItemDelegateForColumn(2, showDelegate);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif //QMLDESIGNER_TEST
|
#endif //QMLDESIGNER_TEST
|
||||||
}
|
}
|
||||||
|
@@ -92,7 +92,6 @@ QList<QToolButton *> NavigatorWidget::createToolBarWidgets()
|
|||||||
{
|
{
|
||||||
QList<QToolButton *> buttons;
|
QList<QToolButton *> buttons;
|
||||||
|
|
||||||
|
|
||||||
auto button = new QToolButton();
|
auto button = new QToolButton();
|
||||||
button->setIcon(Icons::ARROW_LEFT.icon());
|
button->setIcon(Icons::ARROW_LEFT.icon());
|
||||||
button->setToolTip(tr("Become last sibling of parent (CTRL + Left)."));
|
button->setToolTip(tr("Become last sibling of parent (CTRL + Left)."));
|
||||||
@@ -180,7 +179,6 @@ void NavigatorWidget::enableNavigator()
|
|||||||
m_treeView->setEnabled(true);
|
m_treeView->setEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NavigatorView *NavigatorWidget::navigatorView() const
|
NavigatorView *NavigatorWidget::navigatorView() const
|
||||||
{
|
{
|
||||||
return m_navigatorView.data();
|
return m_navigatorView.data();
|
||||||
|
@@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
|
#include <QMessageBox>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
@@ -42,6 +43,7 @@
|
|||||||
#include <qmlitemnode.h>
|
#include <qmlitemnode.h>
|
||||||
#include <qmlstate.h>
|
#include <qmlstate.h>
|
||||||
#include <annotationeditor/annotationeditor.h>
|
#include <annotationeditor/annotationeditor.h>
|
||||||
|
#include <utils/algorithm.h>
|
||||||
|
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
@@ -92,6 +94,41 @@ void StatesEditorView::removeState(int nodeId)
|
|||||||
if (nodeId > 0 && hasModelNodeForInternalId(nodeId)) {
|
if (nodeId > 0 && hasModelNodeForInternalId(nodeId)) {
|
||||||
ModelNode stateNode(modelNodeForInternalId(nodeId));
|
ModelNode stateNode(modelNodeForInternalId(nodeId));
|
||||||
Q_ASSERT(stateNode.metaInfo().isSubclassOf("QtQuick.State"));
|
Q_ASSERT(stateNode.metaInfo().isSubclassOf("QtQuick.State"));
|
||||||
|
|
||||||
|
QmlModelState modelState(stateNode);
|
||||||
|
if (modelState.isValid()) {
|
||||||
|
QStringList lockedTargets;
|
||||||
|
const auto propertyChanges = modelState.propertyChanges();
|
||||||
|
for (const QmlPropertyChanges &change : propertyChanges) {
|
||||||
|
const ModelNode target = change.target();
|
||||||
|
if (target.locked())
|
||||||
|
lockedTargets.push_back(target.id());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!lockedTargets.empty()) {
|
||||||
|
Utils::sort(lockedTargets);
|
||||||
|
QString detailedText = QString("<b>" + tr("Locked items:") + "</b><br>");
|
||||||
|
|
||||||
|
for (const auto &id : qAsConst(lockedTargets))
|
||||||
|
detailedText.append("- " + id + "<br>");
|
||||||
|
|
||||||
|
detailedText.chop(QString("<br>").size());
|
||||||
|
|
||||||
|
QMessageBox msgBox;
|
||||||
|
msgBox.setTextFormat(Qt::RichText);
|
||||||
|
msgBox.setIcon(QMessageBox::Question);
|
||||||
|
msgBox.setWindowTitle(tr("Remove State"));
|
||||||
|
msgBox.setText(QString(tr("Removing this state will modify locked items.") + "<br><br>%1")
|
||||||
|
.arg(detailedText));
|
||||||
|
msgBox.setInformativeText(tr("Do you want to continue by removing the state?"));
|
||||||
|
msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
|
||||||
|
msgBox.setDefaultButton(QMessageBox::Ok);
|
||||||
|
|
||||||
|
if (msgBox.exec() == QMessageBox::Cancel)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NodeListProperty parentProperty = stateNode.parentProperty().toNodeListProperty();
|
NodeListProperty parentProperty = stateNode.parentProperty().toNodeListProperty();
|
||||||
|
|
||||||
if (parentProperty.count() <= 1) {
|
if (parentProperty.count() <= 1) {
|
||||||
@@ -104,7 +141,6 @@ void StatesEditorView::removeState(int nodeId)
|
|||||||
setCurrentState(parentProperty.at(index - 1));
|
setCurrentState(parentProperty.at(index - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
stateNode.destroy();
|
stateNode.destroy();
|
||||||
}
|
}
|
||||||
} catch (const RewritingException &e) {
|
} catch (const RewritingException &e) {
|
||||||
|
@@ -428,6 +428,18 @@ void TimelineGraphicsScene::invalidateKeyframesForTarget(const ModelNode &target
|
|||||||
TimelineSectionItem::updateFramesForTarget(child, target);
|
TimelineSectionItem::updateFramesForTarget(child, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TimelineGraphicsScene::invalidateHeightForTarget(const ModelNode &target)
|
||||||
|
{
|
||||||
|
if (!target.isValid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
const auto children = m_layout->childItems();
|
||||||
|
for (auto child : children)
|
||||||
|
TimelineSectionItem::updateHeightForTarget(child, target);
|
||||||
|
|
||||||
|
invalidateLayout();
|
||||||
|
}
|
||||||
|
|
||||||
void TimelineGraphicsScene::invalidateScene()
|
void TimelineGraphicsScene::invalidateScene()
|
||||||
{
|
{
|
||||||
ModelNode node = timelineView()->modelNodeForId(
|
ModelNode node = timelineView()->modelNodeForId(
|
||||||
|
@@ -158,6 +158,7 @@ public:
|
|||||||
|
|
||||||
void invalidateSectionForTarget(const ModelNode &modelNode);
|
void invalidateSectionForTarget(const ModelNode &modelNode);
|
||||||
void invalidateKeyframesForTarget(const ModelNode &modelNode);
|
void invalidateKeyframesForTarget(const ModelNode &modelNode);
|
||||||
|
void invalidateHeightForTarget(const ModelNode &modelNode);
|
||||||
|
|
||||||
void invalidateScene();
|
void invalidateScene();
|
||||||
void invalidateScrollbar() override;
|
void invalidateScrollbar() override;
|
||||||
|
@@ -156,4 +156,9 @@ TimelineFrameHandle *TimelineMovableAbstractItem::asTimelineFrameHandle()
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TimelineMovableAbstractItem::isLocked() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -69,6 +69,8 @@ public:
|
|||||||
virtual TimelineKeyframeItem *asTimelineKeyframeItem();
|
virtual TimelineKeyframeItem *asTimelineKeyframeItem();
|
||||||
virtual TimelineFrameHandle *asTimelineFrameHandle();
|
virtual TimelineFrameHandle *asTimelineFrameHandle();
|
||||||
|
|
||||||
|
virtual bool isLocked() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int scrollOffset() const;
|
int scrollOffset() const;
|
||||||
void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
|
void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
|
||||||
|
@@ -70,6 +70,9 @@ void TimelineMoveTool::mousePressEvent(TimelineMovableAbstractItem *item,
|
|||||||
{
|
{
|
||||||
Q_UNUSED(item)
|
Q_UNUSED(item)
|
||||||
|
|
||||||
|
if (currentItem() && currentItem()->isLocked())
|
||||||
|
return;
|
||||||
|
|
||||||
if (auto *current = currentItem()->asTimelineKeyframeItem()) {
|
if (auto *current = currentItem()->asTimelineKeyframeItem()) {
|
||||||
const qreal sourceFrame = qRound(current->mapFromSceneToFrame(current->rect().center().x()));
|
const qreal sourceFrame = qRound(current->mapFromSceneToFrame(current->rect().center().x()));
|
||||||
const qreal targetFrame = qRound(current->mapFromSceneToFrame(event->scenePos().x()));
|
const qreal targetFrame = qRound(current->mapFromSceneToFrame(event->scenePos().x()));
|
||||||
@@ -85,6 +88,9 @@ void TimelineMoveTool::mouseMoveEvent(TimelineMovableAbstractItem *item,
|
|||||||
if (!currentItem())
|
if (!currentItem())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (currentItem()->isLocked())
|
||||||
|
return;
|
||||||
|
|
||||||
if (auto *current = currentItem()->asTimelineKeyframeItem()) {
|
if (auto *current = currentItem()->asTimelineKeyframeItem()) {
|
||||||
// prevent dragging if deselecting a keyframe (Ctrl+click and drag a selected keyframe)
|
// prevent dragging if deselecting a keyframe (Ctrl+click and drag a selected keyframe)
|
||||||
if (!current->highlighted())
|
if (!current->highlighted())
|
||||||
|
@@ -171,6 +171,17 @@ void TimelineSectionItem::updateFramesForTarget(QGraphicsItem *item, const Model
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TimelineSectionItem::updateHeightForTarget(QGraphicsItem *item, const ModelNode &target)
|
||||||
|
{
|
||||||
|
if (!target.isValid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (auto sectionItem = qgraphicsitem_cast<TimelineSectionItem *>(item)) {
|
||||||
|
if (sectionItem->targetNode() == target)
|
||||||
|
sectionItem->updateHeight();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TimelineSectionItem::moveAllFrames(qreal offset)
|
void TimelineSectionItem::moveAllFrames(qreal offset)
|
||||||
{
|
{
|
||||||
if (m_timeline.isValid())
|
if (m_timeline.isValid())
|
||||||
@@ -313,6 +324,7 @@ void TimelineSectionItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
|
|||||||
|
|
||||||
if (event->button() == Qt::LeftButton) {
|
if (event->button() == Qt::LeftButton) {
|
||||||
event->accept();
|
event->accept();
|
||||||
|
if (!ModelNode::isThisOrAncestorLocked(m_targetNode))
|
||||||
toggleCollapsed();
|
toggleCollapsed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -345,6 +357,7 @@ void TimelineSectionItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
|||||||
if (m_targetNode.isValid())
|
if (m_targetNode.isValid())
|
||||||
m_targetNode.view()->setSelectedModelNode(m_targetNode);
|
m_targetNode.view()->setSelectedModelNode(m_targetNode);
|
||||||
} else {
|
} else {
|
||||||
|
if (!ModelNode::isThisOrAncestorLocked(m_targetNode))
|
||||||
toggleCollapsed();
|
toggleCollapsed();
|
||||||
}
|
}
|
||||||
update();
|
update();
|
||||||
@@ -414,6 +427,12 @@ void TimelineSectionItem::updateFrames()
|
|||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TimelineSectionItem::updateHeight()
|
||||||
|
{
|
||||||
|
invalidateHeight();
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
void TimelineSectionItem::invalidateHeight()
|
void TimelineSectionItem::invalidateHeight()
|
||||||
{
|
{
|
||||||
int height = 0;
|
int height = 0;
|
||||||
@@ -464,7 +483,8 @@ void TimelineSectionItem::invalidateFrames()
|
|||||||
|
|
||||||
bool TimelineSectionItem::collapsed() const
|
bool TimelineSectionItem::collapsed() const
|
||||||
{
|
{
|
||||||
return m_targetNode.isValid() && !m_targetNode.hasAuxiliaryData("timeline_expanded");
|
return m_targetNode.isValid()
|
||||||
|
&& (!m_targetNode.hasAuxiliaryData("timeline_expanded") || m_targetNode.locked());
|
||||||
}
|
}
|
||||||
|
|
||||||
void TimelineSectionItem::createPropertyItems()
|
void TimelineSectionItem::createPropertyItems()
|
||||||
@@ -845,6 +865,11 @@ void TimelineBarItem::commitPosition(const QPointF & /*point*/)
|
|||||||
m_oldRect = QRectF();
|
m_oldRect = QRectF();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TimelineBarItem::isLocked() const
|
||||||
|
{
|
||||||
|
return sectionItem()->targetNode().isValid() && sectionItem()->targetNode().locked();
|
||||||
|
}
|
||||||
|
|
||||||
void TimelineBarItem::scrollOffsetChanged()
|
void TimelineBarItem::scrollOffsetChanged()
|
||||||
{
|
{
|
||||||
sectionItem()->invalidateBar();
|
sectionItem()->invalidateBar();
|
||||||
@@ -904,7 +929,9 @@ void TimelineBarItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
|
|||||||
const auto p = event->pos();
|
const auto p = event->pos();
|
||||||
|
|
||||||
QRectF left, right;
|
QRectF left, right;
|
||||||
if (handleRects(rect(), left, right)) {
|
if (isLocked() && rect().contains(p)) {
|
||||||
|
setCursor(QCursor(Qt::ForbiddenCursor));
|
||||||
|
} else if (handleRects(rect(), left, right)) {
|
||||||
if (left.contains(p) || right.contains(p)) {
|
if (left.contains(p) || right.contains(p)) {
|
||||||
if (cursor().shape() != Qt::SizeHorCursor)
|
if (cursor().shape() != Qt::SizeHorCursor)
|
||||||
setCursor(QCursor(Qt::SizeHorCursor));
|
setCursor(QCursor(Qt::SizeHorCursor));
|
||||||
@@ -920,6 +947,9 @@ void TimelineBarItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
|
|||||||
|
|
||||||
void TimelineBarItem::contextMenuEvent(QGraphicsSceneContextMenuEvent* event)
|
void TimelineBarItem::contextMenuEvent(QGraphicsSceneContextMenuEvent* event)
|
||||||
{
|
{
|
||||||
|
if (isLocked())
|
||||||
|
return;
|
||||||
|
|
||||||
QMenu menu;
|
QMenu menu;
|
||||||
QAction* overrideColor = menu.addAction(tr("Override Color"));
|
QAction* overrideColor = menu.addAction(tr("Override Color"));
|
||||||
|
|
||||||
|
@@ -50,6 +50,8 @@ public:
|
|||||||
void itemMoved(const QPointF &start, const QPointF &end) override;
|
void itemMoved(const QPointF &start, const QPointF &end) override;
|
||||||
void commitPosition(const QPointF &point) override;
|
void commitPosition(const QPointF &point) override;
|
||||||
|
|
||||||
|
bool isLocked() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void scrollOffsetChanged() override;
|
void scrollOffsetChanged() override;
|
||||||
void paint(QPainter *painter,
|
void paint(QPainter *painter,
|
||||||
@@ -100,6 +102,7 @@ public:
|
|||||||
static void updateData(QGraphicsItem *item);
|
static void updateData(QGraphicsItem *item);
|
||||||
static void updateDataForTarget(QGraphicsItem *item, const ModelNode &target, bool *b);
|
static void updateDataForTarget(QGraphicsItem *item, const ModelNode &target, bool *b);
|
||||||
static void updateFramesForTarget(QGraphicsItem *item, const ModelNode &target);
|
static void updateFramesForTarget(QGraphicsItem *item, const ModelNode &target);
|
||||||
|
static void updateHeightForTarget(QGraphicsItem *item, const ModelNode &target);
|
||||||
|
|
||||||
void moveAllFrames(qreal offset);
|
void moveAllFrames(qreal offset);
|
||||||
void scaleAllFrames(qreal scale);
|
void scaleAllFrames(qreal scale);
|
||||||
@@ -121,6 +124,7 @@ protected:
|
|||||||
private:
|
private:
|
||||||
void updateData();
|
void updateData();
|
||||||
void updateFrames();
|
void updateFrames();
|
||||||
|
void updateHeight();
|
||||||
void invalidateHeight();
|
void invalidateHeight();
|
||||||
void invalidateProperties();
|
void invalidateProperties();
|
||||||
void invalidateFrames();
|
void invalidateFrames();
|
||||||
|
@@ -236,6 +236,18 @@ void TimelineView::selectedNodesChanged(const QList<ModelNode> & /*selectedNodeL
|
|||||||
m_timelineWidget->graphicsScene()->update();
|
m_timelineWidget->graphicsScene()->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TimelineView::auxiliaryDataChanged(const ModelNode &modelNode,
|
||||||
|
const PropertyName &name,
|
||||||
|
const QVariant &data)
|
||||||
|
{
|
||||||
|
if (name == QmlDesigner::lockedProperty && data.toBool() && modelNode.isValid()) {
|
||||||
|
for (const auto &node : modelNode.allSubModelNodesAndThisNode()) {
|
||||||
|
if (node.hasAuxiliaryData("timeline_expanded"))
|
||||||
|
m_timelineWidget->graphicsScene()->invalidateHeightForTarget(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TimelineView::propertiesAboutToBeRemoved(const QList<AbstractProperty> &propertyList)
|
void TimelineView::propertiesAboutToBeRemoved(const QList<AbstractProperty> &propertyList)
|
||||||
{
|
{
|
||||||
for (const auto &property : propertyList) {
|
for (const auto &property : propertyList) {
|
||||||
|
@@ -62,6 +62,9 @@ public:
|
|||||||
PropertyChangeFlags propertyChange) override;
|
PropertyChangeFlags propertyChange) override;
|
||||||
void selectedNodesChanged(const QList<ModelNode> &selectedNodeList,
|
void selectedNodesChanged(const QList<ModelNode> &selectedNodeList,
|
||||||
const QList<ModelNode> &lastSelectedNodeList) override;
|
const QList<ModelNode> &lastSelectedNodeList) override;
|
||||||
|
void auxiliaryDataChanged(const ModelNode &node,
|
||||||
|
const PropertyName &name,
|
||||||
|
const QVariant &data) override;
|
||||||
|
|
||||||
void propertiesAboutToBeRemoved(const QList<AbstractProperty> &propertyList) override;
|
void propertiesAboutToBeRemoved(const QList<AbstractProperty> &propertyList) override;
|
||||||
void propertiesRemoved(const QList<AbstractProperty> &propertyList) override;
|
void propertiesRemoved(const QList<AbstractProperty> &propertyList) override;
|
||||||
|
@@ -218,7 +218,7 @@ void TransitionEditorGraphicsScene::invalidateSectionForTarget(const ModelNode &
|
|||||||
|
|
||||||
const QList<QGraphicsItem *> items = m_layout->childItems();
|
const QList<QGraphicsItem *> items = m_layout->childItems();
|
||||||
for (auto child : items)
|
for (auto child : items)
|
||||||
TimelineSectionItem::updateDataForTarget(child, target, &found);
|
TransitionEditorSectionItem::updateDataForTarget(child, target, &found);
|
||||||
|
|
||||||
if (!found)
|
if (!found)
|
||||||
invalidateScene();
|
invalidateScene();
|
||||||
@@ -227,6 +227,18 @@ void TransitionEditorGraphicsScene::invalidateSectionForTarget(const ModelNode &
|
|||||||
invalidateLayout();
|
invalidateLayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TransitionEditorGraphicsScene::invalidateHeightForTarget(const ModelNode &target)
|
||||||
|
{
|
||||||
|
if (!target.isValid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
const auto children = m_layout->childItems();
|
||||||
|
for (auto child : children)
|
||||||
|
TransitionEditorSectionItem::updateHeightForTarget(child, target);
|
||||||
|
|
||||||
|
invalidateLayout();
|
||||||
|
}
|
||||||
|
|
||||||
void TransitionEditorGraphicsScene::invalidateScene()
|
void TransitionEditorGraphicsScene::invalidateScene()
|
||||||
{
|
{
|
||||||
invalidateScrollbar();
|
invalidateScrollbar();
|
||||||
|
@@ -93,6 +93,7 @@ public:
|
|||||||
void setRulerScaling(int scaling);
|
void setRulerScaling(int scaling);
|
||||||
|
|
||||||
void invalidateSectionForTarget(const ModelNode &modelNode);
|
void invalidateSectionForTarget(const ModelNode &modelNode);
|
||||||
|
void invalidateHeightForTarget(const ModelNode &modelNode);
|
||||||
|
|
||||||
void invalidateScene();
|
void invalidateScene();
|
||||||
void invalidateCurrentValues();
|
void invalidateCurrentValues();
|
||||||
|
@@ -196,6 +196,17 @@ void TransitionEditorSectionItem::updateData(QGraphicsItem *item)
|
|||||||
sectionItem->updateData();
|
sectionItem->updateData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TransitionEditorSectionItem::updateHeightForTarget(QGraphicsItem *item, const ModelNode &target)
|
||||||
|
{
|
||||||
|
if (!target.isValid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (auto sectionItem = qgraphicsitem_cast<TransitionEditorSectionItem *>(item)) {
|
||||||
|
if (sectionItem->targetNode() == target)
|
||||||
|
sectionItem->updateHeight();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TransitionEditorSectionItem::invalidateBar(QGraphicsItem *item)
|
void TransitionEditorSectionItem::invalidateBar(QGraphicsItem *item)
|
||||||
{
|
{
|
||||||
if (auto sectionItem = qgraphicsitem_cast<TransitionEditorSectionItem *>(item))
|
if (auto sectionItem = qgraphicsitem_cast<TransitionEditorSectionItem *>(item))
|
||||||
@@ -360,6 +371,7 @@ void TransitionEditorSectionItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent
|
|||||||
|
|
||||||
if (event->button() == Qt::LeftButton) {
|
if (event->button() == Qt::LeftButton) {
|
||||||
event->accept();
|
event->accept();
|
||||||
|
if (!ModelNode::isThisOrAncestorLocked(m_targetNode))
|
||||||
toggleCollapsed();
|
toggleCollapsed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -392,6 +404,7 @@ void TransitionEditorSectionItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *ev
|
|||||||
if (m_targetNode.isValid())
|
if (m_targetNode.isValid())
|
||||||
m_targetNode.view()->setSelectedModelNode(m_targetNode);
|
m_targetNode.view()->setSelectedModelNode(m_targetNode);
|
||||||
} else {
|
} else {
|
||||||
|
if (!ModelNode::isThisOrAncestorLocked(m_targetNode))
|
||||||
toggleCollapsed();
|
toggleCollapsed();
|
||||||
}
|
}
|
||||||
update();
|
update();
|
||||||
@@ -417,6 +430,12 @@ void TransitionEditorSectionItem::updateData()
|
|||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TransitionEditorSectionItem::updateHeight()
|
||||||
|
{
|
||||||
|
invalidateHeight();
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
const QList<QGraphicsItem *> TransitionEditorSectionItem::propertyItems() const
|
const QList<QGraphicsItem *> TransitionEditorSectionItem::propertyItems() const
|
||||||
{
|
{
|
||||||
QList<QGraphicsItem *> list;
|
QList<QGraphicsItem *> list;
|
||||||
@@ -488,7 +507,8 @@ void TransitionEditorSectionItem::invalidateProperties()
|
|||||||
|
|
||||||
bool TransitionEditorSectionItem::collapsed() const
|
bool TransitionEditorSectionItem::collapsed() const
|
||||||
{
|
{
|
||||||
return m_targetNode.isValid() && !m_targetNode.hasAuxiliaryData("timeline_expanded");
|
return m_targetNode.isValid()
|
||||||
|
&& (!m_targetNode.hasAuxiliaryData("transition_expanded") || m_targetNode.locked());
|
||||||
}
|
}
|
||||||
|
|
||||||
qreal TransitionEditorSectionItem::rulerWidth() const
|
qreal TransitionEditorSectionItem::rulerWidth() const
|
||||||
@@ -501,9 +521,9 @@ void TransitionEditorSectionItem::toggleCollapsed()
|
|||||||
QTC_ASSERT(m_targetNode.isValid(), return );
|
QTC_ASSERT(m_targetNode.isValid(), return );
|
||||||
|
|
||||||
if (collapsed())
|
if (collapsed())
|
||||||
m_targetNode.setAuxiliaryData("timeline_expanded", true);
|
m_targetNode.setAuxiliaryData("transition_expanded", true);
|
||||||
else
|
else
|
||||||
m_targetNode.removeAuxiliaryData("timeline_expanded");
|
m_targetNode.removeAuxiliaryData("transition_expanded");
|
||||||
|
|
||||||
invalidateHeight();
|
invalidateHeight();
|
||||||
}
|
}
|
||||||
@@ -592,6 +612,11 @@ void TransitionEditorBarItem::commitPosition(const QPointF & /*point*/)
|
|||||||
scrollOffsetChanged();
|
scrollOffsetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TransitionEditorBarItem::isLocked() const
|
||||||
|
{
|
||||||
|
return sectionItem() && sectionItem()->targetNode().isValid() && sectionItem()->targetNode().locked();
|
||||||
|
}
|
||||||
|
|
||||||
void TransitionEditorBarItem::scrollOffsetChanged()
|
void TransitionEditorBarItem::scrollOffsetChanged()
|
||||||
{
|
{
|
||||||
if (sectionItem())
|
if (sectionItem())
|
||||||
@@ -637,7 +662,9 @@ void TransitionEditorBarItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
|
|||||||
const auto p = event->pos();
|
const auto p = event->pos();
|
||||||
|
|
||||||
QRectF left, right;
|
QRectF left, right;
|
||||||
if (handleRects(rect(), left, right)) {
|
if (isLocked() && rect().contains(p)) {
|
||||||
|
setCursor(QCursor(Qt::ForbiddenCursor));
|
||||||
|
} else if (handleRects(rect(), left, right)) {
|
||||||
if (left.contains(p) || right.contains(p)) {
|
if (left.contains(p) || right.contains(p)) {
|
||||||
if (cursor().shape() != Qt::SizeHorCursor)
|
if (cursor().shape() != Qt::SizeHorCursor)
|
||||||
setCursor(QCursor(Qt::SizeHorCursor));
|
setCursor(QCursor(Qt::SizeHorCursor));
|
||||||
|
@@ -54,6 +54,8 @@ public:
|
|||||||
void itemMoved(const QPointF &start, const QPointF &end) override;
|
void itemMoved(const QPointF &start, const QPointF &end) override;
|
||||||
void commitPosition(const QPointF &point) override;
|
void commitPosition(const QPointF &point) override;
|
||||||
|
|
||||||
|
bool isLocked() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void scrollOffsetChanged() override;
|
void scrollOffsetChanged() override;
|
||||||
void paint(QPainter *painter,
|
void paint(QPainter *painter,
|
||||||
@@ -106,6 +108,7 @@ public:
|
|||||||
static void updateData(QGraphicsItem *item);
|
static void updateData(QGraphicsItem *item);
|
||||||
static void invalidateBar(QGraphicsItem *item);
|
static void invalidateBar(QGraphicsItem *item);
|
||||||
static void updateDataForTarget(QGraphicsItem *item, const ModelNode &target, bool *b);
|
static void updateDataForTarget(QGraphicsItem *item, const ModelNode &target, bool *b);
|
||||||
|
static void updateHeightForTarget(QGraphicsItem *item, const ModelNode &target);
|
||||||
|
|
||||||
void moveAllDurations(qreal offset);
|
void moveAllDurations(qreal offset);
|
||||||
void scaleAllDurations(qreal scale);
|
void scaleAllDurations(qreal scale);
|
||||||
@@ -125,6 +128,7 @@ protected:
|
|||||||
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override;
|
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void updateHeight();
|
||||||
void invalidateHeight();
|
void invalidateHeight();
|
||||||
void invalidateProperties();
|
void invalidateProperties();
|
||||||
bool collapsed() const;
|
bool collapsed() const;
|
||||||
|
@@ -142,6 +142,18 @@ void TransitionEditorView::selectedNodesChanged(const QList<ModelNode> & /*selec
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TransitionEditorView::auxiliaryDataChanged(const ModelNode &modelNode,
|
||||||
|
const PropertyName &name,
|
||||||
|
const QVariant &data)
|
||||||
|
{
|
||||||
|
if (name == QmlDesigner::lockedProperty && data.toBool() && modelNode.isValid()) {
|
||||||
|
for (const auto &node : modelNode.allSubModelNodesAndThisNode()) {
|
||||||
|
if (node.hasAuxiliaryData("transition_expanded"))
|
||||||
|
m_transitionEditorWidget->graphicsScene()->invalidateHeightForTarget(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TransitionEditorView::propertiesAboutToBeRemoved(
|
void TransitionEditorView::propertiesAboutToBeRemoved(
|
||||||
const QList<AbstractProperty> & /*propertyList */)
|
const QList<AbstractProperty> & /*propertyList */)
|
||||||
{
|
{
|
||||||
|
@@ -60,6 +60,9 @@ public:
|
|||||||
PropertyChangeFlags propertyChange) override;
|
PropertyChangeFlags propertyChange) override;
|
||||||
void selectedNodesChanged(const QList<ModelNode> &selectedNodeList,
|
void selectedNodesChanged(const QList<ModelNode> &selectedNodeList,
|
||||||
const QList<ModelNode> &lastSelectedNodeList) override;
|
const QList<ModelNode> &lastSelectedNodeList) override;
|
||||||
|
void auxiliaryDataChanged(const ModelNode &node,
|
||||||
|
const PropertyName &name,
|
||||||
|
const QVariant &data) override;
|
||||||
|
|
||||||
void propertiesAboutToBeRemoved(const QList<AbstractProperty> &propertyList) override;
|
void propertiesAboutToBeRemoved(const QList<AbstractProperty> &propertyList) override;
|
||||||
void propertiesRemoved(const QList<AbstractProperty> &propertyList) override;
|
void propertiesRemoved(const QList<AbstractProperty> &propertyList) override;
|
||||||
|
@@ -147,6 +147,7 @@ public:
|
|||||||
|
|
||||||
void setSelectedModelNodes(const QList<ModelNode> &selectedNodeList);
|
void setSelectedModelNodes(const QList<ModelNode> &selectedNodeList);
|
||||||
void setSelectedModelNode(const ModelNode &modelNode);
|
void setSelectedModelNode(const ModelNode &modelNode);
|
||||||
|
|
||||||
void selectModelNode(const ModelNode &node);
|
void selectModelNode(const ModelNode &node);
|
||||||
void deselectModelNode(const ModelNode &node);
|
void deselectModelNode(const ModelNode &node);
|
||||||
void clearSelectedModelNodes();
|
void clearSelectedModelNodes();
|
||||||
|
@@ -65,6 +65,8 @@ QMLDESIGNERCORE_EXPORT QList<Internal::InternalNodePointer> toInternalNodeList(c
|
|||||||
|
|
||||||
using PropertyListType = QList<QPair<PropertyName, QVariant> >;
|
using PropertyListType = QList<QPair<PropertyName, QVariant> >;
|
||||||
|
|
||||||
|
static const PropertyName lockedProperty = {("locked")};
|
||||||
|
|
||||||
class QMLDESIGNERCORE_EXPORT ModelNode
|
class QMLDESIGNERCORE_EXPORT ModelNode
|
||||||
{
|
{
|
||||||
friend QMLDESIGNERCORE_EXPORT bool operator ==(const ModelNode &firstNode, const ModelNode &secondNode);
|
friend QMLDESIGNERCORE_EXPORT bool operator ==(const ModelNode &firstNode, const ModelNode &secondNode);
|
||||||
@@ -216,6 +218,11 @@ public:
|
|||||||
void setGlobalStatus(const GlobalAnnotationStatus &status);
|
void setGlobalStatus(const GlobalAnnotationStatus &status);
|
||||||
void removeGlobalStatus();
|
void removeGlobalStatus();
|
||||||
|
|
||||||
|
bool locked() const;
|
||||||
|
void setLocked(bool value);
|
||||||
|
|
||||||
|
static bool isThisOrAncestorLocked(const ModelNode &node);
|
||||||
|
|
||||||
qint32 internalId() const;
|
qint32 internalId() const;
|
||||||
|
|
||||||
void setNodeSource(const QString&);
|
void setNodeSource(const QString&);
|
||||||
@@ -241,6 +248,8 @@ public:
|
|||||||
private: // functions
|
private: // functions
|
||||||
Internal::InternalNodePointer internalNode() const;
|
Internal::InternalNodePointer internalNode() const;
|
||||||
|
|
||||||
|
void removeLocked();
|
||||||
|
bool hasLocked() const;
|
||||||
|
|
||||||
private: // variables
|
private: // variables
|
||||||
Internal::InternalNodePointer m_internalNode;
|
Internal::InternalNodePointer m_internalNode;
|
||||||
|
@@ -534,11 +534,11 @@ void NodeInstanceView::auxiliaryDataChanged(const ModelNode &node,
|
|||||||
const PropertyName &name,
|
const PropertyName &name,
|
||||||
const QVariant &value)
|
const QVariant &value)
|
||||||
{
|
{
|
||||||
if (((node.isRootNode() && (name == "width" || name == "height")) || name == "invisible")
|
if (((node.isRootNode() && (name == "width" || name == "height")) || name == "invisible" || name == "locked")
|
||||||
|| name.endsWith(PropertyName("@NodeInstance"))) {
|
|| name.endsWith(PropertyName("@NodeInstance"))) {
|
||||||
if (hasInstanceForModelNode(node)) {
|
if (hasInstanceForModelNode(node)) {
|
||||||
NodeInstance instance = instanceForModelNode(node);
|
NodeInstance instance = instanceForModelNode(node);
|
||||||
if (value.isValid() || name == "invisible") {
|
if (value.isValid() || name == "invisible" || name == "locked") {
|
||||||
PropertyValueContainer container{instance.instanceId(), name, value, TypeName()};
|
PropertyValueContainer container{instance.instanceId(), name, value, TypeName()};
|
||||||
m_nodeInstanceServer->changeAuxiliaryValues({{container}});
|
m_nodeInstanceServer->changeAuxiliaryValues({{container}});
|
||||||
} else {
|
} else {
|
||||||
|
@@ -35,6 +35,7 @@
|
|||||||
#ifndef QMLDESIGNER_TEST
|
#ifndef QMLDESIGNER_TEST
|
||||||
#include <qmldesignerplugin.h>
|
#include <qmldesignerplugin.h>
|
||||||
#include <viewmanager.h>
|
#include <viewmanager.h>
|
||||||
|
#include <nodeabstractproperty.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <coreplugin/helpmanager.h>
|
#include <coreplugin/helpmanager.h>
|
||||||
@@ -397,7 +398,7 @@ QList<ModelNode> AbstractView::toModelNodeList(const QList<Internal::InternalNod
|
|||||||
QList<ModelNode> toModelNodeList(const QList<Internal::InternalNode::Pointer> &nodeList, AbstractView *view)
|
QList<ModelNode> toModelNodeList(const QList<Internal::InternalNode::Pointer> &nodeList, AbstractView *view)
|
||||||
{
|
{
|
||||||
QList<ModelNode> newNodeList;
|
QList<ModelNode> newNodeList;
|
||||||
foreach (const Internal::InternalNode::Pointer &node, nodeList)
|
for (const Internal::InternalNode::Pointer &node : nodeList)
|
||||||
newNodeList.append(ModelNode(node, view->model(), view));
|
newNodeList.append(ModelNode(node, view->model(), view));
|
||||||
|
|
||||||
return newNodeList;
|
return newNodeList;
|
||||||
@@ -406,7 +407,7 @@ QList<ModelNode> toModelNodeList(const QList<Internal::InternalNode::Pointer> &n
|
|||||||
QList<Internal::InternalNode::Pointer> toInternalNodeList(const QList<ModelNode> &nodeList)
|
QList<Internal::InternalNode::Pointer> toInternalNodeList(const QList<ModelNode> &nodeList)
|
||||||
{
|
{
|
||||||
QList<Internal::InternalNode::Pointer> newNodeList;
|
QList<Internal::InternalNode::Pointer> newNodeList;
|
||||||
foreach (const ModelNode &node, nodeList)
|
for (const ModelNode &node : nodeList)
|
||||||
newNodeList.append(node.internalNode());
|
newNodeList.append(node.internalNode());
|
||||||
|
|
||||||
return newNodeList;
|
return newNodeList;
|
||||||
@@ -414,15 +415,26 @@ QList<Internal::InternalNode::Pointer> toInternalNodeList(const QList<ModelNode>
|
|||||||
|
|
||||||
/*!
|
/*!
|
||||||
Sets the list of nodes to the actual selected nodes specified by
|
Sets the list of nodes to the actual selected nodes specified by
|
||||||
\a selectedNodeList.
|
\a selectedNodeList if the node or its ancestors are not locked.
|
||||||
*/
|
*/
|
||||||
void AbstractView::setSelectedModelNodes(const QList<ModelNode> &selectedNodeList)
|
void AbstractView::setSelectedModelNodes(const QList<ModelNode> &selectedNodeList)
|
||||||
{
|
{
|
||||||
model()->d->setSelectedNodes(toInternalNodeList(selectedNodeList));
|
QList<ModelNode> unlockedNodes;
|
||||||
|
|
||||||
|
for (const auto &modelNode : selectedNodeList) {
|
||||||
|
if (!ModelNode::isThisOrAncestorLocked(modelNode))
|
||||||
|
unlockedNodes.push_back(modelNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
model()->d->setSelectedNodes(toInternalNodeList(unlockedNodes));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractView::setSelectedModelNode(const ModelNode &modelNode)
|
void AbstractView::setSelectedModelNode(const ModelNode &modelNode)
|
||||||
{
|
{
|
||||||
|
if (ModelNode::isThisOrAncestorLocked(modelNode)) {
|
||||||
|
clearSelectedModelNodes();
|
||||||
|
return;
|
||||||
|
}
|
||||||
setSelectedModelNodes({modelNode});
|
setSelectedModelNodes({modelNode});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1228,6 +1228,53 @@ void ModelNode::removeGlobalStatus()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ModelNode::locked() const
|
||||||
|
{
|
||||||
|
if (hasLocked())
|
||||||
|
return auxiliaryData(lockedProperty).toBool();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ModelNode::hasLocked() const
|
||||||
|
{
|
||||||
|
return hasAuxiliaryData(lockedProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelNode::setLocked(bool value)
|
||||||
|
{
|
||||||
|
setAuxiliaryData(lockedProperty, value);
|
||||||
|
|
||||||
|
if (value) {
|
||||||
|
// Remove newly locked node and all its descendants from potential selection
|
||||||
|
for (ModelNode node : allSubModelNodesAndThisNode()) {
|
||||||
|
node.deselectNode();
|
||||||
|
node.removeAuxiliaryData("timeline_expanded");
|
||||||
|
node.removeAuxiliaryData("transition_expanded");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelNode::removeLocked()
|
||||||
|
{
|
||||||
|
if (hasLocked())
|
||||||
|
removeAuxiliaryData(lockedProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ModelNode::isThisOrAncestorLocked(const ModelNode &node)
|
||||||
|
{
|
||||||
|
if (!node.isValid())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (node.locked())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (node.isRootNode() || !node.hasParentProperty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return isThisOrAncestorLocked(node.parentProperty().parentModelNode());
|
||||||
|
}
|
||||||
|
|
||||||
void ModelNode::setScriptFunctions(const QStringList &scriptFunctionList)
|
void ModelNode::setScriptFunctions(const QStringList &scriptFunctionList)
|
||||||
{
|
{
|
||||||
model()->d->setScriptFunctions(internalNode(), scriptFunctionList);
|
model()->d->setScriptFunctions(internalNode(), scriptFunctionList);
|
||||||
|
Reference in New Issue
Block a user