DiagramDesigner/diagramCavas/source/diagramEditor/diagramEditorWizard.cpp

512 lines
17 KiB
C++

#include <QMenu>
#include <QMessageBox>
#include "diagramEditor/diagramEditorWizard.h"
#include "diagramEditor/wizardBusTableDelegate.h"
#include "ui_diagramEditorWizard.h"
#include "diagramEditor/wizardBayContentDlg.h"
#include "diagramEditor/diagramEditorBaseBlock.h"
#include "diagramEditor/diagramEditorStructContainer.h"
#include "diagramEditor/diagramEditorBaySettingDlg.h"
DiagramEditorWizard::DiagramEditorWizard(QWidget *parent)
: QDialog(parent)
, ui(new Ui::diagramEditorWizard)
,_baySettingDlg(nullptr)
{
ui->setupUi(this);
_busPageChanged = false;
this->setWindowFlags(Qt::FramelessWindowHint | windowFlags());
initial();
}
DiagramEditorWizard::~DiagramEditorWizard()
{
delete ui;
}
void DiagramEditorWizard::initial()
{
_bayContentDlg = new WizardBayContentDlg(this);
_bayContentDlg->setParent(this);
ui->stackedWidget->addWidget(_bayContentDlg);
ui->tabWidget->tabBar()->setEnabled(false);
connect(ui->btn_ok,&QPushButton::clicked,this,&DiagramEditorWizard::onOkClicked);
connect(ui->btn_cancel,&QPushButton::clicked,this,&DiagramEditorWizard::onCancelClicked);
connect(ui->btn_last,&QPushButton::clicked,this,&DiagramEditorWizard::onLastClicked);
connect(ui->btn_next,&QPushButton::clicked,this,&DiagramEditorWizard::onNextClicked);
connect(ui->btn_addBus,&QPushButton::clicked,this,&DiagramEditorWizard::onAddBusClicked);
connect(ui->btn_addBay,&QPushButton::clicked,this,&DiagramEditorWizard::onAddBayClicked);
connect(ui->btn_addTrans,&QPushButton::clicked,this,&DiagramEditorWizard::onAddTransClicked);
QStringList headerText;
headerText<<"层级"<<"电压等级"<<"主接线"<<"分段方式"<<"接线方式";
ui->tableWidget_bus->setContextMenuPolicy(Qt::CustomContextMenu);
ui->tableWidget_bus->setSelectionMode(QAbstractItemView::SingleSelection);
ui->tableWidget_bus->setSelectionBehavior(QAbstractItemView::SelectRows);
ui->tableWidget_bus->setColumnCount(headerText.count());
ui->tableWidget_bus->setHorizontalHeaderLabels(headerText);
ui->tableWidget_bus->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
WizardBusTableDelegate* delegate = new WizardBusTableDelegate(this);
ui->tableWidget_bus->setItemDelegate(delegate);
connect(delegate,&WizardBusTableDelegate::editingFinished,this,&DiagramEditorWizard::onDelegateFinishEdit);
connect(ui->tableWidget_bus, &QTableWidget::customContextMenuRequested, this, &DiagramEditorWizard::onBusIndexRbtnClicked);
connect(ui->listWidget_bay,&QListWidget::itemClicked,this,&DiagramEditorWizard::onBayListSelected);
_divideType.insert(1,"A段");
_divideType.insert(2,"B段");
_divideType.insert(3,"C段");
_divideType.insert(4,"D段");
_divideType.insert(5,"E段");
_divideType.insert(6,"F段");
_divideType.insert(7,"G段");
_divideType.insert(8,"H段");
}
void DiagramEditorWizard::reOrderBus()
{
reindexQMap(_mapBus);
for(int row = 0 ;row < ui->tableWidget_bus->rowCount();++row)
{
QTableWidgetItem* pItem = ui->tableWidget_bus->item(row,0);
pItem->setText(""+QString::number(row+1)+"");
pItem->setData(Qt::UserRole,row);
}
}
void DiagramEditorWizard::generateBayStruct()
{
for(auto iter = _mapBus.begin();iter != _mapBus.end();++iter)
{
if(!iter->bChanged) //只生成修改过的程序
continue;
iter->bChanged = false;
QListWidgetItem* item = new QListWidgetItem(""+QString::number(iter->nIndex+1)+"");
item->setData(Qt::UserRole,iter->nIndex);
ui->listWidget_bay->addItem(item);
QString sVoltage; //电压前缀
sVoltage = QString::number(iter->dVoltage)+"kV";
if(iter->nLineType == 1){ //单母
int nDivide = iter->nNum1;
for(int i = 0;i < nDivide;++i){
QString sDivPre; //分段前缀
if(nDivide == 1){//不划分
}
else{
sDivPre = _divideType.value(i+1);
}
auto pContainer = new DiagramEditorStructContainer(this);
auto pBus = new DiagramEditorBusBlock(this);
pBus->setBusPro(sVoltage+"母线"+sDivPre,1,iter->dVoltage,0,i+1);
pContainer->insertBlock(1,pBus);
_mapSturctContainer[iter.key()].insert(i,pContainer);
}
}
else{ //双母
int nDivide1 = iter->nNum1; // Ⅰ母
int nDivide2 = iter->nNum2; // Ⅱ母
if(nDivide1 == nDivide2){ //双母线划分相同
for(int i = 0;i < nDivide1;++i){
QString sDivPre; //分段前缀
if(nDivide1 == 1){//不划分
}
else{
sDivPre = _divideType.value(i+1);
}
auto pContainer = new DiagramEditorStructContainer(this);
auto pBus1 = new DiagramEditorBusBlock(this);
pBus1->setBusPro(sVoltage+"Ⅰ母"+sDivPre,1,iter->dVoltage,1,i+1);
pContainer->insertBlock(1,pBus1);
auto pBus2 = new DiagramEditorBusBlock(this);
pBus2->setBusPro(sVoltage+"Ⅱ母"+sDivPre,1,iter->dVoltage,2,i+1);
pContainer->insertBlock(2,pBus2);
_mapSturctContainer[iter.key()].insert(i,pContainer);
}
}
else{ //双母线划分不同
if(nDivide1 > nDivide2){ //2母段数少于1母
for(int i = 0;i < nDivide1;++i){
QString sDivPre1 = _divideType.value(i+1); //分段前缀
auto pContainer = new DiagramEditorStructContainer(this);
auto pBus1 = new DiagramEditorBusBlock(this);
pBus1->setBusPro(sVoltage+"Ⅰ母"+sDivPre1,1,iter->dVoltage,1,i+1);
pContainer->insertBlock(1,pBus1);
if(i < nDivide2){
QString sDivPre2;
if(nDivide2 == 1){//不划分
}
else{
sDivPre2 = _divideType.value(i+1);
}
auto pBus2 = new DiagramEditorBusBlock(this);
pBus2->setBusPro(sVoltage+"Ⅱ母"+sDivPre2,1,iter->dVoltage,2,i+1);
pContainer->insertBlock(2,pBus2);
}
_mapSturctContainer[iter.key()].insert(i,pContainer);
}
}
else{
for(int i = 0;i < nDivide2;++i){ //1母段数少于2母
QString sDivPre2 = _divideType.value(i+1); //分段前缀
auto pContainer = new DiagramEditorStructContainer(this);
auto pBus2 = new DiagramEditorBusBlock(this);
pBus2->setBusPro(sVoltage+"Ⅱ母"+sDivPre2,1,iter->dVoltage,2,i+1);
pContainer->insertBlock(2,pBus2);
if(i < nDivide1){
QString sDivPre1;
if(nDivide1 == 1){//不划分
}
else{
sDivPre1 = _divideType.value(i+1);
}
auto pBus1 = new DiagramEditorBusBlock(this);
pBus1->setBusPro(sVoltage+"Ⅰ母"+sDivPre1,1,iter->dVoltage,1,i+1);
pContainer->insertBlock(1,pBus1);
}
_mapSturctContainer[iter.key()].insert(i,pContainer);
}
}
}
}
}
}
void DiagramEditorWizard::showSelectedBayPage(int nIdx)
{
}
template <typename T> void DiagramEditorWizard::reindexQMap(QMap<int, T> &map) {
if (map.isEmpty())
return;
// 保存原数据的值(按原键升序排列)
QVector<T> values;
values.reserve(map.size());
for (auto it = map.begin(); it != map.end(); ++it) {
values.append(std::move(it.value())); // 使用移动语义
}
// 清空原map并重新插入连续键
map.clear();
for (int newKey = 0; newKey < values.size(); ++newKey) {
map.insert(newKey, std::move(values[newKey])); // 再次移动
}
}
void DiagramEditorWizard::onOkClicked()
{
DiagramEditorWizardInfo info;
emit wizardFinish(info);
hide();
}
void DiagramEditorWizard::onCancelClicked()
{
hide();
}
void DiagramEditorWizard::onLastClicked()
{
if(ui->tabWidget->currentIndex() == 2){
ui->tabWidget->setCurrentIndex(1);
ui->stackedWidget_last->setCurrentIndex(1);
ui->stackedWidget_next->setCurrentIndex(0);
}
else if(ui->tabWidget->currentIndex() == 1){
ui->tabWidget->setCurrentIndex(0);
ui->stackedWidget_last->setCurrentIndex(0);
ui->stackedWidget_next->setCurrentIndex(0);
}
}
void DiagramEditorWizard::onNextClicked()
{
if(ui->tabWidget->currentIndex() == 0){
ui->tabWidget->setCurrentIndex(1);
ui->stackedWidget_last->setCurrentIndex(1);
ui->stackedWidget_next->setCurrentIndex(0);
generateBayStruct();
if(ui->listWidget_bay->count()){
QListWidgetItem* targetItem = ui->listWidget_bay->item(0);
// 确保项有效
if (targetItem) {
// 手动发射itemClicked信号
emit ui->listWidget_bay->itemClicked(targetItem);
// 如果需要同时选中该项
ui->listWidget_bay->setCurrentItem(targetItem);
}
}
}
else if(ui->tabWidget->currentIndex() == 1){
ui->tabWidget->setCurrentIndex(2);
ui->stackedWidget_last->setCurrentIndex(1);
ui->stackedWidget_next->setCurrentIndex(1);
}
}
void DiagramEditorWizard::onAddBusClicked()
{
int row = ui->tableWidget_bus->rowCount();
ui->tableWidget_bus->insertRow(row);
// 层级
QTableWidgetItem* levelItem = new QTableWidgetItem(""+QString::number(row)+"");
ui->tableWidget_bus->setItem(row, 0, levelItem);
levelItem->setData(Qt::UserRole,row);
// 电压等级
QTableWidgetItem* voltageItem = new QTableWidgetItem("未设置");
ui->tableWidget_bus->setItem(row, 1, voltageItem);
// 主接线
QTableWidgetItem* typeItem = new QTableWidgetItem("未设置");
ui->tableWidget_bus->setItem(row, 2, typeItem);
// 分段方式
QTableWidgetItem* divideItem = new QTableWidgetItem("未设置");
ui->tableWidget_bus->setItem(row, 3, divideItem);
// 接线方式
QTableWidgetItem* connectItem = new QTableWidgetItem("未选择");
ui->tableWidget_bus->setItem(row, 4, connectItem);
DiagramEditorWizardBusInfo info;
info.nIndex = row;
info.bChanged = true;
_mapBus.insert(row,info);
}
void DiagramEditorWizard::onAddBayClicked()
{
if(_baySettingDlg == nullptr){
_baySettingDlg = new DiagramEditorBaySettingDlg(this);
_baySettingDlg->setParent(this);
}
_baySettingDlg->showDlg(ui->listWidget_bay->currentItem()->data(Qt::UserRole).toInt());
}
void DiagramEditorWizard::onAddTransClicked()
{
}
void DiagramEditorWizard::onAddBayFinished(DiagramEditorWizardBayInfo info)
{
int curIndex = ui->listWidget_bay->currentItem()->data(Qt::UserRole).toInt(); //当前层级
if(!info.lstBindObj.isEmpty()){
auto pContainer = getContainerByBlock(curIndex,1,info.lstBindObj.first());
DiagramEditorBayBlock* pBlock = new DiagramEditorBayBlock(this);
pBlock->setName(info.sName);
pBlock->setType(2);
pBlock->setBayType(info.nType);
for(auto& sName:info.lstBindObj){
pBlock->addConnect(sName,1);
}
pContainer->insertBlock(3,pBlock);
_bayContentDlg->flushData(curIndex);
}
}
void DiagramEditorWizard::onDelegateFinishEdit(const QModelIndex &index, const QString &value)
{
int row = index.row();
int col = index.column();
if(_mapBus.contains(row)){
if(col == 1){
_mapBus[row].dVoltage = value.toDouble();
}
else if(col == 2){
_mapBus[row].nLineType = value.toInt();
QTableWidgetItem *divideItem = ui->tableWidget_bus->item(row, 3);
divideItem->setText("未设置");
divideItem->setData(Qt::UserRole,0);
}
else if(col == 3){
QStringList lst = value.split(",");
if(lst.size() > 1) //双母
{
_mapBus[row].nNum1 = lst[0].toInt();
_mapBus[row].nNum2= lst[1].toInt();
}
else{ //单母
_mapBus[row].nNum1 = lst[0].toInt();
}
}
else if(col == 4){
_mapBus[row].connectType = value.toInt();
}
_busPageChanged = true;
//qDebug() << row<<","<<col<<":"<<value;
}
}
void DiagramEditorWizard::onBusDeleteClicked()
{
// 获取当前选中的索引
QMessageBox msgBox;
msgBox.setText(QString::fromWCharArray(L"提示"));
msgBox.setInformativeText(QString::fromWCharArray(L"确认删除?"));
msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
msgBox.setDefaultButton(QMessageBox::Cancel);
int ret = msgBox.exec();
switch (ret) {
case QMessageBox::Ok:
{
QModelIndexList selectedIndexes = ui->tableWidget_bus->selectionModel()->selectedRows();
if (selectedIndexes.isEmpty()) {
return; // 没有选中任何行
}
// 获取当前选中的第一项索引
QModelIndex index = selectedIndexes.first();
if (!index.isValid()) {
return;
}
QModelIndex indexName = index.sibling(index.row(),0);
int nIndex = indexName.data(Qt::UserRole).toInt();
if(_mapBus.contains(nIndex)){
_mapBus.remove(nIndex);
}
int currentRow = ui->tableWidget_bus->currentRow();
if (currentRow == -1) {
return; // 没有选中行
}
ui->tableWidget_bus->removeRow(currentRow);
reOrderBus();
}
break;
case QMessageBox::Cancel:
// Cancel was clicked
break;
default:
// should never be reached
break;
}
}
void DiagramEditorWizard::onBusIndexRbtnClicked(const QPoint &pos)
{
// 获取当前点击的位置对应的索引
QModelIndex index = ui->tableWidget_bus->indexAt(pos);
if (!index.isValid()) {
return; // 如果点击的是空白区域,直接返回
}
QMenu menu;
QAction *deleteAction = new QAction("删除本层", this);
menu.addAction(deleteAction);
// 连接删除菜单项的触发信号与槽函数
connect(deleteAction, &QAction::triggered, this, &DiagramEditorWizard::onBusDeleteClicked);
// 在点击位置显示菜单
menu.exec(ui->tableWidget_bus->mapToGlobal(pos));
}
void DiagramEditorWizard::onBayListSelected(QListWidgetItem* pItem)
{
int nIndex = pItem->data(Qt::UserRole).toInt();
ui->label_level->setText(""+QString::number(nIndex+1)+"");
_bayContentDlg->flushData(nIndex);
}
QList<DiagramEditorBaseBlock*> DiagramEditorWizard::getTargetLevelBlocks(int nLevel,int nType)
{
QList<DiagramEditorBaseBlock*> lstBlock;
for(auto iter = _mapSturctContainer.begin();iter != _mapSturctContainer.end();++iter){
if(iter.key() == nLevel){
for(auto& container:iter.value())
{
auto mapBlock = container->getBlockMap();
for(auto& lst:mapBlock)
{
for(auto& block:lst)
{
if(block->getType() == nType){ //返回对应type
lstBlock.append(block);
}
}
}
}
}
}
return lstBlock;
}
DiagramEditorStructContainer* DiagramEditorWizard::getContainerByBlock(int nLevel,int nType,QString sName)
{
DiagramEditorStructContainer* pContainer = nullptr;
auto lstBlock = getTargetLevelBlocks(nLevel,nType);
for(auto& block:lstBlock){
if(block->getName() == sName){
pContainer = block->getCurContainer();
break;
}
}
return pContainer;
}
DiagramEditorBaseBlock* DiagramEditorWizard::getBlockByName(int nLevel,int nType,QString sName)
{
DiagramEditorBaseBlock* pBlock = nullptr;
auto lstBlock = getTargetLevelBlocks(nLevel,nType);
for(auto& block:lstBlock){
if(block->getName() == sName){
return block;
}
}
return pBlock;
}
bool DiagramEditorWizard::removeBlockByName(int nLevel,int nType,const QString& sName)
{
DiagramEditorStructContainer* pCon = getContainerByBlock(nLevel,nType,sName);
if(pCon){
auto& mapBlock = pCon->getBlockMap();
for(auto& lst:mapBlock){
for(int i = 0;i< lst.size();++i){
if(lst[i]->getName() == sName){
delete lst[i];
lst.removeAt(i);
return true;
}
}
}
}
return false;
}