DiagramDesigner/diagramCavas/source/graphicsDataModel/fixedPortsModel.cpp

673 lines
20 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/fixedPortsModel.h"
#include "graphicsItem/graphicsBaseItem.h"
#include "graphicsItem/electricSvgItemBus.h"
#include "graphicsItem/electricSvgItemRect.h"
#include "graphicsItem/electricSvgItemTriangle.h"
#include "graphicsItem/electricConnectLineItem.h"
#include "graphicsItem/itemPort.h"
#include "designerScene.h"
#include "dataBase.h"
#include "httpInterface.h"
#include "drawingPanel.h"
#include "itemPropertyDlg.h"
#include "dataManager.h"
#include "powerEntity.h"
#include "topologyManager.h"
#include <QJsonArray>
#include <QMessageBox>
QMap<QUuid,BaseProperty*> FixedPortsModel::_nodeData;
bool FixedPortsModel::_dataInitialised = false;
FixedPortsModel::FixedPortsModel(PowerEntity* pEntity)
:_scene(nullptr)
,_widget(nullptr)
,_Interface(nullptr)
,_pEntity(pEntity)
{
loadNodeDataFromDataBase();
_Interface = new HttpInterface(this);
_timer = new QTimer(this);
_modelStateInfo = DataManager::instance().modelState();
_modelDataInfo = DataManager::instance().modelData();
initialPropertyDlg();
connect(_timer,SIGNAL(timeout()),this,SLOT(onTimeOut()));
connect(_Interface,&HttpInterface::sendPointData,this,&FixedPortsModel::onSignal_GetPointData);
}
FixedPortsModel::~FixedPortsModel()
{
}
QMap<QUuid,QPointF> FixedPortsModel::allNodePos() const
{
QMap<QUuid,QPointF> map;
for(auto pItem:_nodeItem)
{
if(pItem->getItemType() != GIT_link)
map.insert(pItem->itemId(),pItem->pos());
}
return map;
}
QVector<Connection> FixedPortsModel::allConnections()
{
QVector<Connection> vec;
for(auto pItem:_nodeItem)
{
if(pItem->getItemType() == GIT_link)
{
auto pLine = dynamic_cast<ElectricConnectLineItem*>(pItem);
if(pLine)
{
vec.push_back(pLine->getConnection());
}
}
}
return vec;
}
QMap<QUuid,GraphicsBaseItem*>& FixedPortsModel::allItems()
{
return _nodeItem;
}
bool FixedPortsModel::addNodeItem(QUuid uuid,GraphicsBaseItem* pItem)
{
if(_nodeItem.contains(uuid))
return false;
else
{
_nodeItem.insert(uuid,pItem);
connect(pItem,&GraphicsBaseItem::ifExist,this,&FixedPortsModel::onSignal_ifExits);
return true;
}
}
void FixedPortsModel::addNodeItem(QUuid id/*,int type*/,QPointF pos)
{
BaseProperty* pro = nullptr;
GraphicsBaseItem* item = nullptr;
if(_nodeData.contains(id))
{
pro = _nodeData[id];
if(pro)
{
int type = pro->type();
if(type == GIT_itemTri)
{
item = new ElectricSvgItemTriangle(QRect(-15, -15, 30, 30));
item->setItemType(GIT_itemTri);
}
else if(type == GIT_itemRect)
{
item = new ElectricSvgItemRect(QRect(-15, -15, 30, 30));
item->setItemType(GIT_itemRect);
}
else if(type == GIT_bus)
{
item = new ElectricSvgItemBus(QRect(-100, -3, 200, 6));
item->setItemType(GIT_bus);
QJsonArray portArr = pro->context()["port"].toArray();
for(QJsonValueRef portJson:portArr)
{
QJsonObject portObj = portJson.toObject();
int nPort = portObj["portId"].toInt();
int x = portObj["x"].toInt();
int y = portObj["y"].toInt();
item->addPort(p_movable,nPort,QPointF(x,y));
}
}
if(item)
{
item->setItemId(id);
item->editShape(0, pos);
item->setPos(pos);
//item->setSelected(true);
_scene->addItem(item);
item->addPoint(pos);
item->setProperty(pro); //绑定模型
item->updateByProperty(); //使用模型更新自身
item->setModelName(pro->modelName());
_nodeItem.insert(id,item);
connect(item,&GraphicsBaseItem::ifExist,this,&FixedPortsModel::onSignal_ifExits);
}
}
}
}
BaseProperty* FixedPortsModel::addNodeData(QUuid id,int type,QString name,QString modelName)
{
if(_nodeData.contains(id))
return nullptr;
VariableProperty* item = new VariableProperty(this);
//todo:关联到对应data
if(item)
{
item->setUuid(id);
item->setModelName(modelName);
item->setType(type);
item->setTag(name);
item->setName(name);
_nodeData.insert(id,item);
}
return item;
}
void FixedPortsModel::loadNodeDataFromDataBase()
{
if(!_dataInitialised)
{
QList<componentInfo> lst= DataBase::GetInstance()->getAllComponents();
for(auto &info:lst)
{
BaseProperty* pData = addNodeData(info.uuid,info.type,info.name,info.modelName);
pData->setPage(info.page_id);
pData->setTag(info.tag);
pData->setName(info.name);
pData->setPath(info.nspath);
pData->setDescription(info.description);
pData->setInService(info.inService);
pData->setState(info.state);
pData->setConnectedBus(info.connected_bus);
pData->setLabel(info.label);
pData->setContext(info.context);
pData->setGrid(info.grid);
pData->setZone(info.zone);
pData->setStation(info.station);
pData->setDataChanged(false);
if(info.type == GIT_itemTri)
{
}
else if(info.type == GIT_itemRect)
{
//busStability bility = DataBase::GetInstance()->getBusStabilityById(info.id);
/*ElectricSvgItemRect_Property* pPro = dynamic_cast<ElectricSvgItemRect_Property*>(pData);
if(pPro)
{
}*/
}
else if(info.type == GIT_bus)
{
}
}
_dataInitialised = true;
}
else
{
for(auto p:_nodeData)
{
int a = 1;
}
}
}
void FixedPortsModel::addConnectLline(QUuid srcId,QUuid destId,int srcPort,int destPort)
{
GraphicsBaseItem* src = _nodeItem[srcId];
GraphicsBaseItem* dest = _nodeItem[destId];
if(src && dest)
{
ElectricConnectLineItem* pItem = new ElectricConnectLineItem();
pItem->setItemId(QUuid::createUuid());
pItem->setItemType(GIT_link);
_scene->addItem(pItem);
ItemPort* ptSrc = src->getPortPtr(srcPort);
HandleType srcType = ptSrc->getType();
PortPos srcPos = ptSrc->portPos();
pItem->setStartPoint(ptSrc->scenePos());
ptSrc->setConnect(pItem);
ItemPort* ptDest = nullptr;
if(dest->getItemType() == GIT_bus) //母线动态创建port
{
ptDest = dest->getPortPtr(destPort);
pItem->setEndPoint(ptDest->scenePos());
}
else
{
ptDest = dest->getPortPtr(destPort);
pItem->setEndPoint(ptDest->scenePos());
}
if(ptDest != nullptr)
{
int destPort = ptDest->getTag();
HandleType destType = ptDest->getType();
PortPos destPos = ptDest->portPos();
pItem->calculatePath();
pItem->setConnection(Connection(srcId,srcPort,srcType,srcPos,destId,destPort,destType,destPos));
ptDest->setConnect(pItem);
addNodeItem(pItem->itemId(),pItem);
/*auto srcParent = ptSrc->getParentPtr();
auto destParent = ptDest->getParentPtr();
srcParent->updateConnectData();
destParent->updateConnectData();*/
}
}
}
void FixedPortsModel::deleteNodeItem(GraphicsBaseItem* pItem)
{
if(pItem->getItemType() == GIT_link)
{
auto pLine = dynamic_cast<ElectricConnectLineItem*>(pItem);
if(pLine)
{
/*Connection con = pLine->getConnection();
GraphicsBaseItem* srcItem = _nodeItem[con.nSrcNodeId];
if(srcItem)
{
ItemPort* ptSrc = srcItem->getPortPtr(con.nSrcPort);
ptSrc->disConnect();
srcItem->setItemChanged(true);
//srcItem->updateConnectData();
}
GraphicsBaseItem* destItem = _nodeItem[con.nDestNodeId];
if(destItem)
{
ItemPort* ptDest = pItem->getPortPtr(con.nDestPort);
ptDest->disConnect();
destItem->setItemChanged(true);
//destItem->updateConnectData();
}
QUuid lineId = pLine->itemId();
_nodeItem.take(lineId);
_scene->removeItem(pLine);
delete pLine;*/
QUuid conId = pLine->itemId();
TopologyManager::instance().removeConnection(conId.toString());
PowerConnection* pCon = TopologyManager::instance().connection(conId.toString());
if(pCon){
PowerEntity* itemFrom = TopologyManager::instance().getEntityByTerminal(pCon->fromTerminalId());
PowerEntity* itemTo = TopologyManager::instance().getEntityByTerminal(pCon->toTerminalId());
if(itemFrom && itemTo)
{
_nodeItem.value(QUuid(itemFrom->id()))->setItemChanged(true);
_nodeItem.value(QUuid(itemTo->id()))->setItemChanged(true);
}
}
_nodeItem.take(conId);
_scene->removeItem(pLine);
delete pLine;
}
}
else
{
/*QMap<QString,ItemPort*> ports = pItem->getPorts();
for(auto port:ports)
{
if(port->connected())
{
ElectricConnectLineItem* pLine = port->getConnectPtr();
Connection con = pLine->getConnection();
QUuid oppositeId = pLine->getOppositeId(pItem->itemId());
int oppositePort = (con.nSrcNodeId==pItem->itemId())?con.nDestPort:con.nSrcPort; //取另一端点序号
GraphicsBaseItem* oppositeItem = _nodeItem[oppositeId];
if(oppositeItem)
{
ItemPort* ptOppo = oppositeItem->getPortPtr(oppositePort);
ptOppo->disConnect();
oppositeItem->setItemChanged(true);
}
QUuid lineId = pLine->itemId();
_nodeItem.take(lineId);
_scene->removeItem(pLine);
delete pLine;
port->disConnect();
}
}*/
QUuid srcId = pItem->itemId();
QList<PowerConnection*> lstCon = TopologyManager::instance().getConnectionsFor(srcId.toString());
for(auto &con:lstCon)
{
PowerEntity* pFrom = TopologyManager::instance().getEntityByTerminal(con->fromTerminalId());
PowerEntity* pTo = TopologyManager::instance().getEntityByTerminal(con->toTerminalId());
if(pFrom && pTo)
{
if(srcId.toString() == pFrom->id()) //对象是srcItem
_nodeItem.value(QUuid(pTo->id()))->setItemChanged(true);
else //对象是toItem
_nodeItem.value(QUuid(pFrom->id()))->setItemChanged(true);
}
//TopologyManager::instance().removeConnection(con->id()); //删除entity时会同时删除相关连接无需手动删除
}
TopologyManager::instance().deleteEntity(srcId.toString());
pItem->setItemChanged(true);
_nodeItem.take(srcId);
_scene->removeItem(pItem);
delete pItem;
}
}
QVariant FixedPortsModel::nodeData(QUuid nodeId, NodeRole role) const
{
QVariant result;
switch(role)
{
case NodeRole::Position:
result = _nodeItem[nodeId]->pos();
break;
}
/*auto it = _models.find(nodeId);
if (it == _models.end())
return result;
auto &model = *it;
switch (role) {
case NodeRole::Type:
result = model->name();
break;
case NodeRole::Position:
result = _nodeGeometryData[nodeId].pos;
break;
case NodeRole::Size:
result = _nodeGeometryData[nodeId].size;
break;
case NodeRole::CaptionVisible:
result = model->captionVisible();
break;
case NodeRole::Caption:
result = model->caption();
break;
case NodeRole::Style: {
//auto style = StyleCollection::nodeStyle();
//result = style.toJson().toVariantMap();
} break;
case NodeRole::InternalData: {
QJsonObject nodeJson;
//nodeJson["internal-data"] = _models[nodeId]->save();
result = nodeJson.toVariantMap();
break;
}
case NodeRole::InPortCount:
result = model->nPorts(PortType::In);
break;
case NodeRole::OutPortCount:
result = model->nPorts(PortType::Out);
break;
case NodeRole::Widget: {
auto w = model->embeddedWidget();
result = QVariant::fromValue(w);
} break;
}*/
return result;
}
QJsonObject FixedPortsModel::saveNode(QUuid const nodeId) const
{
QJsonObject nodeJson;
nodeJson["id"] = nodeId.toString();
nodeJson["type"] = _nodeItem[nodeId]->getItemType();
{
QPointF const pos = nodeData(nodeId, NodeRole::Position).value<QPointF>();
QJsonObject posJson;
posJson["x"] = pos.x();
posJson["y"] = pos.y();
nodeJson["position"] = posJson;
}
return nodeJson;
}
void FixedPortsModel::saveNode(int nPageId)
{
for(auto &pData:_nodeData)
{
if(pData->prepareDelete())
{
DataBase::GetInstance()->deleteComponent(pData->uuid().toString());
continue;
}
if(pData->dataChanged())
{
bool exist = DataBase::GetInstance()->componentExist(pData->uuid().toString());
VariableProperty* pVariable = dynamic_cast<VariableProperty*>(pData);
if(pVariable)
{
modelDataInfo dataInfo = pVariable->getPropertyValue();
if(exist) //已存在更新
{
DataBase::GetInstance()->updateComponent(pData->uuid(),pData->tag(),pData->name(),pData->context());
for(auto &val:dataInfo.groupInfo)
{
DataBase::GetInstance()->updateDynamicProperty(pData->uuid(),val);
}
}
else
{
DataBase::GetInstance()->insertComponent(pData->uuid(),pData->modelName(),pData->path(),pData->tag(),pData->name(),pData->description(),pData->grid(),pData->zone(),pData->station(),pData->type(),true,pData->state(),pData->connectedBus(),pData->label(),pData->context(),nPageId,1);
for(auto &val:dataInfo.groupInfo)
{
DataBase::GetInstance()->insertDynamicProperty(pData->uuid(),val);
}
}
}
}
}
//todo:再循环一遍删除待删除项
}
void FixedPortsModel::onSignal_ifExits(QUuid id,const QString& str,int type,GraphicsBaseItem* pitem)
{
bool exist = false;
BaseProperty* pData = nullptr;
for(auto pro:_nodeData)
{
if(pro->tag() == str)
{
pData = pro;
exist = true;
break;
}
}
if(exist) //已存在将发出信号的item绑定到此data
{
if(_nodeItem.contains(id)) //发出信号对象id与data对象id相同已绑定,不做响应
return;
QMessageBox msgBox;
msgBox.setText(QString::fromWCharArray(L"提示"));
msgBox.setInformativeText(QString::fromWCharArray(L"此名称模型已存在,是否替换?"));
msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
msgBox.setDefaultButton(QMessageBox::Cancel);
int ret = msgBox.exec();
switch (ret) {
case QMessageBox::Ok:
{
//todo:断开原来的连接关系
pitem->setProperty(pData);
pitem->setItemId(pData->uuid());
_nodeItem.take(id);
_nodeItem.insert(pData->uuid(),pitem);
}
break;
case QMessageBox::Cancel:
// Cancel was clicked
break;
default:
// should never be reached
break;
}
}
else //创建新data并绑定
{
BaseProperty* pItem = addNodeData(id,type,str,pitem->getModelName());
if(pItem)
{
pitem->setProperty(pItem);
pItem->setDataChanged(true); //数据状态改变
}
}
}
void FixedPortsModel::onTimeOut()
{
_Interface->getPointData("i");
_Interface->getPointData("v");
}
void FixedPortsModel::onSignal_GetPointData(QString type,QMap<qint64,double> map)
{
if(map.size() == 1) //实时数据
{
double d = map.first();
for(auto pro:_nodeData) //demo版本只有一个数据
{
int t = pro->type();
if(t == GIT_itemRect)
{
//todo:根据id匹配数据
/*auto p = dynamic_cast<ElectricSvgItemRect_Property*>(pro);
if(p)
{
p->notifyUpdate(); //通知更新
}*/
}
}
}
}
void FixedPortsModel::startHttpRequest()
{
if(_timer)
{
_timer->setInterval(1000);
_timer->start();
}
}
QWidget* FixedPortsModel::getTopWidget()
{
return dynamic_cast<QWidget*>(_widget);
}
QPointF FixedPortsModel::getTerminalPos(const QString& sTerminalId)
{
PowerEntity* pParent = TopologyManager::instance().getEntityByTerminal(sTerminalId);
if(pParent)
{
for(auto &item:_nodeItem)
{
if(pParent->id() == item->itemId().toString()) //找到terminal父图元
{
for(auto &pPort:item->getPorts())
{
if(pPort->getId() == sTerminalId)
{
return pPort->scenePos();
}
}
}
}
}
return QPointF(0,0);
}
ElectricConnectLineItem* FixedPortsModel::getLineItemById(const QString& terminalId)
{
for(auto iter:_nodeItem) //获取id所在的lineitem
{
auto item = dynamic_cast<GraphicsBaseItem*>(iter);
if(item)
{
if(item->getItemType() == GIT_link)
{
PowerConnection* pCon = TopologyManager::instance().getConnectionContainsTerminal(terminalId);
if(pCon)
{
if(item->itemId().toString() == pCon->id())
return dynamic_cast<ElectricConnectLineItem*>(item);
}
}
}
}
return nullptr;
}
void FixedPortsModel::showModelDlg(const QString& sName,QUuid uuid,GraphicsBaseItem* pItem)
{
modelStateInfo stateInfo = _modelStateInfo[sName];
ModelDataMap mapData = DataManager::instance().modelData();
ItemPropertyDlg* pDlg = dynamic_cast<ItemPropertyDlg*>(stateInfo._PropertyDlg);
if(pDlg)
{
pDlg->showDlg(mapData[sName],uuid,pItem);
}
else
qDebug()<<"showModelDlg err";
}
void FixedPortsModel::initialPropertyDlg()
{
for(auto &modelInfo:_modelStateInfo)
{
if(modelInfo._PropertyDlg == NULL)
{
generatePropertyDlg(modelInfo.modelName);
}
}
}
void FixedPortsModel::generatePropertyDlg(const QString& sModel)
{
modelStateInfo info = _modelStateInfo[sModel];
if(info._PropertyDlg == NULL)
{
ItemPropertyDlg* dlg = new ItemPropertyDlg(_widget);
if(dlg)
{
dlg->loadGroupButton(info.groupInfo);
_modelStateInfo[sModel]._PropertyDlg = dlg;
}
}
}
ConfigurationDiagram* FixedPortsModel::getTopologyDiagram()
{
return dynamic_cast<ConfigurationDiagram*>(_pEntity);
}