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(); }
QSharedPointer<RBlockReferenceEntity> RDimensionData::getDimensionBlockReference() const { QString dimBlockName = getDimBlockName(); if (dimBlockName.isEmpty()) { return QSharedPointer<RBlockReferenceEntity>(); } const RDocument* doc = getDocument(); if (doc==NULL) { return QSharedPointer<RBlockReferenceEntity>(); } RBlock::Id dimBlockId = doc->getBlockId(dimBlockName); // check if block is empty (ignore): if (!doc->hasBlockEntities(dimBlockId)) { return QSharedPointer<RBlockReferenceEntity>(); } // TODO: ignore block if dimension entity is valid (i.e. only use block if we cannot recompute (?)) RBlockReferenceEntity* dimBlockReference = new RBlockReferenceEntity((RDocument*)doc, RBlockReferenceData(dimBlockId, RVector(0,0), RVector(1,1), 0.0)/*, getId()*/); dimBlockReference->copyAttributesFrom(*this, true); //e.exportEntity(*dimBlockReference, preview, false, forceSelected); //delete dimBlockReference; return QSharedPointer<RBlockReferenceEntity>(dimBlockReference); }
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); }