572 lines
17 KiB
C++
572 lines
17 KiB
C++
#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 <QJsonArray>
|
||
#include <QMessageBox>
|
||
|
||
QMap<QUuid,BaseProperty*> FixedPortsModel::_nodeData;
|
||
bool FixedPortsModel::_dataInitialised = false;
|
||
|
||
FixedPortsModel::FixedPortsModel()
|
||
:_scene(nullptr)
|
||
,_widget(nullptr)
|
||
,_Interface(nullptr)
|
||
{
|
||
loadNodeDataFromDataBase();
|
||
_Interface = new HttpInterface(this);
|
||
_timer = new QTimer(this);
|
||
|
||
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(); //使用模型更新自身
|
||
_nodeItem.insert(id,item);
|
||
connect(item,&GraphicsBaseItem::ifExist,this,&FixedPortsModel::onSignal_ifExits);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
BaseProperty* FixedPortsModel::addNodeData(QUuid id,int type,QString name)
|
||
{
|
||
if(_nodeData.contains(id))
|
||
return nullptr;
|
||
BaseProperty* item = nullptr;
|
||
if(type == GIT_itemTri)
|
||
{
|
||
item = new ElectricSvgItemTriangle_Property(this);
|
||
}
|
||
else if(type == GIT_itemRect)
|
||
{
|
||
item = new ElectricSvgItemRect_Property(this);
|
||
}
|
||
else if(type == GIT_bus)
|
||
{
|
||
item = new ElectricSvgItemBus_Property(this);
|
||
}
|
||
if(item)
|
||
{
|
||
item->setUuid(id);
|
||
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);
|
||
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)
|
||
{
|
||
pPro->setComponent_id(info.id);
|
||
pPro->setResistance(bility.resistance);
|
||
pPro->setAnchor_v(bility.anchor_v);
|
||
pPro->setUv_alarm(bility.uv_alarm);
|
||
pPro->setOv_alarm(bility.ov_alarm);
|
||
pPro->setAnchor_i(bility.anchor_i);
|
||
pPro->setUi_alarm(bility.ui_alarm);
|
||
pPro->setOi_alarm(bility.oi_alarm);
|
||
}
|
||
}
|
||
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;
|
||
}
|
||
}
|
||
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);
|
||
//oppositeItem->updateConnectData();
|
||
}
|
||
|
||
QUuid lineId = pLine->itemId();
|
||
_nodeItem.take(lineId);
|
||
_scene->removeItem(pLine);
|
||
delete pLine;
|
||
|
||
port->disConnect();
|
||
}
|
||
}
|
||
QUuid srcId = pItem->itemId();
|
||
pItem->setItemChanged(true);
|
||
//pItem->updateConnectData();
|
||
_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());
|
||
if(exist) //已存在更新
|
||
{
|
||
DataBase::GetInstance()->updateComponent(pData->uuid(),pData->tag(),pData->name(),pData->context());
|
||
int type = pData->type();
|
||
if(type == GIT_itemRect)
|
||
{
|
||
ElectricSvgItemRect_Property* pro = dynamic_cast<ElectricSvgItemRect_Property*>(pData);
|
||
if(pro)
|
||
{
|
||
DataBase::GetInstance()->updateBus_stability(pro->component_id(),pro->getResistance(),pro->getAnchor_v(),pro->getUv_alarm(),pro->getOv_alarm(),pro->getAnchor_i(),pro->getUi_alarm(),pro->getOi_alarm(),1);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
DataBase::GetInstance()->insertComponent(pData->uuid(),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);
|
||
int type = pData->type();
|
||
if(type == GIT_itemRect)
|
||
{
|
||
ElectricSvgItemRect_Property* pro = dynamic_cast<ElectricSvgItemRect_Property*>(pData);
|
||
if(pro)
|
||
{
|
||
componentInfo info = DataBase::GetInstance()->getComponentInfoByUuid(pData->uuid().toString());
|
||
DataBase::GetInstance()->insertBus_stability(info.id,pro->getResistance(),pro->getAnchor_v(),pro->getUv_alarm(),pro->getOv_alarm(),pro->getAnchor_i(),pro->getUi_alarm(),pro->getOi_alarm(),1);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
//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);
|
||
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)
|
||
{
|
||
if(type == QString("v"))
|
||
p->setVolt(d);
|
||
else if(type == QString("i"))
|
||
p->setElec(d);
|
||
|
||
p->notifyUpdate(); //通知更新
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void FixedPortsModel::startHttpRequest()
|
||
{
|
||
if(_timer)
|
||
{
|
||
_timer->setInterval(1000);
|
||
_timer->start();
|
||
}
|
||
}
|
||
|
||
QWidget* FixedPortsModel::getTopWidget()
|
||
{
|
||
return dynamic_cast<QWidget*>(_widget);
|
||
}
|
||
|