forked from qt-creator/qt-creator
QuickDesigner.navigator: Display all QGraphicsObject-type node
properties The navigator now displays all properties whose type is a sub class of QGraphicsObject, except for those properties inherited by Qt/Item. The contents of the default property are displayed as direct children of the model node's tree node. Reparenting into and from the displayed properties is supported. original author: Joerg Schummer
This commit is contained in:
@@ -31,14 +31,21 @@
|
||||
|
||||
#include <nodeabstractproperty.h>
|
||||
#include <nodelistproperty.h>
|
||||
#include <nodeproperty.h>
|
||||
#include <metainfo.h>
|
||||
#include <propertymetainfo.h>
|
||||
#include <qgraphicswidget.h>
|
||||
#include <abstractview.h>
|
||||
#include <invalididexception.h>
|
||||
|
||||
#include <QMimeData>
|
||||
#include <QMessageBox>
|
||||
#include <QApplication>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
const int NavigatorTreeModel::NavigatorRole = Qt::UserRole;
|
||||
|
||||
NavigatorTreeModel::NavigatorTreeModel(QObject *parent)
|
||||
: QStandardItemModel(parent),
|
||||
m_blockItemChangedSignal(false)
|
||||
@@ -90,7 +97,7 @@ QMimeData *NavigatorTreeModel::mimeData(const QModelIndexList &indexList) const
|
||||
continue;
|
||||
|
||||
rowAlreadyUsedSet.insert(idIndex);
|
||||
stream << idIndex.data(Qt::UserRole).toUInt();
|
||||
stream << idIndex.data(NavigatorRole).toUInt();
|
||||
}
|
||||
|
||||
mimeData->setData("application/vnd.modelnode.list", encodedData);
|
||||
@@ -98,21 +105,11 @@ QMimeData *NavigatorTreeModel::mimeData(const QModelIndexList &indexList) const
|
||||
return mimeData;
|
||||
}
|
||||
|
||||
static bool isAnchestorInList(const ModelNode &node, const QList<ModelNode> &nodeList)
|
||||
{
|
||||
foreach (const ModelNode &nodeInList, nodeList) {
|
||||
if (nodeInList.isAncestorOf(node))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NavigatorTreeModel::dropMimeData(const QMimeData *data,
|
||||
Qt::DropAction action,
|
||||
int row,
|
||||
int column,
|
||||
const QModelIndex &parentIndex)
|
||||
const QModelIndex &dropIndex)
|
||||
{
|
||||
if (action == Qt::IgnoreAction)
|
||||
return true;
|
||||
@@ -122,59 +119,57 @@ bool NavigatorTreeModel::dropMimeData(const QMimeData *data,
|
||||
return false;
|
||||
if (column > 1)
|
||||
return false;
|
||||
if (parentIndex.model() != this)
|
||||
if (dropIndex.model() != this)
|
||||
return false;
|
||||
|
||||
QModelIndex parentIndex, parentItemIndex;
|
||||
QString parentPropertyName;
|
||||
int targetIndex;
|
||||
|
||||
QModelIndex parentIdIndex = parentIndex;
|
||||
parentIdIndex = parentIdIndex.sibling(parentIdIndex.row(), 0);
|
||||
parentIndex = dropIndex.sibling(dropIndex.row(), 0);
|
||||
targetIndex = (row > -1)? row : rowCount(parentIndex);
|
||||
|
||||
Q_ASSERT(parentIdIndex.isValid());
|
||||
|
||||
int targetIndex = 0;
|
||||
if (row > -1) {
|
||||
targetIndex = row;
|
||||
} else {
|
||||
targetIndex = rowCount(parentIdIndex);
|
||||
if (this->data(parentIndex, NavigatorRole).isValid()) {
|
||||
parentItemIndex = parentIndex;
|
||||
ModelNode parentNode = nodeForIndex(parentItemIndex);
|
||||
if (!parentNode.metaInfo().hasDefaultProperty())
|
||||
return false;
|
||||
targetIndex -= visibleProperties(parentNode).count();
|
||||
parentPropertyName = parentNode.metaInfo().defaultProperty();
|
||||
}
|
||||
else {
|
||||
parentItemIndex = parentIndex.parent();
|
||||
parentPropertyName = parentIndex.data(Qt::DisplayRole).toString();
|
||||
}
|
||||
|
||||
// Disallow dropping items between properties, which are listed first.
|
||||
if (targetIndex < 0)
|
||||
return false;
|
||||
|
||||
Q_ASSERT(parentItemIndex.isValid());
|
||||
|
||||
QByteArray encodedData = data->data("application/vnd.modelnode.list");
|
||||
QDataStream stream(&encodedData, QIODevice::ReadOnly);
|
||||
|
||||
ModelNode parentNode(nodeForIndex(parentIdIndex));
|
||||
|
||||
QList<ModelNode> nodeList;
|
||||
|
||||
while (!stream.atEnd()) {
|
||||
uint nodeHash;
|
||||
stream >> nodeHash;
|
||||
ModelNode node(nodeForHash(nodeHash));
|
||||
if (!node.isValid() || (parentNode == node) || node.isAncestorOf(parentNode))
|
||||
continue;
|
||||
nodeList.append(node);
|
||||
}
|
||||
|
||||
RewriterTransaction transaction = m_view->beginRewriterTransaction();
|
||||
foreach (const ModelNode &node, nodeList) {
|
||||
if (!isAnchestorInList(node, nodeList)) {
|
||||
if (node.parentProperty().parentModelNode() != parentNode) {
|
||||
if (node != parentNode) {
|
||||
reparentModelNode(parentNode, node);
|
||||
}
|
||||
}
|
||||
|
||||
if (node.parentProperty().isNodeListProperty()) {
|
||||
int index = node.parentProperty().toNodeListProperty().toModelNodeList().indexOf(node);
|
||||
if (index < targetIndex) { // item is first removed from oldIndex, then inserted at new index
|
||||
--targetIndex;
|
||||
}
|
||||
if (index != targetIndex) {
|
||||
node.parentProperty().toNodeListProperty().slide(index, targetIndex);
|
||||
}
|
||||
}
|
||||
if (containsNodeHash(nodeHash)) {
|
||||
ModelNode node(nodeForHash(nodeHash));
|
||||
nodeList.append(node);
|
||||
}
|
||||
}
|
||||
|
||||
ModelNode parentNode(nodeForIndex(parentItemIndex));
|
||||
NodeAbstractProperty parentProperty = parentNode.nodeAbstractProperty(parentPropertyName);
|
||||
|
||||
if (parentProperty.isNodeProperty() &&
|
||||
nodeList.count() > 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
moveNodesInteractive(parentProperty, nodeList, targetIndex);
|
||||
propagateInvisible(parentNode, isNodeInvisible(parentNode));
|
||||
|
||||
return false; // don't let the view do drag&drop on its own
|
||||
@@ -192,7 +187,7 @@ NavigatorTreeModel::ItemRow NavigatorTreeModel::createItemRow(const ModelNode &n
|
||||
idItem->setDragEnabled(true);
|
||||
idItem->setDropEnabled(dropEnabled);
|
||||
idItem->setEditable(true);
|
||||
idItem->setData(hash, Qt::UserRole);
|
||||
idItem->setData(hash, NavigatorRole);
|
||||
|
||||
# ifdef _LOCK_ITEMS_
|
||||
QStandardItem *lockItem = new QStandardItem;
|
||||
@@ -200,28 +195,40 @@ NavigatorTreeModel::ItemRow NavigatorTreeModel::createItemRow(const ModelNode &n
|
||||
lockItem->setDropEnabled(dropEnabled);
|
||||
lockItem->setEditable(false);
|
||||
lockItem->setCheckable(true);
|
||||
lockItem->setData(hash, Qt::UserRole);
|
||||
lockItem->setData(hash, NavigatorRole);
|
||||
# endif
|
||||
|
||||
QStandardItem *visibilityItem = new QStandardItem;
|
||||
visibilityItem->setDropEnabled(dropEnabled);
|
||||
visibilityItem->setCheckable(true);
|
||||
visibilityItem->setEditable(false);
|
||||
visibilityItem->setData(hash, Qt::UserRole);
|
||||
visibilityItem->setData(hash, NavigatorRole);
|
||||
if (node.isRootNode()) {
|
||||
visibilityItem->setCheckable(false);
|
||||
}
|
||||
|
||||
# ifdef _LOCK_ITEMS_
|
||||
return ItemRow(idItem, lockItem, visibilityItem);
|
||||
# else
|
||||
return ItemRow(idItem, visibilityItem);
|
||||
# endif
|
||||
QMap<QString, QStandardItem *> propertyItems;
|
||||
foreach (QString propertyName, visibleProperties(node)) {
|
||||
QStandardItem *propertyItem = new QStandardItem;
|
||||
propertyItem->setSelectable(false);
|
||||
propertyItem->setDragEnabled(false);
|
||||
propertyItem->setDropEnabled(dropEnabled);
|
||||
propertyItem->setEditable(false);
|
||||
propertyItem->setData(propertyName, Qt::DisplayRole);
|
||||
propertyItems.insert(propertyName, propertyItem);
|
||||
idItem->appendRow(propertyItem);
|
||||
}
|
||||
|
||||
# ifdef _LOCK_ITEMS_
|
||||
return ItemRow(idItem, lockItem, visibilityItem, propertyItems);
|
||||
# else
|
||||
return ItemRow(idItem, visibilityItem, propertyItems);
|
||||
# endif
|
||||
}
|
||||
|
||||
void NavigatorTreeModel::updateItemRow(const ModelNode &node, ItemRow items)
|
||||
{
|
||||
bool blockSignal = blockItemChangedSignal(true);
|
||||
bool blockSignal = blockItemChangedSignal(true);
|
||||
|
||||
items.idItem->setText(node.id());
|
||||
items.visibilityItem->setCheckState(node.auxiliaryData("invisible").toBool() ? Qt::Unchecked : Qt::Checked);
|
||||
@@ -243,20 +250,34 @@ void NavigatorTreeModel::updateItemRow(const ModelNode &node)
|
||||
/**
|
||||
Updates the sibling position of the item, depending on the position in the model.
|
||||
*/
|
||||
void NavigatorTreeModel::updateItemRowOrder(const ModelNode &node)
|
||||
void NavigatorTreeModel::updateItemRowOrder(const NodeListProperty &listProperty, const ModelNode &node, int oldIndex)
|
||||
{
|
||||
Q_UNUSED(oldIndex);
|
||||
|
||||
if (!containsNode(node))
|
||||
return;
|
||||
|
||||
ItemRow itemRow = itemRowForNode(node);
|
||||
int currentRow = itemRow.idItem->row();
|
||||
int newRow = currentRow;
|
||||
if (node.parentProperty().parentModelNode().isValid())
|
||||
newRow = modelNodeChildren(node.parentProperty().parentModelNode()).indexOf(node);
|
||||
int newRow = listProperty.toModelNodeList().indexOf(node);
|
||||
|
||||
Q_ASSERT(newRow >= 0);
|
||||
|
||||
QStandardItem *parentIdItem = 0;
|
||||
if (containsNode(listProperty.parentModelNode())) {
|
||||
ItemRow parentRow = itemRowForNode(listProperty.parentModelNode());
|
||||
parentIdItem = parentRow.propertyItems.value(listProperty.name());
|
||||
if (!parentIdItem) {
|
||||
parentIdItem = parentRow.idItem;
|
||||
newRow += visibleProperties(listProperty.parentModelNode()).count();
|
||||
}
|
||||
}
|
||||
else {
|
||||
parentIdItem = itemRow.idItem->parent();
|
||||
}
|
||||
Q_ASSERT(parentIdItem);
|
||||
|
||||
if (currentRow != newRow) {
|
||||
QStandardItem *parentIdItem = itemRow.idItem->parent();
|
||||
QList<QStandardItem*> items = parentIdItem->takeRow(currentRow);
|
||||
parentIdItem->insertRow(newRow, items);
|
||||
}
|
||||
@@ -266,8 +287,10 @@ void NavigatorTreeModel::handleChangedItem(QStandardItem *item)
|
||||
{
|
||||
if (m_blockItemChangedSignal)
|
||||
return;
|
||||
if (!data(item->index(), NavigatorRole).isValid())
|
||||
return;
|
||||
|
||||
uint nodeHash = item->data(Qt::UserRole).toUInt();
|
||||
uint nodeHash = item->data(NavigatorRole).toUInt();
|
||||
Q_ASSERT(nodeHash && containsNodeHash(nodeHash));
|
||||
ModelNode node = nodeForHash(nodeHash);
|
||||
|
||||
@@ -323,7 +346,12 @@ NavigatorTreeModel::ItemRow NavigatorTreeModel::itemRowForNode(const ModelNode &
|
||||
void NavigatorTreeModel::setView(AbstractView *view)
|
||||
{
|
||||
m_view = view;
|
||||
addSubTree(view->rootModelNode());
|
||||
m_hiddenProperties.clear();
|
||||
if (view) {
|
||||
ModelNode sampleItemNode(m_view->createModelNode("Qt/Item", 4, 7));
|
||||
m_hiddenProperties << visibleProperties(sampleItemNode);
|
||||
addSubTree(view->rootModelNode());
|
||||
}
|
||||
}
|
||||
|
||||
void NavigatorTreeModel::clearView()
|
||||
@@ -346,7 +374,7 @@ QModelIndex NavigatorTreeModel::indexForNode(const ModelNode &node) const
|
||||
ModelNode NavigatorTreeModel::nodeForIndex(const QModelIndex &index) const
|
||||
{
|
||||
Q_ASSERT(index.isValid());
|
||||
uint hash = index.data(Qt::UserRole).toUInt();
|
||||
uint hash = index.data(NavigatorRole).toUInt();
|
||||
Q_ASSERT(hash);
|
||||
Q_ASSERT(containsNodeHash(hash));
|
||||
return nodeForHash(hash);
|
||||
@@ -380,6 +408,8 @@ void NavigatorTreeModel::addSubTree(const ModelNode &node)
|
||||
Q_ASSERT(node.isValid());
|
||||
Q_ASSERT(!containsNodeHash(qHash(node)));
|
||||
|
||||
//updateItemRow(node, newRow);
|
||||
|
||||
// only add items that are in the modelNodeChildren list (that means, visible in the editor)
|
||||
if (!node.isRootNode()
|
||||
&& !modelNodeChildren(node.parentProperty().parentModelNode()).contains(node)) {
|
||||
@@ -397,9 +427,16 @@ void NavigatorTreeModel::addSubTree(const ModelNode &node)
|
||||
|
||||
// We assume that the node is always added to the _end_ of the property list.
|
||||
if (node.hasParentProperty()) {
|
||||
ItemRow parentRow = itemRowForNode(node.parentProperty().parentModelNode());
|
||||
if (parentRow.idItem)
|
||||
parentRow.idItem->appendRow(newRow.toList());
|
||||
AbstractProperty property(node.parentProperty());
|
||||
ItemRow parentRow = itemRowForNode(property.parentModelNode());
|
||||
QStandardItem *parentItem = parentRow.propertyItems.value(property.name());
|
||||
if (!parentItem) {
|
||||
// Child nodes in the default property are added directly under the
|
||||
// parent.
|
||||
parentItem = parentRow.idItem;
|
||||
}
|
||||
if (parentItem)
|
||||
parentItem->appendRow(newRow.toList());
|
||||
} else {
|
||||
appendRow(newRow.toList());
|
||||
}
|
||||
@@ -431,26 +468,111 @@ void NavigatorTreeModel::removeSubTree(const ModelNode &node)
|
||||
m_nodeItemHash.remove(node);
|
||||
}
|
||||
|
||||
void NavigatorTreeModel::reparentModelNode(const ModelNode &parentNode, const ModelNode &node)
|
||||
void NavigatorTreeModel::moveNodesInteractive(NodeAbstractProperty parentProperty, const QList<ModelNode> &modelNodes, int targetIndex)
|
||||
{
|
||||
parentNode.nodeListProperty("data").reparentHere(node);
|
||||
QString propertyQmlType = qmlTypeInQtContainer(parentProperty.metaInfo().type());
|
||||
|
||||
RewriterTransaction transaction = m_view->beginRewriterTransaction();
|
||||
foreach (const ModelNode &node, modelNodes) {
|
||||
if (!node.isValid())
|
||||
continue;
|
||||
|
||||
if (node != parentProperty.parentModelNode() &&
|
||||
!node.isAncestorOf(parentProperty.parentModelNode()) &&
|
||||
node.metaInfo().isSubclassOf(propertyQmlType, -1, -1)) {
|
||||
|
||||
if (node.parentProperty() != parentProperty) {
|
||||
|
||||
if (parentProperty.isNodeProperty()) {
|
||||
ModelNode propertyNode = parentProperty.toNodeProperty().modelNode();
|
||||
// Destruction of ancestors is not allowed
|
||||
if (propertyNode.isAncestorOf(node)) {
|
||||
continue;
|
||||
}
|
||||
if (propertyNode.isValid()) {
|
||||
QApplication::setOverrideCursor(Qt::ArrowCursor);
|
||||
if (QMessageBox::warning(0, tr("Warning"), tr("Reparenting the component %1 here will cause the component %2 to be deleted. Do you want to proceed?").arg(node.id(), propertyNode.id()), QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel) {
|
||||
QApplication::restoreOverrideCursor();
|
||||
continue;
|
||||
}
|
||||
QApplication::restoreOverrideCursor();
|
||||
propertyNode.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
parentProperty.reparentHere(node);
|
||||
}
|
||||
|
||||
if (parentProperty.isNodeListProperty()) {
|
||||
int index = parentProperty.toNodeListProperty().toModelNodeList().indexOf(node);
|
||||
if (index < targetIndex) { // item is first removed from oldIndex, then inserted at new index
|
||||
--targetIndex;
|
||||
}
|
||||
if (index != targetIndex) {
|
||||
parentProperty.toNodeListProperty().slide(index, targetIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QList<ModelNode> NavigatorTreeModel::modelNodeChildren(const ModelNode &parentNode)
|
||||
{
|
||||
QList<ModelNode> children;
|
||||
QStringList properties;
|
||||
|
||||
if (parentNode.hasProperty("children")) {
|
||||
children.append(parentNode.nodeListProperty("children").toModelNodeList());
|
||||
}
|
||||
if (parentNode.metaInfo().hasDefaultProperty())
|
||||
properties << parentNode.metaInfo().defaultProperty();
|
||||
|
||||
if (parentNode.hasProperty("data")) {
|
||||
children.append(parentNode.nodeListProperty("data").toModelNodeList());
|
||||
properties << visibleProperties(parentNode);
|
||||
|
||||
foreach (QString propertyName, properties) {
|
||||
AbstractProperty property(parentNode.property(propertyName));
|
||||
if (property.isNodeProperty())
|
||||
children << property.toNodeProperty().modelNode();
|
||||
else if (property.isNodeListProperty())
|
||||
children << property.toNodeListProperty().toModelNodeList();
|
||||
}
|
||||
|
||||
return children;
|
||||
}
|
||||
|
||||
QString NavigatorTreeModel::qmlTypeInQtContainer(const QString &qtContainerType) const
|
||||
{
|
||||
QString typeName(qtContainerType);
|
||||
if (typeName.startsWith("QDeclarativeListProperty<") &&
|
||||
typeName.endsWith(">")) {
|
||||
typeName.remove(0, 25);
|
||||
typeName.chop(1);
|
||||
}
|
||||
if (typeName.endsWith('*'))
|
||||
typeName.chop(1);
|
||||
|
||||
return m_view->model()->metaInfo().fromQtTypes(typeName);
|
||||
}
|
||||
|
||||
|
||||
QStringList NavigatorTreeModel::visibleProperties(const ModelNode &node) const
|
||||
{
|
||||
QStringList propertyList;
|
||||
|
||||
foreach (PropertyMetaInfo propertyMetaInfo, node.metaInfo().properties().values()) {
|
||||
if (!m_hiddenProperties.contains(propertyMetaInfo.name()) &&
|
||||
propertyMetaInfo.name() != node.metaInfo().defaultProperty() &&
|
||||
propertyMetaInfo.isReadable() &&
|
||||
propertyMetaInfo.isWriteable()) {
|
||||
|
||||
QString qmlType = qmlTypeInQtContainer(propertyMetaInfo.type());
|
||||
if (node.metaInfo().metaInfo().hasNodeMetaInfo(qmlType) &&
|
||||
node.metaInfo().metaInfo().nodeMetaInfo(qmlType).isSubclassOf("QGraphicsObject", -1, -1)) {
|
||||
propertyList << propertyMetaInfo.name();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return propertyList;
|
||||
}
|
||||
|
||||
// along the lines of QObject::blockSignals
|
||||
bool NavigatorTreeModel::blockItemChangedSignal(bool block)
|
||||
{
|
||||
|
||||
@@ -50,8 +50,8 @@ class NavigatorTreeModel : public QStandardItemModel
|
||||
struct ItemRow {
|
||||
ItemRow()
|
||||
: idItem(0), lockItem(0), visibilityItem(0) {}
|
||||
ItemRow(QStandardItem *id, QStandardItem *lock, QStandardItem *visibility)
|
||||
: idItem(id), lockItem(lock), visibilityItem(visibility) {}
|
||||
ItemRow(QStandardItem *id, QStandardItem *lock, QStandardItem *visibility, const PropertyItemMap &properties)
|
||||
: idItem(id), lockItem(lock), visibilityItem(visibility), propertyItems(properties) {}
|
||||
|
||||
QList<QStandardItem*> toList() const {
|
||||
return QList<QStandardItem*>() << idItem << lockItem << visibilityItem;
|
||||
@@ -60,13 +60,14 @@ class NavigatorTreeModel : public QStandardItemModel
|
||||
QStandardItem *idItem;
|
||||
QStandardItem *lockItem;
|
||||
QStandardItem *visibilityItem;
|
||||
QMap<QString, QStandardItem *> propertyItems;
|
||||
};
|
||||
#else
|
||||
struct ItemRow {
|
||||
ItemRow()
|
||||
: idItem(0), visibilityItem(0) {}
|
||||
ItemRow(QStandardItem *id, QStandardItem *visibility)
|
||||
: idItem(id), visibilityItem(visibility) {}
|
||||
ItemRow(QStandardItem *id, QStandardItem *visibility, const QMap<QString, QStandardItem *> &properties)
|
||||
: idItem(id), visibilityItem(visibility), propertyItems(properties) {}
|
||||
|
||||
QList<QStandardItem*> toList() const {
|
||||
return QList<QStandardItem*>() << idItem << visibilityItem;
|
||||
@@ -74,9 +75,12 @@ class NavigatorTreeModel : public QStandardItemModel
|
||||
|
||||
QStandardItem *idItem;
|
||||
QStandardItem *visibilityItem;
|
||||
QMap<QString, QStandardItem *> propertyItems;
|
||||
};
|
||||
#endif
|
||||
|
||||
static const int NavigatorRole;
|
||||
|
||||
public:
|
||||
NavigatorTreeModel(QObject *parent = 0);
|
||||
~NavigatorTreeModel();
|
||||
@@ -105,7 +109,7 @@ public:
|
||||
void addSubTree(const ModelNode &node);
|
||||
void removeSubTree(const ModelNode &node);
|
||||
void updateItemRow(const ModelNode &node);
|
||||
void updateItemRowOrder(const ModelNode &node);
|
||||
void updateItemRowOrder(const NodeListProperty &listProperty, const ModelNode &movedNode, int oldIndex);
|
||||
|
||||
void setId(const QModelIndex &index, const QString &id);
|
||||
void setVisible(const QModelIndex &index, bool visible);
|
||||
@@ -123,9 +127,13 @@ private:
|
||||
ItemRow createItemRow(const ModelNode &node);
|
||||
void updateItemRow(const ModelNode &node, ItemRow row);
|
||||
|
||||
void reparentModelNode(const ModelNode &parentNode, const ModelNode &node);
|
||||
void moveNodesInteractive(NodeAbstractProperty parentProperty, const QList<ModelNode> &modelNodes, int targetIndex);
|
||||
|
||||
QList<ModelNode> modelNodeChildren(const ModelNode &parentNode);
|
||||
|
||||
QString qmlTypeInQtContainer(const QString &qtContainerType) const;
|
||||
QStringList visibleProperties(const ModelNode &node) const;
|
||||
|
||||
bool blockItemChangedSignal(bool block);
|
||||
|
||||
private:
|
||||
@@ -134,6 +142,8 @@ private:
|
||||
QWeakPointer<AbstractView> m_view;
|
||||
|
||||
bool m_blockItemChangedSignal;
|
||||
|
||||
QStringList m_hiddenProperties;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
||||
@@ -127,12 +127,19 @@ QSize IconCheckboxItemDelegate::sizeHint(const QStyleOptionViewItem &option,
|
||||
{
|
||||
Q_UNUSED(option);
|
||||
Q_UNUSED(index);
|
||||
return QSize(15,20);
|
||||
|
||||
if (!index.data(Qt::UserRole).isValid())
|
||||
return QSize();
|
||||
|
||||
return QSize(15, 20);
|
||||
}
|
||||
|
||||
void IconCheckboxItemDelegate::paint(QPainter *painter,
|
||||
const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||
{
|
||||
if (!index.data(Qt::UserRole).isValid())
|
||||
return;
|
||||
|
||||
painter->save();
|
||||
if (option.state & QStyle::State_Selected)
|
||||
drawSelectionBackground(painter, option);
|
||||
@@ -152,70 +159,84 @@ void IconCheckboxItemDelegate::paint(QPainter *painter,
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
void IdItemDelegate::paint(QPainter *painter,
|
||||
void NameItemDelegate::paint(QPainter *painter,
|
||||
const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||
{
|
||||
if (option.state & QStyle::State_Selected)
|
||||
drawSelectionBackground(painter, option);
|
||||
|
||||
QString displayString;
|
||||
QPoint displayStringOffset;
|
||||
|
||||
painter->save();
|
||||
|
||||
if (m_TreeModel->isNodeInvisible( index ))
|
||||
painter->setOpacity(0.5);
|
||||
if (index.data(Qt::UserRole).isValid()) {
|
||||
|
||||
ModelNode node = m_TreeModel->nodeForIndex(index);
|
||||
int pixmapSide = 16;
|
||||
|
||||
QIcon icon;
|
||||
if (node.metaInfo().isValid()) {
|
||||
icon=node.metaInfo().icon();
|
||||
if (icon.isNull())
|
||||
{
|
||||
// if node has no own icon, search for it in the itemlibrary
|
||||
const NodeMetaInfo typeInfo = node.metaInfo();
|
||||
const ItemLibraryInfo *libraryInfo = node.metaInfo().metaInfo().itemLibraryInfo();
|
||||
QList <ItemLibraryEntry> infoList = libraryInfo->entriesForType(typeInfo.typeName(),
|
||||
typeInfo.majorVersion(),
|
||||
typeInfo.minorVersion());
|
||||
foreach (const ItemLibraryEntry &entry, infoList) {
|
||||
if (!icon.isNull()) {
|
||||
icon = entry.icon();
|
||||
break;
|
||||
if (m_TreeModel->isNodeInvisible( index ))
|
||||
painter->setOpacity(0.5);
|
||||
|
||||
ModelNode node = m_TreeModel->nodeForIndex(index);
|
||||
|
||||
QIcon icon;
|
||||
if (node.metaInfo().isValid()) {
|
||||
icon=node.metaInfo().icon();
|
||||
if (icon.isNull())
|
||||
{
|
||||
// if node has no own icon, search for it in the itemlibrary
|
||||
const NodeMetaInfo typeInfo = node.metaInfo();
|
||||
const ItemLibraryInfo *libraryInfo = node.metaInfo().metaInfo().itemLibraryInfo();
|
||||
QList <ItemLibraryEntry> infoList = libraryInfo->entriesForType(typeInfo.typeName(),
|
||||
typeInfo.majorVersion(),
|
||||
typeInfo.minorVersion());
|
||||
foreach (const ItemLibraryEntry &entry, infoList) {
|
||||
if (!icon.isNull()) {
|
||||
icon = entry.icon();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if the library was also empty, use the default icon
|
||||
if (icon.isNull())
|
||||
icon = QIcon(QLatin1String(":/ItemLibrary/images/item-default-icon.png"));
|
||||
|
||||
// If no icon is present, leave an empty space of 24 pixels anyway
|
||||
int pixmapSide = 16;
|
||||
QPixmap pixmap = icon.pixmap(pixmapSide, pixmapSide);
|
||||
painter->drawPixmap(option.rect.x()+1,option.rect.y()+2,pixmap);
|
||||
// If no icon is present, leave an empty space of 24 pixels anyway
|
||||
QPixmap pixmap = icon.pixmap(pixmapSide, pixmapSide);
|
||||
painter->drawPixmap(option.rect.x()+1,option.rect.y()+2,pixmap);
|
||||
|
||||
QString myString = node.id();
|
||||
if (myString.isEmpty())
|
||||
myString = node.simplifiedTypeName();
|
||||
displayString = node.id();
|
||||
if (displayString.isEmpty())
|
||||
displayString = node.simplifiedTypeName();
|
||||
|
||||
// Check text length does not exceed available space
|
||||
int extraSpace=12+pixmapSide;
|
||||
QFontMetrics fm(option.font);
|
||||
myString = fm.elidedText(myString,Qt::ElideMiddle,option.rect.width()-extraSpace);
|
||||
// Check text length does not exceed available space
|
||||
int extraSpace=12+pixmapSide;
|
||||
QFontMetrics fm(option.font);
|
||||
displayString = fm.elidedText(displayString,Qt::ElideMiddle,option.rect.width()-extraSpace);
|
||||
displayStringOffset = QPoint(5+pixmapSide,-5);
|
||||
}
|
||||
else {
|
||||
displayString = index.data(Qt::DisplayRole).toString();
|
||||
displayStringOffset = QPoint(0, -2);
|
||||
}
|
||||
|
||||
painter->drawText(option.rect.bottomLeft()+QPoint(5+pixmapSide,-5),myString);
|
||||
painter->drawText(option.rect.bottomLeft()+displayStringOffset,displayString);
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
QWidget *IdItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||
QWidget *NameItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||
{
|
||||
Q_UNUSED(option);
|
||||
Q_UNUSED(index);
|
||||
if (!index.data(Qt::UserRole).isValid())
|
||||
return 0;
|
||||
|
||||
return new QLineEdit(parent);
|
||||
}
|
||||
|
||||
void IdItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
|
||||
void NameItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
|
||||
{
|
||||
ModelNode node = m_TreeModel->nodeForIndex(index);
|
||||
QString value = node.id();
|
||||
@@ -224,7 +245,7 @@ void IdItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) co
|
||||
lineEdit->setText(value);
|
||||
}
|
||||
|
||||
void IdItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
|
||||
void NameItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
|
||||
{
|
||||
Q_UNUSED(model);
|
||||
QLineEdit *lineEdit = static_cast<QLineEdit*>(editor);
|
||||
@@ -232,7 +253,7 @@ void IdItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, co
|
||||
lineEdit->clearFocus();
|
||||
}
|
||||
|
||||
void IdItemDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||
void NameItemDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||
{
|
||||
Q_UNUSED(index);
|
||||
QLineEdit *lineEdit = static_cast<QLineEdit*>(editor);
|
||||
|
||||
@@ -70,10 +70,10 @@ class IconCheckboxItemDelegate : public QStyledItemDelegate
|
||||
|
||||
};
|
||||
|
||||
class IdItemDelegate : public QStyledItemDelegate
|
||||
class NameItemDelegate : public QStyledItemDelegate
|
||||
{
|
||||
public:
|
||||
explicit IdItemDelegate(QObject *parent=0, NavigatorTreeModel *treeModel=NULL) : QStyledItemDelegate(parent),m_TreeModel(treeModel) {}
|
||||
explicit NameItemDelegate(QObject *parent=0, NavigatorTreeModel *treeModel=NULL) : QStyledItemDelegate(parent),m_TreeModel(treeModel) {}
|
||||
|
||||
void paint(QPainter *painter,
|
||||
const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
||||
|
||||
@@ -49,7 +49,7 @@ NavigatorView::NavigatorView(QObject* parent) :
|
||||
connect(treeWidget()->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(changeSelection(QItemSelection,QItemSelection)));
|
||||
treeWidget()->setIndentation(treeWidget()->indentation() * 0.5);
|
||||
|
||||
IdItemDelegate *idDelegate = new IdItemDelegate(this,m_treeModel.data());
|
||||
NameItemDelegate *idDelegate = new NameItemDelegate(this,m_treeModel.data());
|
||||
IconCheckboxItemDelegate *showDelegate = new IconCheckboxItemDelegate(this,":/qmldesigner/images/eye_open.png",
|
||||
":/qmldesigner/images/placeholder.png",m_treeModel.data());
|
||||
|
||||
@@ -191,10 +191,10 @@ void NavigatorView::scriptFunctionsChanged(const ModelNode &/*node*/, const QStr
|
||||
}
|
||||
|
||||
|
||||
void NavigatorView::nodeOrderChanged(const NodeListProperty &/*listProperty*/, const ModelNode &node, int /*oldIndex*/)
|
||||
void NavigatorView::nodeOrderChanged(const NodeListProperty &listProperty, const ModelNode &node, int oldIndex)
|
||||
{
|
||||
if (m_treeModel->isInTree(node))
|
||||
m_treeModel->updateItemRowOrder(node);
|
||||
m_treeModel->updateItemRowOrder(listProperty, node, oldIndex);
|
||||
}
|
||||
|
||||
void NavigatorView::changeSelection(const QItemSelection & /*newSelection*/, const QItemSelection &/*deselected*/)
|
||||
@@ -203,7 +203,8 @@ void NavigatorView::changeSelection(const QItemSelection & /*newSelection*/, con
|
||||
return;
|
||||
QSet<ModelNode> nodeSet;
|
||||
foreach (const QModelIndex &index, treeWidget()->selectionModel()->selectedIndexes()) {
|
||||
nodeSet.insert(m_treeModel->nodeForIndex(index));
|
||||
if (m_treeModel->data(index, Qt::UserRole).isValid())
|
||||
nodeSet.insert(m_treeModel->nodeForIndex(index));
|
||||
}
|
||||
|
||||
bool blocked = blockSelectionChangedSignal(true);
|
||||
|
||||
Reference in New Issue
Block a user