DiagramDesigner/diagramCavas/source/graphicsDataModel/diagramEditorModel.cpp

2398 lines
114 KiB
C++
Raw Normal View History

#include "graphicsDataModel/diagramEditorModel.h"
#include "basePropertyManager.h"
#include "baseProperty.h"
#include "powerEntity.h"
#include "graphicsItem/graphicsBaseItem.h"
#include "powerTerminal.h"
#include "graphicsItem/itemPort.h"
#include "topologyManager.h"
#include "baseModelItem/electricBaseModelSvgItem.h"
#include "dataBase.h"
#include "diagramEditor/editScene.h"
#include "baseModelItem/electricBaseModelPortItem.h"
#include "baseModelItem/electricBaseModelSvgBus.h"
#include "baseModelItem/electricBaseModelLineItem.h"
2025-09-05 17:30:07 +08:00
#include "diagramEditor/diagramEditorBaseBlock.h"
#include "diagramEditor/editItems.h"
#include "diagramEditor/editPanel.h"
2025-09-19 18:11:28 +08:00
#include "diagramEditor/diagramEditorWizard.h"
#include "diagramEditor/diagramEditorStructContainer.h"
2025-10-24 21:11:07 +08:00
#include <QJsonArray>
#include <QMetaMethod>
2025-10-17 18:14:44 +08:00
int g_nCompoWidth = 50; //元件默认宽度(计算布局使用)
int g_nCompoHeight = 50;
DiagramEditorModel::DiagramEditorModel()
:_pCurBayRoute(nullptr)
,_pCurBayComponent(nullptr)
,_pCurPreviewScene(nullptr)
2025-09-05 17:30:07 +08:00
,_pCurTransComponent(nullptr)
,_pPanel(nullptr)
2025-11-14 19:31:09 +08:00
,_cableCount(0)
{
}
DiagramEditorModel::~DiagramEditorModel()
{
}
2025-09-12 17:28:47 +08:00
bool DiagramEditorModel::addPreviewItem(QUuid uuid,GraphicsBaseModelItem* pItem,int mode)
{
2025-09-12 17:28:47 +08:00
if(mode == 0){
if(_tempItem.contains(uuid))
return false;
else
{
2025-09-26 18:50:21 +08:00
pItem->setMask(false);
2025-09-12 17:28:47 +08:00
_tempItem.insert(uuid,pItem);
return true;
}
}
else if(mode == 1){
if(_previewItem.contains(uuid))
return false;
else
{
2025-09-26 18:50:21 +08:00
pItem->setMask(false);
2025-09-12 17:28:47 +08:00
_previewItem.insert(uuid,pItem);
return true;
}
}
2025-09-12 17:28:47 +08:00
return false;
}
2025-09-12 17:28:47 +08:00
DiagramEditorItemProperty* DiagramEditorModel::addPreviewData(QUuid id,int type,QString name,QString metaName,QString sBlock,int mode)
{
2025-09-12 17:28:47 +08:00
DiagramEditorItemProperty* pData = nullptr;
if(mode == 0){
pData = BasePropertyManager::instance().findTempEditorData(id); //已存在不不创建
}
else if(mode == 1){
pData = BasePropertyManager::instance().findEditorData(id);
}
if(pData != nullptr)
return pData;
DiagramEditorItemProperty* itemData = new DiagramEditorItemProperty(this);
if(itemData)
{
itemData->setUuid(id);
itemData->setMetaModelName(metaName);
itemData->setType(type);
itemData->setTag(name);
itemData->setName(name);
if(!sBlock.isEmpty())
itemData->setBlock(sBlock);
2025-09-12 17:28:47 +08:00
if(mode == 0){
BasePropertyManager::instance().insertTempEditorData(id,itemData);
}
else if(mode == 1){
BasePropertyManager::instance().insertEditorData(id,itemData);
}
}
return itemData;
}
void DiagramEditorModel::createTopoTerminalsByItem(GraphicsBaseItem* pItem,ModelFunctionType funType)
{
PowerEntity* pEntity = pItem->entity();
if(pEntity)
{
QMap<QString,ItemPort*> mapPorts = pItem->getPorts(); //创建实体port对应的拓扑port
for(auto &port:mapPorts)
{
TerminalType terType;
HandleType tpe = port->getType();
switch (tpe) {
case T_lineIn:
terType = TerminalType::PowerInput;
break;
case T_lineOut:
terType = TerminalType::PowerOutput;
break;
case T_lineInOut:
terType = TerminalType::PowerConnect;
break;
2025-10-17 18:14:44 +08:00
case T_newTral:
terType = TerminalType::NewTral;
break;
default:
break;
}
QPointF f = port->pos();
2025-10-17 18:14:44 +08:00
auto pTer = TopologyManager::instance().createTerminal(pEntity->id(),terType,"",port->pos(),port->getId(),funType,port->getXPercent(),port->getYPercent());
if(pTer)
pTer->setPortLocate(port->portPos());
}
}
}
2025-09-19 18:11:28 +08:00
QRectF DiagramEditorModel::generateTempBay()
{
2025-09-19 18:11:28 +08:00
QRectF itemsRect;
2025-09-05 17:30:07 +08:00
generateItemByModel(_pCurBayRoute);
2025-09-19 18:11:28 +08:00
if(_pCurPreviewScene)
itemsRect = _pCurPreviewScene->itemsBoundingRect();
return itemsRect;
}
2025-11-14 19:31:09 +08:00
GraphicsBaseModelItem* DiagramEditorModel::generateComponent(QUuid uid,QString sName,int nCategory,int nType,QPointF pos,int nRotate,int mode,QString sBay)
{
GraphicsBaseModelItem* pItem = nullptr;
2025-10-11 18:51:33 +08:00
int componentType = -1; //对应的componentType
if(nCategory == 0)
{
QByteArray byte;
if(nType == 1){ //母线
byte = DataBase::GetInstance()->ModelType()[nType].icon;
auto pBus = new ElectricBaseModelSvgBus(QRect(-200, -3, 400, 6));
pBus->loadSvg(byte);
2025-08-28 10:59:04 +08:00
pItem = pBus;
pItem->setItemType(GIT_baseBus);
2025-10-11 18:51:33 +08:00
componentType = 1;
}
else if(nType == 2){ //异步电动机
2025-10-11 18:51:33 +08:00
componentType = 2;
}
else if(nType == 3){ //断路器
2025-08-28 10:59:04 +08:00
byte = DataBase::GetInstance()->ModelType()[nType].icon; //注意modelType表与componentType表不一致
auto pBreaker = new ElectricBaseModelSvgItem(QRect(-15, -15, 30, 30));
pBreaker->loadSvg(byte);
2025-08-28 10:59:04 +08:00
pItem = pBreaker;
pItem->setItemType(GIT_baseBreaker);
2025-10-11 18:51:33 +08:00
componentType = 3;
pItem->initialPortsByDatabase(componentType);
}
else if(nType == 4){ //电缆
2025-10-11 18:51:33 +08:00
componentType = 8;
}
else if(nType == 5){ //电流互感器
2025-08-28 10:59:04 +08:00
byte = DataBase::GetInstance()->ModelType()[nType].icon; //注意modelType表与componentType表不一致
2025-09-05 17:30:07 +08:00
auto pCt= new ElectricBaseModelSvgItem(QRect(-10, -10, 20, 20));
pCt->loadSvg(byte);
pItem = pCt;
2025-08-28 10:59:04 +08:00
pItem->setItemType(GIT_baseCT);
2025-10-11 18:51:33 +08:00
componentType = 4;
pItem->initialPortsByDatabase(componentType);
}
else if(nType == 6){ //电压互感器
2025-08-28 10:59:04 +08:00
byte = DataBase::GetInstance()->ModelType()[nType].icon; //注意modelType表与componentType表不一致
2025-09-05 17:30:07 +08:00
auto pPt = new ElectricBaseModelSvgItem(QRect(-25, -25, 50, 50));
pPt->loadSvg(byte);
pItem = pPt;
2025-08-28 10:59:04 +08:00
pItem->setItemType(GIT_basePT);
2025-10-11 18:51:33 +08:00
componentType = 5;
pItem->initialPortsByDatabase(componentType);
}
else if(nType == 7){ //隔离开关
2025-08-28 10:59:04 +08:00
byte = DataBase::GetInstance()->ModelType()[nType].icon; //注意modelType表与componentType表不一致
2025-09-05 17:30:07 +08:00
auto pDs = new ElectricBaseModelSvgItem(QRect(-15, -15, 30, 30));
pDs->loadSvg(byte);
pItem = pDs;
2025-08-28 10:59:04 +08:00
pItem->setItemType(GIT_baseDS);
2025-10-11 18:51:33 +08:00
componentType = 9;
pItem->initialPortsByDatabase(componentType);
}
else if(nType == 8){ //接地开关
2025-10-11 18:51:33 +08:00
byte = DataBase::GetInstance()->ModelType()[nType].icon; //注意modelType表与componentType表不一致
auto pEs = new ElectricBaseModelSvgItem(QRect(-15, -30, 30, 60));
pEs->loadSvg(byte);
pItem = pEs;
pItem->setItemType(GIT_baseES);
componentType = 6;
pItem->initialPortsByDatabase(componentType);
}
else if(nType == 9){ //快速接地开关
2025-10-11 18:51:33 +08:00
byte = DataBase::GetInstance()->ModelType()[nType].icon; //注意modelType表与componentType表不一致
auto pFEs = new ElectricBaseModelSvgItem(QRect(-15, -30, 30, 60));
pFEs->loadSvg(byte);
pItem = pFEs;
pItem->setItemType(GIT_baseFES);
componentType = 7;
pItem->initialPortsByDatabase(componentType);
}
else if(nType == 10){ //双掷接地隔离开关
2025-10-11 18:51:33 +08:00
byte = DataBase::GetInstance()->ModelType()[nType].icon;
auto pDtedes = new ElectricBaseModelSvgItem(QRect(-30, -15, 60, 30));
pDtedes->loadSvg(byte);
pItem = pDtedes;
pItem->setItemType(GIT_baseDTEDS);
componentType = 10;
pItem->initialPortsByDatabase(componentType);
}
else if(nType == 11){ //带电指示器
2025-09-05 17:30:07 +08:00
byte = DataBase::GetInstance()->ModelType()[nType].icon; //注意modelType表与componentType表不一致
auto pPi = new ElectricBaseModelSvgItem(QRect(-15, -30, 30, 60));
pPi->loadSvg(byte);
pItem = pPi;
pItem->setItemType(GIT_basePI);
2025-10-11 18:51:33 +08:00
componentType = 11;
pItem->initialPortsByDatabase(componentType);
}
else if(nType == 12){ //避雷器
2025-10-11 18:51:33 +08:00
byte = DataBase::GetInstance()->ModelType()[nType].icon;
auto pPi = new ElectricBaseModelSvgItem(QRect(-15, -30, 30, 60));
pPi->loadSvg(byte);
pItem = pPi;
pItem->setItemType(GIT_baseLightningArrester);
componentType = 12;
pItem->initialPortsByDatabase(componentType);
}
else if(nType == 13){ //电缆出线套筒
2025-10-11 18:51:33 +08:00
componentType = 13;
}
else if(nType == 14){ //电缆端
2025-10-11 18:51:33 +08:00
byte = DataBase::GetInstance()->ModelType()[nType].icon;
auto pCableEnd = new ElectricBaseModelSvgItem(QRect(-10, -10, 20, 20));
pCableEnd->loadSvg(byte);
pItem = pCableEnd;
pItem->setItemType(GIT_baseCableEnd);
componentType = 14;
pItem->initialPortsByDatabase(componentType);
}
2025-09-05 17:30:07 +08:00
else if(nType == 15){ //两绕组变压器
byte = DataBase::GetInstance()->ModelType()[nType].icon; //注意modelType表与componentType表不一致
auto p2W = new ElectricBaseModelSvgItem(QRect(-50, -50, 100, 100));
p2W->loadSvg(byte);
pItem = p2W;
pItem->setItemType(GIT_base2wTransformer);
2025-10-11 18:51:33 +08:00
componentType = 15;
pItem->initialPortsByDatabase(componentType);
2025-09-05 17:30:07 +08:00
}
else if(nType == 16){ //三绕组变压器
byte = DataBase::GetInstance()->ModelType()[nType].icon; //注意modelType表与componentType表不一致
auto p3W = new ElectricBaseModelSvgItem(QRect(-75, -50, 150, 100));
p3W->loadSvg(byte);
pItem = p3W;
pItem->setItemType(GIT_base3wTransformer);
2025-10-11 18:51:33 +08:00
componentType = 16;
pItem->initialPortsByDatabase(componentType);
2025-09-05 17:30:07 +08:00
}
}
else if(nCategory == 1){
if(nType == 1){ //节点
pItem = new ElectricBaseModelPortItem();
pItem->setItemType(GIT_baseNode);
}
}
if(pItem){
pItem->setItemId(uid);
pItem->setRotation(nRotate);
2025-09-12 17:28:47 +08:00
ModelFunctionType typ;
if(mode == 0){
typ = ModelFunctionType::BlockEditorModel;
}
else if(mode == 1){
typ = ModelFunctionType::EditorModel;
}
PowerEntity* pEntityData = TopologyManager::instance().createEntity(EntityType::Component,uid.toString(),sName,typ);
if(pEntityData)
pItem->setEntity(pEntityData);
DiagramEditorItemProperty* pData = nullptr;
if(nCategory == 1){
2025-11-14 19:31:09 +08:00
pData = addPreviewData(uid,0,sName,"node",sBay,mode);
2025-10-11 18:51:33 +08:00
pData->setGraphicsType(pItem->getItemType());
}
else if(nCategory == 0){ //设备
2025-11-14 19:31:09 +08:00
pData = addPreviewData(uid,componentType,sName,DataBase::GetInstance()->ModelType()[nType].modelType,sBay,mode);
pData->setGraphicsType(pItem->getItemType());
}
if(pData)
{
pItem->setProperty(pData);
2025-09-12 17:28:47 +08:00
createTopoTerminalsByItem(pItem,typ);
pData->setDataChanged(true); //数据状态改变
}
2025-09-12 17:28:47 +08:00
addPreviewItem(uid,pItem,mode);
_pCurPreviewScene->addItem(pItem);
pItem->setPos(pos);
}
2025-09-12 17:28:47 +08:00
return pItem;
}
2025-11-14 19:31:09 +08:00
ElectricBaseModelLineItem* DiagramEditorModel::generateLine(QUuid uid,QString sName,int mode,QString sBay)
{
ElectricBaseModelLineItem* pLine = new ElectricBaseModelLineItem();
pLine->setItemId(uid);
pLine->setItemType(GIT_baseLine);
2025-11-14 19:31:09 +08:00
DiagramEditorItemProperty* pData = addPreviewData(uid,8,sName,DataBase::GetInstance()->ModelType()[4].modelType,sBay,mode);
pData->setGraphicsType(GIT_baseLine);
if(pData)
{
pLine->setProperty(pData);
pData->setDataChanged(true); //数据状态改变
}
2025-09-12 17:28:47 +08:00
addPreviewItem(uid,pLine,mode);
//establishConnection(pBreaker,pBus,pLine,ModelFunctionType::BaseModel);
_pCurPreviewScene->addItem(pLine);
2025-08-28 10:59:04 +08:00
return pLine;
}
void DiagramEditorModel::clearCurPreview()
{
2025-09-05 17:30:07 +08:00
if(_pCurPreviewScene){
_tempItem.clear();
2025-08-28 10:59:04 +08:00
_pCurPreviewScene->clear();
2025-09-05 17:30:07 +08:00
}
}
void DiagramEditorModel::generateTempTrans(int nType,DiagramEditorTransformerBlock* block)
{
if(nType == 0 || nType == 1 || nType == 2){
generateItemByModel(_pCurTransLRoutes.value(nType),1);
}
else if(nType == 3){
TransformerType typ = block->getTransType();
2025-09-19 18:11:28 +08:00
auto pInfo = block->getTranInfo();
2025-09-05 17:30:07 +08:00
int nT = 0;
if(typ == TransformerType::twoWinding){
generateItemByModel(_pCurTransLRoutes.value(0),1,QPoint(100,-25));
generateItemByModel(_pCurTransLRoutes.value(2),1,QPoint(100,25));
2025-10-17 18:14:44 +08:00
if(pInfo.mapNeutral.contains(0))
pInfo.mapNeutral[0].delPoint = QPoint(100,-25);
if(pInfo.mapNeutral.contains(2))
pInfo.mapNeutral[2].delPoint = QPoint(100,25);
2025-09-05 17:30:07 +08:00
}
else if(typ == TransformerType::threeWinding){
generateItemByModel(_pCurTransLRoutes.value(0),1,QPoint(100,-25));
generateItemByModel(_pCurTransLRoutes.value(1),1,QPoint(-150,0));
generateItemByModel(_pCurTransLRoutes.value(2),1,QPoint(100,25));
2025-10-17 18:14:44 +08:00
if(pInfo.mapNeutral.contains(0))
pInfo.mapNeutral[0].delPoint = QPoint(100,-25);
if(pInfo.mapNeutral.contains(1))
pInfo.mapNeutral[1].delPoint = QPoint(-150,0);
if(pInfo.mapNeutral.contains(2))
pInfo.mapNeutral[2].delPoint = QPoint(100,25);
2025-09-05 17:30:07 +08:00
}
connectTransToNeutral(block);
2025-09-19 18:11:28 +08:00
if(_pCurPreviewScene){
QRectF itemsRect = _pCurPreviewScene->itemsBoundingRect();
2025-09-26 18:50:21 +08:00
if(block->getRecSize().isEmpty())
block->setRecSize(itemsRect);
2025-09-19 18:11:28 +08:00
}
2025-09-05 17:30:07 +08:00
}
}
void DiagramEditorModel::connectTransToNeutral(DiagramEditorTransformerBlock* block)
{
if(block){ //生成变压器主体
QUuid uid = block->getId();
QString sName = block->getName();
int nT = 0;
TransformerType typ = block->getTransType();
if(typ == TransformerType::twoWinding){
nT = 15;
}
else if(typ == TransformerType::threeWinding){
nT = 16;
}
2025-09-19 18:11:28 +08:00
generateComponent(uid,sName,0,nT,QPoint(0,0),0,0);
2025-09-05 17:30:07 +08:00
auto pTransItem = _tempItem.value(uid);
2025-09-19 18:11:28 +08:00
if(pTransItem){
if(typ == TransformerType::twoWinding){
linkTransItem(pTransItem,_pCurTransLRoutes.value(0));
linkTransItem(pTransItem,_pCurTransLRoutes.value(2));
}
else if(typ == TransformerType::threeWinding){
linkTransItem(pTransItem,_pCurTransLRoutes.value(0));
linkTransItem(pTransItem,_pCurTransLRoutes.value(1));
linkTransItem(pTransItem,_pCurTransLRoutes.value(2));
}
2025-09-05 17:30:07 +08:00
}
}
}
2025-09-05 17:30:07 +08:00
void DiagramEditorModel::linkTransItem(GraphicsBaseModelItem* pTrans,QStandardItemModel* pModel)
{
2025-09-05 17:30:07 +08:00
QUuid uid1 = pTrans->itemId();
int rowCount = pModel->rowCount();
for(int i = 0;i < rowCount;++i){
QStandardItem *itemComps = pModel->item(i, 1);
QString sComps = itemComps->text();
QStringList lst = sComps.split(",");
for(auto& name:lst){ //寻找绑定到中性点的点
QStandardItem* pItem = getNameItem(name,1);
if(pItem){
QModelIndex index = pItem->index();
QModelIndex indexObj = index.sibling(index.row(),3);
QUuid uid2 = pItem->data(Qt::UserRole+3).toUuid();
QString sBindObj = indexObj.data().toString(); //获取显示数据
auto pItem = _tempItem.value(uid2);
if(sBindObj == "高压绕组中性点" || sBindObj == "中压绕组中性点" || sBindObj == "低压绕组中性点"){
int nPos = 0;
if(sBindObj == "高压绕组中性点")
nPos = 0;
else if(sBindObj == "中压绕组中性点")
nPos = 1;
else if(sBindObj == "低压绕组中性点")
nPos = 2;
2025-11-14 19:31:09 +08:00
QString strCable = "cable_"+QString::number(_cableCount++);
2025-09-05 17:30:07 +08:00
auto pLineData = TopologyManager::instance().ifConnection(uid1.toString(),uid2.toString()); //判断两个item是否有连接
if(pLineData != nullptr){
if(!_tempItem.contains(QUuid(pLineData->id()))){ //connectdata已存在item未绘制
2025-11-14 19:31:09 +08:00
auto pLine = generateLine(QUuid(pLineData->id()),strCable,0); //重新绘制
2025-09-05 17:30:07 +08:00
if(pLine)
establishConnection(pItem,pTrans,pLine,ModelFunctionType::BlockEditorModel,1,nPos);
}
else{ //已绘制,略过
}
}
else{ //connectdata不存在新建
2025-11-14 19:31:09 +08:00
auto pLine = generateLine(QUuid::createUuid(),strCable,0);
2025-09-05 17:30:07 +08:00
if(pLine)
establishConnection(pItem,pTrans,pLine,ModelFunctionType::BlockEditorModel,1,nPos);
}
}
}
}
}
2025-09-05 17:30:07 +08:00
}
2025-09-12 17:28:47 +08:00
void DiagramEditorModel::generatePreview()
{
if(_pPanel){
_pPanel->showPreview();
QList<EditBaseItem*> lst = _pPanel->getBlockItems();
2025-09-19 18:11:28 +08:00
QMap<QString,QList<DiagramEditorComponentInfo>> baysCompo;
QMap<QString,QMap<int,QList<DiagramEditorComponentInfo>>> transCompo;
2025-09-12 17:28:47 +08:00
for(auto item:lst){
if(item->getType() == EditorItemType::bus){ //首次循环生成母线
auto p = item->getBlockData(); //获取blockitem对应的data
if(p){
QUuid uid = p->getId();
QString name = p->getName();
2025-09-19 18:11:28 +08:00
auto pContainer = _pWizard->getContainerByBlock_all(name); //获取block所在的container
auto mapBlocks = pContainer->getBlockMap();
int nMaxLen = 0;
for(auto &lst:mapBlocks){ //根据容器中block的最大长度计算出母线最小length
int nLen = 0;
for(auto block:lst){
if(block->getType() == 1) //容器中block是母线不计算
continue;
nLen = 100+block->getRecSize().width();
}
if(nMaxLen < nLen)
nMaxLen = nLen;
}
QRectF rec = item->boundingRect();
2025-09-12 17:28:47 +08:00
QPointF pos = item->scenePos();
2025-09-26 18:50:21 +08:00
if(_previewItem.contains(uid))
continue;
2025-09-12 17:28:47 +08:00
auto pItem = generateComponent(uid,name,0,1,pos,0,1);
2025-09-19 18:11:28 +08:00
if(nMaxLen > rec.width())
rec.setWidth(nMaxLen);
pItem->setBoundingRect(rec);
p->setRecSize(rec);
2025-09-12 17:28:47 +08:00
}
}
2025-09-19 18:11:28 +08:00
else if(item->getType() == EditorItemType::bay){ //第二次生成间隔、变压器
2025-09-12 17:28:47 +08:00
auto p = item->getBlockData(); //获取blockitem对应的data
DiagramEditorBayBlock* pBay = dynamic_cast<DiagramEditorBayBlock*>(p.data());
if(pBay){
2025-09-19 18:11:28 +08:00
QString sBay = pBay->getName();
2025-09-12 17:28:47 +08:00
auto mapRoute = pBay->getBayInfo().mapRoute;
auto mapCompo = pBay->getBayInfo().mapComponent;
QRectF rect = item->boundingRect();
// 计算中心点(本地坐标系)
QPointF centerLocal = rect.center();
// 转换为场景坐标系
QPointF centerScene = item->mapToScene(centerLocal);
2025-11-14 19:31:09 +08:00
QList<DiagramEditorComponentInfo> lstCompo = generateItemByInfo(mapRoute,mapCompo,centerScene,pBay); //返回与外部连接的compo
2025-09-19 18:11:28 +08:00
if(!baysCompo.contains(sBay))
baysCompo.insert(sBay,lstCompo);
}
}
else if(item->getType() == EditorItemType::trans){
auto p = item->getBlockData(); //获取blockitem对应的data
DiagramEditorTransformerBlock* pTrans = dynamic_cast<DiagramEditorTransformerBlock*>(p.data());
if(pTrans){
//首先绘制本体
auto pType = pTrans->getTransType();
QString sTrans = pTrans->getName();
QUuid uid = pTrans->getId();
QString name = pTrans->getName();
QPointF pos = item->scenePos();
int nType = 0;
if(pType == TransformerType::twoWinding)
nType = 15;
else
nType = 16;
auto pItem = generateComponent(uid,name,0,nType,pos,0,1);
2025-11-14 19:31:09 +08:00
auto pro = pItem->getProperty();
2025-09-19 18:11:28 +08:00
QRectF rect = item->boundingRect();
// 计算中心点(本地坐标系)
QPointF centerLocal = rect.center();
// 转换为场景坐标系
QPointF centerScene = item->mapToScene(centerLocal);
auto transInfo = pTrans->getTranInfo();
QMap<int,QList<DiagramEditorComponentInfo>> neutralInfo;
for(auto &neutral:transInfo.mapNeutral){
QPointF pDelta = neutral.delPoint;
int nT = neutral.nType;
2025-11-14 19:31:09 +08:00
QList<DiagramEditorComponentInfo> lstCompo = generateItemByInfo(neutral.mapRoute,transInfo.mapComponent,centerScene+pDelta,pTrans);
2025-09-19 18:11:28 +08:00
if(!neutralInfo.contains(nT))
neutralInfo.insert(nT,lstCompo);
}
if(!transCompo.contains(sTrans)) //添加需连接的中性点
transCompo.insert(sTrans,neutralInfo);
2025-09-12 17:28:47 +08:00
}
}
}
2025-10-21 18:46:51 +08:00
for(auto iter = baysCompo.begin();iter != baysCompo.end();++iter){
2025-11-14 19:31:09 +08:00
//QMultiMap<int,QUuid> mapId = generateOutConnection(iter.value(),2);
2025-10-21 18:46:51 +08:00
QList<QUuid> lstFrom; //处理进出链接
QList<QUuid> lstTo;
for(auto item:lst){
if(item->getType() == EditorItemType::bay){
auto p = item->getBlockData(); //获取blockitem对应的data
DiagramEditorBayBlock* pBay = dynamic_cast<DiagramEditorBayBlock*>(p.data());
if(pBay){
if(pBay->getName() == iter.key()){ //相同间隔
2025-11-14 19:31:09 +08:00
QMultiMap<int,QUuid> mapId = generateOutConnection(iter.value(),2,0,pBay); //type为2时pos不启用
2025-10-21 18:46:51 +08:00
switch (pBay->getBayType()) {
case BayType::busSectionBay:{
QList<QUuid> values = mapId.values(1);
if (!values.isEmpty()) {
// 第一个值放入lstFrom
lstFrom.append(values.first());
// 如果有第二个值放入lstTo
if (values.size() > 1) {
lstTo.append(values.at(1));
}
}
}
break;
case BayType::busCouplerBay:{
QList<QUuid> values = mapId.values(1);
if (!values.isEmpty()) {
// 第一个值放入lstFrom
lstFrom.append(values.first());
// 如果有第二个值放入lstTo
if (values.size() > 1) {
lstTo.append(values.at(1));
}
}
}
break;
case BayType::ptBay:{
QList<QUuid> values = mapId.values(1);
if (!values.isEmpty()) {
// 第一个值放入lstTo
lstTo.append(values.first());
}
}
break;
case BayType::incomingBay:{
for (auto it = mapId.begin(); it != mapId.end(); ++it) {
if (it.key() == 1) {
lstTo.append(it.value()); // 连接母线,放入 lstTo
} else {
lstFrom.append(it.value()); // 其他,放入 lstFrom
}
}
}
break;
case BayType::outcomingBay:{
for (auto it = mapId.begin(); it != mapId.end(); ++it) {
if (it.key() != 1) {
lstTo.append(it.value()); // 不连接母线,放入 lstTo
} else {
lstFrom.append(it.value()); // 连接母线,放入 lstFrom
}
}
}
break;
default:
break;
}
pBay->getBayInfo().lstFrom = lstFrom;
pBay->getBayInfo().lstTo = lstTo;
}
}
}
}
2025-09-19 18:11:28 +08:00
}
2025-11-14 19:31:09 +08:00
for(auto iter = transCompo.begin();iter != transCompo.end();++iter){
for(auto it = iter.value().begin(); it != iter.value().end();++it){ //遍历每侧中性点
for(auto item:lst){
if(item->getType() == EditorItemType::trans){
auto p = item->getBlockData(); //获取blockitem对应的data
DiagramEditorTransformerBlock* pTrans = dynamic_cast<DiagramEditorTransformerBlock*>(p.data());
if(pTrans){
if(pTrans->getName() == iter.key()){
generateOutConnection(it.value(),1,it.key(),pTrans);
}
}
}
}
2025-09-19 18:11:28 +08:00
}
}
}
}
void DiagramEditorModel::calculateBlockPos()
{
if(_pWizard){
double deltaY = 0; //竖直方向每行增量
double lastMaxDownH = 0; //上一行的下部最大高度
auto mapTotal = _pWizard->getContainerStruct();
for(auto iter = mapTotal.begin();iter != mapTotal.end();++iter){
if(iter.key() == g_transformerLevel)
continue;
double dMaxUp = 0; //计算最大上方空间
double dMaxDown = 0; //计算最大下方空间
for(auto &pCon:iter.value()){ //首次循环遍历每行container,计算最大上空间高度,最大下空间高度,容器宽度
auto mapBlocks = pCon->getBlockMap();
auto lstBlockUp = mapBlocks.value(0);
2025-09-26 18:50:21 +08:00
auto lstBus1 = mapBlocks.value(1); //1母
auto lstBus2 = mapBlocks.value(2); //2母
2025-09-19 18:11:28 +08:00
auto lstBlockDown = mapBlocks.value(3);
double dConWidth = 0;
double dWidthUp = 0;
for(auto pBlock:lstBlockUp){
QRectF rec = pBlock->getRecSize();
double dHeight = rec.height();
double dWidth = rec.width();
if(dMaxUp < dHeight)
dMaxUp = dHeight;
dWidthUp += g_nHorizontalBlockSpacing+dWidth;
}
2025-09-26 18:50:21 +08:00
dMaxUp += g_dEditorItem_Height;
2025-09-19 18:11:28 +08:00
double dWidthDown = 0;
for(auto pBlock:lstBlockDown){
QRectF rec = pBlock->getRecSize();
double dHeight = rec.height();
double dWidth = rec.width();
if(dMaxDown < dHeight)
dMaxDown = dHeight;
dWidthDown = g_nHorizontalBlockSpacing+dWidth;
}
2025-09-26 18:50:21 +08:00
dMaxDown += g_dEditorItem_Height;
int nBusLen = 0;
if(!lstBus1.empty()){
nBusLen = lstBus1.first()->getRecSize().width();
}
if(!lstBus2.empty()){
int nLen = lstBus2.first()->getRecSize().width();
if(nBusLen < nLen)
nBusLen = nLen;
}
2025-09-19 18:11:28 +08:00
dConWidth = dWidthUp > dWidthDown ? dWidthUp : dWidthDown;
2025-09-26 18:50:21 +08:00
if(dConWidth < nBusLen)
dConWidth = nBusLen;
2025-09-19 18:11:28 +08:00
pCon->setWidth(dConWidth);
}
2025-09-26 18:50:21 +08:00
if(dMaxUp == 0){
dMaxUp = g_dEditorItem_Height;
}
if(dMaxDown == 0){
dMaxDown = g_dEditorItem_Height;
}
double dDeltaX = 50; //每行横向偏移
2025-09-19 18:11:28 +08:00
for(auto &pCon:iter.value()){ //第二次循环赋值,计算位置(首先确定母线位置)
pCon->setMaxUpH(dMaxUp);
pCon->setMaxDownH(dMaxDown);
if(iter.value().first() == pCon){ //每行只进行一次y位移
if(iter == mapTotal.begin()){ //首行 deltaY = 首行dMaxUpH
deltaY = pCon->getMaxUpH();
}
2025-09-26 18:50:21 +08:00
else if(iter == std::next(mapTotal.begin())){ //第二行
if(!mapTotal.value(g_transformerLevel).empty()){ //有变压器
deltaY = deltaY + pCon->getMaxUpH();
}
else
deltaY = deltaY + 50 + lastMaxDownH + pCon->getMaxUpH();
}
2025-09-19 18:11:28 +08:00
else //其他行 deltaY = deltaY+母线高度+上行dMaxDownH+本行dMaxUpH
{
deltaY = deltaY + 50 + lastMaxDownH + pCon->getMaxUpH();
}
2025-09-26 18:50:21 +08:00
2025-09-19 18:11:28 +08:00
lastMaxDownH = pCon->getMaxDownH();
}
pCon->setMidUpY(deltaY);
pCon->setMidDownY(deltaY+50);
pCon->setStartX(dDeltaX);
2025-10-17 18:14:44 +08:00
dDeltaX += pCon->getWidth()+100;
2025-09-19 18:11:28 +08:00
//计算container中block中心点的位置
auto mapBlocks = pCon->getBlockMap();
for(auto it = mapBlocks.begin();it != mapBlocks.end();++it){
double pStartX = pCon->getStartX(); //容器起始x
double dMiddleUpY = pCon->getMidUpY(); //获取1母上边y
double dMiddleDownY = pCon->getMidDownY(); //获取2母下边y
double deltaX = pStartX;
for(auto pBlock:it.value()){
QRectF recBlock = pBlock->getRecSize();
QPointF center;
if(pBlock->getType() == 1){ //母线
if(it.key() == 1){ //1母
2025-09-26 18:50:21 +08:00
center = QPointF(pStartX/*+recBlock.width()*0.5*/,dMiddleUpY+recBlock.height()*0.5);
2025-09-19 18:11:28 +08:00
}
else if(it.key() == 2){ //2母
2025-09-26 18:50:21 +08:00
center = QPointF(pStartX/*+recBlock.width()*0.5*/,dMiddleDownY-recBlock.height()*0.5);
2025-09-19 18:11:28 +08:00
}
}
else if(pBlock->getType() == 2){ //间隔
if(it.key() == 0){ //容器最上层
2025-09-26 18:50:21 +08:00
center = QPointF(deltaX+recBlock.width()*0.5,dMiddleUpY-recBlock.height()*0.5-g_dEditorItem_Height*0.5);
2025-09-19 18:11:28 +08:00
}
else if(it.key() == 3){ //容器最下层
2025-09-26 18:50:21 +08:00
center = QPointF(deltaX+recBlock.width()*0.5,dMiddleDownY+recBlock.height()*0.5+g_dEditorItem_Height*0.5);
2025-09-19 18:11:28 +08:00
}
deltaX += recBlock.width();
}
else if(pBlock->getType() == 3){ //变压器
}
if(!center.isNull())
pBlock->setSeceneDelta(center);
2025-09-26 18:50:21 +08:00
//qDebug()<<pBlock->getName()<<":"<<center<<"-"<<recBlock;
2025-09-19 18:11:28 +08:00
}
}
}
2025-10-11 18:51:33 +08:00
dDeltaX = 150; //首个变压器位置
2025-09-19 18:11:28 +08:00
if(iter.key() == 0){ //若设置了变压器,直接插入到第一行下方
if(!mapTotal.value(g_transformerLevel).empty()){
2025-09-26 18:50:21 +08:00
auto lstCon = mapTotal.value(g_transformerLevel);
for(auto &pCon:lstCon){ //首次计算变压器大小
2025-09-19 18:11:28 +08:00
auto mapBlocks = pCon->getBlockMap();
auto lstBlock = mapBlocks.value(1);
for(auto &pb:lstBlock){
QRectF rec = pb->getRecSize();
pCon->setWidth(rec.width());
pCon->setHeight(rec.height());
}
}
2025-09-26 18:50:21 +08:00
for(auto &pCon:lstCon){ //计算位置
if(pCon == lstCon.first()){
2025-09-19 18:11:28 +08:00
//只在每行第一次改变deltaY
2025-09-26 18:50:21 +08:00
deltaY = deltaY + 50 + lastMaxDownH + pCon->getHeight();
2025-09-19 18:11:28 +08:00
}
2025-09-26 18:50:21 +08:00
double dHeight = pCon->getHeight();
double dWidth = pCon->getWidth();
pCon->setStartY(deltaY-dHeight*0.5);
2025-09-19 18:11:28 +08:00
pCon->setStartX(dDeltaX);
2025-10-11 18:51:33 +08:00
dDeltaX += dWidth+200;
2025-09-19 18:11:28 +08:00
auto mapBlocks = pCon->getBlockMap();
2025-09-12 17:28:47 +08:00
2025-09-19 18:11:28 +08:00
for(auto it = mapBlocks.begin();it != mapBlocks.end();++it){
for(auto pBlock:it.value()){
QRectF recBlock = pBlock->getRecSize();
QPointF center = QPointF(pCon->getStartX()+recBlock.width()*0.5,pCon->getStartY()+recBlock.height()*0.5);
pBlock->setSeceneDelta(center);
2025-09-26 18:50:21 +08:00
qDebug()<<pBlock->getName()<<":"<<center<<"-"<<recBlock;
2025-09-19 18:11:28 +08:00
}
}
}
}
}
}
}
}
void DiagramEditorModel::setItemInBlockPos()
{
QList<EditBaseItem*> lst = _pPanel->getBlockItems();
for(auto item:lst){
if(item->getType() == EditorItemType::bus){
auto p = item->getBlockData(); //获取blockitem对应的data
if(p){
QUuid uid = p->getId();
auto pItem = _previewItem.value(uid);
if(pItem){
QPointF pPos = p->getSceneDelta();
pItem->setPos(pPos);
2025-09-26 18:50:21 +08:00
pItem->setPosChanged(true);
//qDebug()<<pItem->sceneBoundingRect()<<pItem->boundingRect();
2025-09-19 18:11:28 +08:00
}
}
}
else if(item->getType() == EditorItemType::bay){
auto p = item->getBlockData(); //获取blockitem对应的data
DiagramEditorBayBlock* pBay = dynamic_cast<DiagramEditorBayBlock*>(p.data());
if(pBay){
QString sBay = pBay->getName();
auto bayInfo = pBay->getBayInfo();
auto mapRoute = bayInfo.mapRoute;
auto mapCompo = bayInfo.mapComponent;
auto lst = getRouteItemInfoList(mapCompo,mapRoute);
for(auto& info:lst){
auto pItem = _previewItem.value(info.uid);
if(pItem){
QPointF pos = info.deltaPos+pBay->getSceneDelta();
pItem->setPos(pos);
2025-09-26 18:50:21 +08:00
pItem->setPosChanged(true);
2025-09-19 18:11:28 +08:00
}
}
}
}
else if(item->getType() == EditorItemType::trans){
auto p = item->getBlockData(); //获取blockitem对应的data
DiagramEditorTransformerBlock* pTrans = dynamic_cast<DiagramEditorTransformerBlock*>(p.data());
if(pTrans){
auto transInfo = pTrans->getTranInfo();
auto mapCompo = transInfo.mapComponent;
2025-09-26 18:50:21 +08:00
//item->setPos(pTrans->getSceneDelta());
auto transItem = _previewItem.value(pTrans->getId());
if(transItem){
transItem->setPos(pTrans->getSceneDelta());
}
2025-09-19 18:11:28 +08:00
for(auto &neuInfo:transInfo.mapNeutral){
auto mapRoute = neuInfo.mapRoute;
auto lst = getRouteItemInfoList(mapCompo,mapRoute);
for(auto& info:lst){
auto pItem = _previewItem.value(info.uid);
if(pItem){
2025-09-26 18:50:21 +08:00
QPointF pos = info.deltaPos+transItem->mapToScene(neuInfo.delPoint);
2025-09-19 18:11:28 +08:00
pItem->setPos(pos);
2025-09-26 18:50:21 +08:00
pItem->setPosChanged(true);
//qDebug()<<pos;
}
}
}
}
}
}
}
void DiagramEditorModel::refreshConnection()
{
for(auto& item:_previewItem){
auto pData = item->getProperty();
if(pData){
int nType = pData->type();
QUuid uid = pData->uuid();
if(nType == 8){ //是电缆
auto pLine = dynamic_cast<ElectricBaseModelLineItem*>(item);
if(pLine){
PowerConnection* pCon = TopologyManager::instance().connection(uid.toString(),ModelFunctionType::EditorModel);
if(pCon){
QString fromTerId = pCon->fromTerminalId();
QString toTerId = pCon->toTerminalId();
QString fromId = pCon->fromComponent();
QString toId = pCon->toComponent();
GraphicsBaseModelItem* pFromItem = _previewItem.value(QUuid(fromId));
GraphicsBaseModelItem* pToItem = _previewItem.value(QUuid(toId));
auto pFromData = pFromItem->getProperty();
auto pToData = pToItem->getProperty();
if(pFromData->type() == 1){ //from是母线
2025-10-17 18:14:44 +08:00
QPointF p = calculateBusPortPos(pFromItem,pToItem);
pFromItem->movePort(fromTerId,pFromItem->mapFromScene(p));
2025-09-26 18:50:21 +08:00
}
else if(pToData->type() == 1){ //to是母线
2025-10-17 18:14:44 +08:00
QPointF p = calculateBusPortPos(pToItem,pFromItem);
pToItem->movePort(toTerId,pToItem->mapFromScene(p));
2025-09-26 18:50:21 +08:00
}
auto portsFrom = pFromItem->getPorts();
auto portsTo = pToItem->getPorts();
ItemPort* pFrom = portsFrom.value(fromTerId);
ItemPort* pTo = portsTo.value(toTerId);
if(pFrom && pTo){ //更新连线起点终点位置
pLine->setStartPoint(pFrom->scenePos());
pLine->setEndPoint(pTo->scenePos());
pLine->calculatePath();
2025-10-17 18:14:44 +08:00
PowerTerminal* pTopoFrom = TopologyManager::instance().getTerminal(fromTerId,ModelFunctionType::EditorModel);
PowerTerminal* pTopoTo = TopologyManager::instance().getTerminal(toTerId,ModelFunctionType::EditorModel);
if(pTopoFrom && pTopoTo){
QPointF p1 = pFrom->pos();
QPointF p2 = pTo->pos();
pTopoFrom->setRelativePosition(p1);
pTopoTo->setRelativePosition(p2);
}
2025-09-19 18:11:28 +08:00
}
}
}
2025-09-12 17:28:47 +08:00
}
}
}
}
2025-09-05 17:30:07 +08:00
QStandardItem* DiagramEditorModel::getNameItem(const QString& sName,int nFrom)
{
QStandardItemModel* pModel = nullptr;
if(nFrom == 0){ //间隔
pModel = _pCurBayComponent;
}
else if(nFrom == 1){
pModel = _pCurTransComponent;
}
if(pModel){
int nRowCount = pModel->rowCount();
for(int i = 0;i < nRowCount;++i){
QStandardItem *itemName = pModel->item(i, 1);
if(sName == itemName->text()){
return itemName;
}
}
}
return nullptr;
}
2025-09-05 17:30:07 +08:00
void DiagramEditorModel::generateItemByModel(QStandardItemModel* pModel,int nFrom,QPoint delta)
{
int rowCount = pModel->rowCount();
for(int i = 0;i < rowCount;++i){
QStandardItem *itemComps = pModel->item(i, 1);
QString sComps = itemComps->text();
QStringList lst = sComps.split(",");
for(auto& name:lst){ //第一次循环生成item
QStandardItem* pItem = getNameItem(name,nFrom);
if(pItem){
QModelIndex index = pItem->index();
QModelIndex indexCate = index.sibling(index.row(),0);
QModelIndex indexType = index.sibling(index.row(),2);
if(!pItem->data(Qt::UserRole+4).isValid()){ //未初始化新建item
pItem->setData(1,Qt::UserRole+4);
}
int nCate = indexCate.data(Qt::UserRole+1).toInt(); //0设备1连接
int nType = indexType.data(Qt::UserRole+1).toInt();
int nDir = pItem->data().toInt();
int nRotate = 0;
if(pItem->data(Qt::UserRole+5).isValid())
nRotate = pItem->data(Qt::UserRole+5).toInt();
QPoint pos = pItem->data(Qt::UserRole+2).toPoint();
pos += delta;
QUuid uid = pItem->data(Qt::UserRole+3).toUuid();
if(!_tempItem.contains(uid))
2025-09-12 17:28:47 +08:00
generateComponent(uid,name,nCate,nType,pos,nRotate,0);
2025-09-05 17:30:07 +08:00
}
}
if(lst.size() > 1){
for(int i = 0;i < lst.size() -1;++i){
QStandardItem* pItemFirst = getNameItem(lst[i],nFrom);
QStandardItem* pItemSecond = getNameItem(lst[i+1],nFrom);
if(pItemFirst && pItemSecond){
QUuid uid1 = pItemFirst->data(Qt::UserRole+3).toUuid();
QUuid uid2 = pItemSecond->data(Qt::UserRole+3).toUuid();
if(_tempItem.contains(uid1) && _tempItem.contains(uid2)){
GraphicsBaseModelItem* p1 = _tempItem.value(uid1);
GraphicsBaseModelItem* p2 = _tempItem.value(uid2);
2025-11-14 19:31:09 +08:00
QString strCable = "cable_"+QString::number(_cableCount++);
2025-09-12 17:28:47 +08:00
auto pLineData = TopologyManager::instance().ifConnection(uid1.toString(),uid2.toString(),ModelFunctionType::BlockEditorModel); //判断两个item是否有连接
2025-09-05 17:30:07 +08:00
if(pLineData != nullptr){
if(!_tempItem.contains(QUuid(pLineData->id()))){ //connectdata已存在item未绘制
2025-11-14 19:31:09 +08:00
auto pLine = generateLine(QUuid(pLineData->id()),strCable,0); //重新绘制
2025-09-05 17:30:07 +08:00
if(pLine)
2025-09-12 17:28:47 +08:00
establishConnection(p1,p2,pLine,ModelFunctionType::BlockEditorModel);
2025-09-05 17:30:07 +08:00
}
else{ //已绘制,略过
}
}
else{ //connectdata不存在新建
2025-11-14 19:31:09 +08:00
auto pLine = generateLine(QUuid::createUuid(),strCable,0);
2025-09-05 17:30:07 +08:00
if(pLine)
2025-09-12 17:28:47 +08:00
establishConnection(p1,p2,pLine,ModelFunctionType::BlockEditorModel);
2025-09-05 17:30:07 +08:00
}
}
}
}
}
}
}
2025-11-14 19:31:09 +08:00
QList<DiagramEditorComponentInfo> DiagramEditorModel::generateItemByInfo(QMap<QString,DiagramEditorRouteInfo> mapRoute,QMap<QString,DiagramEditorComponentInfo> mapCompo,QPointF delta,DiagramEditorBaseBlock* pParent)
2025-09-05 17:30:07 +08:00
{
2025-09-12 17:28:47 +08:00
QList<DiagramEditorComponentInfo> lstBind; //连接外部对象的component
QString sMain;
for(auto& route:mapRoute){ //总路线中包含主路,首次生成主路
if(route.bMainRoute == true){
sMain = route.sRouteName;
for(auto& compo:route.lstCompo){ //首先生成设备
auto info = mapCompo.value(compo.sName);
2025-09-26 18:50:21 +08:00
if(_previewItem.contains(info.uid))
continue;
2025-11-14 19:31:09 +08:00
generateComponent(info.uid,info.sName,info.nCategory,info.nType,info.deltaPos+delta,info.nRotate,1,pParent->getName());
2025-09-12 17:28:47 +08:00
if(!info.sBindObj.isEmpty() && info.sBindObj != QString::fromWCharArray(L"")){ //非空且不是无
if(!lstBind.contains(info))
lstBind.append(info);
}
2025-11-14 19:31:09 +08:00
if(pParent != nullptr){ //添加到block中的子item列表
pParent->addSubList(qMakePair(0,info.uid));
}
2025-09-12 17:28:47 +08:00
}
2025-09-05 17:30:07 +08:00
2025-09-12 17:28:47 +08:00
if(route.lstCompo.size() > 1){
2025-11-14 19:31:09 +08:00
bulidAndLinkComponent(route.lstCompo,mapCompo,pParent); //添加线到subitem
2025-09-12 17:28:47 +08:00
}
}
}
for(auto &route:mapRoute){ //二次生成其他路线
if(route.bMainRoute == true){
continue;
}
for(auto &compo:route.lstOrder){ //生成正序设备
auto info = mapCompo.value(compo.sName);
2025-09-26 18:50:21 +08:00
if(_previewItem.contains(info.uid))
continue;
2025-11-14 19:31:09 +08:00
generateComponent(info.uid,info.sName,info.nCategory,info.nType,info.deltaPos+delta,info.nRotate,1,pParent->getName());
2025-09-12 17:28:47 +08:00
if(!info.sBindObj.isEmpty() && info.sBindObj != QString::fromWCharArray(L"")){ //非空且不是无
if(!lstBind.contains(info))
lstBind.append(info);
}
}
for(auto &compo:route.lstReverse){ //生成逆序设备
auto info = mapCompo.value(compo.sName);
2025-09-26 18:50:21 +08:00
if(_previewItem.contains(info.uid))
continue;
2025-11-14 19:31:09 +08:00
generateComponent(info.uid,info.sName,info.nCategory,info.nType,info.deltaPos+delta,info.nRotate,1,pParent->getName());
2025-09-12 17:28:47 +08:00
if(!info.sBindObj.isEmpty() && info.sBindObj != QString::fromWCharArray(L"")){ //非空且不是无
if(!lstBind.contains(info))
lstBind.append(info);
}
}
if(route.lstOrder.size() > 1){
2025-11-14 19:31:09 +08:00
bulidAndLinkComponent(route.lstOrder,mapCompo,pParent);
2025-09-12 17:28:47 +08:00
}
if(route.lstReverse.size() > 1){
2025-11-14 19:31:09 +08:00
bulidAndLinkComponent(route.lstReverse,mapCompo,pParent);
2025-09-12 17:28:47 +08:00
}
}
2025-09-19 18:11:28 +08:00
return lstBind;
}
2025-11-14 19:31:09 +08:00
QMultiMap<int,QUuid> DiagramEditorModel::generateOutConnection(QList<DiagramEditorComponentInfo> lstBind,int nTypeTransCon,int nPos,DiagramEditorBaseBlock* pParent)
2025-09-19 18:11:28 +08:00
{
2025-10-21 18:46:51 +08:00
QMultiMap<int,QUuid> bindId; //返回关联的对象id<类型id>
2025-09-12 17:28:47 +08:00
for(auto& compo:lstBind){ //遍历关联外部的item进行连线
if(compo.nBindType == 1){ //关联的是母线 母线没有数据获取绘制的母线item
for(auto& pItem:_previewItem){
auto pro = pItem->getProperty();
if(pro){
QString sName = pro->name();
2025-10-21 18:46:51 +08:00
QUuid uId = pro->uuid();
int nType = pro->type();
2025-09-12 17:28:47 +08:00
if(sName == compo.sBindObj){
2025-11-14 19:31:09 +08:00
auto pBus = getBlockDataByName(sName,EditorItemType::bus);
if(pParent && pBus){ //直连到母线的一般是间隔添加到busblock的sublist中
pBus->addSubList(qMakePair(1,pParent->getId()));
}
2025-09-12 17:28:47 +08:00
GraphicsBaseModelItem* pSrc = _previewItem.value(compo.uid);
GraphicsBaseModelItem* pTarget = pItem;
2025-11-14 19:31:09 +08:00
QString strCable = "cable_"+QString::number(_cableCount++);
QUuid lineId;
2025-09-12 17:28:47 +08:00
auto pLineData = TopologyManager::instance().ifConnection(pSrc->itemId().toString(),pTarget->itemId().toString(),ModelFunctionType::EditorModel); //判断两个item是否有连接
if(pLineData != nullptr){
2025-11-14 19:31:09 +08:00
lineId = QUuid(pLineData->id());
if(!_previewItem.contains(lineId)){ //connectdata已存在item未绘制
auto pLine = generateLine(lineId,strCable,1,pParent->getName()); //重新绘制
2025-09-12 17:28:47 +08:00
if(pLine)
establishConnection(pSrc,pTarget,pLine,ModelFunctionType::EditorModel);
}
else{ //已绘制,略过
}
}
else{ //connectdata不存在新建
2025-11-14 19:31:09 +08:00
lineId = QUuid::createUuid();
auto pLine = generateLine(lineId,strCable,1,pParent->getName());
2025-09-12 17:28:47 +08:00
if(pLine)
establishConnection(pSrc,pTarget,pLine,ModelFunctionType::EditorModel);
}
2025-10-21 18:46:51 +08:00
bindId.insert(nType,uId);
2025-11-14 19:31:09 +08:00
if(pParent){
pParent->addSubList(qMakePair(0,lineId));
}
2025-09-12 17:28:47 +08:00
}
}
2025-09-05 17:30:07 +08:00
}
}
2025-09-19 18:11:28 +08:00
else if(compo.nBindType == 3){ //关联变压器
for(auto& pItem:_previewItem){
auto pro = pItem->getProperty();
if(pro){
QString sName = pro->name();
2025-10-21 18:46:51 +08:00
QUuid uId = pro->uuid();
int nType = pro->type();
2025-09-19 18:11:28 +08:00
if(sName == compo.sBindParent){ //判断变压器名
GraphicsBaseModelItem* pSrc = _previewItem.value(compo.uid);
GraphicsBaseModelItem* pTarget = pItem;
2025-11-14 19:31:09 +08:00
QString strCable = "cable_"+QString::number(_cableCount++);
QUuid lineId;
2025-09-19 18:11:28 +08:00
auto pLineData = TopologyManager::instance().ifConnection(pSrc->itemId().toString(),pTarget->itemId().toString(),ModelFunctionType::EditorModel); //判断两个item是否有连接
if(pLineData != nullptr){
2025-11-14 19:31:09 +08:00
lineId = QUuid(pLineData->id());
if(!_previewItem.contains(lineId)){ //connectdata已存在item未绘制
auto pLine = generateLine(lineId,strCable,1); //重新绘制
2025-09-19 18:11:28 +08:00
if(pLine){
if(nTypeTransCon == 2)
establishConnection(pSrc,pTarget,pLine,ModelFunctionType::EditorModel,2,compo.nBindPara);
else
establishConnection(pSrc,pTarget,pLine,ModelFunctionType::EditorModel,nTypeTransCon,nPos);
}
}
else{ //已绘制,略过
}
}
else{ //connectdata不存在新建
2025-11-14 19:31:09 +08:00
lineId = QUuid::createUuid();
auto pLine = generateLine(lineId,strCable,1);
2025-09-19 18:11:28 +08:00
if(pLine){
if(nTypeTransCon == 2)
establishConnection(pSrc,pTarget,pLine,ModelFunctionType::EditorModel,2,compo.nBindPara);
else
establishConnection(pSrc,pTarget,pLine,ModelFunctionType::EditorModel,nTypeTransCon,nPos);
}
}
2025-10-21 18:46:51 +08:00
bindId.insert(nType,uId);
2025-11-14 19:31:09 +08:00
if(pParent){
pParent->addSubList(qMakePair(0,lineId));
}
2025-09-19 18:11:28 +08:00
}
}
}
}
2025-09-05 17:30:07 +08:00
}
2025-10-21 18:46:51 +08:00
return bindId;
2025-09-05 17:30:07 +08:00
}
2025-10-17 18:14:44 +08:00
void DiagramEditorModel::clearCompoDir(QMap<QString,DiagramEditorRouteInfo>& data,QMap<QString,DiagramEditorComponentInfo>& compos,int nSource)
2025-09-05 17:30:07 +08:00
{
2025-10-17 18:14:44 +08:00
for(auto &routeInfo:data){
routeInfo.lstOrder.clear();
routeInfo.lstReverse.clear();
for(auto &compo:routeInfo.lstCompo){
compo.nUsedDirection = 0;
auto pItemName = getNameItem(compo.sName,nSource);
if(pItemName){ //手动清空item数据
int nVal = pItemName->data().toInt();
pItemName->setData(QString::number(0)); //在公用模型中更新设备方向占用(重要)
//pItemName->setData(QPoint(0,0),Qt::UserRole+2); //设置相对位置
pItemName->setData(0,Qt::UserRole+5); //旋转
2025-09-26 18:50:21 +08:00
}
}
2025-10-17 18:14:44 +08:00
for(auto &compoInfo:compos){
compoInfo.nUsedDirection = 0;
compoInfo.nRotate = 0;
}
}
/*for(auto &routeInfo:data){
routeInfo.lstOrder.clear();
routeInfo.lstReverse.clear();
for(auto &compo:routeInfo.lstCompo){
compo.nUsedDirection = 0;
2025-09-26 18:50:21 +08:00
}
}
2025-10-17 18:14:44 +08:00
for(auto &compoInfo:compos){
compoInfo.nUsedDirection = 0;
compoInfo.nRotate = 0;
}*/
}
QRectF DiagramEditorModel::updateTarget(QMap<QString,DiagramEditorRouteInfo>& data,QMap<QString,DiagramEditorComponentInfo>& compos,int nLayout,int nSource,bool saveToModel)
{
QRectF recBounding; //包含所有元件的矩形
auto& mapRoute = data;
QString sMainRoute;
2025-09-12 17:28:47 +08:00
bool hasMain = false;
for(auto& route:mapRoute){
if(route.bMainRoute == true){
2025-09-05 17:30:07 +08:00
sMainRoute = route.sRouteName;
2025-09-12 17:28:47 +08:00
hasMain = true;
}
}
if(!hasMain){ //没设置主线将最长设为主线
int nCount = 0;
for(auto& route:mapRoute){ //寻找包含设备最多的线路
if(nCount < route.lstCompo.count()){
nCount = route.lstCompo.count();
sMainRoute = route.sRouteName;
route.bMainRoute = true;
}
2025-09-05 17:30:07 +08:00
}
}
int nMainDir = nLayout/10; //主朝向倾向 8421上下左右
int nSubDir = nLayout%10; //次朝向倾向 8421
if(nMainDir == 4 || nMainDir == 8){ //竖直
auto& maoCompo = mapRoute[sMainRoute].lstCompo; //假设竖直情况下上下等分为nSeg段 假设主线路水平居中
int nSeg = maoCompo.size()*0.5;
int nSegIndex = 0;
if(nMainDir == 4) //正向从负半加到正半
nSegIndex = -nSeg; //计数器计算deltaY
else
nSegIndex = nSeg; //反向从正半减到负半
for(int i = 0;i < maoCompo.size();++i){ //优先遍历主线路,构建主体结构
int nDir = 0;
if(i == 0){ //队首
maoCompo[i].nUsedDirection |= nMainDir; //默认向下,队首单向下(单线路记录,不可作为跨线判断依据)
nDir = nMainDir;
}
else if(i == maoCompo.size()-1){
maoCompo[i].nUsedDirection |= 12-nMainDir; //队尾单向上(单线路记录,不可作为跨线判断依据)
nDir = 12-nMainDir;
}
else{
maoCompo[i].nUsedDirection |= 12; //其余向上向下都被占用(单线路记录,不可作为跨线判断依据)
nDir = 12;
}
int deltaY = nSegIndex*g_nVDiagramSpacing;
2025-09-26 18:50:21 +08:00
int rotate = 0;
if(nMainDir == 4)
rotate = 0;
else
rotate = 180;
if(saveToModel){
auto pItemName = getNameItem(maoCompo[i].sName,nSource);
if(pItemName){
int nVal = pItemName->data().toInt();
pItemName->setData(QString::number(nVal |= nDir)); //在公用模型中更新设备方向占用(重要)
pItemName->setData(QPoint(0,deltaY),Qt::UserRole+2); //设置相对位置
maoCompo[i].nRotate = rotate;
pItemName->setData(rotate,Qt::UserRole+5);
2025-09-12 17:28:47 +08:00
}
2025-09-26 18:50:21 +08:00
}
else{
if(compos.contains(maoCompo[i].sName)){
auto &compInfo = compos[maoCompo[i].sName];
compInfo.nUsedDirection |= nDir;
compInfo.deltaPos = QPoint(0,deltaY);
maoCompo[i].nRotate = rotate;
compInfo.nRotate = rotate;
2025-09-12 17:28:47 +08:00
}
2025-09-05 17:30:07 +08:00
}
2025-09-26 18:50:21 +08:00
2025-09-05 17:30:07 +08:00
if(nMainDir == 8)
nSegIndex -= 1;
else
nSegIndex += 1;
}
for(auto& route:mapRoute){ //遍历主线路之外的线路
if(route.sRouteName == sMainRoute){
continue;
}
if(!route.lstCompo.isEmpty()){ //拆分线路为以节点为首
2025-09-26 18:50:21 +08:00
if(saveToModel){
auto pItemFirst = getNameItem(route.lstCompo.first().sName,nSource);
int nFirstVal = pItemFirst->data().toInt();
auto pItemLast = getNameItem(route.lstCompo.last().sName,nSource);
int nLastVal = pItemLast->data().toInt();
if(nFirstVal != 0){ //首位为节点
route.lstOrder = route.lstCompo;
2025-09-05 17:30:07 +08:00
}
2025-09-26 18:50:21 +08:00
else if(nLastVal != 0){ //末位为节点
for (auto it = route.lstCompo.rbegin(); it != route.lstCompo.rend(); ++it) {
route.lstReverse.append(*it);
2025-09-05 17:30:07 +08:00
}
}
2025-09-26 18:50:21 +08:00
else{ //节点在中间
int nIndex = 0;
for(int i = 0;i < route.lstCompo.size();++i){
auto pItem = getNameItem(route.lstCompo[i].sName,nSource);
if(pItem){
int nVal = pItem->data().toInt();
if(nVal != 0){
nIndex = i;
break;
}
}
}
2025-09-05 17:30:07 +08:00
2025-09-26 18:50:21 +08:00
for(int i = nIndex;i >= 0;--i){
route.lstReverse.append(route.lstCompo[i]);
}
for(int i = nIndex;i < route.lstCompo.size();++i){
route.lstOrder.append(route.lstCompo[i]);
}
2025-09-05 17:30:07 +08:00
}
2025-09-26 18:50:21 +08:00
}
else{
if(compos.contains(route.lstCompo.first().sName) && compos.contains(route.lstCompo.last().sName)){
auto compoFirst = compos[route.lstCompo.first().sName];
int nFirstVal = compoFirst.nUsedDirection;
auto compoLast = compos[route.lstCompo.last().sName];
int nLastVal = compoLast.nUsedDirection;
if(nFirstVal != 0){ //首位为节点
route.lstOrder = route.lstCompo;
}
else if(nLastVal != 0){ //末位为节点
for (auto it = route.lstCompo.rbegin(); it != route.lstCompo.rend(); ++it) {
route.lstReverse.append(*it);
}
}
else{ //节点在中间
int nIndex = 0;
for(int i = 0;i < route.lstCompo.size();++i){
if(compos.contains(route.lstCompo[i].sName)){
auto compo = compos[route.lstCompo[i].sName];
int nVal = compo.nUsedDirection;
if(nVal != 0){
nIndex = i;
break;
}
}
}
2025-09-05 17:30:07 +08:00
2025-09-26 18:50:21 +08:00
for(int i = nIndex;i >= 0;--i){
route.lstReverse.append(route.lstCompo[i]);
}
for(int i = nIndex;i < route.lstCompo.size();++i){
route.lstOrder.append(route.lstCompo[i]);
}
}
2025-09-05 17:30:07 +08:00
}
}
}
int nOrderFirstDeltaY = 0; //首节点y偏移量(假设后续节点与头节点水平)
int nXOrderIndex = 1; //横向计数
int nOrderPolarity = 1; //方向 1右 -1左
if(route.lstOrder.size() > 1){
for(int i = 0;i < route.lstOrder.size()-1;++i){ //遍历以节点为首的队列
2025-09-26 18:50:21 +08:00
if(saveToModel){
auto pItem = getNameItem(route.lstOrder[i].sName,nSource);
int nVal = pItem->data().toInt();
QPoint deltaP = pItem->data(Qt::UserRole+2).toPoint();
auto pNextItem = getNameItem(route.lstOrder[i+1].sName,nSource); //下一个item
nOrderFirstDeltaY = deltaP.y();
int nNextVal = pNextItem->data().toInt();
if(i == 0){ //首节点
if(((nVal & 2) == 1) && ((nVal & 1) == 1)){
qDebug()<<QString("point %1 full of connection").arg(route.lstOrder[i].sName);
}
else if((nVal & 2) == 1){
//左被占用,右空
pItem->setData(QString::number(nVal | 1));
pNextItem->setData(QString::number(nNextVal | 2)); //同时连接下个点的一侧占用
nOrderPolarity = 1;
route.lstOrder[i+1].nRotate = -90;
pNextItem->setData(-90,Qt::UserRole+5);
}
else if((nVal & 1) == 1){
//右被占用,左空
pItem->setData(QString::number(nVal | 2));
pNextItem->setData(QString::number(nNextVal | 1));
nOrderPolarity = -1;
route.lstOrder[i+1].nRotate = 90;
pNextItem->setData(90,Qt::UserRole+5);
}
else{ //左右都没被占,放到倾向位置
pItem->setData(QString::number(nVal | nSubDir));
pNextItem->setData(QString::number(nNextVal | 3-nSubDir));
if(nSubDir == 1){
nOrderPolarity = 1;
route.lstOrder[i+1].nRotate = -90;
pNextItem->setData(-90,Qt::UserRole+5);
}
else if(nSubDir == 2){
nOrderPolarity = -1;
route.lstOrder[i+1].nRotate = 90;
pNextItem->setData(90,Qt::UserRole+5);
}
}
int deltaX = nXOrderIndex*nOrderPolarity*g_nHDiagramSpacing;
pNextItem->setData(QPoint(deltaX,nOrderFirstDeltaY),Qt::UserRole + 2);
continue;
}
2025-09-05 17:30:07 +08:00
if(((nVal & 2) == 1) && ((nVal & 1) == 1)){
qDebug()<<QString("point %1 full of connection").arg(route.lstOrder[i].sName);
}
else if((nVal & 2) == 1){
//左被占用,右空
pItem->setData(QString::number(nVal | 1));
pNextItem->setData(QString::number(nNextVal | 2)); //同时连接下个点的一侧占用
2025-09-12 17:28:47 +08:00
route.lstOrder[i+1].nRotate = -90;
2025-09-05 17:30:07 +08:00
pNextItem->setData(-90,Qt::UserRole+5);
}
else if((nVal & 1) == 1){
//右被占用,左空
pItem->setData(QString::number(nVal | 2));
pNextItem->setData(QString::number(nNextVal | 1));
2025-09-12 17:28:47 +08:00
route.lstOrder[i+1].nRotate = 90;
2025-09-05 17:30:07 +08:00
pNextItem->setData(90,Qt::UserRole+5);
}
2025-09-26 18:50:21 +08:00
else{ //左右都没被占,放到设定位置
2025-09-05 17:30:07 +08:00
pItem->setData(QString::number(nVal | nSubDir));
pNextItem->setData(QString::number(nNextVal | 3-nSubDir));
if(nSubDir == 1){
2025-09-12 17:28:47 +08:00
route.lstOrder[i+1].nRotate = -90;
2025-09-05 17:30:07 +08:00
pNextItem->setData(-90,Qt::UserRole+5);
}
2025-09-12 17:28:47 +08:00
else if(nSubDir == 2){
route.lstOrder[i+1].nRotate = 90;
pNextItem->setData(90,Qt::UserRole+5);
}
2025-09-05 17:30:07 +08:00
}
int deltaX = nXOrderIndex*nOrderPolarity*g_nHDiagramSpacing;
pNextItem->setData(QPoint(deltaX,nOrderFirstDeltaY),Qt::UserRole + 2);
2025-09-26 18:50:21 +08:00
nXOrderIndex += 1;
2025-09-05 17:30:07 +08:00
}
2025-09-26 18:50:21 +08:00
else{
if(compos.contains(route.lstOrder[i].sName) && compos.contains(route.lstOrder[i+1].sName)){
auto &compo = compos[route.lstOrder[i].sName];
auto &compoNext = compos[route.lstOrder[i+1].sName];
int nVal = compo.nUsedDirection;
QPoint deltaP = compo.deltaPos;
nOrderFirstDeltaY = deltaP.y();
int nNextVal = compoNext.nUsedDirection;
if(i == 0){ //首节点
if(((nVal & 2) == 1) && ((nVal & 1) == 1)){
qDebug()<<QString("point %1 full of connection").arg(route.lstOrder[i].sName);
}
else if((nVal & 2) == 1){
//左被占用,右空
compo.nUsedDirection |= 1;
compoNext.nUsedDirection |= 2; //同时连接下个点的一侧占用
nOrderPolarity = 1;
route.lstOrder[i+1].nRotate = -90;
compoNext.nRotate = -90;
}
else if((nVal & 1) == 1){
//右被占用,左空
compo.nUsedDirection |= 2;
compoNext.nUsedDirection |= 1;
nOrderPolarity = -1;
route.lstOrder[i+1].nRotate = 90;
compoNext.nRotate = 90;
}
else{ //左右都没被占,放到倾向位置
compo.nUsedDirection |= nSubDir;
compoNext.nUsedDirection |= 3-nSubDir;
if(nSubDir == 1){
nOrderPolarity = 1;
route.lstOrder[i+1].nRotate = -90;
compoNext.nRotate = -90;
}
else if(nSubDir == 2){
nOrderPolarity = -1;
route.lstOrder[i+1].nRotate = 90;
compoNext.nRotate = 90;
}
}
int deltaX = nXOrderIndex*nOrderPolarity*g_nHDiagramSpacing;
compoNext.deltaPos = QPoint(deltaX,nOrderFirstDeltaY);
continue;
}
2025-09-05 17:30:07 +08:00
2025-09-26 18:50:21 +08:00
if(((nVal & 2) == 1) && ((nVal & 1) == 1)){
qDebug()<<QString("point %1 full of connection").arg(route.lstOrder[i].sName);
}
else if((nVal & 2) == 1){
//左被占用,右空
compo.nUsedDirection |= 1;
compoNext.nUsedDirection |= 2; //同时连接下个点的一侧占用
route.lstOrder[i+1].nRotate = -90;
compoNext.nRotate = -90;
}
else if((nVal & 1) == 1){
//右被占用,左空
compo.nUsedDirection |= 2;
compoNext.nUsedDirection |= 1;
route.lstOrder[i+1].nRotate = 90;
compoNext.nRotate = 90;
}
else{ //左右都没被占,放到设定位置
compo.nUsedDirection |= nSubDir;
compoNext.nUsedDirection |= 3-nSubDir;
if(nSubDir == 1){
route.lstOrder[i+1].nRotate = -90;
compoNext.nRotate = -90;
}
else if(nSubDir == 2){
route.lstOrder[i+1].nRotate = 90;
compoNext.nRotate = 90;
}
}
int deltaX = nXOrderIndex*nOrderPolarity*g_nHDiagramSpacing;
compoNext.deltaPos = QPoint(deltaX,nOrderFirstDeltaY);
nXOrderIndex += 1;
2025-09-05 17:30:07 +08:00
}
}
}
}
int nReverseFirstDeltaY = 0; //首节点y偏移量(假设后续节点与头节点水平)
int nXReverseIndex = 1; //横向计数
int nReversePolarity = 1; //方向 1右 -1左
if(route.lstReverse.size() > 1){
for(int i = 0;i < route.lstReverse.size()-1;++i){ //遍历以节点为首的队列
2025-09-26 18:50:21 +08:00
if(saveToModel){
auto pItem = getNameItem(route.lstReverse[i].sName,nSource);
int nVal = pItem->data().toInt();
QPoint deltaP = pItem->data(Qt::UserRole+2).toPoint();
auto pNextItem = getNameItem(route.lstReverse[i+1].sName,nSource); //下一个item
nReverseFirstDeltaY = deltaP.y();
int nNextVal = pNextItem->data().toInt();
if(i == 0){ //首节点
if(((nVal & 2) == 1) && ((nVal & 1) == 1)){
qDebug()<<QString("point %1 full of connection").arg(route.lstReverse[i].sName);
}
else if((nVal & 2) == 1){
//左被占用,右空
pItem->setData(QString::number(nVal | 1));
pNextItem->setData(QString::number(nNextVal | 2)); //同时连接下个点的一侧占用
nReversePolarity = 1;
route.lstReverse[i+1].nRotate = -90;
pNextItem->setData(-90,Qt::UserRole+5);
}
else if((nVal & 1) == 1){
//右被占用,左空
pItem->setData(QString::number(nVal | 2));
pNextItem->setData(QString::number(nNextVal | 1));
nReversePolarity = -1;
route.lstReverse[i+1].nRotate = 90;
pNextItem->setData(90,Qt::UserRole+5);
}
else{ //左右都没被占,放到倾向位置
pItem->setData(QString::number(nVal | nSubDir));
pNextItem->setData(QString::number(nNextVal | 3-nSubDir));
if(nSubDir == 1){
nReversePolarity = 1;
route.lstReverse[i+1].nRotate = -90;
pNextItem->setData(-90,Qt::UserRole+5);
}
else if(nSubDir == 2){
nReversePolarity = -1;
route.lstReverse[i+1].nRotate = 90;
pNextItem->setData(90,Qt::UserRole+5);
}
}
int deltaX = nXReverseIndex*nReversePolarity*g_nHDiagramSpacing;
pNextItem->setData(QPoint(deltaX,nReverseFirstDeltaY),Qt::UserRole + 2);
continue;
}
2025-09-05 17:30:07 +08:00
if(((nVal & 2) == 1) && ((nVal & 1) == 1)){
qDebug()<<QString("point %1 full of connection").arg(route.lstReverse[i].sName);
}
else if((nVal & 2) == 1){
//左被占用,右空
pItem->setData(QString::number(nVal | 1));
pNextItem->setData(QString::number(nNextVal | 2)); //同时连接下个点的一侧占用
2025-09-12 17:28:47 +08:00
route.lstReverse[i+1].nRotate = -90;
2025-09-05 17:30:07 +08:00
pNextItem->setData(-90,Qt::UserRole+5);
}
else if((nVal & 1) == 1){
//右被占用,左空
pItem->setData(QString::number(nVal | 2));
pNextItem->setData(QString::number(nNextVal | 1));
2025-09-12 17:28:47 +08:00
route.lstReverse[i+1].nRotate = 90;
2025-09-05 17:30:07 +08:00
pNextItem->setData(90,Qt::UserRole+5);
}
2025-09-26 18:50:21 +08:00
else{ //左右都没被占,放到设定位置
2025-09-05 17:30:07 +08:00
pItem->setData(QString::number(nVal | nSubDir));
pNextItem->setData(QString::number(nNextVal | 3-nSubDir));
if(nSubDir == 1){
2025-09-12 17:28:47 +08:00
route.lstReverse[i+1].nRotate = -90;
pNextItem->setData(-90,Qt::UserRole+5);
2025-09-05 17:30:07 +08:00
}
else if(nSubDir == 2){
2025-09-12 17:28:47 +08:00
route.lstReverse[i+1].nRotate = 90;
pNextItem->setData(90,Qt::UserRole+5);
2025-09-05 17:30:07 +08:00
}
}
int deltaX = nXReverseIndex*nReversePolarity*g_nHDiagramSpacing;
pNextItem->setData(QPoint(deltaX,nReverseFirstDeltaY),Qt::UserRole + 2);
2025-09-26 18:50:21 +08:00
nXReverseIndex += 1;
2025-09-05 17:30:07 +08:00
}
2025-09-26 18:50:21 +08:00
else{
if(compos.contains(route.lstReverse[i].sName) && compos.contains(route.lstReverse[i+1].sName)){
auto &compo = compos[route.lstReverse[i].sName];
auto &compoNext = compos[route.lstReverse[i+1].sName];
int nVal = compo.nUsedDirection;
QPoint deltaP = compo.deltaPos;
nReverseFirstDeltaY = deltaP.y();
int nNextVal = compoNext.nUsedDirection;
if(i == 0){ //首节点
if(((nVal & 2) == 1) && ((nVal & 1) == 1)){
qDebug()<<QString("point %1 full of connection").arg(route.lstReverse[i].sName);
}
else if((nVal & 2) == 1){
//左被占用,右空
compo.nUsedDirection |= 1;
compoNext.nUsedDirection |= 2; //同时连接下个点的一侧占用
nReversePolarity = 1;
route.lstReverse[i+1].nRotate = -90;
compoNext.nRotate = -90;
}
else if((nVal & 1) == 1){
//右被占用,左空
compo.nUsedDirection |= 2;
compoNext.nUsedDirection |= 1;
nReversePolarity = -1;
route.lstReverse[i+1].nRotate = 90;
compoNext.nRotate = 90;
}
else{ //左右都没被占,放到倾向位置
compo.nUsedDirection |= nSubDir;
compoNext.nUsedDirection |= 3-nSubDir;
if(nSubDir == 1){
nReversePolarity = 1;
route.lstReverse[i+1].nRotate = -90;
compoNext.nRotate = -90;
}
else if(nSubDir == 2){
nReversePolarity = -1;
route.lstReverse[i+1].nRotate = 90;
compoNext.nRotate = 90;
}
}
int deltaX = nXReverseIndex*nReversePolarity*g_nHDiagramSpacing;
compoNext.deltaPos = QPoint(deltaX,nOrderFirstDeltaY);
continue;
}
2025-09-05 17:30:07 +08:00
2025-09-26 18:50:21 +08:00
if(((nVal & 2) == 1) && ((nVal & 1) == 1)){
qDebug()<<QString("point %1 full of connection").arg(route.lstReverse[i].sName);
}
else if((nVal & 2) == 1){
//左被占用,右空
compo.nUsedDirection |= 1;
compoNext.nUsedDirection |= 2; //同时连接下个点的一侧占用
route.lstReverse[i+1].nRotate = -90;
compoNext.nRotate = -90;
}
else if((nVal & 1) == 1){
//右被占用,左空
compo.nUsedDirection |= 2;
compoNext.nUsedDirection |= 1;
route.lstReverse[i+1].nRotate = 90;
compoNext.nRotate = 90;
}
else{ //左右都没被占,放到设定位置
compo.nUsedDirection |= nSubDir;
compoNext.nUsedDirection |= 3-nSubDir;
if(nSubDir == 1){
route.lstReverse[i+1].nRotate = -90;
compoNext.nRotate = -90;
}
else if(nSubDir == 2){
route.lstReverse[i+1].nRotate = 90;
compoNext.nRotate = 90;
}
}
int deltaX = nXReverseIndex*nReversePolarity*g_nHDiagramSpacing;
compoNext.deltaPos = QPoint(deltaX,nOrderFirstDeltaY);
nXReverseIndex += 1;
2025-09-05 17:30:07 +08:00
}
}
}
}
}
}
else if(nMainDir == 2 || nMainDir == 1){ //2左1右
auto& maoCompo = mapRoute[sMainRoute].lstCompo; //左右等分为nSeg段 假设主线路水平居中
int nSeg = maoCompo.size()*0.5;
int nSegIndex = 0; //计数器计算deltaY
if(nMainDir == 1) //正向从负半加到正半
nSegIndex = -nSeg; //计数器计算deltaY
else
nSegIndex = nSeg; //反向从正半减到负半
for(int i = 0;i < maoCompo.size();++i){ //优先遍历主线路,构建主体结构
int nDir = 0;
if(i == 0){ //队首
maoCompo[i].nUsedDirection |= 1; //队首向右
nDir = 1;
}
else if(i == maoCompo.size()-1){
maoCompo[i].nUsedDirection |= 2; //队尾单向左(单线路记录,不可作为跨线判断依据)
nDir = 2;
}
else{
maoCompo[i].nUsedDirection |= 3; //其余左右都被占用(单线路记录,不可作为跨线判断依据)
nDir = 3;
}
int deltaX = nSegIndex*g_nHDiagramSpacing;
2025-09-26 18:50:21 +08:00
int rotate = 0;
if(nMainDir == 1)
rotate = -90;
else
rotate = 90;
if(saveToModel){
auto pItemName = getNameItem(maoCompo[i].sName,nSource);
if(pItemName){
int nVal = pItemName->data().toInt();
pItemName->setData(QString::number(nVal |= nDir)); //在公用模型中更新设备方向占用(重要)
pItemName->setData(QPoint(deltaX,0),Qt::UserRole+2); //设置相对位置
maoCompo[i].nRotate = rotate;
pItemName->setData(rotate,Qt::UserRole+5);
2025-09-12 17:28:47 +08:00
}
2025-09-26 18:50:21 +08:00
}
else{
if(compos.contains(maoCompo[i].sName)){
auto &compInfo = compos[maoCompo[i].sName];
compInfo.nUsedDirection |= nDir;
compInfo.deltaPos = QPoint(deltaX,0);
maoCompo[i].nRotate = rotate;
compInfo.nRotate = rotate;
2025-09-12 17:28:47 +08:00
}
2025-09-05 17:30:07 +08:00
}
2025-09-26 18:50:21 +08:00
2025-09-05 17:30:07 +08:00
if(nMainDir == 2)
nSegIndex -= 1;
else
nSegIndex += 1;
}
for(auto& route:mapRoute){ //遍历主线路之外的线路
if(route.sRouteName == sMainRoute){
continue;
}
if(!route.lstCompo.isEmpty()){ //拆分线路为以节点为首
2025-09-26 18:50:21 +08:00
/*auto pItemFirst = getNameItem(route.lstCompo.first().sName,nSource);
2025-09-05 17:30:07 +08:00
int nFirstVal = pItemFirst->data().toInt();
auto pItemLast = getNameItem(route.lstCompo.last().sName,nSource);
int nLastVal = pItemLast->data().toInt();
if(nFirstVal != 0){ //首位为节点
route.lstOrder = route.lstCompo;
}
else if(nLastVal != 0){ //末位为节点
for (auto it = route.lstCompo.rbegin(); it != route.lstCompo.rend(); ++it) {
route.lstReverse.append(*it);
}
}
else{ //节点在中间
int nIndex = 0;
for(int i = 0;i < route.lstCompo.size();++i){
auto pItem = getNameItem(route.lstCompo[i].sName,nSource);
if(pItem){
int nVal = pItem->data().toInt();
if(nVal != 0){
nIndex = i;
break;
}
}
}
for(int i = nIndex;i >= 0;--i){
route.lstReverse.append(route.lstCompo[i]);
}
for(int i = nIndex;i < route.lstCompo.size();++i){
route.lstOrder.append(route.lstCompo[i]);
}
2025-09-26 18:50:21 +08:00
}*/
if(saveToModel){
auto pItemFirst = getNameItem(route.lstCompo.first().sName,nSource);
int nFirstVal = pItemFirst->data().toInt();
auto pItemLast = getNameItem(route.lstCompo.last().sName,nSource);
int nLastVal = pItemLast->data().toInt();
if(nFirstVal != 0){ //首位为节点
route.lstOrder = route.lstCompo;
}
else if(nLastVal != 0){ //末位为节点
for (auto it = route.lstCompo.rbegin(); it != route.lstCompo.rend(); ++it) {
route.lstReverse.append(*it);
}
}
else{ //节点在中间
int nIndex = 0;
for(int i = 0;i < route.lstCompo.size();++i){
auto pItem = getNameItem(route.lstCompo[i].sName,nSource);
if(pItem){
int nVal = pItem->data().toInt();
if(nVal != 0){
nIndex = i;
break;
}
}
}
for(int i = nIndex;i >= 0;--i){
route.lstReverse.append(route.lstCompo[i]);
}
for(int i = nIndex;i < route.lstCompo.size();++i){
route.lstOrder.append(route.lstCompo[i]);
}
}
}
else{
if(compos.contains(route.lstCompo.first().sName) && compos.contains(route.lstCompo.last().sName)){
auto compoFirst = compos[route.lstCompo.first().sName];
int nFirstVal = compoFirst.nUsedDirection;
auto compoLast = compos[route.lstCompo.last().sName];
int nLastVal = compoLast.nUsedDirection;
if(nFirstVal != 0){ //首位为节点
route.lstOrder = route.lstCompo;
}
else if(nLastVal != 0){ //末位为节点
for (auto it = route.lstCompo.rbegin(); it != route.lstCompo.rend(); ++it) {
route.lstReverse.append(*it);
}
}
else{ //节点在中间
int nIndex = 0;
for(int i = 0;i < route.lstCompo.size();++i){
if(compos.contains(route.lstCompo[i].sName)){
auto compo = compos[route.lstCompo[i].sName];
int nVal = compo.nUsedDirection;
if(nVal != 0){
nIndex = i;
break;
}
}
}
for(int i = nIndex;i >= 0;--i){
route.lstReverse.append(route.lstCompo[i]);
}
for(int i = nIndex;i < route.lstCompo.size();++i){
route.lstOrder.append(route.lstCompo[i]);
}
}
}
2025-09-05 17:30:07 +08:00
}
}
int nOrderFirstDeltaX = 0; //首节点x偏移量(假设后续节点与头节点水平相同,纵向分布)
int nYOrderIndex = 1; //总向计数
int nOrderPolarity = 1; //方向 1下 -1上
if(route.lstOrder.size() > 1){
for(int i = 0;i < route.lstOrder.size()-1;++i){ //遍历以节点为首的队列
2025-09-26 18:50:21 +08:00
if(saveToModel){
auto pItem = getNameItem(route.lstOrder[i].sName,nSource);
int nVal = pItem->data().toInt();
QPoint deltaP = pItem->data(Qt::UserRole+2).toPoint();
auto pNextItem = getNameItem(route.lstOrder[i+1].sName,nSource); //下一个item
nOrderFirstDeltaX = deltaP.x();
int nNextVal = pNextItem->data().toInt();
if(i == 0){ //首节点
if(((nVal & 8) == 1) && ((nVal & 4) == 1)){
qDebug()<<QString("point %1 full of connection").arg(route.lstOrder[i].sName);
}
else if((nVal & 8) == 1){
//上被占用,下空
pItem->setData(QString::number(nVal | 4));
pNextItem->setData(QString::number(nNextVal | 8)); //同时连接下个点的一侧占用
nOrderPolarity = 1;
route.lstOrder[i+1].nRotate = 0;
pNextItem->setData(0,Qt::UserRole+5);
}
else if((nVal & 4) == 1){
//下被占用,上空
pItem->setData(QString::number(nVal | 8));
pNextItem->setData(QString::number(nNextVal | 4));
nOrderPolarity = -1;
route.lstOrder[i+1].nRotate = 180;
pNextItem->setData(180,Qt::UserRole+5);
}
else{ //上下都没占,放到设定位置
pItem->setData(QString::number(nVal | nSubDir));
pNextItem->setData(QString::number(nNextVal | 12-nSubDir));
if(nSubDir == 4){
nOrderPolarity = 1;
route.lstOrder[i+1].nRotate = 0;
pNextItem->setData(0,Qt::UserRole+5);
}
else if(nSubDir == 8){
nOrderPolarity = -1;
route.lstOrder[i+1].nRotate = 180;
pNextItem->setData(180,Qt::UserRole+5);
}
}
int deltaY = nYOrderIndex*nOrderPolarity*g_nVDiagramSpacing;
pNextItem->setData(QPoint(nOrderFirstDeltaX,deltaY),Qt::UserRole + 2);
continue;
}
2025-09-05 17:30:07 +08:00
if(((nVal & 8) == 1) && ((nVal & 4) == 1)){
qDebug()<<QString("point %1 full of connection").arg(route.lstOrder[i].sName);
}
else if((nVal & 8) == 1){
//上被占用,下空
pItem->setData(QString::number(nVal | 4));
pNextItem->setData(QString::number(nNextVal | 8)); //同时连接下个点的一侧占用
pNextItem->setData(0,Qt::UserRole+5);
}
else if((nVal & 4) == 1){
//下被占用,上空
pItem->setData(QString::number(nVal | 8));
pNextItem->setData(QString::number(nNextVal | 4));
pNextItem->setData(180,Qt::UserRole+5);
}
2025-09-26 18:50:21 +08:00
else{ //上下都没被占,放到设定位置
2025-09-05 17:30:07 +08:00
pItem->setData(QString::number(nVal | nSubDir));
pNextItem->setData(QString::number(nNextVal | 12-nSubDir));
if(nSubDir == 4){
2025-09-26 18:50:21 +08:00
//nOrderPolarity = 1;
2025-09-12 17:28:47 +08:00
route.lstOrder[i+1].nRotate = 0;
2025-09-05 17:30:07 +08:00
pNextItem->setData(0,Qt::UserRole+5);
}
else if(nSubDir == 8){
2025-09-26 18:50:21 +08:00
//nOrderPolarity = -1;
2025-09-12 17:28:47 +08:00
route.lstOrder[i+1].nRotate = 180;
2025-09-05 17:30:07 +08:00
pNextItem->setData(180,Qt::UserRole+5);
}
}
int deltaY = nYOrderIndex*nOrderPolarity*g_nVDiagramSpacing;
pNextItem->setData(QPoint(nOrderFirstDeltaX,deltaY),Qt::UserRole + 2);
2025-09-26 18:50:21 +08:00
nYOrderIndex += 1;
2025-09-05 17:30:07 +08:00
}
2025-09-26 18:50:21 +08:00
else{
if(compos.contains(route.lstOrder[i].sName) && compos.contains(route.lstOrder[i+1].sName)){
auto &compo = compos[route.lstOrder[i].sName];
auto &compoNext = compos[route.lstOrder[i+1].sName];
int nVal = compo.nUsedDirection;
QPoint deltaP = compo.deltaPos;
nOrderFirstDeltaX = deltaP.x();
int nNextVal = compoNext.nUsedDirection;
if(i == 0){ //首节点
if(((nVal & 8) == 1) && ((nVal & 4) == 1)){
qDebug()<<QString("point %1 full of connection").arg(route.lstOrder[i].sName);
}
else if((nVal & 8) == 1){
//上被占用,下空
compo.nUsedDirection |= 4;
compoNext.nUsedDirection |= 8; //同时连接下个点的一侧占用
nOrderPolarity = 1;
route.lstOrder[i+1].nRotate = 0;
compoNext.nRotate = 0;
}
else if((nVal & 4) == 1){
//下被占用,上空
compo.nUsedDirection |= 8;
compoNext.nUsedDirection |= 4;
nOrderPolarity = -1;
route.lstOrder[i+1].nRotate = 180;
compoNext.nRotate = 180;
}
else{ //上下都没占,放到设定位置
compo.nUsedDirection |= nSubDir;
compoNext.nUsedDirection |= 12-nSubDir;
if(nSubDir == 4){
nOrderPolarity = 1;
route.lstOrder[i+1].nRotate = 0;
compoNext.nRotate = 0;
}
else if(nSubDir == 8){
nOrderPolarity = -1;
route.lstOrder[i+1].nRotate = 180;
compoNext.nRotate = 180;
}
}
int deltaY = nYOrderIndex*nOrderPolarity*g_nVDiagramSpacing;
compoNext.deltaPos = QPoint(nOrderFirstDeltaX,deltaY);
continue;
}
2025-09-05 17:30:07 +08:00
2025-09-26 18:50:21 +08:00
if(((nVal & 8) == 1) && ((nVal & 4) == 1)){
qDebug()<<QString("point %1 full of connection").arg(route.lstOrder[i].sName);
}
else if((nVal & 8) == 1){
//上被占用,下空
compo.nUsedDirection |= 4;
compoNext.nUsedDirection |= 8; //同时连接下个点的一侧占用
compoNext.nRotate = 0;
}
else if((nVal & 4) == 1){
//下被占用,上空
compo.nUsedDirection |= 8;
compoNext.nUsedDirection |= 4;
compoNext.nRotate = 180;
}
else{ //上下都没被占,放到设定位置
compo.nUsedDirection |= nSubDir;
compoNext.nUsedDirection |= 12-nSubDir;
if(nSubDir == 4){
route.lstOrder[i+1].nRotate = 0;
compoNext.nRotate = 0;
}
else if(nSubDir == 8){
route.lstOrder[i+1].nRotate = 180;
compoNext.nRotate = 180;
}
}
int deltaY = nYOrderIndex*nOrderPolarity*g_nVDiagramSpacing;
compoNext.deltaPos = QPoint(nOrderFirstDeltaX,deltaY);
nYOrderIndex += 1;
2025-09-05 17:30:07 +08:00
}
}
}
}
int nReverseFirstDeltaX = 0; //首节点X偏移量(假设后续节点与头节点垂直分布)
int nYReverseIndex = 1; //纵向计数
int nReversePolarity = 1; //方向 1下 -1上
if(route.lstReverse.size() > 1){
for(int i = 0;i < route.lstReverse.size()-1;++i){ //遍历以节点为首的队列
2025-09-26 18:50:21 +08:00
if(saveToModel){
auto pItem = getNameItem(route.lstReverse[i].sName,nSource);
int nVal = pItem->data().toInt();
QPoint deltaP = pItem->data(Qt::UserRole+2).toPoint();
auto pNextItem = getNameItem(route.lstReverse[i+1].sName,nSource); //下一个item
nReverseFirstDeltaX = deltaP.x();
int nNextVal = pNextItem->data().toInt();
if(i == 0){ //首节点
if(((nVal & 8) == 1) && ((nVal & 4) == 1)){
qDebug()<<QString("point %1 full of connection").arg(route.lstReverse[i].sName);
}
else if((nVal & 8) == 1){
//上被占用,下空
pItem->setData(QString::number(nVal | 4));
pNextItem->setData(QString::number(nNextVal | 8)); //同时连接下个点的一侧占用
nReversePolarity = 1;
route.lstReverse[i+1].nRotate = 0;
pNextItem->setData(0,Qt::UserRole+5);
}
else if((nVal & 1) == 4){
//下被占用,上空
pItem->setData(QString::number(nVal | 8));
pNextItem->setData(QString::number(nNextVal | 4));
nReversePolarity = -1;
route.lstReverse[i+1].nRotate = 180;
pNextItem->setData(180,Qt::UserRole+5);
}
else{ //上下都没被占,放到设定位置
pItem->setData(QString::number(nVal | nSubDir));
pNextItem->setData(QString::number(nNextVal | 12-nSubDir));
if(nSubDir == 4){
nReversePolarity = 1;
route.lstReverse[i+1].nRotate = 0;
pNextItem->setData(0,Qt::UserRole+5);
}
else if(nSubDir == 8){
nReversePolarity = -1;
route.lstReverse[i+1].nRotate = 180;
pNextItem->setData(180,Qt::UserRole+5);
}
}
int deltaY = nYReverseIndex*nReversePolarity*g_nVDiagramSpacing;
pNextItem->setData(QPoint(nReverseFirstDeltaX,deltaY),Qt::UserRole + 2);
continue;
}
2025-09-05 17:30:07 +08:00
if(((nVal & 8) == 1) && ((nVal & 4) == 1)){
2025-09-26 18:50:21 +08:00
qDebug()<<QString("point %1 full of connection").arg(route.lstOrder[i].sName);
2025-09-05 17:30:07 +08:00
}
else if((nVal & 8) == 1){
//上被占用,下空
pItem->setData(QString::number(nVal | 4));
pNextItem->setData(QString::number(nNextVal | 8)); //同时连接下个点的一侧占用
2025-09-12 17:28:47 +08:00
route.lstReverse[i+1].nRotate = 0;
2025-09-05 17:30:07 +08:00
pNextItem->setData(0,Qt::UserRole+5);
}
2025-09-26 18:50:21 +08:00
else if((nVal & 4) == 1){
2025-09-05 17:30:07 +08:00
//下被占用,上空
pItem->setData(QString::number(nVal | 8));
pNextItem->setData(QString::number(nNextVal | 4));
2025-09-12 17:28:47 +08:00
route.lstReverse[i+1].nRotate = 180;
2025-09-05 17:30:07 +08:00
pNextItem->setData(180,Qt::UserRole+5);
}
2025-09-26 18:50:21 +08:00
else{ //上下都没被占,默认放到下边
2025-09-05 17:30:07 +08:00
pItem->setData(QString::number(nVal | nSubDir));
pNextItem->setData(QString::number(nNextVal | 12-nSubDir));
if(nSubDir == 4){
2025-09-26 18:50:21 +08:00
//nReversePolarity = 1;
2025-09-12 17:28:47 +08:00
route.lstReverse[i+1].nRotate = 0;
2025-09-05 17:30:07 +08:00
pNextItem->setData(0,Qt::UserRole+5);
}
else if(nSubDir == 8){
2025-09-26 18:50:21 +08:00
//nReversePolarity = -1;
2025-09-12 17:28:47 +08:00
route.lstReverse[i+1].nRotate = 180;
2025-09-05 17:30:07 +08:00
pNextItem->setData(180,Qt::UserRole+5);
}
}
int deltaY = nYReverseIndex*nReversePolarity*g_nVDiagramSpacing;
pNextItem->setData(QPoint(nReverseFirstDeltaX,deltaY),Qt::UserRole + 2);
2025-09-26 18:50:21 +08:00
nYReverseIndex += 1;
2025-09-05 17:30:07 +08:00
}
2025-09-26 18:50:21 +08:00
else{
if(compos.contains(route.lstReverse[i].sName) && compos.contains(route.lstReverse[i+1].sName)){
auto &compo = compos[route.lstReverse[i].sName];
auto &compoNext = compos[route.lstReverse[i+1].sName];
int nVal = compo.nUsedDirection;
QPoint deltaP = compo.deltaPos;
nReverseFirstDeltaX = deltaP.x();
int nNextVal = compoNext.nUsedDirection;
if(i == 0){ //首节点
if(((nVal & 8) == 1) && ((nVal & 4) == 1)){
qDebug()<<QString("point %1 full of connection").arg(route.lstReverse[i].sName);
}
else if((nVal & 8) == 1){
//上被占用,下空
compo.nUsedDirection |= 4;
compoNext.nUsedDirection |= 8; //同时连接下个点的一侧占用
nReversePolarity = 1;
route.lstReverse[i+1].nRotate = 0;
compoNext.nRotate = 0;
}
else if((nVal & 1) == 4){
//下被占用,上空
compo.nUsedDirection |= 8;
compoNext.nUsedDirection |= 4;
nReversePolarity = -1;
route.lstReverse[i+1].nRotate = 180;
compoNext.nRotate = 180;
}
else{ //上下都没被占,放到设定位置
compo.nUsedDirection |= nSubDir;
compoNext.nUsedDirection |= 12-nSubDir;
if(nSubDir == 4){
nReversePolarity = 1;
route.lstReverse[i+1].nRotate = 0;
compoNext.nRotate = 0;
}
else if(nSubDir == 8){
nReversePolarity = -1;
route.lstReverse[i+1].nRotate = 180;
compoNext.nRotate = 180;
}
}
int deltaY = nYReverseIndex*nReversePolarity*g_nVDiagramSpacing;
compoNext.deltaPos = QPoint(nReverseFirstDeltaX,deltaY);
continue;
}
2025-09-05 17:30:07 +08:00
2025-09-26 18:50:21 +08:00
if(((nVal & 8) == 1) && ((nVal & 4) == 1)){
qDebug()<<QString("point %1 full of connection").arg(route.lstOrder[i].sName);
}
else if((nVal & 8) == 1){
//上被占用,下空
compo.nUsedDirection |= 4;
compoNext.nUsedDirection |= 8; //同时连接下个点的一侧占用
route.lstReverse[i+1].nRotate = 0;
compoNext.nRotate = 0;
}
else if((nVal & 4) == 1){
//下被占用,上空
compo.nUsedDirection |= 8;
compoNext.nUsedDirection |= 4;
route.lstReverse[i+1].nRotate = 180;
compoNext.nRotate = 180;
}
else{ //上下都没被占,默认放到下边
compo.nUsedDirection |= nSubDir;
compoNext.nUsedDirection |= 12-nSubDir;
if(nSubDir == 4){
//nReversePolarity = 1;
route.lstReverse[i+1].nRotate = 0;
compoNext.nRotate = 0;
}
else if(nSubDir == 8){
//nReversePolarity = -1;
route.lstReverse[i+1].nRotate = 180;
compoNext.nRotate = 180;
}
}
int deltaY = nYReverseIndex*nReversePolarity*g_nVDiagramSpacing;
compoNext.deltaPos = QPoint(nReverseFirstDeltaX,deltaY);
nYReverseIndex += 1;
2025-09-05 17:30:07 +08:00
}
}
}
}
}
}
2025-09-26 18:50:21 +08:00
if(!saveToModel){ //保存到模型时由scene获取recBounding
QList<QPointF> points;
for(auto &info:compos){
if(info.nUsedDirection != 0){ //该元件被使用
QPointF pDelta = info.deltaPos; //todo:考虑元件宽度
points.append(pDelta);
}
}
if(!points.empty()){
qreal minX = points[0].x();
2025-10-17 18:14:44 +08:00
qreal maxX = points[0].x()+g_nCompoWidth;
2025-09-26 18:50:21 +08:00
qreal minY = points[0].y();
2025-10-17 18:14:44 +08:00
qreal maxY = points[0].y()+g_nCompoHeight;
2025-09-26 18:50:21 +08:00
for (const QPointF& point : points) {
minX = qMin(minX, point.x());
2025-10-17 18:14:44 +08:00
maxX = qMax(maxX, point.x()+g_nCompoWidth);
2025-09-26 18:50:21 +08:00
minY = qMin(minY, point.y());
2025-10-17 18:14:44 +08:00
maxY = qMax(maxY, point.y()+g_nCompoHeight);
2025-09-26 18:50:21 +08:00
}
recBounding = QRectF(QPointF(minX, minY), QPointF(maxX, maxY));
}
}
return recBounding;
2025-09-12 17:28:47 +08:00
}
2025-09-05 17:30:07 +08:00
2025-11-14 19:31:09 +08:00
void DiagramEditorModel::bulidAndLinkComponent(QList<DiagramEditorComponentInfo> lst,QMap<QString,DiagramEditorComponentInfo> components,DiagramEditorBaseBlock* pParent)
2025-09-12 17:28:47 +08:00
{
for(int i = 0;i < lst.size()-1;++i){
auto item1 = lst[i];
auto item2 = lst[i+1];
2025-09-19 18:11:28 +08:00
auto info1 = components.value(item1.sName);
auto info2 = components.value(item2.sName);
if(_previewItem.contains(info1.uid) && _previewItem.contains(info2.uid)){
GraphicsBaseModelItem* p1 = _previewItem.value(info1.uid);
GraphicsBaseModelItem* p2 = _previewItem.value(info2.uid);
2025-11-14 19:31:09 +08:00
QString strCable = "cable_"+QString::number(_cableCount++);
QUuid lineId;
2025-09-19 18:11:28 +08:00
auto pLineData = TopologyManager::instance().ifConnection(info1.uid.toString(),info2.uid.toString(),ModelFunctionType::EditorModel); //判断两个item是否有连接
2025-09-12 17:28:47 +08:00
if(pLineData != nullptr){
2025-11-14 19:31:09 +08:00
lineId = QUuid(pLineData->id());
if(_previewItem.contains(lineId)) //已绘制
2025-09-26 18:50:21 +08:00
continue;
2025-11-14 19:31:09 +08:00
if(!_previewItem.contains(lineId)){ //connectdata已存在item未绘制
auto pLine = generateLine(lineId,strCable,1,pParent->getName()); //重新绘制
2025-09-12 17:28:47 +08:00
if(pLine)
establishConnection(p1,p2,pLine,ModelFunctionType::EditorModel);
}
else{ //已绘制,略过
}
}
else{ //connectdata不存在新建
2025-11-14 19:31:09 +08:00
lineId = QUuid::createUuid();
auto pLine = generateLine(lineId,strCable,1,pParent->getName());
2025-09-12 17:28:47 +08:00
if(pLine)
establishConnection(p1,p2,pLine,ModelFunctionType::EditorModel);
}
2025-11-14 19:31:09 +08:00
if(pParent){
pParent->addSubList(qMakePair(0,lineId));
}
2025-09-12 17:28:47 +08:00
}
}
2025-09-05 17:30:07 +08:00
}
2025-09-19 18:11:28 +08:00
QList<DiagramEditorComponentInfo> DiagramEditorModel::getRouteItemInfoList(QMap<QString,DiagramEditorComponentInfo> mapCompo,QMap<QString,DiagramEditorRouteInfo> mapRoute)
{
QList<DiagramEditorComponentInfo> lst;
for(auto& route:mapRoute){ //总路线中包含主路,首次生成主路
for(auto& compo:route.lstCompo){ //首先生成设备
auto info = mapCompo.value(compo.sName);
bool exist = false;
for(auto& inf:lst){
if(inf == info){
exist = true;
break;
}
}
if(!exist){
lst.append(info);
}
}
}
return lst;
}
2025-10-24 21:11:07 +08:00
QByteArray DiagramEditorModel::getWizardInfo()
{
DiagramEditorProjectInfo wizaInfo = _pWizard->getCurPara();
wizaInfo.sName = _pPanel->getProjectName();
wizaInfo.uid = _pPanel->getUuid();
QByteArray data = serializeWizardData(wizaInfo);
return data;
}
void DiagramEditorModel::setWizardInfo(const QByteArray& btye)
{
DiagramEditorProjectInfo info = deserializeWizardData(btye);
_pWizard->setPara(info);
}
QByteArray DiagramEditorModel::serializeWizardData(const DiagramEditorProjectInfo &data)
{
QByteArray byteArray;
QDataStream stream(&byteArray, QIODevice::WriteOnly);
stream << data; // 调用重载的操作符
return byteArray;
}
DiagramEditorProjectInfo DiagramEditorModel::deserializeWizardData(const QByteArray &byteArray)
{
QDataStream stream(byteArray);
DiagramEditorProjectInfo data;
stream >> data; // 调用重载的操作符
return data;
}
2025-11-14 19:31:09 +08:00
DiagramEditorBaseBlock* DiagramEditorModel::getBlockDataByName(QString sName,EditorItemType typ)
{
auto lstBlock = _pPanel->getBlockItems();
for(auto& block:lstBlock){
if(block->getName() == sName){
if(block->getType() == typ){
return block->getBlockData().data();
}
}
}
return nullptr;
}