Commit d2b3258e authored by Marco Bubke's avatar Marco Bubke Committed by Thomas Hartmann

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

parent 48ff3f7a
......@@ -128,12 +128,15 @@ AbstractFormEditorTool* FormEditorScene::currentTool() const
//This method calculates the possible parent for reparent
FormEditorItem* FormEditorScene::calulateNewParent(FormEditorItem *formEditorItem)
{
QList<QGraphicsItem *> list = items(formEditorItem->qmlItemNode().instanceBoundingRect().center());
foreach (QGraphicsItem *graphicsItem, list) {
if (qgraphicsitem_cast<FormEditorItem*>(graphicsItem) &&
graphicsItem->collidesWithItem(formEditorItem, Qt::ContainsItemShape))
return qgraphicsitem_cast<FormEditorItem*>(graphicsItem);
if (formEditorItem->qmlItemNode().isValid()) {
QList<QGraphicsItem *> list = items(formEditorItem->qmlItemNode().instanceBoundingRect().center());
foreach (QGraphicsItem *graphicsItem, list) {
if (qgraphicsitem_cast<FormEditorItem*>(graphicsItem) &&
graphicsItem->collidesWithItem(formEditorItem, Qt::ContainsItemShape))
return qgraphicsitem_cast<FormEditorItem*>(graphicsItem);
}
}
return 0;
}
......
......@@ -160,6 +160,9 @@ void ItemCreatorTool::createAtItem(const QRectF &rect)
QPointF pos = rect.topLeft();
QmlItemNode parentNode = view()->rootQmlItemNode();
if (!parentNode.isValid())
return;
FormEditorItem *parentItem = calculateContainer(pos);
if (parentItem) {
parentNode = parentItem->qmlItemNode();
......
......@@ -100,7 +100,9 @@ void MoveManipulator::updateHashes()
bool MoveManipulator::itemsCanReparented() const
{
foreach (FormEditorItem* item, m_itemList) {
if (!item->qmlItemNode().canReparent())
if (item
&& item->qmlItemNode().isValid()
&& !item->qmlItemNode().canReparent())
return false;
}
......@@ -114,26 +116,32 @@ void MoveManipulator::begin(const QPointF &beginPoint)
m_snapper.updateSnappingLines(m_itemList);
foreach (FormEditorItem* item, m_itemList)
m_beginItemRectHash.insert(item, m_snapper.containerFormEditorItem()->mapRectFromItem(item, item->qmlItemNode().instanceBoundingRect()));
foreach (FormEditorItem* item, m_itemList) {
QPointF positionInParentSpace(item->qmlItemNode().instancePosition());
QPointF positionInScenesSpace = m_snapper.containerFormEditorItem()->mapToScene(positionInParentSpace);
m_beginPositionInSceneSpaceHash.insert(item, positionInScenesSpace);
if (item && item->qmlItemNode().isValid())
m_beginItemRectHash.insert(item, m_snapper.containerFormEditorItem()->mapRectFromItem(item, item->qmlItemNode().instanceBoundingRect()));
}
foreach (FormEditorItem* item, m_itemList) {
QPointF positionInParentSpace = m_snapper.containerFormEditorItem()->mapFromScene(m_beginPositionInSceneSpaceHash.value(item));
m_beginPositionHash.insert(item, positionInParentSpace);
if (item && item->qmlItemNode().isValid()) {
QPointF positionInParentSpace(item->qmlItemNode().instancePosition());
QPointF positionInScenesSpace = m_snapper.containerFormEditorItem()->mapToScene(positionInParentSpace);
m_beginPositionInSceneSpaceHash.insert(item, positionInScenesSpace);
}
}
QmlAnchors anchors(item->qmlItemNode().anchors());
m_beginTopMarginHash.insert(item, anchors.instanceMargin(AnchorLine::Top));
m_beginLeftMarginHash.insert(item, anchors.instanceMargin(AnchorLine::Left));
m_beginRightMarginHash.insert(item, anchors.instanceMargin(AnchorLine::Right));
m_beginBottomMarginHash.insert(item, anchors.instanceMargin(AnchorLine::Bottom));
m_beginHorizontalCenterHash.insert(item, anchors.instanceMargin(AnchorLine::HorizontalCenter));
m_beginVerticalCenterHash.insert(item, anchors.instanceMargin(AnchorLine::VerticalCenter));
foreach (FormEditorItem* item, m_itemList) {
if (item && item->qmlItemNode().isValid()) {
QPointF positionInParentSpace = m_snapper.containerFormEditorItem()->mapFromScene(m_beginPositionInSceneSpaceHash.value(item));
m_beginPositionHash.insert(item, positionInParentSpace);
QmlAnchors anchors(item->qmlItemNode().anchors());
m_beginTopMarginHash.insert(item, anchors.instanceMargin(AnchorLine::Top));
m_beginLeftMarginHash.insert(item, anchors.instanceMargin(AnchorLine::Left));
m_beginRightMarginHash.insert(item, anchors.instanceMargin(AnchorLine::Right));
m_beginBottomMarginHash.insert(item, anchors.instanceMargin(AnchorLine::Bottom));
m_beginHorizontalCenterHash.insert(item, anchors.instanceMargin(AnchorLine::HorizontalCenter));
m_beginVerticalCenterHash.insert(item, anchors.instanceMargin(AnchorLine::VerticalCenter));
}
}
m_beginPoint = beginPoint;
......@@ -159,6 +167,10 @@ QPointF MoveManipulator::findSnappingOffset(const QHash<FormEditorItem*, QRectF>
hashIterator.next();
FormEditorItem *formEditorItem = hashIterator.key();
QRectF boundingRect = hashIterator.value();
if (!formEditorItem || !formEditorItem->qmlItemNode().isValid())
continue;
if (!formEditorItem->qmlItemNode().hasBindingProperty("x")) {
double verticalOffset = m_snapper.snappedVerticalOffset(boundingRect);
if (verticalOffset < std::numeric_limits<double>::max())
......@@ -203,6 +215,10 @@ QHash<FormEditorItem*, QRectF> MoveManipulator::tanslatedBoundingRects(const QHa
hashIterator.next();
FormEditorItem *formEditorItem = hashIterator.key();
QRectF boundingRect = hashIterator.value();
if (!formEditorItem || !formEditorItem->qmlItemNode().isValid())
continue;
if (formEditorItem->qmlItemNode().hasBindingProperty("x"))
alignedOffset.setX(0);
if (formEditorItem->qmlItemNode().hasBindingProperty("y"))
......@@ -245,6 +261,9 @@ void MoveManipulator::update(const QPointF& updatePoint, Snapping useSnapping, S
foreach (FormEditorItem* item, m_itemList) {
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
if (stateToBeManipulated == UseActualState) {
QmlAnchors anchors(item->qmlItemNode().anchors());
......@@ -311,6 +330,9 @@ void MoveManipulator::reparentTo(FormEditorItem *newParent)
return;
foreach (FormEditorItem* item, m_itemList) {
if (!item || !item->qmlItemNode().isValid())
continue;
QmlItemNode parent(newParent->qmlItemNode());
if (parent.isValid()) {
if (parent.hasDefaultProperty())
......@@ -340,6 +362,9 @@ void MoveManipulator::end(const QPointF &/*endPoint*/)
void MoveManipulator::moveBy(double deltaX, double deltaY)
{
foreach (FormEditorItem* item, m_itemList) {
if (!item || !item->qmlItemNode().isValid())
continue;
QmlAnchors anchors(item->qmlItemNode().anchors());
if (anchors.instanceHasAnchor(AnchorLine::Top)) {
......
......@@ -296,7 +296,9 @@ void MoveTool::beginWithPoint(const QPointF &beginPoint)
static bool isNotAncestorOfItemInList(FormEditorItem *formEditorItem, const QList<FormEditorItem*> &itemList)
{
foreach (FormEditorItem *item, itemList) {
if (item->qmlItemNode().isAncestorOf(formEditorItem->qmlItemNode()))
if (item
&& item->qmlItemNode().isValid()
&& item->qmlItemNode().isAncestorOf(formEditorItem->qmlItemNode()))
return false;
}
......
......@@ -136,7 +136,7 @@ ResizeController::ResizeController(LayerItem *layerItem, FormEditorItem *formEdi
bool ResizeController::isValid() const
{
return m_data->formEditorItem != 0;
return m_data->formEditorItem && m_data->formEditorItem->qmlItemNode().isValid();
}
void ResizeController::show()
......@@ -186,36 +186,39 @@ static QPointF bottomCenter(const QRectF &rect)
void ResizeController::updatePosition()
{
QRectF boundingRect = m_data->formEditorItem->qmlItemNode().instanceBoundingRect();
QPointF topLeftPointInLayerSpace(m_data->formEditorItem->mapToItem(m_data->layerItem.data(),
boundingRect.topLeft()));
QPointF topRightPointInLayerSpace(m_data->formEditorItem->mapToItem(m_data->layerItem.data(),
boundingRect.topRight()));
QPointF bottomLeftPointInLayerSpace(m_data->formEditorItem->mapToItem(m_data->layerItem.data(),
boundingRect.bottomLeft()));
QPointF bottomRightPointInLayerSpace(m_data->formEditorItem->mapToItem(m_data->layerItem.data(),
boundingRect.bottomRight()));
QPointF topPointInLayerSpace(m_data->formEditorItem->mapToItem(m_data->layerItem.data(),
topCenter(boundingRect)));
QPointF leftPointInLayerSpace(m_data->formEditorItem->mapToItem(m_data->layerItem.data(),
leftCenter(boundingRect)));
QPointF rightPointInLayerSpace(m_data->formEditorItem->mapToItem(m_data->layerItem.data(),
rightCenter(boundingRect)));
QPointF bottomPointInLayerSpace(m_data->formEditorItem->mapToItem(m_data->layerItem.data(),
bottomCenter(boundingRect)));
m_data->topRightItem->setHandlePosition(topRightPointInLayerSpace, boundingRect.topRight());
m_data->topLeftItem->setHandlePosition(topLeftPointInLayerSpace, boundingRect.topLeft());
m_data->bottomLeftItem->setHandlePosition(bottomLeftPointInLayerSpace, boundingRect.bottomLeft());
m_data->bottomRightItem->setHandlePosition(bottomRightPointInLayerSpace, boundingRect.bottomRight());
m_data->topItem->setHandlePosition(topPointInLayerSpace, topCenter(boundingRect));
m_data->leftItem->setHandlePosition(leftPointInLayerSpace, leftCenter(boundingRect));
m_data->rightItem->setHandlePosition(rightPointInLayerSpace, rightCenter(boundingRect));
m_data->bottomItem->setHandlePosition(bottomPointInLayerSpace, bottomCenter(boundingRect));
if (isValid()) {
QRectF boundingRect = m_data->formEditorItem->qmlItemNode().instanceBoundingRect();
QPointF topLeftPointInLayerSpace(m_data->formEditorItem->mapToItem(m_data->layerItem.data(),
boundingRect.topLeft()));
QPointF topRightPointInLayerSpace(m_data->formEditorItem->mapToItem(m_data->layerItem.data(),
boundingRect.topRight()));
QPointF bottomLeftPointInLayerSpace(m_data->formEditorItem->mapToItem(m_data->layerItem.data(),
boundingRect.bottomLeft()));
QPointF bottomRightPointInLayerSpace(m_data->formEditorItem->mapToItem(m_data->layerItem.data(),
boundingRect.bottomRight()));
QPointF topPointInLayerSpace(m_data->formEditorItem->mapToItem(m_data->layerItem.data(),
topCenter(boundingRect)));
QPointF leftPointInLayerSpace(m_data->formEditorItem->mapToItem(m_data->layerItem.data(),
leftCenter(boundingRect)));
QPointF rightPointInLayerSpace(m_data->formEditorItem->mapToItem(m_data->layerItem.data(),
rightCenter(boundingRect)));
QPointF bottomPointInLayerSpace(m_data->formEditorItem->mapToItem(m_data->layerItem.data(),
bottomCenter(boundingRect)));
m_data->topRightItem->setHandlePosition(topRightPointInLayerSpace, boundingRect.topRight());
m_data->topLeftItem->setHandlePosition(topLeftPointInLayerSpace, boundingRect.topLeft());
m_data->bottomLeftItem->setHandlePosition(bottomLeftPointInLayerSpace, boundingRect.bottomLeft());
m_data->bottomRightItem->setHandlePosition(bottomRightPointInLayerSpace, boundingRect.bottomRight());
m_data->topItem->setHandlePosition(topPointInLayerSpace, topCenter(boundingRect));
m_data->leftItem->setHandlePosition(leftPointInLayerSpace, leftCenter(boundingRect));
m_data->rightItem->setHandlePosition(rightPointInLayerSpace, rightCenter(boundingRect));
m_data->bottomItem->setHandlePosition(bottomPointInLayerSpace, bottomCenter(boundingRect));
}
}
......
......@@ -71,7 +71,9 @@ void ResizeIndicator::setItems(const QList<FormEditorItem*> &itemList)
clear();
foreach (FormEditorItem* item, itemList) {
if (item->qmlItemNode().isRootNode())
if (item
&& item->qmlItemNode().isValid()
&& item->qmlItemNode().isRootNode())
continue;
ResizeController controller(m_layerItem, item);
m_itemControllerHash.insert(item, controller);
......
......@@ -396,7 +396,7 @@ void ResizeManipulator::end()
void ResizeManipulator::moveBy(double deltaX, double deltaY)
{
if (resizeHandle()) {
if (resizeHandle() && m_resizeController.isValid()) {
QmlItemNode qmlItemNode(m_resizeController.formEditorItem()->qmlItemNode());
QmlAnchors anchors(qmlItemNode.anchors());
......
......@@ -101,6 +101,7 @@ void RubberBandSelectionManipulator::select(SelectionType selectionType)
FormEditorItem *formEditorItem = FormEditorItem::fromQGraphicsItem(item);
if (formEditorItem
&& formEditorItem->qmlItemNode().isValid()
&& m_beginFormEditorItem->childItems().contains(formEditorItem)
&& !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());
QList<QmlItemNode> nodeList;
......
......@@ -85,6 +85,9 @@ void SelectionIndicator::setItems(const QList<FormEditorItem*> &itemList)
clear();
foreach (FormEditorItem *item, itemList) {
if (item->qmlItemNode().isValid())
continue;
QGraphicsPolygonItem *newSelectionIndicatorGraphicsItem = new QGraphicsPolygonItem(m_layerItem.data());
m_indicatorShapeHash.insert(item, newSelectionIndicatorGraphicsItem);
QPolygonF boundingRectInSceneSpace(item->mapToScene(item->qmlItemNode().instanceBoundingRect()));
......
......@@ -65,7 +65,9 @@ void SelectionTool::mousePressEvent(const QList<QGraphicsItem*> &itemList,
{
m_mousePressTimer.start();
FormEditorItem* formEditorItem = topFormEditorItem(itemList);
if (formEditorItem && !formEditorItem->qmlItemNode().hasChildren()) {
if (formEditorItem
&& formEditorItem->qmlItemNode().isValid()
&& !formEditorItem->qmlItemNode().hasChildren()) {
m_singleSelectionManipulator.begin(event->scenePos());
if (event->modifiers().testFlag(Qt::ControlModifier))
......
......@@ -80,6 +80,7 @@ void SingleSelectionManipulator::select(SelectionType selectionType, bool select
FormEditorItem *formEditorItem = FormEditorItem::fromQGraphicsItem(item);
if (formEditorItem
&& formEditorItem->qmlItemNode().isValid()
&& !formEditorItem->qmlItemNode().isRootNode()
&& (formEditorItem->qmlItemNode().hasShowContent() || !selectOnlyContentItems))
{
......
......@@ -88,6 +88,9 @@ void SnappingLineCreator::addOffsets(const QRectF &rectInSceneSpace, FormEditorI
void SnappingLineCreator::generateLines(const QList<FormEditorItem*> &exceptionList,
FormEditorItem *transformationSpaceItem)
{
if (!m_formEditorItem->qmlItemNode().isValid())
return;
Q_ASSERT(transformationSpaceItem);
{
QRectF containerBoundingRectInTransformationSpace = m_formEditorItem->mapRectToItem(transformationSpaceItem,
......@@ -99,6 +102,10 @@ void SnappingLineCreator::generateLines(const QList<FormEditorItem*> &exceptionL
}
foreach (FormEditorItem *item, m_formEditorItem->childFormEditorItems()) {
if (!item || !item->qmlItemNode().isValid())
continue;
if (exceptionList.contains(item))
continue;
QRectF boundingRectInContainerSpace;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment