GridFrame/diagramCavas/source/diagramEditor/editPanel.cpp

637 lines
22 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <QVBoxLayout>
#include <QGraphicsWidget>
#include <QGraphicsGridLayout>
#include <QPushButton>
#include <QTimer>
#include <QMessageBox>
#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"
#include "diagramEditor/transformerBuilder.h"
#include "diagramEditor/layoutBuilder.h"
#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*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<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);
_pPreview->setWindowTitle(_projectName+"_"+_timeStamp);
}
_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();
for(auto &item:allItems){
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();
for(auto &p:lst){
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; //是否分段
for(auto &p:lst){
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)
{
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();
if (ret == QMessageBox::Ok)
{
emit panelDelete(_tagName, 0);
closeEvent->accept(); //允许关闭
}
else
{
closeEvent->ignore(); //阻止关闭
}
}
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::activePreview()
{
if(_pPreview){
_pPreview->raise();
_pPreview->activateWindow();
}
}
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<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);
}
// 累积层级项
_accumulatedBayItems.append(result.bayItems);
_accumulatedDeviceItems.append(result.deviceItems);
}
// 保存行数据
_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);
/*if (result.container) {
rowLayout->addItem(result.container);
}*/
// ✅ 每个变压器前加 stretch
rowLayout->addStretch();
// ✅ 变压器本身
rowLayout->addItem(result.container);
// ✅ 每个变压器后加 stretch
rowLayout->addStretch();
// 累积变压器层级项
_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();
}