GridFrame/diagramCavas/source/diagramEditor/editPanel.cpp

632 lines
22 KiB
C++
Raw Normal View History

2026-03-23 11:11:55 +08:00
#include <QVBoxLayout>
#include <QGraphicsWidget>
#include <QGraphicsGridLayout>
#include <QPushButton>
#include <QTimer>
2026-05-14 20:11:48 +08:00
#include <QMessageBox>
2026-03-23 11:11:55 +08:00
#include <QGraphicsProxyWidget>
#include "diagramEditor/editPanel.h"
#include "diagramEditor/editScene.h"
#include "diagramEditor/editView.h"
#include "diagramEditor/editRowData.h"
#include "diagramEditor/editMainRect.h"
#include "diagramEditor/diagramEditorWizard.h"
#include "diagramEditor/editContainerItem.h"
#include "diagramEditor/diagramEditorStructContainer.h"
#include "diagramEditor/diagramEditorBaseBlock.h"
#include "diagramEditor/editItems.h"
#include "diagramEditor/diagramEditorBayDetailSettingDlg.h"
#include "diagramEditor/diagramEditorTransDetailSettingDlg.h"
#include "graphicsDataModel/diagramEditorModel.h"
#include "diagramEditor/diagramEditorPreviewDlg.h"
#include "diagramEditor/confirmEditorDlg.h"
#include "projectManager.h"
#include "diagramCavas.h"
#include "common/core_model/constants.h"
#include "basePropertyManager.h"
2026-05-06 19:48:33 +08:00
#include "diagramEditor/transformerBuilder.h"
#include "diagramEditor/layoutBuilder.h"
2026-03-23 11:11:55 +08:00
#include <QDebug>
EditPanel::EditPanel(QWidget *parent)
: QWidget(parent)
,_pEditorWizard(nullptr)
,_bayDetailSetting(nullptr)
,_transDetailSetting(nullptr)
,_pModel(nullptr)
,_pPreview(nullptr)
,_confirmEditor(nullptr)
{
_pModel = new DiagramEditorModel();
_pModel->setPanel(this);
_maxWidth = 0;
_maxHeight = 0;
_layout = new QVBoxLayout(this);
m_pEditScene = new EditScene(this);
m_pEditScene->setModel(_pModel);
//设置场景大小.前两个参数为scene的坐标远点设置到view的中心点后无论view如何缩放secne的坐标原点都不会动方便后续的位置计算
m_pEditScene->setSceneRect(0, 0, Constants::SCENE_WIDTH*6, Constants::SCENE_HEIGHT*6);
2026-03-23 11:11:55 +08:00
m_pEditView = new EditView(this);
m_pEditView->setScene(m_pEditScene);
_layout->addWidget(m_pEditView);
initial();
setStyleSheet("backGround-color:rgb(112,128,144);");
}
EditPanel::~EditPanel()
{
if(_pModel)
delete _pModel;
}
void EditPanel::initByWizardInfo()
{
2026-05-06 19:48:33 +08:00
// 阶段1: 清理和初始化
performCleanup();
initializeSceneLayout();
// 阶段2: 获取数据
const auto& containerStruct = _pEditorWizard->getContainerStruct();
// 阶段3: 处理所有层级
processAllContainerLevels(containerStruct);
// 阶段4: 完成构建
finalizeConstruction();
2026-03-23 11:11:55 +08:00
}
void EditPanel::initBlockConnection()
{
if(_pEditorWizard){
auto mapCon = _pEditorWizard->getConnection();
//todo:添加过的不再添加
for(auto& con:mapCon){
int nPara = con.nPara;
auto item1 = _pEditorWizard->getBlockByName_all(con.con1.sName);
auto item2 = _pEditorWizard->getBlockByName_all(con.con2.sName);
if(!item1 || !item2)
continue;
auto con1 = _pEditorWizard->getContainerByBlock_all(con.con1.sName);
auto con2 = _pEditorWizard->getContainerByBlock_all(con.con2.sName);
auto pItem1 = getItemByName(item1->getName());
auto pItem2 = getItemByName(item2->getName());
EditLineItem* pLine = new EditLineItem();
pLine->setName(con.uid.toString());
pLine->setType(EditorItemType::line);
m_pEditScene->addItem(pLine);
if(con1 && con2){
int nT1 = item1->getType();
int nT2 = item2->getType();
QPointF center1 = pItem1->scenePos();
QPointF center2 = pItem2->scenePos();
if(con1 == con2){ //两个block在同一个容器中(上下连接)
center1 += QPointF(pItem1->boundingRect().width()*0.5,0);
center2 += QPointF(pItem2->boundingRect().width()*0.5,0);
if((nT1 == 1 && nT2 == 2) || (nT2 == 1 && nT1 == 2)){ //对象是母线段母线横坐标与同容器Block相同
if(nT1 == 1){ //pItem1是母线
center1.setX(center2.x());
}
else{ //pItem2是母线
center2.setX(center1.x());
}
if(center1.y() < center2.y()){ //item1在item2上 2的上边连接1下边
center1 += QPointF(0,pItem1->boundingRect().height()); //将1的点移动到下边
}
else{ //2在1上
center2 += QPointF(0,pItem2->boundingRect().height()); //将2的点移动到下边
}
pLine->setStartPoint(center1);
pLine->setEndPoint(center2);
pLine->calculatePath();
}
}
else{
if((nT1 == 1 && nT2 == 2) || (nT2 == 1 && nT1 == 2)){ //分段连接(左右连接)
center1 += QPointF(0,pItem1->boundingRect().height()*0.5);
center2 += QPointF(0,pItem2->boundingRect().height()*0.5);
if(center1.x() < center2.x()){ //item1在item2左边 1右连2左
center1 += QPointF(pItem1->boundingRect().width(),0);
}
else{ //1在2右 2右连1左
center2 += QPointF(pItem2->boundingRect().width(),0);
}
pLine->setStartPoint(center1);
pLine->setEndPoint(center2);
pLine->calculatePath();
}
else if((nT1 == 3 && nT2 == 2) || (nT2 == 2 && nT1 == 3)){ //变压器连间隔
center1 += QPointF(pItem1->boundingRect().width()*0.5,0);
center2 += QPointF(pItem2->boundingRect().width()*0.5,0);
DiagramEditorTransformerBlock* pTrans = nullptr;
DiagramEditorBayBlock* pBay = nullptr;
if(nT1 == 3){
pTrans = dynamic_cast<DiagramEditorTransformerBlock*>(item1);
pBay = dynamic_cast<DiagramEditorBayBlock*>(item2);
}
else if(nT2 == 3){ //todo:此分支暂不起作用
pTrans = dynamic_cast<DiagramEditorTransformerBlock*>(item2);
pBay = dynamic_cast<DiagramEditorBayBlock*>(item1);
}
if(pTrans && pBay){
TransformerType typTrans = pTrans->getTransType();
BayType typBay = pBay->getBayType();
if(typTrans == TransformerType::twoWinding){ //两绕组
if(typBay == BayType::outcomingBay){ //进线间隔,在低压侧
center2 += QPointF(0,pItem2->boundingRect().height());
}
else if(typBay == BayType::incomingBay){ //出线间隔,在高压侧
center1 += QPointF(0,pItem1->boundingRect().height());
}
}
else{ //三绕组
if(nPara == 0){ //高压侧
center2 += QPointF(0,pItem2->boundingRect().height());
}
else if(nPara == 1){ //中压
if(center1.x() < center2.x()){ //变压器在左
center1 += QPointF(pItem1->boundingRect().width()*0.5,pItem1->boundingRect().height()*0.5);
}
else{
center1 -= QPointF(pItem1->boundingRect().width()*0.5,0);
center1 += QPointF(0,pItem1->boundingRect().height()*0.5);
}
pLine->setStartPoint(center1);
pLine->setEndPoint(center2);
pLine->calculatePath();
continue;
}
else if(nPara == 2){ //低压
center1 += QPointF(0,pItem1->boundingRect().height());
}
}
}
pLine->setStartPoint(center1);
pLine->setEndPoint(center2);
pLine->calculatePath(3);
}
}
}
}
}
}
void EditPanel::showPreview()
{
if(!_pPreview){
_pPreview = new DiagramEditorPreviewDlg(this);
2026-05-22 16:08:15 +08:00
_pPreview->setWindowTitle(_projectName+"_"+_timeStamp);
2026-03-23 11:11:55 +08:00
}
_pPreview->showDlg();
}
void EditPanel::showConfirmDlg()
{
if(!_confirmEditor){
_confirmEditor = new ConfirmEditorDlg(this);
_confirmEditor->setModelDelegate(_pModel);
connect(_confirmEditor,&ConfirmEditorDlg::onConfirmEditor,this,[&](QString sAuthor,QString sTime){
auto pCavas = getCavas();
if(pCavas){
QByteArray btWizard = _pModel->getWizardInfo();
setWindowTitle(sTime);
ProjectManager::instance().saveEditorDataToDB(_uid,_projectName,_projectName,btWizard,sAuthor,sTime);
}
});
}
_confirmEditor->showDlg(_author,_timeStamp);
}
void EditPanel::generate()
{
if(_pPreview){
_pPreview->hide();
}
auto pCavas = getCavas();
QList<EditBaseItem*> pBlocks = getBlockItems();
pCavas->onSignal_wizardFinished(_projectName,_pModel->getPreviewItem(),pBlocks);
}
void EditPanel::showWizard()
{
if(_pEditorWizard)
_pEditorWizard->show();
}
QList<EditBaseItem*> EditPanel::getBlockItems(EditorItemType typ)
{
QList<EditBaseItem*> lst;
auto allItems = m_pEditScene->items();
2026-05-18 19:12:28 +08:00
for(auto &item:allItems){
2026-03-23 11:11:55 +08:00
auto p = dynamic_cast<EditBaseItem*>(item);
if(p){
EditorItemType eType = p->getType();
if(typ == EditorItemType::None){ //返回所有block item
if(eType == EditorItemType::bay || eType == EditorItemType::bus || eType == EditorItemType::trans){
lst.push_back(p);
}
}
else{
if(eType == typ){
lst.push_back(p);
}
}
}
}
return lst;
}
void EditPanel::onWidthChanged(int width)
{
if(_maxWidth < width)
{
_maxWidth = width;
int x = _mainWidget->geometry().width();
int y = _mainWidget->geometry().y();
_mainWidget->setGeometry(x,y,_maxWidth,_maxHeight);
m_pEditScene->setSceneRect(x,y,_maxWidth,_maxHeight);
m_pEditView->viewport()->update();
//qDebug()<<m_pEditScene->sceneRect();
}
}
void EditPanel::onContainerSizeChanged(EditContainerItem* pItem)
{
if(pItem){
auto lst = pItem->childItems();
2026-05-18 19:12:28 +08:00
for(auto &p:lst){
2026-03-23 11:11:55 +08:00
auto pBase = dynamic_cast<EditBaseItem*>(p);
if(pBase){
QString sName = pBase->getName();
EditorItemType tpe = pBase->getType();
if(tpe == EditorItemType::bus){
pBase->setBoundingRect(QRectF(0,0,pItem->boundingRect().width()-20,Constants::EDITOR_BUS_HEIGHT));
}
}
}
}
}
void EditPanel::onItemDbClicked(QPointer<DiagramEditorBaseBlock> pBlock)
{
if(pBlock->getType() == 2){ //间隔
if(_bayDetailSetting == nullptr){
_bayDetailSetting = new DiagramEditorBayDetailSettingDlg(this,_pModel);
_bayDetailSetting->setWizard(_pEditorWizard);
}
auto pBay = dynamic_cast<DiagramEditorBayBlock*>(pBlock.data());
if(pBay)
_bayDetailSetting->showDlg(pBay);
_bayDetailSetting->showPreview();
}
else if(pBlock->getType() == 3){ //变压器
if(_transDetailSetting == nullptr){
_transDetailSetting = new DiagramEditorTransDetailSettingDlg(this,_pModel);
_transDetailSetting->setWizard(_pEditorWizard);
}
auto pTrans = dynamic_cast<DiagramEditorTransformerBlock*>(pBlock.data());
if(pTrans)
_transDetailSetting->showDlg(pTrans);
_transDetailSetting->showPreview();
}
}
void EditPanel::initial()
{
_mainWidget = new EditMainRect;
_widgetLayout = new QGraphicsLinearLayout(Qt::Vertical);
_widgetLayout->setSpacing(40);
_mainWidget->setLayout(_widgetLayout);
m_pEditScene->addItem(_mainWidget);
_mainWidget->setGeometry(m_pEditScene->sceneRect());
_maxWidth = _mainWidget->rect().width();
_maxHeight = _mainWidget->rect().height();
m_pEditView->centerOn(0,0);
_pEditorWizard = new DiagramEditorWizard(this);
connect(_pEditorWizard,&DiagramEditorWizard::wizardFinish,this,[&](){
initByWizardInfo();
});
_pModel->setWizard(_pEditorWizard);
}
void EditPanel::calculateContainerWidth(EditContainerItem* pItem)
{
if(pItem){
auto lst = pItem->childItems();
int nWidth = 0;
int nTop = 0; //container上层item数
int nBottom = 0; //下层
bool isSection = false; //是否分段
2026-05-18 19:12:28 +08:00
for(auto &p:lst){
2026-03-23 11:11:55 +08:00
auto pBase = dynamic_cast<EditBaseItem*>(p);
if(pBase){
QString sName = pBase->getName();
EditorItemType tpe = pBase->getType();
if(tpe == EditorItemType::bay){
auto pBay = dynamic_cast<DiagramEditorBayBlock*>(pBase->getBlockData().data());
if(pBay){ //分段连接的container固定大小
BayType typ = pBay->getBayType();
if(typ == BayType::busSectionBay){
isSection = true;
}
}
auto pData = pBase->getBlockData();
if(pData){
int n = pData->getContainerLevel();
if(n == 0){
nTop += 1;
}
else if(n == 3){
nBottom += 1;
}
}
//nWidth += g_dEditorItem_Width+20;
}
}
}
if(nTop || nBottom){
nWidth = (nTop > nBottom ? nTop : nBottom)*(Constants::EDITOR_ITEM_WIDTH+20);
pItem->setMinimumWidth(nWidth);
if(isSection){ //分段连接的container固定大小
pItem->setMaximumWidth(nWidth);
}
}
}
}
int EditPanel::getContainerBusType(QMap<int,QList<DiagramEditorBaseBlock*>> map)
{
if(!map.value(1).isEmpty() && !map.value(2).isEmpty()){ //两条母线数据
return 2;
}
else{
return 1;
}
}
EditBaseItem* EditPanel::getItemByName(const QString& sName)
{
auto lstItems = m_pEditScene->items();
for(auto& item:lstItems){
auto pBase = dynamic_cast<EditBaseItem*>(item);
if(pBase){
if(pBase->getName() == sName){
return pBase;
}
}
}
return nullptr;
}
void EditPanel::closeEvent(QCloseEvent *closeEvent)
{
2026-05-14 20:11:48 +08:00
QMessageBox msgBox;
msgBox.setText(QString::fromWCharArray(L"提示"));
msgBox.setInformativeText(QString::fromWCharArray(L"确认关闭?"));
msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
msgBox.setDefaultButton(QMessageBox::Ok);
int ret = msgBox.exec();
2026-05-22 16:08:15 +08:00
if (ret == QMessageBox::Ok)
2026-05-14 20:11:48 +08:00
{
2026-05-22 16:08:15 +08:00
emit panelDelete(_tagName, 0);
closeEvent->accept(); //允许关闭
2026-05-14 20:11:48 +08:00
}
2026-05-22 16:08:15 +08:00
else
{
closeEvent->ignore(); //阻止关闭
2026-05-14 20:11:48 +08:00
}
2026-03-23 11:11:55 +08:00
}
void EditPanel::prepareSaveEditor()
{
if(_pModel){
showConfirmDlg();
}
}
void EditPanel::loadBaseSetting(QUuid uid)
{
auto info = ProjectManager::instance().getBaseSetting(uid);
if(_pModel){
_author = info.autor;
_timeStamp = info.ts;
_tagName = _projectName; //将临时名称保存到变量
_projectName = info.projectName;
_pModel->setWizardInfo(info.context);
2026-05-08 18:03:54 +08:00
QTimer::singleShot(300, this, [&](){
//_pModel->clearCurPreview();
_pModel->generatePreview();
_pModel->calculateBlockPos();
_pModel->setItemInBlockPos();
_pModel->refreshConnection();
});
2026-03-23 11:11:55 +08:00
}
}
2026-05-06 19:48:33 +08:00
2026-05-20 16:16:49 +08:00
void EditPanel::activePreview()
{
if(_pPreview){
_pPreview->raise();
_pPreview->activateWindow();
2026-06-05 18:42:09 +08:00
emitTopologySignals();
2026-05-20 16:16:49 +08:00
}
}
2026-05-06 19:48:33 +08:00
void EditPanel::performCleanup() {
// 清理模型
if (_pModel) {
_pModel->clearItems();
}
// 清理场景
if (m_pEditScene) {
m_pEditScene->clear();
}
// 清理数据
qDeleteAll(_lstData);
_lstData.clear();
2026-06-05 18:42:09 +08:00
//_accumulatedBayItems.clear();
//_accumulatedDeviceItems.clear();
2026-05-06 19:48:33 +08:00
// 清理主部件
_mainWidget = nullptr;
_widgetLayout = nullptr;
// 清理属性管理器
BasePropertyManager::instance().clearEditorData();
}
void EditPanel::initializeSceneLayout() {
_mainWidget = new EditMainRect;
_widgetLayout = new QGraphicsLinearLayout(Qt::Vertical);
_widgetLayout->setSpacing(40);
_mainWidget->setLayout(_widgetLayout);
m_pEditScene->addItem(_mainWidget);
_mainWidget->setGeometry(m_pEditScene->sceneRect());
}
void EditPanel::processAllContainerLevels(const ContainerStructMap& containerStruct) {
// 普通层级构建器
LayoutBuilder normalBuilder(this);
// 按顺序处理所有层级
auto keys = containerStruct.keys();
std::sort(keys.begin(), keys.end());
2026-05-18 19:12:28 +08:00
for (int &level : keys) {
2026-05-06 19:48:33 +08:00
if (level == Constants::TRANSFORMER_LEVEL) {
// 特殊处理变压器层级
processTransformerLevel(containerStruct.value(level));
} else {
// 处理普通层级
processNormalContainerLevel(level, containerStruct.value(level), normalBuilder);
// 如果当前是层级0且存在变压器层级在之后插入变压器
if (level == 0 && containerStruct.contains(Constants::TRANSFORMER_LEVEL)) {
int transformerIndex = keys.indexOf(Constants::TRANSFORMER_LEVEL);
if (transformerIndex > 0) { // 变压器在后面
continue; // 会在遍历到时处理
} else if (transformerIndex < 0) { // 变压器不存在于keys中
processTransformerLevel(containerStruct.value(Constants::TRANSFORMER_LEVEL));
}
}
}
}
}
void EditPanel::processNormalContainerLevel(int level,
const QList<ContainerDataPtr>& containers,
LayoutBuilder& builder) {
if (containers.isEmpty()) return;
// 创建行
auto rowLayout = builder.createRowLayout();
auto rowData = new EditRowData();
rowData->setId(QString::number(level));
// 处理该层级的所有容器
for (auto container : containers) {
if (!container) continue;
const auto& blockMap = container->getBlockMap();
auto result = builder.buildContainer(blockMap);
if (result.container) {
rowLayout->addItem(result.container);
}
// 累积层级项
2026-06-05 18:42:09 +08:00
//_accumulatedBayItems.append(result.bayItems);
//_accumulatedDeviceItems.append(result.deviceItems);
2026-05-06 19:48:33 +08:00
}
// 保存行数据
_lstData.append(rowData);
_widgetLayout->addItem(rowLayout);
}
void EditPanel::processTransformerLevel(const QList<ContainerDataPtr>& containers) {
if (containers.isEmpty()) return;
// 使用变压器专用构建器
TransformerBuilder transformerBuilder(this);
// 创建变压器行
auto rowLayout = transformerBuilder.createTransformerRowLayout();
auto rowData = new EditRowData();
rowData->setId(QString::number(Constants::TRANSFORMER_LEVEL));
// 处理所有变压器容器
for (auto container : containers) {
if (!container) continue;
const auto& blockMap = container->getBlockMap();
auto result = transformerBuilder.buildContainer(blockMap);
2026-05-18 19:12:28 +08:00
/*if (result.container) {
2026-05-06 19:48:33 +08:00
rowLayout->addItem(result.container);
2026-05-18 19:12:28 +08:00
}*/
// ✅ 每个变压器前加 stretch
rowLayout->addStretch();
// ✅ 变压器本身
rowLayout->addItem(result.container);
// ✅ 每个变压器后加 stretch
rowLayout->addStretch();
2026-05-06 19:48:33 +08:00
// 累积变压器层级项
2026-06-05 18:42:09 +08:00
//_accumulatedBayItems.append(result.bayItems);
//_accumulatedDeviceItems.append(result.deviceItems);
2026-05-06 19:48:33 +08:00
}
// 插入变压器行在层级0之后
_lstData.append(rowData);
// 找到层级0的位置在它之后插入变压器
int insertPosition = 1; // 默认在第一个之后
for (int i = 0; i < _widgetLayout->count(); ++i) {
if (i < _lstData.size() && _lstData[i]->getId() == "0") {
insertPosition = i + 1;
break;
}
}
_widgetLayout->insertItem(insertPosition, rowLayout);
}
void EditPanel::finalizeConstruction() {
// 添加最后的拉伸
_widgetLayout->addStretch();
// 发射拓扑更新信号
2026-06-05 18:42:09 +08:00
//emitTopologySignals();
2026-05-06 19:48:33 +08:00
// 延迟初始化连接
QTimer::singleShot(300, this, &EditPanel::initBlockConnection);
}
void EditPanel::emitTopologySignals() {
2026-06-05 18:42:09 +08:00
if (_pModel)
_pModel->updateTolology();
2026-05-06 19:48:33 +08:00
}