new topology structure complete

This commit is contained in:
baiYue 2025-04-30 16:29:17 +08:00
parent 2d26efcae3
commit 014051e9c4
47 changed files with 1433 additions and 183 deletions

View File

@ -48,6 +48,7 @@ set(H_HEADER_FILES
include/projectModelDlg.h
include/projectTableDelegate.h
include/selectorDialog.h
include/topologyView.h
common/include/global.h
common/include/tools.h
@ -71,15 +72,18 @@ set(CPP_SOURCE_FILES
source/projectModelDlg.cpp
source/projectTableDelegate.cpp
source/selectorDialog.cpp
source/topologyView.cpp
common/source/httpInterface.cpp
common/source/global.cpp
common/source/tools.cpp
)
set(UI_FILES
ui/mainwindow.ui
ui/graphicElementsPanel.ui
ui/loadPageDlg.ui
ui/projectModelDlg.ui
ui/topologyView.ui
)
#

View File

@ -7,6 +7,7 @@
#include <QHash>
#include <QUuid>
#include <QJsonObject>
#include <QWidget>
const double g_dGriaphicsScene_Width = 800;
const double g_dGriaphicsScene_Height = 600;
@ -78,13 +79,19 @@ enum TableItemState //工程模table操作的对象状态
TS_edit = 4
};
enum class AlertInfo //警告提示信息
{
success = 1,
fail = 2,
exist = 4
};
struct attributeGroup //属性组(元模)
{
int id = 0;
QString groupType;
QString groupName;
int isPublic = -1;
int ispublic = -1;
QString remark;
};
@ -131,6 +138,13 @@ struct modelAttribute //模型属性表(所有模型属性的索引)
qint64 attributeId = 0;
};
struct modelAttributePublic //公共属性表
{
int id = 0;
qint64 attributeGroupId = 0;
qint64 attributeId = 0;
};
struct modelConnectivity //模型连接性表(元模是否可以连接)
{
int id = 0;
@ -176,6 +190,7 @@ struct groupStateInfo //属性组(结构信息)
{
QString groupName; //组名
QString tableName; //表名
bool isPublic = false;;
PropertyValueInfo info; //属性信息
};
@ -192,6 +207,11 @@ struct modelStateInfo //模型结构信息
int modelType;
QWidget* _PropertyDlg = NULL; //属性设置界面,每个模型维护一种界面
QMap<QString,groupStateInfo> groupInfo; //属性组信息
void release()
{
if(_PropertyDlg)
delete _PropertyDlg;
}
};
struct modelDataInfo //模型数据信息
@ -208,6 +228,35 @@ struct propertyContentInfo //单个属性结构
QWidget* proEditer = NULL; //编辑窗口对象
};
//==================组态拓扑结构======================
/*struct diagramInfo
{
QString name;
QString uuid;
QMap<QString,diagramInfo> childMap;
};
struct stationInfo
{
QString stationName;
QString uuid;
QMap<QString,diagramInfo> diagramMap;
};
struct zoneInfo
{
QString zoneName;
QString uuid;
QMap<QString,stationInfo> stationMap;
};
struct gridInfo //grid
{
QString gridName;
QString uuid;
QMap<QString,zoneInfo> zoneMap;
};*/
//==================组态图使用=====================
// 基础实体类型(电力元素或组态图)
enum class EntityType {
@ -219,6 +268,14 @@ enum class EntityType {
BusBar,
CircuitBreaker };
struct EntityInfo
{
QString sName;
QString sUuid;
QString sParentId;
EntityType eType;
};
struct DiagramView {
QString diagramId; // 对应的PowerEntity ID

View File

@ -2,6 +2,7 @@
#define TOOLS_H
#include <QHash>
#include <QStandardItem>
template <typename Key, typename Value> //双向map工具类实现key->value,value->key的映射
class BiDirectionalMap {
@ -64,4 +65,6 @@ private:
QHash<Key, Value> m_keyToValue; // 键 → 值
QHash<Value, Key> m_valueToKey; // 值 → 键
};
int getLevel(QStandardItem *item);
#endif // DATABASE_H

17
common/source/tools.cpp Normal file
View File

@ -0,0 +1,17 @@
#include "tools.h"
int getLevel(QStandardItem *item) {
int level = 0;
QStandardItem *parent = item->parent();
if(parent)
{
while (parent) {
level++;
parent = parent->parent();
}
return level;
}
else{
return -1;
}
}

View File

@ -10,6 +10,7 @@ namespace Ui { class diagramCavas; }
QT_END_NAMESPACE
class DrawingPanel;
class PowerEntity;
class DIAGRAM_DESIGNER_PUBLIC DiagramCavas : public QMdiArea
{
@ -22,19 +23,26 @@ public:
public:
void initial();
public slots:
void onSignal_addDrawingPanel(const QString& sTitile,DiagramMode = DM_edit);
void onSignal_addDrawingPanel(PowerEntity* p,DiagramMode = DM_edit);
void onSignal_addGraphicsItem(modelStateInfo&);
void onSignal_addPage();
void onSignal_savePage();
void onSignal_loadPage(const QString&);
void onSignal_loadPage(PowerEntity* p);
void runPage(const QString); //运行时
void onSignal_runPage();
void onSignal_deletePage();
void onSignal_activatePage(const QString& name);
void onSignal_panelDelete(const QString& name);
void onSignal_createEntity(EntityInfo);
void onSignal_changeEntity(EntityInfo);
void onSignal_deleteEntity(EntityInfo);
void onSignal_selectEntity(EntityInfo);
private:
QMap<QString,DrawingPanel*> m_mapDrawPanel;
void removePanel(PowerEntity*);
private:
QMap<QString,QPair<DrawingPanel*,QMdiSubWindow*>> m_mapDrawPanel;
int _pageIndex;
QString _curPage;
};

View File

@ -14,13 +14,14 @@ class DesignerScene;
class SelectorManager;
class GraphicsItemGroup;
class StatusBar;
class PowerEntity;
class DrawingPanel : public QWidget
{
Q_OBJECT
public:
DrawingPanel(QWidget *parent = nullptr,DiagramMode mode = DM_edit);
DrawingPanel(PowerEntity* pEntity,QWidget *parent = nullptr,DiagramMode mode = DM_edit);
~DrawingPanel();
QGraphicsScene* getQGraphicsScene();
@ -59,6 +60,7 @@ private:
FixedPortsModel* _pModel;
DiagramMode _mode;
QString _name;
PowerEntity* _pEntity; //组态图拓扑对象
};
#endif

View File

@ -2,6 +2,7 @@
#include "graphicsDataModel/baseModel.h"
#include "serializable.h"
#include "powerEntity.h"
#include <QSharedPointer>
#include <QJsonObject>
@ -14,12 +15,15 @@ class DesignerScene;
class HttpInterface;
struct Connection;
class PowerEntity;
class ElectricConnectLineItem;
class FixedPortsModel : public BaseModel, public Serializable
{
Q_OBJECT
public:
FixedPortsModel();
FixedPortsModel(PowerEntity*);
~FixedPortsModel();
public:
QMap<QUuid,QPointF> allNodePos() const;
@ -37,10 +41,13 @@ public:
void setScene(DesignerScene* p){_scene = p;}
void setTopWidget(DrawingPanel* p) {_widget = p;}
QWidget* getTopWidget();
QPointF getTerminalPos(const QString& sTerminalId); //获取拓扑接线点在当前diagram中的位置
ElectricConnectLineItem* getLineItemById(const QString& terminalId);
void showModelDlg(const QString&,QUuid,GraphicsBaseItem*); //点击时显示指定模型的dlg、指定item的数据(模型名对象Uuid,触发事件的item)
void initialPropertyDlg(); //初始化属性设置dlg每个模型拥各自的dlg
void generatePropertyDlg(const QString&);
ConfigurationDiagram* getTopologyDiagram(); //返回当前组态图的拓扑实体
Q_SIGNALS:
void activatePage(const QString&); //激活当前model所在page
public:
@ -62,6 +69,7 @@ private:
DrawingPanel* _widget; //顶层widget
HttpInterface* _Interface;
QTimer* _timer;
PowerEntity* _pEntity; //拓扑实体
QMap<QString,modelStateInfo> _modelStateInfo; //模型结构信息
QMap<QString,modelDataInfo> _modelDataInfo; //模型数据信息

View File

@ -88,10 +88,10 @@ public:
bool addConnection();
void resetCurLine(){_curLine = QPoint();}
void updateConnection(QUuid callerId,QPointF pos); //外部调用的更新函数,id为调用者id
//void updateConnection(QUuid callerId,QPointF pos); //外部调用的更新函数,id为调用者id
void setConnection(Connection con){m_connectState = con;}
Connection getConnection() const {return m_connectState;}
QUuid getOppositeId(QUuid); //获取另一端点id
//QUuid getOppositeId(QUuid); //获取另一端点id
protected:
virtual QPainterPath shape() const override;
virtual QRectF boundingRect() const override;

View File

@ -437,6 +437,7 @@ protected:
class ItemPort;
class BaseProperty;
class PowerEntity;
typedef AbstractShapeType<QGraphicsItem> AbstractShape;
@ -464,7 +465,7 @@ public:
virtual QString getLabelCurrent() const;
virtual void setLabelVoltage(const QString& str); //设置电压标签
virtual QString getLabelVoltage() const;
virtual int addPort(PortState typ,QPointF vec); //新建,返回-1失败
virtual int addPort(PortState typ,QPointF vec,QString id = "",HandleType hType = T_lineInOut,PortPos pos = P_top); //新建,返回-1失败
virtual void addPort(PortState typ,int ntagId,QPointF vec); //载入 PortState为P_const时QPointF中为(0~10~1)的相对位置;PortState为p_movable时QPointF为坐标值
virtual QUuid itemId() const {return m_itemId;}
virtual void setItemId(QUuid n){m_itemId = n;}
@ -477,7 +478,7 @@ public:
virtual int getLastPort() const {return _lastPort;}
virtual ItemPort* getPortPtr(int) const;
virtual ItemControlHandle* getHandlePtr(int) const;
virtual QMap<QString,ItemPort*>& getPorts() {return m_mapPort;}
virtual QMap<QString,ItemPort*> getPorts() {return m_mapPort;}
virtual void setProperty(BaseProperty* p);
virtual BaseProperty* getProperty() {return _property;}
virtual void unbindProperty(); //断开图元与数据的绑定
@ -487,6 +488,8 @@ public:
virtual bool itemChanged() const {return _itemChanged;}
virtual void setModelName(QString sName){_modelName = sName;}
virtual QString getModelName() const {return _modelName;}
virtual void setEntity(PowerEntity*); //设置当前图元的拓扑数据
virtual PowerEntity* entity();
protected:
virtual QVariant itemChange(QGraphicsItem::GraphicsItemChange, const QVariant&);
virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent*);
@ -507,6 +510,7 @@ protected:
BaseProperty* _property;
bool _itemChanged; //图元变化标志,判断是否需要保存
QString _modelName; //当前图元使用的模型名用来在model中检索属性信息
PowerEntity* _pEntity; //图元拓扑
};
class BaseProperty:public QObject //属性类,存放电路元件属性

View File

@ -10,7 +10,7 @@ class ItemPort : public HandleRect
Q_OBJECT
public:
ItemPort(QGraphicsItem *parent);
ItemPort(QGraphicsItem *parent,QString uuid = "");
virtual ~ItemPort();
public:
@ -20,10 +20,16 @@ public:
void disConnect(){_ptr = nullptr;}
bool connected() const {return _ptr == nullptr?false:true;}
ElectricConnectLineItem* getConnectPtr() const {return _ptr;}
void setId(const QString& id){_uuid = id;}
QString getId() {return _uuid;}
void setName(const QString& str) {_name = str;}
QString getName() const {return _name;}
protected:
virtual void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) override;
private:
QString _uuid;
QString _name;
PortPos _pos;
ElectricConnectLineItem* _ptr;
};

View File

@ -17,7 +17,7 @@ public:
: m_type(type), m_id(id), m_name(name) {}
virtual ~PowerEntity() {
qDeleteAll(m_children);
//qDeleteAll(m_children);
}
// 添加/删除子元素

View File

@ -11,6 +11,7 @@
enum class TerminalType {
PowerInput,
PowerOutput,
PowerConnect,
ControlSignal,
ProtectiveGround
};
@ -22,6 +23,7 @@ public:
TerminalType type,
const QString& name,
const QPointF& relativePos = QPointF(),
const QString& uuid = "",
QObject* parent = nullptr);
// 属性访问

View File

@ -27,13 +27,15 @@ public:
// 连接管理
PowerConnection* createConnection(const QString& uuid,const QString& fromId, const QString& toId);
QList<PowerConnection*> getConnectionsForElement(const QString& elementId) const;
QList<PowerConnection*> getConnectionsForTerminal(const QString& terminalId) const;
void removeConnection(const QString& connId);
bool validateConnection(const QString& fromTermId, const QString& toTermId) const;
// 连接查询接口
QList<PowerConnection*> connectionsFrom(const QString& elementId) const;
QList<PowerConnection*> connectionsTo(const QString& elementId) const;
QList<PowerConnection*> getConnectionsFor(const QString& entityId) const;
PowerConnection* connection(const QString& conId) const;
void saveToDB(const QString& path);
void loadFromDB(const QString& path);
@ -46,10 +48,13 @@ public:
PowerTerminal* createTerminal(const QString& parentEntityId,
TerminalType type,
const QString& name,
const QPointF& relPos = QPointF());
const QPointF& relPos = QPointF(),
const QString& uuid = "");
bool deleteTerminal(const QString& terminalId);
PowerTerminal* getTerminal(const QString& terminalId) const;
QList<PowerTerminal*> getTerminalsForEntity(const QString& entityId) const;
PowerEntity* getEntityByTerminal(const QString& terminalId) const; //返回terminal所在的entity实体
PowerConnection* getConnectionContainsTerminal(const QString& terminalId) const; //返回包含terminal的connection
signals:
void entityCreated(const QString&);
void entityDeleted(const QString&);
@ -65,10 +70,12 @@ private:
// 连接存储
QHash<QString,PowerConnection*> m_connections;
QMultiHash<QString,PowerConnection*> m_connectionIndex; // 元素ID到连接的映射
QMultiHash<QString,PowerConnection*> m_connectionIndex; // 接线点ID到连接的映射
private:
QHash<QString, PowerTerminal*> m_allTerminals; // ID到接线点映射
QHash<QString, QList<PowerTerminal*>> m_terminalsByEntity; // 实体ID到接线点列表
QHash<QString, QSet<QString>> m_entityConnections; // <entityId, Set<connectionId>>
};
#endif

View File

@ -64,6 +64,9 @@ public:
void setSceneName(const QString& str) {m_sceneName = str;}
QString sceneName() const {return m_sceneName;}
FixedPortsModel* getModel() {return _model;}
void createTopoTerminals(GraphicsBaseItem*);
void updateConnectLineByTopology(QList<QGraphicsItem *>); //通过拓扑关系更新位置
signals:
void setWorkingSelector(SelectorType);

View File

@ -36,7 +36,6 @@ public:
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent*, DesignerScene*);
void setCreatingItem(modelStateInfo& info) { m_creatingItemInfo=info; }
private:
CreatingMethod m_creatingMethod;
modelStateInfo m_creatingItemInfo;

View File

@ -19,7 +19,7 @@ public:
explicit MovingSelector(FixedPortsModel* model,QObject *parent = 0);
virtual ~MovingSelector();
void updateConnectLine(QList<QGraphicsItem *>);
//void updateConnectLine(QList<QGraphicsItem *>);
public:
void mousePressEvent(QGraphicsSceneMouseEvent*, DesignerScene*);
void mouseMoveEvent(QGraphicsSceneMouseEvent*, DesignerScene*);

View File

@ -3,6 +3,8 @@
#include "mainwindow.h"
#include "dataBase.h"
#include "graphicsItem/graphicsBaseItem.h"
#include "topologyManager.h"
#include "powerEntity.h"
#include <QMdiSubWindow>
#include <QMessageBox>
#include <QJsonObject>
@ -24,14 +26,15 @@ void DiagramCavas::initial()
//onSignal_addDrawingPanel(QString("electricElements"));
}
void DiagramCavas::onSignal_addDrawingPanel(const QString& sTitile,DiagramMode mode)
void DiagramCavas::onSignal_addDrawingPanel(PowerEntity* pItem,DiagramMode mode)
{
DrawingPanel* pPanel = new DrawingPanel(this,mode);
_curPage = sTitile;
pPanel->setPageName(sTitile);
m_mapDrawPanel.insert(sTitile,pPanel);
pPanel->setWindowTitle(sTitile);
this->addSubWindow(pPanel);
DrawingPanel* pPanel = new DrawingPanel(pItem,this,mode);
_curPage = pItem->name();
pPanel->setPageName(_curPage);
pPanel->setWindowTitle(_curPage);
//->setAttribute(Qt::WA_DeleteOnClose);
QMdiSubWindow* pSub = this->addSubWindow(pPanel);
m_mapDrawPanel.insert(_curPage,qMakePair(pPanel,pSub));
pPanel->show();
FixedPortsModel* pModel = pPanel->getModel();
@ -41,6 +44,9 @@ void DiagramCavas::onSignal_addDrawingPanel(const QString& sTitile,DiagramMode m
void DiagramCavas::onSignal_addGraphicsItem(modelStateInfo& info)
{
QMdiSubWindow* actWindow = activeSubWindow();
if(!actWindow)
return;
QWidget* pWindow= currentSubWindow()->widget();
DrawingPanel* pPanel = dynamic_cast<DrawingPanel*>(pWindow);
@ -50,7 +56,7 @@ void DiagramCavas::onSignal_addGraphicsItem(modelStateInfo& info)
void DiagramCavas::onSignal_addPage()
{
onSignal_addDrawingPanel(QString("Page_")+QString::number(++_pageIndex));
//onSignal_addDrawingPanel(QString("Page_")+QString::number(++_pageIndex));
}
void DiagramCavas::onSignal_savePage()
@ -105,18 +111,18 @@ void DiagramCavas::onSignal_savePage()
}
}
void DiagramCavas::onSignal_loadPage(const QString& sName)
void DiagramCavas::onSignal_loadPage(PowerEntity* p)
{
if(!m_mapDrawPanel.contains(sName))
if(!m_mapDrawPanel.contains(p->name()))
{
//todo:加载数据
onSignal_addDrawingPanel(sName);
QJsonObject context = DataBase::GetInstance()->getPageContextByName(sName);
m_mapDrawPanel[sName]->loadNodes(context);
onSignal_addDrawingPanel(p);
QJsonObject context = DataBase::GetInstance()->getPageContextByName(p->name());
m_mapDrawPanel[p->name()].first->loadNodes(context);
}
else //已存在
{
m_mapDrawPanel[sName]->show();
m_mapDrawPanel[p->name()].first->show();
}
}
@ -125,13 +131,13 @@ void DiagramCavas::runPage(const QString sName)
QString pageName = sName+QString("_run");
if(!m_mapDrawPanel.contains(pageName))
{
onSignal_addDrawingPanel(pageName,DM_run);
//onSignal_addDrawingPanel(pageName,DM_run);
QJsonObject context = DataBase::GetInstance()->getPageContextByName(sName);
m_mapDrawPanel[pageName]->loadNodes(context);
//m_mapDrawPanel[pageName]->loadNodes(context);
}
else //已存在
{
m_mapDrawPanel[pageName]->show();
//m_mapDrawPanel[pageName]->show();
}
}
@ -152,7 +158,7 @@ void DiagramCavas::onSignal_activatePage(const QString& name)
void DiagramCavas::onSignal_panelDelete(const QString& name)
{
DrawingPanel* pPanel = m_mapDrawPanel.take(name);
DrawingPanel* pPanel = m_mapDrawPanel.take(name).first;
if(m_mapDrawPanel.isEmpty())
{
/*for(auto it = FixedPortsModel::_nodeData.begin();it!=FixedPortsModel::_nodeData.end();)
@ -166,3 +172,103 @@ void DiagramCavas::onSignal_panelDelete(const QString& name)
this->removeSubWindow(pPanel);
delete pPanel;
}
void DiagramCavas::onSignal_createEntity(EntityInfo info)
{
PowerEntity* pEntity;
pEntity = TopologyManager::instance().findEntity(info.sUuid);
if(!pEntity) //不存在创建
{
pEntity = TopologyManager::instance().createEntity(info.eType,info.sUuid,info.sName);
PowerEntity* pParent = TopologyManager::instance().findEntity(info.sParentId);
if(pParent) //构建父子关系
{
pParent->addChild(pEntity);
}
switch (info.eType){
case EntityType::Grid:
case EntityType::Zone:
case EntityType::Station:
break;
case EntityType::ConfigurationDiagram:
onSignal_addDrawingPanel(pEntity);
break;
default:
break;
}
}
}
void DiagramCavas::onSignal_changeEntity(EntityInfo info)
{
}
void DiagramCavas::onSignal_deleteEntity(EntityInfo info)
{
PowerEntity* pEntity = TopologyManager::instance().findEntity(info.sUuid);
if(pEntity)
{
switch (info.eType){
case EntityType::Grid:
case EntityType::Zone:
case EntityType::Station:
TopologyManager::instance().deleteEntity(info.sUuid);
break;
case EntityType::ConfigurationDiagram:
removePanel(pEntity);
TopologyManager::instance().deleteEntity(info.sUuid);
break;
default:
break;
}
}
}
void DiagramCavas::onSignal_selectEntity(EntityInfo info)
{
PowerEntity* pEntity = TopologyManager::instance().findEntity(info.sUuid);
if(pEntity)
{
if(info.eType == EntityType::ConfigurationDiagram)
{
PowerEntity* pEntity = TopologyManager::instance().findEntity(info.sUuid);
if(pEntity)
{
switch (info.eType){
case EntityType::Grid:
case EntityType::Zone:
case EntityType::Station:
break;
case EntityType::ConfigurationDiagram:
onSignal_loadPage(pEntity);
break;
default:
break;
}
}
}
}
}
void DiagramCavas::removePanel(PowerEntity* pEntity)
{
QMap<QString,QPair<DrawingPanel*,QMdiSubWindow*>>::Iterator iter;
for(iter = m_mapDrawPanel.begin(); iter != m_mapDrawPanel.end();++iter)
{
if(pEntity->name() == iter.value().first->pageName())
{
DrawingPanel* pPanel = m_mapDrawPanel.take(iter.key()).first;
QWidget* pWindow = static_cast<QWidget*>(pPanel);
setActiveSubWindow(iter->second);
closeActiveSubWindow();
//removeSubWindow(pPanel);
//todo记录删除组态图从数据库中删除
delete pPanel;
break;
}
}
}

View File

@ -2,22 +2,25 @@
#include "drawingPanel.h"
#include "ui_drawingPanel.h"
#include <QMessageBox>
#include <QCloseEvent>
#include "designerView.h"
#include "graphicsDataModel/fixedPortsModel.h"
#include "util/selectorManager.h"
#include "graphicsItem/electricConnectLineItem.h"
#include "statusBar.h"
#include "dataBase.h"
#include "powerEntity.h"
DrawingPanel::DrawingPanel(QWidget *parent,DiagramMode mode)
DrawingPanel::DrawingPanel(PowerEntity* pEntity,QWidget *parent,DiagramMode mode)
: QWidget(parent)
, ui(new Ui::drawingPanel)
,_pModel(nullptr)
,_mode(mode)
,_pEntity(pEntity)
{
ui->setupUi(this);
_pModel = new FixedPortsModel();
_pModel = new FixedPortsModel(pEntity);
_pModel->setTopWidget(this);
if(mode == DM_edit)
m_pSelectorManager = new SelectorManager(_pModel,this);
@ -144,6 +147,8 @@ void DrawingPanel::closeEvent(QCloseEvent *closeEvent)
pItem->unbindProperty();
}*/
emit panelDelete(_name);
//closeEvent->ignore();
//hide();
}
void DrawingPanel::onSignal_addGraphicsItem(modelStateInfo& info)

View File

@ -11,16 +11,19 @@
#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()
FixedPortsModel::FixedPortsModel(PowerEntity* pEntity)
:_scene(nullptr)
,_widget(nullptr)
,_Interface(nullptr)
,_pEntity(pEntity)
{
loadNodeDataFromDataBase();
_Interface = new HttpInterface(this);
@ -265,7 +268,7 @@ void FixedPortsModel::deleteNodeItem(GraphicsBaseItem* pItem)
auto pLine = dynamic_cast<ElectricConnectLineItem*>(pItem);
if(pLine)
{
Connection con = pLine->getConnection();
/*Connection con = pLine->getConnection();
GraphicsBaseItem* srcItem = _nodeItem[con.nSrcNodeId];
if(srcItem)
{
@ -287,12 +290,30 @@ void FixedPortsModel::deleteNodeItem(GraphicsBaseItem* pItem)
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();
/*QMap<QString,ItemPort*> ports = pItem->getPorts();
for(auto port:ports)
{
if(port->connected())
@ -307,7 +328,6 @@ void FixedPortsModel::deleteNodeItem(GraphicsBaseItem* pItem)
ItemPort* ptOppo = oppositeItem->getPortPtr(oppositePort);
ptOppo->disConnect();
oppositeItem->setItemChanged(true);
//oppositeItem->updateConnectData();
}
QUuid lineId = pLine->itemId();
@ -317,10 +337,26 @@ void FixedPortsModel::deleteNodeItem(GraphicsBaseItem* pItem)
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);
//pItem->updateConnectData();
_nodeItem.take(srcId);
_scene->removeItem(pItem);
delete pItem;
@ -549,6 +585,49 @@ 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];
@ -586,3 +665,8 @@ void FixedPortsModel::generatePropertyDlg(const QString& sModel)
}
}
}
ConfigurationDiagram* FixedPortsModel::getTopologyDiagram()
{
return dynamic_cast<ConfigurationDiagram*>(_pEntity);
}

View File

@ -376,7 +376,7 @@ void ElectricConnectLineItem::calculatePath()
m_boundingRect = m_points.boundingRect();
}
void ElectricConnectLineItem::updateConnection(QUuid callerId,QPointF pos)
/*void ElectricConnectLineItem::updateConnection(QUuid callerId,QPointF pos)
{
//qDebug()<<pos;
if(callerId == m_connectState.nSrcNodeId)
@ -386,12 +386,12 @@ void ElectricConnectLineItem::updateConnection(QUuid callerId,QPointF pos)
else
qDebug()<<"ConnectLine update err";
calculatePath();
}
}*/
QUuid ElectricConnectLineItem::getOppositeId(QUuid id)
/*QUuid ElectricConnectLineItem::getOppositeId(QUuid id)
{
if(id == m_connectState.nSrcNodeId)
return m_connectState.nDestNodeId;
else
return m_connectState.nSrcNodeId;
}
}*/

View File

@ -40,9 +40,9 @@ void ElectricSvgItemBus::updateConnectData()
if(ptr->connected())
{
QJsonObject port;
port["portId"] = ptr->getTag();
port["portId"] = ptr->getId();
auto pLine = ptr->getConnectPtr();
port["connectedItem"] = pLine->getOppositeId(m_itemId).toString();
//port["connectedItem"] = pLine->getOppositeId(m_itemId).toString();
port["x"] = ptr->pos().x();
port["y"] = ptr->pos().y();
arr.push_back(port);

View File

@ -1,5 +1,6 @@
#include "graphicsItem/electricSvgItemRect.h"
#include "graphicsItem/itemPort.h"
#include "global.h"
#include <QPainter>
#include <QStyleOption>
@ -18,7 +19,7 @@ ElectricSvgItemRect::ElectricSvgItemRect(const QRect &rect, QGraphicsItem *paren
setFunctionHandleEnaable(false);
//入线口
ItemPort* pHandle1 = new ItemPort(this);
/*ItemPort* pHandle1 = new ItemPort(this);
pHandle1->setType(T_lineIn);
pHandle1->setTag(H_connect);
pHandle1->setPortPos(P_top);
@ -32,10 +33,13 @@ ElectricSvgItemRect::ElectricSvgItemRect(const QRect &rect, QGraphicsItem *paren
pHandle2->setParent(this);
m_vecHanle.insert(H_connect+1,pHandle2);
m_mapPort.insert(QString::number(_portId++),pHandle1);
m_mapPort.insert(QString::number(_portId++),pHandle2);*/
m_dRatioX = 0.5;
m_mapPort.insert(QString::number(_portId++),pHandle1);
m_mapPort.insert(QString::number(_portId++),pHandle2);
addPort(P_const,QPointF(boundingRect().right() - boundingRect().width() * m_dRatioX, boundingRect().top()),QUuid::createUuid().toString(),T_lineIn,P_top);
addPort(P_const,QPointF(boundingRect().right() - boundingRect().width() * m_dRatioX, boundingRect().bottom()),QUuid::createUuid().toString(),T_lineOut,P_down);
qRegisterMetaType<PropertyInfo>("PropertyInfo"); //注册自定义数据类型
}
@ -49,7 +53,7 @@ ElectricSvgItemRect::~ElectricSvgItemRect()
void ElectricSvgItemRect::updateHandles()
{
ElectricSvgItem::updateHandles();
if( m_vecHanle.contains(H_connect))
/*if( m_vecHanle.contains(H_connect))
{
const QRectF& boundingRect = this->boundingRect();
@ -62,7 +66,7 @@ void ElectricSvgItemRect::updateHandles()
{
m_vecHanle[H_connect + 1]->move(boundingRect.right() - boundingRect.width() * m_dRatioX, boundingRect.bottom());
}
}
}*/
}
void ElectricSvgItemRect::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)

View File

@ -11,6 +11,7 @@
GraphicsBaseItem::GraphicsBaseItem(QGraphicsItem *parent)
: AbstractShapeType<QGraphicsItem>(parent)
,_property(nullptr)
,_pEntity(nullptr)
{
m_type = T_item;
_portId = 1;
@ -151,6 +152,16 @@ void GraphicsBaseItem::contextMenuEvent(QGraphicsSceneContextMenuEvent* event)
Q_UNUSED(event);
}
void GraphicsBaseItem::setEntity(PowerEntity* pEntity)
{
_pEntity = pEntity;
}
PowerEntity* GraphicsBaseItem::entity()
{
return _pEntity;
}
void GraphicsBaseItem::setLabelTag(const QString& name)
{
m_vecHanle[H_textCaption]->setText(name);
@ -181,7 +192,7 @@ QString GraphicsBaseItem::getLabelVoltage() const
return m_vecHanle[h_textVoltage]->getText();
}
int GraphicsBaseItem::addPort(PortState typ,QPointF vec)
int GraphicsBaseItem::addPort(PortState typ,QPointF vec,QString id,HandleType hType,PortPos pos)
{
int ntagId = -1;
for(ntagId = H_connect;ntagId < 999;++ntagId) //添加到未占用位置
@ -189,17 +200,30 @@ int GraphicsBaseItem::addPort(PortState typ,QPointF vec)
if(!m_vecHanle.contains(ntagId))
break;
}
ItemPort* pPort = new ItemPort(this);
if(id.isEmpty())
{
pPort->setId(QUuid::createUuid().toString());
}
else
{
pPort->setId(id);
}
if(typ == p_movable)
{
ItemPort* pPort = new ItemPort(this);
pPort->setType(T_lineInOut);
pPort->setTag(ntagId);
m_vecHanle.insert(ntagId,pPort);
pPort->setPos(vec);
pPort->setParent(this);
m_mapPort.insert(QString::number(_portId++),pPort);
}
else
{
pPort->setType(hType);
pPort->setPortPos(pos);
}
pPort->setTag(ntagId);
m_vecHanle.insert(ntagId,pPort);
pPort->setPos(vec);
pPort->setParent(this);
m_mapPort.insert(QString::number(_portId++),pPort);
return ntagId;
}
@ -275,9 +299,9 @@ void GraphicsBaseItem::updateConnectData()
if(ptr->connected())
{
QJsonObject port;
port["portId"] = ptr->getTag();
port["portId"] = ptr->getId();
auto pLine = ptr->getConnectPtr();
port["connectedItem"] = pLine->getOppositeId(m_itemId).toString();
//port["connectedItem"] = pLine->getOppositeId(m_itemId).toString();
arr.push_back(port);
}
}

View File

@ -2,8 +2,8 @@
#include "graphicsItem/itemPort.h"
#include "graphicsItem/handleRect.h"
ItemPort::ItemPort(QGraphicsItem *parent)
: HandleRect(parent)
ItemPort::ItemPort(QGraphicsItem *parent,QString uuid)
: HandleRect(parent),_uuid(uuid)
{
_pos = P_top;
_ptr = nullptr;

View File

@ -40,7 +40,10 @@ void ItemPropertyDlg::loadGroupButton(QMap<QString,groupStateInfo> map)
btn->setCheckable(true);
btnGroup_->addButton(btn);
btnMap_.insert(info.groupName, btn);
layout_->addWidget(btn);
if(info.isPublic) //公共属性组置顶
layout_->insertWidget(0,btn);
else
layout_->addWidget(btn);
connect(btn, &QAbstractButton::clicked, [this, info](){
onGroupSelected(info.groupName);

View File

@ -4,13 +4,18 @@ PowerTerminal::PowerTerminal(const QString& parentEntityId,
TerminalType type,
const QString& name,
const QPointF& relativePos,
const QString& uuid,
QObject* parent)
: QObject(parent),
m_id(QUuid::createUuid().toString()),
m_id(uuid),
m_parentEntityId(parentEntityId),
m_type(type),
m_name(name),
m_relativePosition(relativePos) {}
m_relativePosition(relativePos)
{
if(m_id.isEmpty())
m_id = QUuid::createUuid().toString();
}
void PowerTerminal::setRelativePosition(const QPointF& newPos) {
if (m_relativePosition != newPos) {
@ -38,7 +43,7 @@ PowerTerminal* PowerTerminal::fromJson(const QJsonObject& json, QObject* parent)
qreal x = json["relX"].toDouble();
qreal y = json["relY"].toDouble();
PowerTerminal* term = new PowerTerminal(parentId, type, name, QPointF(x, y), parent);
PowerTerminal* term = new PowerTerminal(parentId, type, name, QPointF(x, y),id, parent);
term->m_id = id; // 注意需要修改m_id为可写或使用其他机制保持ID一致
return term;
}

View File

@ -26,6 +26,8 @@ void TopologyManager::clearAllData()
// 删除所有实体(自动删除子对象)
qDeleteAll(m_entities);
m_entities.clear();
m_allTerminals.clear(); //端点由父亲entity释放
}
PowerEntity* TopologyManager::createEntity(EntityType type,const QString& uuid, const QString& name)
@ -60,7 +62,8 @@ bool TopologyManager::deleteEntity(const QString& id)
PowerEntity* entity = m_entities[id];
// 步骤1删除所有相关连接
auto relatedConns = m_connectionIndex.values(id);
auto relatedConns = getConnectionsFor(id);
for (auto conn : relatedConns) {
removeConnection(conn->id());
}
@ -88,8 +91,8 @@ bool TopologyManager::deleteEntity(const QString& id)
PowerConnection* TopologyManager::createConnection(const QString& connId,const QString& fromId, const QString& toId)
{
// 验证有效性
if (!m_entities.contains(fromId) ||
!m_entities.contains(toId) ||
if (!m_allTerminals.contains(fromId) ||
!m_allTerminals.contains(toId) ||
fromId == toId)
{
qWarning() << "Invalid connection endpoints";
@ -117,9 +120,9 @@ PowerConnection* TopologyManager::createConnection(const QString& connId,const Q
return conn;
}
QList<PowerConnection*> TopologyManager::getConnectionsForElement(const QString& elementId) const
QList<PowerConnection*> TopologyManager::getConnectionsForTerminal(const QString& terminalId) const
{
return m_connectionIndex.values(elementId);
return m_connectionIndex.values(terminalId);
}
void TopologyManager::removeConnection(const QString& connId)
@ -139,44 +142,96 @@ void TopologyManager::removeConnection(const QString& connId)
emit connectionRemoved(connId);
}
bool TopologyManager::validateConnection(const QString& fromTermId, const QString& toTermId) const
{
PowerTerminal* fromTerm = getTerminal(fromTermId);
PowerTerminal* toTerm = getTerminal(toTermId);
if (!fromTerm || !toTerm) return false;
// 类型兼容性检查(示例规则)
switch(fromTerm->type()) {
case TerminalType::PowerOutput:
if (toTerm->type() != TerminalType::PowerInput && toTerm->type() != TerminalType::PowerConnect) return false;
break;
case TerminalType::PowerInput:
if (toTerm->type() != TerminalType::PowerOutput && toTerm->type() != TerminalType::PowerConnect) return false;
break;
case TerminalType::PowerConnect:
break;
case TerminalType::ControlSignal:
if (toTerm->type() != TerminalType::ControlSignal) return false;
break;
default:
return false;
}
int a =1;
// 禁止自连接
return (fromTerm->parentEntityId() != toTerm->parentEntityId());
}
// 连接查询接口
QList<PowerConnection*> TopologyManager::connectionsFrom(const QString& elementId) const
{
QList<PowerConnection*> res;
QList<PowerConnection*> lst = m_connectionIndex.values(elementId);
/*QList<PowerConnection*> lst = m_connectionIndex.values(elementId);
for(auto &val:lst)
{
if(val->fromTerminalId() == elementId)
res.append(val);
}
}*/
return res;
}
QList<PowerConnection*> TopologyManager::connectionsTo(const QString& elementId) const
{
QList<PowerConnection*> res;
QList<PowerConnection*> lst = m_connectionIndex.values(elementId);
/*QList<PowerConnection*> lst = m_connectionIndex.values(elementId);
for(auto &val:lst)
{
if(val->toTerminalId() == elementId)
res.append(val);
}
}*/
return res;
}
QList<PowerConnection*> TopologyManager::getConnectionsFor(const QString& entityId) const
{
return m_connectionIndex.values(entityId);
QList<PowerConnection*> lst;
QList<PowerTerminal*> lstTerminal = getTerminalsForEntity(entityId);
for(auto &terminal:lstTerminal)
{
PowerConnection* con = getConnectionContainsTerminal(terminal->id());
if(con)
lst.append(con);
}
return lst;
}
PowerConnection* TopologyManager::connection(const QString& conId) const
{
return m_connections.value(conId,nullptr);
}
void TopologyManager::saveToDB(const QString& path)
{
QJsonObject root;
QJsonArray entitiesArray;
for (auto entity : m_entities)
entitiesArray.append(entity->toJson());
root["entities"] = entitiesArray;
// 序列化实体(含接线点)
QJsonArray entities;
foreach (auto entity, m_entities) {
QJsonObject entObj = entity->toJson();
QJsonArray terminalsArray;
foreach (auto term, entity->terminals()) {
terminalsArray.append(term->toJson());
}
entObj["terminals"] = terminalsArray;
entities.append(entObj);
}
root["entities"] = entities;
QJsonArray connectionsArray;
for (auto conn : m_connections)
@ -209,6 +264,12 @@ void TopologyManager::loadFromDB(const QString& path)
PowerEntity* entity = createEntity(type, id, name);
foreach (auto termJson, entObj["terminals"].toArray()) {
PowerTerminal* term = PowerTerminal::fromJson(termJson.toObject(), entity);
m_allTerminals[term->id()] = term;
m_terminalsByEntity[entity->id()].append(term);
}
// 记录待处理的子关系
pendingChildren[id] = entObj["children"].toVariant().toStringList();
}
@ -259,10 +320,11 @@ QList<PowerEntity*> TopologyManager::findEntitiesByName(const QString& name) con
PowerTerminal* TopologyManager::createTerminal(const QString& parentEntityId,
TerminalType type,
const QString& name,
const QPointF& relPos) {
const QPointF& relPos,
const QString& uuid) {
if (!m_entities.contains(parentEntityId)) return nullptr;
PowerTerminal* term = new PowerTerminal(parentEntityId, type, name, relPos);
PowerTerminal* term = new PowerTerminal(parentEntityId, type, name, relPos, uuid);
m_allTerminals[term->id()] = term;
m_terminalsByEntity[parentEntityId].append(term);
@ -293,6 +355,40 @@ bool TopologyManager::deleteTerminal(const QString& terminalId) {
return true;
}
PowerTerminal* TopologyManager::getTerminal(const QString& terminalId) const
{
auto it = m_allTerminals.find(terminalId);
return (it != m_allTerminals.end()) ? it.value() : nullptr;
}
QList<PowerTerminal*> TopologyManager::getTerminalsForEntity(const QString& entityId) const {
return m_terminalsByEntity.value(entityId);
}
PowerEntity* TopologyManager::getEntityByTerminal(const QString& terminalId) const
{
QHash<QString, QList<PowerTerminal*>>::ConstIterator iter;
for(iter = m_terminalsByEntity.begin();iter != m_terminalsByEntity.end();++iter)
{
for(auto &terminal:iter.value())
{
if(terminal->id() == terminalId)
{
return m_entities[iter.key()];
}
}
}
return nullptr;
}
PowerConnection* TopologyManager::getConnectionContainsTerminal(const QString& terminalId) const
{
for(auto &con:m_connections)
{
if(con->fromTerminalId() == terminalId || con->toTerminalId() == terminalId)
{
return con;
}
}
return nullptr;
}

View File

@ -4,8 +4,11 @@
#include <QDebug>
#include "graphicsItem/graphicsBaseItem.h"
#include "graphicsItem/handleText.h"
#include "powerEntity.h"
#include "topologyManager.h"
#include "graphicsItem/itemPort.h"
#include "graphicsItem/electricConnectLineItem.h"
#include "topologyManager.h"
QPointF BaseSelector::ms_ptMouseDown(0.0,0.0);
QPointF BaseSelector::ms_ptMouseLast(0.0,0.0);
@ -386,3 +389,68 @@ void BaseSelector::setCursor(DesignerScene *scene, const QCursor &cursor)
view->setCursor(cursor);
}
void BaseSelector::createTopoTerminals(GraphicsBaseItem* pItem)
{
PowerEntity* pEntity = pItem->entity();
if(pEntity)
{
QMap<QString,ItemPort*> mapPorts = pItem->getPorts(); //创建对应
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;
}
TopologyManager::instance().createTerminal(pEntity->id(),terType,"",port->pos(),port->getId());
}
}
}
void BaseSelector::updateConnectLineByTopology(QList<QGraphicsItem *> lst)
{
for(auto iter:lst) //更新连接线
{
auto item = dynamic_cast<GraphicsBaseItem*>(iter);
if(item)
{
if(item->getItemType() != GIT_link) //获取非电缆对象
{
QUuid nId = item->itemId();
auto lstConnect = TopologyManager::instance().getConnectionsFor(nId.toString());
for(auto &pConnect:lstConnect)
{
if(pConnect)
{
QString fromTerminalId = pConnect->fromTerminalId(); //connect自身包含头尾巴顺序
QString toTerminalId = pConnect->toTerminalId();
QPointF fromPos = _model->getTerminalPos(fromTerminalId);
QPointF toPos = _model->getTerminalPos(toTerminalId);
ElectricConnectLineItem* connectItem = _model->getLineItemById(fromTerminalId);
if(connectItem)
{
connectItem->setStartPoint(fromPos);
connectItem->setEndPoint(toPos);
//qDebug()<<nId<<"start:"<<fromPos.x()<<","<<fromPos.y()<<"end:"<<toPos.x()<<","<<toPos.y();
connectItem->calculatePath();
}
}
}
}
}
}
}

View File

@ -2,6 +2,7 @@
#include "graphicsItem/itemControlHandle.h"
#include "graphicsItem/itemPort.h"
#include "graphicsItem/electricConnectLineItem.h"
#include "topologyManager.h"
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsView>
#include <graphicsItem/graphicsBaseItem.h>
@ -88,18 +89,20 @@ void ConnectingSelector::setTargetHighLight(bool val)
void ConnectingSelector::createConnectLline(GraphicsBaseItem* connectingItem,GraphicsBaseItem* touchedItem,DesignerScene* scene)
{
QUuid uid = QUuid::createUuid();
ElectricConnectLineItem* pItem = new ElectricConnectLineItem();
pItem->setItemId(QUuid::createUuid());
pItem->setItemId(uid);
pItem->setItemType(GIT_link);
scene->addItem(pItem);
ItemPort* ptSrc = connectingItem->getPortPtr(ms_nDragHandle);
QUuid srcId = connectingItem->itemId();
int srcPort = ptSrc->getTag();
HandleType srcType = ptSrc->getType();
PortPos srcPos = ptSrc->portPos();
//QUuid srcId = connectingItem->itemId();
//int srcPort = ptSrc->getTag();
//HandleType srcType = ptSrc->getType();
//PortPos srcPos = ptSrc->portPos();
pItem->setStartPoint(ptSrc->scenePos());
ptSrc->setConnect(pItem);
QString srcPortId = ptSrc->getId(); //port自身id
ItemPort* ptDest = nullptr;
if(touchedItem->getItemType() == GIT_bus) //母线动态创建port
@ -110,6 +113,8 @@ void ConnectingSelector::createConnectLline(GraphicsBaseItem* connectingItem,Gra
ptDest = touchedItem->getPortPtr(nId);
pItem->setEndPoint(ptDest->scenePos());
}
createTopoTerminals(touchedItem); //创建port时创建对应的terminal
}
else
{
@ -120,14 +125,18 @@ void ConnectingSelector::createConnectLline(GraphicsBaseItem* connectingItem,Gra
if(ptDest != nullptr)
{
QUuid destId = touchedItem->itemId();
int destPort = ptDest->getTag();
HandleType destType = ptDest->getType();
PortPos destPos = ptDest->portPos();
//QUuid destId = touchedItem->itemId();
//int destPort = ptDest->getTag();
//HandleType destType = ptDest->getType();
//PortPos destPos = ptDest->portPos();
QString destPortId = ptDest->getId(); //port自身id
pItem->calculatePath();
pItem->setConnection(Connection(srcId,srcPort,srcType,srcPos,destId,destPort,destType,destPos));
ptDest->setConnect(pItem);
//pItem->calculatePath();
//pItem->setConnection(Connection(srcId,srcPort,srcType,srcPos,destId,destPort,destType,destPos));
//ptDest->setConnect(pItem);
if(TopologyManager::instance().validateConnection(srcPortId,destPortId))
TopologyManager::instance().createConnection(uid.toString(),srcPortId,destPortId); //创建拓扑连接(逻辑)
_model->addNodeItem(pItem->itemId(),pItem);
auto srcParent = ptSrc->getParentPtr();
@ -135,9 +144,6 @@ void ConnectingSelector::createConnectLline(GraphicsBaseItem* connectingItem,Gra
srcParent->setItemChanged(true);
destParent->setItemChanged(true);
//srcParent->updateConnectData();
//destParent->updateConnectData();
//m_graphicsItem[sceneName()].insert(QString::number(pItem->itemId()),pItem); //插入连接线到总表
}
}
@ -152,7 +158,7 @@ void ConnectingSelector::mouseMoveEvent(QGraphicsSceneMouseEvent* event, Designe
GraphicsBaseItem* item = qgraphicsitem_cast<GraphicsBaseItem*>(items.first());
if(item)
{
if(ms_nDragHandle >= H_connect)
if(ms_nDragHandle >= H_connect) //操作的是port端点
{
ItemPort* pt = item->getPortPtr(ms_nDragHandle);
if(pt)
@ -215,6 +221,10 @@ void ConnectingSelector::mouseReleaseEvent(QGraphicsSceneMouseEvent* event, Desi
if(m_pConnectingItem && m_pTouchedItem)
{
createConnectLline(m_pConnectingItem,m_pTouchedItem,scene);
auto obj = dynamic_cast<QGraphicsItem*>(m_pConnectingItem);
QList<QGraphicsItem*> lst;
lst.append(obj);
updateConnectLineByTopology(lst);
}
}

View File

@ -4,6 +4,9 @@
#include "graphicsItem/electricSvgItemBus.h"
#include "graphicsItem/electricSvgItemRect.h"
#include "graphicsItem/electricSvgItemTriangle.h"
#include "graphicsItem/itemPort.h"
#include "topologyManager.h"
#include "global.h"
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsView>
#include <QGraphicsSvgItem>
@ -30,6 +33,8 @@ void CreatingSelector::mousePressEvent(QGraphicsSceneMouseEvent* event, Designer
ms_ptMouseDown = event->scenePos();
ms_ptMouseLast = event->scenePos();
QUuid uuid = QUuid::createUuid();
EntityInfo info;
if(m_pCreatingItem == nullptr)
{
scene->clearSelection();
@ -58,27 +63,29 @@ void CreatingSelector::mousePressEvent(QGraphicsSceneMouseEvent* event, Designer
{
m_creatingMethod = CM_click;
m_pCreatingItem = new ElectricSvgItemBus(QRect(-100, -3, 200, 6));
m_pCreatingItem->setItemId(QUuid::createUuid());
m_pCreatingItem->setItemId(uuid);
m_pCreatingItem->setItemType(GIT_bus);
m_pCreatingItem->editShape(ms_nDragHandle, ms_ptMouseLast);
emit setWorkingSelector(ST_base);
info.eType = EntityType::BusBar;
}
break;
case GIT_itemRect:
{
m_creatingMethod = CM_click;
m_pCreatingItem = new ElectricSvgItemRect(QRect(-15, -15, 30, 30));
m_pCreatingItem->setItemId(QUuid::createUuid());
m_pCreatingItem->setItemId(uuid);
m_pCreatingItem->setItemType(GIT_itemRect);
m_pCreatingItem->editShape(ms_nDragHandle, ms_ptMouseLast);
emit setWorkingSelector(ST_base);
info.eType = EntityType::CircuitBreaker;
}
break;
case GIT_itemTri:
{
m_creatingMethod = CM_click;
m_pCreatingItem = new ElectricSvgItemTriangle(QRect(-15, -15, 30, 30));
m_pCreatingItem->setItemId(QUuid::createUuid());
m_pCreatingItem->setItemId(uuid);
m_pCreatingItem->setItemType(GIT_itemTri);
m_pCreatingItem->editShape(ms_nDragHandle, ms_ptMouseLast);
emit setWorkingSelector(ST_base);
@ -103,6 +110,17 @@ void CreatingSelector::mousePressEvent(QGraphicsSceneMouseEvent* event, Designer
else if(m_creatingMethod == CM_click)
m_pCreatingItem->addPoint(ms_ptMouseDown);
}
else{
qDebug()<<"item type error";
return;
}
info.sUuid = uuid.toString();
PowerEntity* pEntity = TopologyManager::instance().createEntity(info.eType,info.sUuid,info.sName);
if(pEntity)
m_pCreatingItem->setEntity(pEntity);
createTopoTerminals(m_pCreatingItem);
}
if(m_pCreatingItem && m_creatingMethod == CM_click)

View File

@ -3,7 +3,6 @@
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsView>
#include <graphicsItem/graphicsBaseItem.h>
#include "graphicsItem/electricConnectLineItem.h"
MovingSelector::MovingSelector(FixedPortsModel* model,QObject *parent)
: BaseSelector(model,parent)
@ -20,7 +19,8 @@ void MovingSelector::mousePressEvent(QGraphicsSceneMouseEvent* event, DesignerSc
ms_ptMouseLast = event->scenePos();
QList<QGraphicsItem *> items = scene->selectedItems();
updateConnectLine(items);
//updateConnectLine(items);
updateConnectLineByTopology(items);
}
void MovingSelector::mouseMoveEvent(QGraphicsSceneMouseEvent* event, DesignerScene* scene)
@ -45,14 +45,15 @@ void MovingSelector::mouseReleaseEvent(QGraphicsSceneMouseEvent* event, Designer
if(item)
item->removeOperationCopy();
}
updateConnectLine(items);
//updateConnectLine(items);
updateConnectLineByTopology(items);
setCursor(scene, Qt::ArrowCursor);
scene->callParentEvent(event);
emit setWorkingSelector(ST_base);
}
void MovingSelector::updateConnectLine(QList<QGraphicsItem *> lst)
/*void MovingSelector::updateConnectLine(QList<QGraphicsItem *> lst)
{
for(auto iter:lst) //更新连接线
{
@ -73,5 +74,5 @@ void MovingSelector::updateConnectLine(QList<QGraphicsItem *> lst)
}
}
}
}
}*/

View File

@ -34,8 +34,6 @@
</property>
</layout>
</widget>
<resources>
<include location="../resource/DiagramDesigner.qrc"/>
</resources>
<resources/>
<connections/>
</ui>

View File

@ -64,6 +64,7 @@ public:
bool getModelGroup(); //获取模型组
bool getAttribute(); //获取属性
bool getModelAttribute(); //获取模型-属性对照组
bool getModelAttributePublic(); //获取公共属性组
bool getModelConnectivity(); //获取连接性
QMap<int,attributeGroup> AttributeGroup() const {return _attributeGroup;}
@ -72,16 +73,19 @@ public:
QMap<int,modelGroup> ModelGroup() const {return _modelGroup;}
QMap<int,attribute> Attribute() const {return _attribute;}
QMap<int,modelAttribute> ModelAttribute() const {return _modelAttribute;}
QMap<int,modelAttributePublic> ModelAttributePublic() const {return _modelAttributePublic;}
QMap<int,modelConnectivity> ModelConnectivity() const {return _modelConnectivity;}
//***********工程模
bool createProjectManager(); //生成记录表,包含工程模名称,属性组名,启用和关闭的属性字段(json类型)[一个属性组建一个表]
bool insertProjectManager(const QString& name,const QString& tag,const QString& metaModel,const QString& groupName,int linkType,QJsonObject checkState);
bool insertProjectManager(const QString& name,const QString& tag,const QString& metaModel,const QString& groupName,int linkType,QJsonObject checkState,bool isPublic = false);
bool updateCheckState(const QString& tableName,QJsonObject checkState); //更新属性选中状态
QMap<QString,int> getProjectFromManager(const QString& sMeta); //返回元模下已创建的工程名
QMap<QString,QJsonObject> getCheckStateFromManager(const QString& sProject); //获取当前工程模型所有属性的选择状态 <属性名,选择状态>
QMap<QString,QJsonObject> getPublicStateFromManager(); //获取公共属性组
QMap<QString,QString> getProjectTableName(const QString& sProject); //获取当前工程模型下所有表信息
bool createDynamicTable(const QString&, const QStringList&);
bool deleteProjectModel(const QString&);
bool ifDynamicTableExist(const QString&); //动态表是否存在
bool updateProjectName(const QString& newTable,const QString& newPro,const QString& oldTable); //更新mangager工程模名称
bool alterTableName(const QString& oldTable,const QString& newTable); //修改表名
bool updateComponentModelName(const QString& strOld,const QString& strNew); //修改component中的模型名
@ -94,6 +98,7 @@ public:
//**********使用工程模
QMap<QString,int> getAllProjectModel(); //获取所有工程模<名称,图元类型>
QMap<QString,propertyGroupState> getModelInfo(const QString&); //获取模型信息
QMap<QString,propertyGroupState> getPublicInfo(); //获取公共属性组信息
QMap<QString,projectManager> getProjectModelGroupInfo(const QString&); //获取指定工程模所有属性组信息<属性组名,属性信息>
QMap<QUuid,PropertyValueInfo> selectGroupProperty(const QString& tableName,QMap<QString,propertyStateInfo> mapPro); //返回属性组表中的信息
private:
@ -103,6 +108,7 @@ private:
QMap<int,modelGroup> _modelGroup; //模型组
QMap<int,attribute> _attribute; //属性组
QMap<int,modelAttribute> _modelAttribute; //模型-属性对照组
QMap<int,modelAttributePublic> _modelAttributePublic; //公共属性组
QMap<int,modelConnectivity> _modelConnectivity; //连接性组
private:
void initial();

View File

@ -20,8 +20,8 @@ public:
static DataManager& instance();
public:
void initialModelState();
void initialModelData();
void initialModelState(bool refresh = false);
void initialModelData(bool refresh = false);
void updateModelData(const QString& sModel,QUuid uuid,const QString& sGroup,QMap<QString,propertyStateInfo> mapPro);

View File

@ -4,6 +4,7 @@
#include <QObject>
#include <QFile>
#include <QDateTime>
#include "export.hpp"
// 日志宏定义
#define LOG(level, module, message) Logger::instance().log(Logger::level, module, message)
@ -13,7 +14,7 @@
#define LOG_ERROR(module, message) LOG(ERROR, module, message)
#define LOG_FATAL(module, message) LOG(FATAL, module, message)
class Logger : public QObject
class DIAGRAM_DESIGNER_PUBLIC Logger : public QObject
{
Q_OBJECT

View File

@ -56,6 +56,7 @@ void DataBase::initial()
getModelGroup(); //获取模型组
getAttribute(); //获取属性
getModelAttribute();
getModelAttributePublic(); //获取公共属性组
getModelConnectivity(); //获取连接性
}
@ -966,7 +967,7 @@ bool DataBase::getAttributeGroup()
int id = query.value(0).toInt();
QString groupType = query.value(1).toString();
QString groupName = query.value(2).toString();
int isPublic = query.value(3).toInt();
int ispublic = query.value(3).toInt();
QString remark = query.value(4).toString();
if(!_attributeGroup.contains(id))
@ -975,7 +976,7 @@ bool DataBase::getAttributeGroup()
ag.id = id;
ag.groupType = groupType;
ag.groupName = groupName;
ag.isPublic = isPublic;
ag.ispublic = ispublic;
ag.remark = remark;
_attributeGroup.insert(id,ag);
}
@ -1120,6 +1121,38 @@ bool DataBase::getModelAttribute()
}
}
bool DataBase::getModelAttributePublic()
{
QString strSQL = "SELECT * FROM basic.model_attribute_public";
try
{
QSqlQuery query = executeSQL(strSQL);
while (query.next())
{
int id = query.value(0).toInt();
qint64 agi = query.value(1).toLongLong();
qint64 ai = query.value(2).toLongLong();
if(!_modelAttributePublic.contains(id))
{
modelAttributePublic ma;
ma.id = id;
ma.attributeGroupId = agi;
ma.attributeId = ai;
_modelAttributePublic.insert(id,ma);
}
}
query.finish();
return true;
}
catch (const std::exception& e)
{
return false;
}
}
bool DataBase::getAttribute()
{
QString strSQL = "SELECT * FROM basic.attribute";
@ -1208,7 +1241,8 @@ bool DataBase::createProjectManager()
meta_model VARCHAR(64) NOT NULL,
group_name VARCHAR(64) NOT NULL,
link_type integer NOT NULL DEFAULT 0,
check_state JSONB NOT NULL DEFAULT '{}'::jsonb
check_state JSONB NOT NULL DEFAULT '{}'::jsonb,
"ispublic" boolean NOT NULL DEFAULT false
);
)";
@ -1245,9 +1279,9 @@ bool DataBase::createProjectManager()
}*/
}
bool DataBase::insertProjectManager(const QString& name,const QString& tag,const QString& metaModel,const QString& groupName,int linkType,QJsonObject checkState)
bool DataBase::insertProjectManager(const QString& name,const QString& tag,const QString& metaModel,const QString& groupName,int linkType,QJsonObject checkState,bool ispublic)
{
QString strSQL = "INSERT INTO project_manager(name, tag, meta_model, group_name, link_type, check_state) VALUES (?, ?, ?, ?, ?, ?)";
QString strSQL = "INSERT INTO project_manager(name, tag, meta_model, group_name, link_type, check_state, ispublic) VALUES (?, ?, ?, ?, ?, ?, ?)";
QJsonDocument checkDoc(checkState);
QString strCheck = checkDoc.toJson(QJsonDocument::Compact);
@ -1258,6 +1292,7 @@ bool DataBase::insertProjectManager(const QString& name,const QString& tag,const
params.append(groupName);
params.append(linkType);
params.append(strCheck);
params.append(ispublic);
try
{
executeSQL(strSQL,false,params);
@ -1348,6 +1383,34 @@ QMap<QString,QJsonObject> DataBase::getCheckStateFromManager(const QString& sPro
}
}
QMap<QString,QJsonObject> DataBase::getPublicStateFromManager()
{
QMap<QString,QJsonObject> map;
bool ispublic = true;
QString strSQL = "SELECT group_name, check_state FROM project_manager WHERE ispublic = ?";
QVariantList params;
params.append(ispublic);
try
{
QSqlQuery query = executeSQL(strSQL,false,params);
while (query.next())
{
QString group = query.value(0).toString();
QString state = query.value(1).toString();
QJsonObject jsonObj = QstringToJson(state);
map.insert(group,jsonObj);
}
query.clear();
return map;
}
catch (const std::exception& e)
{
return map;
}
}
QMap<QString,QString> DataBase::getProjectTableName(const QString& sProject)
{
QMap<QString,QString> map;
@ -1376,7 +1439,7 @@ QMap<QString,QString> DataBase::getProjectTableName(const QString& sProject)
QMap<QString,int> DataBase::getAllProjectModel()
{
QMap<QString,int> map; //工程模名,类型
QString strSQL = "SELECT tag, MAX(link_type) AS link_type FROM project_manager GROUP BY tag";
QString strSQL = "SELECT tag, MAX(link_type) AS link_type,ispublic FROM project_manager GROUP BY tag,ispublic";
try
{
@ -1385,7 +1448,9 @@ QMap<QString,int> DataBase::getAllProjectModel()
{
QString tableName = query.value(0).toString();
int linkType = query.value(1).toInt();
map.insert(tableName,linkType);
bool ispublic = query.value(2).toBool();
if(!ispublic)
map.insert(tableName,linkType);
}
query.clear();
return map;
@ -1423,6 +1488,34 @@ QMap<QString,propertyGroupState> DataBase::getModelInfo(const QString& sProject)
}
}
QMap<QString,propertyGroupState> DataBase::getPublicInfo()
{
QMap<QString,propertyGroupState> map;
bool ispublic = true;
QString strSQL = "SELECT group_name,name,check_state FROM project_manager WHERE ispublic = ?";
QVariantList params;
params.append(ispublic);
try
{
QSqlQuery query = executeSQL(strSQL,false,params);
while (query.next())
{
propertyGroupState sta;
sta.groupName = query.value(0).toString();
sta.tableName = query.value(1).toString();
sta.propertyState = QstringToJson(query.value(2).toString());
map.insert(sta.groupName,sta);
}
query.clear();
return map;
}
catch (const std::exception& e)
{
return map;
}
}
QMap<QString,projectManager> DataBase::getProjectModelGroupInfo(const QString& sTable)
{
QMap<QString,projectManager> map;
@ -1476,11 +1569,15 @@ QMap<QUuid,PropertyValueInfo> DataBase::selectGroupProperty(const QString& table
for(auto &proVal:mapPro)
{
propertyStateInfo pro;
if(proVal.name == "global_uuid") //剔除uuid所属的临时对象
if(proVal.name == "global_uuid" && tableName != "baseProperty") //除基础属性组其他组不显示uuid todo:组名适配
{
uuid = QUuid(query.value(proVal.name).toString());
continue;
}
else if(proVal.name == "global_uuid" && tableName == "baseProperty")
{
uuid = QUuid(query.value(proVal.name).toString());
}
pro.name = proVal.name;
pro.type = proVal.type;
pro.defaultValue = query.value(proVal.name );
@ -1583,7 +1680,26 @@ bool DataBase::deleteProjectModel(const QString& sProject)
LOG_ERROR("DB", QString("Delete row %1 failed").arg(sProject));
return false;
}
}
bool DataBase::ifDynamicTableExist(const QString& sTable)
{
QStringList lstTable;
QString strSQL = "SELECT name FROM project_manager WHERE name = ?";
QVariantList params;
params.append(sTable);
try
{
QSqlQuery query = executeSQL(strSQL,false,params);
while (query.next())
{
return true;
}
}
catch (const std::exception& e)
{
return false;
}
}
bool DataBase::updateProjectName(const QString& newTable,const QString& newPro,const QString& oldTable)

View File

@ -21,10 +21,18 @@ DataManager::~DataManager()
}
void DataManager::initialModelState()
void DataManager::initialModelState(bool refresh)
{
QMap<QString,int> model = DataBase::GetInstance()->getAllProjectModel();
if(refresh)
{
for(auto &info:_modelStateInfo)
{
info.release();
}
_modelStateInfo.clear();
}
QMap<QString,int>::Iterator iter;
for(iter = model.begin();iter != model.end(); ++iter) //遍历模型
{
@ -33,8 +41,40 @@ void DataManager::initialModelState()
modelInfo.modelName = iter.key();
QMap<QString,propertyGroupState> mapState = DataBase::GetInstance()->getModelInfo(iter.key());
QMap<QString,propertyGroupState> mapPublic = DataBase::GetInstance()->getPublicInfo(); //公共属性组
QMap<QString,propertyGroupState>::Iterator it;
for(it = mapPublic.begin();it != mapPublic.end();++it) //遍历公共属性组
{
groupStateInfo groupInfo;
groupInfo.groupName = it.key();
groupInfo.tableName = it->tableName;
groupInfo.isPublic = true;
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();
QVariant defaultValue = node["defaultValue"].toVariant();
int lengthPrecision = node["lengthPrecision"].toInt();
if(nState)
{
propertyInfo.name = propertyName;
propertyInfo.type = dataType;
propertyInfo.defaultValue = defaultValue;
propertyInfo.lengthPrecision = lengthPrecision;
groupInfo.info.insert(propertyName,propertyInfo);
}
}
modelInfo.groupInfo.insert(it.key(),groupInfo);
}
for(it = mapState.begin();it != mapState.end();++it) //遍历模型属性组
{
groupStateInfo groupInfo;
@ -65,15 +105,19 @@ void DataManager::initialModelState()
}
modelInfo.groupInfo.insert(it.key(),groupInfo);
}
_modelStateInfo.insert(iter.key(),modelInfo);
}
_stateInitialised = true;
}
void DataManager::initialModelData()
void DataManager::initialModelData(bool refresh)
{
QMap<QString,int> model = DataBase::GetInstance()->getAllProjectModel();
if(refresh)
{
_modleDataInfo.clear();
}
QMap<QString,int>::Iterator iter;
for(iter = model.begin();iter != model.end(); ++iter) //遍历模型
{
@ -82,8 +126,46 @@ void DataManager::initialModelData()
modelInfo.modelName = iter.key();
QMap<QString,propertyGroupState> mapState = DataBase::GetInstance()->getModelInfo(iter.key());
QMap<QString,propertyGroupState> mapPublic = DataBase::GetInstance()->getPublicInfo(); //公共属性组
QMap<QString,propertyGroupState>::Iterator it;
for(it = mapPublic.begin();it != mapPublic.end();++it) //遍历公共属性组
{
groupStateValue groupValue;
groupValue.groupName = it.key();
groupValue.tableName = it->tableName;
QJsonArray nodesJsonArray = it->propertyState["checkState"].toArray();
QMap<QString,propertyStateInfo> mapPro;
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();
QVariant defaultValue = node["defaultValue"].toVariant();
propertyInfo.name = propertyName;
propertyInfo.type = dataType;
if(nState)
{
mapPro.insert(propertyName,propertyInfo);
}
}
if(!mapPro.contains("global_uuid")) //不包含uuid则手动添加
{
propertyStateInfo uuidInfo;
uuidInfo.name = "global_uuid"; //全局id未添加到属性状态中手动添加
mapPro.insert("global_uuid",uuidInfo);
}
groupValue.mapInfo = DataBase::GetInstance()->selectGroupProperty(it->tableName,mapPro); //返回表中属性值
modelInfo.groupInfo.insert(it.key(),groupValue);
}
for(it = mapState.begin();it != mapState.end();++it) //遍历模型属性组
{
groupStateValue groupValue;
@ -135,6 +217,8 @@ ModleStateMap& DataManager::modelState()
{
if(!_stateInitialised)
initialModelState();
else
initialModelState(true);
return _modelStateInfo;
}
@ -142,5 +226,7 @@ ModelDataMap& DataManager::modelData()
{
if(!_dataInitialised)
initialModelData();
else
initialModelData(true);
return _modleDataInfo;
}

View File

@ -26,6 +26,7 @@ signals:
void addEletricItem(modelStateInfo&);
public slots:
void onSignal_addEletricItem(modelStateInfo&);
void onSignal_modelChanged();
private:
ToolBox* m_pToolBox;
QMap<QString,ElectricElementsPanel*> m_mapPanels;

View File

@ -19,6 +19,7 @@ class DiagramCavas;
class ElectricElementsBox;
class LoadPageDlg;
class projectModelDlg;
class TopologyView;
class CMainWindow : public QMainWindow
{
@ -66,6 +67,7 @@ private:
DiagramCavas* m_pDiagramCavas;
DrawingPanel* m_pDrawingPanel;
ElectricElementsBox* m_pElectricElementsBox;
TopologyView* m_pTopologyView;
GraphicElementsPanel* m_pGraphicElementsPanel;
LoadPageDlg* m_pLoadPageDlg;
projectModelDlg* m_pProjectModelDlg;

View File

@ -30,11 +30,13 @@ struct PropertyState //每个属性的状态
{
bool checkState = false;
QString dataType;
bool editable = true; //可勾选状态
};
struct PropertyPage //属性信息
{
QMap<QString,PropertyState> mCheckState; //属性选择状态
bool isPublic = false;
};
typedef QMap<QString,PropertyPage> MapProperty; //属性组
@ -85,7 +87,9 @@ public slots:
public:
QStringList getModelList() const; //获取元模型列表
QStringList getGroupList(const QString& model) const; //返回该元模下的属性组列表
QStringList getPublicGroupList() const; //返回公共属性组列表
QStringList getAttributeList(const QString& model,const QString& group) const; //根据元模名和组名返回属性列表
QStringList getPublicAttributeList(const QString& group); //返回公共属性组的属性列表
void setItemAttribute(const QString&,QStandardItem*); //设置item的属性(数据库表字段名)
QPair<QString,QString> combinePropertySql(const QStandardItem*); //根据item属性生成sql
QString getProjectName() const; //返回当前选择项目的名称
@ -94,21 +98,25 @@ public:
QString modifyProjectModel(QMap<QString,QJsonObject>); //修改工程模
bool renameProjectModel(const QString& strCur,QMap<QString,projectManager> datas); //重命名工程模
void updateComponentModelName(const QString& strOld,const QString& strNew); //更新component中的工程模
signals:
void modelChange(); //模型改变信号
private:
//void updateIconList(); //选择工程模后刷新关联图标
void removeProjectData(const QString&,const QString&,int role); //移除对应的project层级结构
QString getItemDataType(const QStandardItem* pItem); //返回数据类型
bool createPropertyTable(const QString& sProject,const QString& sGroup,QList<QStandardItem*> lstSelect,QList<QStandardItem*> lstBase,int nLinkType); //创建属性组表并插入记录到管理表(工程名,当前项迭代器,关联图元类型)
int createPropertyTable(const QString& sProject,const QString& sGroup,QList<QStandardItem*> lstSelect,QList<QStandardItem*> lstBase,int nLinkType,bool isPublic = false); //创建属性组表并插入记录到管理表(工程名,当前项迭代器,关联图元类型)
QJsonObject getSelectedState(QList<QStandardItem*> select,QList<QStandardItem*> base); //返回json格式的选中状态
QList<QStandardItem*> getGroupSub(QStandardItemModel*,const QString&); //返回指定组下的属性(如果存在)
void setupUI();
void initialTypeMap();
int getLevel(QStandardItem *item); //返回当前item所在层级,0为根
projectState couldSave();
void setTableItemState(int row,TableItemState state); //设置状态
int getModelEditState(); //返回工程模编辑状态(选择、编辑、新建)
bool ifProjectExsit(const QString&); //判断工程模存在
private:
Ui::projectModelDlg *ui;
MapMeta m_mapTotal;

36
include/topologyView.h Normal file
View File

@ -0,0 +1,36 @@
#ifndef TOPOLOGYVIEW_H
#define TOPOLOGYVIEW_H
#include <QDialog>
#include <QStandardItemModel>
#include "global.h"
QT_BEGIN_NAMESPACE
namespace Ui { class topologyView; }
QT_END_NAMESPACE
class TopologyView : public QDialog
{
Q_OBJECT
public:
TopologyView(QWidget *parent = nullptr);
~TopologyView();
void initial();
signals:
void entityCreate(EntityInfo);
void entityChange(EntityInfo);
void entityDelete(EntityInfo);
void entitySelected(EntityInfo);
public slots:
void onIndexRbtnClicked(const QPoint &pos); //索引列表右键菜单
void onItemChanged(QStandardItem *item);
void onItemClicked(const QModelIndex &index);
private:
Ui::topologyView *ui;
QStandardItemModel* _pModel;
};
#endif

View File

@ -59,11 +59,26 @@ void ElectricElementsBox::updateModelList()
for(auto &model:_modelInfo)
{
GraphicsItemType localType = corresbondItem::linkType[(AbstractItemType)model.modelType];
model.modelType = localType;
}
if(!m_mapPanels.isEmpty()) //暂时1个类别
{
QMap<QString,ElectricElementsPanel*>::iterator it = m_mapPanels.begin();
if(it != m_mapPanels.end())
{
it.value()->setData(_modelInfo);
}
}
}
void ElectricElementsBox::onSignal_addEletricItem(modelStateInfo& info)
{
emit addEletricItem(info);
}
void ElectricElementsBox::onSignal_modelChanged()
{
getModelInfo();
updateModelList();
}

View File

@ -39,6 +39,8 @@ void ElectricElementsPanel::initial()
void ElectricElementsPanel::setData(QMap<QString,modelStateInfo> map)
{
if(m_pListWidget->count() != 0)
m_pListWidget->clear();
m_mapEleData = map;
initial();
}

View File

@ -23,6 +23,7 @@
#include "toolBox.h"
#include "loadPageDlg.h"
#include "projectModelDlg.h"
#include "topologyView.h"
//using namespace ads;
@ -34,6 +35,7 @@ CMainWindow::CMainWindow(QWidget *parent)
ui->setupUi(this);
m_pUndoStack = nullptr;
m_pLoadPageDlg = nullptr;
m_pTopologyView = nullptr;
initializeDockUi();
initializeAction();
@ -72,12 +74,21 @@ void CMainWindow::initializeDockUi()
ElectricElementsDock->setAllowedAreas(Qt::LeftDockWidgetArea|Qt::RightDockWidgetArea);
this->addDockWidget(Qt::RightDockWidgetArea,ElectricElementsDock);
m_pTopologyView = new TopologyView(this);
m_pTopologyView->initial();
QDockWidget* topologyDock = new QDockWidget(QString::fromWCharArray(L"拓扑关系"),this);
topologyDock->setWidget(m_pTopologyView);
topologyDock->setMinimumSize(120,550);
topologyDock->setAllowedAreas(Qt::LeftDockWidgetArea|Qt::RightDockWidgetArea);
this->addDockWidget(Qt::LeftDockWidgetArea,topologyDock);
m_pDiagramCavas = new DiagramCavas();
m_pDiagramCavas->initial();
this->setCentralWidget(m_pDiagramCavas);
connect(m_pElectricElementsBox,&ElectricElementsBox::addEletricItem,m_pDiagramCavas,&DiagramCavas::onSignal_addGraphicsItem);
m_pProjectModelDlg = new projectModelDlg(this);
connect(m_pProjectModelDlg,&projectModelDlg::modelChange,m_pElectricElementsBox,&ElectricElementsBox::onSignal_modelChanged);
}
void CMainWindow::initializeAction()
@ -104,6 +115,11 @@ void CMainWindow::initializeAction()
connect(ui->actionGroup, SIGNAL(triggered()), this, SLOT(onAction_createGroup()));
connect(ui->actionUngroup, SIGNAL(triggered()), this, SLOT(onAction_destroyGroup()));
connect(m_pTopologyView,&TopologyView::entityCreate,m_pDiagramCavas,&DiagramCavas::onSignal_createEntity);
connect(m_pTopologyView,&TopologyView::entityChange,m_pDiagramCavas,&DiagramCavas::onSignal_changeEntity);
connect(m_pTopologyView,&TopologyView::entityDelete,m_pDiagramCavas,&DiagramCavas::onSignal_deleteEntity);
connect(m_pTopologyView,&TopologyView::entitySelected,m_pDiagramCavas,&DiagramCavas::onSignal_selectEntity);
connect(ui->actionNew,&QAction::triggered,m_pDiagramCavas,&DiagramCavas::onSignal_addPage);
connect(ui->actionOpen,&QAction::triggered,this,&CMainWindow::onSignal_loadPage);
connect(ui->actionSave,&QAction::triggered,m_pDiagramCavas,&DiagramCavas::onSignal_savePage);
@ -191,7 +207,7 @@ void CMainWindow::onSignal_loadPage()
if(m_pLoadPageDlg == nullptr)
{
m_pLoadPageDlg = new LoadPageDlg(this);
connect(m_pLoadPageDlg,&LoadPageDlg::selectedPage,m_pDiagramCavas,&DiagramCavas::onSignal_loadPage);
//connect(m_pLoadPageDlg,&LoadPageDlg::selectedPage,m_pDiagramCavas,&DiagramCavas::onSignal_loadPage);
}
m_pLoadPageDlg->updateList();
m_pLoadPageDlg->show();

View File

@ -7,6 +7,7 @@
#include "dataBase.h"
#include "global.h"
#include "projectTableDelegate.h"
#include "logger.h"
const QSet<QString> stringDataTypes = {"varchar", "char", "text", "date", "time", "timestamp"};
@ -54,6 +55,7 @@ MapProperty projectModelDlg::addNewProject(const QString& sMeta,const QString& s
{
MapProperty mt;
QStringList lstProperty = getGroupList(sMeta); //返回元模下的属性组名
QStringList lstProPublic = getPublicGroupList(); //返回公共属性组
//lstProperty<<QString("base")<<QString("seperation");
QMap<QString,QJsonObject> mapCheckState = DataBase::GetInstance()->getCheckStateFromManager(sProject); //获取选择状态
@ -140,7 +142,39 @@ MapProperty projectModelDlg::addNewProject(const QString& sMeta,const QString& s
mt.insert(property,struProperty);
}
return mt;
MapProperty pubMap;
for(auto &pro:lstProPublic) //公共属性组
{
PropertyPage struProperty;
struProperty.isPublic = true;
QStandardItem* pGroup = nullptr;
pGroup = new QStandardItem(pro);
//model.pSelect->appendRow(pGroup); //公共属性组默认都包含
model.pSelect->insertRow(0,pGroup);
QStringList lstName = getPublicAttributeList(pro);
for(auto &name:lstName)
{
QStandardItem* pItem = new QStandardItem(name);
pItem->setData(QColor(60,140,180,180), Qt::BackgroundRole);
setItemAttribute(name,pItem);
pGroup->appendRow(pItem);
QString dataType = getItemDataType(pItem);
PropertyState sta;
sta.dataType = dataType;
sta.checkState = true;
sta.editable = false;
struProperty.mCheckState.insert(name,sta); //初始都已经选择
}
pubMap.insert(pro,struProperty);
}
for (auto it = mt.begin(); it != mt.end(); ++it) { //将正常属性添到公共属性后
pubMap.insert(it.key(), it.value());
}
return pubMap;
}
void projectModelDlg::initialModel()
@ -155,7 +189,7 @@ void projectModelDlg::initialModel()
QMap<QString,int>::Iterator iter;
for(iter = mapProject.begin();iter != mapProject.end(); ++iter)
{
QStandardItem* propertyItem = new QStandardItem(iter.key());
//QStandardItem* propertyItem = new QStandardItem(iter.key());
PropertyModel pm;
pm.pBase = new QStandardItemModel(this);
@ -223,30 +257,38 @@ void projectModelDlg::generate(const QString& str)
{
MapProperty mapProperty = ite.value().mapProperty;
bool createRes = true; //动态表生成结果
int createRes = 0; //动态表生成结果
for(MapProperty::Iterator it = mapProperty.begin();it != mapProperty.end();++it){ //每个属性组单独生成表
int nType = ite.value().nType;
QStandardItemModel* pSelectModel = ite->pSelect;
QStandardItemModel* pBaseModel = ite->pBase;
/*QStandardItem *rootItem = pSelectModel->invisibleRootItem();
if(rootItem->rowCount() == 0) //修改逻辑,未勾选的属性组不生成表 by/20250311
continue;*/
QList<QStandardItem*> lstSelected = getGroupSub(pSelectModel,it.key());
QList<QStandardItem*> lstBase = getGroupSub(pBaseModel,it.key());
if(!lstSelected.isEmpty())
{
bool res = createPropertyTable(str,it.key(),lstSelected,lstBase,nType);
createRes = createRes && res;
bool isPub = it->isPublic;
int res = createPropertyTable(str,it.key(),lstSelected,lstBase,nType,isPub);
switch (res){
case int(AlertInfo::success):
LOG_INFO("DB", QString("create %1 dynamicTable success").arg(str));
break;
case int(AlertInfo::fail):
LOG_WARN("DB", QString("create %1 dynamicTable fail").arg(str));
break;
case int(AlertInfo::exist):
LOG_WARN("DB", QString("%1 dynamicTable exist").arg(str));
break;
default:
break;
}
createRes = createRes | res;
}
}
if(createRes)
if(!(createRes & int(AlertInfo::fail))) //结果不含失败就成功
{
/*PropertyModel pm = m_mapTotal[_curMeta].take(_curProject); //取出要保存的对象,另存为新索引
m_mapTotal[_curMeta].insert(str,pm);
_curProject = str;*/
QMessageBox::information(NULL, QString::fromWCharArray(L"提示"), QString::fromWCharArray(L"创建表成功"));
emit modelChange();
}
else //创建失败
{
@ -347,6 +389,7 @@ void projectModelDlg::onSaveClicked()
{
QMessageBox::information(NULL, QString::fromWCharArray(L"提示"), QString::fromWCharArray(L"修改模型成功"));
setTableItemState(_curRow,TS_select);
emit modelChange();
}
else
{
@ -378,6 +421,7 @@ void projectModelDlg::onSaveClicked()
{
QMessageBox::information(NULL, QString::fromWCharArray(L"提示"), QString::fromWCharArray(L"修改模型成功"));
setTableItemState(_curRow,TS_select);
emit modelChange();
}
else
{
@ -497,6 +541,7 @@ void projectModelDlg::onApplyClicked()
void projectModelDlg::onRevokeClicked()
{
QStringList lstPub = getPublicGroupList();
MapMeta::Iterator iter = m_mapTotal.find(_curMeta);
if(iter != m_mapTotal.end())
{
@ -510,6 +555,10 @@ void projectModelDlg::onRevokeClicked()
if(pItem)
{
if(lstPub.contains(pItem->parent()->text())){
QMessageBox::information(NULL, QString("提示"), QString::fromWCharArray(L"公共属性无法编辑"));
return;
}
int nLevel = getLevel(pItem);
if(nLevel != 1) //不是二级节点就返回
return;
@ -937,6 +986,14 @@ void projectModelDlg::onDelegateFinishEdit(const QModelIndex &index, const QStri
int col = index.column();
if(col == TD_ProjectModel)
{
if(ifProjectExsit(value))
{
QMessageBox::information(NULL, QString::fromWCharArray(L"提示"), QString::fromWCharArray(L"模型名已存在"));
QTableWidgetItem* pItem = ui->tableWidget_model->item(index.row(),index.column());
if(pItem)
pItem->setText(QString::fromWCharArray(L"未命名"));
return;
}
if(m_mapTotal.contains(_curMeta)) //判断元模存在
{
if(m_mapTotal[_curMeta].contains(_curProject)) //已经存在
@ -1120,6 +1177,25 @@ QStringList projectModelDlg::getGroupList(const QString& sM) const
return groupList;
}
QStringList projectModelDlg::getPublicGroupList() const
{
QMap<int,modelAttributePublic> modelAttPublic = DataBase::GetInstance()->ModelAttributePublic();
QMap<int,attributeGroup> groupMap = DataBase::GetInstance()->AttributeGroup();
QSet<int> setGroup;
for(auto &model:modelAttPublic)
{
setGroup.insert(model.attributeGroupId);
}
QStringList groupList;
for(auto &id:setGroup)
{
groupList.append(groupMap[id].groupType);
}
return groupList;
}
QStringList projectModelDlg::getAttributeList(const QString& sM,const QString& sG) const
{
QMap<int,modelType> modelType = DataBase::GetInstance()->ModelType();
@ -1160,6 +1236,34 @@ QStringList projectModelDlg::getAttributeList(const QString& sM,const QString& s
return lst;
}
QStringList projectModelDlg::getPublicAttributeList(const QString& group)
{
QMap<int,modelAttributePublic> modelAttPublic = DataBase::GetInstance()->ModelAttributePublic();
QMap<int,attributeGroup> groupMap = DataBase::GetInstance()->AttributeGroup();
QMap<int,attribute> attMap = DataBase::GetInstance()->Attribute();
int groupId = -1;
for(auto &attGroup:groupMap)
{
if(attGroup.groupType == group) //返回参数属性组名对应的id
{
groupId = attGroup.id;
break;
}
}
QStringList lst;
for(auto &mt:modelAttPublic)
{
if(mt.attributeGroupId == groupId)
{
lst.append(attMap[mt.attributeId].attribute);
}
}
return lst;
}
void projectModelDlg::setItemAttribute(const QString& name,QStandardItem* p)
{
QMap<int,attribute> attMap = DataBase::GetInstance()->Attribute();
@ -1251,6 +1355,8 @@ bool projectModelDlg::ifProjectEqual(QMap<QString,QJsonObject> map)
QMap<QString,PropertyPage>::Iterator iter;
for(iter = curPro.begin();iter != curPro.end();++iter)
{
if(iter->isPublic) //公共组跳过判断
continue;
if(!map.contains(iter.key())) //已存在的模型中不包含该属性组
{
QMap<QString,PropertyState> curCheckState = iter.value().mCheckState;
@ -1437,31 +1543,68 @@ QString projectModelDlg::getItemDataType(const QStandardItem* pItem)
return dataTypePart;
}
bool projectModelDlg::createPropertyTable(const QString& sProject,const QString& sGroup,QList<QStandardItem*> lstSelect,QList<QStandardItem*> lstBase,int nLinkType)
int projectModelDlg::createPropertyTable(const QString& sProject,const QString& sGroup,QList<QStandardItem*> lstSelect,QList<QStandardItem*> lstBase,int nLinkType,bool isPublic)
{
QString sName = _curMeta + QString("_") + sProject + QString("_")+sGroup;
QStringList fields;
fields.append("id SERIAL NOT NULL PRIMARY KEY");
fields.append("global_uuid uuid NOT NULL DEFAULT gen_random_uuid()");
fields.append("attribute_group VARCHAR(64) NOT NULL");
for(auto &item:lstSelect)
if(!isPublic)
{
QPair<QString,QString> pair = combinePropertySql(item); //拼接单句sql
fields.append(pair.first);
}
QString sName = _curMeta + QString("_") + sProject + QString("_")+sGroup;
QJsonObject objState = getSelectedState(lstSelect,lstBase);
QStringList fields;
fields.append("id SERIAL NOT NULL PRIMARY KEY");
fields.append("global_uuid uuid NOT NULL DEFAULT gen_random_uuid()");
fields.append("attribute_group VARCHAR(64) NOT NULL");
if(!DataBase::GetInstance()->createDynamicTable(sName,fields))
{
return false;
for(auto &item:lstSelect)
{
QPair<QString,QString> pair = combinePropertySql(item); //拼接单句sql
fields.append(pair.first);
}
QJsonObject objState = getSelectedState(lstSelect,lstBase);
if(!DataBase::GetInstance()->createDynamicTable(sName,fields))
{
return int(AlertInfo::fail);
}
else
{
DataBase::GetInstance()->insertProjectManager(sName,sProject,_curMeta,sGroup,nLinkType,objState);
return int(AlertInfo::success);
}
}
else
{
DataBase::GetInstance()->insertProjectManager(sName,sProject,_curMeta,sGroup,nLinkType,objState);
return true;
QString sName = sGroup;
QStringList fields;
fields.append("id SERIAL NOT NULL PRIMARY KEY");
fields.append("global_uuid uuid NOT NULL DEFAULT gen_random_uuid()");
fields.append("attribute_group VARCHAR(64) NOT NULL");
for(auto &item:lstSelect)
{
QPair<QString,QString> pair = combinePropertySql(item); //拼接单句sql
fields.append(pair.first);
}
QJsonObject objState = getSelectedState(lstSelect,lstBase);
if(!DataBase::GetInstance()->ifDynamicTableExist(sName))
{
bool val = DataBase::GetInstance()->createDynamicTable(sName,fields);
if(val)
{
DataBase::GetInstance()->insertProjectManager(sName,sName,"NULL",sGroup,0,objState,true);
return int(AlertInfo::success);
}
else {
return int(AlertInfo::fail);
}
}
else
{
return int(AlertInfo::exist);
}
}
}
@ -1569,22 +1712,6 @@ void projectModelDlg::initialTypeMap()
_mapType.insert(QString::fromWCharArray(L"异步电动机"),3);
}
int projectModelDlg::getLevel(QStandardItem *item) {
int level = 0;
QStandardItem *parent = item->parent();
if(parent)
{
while (parent) {
level++;
parent = parent->parent();
}
return level;
}
else{
return -1;
}
}
projectState projectModelDlg::couldSave()
{
@ -1632,3 +1759,15 @@ int projectModelDlg::getModelEditState()
}
return res;
}
bool projectModelDlg::ifProjectExsit(const QString& sPro)
{
for(auto &meta:m_mapTotal)
{
if(meta.contains(sPro))
{
return true;
}
}
return false;
}

243
source/topologyView.cpp Normal file
View File

@ -0,0 +1,243 @@
#include "topologyView.h"
#include "ui_topologyView.h"
#include "tools.h"
#include <QStandardItemModel>
#include <QMenu>
#include <QUuid>
TopologyView::TopologyView(QWidget *parent)
: QDialog(parent)
, ui(new Ui::topologyView)
,_pModel(nullptr)
{
ui->setupUi(this);
//setWindowFlags(windowFlags() | Qt::WindowMinMaxButtonsHint&Qt::WindowCloseButtonHint);
_pModel = new QStandardItemModel(this);
ui->treeView->setContextMenuPolicy(Qt::CustomContextMenu);
}
TopologyView::~TopologyView()
{
delete ui;
}
void TopologyView::initial()
{
connect(ui->treeView, &QTreeView::customContextMenuRequested, this, &TopologyView::onIndexRbtnClicked);
connect(ui->treeView, &QTreeView::clicked, this, &TopologyView::onItemClicked);
connect(_pModel, &QStandardItemModel::itemChanged, this, &TopologyView::onItemChanged);
ui->treeView->setHeaderHidden(true);
// 设置模型的列数
_pModel->setColumnCount(1);
// 设置模型的标题
//_pModel->setHeaderData(0, Qt::Horizontal, QObject::tr("层级"));
// 创建根节点
QStandardItem *rootItem = new QStandardItem("电网");
rootItem->setFlags(rootItem->flags() & ~Qt::ItemIsEditable);
_pModel->appendRow(rootItem);
// 创建树视图
ui->treeView->setModel(_pModel);
// 展开所有节点
ui->treeView->expandAll();
// 显示树视图
ui->treeView->setWindowTitle(QObject::tr("拓扑树"));
}
void TopologyView::onIndexRbtnClicked(const QPoint &pos)
{
// 获取当前点击的位置对应的索引
QModelIndex index = ui->treeView->indexAt(pos);
if (!index.isValid()) {
return; // 如果点击的是空白区域,直接返回
}
QMenu menu;
QStandardItem* item = _pModel->itemFromIndex(index);
if(item)
{
int nCount = item->rowCount();
int nLevel = getLevel(item);
if(nLevel == -1) //根节点
{
QAction *addAction = new QAction("添加电网", this);
connect(addAction,&QAction::triggered,this,[&](){
QString uuid = QUuid::createUuid().toString();
QStandardItem *gridItem = new QStandardItem(QString("电网_")+QString::number(nCount));
gridItem->setData(uuid,Qt::UserRole+1);
gridItem->setData(int(EntityType::Grid),Qt::UserRole+2);
item->appendRow(gridItem);
EntityInfo info;
info.eType = EntityType::Grid;
info.sName = gridItem->text();
info.sUuid = uuid;
emit entityCreate(info);
});
menu.addAction(addAction);
}
else if(nLevel == 1) //grid
{
QAction *addAction = new QAction("添加区域", this);
QString sParentid = item->data(Qt::UserRole+1).toString();
connect(addAction,&QAction::triggered,this,[&](){
QString uuid = QUuid::createUuid().toString();
QStandardItem *zoneItem = new QStandardItem(QString("区域_")+QString::number(nCount));
zoneItem->setData(uuid,Qt::UserRole+1);
zoneItem->setData(int(EntityType::Zone),Qt::UserRole+2);
item->appendRow(zoneItem);
EntityInfo info;
info.eType = EntityType::Zone;
info.sName = zoneItem->text();
info.sParentId = sParentid;
info.sUuid = uuid;
emit entityCreate(info);
ui->treeView->expandAll();
});
menu.addAction(addAction);
}
else if(nLevel == 2) //zone
{
QAction *addAction = new QAction("添加场站", this);
QString sParentid = item->data(Qt::UserRole+1).toString();
connect(addAction,&QAction::triggered,this,[&](){
QString uuid = QUuid::createUuid().toString();
QStandardItem *stationItem = new QStandardItem(QString("场站_")+QString::number(nCount));
stationItem->setData(uuid,Qt::UserRole+1);
stationItem->setData(int(EntityType::Station),Qt::UserRole+2);
item->appendRow(stationItem);
EntityInfo info;
info.eType = EntityType::Station;
info.sName = stationItem->text();
info.sUuid = uuid;
info.sParentId = sParentid;
emit entityCreate(info);
ui->treeView->expandAll();
});
menu.addAction(addAction);
}
else if(nLevel == 3) //station
{
QAction *addAction = new QAction("添加组态图", this);
QString sParentid = item->data(Qt::UserRole+1).toString();
connect(addAction,&QAction::triggered,this,[&](){
QString uuid = QUuid::createUuid().toString();
QStandardItem *diagramItem = new QStandardItem(QString("组态图_")+QString::number(nCount));
diagramItem->setData(uuid,Qt::UserRole+1);
diagramItem->setData(int(EntityType::ConfigurationDiagram),Qt::UserRole+2);
item->appendRow(diagramItem);
EntityInfo info;
info.eType = EntityType::ConfigurationDiagram;
info.sName = diagramItem->text();
info.sUuid = uuid;
info.sParentId = sParentid;
emit entityCreate(info);
ui->treeView->expandAll();
});
menu.addAction(addAction);
}
else if(nLevel == 4) //组态图
{
QAction *addAction = new QAction("添加子组态图", this);
QString sText = item->text();
QString sParentid = item->data(Qt::UserRole+1).toString();
connect(addAction,&QAction::triggered,this,[&](){
QString uuid = QUuid::createUuid().toString();
QStandardItem *diagramItem = new QStandardItem(sText+QString("_")+QString::number(nCount));
diagramItem->setData(uuid,Qt::UserRole+1);
diagramItem->setData(int(EntityType::ConfigurationDiagram),Qt::UserRole+2);
item->appendRow(diagramItem);
EntityInfo info;
info.eType = EntityType::ConfigurationDiagram;
info.sName = diagramItem->text();
info.sUuid = uuid;
info.sParentId = sParentid;
emit entityCreate(info);
ui->treeView->expandAll();
});
menu.addAction(addAction);
}
if(nLevel != -1) //除了根节点其余都能删除
{
QAction *delAction = new QAction("删除", this);
connect(delAction,&QAction::triggered,this,[&](){
QModelIndex currentIndex = ui->treeView->currentIndex();
if(currentIndex.isValid())
{
QStandardItem* pItem = _pModel->itemFromIndex(currentIndex);
if(pItem)
{
QString str = item->text();
EntityInfo info;
info.sName = str;
info.sUuid = item->data(Qt::UserRole+1).toString();
info.eType = EntityType(item->data(Qt::UserRole+2).toInt());
emit entityDelete(info);
QStandardItem* pParent = item->parent();
if(pParent)
{
pParent->removeRow(currentIndex.row());
}
}
}
});
menu.addAction(delAction);
}
}
// 在点击位置显示菜单
menu.exec(ui->treeView->mapToGlobal(pos));
}
void TopologyView::onItemChanged(QStandardItem *item)
{
int nLevel = getLevel(item);
QString str = item->text();
EntityInfo info;
info.sName = str;
info.sUuid = item->data(Qt::UserRole+1).toString();
info.eType = EntityType(item->data(Qt::UserRole+2).toInt());
emit entityChange(info);
}
void TopologyView::onItemClicked(const QModelIndex &index)
{
QStandardItem* item = _pModel->itemFromIndex(index);
if(item)
{
EntityType type = EntityType(item->data(Qt::UserRole+2).toInt());
if(type == EntityType::ConfigurationDiagram)
{
EntityInfo info;
info.eType = EntityType::ConfigurationDiagram;
info.sName = item->text();
info.sUuid = item->data(Qt::UserRole+1).toString();
info.sParentId = item->parent()->data(Qt::UserRole+1).toString();
emit entitySelected(info);
}
}
}

37
ui/topologyView.ui Normal file
View File

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>topologyView</class>
<widget class="QDialog" name="topologyView">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>182</width>
<height>442</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QTreeView" name="treeView">
<property name="minimumSize">
<size>
<width>170</width>
<height>430</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>