#include #include #include #include #include #include #include #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" #include "diagramEditor/transformerBuilder.h" #include "diagramEditor/layoutBuilder.h" #include 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*4, Constants::SCENE_HEIGHT*4); 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() { // 阶段1: 清理和初始化 performCleanup(); initializeSceneLayout(); // 阶段2: 获取数据 const auto& containerStruct = _pEditorWizard->getContainerStruct(); // 阶段3: 处理所有层级 processAllContainerLevels(containerStruct); // 阶段4: 完成构建 finalizeConstruction(); } 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(item1); pBay = dynamic_cast(item2); } else if(nT2 == 3){ //todo:此分支暂不起作用 pTrans = dynamic_cast(item2); pBay = dynamic_cast(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); } _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 pBlocks = getBlockItems(); pCavas->onSignal_wizardFinished(_projectName,_pModel->getPreviewItem(),pBlocks); } void EditPanel::showWizard() { if(_pEditorWizard) _pEditorWizard->show(); } QList EditPanel::getBlockItems(EditorItemType typ) { QList lst; auto allItems = m_pEditScene->items(); for(auto item:allItems){ auto p = dynamic_cast(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()<sceneRect(); } } void EditPanel::onContainerSizeChanged(EditContainerItem* pItem) { if(pItem){ auto lst = pItem->childItems(); for(auto p:lst){ auto pBase = dynamic_cast(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 pBlock) { if(pBlock->getType() == 2){ //间隔 if(_bayDetailSetting == nullptr){ _bayDetailSetting = new DiagramEditorBayDetailSettingDlg(this,_pModel); _bayDetailSetting->setWizard(_pEditorWizard); } auto pBay = dynamic_cast(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(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; //是否分段 for(auto p:lst){ auto pBase = dynamic_cast(p); if(pBase){ QString sName = pBase->getName(); EditorItemType tpe = pBase->getType(); if(tpe == EditorItemType::bay){ auto pBay = dynamic_cast(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> 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(item); if(pBase){ if(pBase->getName() == sName){ return pBase; } } } return nullptr; } void EditPanel::closeEvent(QCloseEvent *closeEvent) { 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(); switch (ret) { case QMessageBox::Ok: { emit panelDelete(_tagName,0); } break; case QMessageBox::Cancel: // Cancel was clicked break; default: // should never be reached break; } } 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); QTimer::singleShot(300, this, [&](){ //_pModel->clearCurPreview(); _pModel->generatePreview(); _pModel->calculateBlockPos(); _pModel->setItemInBlockPos(); _pModel->refreshConnection(); }); } } void EditPanel::performCleanup() { // 清理模型 if (_pModel) { _pModel->clearItems(); } // 清理场景 if (m_pEditScene) { m_pEditScene->clear(); } // 清理数据 qDeleteAll(_lstData); _lstData.clear(); _accumulatedBayItems.clear(); _accumulatedDeviceItems.clear(); // 清理主部件 _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()); for (int level : keys) { 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& 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); } // 累积层级项 _accumulatedBayItems.append(result.bayItems); _accumulatedDeviceItems.append(result.deviceItems); } // 保存行数据 _lstData.append(rowData); _widgetLayout->addItem(rowLayout); } void EditPanel::processTransformerLevel(const QList& 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); if (result.container) { rowLayout->addItem(result.container); } // 累积变压器层级项 _accumulatedBayItems.append(result.bayItems); _accumulatedDeviceItems.append(result.deviceItems); } // 插入变压器行(在层级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(); // 发射拓扑更新信号 emitTopologySignals(); // 延迟初始化连接 QTimer::singleShot(300, this, &EditPanel::initBlockConnection); } void EditPanel::emitTopologySignals() { if (_pModel) { emit _pModel->updateTopologyItems(_accumulatedBayItems, true, false); emit _pModel->updateTopologyItems(_accumulatedDeviceItems, false, false); } // 清空累积的数据 _accumulatedBayItems.clear(); _accumulatedDeviceItems.clear(); }