fix editor topology setting
This commit is contained in:
parent
b089163f32
commit
3afdc864d9
|
|
@ -252,6 +252,7 @@ set(DIAGRAMCAVAS_SOURCE_FILES
|
|||
source/diagramEditor/layoutBuilder.cpp
|
||||
source/diagramEditor/transformerBuilder.cpp
|
||||
source/diagramEditor/layoutCalculator.cpp
|
||||
source/diagramEditor/editorDiagramLayoutEngine.cpp
|
||||
source/graphicsDataModel/baseModel.cpp
|
||||
source/graphicsDataModel/fixedPortsModel.cpp
|
||||
source/graphicsDataModel/diagramEditorModel.cpp
|
||||
|
|
|
|||
|
|
@ -11,11 +11,22 @@ QT_END_NAMESPACE
|
|||
|
||||
class DiagramEditorBayDetailSettingDlg;
|
||||
class QStandardItemModel;
|
||||
class QComboBox;
|
||||
|
||||
class DiagramEditorBayDetailAddDlg : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Column
|
||||
{
|
||||
Col_Category = 0,
|
||||
Col_Name,
|
||||
Col_Type,
|
||||
Col_BindObj,
|
||||
Col_Route,
|
||||
Col_Count
|
||||
};
|
||||
|
||||
DiagramEditorBayDetailAddDlg(QWidget *parent = nullptr);
|
||||
~DiagramEditorBayDetailAddDlg();
|
||||
|
||||
|
|
@ -25,6 +36,11 @@ public:
|
|||
void setParent(DiagramEditorBayDetailSettingDlg* p) {_pParent = p;}
|
||||
private:
|
||||
void updateBindLst(); //刷新关联列表
|
||||
void loadFromModelRow(int row); //载入行数据到界面
|
||||
void setComboBoxByData(QComboBox *combo,int targetData); //按 data 设置 ComboBox 适用于:cb_category cb_type
|
||||
void setBindObjComboBox(QComboBox *combo,int bindType,int bindPara,const QString &bindParent); //专用:设置 cb_bindObj(多 UserRole)
|
||||
|
||||
void syncSelectedModel(const QString &deviceName); //按设备名同步当前线路(todo:其他线路)
|
||||
public slots:
|
||||
void onAddClicked();
|
||||
void onDeleteClicked();
|
||||
|
|
@ -35,6 +51,7 @@ public slots:
|
|||
|
||||
void onComponentDeleteClicked();
|
||||
void onComponentRbtnClicked(const QPoint &pos);
|
||||
void onComponentSelected(const QModelIndex &index);
|
||||
void onRouteDeleteClicked();
|
||||
void onRouteRbtnClicked(const QPoint &pos); //线路右键菜单
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ QT_END_NAMESPACE
|
|||
|
||||
class DiagramEditorWizard;
|
||||
class DiagramEditorBayBlock;
|
||||
class QListWidgetItem;
|
||||
|
||||
class DiagramEditorBaySettingDlg : public QDialog
|
||||
{
|
||||
|
|
@ -29,6 +30,7 @@ public slots:
|
|||
void onOkClicked();
|
||||
void onCancelClicked();
|
||||
void onConnectLevelChanged(const QString&); //连接层级改变信号
|
||||
void onListItemClicked(QListWidgetItem *item);
|
||||
private:
|
||||
Ui::diagramEditorBaySettingDlg *ui;
|
||||
DiagramEditorWizard* _pWizard;
|
||||
|
|
|
|||
|
|
@ -11,11 +11,22 @@ namespace Ui { class diagramEditorTransDetailAddDlg; }
|
|||
QT_END_NAMESPACE
|
||||
|
||||
class DiagramEditorTransDetailSettingDlg;
|
||||
class QComboBox;
|
||||
|
||||
class DiagramEditorTransDetailAddDlg : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Column
|
||||
{
|
||||
Col_Category = 0,
|
||||
Col_Name,
|
||||
Col_Type,
|
||||
Col_BindObj,
|
||||
Col_Route,
|
||||
Col_Count
|
||||
};
|
||||
|
||||
DiagramEditorTransDetailAddDlg(QWidget *parent = nullptr);
|
||||
~DiagramEditorTransDetailAddDlg();
|
||||
|
||||
|
|
@ -25,6 +36,11 @@ public:
|
|||
void setParent(DiagramEditorTransDetailSettingDlg* p) {_pParent = p;}
|
||||
private:
|
||||
void updateBindLst(); //刷新关联列表
|
||||
void loadFromModelRow(int row); //加载数据到界面
|
||||
void setComboByData(QComboBox *combo, int data);
|
||||
void setBindObjCombo(QComboBox *combo,int bindType,const QString &bindParent);
|
||||
|
||||
void syncSelectedModel(const QString &deviceName); //同步设置到当前线路
|
||||
public slots:
|
||||
void onAddClicked();
|
||||
void onDeleteClicked();
|
||||
|
|
|
|||
|
|
@ -30,11 +30,13 @@ public slots:
|
|||
void onCancelClicked();
|
||||
void onConnectLevelChanged(const QString&); //连接层级改变信号
|
||||
void onBayTypeChanged(int n);
|
||||
void onTableItemSelected();
|
||||
private:
|
||||
Ui::diagramEditorTransSettingDlg *ui;
|
||||
DiagramEditorWizard* _pWizard;
|
||||
int _curModel; //0新增,1修改
|
||||
DiagramEditorTransformerBlock* _curOperateBlock; //当前修改对象
|
||||
QList<QString> _prepareDisconnectBlock; //准备断开的连接间隔
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ public:
|
|||
void flushTransPage(); //刷新变压器界面
|
||||
int getContainerIndex(int nLevel,DiagramEditorStructContainer*); //返回目标层级container的序号
|
||||
QUuid addConnection(const QString& str1,const QString& str2,int nType1,int nType2,int nPara = 0); //插入连接
|
||||
QUuid findConnection(const QString& str1,const QString& str2); //查找两个间隔的连接
|
||||
QMap<QUuid,DiagramEditorBriefConnect>& getConnection() {return _mapConnect;}
|
||||
QList<QUuid> findConnectionByBlock(QString,int); //通过block找到连接
|
||||
void removeConnection(QUuid);
|
||||
|
|
|
|||
|
|
@ -6,53 +6,61 @@
|
|||
|
||||
class DiagramLayoutEngine {
|
||||
public:
|
||||
struct LayoutResult {
|
||||
QRectF boundingRect;
|
||||
bool success = true;
|
||||
QString errorMessage;
|
||||
struct Context {
|
||||
int sourceId = 0;
|
||||
bool saveToModel = false;
|
||||
QMap<QString, QStandardItem*> itemCache;
|
||||
QMap<QString, DiagramEditorComponentInfo> componentsCache;
|
||||
|
||||
void initComponentsCache(const QMap<QString, DiagramEditorComponentInfo>& compos) {
|
||||
componentsCache = compos;
|
||||
}
|
||||
};
|
||||
|
||||
LayoutResult layoutRoutes(QMap<QString, DiagramEditorRouteInfo>& routes,
|
||||
QMap<QString, DiagramEditorComponentInfo>& components,
|
||||
const LayoutConfig& config,
|
||||
int nSource,
|
||||
bool saveToModel);
|
||||
QRectF executeLayout(
|
||||
QMap<QString, DiagramEditorRouteInfo>& routes,
|
||||
QMap<QString, DiagramEditorComponentInfo>& components,
|
||||
const LayoutConfig& config,
|
||||
Context& context
|
||||
);
|
||||
|
||||
private:
|
||||
// 主线布局
|
||||
// 主线相关
|
||||
QString findMainRoute(const QMap<QString, DiagramEditorRouteInfo>& routes);
|
||||
void layoutMainRoute(DiagramEditorRouteInfo& route,
|
||||
const LayoutConfig& config,
|
||||
bool saveToModel,
|
||||
int nSource);
|
||||
Context& context);
|
||||
|
||||
// 支线布局
|
||||
// 支线相关
|
||||
void layoutBranchRoute(DiagramEditorRouteInfo& route,
|
||||
const LayoutConfig& config,
|
||||
bool saveToModel,
|
||||
int nSource);
|
||||
|
||||
// 更新元件信息
|
||||
void updateComponentInfo(DiagramEditorComponentInfo& compo,
|
||||
Direction dir,
|
||||
const QPoint& delta,
|
||||
int rotate,
|
||||
bool saveToModel,
|
||||
int nSource);
|
||||
|
||||
// 拆分支线
|
||||
Context& context);
|
||||
void splitBranchRoute(DiagramEditorRouteInfo& route,
|
||||
bool saveToModel,
|
||||
int nSource);
|
||||
Context& context);
|
||||
void layoutBranchSequence(QList<DiagramEditorComponentInfo>& sequence,
|
||||
Direction branchDir,
|
||||
const LayoutConfig& config,
|
||||
Context& context,
|
||||
bool isOrder);
|
||||
|
||||
// 计算边界
|
||||
// 组件相关
|
||||
Direction determineBranchDirection(const DiagramEditorComponentInfo& currentNode,
|
||||
Direction preferredDir,
|
||||
Context& context);
|
||||
QPoint getComponentPosition(const QString& componentName,
|
||||
Context& context);
|
||||
void updateComponent(DiagramEditorComponentInfo& compo,
|
||||
Direction dir,
|
||||
const QPoint& position,
|
||||
int rotate,
|
||||
Context& context);
|
||||
|
||||
// 辅助函数
|
||||
QStandardItem* getNameItem(const QString& name, Context& context);
|
||||
int getComponentDirection(const QString& compoName, Context& context);
|
||||
QRectF calculateBoundingRect(const QMap<QString, DiagramEditorComponentInfo>& components);
|
||||
|
||||
// 辅助方法
|
||||
QString findMainRoute(const QMap<QString, DiagramEditorRouteInfo>& routes);
|
||||
QStandardItem* getNameItem(const QString& name, int nSource);
|
||||
|
||||
private:
|
||||
QMap<QString, QStandardItem*> m_itemCache;
|
||||
int m_compoWidth = 50; // 可配置
|
||||
int m_compoHeight = 30; // 可配置
|
||||
int m_compoWidth = 50;
|
||||
int m_compoHeight = 30;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -22,14 +22,12 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
static int getRotationAngle(Direction dir) {
|
||||
switch (dir) {
|
||||
case Direction::Right: return -90;
|
||||
case Direction::Left: return 90;
|
||||
case Direction::Down: return 0;
|
||||
case Direction::Up: return 180;
|
||||
default: return 0;
|
||||
}
|
||||
static bool isDirectionOccupied(int usedFlags, Direction dir) {
|
||||
return (usedFlags & static_cast<int>(dir)) != 0;
|
||||
}
|
||||
|
||||
static int markDirectionOccupied(int usedFlags, Direction dir) {
|
||||
return usedFlags | static_cast<int>(dir);
|
||||
}
|
||||
|
||||
static QPoint getIncrement(Direction dir, int hSpacing, int vSpacing) {
|
||||
|
|
@ -40,11 +38,13 @@ public:
|
|||
return QPoint(0, 0);
|
||||
}
|
||||
|
||||
static bool isDirectionOccupied(int usedDirections, Direction dir) {
|
||||
return (usedDirections & static_cast<int>(dir)) != 0;
|
||||
}
|
||||
|
||||
static int markDirectionOccupied(int usedDirections, Direction dir) {
|
||||
return usedDirections | static_cast<int>(dir);
|
||||
static int getRotationAngle(Direction dir) {
|
||||
switch (dir) {
|
||||
case Direction::Right: return -90;
|
||||
case Direction::Left: return 90;
|
||||
case Direction::Down: return 0;
|
||||
case Direction::Up: return 180;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ void DiagramEditorBayDetailAddDlg::initial()
|
|||
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);
|
||||
connect(ui->tableView_items, &QTableView::clicked, this, &DiagramEditorBayDetailAddDlg::onComponentSelected);
|
||||
|
||||
QMap<int,modelType> mapType = BaseTypeManager::getInstance()->getMapType(); //直接添加数据库中的基础类型
|
||||
for(auto iter = mapType.begin();iter != mapType.end();++iter){
|
||||
|
|
@ -70,6 +71,134 @@ void DiagramEditorBayDetailAddDlg::initial()
|
|||
ui->cb_bindObj->setModel(_bindItemModel);
|
||||
}
|
||||
|
||||
void DiagramEditorBayDetailAddDlg::loadFromModelRow(int row)
|
||||
{
|
||||
if (!_pParent)
|
||||
return;
|
||||
|
||||
auto pModel = _pParent->getComponentModel();
|
||||
if (!pModel || row < 0 || row >= pModel->rowCount())
|
||||
return;
|
||||
|
||||
// ===== 1. 基础字段 =====
|
||||
ui->le_name->setText(pModel->item(row, Col_Name)->text());
|
||||
|
||||
// ===== 2. 分类 cb_category =====
|
||||
int cateData = pModel->item(row, Col_Category)->data().toInt();
|
||||
setComboBoxByData(ui->cb_category, cateData);
|
||||
|
||||
// ===== 3. 类型 cb_type =====
|
||||
int typeData = pModel->item(row, Col_Type)->data().toInt();
|
||||
setComboBoxByData(ui->cb_type, typeData);
|
||||
|
||||
// ===== 4. 绑定对象 cb_bindObj =====
|
||||
QStandardItem *objItem = pModel->item(row, Col_BindObj);
|
||||
if (objItem)
|
||||
{
|
||||
int bindType = objItem->data(Qt::UserRole + 1).toInt();
|
||||
int bindPara = objItem->data(Qt::UserRole + 2).toInt();
|
||||
QString bindParent = objItem->data(Qt::UserRole + 3).toString();
|
||||
|
||||
setBindObjComboBox(
|
||||
ui->cb_bindObj,
|
||||
bindType,
|
||||
bindPara,
|
||||
bindParent
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void DiagramEditorBayDetailAddDlg::setComboBoxByData(
|
||||
QComboBox *combo,
|
||||
int targetData)
|
||||
{
|
||||
for (int i = 0; i < combo->count(); ++i)
|
||||
{
|
||||
if (combo->itemData(i).toInt() == targetData)
|
||||
{
|
||||
combo->setCurrentIndex(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
combo->setCurrentIndex(-1);
|
||||
}
|
||||
|
||||
void DiagramEditorBayDetailAddDlg::setBindObjComboBox(
|
||||
QComboBox *combo,
|
||||
int bindType,
|
||||
int bindPara,
|
||||
const QString &bindParent)
|
||||
{
|
||||
for (int i = 0; i < combo->count(); ++i)
|
||||
{
|
||||
int type = combo->itemData(i, Qt::UserRole + 1).toInt();
|
||||
int para = combo->itemData(i, Qt::UserRole + 2).toInt();
|
||||
QString parent = combo->itemData(i, Qt::UserRole + 3).toString();
|
||||
|
||||
if (type == bindType &&
|
||||
para == bindPara &&
|
||||
parent == bindParent)
|
||||
{
|
||||
combo->setCurrentIndex(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
combo->setCurrentIndex(-1);
|
||||
}
|
||||
|
||||
void DiagramEditorBayDetailAddDlg::syncSelectedModel(
|
||||
const QString &deviceName)
|
||||
{
|
||||
if (!_pParent || !_selectedModel)
|
||||
return;
|
||||
|
||||
auto pMainModel = _pParent->getComponentModel();
|
||||
|
||||
// ===== 1. 找到主表中最新数据 =====
|
||||
QStandardItem *mainNameItem = nullptr;
|
||||
int mainRow = -1;
|
||||
|
||||
for (int i = 0; i < pMainModel->rowCount(); ++i)
|
||||
{
|
||||
QStandardItem *item = pMainModel->item(i, Col_Name);
|
||||
if (item && item->text() == deviceName)
|
||||
{
|
||||
mainNameItem = item;
|
||||
mainRow = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!mainNameItem)
|
||||
return;
|
||||
|
||||
// ===== 2. 同步 _selectedModel 中所有引用该设备的行 =====
|
||||
for (int i = 0; i < _selectedModel->rowCount(); ++i)
|
||||
{
|
||||
QStandardItem *selNameItem = _selectedModel->item(i, Col_Name);
|
||||
if (!selNameItem)
|
||||
continue;
|
||||
|
||||
if (selNameItem->text() != deviceName)
|
||||
continue;
|
||||
|
||||
// ===== 同步字段 =====
|
||||
_selectedModel->item(i, Col_Category)
|
||||
->setText(pMainModel->item(mainRow, Col_Category)->text());
|
||||
|
||||
_selectedModel->item(i, Col_Type)
|
||||
->setText(pMainModel->item(mainRow, Col_Type)->text());
|
||||
|
||||
QStandardItem *mainObj = pMainModel->item(mainRow, Col_BindObj);
|
||||
QStandardItem *selObj = _selectedModel->item(i, Col_BindObj);
|
||||
|
||||
selObj->setText(mainObj->text());
|
||||
selObj->setData(mainObj->data(Qt::UserRole + 1), Qt::UserRole + 1);
|
||||
selObj->setData(mainObj->data(Qt::UserRole + 2), Qt::UserRole + 2);
|
||||
selObj->setData(mainObj->data(Qt::UserRole + 3), Qt::UserRole + 3);
|
||||
}
|
||||
}
|
||||
|
||||
void DiagramEditorBayDetailAddDlg::updateBindLst()
|
||||
{
|
||||
_bindItemModel->clear();
|
||||
|
|
@ -266,76 +395,90 @@ 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();
|
||||
// ===== 1. 读取 UI 数据 =====
|
||||
const QString sCategory = ui->cb_category->currentText();
|
||||
const int nCate = ui->cb_category->currentData().toInt();
|
||||
|
||||
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();
|
||||
const QString sName = ui->le_name->text();
|
||||
if (sName.isEmpty())
|
||||
return;
|
||||
|
||||
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);
|
||||
const QString sType = ui->cb_type->currentText();
|
||||
const int nType = ui->cb_type->currentData().toInt();
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
const QString sBindObj = ui->cb_bindObj->currentText();
|
||||
const int nBindType = ui->cb_bindObj->currentData(Qt::UserRole + 1).toInt();
|
||||
const int nBindPara = ui->cb_bindObj->currentData(Qt::UserRole + 2).toInt();
|
||||
const QString sBindParent = ui->cb_bindObj->currentData(Qt::UserRole + 3).toString();
|
||||
|
||||
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);
|
||||
if (!_pParent)
|
||||
return;
|
||||
|
||||
QList<QStandardItem*> lstItems;
|
||||
lstItems<<itemCate<<itemName<<itemType<<itemObj<<itemRoute;
|
||||
pCompoModel->appendRow(lstItems);
|
||||
auto pModel = _pParent->getComponentModel();
|
||||
if (!pModel)
|
||||
return;
|
||||
|
||||
// ===== 2. 查找是否已存在同名设备 =====
|
||||
for (int row = 0; row < pModel->rowCount(); ++row)
|
||||
{
|
||||
QStandardItem *nameItem = pModel->item(row, Col_Name);
|
||||
if (!nameItem)
|
||||
continue;
|
||||
|
||||
if (nameItem->text() != sName)
|
||||
continue;
|
||||
|
||||
// ===== 3. 重名确认 =====
|
||||
QMessageBox msgBox;
|
||||
msgBox.setText(QString::fromWCharArray(L"提示"));
|
||||
msgBox.setInformativeText(QString::fromWCharArray(L"设备名已存在,是否覆盖?"));
|
||||
msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
|
||||
msgBox.setDefaultButton(QMessageBox::Cancel);
|
||||
|
||||
if (msgBox.exec() != QMessageBox::Ok)
|
||||
return;
|
||||
|
||||
// ===== 4. 覆盖已有行 =====
|
||||
pModel->item(row, Col_Category)->setText(sCategory);
|
||||
pModel->item(row, Col_Category)->setData(nCate);
|
||||
|
||||
nameItem->setData(0); // 初始化方向占用
|
||||
|
||||
pModel->item(row, Col_Type)->setText(sType);
|
||||
pModel->item(row, Col_Type)->setData(nType);
|
||||
|
||||
QStandardItem *objItem = pModel->item(row, Col_BindObj);
|
||||
objItem->setText(sBindObj);
|
||||
objItem->setData(nBindType, Qt::UserRole + 1);
|
||||
objItem->setData(nBindPara, Qt::UserRole + 2);
|
||||
objItem->setData(sBindParent, Qt::UserRole + 3);
|
||||
|
||||
syncSelectedModel(sName);
|
||||
return;
|
||||
}
|
||||
|
||||
// ===== 5. 新增行 =====
|
||||
QList<QStandardItem*> rowItems;
|
||||
rowItems.resize(Col_Count);
|
||||
|
||||
rowItems[Col_Category] = new QStandardItem(sCategory);
|
||||
rowItems[Col_Category]->setData(nCate);
|
||||
|
||||
rowItems[Col_Name] = new QStandardItem(sName);
|
||||
rowItems[Col_Name]->setData(0); // 方向占用
|
||||
rowItems[Col_Name]->setData(QUuid::createUuid(), Qt::UserRole + 3);
|
||||
|
||||
rowItems[Col_Type] = new QStandardItem(sType);
|
||||
rowItems[Col_Type]->setData(nType);
|
||||
|
||||
rowItems[Col_BindObj] = new QStandardItem(sBindObj);
|
||||
rowItems[Col_BindObj]->setData(nBindType, Qt::UserRole + 1);
|
||||
rowItems[Col_BindObj]->setData(nBindPara, Qt::UserRole + 2);
|
||||
rowItems[Col_BindObj]->setData(sBindParent, Qt::UserRole + 3);
|
||||
|
||||
rowItems[Col_Route] = new QStandardItem();
|
||||
|
||||
pModel->appendRow(rowItems);
|
||||
}
|
||||
|
||||
void DiagramEditorBayDetailAddDlg::onOkClicked()
|
||||
|
|
@ -573,6 +716,12 @@ void DiagramEditorBayDetailAddDlg::onComponentRbtnClicked(const QPoint &pos)
|
|||
menu.exec(ui->tableView_items->mapToGlobal(pos));
|
||||
}
|
||||
|
||||
void DiagramEditorBayDetailAddDlg::onComponentSelected(const QModelIndex &index)
|
||||
{
|
||||
int row = index.row();
|
||||
loadFromModelRow(row);
|
||||
}
|
||||
|
||||
void DiagramEditorBayDetailAddDlg::onRouteDeleteClicked()
|
||||
{
|
||||
// 获取当前选中的索引
|
||||
|
|
|
|||
|
|
@ -53,15 +53,27 @@ void DiagramEditorBaySettingDlg::showDlg(int nLevel,DiagramEditorBayBlock* p)
|
|||
if(p){
|
||||
auto lstCon = p->getConnect();
|
||||
QStringList lst;
|
||||
QSet<QString> otherItems;
|
||||
|
||||
for(auto& conId:lstCon){
|
||||
if(_pWizard->getConnection().contains(conId)){
|
||||
auto con = _pWizard->getConnection().value(conId);
|
||||
QString sOpposite = con.getOpposite(p->getName()).sName;
|
||||
lst.append(sOpposite);
|
||||
if(con.getOpposite(p->getName()).nType == 3){
|
||||
otherItems.insert(sOpposite);
|
||||
}
|
||||
}
|
||||
}
|
||||
ui->listWidget->addItems(lst);
|
||||
|
||||
for(int i = 0; i < ui->listWidget->count(); ++i){
|
||||
QListWidgetItem *item = ui->listWidget->item(i);
|
||||
if (otherItems.contains(item->text()))
|
||||
{
|
||||
item->setFlags(item->flags() & ~Qt::ItemIsEnabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_curLevel = nLevel;
|
||||
|
|
@ -92,6 +104,7 @@ void DiagramEditorBaySettingDlg::initial()
|
|||
connect(ui->btn_ok,&QPushButton::clicked,this,&DiagramEditorBaySettingDlg::onOkClicked);
|
||||
connect(ui->btn_cancel,&QPushButton::clicked,this,&DiagramEditorBaySettingDlg::onCancelClicked);
|
||||
connect(ui->cb_level,&QComboBox::currentTextChanged,this,&DiagramEditorBaySettingDlg::onConnectLevelChanged);
|
||||
connect(ui->listWidget, &QListWidget::itemClicked,this,&DiagramEditorBaySettingDlg::onListItemClicked);
|
||||
}
|
||||
|
||||
void DiagramEditorBaySettingDlg::onAddClicked()
|
||||
|
|
@ -187,3 +200,36 @@ void DiagramEditorBaySettingDlg::onConnectLevelChanged(const QString& str)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DiagramEditorBaySettingDlg::onListItemClicked(QListWidgetItem *item)
|
||||
{
|
||||
if (!item || !_pWizard)
|
||||
return;
|
||||
|
||||
QString targetName = item->text();
|
||||
|
||||
// 1. 根据 targetName 反查 level
|
||||
// 这里假设:level -> target 是一对多关系
|
||||
// 需要遍历所有 level,查找包含该 target 的 level
|
||||
int levelCount = ui->cb_level->count();
|
||||
for (int i = 0; i < levelCount; ++i)
|
||||
{
|
||||
int nIndex = ui->cb_level->itemData(i).toInt();
|
||||
auto lstBlock = _pWizard->getTargetLevelBlocks(nIndex, 1);
|
||||
|
||||
for (auto& block : lstBlock)
|
||||
{
|
||||
if (block->getName() == targetName)
|
||||
{
|
||||
// 2. 设置 cb_level
|
||||
ui->cb_level->setCurrentIndex(i);
|
||||
|
||||
// 3. cb_target 会自动由 onConnectLevelChanged 刷新
|
||||
// 4. 再设置 cb_target 为当前项
|
||||
ui->cb_target->setCurrentText(targetName);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,10 @@ void DiagramEditorTransDetailAddDlg::initial()
|
|||
connect(ui->cb_category,&QComboBox::currentTextChanged,this,&DiagramEditorTransDetailAddDlg::onCategoryChanged);
|
||||
connect(ui->tableView_selected, &QTableView::customContextMenuRequested, this, &DiagramEditorTransDetailAddDlg::onRouteRbtnClicked);
|
||||
connect(ui->tableView_items, &QTableView::customContextMenuRequested, this, &DiagramEditorTransDetailAddDlg::onComponentRbtnClicked);
|
||||
connect(ui->tableView_items, &QTableView::clicked, this, [this](const QModelIndex &index){
|
||||
int row = index.row();
|
||||
loadFromModelRow(row);
|
||||
});
|
||||
|
||||
QMap<int,modelType> mapType = BaseTypeManager::getInstance()->getMapType(); //直接添加数据库中的基础类型
|
||||
for(auto iter = mapType.begin();iter != mapType.end();++iter){
|
||||
|
|
@ -131,6 +135,95 @@ void DiagramEditorTransDetailAddDlg::showDlg(DiagramEditorRouteInfo info)
|
|||
}
|
||||
}
|
||||
|
||||
void DiagramEditorTransDetailAddDlg::setComboByData(QComboBox *combo, int data)
|
||||
{
|
||||
for (int i = 0; i < combo->count(); ++i)
|
||||
{
|
||||
if (combo->itemData(i).toInt() == data)
|
||||
{
|
||||
combo->setCurrentIndex(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
combo->setCurrentIndex(-1);
|
||||
}
|
||||
|
||||
void DiagramEditorTransDetailAddDlg::setBindObjCombo(QComboBox *combo,
|
||||
int bindType,
|
||||
const QString &bindParent)
|
||||
{
|
||||
for (int i = 0; i < combo->count(); ++i)
|
||||
{
|
||||
if (combo->itemData(i, Qt::UserRole + 1).toInt() == bindType &&
|
||||
combo->itemData(i, Qt::UserRole + 3).toString() == bindParent)
|
||||
{
|
||||
combo->setCurrentIndex(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
combo->setCurrentIndex(-1);
|
||||
}
|
||||
|
||||
void DiagramEditorTransDetailAddDlg::syncSelectedModel(
|
||||
const QString &deviceName)
|
||||
{
|
||||
if (!_pParent || !_selectedModel)
|
||||
return;
|
||||
|
||||
auto pMainModel = _pParent->getComponentModel();
|
||||
|
||||
int mainRow = -1;
|
||||
for (int i = 0; i < pMainModel->rowCount(); ++i)
|
||||
{
|
||||
if (pMainModel->item(i, Col_Name)->text() == deviceName)
|
||||
{
|
||||
mainRow = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mainRow < 0)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < _selectedModel->rowCount(); ++i)
|
||||
{
|
||||
if (_selectedModel->item(i, Col_Name)->text() != deviceName)
|
||||
continue;
|
||||
|
||||
_selectedModel->item(i, Col_Category)
|
||||
->setText(pMainModel->item(mainRow, Col_Category)->text());
|
||||
|
||||
_selectedModel->item(i, Col_Type)
|
||||
->setText(pMainModel->item(mainRow, Col_Type)->text());
|
||||
|
||||
QStandardItem *mainObj = pMainModel->item(mainRow, Col_BindObj);
|
||||
QStandardItem *selObj = _selectedModel->item(i, Col_BindObj);
|
||||
|
||||
selObj->setText(mainObj->text());
|
||||
selObj->setData(mainObj->data(Qt::UserRole + 1), Qt::UserRole + 1);
|
||||
selObj->setData(mainObj->data(Qt::UserRole + 3), Qt::UserRole + 3);
|
||||
}
|
||||
}
|
||||
|
||||
void DiagramEditorTransDetailAddDlg::loadFromModelRow(int row)
|
||||
{
|
||||
auto pModel = _pParent->getComponentModel();
|
||||
if (!pModel) return;
|
||||
|
||||
ui->le_name->setText(pModel->item(row, Col_Name)->text());
|
||||
|
||||
setComboByData(ui->cb_category,
|
||||
pModel->item(row, Col_Category)->data().toInt());
|
||||
|
||||
setComboByData(ui->cb_type,
|
||||
pModel->item(row, Col_Type)->data().toInt());
|
||||
|
||||
QStandardItem *objItem = pModel->item(row, Col_BindObj);
|
||||
setBindObjCombo(ui->cb_bindObj,
|
||||
objItem->data(Qt::UserRole + 1).toInt(),
|
||||
objItem->data(Qt::UserRole + 3).toString());
|
||||
}
|
||||
|
||||
void DiagramEditorTransDetailAddDlg::updateBindLst()
|
||||
{
|
||||
_bindItemModel->clear();
|
||||
|
|
@ -210,55 +303,82 @@ void DiagramEditorTransDetailAddDlg::updateBindLst()
|
|||
|
||||
void DiagramEditorTransDetailAddDlg::onAddClicked()
|
||||
{
|
||||
// 获取当前选中的索引
|
||||
QModelIndexList selectedIndexes = ui->tableView_items->selectionModel()->selectedRows();
|
||||
if (selectedIndexes.isEmpty()) {
|
||||
return; // 没有选中任何行
|
||||
}
|
||||
if (!_pParent || !_selectedModel)
|
||||
return;
|
||||
|
||||
QSet<int> uniqueRows;
|
||||
foreach (const QModelIndex &index, selectedIndexes) {
|
||||
uniqueRows.insert(index.row());
|
||||
}
|
||||
auto pMainModel = _pParent->getComponentModel();
|
||||
if (!pMainModel)
|
||||
return;
|
||||
|
||||
auto pCompoModel = _pParent->getComponentModel();
|
||||
// ===== 1. 获取选中行 =====
|
||||
QModelIndexList indexes =
|
||||
ui->tableView_items->selectionModel()->selectedRows();
|
||||
|
||||
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"线路中设备已存在"));
|
||||
if (indexes.isEmpty())
|
||||
return;
|
||||
|
||||
QSet<int> rows;
|
||||
for (const QModelIndex &idx : indexes)
|
||||
rows.insert(idx.row());
|
||||
|
||||
const QString curRoute = ui->le_routeName->text();
|
||||
|
||||
// ===== 2. 逐行处理 =====
|
||||
for (int row : rows)
|
||||
{
|
||||
QStandardItem *mainNameItem = pMainModel->item(row, Col_Name);
|
||||
if (!mainNameItem)
|
||||
continue;
|
||||
|
||||
const QString deviceName = mainNameItem->text();
|
||||
|
||||
// ===== 3. 去重校验 =====
|
||||
for (int i = 0; i < _selectedModel->rowCount(); ++i)
|
||||
{
|
||||
if (_selectedModel->item(i, Col_Name)->text() == deviceName)
|
||||
{
|
||||
QMessageBox::information(
|
||||
this,
|
||||
QString("提示"),
|
||||
QString::fromWCharArray(L"线路中设备已存在")
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
QList<QStandardItem*> 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();
|
||||
// ===== 4. 深拷贝主表行 =====
|
||||
QList<QStandardItem*> newRow;
|
||||
newRow.reserve(Col_Count);
|
||||
|
||||
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());
|
||||
for (int col = 0; col < Col_Count; ++col)
|
||||
{
|
||||
QStandardItem *srcItem = pMainModel->item(row, col);
|
||||
if (!srcItem)
|
||||
{
|
||||
newRow.append(new QStandardItem());
|
||||
continue;
|
||||
}
|
||||
|
||||
QStandardItem *newItem = srcItem->clone();
|
||||
|
||||
// ===== 5. Route 字段特殊处理 =====
|
||||
if (col == Col_Route)
|
||||
{
|
||||
QString routeText = newItem->text();
|
||||
|
||||
if (!routeText.contains(curRoute))
|
||||
{
|
||||
if (routeText.isEmpty())
|
||||
newItem->setText(curRoute);
|
||||
else
|
||||
newItem->setText(routeText + "," + curRoute);
|
||||
}
|
||||
}
|
||||
|
||||
newRow.append(newItem);
|
||||
}
|
||||
_selectedModel->appendRow(newRowItems);
|
||||
|
||||
_selectedModel->appendRow(newRow);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -269,74 +389,88 @@ void DiagramEditorTransDetailAddDlg::onDeleteClicked()
|
|||
|
||||
void DiagramEditorTransDetailAddDlg::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();
|
||||
QString sBindParent = ui->cb_bindObj->currentData(Qt::UserRole+3).toString();
|
||||
// ===== 1. 读取 UI 数据 =====
|
||||
const QString sCategory = ui->cb_category->currentText();
|
||||
const int nCate = ui->cb_category->currentData().toInt();
|
||||
|
||||
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();
|
||||
const QString sName = ui->le_name->text();
|
||||
if (sName.isEmpty())
|
||||
return;
|
||||
|
||||
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);
|
||||
const QString sType = ui->cb_type->currentText();
|
||||
const int nType = ui->cb_type->currentData().toInt();
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
const QString sBindObj = ui->cb_bindObj->currentText();
|
||||
const int nBindType = ui->cb_bindObj->currentData(Qt::UserRole + 1).toInt();
|
||||
const QString sBindParent = ui->cb_bindObj->currentData(Qt::UserRole + 3).toString();
|
||||
|
||||
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);
|
||||
itemObj->setData(sBindParent,Qt::UserRole+3);
|
||||
if (!_pParent)
|
||||
return;
|
||||
|
||||
QList<QStandardItem*> lstItems;
|
||||
lstItems<<itemCate<<itemName<<itemType<<itemObj<<itemRoute;
|
||||
pCompoModel->appendRow(lstItems);
|
||||
auto pModel = _pParent->getComponentModel();
|
||||
if (!pModel)
|
||||
return;
|
||||
|
||||
// ===== 2. 查找同名设备 =====
|
||||
for (int row = 0; row < pModel->rowCount(); ++row)
|
||||
{
|
||||
QStandardItem *nameItem = pModel->item(row, Col_Name);
|
||||
if (!nameItem)
|
||||
continue;
|
||||
|
||||
if (nameItem->text() != sName)
|
||||
continue;
|
||||
|
||||
// ===== 3. 重名确认 =====
|
||||
QMessageBox msgBox;
|
||||
msgBox.setText(QString::fromWCharArray(L"提示"));
|
||||
msgBox.setInformativeText(QString::fromWCharArray(L"设备名已存在,是否覆盖?"));
|
||||
msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
|
||||
msgBox.setDefaultButton(QMessageBox::Cancel);
|
||||
|
||||
if (msgBox.exec() != QMessageBox::Ok)
|
||||
return;
|
||||
|
||||
// ===== 4. 覆盖已有行(完整更新)=====
|
||||
pModel->item(row, Col_Category)->setText(sCategory);
|
||||
pModel->item(row, Col_Category)->setData(nCate);
|
||||
|
||||
nameItem->setData(0); // 初始化方向占用
|
||||
|
||||
QStandardItem *typeItem = pModel->item(row, Col_Type);
|
||||
typeItem->setText(sType);
|
||||
typeItem->setData(nType);
|
||||
|
||||
QStandardItem *objItem = pModel->item(row, Col_BindObj);
|
||||
objItem->setText(sBindObj);
|
||||
objItem->setData(nBindType, Qt::UserRole + 1);
|
||||
objItem->setData(sBindParent, Qt::UserRole + 3);
|
||||
|
||||
syncSelectedModel(sName);
|
||||
return;
|
||||
}
|
||||
|
||||
// ===== 5. 新增行 =====
|
||||
QList<QStandardItem*> rowItems;
|
||||
rowItems.resize(Col_Count);
|
||||
|
||||
rowItems[Col_Category] = new QStandardItem(sCategory);
|
||||
rowItems[Col_Category]->setData(nCate);
|
||||
|
||||
rowItems[Col_Name] = new QStandardItem(sName);
|
||||
rowItems[Col_Name]->setData(0); // 方向占用
|
||||
rowItems[Col_Name]->setData(QUuid::createUuid(), Qt::UserRole + 3);
|
||||
|
||||
rowItems[Col_Type] = new QStandardItem(sType);
|
||||
rowItems[Col_Type]->setData(nType);
|
||||
|
||||
rowItems[Col_BindObj] = new QStandardItem(sBindObj);
|
||||
rowItems[Col_BindObj]->setData(nBindType, Qt::UserRole + 1);
|
||||
rowItems[Col_BindObj]->setData(sBindParent, Qt::UserRole + 3);
|
||||
|
||||
rowItems[Col_Route] = new QStandardItem();
|
||||
|
||||
pModel->appendRow(rowItems);
|
||||
}
|
||||
|
||||
void DiagramEditorTransDetailAddDlg::onOkClicked()
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#include "diagramEditor/diagramEditorStructContainer.h"
|
||||
#include "diagramEditor/wizardBayContentDlg.h"
|
||||
#include "common/core_model/constants.h"
|
||||
#include <QTimer>
|
||||
|
||||
DiagramEditorTransSettingDlg::DiagramEditorTransSettingDlg(QWidget *parent)
|
||||
: QDialog(parent)
|
||||
|
|
@ -74,7 +75,16 @@ void DiagramEditorTransSettingDlg::showDlg(DiagramEditorTransformerBlock* p)
|
|||
ui->tableWidget->insertRow(row);
|
||||
|
||||
//名称
|
||||
int bayType = 0;
|
||||
auto pBlock = _pWizard->getBlockByName_all(sOpposite);
|
||||
if(pBlock){
|
||||
auto pBay = dynamic_cast<DiagramEditorBayBlock*>(pBlock);
|
||||
if(pBay){
|
||||
bayType = int(pBay->getBayType());
|
||||
}
|
||||
}
|
||||
QTableWidgetItem* nameItem = new QTableWidgetItem(sOpposite);
|
||||
nameItem->setData(Qt::UserRole, bayType);
|
||||
ui->tableWidget->setItem(row, 0, nameItem);
|
||||
|
||||
//位置
|
||||
|
|
@ -112,6 +122,7 @@ void DiagramEditorTransSettingDlg::initial()
|
|||
connect(ui->btn_cancel,&QPushButton::clicked,this,&DiagramEditorTransSettingDlg::onCancelClicked);
|
||||
connect(ui->cb_level,&QComboBox::currentTextChanged,this,&DiagramEditorTransSettingDlg::onConnectLevelChanged);
|
||||
connect(ui->cb_bayType,&QComboBox::currentIndexChanged,this,&DiagramEditorTransSettingDlg::onBayTypeChanged);
|
||||
connect(ui->tableWidget, &QTableWidget::itemSelectionChanged,this, &DiagramEditorTransSettingDlg::onTableItemSelected);
|
||||
ui->cb_bayType->setItemData(0,3); //将类型与item关联
|
||||
ui->cb_bayType->setItemData(1,4);
|
||||
|
||||
|
|
@ -141,6 +152,7 @@ void DiagramEditorTransSettingDlg::onAddClicked()
|
|||
|
||||
//名称
|
||||
QTableWidgetItem* nameItem = new QTableWidgetItem(str);
|
||||
nameItem->setData(Qt::UserRole, ui->cb_bayType->currentData().toInt());
|
||||
ui->tableWidget->setItem(row, 0, nameItem);
|
||||
|
||||
//位置
|
||||
|
|
@ -163,8 +175,10 @@ void DiagramEditorTransSettingDlg::onDeleteClicked()
|
|||
}
|
||||
|
||||
QModelIndex indexName = index.sibling(index.row(),0);
|
||||
/*QString sName = indexName.data().toString();
|
||||
if(_pWizard){
|
||||
QString sName = indexName.data().toString();
|
||||
if(!_prepareDisconnectBlock.contains(sName))
|
||||
_prepareDisconnectBlock.append(sName);
|
||||
/*if(_pWizard){
|
||||
//delete con?
|
||||
}*/
|
||||
|
||||
|
|
@ -238,11 +252,55 @@ void DiagramEditorTransSettingDlg::onOkClicked()
|
|||
{
|
||||
nVal = 2;
|
||||
}
|
||||
QUuid uid = _pWizard->addConnection(_curOperateBlock->getName(),ui->tableWidget->item(i,0)->text(),3,2,nVal);
|
||||
QString sTargetBay = ui->tableWidget->item(i,0)->text();
|
||||
QUuid uid = _pWizard->addConnection(_curOperateBlock->getName(),sTargetBay,3,2,nVal);
|
||||
auto pBlock = _pWizard->getBlockByName_all(sTargetBay); //连接的双方都保存连接(todo:修改时删除对面保存的连接)
|
||||
if(pBlock){
|
||||
pBlock->addConnect(uid);
|
||||
}
|
||||
_curOperateBlock->addConnect(uid);
|
||||
}
|
||||
//todo: may delete
|
||||
|
||||
if(_prepareDisconnectBlock.size()){
|
||||
|
||||
for(auto& sTargetBay:_prepareDisconnectBlock){
|
||||
QUuid uid = _pWizard->findConnection(_curOperateBlock->getName(),sTargetBay);
|
||||
if(!uid.isNull())
|
||||
{
|
||||
_pWizard->removeConnection(uid); //从记录中删除链接
|
||||
auto pBlock = _pWizard->getBlockByName_all(sTargetBay); //连接的双方都保存连接(todo:修改时删除对面保存的连接)
|
||||
if(pBlock){
|
||||
pBlock->removeConnect(uid);//从各自block中删除链接
|
||||
|
||||
auto pBay = dynamic_cast<DiagramEditorBayBlock*>(pBlock);
|
||||
if(pBay){
|
||||
auto& mapComponent = pBay->getBayInfo().mapComponent;
|
||||
for(auto& comp:mapComponent){
|
||||
if(comp.sBindParent == _curOperateBlock->getName()){ //block中设备信息断开
|
||||
comp.sBindParent.clear();
|
||||
comp.sBindObj.clear();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
auto& mapRoute = pBay->getBayInfo().mapRoute;
|
||||
for(auto& route:mapRoute){ //block中线路信息断开
|
||||
for(auto& comp:route.lstCompo){
|
||||
if(comp.sBindParent == _curOperateBlock->getName()){
|
||||
comp.sBindParent.clear();
|
||||
comp.sBindObj.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_curOperateBlock->removeConnect(uid); //从各自block中删除链接
|
||||
}
|
||||
}
|
||||
_prepareDisconnectBlock.clear();
|
||||
}
|
||||
|
||||
_pWizard->flushTransPage();
|
||||
_curOperateBlock = nullptr;
|
||||
}
|
||||
|
|
@ -252,6 +310,8 @@ void DiagramEditorTransSettingDlg::onOkClicked()
|
|||
|
||||
void DiagramEditorTransSettingDlg::onCancelClicked()
|
||||
{
|
||||
if(_prepareDisconnectBlock.size())
|
||||
_prepareDisconnectBlock.clear();
|
||||
hide();
|
||||
}
|
||||
|
||||
|
|
@ -294,3 +354,60 @@ void DiagramEditorTransSettingDlg::onBayTypeChanged(int idx)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DiagramEditorTransSettingDlg::onTableItemSelected()
|
||||
{
|
||||
auto items = ui->tableWidget->selectedItems();
|
||||
if (items.isEmpty())
|
||||
return;
|
||||
|
||||
// 取第一列(名称)
|
||||
QTableWidgetItem* nameItem = ui->tableWidget->item(items.first()->row(), 0);
|
||||
if (!nameItem)
|
||||
return;
|
||||
|
||||
QString targetName = nameItem->text();
|
||||
int bayTypeValue = nameItem->data(Qt::UserRole).toInt();
|
||||
BayType targetBayType = BayType(bayTypeValue);
|
||||
|
||||
if (!_pWizard)
|
||||
return;
|
||||
|
||||
// 遍历所有 level
|
||||
for (int i = 0; i < ui->cb_level->count(); ++i)
|
||||
{
|
||||
int levelIndex = ui->cb_level->itemData(i).toInt();
|
||||
auto lstBlock = _pWizard->getTargetLevelBlocks(levelIndex, 2);
|
||||
|
||||
for (auto& block : lstBlock)
|
||||
{
|
||||
auto pBay = dynamic_cast<DiagramEditorBayBlock*>(block);
|
||||
if (!pBay)
|
||||
continue;
|
||||
|
||||
if (pBay->getName() == targetName &&
|
||||
pBay->getBayType() == targetBayType)
|
||||
{
|
||||
// ✅ 1. 设置 bayType(必须先)
|
||||
for (int j = 0; j < ui->cb_bayType->count(); ++j)
|
||||
{
|
||||
if (ui->cb_bayType->itemData(j).toInt() == bayTypeValue)
|
||||
{
|
||||
ui->cb_bayType->setCurrentIndex(j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// ✅ 2. 设置 level
|
||||
ui->cb_level->setCurrentIndex(i);
|
||||
|
||||
// ✅ 3. 等待 onConnectLevelChanged 刷新 cb_target
|
||||
QTimer::singleShot(0, this, [=] {
|
||||
ui->cb_target->setCurrentText(targetName);
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -290,13 +290,21 @@ int DiagramEditorWizard::getContainerIndex(int nLevel,DiagramEditorStructContain
|
|||
return -1;
|
||||
}
|
||||
|
||||
QUuid DiagramEditorWizard::addConnection(const QString& str1,const QString& str2,int nType1,int nType2,int nPara)
|
||||
QUuid DiagramEditorWizard::findConnection(const QString& str1,const QString& str2)
|
||||
{
|
||||
for(auto& con:_mapConnect){
|
||||
if((con.con1.sName == str1 && con.con2.sName == str2) || (con.con1.sName == str2 && con.con2.sName == str1)){ //已存在不插入
|
||||
if((con.con1.sName == str1 && con.con2.sName == str2) || (con.con1.sName == str2 && con.con2.sName == str1)){ //已存在
|
||||
return con.uid;
|
||||
}
|
||||
}
|
||||
return QUuid();
|
||||
}
|
||||
|
||||
QUuid DiagramEditorWizard::addConnection(const QString& str1,const QString& str2,int nType1,int nType2,int nPara)
|
||||
{
|
||||
QUuid uid = findConnection(str1,str2);
|
||||
if(!uid.isNull())
|
||||
return uid;
|
||||
|
||||
DiagramEditorBriefConnect con;
|
||||
con.uid = QUuid::createUuid();
|
||||
|
|
|
|||
|
|
@ -662,6 +662,14 @@ void EditPanel::loadBaseSetting(QUuid uid)
|
|||
_tagName = _projectName; //将临时名称保存到变量
|
||||
_projectName = info.projectName;
|
||||
_pModel->setWizardInfo(info.context);
|
||||
|
||||
QTimer::singleShot(300, this, [&](){
|
||||
//_pModel->clearCurPreview();
|
||||
_pModel->generatePreview();
|
||||
_pModel->calculateBlockPos();
|
||||
_pModel->setItemInBlockPos();
|
||||
_pModel->refreshConnection();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,447 @@
|
|||
#include "diagramEditor/editorDiagramLayoutEngine.h"
|
||||
#include "diagramEditor/editorDirectionManager.h"
|
||||
|
||||
// 主入口函数
|
||||
QRectF DiagramLayoutEngine::executeLayout(
|
||||
QMap<QString, DiagramEditorRouteInfo>& routes,
|
||||
QMap<QString, DiagramEditorComponentInfo>& components,
|
||||
const LayoutConfig& config,
|
||||
Context& context) {
|
||||
|
||||
// 1. 初始化上下文
|
||||
context.initComponentsCache(components);
|
||||
context.itemCache.clear();
|
||||
|
||||
// 2. 查找主线
|
||||
QString mainRouteName = findMainRoute(routes);
|
||||
if (mainRouteName.isEmpty()) {
|
||||
qWarning() << "No main route found";
|
||||
return QRectF();
|
||||
}
|
||||
|
||||
// 3. 布局主线
|
||||
if (routes.contains(mainRouteName)) {
|
||||
layoutMainRoute(routes[mainRouteName], config, context);
|
||||
}
|
||||
|
||||
// 4. 布局所有支线
|
||||
for (auto it = routes.begin(); it != routes.end(); ++it) {
|
||||
if (it->sRouteName == mainRouteName) continue;
|
||||
layoutBranchRoute(*it, config, context);
|
||||
}
|
||||
|
||||
// 5. 更新组件映射
|
||||
if (!context.saveToModel) {
|
||||
for (auto& route : routes) {
|
||||
for (auto& compo : route.lstCompo) {
|
||||
components[compo.sName] = compo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 6. 计算边界矩形
|
||||
if (!context.saveToModel) {
|
||||
return calculateBoundingRect(components);
|
||||
}
|
||||
|
||||
return QRectF(); // saveToModel 时由场景计算边界
|
||||
}
|
||||
|
||||
// 查找主线
|
||||
QString DiagramLayoutEngine::findMainRoute(
|
||||
const QMap<QString, DiagramEditorRouteInfo>& routes) {
|
||||
|
||||
QString mainRoute;
|
||||
bool hasMain = false;
|
||||
|
||||
// 查找标记为主线
|
||||
for (auto it = routes.begin(); it != routes.end(); ++it) {
|
||||
if (it->bMainRoute) {
|
||||
mainRoute = it->sRouteName;
|
||||
hasMain = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 未设置主线,选择设备最多的线路
|
||||
if (!hasMain) {
|
||||
int maxCount = 0;
|
||||
for (auto it = routes.begin(); it != routes.end(); ++it) {
|
||||
int count = it->lstCompo.size();
|
||||
if (count > maxCount) {
|
||||
maxCount = count;
|
||||
mainRoute = it->sRouteName;
|
||||
}
|
||||
}
|
||||
|
||||
// 标记为主线
|
||||
if (!mainRoute.isEmpty()) {
|
||||
const_cast<QMap<QString, DiagramEditorRouteInfo>&>(routes)[mainRoute].bMainRoute = true;
|
||||
}
|
||||
}
|
||||
|
||||
return mainRoute;
|
||||
}
|
||||
|
||||
// 布局主线
|
||||
void DiagramLayoutEngine::layoutMainRoute(
|
||||
DiagramEditorRouteInfo& route,
|
||||
const LayoutConfig& config,
|
||||
Context& context) {
|
||||
|
||||
Direction mainDir = config.mainDirection();
|
||||
auto& components = route.lstCompo;
|
||||
|
||||
if (components.isEmpty()) return;
|
||||
|
||||
// 计算分段
|
||||
int nSeg = components.size() / 2;
|
||||
int nSegIndex = 0;
|
||||
|
||||
// 确定起始索引方向
|
||||
if (mainDir == Direction::Down || mainDir == Direction::Right) {
|
||||
nSegIndex = -nSeg; // 正向从负半开始
|
||||
} else {
|
||||
nSegIndex = nSeg; // 反向从正半开始
|
||||
}
|
||||
|
||||
// 遍历所有组件
|
||||
for (int i = 0; i < components.size(); ++i) {
|
||||
DiagramEditorComponentInfo& compo = components[i];
|
||||
|
||||
// 确定方向占用
|
||||
Direction dir = mainDir;
|
||||
if (i == 0) {
|
||||
// 队首保持主线方向
|
||||
} else if (i == components.size() - 1) {
|
||||
// 队尾取反方向
|
||||
dir = DirectionManager::getOpposite(mainDir);
|
||||
} else {
|
||||
// 中间元件双向占用
|
||||
compo.nUsedDirection = static_cast<int>(mainDir) |
|
||||
static_cast<int>(DirectionManager::getOpposite(mainDir));
|
||||
}
|
||||
|
||||
// 计算位置增量
|
||||
QPoint delta = QPoint(0, 0);
|
||||
int spacing = DirectionManager::isHorizontal(mainDir)
|
||||
? config.horizontalSpacing()
|
||||
: config.verticalSpacing();
|
||||
|
||||
if (DirectionManager::isHorizontal(mainDir)) {
|
||||
delta.setX(nSegIndex * spacing);
|
||||
} else {
|
||||
delta.setY(nSegIndex * spacing);
|
||||
}
|
||||
|
||||
// 计算旋转角度
|
||||
int rotate = DirectionManager::getRotationAngle(mainDir);
|
||||
|
||||
// 更新组件
|
||||
updateComponent(compo, dir, delta, rotate, context);
|
||||
|
||||
// 更新索引
|
||||
if (mainDir == Direction::Up || mainDir == Direction::Left) {
|
||||
nSegIndex -= 1;
|
||||
} else {
|
||||
nSegIndex += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 拆分支线
|
||||
void DiagramLayoutEngine::splitBranchRoute(
|
||||
DiagramEditorRouteInfo& route,
|
||||
Context& context) {
|
||||
|
||||
route.lstOrder.clear();
|
||||
route.lstReverse.clear();
|
||||
|
||||
if (route.lstCompo.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查首尾元件
|
||||
int firstDir = getComponentDirection(route.lstCompo.first().sName, context);
|
||||
int lastDir = getComponentDirection(route.lstCompo.last().sName, context);
|
||||
|
||||
if (firstDir != 0) {
|
||||
// 情况1: 首元件是节点
|
||||
route.lstOrder = route.lstCompo;
|
||||
} else if (lastDir != 0) {
|
||||
// 情况2: 末元件是节点
|
||||
for (auto it = route.lstCompo.rbegin(); it != route.lstCompo.rend(); ++it) {
|
||||
route.lstReverse.append(*it);
|
||||
}
|
||||
} else {
|
||||
// 情况3: 查找中间节点
|
||||
int nodeIndex = -1;
|
||||
for (int i = 0; i < route.lstCompo.size(); ++i) {
|
||||
int dir = getComponentDirection(route.lstCompo[i].sName, context);
|
||||
if (dir != 0) {
|
||||
nodeIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (nodeIndex == -1) {
|
||||
// 没有节点,默认为正序
|
||||
route.lstOrder = route.lstCompo;
|
||||
return;
|
||||
}
|
||||
|
||||
// 反向序列: 从节点到开头
|
||||
for (int i = nodeIndex; i >= 0; --i) {
|
||||
route.lstReverse.append(route.lstCompo[i]);
|
||||
}
|
||||
|
||||
// 正序序列: 从节点到结尾
|
||||
for (int i = nodeIndex; i < route.lstCompo.size(); ++i) {
|
||||
route.lstOrder.append(route.lstCompo[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 布局支线
|
||||
void DiagramLayoutEngine::layoutBranchRoute(
|
||||
DiagramEditorRouteInfo& route,
|
||||
const LayoutConfig& config,
|
||||
Context& context) {
|
||||
|
||||
// 1. 拆分支线
|
||||
splitBranchRoute(route, context);
|
||||
|
||||
// 2. 布局正序序列
|
||||
if (route.lstOrder.size() > 1) {
|
||||
layoutBranchSequence(route.lstOrder, config.subDirection(),
|
||||
config, context, true);
|
||||
}
|
||||
|
||||
// 3. 布局反序序列
|
||||
if (route.lstReverse.size() > 1) {
|
||||
layoutBranchSequence(route.lstReverse, config.subDirection(),
|
||||
config, context, false);
|
||||
}
|
||||
}
|
||||
|
||||
// 布局分支序列
|
||||
void DiagramLayoutEngine::layoutBranchSequence(
|
||||
QList<DiagramEditorComponentInfo>& sequence,
|
||||
Direction branchDir,
|
||||
const LayoutConfig& config,
|
||||
Context& context,
|
||||
bool isOrder) {
|
||||
|
||||
if (sequence.size() < 2) return;
|
||||
|
||||
// 获取基准位置
|
||||
QPoint basePos = getComponentPosition(sequence[0].sName, context);
|
||||
int index = 1; // 偏移索引从1开始
|
||||
int polarity = 1; // 方向极性
|
||||
|
||||
// 确定极性
|
||||
if (branchDir == Direction::Left || branchDir == Direction::Up) {
|
||||
polarity = -1;
|
||||
}
|
||||
|
||||
// 计算间距
|
||||
int spacing = DirectionManager::isHorizontal(branchDir)
|
||||
? config.horizontalSpacing()
|
||||
: config.verticalSpacing();
|
||||
|
||||
// 布局后续元件
|
||||
for (int i = 0; i < sequence.size() - 1; ++i) {
|
||||
DiagramEditorComponentInfo& current = sequence[i];
|
||||
DiagramEditorComponentInfo& next = sequence[i + 1];
|
||||
|
||||
// 确定分支方向
|
||||
Direction dir = determineBranchDirection(current, branchDir, context);
|
||||
|
||||
// 计算下一个元件的位置
|
||||
QPoint nextPos = basePos;
|
||||
int offset = index * polarity * spacing;
|
||||
|
||||
if (DirectionManager::isHorizontal(dir)) {
|
||||
nextPos.setX(basePos.x() + offset);
|
||||
} else {
|
||||
nextPos.setY(basePos.y() + offset);
|
||||
}
|
||||
|
||||
// 计算相对位置
|
||||
QPoint deltaPos = nextPos - basePos;
|
||||
|
||||
// 下一个元件的连接方向与当前方向相反
|
||||
Direction nextConnectionDir = DirectionManager::getOpposite(dir);
|
||||
|
||||
// 计算旋转角度
|
||||
int rotate = DirectionManager::getRotationAngle(dir);
|
||||
|
||||
// 更新元件
|
||||
updateComponent(next, nextConnectionDir, deltaPos, rotate, context);
|
||||
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
// 确定支线方向
|
||||
Direction DiagramLayoutEngine::determineBranchDirection(
|
||||
const DiagramEditorComponentInfo& currentNode,
|
||||
Direction preferredDir,
|
||||
Context& context) {
|
||||
|
||||
int usedDirections = getComponentDirection(currentNode.sName, context);
|
||||
bool isHorizontalLayout = DirectionManager::isHorizontal(preferredDir);
|
||||
|
||||
if (isHorizontalLayout) {
|
||||
// 水平布局,检查左右
|
||||
bool leftOccupied = DirectionManager::isDirectionOccupied(usedDirections, Direction::Left);
|
||||
bool rightOccupied = DirectionManager::isDirectionOccupied(usedDirections, Direction::Right);
|
||||
|
||||
if (leftOccupied && rightOccupied) {
|
||||
qWarning() << "Component" << currentNode.sName
|
||||
<< "has both left and right directions occupied";
|
||||
return preferredDir;
|
||||
} else if (leftOccupied && !rightOccupied) {
|
||||
return Direction::Right;
|
||||
} else if (rightOccupied && !leftOccupied) {
|
||||
return Direction::Left;
|
||||
} else {
|
||||
return preferredDir;
|
||||
}
|
||||
} else {
|
||||
// 垂直布局,检查上下
|
||||
bool upOccupied = DirectionManager::isDirectionOccupied(usedDirections, Direction::Up);
|
||||
bool downOccupied = DirectionManager::isDirectionOccupied(usedDirections, Direction::Down);
|
||||
|
||||
if (upOccupied && downOccupied) {
|
||||
qWarning() << "Component" << currentNode.sName
|
||||
<< "has both up and down directions occupied";
|
||||
return preferredDir;
|
||||
} else if (upOccupied && !downOccupied) {
|
||||
return Direction::Down;
|
||||
} else if (downOccupied && !upOccupied) {
|
||||
return Direction::Up;
|
||||
} else {
|
||||
return preferredDir;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 获取组件位置
|
||||
QPoint DiagramLayoutEngine::getComponentPosition(
|
||||
const QString& componentName,
|
||||
Context& context) {
|
||||
|
||||
if (context.saveToModel) {
|
||||
QStandardItem* item = getNameItem(componentName, context);
|
||||
if (item) {
|
||||
QVariant posData = item->data(Qt::UserRole + 2);
|
||||
if (posData.isValid() && posData.canConvert<QPoint>()) {
|
||||
return posData.toPoint();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (context.componentsCache.contains(componentName)) {
|
||||
return context.componentsCache[componentName].deltaPos;
|
||||
}
|
||||
}
|
||||
|
||||
return QPoint(0, 0);
|
||||
}
|
||||
|
||||
// 获取组件方向
|
||||
int DiagramLayoutEngine::getComponentDirection(
|
||||
const QString& compoName,
|
||||
Context& context) {
|
||||
|
||||
if (context.saveToModel) {
|
||||
QStandardItem* item = getNameItem(compoName, context);
|
||||
return item ? item->data().toInt() : 0;
|
||||
} else {
|
||||
if (context.componentsCache.contains(compoName)) {
|
||||
return context.componentsCache[compoName].nUsedDirection;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 获取名称项
|
||||
QStandardItem* DiagramLayoutEngine::getNameItem(
|
||||
const QString& name,
|
||||
Context& context) {
|
||||
|
||||
QString cacheKey = QString("%1_%2").arg(name).arg(context.sourceId);
|
||||
|
||||
if (!context.itemCache.contains(cacheKey)) {
|
||||
// 这里应该是具体的模型查找实现
|
||||
// 为了示例,返回一个临时项
|
||||
QStandardItem* item = new QStandardItem(name);
|
||||
context.itemCache[cacheKey] = item;
|
||||
}
|
||||
|
||||
return context.itemCache[cacheKey];
|
||||
}
|
||||
|
||||
// 更新组件
|
||||
void DiagramLayoutEngine::updateComponent(
|
||||
DiagramEditorComponentInfo& compo,
|
||||
Direction dir,
|
||||
const QPoint& position,
|
||||
int rotate,
|
||||
Context& context) {
|
||||
|
||||
if (context.saveToModel) {
|
||||
QStandardItem* item = getNameItem(compo.sName, context);
|
||||
if (item) {
|
||||
int currentDir = item->data().toInt();
|
||||
int newDir = DirectionManager::markDirectionOccupied(currentDir, dir);
|
||||
item->setData(QString::number(newDir));
|
||||
item->setData(position, Qt::UserRole + 2);
|
||||
item->setData(rotate, Qt::UserRole + 5);
|
||||
}
|
||||
} else {
|
||||
compo.nUsedDirection = DirectionManager::markDirectionOccupied(compo.nUsedDirection, dir);
|
||||
compo.deltaPos = position;
|
||||
compo.nRotate = rotate;
|
||||
|
||||
// 更新缓存
|
||||
context.componentsCache[compo.sName] = compo;
|
||||
}
|
||||
}
|
||||
|
||||
// 计算边界矩形
|
||||
QRectF DiagramLayoutEngine::calculateBoundingRect(
|
||||
const QMap<QString, DiagramEditorComponentInfo>& components) {
|
||||
|
||||
if (components.isEmpty()) {
|
||||
return QRectF();
|
||||
}
|
||||
|
||||
qreal minX = 0, maxX = 0, minY = 0, maxY = 0;
|
||||
bool first = true;
|
||||
|
||||
for (auto it = components.begin(); it != components.end(); ++it) {
|
||||
if (it->nUsedDirection == 0) continue; // 未使用的组件
|
||||
|
||||
QPointF pos = it->deltaPos;
|
||||
|
||||
if (first) {
|
||||
minX = pos.x();
|
||||
maxX = pos.x() + m_compoWidth;
|
||||
minY = pos.y();
|
||||
maxY = pos.y() + m_compoHeight;
|
||||
first = false;
|
||||
} else {
|
||||
minX = qMin(minX, pos.x());
|
||||
maxX = qMax(maxX, pos.x() + m_compoWidth);
|
||||
minY = qMin(minY, pos.y());
|
||||
maxY = qMax(maxY, pos.y() + m_compoHeight);
|
||||
}
|
||||
}
|
||||
|
||||
if (first) {
|
||||
return QRectF(); // 没有使用的组件
|
||||
}
|
||||
|
||||
return QRectF(minX, minY, maxX - minX, maxY - minY);
|
||||
}
|
||||
|
|
@ -177,7 +177,7 @@ QWidget QLabel {
|
|||
<property name="title">
|
||||
<string>连接信息</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2" columnstretch="1,1">
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<property name="horizontalSpacing">
|
||||
<number>20</number>
|
||||
</property>
|
||||
|
|
@ -216,6 +216,12 @@ QWidget QLabel {
|
|||
</property>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btn_add">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QPushButton {
|
||||
background-color: #5a79a1; /* 中性灰蓝,不刺眼 */
|
||||
|
|
@ -245,10 +251,42 @@ QPushButton:disabled {
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btn_delete">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QPushButton {
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="1" rowspan="2">
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>连接列表</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QPushButton" name="btn_delete">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QPushButton {
|
||||
background-color: #5a79a1; /* 中性灰蓝,不刺眼 */
|
||||
color: white;
|
||||
border: none; /* 无边框,扁平化 */
|
||||
|
|
@ -270,26 +308,13 @@ QPushButton:disabled {
|
|||
color: #d1dce9; /* 浅灰色文字 */
|
||||
}
|
||||
</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>删除</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="1" rowspan="2">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>连接列表</string>
|
||||
<string>删除</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<item row="1" column="0" colspan="3">
|
||||
<widget class="QListWidget" name="listWidget"/>
|
||||
</item>
|
||||
</layout>
|
||||
|
|
|
|||
|
|
@ -147,22 +147,42 @@ QWidget QLabel {
|
|||
<property name="title">
|
||||
<string>连接信息</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<property name="horizontalSpacing">
|
||||
<number>20</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout" rowstretch="1,1,1,0,0,0" columnstretch="1,2">
|
||||
<layout class="QGridLayout" name="gridLayout" rowstretch="0,0,0,0,0,0" columnstretch="1,2">
|
||||
<property name="verticalSpacing">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>间隔类型</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>间隔名称</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<property name="spacing">
|
||||
<number>10</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btn_add">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QPushButton {
|
||||
background-color: #5a79a1; /* 中性灰蓝,不刺眼 */
|
||||
|
|
@ -192,10 +212,114 @@ QPushButton:disabled {
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>间隔位置</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="cb_bayType">
|
||||
<item>
|
||||
<widget class="QPushButton" name="btn_delete">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QPushButton {
|
||||
<property name="text">
|
||||
<string>进线间隔</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>出线间隔</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="cb_level"/>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QComboBox" name="cb_toPos">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>高压侧</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>中压侧</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>低压侧</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string>连接到</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="cb_target"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>155</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="1" rowspan="2">
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>连接列表</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QPushButton" name="btn_delete">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QPushButton {
|
||||
background-color: #5a79a1; /* 中性灰蓝,不刺眼 */
|
||||
color: white;
|
||||
border: none; /* 无边框,扁平化 */
|
||||
|
|
@ -217,110 +341,17 @@ QPushButton:disabled {
|
|||
color: #d1dce9; /* 浅灰色文字 */
|
||||
}
|
||||
</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>删除</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>间隔名称</string>
|
||||
<string>删除</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>间隔位置</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>间隔类型</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="cb_target"/>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="cb_bayType">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>进线间隔</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>出线间隔</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="cb_level"/>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string>连接到</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QComboBox" name="cb_toPos">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>高压侧</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>中压侧</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>低压侧</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="1" rowspan="2">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>连接列表</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<item row="1" column="0" colspan="3">
|
||||
<widget class="QTableWidget" name="tableWidget"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>155</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
|
|||
Loading…
Reference in New Issue