void RTransaction::deleteObject(QSharedPointer<RObject> object) { if (storage == NULL) { return; } //QSharedPointer<RObject> obj = storage->queryObject(objectId); if (object.isNull()) { qWarning("RTransaction::deleteObject: " "original object not found in storage"); failed = true; return; } RLinkedStorage* ls = dynamic_cast<RLinkedStorage*>(storage); bool storageIsLinked = (ls!=NULL); onlyChanges = false; RObject::Id objectId = object->getId(); if (object->isProtected()) { qWarning() << "RTransaction::deleteObject: trying to delete protected object"; return; } // if a layer is deleted, delete all entities on the layer: QSharedPointer<RLayer> layer = object.dynamicCast<RLayer>(); if (!layer.isNull()) { if (layer->getName() == "0") { qWarning() << "RTransaction::deleteObject: " "trying to delete the default layer \"0\""; return; } // TODO: undeletable layers QSet<REntity::Id> ids = storage->queryLayerEntities(objectId, true); QSetIterator<REntity::Id> it(ids); while (it.hasNext()) { deleteObject(it.next()); } // current layer deleted, reset current layer to layer "0": if (objectId == storage->getCurrentLayerId()) { storage->setCurrentLayer("0"); } } // if a block is deleted, delete all entities in the block: QSharedPointer<RBlock> block = object.dynamicCast<RBlock> (); if (!block.isNull()) { if (block->getName() == RBlock::modelSpaceName) { qWarning() << "RTransaction::deleteObject: " "trying to delete the model space block"; return; } // delete all block references to this block: QSet<REntity::Id> ids = storage->queryBlockReferences(objectId); QSetIterator<REntity::Id> it(ids); while (it.hasNext()) { deleteObject(it.next()); } // delete all entities of this block definition: ids = storage->queryBlockEntities(objectId); it = QSetIterator<REntity::Id>(ids); while (it.hasNext()) { deleteObject(it.next()); } // current block deleted, reset current block to model space: if (objectId == storage->getCurrentBlockId()) { storage->setCurrentBlock(RBlock::modelSpaceName); } } QSharedPointer<REntity> entity = object.dynamicCast<REntity>(); if (!entity.isNull()) { if (!allowAll && !entity->isEditable(allowInvisible)) { qWarning() << "RTransaction::deleteObject: entity not editable (locked or hidden layer)"; fail(); return; } } // if the entity has child entities, delete all child entities (e.g. attributes): if (!entity.isNull() && storage->hasChildEntities(entity->getId())) { QSet<REntity::Id> ids = storage->queryChildEntities(entity->getId()); QSetIterator<REntity::Id> it(ids); while (it.hasNext()) { deleteObject(it.next()); } } // if the current view is deleted, reset current view: QSharedPointer<RView> view = object.dynamicCast<RView>(); if (!view.isNull()) { if (objectId == storage->getCurrentViewId()) { storage->setCurrentView(QString()); } } // add affected object to list (also adds block the object is in): addAffectedObject(objectId); statusChanges.insert(objectId); RDocument* document = storage->getDocument(); if (document!=NULL) { if (!undoable) { // only remove from si, if not linked storage / preview if (!storageIsLinked && !spatialIndexDisabled && !entity.isNull()) { document->removeFromSpatialIndex(entity); } storage->deleteObject(objectId); } else { // only remove from si, if not linked storage / preview if (!storageIsLinked && !spatialIndexDisabled && !entity.isNull()) { document->removeFromSpatialIndex(entity); } storage->setUndoStatus(objectId, true); } } }
/** * Undoes this transaction. */ void RTransaction::undo() { RDocument* document = storage->getDocument(); if (document==NULL) { return; } // iterate through all objects that were affected by this transaction: for (int k=affectedObjectIds.size()-1; k>=0; --k) { RObject::Id objId = affectedObjectIds[k]; // no properties have changed for this object, // i.e. object was created or deleted: if (statusChanges.contains(objId)) { QSharedPointer<RObject> object = storage->queryObjectDirect(objId); // toggle undo status of affected object: if (object->isUndone()) { // object was deleted and is now restored: QSharedPointer<REntity> entity = object.dynamicCast<REntity>(); storage->setUndoStatus(*object, false); if (!spatialIndexDisabled && !entity.isNull()) { document->addToSpatialIndex(entity); } } else { // object was created and is now undone: QSharedPointer<REntity> entity = object.dynamicCast<REntity>(); if (!spatialIndexDisabled && !entity.isNull()) { document->removeFromSpatialIndex(entity); } storage->setUndoStatus(*object, true); } } // undo property changes: else { QSharedPointer<RObject> object = storage->queryObject(objId); if (object.isNull()) { qWarning("RTransaction::undo: " "object '%d' not found in storage", objId); continue; } if (document!=NULL) { QSharedPointer<REntity> entity = object.dynamicCast<REntity>(); if (!spatialIndexDisabled && !entity.isNull()) { document->removeFromSpatialIndex(entity); } } storage->removeObject(storage->queryObjectDirect(objId)); QList<RPropertyChange> objectChanges = propertyChanges.value(objId); for (int i=objectChanges.size()-1; i>=0; --i) { RPropertyTypeId propertyTypeId = objectChanges.at(i).propertyTypeId; object->setProperty(propertyTypeId, objectChanges.at(i).oldValue); } storage->saveObject(object, false); if (document!=NULL) { QSharedPointer<REntity> entity = object.dynamicCast<REntity>(); if (!spatialIndexDisabled && !entity.isNull()) { // entity of the block might have changed (in block drag and drop): if (entity->getType()==RS::EntityBlockRef) { //entity->update(); affectedBlockReferenceIds.insert(objId); } document->addToSpatialIndex(entity); } } } } updateAffectedBlockReferences(); undoing = true; }