QmlDesigner.FormEditor: Test if a qml item is valid to prevent crashes

This commit is contained in:
Marco Bubke
2010-09-21 16:21:35 +02:00
committed by Thomas Hartmann
parent 48ff3f7a29
commit d2b3258e59
12 changed files with 106 additions and 52 deletions

View File

@@ -128,12 +128,15 @@ AbstractFormEditorTool* FormEditorScene::currentTool() const
//This method calculates the possible parent for reparent //This method calculates the possible parent for reparent
FormEditorItem* FormEditorScene::calulateNewParent(FormEditorItem *formEditorItem) FormEditorItem* FormEditorScene::calulateNewParent(FormEditorItem *formEditorItem)
{ {
if (formEditorItem->qmlItemNode().isValid()) {
QList<QGraphicsItem *> list = items(formEditorItem->qmlItemNode().instanceBoundingRect().center()); QList<QGraphicsItem *> list = items(formEditorItem->qmlItemNode().instanceBoundingRect().center());
foreach (QGraphicsItem *graphicsItem, list) { foreach (QGraphicsItem *graphicsItem, list) {
if (qgraphicsitem_cast<FormEditorItem*>(graphicsItem) && if (qgraphicsitem_cast<FormEditorItem*>(graphicsItem) &&
graphicsItem->collidesWithItem(formEditorItem, Qt::ContainsItemShape)) graphicsItem->collidesWithItem(formEditorItem, Qt::ContainsItemShape))
return qgraphicsitem_cast<FormEditorItem*>(graphicsItem); return qgraphicsitem_cast<FormEditorItem*>(graphicsItem);
} }
}
return 0; return 0;
} }

View File

@@ -160,6 +160,9 @@ void ItemCreatorTool::createAtItem(const QRectF &rect)
QPointF pos = rect.topLeft(); QPointF pos = rect.topLeft();
QmlItemNode parentNode = view()->rootQmlItemNode(); QmlItemNode parentNode = view()->rootQmlItemNode();
if (!parentNode.isValid())
return;
FormEditorItem *parentItem = calculateContainer(pos); FormEditorItem *parentItem = calculateContainer(pos);
if (parentItem) { if (parentItem) {
parentNode = parentItem->qmlItemNode(); parentNode = parentItem->qmlItemNode();

View File

@@ -100,7 +100,9 @@ void MoveManipulator::updateHashes()
bool MoveManipulator::itemsCanReparented() const bool MoveManipulator::itemsCanReparented() const
{ {
foreach (FormEditorItem* item, m_itemList) { foreach (FormEditorItem* item, m_itemList) {
if (!item->qmlItemNode().canReparent()) if (item
&& item->qmlItemNode().isValid()
&& !item->qmlItemNode().canReparent())
return false; return false;
} }
@@ -114,16 +116,21 @@ void MoveManipulator::begin(const QPointF &beginPoint)
m_snapper.updateSnappingLines(m_itemList); m_snapper.updateSnappingLines(m_itemList);
foreach (FormEditorItem* item, m_itemList) foreach (FormEditorItem* item, m_itemList) {
if (item && item->qmlItemNode().isValid())
m_beginItemRectHash.insert(item, m_snapper.containerFormEditorItem()->mapRectFromItem(item, item->qmlItemNode().instanceBoundingRect())); m_beginItemRectHash.insert(item, m_snapper.containerFormEditorItem()->mapRectFromItem(item, item->qmlItemNode().instanceBoundingRect()));
}
foreach (FormEditorItem* item, m_itemList) { foreach (FormEditorItem* item, m_itemList) {
if (item && item->qmlItemNode().isValid()) {
QPointF positionInParentSpace(item->qmlItemNode().instancePosition()); QPointF positionInParentSpace(item->qmlItemNode().instancePosition());
QPointF positionInScenesSpace = m_snapper.containerFormEditorItem()->mapToScene(positionInParentSpace); QPointF positionInScenesSpace = m_snapper.containerFormEditorItem()->mapToScene(positionInParentSpace);
m_beginPositionInSceneSpaceHash.insert(item, positionInScenesSpace); m_beginPositionInSceneSpaceHash.insert(item, positionInScenesSpace);
} }
}
foreach (FormEditorItem* item, m_itemList) { foreach (FormEditorItem* item, m_itemList) {
if (item && item->qmlItemNode().isValid()) {
QPointF positionInParentSpace = m_snapper.containerFormEditorItem()->mapFromScene(m_beginPositionInSceneSpaceHash.value(item)); QPointF positionInParentSpace = m_snapper.containerFormEditorItem()->mapFromScene(m_beginPositionInSceneSpaceHash.value(item));
m_beginPositionHash.insert(item, positionInParentSpace); m_beginPositionHash.insert(item, positionInParentSpace);
@@ -135,6 +142,7 @@ void MoveManipulator::begin(const QPointF &beginPoint)
m_beginHorizontalCenterHash.insert(item, anchors.instanceMargin(AnchorLine::HorizontalCenter)); m_beginHorizontalCenterHash.insert(item, anchors.instanceMargin(AnchorLine::HorizontalCenter));
m_beginVerticalCenterHash.insert(item, anchors.instanceMargin(AnchorLine::VerticalCenter)); m_beginVerticalCenterHash.insert(item, anchors.instanceMargin(AnchorLine::VerticalCenter));
} }
}
m_beginPoint = beginPoint; m_beginPoint = beginPoint;
@@ -159,6 +167,10 @@ QPointF MoveManipulator::findSnappingOffset(const QHash<FormEditorItem*, QRectF>
hashIterator.next(); hashIterator.next();
FormEditorItem *formEditorItem = hashIterator.key(); FormEditorItem *formEditorItem = hashIterator.key();
QRectF boundingRect = hashIterator.value(); QRectF boundingRect = hashIterator.value();
if (!formEditorItem || !formEditorItem->qmlItemNode().isValid())
continue;
if (!formEditorItem->qmlItemNode().hasBindingProperty("x")) { if (!formEditorItem->qmlItemNode().hasBindingProperty("x")) {
double verticalOffset = m_snapper.snappedVerticalOffset(boundingRect); double verticalOffset = m_snapper.snappedVerticalOffset(boundingRect);
if (verticalOffset < std::numeric_limits<double>::max()) if (verticalOffset < std::numeric_limits<double>::max())
@@ -203,6 +215,10 @@ QHash<FormEditorItem*, QRectF> MoveManipulator::tanslatedBoundingRects(const QHa
hashIterator.next(); hashIterator.next();
FormEditorItem *formEditorItem = hashIterator.key(); FormEditorItem *formEditorItem = hashIterator.key();
QRectF boundingRect = hashIterator.value(); QRectF boundingRect = hashIterator.value();
if (!formEditorItem || !formEditorItem->qmlItemNode().isValid())
continue;
if (formEditorItem->qmlItemNode().hasBindingProperty("x")) if (formEditorItem->qmlItemNode().hasBindingProperty("x"))
alignedOffset.setX(0); alignedOffset.setX(0);
if (formEditorItem->qmlItemNode().hasBindingProperty("y")) if (formEditorItem->qmlItemNode().hasBindingProperty("y"))
@@ -245,6 +261,9 @@ void MoveManipulator::update(const QPointF& updatePoint, Snapping useSnapping, S
foreach (FormEditorItem* item, m_itemList) { foreach (FormEditorItem* item, m_itemList) {
QPointF positionInContainerSpace(m_beginPositionHash.value(item) + offsetVector); QPointF positionInContainerSpace(m_beginPositionHash.value(item) + offsetVector);
if (!item || !item->qmlItemNode().isValid())
continue;
// don't support anchors for base state because it is not needed by the droptool // don't support anchors for base state because it is not needed by the droptool
if (stateToBeManipulated == UseActualState) { if (stateToBeManipulated == UseActualState) {
QmlAnchors anchors(item->qmlItemNode().anchors()); QmlAnchors anchors(item->qmlItemNode().anchors());
@@ -311,6 +330,9 @@ void MoveManipulator::reparentTo(FormEditorItem *newParent)
return; return;
foreach (FormEditorItem* item, m_itemList) { foreach (FormEditorItem* item, m_itemList) {
if (!item || !item->qmlItemNode().isValid())
continue;
QmlItemNode parent(newParent->qmlItemNode()); QmlItemNode parent(newParent->qmlItemNode());
if (parent.isValid()) { if (parent.isValid()) {
if (parent.hasDefaultProperty()) if (parent.hasDefaultProperty())
@@ -340,6 +362,9 @@ void MoveManipulator::end(const QPointF &/*endPoint*/)
void MoveManipulator::moveBy(double deltaX, double deltaY) void MoveManipulator::moveBy(double deltaX, double deltaY)
{ {
foreach (FormEditorItem* item, m_itemList) { foreach (FormEditorItem* item, m_itemList) {
if (!item || !item->qmlItemNode().isValid())
continue;
QmlAnchors anchors(item->qmlItemNode().anchors()); QmlAnchors anchors(item->qmlItemNode().anchors());
if (anchors.instanceHasAnchor(AnchorLine::Top)) { if (anchors.instanceHasAnchor(AnchorLine::Top)) {

View File

@@ -296,7 +296,9 @@ void MoveTool::beginWithPoint(const QPointF &beginPoint)
static bool isNotAncestorOfItemInList(FormEditorItem *formEditorItem, const QList<FormEditorItem*> &itemList) static bool isNotAncestorOfItemInList(FormEditorItem *formEditorItem, const QList<FormEditorItem*> &itemList)
{ {
foreach (FormEditorItem *item, itemList) { foreach (FormEditorItem *item, itemList) {
if (item->qmlItemNode().isAncestorOf(formEditorItem->qmlItemNode())) if (item
&& item->qmlItemNode().isValid()
&& item->qmlItemNode().isAncestorOf(formEditorItem->qmlItemNode()))
return false; return false;
} }

View File

@@ -136,7 +136,7 @@ ResizeController::ResizeController(LayerItem *layerItem, FormEditorItem *formEdi
bool ResizeController::isValid() const bool ResizeController::isValid() const
{ {
return m_data->formEditorItem != 0; return m_data->formEditorItem && m_data->formEditorItem->qmlItemNode().isValid();
} }
void ResizeController::show() void ResizeController::show()
@@ -186,6 +186,8 @@ static QPointF bottomCenter(const QRectF &rect)
void ResizeController::updatePosition() void ResizeController::updatePosition()
{ {
if (isValid()) {
QRectF boundingRect = m_data->formEditorItem->qmlItemNode().instanceBoundingRect(); QRectF boundingRect = m_data->formEditorItem->qmlItemNode().instanceBoundingRect();
QPointF topLeftPointInLayerSpace(m_data->formEditorItem->mapToItem(m_data->layerItem.data(), QPointF topLeftPointInLayerSpace(m_data->formEditorItem->mapToItem(m_data->layerItem.data(),
boundingRect.topLeft())); boundingRect.topLeft()));
@@ -217,6 +219,7 @@ void ResizeController::updatePosition()
m_data->rightItem->setHandlePosition(rightPointInLayerSpace, rightCenter(boundingRect)); m_data->rightItem->setHandlePosition(rightPointInLayerSpace, rightCenter(boundingRect));
m_data->bottomItem->setHandlePosition(bottomPointInLayerSpace, bottomCenter(boundingRect)); m_data->bottomItem->setHandlePosition(bottomPointInLayerSpace, bottomCenter(boundingRect));
} }
}
FormEditorItem* ResizeController::formEditorItem() const FormEditorItem* ResizeController::formEditorItem() const

View File

@@ -71,7 +71,9 @@ void ResizeIndicator::setItems(const QList<FormEditorItem*> &itemList)
clear(); clear();
foreach (FormEditorItem* item, itemList) { foreach (FormEditorItem* item, itemList) {
if (item->qmlItemNode().isRootNode()) if (item
&& item->qmlItemNode().isValid()
&& item->qmlItemNode().isRootNode())
continue; continue;
ResizeController controller(m_layerItem, item); ResizeController controller(m_layerItem, item);
m_itemControllerHash.insert(item, controller); m_itemControllerHash.insert(item, controller);

View File

@@ -396,7 +396,7 @@ void ResizeManipulator::end()
void ResizeManipulator::moveBy(double deltaX, double deltaY) void ResizeManipulator::moveBy(double deltaX, double deltaY)
{ {
if (resizeHandle()) { if (resizeHandle() && m_resizeController.isValid()) {
QmlItemNode qmlItemNode(m_resizeController.formEditorItem()->qmlItemNode()); QmlItemNode qmlItemNode(m_resizeController.formEditorItem()->qmlItemNode());
QmlAnchors anchors(qmlItemNode.anchors()); QmlAnchors anchors(qmlItemNode.anchors());

View File

@@ -101,6 +101,7 @@ void RubberBandSelectionManipulator::select(SelectionType selectionType)
FormEditorItem *formEditorItem = FormEditorItem::fromQGraphicsItem(item); FormEditorItem *formEditorItem = FormEditorItem::fromQGraphicsItem(item);
if (formEditorItem if (formEditorItem
&& formEditorItem->qmlItemNode().isValid()
&& m_beginFormEditorItem->childItems().contains(formEditorItem) && m_beginFormEditorItem->childItems().contains(formEditorItem)
&& !formEditorItem->qmlItemNode().isRootNode()) && !formEditorItem->qmlItemNode().isRootNode())
{ {
@@ -108,7 +109,9 @@ void RubberBandSelectionManipulator::select(SelectionType selectionType)
} }
} }
if (newNodeList.isEmpty() && !m_beginFormEditorItem->qmlItemNode().isRootNode()) if (newNodeList.isEmpty()
&& m_beginFormEditorItem->qmlItemNode().isValid()
&& !m_beginFormEditorItem->qmlItemNode().isRootNode())
newNodeList.append(m_beginFormEditorItem->qmlItemNode()); newNodeList.append(m_beginFormEditorItem->qmlItemNode());
QList<QmlItemNode> nodeList; QList<QmlItemNode> nodeList;

View File

@@ -85,6 +85,9 @@ void SelectionIndicator::setItems(const QList<FormEditorItem*> &itemList)
clear(); clear();
foreach (FormEditorItem *item, itemList) { foreach (FormEditorItem *item, itemList) {
if (item->qmlItemNode().isValid())
continue;
QGraphicsPolygonItem *newSelectionIndicatorGraphicsItem = new QGraphicsPolygonItem(m_layerItem.data()); QGraphicsPolygonItem *newSelectionIndicatorGraphicsItem = new QGraphicsPolygonItem(m_layerItem.data());
m_indicatorShapeHash.insert(item, newSelectionIndicatorGraphicsItem); m_indicatorShapeHash.insert(item, newSelectionIndicatorGraphicsItem);
QPolygonF boundingRectInSceneSpace(item->mapToScene(item->qmlItemNode().instanceBoundingRect())); QPolygonF boundingRectInSceneSpace(item->mapToScene(item->qmlItemNode().instanceBoundingRect()));

View File

@@ -65,7 +65,9 @@ void SelectionTool::mousePressEvent(const QList<QGraphicsItem*> &itemList,
{ {
m_mousePressTimer.start(); m_mousePressTimer.start();
FormEditorItem* formEditorItem = topFormEditorItem(itemList); FormEditorItem* formEditorItem = topFormEditorItem(itemList);
if (formEditorItem && !formEditorItem->qmlItemNode().hasChildren()) { if (formEditorItem
&& formEditorItem->qmlItemNode().isValid()
&& !formEditorItem->qmlItemNode().hasChildren()) {
m_singleSelectionManipulator.begin(event->scenePos()); m_singleSelectionManipulator.begin(event->scenePos());
if (event->modifiers().testFlag(Qt::ControlModifier)) if (event->modifiers().testFlag(Qt::ControlModifier))

View File

@@ -80,6 +80,7 @@ void SingleSelectionManipulator::select(SelectionType selectionType, bool select
FormEditorItem *formEditorItem = FormEditorItem::fromQGraphicsItem(item); FormEditorItem *formEditorItem = FormEditorItem::fromQGraphicsItem(item);
if (formEditorItem if (formEditorItem
&& formEditorItem->qmlItemNode().isValid()
&& !formEditorItem->qmlItemNode().isRootNode() && !formEditorItem->qmlItemNode().isRootNode()
&& (formEditorItem->qmlItemNode().hasShowContent() || !selectOnlyContentItems)) && (formEditorItem->qmlItemNode().hasShowContent() || !selectOnlyContentItems))
{ {

View File

@@ -88,6 +88,9 @@ void SnappingLineCreator::addOffsets(const QRectF &rectInSceneSpace, FormEditorI
void SnappingLineCreator::generateLines(const QList<FormEditorItem*> &exceptionList, void SnappingLineCreator::generateLines(const QList<FormEditorItem*> &exceptionList,
FormEditorItem *transformationSpaceItem) FormEditorItem *transformationSpaceItem)
{ {
if (!m_formEditorItem->qmlItemNode().isValid())
return;
Q_ASSERT(transformationSpaceItem); Q_ASSERT(transformationSpaceItem);
{ {
QRectF containerBoundingRectInTransformationSpace = m_formEditorItem->mapRectToItem(transformationSpaceItem, QRectF containerBoundingRectInTransformationSpace = m_formEditorItem->mapRectToItem(transformationSpaceItem,
@@ -99,6 +102,10 @@ void SnappingLineCreator::generateLines(const QList<FormEditorItem*> &exceptionL
} }
foreach (FormEditorItem *item, m_formEditorItem->childFormEditorItems()) { foreach (FormEditorItem *item, m_formEditorItem->childFormEditorItems()) {
if (!item || !item->qmlItemNode().isValid())
continue;
if (exceptionList.contains(item)) if (exceptionList.contains(item))
continue; continue;
QRectF boundingRectInContainerSpace; QRectF boundingRectInContainerSpace;