DiagramDesigner/diagramCavas/source/graphicsDataModel/diagramEditorModel.cpp

1163 lines
52 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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"
#include "diagramEditor/diagramEditorBaseBlock.h"
#include "diagramEditor/editItems.h"
#include "diagramEditor/editPanel.h"
DiagramEditorModel::DiagramEditorModel()
:_pCurBayRoute(nullptr)
,_pCurBayComponent(nullptr)
,_pCurPreviewScene(nullptr)
,_pCurTransComponent(nullptr)
,_pPanel(nullptr)
{
}
DiagramEditorModel::~DiagramEditorModel()
{
}
bool DiagramEditorModel::addPreviewItem(QUuid uuid,GraphicsBaseModelItem* pItem,int mode)
{
if(mode == 0){
if(_tempItem.contains(uuid))
return false;
else
{
_tempItem.insert(uuid,pItem);
return true;
}
}
else if(mode == 1){
if(_previewItem.contains(uuid))
return false;
else
{
_previewItem.insert(uuid,pItem);
return true;
}
}
return false;
}
DiagramEditorItemProperty* DiagramEditorModel::addPreviewData(QUuid id,int type,QString name,QString metaName,QString sBlock,int mode)
{
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);
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;
default:
break;
}
QPointF f = port->pos();
TopologyManager::instance().createTerminal(pEntity->id(),terType,"",port->pos(),port->getId(),funType);
}
}
}
void DiagramEditorModel::generateTempBay()
{
generateItemByModel(_pCurBayRoute);
}
GraphicsBaseModelItem* DiagramEditorModel::generateComponent(QUuid uid,QString sName,int nCategory,int nType,QPointF pos,int nRotate,int mode)
{
GraphicsBaseModelItem* pItem = nullptr;
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);
pItem = pBus;
pItem->setItemType(GIT_baseBus);
}
else if(nType == 2){ //异步电动机
}
else if(nType == 3){ //断路器
byte = DataBase::GetInstance()->ModelType()[nType].icon; //注意modelType表与componentType表不一致
auto pBreaker = new ElectricBaseModelSvgItem(QRect(-15, -15, 30, 30));
pBreaker->loadSvg(byte);
pItem = pBreaker;
pItem->setItemType(GIT_baseBreaker);
pItem->initialPortsByDatabase(3);
}
else if(nType == 4){ //电缆
}
else if(nType == 5){ //电流互感器
byte = DataBase::GetInstance()->ModelType()[nType].icon; //注意modelType表与componentType表不一致
auto pCt= new ElectricBaseModelSvgItem(QRect(-10, -10, 20, 20));
pCt->loadSvg(byte);
pItem = pCt;
pItem->setItemType(GIT_baseCT);
pItem->initialPortsByDatabase(4);
}
else if(nType == 6){ //电压互感器
byte = DataBase::GetInstance()->ModelType()[nType].icon; //注意modelType表与componentType表不一致
auto pPt = new ElectricBaseModelSvgItem(QRect(-25, -25, 50, 50));
pPt->loadSvg(byte);
pItem = pPt;
pItem->setItemType(GIT_basePT);
pItem->initialPortsByDatabase(5);
}
else if(nType == 7){ //隔离开关
byte = DataBase::GetInstance()->ModelType()[nType].icon; //注意modelType表与componentType表不一致
auto pDs = new ElectricBaseModelSvgItem(QRect(-15, -15, 30, 30));
pDs->loadSvg(byte);
pItem = pDs;
pItem->setItemType(GIT_baseDS);
pItem->initialPortsByDatabase(9);
}
else if(nType == 8){ //接地开关
}
else if(nType == 9){ //快速接地开关
}
else if(nType == 10){ //双掷接地隔离开关
}
else if(nType == 11){ //带电指示器
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);
pItem->initialPortsByDatabase(11);
}
else if(nType == 12){ //避雷器
}
else if(nType == 13){ //电缆出线套筒
}
else if(nType == 14){ //电缆端
}
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);
pItem->initialPortsByDatabase(15);
}
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);
pItem->initialPortsByDatabase(16);
}
}
else if(nCategory == 1){
if(nType == 1){ //节点
pItem = new ElectricBaseModelPortItem();
pItem->setItemType(GIT_baseNode);
}
}
if(pItem){
pItem->setItemId(uid);
pItem->setRotation(nRotate);
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){
pData = addPreviewData(uid,0,sName,"node","",mode);
}
else if(nCategory == 0){ //设备
pData = addPreviewData(uid,nType,sName,DataBase::GetInstance()->ModelType()[nType].modelType,"",mode);
pData->setGraphicsType(pItem->getItemType());
}
if(pData)
{
pItem->setProperty(pData);
createTopoTerminalsByItem(pItem,typ);
pData->setDataChanged(true); //数据状态改变
}
addPreviewItem(uid,pItem,mode);
_pCurPreviewScene->addItem(pItem);
pItem->setPos(pos);
}
return pItem;
}
ElectricBaseModelLineItem* DiagramEditorModel::generateLine(QUuid uid,QString sName,int mode)
{
ElectricBaseModelLineItem* pLine = new ElectricBaseModelLineItem();
pLine->setItemId(uid);
pLine->setItemType(GIT_baseLine);
DiagramEditorItemProperty* pData = addPreviewData(uid,8,sName,DataBase::GetInstance()->ModelType()[4].modelType,"",mode);
pData->setGraphicsType(GIT_baseLine);
if(pData)
{
pLine->setProperty(pData);
pData->setDataChanged(true); //数据状态改变
}
addPreviewItem(uid,pLine,mode);
//establishConnection(pBreaker,pBus,pLine,ModelFunctionType::BaseModel);
_pCurPreviewScene->addItem(pLine);
return pLine;
}
void DiagramEditorModel::clearCurPreview()
{
if(_pCurPreviewScene){
_tempItem.clear();
_pCurPreviewScene->clear();
}
}
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();
int nT = 0;
if(typ == TransformerType::twoWinding){
generateItemByModel(_pCurTransLRoutes.value(0),1,QPoint(100,-25));
generateItemByModel(_pCurTransLRoutes.value(2),1,QPoint(100,25));
}
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));
}
connectTransToNeutral(block);
}
}
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;
}
generateComponent(uid,sName,0,nT,QPoint(0,0),0,1);
auto pTransItem = _tempItem.value(uid);
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));
}
}
}
void DiagramEditorModel::linkTransItem(GraphicsBaseModelItem* pTrans,QStandardItemModel* pModel)
{
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;
auto pLineData = TopologyManager::instance().ifConnection(uid1.toString(),uid2.toString()); //判断两个item是否有连接
if(pLineData != nullptr){
if(!_tempItem.contains(QUuid(pLineData->id()))){ //connectdata已存在item未绘制
auto pLine = generateLine(QUuid(pLineData->id()),"",1); //重新绘制
if(pLine)
establishConnection(pItem,pTrans,pLine,ModelFunctionType::BlockEditorModel,1,nPos);
}
else{ //已绘制,略过
}
}
else{ //connectdata不存在新建
auto pLine = generateLine(QUuid::createUuid(),"",1);
if(pLine)
establishConnection(pItem,pTrans,pLine,ModelFunctionType::BlockEditorModel,1,nPos);
}
}
}
}
}
}
void DiagramEditorModel::generatePreview()
{
if(_pPanel){
_pPanel->showPreview();
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();
QString name = p->getName();
QPointF pos = item->scenePos();
auto pItem = generateComponent(uid,name,0,1,pos,0,1);
pItem->setBoundingRect(item->boundingRect());
}
}
}
for(auto item:lst){
if(item->getType() == EditorItemType::bay){ //第二次生成间隔,部分接线
auto p = item->getBlockData(); //获取blockitem对应的data
DiagramEditorBayBlock* pBay = dynamic_cast<DiagramEditorBayBlock*>(p.data());
if(pBay){
auto mapRoute = pBay->getBayInfo().mapRoute;
auto mapCompo = pBay->getBayInfo().mapComponent;
QRectF rect = item->boundingRect();
// 计算中心点(本地坐标系)
QPointF centerLocal = rect.center();
// 转换为场景坐标系
QPointF centerScene = item->mapToScene(centerLocal);
generateItemByInfo(mapRoute,mapCompo,centerScene);
}
}
}
for(auto item:lst){
if(item->getType() == EditorItemType::trans){ //第三次生成变压器,部分接线
}
}
}
}
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;
}
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))
generateComponent(uid,name,nCate,nType,pos,nRotate,0);
}
}
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);
auto pLineData = TopologyManager::instance().ifConnection(uid1.toString(),uid2.toString(),ModelFunctionType::BlockEditorModel); //判断两个item是否有连接
if(pLineData != nullptr){
if(!_tempItem.contains(QUuid(pLineData->id()))){ //connectdata已存在item未绘制
auto pLine = generateLine(QUuid(pLineData->id()),"",0); //重新绘制
if(pLine)
establishConnection(p1,p2,pLine,ModelFunctionType::BlockEditorModel);
}
else{ //已绘制,略过
}
}
else{ //connectdata不存在新建
auto pLine = generateLine(QUuid::createUuid(),"",0);
if(pLine)
establishConnection(p1,p2,pLine,ModelFunctionType::BlockEditorModel);
}
}
}
}
}
}
}
void DiagramEditorModel::generateItemByInfo(QMap<QString,DiagramEditorRouteInfo> mapRoute,QMap<QString,DiagramEditorComponentInfo> mapCompo,QPointF delta)
{
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);
generateComponent(info.uid,info.sName,info.nCategory,info.nType,info.deltaPos+delta,info.nRotate,1);
if(!info.sBindObj.isEmpty() && info.sBindObj != QString::fromWCharArray(L"")){ //非空且不是无
if(!lstBind.contains(info))
lstBind.append(info);
}
}
if(route.lstCompo.size() > 1){
bulidAndLinkComponent(route.lstCompo);
}
}
}
for(auto &route:mapRoute){ //二次生成其他路线
if(route.bMainRoute == true){
continue;
}
for(auto &compo:route.lstOrder){ //生成正序设备
auto info = mapCompo.value(compo.sName);
generateComponent(info.uid,info.sName,info.nCategory,info.nType,info.deltaPos+delta,info.nRotate,1);
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);
generateComponent(info.uid,info.sName,info.nCategory,info.nType,info.deltaPos+delta,info.nRotate,1);
if(!info.sBindObj.isEmpty() && info.sBindObj != QString::fromWCharArray(L"")){ //非空且不是无
if(!lstBind.contains(info))
lstBind.append(info);
}
}
if(route.lstOrder.size() > 1){
bulidAndLinkComponent(route.lstOrder);
}
if(route.lstReverse.size() > 1){
bulidAndLinkComponent(route.lstReverse);
}
}
for(auto& compo:lstBind){ //遍历关联外部的item进行连线
if(compo.nBindType == 1){ //关联的是母线 母线没有数据获取绘制的母线item
for(auto& pItem:_previewItem){
auto pro = pItem->getProperty();
if(pro){
QString sName = pro->name();
if(sName == compo.sBindObj){
GraphicsBaseModelItem* pSrc = _previewItem.value(compo.uid);
GraphicsBaseModelItem* pTarget = pItem;
auto pLineData = TopologyManager::instance().ifConnection(pSrc->itemId().toString(),pTarget->itemId().toString(),ModelFunctionType::EditorModel); //判断两个item是否有连接
if(pLineData != nullptr){
if(!_previewItem.contains(QUuid(pLineData->id()))){ //connectdata已存在item未绘制
auto pLine = generateLine(QUuid(pLineData->id()),"",1); //重新绘制
if(pLine)
establishConnection(pSrc,pTarget,pLine,ModelFunctionType::EditorModel);
}
else{ //已绘制,略过
}
}
else{ //connectdata不存在新建
auto pLine = generateLine(QUuid::createUuid(),"",1);
if(pLine)
establishConnection(pSrc,pTarget,pLine,ModelFunctionType::EditorModel);
}
}
}
}
}
}
}
void DiagramEditorModel::updateTarget(QMap<QString,DiagramEditorRouteInfo>& data,int nLayout,int nSource)
{
auto& mapRoute = data;
QString sMainRoute;
bool hasMain = false;
for(auto& route:mapRoute){
if(route.bMainRoute == true){
sMainRoute = route.sRouteName;
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;
}
}
}
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;
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); //设置相对位置
if(nMainDir == 4){
maoCompo[i].nRotate = 0;
pItemName->setData(0,Qt::UserRole+5);
}
else{
maoCompo[i].nRotate = 180;
pItemName->setData(180,Qt::UserRole+5);
}
}
if(nMainDir == 8)
nSegIndex -= 1;
else
nSegIndex += 1;
}
for(auto& route:mapRoute){ //遍历主线路之外的线路
if(route.sRouteName == sMainRoute){
continue;
}
if(!route.lstCompo.isEmpty()){ //拆分线路为以节点为首
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]);
}
}
}
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){ //遍历以节点为首的队列
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;
}
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)); //同时连接下个点的一侧占用
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));
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){
route.lstOrder[i+1].nRotate = -90;
pNextItem->setData(-90,Qt::UserRole+5);
}
else if(nSubDir == 2){
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);
nXOrderIndex += 1;
}
}
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){ //遍历以节点为首的队列
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;
}
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)); //同时连接下个点的一侧占用
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));
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){
route.lstReverse[i+1].nRotate = -90;
pNextItem->setData(-90,Qt::UserRole+5);
}
else if(nSubDir == 2){
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);
nXReverseIndex += 1;
}
}
}
}
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;
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); //设置相对位置
if(nMainDir == 1){
maoCompo[i].nRotate = -90;
pItemName->setData(-90,Qt::UserRole+5); //转至水平
}
else{
maoCompo[i].nRotate = 90;
pItemName->setData(90,Qt::UserRole+5);
}
}
if(nMainDir == 2)
nSegIndex -= 1;
else
nSegIndex += 1;
}
for(auto& route:mapRoute){ //遍历主线路之外的线路
if(route.sRouteName == sMainRoute){
continue;
}
if(!route.lstCompo.isEmpty()){ //拆分线路为以节点为首
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]);
}
}
}
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){ //遍历以节点为首的队列
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;
}
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);
}
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);
nYOrderIndex += 1;
}
}
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){ //遍历以节点为首的队列
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;
}
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)); //同时连接下个点的一侧占用
route.lstReverse[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));
route.lstReverse[i+1].nRotate = 180;
pNextItem->setData(180,Qt::UserRole+5);
}
else{ //上下都没被占,默认放到下边
pItem->setData(QString::number(nVal | 4));
pNextItem->setData(QString::number(nNextVal | 8));
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);
nYReverseIndex += 1;
}
}
}
}
}
void DiagramEditorModel::bulidAndLinkComponent(QList<DiagramEditorComponentInfo> lst)
{
for(int i = 0;i < lst.size()-1;++i){
auto item1 = lst[i];
auto item2 = lst[i+1];
if(_previewItem.contains(item1.uid) && _previewItem.contains(item2.uid)){
GraphicsBaseModelItem* p1 = _previewItem.value(item1.uid);
GraphicsBaseModelItem* p2 = _previewItem.value(item2.uid);
auto pLineData = TopologyManager::instance().ifConnection(item1.uid.toString(),item2.uid.toString(),ModelFunctionType::EditorModel); //判断两个item是否有连接
if(pLineData != nullptr){
if(!_previewItem.contains(QUuid(pLineData->id()))){ //connectdata已存在item未绘制
auto pLine = generateLine(QUuid(pLineData->id()),"",1); //重新绘制
if(pLine)
establishConnection(p1,p2,pLine,ModelFunctionType::EditorModel);
}
else{ //已绘制,略过
}
}
else{ //connectdata不存在新建
auto pLine = generateLine(QUuid::createUuid(),"",1);
if(pLine)
establishConnection(p1,p2,pLine,ModelFunctionType::EditorModel);
}
}
}
}