DiagramDesigner/diagramCavas/source/graphicsDataModel/fixedPortsModel.cpp

701 lines
22 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 <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(); //使用模型更新自身
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;
modelStateInfo modelInfo;
for(auto &model:_modelStateInfo){ //找到对象对应的工程模
if(model.modelName == modelName){
modelInfo = model;
break;
}
}
VariableProperty* item = new VariableProperty(this);
QMap<QString,VariableMap>& propertyGroup = item->getMapGroup();
for(auto &groupInfo:modelInfo.groupInfo)
{
VariableMap map;
for(auto &pro:groupInfo.info)
{
map.insert(pro.name,pro.defaultValue); //添加属性信息
}
propertyGroup.insert(groupInfo.groupName,map);
}
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);
VariableProperty* pPro = dynamic_cast<VariableProperty*>(pData);
if(pPro)
{
QMap<QString,VariableMap>& mapVariableGroup = pPro->getMapGroup();
QMap<QString,groupStateValue> mapGroup = _modleDataInfo[info.modelName].groupInfo; //取得该模型下的所有属性组
QMap<QString,groupStateValue>::Iterator iter;
for(iter = mapGroup.begin();iter != mapGroup.end();++iter)
{
VariableMap varMap;
PropertyValueInfo valueInfo = iter->mapInfo[info.uuid];
PropertyValueInfo::Iterator it;
for(it = valueInfo.begin(); it != valueInfo.end();++it)
{
varMap.insert(it.key(),it->defaultValue);
}
mapVariableGroup.insert(iter.key(),varMap);
}
}
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->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);
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,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)
{
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);
}
void FixedPortsModel::addModelProperty(modelStateInfo info)
{
if(!_modelStateInfo.contains(info.modelName))
{
_modelStateInfo.insert(info.modelName,info);
}
}
void FixedPortsModel::getModelInfo()
{
QMap<QString,int> model = DataBase::GetInstance()->getAllProjectModel();
QMap<QString,int>::Iterator iter;
for(iter = model.begin();iter != model.end(); ++iter) //遍历模型
{
modelStateInfo modelInfo;
modelInfo.modelType = iter.value(); //模型类型
groupStateInfo groupInfo;
QMap<QString,propertyGroupState> mapState = DataBase::GetInstance()->getModelInfo(iter.key());
QMap<QString,propertyGroupState>::Iterator it;
for(it = mapState.begin();it != mapState.end();++it) //遍历模型属性组
{
groupInfo.groupName = it.key();
groupInfo.tableName = it->tableName;
QJsonArray nodesJsonArray = it->propertyState["checkState"].toArray();
for (QJsonValueRef nodeJson : nodesJsonArray) //每个属性的状态信息
{
propertyStateInfo propertyInfo;
QJsonObject node = nodeJson.toObject();
QString propertyName = node["name"].toString();
int nState = node["checked"].toInt();
QString dataType = node["type"].toString();
QString defaultValue = node["defaultValue"].toString();
if(nState)
{
//todo:别名赋值
propertyInfo.name = propertyName;
propertyInfo.type = dataType;
propertyInfo.defaultValue = defaultValue;
groupInfo.info.insert(propertyName,propertyInfo);
}
}
modelInfo.groupInfo.insert(it.key(),groupInfo);
}
_modelStateInfo.insert(iter.key(),modelInfo);
}
}
void FixedPortsModel::getModelData()
{
QMap<QString,int> model = DataBase::GetInstance()->getAllProjectModel();
QMap<QString,int>::Iterator iter;
for(iter = model.begin();iter != model.end(); ++iter) //遍历模型
{
modelDataInfo modelInfo;
modelInfo.modelType = iter.value(); //模型类型
QMap<QString,propertyGroupState> mapState = DataBase::GetInstance()->getModelInfo(iter.key());
QMap<QString,propertyGroupState>::Iterator it;
for(it = mapState.begin();it != mapState.end();++it) //遍历模型属性组
{
groupStateValue groupValue;
groupValue.groupName = it.key();
QJsonArray nodesJsonArray = it->propertyState["checkState"].toArray();
QStringList lstParam; //需检索的属性组中属性名列表
for (QJsonValueRef nodeJson : nodesJsonArray) //每个属性的状态信息
{
propertyStateInfo propertyInfo;
QJsonObject node = nodeJson.toObject();
QString propertyName = node["name"].toString();
int nState = node["checked"].toInt();
QString dataType = node["type"].toString();
QString defaultValue = node["defaultValue"].toString();
if(nState)
{
lstParam.append(propertyName);
}
}
lstParam.append("global_uuid"); //全局id未添加到属性状态中手动选择
groupValue.mapInfo = DataBase::GetInstance()->selectGroupProperty(it->tableName,lstParam); //返回表中属性值
modelInfo.groupInfo.insert(it.key(),groupValue);
}
_modleDataInfo.insert(iter.key(),modelInfo);
}
}