QSharedPointer<RBlock> RClipboardOperation::copyBlock( RBlock::Id blockId, RDocument& src, RDocument& dest, bool overwriteBlocks, bool toCurrentBlock, const QString& blockName, RTransaction& transaction) const { QSharedPointer<RBlock> srcBlock = src.queryBlock(blockId); if (srcBlock.isNull()) { qWarning("RClipboardOperation::copyEntityBlock: " "block of entity is NULL."); return QSharedPointer<RBlock>(); } QString srcBlockName = srcBlock->getName(); QSharedPointer<RBlock> destBlock; if (copiedBlocks.contains(srcBlockName)) { destBlock = copiedBlocks.value(srcBlockName); } else { QString destBlockName; if (!blockName.isNull()) { destBlockName = blockName; } else { if (toCurrentBlock) { destBlockName = dest.getBlockName(dest.getCurrentBlockId()); } else { destBlockName = srcBlock->getName(); } } if (!dest.hasBlock(destBlockName) || (overwriteBlocks && blockName.isNull())) { destBlock = QSharedPointer<RBlock> (srcBlock->clone()); dest.getStorage().setObjectId(*destBlock.data(), RObject::INVALID_ID); dest.getStorage().setObjectHandle(*destBlock.data(), RObject::INVALID_HANDLE); destBlock->setDocument(&dest); if (dest.hasBlock(destBlockName)) { if (!transaction.overwriteBlock(destBlock)) { destBlock = dest.queryBlock(destBlockName); } } else { transaction.addObject(destBlock); } } else { destBlock = dest.queryBlock(destBlockName); } copiedBlocks.insert(srcBlockName, destBlock); } return destBlock; }
QSharedPointer<RLayer> RClipboardOperation::copyLayer( RLayer::Id layerId, RDocument& src, RDocument& dest, bool overwriteLayers, RTransaction& transaction) const { bool overwriteLinetypes = false; // add layer the entity is on, if the layer exists it is overwritten // if overwriteLayers is true: QSharedPointer<RLayer> srcLayer = src.queryLayer(layerId); if (srcLayer.isNull()) { qWarning("RClipboardOperation::copyLayer: " "layer is NULL."); return QSharedPointer<RLayer>(); } QSharedPointer<RLinetype> destLinetype = copyLinetype(srcLayer->getLinetypeId(), src, dest, overwriteLinetypes, transaction); QString srcLayerName = srcLayer->getName(); QSharedPointer<RLayer> destLayer; if (copiedLayers.contains(srcLayerName)) { destLayer = copiedLayers.value(srcLayerName); Q_ASSERT(!destLayer.isNull()); } else { if (!dest.hasLayer(srcLayerName) || overwriteLayers) { destLayer = QSharedPointer<RLayer>(srcLayer->clone()); destLayer->setDocument(&dest); if (destLayer->getDocument()!=srcLayer->getDocument()) { dest.getStorage().setObjectId(*destLayer.data(), RObject::INVALID_ID); dest.getStorage().setObjectHandle(*destLayer.data(), RObject::INVALID_HANDLE); } transaction.addObject(destLayer); } else { destLayer = dest.queryLayer(srcLayerName); Q_ASSERT(!destLayer.isNull()); } copiedLayers.insert(srcLayerName, destLayer); } if (!destLinetype.isNull()) { destLayer->setLinetypeId(destLinetype->getId()); } return destLayer; }
RTransaction RMixedOperation::apply(RDocument& document, bool preview) const { Q_UNUSED(preview) RTransaction transaction(document.getStorage(), text, undoable); transaction.setGroup(transactionGroup); for (int i = 0; i < list.size(); ++i) { if (list[i].first.isNull()) { qWarning() << "RMixedOperation::apply: " "list contains NULL object"; continue; } if (getMode(list[i].second, RMixedOperation::EndCycle)) { transaction.endCycle(); } else if (getMode(list[i].second, RMixedOperation::Delete)) { transaction.deleteObject(list[i].first); } else { transaction.addObject(list[i].first, getMode(list[i].second, RMixedOperation::UseCurrentAttributes), getMode(list[i].second, RMixedOperation::ForceNew)); } } transaction.end(); return transaction; }
RTransaction RAddObjectsOperation::apply(RDocument& document, bool preview) const { RTransaction transaction(document.getStorage(), "Adding object(s)", undoable); transaction.setRecordAffectedObjects(recordAffectedObjects); transaction.setSpatialIndexDisabled(spatialIndexDisabled); for (int i = 0; i < addedObjects.size(); ++i) { if (limitPreview && preview && i>RSettings::getPreviewEntities()) { break; } if (addedObjects[i].object.isNull()) { transaction.endCycle(); //qWarning() << "RAddObjectsOperation::apply: " // "list contains NULL object"; continue; } if (addedObjects[i].deleteIt) { transaction.deleteObject(addedObjects[i].object, &document); continue; } transaction.addObject( addedObjects[i].object, addedObjects[i].useCurrentAttributes, addedObjects[i].forceNew); } transaction.end(); return transaction; }
RTransaction RCopyOperation::apply(RDocument& document, bool preview) const { RTransaction transaction(document.getStorage(), text); transaction.setGroup(transactionGroup); copy( src, document, offset, 1.0, 0.0, // scale, angle false, // flipHorizontal false, // flipVertical false, // toCurrentLayer false, // toCurrentBlock true, // overwriteLayers false, // overwriteBlocks QString(), // blockName QString(), // layerName transaction, true, // selectionOnly clear, // clear true, // toModelSpace (clipboard root is always model space) preview ); transaction.end(); return transaction; }
RTransaction RMoveReferencePointOperation::apply(RDocument& document, bool preview) const { Q_UNUSED(preview) RTransaction transaction(document.getStorage(), text); transaction.setGroup(transactionGroup); QSet<REntity::Id> selectedEntities = document.querySelectedEntities(); QSet<REntity::Id>::iterator it; for (it=selectedEntities.begin(); it!=selectedEntities.end(); it++) { QSharedPointer<REntity> entity = document.queryEntity(*it); if (entity.isNull()) { continue; } // apply operation to cloned entity: bool modified = entity->moveReferencePoint(referencePoint, targetPoint); if (modified) { transaction.addObject(entity, false); } } transaction.end(); return transaction; }
RTransaction RChangePropertyOperation::apply(RDocument& document, bool preview) const { Q_UNUSED(preview) RTransaction transaction(document.getStorage(), text); // always allow property changes (e.g. move entity to hidden layer) transaction.setAllowInvisible(true); transaction.setGroup(transactionGroup); QVariant val = value; // optimization: change layer ID instead of changing layer name: if (propertyTypeId==REntity::PropertyLayer && value.type() == QVariant::String) { val = QVariant(document.getLayerId(value.toString())); } //RDebug::startTimer(); //qDebug() << "filter: " << entityTypeFilter; QSet<RObject::Id> selectedObjects = document.queryPropertyEditorObjects(); QSet<RObject::Id>::iterator it; for (it = selectedObjects.begin(); it != selectedObjects.end(); it++) { QSharedPointer<RObject> obj = document.queryObject(*it); if (obj.isNull()) { continue; } if (entityTypeFilter!=RS::EntityAll) { // special filter for block references and attributes: if (entityTypeFilter==RS::EntityBlockRefAttr) { if (obj->getType()!=RS::EntityBlockRef && obj->getType()!=RS::EntityAttribute) { continue; } } else { if (entityTypeFilter!=obj->getType()) { continue; } } } // apply operation to object: bool modified = obj->setProperty(propertyTypeId, val, &transaction); if (modified) { transaction.addObject(obj, false, false, QSet<RPropertyTypeId>() << propertyTypeId); } } transaction.end(); //RDebug::stopTimer("RChangePropertyOperation::apply"); return transaction; }
QSharedPointer<RLinetype> RClipboardOperation::copyLinetype( RLinetype::Id linetypeId, RDocument& src, RDocument& dest, bool overwriteLinetypes, RTransaction& transaction) const { // add linetype of entity, if the linetype exists it is overwritten // if overwriteLinetypes is true: QSharedPointer<RLinetype> srcLinetype = src.queryLinetype(linetypeId); if (srcLinetype.isNull()) { qWarning("RClipboardOperation::copyLinetype: " "linetype is NULL."); return QSharedPointer<RLinetype>(); } QString srcLinetypeName = srcLinetype->getName().toLower(); QSharedPointer<RLinetype> destLinetype; if (copiedLinetypes.contains(srcLinetypeName)) { destLinetype = copiedLinetypes.value(srcLinetypeName); Q_ASSERT(!destLinetype.isNull()); } else { if (!dest.hasLinetype(srcLinetypeName) || overwriteLinetypes) { destLinetype = QSharedPointer<RLinetype>(srcLinetype->clone()); destLinetype->setDocument(&dest); if (destLinetype->getDocument()!=srcLinetype->getDocument()) { dest.getStorage().setObjectId(*destLinetype.data(), RObject::INVALID_ID); dest.getStorage().setObjectHandle(*destLinetype.data(), RObject::INVALID_HANDLE); } transaction.addObject(destLinetype); } else { destLinetype = dest.queryLinetype(srcLinetypeName); Q_ASSERT(!destLinetype.isNull()); } copiedLinetypes.insert(srcLinetypeName, destLinetype); } return destLinetype; }
RTransaction RDeleteAllEntitiesOperation::apply(RDocument& document, bool preview) const { RTransaction transaction(document.getStorage(), "Deleting object(s)", undoable); QSet<RObject::Id> ids = document.queryAllEntities(); QSetIterator<RObject::Id> i(ids); while (i.hasNext()) { transaction.deleteObject(i.next(), &document); } transaction.end(); return transaction; }
RTransaction RDeleteSelectionOperation::apply(RDocument& document, bool preview) const { RTransaction transaction(document.getStorage(), text); transaction.setGroup(transactionGroup); QSet<REntity::Id> selectedEntities = document.querySelectedEntities(); QSet<REntity::Id>::iterator it; for (it=selectedEntities.begin(); it!=selectedEntities.end(); it++) { transaction.deleteObject(*it); } transaction.end(); return transaction; }
RImporter::RImporter(RDocument& document, RMessageHandler* messageHandler, RProgressHandler* progressHandler) : document(&document), messageHandler(messageHandler), progressHandler(progressHandler), transaction(document.getStorage(), "Importing", false), blockId(RBlock::INVALID_ID) { transaction.setRecordAffectedObjects(false); transaction.setAllowAll(true); transaction.setSpatialIndexDisabled(true); transaction.setExistingLayerDetectionDisabled(true); transaction.setExistingBlockDetectionDisabled(true); transaction.setBlockRecursionDetectionDisabled(true); }
RTransaction RDeleteAllEntitiesOperation::apply(RDocument& document, bool preview) const { Q_UNUSED(preview) RTransaction transaction(document.getStorage(), text, undoable); transaction.setGroup(transactionGroup); QSet<RObject::Id> ids = document.queryAllEntities(); QSetIterator<RObject::Id> i(ids); while (i.hasNext()) { transaction.deleteObject(i.next()); } transaction.end(); return transaction; }
RTransaction RChangePropertyOperation::apply(RDocument& document, bool preview) const { RTransaction transaction(document.getStorage(), "Changing property"); // 20111110: always allow property changes (e.g. move entity to hidden layer) transaction.setAllowInvisible(true); QVariant val = value; // optimization: change layer ID instead of changing layer name: if (propertyTypeId==REntity::PropertyLayer && value.type() == QVariant::String) { val = QVariant(document.getLayerId(value.toString())); } //RDebug::startTimer(); QSet<REntity::Id> selectedEntities = document.querySelectedEntities(); QSet<REntity::Id>::iterator it; for (it = selectedEntities.begin(); it != selectedEntities.end(); it++) { QSharedPointer<REntity> entity = document.queryEntity(*it); if (entity.isNull()) { continue; } if (entityTypeFilter!=RS::EntityAll && entityTypeFilter!=entity->getType()) { continue; } // apply operation to entity: bool modified = entity->setProperty(propertyTypeId, val); if (modified) { transaction.addObject(entity, false, QSet<RPropertyTypeId>() << propertyTypeId); } } transaction.end(); //RDebug::stopTimer("RChangePropertyOperation::apply"); return transaction; }
RTransaction RDeleteObjectsOperation::apply(RDocument& document, bool preview) const { Q_UNUSED(preview) RTransaction transaction(document.getStorage(), text, undoable); transaction.setRecordAffectedObjects(recordAffectedObjects); transaction.setSpatialIndexDisabled(spatialIndexDisabled); transaction.setAllowAll(allowAll); transaction.setAllowInvisible(allowInvisible); transaction.setGroup(transactionGroup); for (int i = 0; i < list.size(); ++i) { if (list[i].isNull()) { qWarning() << "RDeleteObjectsOperation::apply: " "list contains NULL object"; continue; } transaction.deleteObject(list[i]); } transaction.end(); return transaction; }
RTransaction RPasteOperation::apply(RDocument& document, bool preview) const { RTransaction transaction(document.getStorage(), "Inserting object(s)", undoable); copy( sourceDocument, document, offset, scale, rotation, flipHorizontal, flipVertical, toCurrentLayer, /*toCurrentBlock=*/ true, overwriteLayers, overwriteBlocks, blockName, transaction, false, false, false, // toModelSpace (paste to current block, not model space) preview ); transaction.end(); return transaction; }
RTransaction RPasteOperation::apply(RDocument& document, bool preview) const { RTransaction transaction(document.getStorage(), text, undoable); transaction.setGroup(transactionGroup); // 20151118: allow also entities on locked / invisible layers to be pasted: transaction.setAllowAll(true); int iMax = offsets.length(); if (preview && iMax>10) { iMax = 10; } double rotation = 0.0; if (rotations.length()==1) { // same rotation for all pasted instances: rotation = rotations[0]; } for (int i=0; i<iMax; i++) { copy( sourceDocument, document, offsets[i], scale, i < rotations.length() ? rotations[i] : rotation, flipHorizontal, flipVertical, toCurrentLayer, /*toCurrentBlock=*/ true, overwriteLayers && i==0, overwriteBlocks && i==0, blockName, layerName, transaction, false, false, false, // toModelSpace (paste to current block, not model space) preview, attributes ); } transaction.end(); return transaction; }
void RViewportEntity::exportEntity(RExporter& e, bool preview, bool forceSelected) const { Q_UNUSED(preview); Q_UNUSED(forceSelected); RDocument* doc = (RDocument*)getDocument(); if (doc==NULL) { return; } RBox viewportBox(data.position, data.width, data.height); // if layer is visible, export viewport frame // viewport contents is always exported (unless viewport if off): if (isVisible()) { // export viewport frame to layer of viewport: e.setBrush(Qt::NoBrush); QList<RLine> lines = viewportBox.getLines2d(); for (int i=0; i<lines.length(); i++) { e.exportLine(lines[i]); } } // if viewport is off, we're done: if (isOff()) { return; } // clip rectangle export e.exportClipRectangle(viewportBox); RVector offset(0,0); offset -= data.viewCenter * data.scale; offset -= data.viewTarget * data.scale; // create temporary block reference to model space block: RBlockReferenceData modelSpaceData( doc, RBlockReferenceData( doc->getModelSpaceBlockId(), data.position + offset, RVector(data.scale, data.scale), 0.0 ) ); modelSpaceData.update(); // start clipping from here: e.setClipping(true); // render model space block reference into viewport: QSet<REntity::Id> ids = doc->queryBlockEntities(doc->getModelSpaceBlockId()); QList<REntity::Id> list = doc->getStorage().orderBackToFront(ids); int i; QList<REntity::Id>::iterator it; for (it = list.begin(), i = 0; it != list.end(); it++) { if (preview && i>RSettings::getPreviewEntities()) { break; } QSharedPointer<REntity> entity = modelSpaceData.queryEntity(*it); if (entity.isNull()) { continue; } entity->rotate(data.rotation, data.position); // prevent recursions: if (entity->getType()==RS::EntityViewport) { continue; } RBox bb = entity->getBoundingBox(); if (!viewportBox.intersects(bb)) { continue; } entity->scaleVisualProperties(data.scale); e.exportEntity(*entity, preview, true); i++; } e.setClipping(false); }
void RClipboardOperation::copy( RDocument& src, RDocument& dest, const RVector& offset, double scale, double rotation, bool flipHorizontal, bool flipVertical, bool toCurrentLayer, bool toCurrentBlock, bool overwriteLayers, bool overwriteBlocks, const QString& blockName, const QString& layerName, RTransaction& transaction, bool selectionOnly, bool clear, bool toModelSpaceBlock, bool preview, const RQMapQStringQString& attributes) const { bool overwriteLinetypes = false; double unitScale; if (src.getUnit()==RS::None) { unitScale = 1.0; } else { unitScale = RUnit::convert(1.0, src.getUnit(), dest.getUnit()); } if (clear) { dest.clear(); } QSet<REntity::Id> entityIdsSet; if (selectionOnly) { entityIdsSet = src.querySelectedEntities(); } else { entityIdsSet = src.queryAllEntities(); } QList<REntity::Id> entityIdsList = src.getStorage().orderBackToFront(entityIdsSet); // Non-const offset. reset to 0/0/0 if copying to block // (offset implemented as block reference offset). RVector off = offset; bool hasBlock = false; QSet<REntity::Id> attributeIds; // this part is used to insert ('paste') blocks from the part library // as new blocks: QSharedPointer<RBlockReferenceEntity> refp; if (!blockName.isNull()) { QSharedPointer<RBlock> block; hasBlock = dest.hasBlock(blockName); // block does not exist in dest - or - // block exists in dest and must be overwritten: if (!hasBlock || overwriteBlocks) { block = QSharedPointer<RBlock> (new RBlock(&dest, blockName, RVector(0, 0, 0))); transaction.overwriteBlock(block); } // block exists and must not be overwritten: else { block = dest.queryBlock(blockName); } Q_ASSERT(!block.isNull()); // create new block reference that references new, overwritten or existing block // (insert later, when block is complete, so we have bounding box for spatial index): RBlockReferenceEntity* ref = new RBlockReferenceEntity(&dest, RBlockReferenceData(block->getId(), RVector(0,0,0), RVector(1.0, 1.0, 1.0), 0.0)); refp = QSharedPointer<RBlockReferenceEntity>(ref); refp->setBlockId(dest.getCurrentBlockId()); off = RVector(0, 0, 0); if (flipHorizontal) { refp->flipHorizontal(); } if (flipVertical) { refp->flipVertical(); } //ref->scale(scale * unitScale); refp->scale(scale); refp->rotate(rotation); refp->move(offset); // create attribute for each attribute definition in block with // invalid parent ID (fixed later, when block reference ID is known): QSet<REntity::Id> ids = src.queryAllEntities(); QSet<REntity::Id>::iterator it; for (it=ids.begin(); it!=ids.end(); it++) { REntity::Id id = *it; QSharedPointer<RAttributeDefinitionEntity> attDef = src.queryEntity(id).dynamicCast<RAttributeDefinitionEntity>(); if (attDef.isNull()) { continue; } QSharedPointer<RAttributeEntity> att( new RAttributeEntity( &dest, RAttributeData(attDef->getData(), REntity::INVALID_ID, attDef->getTag()) ) ); att->scale(unitScale); refp->applyTransformationTo(*att); // assign values to attributes: QString tag = att->getTag(); if (attributes.contains(tag)) { att->setText(attributes[tag]); } // make sure the attribute has the correct layer ID of the // corresponding layer in dest: QSharedPointer<RLayer> destLayer = copyEntityLayer(*attDef, src, dest, overwriteLayers, transaction); att->setLayerId(destLayer->getId()); QSharedPointer<RLinetype> destLinetype = copyEntityLinetype(*attDef, src, dest, overwriteLinetypes, transaction); att->setLinetypeId(destLinetype->getId()); transaction.addObject(att, false); attributeIds.insert(att->getId()); } scale = 1.0; rotation = 0.0; flipHorizontal = false; flipVertical = false; toCurrentLayer = false; //toCurrentBlock = false; } // copy entities from src to dest: // if the block existed already in dest and is not overwritten, // there's nothing to do here: if (!hasBlock || overwriteBlocks || preview) { copiedLayers.clear(); copiedLinetypes.clear(); copiedBlocks.clear(); int counter = 0; QList<REntity::Id>::iterator it; for (it=entityIdsList.begin(); it!=entityIdsList.end(); ++it) { if (preview && ++counter>RSettings::getPreviewEntities()) { break; } QSharedPointer<REntity> entity = src.queryEntityDirect(*it); if (entity.isNull() || entity->isUndone()) { continue; } copyEntity( *entity.data(), src, dest, off, scale, unitScale, rotation, flipHorizontal, flipVertical, toCurrentLayer, toCurrentBlock, overwriteLayers, overwriteBlocks, blockName, transaction, toModelSpaceBlock // to model space: true for copy // (allow copy from inside any block definition), // false for paste ); } } // only overwrite layers: else if (overwriteLayers) { copiedLayers.clear(); int counter = 0; QList<REntity::Id>::iterator it; for (it=entityIdsList.begin(); it!=entityIdsList.end(); ++it) { if (preview && ++counter>RSettings::getPreviewEntities()) { break; } QSharedPointer<REntity> entity = src.queryEntityDirect(*it); if (entity.isNull() || entity->isUndone()) { continue; } copyEntityLayer( *entity.data(), src, dest, overwriteLayers, transaction ); } } // copying of entire block complete, insert block reference now since // we now have the bounding box for the spatial index: if (!refp.isNull()) { bool useCurrentAttributes = true; if (!layerName.isEmpty()) { useCurrentAttributes = false; refp->setLayerId(dest.getLayerId(layerName)); } transaction.addObject(refp, useCurrentAttributes); // fix parent ID of attributes created by the new inserted block: REntity::Id refId = refp->getId(); //QSet<REntity::Id> ids = dest.queryAllEntities(); QSet<REntity::Id>::iterator it; for (it=attributeIds.begin(); it!=attributeIds.end(); it++) { REntity::Id id = *it; QSharedPointer<RAttributeEntity> e = dest.queryEntityDirect(id).dynamicCast<RAttributeEntity>(); if (e.isNull()) { continue; } if (e->getParentId()==REntity::INVALID_ID) { e->setParentId(refId); } } } transaction.endCycle(); }
/** * Adds the given entity (and its layer(s) and block reference(s)) to the * given document. * * \param blockName Name of an existing block in dest */ void RClipboardOperation::copyEntity( REntity& entity, RDocument& src, RDocument& dest, const RVector& offset, double scale, double unitScale, double rotation, bool flipHorizontal, bool flipVertical, bool toCurrentLayer, bool toCurrentBlock, bool overwriteLayers, bool overwriteBlocks, const QString& blockName, RTransaction& transaction, bool toModelSpaceBlock) const { bool overwriteLinetypes = false; QSharedPointer<RLayer> destLayer = copyEntityLayer(entity, src, dest, overwriteLayers, transaction); QSharedPointer<RLinetype> destLinetype = copyEntityLinetype(entity, src, dest, overwriteLinetypes, transaction); // add block the entity belongs to, if the block exists it is overwritten // if 'overwriteBlocks' is true: QSharedPointer<RBlock> srcBlock = src.queryBlock(entity.getBlockId()); if (srcBlock.isNull()) { qWarning("RClipboardOperation::copyToDocument: " "block of entity is NULL."); return; } QString srcBlockName = srcBlock->getName(); QSharedPointer<RBlock> destBlock; if (copiedBlocks.contains(srcBlockName)) { destBlock = copiedBlocks.value(srcBlockName); } else { QString destBlockName; if (!blockName.isNull()) { destBlockName = blockName; } else { if (toCurrentBlock) { destBlockName = dest.getBlockName(dest.getCurrentBlockId()); } else { destBlockName = srcBlock->getName(); } } if (!dest.hasBlock(destBlockName) || (overwriteBlocks && blockName.isNull())) { destBlock = QSharedPointer<RBlock> (srcBlock->clone()); dest.getStorage().setObjectId(*destBlock.data(), RObject::INVALID_ID); dest.getStorage().setObjectHandle(*destBlock.data(), RObject::INVALID_HANDLE); destBlock->setDocument(&dest); if (dest.hasBlock(destBlockName)) { if (!transaction.overwriteBlock(destBlock)) { destBlock = dest.queryBlock(destBlockName); } } else { transaction.addObject(destBlock); } } else { destBlock = dest.queryBlock(destBlockName); } copiedBlocks.insert(srcBlockName, destBlock); } Q_ASSERT(destBlock->getId()!=RBlock::INVALID_ID); // entity is a block reference: // add entities of the block the block reference refers to (the block // definition is then added automatically): // if block contents has already been copied, do nothing RBlockReferenceEntity* blockRef = dynamic_cast<RBlockReferenceEntity*>(&entity); if (blockRef!=NULL && !copiedBlockContents.contains(blockRef->getReferencedBlockId())) { QSharedPointer<RBlock> refBlock = src.queryBlock(blockRef->getReferencedBlockId()); if (refBlock.isNull()) { qWarning("RClipboardOperation::copyToDocument: " "entity references a NULL block."); return; } copiedBlockContents.insert(blockRef->getReferencedBlockId()); // TODO: don't do this twice: //qDebug() << "RClipboardOperation::copyToDocument: copying block: " << refBlock->getName(); // if block exists in dest, it has already been copied or was // already there and needs to be overwritten: QSharedPointer<RBlock> refBlockDest = dest.queryBlock(refBlock->getName()); if (refBlockDest.isNull() || overwriteBlocks) { QSet<REntity::Id> ids = src.queryBlockEntities(refBlock->getId()); bool first = true; QSet<REntity::Id>::iterator it; for (it=ids.begin(); it!=ids.end(); ++it) { QSharedPointer<REntity> e = src.queryEntityDirect(*it); if (e.isNull()) { continue; } copyEntity( *e.data(), src, dest, RVector::nullVector, 1.0, // scale from user options not applied to block contents // but to block reference unitScale, 0.0, false, false, // no flips false, false, // keep original block and layer overwriteLayers, first && overwriteBlocks, QString(), transaction, false // not to model space but actual block ); first = false; } } } // add entity self: QSharedPointer<REntity> destEntity = QSharedPointer<REntity>(entity.clone()); //dest.getStorage().setObjectId(*destEntity.data(), RObject::INVALID_ID); dest.getStorage().setObjectHandle(*destEntity.data(), RObject::INVALID_HANDLE); destEntity->setSelected(false); // apply transformations: if (flipHorizontal) { destEntity->flipHorizontal(); } if (flipVertical) { destEntity->flipVertical(); } if (blockRef!=NULL) { destEntity->scale(scale); } else { destEntity->scale(scale * unitScale); } destEntity->rotate(rotation); // correct block reference offset. necessary for unit conversion: if (blockRef!=NULL && src.getUnit()!=dest.getUnit()) { destEntity->move(-blockRef->getPosition()); destEntity->move(blockRef->getPosition() * unitScale); } destEntity->move(offset); destEntity->setDocument(&dest); if (toCurrentLayer) { // paste to current layer: destEntity->setLayerId(dest.getCurrentLayerId()); } else { // paste to original layer: Q_ASSERT(!destLayer.isNull()); destEntity->setLayerId(destLayer->getId()); } destEntity->setLinetypeId(destLinetype->getId()); if (toModelSpaceBlock) { destEntity->setBlockId(dest.getModelSpaceBlockId()); } else { destEntity->setBlockId(destBlock->getId()); } // correct referenced block id of pasted block reference: QSharedPointer<RBlockReferenceEntity> destBlockRef = destEntity.dynamicCast<RBlockReferenceEntity>(); if (!destBlockRef.isNull() && blockRef!=NULL) { QString bn = src.getBlockName(blockRef->getReferencedBlockId()); RBlock::Id blockId = dest.getBlockId(bn); destBlockRef->setReferencedBlockId(blockId); // qDebug() << "not yet updated block ref: " << *destBlockRef; // destBlockRef->update(); // qDebug() << "updated block ref: " << *destBlockRef; } transaction.addObject(destEntity, false, true); }
QSharedPointer<RLayer> RClipboardOperation::copyLayer( RLayer::Id layerId, RDocument& src, RDocument& dest, bool overwriteLayers, RTransaction& transaction) const { // copy parent layers: QString layerName = src.getLayerName(layerId); if (layerName.contains(" ... ")) { QStringList l = layerName.split(" ... "); l.removeLast(); while (!l.isEmpty()) { QString parentLayerName = l.join(" ... "); QSharedPointer<RLayer> parentLayer = src.queryLayer(parentLayerName); if (!parentLayer.isNull()) { copyLayer(parentLayer->getId(), src, dest, overwriteLayers, transaction); } else { qWarning() << "parent layer of layer '" << layerName << "' not found: " << parentLayerName; } l.removeLast(); } } bool overwriteLinetypes = false; // add layer the entity is on, if the layer exists it is overwritten // if overwriteLayers is true: QSharedPointer<RLayer> srcLayer = src.queryLayer(layerId); if (srcLayer.isNull()) { qWarning("RClipboardOperation::copyLayer: " "layer is NULL."); return QSharedPointer<RLayer>(); } QSharedPointer<RLinetype> destLinetype = copyLinetype(srcLayer->getLinetypeId(), src, dest, overwriteLinetypes, transaction); QString srcLayerName = srcLayer->getName(); QSharedPointer<RLayer> destLayer; if (copiedLayers.contains(srcLayerName)) { destLayer = copiedLayers.value(srcLayerName); Q_ASSERT(!destLayer.isNull()); } else { if (!dest.hasLayer(srcLayerName) || overwriteLayers) { destLayer = QSharedPointer<RLayer>(srcLayer->clone()); destLayer->setDocument(&dest); if (destLayer->getDocument()!=srcLayer->getDocument()) { dest.getStorage().setObjectId(*destLayer.data(), RObject::INVALID_ID); dest.getStorage().setObjectHandle(*destLayer.data(), RObject::INVALID_HANDLE); } transaction.addObject(destLayer); } else { destLayer = dest.queryLayer(srcLayerName); Q_ASSERT(!destLayer.isNull()); } copiedLayers.insert(srcLayerName, destLayer); } if (!destLinetype.isNull()) { destLayer->setLinetypeId(destLinetype->getId()); } return destLayer; }