#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 #include QMap 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 FixedPortsModel::allNodePos() const { QMap map; for(auto pItem:_nodeItem) { if(pItem->getItemType() != GIT_link) map.insert(pItem->itemId(),pItem->pos()); } return map; } QVector FixedPortsModel::allConnections() { QVector vec; for(auto pItem:_nodeItem) { if(pItem->getItemType() == GIT_link) { auto pLine = dynamic_cast(pItem); if(pLine) { vec.push_back(pLine->getConnection()); } } } return vec; } QMap& 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 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(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(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 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(); 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(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(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 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(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(_widget); }