Group crashes fixed

preferencesAboutTextFull
Ilia Ryabokon 12 years ago
parent 51aa2f96f0
commit 356a4929bb
  1. 108
      src/domain/UBGraphicsGroupContainerItem.cpp
  2. 4
      src/domain/UBGraphicsGroupContainerItem.h
  3. 14
      src/frameworks/UBCoreGraphicsScene.cpp
  4. 1
      src/frameworks/UBCoreGraphicsScene.h

@ -88,49 +88,16 @@ void UBGraphicsGroupContainerItem::addToGroup(QGraphicsItem *item)
void UBGraphicsGroupContainerItem::removeFromGroup(QGraphicsItem *item)
{
if (!item) {
qWarning("QGraphicsItemGroup::removeFromGroup: cannot remove null item");
return;
qDebug() << "can't specify the item because of the null pointer";
}
QGraphicsItem *newParent = parentItem();
// COMBINE
bool ok;
QTransform itemTransform;
if (newParent)
itemTransform = item->itemTransform(newParent, &ok);
else
itemTransform = item->sceneTransform();
QPointF oldPos = item->mapToItem(newParent, 0, 0);
item->setParentItem(newParent);
item->setPos(oldPos);
// removing position from translation component of the new transform
if (!item->pos().isNull())
itemTransform *= QTransform::fromTranslate(-item->x(), -item->y());
// removing additional transformations properties applied
// with itemTransform() or sceneTransform()
QPointF origin = item->transformOriginPoint();
QMatrix4x4 m;
QList<QGraphicsTransform*> transformList = item->transformations();
for (int i = 0; i < transformList.size(); ++i)
transformList.at(i)->applyTo(&m);
itemTransform *= m.toTransform().inverted();
itemTransform.translate(origin.x(), origin.y());
itemTransform.rotate(-item->rotation());
itemTransform.scale(1 / item->scale(), 1 / item->scale());
itemTransform.translate(-origin.x(), -origin.y());
UBGraphicsScene *groupScene = scene();
if (groupScene) {
groupScene->addItemToDeletion(item);
}
// ### Expensive, we could maybe use dirtySceneTransform bit for optimization
pRemoveFromGroup(item);
item->setTransform(itemTransform);
// item->d_func()->setIsMemberOfGroup(item->group() != 0);
// ### Quite expensive. But removeFromGroup() isn't called very often.
prepareGeometryChange();
itemsBoundingRect = childrenBoundingRect();
}
void UBGraphicsGroupContainerItem::deselectCurrentItem()
@ -216,18 +183,21 @@ void UBGraphicsGroupContainerItem::setUuid(const QUuid &pUuid)
void UBGraphicsGroupContainerItem::destroy() {
UBGraphicsScene *groupScene = scene();
foreach (QGraphicsItem *item, childItems()) {
removeFromGroup(item);
if (groupScene) {
groupScene->addItemToDeletion(item);
}
pRemoveFromGroup(item);
item->setFlag(QGraphicsItem::ItemIsSelectable, true);
item->setFlag(QGraphicsItem::ItemIsFocusable, true);
}
remove();
if (scene()) {
qDebug() << "scene is well casted";
scene()->removeItem(this);
}
}
void UBGraphicsGroupContainerItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
@ -279,3 +249,51 @@ QVariant UBGraphicsGroupContainerItem::itemChange(GraphicsItemChange change, con
return QGraphicsItem::itemChange(change, newValue);
}
void UBGraphicsGroupContainerItem::pRemoveFromGroup(QGraphicsItem *item)
{
if (!item) {
qWarning("QGraphicsItemGroup::removeFromGroup: cannot remove null item");
return;
}
QGraphicsItem *newParent = parentItem();
// COMBINE
bool ok;
QTransform itemTransform;
if (newParent)
itemTransform = item->itemTransform(newParent, &ok);
else
itemTransform = item->sceneTransform();
QPointF oldPos = item->mapToItem(newParent, 0, 0);
item->setParentItem(newParent);
item->setPos(oldPos);
// removing position from translation component of the new transform
if (!item->pos().isNull())
itemTransform *= QTransform::fromTranslate(-item->x(), -item->y());
// removing additional transformations properties applied
// with itemTransform() or sceneTransform()
QPointF origin = item->transformOriginPoint();
QMatrix4x4 m;
QList<QGraphicsTransform*> transformList = item->transformations();
for (int i = 0; i < transformList.size(); ++i)
transformList.at(i)->applyTo(&m);
itemTransform *= m.toTransform().inverted();
itemTransform.translate(origin.x(), origin.y());
itemTransform.rotate(-item->rotation());
itemTransform.scale(1 / item->scale(), 1 / item->scale());
itemTransform.translate(-origin.x(), -origin.y());
// ### Expensive, we could maybe use dirtySceneTransform bit for optimization
item->setTransform(itemTransform);
// item->d_func()->setIsMemberOfGroup(item->group() != 0);
// ### Quite expensive. But removeFromGroup() isn't called very often.
prepareGeometryChange();
itemsBoundingRect = childrenBoundingRect();
}

@ -35,7 +35,6 @@ public:
virtual void setUuid(const QUuid &pUuid);
void destroy();
protected:
virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
@ -43,7 +42,10 @@ protected:
virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value);
void pRemoveFromGroup(QGraphicsItem *item);
private:
QRectF itemsBoundingRect;
QGraphicsItem *mCurrentItem;

@ -17,6 +17,7 @@
#include "domain/UBGraphicsMediaItem.h"
#include "domain/UBGraphicsWidgetItem.h"
#include "domain/UBGraphicsGroupContainerItem.h"
#include "core/memcheck.h"
@ -40,6 +41,12 @@ UBCoreGraphicsScene::~UBCoreGraphicsScene()
void UBCoreGraphicsScene::addItem(QGraphicsItem* item)
{
if (item->type() == UBGraphicsGroupContainerItem::Type && item->childItems().count()) {
foreach (QGraphicsItem *curItem, item->childItems()) {
removeItemFromDeletion(curItem);
}
}
mItemsToDelete << item;
if (item->scene() != this)
@ -89,3 +96,10 @@ void UBCoreGraphicsScene::removeItemFromDeletion(QGraphicsItem *item)
mItemsToDelete.remove(item);
}
}
void UBCoreGraphicsScene::addItemToDeletion(QGraphicsItem *item)
{
if (item) {
mItemsToDelete.insert(item);
}
}

@ -31,6 +31,7 @@ class UBCoreGraphicsScene : public QGraphicsScene
virtual bool deleteItem(QGraphicsItem* item);
void removeItemFromDeletion(QGraphicsItem* item);
void addItemToDeletion(QGraphicsItem *item);
private:
QSet<QGraphicsItem*> mItemsToDelete;

Loading…
Cancel
Save