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
|
//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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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)) {
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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());
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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()));
|
||||||
|
|||||||
@@ -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))
|
||||||
|
|||||||
@@ -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))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user