add editor layout occupancy management
This commit is contained in:
parent
947c1a6858
commit
01ce273d68
|
|
@ -129,6 +129,122 @@ enum class Direction : int {
|
|||
Up = 8
|
||||
};
|
||||
|
||||
// 方向占用记录
|
||||
struct DirectionOccupancyRecord {
|
||||
QString routeId; // 占用此方向的线路ID
|
||||
int directionMask; // 占用的方向位掩码
|
||||
qint64 timestamp; // 占用时间
|
||||
friend QDataStream &operator<<(QDataStream &out, const DirectionOccupancyRecord &data) {
|
||||
out << data.routeId << data.directionMask << data.timestamp;
|
||||
return out;
|
||||
}
|
||||
friend QDataStream &operator>>(QDataStream &in, DirectionOccupancyRecord &data) {
|
||||
in >> data.routeId >> data.directionMask >> data.timestamp;
|
||||
return in;
|
||||
}
|
||||
};
|
||||
|
||||
// 线路方向占用记录
|
||||
struct DirectionOccupancyRouteInfo {
|
||||
QList<QString> componentOrder; // 组件顺序
|
||||
QHash<QString, int> componentDirections; // 组件->方向掩码
|
||||
|
||||
friend QDataStream &operator<<(QDataStream &out, const DirectionOccupancyRouteInfo &data) {
|
||||
out << data.componentOrder << data.componentDirections;
|
||||
return out;
|
||||
}
|
||||
friend QDataStream &operator>>(QDataStream &in, DirectionOccupancyRouteInfo &data) {
|
||||
in >> data.componentOrder >> data.componentDirections;
|
||||
return in;
|
||||
}
|
||||
|
||||
// 添加组件
|
||||
bool addComponent(const QString& compoName, int direction, int position = -1) {
|
||||
if (componentDirections.contains(compoName)) {
|
||||
return false; // 组件已存在
|
||||
}
|
||||
|
||||
if (position < 0 || position >= componentOrder.size()) {
|
||||
componentOrder.append(compoName);
|
||||
} else {
|
||||
componentOrder.insert(position, compoName);
|
||||
}
|
||||
|
||||
componentDirections[compoName] = direction;
|
||||
return true;
|
||||
}
|
||||
|
||||
// 移除组件
|
||||
bool removeComponent(const QString& compoName) {
|
||||
if (!componentDirections.contains(compoName)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
componentOrder.removeAll(compoName);
|
||||
componentDirections.remove(compoName);
|
||||
return true;
|
||||
}
|
||||
|
||||
// 获取组件方向
|
||||
int getDirection(const QString& compoName) const {
|
||||
return componentDirections.value(compoName, 0);
|
||||
}
|
||||
|
||||
// 更新组件方向
|
||||
bool updateDirection(const QString& compoName, int newDirection) {
|
||||
if (!componentDirections.contains(compoName)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
componentDirections[compoName] = newDirection;
|
||||
return true;
|
||||
}
|
||||
|
||||
// 获取前一个组件
|
||||
QString getPreviousComponent(const QString& compoName) const {
|
||||
int index = componentOrder.indexOf(compoName);
|
||||
if (index > 0) {
|
||||
return componentOrder.at(index - 1);
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
// 获取后一个组件
|
||||
QString getNextComponent(const QString& compoName) const {
|
||||
int index = componentOrder.indexOf(compoName);
|
||||
if (index >= 0 && index < componentOrder.size() - 1) {
|
||||
return componentOrder.at(index + 1);
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
// 检查是否包含组件
|
||||
bool contains(const QString& compoName) const {
|
||||
return componentDirections.contains(compoName);
|
||||
}
|
||||
|
||||
// 获取所有组件(按顺序)
|
||||
QList<QString> getAllComponents() const {
|
||||
return componentOrder;
|
||||
}
|
||||
|
||||
// 获取路由大小
|
||||
int size() const {
|
||||
return componentOrder.size();
|
||||
}
|
||||
|
||||
// 是否为空
|
||||
bool isEmpty() const {
|
||||
return componentOrder.isEmpty();
|
||||
}
|
||||
|
||||
// 清空
|
||||
void clear() {
|
||||
componentOrder.clear();
|
||||
componentDirections.clear();
|
||||
}
|
||||
};
|
||||
|
||||
inline uint qHash(const DiagramEditorComponentInfo &key, uint seed = 0) {
|
||||
return qHash(key.uid, seed);
|
||||
}
|
||||
|
|
@ -163,13 +279,15 @@ struct DiagramEditorBayInfo //组态编辑间隔信息
|
|||
QMap<QString,DiagramEditorRouteInfo> mapRoute; //线路信息
|
||||
QMap<QString,DiagramEditorComponentInfo> mapComponent; //设备信息
|
||||
QList<QString> routeOrder; //线路顺序
|
||||
QMap<QString, QMap<int,DirectionOccupancyRecord>> directionOccupancyMap; //组件方向占用表 名称,4个方向占用记录
|
||||
QMap<QString, DirectionOccupancyRouteInfo> routeDirectionMap; //线路方向映射表 key: 线路名, value: 组件->方向占用映射
|
||||
|
||||
friend QDataStream &operator<<(QDataStream &out, const DiagramEditorBayInfo &data) {
|
||||
out << data.name << data.nLayout << data.lstFrom << data.lstTo << data.mapRoute << data.mapComponent << data.routeOrder;
|
||||
out << data.name << data.nLayout << data.lstFrom << data.lstTo << data.mapRoute << data.mapComponent << data.routeOrder << data.directionOccupancyMap << data.routeDirectionMap;
|
||||
return out;
|
||||
}
|
||||
friend QDataStream &operator>>(QDataStream &in, DiagramEditorBayInfo &data) {
|
||||
in >> data.name >> data.nLayout >> data.lstFrom >> data.lstTo >> data.mapRoute >> data.mapComponent >> data.routeOrder;
|
||||
in >> data.name >> data.nLayout >> data.lstFrom >> data.lstTo >> data.mapRoute >> data.mapComponent >> data.routeOrder >> data.directionOccupancyMap >> data.routeDirectionMap;
|
||||
return in;
|
||||
}
|
||||
};
|
||||
|
|
@ -182,13 +300,15 @@ struct DiagramEditorTransNeutralInfo //组态编辑变压器中性点信息
|
|||
int nType = 0; //中性点类型 0高1中2低
|
||||
QPointF delPoint; //相对变压器偏移量
|
||||
QMap<QString,DiagramEditorRouteInfo> mapRoute; //中性点对应的线路结构
|
||||
QMap<QString, QMap<int,DirectionOccupancyRecord>> directionOccupancyMap; //组件方向占用表 名称,4个方向占用记录
|
||||
QMap<QString, DirectionOccupancyRouteInfo> routeDirectionMap; //线路方向映射表 key: 线路名, value: 组件->方向占用映射
|
||||
|
||||
friend QDataStream &operator<<(QDataStream &out, const DiagramEditorTransNeutralInfo &data) {
|
||||
out << data.name << data.nType << data.delPoint << data.mapRoute;
|
||||
out << data.name << data.nType << data.delPoint << data.mapRoute << data.directionOccupancyMap << data.directionOccupancyMap;
|
||||
return out;
|
||||
}
|
||||
friend QDataStream &operator>>(QDataStream &in, DiagramEditorTransNeutralInfo &data) {
|
||||
in >> data.name >> data.nType >> data.delPoint >> data.mapRoute;
|
||||
in >> data.name >> data.nType >> data.delPoint >> data.mapRoute >> data.directionOccupancyMap >> data.routeDirectionMap;
|
||||
return in;
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -10,14 +10,32 @@ class DiagramLayoutEngine {
|
|||
public:
|
||||
struct Context {
|
||||
int sourceId = 0;
|
||||
QString currentRouteId; // 当前正在处理的线路ID
|
||||
bool isRemovingRoute = false; // 是否为删除操作
|
||||
bool saveToModel = false;
|
||||
QMap<QString, QStandardItem*> itemCache;
|
||||
QMap<QString, DiagramEditorComponentInfo> componentsCache;
|
||||
QMap<QString, QSet<Direction>> branchUsedDirections; //key: 组件名 value: 已被支线占用的方向集合
|
||||
QMap<QString, QMap<int,DirectionOccupancyRecord>> directionOccupancyMap;
|
||||
QMap<QString, DirectionOccupancyRouteInfo> routeDirectionMap;
|
||||
|
||||
void initComponentsCache(const QMap<QString, DiagramEditorComponentInfo>& compos) {
|
||||
componentsCache = compos;
|
||||
}
|
||||
|
||||
void initDirectionOccupancyCache(const QMap<QString, QMap<int,DirectionOccupancyRecord>>& occus){
|
||||
directionOccupancyMap = occus;
|
||||
}
|
||||
|
||||
void initRouteDirectionMapCache(const QMap<QString, DirectionOccupancyRouteInfo>& routes){
|
||||
routeDirectionMap = routes;
|
||||
}
|
||||
};
|
||||
|
||||
enum class DirectionOperation {
|
||||
ADD, // 添加方向
|
||||
REMOVE, // 移除方向
|
||||
SET // 设置方向(替换)
|
||||
};
|
||||
|
||||
explicit DiagramLayoutEngine(DiagramEditorModel* model)
|
||||
|
|
@ -26,16 +44,19 @@ public:
|
|||
QRectF executeLayout(
|
||||
QMap<QString, DiagramEditorRouteInfo>& routes,
|
||||
QMap<QString, DiagramEditorComponentInfo>& components,
|
||||
QMap<QString, QMap<int,DirectionOccupancyRecord>>& directionOccupancyMap,
|
||||
QMap<QString, DirectionOccupancyRouteInfo>& routeDirectionMap,
|
||||
const LayoutConfig& config,
|
||||
Context& context
|
||||
);
|
||||
|
||||
bool clearRouteDirectionOccupancy(const QString& routeId,Context& context);
|
||||
private:
|
||||
// 主线相关
|
||||
QString findMainRoute(const QMap<QString, DiagramEditorRouteInfo>& routes);
|
||||
void layoutMainRoute(DiagramEditorRouteInfo& route,
|
||||
const LayoutConfig& config,
|
||||
Context& context);
|
||||
void layoutMainRouteInternal(DiagramEditorRouteInfo& route,const LayoutConfig& config,Context& context);
|
||||
|
||||
// 支线相关
|
||||
void layoutBranchRoute(DiagramEditorRouteInfo& route,
|
||||
|
|
@ -49,7 +70,6 @@ private:
|
|||
Context& context,
|
||||
bool isOrder,
|
||||
int polarity);
|
||||
void markDirectionUsed(const QString& compoName,Direction dir,Context& context);
|
||||
// 组件相关
|
||||
Direction determineBranchDirection(const DiagramEditorComponentInfo& currentNode,
|
||||
Direction preferredDir,
|
||||
|
|
@ -61,13 +81,56 @@ private:
|
|||
const QPoint& position,
|
||||
int rotate,
|
||||
Context& context);
|
||||
//记录线路在组件上的方向占用
|
||||
bool recordRouteDirectionOccupancy(const QString& routeId,const QString& compoName,int directionMask,Context& context); //线路ID,组件名称,方向位掩码
|
||||
/**
|
||||
* @brief 统一更新组件方向占用
|
||||
* @param compoName 组件名称
|
||||
* @param directionMask 方向掩码 (8上,4下,2左,1右)
|
||||
* @param operation 操作类型: 添加、移除、设置
|
||||
* @param context 上下文
|
||||
* @return 是否成功
|
||||
*/
|
||||
bool updateComponentDirections(const QString& compoName,int directionMask,DirectionOperation operation,Context& context);
|
||||
bool updateComponentCacheInternal(const QString& compoName,int directionMask,DirectionOperation operation,Context& context);
|
||||
bool updateComponentModel(const QString& compoName,int directionMask,DirectionOperation operation,Context& context);
|
||||
|
||||
// 辅助函数
|
||||
QStandardItem* getNameItem(const QString& name, Context& context);
|
||||
int getComponentDirection(const QString& compoName, Context& context);
|
||||
QRectF calculateBoundingRect(const QMap<QString, DiagramEditorComponentInfo>& components);
|
||||
Direction getRouteDirection(const QString& routeName,const QMap<QString, DiagramEditorRouteInfo>& routes);
|
||||
int getComponentTotalOccupiedDirections(const QString& compoName, Context& context); //从总占用表中获取元件占用方向
|
||||
int getComponentDirectionFromCache(const QString& compoName,const QString& routeId,Context& context); //从缓存获取方向占用
|
||||
QString getDirectionName(int dirBit) {
|
||||
switch (dirBit) {
|
||||
case 8: return "上";
|
||||
case 4: return "下";
|
||||
case 2: return "左";
|
||||
case 1: return "右";
|
||||
default: return QString("未知(%1)").arg(dirBit);
|
||||
}
|
||||
}
|
||||
|
||||
int getOppositeDirection(int dirBit) {
|
||||
switch (dirBit) {
|
||||
case 8: return 4; // 上 ↔ 下
|
||||
case 4: return 8; // 下 ↔ 上
|
||||
case 2: return 1; // 左 ↔ 右
|
||||
case 1: return 2; // 右 ↔ 左
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int getDirectionIndex(int dirBit) {
|
||||
switch (dirBit) {
|
||||
case 1: return 0; // 右
|
||||
case 2: return 1; // 左
|
||||
case 4: return 2; // 下
|
||||
case 8: return 3; // 上
|
||||
default: return -1;
|
||||
}
|
||||
}
|
||||
private:
|
||||
int m_compoWidth = 50;
|
||||
int m_compoHeight = 30;
|
||||
|
|
|
|||
|
|
@ -68,8 +68,9 @@ public:
|
|||
void generateItemByModel(QStandardItemModel* pModel,DiagramEditorBaseBlock* pBlock,int nFrom = 0,QPoint delta = QPoint(0,0)); //0间隔1变压器
|
||||
QList<DiagramEditorComponentInfo> generateItemByInfo(QMap<QString,DiagramEditorRouteInfo>& mapRoute,QMap<QString,DiagramEditorComponentInfo>& mapCompo,QPointF delta = QPointF(0,0),DiagramEditorBaseBlock* pParent = nullptr); //根据data生成item parent:生成的对象添加到parent下(非拓扑计算)
|
||||
QMultiMap<int,QUuid> generateOutConnection(QList<DiagramEditorComponentInfo>,QList<HierarchyItem>&,int nTypeTransCon,int nPos = 0,DiagramEditorBaseBlock* pParent = nullptr); //生成外部连接(手动bind的连接)relation:层级关系引用 nTypeTransCon变压器连线类型,1中性点连接2外部连接,nPos中性点连接时的位置
|
||||
QRectF updateTarget(QMap<QString,DiagramEditorRouteInfo>&,QMap<QString,DiagramEditorComponentInfo>&,int nLayout,int nSource,bool saveToModel = true); //更新位置 nLayout主次朝向:8421,8421 上下左右,上下左右 nSource:0间隔1变压器 regenerate重新生成标志 saveToModel:生成到模型或map
|
||||
void clearCompoDir(QMap<QString,DiagramEditorRouteInfo>&,QMap<QString,DiagramEditorComponentInfo>&,int nSource); //清空component中的dir(updateTarget前调用)
|
||||
QRectF updateTarget(QMap<QString,DiagramEditorRouteInfo>&,QMap<QString,DiagramEditorComponentInfo>&,QMap<QString, QMap<int,DirectionOccupancyRecord>>& directionOccupancyMap,QMap<QString, DirectionOccupancyRouteInfo>& routeDirectionMap,int nLayout,int nSource,bool saveToModel = true); //更新位置 nLayout主次朝向:8421,8421 上下左右,上下左右 nSource:0间隔1变压器 regenerate重新生成标志 saveToModel:生成到模型或map
|
||||
void clearCompoDir(QMap<QString,DiagramEditorRouteInfo>&,QMap<QString,DiagramEditorComponentInfo>&,QMap<QString, QMap<int,DirectionOccupancyRecord>>& directionOccupancyMap,QMap<QString, DirectionOccupancyRouteInfo>& routeDirectionMap,int nSource); //清空component中的dir(updateTarget前调用)
|
||||
void removeRouteDir(QMap<QString,DiagramEditorRouteInfo>&,QMap<QString,DiagramEditorComponentInfo>&,QMap<QString, QMap<int,DirectionOccupancyRecord>>& directionOccupancyMap,QMap<QString, DirectionOccupancyRouteInfo>& routeDirectionMap,int nSource); //删除某条线路上的方向占用
|
||||
|
||||
QList<DiagramEditorComponentInfo> getRouteItemInfoList(QMap<QString,DiagramEditorComponentInfo>,QMap<QString,DiagramEditorRouteInfo>); //返回线路中包含的设备信息列表
|
||||
|
||||
|
|
|
|||
|
|
@ -719,8 +719,9 @@ void DiagramCavas::onSignal_unloadProject(const QString& sName)
|
|||
|
||||
for(auto &pair:m_mapEditPanel){
|
||||
EditPanel* pPanel = pair.first;
|
||||
this->removeSubWindow(pPanel);
|
||||
delete pPanel;
|
||||
this->removeSubWindow(pair.second);
|
||||
delete pPanel; //只删除界面会留下无效sub
|
||||
delete pair.second;
|
||||
}
|
||||
m_mapEditPanel.clear();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -263,12 +263,16 @@ void DiagramEditorBayDetailSettingDlg::onOkClicked()
|
|||
getModel()->clearCompoDir(
|
||||
_curBayInfo.mapRoute,
|
||||
_curBayInfo.mapComponent,
|
||||
_curBayInfo.directionOccupancyMap,
|
||||
_curBayInfo.routeDirectionMap,
|
||||
0);
|
||||
|
||||
QRectF recBounding =
|
||||
getModel()->updateTarget(
|
||||
_curBayInfo.mapRoute,
|
||||
_curBayInfo.mapComponent,
|
||||
_curBayInfo.directionOccupancyMap,
|
||||
_curBayInfo.routeDirectionMap,
|
||||
nDir,
|
||||
0,
|
||||
false); // ✅ 结果写回 mapComponent
|
||||
|
|
|
|||
|
|
@ -48,8 +48,9 @@ void DiagramEditorBayPreviewDlg::showDlg(int nLayout)
|
|||
else if(nLayout == 1){ //横,右下
|
||||
nDir = 14;
|
||||
}
|
||||
_pParent->getModel()->clearCompoDir(_pParent->getBayInfo().mapRoute,_pParent->getBayInfo().mapComponent,0);
|
||||
_pParent->getModel()->updateTarget(_pParent->getBayInfo().mapRoute,_pParent->getBayInfo().mapComponent,nDir,0);
|
||||
auto& bayInfo = _pParent->getBayInfo();
|
||||
_pParent->getModel()->clearCompoDir(bayInfo.mapRoute,bayInfo.mapComponent,bayInfo.directionOccupancyMap,bayInfo.routeDirectionMap,0);
|
||||
_pParent->getModel()->updateTarget(_pParent->getBayInfo().mapRoute,_pParent->getBayInfo().mapComponent,bayInfo.directionOccupancyMap,bayInfo.routeDirectionMap,nDir,0);
|
||||
}
|
||||
|
||||
void DiagramEditorBayPreviewDlg::setSceneRect(const QRect rec)
|
||||
|
|
|
|||
|
|
@ -258,17 +258,17 @@ void DiagramEditorTransDetailSettingDlg::onOkClicked()
|
|||
QRectF result;
|
||||
|
||||
if(_transInfo.mapNeutral.contains(0))
|
||||
getModel()->clearCompoDir(_transInfo.mapNeutral[0].mapRoute,_transInfo.mapComponent,1);
|
||||
getModel()->clearCompoDir(_transInfo.mapNeutral[0].mapRoute,_transInfo.mapComponent,_transInfo.mapNeutral[0].directionOccupancyMap,_transInfo.mapNeutral[0].routeDirectionMap,1);
|
||||
if(_transInfo.mapNeutral.contains(1))
|
||||
getModel()->clearCompoDir(_transInfo.mapNeutral[1].mapRoute,_transInfo.mapComponent,1);
|
||||
getModel()->clearCompoDir(_transInfo.mapNeutral[1].mapRoute,_transInfo.mapComponent,_transInfo.mapNeutral[1].directionOccupancyMap,_transInfo.mapNeutral[1].routeDirectionMap,1);
|
||||
if(_transInfo.mapNeutral.contains(2))
|
||||
getModel()->clearCompoDir(_transInfo.mapNeutral[2].mapRoute,_transInfo.mapComponent,1);
|
||||
getModel()->clearCompoDir(_transInfo.mapNeutral[2].mapRoute,_transInfo.mapComponent,_transInfo.mapNeutral[2].directionOccupancyMap,_transInfo.mapNeutral[2].routeDirectionMap,1);
|
||||
|
||||
if(_transInfo.mapNeutral.contains(0)){
|
||||
QPointF delta = QPointF(100,-25);
|
||||
_transInfo.mapNeutral[0].nType = 0;
|
||||
_transInfo.mapNeutral[0].delPoint = delta;
|
||||
rec1 = getModel()->updateTarget(_transInfo.mapNeutral[0].mapRoute,_transInfo.mapComponent,14,1,false); //1右2下
|
||||
rec1 = getModel()->updateTarget(_transInfo.mapNeutral[0].mapRoute,_transInfo.mapComponent,_transInfo.mapNeutral[0].directionOccupancyMap,_transInfo.mapNeutral[0].routeDirectionMap,14,1,false); //1右2下
|
||||
rec1.translate(delta); //相对trans偏移
|
||||
result = result.united(rec1);
|
||||
}
|
||||
|
|
@ -276,7 +276,7 @@ void DiagramEditorTransDetailSettingDlg::onOkClicked()
|
|||
QPointF delta = QPointF(-150,0);
|
||||
_transInfo.mapNeutral[1].nType = 1;
|
||||
_transInfo.mapNeutral[1].delPoint = delta;
|
||||
rec2 = getModel()->updateTarget(_transInfo.mapNeutral[1].mapRoute,_transInfo.mapComponent,24,1,false); //1左2下
|
||||
rec2 = getModel()->updateTarget(_transInfo.mapNeutral[1].mapRoute,_transInfo.mapComponent,_transInfo.mapNeutral[1].directionOccupancyMap,_transInfo.mapNeutral[1].routeDirectionMap,24,1,false); //1左2下
|
||||
rec2.translate(delta);
|
||||
result = result.united(rec2);
|
||||
}
|
||||
|
|
@ -284,7 +284,7 @@ void DiagramEditorTransDetailSettingDlg::onOkClicked()
|
|||
QPointF delta = QPointF(100,25);
|
||||
_transInfo.mapNeutral[2].nType = 2;
|
||||
_transInfo.mapNeutral[2].delPoint = delta;
|
||||
rec3 = getModel()->updateTarget(_transInfo.mapNeutral[2].mapRoute,_transInfo.mapComponent,14,1,false); //1右2下
|
||||
rec3 = getModel()->updateTarget(_transInfo.mapNeutral[2].mapRoute,_transInfo.mapComponent,_transInfo.mapNeutral[2].directionOccupancyMap,_transInfo.mapNeutral[2].routeDirectionMap,14,1,false); //1右2下
|
||||
rec3.translate(delta);
|
||||
result = result.united(rec3);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,21 +44,22 @@ void DiagramEditorTransPreviewDlg::showDlg(int nType)
|
|||
|
||||
void DiagramEditorTransPreviewDlg::updateModelData(int nType)
|
||||
{
|
||||
auto& transInfo = _pParent->getTransInfo();
|
||||
if(nType == 0 || nType == 1 || nType == 2){
|
||||
_pParent->getModel()->clearCompoDir(_pParent->getTransInfo().mapNeutral[nType].mapRoute,_pParent->getTransInfo().mapComponent,1);
|
||||
_pParent->getModel()->clearCompoDir(transInfo.mapNeutral[nType].mapRoute,transInfo.mapComponent,transInfo.mapNeutral[nType].directionOccupancyMap,transInfo.mapNeutral[nType].routeDirectionMap,1);
|
||||
if(nType == 0 || nType == 2)
|
||||
_pParent->getModel()->updateTarget(_pParent->getTransInfo().mapNeutral[nType].mapRoute,_pParent->getTransInfo().mapComponent,14,1); //1右2下
|
||||
_pParent->getModel()->updateTarget(transInfo.mapNeutral[nType].mapRoute,transInfo.mapComponent,transInfo.mapNeutral[nType].directionOccupancyMap,transInfo.mapNeutral[nType].routeDirectionMap,14,1); //1右2下
|
||||
else if(nType == 1)
|
||||
_pParent->getModel()->updateTarget(_pParent->getTransInfo().mapNeutral[nType].mapRoute,_pParent->getTransInfo().mapComponent,24,1); //1左2下
|
||||
_pParent->getModel()->updateTarget(transInfo.mapNeutral[nType].mapRoute,transInfo.mapComponent,transInfo.mapNeutral[nType].directionOccupancyMap,transInfo.mapNeutral[nType].routeDirectionMap,24,1); //1左2下
|
||||
}
|
||||
else if(nType == 3){ //整个变压器
|
||||
_pParent->getModel()->clearCompoDir(_pParent->getTransInfo().mapNeutral[0].mapRoute,_pParent->getTransInfo().mapComponent,1);
|
||||
_pParent->getModel()->clearCompoDir(_pParent->getTransInfo().mapNeutral[1].mapRoute,_pParent->getTransInfo().mapComponent,1);
|
||||
_pParent->getModel()->clearCompoDir(_pParent->getTransInfo().mapNeutral[2].mapRoute,_pParent->getTransInfo().mapComponent,1);
|
||||
_pParent->getModel()->clearCompoDir(transInfo.mapNeutral[0].mapRoute,transInfo.mapComponent,transInfo.mapNeutral[0].directionOccupancyMap,transInfo.mapNeutral[0].routeDirectionMap,1);
|
||||
_pParent->getModel()->clearCompoDir(transInfo.mapNeutral[1].mapRoute,transInfo.mapComponent,transInfo.mapNeutral[1].directionOccupancyMap,transInfo.mapNeutral[1].routeDirectionMap,1);
|
||||
_pParent->getModel()->clearCompoDir(transInfo.mapNeutral[2].mapRoute,transInfo.mapComponent,transInfo.mapNeutral[2].directionOccupancyMap,transInfo.mapNeutral[2].routeDirectionMap,1);
|
||||
|
||||
_pParent->getModel()->updateTarget(_pParent->getTransInfo().mapNeutral[0].mapRoute,_pParent->getTransInfo().mapComponent,14,1); //1右2下
|
||||
_pParent->getModel()->updateTarget(_pParent->getTransInfo().mapNeutral[1].mapRoute,_pParent->getTransInfo().mapComponent,24,1); //1左2下
|
||||
_pParent->getModel()->updateTarget(_pParent->getTransInfo().mapNeutral[2].mapRoute,_pParent->getTransInfo().mapComponent,14,1); //1右2下
|
||||
_pParent->getModel()->updateTarget(transInfo.mapNeutral[0].mapRoute,transInfo.mapComponent,transInfo.mapNeutral[0].directionOccupancyMap,transInfo.mapNeutral[0].routeDirectionMap,14,1); //1右2下
|
||||
_pParent->getModel()->updateTarget(transInfo.mapNeutral[1].mapRoute,transInfo.mapComponent,transInfo.mapNeutral[1].directionOccupancyMap,transInfo.mapNeutral[1].routeDirectionMap,24,1); //1左2下
|
||||
_pParent->getModel()->updateTarget(transInfo.mapNeutral[2].mapRoute,transInfo.mapComponent,transInfo.mapNeutral[2].directionOccupancyMap,transInfo.mapNeutral[2].routeDirectionMap,14,1); //1右2下
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,10 +6,14 @@
|
|||
QRectF DiagramLayoutEngine::executeLayout(
|
||||
QMap<QString, DiagramEditorRouteInfo>& routes,
|
||||
QMap<QString, DiagramEditorComponentInfo>& components,
|
||||
QMap<QString, QMap<int,DirectionOccupancyRecord>>& directionOccupancyMap,
|
||||
QMap<QString, DirectionOccupancyRouteInfo>& routeDirectionMap,
|
||||
const LayoutConfig& config,
|
||||
Context& context) {
|
||||
|
||||
context.initComponentsCache(components);
|
||||
context.initDirectionOccupancyCache(directionOccupancyMap);
|
||||
context.initRouteDirectionMapCache(routeDirectionMap);
|
||||
context.itemCache.clear();
|
||||
|
||||
QString mainRouteName = findMainRoute(routes);
|
||||
|
|
@ -100,7 +104,22 @@ void DiagramLayoutEngine::layoutMainRoute(
|
|||
const LayoutConfig& config,
|
||||
Context& context) {
|
||||
|
||||
Direction mainDir = config.mainDirection();
|
||||
// 1. 设置当前线路上下文
|
||||
QString originalRouteId = context.currentRouteId;
|
||||
bool originalIsRemoving = context.isRemovingRoute;
|
||||
|
||||
context.currentRouteId = route.sRouteName;
|
||||
context.isRemovingRoute = false;
|
||||
|
||||
// 2. 执行布局计算
|
||||
layoutMainRouteInternal(route, config, context);
|
||||
|
||||
// 4. 恢复上下文
|
||||
context.currentRouteId = originalRouteId;
|
||||
context.isRemovingRoute = originalIsRemoving;
|
||||
|
||||
qInfo() << "Main route" << route.sRouteName << "layout completed";
|
||||
/*Direction mainDir = config.mainDirection();
|
||||
auto& components = route.lstCompo;
|
||||
|
||||
if (components.isEmpty()) return;
|
||||
|
|
@ -149,6 +168,61 @@ void DiagramLayoutEngine::layoutMainRoute(
|
|||
nSegIndex += (mainDir == Direction::Up || mainDir == Direction::Left)
|
||||
? -1
|
||||
: 1;
|
||||
}*/
|
||||
}
|
||||
|
||||
void DiagramLayoutEngine::layoutMainRouteInternal(
|
||||
DiagramEditorRouteInfo& route,
|
||||
const LayoutConfig& config,
|
||||
Context& context) {
|
||||
|
||||
QString routeId = route.sRouteName;
|
||||
auto& components = route.lstCompo;
|
||||
if (components.isEmpty()) return;
|
||||
|
||||
Direction mainDir = config.mainDirection();
|
||||
int mainDirFlag = static_cast<int>(mainDir);
|
||||
int oppositeFlag = static_cast<int>(DirectionManager::getOpposite(mainDir));
|
||||
bool isHorizontal = DirectionManager::isHorizontal(mainDir);
|
||||
int spacing = isHorizontal ? config.horizontalSpacing() : config.verticalSpacing();
|
||||
|
||||
// 计算分段索引
|
||||
int nSeg = components.size() - 1; // 实际段数
|
||||
int nSegIndex = (mainDir == Direction::Down || mainDir == Direction::Right)
|
||||
? -nSeg : nSeg;
|
||||
|
||||
for (int i = 0; i < components.size(); ++i) {
|
||||
DiagramEditorComponentInfo& compo = components[i];
|
||||
const QString& compoName = compo.sName;
|
||||
|
||||
int dirMask = 0;
|
||||
|
||||
// 计算方向占用掩码
|
||||
if (i == 0) {
|
||||
dirMask = mainDirFlag; // 队首:出方向
|
||||
} else if (i == components.size() - 1) {
|
||||
dirMask = oppositeFlag; // 队尾:入方向
|
||||
} else {
|
||||
dirMask = mainDirFlag | oppositeFlag; // 中间:入方向 + 出方向
|
||||
}
|
||||
// 计算位置偏移
|
||||
QPoint delta(0, 0);
|
||||
if (isHorizontal) {
|
||||
delta.setX(nSegIndex * spacing);
|
||||
} else {
|
||||
delta.setY(nSegIndex * spacing);
|
||||
}
|
||||
|
||||
int rotate = DirectionManager::getRotationAngle(mainDir);
|
||||
|
||||
// 更新组件
|
||||
updateComponent(compo, dirMask, delta, rotate, context);
|
||||
|
||||
//recordRouteDirectionOccupancy(routeId, compoName, dirMask ,context);
|
||||
|
||||
// 更新索引
|
||||
nSegIndex += (mainDir == Direction::Up || mainDir == Direction::Left)
|
||||
? -1 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -211,9 +285,32 @@ void DiagramLayoutEngine::layoutBranchRoute(
|
|||
const LayoutConfig& config,
|
||||
Context& context) {
|
||||
|
||||
// 1. 设置当前线路上下文
|
||||
QString originalRouteId = context.currentRouteId;
|
||||
bool originalIsRemoving = context.isRemovingRoute;
|
||||
|
||||
context.currentRouteId = route.sRouteName;
|
||||
context.isRemovingRoute = false;
|
||||
|
||||
splitBranchRoute(route, context);
|
||||
|
||||
if (route.lstOrder.size() > 1) {
|
||||
layoutBranchSequence(route.lstOrder, route.preferDirection,
|
||||
config, context, true, 1);
|
||||
}
|
||||
|
||||
// 4. 布局反序序列
|
||||
if (route.lstReverse.size() > 1) {
|
||||
layoutBranchSequence(route.lstReverse, route.preferDirection,
|
||||
config, context, false, -1);
|
||||
}
|
||||
|
||||
// 6. 恢复上下文
|
||||
context.currentRouteId = originalRouteId;
|
||||
context.isRemovingRoute = originalIsRemoving;
|
||||
|
||||
qInfo() << "Branch route" << route.sRouteName << "layout completed";
|
||||
/*if (route.lstOrder.size() > 1) {
|
||||
// ✅ 第一个元件的真实方向,由 determineBranchDirection 决定
|
||||
Direction startDir =
|
||||
determineBranchDirection(route.lstOrder[0],
|
||||
|
|
@ -241,7 +338,7 @@ void DiagramLayoutEngine::layoutBranchRoute(
|
|||
context,
|
||||
false,
|
||||
polarity);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
// 布局分支序列
|
||||
|
|
@ -255,8 +352,8 @@ void DiagramLayoutEngine::layoutBranchSequence(
|
|||
|
||||
if (sequence.size() < 2) return;
|
||||
|
||||
bool isVertical =
|
||||
DirectionManager::isVertical(branchDir);
|
||||
QString routeId = context.currentRouteId;
|
||||
bool isVertical = DirectionManager::isVertical(branchDir);
|
||||
|
||||
// ✅ 2. 间距由主线方向决定
|
||||
int spacing = isVertical
|
||||
|
|
@ -290,30 +387,15 @@ void DiagramLayoutEngine::layoutBranchSequence(
|
|||
int rotate =
|
||||
DirectionManager::getRotationAngle(dir);
|
||||
|
||||
updateComponent(sequence[i], int(dir),
|
||||
basePos, rotate, context);
|
||||
|
||||
updateComponent(next, int(nextConnectionDir),
|
||||
nextPos, rotate, context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DiagramLayoutEngine::markDirectionUsed(
|
||||
const QString& compoName,
|
||||
Direction dir,
|
||||
Context& context)
|
||||
{
|
||||
if (context.saveToModel) {
|
||||
QStandardItem* item = getNameItem(compoName, context);
|
||||
if (!item) return;
|
||||
|
||||
int old = item->data().toInt();
|
||||
int updated = old | static_cast<int>(dir);
|
||||
item->setData(updated);
|
||||
} else {
|
||||
context.componentsCache[compoName].nUsedDirection |=
|
||||
static_cast<int>(dir);
|
||||
}
|
||||
}
|
||||
|
||||
// 确定支线方向
|
||||
Direction DiagramLayoutEngine::determineBranchDirection(
|
||||
const DiagramEditorComponentInfo& currentNode,
|
||||
|
|
@ -408,27 +490,261 @@ void DiagramLayoutEngine::updateComponent(
|
|||
int rotate,
|
||||
Context& context) {
|
||||
|
||||
// 1. 如果是添加操作,记录方向占用
|
||||
if (dir != 0 && !context.isRemovingRoute) {
|
||||
QString routeId = context.currentRouteId;
|
||||
if (!routeId.isEmpty()) {
|
||||
// 记录方向占用
|
||||
bool success = recordRouteDirectionOccupancy(routeId, compo.sName, dir,context);
|
||||
if (success) {
|
||||
// 使用统一的缓存更新函数
|
||||
int nTotalDir = getComponentTotalOccupiedDirections(compo.sName,context);
|
||||
updateComponentDirections(compo.sName, nTotalDir, DirectionOperation::ADD, 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));
|
||||
//int currentDir = item->data().toInt();
|
||||
//int newDir = DirectionManager::markDirectionOccupied(currentDir, dir);
|
||||
//item->setData(QString::number(newDir));
|
||||
//int nUsedDir = item->data().toInt();
|
||||
//item->setData(dir | nUsedDir);
|
||||
item->setData(position, Qt::UserRole + 2);
|
||||
item->setData(rotate, Qt::UserRole + 5);
|
||||
}
|
||||
} else {
|
||||
compo.nUsedDirection = DirectionManager::markDirectionOccupied(compo.nUsedDirection, dir);
|
||||
//compo.nUsedDirection = DirectionManager::markDirectionOccupied(compo.nUsedDirection, dir);
|
||||
compo.deltaPos = position;
|
||||
compo.nRotate = rotate;
|
||||
|
||||
// 更新缓存
|
||||
context.componentsCache[compo.sName].nUsedDirection = compo.nUsedDirection;
|
||||
//context.componentsCache[compo.sName].nUsedDirection |= dir;
|
||||
context.componentsCache[compo.sName].deltaPos = compo.deltaPos;
|
||||
context.componentsCache[compo.sName].nRotate = compo.nRotate;
|
||||
}
|
||||
}
|
||||
|
||||
bool DiagramLayoutEngine::recordRouteDirectionOccupancy(
|
||||
const QString& routeId,
|
||||
const QString& compoName,
|
||||
int directionMask,
|
||||
Context& context) {
|
||||
|
||||
if (directionMask == 0 || routeId.isEmpty() || compoName.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 1. 检查冲突
|
||||
auto& dirRecords = context.directionOccupancyMap[compoName];
|
||||
bool allRecorded = true;
|
||||
|
||||
for (int dirIndex = 0; dirIndex < 4; ++dirIndex) {
|
||||
int dirBit = 1 << dirIndex;
|
||||
|
||||
if ((directionMask & dirBit) == 0) {
|
||||
continue; // 不是要记录的方向
|
||||
}
|
||||
|
||||
// 检查方向冲突
|
||||
if (!dirRecords[dirIndex].routeId.isEmpty() &&
|
||||
dirRecords[dirIndex].routeId != routeId) {
|
||||
qWarning() << "方向冲突: 组件" << compoName << "方向"
|
||||
<< getDirectionName(dirBit) << "已被线路"
|
||||
<< dirRecords[dirIndex].routeId << "占用";
|
||||
allRecorded = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!allRecorded) {
|
||||
return false; // 有冲突,不记录
|
||||
}
|
||||
|
||||
// 2. 记录到全局表
|
||||
for (int dirIndex = 0; dirIndex < 4; ++dirIndex) {
|
||||
int dirBit = 1 << dirIndex;
|
||||
|
||||
if ((directionMask & dirBit) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
dirRecords[dirIndex] = DirectionOccupancyRecord{
|
||||
.routeId = routeId,
|
||||
.directionMask = dirBit,
|
||||
.timestamp = QDateTime::currentMSecsSinceEpoch()
|
||||
};
|
||||
|
||||
qDebug() << "记录: 线路" << routeId << "占用组件" << compoName
|
||||
<< "方向" << getDirectionName(dirBit);
|
||||
}
|
||||
|
||||
// 3. 更新线路的routeInfo(关键变化:只存储实际占用的方向)
|
||||
DirectionOccupancyRouteInfo& routeInfo = context.routeDirectionMap[routeId];
|
||||
|
||||
if (routeInfo.contains(compoName)) {
|
||||
// 合并方向
|
||||
int existingMask = routeInfo.getDirection(compoName);
|
||||
routeInfo.updateDirection(compoName, existingMask | directionMask);
|
||||
} else {
|
||||
// 添加组件
|
||||
routeInfo.addComponent(compoName, directionMask);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DiagramLayoutEngine::updateComponentDirections(const QString& compoName,
|
||||
int directionMask,
|
||||
DirectionOperation operation,
|
||||
Context& context) {
|
||||
|
||||
if (compoName.isEmpty()) {
|
||||
qWarning() << "Component name is empty";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (directionMask == 0) {
|
||||
qDebug() << "Direction mask is zero, skipping update for" << compoName;
|
||||
return true; // 方向掩码为0也算成功
|
||||
}
|
||||
|
||||
// 验证方向掩码
|
||||
/*if (!isValidDirectionMask(directionMask)) {
|
||||
qWarning() << "Invalid direction mask:" << directionMask
|
||||
<< "for component" << compoName;
|
||||
return false;
|
||||
}*/
|
||||
|
||||
// 1. 更新缓存
|
||||
bool cacheUpdated = updateComponentCacheInternal(compoName, directionMask, operation, context);
|
||||
|
||||
// 2. 如果需要,更新模型
|
||||
bool modelUpdated = true; // 默认成功
|
||||
if (context.saveToModel) {
|
||||
modelUpdated = updateComponentModel(compoName, directionMask, operation, context);
|
||||
}
|
||||
|
||||
return cacheUpdated && modelUpdated;
|
||||
}
|
||||
|
||||
bool DiagramLayoutEngine::updateComponentCacheInternal(const QString& compoName,
|
||||
int directionMask,
|
||||
DirectionOperation operation,
|
||||
Context& context) {
|
||||
|
||||
auto it = context.componentsCache.find(compoName);
|
||||
|
||||
switch (operation) {
|
||||
case DirectionOperation::ADD: {
|
||||
if (it == context.componentsCache.end()) {
|
||||
// 创建新缓存条目
|
||||
DiagramEditorComponentInfo info;
|
||||
info.nUsedDirection = directionMask;
|
||||
context.componentsCache[compoName] = info;
|
||||
|
||||
qDebug() << "catch create compo" << compoName
|
||||
<< "used dir:" << directionMask;
|
||||
} else {
|
||||
int oldDir = it->nUsedDirection;
|
||||
it->nUsedDirection |= directionMask;
|
||||
|
||||
if (oldDir != it->nUsedDirection) {
|
||||
qDebug() << "catch add compo" << compoName << "direction:"
|
||||
<< oldDir << "→"
|
||||
<< it->nUsedDirection;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case DirectionOperation::REMOVE: {
|
||||
if (it == context.componentsCache.end()) {
|
||||
qWarning() << compoName << "does't exist";
|
||||
return false;
|
||||
}
|
||||
|
||||
int oldDir = it->nUsedDirection;
|
||||
it->nUsedDirection &= ~directionMask;
|
||||
|
||||
qDebug() << "catch remove compo" << compoName << "direction:"
|
||||
<< oldDir << "→"
|
||||
<< it->nUsedDirection;
|
||||
|
||||
// 如果没有占用的方向,清理缓存
|
||||
/*if (it->nUsedDirection == 0) {
|
||||
context.componentsCache.erase(it);
|
||||
qDebug() << "[缓存] 移除组件" << compoName << "(无占用方向)";
|
||||
}*/
|
||||
break;
|
||||
}
|
||||
|
||||
case DirectionOperation::SET: {
|
||||
if (it == context.componentsCache.end()) {
|
||||
DiagramEditorComponentInfo info;
|
||||
info.nUsedDirection = directionMask;
|
||||
context.componentsCache[compoName] = info;
|
||||
} else {
|
||||
it->nUsedDirection = directionMask;
|
||||
}
|
||||
|
||||
qDebug() << "catch set compo" << compoName
|
||||
<< "direction:" << directionMask;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
qWarning() << "catch unknown";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DiagramLayoutEngine::updateComponentModel(const QString& compoName,
|
||||
int directionMask,
|
||||
DirectionOperation operation,
|
||||
Context& context) {
|
||||
|
||||
QStandardItem* item = getNameItem(compoName, context);
|
||||
if (!item) {
|
||||
qWarning() << "model can't find" << compoName << " model";
|
||||
return false;
|
||||
}
|
||||
|
||||
int currentDir = item->data().toInt(); // 当前模型中的方向
|
||||
int newDir = currentDir;
|
||||
|
||||
switch (operation) {
|
||||
case DirectionOperation::ADD:
|
||||
newDir = currentDir | directionMask;
|
||||
break;
|
||||
|
||||
case DirectionOperation::REMOVE:
|
||||
newDir = currentDir & ~directionMask;
|
||||
break;
|
||||
|
||||
case DirectionOperation::SET:
|
||||
newDir = directionMask;
|
||||
break;
|
||||
|
||||
default:
|
||||
qWarning() << "[model] unknown";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (currentDir != newDir) {
|
||||
item->setData(newDir);
|
||||
qDebug() << "[model] update compo" << compoName << "direction:"
|
||||
<< currentDir << "→"
|
||||
<< newDir;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// 计算边界矩形
|
||||
QRectF DiagramLayoutEngine::calculateBoundingRect(
|
||||
const QMap<QString, DiagramEditorComponentInfo>& components) {
|
||||
|
|
@ -484,3 +800,102 @@ Direction DiagramLayoutEngine::getRouteDirection(
|
|||
|
||||
return route.preferDirection;
|
||||
}
|
||||
|
||||
int DiagramLayoutEngine::getComponentTotalOccupiedDirections(const QString& compoName, Context& context) {
|
||||
auto it = context.directionOccupancyMap.find(compoName);
|
||||
if (it == context.directionOccupancyMap.end()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int totalMask = 0;
|
||||
for (int dirIndex = 0; dirIndex < 4; ++dirIndex) {
|
||||
if (!it.value()[dirIndex].routeId.isEmpty()) {
|
||||
totalMask |= it.value()[dirIndex].directionMask;
|
||||
}
|
||||
}
|
||||
|
||||
return totalMask;
|
||||
}
|
||||
|
||||
int DiagramLayoutEngine::getComponentDirectionFromCache(const QString& compoName,const QString& routeId,Context& context)
|
||||
{
|
||||
if (!context.routeDirectionMap.contains(routeId)) {
|
||||
qDebug() << "Route" << routeId << "not found in direction map";
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 4. 从全局方向占用表中查找
|
||||
if (context.directionOccupancyMap.contains(compoName)) {
|
||||
const auto& dirRecords = context.directionOccupancyMap[compoName];
|
||||
|
||||
int directionMask = 0;
|
||||
|
||||
// 遍历4个方向,检查哪些被指定线路占用
|
||||
for (int i = 0; i < dirRecords.size(); ++i) {
|
||||
if (dirRecords[i].routeId == routeId) {
|
||||
directionMask |= dirRecords[i].directionMask;
|
||||
}
|
||||
}
|
||||
|
||||
if (directionMask != 0) {
|
||||
qDebug() << "Found direction mask" << directionMask
|
||||
<< "for component" << compoName
|
||||
<< "in route" << routeId << "from global occupancy map";
|
||||
return directionMask;
|
||||
}
|
||||
}
|
||||
|
||||
// 5. 未找到
|
||||
qDebug() << "Component" << compoName << "not found in route" << routeId;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool DiagramLayoutEngine::clearRouteDirectionOccupancy(const QString& routeId,Context& context) {
|
||||
|
||||
// 1. 查找要清理的线路
|
||||
auto routeIt = context.routeDirectionMap.find(routeId);
|
||||
if (routeIt == context.routeDirectionMap.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DirectionOccupancyRouteInfo& routeToClear = routeIt.value();
|
||||
|
||||
qDebug() << "=== 清理线路:" << routeId << "===";
|
||||
|
||||
// 2. 从全局表中清理这个线路的所有占用
|
||||
for (const QString& compoName : routeToClear.getAllComponents()) {
|
||||
int routeDirection = routeToClear.getDirection(compoName);
|
||||
|
||||
qDebug() << "clear compo" << compoName << "direction:" << routeDirection;
|
||||
|
||||
// 从全局表中清理
|
||||
auto& dirRecords = context.directionOccupancyMap[compoName];
|
||||
|
||||
for (int dirIndex = 0; dirIndex < 4; ++dirIndex) {
|
||||
int dirBit = 1 << dirIndex;
|
||||
|
||||
if ((routeDirection & dirBit) == 0) {
|
||||
continue; // 不是这个线路占用的方向
|
||||
}
|
||||
|
||||
if (!dirRecords[dirIndex].routeId.isEmpty() &&
|
||||
dirRecords[dirIndex].routeId == routeId) {
|
||||
|
||||
qDebug() << " clear direction" << getDirectionName(dirBit);
|
||||
dirRecords[dirIndex] = DirectionOccupancyRecord{};
|
||||
}
|
||||
}
|
||||
|
||||
// 更新组件缓存
|
||||
updateComponentDirections(compoName, routeDirection, DirectionOperation::REMOVE, context);
|
||||
}
|
||||
|
||||
// 3. 从routeDirectionMap中删除这个线路
|
||||
context.routeDirectionMap.erase(routeIt);
|
||||
|
||||
// 4. 清理空的组件条目(可选)
|
||||
//cleanupEmptyComponents(context);
|
||||
|
||||
qDebug() << "=== route" << routeId << "clear ===";
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1325,8 +1325,11 @@ QMultiMap<int,QUuid> DiagramEditorModel::generateOutConnection(QList<DiagramEdit
|
|||
return bindId;
|
||||
}
|
||||
|
||||
void DiagramEditorModel::clearCompoDir(QMap<QString,DiagramEditorRouteInfo>& data,QMap<QString,DiagramEditorComponentInfo>& compos,int nSource)
|
||||
void DiagramEditorModel::clearCompoDir(QMap<QString,DiagramEditorRouteInfo>& data,QMap<QString,DiagramEditorComponentInfo>& compos,
|
||||
QMap<QString, QMap<int,DirectionOccupancyRecord>>& directionOccupancyMap,QMap<QString, DirectionOccupancyRouteInfo>& routeDirectionMap,int nSource)
|
||||
{
|
||||
directionOccupancyMap.clear();
|
||||
routeDirectionMap.clear();
|
||||
for(auto &routeInfo:data){
|
||||
routeInfo.lstOrder.clear();
|
||||
routeInfo.lstReverse.clear();
|
||||
|
|
@ -1349,9 +1352,19 @@ void DiagramEditorModel::clearCompoDir(QMap<QString,DiagramEditorRouteInfo>& dat
|
|||
}
|
||||
}
|
||||
|
||||
void DiagramEditorModel::removeRouteDir(QMap<QString,DiagramEditorRouteInfo>&,QMap<QString,DiagramEditorComponentInfo>&,QMap<QString, QMap<int,DirectionOccupancyRecord>>& directionOccupancyMap,
|
||||
QMap<QString, DirectionOccupancyRouteInfo>& routeDirectionMap,int nSource)
|
||||
{
|
||||
DiagramLayoutEngine engine(this);
|
||||
DiagramLayoutEngine::Context context;
|
||||
//engine.clearRouteDirectionOccupancy(routeId,context);
|
||||
}
|
||||
|
||||
QRectF DiagramEditorModel::updateTarget(
|
||||
QMap<QString, DiagramEditorRouteInfo>& data,
|
||||
QMap<QString, DiagramEditorComponentInfo>& compos,
|
||||
QMap<QString, QMap<int,DirectionOccupancyRecord>>& directionOccupancyMap,
|
||||
QMap<QString, DirectionOccupancyRouteInfo>& routeDirectionMap,
|
||||
int nLayout,
|
||||
int nSource,
|
||||
bool saveToModel) {
|
||||
|
|
@ -1368,7 +1381,7 @@ QRectF DiagramEditorModel::updateTarget(
|
|||
context.saveToModel = saveToModel;
|
||||
|
||||
// 3. 执行布局
|
||||
QRectF boundingRect = engine.executeLayout(data, compos, config, context);
|
||||
QRectF boundingRect = engine.executeLayout(data, compos, directionOccupancyMap, routeDirectionMap, config, context);
|
||||
|
||||
return boundingRect;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -335,6 +335,7 @@ void CMainWindow::onSignal_loadProject()
|
|||
m_pLoadPageDlg = new LoadPageDlg(this);
|
||||
connect(&ProjectManager::instance(),&ProjectManager::prepareLoadBaseSetting,m_pDiagramCavas,&DiagramCavas::onSignal_loadEdit);
|
||||
connect(m_pLoadPageDlg,&LoadPageDlg::selectedProject,m_pDiagramView,&DiagramView::onEditorLoaded);
|
||||
connect(m_pLoadPageDlg,&LoadPageDlg::selectedProject,m_pDiagramCavas,&DiagramCavas::onSignal_unloadProject);
|
||||
connect(&ProjectManager::instance(),&ProjectManager::createNewEditor,m_pDiagramCavas,&DiagramCavas::onSignal_createEditPanel);
|
||||
connect(&ProjectManager::instance(),&ProjectManager::prepareSaveEditor,m_pDiagramCavas,&DiagramCavas::onSignal_prepareSaveEdit);
|
||||
connect(&ProjectManager::instance(),&ProjectManager::prepareDeleteBaseSetting,m_pDiagramCavas,&DiagramCavas::onSignal_prepareDeleteEditor);
|
||||
|
|
|
|||
Loading…
Reference in New Issue