optimize editor structure
This commit is contained in:
parent
4c3151750b
commit
8f152e0b15
|
|
@ -12,4 +12,31 @@ const int H_DIAGRAM_SPACING = 80;
|
||||||
const int TRANSFORMER_LEVEL = 999; // 层级结构中变压器所处层级
|
const int TRANSFORMER_LEVEL = 999; // 层级结构中变压器所处层级
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********布局计算************/
|
||||||
|
namespace LayoutConstants {
|
||||||
|
// 容器参数
|
||||||
|
constexpr double CONTAINER_H_SPACING = 100.0; // 容器水平间距
|
||||||
|
constexpr double CONTAINER_V_SPACING = 50.0; // 容器垂直基础间距
|
||||||
|
constexpr double BUS_V_SPACING = 50.0; // 双母线垂直间距
|
||||||
|
|
||||||
|
// 设备参数
|
||||||
|
constexpr double BLOCK_H_SPACING = 20.0; // 设备水平间距
|
||||||
|
constexpr double BLOCK_V_MARGIN = 20.0; // 设备垂直边距
|
||||||
|
|
||||||
|
// 变压器参数
|
||||||
|
constexpr double TRANSFORMER_START_X = 150.0; // 变压器起始X
|
||||||
|
constexpr double TRANSFORMER_SPACING = 200.0; // 变压器间距
|
||||||
|
|
||||||
|
// 默认尺寸
|
||||||
|
constexpr double DEFAULT_BLOCK_WIDTH = Constants::EDITOR_ITEM_WIDTH;
|
||||||
|
constexpr double DEFAULT_BLOCK_HEIGHT = Constants::EDITOR_ITEM_HEIGHT;
|
||||||
|
|
||||||
|
// 图层索引
|
||||||
|
namespace Layer {
|
||||||
|
constexpr int TOP_BAYS = 0; // 上间隔层
|
||||||
|
constexpr int BUS1 = 1; // 母线1层
|
||||||
|
constexpr int BUS2 = 2; // 母线2层
|
||||||
|
constexpr int BOTTOM_BAYS = 3; // 下间隔层
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -5,5 +5,5 @@ const QMap<AbstractItemType,GraphicsItemType> linkType = {
|
||||||
};
|
};
|
||||||
//类型转换
|
//类型转换
|
||||||
const QMap<int,GraphicsItemType> typeToProGraphic = {
|
const QMap<int,GraphicsItemType> typeToProGraphic = {
|
||||||
{0,GIT_node},{1,GIT_bus},{3,GIT_itemRect},{4,GIT_ctGroup},{5,GIT_ptGroup},{6,GIT_ES},{7,GIT_FES},{8,GIT_link},{9,GIT_DS},{10,GIT_DTEDS},{11,GIT_PI},{12,GIT_LA},{13,GIT_cableTer},{14,GIT_cableEnd},{15,GIT_2wTransformer},{16,GIT_3wTransformer}
|
{0,GIT_node},{1,GIT_bus},{3,GIT_itemRect},{4,GIT_ctGroup},{5,GIT_ptGroup},{6,GIT_ES},{7,GIT_FES},{8,GIT_link},{9,GIT_DS},{10,GIT_DTEDS},{11,GIT_PI},{12,GIT_LA},{13,GIT_cableTer},{14,GIT_cableEnd},{15,GIT_2wTransformer},{16,GIT_3wTransformer},{18,GIT_CustomType}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,16 @@ set(DIAGRAMCAVAS_HEADER_FILES
|
||||||
include/diagramEditor/diagramEditorTransPreviewDlg.h
|
include/diagramEditor/diagramEditorTransPreviewDlg.h
|
||||||
include/diagramEditor/diagramEditorPreviewDlg.h
|
include/diagramEditor/diagramEditorPreviewDlg.h
|
||||||
include/diagramEditor/confirmEditorDlg.h
|
include/diagramEditor/confirmEditorDlg.h
|
||||||
|
include/diagramEditor/dataModel.h
|
||||||
|
include/diagramEditor/editItemFactory.h
|
||||||
|
include/diagramEditor/busItemFactory.h
|
||||||
|
include/diagramEditor/bayItemFactory.h
|
||||||
|
include/diagramEditor/transItemFactory.h
|
||||||
|
include/diagramEditor/hierarchyItemBuilder.h
|
||||||
|
include/diagramEditor/layoutBuilder.h
|
||||||
|
include/diagramEditor/transformerBuilder.h
|
||||||
|
include/diagramEditor/layoutData.h
|
||||||
|
include/diagramEditor/layoutCalculator.h
|
||||||
include/graphicsDataModel/baseModel.h
|
include/graphicsDataModel/baseModel.h
|
||||||
include/graphicsDataModel/fixedPortsModel.h
|
include/graphicsDataModel/fixedPortsModel.h
|
||||||
include/graphicsDataModel/diagramEditorModel.h
|
include/graphicsDataModel/diagramEditorModel.h
|
||||||
|
|
@ -231,6 +241,14 @@ set(DIAGRAMCAVAS_SOURCE_FILES
|
||||||
source/diagramEditor/diagramEditorTransPreviewDlg.cpp
|
source/diagramEditor/diagramEditorTransPreviewDlg.cpp
|
||||||
source/diagramEditor/diagramEditorPreviewDlg.cpp
|
source/diagramEditor/diagramEditorPreviewDlg.cpp
|
||||||
source/diagramEditor/confirmEditorDlg.cpp
|
source/diagramEditor/confirmEditorDlg.cpp
|
||||||
|
source/diagramEditor/editItemFactory.cpp
|
||||||
|
source/diagramEditor/busItemFactory.cpp
|
||||||
|
source/diagramEditor/bayItemFactory.cpp
|
||||||
|
source/diagramEditor/transItemFactory.cpp
|
||||||
|
source/diagramEditor/hierarchyItemBuilder.cpp
|
||||||
|
source/diagramEditor/layoutBuilder.cpp
|
||||||
|
source/diagramEditor/transformerBuilder.cpp
|
||||||
|
source/diagramEditor/layoutCalculator.cpp
|
||||||
source/graphicsDataModel/baseModel.cpp
|
source/graphicsDataModel/baseModel.cpp
|
||||||
source/graphicsDataModel/fixedPortsModel.cpp
|
source/graphicsDataModel/fixedPortsModel.cpp
|
||||||
source/graphicsDataModel/diagramEditorModel.cpp
|
source/graphicsDataModel/diagramEditorModel.cpp
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
// BayItemFactory.h
|
||||||
|
#pragma once
|
||||||
|
#include "editItemFactory.h"
|
||||||
|
|
||||||
|
class BayItemFactory : public EditItemFactory {
|
||||||
|
public:
|
||||||
|
EditBaseItem* createItem(BlockDataPtr blockData) override;
|
||||||
|
QGraphicsLinearLayout* createLayerLayout() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void setupItem(EditBaseItem* item, BlockDataPtr blockData) override;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
// 具体的工厂实现
|
||||||
|
// BusItemFactory.h
|
||||||
|
#pragma once
|
||||||
|
#include "editItemFactory.h"
|
||||||
|
|
||||||
|
class BusItemFactory : public EditItemFactory {
|
||||||
|
public:
|
||||||
|
EditBaseItem* createItem(BlockDataPtr blockData) override;
|
||||||
|
QGraphicsLinearLayout* createLayerLayout() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void setupItem(EditBaseItem* item, BlockDataPtr blockData) override;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
// dataModel.h
|
||||||
|
#pragma once
|
||||||
|
#include <QString>
|
||||||
|
#include <QUuid>
|
||||||
|
#include <QMap>
|
||||||
|
#include <QList>
|
||||||
|
#include "diagramEditor/diagramEditorBaseBlock.h"
|
||||||
|
|
||||||
|
// 原始类的前置声明
|
||||||
|
class DiagramEditorBaseBlock;
|
||||||
|
class DiagramEditorStructContainer;
|
||||||
|
class HierarchyItem;
|
||||||
|
|
||||||
|
// 类型别名
|
||||||
|
using BlockDataPtr = DiagramEditorBaseBlock*;
|
||||||
|
using ContainerDataPtr = DiagramEditorStructContainer*;
|
||||||
|
using BlockMap = QMap<int, QList<BlockDataPtr>>;
|
||||||
|
using ContainerStructMap = QMap<int, QList<ContainerDataPtr>>;
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
#define DIAGRAMEDITORWIZARD_H
|
#define DIAGRAMEDITORWIZARD_H
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
//#include "global.h"
|
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
#include "common/core_model/diagram.h"
|
#include "common/core_model/diagram.h"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
// dataModel.h
|
||||||
|
#pragma once
|
||||||
|
#include "diagramEditor/editItems.h"
|
||||||
|
#include "diagramEditor/dataModel.h"
|
||||||
|
#include <QGraphicsLinearLayout>
|
||||||
|
|
||||||
|
class EditItemFactory {
|
||||||
|
public:
|
||||||
|
virtual ~EditItemFactory() = default;
|
||||||
|
|
||||||
|
virtual EditBaseItem* createItem(BlockDataPtr blockData) = 0;
|
||||||
|
virtual QGraphicsLinearLayout* createLayerLayout() = 0;
|
||||||
|
|
||||||
|
static EditItemFactory* getFactory(int itemType);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void setupItem(EditBaseItem* item, BlockDataPtr blockData) = 0;
|
||||||
|
};
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
//编辑文本项生成组态图
|
//编辑文本项生成组态图
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
//#include "global.h"
|
#include "dataModel.h"
|
||||||
#include "common/core_model/diagram.h"
|
#include "common/core_model/diagram.h"
|
||||||
|
|
||||||
class EditView;
|
class EditView;
|
||||||
|
|
@ -24,6 +24,15 @@ class DiagramEditorModel;
|
||||||
class DiagramEditorPreviewDlg;
|
class DiagramEditorPreviewDlg;
|
||||||
class ConfirmEditorDlg;
|
class ConfirmEditorDlg;
|
||||||
class DiagramCavas;
|
class DiagramCavas;
|
||||||
|
struct HierarchyItem;
|
||||||
|
class LayoutBuilder;
|
||||||
|
|
||||||
|
enum class ConnectionType {
|
||||||
|
Unknown,
|
||||||
|
BusBaySameContainer, // 母线-间隔同容器
|
||||||
|
BusBayDiffContainer, // 母线-间隔跨容器
|
||||||
|
TransBay // 变压器-间隔
|
||||||
|
};
|
||||||
|
|
||||||
class EditPanel : public QWidget
|
class EditPanel : public QWidget
|
||||||
{
|
{
|
||||||
|
|
@ -63,6 +72,14 @@ private:
|
||||||
void calculateContainerWidth(EditContainerItem*); //根据间隔数量计算容器宽度 todo:区分上下间隔
|
void calculateContainerWidth(EditContainerItem*); //根据间隔数量计算容器宽度 todo:区分上下间隔
|
||||||
int getContainerBusType(QMap<int,QList<DiagramEditorBaseBlock*>>); //返回容器中母线类型(单双)
|
int getContainerBusType(QMap<int,QList<DiagramEditorBaseBlock*>>); //返回容器中母线类型(单双)
|
||||||
EditBaseItem* getItemByName(const QString&); //根据名称获取指定item
|
EditBaseItem* getItemByName(const QString&); //根据名称获取指定item
|
||||||
|
|
||||||
|
void performCleanup();
|
||||||
|
void initializeSceneLayout();
|
||||||
|
void processAllContainerLevels(const ContainerStructMap& containerStruct);
|
||||||
|
void processNormalContainerLevel(int level, const QList<ContainerDataPtr>& containers,LayoutBuilder& builder);
|
||||||
|
void processTransformerLevel(const QList<ContainerDataPtr>& containers);
|
||||||
|
void finalizeConstruction();
|
||||||
|
void emitTopologySignals();
|
||||||
signals:
|
signals:
|
||||||
void panelDelete(const QString&,int);
|
void panelDelete(const QString&,int);
|
||||||
protected:
|
protected:
|
||||||
|
|
@ -79,6 +96,8 @@ private:
|
||||||
int _maxWidth;
|
int _maxWidth;
|
||||||
int _maxHeight;
|
int _maxHeight;
|
||||||
QList<EditRowData*> _lstData;
|
QList<EditRowData*> _lstData;
|
||||||
|
QList<HierarchyItem> _accumulatedBayItems;
|
||||||
|
QList<HierarchyItem> _accumulatedDeviceItems;
|
||||||
QMap<int,QMap<int,EditContainerItem*>> _mapStruct;
|
QMap<int,QMap<int,EditContainerItem*>> _mapStruct;
|
||||||
DiagramEditorModel* _pModel;
|
DiagramEditorModel* _pModel;
|
||||||
DiagramEditorPreviewDlg* _pPreview;
|
DiagramEditorPreviewDlg* _pPreview;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
// HierarchyItemBuilder.h
|
||||||
|
#pragma once
|
||||||
|
#include "common/core_model/topology.h"
|
||||||
|
#include "dataModel.h"
|
||||||
|
|
||||||
|
class HierarchyItemBuilder {
|
||||||
|
public:
|
||||||
|
static HierarchyItemBuilder& instance();
|
||||||
|
|
||||||
|
// 创建间隔层级项
|
||||||
|
HierarchyItem buildBayItem(BlockDataPtr blockData);
|
||||||
|
|
||||||
|
// 创建设备层级项
|
||||||
|
HierarchyItem buildDeviceItem(BlockDataPtr blockData, int deviceType);
|
||||||
|
|
||||||
|
// 创建带父间隔的设备项
|
||||||
|
HierarchyItem buildDeviceWithParent(BlockDataPtr deviceBlock,
|
||||||
|
BlockDataPtr parentBlock,
|
||||||
|
int deviceType);
|
||||||
|
|
||||||
|
// 根据block类型自动创建对应层级项
|
||||||
|
HierarchyItem buildAutoFromBlock(BlockDataPtr blockData);
|
||||||
|
|
||||||
|
private:
|
||||||
|
HierarchyItemBuilder() = default;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
// LayoutBuilder.h
|
||||||
|
#pragma once
|
||||||
|
#include <QGraphicsLinearLayout>
|
||||||
|
#include "editContainerItem.h"
|
||||||
|
#include "dataModel.h"
|
||||||
|
#include "common/core_model/topology.h"
|
||||||
|
|
||||||
|
class EditPanel;
|
||||||
|
class EditBaseItem;
|
||||||
|
|
||||||
|
class LayoutBuilder {
|
||||||
|
public:
|
||||||
|
struct BuildResult {
|
||||||
|
EditContainerItem* container = nullptr;
|
||||||
|
QList<HierarchyItem> bayItems;
|
||||||
|
QList<HierarchyItem> deviceItems;
|
||||||
|
};
|
||||||
|
|
||||||
|
explicit LayoutBuilder(EditPanel* panel);
|
||||||
|
virtual ~LayoutBuilder() = default;
|
||||||
|
|
||||||
|
// 构建一个容器
|
||||||
|
virtual BuildResult buildContainer(const BlockMap& blockMap);
|
||||||
|
|
||||||
|
// 构建行布局
|
||||||
|
static QGraphicsLinearLayout* createRowLayout();
|
||||||
|
|
||||||
|
// 构建垂直布局
|
||||||
|
static QGraphicsLinearLayout* createVerticalLayout();
|
||||||
|
|
||||||
|
// 构建水平布局
|
||||||
|
static QGraphicsLinearLayout* createHorizontalLayout();
|
||||||
|
|
||||||
|
// 添加间隔占位符
|
||||||
|
static EditBaseItem* createSpacerItem();
|
||||||
|
|
||||||
|
// 为垂直布局添加拉伸
|
||||||
|
static void addStretchToVerticalLayout(QGraphicsLinearLayout* layout);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
EditPanel* m_panel = nullptr;
|
||||||
|
|
||||||
|
// 处理一个Block
|
||||||
|
virtual EditBaseItem* processBlock(BlockDataPtr block,
|
||||||
|
QList<HierarchyItem>& bayItems,
|
||||||
|
QList<HierarchyItem>& deviceItems);
|
||||||
|
|
||||||
|
// 处理一个层的所有Blocks
|
||||||
|
void processLayer(const QList<BlockDataPtr>& blocks,
|
||||||
|
QGraphicsLinearLayout* layerLayout,
|
||||||
|
QList<HierarchyItem>& bayItems,
|
||||||
|
QList<HierarchyItem>& deviceItems);
|
||||||
|
|
||||||
|
// 连接信号
|
||||||
|
void connectSignals(EditBaseItem* item);
|
||||||
|
void connectContainerSignals(EditContainerItem* container);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static constexpr int TOTAL_LAYERS = 4; // 总共4层
|
||||||
|
static constexpr int MIN_CONTAINER_WIDTH = 100; // 最小容器宽度
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
// LayoutCalculator.h
|
||||||
|
#pragma once
|
||||||
|
#include "layoutData.h"
|
||||||
|
#include "common/core_model/constants.h"
|
||||||
|
|
||||||
|
class DiagramEditorWizard;
|
||||||
|
class DiagramEditorBaseBlock;
|
||||||
|
class DiagramEditorStructContainer;
|
||||||
|
|
||||||
|
class FixedLayoutCalculator {
|
||||||
|
public:
|
||||||
|
struct LevelLayout {
|
||||||
|
int level = 0;
|
||||||
|
double maxUpHeight = 0; // 整行最大上高度
|
||||||
|
double maxDownHeight = 0; // 整行最大下高度
|
||||||
|
double startY = 0; // 行起始Y
|
||||||
|
QList<DiagramEditorStructContainer*> containers;
|
||||||
|
};
|
||||||
|
|
||||||
|
explicit FixedLayoutCalculator(DiagramEditorWizard* wizard);
|
||||||
|
|
||||||
|
QMap<DiagramEditorBaseBlock*, QPointF> calculateLayout();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// 第一阶段:计算尺寸
|
||||||
|
void calculateContainerSizes(LevelLayout& levelLayout);
|
||||||
|
|
||||||
|
// 第二阶段:计算位置
|
||||||
|
void calculatePositions(LevelLayout& levelLayout, double& deltaY, double& lastMaxDownH);
|
||||||
|
|
||||||
|
// 计算单个容器的设备位置
|
||||||
|
void calculateBlockPositionsInContainer(DiagramEditorStructContainer* container,
|
||||||
|
double startX,
|
||||||
|
double midUpY,
|
||||||
|
double midDownY);
|
||||||
|
|
||||||
|
// 计算变压器位置
|
||||||
|
void calculateTransformerPositions(const QList<DiagramEditorStructContainer*>& transformers,
|
||||||
|
double& deltaY, double& lastMaxDownH);
|
||||||
|
|
||||||
|
private:
|
||||||
|
DiagramEditorWizard* m_wizard = nullptr;
|
||||||
|
QMap<DiagramEditorBaseBlock*, QPointF> m_blockPositions;
|
||||||
|
|
||||||
|
// 全局常量
|
||||||
|
const double BUS_V_SPACING = 50.0; // 母线1和母线2间距
|
||||||
|
const double CONTAINER_H_SPACING = 100.0; // 容器水平间距
|
||||||
|
const double CONTAINER_START_X = 50.0; // 容器起始X
|
||||||
|
const double TRANSFORMER_START_X = 150.0; // 变压器起始X
|
||||||
|
const double TRANSFORMER_SPACING = 200.0; // 变压器间距
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
// LayoutData.h
|
||||||
|
#pragma once
|
||||||
|
#include <QMap>
|
||||||
|
#include <QPointF>
|
||||||
|
#include <QRectF>
|
||||||
|
|
||||||
|
class DiagramEditorBaseBlock;
|
||||||
|
class DiagramEditorStructContainer;
|
||||||
|
|
||||||
|
struct ContainerLayout {
|
||||||
|
double width = 0;
|
||||||
|
double height = 0;
|
||||||
|
double maxUpHeight = 0; // 上间隔最大高度
|
||||||
|
double maxDownHeight = 0; // 下间隔最大高度
|
||||||
|
double startX = 0; // 容器起始X
|
||||||
|
double startY = 0; // 容器起始Y
|
||||||
|
double midUpY = 0; // 母线1中心Y
|
||||||
|
double midDownY = 0; // 母线2中心Y
|
||||||
|
QMap<DiagramEditorBaseBlock*, QPointF> blockPositions; // 设备位置
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RowLayout {
|
||||||
|
int level = 0;
|
||||||
|
double topY = 0; // 行顶部Y
|
||||||
|
double height = 0; // 行高度
|
||||||
|
double width = 0; // 行宽度
|
||||||
|
QList<ContainerLayout*> containers;
|
||||||
|
bool isTransformerRow = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LayoutResult {
|
||||||
|
QMap<int, RowLayout> rows; // 各层级布局
|
||||||
|
QMap<DiagramEditorBaseBlock*, QPointF> allBlockPositions; // 所有设备位置
|
||||||
|
QMap<DiagramEditorStructContainer*, ContainerLayout> containerLayouts; // 容器布局
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
// TransItemFactory.h
|
||||||
|
#pragma once
|
||||||
|
#include "editItemFactory.h"
|
||||||
|
|
||||||
|
class TransItemFactory : public EditItemFactory {
|
||||||
|
public:
|
||||||
|
EditBaseItem* createItem(BlockDataPtr blockData) override;
|
||||||
|
QGraphicsLinearLayout* createLayerLayout() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void setupItem(EditBaseItem* item, BlockDataPtr blockData) override;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
// TransformerBuilder.h
|
||||||
|
#pragma once
|
||||||
|
#include "layoutBuilder.h"
|
||||||
|
|
||||||
|
class TransformerBuilder : public LayoutBuilder {
|
||||||
|
public:
|
||||||
|
explicit TransformerBuilder(EditPanel* panel);
|
||||||
|
|
||||||
|
// 重写容器构建方法
|
||||||
|
BuildResult buildContainer(const BlockMap& blockMap) override;
|
||||||
|
|
||||||
|
// 创建变压器行布局
|
||||||
|
QGraphicsLinearLayout* createTransformerRowLayout();
|
||||||
|
|
||||||
|
// 处理变压器的层级项
|
||||||
|
HierarchyItem buildTransformerHierarchyItem(BlockDataPtr blockData);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// 处理变压器的特殊逻辑
|
||||||
|
void processTransformerBlock(BlockDataPtr block,
|
||||||
|
QList<HierarchyItem>& bayItems,
|
||||||
|
QList<HierarchyItem>& deviceItems);
|
||||||
|
|
||||||
|
static constexpr int TRANSFORMER_TYPE = 3;
|
||||||
|
static constexpr int TRANSFORMER_DEVICE_TYPE = 16;
|
||||||
|
};
|
||||||
|
|
@ -20,7 +20,7 @@ class BaseModel : public QObject
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
void createTopoTerminalsByItem(GraphicsBaseItem*,ModelFunctionType funType = ModelFunctionType::ProjectModel); //通过图形对象创建port接线点(新建)
|
void createTopoTerminalsByItem(GraphicsBaseItem*,ModelFunctionType funType = ModelFunctionType::ProjectModel); //通过图形对象创建port接线点(新建)
|
||||||
QPointF calculateBusPortPos(GraphicsBaseItem* pBus,GraphicsBaseItem* item); //计算母线上接线点位置
|
QPointF calculateBusPortPos(GraphicsBaseItem* pBus,GraphicsBaseItem* item,QPointF para = QPointF(0,0)); //计算母线上接线点位置
|
||||||
template<typename TypeLine> void establishConnection(GraphicsBaseItem*,GraphicsBaseItem*,TypeLine*,ModelFunctionType,int nMode=0,int nParam = 0); //在两个item之间建立连接 nMode:0正常1变压器中性点2变压器 nParam附加参数:中性点中表示需连接的位置(012高中低)
|
template<typename TypeLine> void establishConnection(GraphicsBaseItem*,GraphicsBaseItem*,TypeLine*,ModelFunctionType,int nMode=0,int nParam = 0); //在两个item之间建立连接 nMode:0正常1变压器中性点2变压器 nParam附加参数:中性点中表示需连接的位置(012高中低)
|
||||||
double distanceBetweenItems(QGraphicsItem* item1, QGraphicsItem* item2) {
|
double distanceBetweenItems(QGraphicsItem* item1, QGraphicsItem* item2) {
|
||||||
QPointF center1 = item1->mapToScene(item1->boundingRect().center());
|
QPointF center1 = item1->mapToScene(item1->boundingRect().center());
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
#include <QStandardItemModel>
|
#include <QStandardItemModel>
|
||||||
#include "common/core_model/diagram.h"
|
#include "common/core_model/diagram.h"
|
||||||
#include "common/core_model/topology.h"
|
#include "common/core_model/topology.h"
|
||||||
|
#include "diagramEditor/layoutData.h"
|
||||||
|
|
||||||
class GraphicsBaseModelItem;
|
class GraphicsBaseModelItem;
|
||||||
class DiagramEditorItemProperty;
|
class DiagramEditorItemProperty;
|
||||||
|
|
@ -48,6 +49,7 @@ public:
|
||||||
void calculateBlockPos(); //重新计算block位置
|
void calculateBlockPos(); //重新计算block位置
|
||||||
void setItemInBlockPos(); //设置block中的item位置
|
void setItemInBlockPos(); //设置block中的item位置
|
||||||
void refreshConnection(); //刷新连接线
|
void refreshConnection(); //刷新连接线
|
||||||
|
void applyLayoutResult(const LayoutResult& result);
|
||||||
|
|
||||||
void setCurBayRouteModel(QStandardItemModel* p) {_pCurBayRoute = p;}
|
void setCurBayRouteModel(QStandardItemModel* p) {_pCurBayRoute = p;}
|
||||||
QStandardItemModel* getCurBayRouteModel() {return _pCurBayRoute;}
|
QStandardItemModel* getCurBayRouteModel() {return _pCurBayRoute;}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
// BusItemFactory.cpp
|
||||||
|
#include "diagramEditor/bayItemFactory.h"
|
||||||
|
#include "common/core_model/constants.h"
|
||||||
|
|
||||||
|
EditBaseItem* BayItemFactory::createItem(BlockDataPtr blockData) {
|
||||||
|
auto pBay = new EditBayItem();
|
||||||
|
setupItem(pBay, blockData);
|
||||||
|
return pBay;
|
||||||
|
}
|
||||||
|
|
||||||
|
QGraphicsLinearLayout* BayItemFactory::createLayerLayout() {
|
||||||
|
return new QGraphicsLinearLayout(Qt::Horizontal);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BayItemFactory::setupItem(EditBaseItem* item, BlockDataPtr blockData) {
|
||||||
|
item->setType(EditorItemType::bay);
|
||||||
|
item->setBoundingRect(QRectF(0, 0,
|
||||||
|
Constants::EDITOR_ITEM_WIDTH, Constants::EDITOR_ITEM_HEIGHT));
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
// BusItemFactory.cpp
|
||||||
|
#include "diagramEditor/busItemFactory.h"
|
||||||
|
#include "common/core_model/constants.h"
|
||||||
|
|
||||||
|
EditBaseItem* BusItemFactory::createItem(BlockDataPtr blockData) {
|
||||||
|
auto pBus = new EditBusItem();
|
||||||
|
setupItem(pBus, blockData);
|
||||||
|
return pBus;
|
||||||
|
}
|
||||||
|
|
||||||
|
QGraphicsLinearLayout* BusItemFactory::createLayerLayout() {
|
||||||
|
auto layout = new QGraphicsLinearLayout(Qt::Horizontal);
|
||||||
|
layout->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum);
|
||||||
|
layout->setPreferredHeight(10);
|
||||||
|
return layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BusItemFactory::setupItem(EditBaseItem* item, BlockDataPtr blockData) {
|
||||||
|
item->setType(EditorItemType::bus);
|
||||||
|
item->setBoundingRect(QRectF(0, 0,
|
||||||
|
Constants::EDITOR_ITEM_WIDTH, Constants::EDITOR_ITEM_HEIGHT));
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
// EditItemFactory.cpp - 工厂管理器
|
||||||
|
#include "diagramEditor/editItemFactory.h"
|
||||||
|
#include "diagramEditor/busItemFactory.h"
|
||||||
|
#include "diagramEditor/bayItemFactory.h"
|
||||||
|
#include "diagramEditor/transItemFactory.h"
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
EditItemFactory* EditItemFactory::getFactory(int itemType) {
|
||||||
|
static std::map<int, std::unique_ptr<EditItemFactory>> factories;
|
||||||
|
|
||||||
|
// 延迟初始化
|
||||||
|
if (factories.empty()) {
|
||||||
|
factories[1] = std::make_unique<BusItemFactory>();
|
||||||
|
factories[2] = std::make_unique<BayItemFactory>();
|
||||||
|
factories[3] = std::make_unique<TransItemFactory>();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto it = factories.find(itemType);
|
||||||
|
if (it != factories.end()) {
|
||||||
|
return it->second.get();
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
@ -21,9 +21,10 @@
|
||||||
#include "diagramEditor/confirmEditorDlg.h"
|
#include "diagramEditor/confirmEditorDlg.h"
|
||||||
#include "projectManager.h"
|
#include "projectManager.h"
|
||||||
#include "diagramCavas.h"
|
#include "diagramCavas.h"
|
||||||
//#include "global.h"
|
|
||||||
#include "common/core_model/constants.h"
|
#include "common/core_model/constants.h"
|
||||||
#include "basePropertyManager.h"
|
#include "basePropertyManager.h"
|
||||||
|
#include "diagramEditor/transformerBuilder.h"
|
||||||
|
#include "diagramEditor/layoutBuilder.h"
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
EditPanel::EditPanel(QWidget *parent)
|
EditPanel::EditPanel(QWidget *parent)
|
||||||
|
|
@ -60,20 +61,18 @@ EditPanel::~EditPanel()
|
||||||
|
|
||||||
void EditPanel::initByWizardInfo()
|
void EditPanel::initByWizardInfo()
|
||||||
{
|
{
|
||||||
QList<HierarchyItem> lstBay;
|
/*QList<HierarchyItem> lstBay;
|
||||||
QList<HierarchyItem> lstItem;
|
QList<HierarchyItem> lstItem;
|
||||||
//if(!_lstData.empty() || !_pModel->getPreviewItem().empty()){
|
_pModel->clearItems();
|
||||||
_pModel->clearItems();
|
m_pEditScene->clear();
|
||||||
m_pEditScene->clear();
|
_lstData.clear();
|
||||||
_lstData.clear();
|
_mainWidget = new EditMainRect;
|
||||||
_mainWidget = new EditMainRect;
|
_widgetLayout = new QGraphicsLinearLayout(Qt::Vertical);
|
||||||
_widgetLayout = new QGraphicsLinearLayout(Qt::Vertical);
|
_widgetLayout->setSpacing(40);
|
||||||
_widgetLayout->setSpacing(40);
|
_mainWidget->setLayout(_widgetLayout);
|
||||||
_mainWidget->setLayout(_widgetLayout);
|
m_pEditScene->addItem(_mainWidget);
|
||||||
m_pEditScene->addItem(_mainWidget);
|
_mainWidget->setGeometry(m_pEditScene->sceneRect());
|
||||||
_mainWidget->setGeometry(m_pEditScene->sceneRect());
|
BasePropertyManager::instance().clearEditorData();
|
||||||
BasePropertyManager::instance().clearEditorData();
|
|
||||||
//}
|
|
||||||
auto& mapTotal = _pEditorWizard->getContainerStruct();
|
auto& mapTotal = _pEditorWizard->getContainerStruct();
|
||||||
for(auto iter = mapTotal.begin();iter != mapTotal.end();++iter){
|
for(auto iter = mapTotal.begin();iter != mapTotal.end();++iter){
|
||||||
if(iter.key() == Constants::TRANSFORMER_LEVEL)
|
if(iter.key() == Constants::TRANSFORMER_LEVEL)
|
||||||
|
|
@ -145,11 +144,6 @@ void EditPanel::initByWizardInfo()
|
||||||
pBay->setBoundingRect(QRectF(0,0,Constants::EDITOR_ITEM_WIDTH,Constants::EDITOR_ITEM_HEIGHT));
|
pBay->setBoundingRect(QRectF(0,0,Constants::EDITOR_ITEM_WIDTH,Constants::EDITOR_ITEM_HEIGHT));
|
||||||
pItem = pBay;
|
pItem = pBay;
|
||||||
}
|
}
|
||||||
/*else if(nType == 3){ //变压器
|
|
||||||
auto pTrans = new EditTransItem();
|
|
||||||
pTrans->setType(EditorItemType::Trans);
|
|
||||||
pItem = pTrans;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
if(pItem){
|
if(pItem){
|
||||||
HierarchyItem bayInfo; //间隔层级
|
HierarchyItem bayInfo; //间隔层级
|
||||||
|
|
@ -169,7 +163,6 @@ void EditPanel::initByWizardInfo()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(mapBlock.value(0).isEmpty()){ //为空则添加间距
|
if(mapBlock.value(0).isEmpty()){ //为空则添加间距
|
||||||
//layV->insertStretch(0);
|
|
||||||
QGraphicsLinearLayout* layH = new QGraphicsLinearLayout(Qt::Horizontal); //container中每一层的布局
|
QGraphicsLinearLayout* layH = new QGraphicsLinearLayout(Qt::Horizontal); //container中每一层的布局
|
||||||
layV->insertItem(0,layH);
|
layV->insertItem(0,layH);
|
||||||
auto pSpace = new EditBaseItem();
|
auto pSpace = new EditBaseItem();
|
||||||
|
|
@ -179,7 +172,6 @@ void EditPanel::initByWizardInfo()
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mapBlock.value(3).isEmpty()){ //为空则添加间距
|
if(mapBlock.value(3).isEmpty()){ //为空则添加间距
|
||||||
//layV->addStretch();
|
|
||||||
QGraphicsLinearLayout* layH = new QGraphicsLinearLayout(Qt::Horizontal); //container中每一层的布局
|
QGraphicsLinearLayout* layH = new QGraphicsLinearLayout(Qt::Horizontal); //container中每一层的布局
|
||||||
layV->insertItem(3,layH);
|
layV->insertItem(3,layH);
|
||||||
auto pSpace = new EditBaseItem();
|
auto pSpace = new EditBaseItem();
|
||||||
|
|
@ -198,13 +190,8 @@ void EditPanel::initByWizardInfo()
|
||||||
|
|
||||||
|
|
||||||
calculateContainerWidth(pContain);
|
calculateContainerWidth(pContain);
|
||||||
/*int n = getContainerBusType(mapBlock);
|
|
||||||
if(n == 1){
|
|
||||||
layoutRowData->setMaximumHeight(210);
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
_lstData.append(pRow);
|
_lstData.append(pRow);
|
||||||
//layoutRowData->addStretch();
|
|
||||||
_widgetLayout->addItem(layoutRowData);
|
_widgetLayout->addItem(layoutRowData);
|
||||||
|
|
||||||
if(iter.key() == 0){ //若设置了变压器,直接插入到第一行下方
|
if(iter.key() == 0){ //若设置了变压器,直接插入到第一行下方
|
||||||
|
|
@ -303,7 +290,19 @@ void EditPanel::initByWizardInfo()
|
||||||
QTimer::singleShot(300, [&]() { // 1000 毫秒 = 1 秒
|
QTimer::singleShot(300, [&]() { // 1000 毫秒 = 1 秒
|
||||||
qDebug() << "一次性定时器触发!";
|
qDebug() << "一次性定时器触发!";
|
||||||
initBlockConnection();
|
initBlockConnection();
|
||||||
});
|
});*/
|
||||||
|
// 阶段1: 清理和初始化
|
||||||
|
performCleanup();
|
||||||
|
initializeSceneLayout();
|
||||||
|
|
||||||
|
// 阶段2: 获取数据
|
||||||
|
const auto& containerStruct = _pEditorWizard->getContainerStruct();
|
||||||
|
|
||||||
|
// 阶段3: 处理所有层级
|
||||||
|
processAllContainerLevels(containerStruct);
|
||||||
|
|
||||||
|
// 阶段4: 完成构建
|
||||||
|
finalizeConstruction();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditPanel::initBlockConnection()
|
void EditPanel::initBlockConnection()
|
||||||
|
|
@ -324,13 +323,6 @@ void EditPanel::initBlockConnection()
|
||||||
auto pItem1 = getItemByName(item1->getName());
|
auto pItem1 = getItemByName(item1->getName());
|
||||||
auto pItem2 = getItemByName(item2->getName());
|
auto pItem2 = getItemByName(item2->getName());
|
||||||
|
|
||||||
/*QRectF rect1 = pItem1->geometry();
|
|
||||||
QRectF rect2 = pItem2->geometry();
|
|
||||||
|
|
||||||
QPointF center1 = pItem1->mapToScene(rect1.center());
|
|
||||||
QPointF center2 = pItem2->mapToScene(rect2.center());*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
EditLineItem* pLine = new EditLineItem();
|
EditLineItem* pLine = new EditLineItem();
|
||||||
pLine->setName(con.uid.toString());
|
pLine->setName(con.uid.toString());
|
||||||
|
|
@ -436,7 +428,6 @@ void EditPanel::initBlockConnection()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -673,3 +664,161 @@ void EditPanel::loadBaseSetting(QUuid uid)
|
||||||
_pModel->setWizardInfo(info.context);
|
_pModel->setWizardInfo(info.context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EditPanel::performCleanup() {
|
||||||
|
// 清理模型
|
||||||
|
if (_pModel) {
|
||||||
|
_pModel->clearItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清理场景
|
||||||
|
if (m_pEditScene) {
|
||||||
|
m_pEditScene->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清理数据
|
||||||
|
qDeleteAll(_lstData);
|
||||||
|
_lstData.clear();
|
||||||
|
_accumulatedBayItems.clear();
|
||||||
|
_accumulatedDeviceItems.clear();
|
||||||
|
|
||||||
|
// 清理主部件
|
||||||
|
_mainWidget = nullptr;
|
||||||
|
_widgetLayout = nullptr;
|
||||||
|
|
||||||
|
// 清理属性管理器
|
||||||
|
BasePropertyManager::instance().clearEditorData();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditPanel::initializeSceneLayout() {
|
||||||
|
_mainWidget = new EditMainRect;
|
||||||
|
_widgetLayout = new QGraphicsLinearLayout(Qt::Vertical);
|
||||||
|
_widgetLayout->setSpacing(40);
|
||||||
|
_mainWidget->setLayout(_widgetLayout);
|
||||||
|
m_pEditScene->addItem(_mainWidget);
|
||||||
|
_mainWidget->setGeometry(m_pEditScene->sceneRect());
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditPanel::processAllContainerLevels(const ContainerStructMap& containerStruct) {
|
||||||
|
// 普通层级构建器
|
||||||
|
LayoutBuilder normalBuilder(this);
|
||||||
|
|
||||||
|
// 按顺序处理所有层级
|
||||||
|
auto keys = containerStruct.keys();
|
||||||
|
std::sort(keys.begin(), keys.end());
|
||||||
|
|
||||||
|
for (int level : keys) {
|
||||||
|
if (level == Constants::TRANSFORMER_LEVEL) {
|
||||||
|
// 特殊处理变压器层级
|
||||||
|
processTransformerLevel(containerStruct.value(level));
|
||||||
|
} else {
|
||||||
|
// 处理普通层级
|
||||||
|
processNormalContainerLevel(level, containerStruct.value(level), normalBuilder);
|
||||||
|
|
||||||
|
// 如果当前是层级0,且存在变压器层级,在之后插入变压器
|
||||||
|
if (level == 0 && containerStruct.contains(Constants::TRANSFORMER_LEVEL)) {
|
||||||
|
int transformerIndex = keys.indexOf(Constants::TRANSFORMER_LEVEL);
|
||||||
|
if (transformerIndex > 0) { // 变压器在后面
|
||||||
|
continue; // 会在遍历到时处理
|
||||||
|
} else if (transformerIndex < 0) { // 变压器不存在于keys中
|
||||||
|
processTransformerLevel(containerStruct.value(Constants::TRANSFORMER_LEVEL));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditPanel::processNormalContainerLevel(int level,
|
||||||
|
const QList<ContainerDataPtr>& containers,
|
||||||
|
LayoutBuilder& builder) {
|
||||||
|
if (containers.isEmpty()) return;
|
||||||
|
|
||||||
|
// 创建行
|
||||||
|
auto rowLayout = builder.createRowLayout();
|
||||||
|
auto rowData = new EditRowData();
|
||||||
|
rowData->setId(QString::number(level));
|
||||||
|
|
||||||
|
// 处理该层级的所有容器
|
||||||
|
for (auto container : containers) {
|
||||||
|
if (!container) continue;
|
||||||
|
|
||||||
|
const auto& blockMap = container->getBlockMap();
|
||||||
|
auto result = builder.buildContainer(blockMap);
|
||||||
|
|
||||||
|
if (result.container) {
|
||||||
|
rowLayout->addItem(result.container);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 累积层级项
|
||||||
|
_accumulatedBayItems.append(result.bayItems);
|
||||||
|
_accumulatedDeviceItems.append(result.deviceItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存行数据
|
||||||
|
_lstData.append(rowData);
|
||||||
|
_widgetLayout->addItem(rowLayout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditPanel::processTransformerLevel(const QList<ContainerDataPtr>& containers) {
|
||||||
|
if (containers.isEmpty()) return;
|
||||||
|
|
||||||
|
// 使用变压器专用构建器
|
||||||
|
TransformerBuilder transformerBuilder(this);
|
||||||
|
|
||||||
|
// 创建变压器行
|
||||||
|
auto rowLayout = transformerBuilder.createTransformerRowLayout();
|
||||||
|
auto rowData = new EditRowData();
|
||||||
|
rowData->setId(QString::number(Constants::TRANSFORMER_LEVEL));
|
||||||
|
|
||||||
|
// 处理所有变压器容器
|
||||||
|
for (auto container : containers) {
|
||||||
|
if (!container) continue;
|
||||||
|
|
||||||
|
const auto& blockMap = container->getBlockMap();
|
||||||
|
auto result = transformerBuilder.buildContainer(blockMap);
|
||||||
|
|
||||||
|
if (result.container) {
|
||||||
|
rowLayout->addItem(result.container);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 累积变压器层级项
|
||||||
|
_accumulatedBayItems.append(result.bayItems);
|
||||||
|
_accumulatedDeviceItems.append(result.deviceItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 插入变压器行(在层级0之后)
|
||||||
|
_lstData.append(rowData);
|
||||||
|
|
||||||
|
// 找到层级0的位置,在它之后插入变压器
|
||||||
|
int insertPosition = 1; // 默认在第一个之后
|
||||||
|
for (int i = 0; i < _widgetLayout->count(); ++i) {
|
||||||
|
if (i < _lstData.size() && _lstData[i]->getId() == "0") {
|
||||||
|
insertPosition = i + 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_widgetLayout->insertItem(insertPosition, rowLayout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditPanel::finalizeConstruction() {
|
||||||
|
// 添加最后的拉伸
|
||||||
|
_widgetLayout->addStretch();
|
||||||
|
|
||||||
|
// 发射拓扑更新信号
|
||||||
|
emitTopologySignals();
|
||||||
|
|
||||||
|
// 延迟初始化连接
|
||||||
|
QTimer::singleShot(300, this, &EditPanel::initBlockConnection);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditPanel::emitTopologySignals() {
|
||||||
|
if (_pModel) {
|
||||||
|
emit _pModel->updateTopologyItems(_accumulatedBayItems, true, false);
|
||||||
|
emit _pModel->updateTopologyItems(_accumulatedDeviceItems, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清空累积的数据
|
||||||
|
_accumulatedBayItems.clear();
|
||||||
|
_accumulatedDeviceItems.clear();
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,64 @@
|
||||||
|
// HierarchyItemBuilder.cpp
|
||||||
|
#include "diagramEditor/hierarchyItemBuilder.h"
|
||||||
|
|
||||||
|
HierarchyItemBuilder& HierarchyItemBuilder::instance() {
|
||||||
|
static HierarchyItemBuilder instance;
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
HierarchyItem HierarchyItemBuilder::buildBayItem(BlockDataPtr blockData) {
|
||||||
|
if (!blockData) return {};
|
||||||
|
|
||||||
|
HierarchyItem item;
|
||||||
|
item.item.nEquipType = 0; // 间隔的设备类型为0
|
||||||
|
item.item.nCategory = 1; // 类别为1表示间隔
|
||||||
|
item.item.sName = blockData->getName();
|
||||||
|
item.item.uid = blockData->getId();
|
||||||
|
item.item.sVoltageLevel = QString::number(blockData->getVoltage());
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
HierarchyItem HierarchyItemBuilder::buildDeviceItem(BlockDataPtr blockData, int deviceType) {
|
||||||
|
if (!blockData) return {};
|
||||||
|
|
||||||
|
HierarchyItem item;
|
||||||
|
item.item.nEquipType = deviceType;
|
||||||
|
item.item.nCategory = 0; // 类别为0表示设备
|
||||||
|
item.item.sName = blockData->getName();
|
||||||
|
item.item.uid = blockData->getId();
|
||||||
|
item.item.sVoltageLevel = QString::number(blockData->getVoltage());
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
HierarchyItem HierarchyItemBuilder::buildDeviceWithParent(BlockDataPtr deviceBlock,
|
||||||
|
BlockDataPtr parentBlock,
|
||||||
|
int deviceType) {
|
||||||
|
if (!deviceBlock) return {};
|
||||||
|
|
||||||
|
HierarchyItem item = buildDeviceItem(deviceBlock, deviceType);
|
||||||
|
|
||||||
|
if (parentBlock) {
|
||||||
|
item.parent.nEquipType = 0;
|
||||||
|
item.parent.nCategory = 1;
|
||||||
|
item.parent.sName = parentBlock->getName();
|
||||||
|
item.parent.uid = parentBlock->getId();
|
||||||
|
item.parent.sVoltageLevel = QString::number(parentBlock->getVoltage());
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
HierarchyItem HierarchyItemBuilder::buildAutoFromBlock(BlockDataPtr blockData) {
|
||||||
|
if (!blockData) return {};
|
||||||
|
|
||||||
|
int blockType = blockData->getType();
|
||||||
|
switch (blockType) {
|
||||||
|
case 1: // 母线
|
||||||
|
return buildDeviceWithParent(blockData, blockData, 1);
|
||||||
|
case 2: // 间隔
|
||||||
|
return buildBayItem(blockData);
|
||||||
|
case 3: // 变压器
|
||||||
|
return buildDeviceWithParent(blockData, blockData, 16);
|
||||||
|
default:
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,158 @@
|
||||||
|
// LayoutBuilder.cpp
|
||||||
|
#include "diagramEditor/layoutBuilder.h"
|
||||||
|
#include "diagramEditor/editItemFactory.h"
|
||||||
|
#include "diagramEditor/hierarchyItemBuilder.h"
|
||||||
|
#include "common/core_model/constants.h"
|
||||||
|
#include "diagramEditor/editPanel.h"
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
LayoutBuilder::LayoutBuilder(EditPanel* panel)
|
||||||
|
: m_panel(panel) {}
|
||||||
|
|
||||||
|
LayoutBuilder::BuildResult LayoutBuilder::buildContainer(const BlockMap& blockMap) {
|
||||||
|
BuildResult result;
|
||||||
|
|
||||||
|
// 1. 创建容器
|
||||||
|
result.container = new EditContainerItem();
|
||||||
|
result.container->setMinimumWidth(Constants::EDITOR_ITEM_WIDTH + 40);
|
||||||
|
result.container->setId(QUuid::createUuid().toString());
|
||||||
|
|
||||||
|
// 2. 连接容器信号
|
||||||
|
connectContainerSignals(result.container);
|
||||||
|
|
||||||
|
// 3. 创建垂直布局
|
||||||
|
auto verticalLayout = createVerticalLayout();
|
||||||
|
result.container->setLayout(verticalLayout);
|
||||||
|
|
||||||
|
// 4. 处理每一层
|
||||||
|
for (int layerIndex = 0; layerIndex < TOTAL_LAYERS; ++layerIndex) {
|
||||||
|
auto blocks = blockMap.value(layerIndex);
|
||||||
|
auto layerLayout = createHorizontalLayout();
|
||||||
|
verticalLayout->addItem(layerLayout);
|
||||||
|
|
||||||
|
if (blocks.isEmpty()) {
|
||||||
|
// 空层添加占位符
|
||||||
|
layerLayout->addItem(createSpacerItem());
|
||||||
|
} else {
|
||||||
|
// 处理有Blocks的层
|
||||||
|
processLayer(blocks, layerLayout, result.bayItems, result.deviceItems);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. 添加拉伸
|
||||||
|
addStretchToVerticalLayout(verticalLayout);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
EditBaseItem* LayoutBuilder::processBlock(BlockDataPtr block,
|
||||||
|
QList<HierarchyItem>& bayItems,
|
||||||
|
QList<HierarchyItem>& deviceItems) {
|
||||||
|
if (!block) return nullptr;
|
||||||
|
|
||||||
|
// 1. 通过工厂创建Item
|
||||||
|
auto factory = EditItemFactory::getFactory(block->getType());
|
||||||
|
if (!factory) {
|
||||||
|
qWarning() << "No factory found for block type:" << block->getType();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto editItem = factory->createItem(block);
|
||||||
|
if (!editItem) {
|
||||||
|
qWarning() << "Failed to create item for block type:" << block->getType();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 设置Item属性
|
||||||
|
editItem->setName(block->getName());
|
||||||
|
// 注意:这里使用原始指针,不涉及所有权转移
|
||||||
|
editItem->setBlockData(block);
|
||||||
|
|
||||||
|
// 3. 连接信号
|
||||||
|
connectSignals(editItem);
|
||||||
|
|
||||||
|
// 4. 构建层级项
|
||||||
|
int blockType = block->getType();
|
||||||
|
switch (blockType) {
|
||||||
|
case 1: // 母线
|
||||||
|
bayItems.append(HierarchyItemBuilder::instance().buildBayItem(block));
|
||||||
|
deviceItems.append(HierarchyItemBuilder::instance().buildDeviceWithParent(block, block, 1));
|
||||||
|
break;
|
||||||
|
case 2: // 间隔
|
||||||
|
bayItems.append(HierarchyItemBuilder::instance().buildBayItem(block));
|
||||||
|
break;
|
||||||
|
case 3: // 变压器
|
||||||
|
// 变压器不创建bayItem,但会创建deviceItem
|
||||||
|
deviceItems.append(HierarchyItemBuilder::instance().buildDeviceWithParent(block, block, 16));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return editItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LayoutBuilder::processLayer(const QList<BlockDataPtr>& blocks,
|
||||||
|
QGraphicsLinearLayout* layerLayout,
|
||||||
|
QList<HierarchyItem>& bayItems,
|
||||||
|
QList<HierarchyItem>& deviceItems) {
|
||||||
|
if (!layerLayout) return;
|
||||||
|
|
||||||
|
for (auto block : blocks) {
|
||||||
|
auto editItem = processBlock(block, bayItems, deviceItems);
|
||||||
|
if (editItem) {
|
||||||
|
layerLayout->addItem(editItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LayoutBuilder::connectSignals(EditBaseItem* item) {
|
||||||
|
if (!m_panel || !item) return;
|
||||||
|
|
||||||
|
QObject::connect(item, &EditBaseItem::itemDbClicked,
|
||||||
|
m_panel, &EditPanel::onItemDbClicked);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LayoutBuilder::connectContainerSignals(EditContainerItem* container) {
|
||||||
|
if (!m_panel || !container) return;
|
||||||
|
|
||||||
|
QObject::connect(container, &EditContainerItem::containerSizeChange,
|
||||||
|
m_panel, &EditPanel::onContainerSizeChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
QGraphicsLinearLayout* LayoutBuilder::createRowLayout() {
|
||||||
|
auto layout = new QGraphicsLinearLayout(Qt::Horizontal);
|
||||||
|
layout->setSpacing(20);
|
||||||
|
layout->setMaximumHeight(300);
|
||||||
|
return layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
QGraphicsLinearLayout* LayoutBuilder::createVerticalLayout() {
|
||||||
|
auto layout = new QGraphicsLinearLayout(Qt::Vertical);
|
||||||
|
layout->setSpacing(10);
|
||||||
|
layout->setMinimumHeight(260);
|
||||||
|
return layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
QGraphicsLinearLayout* LayoutBuilder::createHorizontalLayout() {
|
||||||
|
return new QGraphicsLinearLayout(Qt::Horizontal);
|
||||||
|
}
|
||||||
|
|
||||||
|
EditBaseItem* LayoutBuilder::createSpacerItem() {
|
||||||
|
auto spacer = new EditBaseItem();
|
||||||
|
spacer->setType(EditorItemType::None);
|
||||||
|
spacer->setBoundingRect(QRectF(0, 0,
|
||||||
|
Constants::EDITOR_ITEM_WIDTH, Constants::EDITOR_ITEM_HEIGHT));
|
||||||
|
return spacer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LayoutBuilder::addStretchToVerticalLayout(QGraphicsLinearLayout* layout) {
|
||||||
|
if (!layout) return;
|
||||||
|
|
||||||
|
int count = layout->count();
|
||||||
|
if (count == 4) {
|
||||||
|
layout->insertStretch(3);
|
||||||
|
layout->insertStretch(1);
|
||||||
|
} else if (count == 2) {
|
||||||
|
layout->insertStretch(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,265 @@
|
||||||
|
// LayoutCalculator.cpp
|
||||||
|
#include "diagramEditor/layoutCalculator.h"
|
||||||
|
#include "diagramEditor/diagramEditorWizard.h"
|
||||||
|
#include "diagramEditor/diagramEditorStructContainer.h"
|
||||||
|
#include "diagramEditor/diagramEditorBaseBlock.h"
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
FixedLayoutCalculator::FixedLayoutCalculator(DiagramEditorWizard* wizard)
|
||||||
|
: m_wizard(wizard) {}
|
||||||
|
|
||||||
|
QMap<DiagramEditorBaseBlock*, QPointF> FixedLayoutCalculator::calculateLayout() {
|
||||||
|
m_blockPositions.clear();
|
||||||
|
|
||||||
|
if (!m_wizard) {
|
||||||
|
qWarning() << "FixedLayoutCalculator: Wizard为空";
|
||||||
|
return m_blockPositions;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto mapTotal = m_wizard->getContainerStruct();
|
||||||
|
double deltaY = 0;
|
||||||
|
double lastMaxDownH = 0;
|
||||||
|
|
||||||
|
// 按层级顺序处理
|
||||||
|
for (auto iter = mapTotal.begin(); iter != mapTotal.end(); ++iter) {
|
||||||
|
int level = iter.key();
|
||||||
|
|
||||||
|
if (level == Constants::TRANSFORMER_LEVEL) {
|
||||||
|
continue; // 变压器特殊处理
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建层级布局
|
||||||
|
LevelLayout levelLayout;
|
||||||
|
levelLayout.level = level;
|
||||||
|
levelLayout.containers = iter.value();
|
||||||
|
|
||||||
|
if (levelLayout.containers.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 第一阶段:计算尺寸
|
||||||
|
calculateContainerSizes(levelLayout);
|
||||||
|
|
||||||
|
// 第二阶段:计算位置
|
||||||
|
calculatePositions(levelLayout, deltaY, lastMaxDownH);
|
||||||
|
|
||||||
|
// 处理变压器(在层级0之后)
|
||||||
|
if (level == 0 && mapTotal.contains(Constants::TRANSFORMER_LEVEL)) {
|
||||||
|
auto transformers = mapTotal.value(Constants::TRANSFORMER_LEVEL);
|
||||||
|
if (!transformers.isEmpty()) {
|
||||||
|
calculateTransformerPositions(transformers, deltaY, lastMaxDownH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_blockPositions;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FixedLayoutCalculator::calculateContainerSizes(LevelLayout& levelLayout) {
|
||||||
|
levelLayout.maxUpHeight = 0;
|
||||||
|
levelLayout.maxDownHeight = 0;
|
||||||
|
|
||||||
|
for (auto container : levelLayout.containers) {
|
||||||
|
if (!container) continue;
|
||||||
|
|
||||||
|
auto mapBlocks = container->getBlockMap();
|
||||||
|
|
||||||
|
// 计算上间隔尺寸
|
||||||
|
auto topBays = mapBlocks.value(0);
|
||||||
|
double maxUp = 0;
|
||||||
|
double widthUp = 0;
|
||||||
|
|
||||||
|
for (auto block : topBays) {
|
||||||
|
if (!block) continue;
|
||||||
|
QRectF rec = block->getRecSize();
|
||||||
|
maxUp = qMax(maxUp, rec.height());
|
||||||
|
widthUp += 100 + rec.width();
|
||||||
|
}
|
||||||
|
maxUp += Constants::EDITOR_ITEM_HEIGHT;
|
||||||
|
levelLayout.maxUpHeight = qMax(levelLayout.maxUpHeight, maxUp);
|
||||||
|
|
||||||
|
// 计算下间隔尺寸
|
||||||
|
auto bottomBays = mapBlocks.value(3);
|
||||||
|
double maxDown = 0;
|
||||||
|
double widthDown = 0;
|
||||||
|
|
||||||
|
for (auto block : bottomBays) {
|
||||||
|
if (!block) continue;
|
||||||
|
QRectF rec = block->getRecSize();
|
||||||
|
maxDown = qMax(maxDown, rec.height());
|
||||||
|
widthDown += 100 + rec.width();
|
||||||
|
}
|
||||||
|
maxDown += Constants::EDITOR_ITEM_HEIGHT;
|
||||||
|
levelLayout.maxDownHeight = qMax(levelLayout.maxDownHeight, maxDown);
|
||||||
|
|
||||||
|
// 计算母线宽度
|
||||||
|
double busWidth = 0;
|
||||||
|
auto bus1 = mapBlocks.value(1);
|
||||||
|
auto bus2 = mapBlocks.value(2);
|
||||||
|
|
||||||
|
if (!bus1.isEmpty()) {
|
||||||
|
busWidth = qMax(busWidth, bus1.first()->getRecSize().width());
|
||||||
|
}
|
||||||
|
if (!bus2.isEmpty()) {
|
||||||
|
busWidth = qMax(busWidth, bus2.first()->getRecSize().width());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算容器宽度
|
||||||
|
double containerWidth = qMax(widthUp, widthDown);
|
||||||
|
if (containerWidth < busWidth) {
|
||||||
|
containerWidth = busWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置容器尺寸
|
||||||
|
container->setWidth(containerWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理空的情况
|
||||||
|
if (levelLayout.maxUpHeight == 0) {
|
||||||
|
levelLayout.maxUpHeight = Constants::EDITOR_ITEM_HEIGHT;
|
||||||
|
}
|
||||||
|
if (levelLayout.maxDownHeight == 0) {
|
||||||
|
levelLayout.maxDownHeight = Constants::EDITOR_ITEM_HEIGHT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FixedLayoutCalculator::calculatePositions(LevelLayout& levelLayout,
|
||||||
|
double& deltaY, double& lastMaxDownH) {
|
||||||
|
double startX = CONTAINER_START_X;
|
||||||
|
bool isFirstContainer = true;
|
||||||
|
|
||||||
|
for (auto container : levelLayout.containers) {
|
||||||
|
if (!container) continue;
|
||||||
|
|
||||||
|
// 设置容器高度
|
||||||
|
container->setMaxUpH(levelLayout.maxUpHeight);
|
||||||
|
container->setMaxDownH(levelLayout.maxDownHeight);
|
||||||
|
|
||||||
|
// 计算垂直位置(每行第一个容器计算一次)
|
||||||
|
if (isFirstContainer) {
|
||||||
|
if (levelLayout.level == 0) { // 首行
|
||||||
|
deltaY = container->getMaxUpH();
|
||||||
|
} else { // 其他行
|
||||||
|
deltaY = deltaY + BUS_V_SPACING + lastMaxDownH + container->getMaxUpH();
|
||||||
|
}
|
||||||
|
lastMaxDownH = container->getMaxDownH();
|
||||||
|
isFirstContainer = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置容器的关键Y坐标
|
||||||
|
container->setMidUpY(deltaY);
|
||||||
|
container->setMidDownY(deltaY + BUS_V_SPACING);
|
||||||
|
container->setStartX(startX);
|
||||||
|
|
||||||
|
// 计算容器内设备位置
|
||||||
|
calculateBlockPositionsInContainer(container, startX, deltaY, deltaY + BUS_V_SPACING);
|
||||||
|
|
||||||
|
// 更新水平位置
|
||||||
|
startX += container->getWidth() + CONTAINER_H_SPACING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FixedLayoutCalculator::calculateBlockPositionsInContainer(DiagramEditorStructContainer* container,
|
||||||
|
double startX,
|
||||||
|
double midUpY,
|
||||||
|
double midDownY) {
|
||||||
|
if (!container) return;
|
||||||
|
|
||||||
|
auto mapBlocks = container->getBlockMap();
|
||||||
|
double currentX = startX;
|
||||||
|
|
||||||
|
for (auto it = mapBlocks.begin(); it != mapBlocks.end(); ++it) {
|
||||||
|
int layer = it.key();
|
||||||
|
auto blocks = it.value();
|
||||||
|
|
||||||
|
for (auto block : blocks) {
|
||||||
|
if (!block) continue;
|
||||||
|
|
||||||
|
QRectF rec = block->getRecSize();
|
||||||
|
QPointF center;
|
||||||
|
|
||||||
|
int blockType = block->getType();
|
||||||
|
|
||||||
|
if (blockType == 1) { // 母线
|
||||||
|
if (layer == 1) { // 母线1
|
||||||
|
center = QPointF(startX, midUpY + rec.height() * 0.5);
|
||||||
|
} else if (layer == 2) { // 母线2
|
||||||
|
center = QPointF(startX, midDownY - rec.height() * 0.5);
|
||||||
|
}
|
||||||
|
} else if (blockType == 2) { // 间隔
|
||||||
|
if (layer == 0) { // 上间隔
|
||||||
|
center = QPointF(currentX + rec.width() * 0.5,
|
||||||
|
midUpY - rec.height() * 0.5 - Constants::EDITOR_ITEM_HEIGHT * 0.5);
|
||||||
|
} else if (layer == 3) { // 下间隔
|
||||||
|
center = QPointF(currentX + rec.width() * 0.5,
|
||||||
|
midDownY + rec.height() * 0.5 + Constants::EDITOR_ITEM_HEIGHT * 0.5);
|
||||||
|
}
|
||||||
|
currentX += rec.width();
|
||||||
|
}
|
||||||
|
// 变压器不在这里处理
|
||||||
|
|
||||||
|
if (!center.isNull()) {
|
||||||
|
m_blockPositions[block] = center;
|
||||||
|
block->setSeceneDelta(center);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FixedLayoutCalculator::calculateTransformerPositions(const QList<DiagramEditorStructContainer*>& transformers,
|
||||||
|
double& deltaY, double& lastMaxDownH) {
|
||||||
|
if (transformers.isEmpty()) return;
|
||||||
|
|
||||||
|
// 计算变压器尺寸
|
||||||
|
for (auto container : transformers) {
|
||||||
|
if (!container) continue;
|
||||||
|
|
||||||
|
auto mapBlocks = container->getBlockMap();
|
||||||
|
auto transBlocks = mapBlocks.value(1); // 变压器在layer 1
|
||||||
|
|
||||||
|
for (auto block : transBlocks) {
|
||||||
|
if (!block) continue;
|
||||||
|
QRectF rec = block->getRecSize();
|
||||||
|
container->setWidth(rec.width());
|
||||||
|
container->setHeight(rec.height());
|
||||||
|
break; // 只取第一个变压器
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算变压器位置
|
||||||
|
double startX = TRANSFORMER_START_X;
|
||||||
|
bool isFirstTransformer = true;
|
||||||
|
|
||||||
|
for (auto container : transformers) {
|
||||||
|
if (!container) continue;
|
||||||
|
|
||||||
|
// 计算垂直位置
|
||||||
|
if (isFirstTransformer) {
|
||||||
|
deltaY = deltaY + BUS_V_SPACING + lastMaxDownH + container->getHeight();
|
||||||
|
isFirstTransformer = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
double centerY = deltaY - container->getHeight() * 0.5;
|
||||||
|
container->setStartY(centerY);
|
||||||
|
container->setStartX(startX);
|
||||||
|
|
||||||
|
// 计算变压器内部设备位置
|
||||||
|
auto mapBlocks = container->getBlockMap();
|
||||||
|
for (auto it = mapBlocks.begin(); it != mapBlocks.end(); ++it) {
|
||||||
|
for (auto block : it.value()) {
|
||||||
|
if (!block) continue;
|
||||||
|
|
||||||
|
QRectF rec = block->getRecSize();
|
||||||
|
QPointF center(startX + rec.width() * 0.5,
|
||||||
|
centerY + rec.height() * 0.5);
|
||||||
|
|
||||||
|
m_blockPositions[block] = center;
|
||||||
|
block->setSeceneDelta(center);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新水平位置
|
||||||
|
startX += container->getWidth() + TRANSFORMER_SPACING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
// BusItemFactory.cpp
|
||||||
|
#include "diagramEditor/transItemFactory.h"
|
||||||
|
#include "common/core_model/constants.h"
|
||||||
|
|
||||||
|
EditBaseItem* TransItemFactory::createItem(BlockDataPtr blockData) {
|
||||||
|
auto pTrans = new EditTransItem();
|
||||||
|
setupItem(pTrans, blockData);
|
||||||
|
return pTrans;
|
||||||
|
}
|
||||||
|
|
||||||
|
QGraphicsLinearLayout* TransItemFactory::createLayerLayout() {
|
||||||
|
return new QGraphicsLinearLayout(Qt::Horizontal);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransItemFactory::setupItem(EditBaseItem* item, BlockDataPtr blockData) {
|
||||||
|
item->setType(EditorItemType::trans);
|
||||||
|
item->setBoundingRect(QRectF(0, 0,
|
||||||
|
Constants::EDITOR_ITEM_WIDTH, Constants::EDITOR_ITEM_WIDTH));
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
// TransformerBuilder.cpp
|
||||||
|
#include "diagramEditor/transformerBuilder.h"
|
||||||
|
#include "diagramEditor/hierarchyItemBuilder.h"
|
||||||
|
|
||||||
|
TransformerBuilder::TransformerBuilder(EditPanel* panel)
|
||||||
|
: LayoutBuilder(panel) {}
|
||||||
|
|
||||||
|
LayoutBuilder::BuildResult TransformerBuilder::buildContainer(const BlockMap& blockMap) {
|
||||||
|
BuildResult result = LayoutBuilder::buildContainer(blockMap);
|
||||||
|
|
||||||
|
// 为变压器创建额外的层级项
|
||||||
|
for (int layerIndex = 0; layerIndex < TOTAL_LAYERS; ++layerIndex) {
|
||||||
|
auto blocks = blockMap.value(layerIndex);
|
||||||
|
for (auto &block : blocks) {
|
||||||
|
if (block && block->getType() == TRANSFORMER_TYPE) {
|
||||||
|
processTransformerBlock(block, result.bayItems, result.deviceItems);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
QGraphicsLinearLayout* TransformerBuilder::createTransformerRowLayout() {
|
||||||
|
auto layout = createRowLayout();
|
||||||
|
layout->insertStretch(0);
|
||||||
|
layout->addStretch();
|
||||||
|
return layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
HierarchyItem TransformerBuilder::buildTransformerHierarchyItem(BlockDataPtr blockData) {
|
||||||
|
if (!blockData) return {};
|
||||||
|
|
||||||
|
return HierarchyItemBuilder::instance()
|
||||||
|
.buildDeviceWithParent(blockData, blockData, TRANSFORMER_DEVICE_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformerBuilder::processTransformerBlock(BlockDataPtr block,
|
||||||
|
QList<HierarchyItem>& bayItems,
|
||||||
|
QList<HierarchyItem>& deviceItems) {
|
||||||
|
if (!block) return;
|
||||||
|
|
||||||
|
// 变压器需要bayItem吗?根据原始代码,变压器会创建bayItem
|
||||||
|
auto bayItem = HierarchyItemBuilder::instance().buildBayItem(block);
|
||||||
|
bayItems.append(bayItem);
|
||||||
|
|
||||||
|
// 创建变压器的deviceItem
|
||||||
|
auto deviceItem = buildTransformerHierarchyItem(block);
|
||||||
|
deviceItems.append(deviceItem);
|
||||||
|
}
|
||||||
|
|
@ -42,34 +42,8 @@ void BaseModel::createTopoTerminalsByItem(GraphicsBaseItem* pItem,ModelFunctionT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QPointF BaseModel::calculateBusPortPos(GraphicsBaseItem* pBus,GraphicsBaseItem* item)
|
QPointF BaseModel::calculateBusPortPos(GraphicsBaseItem* pBus,GraphicsBaseItem* item,QPointF para)
|
||||||
{
|
{
|
||||||
//return QPointF(item->pos().x(),pBus->pos().y());
|
|
||||||
/*QRectF recBus = pBus->sceneBoundingRect();
|
|
||||||
QLineF busLine = QLineF(recBus.left(),recBus.y(),recBus.right(),recBus.y());
|
|
||||||
|
|
||||||
QPointF p1 = busLine.p1();
|
|
||||||
QPointF p2 = busLine.p2();
|
|
||||||
|
|
||||||
// 计算item的中心点在垂直于线段方向上的投影
|
|
||||||
QPointF itemCenter = item->pos();// + QPointF(item->boundingRect().width()/2, item->boundingRect().height()/2);
|
|
||||||
|
|
||||||
// 计算投影点在线段上的位置
|
|
||||||
QPointF projection;
|
|
||||||
if (busLine.length() == 0) { // 如果线段长度为0,直接返回端点
|
|
||||||
projection = p1;
|
|
||||||
} else {
|
|
||||||
// 计算投影点
|
|
||||||
QPointF vec = p2 - p1;
|
|
||||||
QPointF relPos = itemCenter - p1;
|
|
||||||
qreal dot = QPointF::dotProduct(relPos, vec) / (busLine.length() * busLine.length());
|
|
||||||
|
|
||||||
// 限制投影点在线段范围内
|
|
||||||
dot = qBound(0.0, dot, 1.0);
|
|
||||||
projection = p1 + dot * vec;
|
|
||||||
}
|
|
||||||
|
|
||||||
return projection;*/
|
|
||||||
QRectF recBus = pBus->sceneBoundingRect();
|
QRectF recBus = pBus->sceneBoundingRect();
|
||||||
QRectF recItem = item->sceneBoundingRect();
|
QRectF recItem = item->sceneBoundingRect();
|
||||||
|
|
||||||
|
|
@ -81,16 +55,23 @@ QPointF BaseModel::calculateBusPortPos(GraphicsBaseItem* pBus,GraphicsBaseItem*
|
||||||
QPointF p1 = busLine.p1();
|
QPointF p1 = busLine.p1();
|
||||||
QPointF p2 = busLine.p2();
|
QPointF p2 = busLine.p2();
|
||||||
|
|
||||||
// 计算item的中心点
|
|
||||||
QPointF itemCenter = recItem.center();
|
|
||||||
|
|
||||||
// 计算投影点在线段上的位置
|
// 计算投影点在线段上的位置
|
||||||
QPointF projection;
|
QPointF projection;
|
||||||
if (busLine.length() == 0) {
|
if (busLine.length() == 0) {
|
||||||
projection = p1;
|
projection = p1;
|
||||||
} else {
|
} else {
|
||||||
QPointF vec = p2 - p1;
|
QPointF vec = p2 - p1;
|
||||||
QPointF relPos = itemCenter - p1;
|
|
||||||
|
// 如果para不是(0,0),则使用para点计算投影
|
||||||
|
// 否则使用item的中心点计算投影
|
||||||
|
QPointF pointToProject;
|
||||||
|
if (para != QPointF(0, 0)) {
|
||||||
|
pointToProject = para;
|
||||||
|
} else {
|
||||||
|
pointToProject = recItem.center();
|
||||||
|
}
|
||||||
|
|
||||||
|
QPointF relPos = pointToProject - p1;
|
||||||
qreal dot = QPointF::dotProduct(relPos, vec) / (busLine.length() * busLine.length());
|
qreal dot = QPointF::dotProduct(relPos, vec) / (busLine.length() * busLine.length());
|
||||||
dot = qBound(0.0, dot, 1.0);
|
dot = qBound(0.0, dot, 1.0);
|
||||||
projection = p1 + dot * vec;
|
projection = p1 + dot * vec;
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
#include <QMetaMethod>
|
#include <QMetaMethod>
|
||||||
#include "common/core_model/constants.h"
|
#include "common/core_model/constants.h"
|
||||||
#include "include/instance/baseTypeManager.h"
|
#include "include/instance/baseTypeManager.h"
|
||||||
|
#include "diagramEditor/layoutCalculator.h"
|
||||||
|
|
||||||
int g_nCompoWidth = 50; //元件默认宽度(计算布局使用)
|
int g_nCompoWidth = 50; //元件默认宽度(计算布局使用)
|
||||||
int g_nCompoHeight = 50;
|
int g_nCompoHeight = 50;
|
||||||
|
|
@ -796,7 +797,7 @@ void DiagramEditorModel::generatePreview(bool bVisible)
|
||||||
|
|
||||||
void DiagramEditorModel::calculateBlockPos()
|
void DiagramEditorModel::calculateBlockPos()
|
||||||
{
|
{
|
||||||
if(_pWizard){
|
/*if(_pWizard){
|
||||||
double deltaY = 0; //竖直方向每行增量
|
double deltaY = 0; //竖直方向每行增量
|
||||||
double lastMaxDownH = 0; //上一行的下部最大高度
|
double lastMaxDownH = 0; //上一行的下部最大高度
|
||||||
auto mapTotal = _pWizard->getContainerStruct();
|
auto mapTotal = _pWizard->getContainerStruct();
|
||||||
|
|
@ -899,10 +900,10 @@ void DiagramEditorModel::calculateBlockPos()
|
||||||
QPointF center;
|
QPointF center;
|
||||||
if(pBlock->getType() == 1){ //母线
|
if(pBlock->getType() == 1){ //母线
|
||||||
if(it.key() == 1){ //1母
|
if(it.key() == 1){ //1母
|
||||||
center = QPointF(pStartX/*+recBlock.width()*0.5*/,dMiddleUpY+recBlock.height()*0.5);
|
center = QPointF(pStartX,dMiddleUpY+recBlock.height()*0.5);
|
||||||
}
|
}
|
||||||
else if(it.key() == 2){ //2母
|
else if(it.key() == 2){ //2母
|
||||||
center = QPointF(pStartX/*+recBlock.width()*0.5*/,dMiddleDownY-recBlock.height()*0.5);
|
center = QPointF(pStartX,dMiddleDownY-recBlock.height()*0.5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(pBlock->getType() == 2){ //间隔
|
else if(pBlock->getType() == 2){ //间隔
|
||||||
|
|
@ -963,7 +964,22 @@ void DiagramEditorModel::calculateBlockPos()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}*/
|
||||||
|
if (!_pWizard) {
|
||||||
|
qWarning() << "calculateBlockPos: Wizard为空";
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 使用修正后的布局计算器
|
||||||
|
FixedLayoutCalculator calculator(_pWizard);
|
||||||
|
|
||||||
|
// 计算布局
|
||||||
|
auto blockPositions = calculator.calculateLayout();
|
||||||
|
|
||||||
|
// 可以记录布局结果
|
||||||
|
//m_blockPositions = blockPositions;
|
||||||
|
|
||||||
|
qDebug() << "布局计算完成,处理了" << blockPositions.size() << "个设备";
|
||||||
}
|
}
|
||||||
|
|
||||||
void DiagramEditorModel::setItemInBlockPos()
|
void DiagramEditorModel::setItemInBlockPos()
|
||||||
|
|
@ -1058,11 +1074,13 @@ void DiagramEditorModel::refreshConnection()
|
||||||
auto pFromData = pFromItem->getProperty();
|
auto pFromData = pFromItem->getProperty();
|
||||||
auto pToData = pToItem->getProperty();
|
auto pToData = pToItem->getProperty();
|
||||||
if(pFromData->type() == 1){ //from是母线
|
if(pFromData->type() == 1){ //from是母线
|
||||||
QPointF p = calculateBusPortPos(pFromItem,pToItem);
|
auto pToPort = pToItem->getPortById(toTerId);
|
||||||
|
QPointF p = calculateBusPortPos(pFromItem,pToItem,pToPort->scenePos());
|
||||||
pFromItem->movePort(fromTerId,pFromItem->mapFromScene(p));
|
pFromItem->movePort(fromTerId,pFromItem->mapFromScene(p));
|
||||||
}
|
}
|
||||||
else if(pToData->type() == 1){ //to是母线
|
else if(pToData->type() == 1){ //to是母线
|
||||||
QPointF p = calculateBusPortPos(pToItem,pFromItem);
|
auto pFromPort = pFromItem->getPortById(fromTerId);
|
||||||
|
QPointF p = calculateBusPortPos(pToItem,pFromItem,pFromPort->scenePos());
|
||||||
pToItem->movePort(toTerId,pToItem->mapFromScene(p));
|
pToItem->movePort(toTerId,pToItem->mapFromScene(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1092,6 +1110,20 @@ void DiagramEditorModel::refreshConnection()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DiagramEditorModel::applyLayoutResult(const LayoutResult& result) {
|
||||||
|
// 应用所有设备位置
|
||||||
|
for (auto it = result.allBlockPositions.begin(); it != result.allBlockPositions.end(); ++it) {
|
||||||
|
DiagramEditorBaseBlock* block = it.key();
|
||||||
|
QPointF position = it.value();
|
||||||
|
|
||||||
|
if (block) {
|
||||||
|
block->setSeceneDelta(position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "布局计算完成,共处理" << result.allBlockPositions.size() << "个设备";
|
||||||
|
}
|
||||||
|
|
||||||
QStandardItem* DiagramEditorModel::getNameItem(const QString& sName,int nFrom)
|
QStandardItem* DiagramEditorModel::getNameItem(const QString& sName,int nFrom)
|
||||||
{
|
{
|
||||||
QStandardItemModel* pModel = nullptr;
|
QStandardItemModel* pModel = nullptr;
|
||||||
|
|
|
||||||
|
|
@ -647,6 +647,34 @@ QString FixedPortsModel::addNodeItem(QUuid id,QPointF pos,double width,double he
|
||||||
|
|
||||||
addPortsToItem_json(P_const,portArr,item);
|
addPortsToItem_json(P_const,portArr,item);
|
||||||
}
|
}
|
||||||
|
else if(type == GIT_CustomType)
|
||||||
|
{
|
||||||
|
PropertyModel model = ProjectModelManager::instance().getData()[sMeta][sProModel];
|
||||||
|
QByteArray svg;
|
||||||
|
if(model.modelSetting.mapSvg.isEmpty()){
|
||||||
|
svg = DataBase::GetInstance()->ModelType()[18].icon;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
svg = ProjectModelManager::instance().getData()[sMeta][sProModel].modelSetting.mapUsedSvg["customType"];
|
||||||
|
}
|
||||||
|
|
||||||
|
if(width == 0 && height == 0){
|
||||||
|
dX = 40;
|
||||||
|
dY = 40;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
dX = width;
|
||||||
|
dY = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto pCustom = new ElectricSvgItem(QRect(-dX*0.5, -dY*0.5, dX, dY));
|
||||||
|
pCustom->setItemType(GIT_CustomType);
|
||||||
|
pCustom->loadSvg(svg);
|
||||||
|
item = pCustom;
|
||||||
|
QJsonArray portArr = pro->context()["port"].toArray();
|
||||||
|
|
||||||
|
addPortsToItem_json(P_const,portArr,item);
|
||||||
|
}
|
||||||
if(item)
|
if(item)
|
||||||
{
|
{
|
||||||
item->setItemId(id);
|
item->setItemId(id);
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ class CreateEditor;
|
||||||
class MonitorItemsDlg;
|
class MonitorItemsDlg;
|
||||||
class MonitorPagesDlg;
|
class MonitorPagesDlg;
|
||||||
class QDetailsView;
|
class QDetailsView;
|
||||||
|
class BaseDockWidget;
|
||||||
|
|
||||||
class CMainWindow : public QMainWindow
|
class CMainWindow : public QMainWindow
|
||||||
{
|
{
|
||||||
|
|
@ -87,6 +88,7 @@ private:
|
||||||
MonitorPagesDlg* m_pMonitorPagesDlg;
|
MonitorPagesDlg* m_pMonitorPagesDlg;
|
||||||
QDockWidget* m_pMonitorItemsDock;
|
QDockWidget* m_pMonitorItemsDock;
|
||||||
QDockWidget* m_pMonitorPagesDock;
|
QDockWidget* m_pMonitorPagesDock;
|
||||||
|
BaseDockWidget* m_pPropertyEditorDock;
|
||||||
QDetailsView* m_pPropertiesEditorView;
|
QDetailsView* m_pPropertiesEditorView;
|
||||||
QAction* _pActMonitor;
|
QAction* _pActMonitor;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@ CMainWindow::CMainWindow(QWidget *parent)
|
||||||
m_pMonitorItemsDock = nullptr;
|
m_pMonitorItemsDock = nullptr;
|
||||||
m_pMonitorPagesDock = nullptr;
|
m_pMonitorPagesDock = nullptr;
|
||||||
m_pPropertiesEditorView = nullptr;
|
m_pPropertiesEditorView = nullptr;
|
||||||
|
m_pPropertyEditorDock = nullptr;
|
||||||
_pActMonitor = nullptr;
|
_pActMonitor = nullptr;
|
||||||
|
|
||||||
qRegisterMetaType<PropertyStateInfo>("PropertyStateInfo");
|
qRegisterMetaType<PropertyStateInfo>("PropertyStateInfo");
|
||||||
|
|
@ -137,12 +138,13 @@ void CMainWindow::initializeDockUi()
|
||||||
connect(&ProjectModelManager::instance(),&ProjectModelManager::modelChange,m_pElectricElementsBox,&ElectricElementsBox::onSignal_modelChanged);
|
connect(&ProjectModelManager::instance(),&ProjectModelManager::modelChange,m_pElectricElementsBox,&ElectricElementsBox::onSignal_modelChanged);
|
||||||
|
|
||||||
m_pPropertiesEditorView = new QDetailsView();
|
m_pPropertiesEditorView = new QDetailsView();
|
||||||
BaseDockWidget* PropertyEditorDock = new BaseDockWidget(QString::fromWCharArray(L"属性面板"),this);
|
m_pPropertyEditorDock = new BaseDockWidget(QString::fromWCharArray(L"属性面板"),this);
|
||||||
PropertyEditorDock->setWidget(m_pPropertiesEditorView);
|
m_pPropertyEditorDock->setWidget(m_pPropertiesEditorView);
|
||||||
PropertyEditorDock->setMinimumSize(350,150);
|
m_pPropertyEditorDock->setMinimumSize(350,150);
|
||||||
m_pPropertiesEditorView->setObject(m_pDiagramCavas);
|
m_pPropertiesEditorView->setObject(new QObject(this));
|
||||||
PropertyEditorDock->setAllowedAreas(Qt::LeftDockWidgetArea|Qt::RightDockWidgetArea);
|
m_pPropertyEditorDock->setAllowedAreas(Qt::LeftDockWidgetArea|Qt::RightDockWidgetArea);
|
||||||
this->addDockWidget(Qt::RightDockWidgetArea,PropertyEditorDock);
|
this->addDockWidget(Qt::RightDockWidgetArea,m_pPropertyEditorDock);
|
||||||
|
m_pPropertyEditorDock->hide();
|
||||||
connect(m_pDiagramCavas,&DiagramCavas::selectTarget,this,&CMainWindow::onCavasItemSelected);
|
connect(m_pDiagramCavas,&DiagramCavas::selectTarget,this,&CMainWindow::onCavasItemSelected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -359,6 +361,7 @@ void CMainWindow::onAction_unloadEditor(const QString& str)
|
||||||
|
|
||||||
void CMainWindow::onCavasItemSelected(QObject* obj)
|
void CMainWindow::onCavasItemSelected(QObject* obj)
|
||||||
{
|
{
|
||||||
|
m_pPropertyEditorDock->show();
|
||||||
if(m_pPropertiesEditorView)
|
if(m_pPropertiesEditorView)
|
||||||
m_pPropertiesEditorView->setObject(obj);
|
m_pPropertiesEditorView->setObject(obj);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue