forked from qt-creator/qt-creator
QmlDesigner.FormEditor: Test if a qml item is valid to prevent crashes
This commit is contained in:
committed by
Thomas Hartmann
parent
48ff3f7a29
commit
d2b3258e59
@@ -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()));
|
||||
if (isValid()) {
|
||||
|
||||
QPointF topPointInLayerSpace(m_data->formEditorItem->mapToItem(m_data->layerItem.data(),
|
||||
topCenter(boundingRect)));
|
||||
QPointF leftPointInLayerSpace(m_data->formEditorItem->mapToItem(m_data->layerItem.data(),
|
||||
leftCenter(boundingRect)));
|
||||
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 rightPointInLayerSpace(m_data->formEditorItem->mapToItem(m_data->layerItem.data(),
|
||||
rightCenter(boundingRect)));
|
||||
QPointF bottomPointInLayerSpace(m_data->formEditorItem->mapToItem(m_data->layerItem.data(),
|
||||
bottomCenter(boundingRect)));
|
||||
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));
|
||||
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;
|
||||
|
||||
Reference in New Issue
Block a user