#include #include #include #include "diagramEditor/diagramEditorBayDetailAddDlg.h" #include "diagramEditor/diagramEditorBayDetailSettingDlg.h" #include "ui_diagramEditorBayDetailAddDlg.h" #include "diagramEditor/diagramEditorBaseBlock.h" #include "diagramEditor/diagramEditorWizard.h" #include "diagramEditor/diagramEditorStructContainer.h" DiagramEditorBayDetailAddDlg::DiagramEditorBayDetailAddDlg(QWidget *parent) : QDialog(parent) , ui(new Ui::diagramEditorBayDetailAddDlg) ,_selectedModel(nullptr) ,_pParent(nullptr) ,_bindItemModel(nullptr) { ui->setupUi(this); this->setWindowFlags(Qt::FramelessWindowHint | windowFlags()); this->setWindowModality(Qt::WindowModal); initial(); } DiagramEditorBayDetailAddDlg::~DiagramEditorBayDetailAddDlg() { delete ui; } void DiagramEditorBayDetailAddDlg::initial() { _curMode = 0; _selectedModel = new QStandardItemModel(this); _selectedModel->setHorizontalHeaderLabels({"分类", "名称", "类型", "关联对象", "引用线路"}); ui->tableView_selected->setModel(_selectedModel); connect(ui->btn_add,&QPushButton::clicked,this,&DiagramEditorBayDetailAddDlg::onAddClicked); //connect(ui->btn_delete,&QPushButton::clicked,this,&DiagramEditorBayDetailAddDlg::onDeleteClicked); connect(ui->btn_save,&QPushButton::clicked,this,&DiagramEditorBayDetailAddDlg::onSaveClicked); connect(ui->btn_ok,&QPushButton::clicked,this,&DiagramEditorBayDetailAddDlg::onOkClicked); connect(ui->btn_cancel,&QPushButton::clicked,this,&DiagramEditorBayDetailAddDlg::onCancelClicked); connect(ui->cb_category,&QComboBox::currentTextChanged,this,&DiagramEditorBayDetailAddDlg::onCategoryChanged); connect(ui->tableView_selected, &QTableView::customContextMenuRequested, this, &DiagramEditorBayDetailAddDlg::onRouteRbtnClicked); connect(ui->tableView_items, &QTableView::customContextMenuRequested, this, &DiagramEditorBayDetailAddDlg::onComponentRbtnClicked); ui->cb_category->addItem("电气设备",0); ui->cb_category->addItem("连接关系",1); ui->cb_type->addItem("母线",1); ui->cb_type->addItem("异步电动机",2); ui->cb_type->addItem("断路器",3); ui->cb_type->addItem("电缆",4); ui->cb_type->addItem("电流互感器",5); ui->cb_type->addItem("电压互感器",6); ui->cb_type->addItem("隔离开关",7); ui->cb_type->addItem("接地开关",8); ui->cb_type->addItem("快速接地开关",9); ui->cb_type->addItem("双掷接地隔离开关",10); ui->cb_type->addItem("带电指示器",11); ui->cb_type->addItem("避雷器",12); ui->cb_type->addItem("电缆出线套筒",13); ui->cb_type->addItem("电缆端",14); ui->tableView_items->setContextMenuPolicy(Qt::CustomContextMenu); ui->tableView_items->setSelectionMode(QAbstractItemView::SingleSelection); ui->tableView_items->setSelectionBehavior(QAbstractItemView::SelectRows); ui->tableView_items->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); ui->tableView_items->verticalHeader()->setVisible(false); ui->tableView_selected->setContextMenuPolicy(Qt::CustomContextMenu); ui->tableView_selected->setSelectionMode(QAbstractItemView::SingleSelection); ui->tableView_selected->setSelectionBehavior(QAbstractItemView::SelectRows); ui->tableView_selected->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); ui->tableView_selected->verticalHeader()->setVisible(false); ui->cb_lineType->setItemData(0,1); //设置主线支线 ui->cb_lineType->setItemData(1,0); _bindItemModel = new QStandardItemModel(this); ui->cb_bindObj->setModel(_bindItemModel); } void DiagramEditorBayDetailAddDlg::updateBindLst() { _bindItemModel->clear(); QStandardItem* it = new QStandardItem("无"); _bindItemModel->appendRow(it); DiagramEditorBayBlock* pBlock = _pParent->getCurBlock(); if(pBlock){ QList lstCon = pBlock->getConnect(); DiagramEditorWizard* pWizard = _pParent->getWizard(); if(pWizard){ QMap mapCon = pWizard->getConnection(); for(auto& uid:lstCon){ if(mapCon.contains(uid)){ auto con = mapCon.value(uid); DiagramEditorConnectType conOp = con.getOpposite(pBlock->getName()); if(conOp.nType == 1){ //母线单block单item //ui->cb_bindObj->addItem(conOp.sName,conOp.nType); QStandardItem* item = new QStandardItem(conOp.sName); item->setData(conOp.nType, Qt::UserRole+1); // 设置用户数据 _bindItemModel->appendRow(item); } else if(conOp.nType == 3){ //变压器,选择对应进/出线口 QStandardItem* item = nullptr; if(con.nPara == 0){ item = new QStandardItem("高压接线端子"); } else if(con.nPara == 1){ item = new QStandardItem("中压接线端子"); } else if(con.nPara == 2){ item = new QStandardItem("低压接线端子"); } if(item){ item->setData(conOp.nType, Qt::UserRole+1); item->setData(con.nPara, Qt::UserRole+2); item->setData(conOp.sName, Qt::UserRole+3); _bindItemModel->appendRow(item); } } } } } } ui->cb_bindObj->setCurrentIndex(0); } void DiagramEditorBayDetailAddDlg::showDlg() { if(_pParent){ _selectedModel->clear(); _selectedModel->setHorizontalHeaderLabels({"分类", "名称", "类型", "关联对象", "引用线路"}); show(); auto pCompo = _pParent->getComponentModel(); auto pRoute = _pParent->getRouteModel(); int n = pRoute->rowCount(); ui->le_routeName->setText("线路"+QString::number(n+1)); ui->tableView_items->setModel(pCompo); ui->label->setText("新建线路"); ui->le_routeName->setReadOnly(true); _curMode = 0; updateBindLst(); int nCount = pRoute->rowCount(); for(int i = 0;i < nCount;++i){ QStandardItem *itemRouteName = pRoute->item(i, 0); int nMain = itemRouteName->data().toInt(); if(nMain == 1){ //主线已存在,新路线(本路线)设置为支线 ui->cb_lineType->setCurrentIndex(1); } } } } void DiagramEditorBayDetailAddDlg::showDlg(DiagramEditorRouteInfo info) { if(_pParent){ auto pCompo = _pParent->getComponentModel(); auto pRoute = _pParent->getRouteModel(); ui->tableView_items->setModel(pCompo); _selectedModel->clear(); _selectedModel->setHorizontalHeaderLabels({"分类", "名称", "类型", "关联对象", "引用线路"}); ui->le_routeName->setText(info.sRouteName); for(auto& component:info.lstCompo){ QStandardItem *itemCate = new QStandardItem(); QStandardItem *itemName = new QStandardItem(); QStandardItem *itemType = new QStandardItem(); QStandardItem *itemObj = new QStandardItem(); QStandardItem *itemRoute = new QStandardItem(); QString sCate; QString sType; if(component.nCategory == 0){ sCate = "电气设备"; if(component.nType == 1){ sType = "母线"; } else if(component.nType == 2){ sType = "异步电动机"; } else if(component.nType == 3){ sType = "断路器"; } else if(component.nType == 4){ sType = "电缆"; } else if(component.nType == 5){ sType = "电流互感器"; } else if(component.nType == 6){ sType = "电压互感器"; } else if(component.nType == 7){ sType = "隔离开关"; } else if(component.nType == 8){ sType = "接地开关"; } else if(component.nType == 9){ sType = "快速接地开关"; } else if(component.nType == 10){ sType = "双掷接地隔离开关"; } else if(component.nType == 11){ sType = "带电指示器"; } else if(component.nType == 12){ sType = "避雷器"; } else if(component.nType == 13){ sType = "电缆出线套筒"; } else if(component.nType == 14){ sType = "电缆端"; } } else if(component.nCategory == 1){ sCate = "连接关系"; if(component.nType == 1){ sType = "连接点"; } } itemCate->setText(sCate); itemName->setText(component.sName); itemType->setText(sType); itemObj->setText(component.sBindObj); itemRoute->setText(component.sUsedRoute.join(",")); QList lstItems; lstItems<appendRow(lstItems); } show(); ui->label->setText("编辑线路"); ui->le_routeName->setReadOnly(false); _curMode = 1; updateBindLst(); int nCount = pRoute->rowCount(); for(int i = 0;i < nCount;++i){ QStandardItem *itemRouteName = pRoute->item(i, 0); if(itemRouteName->text() == info.sRouteName){ int nMain = itemRouteName->data().toInt(); if(nMain == 1){ //读取并设置是否主线 ui->cb_lineType->setCurrentIndex(0); } else{ ui->cb_lineType->setCurrentIndex(1); } } } } } void DiagramEditorBayDetailAddDlg::onAddClicked() { // 获取当前选中的索引 QModelIndexList selectedIndexes = ui->tableView_items->selectionModel()->selectedRows(); if (selectedIndexes.isEmpty()) { return; // 没有选中任何行 } QSet uniqueRows; foreach (const QModelIndex &index, selectedIndexes) { uniqueRows.insert(index.row()); } auto pCompoModel = _pParent->getComponentModel(); foreach (int row, uniqueRows) { QStandardItem *sourceItemName = pCompoModel->item(row, 1); //名称 int rowCount = _selectedModel->rowCount(); for(int i = 0;i < rowCount;++i){ QStandardItem *item = _selectedModel->item(i, 1); if(item->text() == sourceItemName->text()){ QMessageBox::information(NULL, QString("提示"), QString::fromWCharArray(L"线路中设备已存在")); return; } } QList newRowItems; for (int col = 0; col < pCompoModel->columnCount(); ++col) { QStandardItem *sourceItem = pCompoModel->item(row, col); if (sourceItem) { // 创建深拷贝(重要!) if(col == 4){ //线路引用,特殊处理 QString strAllRoute = sourceItem->text(); QString strCurRoute = ui->le_routeName->text(); if(!strAllRoute.contains(strCurRoute)){ //第一个引用不加符号 if(strAllRoute.isEmpty()) sourceItem->setText(strCurRoute); else sourceItem->setText(strAllRoute+","+strCurRoute); } } QStandardItem *newItem = sourceItem->clone(); newRowItems.append(newItem); } else { // 如果单元格为空,创建空项目 newRowItems.append(new QStandardItem()); } } _selectedModel->appendRow(newRowItems); } } void DiagramEditorBayDetailAddDlg::onDeleteClicked() { } void DiagramEditorBayDetailAddDlg::onSaveClicked() { QString sCategory = ui->cb_category->currentText(); int nCate = ui->cb_category->currentData().toInt(); QString sName = ui->le_name->text(); QString sType = ui->cb_type->currentText(); int nType = ui->cb_type->currentData().toInt(); QString sBindObj = ui->cb_bindObj->currentText(); int nBindType = ui->cb_bindObj->currentData(Qt::UserRole+1).toInt(); int nBindPara = ui->cb_bindObj->currentData(Qt::UserRole+2).toInt(); QString sBindParent = ui->cb_bindObj->currentData(Qt::UserRole+3).toString(); if(_pParent){ auto pCompoModel = _pParent->getComponentModel(); int rowCount = pCompoModel->rowCount(); for(int i = 0;i < rowCount;++i){ QStandardItem *item = pCompoModel->item(i, 1); if(item->text() == sName){ 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: //覆盖 { QStandardItem *itemCate = pCompoModel->item(i, 0); QStandardItem *itemType = pCompoModel->item(i, 2); QStandardItem *itemObj = pCompoModel->item(i, 3); QStandardItem *itemRoute = pCompoModel->item(i, 4); item->setData(0); //覆盖时初始化方向占用 itemCate->setText(sCategory); itemType->setText(sType); itemType->setData(nType); itemObj->setText(sBindObj); return; } break; case QMessageBox::Cancel: // Cancel was clicked return; default: // should never be reached break; } } } QStandardItem *itemCate = new QStandardItem(); QStandardItem *itemName = new QStandardItem(); QStandardItem *itemType = new QStandardItem(); QStandardItem *itemObj = new QStandardItem(); QStandardItem *itemRoute = new QStandardItem(); itemCate->setText(sCategory); itemCate->setData(nCate); itemName->setText(sName); itemName->setData(0); //初始化方向占用 itemName->setData(QUuid::createUuid(),Qt::UserRole+3); //初始化时赋予uuid itemType->setText(sType); itemType->setData(nType); itemObj->setText(sBindObj); itemObj->setData(nBindType,Qt::UserRole+1); itemObj->setData(nBindPara,Qt::UserRole+2); itemObj->setData(sBindParent,Qt::UserRole+3); QList lstItems; lstItems<appendRow(lstItems); } } void DiagramEditorBayDetailAddDlg::onOkClicked() { QString sRoute = ui->le_routeName->text(); auto& mapRoute = _pParent->getBayInfo().mapRoute; QStringList lstName; //线路的设备列表 DiagramEditorRouteInfo routeInfo; routeInfo.sRouteName = sRoute; int rowCount = _selectedModel->rowCount(); for(int i = 0;i < rowCount;++i){ DiagramEditorComponentInfo compoInfo; QStandardItem *itemCategory = _selectedModel->item(i, 0); QStandardItem *itemName = _selectedModel->item(i, 1); QStandardItem *itemType = _selectedModel->item(i, 2); QStandardItem *itemBind = _selectedModel->item(i, 3); QStandardItem *itemAllRoute = _selectedModel->item(i, 4); QString sCate = itemCategory->text(); QString sName = itemName->text(); QString sType = itemType->text(); QString sBind = itemBind->text(); int nBindType = itemBind->data(Qt::UserRole + 1).toInt(); int nBindPara = itemBind->data(Qt::UserRole + 2).toInt(); QString sBindParent = itemBind->data(Qt::UserRole + 3).toString(); QString sAllRoute = itemAllRoute->text(); QUuid uid = itemName->data(Qt::UserRole+3).toUuid(); int nCate = 0; if(sCate == "电气设备") nCate = 0; else if(sCate == "连接关系") nCate = 1; int nType = 0; nType = itemType->data().toInt(); compoInfo.nCategory = nCate; compoInfo.sName = sName; compoInfo.nType = nType; compoInfo.sBindObj = sBind; compoInfo.nBindType = nBindType; compoInfo.nBindPara = nBindPara; compoInfo.sBindParent = sBindParent; compoInfo.uid = uid; compoInfo.sUsedRoute = sAllRoute.split(","); routeInfo.lstCompo.append(compoInfo); lstName.append(sName); } QString strCompoNames = lstName.join(","); int nMain = ui->cb_lineType->currentData().toInt(); //是否主线 if(nMain == 1){ //设本线路为主线,重置其他线路主线标志 auto pRoute = _pParent->getRouteModel(); int nCount = pRoute->rowCount(); for(int i = 0;i < rowCount;++i){ QStandardItem *itemRouteName = pRoute->item(i, 0); if(itemRouteName) itemRouteName->setData(0); } } routeInfo.bMainRoute = nMain; if(_curMode == 0){ if(mapRoute.contains(sRoute)){ QMessageBox::information(NULL, QString("提示"), QString::fromWCharArray(L"线路名重复")); return; } mapRoute.insert(sRoute,routeInfo); //插入线路到parent存储中 QStandardItem *itemRoute = new QStandardItem(); QStandardItem *itemNames = new QStandardItem(); itemRoute->setText(sRoute); itemRoute->setData(nMain); itemNames->setText(strCompoNames); QList lstItems; lstItems<getRouteModel(); pRoute->appendRow(lstItems); } else if(_curMode == 1){ mapRoute[sRoute] = routeInfo; auto pRoute = _pParent->getRouteModel(); int nCount = pRoute->rowCount(); for(int i = 0;i < rowCount;++i){ QStandardItem *itemName = pRoute->item(i, 0); if(itemName->text() == sRoute){ itemName->setData(nMain); QStandardItem *itemRoutes = pRoute->item(i, 1); itemRoutes->setText(strCompoNames); break; } } } hide(); } void DiagramEditorBayDetailAddDlg::onCancelClicked() { hide(); } void DiagramEditorBayDetailAddDlg::onCategoryChanged(const QString& str) { ui->cb_type->clear(); if(str == "电气设备"){ QStringList lst; ui->cb_type->addItem("母线",1); ui->cb_type->addItem("异步电动机",2); ui->cb_type->addItem("断路器",3); ui->cb_type->addItem("电缆",4); ui->cb_type->addItem("电流互感器",5); ui->cb_type->addItem("电压互感器",6); ui->cb_type->addItem("隔离开关",7); ui->cb_type->addItem("接地开关",8); ui->cb_type->addItem("快速接地开关",9); ui->cb_type->addItem("双掷接地隔离开关",10); ui->cb_type->addItem("带电指示器",11); ui->cb_type->addItem("避雷器",12); ui->cb_type->addItem("电缆出线套筒",13); ui->cb_type->addItem("电缆端",14); } else if(str == "连接关系"){ ui->cb_type->addItem("连接点",1); } } void DiagramEditorBayDetailAddDlg::onComponentDeleteClicked() { // 获取当前选中的索引 QModelIndexList selectedIndexes = ui->tableView_items->selectionModel()->selectedRows(); if (selectedIndexes.isEmpty()) { return; // 没有选中任何行 } // 获取行号并排序(从大到小删除避免索引变化) QList rowsToRemove; foreach (const QModelIndex &index, selectedIndexes) { rowsToRemove.append(index.row()); } // 获取当前选中的第一项索引 QModelIndex index = selectedIndexes.first(); if (!index.isValid()) { return; } QModelIndex indexName = index.sibling(index.row(),1); QString sName = indexName.data().toString(); bool bUsed = false; auto& mapRoute = _pParent->getBayInfo().mapRoute; //检索所有路线,判断设备占用情况 for(auto& route:mapRoute){ QString sRoute = route.sRouteName; for(auto& compo:route.lstCompo){ if(compo.sName == sName){ bUsed = true; break; } } } auto pCompoModel = _pParent->getComponentModel(); if(bUsed){ 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: //同步删除所有占用对象 { for(auto& route:mapRoute){ QString sRoute = route.sRouteName; for(int i = 0;i < route.lstCompo.size();++i){ QString sCompo = route.lstCompo[i].sName; if(sCompo == sName){ route.lstCompo.removeAt(i); } } } //todo:刷新主界面 foreach (int row, rowsToRemove) { QList rowItems; for (int col = 0; col < pCompoModel->columnCount(); ++col) { QStandardItem *item = pCompoModel->takeItem(row, col); rowItems.append(item); } qDeleteAll(rowItems); //take的item不释放 pCompoModel->removeRow(row); } } break; case QMessageBox::Cancel: // Cancel was clicked break; default: // should never be reached break; } } else{ // 移除行 foreach (int row, rowsToRemove) { QList rowItems; for (int col = 0; col < pCompoModel->columnCount(); ++col) { QStandardItem *item = pCompoModel->takeItem(row, col); rowItems.append(item); } qDeleteAll(rowItems); //take的item不释放 pCompoModel->removeRow(row); } } } void DiagramEditorBayDetailAddDlg::onComponentRbtnClicked(const QPoint &pos) { QModelIndex index = ui->tableView_items->indexAt(pos); if (!index.isValid()) { return; // 如果点击的是空白区域,直接返回 } QMenu menu; QAction *deleteAction = new QAction("删除", this); menu.addAction(deleteAction); // 连接删除菜单项的触发信号与槽函数 connect(deleteAction, &QAction::triggered, this, &DiagramEditorBayDetailAddDlg::onComponentDeleteClicked); // 在点击位置显示菜单 menu.exec(ui->tableView_items->mapToGlobal(pos)); } void DiagramEditorBayDetailAddDlg::onRouteDeleteClicked() { // 获取当前选中的索引 QModelIndexList selectedIndexes = ui->tableView_selected->selectionModel()->selectedRows(); if (selectedIndexes.isEmpty()) { return; // 没有选中任何行 } // 获取行号并排序(从大到小删除避免索引变化) QList rowsToRemove; foreach (const QModelIndex &index, selectedIndexes) { rowsToRemove.append(index.row()); } // 获取当前选中的第一项索引 QModelIndex index = selectedIndexes.first(); if (!index.isValid()) { return; } QModelIndex indexName = index.sibling(index.row(),1); QString sName = indexName.data().toString(); // 移除行 foreach (int row, rowsToRemove) { QList rowItems; for (int col = 0; col < _selectedModel->columnCount(); ++col) { QStandardItem *item = _selectedModel->takeItem(row, col); rowItems.append(item); } qDeleteAll(rowItems); //take的item不释放 _selectedModel->removeRow(row); } QString sRoute = ui->le_routeName->text(); auto pCompoModel = _pParent->getComponentModel(); int rowCount = pCompoModel->rowCount(); //移除设备库占用记录 for(int i = 0;i < rowCount;++i){ QStandardItem *itemName = pCompoModel->item(i, 1); if(itemName->text() == sName){ QStandardItem *itemUsed = pCompoModel->item(i, 4); QString sUsed = itemUsed->text(); QStringList lst = sUsed.split(","); lst.removeAll(sRoute); itemUsed->setText(lst.join(",")); } } } void DiagramEditorBayDetailAddDlg::onRouteRbtnClicked(const QPoint &pos) { QModelIndex index = ui->tableView_selected->indexAt(pos); if (!index.isValid()) { return; // 如果点击的是空白区域,直接返回 } QMenu menu; QAction *deleteAction = new QAction("移除", this); menu.addAction(deleteAction); // 连接删除菜单项的触发信号与槽函数 connect(deleteAction, &QAction::triggered, this, &DiagramEditorBayDetailAddDlg::onRouteDeleteClicked); // 在点击位置显示菜单 menu.exec(ui->tableView_selected->mapToGlobal(pos)); }