Merge branch 'new_osg' of http://brigecode.icu:16623/PM/DYTSrouce into new_osg
This commit is contained in:
commit
387792620a
2
.gitignore
vendored
2
.gitignore
vendored
@ -2,3 +2,5 @@
|
||||
build/
|
||||
bin/
|
||||
thirdparty/
|
||||
tritoin/
|
||||
QWEN.md
|
||||
|
||||
BIN
doc/dyttu.docx
Normal file
BIN
doc/dyttu.docx
Normal file
Binary file not shown.
26
doc/交互设计.md
Normal file
26
doc/交互设计.md
Normal file
@ -0,0 +1,26 @@
|
||||
# 交互设计
|
||||
## 拖拽式添加实体
|
||||
## 图表数据格式
|
||||
### WAVE图表
|
||||
按照一个文件多个曲线来,一行一个曲线
|
||||
|
||||
|
||||
曲线、曲面每一个类型一个tab页面 最大可以显示9宫格
|
||||
|
||||
表格、灯 灯在上方,表格在下方(待定)
|
||||
|
||||
## 菜单
|
||||
### 文件
|
||||
* 新建wordspace
|
||||
* 打开wordspace
|
||||
* 保存wordspace
|
||||
----
|
||||
* 新建曲线
|
||||
* 新建曲面
|
||||
* 新建表格
|
||||
* 新建灯
|
||||
|
||||
### 仿真管理
|
||||
* 命令运行(手动编辑xml: <commond "delfeile" exe="cmd.exe" path="d:/1.bat"/>)
|
||||
* 参数编辑:弹出编辑框
|
||||
|
||||
BIN
doc/流程图.vsdx
Normal file
BIN
doc/流程图.vsdx
Normal file
Binary file not shown.
15
doc/预设实体清单.txt
Normal file
15
doc/预设实体清单.txt
Normal file
@ -0,0 +1,15 @@
|
||||
船:
|
||||
驱逐机(阿利伯克)、航母(尼米兹)
|
||||
|
||||
卫星:
|
||||
高轨(静止)
|
||||
|
||||
弹:
|
||||
高超音速弹(DF21)
|
||||
|
||||
无源干扰:
|
||||
角反、箔条
|
||||
|
||||
有源干扰:
|
||||
弦内、弦外
|
||||
|
||||
@ -14,8 +14,8 @@ find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Widgets LinguistTools DataVis
|
||||
|
||||
message("qt VERSION " ${QT_VERSION_MAJOR})
|
||||
|
||||
FILE(GLOB_RECURSE HEADER_FILES ./*.h common/*.h common/*.hpp model/*.h app/*.h)
|
||||
FILE(GLOB_RECURSE CPP_FILES ./*.cpp common/*.cpp model/*.cpp app/*.cpp)
|
||||
FILE(GLOB_RECURSE HEADER_FILES ./*.h common/*.h common/*.hpp model/*.h app/*.h utils/*.h)
|
||||
FILE(GLOB_RECURSE CPP_FILES ./*.cpp common/*.cpp model/*.cpp app/*.cpp utils/*.cpp)
|
||||
FILE(GLOB_RECURSE CC_FILES ./*.cc)
|
||||
FILE(GLOB_RECURSE UI_FILES ./*.ui)
|
||||
FILE(GLOB_RECURSE QRC_FILES ./*.qrc)
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>res/sys_close.png</file>
|
||||
<file>res/sys_float.png</file>
|
||||
<file>res/sys_max.png</file>
|
||||
<file>res/sys_min.png</file>
|
||||
<file>res/sys_restore.png</file>
|
||||
@ -11,7 +12,10 @@
|
||||
<file>res/default/menu_new_file.png</file>
|
||||
<file>res/default/menu_open_file.png</file>
|
||||
<file>res/default/menu_save_file.png</file>
|
||||
<file>res/default/menu_save_as_file.png</file>
|
||||
<file>res/default/menu_wave_file.png</file>
|
||||
<file>res/default/menu_light_file.png</file>
|
||||
<file>res/default/menu_table_file.png</file>
|
||||
<file>res/default/menu_surface_file.png</file>
|
||||
<file>res/default/menu_save_shape_file.png</file>
|
||||
<file>res/default/menu_save_store_file.png</file>
|
||||
<file>res/default/menu_report_mesh.png</file>
|
||||
|
||||
@ -72,6 +72,17 @@ QPushButton#sys_close {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
QPushButton#sys_float {
|
||||
max-width:48px;
|
||||
min-width:48px;
|
||||
max-height:28px;
|
||||
min-height:28px;
|
||||
border: none;
|
||||
background: transparent;
|
||||
image: url(:/res/sys_float.png);
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
QPushButton#sys_min {
|
||||
max-width:48px;
|
||||
min-width:48px;
|
||||
@ -219,6 +230,18 @@ QWidget#FileManagerMenu > QToolButton#menu_save_shape_file {
|
||||
QWidget#FileManagerMenu > QToolButton#menu_save_shape_file {
|
||||
qproperty-icon: url(:/res/default/menu_report_mesh.png);
|
||||
}
|
||||
QWidget#FileManagerMenu > QToolButton#menu_wave_file {
|
||||
qproperty-icon: url(:/res/default/menu_wave_file.png);
|
||||
}
|
||||
QWidget#FileManagerMenu > QToolButton#menu_surface_file {
|
||||
qproperty-icon: url(:/res/default/menu_surface_file.png);
|
||||
}
|
||||
QWidget#FileManagerMenu > QToolButton#menu_table_file {
|
||||
qproperty-icon: url(:/res/default/menu_table_file.png);
|
||||
}
|
||||
QWidget#FileManagerMenu > QToolButton#menu_light_file {
|
||||
qproperty-icon: url(:/res/default/menu_light_file.png);
|
||||
}
|
||||
|
||||
QWidget#SystemManagerMenu > QToolButton#menu_exit {
|
||||
qproperty-icon: url(:/res/default/menu_exit.png);
|
||||
@ -322,6 +345,7 @@ QMenu {
|
||||
background: #212F3C;
|
||||
color: #e0e0e0;
|
||||
padding: 4px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
QMenu::item {
|
||||
padding: 6px 30px 6px 20px;
|
||||
@ -340,4 +364,4 @@ QMenu::separator {
|
||||
height: 1px;
|
||||
background: #555;
|
||||
margin: 5px 10px;
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,8 @@
|
||||
#include "entities/Entity.h"
|
||||
|
||||
#include <QUuid>
|
||||
// Ensure QVariant can hold and convert Entity* in signals/slots
|
||||
Q_DECLARE_METATYPE(Entity*)
|
||||
|
||||
#include "common/SpdLogger.h"
|
||||
#include "entities/SceneComponent.h"
|
||||
|
||||
@ -68,7 +68,7 @@ void PathComponent::Begin() {
|
||||
for (int index = 0; index < num; ++index) {
|
||||
const Transform& transform = transforms[index];
|
||||
osg::AnimationPath::ControlPoint controlPoint(transform.GetLocation() /*+ osg::Vec3(index * 10, 0, 0)*/,
|
||||
OsgUtils::HPRToQuat(transform.GetRotation() + osg::Vec3(0, 0, -90.0)), transform.GetScale());
|
||||
OsgUtils::HPRToQuat(transform.GetRotation()), transform.GetScale());
|
||||
animationPath_->insert(steps[index], controlPoint);
|
||||
}
|
||||
|
||||
|
||||
BIN
src/res/default/menu_light_file.png
Normal file
BIN
src/res/default/menu_light_file.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 973 B |
BIN
src/res/default/menu_surface_file.png
Normal file
BIN
src/res/default/menu_surface_file.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.0 KiB |
BIN
src/res/default/menu_table_file.png
Normal file
BIN
src/res/default/menu_table_file.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 326 B |
BIN
src/res/default/menu_wave_file.png
Normal file
BIN
src/res/default/menu_wave_file.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 662 B |
BIN
src/res/sys_float.png
Normal file
BIN
src/res/sys_float.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 361 B |
File diff suppressed because it is too large
Load Diff
@ -14,6 +14,7 @@ DockTitleBar::DockTitleBar(QWidget* parent)
|
||||
, ui(new Ui::DockTitleBar) {
|
||||
ui->setupUi(this);
|
||||
connect(ui->sys_close, &QPushButton::clicked, this, &DockTitleBar::signalClose);
|
||||
connect(ui->sys_float, &QPushButton::clicked, this, &DockTitleBar::signalToggleFloating);
|
||||
}
|
||||
|
||||
DockTitleBar::~DockTitleBar() {
|
||||
|
||||
@ -49,6 +49,19 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="sys_float">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="sys_close">
|
||||
<property name="maximumSize">
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
#include "DockWidget.h"
|
||||
|
||||
#include <QStyleOptionDockWidget>
|
||||
#include <QMouseEvent>
|
||||
|
||||
#include "ui/Menu/SystemManagerMenu.h"
|
||||
#include "common/SpdLogger.h"
|
||||
@ -8,7 +9,7 @@
|
||||
|
||||
|
||||
DockWidgetTitleBar::DockWidgetTitleBar(QWidget* parent)
|
||||
: QWidget(parent) {
|
||||
: QWidget(parent) {
|
||||
|
||||
}
|
||||
|
||||
@ -54,6 +55,7 @@ void DockWidget::setWindowTitle(const QString& text) {
|
||||
void DockWidget::SetDockWidgetTitleBar(DockWidgetTitleBar* titleBar) {
|
||||
if (nullptr != titleBar_) {
|
||||
disconnect(titleBar_, &DockWidgetTitleBar::signalClose, this, &DockWidget::close);
|
||||
disconnect(titleBar_, &DockWidgetTitleBar::signalToggleFloating, this, &DockWidget::OnToggleFloat);
|
||||
}
|
||||
titleBar_ = titleBar;
|
||||
if (nullptr == titleBar_) {
|
||||
@ -63,6 +65,7 @@ void DockWidget::SetDockWidgetTitleBar(DockWidgetTitleBar* titleBar) {
|
||||
|
||||
titleBar_->SetTitle(windowTitle());
|
||||
connect(titleBar_, &DockWidgetTitleBar::signalClose, this, &DockWidget::OnClose);
|
||||
connect(titleBar_, &DockWidgetTitleBar::signalToggleFloating, this, &DockWidget::OnToggleFloat);
|
||||
QDockWidget::setTitleBarWidget(titleBar_);
|
||||
}
|
||||
|
||||
@ -86,3 +89,12 @@ void DockWidget::OnClose() {
|
||||
emit signalClose();
|
||||
}
|
||||
|
||||
void DockWidget::OnToggleFloat() {
|
||||
setFloating(!isFloating());
|
||||
}
|
||||
|
||||
void DockWidgetTitleBar::mouseDoubleClickEvent(QMouseEvent* event) {
|
||||
QWidget::mouseDoubleClickEvent(event);
|
||||
emit signalToggleFloating();
|
||||
}
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
#include <QTimer>
|
||||
|
||||
class DockWidgetTitleBar : public QWidget {
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DockWidgetTitleBar(QWidget* parent);
|
||||
@ -18,9 +18,12 @@ public:
|
||||
// return QSize(270, 900);
|
||||
//}
|
||||
//QSize minimumSizeHint() const override;
|
||||
protected:
|
||||
void mouseDoubleClickEvent(QMouseEvent* event) override;
|
||||
|
||||
Q_SIGNALS:
|
||||
void signalClose();
|
||||
void signalToggleFloating();
|
||||
};
|
||||
|
||||
class DockWidget : public QDockWidget {
|
||||
@ -45,6 +48,7 @@ protected:
|
||||
|
||||
private:
|
||||
void OnClose();
|
||||
void OnToggleFloat();
|
||||
|
||||
private:
|
||||
DockWidgetTitleBar* titleBar_{ nullptr };
|
||||
|
||||
48
src/ui/EntityBrowser.cpp
Normal file
48
src/ui/EntityBrowser.cpp
Normal file
@ -0,0 +1,48 @@
|
||||
#include "EntityBrowser.h"
|
||||
|
||||
#include <QBoxLayout>
|
||||
#include <QDebug>
|
||||
|
||||
#include "DockTitleBar.h"
|
||||
#include "DockWidget.h"
|
||||
// #include "ModelBrowser/ModelTreeWidget.h"
|
||||
#include "workspace/WorkSpaceManager.h"
|
||||
|
||||
EntityBrowser::EntityBrowser(QWidget *parent) :
|
||||
QWidget(parent) {
|
||||
|
||||
InitUI();
|
||||
}
|
||||
|
||||
EntityBrowser::~EntityBrowser() {
|
||||
|
||||
}
|
||||
|
||||
void EntityBrowser::AttachDock(DockWidget* dockWidget) {
|
||||
if (nullptr == dockWidget) {
|
||||
qDebug() << __FUNCTION__ << "dockwidget is nullptr";
|
||||
return;
|
||||
}
|
||||
|
||||
dockWidget->SetDockWidgetTitleBar(nullptr);
|
||||
dockWidget->setWidget(this);
|
||||
|
||||
DockTitleBar* dockTitleBar = new DockTitleBar;
|
||||
dockWidget->SetDockWidgetTitleBar(dockTitleBar);
|
||||
}
|
||||
|
||||
void EntityBrowser::InitUI() {
|
||||
// QBoxLayout* layout = new QVBoxLayout(this);
|
||||
// layout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
// treeWidget_ = new ModelTreeWidget;
|
||||
// treeWidget_->setHeaderHidden(true);
|
||||
// layout->addWidget(treeWidget_);
|
||||
|
||||
// connect(&WorkSpaceManager::Get(), &WorkSpaceManager::WorkSpaceChanged,
|
||||
// treeWidget_, &ModelTreeWidget::OnWorkspaceChange);
|
||||
|
||||
// //ModelTreeWidget* treeWidget = modelBrowserPannal_->GetModelTreeWidget();
|
||||
// connect(treeWidget_, &ModelTreeWidget::WorkSpaceChange, this, &ModelBrowser::WorkSpaceChange);
|
||||
// connect(treeWidget_, &ModelTreeWidget::EntityChange, this, &ModelBrowser::EntityChange);
|
||||
}
|
||||
24
src/ui/EntityBrowser.h
Normal file
24
src/ui/EntityBrowser.h
Normal file
@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class EntityBrowser : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit EntityBrowser(QWidget *parent = nullptr);
|
||||
~EntityBrowser() override;
|
||||
|
||||
void AttachDock(class DockWidget* dockWidget);
|
||||
|
||||
Q_SIGNALS:
|
||||
void WorkSpaceChange(const QVariant& workSpace);
|
||||
void EntityChange(const QVariant& workSpace);
|
||||
|
||||
private:
|
||||
void InitUI();
|
||||
|
||||
private:
|
||||
// class ModelTreeWidget* treeWidget_;
|
||||
};
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
#include "MainWindow.h"
|
||||
|
||||
#include <qtabwidget.h>
|
||||
#include "utils/UiLayoutManager.h"
|
||||
|
||||
#include "PropertyBrowser.h"
|
||||
#include "ModelBrowser.h"
|
||||
@ -28,6 +29,7 @@
|
||||
|
||||
#include "ui_MainWindow.h"
|
||||
#include "viewer/OsgWidget.h"
|
||||
#include "DockTitleBar.h"
|
||||
|
||||
MainWindow::MainWindow(QWidget* parent)
|
||||
: QMainWindow(parent)
|
||||
@ -43,43 +45,49 @@ MainWindow::~MainWindow() {
|
||||
}
|
||||
|
||||
void MainWindow::InitUI() {
|
||||
|
||||
tabWidget_ = new QTabWidget;
|
||||
tabWidget_->setTabPosition(QTabWidget::South);
|
||||
tabWidget_->tabBar()->setMinimumWidth(300);
|
||||
|
||||
ui->viewWidget->layout()->addWidget(tabWidget_);
|
||||
|
||||
pSettingUI = new LayoutSettingUI();
|
||||
|
||||
const QString uiLaytouPath = RecourceHelper::Get().GetBasePath() + "/workspace/UILayout.xml";
|
||||
|
||||
pSettingUI->InitConfig(uiLaytouPath);
|
||||
//pSettingUI->show();
|
||||
|
||||
connect(pSettingUI, &LayoutSettingUI::signalUpdate, this, &MainWindow::InitDockLayout);
|
||||
QWidget* centralWidget = takeCentralWidget();
|
||||
if (nullptr != centralWidget) {
|
||||
delete centralWidget;
|
||||
}
|
||||
setDockNestingEnabled(true);
|
||||
|
||||
setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea);
|
||||
setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea);
|
||||
setDockOptions(QMainWindow::AllowTabbedDocks | QMainWindow::AllowNestedDocks | QMainWindow::AnimatedDocks);
|
||||
|
||||
DockWidget* model = new DockWidget(tr("model elements"), 0);
|
||||
model->SetDockWidgetTitleBar(new DockTitleBar(model));
|
||||
model->setObjectName("Dock.ModelBrowser");
|
||||
// addDockWidget(pSettingUI->GetArea("ModelBrowser"), model);
|
||||
modelBrowser_ = new ModelBrowser(0);
|
||||
modelBrowser_->AttachDock(model);
|
||||
m_mapDockWidget.insert("ModelBrowser", model);
|
||||
|
||||
DockWidget* attribte = new DockWidget(tr("attribte"), 0);
|
||||
attribte->SetDockWidgetTitleBar(new DockTitleBar(attribte));
|
||||
attribte->setObjectName("Dock.PropertyBrowser");
|
||||
//addDockWidget(pSettingUI->GetArea("PropertyBrowser"), attribte);
|
||||
propertyBrowser_ = new PropertyBrowser(0);
|
||||
propertyBrowser_->AttachDock(attribte);
|
||||
m_mapDockWidget.insert("PropertyBrowser", attribte);
|
||||
addDockWidget(Qt::RightDockWidgetArea, attribte);
|
||||
|
||||
connect(modelBrowser_, &ModelBrowser::WorkSpaceChange, propertyBrowser_, &PropertyBrowser::OnWorkSpaceChange);
|
||||
connect(modelBrowser_, &ModelBrowser::EntityChange, propertyBrowser_, &PropertyBrowser::OnEntityChange);
|
||||
|
||||
qtOsgViewWidget_ = new OsgWidget;
|
||||
qtOsgViewWidget_->Initialize();
|
||||
//m_mapDockWidget.insert("PropertyBrowser", attribte);
|
||||
|
||||
// 主视图改为 DockWidget,支持自由停靠
|
||||
DockWidget* viewDock = new DockWidget(tr("Main View"), 0);
|
||||
viewDock->SetDockWidgetTitleBar(new DockTitleBar(viewDock));
|
||||
viewDock->setObjectName("Dock.MainView");
|
||||
viewDock->setWidget(qtOsgViewWidget_);
|
||||
addDockWidget(Qt::LeftDockWidgetArea, viewDock);
|
||||
m_mapDockWidget.insert("MainView", viewDock);
|
||||
|
||||
addDockWidget(Qt::LeftDockWidgetArea, model);
|
||||
splitDockWidget(model, viewDock, Qt::Horizontal);
|
||||
|
||||
QString wavePath ="", speedPath = "", rdPath = "", matlabParam="";
|
||||
if (WorkSpaceManager::Get().GetCurrent())
|
||||
@ -106,25 +114,36 @@ void MainWindow::InitUI() {
|
||||
}
|
||||
|
||||
DockWidget* fitCurveDock = new DockWidget(tr("Wave Curve"), 0);
|
||||
fitCurveDock->SetDockWidgetTitleBar(new DockTitleBar(fitCurveDock));
|
||||
fitCurveDock->setObjectName("Dock.WaveCurveDialog");
|
||||
fitCurveDlg_ = new FitCurveDialog(1);
|
||||
fitCurveDlg_->AttachDock(fitCurveDock);
|
||||
m_mapDockWidget.insert("WaveCurveDialog", fitCurveDock);
|
||||
addDockWidget(Qt::BottomDockWidgetArea, fitCurveDock);
|
||||
|
||||
fitCurveDlg_->InitWaveFile(wavePath);
|
||||
DockWidget* fitLgCurveDock = new DockWidget(tr("Speed Curve"), 0);
|
||||
fitLgCurveDock->SetDockWidgetTitleBar(new DockTitleBar(fitLgCurveDock));
|
||||
fitLgCurveDock->setObjectName("Dock.SpeedCurveDialog");
|
||||
|
||||
fitYLgCurveDlg_ = new FitCurveDialog(1);
|
||||
fitYLgCurveDlg_->AttachDock(fitLgCurveDock);
|
||||
m_mapDockWidget.insert("SpeedCurveDialog", fitLgCurveDock);
|
||||
addDockWidget(Qt::BottomDockWidgetArea, fitLgCurveDock);
|
||||
tabifyDockWidget(fitCurveDock, fitLgCurveDock);
|
||||
|
||||
|
||||
fitYLgCurveDlg_->InitReportFile(speedPath);
|
||||
|
||||
DockWidget* surfaceCurveDock = new DockWidget(tr("3D Curve"), 0);
|
||||
surfaceCurveDock->SetDockWidgetTitleBar(new DockTitleBar(surfaceCurveDock));
|
||||
surfaceCurveDock->setObjectName("Dock.3DCurveDialog");
|
||||
|
||||
surfaceDlg_ = new SurfaceDialog();
|
||||
surfaceDlg_->AttachDock(surfaceCurveDock);
|
||||
m_mapDockWidget.insert("3DCurveDialog", surfaceCurveDock);
|
||||
addDockWidget(Qt::BottomDockWidgetArea, surfaceCurveDock);
|
||||
tabifyDockWidget(fitCurveDock, surfaceCurveDock);
|
||||
|
||||
surfaceDlg_->InitRD(rdPath);
|
||||
|
||||
@ -146,37 +165,55 @@ void MainWindow::InitUI() {
|
||||
targetUITable_->InitFile(speedPath, 50);
|
||||
|
||||
DockWidget* dataTableDock = new DockWidget(tr("Report Table"), 0);
|
||||
dataTableDock->SetDockWidgetTitleBar(new DockTitleBar(dataTableDock));
|
||||
dataTableDock->setObjectName("Dock.TargetListWgt_Table");
|
||||
// addDockWidget(pSettingUI->GetArea("TargetListWgt"), dataTableDock);
|
||||
targetUITable_->AttachDock(dataTableDock);
|
||||
m_mapDockWidget.insert("TargetListWgt_Table", dataTableDock);
|
||||
addDockWidget(Qt::BottomDockWidgetArea, dataTableDock);
|
||||
tabifyDockWidget(fitCurveDock, dataTableDock);
|
||||
|
||||
}
|
||||
|
||||
const QString lampPath = RecourceHelper::Get().GetBasePath() + "/workspace/Lamp.txt";
|
||||
|
||||
DockWidget* signalIndicatorLampDock = new DockWidget(tr("Signal Indicator Lamp"), 0);
|
||||
signalIndicatorLampDock->SetDockWidgetTitleBar(new DockTitleBar(signalIndicatorLampDock));
|
||||
signalIndicatorLampDock->setObjectName("Dock.SignalIndicatorLampUI");
|
||||
signalIndicatorLampUI_ = new SignalIndicatorLampUI;
|
||||
signalIndicatorLampUI_->AttachDock(signalIndicatorLampDock);
|
||||
signalIndicatorLampUI_->InitLamp(lampPath);
|
||||
|
||||
m_mapDockWidget.insert("SignalIndicatorLampUI", signalIndicatorLampDock);
|
||||
addDockWidget(Qt::BottomDockWidgetArea, signalIndicatorLampDock);
|
||||
tabifyDockWidget(fitCurveDock, signalIndicatorLampDock);
|
||||
|
||||
DockWidget* addParamSettingDock = new DockWidget(tr("ParamSetting"), 0);
|
||||
addParamSettingDock->SetDockWidgetTitleBar(new DockTitleBar(addParamSettingDock));
|
||||
addParamSettingDock->setObjectName("Dock.ParamSetting");
|
||||
addParamDlg_ = new AddParamSetting(matlabParam);
|
||||
addParamDlg_->AttachDock(addParamSettingDock);
|
||||
m_mapDockWidget.insert("ParamSetting", addParamSettingDock);
|
||||
addDockWidget(Qt::BottomDockWidgetArea, addParamSettingDock);
|
||||
tabifyDockWidget(fitCurveDock, addParamSettingDock);
|
||||
|
||||
DockWidget* matlabDock = new DockWidget(tr("bat File"), 0);
|
||||
matlabDock->SetDockWidgetTitleBar(new DockTitleBar(matlabDock));
|
||||
matlabDock->setObjectName("Dock.Matlab");
|
||||
matlabFileDlg_ = new CodeEdtUI;
|
||||
matlabFileDlg_->AttachDock(matlabDock);
|
||||
m_mapDockWidget.insert("Matlab", matlabDock);
|
||||
addDockWidget(Qt::BottomDockWidgetArea, matlabDock);
|
||||
tabifyDockWidget(fitCurveDock, matlabDock);
|
||||
|
||||
//ui->discript->setText(tr("name: 5year 0412"));
|
||||
//ui->status->setText(tr("start: no start"));
|
||||
|
||||
InitDockLayout();
|
||||
InitChartLayout();
|
||||
|
||||
// InitDockLayout();
|
||||
|
||||
// Restore previous UI layout if available
|
||||
UiLayoutManager::Restore(this, 1);
|
||||
|
||||
//ui->viewWidget->layout()->addWidget(qtOsgViewWidget_);
|
||||
qtOsgViewWidget_->LoadDefaultScene();
|
||||
/*OsgViewer::Get().Initialize();
|
||||
@ -189,6 +226,8 @@ void MainWindow::InitUI() {
|
||||
}
|
||||
|
||||
void MainWindow::UninitUI() {
|
||||
// Save layout state before tearing down widgets
|
||||
UiLayoutManager::Save(this, 1);
|
||||
if (qtOsgViewWidget_) {
|
||||
qtOsgViewWidget_->Uninitialize();
|
||||
delete qtOsgViewWidget_;
|
||||
@ -196,248 +235,6 @@ void MainWindow::UninitUI() {
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::InitDockLayout() {
|
||||
while (tabWidget_->count() > 0) {
|
||||
tabWidget_->removeTab(0);
|
||||
}
|
||||
|
||||
tabWidget_->tabBar()->setExpanding(true);
|
||||
|
||||
QVariantList listTab = pSettingUI->GetAreaLayout().toList();
|
||||
for (int i = 0; i < listTab.size(); i++) {
|
||||
QVariantMap mapTab = listTab[i].toMap();
|
||||
QString strTabName = mapTab.value("Name").toString();
|
||||
|
||||
QMainWindow* mainWindow_ = new QMainWindow;
|
||||
connect(mainWindow_, &QMainWindow::tabifiedDockWidgetActivated, this, &MainWindow::OnTabifiedDockWidgetActivated);
|
||||
|
||||
QVariantList listDocArea = mapTab.value("Widget").toList();
|
||||
|
||||
tabWidget_->insertTab(i, mainWindow_, strTabName);
|
||||
if (listDocArea[0].toList().size() > 0) {
|
||||
mainWindow_->setCentralWidget(qtOsgViewWidget_);
|
||||
//OsgViewer::Get().Initialize();
|
||||
//OsgViewer::Get().OnFrame();
|
||||
} else {
|
||||
mainWindow_->takeCentralWidget();
|
||||
}
|
||||
|
||||
|
||||
if (listDocArea.size() > 0) {
|
||||
QDockWidget* lastDock = nullptr;
|
||||
|
||||
for (int j = 1; j < listDocArea.size(); j++) {
|
||||
Qt::DockWidgetArea dockArea;
|
||||
if (j == 1) {
|
||||
dockArea = Qt::LeftDockWidgetArea;
|
||||
} else if (j == 2) {
|
||||
dockArea = Qt::TopDockWidgetArea;
|
||||
} else if (j == 3) {
|
||||
dockArea = Qt::RightDockWidgetArea;
|
||||
} else if (j == 4) {
|
||||
dockArea = Qt::BottomDockWidgetArea;
|
||||
}
|
||||
|
||||
QVariantList listDocAreaChild = listDocArea[j].toList();
|
||||
for (int m = 0; m < listDocAreaChild.size(); m++) {
|
||||
QVariant varWidget = listDocAreaChild[m];
|
||||
|
||||
if (varWidget.type() == QVariant::String) {
|
||||
QDockWidget* pDock = m_mapDockWidget.value(varWidget.toString());
|
||||
if (pDock == nullptr) {
|
||||
continue;
|
||||
}
|
||||
mainWindow_->addDockWidget(dockArea, pDock);
|
||||
lastDock = pDock;
|
||||
} else {
|
||||
QVariantList listWidget = varWidget.toList();
|
||||
for (int k = 0; k < listWidget.size(); k++) {
|
||||
QDockWidget* pDock = m_mapDockWidget.value(listWidget[k].toString());
|
||||
mainWindow_->addDockWidget(dockArea, pDock);
|
||||
|
||||
if (k == 0) {
|
||||
if (lastDock) {
|
||||
mainWindow_->splitDockWidget(lastDock, pDock, Qt::Vertical);
|
||||
}
|
||||
} else {
|
||||
mainWindow_->splitDockWidget(lastDock, pDock, Qt::Horizontal);
|
||||
}
|
||||
|
||||
lastDock = pDock;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tabWidget_->tabBar()->setMinimumWidth(500);
|
||||
/* AddDockArea("DockLeftArea");
|
||||
AddDockArea("DockTopArea");
|
||||
AddDockArea("DockRightArea");
|
||||
AddDockArea("DockBottomArea");*/
|
||||
}
|
||||
|
||||
void MainWindow::AddDockArea(const QString& strArea) {
|
||||
Qt::DockWidgetArea dockArea;
|
||||
Qt::Orientation orient;
|
||||
|
||||
if (strArea == "DockLeftArea") {
|
||||
dockArea = Qt::LeftDockWidgetArea;
|
||||
orient = Qt::Vertical;
|
||||
} else if (strArea == "DockTopArea") {
|
||||
dockArea = Qt::TopDockWidgetArea;
|
||||
orient = Qt::Horizontal;
|
||||
} else if (strArea == "DockRightArea") {
|
||||
dockArea = Qt::RightDockWidgetArea;
|
||||
orient = Qt::Vertical;
|
||||
} else if (strArea == "DockBottomArea") {
|
||||
dockArea = Qt::BottomDockWidgetArea;
|
||||
orient = Qt::Horizontal;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
QList<QDockWidget*> listAdd;
|
||||
|
||||
QVariant varArea = pSettingUI->GetAreaLayout();
|
||||
if (varArea.isValid()) {
|
||||
QVariantList listWidget = varArea.toList();
|
||||
for each(QVariant varWidget in listWidget) {
|
||||
if (varWidget.type() == QVariant::String) {
|
||||
QDockWidget* pDock = m_mapDockWidget.value(varWidget.toString());
|
||||
addDockWidget(dockArea, pDock);
|
||||
|
||||
listAdd.push_back(pDock);
|
||||
} else {
|
||||
QDockWidget* pLastDock = nullptr;
|
||||
QVariantList listTab = varWidget.toList();
|
||||
for each(QVariant tabChild in listTab) {
|
||||
QDockWidget* pDock = m_mapDockWidget.value(tabChild.toString());
|
||||
addDockWidget(dockArea, pDock);
|
||||
|
||||
if (pLastDock) {
|
||||
//tabifyDockWidget(pLastDock, pDock);
|
||||
splitDockWidget(pLastDock, pDock, Qt::Horizontal);
|
||||
}
|
||||
|
||||
listAdd.push_back(pDock);
|
||||
|
||||
pLastDock = pDock;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
QList<int> listSpliter;
|
||||
for (size_t i = 0; i < listAdd.size(); i++) {
|
||||
listSpliter.push_back(1);
|
||||
}
|
||||
|
||||
resizeDocks(listAdd, listSpliter, orient);
|
||||
}
|
||||
|
||||
void MainWindow::InitChartLayout()
|
||||
{
|
||||
QString strChart = RecourceHelper::Get().GetBasePath() + "/workspace/Chart.xml";
|
||||
m_mgrChart.Load(strChart);
|
||||
|
||||
QVariantList varList = m_mgrChart.GetChartWgt();
|
||||
for (int nI = 0; nI < varList.size(); nI++)
|
||||
{
|
||||
QVariantMap mapWgt = varList.at(nI).toMap();
|
||||
QString strWgt = mapWgt.begin().key();
|
||||
QVariantList listChart = mapWgt.begin().value().toList();
|
||||
|
||||
QMainWindow* mainWindow_ = new QMainWindow;
|
||||
connect(mainWindow_, &QMainWindow::tabifiedDockWidgetActivated, this, &MainWindow::OnTabifiedDockWidgetActivated);
|
||||
|
||||
int nCount = tabWidget_->count();
|
||||
tabWidget_->insertTab(nCount, mainWindow_, strWgt);
|
||||
|
||||
QVariantMap varRows;
|
||||
for (int nJ = 0; nJ < listChart.size(); nJ++)
|
||||
{
|
||||
QVariantMap mapChart = listChart.at(nJ).toMap();
|
||||
int nRow = mapChart.value("row").toInt();
|
||||
int nCol = mapChart.value("column").toInt();
|
||||
QString strKey = QString::number(nRow) + "-" + QString::number(nCol);
|
||||
varRows.insert(strKey, mapChart);
|
||||
}
|
||||
|
||||
QDockWidget* lastRowDock = nullptr;
|
||||
QDockWidget* lastColDock = nullptr;
|
||||
int lastRow = -1;
|
||||
int lastCol = -1;
|
||||
for (QVariantMap::Iterator ite = varRows.begin(); ite != varRows.end(); ++ite)
|
||||
{
|
||||
QVariantMap mapChart = ite.value().toMap();
|
||||
int nRow = mapChart.value("row").toInt();
|
||||
int nCol = mapChart.value("column").toInt();
|
||||
QString strName = mapChart.value("Name").toString();
|
||||
QString xTitle = mapChart.value("xTitle").toString();
|
||||
QString yTitle = mapChart.value("yTitle").toString();
|
||||
float xMin = mapChart.value("xMin").toFloat();
|
||||
float xMax = mapChart.value("xMax").toFloat();
|
||||
int xCount = mapChart.value("xCount").toInt();
|
||||
float yMin = mapChart.value("yMin").toFloat();
|
||||
float yMax = mapChart.value("yMax").toFloat();
|
||||
|
||||
DockWidget* pDock = new DockWidget(strName, 0);
|
||||
fitCurveDlg_ = new FitCurveDialog(1);
|
||||
fitCurveDlg_->AttachDock(pDock);
|
||||
fitCurveDlg_->updateTitle(xTitle, yTitle);
|
||||
fitCurveDlg_->updateMinMaxX(xMin, xMax, xCount);
|
||||
fitCurveDlg_->updateMinMaxY(yMin, yMax);
|
||||
|
||||
mainWindow_->addDockWidget(Qt::LeftDockWidgetArea, pDock);
|
||||
|
||||
if (lastRow > -1)
|
||||
{
|
||||
if (lastRow == nRow)
|
||||
{
|
||||
if (lastCol > -1)
|
||||
{
|
||||
if (lastCol != nCol)
|
||||
{
|
||||
mainWindow_->splitDockWidget(lastColDock, pDock, Qt::Horizontal);
|
||||
}
|
||||
lastColDock = pDock;
|
||||
}
|
||||
else
|
||||
{
|
||||
lastColDock = pDock;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//mainWindow_->splitDockWidget(lastRowDock, pDock, Qt::Vertical);
|
||||
|
||||
lastRowDock = pDock;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lastRowDock = pDock;
|
||||
lastColDock = pDock;
|
||||
}
|
||||
|
||||
lastRow = nRow;
|
||||
lastCol = nCol;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::OnTabifiedDockWidgetActivated(QDockWidget* dockWidget) {
|
||||
//if (dockWidget) {
|
||||
// QMainWindow* mainWindow = qobject_cast<QMainWindow*>(dockWidget->parentWidget());
|
||||
// if (mainWindow) {
|
||||
// mainWindow->removeDockWidget(dockWidget);
|
||||
// }
|
||||
|
||||
// // tabWidget_->setCurrentWidget(dockWidget->parentWidget());
|
||||
//}
|
||||
}
|
||||
|
||||
void MainWindow::slotShowUISetting() {
|
||||
pSettingUI->show();
|
||||
}
|
||||
|
||||
@ -46,14 +46,6 @@ private:
|
||||
void InitUI();
|
||||
void UninitUI();
|
||||
|
||||
void InitDockLayout();
|
||||
void AddDockArea(const QString& strArea);
|
||||
|
||||
void InitChartLayout();
|
||||
|
||||
protected:
|
||||
void OnTabifiedDockWidgetActivated(QDockWidget* dockWidget);
|
||||
|
||||
private:
|
||||
Ui::MainWindow* ui;
|
||||
|
||||
|
||||
@ -1,131 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindow</class>
|
||||
<widget class="QMainWindow" name="MainWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>658</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>MainWindow</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QWidget" name="viewDisplay" native="true">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<property name="leftMargin">
|
||||
<number>19</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>19</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>19</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>19</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QWidget" name="viewWidget" native="true">
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="statusWidget" native="true">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="discript">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="status">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>767</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
<class>MainWindow</class>
|
||||
<widget class="QMainWindow" name="MainWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1223</width>
|
||||
<height>950</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>MainWindow</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget"/>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
#include "common/SpdLogger.h"
|
||||
#include "workspace/WorkSpace.h"
|
||||
#include "workspace/WorkSpaceManager.h"
|
||||
#include "workspace/FileEntry.h"
|
||||
#include "utils/FileUtils.h"
|
||||
|
||||
#include "ui_FileManagerMenu.h"
|
||||
@ -32,6 +33,12 @@ void FileManagerMenu::InitConnect() {
|
||||
connect(ui->menu_new_file, &QToolButton::clicked, this, &FileManagerMenu::NewWorkSpace);
|
||||
connect(ui->menu_open_file, &QToolButton::clicked, this, &FileManagerMenu::OpenWorkSpace);
|
||||
connect(ui->menu_save_file, &QToolButton::clicked, this, &FileManagerMenu::SaveWorkSpace);
|
||||
|
||||
// add file entity buttons
|
||||
connect(ui->menu_wave_file, &QToolButton::clicked, this, &FileManagerMenu::AddWaveFile);
|
||||
connect(ui->menu_surface_file, &QToolButton::clicked, this, &FileManagerMenu::AddSurfaceFile);
|
||||
connect(ui->menu_table_file, &QToolButton::clicked, this, &FileManagerMenu::AddTableFile);
|
||||
connect(ui->menu_light_file, &QToolButton::clicked, this, &FileManagerMenu::AddLightFile);
|
||||
}
|
||||
|
||||
void FileManagerMenu::NewWorkSpace() {
|
||||
@ -70,19 +77,94 @@ void FileManagerMenu::SaveWorkSpace() {
|
||||
QString dytFile = workspace->GetPath();
|
||||
LOG_INFO("save {} dyt file: {}", name.toLocal8Bit().constData(),
|
||||
dytFile.toLocal8Bit().constData());
|
||||
/* if (!FileUtils::IsExist(dytFile)) {
|
||||
QString selfilter = tr("Dyt (*.dyt)");
|
||||
const QString workspacePath = Application::GetWorkSpacePath();
|
||||
dytFile = QFileDialog::getSaveFileName(&MainFrame::Get(), tr("save dyt file"), workspacePath,
|
||||
tr("Dyt (*.dyt);;All files (*.*)"),
|
||||
&selfilter);
|
||||
LOG_INFO("user select file: {}", dytFile.toLocal8Bit().constData());
|
||||
if (dytFile.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
}*/
|
||||
|
||||
bool success = workspace->Save(dytFile);
|
||||
LOG_INFO("save dyt: {}", success);
|
||||
}
|
||||
|
||||
void FileManagerMenu::AddWaveFile() {
|
||||
auto current = WorkSpaceManager::Get().GetCurrent();
|
||||
if (nullptr == current) {
|
||||
QMessageBox::information(&MainFrame::Get(), tr("prompt"), tr("please create workspace first"));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (current->CreateFileEntry(FileEntryType::Curve)) {
|
||||
case WorkSpace::FileEntryResult::Ok:
|
||||
break;
|
||||
case WorkSpace::FileEntryResult::LimitExceeded:
|
||||
QMessageBox::information(&MainFrame::Get(), tr("prompt"), tr("up to 9 files allowed for this type"));
|
||||
break;
|
||||
case WorkSpace::FileEntryResult::Duplicate:
|
||||
QMessageBox::information(&MainFrame::Get(), tr("prompt"), tr("file already added for this type"));
|
||||
break;
|
||||
case WorkSpace::FileEntryResult::CopyFailed:
|
||||
QMessageBox::information(&MainFrame::Get(), tr("prompt"), tr("copy file failed"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void FileManagerMenu::AddSurfaceFile() {
|
||||
auto current = WorkSpaceManager::Get().GetCurrent();
|
||||
if (nullptr == current) {
|
||||
QMessageBox::information(&MainFrame::Get(), tr("prompt"), tr("please create workspace first"));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (current->CreateFileEntry(FileEntryType::Surface)) {
|
||||
case WorkSpace::FileEntryResult::Ok:
|
||||
break;
|
||||
case WorkSpace::FileEntryResult::LimitExceeded:
|
||||
QMessageBox::information(&MainFrame::Get(), tr("prompt"), tr("up to 9 files allowed for this type"));
|
||||
break;
|
||||
case WorkSpace::FileEntryResult::Duplicate:
|
||||
QMessageBox::information(&MainFrame::Get(), tr("prompt"), tr("file already added for this type"));
|
||||
break;
|
||||
case WorkSpace::FileEntryResult::CopyFailed:
|
||||
QMessageBox::information(&MainFrame::Get(), tr("prompt"), tr("copy file failed"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void FileManagerMenu::AddTableFile() {
|
||||
auto current = WorkSpaceManager::Get().GetCurrent();
|
||||
if (nullptr == current) {
|
||||
QMessageBox::information(&MainFrame::Get(), tr("prompt"), tr("please create workspace first"));
|
||||
return;
|
||||
}
|
||||
switch (current->CreateFileEntry(FileEntryType::Table)) {
|
||||
case WorkSpace::FileEntryResult::Ok:
|
||||
break;
|
||||
case WorkSpace::FileEntryResult::LimitExceeded:
|
||||
QMessageBox::information(&MainFrame::Get(), tr("prompt"), tr("up to 9 files allowed for this type"));
|
||||
break;
|
||||
case WorkSpace::FileEntryResult::Duplicate:
|
||||
QMessageBox::information(&MainFrame::Get(), tr("prompt"), tr("file already added for this type"));
|
||||
break;
|
||||
case WorkSpace::FileEntryResult::CopyFailed:
|
||||
QMessageBox::information(&MainFrame::Get(), tr("prompt"), tr("copy file failed"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void FileManagerMenu::AddLightFile() {
|
||||
auto current = WorkSpaceManager::Get().GetCurrent();
|
||||
if (nullptr == current) {
|
||||
QMessageBox::information(&MainFrame::Get(), tr("prompt"), tr("please create workspace first"));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (current->CreateFileEntry(FileEntryType::Light)) {
|
||||
case WorkSpace::FileEntryResult::Ok:
|
||||
break;
|
||||
case WorkSpace::FileEntryResult::LimitExceeded:
|
||||
QMessageBox::information(&MainFrame::Get(), tr("prompt"), tr("up to 9 files allowed for this type"));
|
||||
break;
|
||||
case WorkSpace::FileEntryResult::Duplicate:
|
||||
QMessageBox::information(&MainFrame::Get(), tr("prompt"), tr("file already added for this type"));
|
||||
break;
|
||||
case WorkSpace::FileEntryResult::CopyFailed:
|
||||
QMessageBox::information(&MainFrame::Get(), tr("prompt"), tr("copy file failed"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,6 +24,11 @@ private:
|
||||
void OpenWorkSpace();
|
||||
void SaveWorkSpace();
|
||||
|
||||
void AddWaveFile();
|
||||
void AddSurfaceFile();
|
||||
void AddTableFile();
|
||||
void AddLightFile();
|
||||
|
||||
private:
|
||||
Ui::FileManagerMenu* ui;
|
||||
};
|
||||
@ -54,6 +54,46 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="menu_wave_file">
|
||||
<property name="toolTip">
|
||||
<string>new wave file</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="menu_surface_file">
|
||||
<property name="toolTip">
|
||||
<string>new surface file</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="menu_table_file">
|
||||
<property name="toolTip">
|
||||
<string>new table file</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="menu_light_file">
|
||||
<property name="toolTip">
|
||||
<string>new light file</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
|
||||
@ -56,6 +56,14 @@ void PropertyBrowser::OnWorkSpaceChange(const QVariant& value) {
|
||||
QWorkspaceAttribute worksapceAttribute(workspace);
|
||||
workSpaceManager_->setValue(property, worksapceAttribute);
|
||||
addProperty(property, tr("WorkSpace"));
|
||||
|
||||
// Track and react to runtime workspace changes
|
||||
if (currentWorkspace_) {
|
||||
QObject::disconnect(currentWorkspace_, nullptr, this, nullptr);
|
||||
}
|
||||
currentWorkspace_ = workspace;
|
||||
QObject::connect(currentWorkspace_, &WorkSpace::FilesChanged,
|
||||
this, &PropertyBrowser::OnWorkspaceFilesChanged);
|
||||
}
|
||||
|
||||
void PropertyBrowser::OnEntityChange(const QVariant& value) {
|
||||
@ -152,6 +160,8 @@ void PropertyBrowser::InitPropertyManager() {
|
||||
browser_->setFactoryForManager(sizeManager_->subIntPropertyManager(), spinBoxFactory);
|
||||
browser_->setFactoryForManager(workSpaceManager_->subStringProperyManager(), lineEditFactory);
|
||||
browser_->setFactoryForManager(workSpaceManager_->subFilesProperyManager(), filePathFactory);
|
||||
// Enable editing for grouped file entry counts
|
||||
browser_->setFactoryForManager(workSpaceManager_->subIntProperyManager(), spinBoxFactory);
|
||||
browser_->setFactoryForManager(entityManager_->subStringProperyManager(), lineEditFactory);
|
||||
browser_->setFactoryForManager(entityManager_->subBoolProperyManager(), checkBoxFactory);
|
||||
browser_->setFactoryForManager(
|
||||
@ -165,6 +175,16 @@ void PropertyBrowser::InitPropertyManager() {
|
||||
doubleSpinBoxFactory);
|
||||
}
|
||||
|
||||
void PropertyBrowser::OnWorkspaceFilesChanged(FileEntryType /*type*/) {
|
||||
if (!currentWorkspace_) return;
|
||||
auto it = idToProperty_.find(tr("WorkSpace"));
|
||||
if (it == idToProperty_.end()) return;
|
||||
QtProperty* property = it.value();
|
||||
QWorkspaceAttribute worksapceAttribute(currentWorkspace_);
|
||||
// Refresh the full workspace property tree to reflect new counts/paths
|
||||
workSpaceManager_->setValue(property, worksapceAttribute);
|
||||
}
|
||||
|
||||
void PropertyBrowser::InitComponentPropertyManager() {
|
||||
QtDoubleSpinBoxFactory* doubleSpinBoxFactory = new QtDoubleSpinBoxFactory(this);
|
||||
QtCheckBoxFactory* checkBoxFactory = new QtCheckBoxFactory(this);
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
#include <QWidget>
|
||||
#include <QMap>
|
||||
#include "workspace/FileEntry.h"
|
||||
|
||||
class QtProperty;
|
||||
|
||||
@ -17,6 +18,7 @@ public:
|
||||
|
||||
void OnWorkSpaceChange(const QVariant& value);
|
||||
void OnEntityChange(const QVariant& value);
|
||||
void OnWorkspaceFilesChanged(enum class FileEntryType type);
|
||||
|
||||
void Test();
|
||||
|
||||
@ -49,5 +51,8 @@ private:
|
||||
QMap<QString, bool> idToExpanded_;
|
||||
|
||||
QMap<QString, class QtComponentPropertyManager*> componetManager_;
|
||||
|
||||
// Track current workspace for real-time refresh
|
||||
class WorkSpace* currentWorkspace_{ nullptr };
|
||||
};
|
||||
|
||||
|
||||
@ -42,6 +42,7 @@
|
||||
#include <QtCore/QDateTime>
|
||||
#include <QtCore/QLocale>
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QVector>
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtCore/QRegularExpression>
|
||||
#include <QtGui/QIcon>
|
||||
@ -7893,35 +7894,84 @@ void QtModelBasePropertyManager::uninitializeProperty(QtProperty* property) {
|
||||
#pragma region QtWorkspacePropertyManager
|
||||
|
||||
class QtWorkspacePropertyManagerPrivate {
|
||||
QtWorkspacePropertyManager* q_ptr;
|
||||
Q_DECLARE_PUBLIC(QtWorkspacePropertyManager)
|
||||
QtWorkspacePropertyManager* q_ptr;
|
||||
Q_DECLARE_PUBLIC(QtWorkspacePropertyManager)
|
||||
public:
|
||||
|
||||
void slotStringChanged(QtProperty* property, QString value);
|
||||
void slotStringChanged(QtProperty* property, QString value);
|
||||
void slotIntChanged(QtProperty* property, int value);
|
||||
|
||||
void slotPropertyDestroyed(QtProperty* property);
|
||||
void slotPropertyDestroyed(QtProperty* property);
|
||||
|
||||
typedef QMap<const QtProperty*, QWorkspaceAttribute> PropertyValueMap;
|
||||
PropertyValueMap m_values;
|
||||
typedef QMap<const QtProperty*, QWorkspaceAttribute> PropertyValueMap;
|
||||
PropertyValueMap m_values;
|
||||
|
||||
|
||||
QtStringPropertyManager* m_stringProperyManager;
|
||||
QtFilesPropertyManager* m_filesProperyManager;
|
||||
QtStringPropertyManager* m_stringProperyManager;
|
||||
QtFilesPropertyManager* m_filesProperyManager;
|
||||
QtIntPropertyManager* m_intProperyManager{ nullptr };
|
||||
QtGroupPropertyManager* m_groupProperyManager{ nullptr };
|
||||
|
||||
QMap<const QtProperty*, QtProperty*> m_properyToName;
|
||||
QMap<const QtProperty*, QtProperty*> m_properyToDescription;
|
||||
QMap<const QtProperty*, QtProperty*> m_properyToTimestep;
|
||||
QMap<const QtProperty*, QtProperty*> m_properyToName;
|
||||
QMap<const QtProperty*, QtProperty*> m_properyToDescription;
|
||||
QMap<const QtProperty*, QtProperty*> m_properyToTimestep;
|
||||
QMap<const QtProperty*, QtProperty*> m_properyToSimMatlab;
|
||||
QMap<const QtProperty*, QtProperty*> m_properyToMatlabParam;
|
||||
QMap<const QtProperty*, QtProperty*> m_properyToWavePath;
|
||||
QMap<const QtProperty*, QtProperty*> m_properyToReportPath;
|
||||
QMap<const QtProperty*, QtProperty*> m_properyToRDPath;
|
||||
|
||||
QMap<const QtProperty*, QtProperty*> m_nameToPropery;
|
||||
QMap<const QtProperty*, QtProperty*> m_descriptionToPropery;
|
||||
QMap<const QtProperty*, QtProperty*> m_timestepToPropery;
|
||||
QMap<const QtProperty*, QtProperty*> m_nameToPropery;
|
||||
QMap<const QtProperty*, QtProperty*> m_descriptionToPropery;
|
||||
QMap<const QtProperty*, QtProperty*> m_timestepToPropery;
|
||||
QMap<const QtProperty*, QtProperty*> m_simMatlabToPropery;
|
||||
QMap<const QtProperty*, QtProperty*> m_matlabParamToPropery;
|
||||
QMap<const QtProperty*, QtProperty*> m_wavePathToPropery;
|
||||
QMap<const QtProperty*, QtProperty*> m_reportPathToPropery;
|
||||
QMap<const QtProperty*, QtProperty*> m_rdPathToPropery;
|
||||
|
||||
// Grouped file entries: Curve
|
||||
QMap<const QtProperty*, QtProperty*> m_properyToCurveGroup;
|
||||
QMap<const QtProperty*, QtProperty*> m_curveGroupToPropery;
|
||||
QMap<const QtProperty*, QtProperty*> m_properyToCurveCount;
|
||||
QMap<const QtProperty*, QtProperty*> m_curveCountToPropery;
|
||||
QMap<const QtProperty*, QVector<QtProperty*>> m_properyToCurvePaths;
|
||||
QMap<const QtProperty*, QtProperty*> m_curvePathToPropery;
|
||||
QMap<const QtProperty*, int> m_curvePathIndex;
|
||||
|
||||
// Surface
|
||||
QMap<const QtProperty*, QtProperty*> m_properyToSurfaceGroup;
|
||||
QMap<const QtProperty*, QtProperty*> m_surfaceGroupToPropery;
|
||||
QMap<const QtProperty*, QtProperty*> m_properyToSurfaceCount;
|
||||
QMap<const QtProperty*, QtProperty*> m_surfaceCountToPropery;
|
||||
QMap<const QtProperty*, QVector<QtProperty*>> m_properyToSurfacePaths;
|
||||
QMap<const QtProperty*, QtProperty*> m_surfacePathToPropery;
|
||||
QMap<const QtProperty*, int> m_surfacePathIndex;
|
||||
|
||||
// Table
|
||||
QMap<const QtProperty*, QtProperty*> m_properyToTableGroup;
|
||||
QMap<const QtProperty*, QtProperty*> m_tableGroupToPropery;
|
||||
QMap<const QtProperty*, QtProperty*> m_properyToTableCount;
|
||||
QMap<const QtProperty*, QtProperty*> m_tableCountToPropery;
|
||||
QMap<const QtProperty*, QVector<QtProperty*>> m_properyToTablePaths;
|
||||
QMap<const QtProperty*, QtProperty*> m_tablePathToPropery;
|
||||
QMap<const QtProperty*, int> m_tablePathIndex;
|
||||
|
||||
// Light
|
||||
QMap<const QtProperty*, QtProperty*> m_properyToLightGroup;
|
||||
QMap<const QtProperty*, QtProperty*> m_lightGroupToPropery;
|
||||
QMap<const QtProperty*, QtProperty*> m_properyToLightCount;
|
||||
QMap<const QtProperty*, QtProperty*> m_lightCountToPropery;
|
||||
QMap<const QtProperty*, QVector<QtProperty*>> m_properyToLightPaths;
|
||||
QMap<const QtProperty*, QtProperty*> m_lightPathToPropery;
|
||||
QMap<const QtProperty*, int> m_lightPathIndex;
|
||||
};
|
||||
|
||||
void QtWorkspacePropertyManagerPrivate::slotStringChanged(QtProperty* property, QString value) {
|
||||
if (QtProperty* prop = m_nameToPropery.value(property, 0)) {
|
||||
QWorkspaceAttribute c = m_values[prop];
|
||||
c.SetName(value);
|
||||
q_ptr->setValue(prop, c);
|
||||
if (QtProperty* prop = m_nameToPropery.value(property, 0)) {
|
||||
QWorkspaceAttribute c = m_values[prop];
|
||||
c.SetName(value);
|
||||
q_ptr->setValue(prop, c);
|
||||
} else if (QtProperty* prop = m_descriptionToPropery.value(property, 0)) {
|
||||
QWorkspaceAttribute c = m_values[prop];
|
||||
c.SetDescription(value);
|
||||
@ -7930,9 +7980,102 @@ void QtWorkspacePropertyManagerPrivate::slotStringChanged(QtProperty* property,
|
||||
QWorkspaceAttribute c = m_values[prop];
|
||||
c.SetTimeStep(value);
|
||||
q_ptr->setValue(prop, c);
|
||||
} else if (QtProperty* prop = m_simMatlabToPropery.value(property, 0)) {
|
||||
QWorkspaceAttribute c = m_values[prop];
|
||||
c.SetSimMatlab(value);
|
||||
q_ptr->setValue(prop, c);
|
||||
} else if (QtProperty* prop = m_matlabParamToPropery.value(property, 0)) {
|
||||
QWorkspaceAttribute c = m_values[prop];
|
||||
c.SetMatlabParam(value);
|
||||
q_ptr->setValue(prop, c);
|
||||
} else if (QtProperty* prop = m_wavePathToPropery.value(property, 0)) {
|
||||
QWorkspaceAttribute c = m_values[prop];
|
||||
c.SetWavePath(value);
|
||||
q_ptr->setValue(prop, c);
|
||||
} else if (QtProperty* prop = m_reportPathToPropery.value(property, 0)) {
|
||||
QWorkspaceAttribute c = m_values[prop];
|
||||
c.SetReportPath(value);
|
||||
q_ptr->setValue(prop, c);
|
||||
} else if (QtProperty* prop = m_rdPathToPropery.value(property, 0)) {
|
||||
QWorkspaceAttribute c = m_values[prop];
|
||||
c.SetRDPath(value);
|
||||
q_ptr->setValue(prop, c);
|
||||
} else if (QtProperty* prop = m_curvePathToPropery.value(property, 0)) {
|
||||
QWorkspaceAttribute c = m_values[prop];
|
||||
int idx = m_curvePathIndex.value(property, 0);
|
||||
c.SetFileEntryPath(FileEntryType::Curve, idx, value);
|
||||
q_ptr->setValue(prop, c);
|
||||
} else if (QtProperty* prop = m_surfacePathToPropery.value(property, 0)) {
|
||||
QWorkspaceAttribute c = m_values[prop];
|
||||
int idx = m_surfacePathIndex.value(property, 0);
|
||||
c.SetFileEntryPath(FileEntryType::Surface, idx, value);
|
||||
q_ptr->setValue(prop, c);
|
||||
} else if (QtProperty* prop = m_tablePathToPropery.value(property, 0)) {
|
||||
QWorkspaceAttribute c = m_values[prop];
|
||||
int idx = m_tablePathIndex.value(property, 0);
|
||||
c.SetFileEntryPath(FileEntryType::Table, idx, value);
|
||||
q_ptr->setValue(prop, c);
|
||||
} else if (QtProperty* prop = m_lightPathToPropery.value(property, 0)) {
|
||||
QWorkspaceAttribute c = m_values[prop];
|
||||
int idx = m_lightPathIndex.value(property, 0);
|
||||
c.SetFileEntryPath(FileEntryType::Light, idx, value);
|
||||
q_ptr->setValue(prop, c);
|
||||
}
|
||||
}
|
||||
|
||||
void QtWorkspacePropertyManagerPrivate::slotIntChanged(QtProperty* property, int value) {
|
||||
// Determine which type this count property belongs to
|
||||
auto handleType = [&](FileEntryType type,
|
||||
QMap<const QtProperty*, QtProperty*>& countToProp,
|
||||
QMap<const QtProperty*, QVector<QtProperty*>>& propToPaths,
|
||||
QMap<const QtProperty*, QtProperty*>& pathToProp,
|
||||
QMap<const QtProperty*, int>& pathIndex,
|
||||
QMap<const QtProperty*, QtProperty*>& propToGroup) {
|
||||
if (QtProperty* root = countToProp.value(property, nullptr)) {
|
||||
// Adjust UI path properties to match new count
|
||||
QVector<QtProperty*>& paths = propToPaths[root];
|
||||
int current = paths.size();
|
||||
// Add new path properties
|
||||
if (value > current) {
|
||||
QtProperty* group = propToGroup.value(root, nullptr);
|
||||
for (int i = current; i < value; ++i) {
|
||||
QtProperty* p = m_filesProperyManager->addProperty();
|
||||
QString title;
|
||||
switch (type) {
|
||||
case FileEntryType::Curve: title = QObject::tr("Curve[%1]").arg(i + 1); break;
|
||||
case FileEntryType::Surface: title = QObject::tr("Surface[%1]").arg(i + 1); break;
|
||||
case FileEntryType::Table: title = QObject::tr("Table[%1]").arg(i + 1); break;
|
||||
case FileEntryType::Light: title = QObject::tr("Light[%1]").arg(i + 1); break;
|
||||
}
|
||||
p->setPropertyName(title);
|
||||
group->addSubProperty(p);
|
||||
paths.append(p);
|
||||
pathToProp[p] = root;
|
||||
pathIndex[p] = i;
|
||||
}
|
||||
} else if (value < current) {
|
||||
// Remove excess path properties
|
||||
for (int i = current - 1; i >= value; --i) {
|
||||
QtProperty* p = paths.at(i);
|
||||
pathIndex.remove(p);
|
||||
pathToProp.remove(p);
|
||||
paths.remove(i);
|
||||
delete p;
|
||||
}
|
||||
}
|
||||
// Update underlying model count
|
||||
QWorkspaceAttribute c = m_values[root];
|
||||
c.SetFileEntryCount(type, value);
|
||||
q_ptr->setValue(root, c);
|
||||
}
|
||||
};
|
||||
|
||||
handleType(FileEntryType::Curve, m_curveCountToPropery, m_properyToCurvePaths, m_curvePathToPropery, m_curvePathIndex, m_properyToCurveGroup);
|
||||
handleType(FileEntryType::Surface, m_surfaceCountToPropery, m_properyToSurfacePaths, m_surfacePathToPropery, m_surfacePathIndex, m_properyToSurfaceGroup);
|
||||
handleType(FileEntryType::Table, m_tableCountToPropery, m_properyToTablePaths, m_tablePathToPropery, m_tablePathIndex, m_properyToTableGroup);
|
||||
handleType(FileEntryType::Light, m_lightCountToPropery, m_properyToLightPaths, m_lightPathToPropery, m_lightPathIndex, m_properyToLightGroup);
|
||||
}
|
||||
|
||||
void QtWorkspacePropertyManagerPrivate::slotPropertyDestroyed(QtProperty* property) {
|
||||
if (QtProperty* subProp = m_nameToPropery.value(property, nullptr)) {
|
||||
m_nameToPropery[subProp] = 0;
|
||||
@ -7943,23 +8086,48 @@ void QtWorkspacePropertyManagerPrivate::slotPropertyDestroyed(QtProperty* proper
|
||||
m_descriptionToPropery[subProp] = 0;
|
||||
m_descriptionToPropery.remove(property);
|
||||
}
|
||||
|
||||
if (QtProperty* subProp = m_timestepToPropery.value(property, nullptr)) {
|
||||
m_timestepToPropery[subProp] = 0;
|
||||
m_timestepToPropery.remove(property);
|
||||
}
|
||||
|
||||
if (QtProperty* subProp = m_timestepToPropery.value(property, nullptr)) {
|
||||
m_timestepToPropery[subProp] = 0;
|
||||
m_timestepToPropery.remove(property);
|
||||
}
|
||||
|
||||
if (QtProperty* subProp = m_simMatlabToPropery.value(property, nullptr)) {
|
||||
m_simMatlabToPropery[subProp] = 0;
|
||||
m_simMatlabToPropery.remove(property);
|
||||
}
|
||||
if (QtProperty* subProp = m_matlabParamToPropery.value(property, nullptr)) {
|
||||
m_matlabParamToPropery[subProp] = 0;
|
||||
m_matlabParamToPropery.remove(property);
|
||||
}
|
||||
if (QtProperty* subProp = m_wavePathToPropery.value(property, nullptr)) {
|
||||
m_wavePathToPropery[subProp] = 0;
|
||||
m_wavePathToPropery.remove(property);
|
||||
}
|
||||
if (QtProperty* subProp = m_reportPathToPropery.value(property, nullptr)) {
|
||||
m_reportPathToPropery[subProp] = 0;
|
||||
m_reportPathToPropery.remove(property);
|
||||
}
|
||||
if (QtProperty* subProp = m_rdPathToPropery.value(property, nullptr)) {
|
||||
m_rdPathToPropery[subProp] = 0;
|
||||
m_rdPathToPropery.remove(property);
|
||||
}
|
||||
}
|
||||
|
||||
QtWorkspacePropertyManager::QtWorkspacePropertyManager(QObject* parent)
|
||||
: QtAbstractPropertyManager(parent), d_ptr(new QtWorkspacePropertyManagerPrivate) {
|
||||
d_ptr->q_ptr = this;
|
||||
: QtAbstractPropertyManager(parent), d_ptr(new QtWorkspacePropertyManagerPrivate) {
|
||||
d_ptr->q_ptr = this;
|
||||
|
||||
d_ptr->m_stringProperyManager = new QtStringPropertyManager(this);
|
||||
connect(d_ptr->m_stringProperyManager, SIGNAL(valueChanged(QtProperty*, QString)),
|
||||
this, SLOT(slotStringChanged(QtProperty*, QString)));
|
||||
d_ptr->m_stringProperyManager = new QtStringPropertyManager(this);
|
||||
connect(d_ptr->m_stringProperyManager, SIGNAL(valueChanged(QtProperty*, QString)),
|
||||
this, SLOT(slotStringChanged(QtProperty*, QString)));
|
||||
d_ptr->m_filesProperyManager = new QtFilesPropertyManager(this);
|
||||
connect(d_ptr->m_filesProperyManager, SIGNAL(valueChanged(QtProperty*, QString)),
|
||||
this, SLOT(slotStringChanged(QtProperty*, QString)));
|
||||
d_ptr->m_intProperyManager = new QtIntPropertyManager(this);
|
||||
connect(d_ptr->m_intProperyManager, SIGNAL(valueChanged(QtProperty*, int)),
|
||||
this, SLOT(slotIntChanged(QtProperty*, int)));
|
||||
d_ptr->m_groupProperyManager = new QtGroupPropertyManager(this);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -7982,11 +8150,19 @@ QWorkspaceAttribute QtWorkspacePropertyManager::value(const QtProperty* property
|
||||
}
|
||||
|
||||
QtStringPropertyManager* QtWorkspacePropertyManager::subStringProperyManager() const {
|
||||
return d_ptr->m_stringProperyManager;
|
||||
return d_ptr->m_stringProperyManager;
|
||||
}
|
||||
|
||||
QtFilesPropertyManager* QtWorkspacePropertyManager::subFilesProperyManager() const {
|
||||
return d_ptr->m_filesProperyManager;
|
||||
return d_ptr->m_filesProperyManager;
|
||||
}
|
||||
|
||||
QtIntPropertyManager* QtWorkspacePropertyManager::subIntProperyManager() const {
|
||||
return d_ptr->m_intProperyManager;
|
||||
}
|
||||
|
||||
QtGroupPropertyManager* QtWorkspacePropertyManager::subGroupProperyManager() const {
|
||||
return d_ptr->m_groupProperyManager;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -8019,30 +8195,88 @@ QIcon QtWorkspacePropertyManager::valueIcon(const QtProperty* property) const {
|
||||
\sa value(), valueChanged()
|
||||
*/
|
||||
void QtWorkspacePropertyManager::setValue(QtProperty* property, const QWorkspaceAttribute& value) {
|
||||
const QtWorkspacePropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
|
||||
if (it == d_ptr->m_values.end())
|
||||
return;
|
||||
const QtWorkspacePropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
|
||||
if (it == d_ptr->m_values.end())
|
||||
return;
|
||||
|
||||
|
||||
if (it.value() == value)
|
||||
return;
|
||||
if (it.value() == value)
|
||||
return;
|
||||
|
||||
it.value() = value;
|
||||
it.value() = value;
|
||||
|
||||
d_ptr->m_stringProperyManager->setValue(d_ptr->m_properyToName[property], value.GetName());
|
||||
d_ptr->m_stringProperyManager->setValue(d_ptr->m_properyToDescription[property], value.GetDescription());
|
||||
d_ptr->m_filesProperyManager->setValue(d_ptr->m_properyToTimestep[property], value.GetTimeStep());
|
||||
d_ptr->m_stringProperyManager->setValue(d_ptr->m_properyToName[property], value.GetName());
|
||||
d_ptr->m_stringProperyManager->setValue(d_ptr->m_properyToDescription[property], value.GetDescription());
|
||||
d_ptr->m_filesProperyManager->setValue(d_ptr->m_properyToTimestep[property], value.GetTimeStep());
|
||||
d_ptr->m_filesProperyManager->setValue(d_ptr->m_properyToSimMatlab[property], value.GetSimMatlab());
|
||||
d_ptr->m_filesProperyManager->setValue(d_ptr->m_properyToMatlabParam[property], value.GetMatlabParam());
|
||||
d_ptr->m_filesProperyManager->setValue(d_ptr->m_properyToWavePath[property], value.GetWavePath());
|
||||
d_ptr->m_filesProperyManager->setValue(d_ptr->m_properyToReportPath[property], value.GetReportPath());
|
||||
d_ptr->m_filesProperyManager->setValue(d_ptr->m_properyToRDPath[property], value.GetRDPath());
|
||||
|
||||
emit propertyChanged(property);
|
||||
emit valueChanged(property, value);
|
||||
auto syncGroup = [&](FileEntryType type,
|
||||
QMap<const QtProperty*, QtProperty*>& propToGroup,
|
||||
QMap<const QtProperty*, QtProperty*>& propToCount,
|
||||
QMap<const QtProperty*, QVector<QtProperty*>>& propToPaths,
|
||||
QMap<const QtProperty*, QtProperty*>& pathToProp,
|
||||
QMap<const QtProperty*, int>& pathIndex) {
|
||||
QtProperty* group = propToGroup.value(property, nullptr);
|
||||
if (!group) return;
|
||||
auto entries = value.GetFileEntries(type);
|
||||
int count = static_cast<int>(entries.size());
|
||||
// update count without triggering slot
|
||||
QtProperty* countProp = propToCount.value(property, nullptr);
|
||||
if (countProp) d_ptr->m_intProperyManager->setValueOnly(countProp, count);
|
||||
QVector<QtProperty*>& paths = propToPaths[property];
|
||||
int current = paths.size();
|
||||
// expand
|
||||
if (count > current) {
|
||||
for (int i = current; i < count; ++i) {
|
||||
QtProperty* p = d_ptr->m_filesProperyManager->addProperty();
|
||||
QString title;
|
||||
switch (type) {
|
||||
case FileEntryType::Curve: title = QObject::tr("Curve[%1]").arg(i + 1); break;
|
||||
case FileEntryType::Surface: title = QObject::tr("Surface[%1]").arg(i + 1); break;
|
||||
case FileEntryType::Table: title = QObject::tr("Table[%1]").arg(i + 1); break;
|
||||
case FileEntryType::Light: title = QObject::tr("Light[%1]").arg(i + 1); break;
|
||||
}
|
||||
p->setPropertyName(title);
|
||||
group->addSubProperty(p);
|
||||
paths.append(p);
|
||||
pathToProp[p] = property;
|
||||
pathIndex[p] = i;
|
||||
}
|
||||
} else if (count < current) {
|
||||
for (int i = current - 1; i >= count; --i) {
|
||||
QtProperty* p = paths.at(i);
|
||||
pathIndex.remove(p);
|
||||
pathToProp.remove(p);
|
||||
paths.remove(i);
|
||||
delete p;
|
||||
}
|
||||
}
|
||||
// set values
|
||||
for (int i = 0; i < count; ++i) {
|
||||
const QString absPath = value.GetFileEntryAbsPath(type, i);
|
||||
d_ptr->m_filesProperyManager->setValueOnly(paths.at(i), absPath);
|
||||
}
|
||||
};
|
||||
|
||||
syncGroup(FileEntryType::Curve, d_ptr->m_properyToCurveGroup, d_ptr->m_properyToCurveCount, d_ptr->m_properyToCurvePaths, d_ptr->m_curvePathToPropery, d_ptr->m_curvePathIndex);
|
||||
syncGroup(FileEntryType::Surface, d_ptr->m_properyToSurfaceGroup, d_ptr->m_properyToSurfaceCount, d_ptr->m_properyToSurfacePaths, d_ptr->m_surfacePathToPropery, d_ptr->m_surfacePathIndex);
|
||||
syncGroup(FileEntryType::Table, d_ptr->m_properyToTableGroup, d_ptr->m_properyToTableCount, d_ptr->m_properyToTablePaths, d_ptr->m_tablePathToPropery, d_ptr->m_tablePathIndex);
|
||||
syncGroup(FileEntryType::Light, d_ptr->m_properyToLightGroup, d_ptr->m_properyToLightCount, d_ptr->m_properyToLightPaths, d_ptr->m_lightPathToPropery, d_ptr->m_lightPathIndex);
|
||||
|
||||
emit propertyChanged(property);
|
||||
emit valueChanged(property, value);
|
||||
}
|
||||
|
||||
/*!
|
||||
\reimp
|
||||
*/
|
||||
void QtWorkspacePropertyManager::initializeProperty(QtProperty* property) {
|
||||
QWorkspaceAttribute val;
|
||||
d_ptr->m_values[property] = val;
|
||||
QWorkspaceAttribute val;
|
||||
d_ptr->m_values[property] = val;
|
||||
|
||||
QtProperty* prop = d_ptr->m_stringProperyManager->addProperty();
|
||||
prop->setPropertyName(tr("Name"));
|
||||
@ -8064,18 +8298,113 @@ void QtWorkspacePropertyManager::initializeProperty(QtProperty* property) {
|
||||
d_ptr->m_properyToTimestep[property] = prop;
|
||||
d_ptr->m_timestepToPropery[prop] = property;
|
||||
property->addSubProperty(prop);
|
||||
|
||||
prop = d_ptr->m_filesProperyManager->addProperty();
|
||||
prop->setPropertyName(tr("SimMatlab"));
|
||||
d_ptr->m_filesProperyManager->setValueOnly(prop, val.GetSimMatlab());
|
||||
d_ptr->m_properyToSimMatlab[property] = prop;
|
||||
d_ptr->m_simMatlabToPropery[prop] = property;
|
||||
property->addSubProperty(prop);
|
||||
|
||||
prop = d_ptr->m_filesProperyManager->addProperty();
|
||||
prop->setPropertyName(tr("MatlabParam"));
|
||||
d_ptr->m_filesProperyManager->setValueOnly(prop, val.GetMatlabParam());
|
||||
d_ptr->m_properyToMatlabParam[property] = prop;
|
||||
d_ptr->m_matlabParamToPropery[prop] = property;
|
||||
property->addSubProperty(prop);
|
||||
|
||||
prop = d_ptr->m_filesProperyManager->addProperty();
|
||||
prop->setPropertyName(tr("WavePath"));
|
||||
d_ptr->m_filesProperyManager->setValueOnly(prop, val.GetWavePath());
|
||||
d_ptr->m_properyToWavePath[property] = prop;
|
||||
d_ptr->m_wavePathToPropery[prop] = property;
|
||||
property->addSubProperty(prop);
|
||||
|
||||
prop = d_ptr->m_filesProperyManager->addProperty();
|
||||
prop->setPropertyName(tr("ReportPath"));
|
||||
d_ptr->m_filesProperyManager->setValueOnly(prop, val.GetReportPath());
|
||||
d_ptr->m_properyToReportPath[property] = prop;
|
||||
d_ptr->m_reportPathToPropery[prop] = property;
|
||||
property->addSubProperty(prop);
|
||||
|
||||
prop = d_ptr->m_filesProperyManager->addProperty();
|
||||
prop->setPropertyName(tr("RDPath"));
|
||||
d_ptr->m_filesProperyManager->setValueOnly(prop, val.GetRDPath());
|
||||
d_ptr->m_properyToRDPath[property] = prop;
|
||||
d_ptr->m_rdPathToPropery[prop] = property;
|
||||
property->addSubProperty(prop);
|
||||
|
||||
// Add grouped file sections
|
||||
auto addGroup = [&](FileEntryType type, const QString& groupName,
|
||||
QMap<const QtProperty*, QtProperty*>& propToGroup,
|
||||
QMap<const QtProperty*, QtProperty*>& groupToProp,
|
||||
QMap<const QtProperty*, QtProperty*>& propToCount,
|
||||
QMap<const QtProperty*, QtProperty*>& countToProp,
|
||||
QMap<const QtProperty*, QVector<QtProperty*>>& propToPaths,
|
||||
QMap<const QtProperty*, QtProperty*>& pathToProp,
|
||||
QMap<const QtProperty*, int>& pathIndex) {
|
||||
QtProperty* group = d_ptr->m_groupProperyManager->addProperty();
|
||||
group->setPropertyName(groupName);
|
||||
property->addSubProperty(group);
|
||||
propToGroup[property] = group;
|
||||
groupToProp[group] = property;
|
||||
|
||||
// Count property
|
||||
QtProperty* countProp = d_ptr->m_intProperyManager->addProperty();
|
||||
countProp->setPropertyName(tr("Count"));
|
||||
d_ptr->m_intProperyManager->setRange(countProp, 0, 1024);
|
||||
// initial count from workspace
|
||||
int initialCount = static_cast<int>(val.GetFileEntries(type).size());
|
||||
d_ptr->m_intProperyManager->setValueOnly(countProp, initialCount);
|
||||
propToCount[property] = countProp;
|
||||
countToProp[countProp] = property;
|
||||
group->addSubProperty(countProp);
|
||||
|
||||
// initial paths
|
||||
auto entries = val.GetFileEntries(type);
|
||||
QVector<QtProperty*>& paths = propToPaths[property];
|
||||
for (int i = 0; i < static_cast<int>(entries.size()); ++i) {
|
||||
QtProperty* p = d_ptr->m_filesProperyManager->addProperty();
|
||||
QString title;
|
||||
switch (type) {
|
||||
case FileEntryType::Curve: title = tr("Curve[%1]").arg(i + 1); break;
|
||||
case FileEntryType::Surface: title = tr("Surface[%1]").arg(i + 1); break;
|
||||
case FileEntryType::Table: title = tr("Table[%1]").arg(i + 1); break;
|
||||
case FileEntryType::Light: title = tr("Light[%1]").arg(i + 1); break;
|
||||
}
|
||||
p->setPropertyName(title);
|
||||
d_ptr->m_filesProperyManager->setValueOnly(p, val.GetFileEntryAbsPath(type, i));
|
||||
group->addSubProperty(p);
|
||||
paths.append(p);
|
||||
pathToProp[p] = property;
|
||||
pathIndex[p] = i;
|
||||
}
|
||||
};
|
||||
|
||||
addGroup(FileEntryType::Curve, tr("Curves"), d_ptr->m_properyToCurveGroup, d_ptr->m_curveGroupToPropery,
|
||||
d_ptr->m_properyToCurveCount, d_ptr->m_curveCountToPropery,
|
||||
d_ptr->m_properyToCurvePaths, d_ptr->m_curvePathToPropery, d_ptr->m_curvePathIndex);
|
||||
addGroup(FileEntryType::Surface, tr("Surfaces"), d_ptr->m_properyToSurfaceGroup, d_ptr->m_surfaceGroupToPropery,
|
||||
d_ptr->m_properyToSurfaceCount, d_ptr->m_surfaceCountToPropery,
|
||||
d_ptr->m_properyToSurfacePaths, d_ptr->m_surfacePathToPropery, d_ptr->m_surfacePathIndex);
|
||||
addGroup(FileEntryType::Table, tr("Tables"), d_ptr->m_properyToTableGroup, d_ptr->m_tableGroupToPropery,
|
||||
d_ptr->m_properyToTableCount, d_ptr->m_tableCountToPropery,
|
||||
d_ptr->m_properyToTablePaths, d_ptr->m_tablePathToPropery, d_ptr->m_tablePathIndex);
|
||||
addGroup(FileEntryType::Light, tr("Lights"), d_ptr->m_properyToLightGroup, d_ptr->m_lightGroupToPropery,
|
||||
d_ptr->m_properyToLightCount, d_ptr->m_lightCountToPropery,
|
||||
d_ptr->m_properyToLightPaths, d_ptr->m_lightPathToPropery, d_ptr->m_lightPathIndex);
|
||||
}
|
||||
|
||||
/*!
|
||||
\reimp
|
||||
*/
|
||||
void QtWorkspacePropertyManager::uninitializeProperty(QtProperty* property) {
|
||||
QtProperty* prop = d_ptr->m_nameToPropery[property];
|
||||
if (prop) {
|
||||
d_ptr->m_nameToPropery.remove(prop);
|
||||
delete prop;
|
||||
}
|
||||
d_ptr->m_properyToName.remove(property);
|
||||
QtProperty* prop = d_ptr->m_nameToPropery[property];
|
||||
if (prop) {
|
||||
d_ptr->m_nameToPropery.remove(prop);
|
||||
delete prop;
|
||||
}
|
||||
d_ptr->m_properyToName.remove(property);
|
||||
|
||||
prop = d_ptr->m_descriptionToPropery[property];
|
||||
if (prop) {
|
||||
@ -8090,6 +8419,84 @@ void QtWorkspacePropertyManager::uninitializeProperty(QtProperty* property) {
|
||||
delete prop;
|
||||
}
|
||||
d_ptr->m_properyToTimestep.remove(property);
|
||||
|
||||
prop = d_ptr->m_simMatlabToPropery[property];
|
||||
if (prop) {
|
||||
d_ptr->m_simMatlabToPropery.remove(prop);
|
||||
delete prop;
|
||||
}
|
||||
d_ptr->m_properyToSimMatlab.remove(property);
|
||||
|
||||
prop = d_ptr->m_matlabParamToPropery[property];
|
||||
if (prop) {
|
||||
d_ptr->m_matlabParamToPropery.remove(prop);
|
||||
delete prop;
|
||||
}
|
||||
d_ptr->m_properyToMatlabParam.remove(property);
|
||||
|
||||
prop = d_ptr->m_wavePathToPropery[property];
|
||||
if (prop) {
|
||||
d_ptr->m_wavePathToPropery.remove(prop);
|
||||
delete prop;
|
||||
}
|
||||
d_ptr->m_properyToWavePath.remove(property);
|
||||
|
||||
prop = d_ptr->m_reportPathToPropery[property];
|
||||
if (prop) {
|
||||
d_ptr->m_reportPathToPropery.remove(prop);
|
||||
delete prop;
|
||||
}
|
||||
d_ptr->m_properyToReportPath.remove(property);
|
||||
|
||||
prop = d_ptr->m_rdPathToPropery[property];
|
||||
if (prop) {
|
||||
d_ptr->m_rdPathToPropery.remove(prop);
|
||||
delete prop;
|
||||
}
|
||||
d_ptr->m_properyToRDPath.remove(property);
|
||||
|
||||
// Cleanup grouped file properties
|
||||
auto cleanupGroup = [&](QMap<const QtProperty*, QtProperty*>& propToGroup,
|
||||
QMap<const QtProperty*, QtProperty*>& groupToProp,
|
||||
QMap<const QtProperty*, QtProperty*>& propToCount,
|
||||
QMap<const QtProperty*, QtProperty*>& countToProp,
|
||||
QMap<const QtProperty*, QVector<QtProperty*>>& propToPaths,
|
||||
QMap<const QtProperty*, QtProperty*>& pathToProp,
|
||||
QMap<const QtProperty*, int>& pathIndex) {
|
||||
QtProperty* group = propToGroup.value(property, nullptr);
|
||||
if (group) {
|
||||
propToGroup.remove(property);
|
||||
groupToProp.remove(group);
|
||||
}
|
||||
QtProperty* countProp = propToCount.value(property, nullptr);
|
||||
if (countProp) {
|
||||
countToProp.remove(countProp);
|
||||
propToCount.remove(property);
|
||||
delete countProp;
|
||||
}
|
||||
QVector<QtProperty*>& paths = propToPaths[property];
|
||||
for (QtProperty* p : paths) {
|
||||
pathIndex.remove(p);
|
||||
pathToProp.remove(p);
|
||||
delete p;
|
||||
}
|
||||
paths.clear();
|
||||
propToPaths.remove(property);
|
||||
if (group) delete group;
|
||||
};
|
||||
|
||||
cleanupGroup(d_ptr->m_properyToCurveGroup, d_ptr->m_curveGroupToPropery,
|
||||
d_ptr->m_properyToCurveCount, d_ptr->m_curveCountToPropery,
|
||||
d_ptr->m_properyToCurvePaths, d_ptr->m_curvePathToPropery, d_ptr->m_curvePathIndex);
|
||||
cleanupGroup(d_ptr->m_properyToSurfaceGroup, d_ptr->m_surfaceGroupToPropery,
|
||||
d_ptr->m_properyToSurfaceCount, d_ptr->m_surfaceCountToPropery,
|
||||
d_ptr->m_properyToSurfacePaths, d_ptr->m_surfacePathToPropery, d_ptr->m_surfacePathIndex);
|
||||
cleanupGroup(d_ptr->m_properyToTableGroup, d_ptr->m_tableGroupToPropery,
|
||||
d_ptr->m_properyToTableCount, d_ptr->m_tableCountToPropery,
|
||||
d_ptr->m_properyToTablePaths, d_ptr->m_tablePathToPropery, d_ptr->m_tablePathIndex);
|
||||
cleanupGroup(d_ptr->m_properyToLightGroup, d_ptr->m_lightGroupToPropery,
|
||||
d_ptr->m_properyToLightCount, d_ptr->m_lightCountToPropery,
|
||||
d_ptr->m_properyToLightPaths, d_ptr->m_lightPathToPropery, d_ptr->m_lightPathIndex);
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
@ -1027,6 +1027,8 @@ public:
|
||||
|
||||
QtStringPropertyManager* subStringProperyManager() const;
|
||||
QtFilesPropertyManager* subFilesProperyManager() const;
|
||||
QtIntPropertyManager* subIntProperyManager() const;
|
||||
QtGroupPropertyManager* subGroupProperyManager() const;
|
||||
|
||||
public Q_SLOTS:
|
||||
void setValue(QtProperty* property, const QWorkspaceAttribute& val);
|
||||
@ -1042,6 +1044,7 @@ private:
|
||||
Q_DECLARE_PRIVATE(QtWorkspacePropertyManager)
|
||||
Q_DISABLE_COPY_MOVE(QtWorkspacePropertyManager)
|
||||
Q_PRIVATE_SLOT(d_func(), void slotStringChanged(QtProperty*, QString))
|
||||
Q_PRIVATE_SLOT(d_func(), void slotIntChanged(QtProperty*, int))
|
||||
};
|
||||
|
||||
#pragma endregion
|
||||
|
||||
@ -14,15 +14,18 @@
|
||||
|
||||
QWorkspaceAttribute::QWorkspaceAttribute(class WorkSpace* workspace)
|
||||
: workspace_(workspace) {
|
||||
|
||||
if (workspace_) {
|
||||
filesSeq_ = workspace_->GetFilesSeq();
|
||||
}
|
||||
}
|
||||
|
||||
bool QWorkspaceAttribute::operator==(const QWorkspaceAttribute& other) {
|
||||
return workspace_ == other.workspace_;
|
||||
return workspace_ == other.workspace_ && filesSeq_ == other.filesSeq_;
|
||||
}
|
||||
|
||||
QWorkspaceAttribute& QWorkspaceAttribute::operator=(const QWorkspaceAttribute& other) {
|
||||
workspace_ = other.workspace_;
|
||||
filesSeq_ = other.filesSeq_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -163,7 +166,7 @@ void QWorkspaceAttribute::SetRDPath(const QString& path)
|
||||
workspace_->SetRDPath(path);
|
||||
}
|
||||
|
||||
const QString QWorkspaceAttribute::GetRDPath() const
|
||||
const QString QWorkspaceAttribute::GetRDPath() const
|
||||
{
|
||||
if (nullptr == workspace_) {
|
||||
return "";
|
||||
@ -171,6 +174,34 @@ const QString QWorkspaceAttribute::GetRDPath() const
|
||||
return workspace_->GetRDPath();
|
||||
}
|
||||
|
||||
std::vector<FileEntry> QWorkspaceAttribute::GetFileEntries(FileEntryType type) const {
|
||||
if (nullptr == workspace_) {
|
||||
return {};
|
||||
}
|
||||
return workspace_->GetFileEntries(type);
|
||||
}
|
||||
|
||||
void QWorkspaceAttribute::SetFileEntryCount(FileEntryType type, int count) {
|
||||
if (nullptr == workspace_) {
|
||||
return;
|
||||
}
|
||||
workspace_->SetFileEntryCount(type, count);
|
||||
}
|
||||
|
||||
void QWorkspaceAttribute::SetFileEntryPath(FileEntryType type, int index, const QString& path) {
|
||||
if (nullptr == workspace_) {
|
||||
return;
|
||||
}
|
||||
workspace_->SetFileEntryPath(type, index, path);
|
||||
}
|
||||
|
||||
QString QWorkspaceAttribute::GetFileEntryAbsPath(FileEntryType type, int index) const {
|
||||
if (nullptr == workspace_) {
|
||||
return QString();
|
||||
}
|
||||
return workspace_->GetFileEntryAbsPath(type, index);
|
||||
}
|
||||
|
||||
QTransformAttribute::QTransformAttribute(class Transform* obj)
|
||||
: object_(obj) {
|
||||
|
||||
|
||||
@ -43,6 +43,9 @@
|
||||
#include <QString>
|
||||
#include <QColor>
|
||||
#include <osg/Vec3>
|
||||
#include "workspace/FileEntry.h"
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
|
||||
class QWorkspaceAttribute {
|
||||
public:
|
||||
@ -76,8 +79,16 @@ public:
|
||||
|
||||
void SetRDPath(const QString& path);
|
||||
const QString GetRDPath() const;
|
||||
|
||||
// Grouped files API
|
||||
std::vector<FileEntry> GetFileEntries(FileEntryType type) const;
|
||||
void SetFileEntryCount(FileEntryType type, int count);
|
||||
void SetFileEntryPath(FileEntryType type, int index, const QString& path);
|
||||
QString GetFileEntryAbsPath(FileEntryType type, int index) const;
|
||||
private:
|
||||
class WorkSpace* workspace_{ nullptr };
|
||||
// Snapshot of workspace files change sequence to detect mutations
|
||||
std::uint64_t filesSeq_{ 0 };
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -33,6 +33,7 @@ void WorkSpaceDlg::InitConnect() {
|
||||
connect(ui->pbSure, &QPushButton::clicked, this, &WorkSpaceDlg::OnSure);
|
||||
connect(ui->pbCancel, &QPushButton::clicked, this, &WorkSpaceDlg::reject);
|
||||
connect(ui->tbPath, &QPushButton::clicked, this, &WorkSpaceDlg::OnSelectSavePath);
|
||||
connect(ui->tbCommondPath, &QPushButton::clicked, this, &WorkSpaceDlg::OnSelectCommondPath);
|
||||
connect(ui->leName, &QLineEdit::textChanged, [this](const QString& txt) {
|
||||
QString path = QString("%1/%2").arg(path_).arg(txt);
|
||||
ui->lePath->setText(path);
|
||||
@ -93,6 +94,9 @@ void WorkSpaceDlg::OnSure() {
|
||||
workspacePath += QString("/%1.dyt").arg(name);
|
||||
WorkSpace* workSpace = WorkSpaceManager::Get().GetOrCreate(workspacePath, name);
|
||||
workSpace->SetDescribe(ui->etDescribe->toPlainText());
|
||||
workSpace->SetCommondFilePath(commondPath_);
|
||||
// Execute commands configured for onCreate right after workspace is set up
|
||||
workSpace->ExecuteCommands(WorkSpace::CommandWhen::OnCreate);
|
||||
|
||||
WorkSpaceManager::Get().SetCurrent(workSpace);
|
||||
accept();
|
||||
@ -110,23 +114,20 @@ void WorkSpaceDlg::OnSelectSavePath() {
|
||||
ui->lePath->setText(QString("%1/%2").arg(path_).arg(ui->leName->text()));
|
||||
LOG_INFO("save path: {}", path_.toLocal8Bit().constData());
|
||||
}
|
||||
//
|
||||
//void WorkSpaceDlg::InitFrame() {
|
||||
// FrameTitleBar* titleBar = new FrameTitleBar(this);
|
||||
// titleBar->SetMainWidget(this);
|
||||
//
|
||||
// titleBar->SetSysButton(FrameTitleBar::FTB_ICON | FrameTitleBar::FTB_CLOSE);
|
||||
//
|
||||
// QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
// layout->setContentsMargins(0, 0, 0, 0);
|
||||
// layout->setSpacing(0);
|
||||
//
|
||||
// layout->setStretch(0, 0);
|
||||
// layout->setStretch(1, 1);
|
||||
// layout->setAlignment(Qt::AlignLeft | Qt::AlignTop);
|
||||
// SetTitleBar(titleBar);
|
||||
//
|
||||
// QWidget* mainDilag_ = new QWidget(this);
|
||||
// layout->addWidget(mainDilag_, 1);
|
||||
// ui->setupUi(mainDilag_);
|
||||
//}
|
||||
|
||||
void WorkSpaceDlg::OnSelectCommondPath() {
|
||||
const QString workspacePath = Application::GetWorkSpacePath();
|
||||
const QString xmlPath = QFileDialog::getOpenFileName(
|
||||
this,
|
||||
tr("select command xml file"),
|
||||
workspacePath,
|
||||
tr("XML files (*.xml);;All files (*.*)"));
|
||||
if (xmlPath.isEmpty()) {
|
||||
LOG_WARN("command xml file is empty");
|
||||
return;
|
||||
}
|
||||
commondPath_ = xmlPath;
|
||||
ui->leCommondPath->setText(commondPath_);
|
||||
LOG_INFO("select command xml: {}", commondPath_.toLocal8Bit().constData());
|
||||
}
|
||||
|
||||
|
||||
@ -18,10 +18,12 @@ protected:
|
||||
|
||||
void OnSure();
|
||||
void OnSelectSavePath();
|
||||
void OnSelectCommondPath();
|
||||
|
||||
//void InitFrame();
|
||||
|
||||
private:
|
||||
Ui::WorkSpaceDlg* ui;
|
||||
QString path_;
|
||||
QString commondPath_;
|
||||
};
|
||||
@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>345</width>
|
||||
<height>243</height>
|
||||
<width>528</width>
|
||||
<height>418</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@ -66,6 +66,37 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>commond Path</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="leCommondPath">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="placeholderText">
|
||||
<string>select commond file path</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="tbCommondPath">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
@ -113,8 +144,6 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../Hydro.qrc"/>
|
||||
</resources>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
||||
38
src/utils/UiLayoutManager.cpp
Normal file
38
src/utils/UiLayoutManager.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
#include "UiLayoutManager.h"
|
||||
|
||||
#include <QSettings>
|
||||
#include <QFile>
|
||||
#include <QMainWindow>
|
||||
|
||||
#include "common/RecourceHelper.h"
|
||||
|
||||
namespace {
|
||||
static inline QString layoutIniPath() {
|
||||
return RecourceHelper::Get().GetBasePath() + "/config/UIState.ini";
|
||||
}
|
||||
}
|
||||
|
||||
void UiLayoutManager::Save(QMainWindow* mainWindow, int version) {
|
||||
if (!mainWindow) return;
|
||||
const QString iniPath = layoutIniPath();
|
||||
QSettings settings(iniPath, QSettings::IniFormat);
|
||||
settings.setValue("MainWindow/geometry", mainWindow->saveGeometry());
|
||||
settings.setValue("MainWindow/state", mainWindow->saveState(version));
|
||||
}
|
||||
|
||||
void UiLayoutManager::Restore(QMainWindow* mainWindow, int version) {
|
||||
if (!mainWindow) return;
|
||||
const QString iniPath = layoutIniPath();
|
||||
if (!QFile::exists(iniPath)) {
|
||||
return;
|
||||
}
|
||||
QSettings settings(iniPath, QSettings::IniFormat);
|
||||
const QByteArray geometry = settings.value("MainWindow/geometry").toByteArray();
|
||||
if (!geometry.isEmpty()) {
|
||||
mainWindow->restoreGeometry(geometry);
|
||||
}
|
||||
const QByteArray state = settings.value("MainWindow/state").toByteArray();
|
||||
if (!state.isEmpty()) {
|
||||
mainWindow->restoreState(state, version);
|
||||
}
|
||||
}
|
||||
13
src/utils/UiLayoutManager.h
Normal file
13
src/utils/UiLayoutManager.h
Normal file
@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include <QString>
|
||||
class QMainWindow;
|
||||
|
||||
class UiLayoutManager {
|
||||
public:
|
||||
// 保存主窗口布局到 workspace/UIState.ini
|
||||
static void Save(QMainWindow* mainWindow, int version = 1);
|
||||
|
||||
// 从 workspace/UIState.ini 恢复布局
|
||||
static void Restore(QMainWindow* mainWindow, int version = 1);
|
||||
};
|
||||
@ -46,6 +46,8 @@ OsgWidget::OsgWidget(QWidget* parent, Qt::WindowFlags f)
|
||||
|
||||
connect( &timer_, SIGNAL(timeout()), this, SLOT(update()) );
|
||||
timer_.start( 10 );
|
||||
|
||||
setMinimumSize(100, 100);
|
||||
LOG_INFO("OsgWidget::OsgWidget");
|
||||
}
|
||||
|
||||
|
||||
68
src/workspace/CommandExecutor.cpp
Normal file
68
src/workspace/CommandExecutor.cpp
Normal file
@ -0,0 +1,68 @@
|
||||
#include "workspace/CommandExecutor.h"
|
||||
|
||||
#include <QFileInfo>
|
||||
#include <QProcess>
|
||||
#include <QProcessEnvironment>
|
||||
|
||||
#include "common/SpdLogger.h"
|
||||
|
||||
void CommandExecutor::Execute(WorkSpace* ws, WorkSpace::CommandWhen when) {
|
||||
if (!ws) return;
|
||||
if (!cmd_.enabled) return;
|
||||
|
||||
const QString whenStr = (when == WorkSpace::CommandWhen::OnCreate) ? QStringLiteral("oncreate") : QStringLiteral("onload");
|
||||
|
||||
// Build final arguments (already prepared by manager but honor rawArgs if provided)
|
||||
QStringList argsList = cmd_.args;
|
||||
auto pushArgs = [&argsList](const QString& s) {
|
||||
if (!s.isEmpty()) {
|
||||
for (const auto& part : s.split(' ', Qt::SkipEmptyParts)) {
|
||||
argsList << part;
|
||||
}
|
||||
}
|
||||
};
|
||||
if (!cmd_.rawArgs.isEmpty()) {
|
||||
pushArgs(cmd_.rawArgs);
|
||||
}
|
||||
|
||||
const QString programLower = cmd_.program.toLower();
|
||||
if (!cmd_.path.isEmpty()) {
|
||||
if (programLower.endsWith("cmd.exe")) {
|
||||
argsList << "/c" << cmd_.path;
|
||||
} else if (programLower.endsWith("powershell.exe")) {
|
||||
argsList << "-NoProfile" << "-ExecutionPolicy" << "Bypass" << "-File" << cmd_.path;
|
||||
} else {
|
||||
argsList << cmd_.path;
|
||||
}
|
||||
}
|
||||
|
||||
QProcess proc;
|
||||
// Apply environment if provided
|
||||
if (!cmd_.env.empty()) {
|
||||
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
|
||||
for (auto it = cmd_.env.begin(); it != cmd_.env.end(); ++it) {
|
||||
env.insert(it.key(), it.value());
|
||||
}
|
||||
proc.setProcessEnvironment(env);
|
||||
}
|
||||
|
||||
proc.setProgram(cmd_.program);
|
||||
proc.setArguments(argsList);
|
||||
proc.setWorkingDirectory(cmd_.workingDir.isEmpty() ? ws->GetDir() : cmd_.workingDir);
|
||||
LOG_INFO("run command: name={} prog={} args={} cwd={} when={} desc={}",
|
||||
cmd_.name.toLocal8Bit().constData(),
|
||||
cmd_.program.toLocal8Bit().constData(),
|
||||
argsList.join(' ').toLocal8Bit().constData(),
|
||||
proc.workingDirectory().toLocal8Bit().constData(),
|
||||
whenStr.toLocal8Bit().constData(),
|
||||
cmd_.descript.toLocal8Bit().constData());
|
||||
proc.start();
|
||||
if (!proc.waitForStarted()) {
|
||||
LOG_WARN("command failed to start: {}", cmd_.program.toLocal8Bit().constData());
|
||||
return;
|
||||
}
|
||||
proc.waitForFinished(cmd_.timeoutMs);
|
||||
const QByteArray out = proc.readAllStandardOutput();
|
||||
const QByteArray err = proc.readAllStandardError();
|
||||
LOG_INFO("command '{}' exitCode={} stdout={} stderr={}", cmd_.name.toLocal8Bit().constData(), proc.exitCode(), out.constData(), err.constData());
|
||||
}
|
||||
32
src/workspace/CommandExecutor.h
Normal file
32
src/workspace/CommandExecutor.h
Normal file
@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QMap>
|
||||
|
||||
#include "workspace/WorkSpace.h"
|
||||
|
||||
// Merge Command model into this header to reduce files
|
||||
struct Command {
|
||||
QString name;
|
||||
QString program;
|
||||
QStringList args; // final argument list to pass to QProcess
|
||||
QString rawArgs; // original args string from XML (optional)
|
||||
QString path; // script or executable path
|
||||
QString workingDir; // working directory
|
||||
bool enabled{true};
|
||||
QMap<QString, QString> env; // environment key/value pairs
|
||||
QString descript; // description
|
||||
int timeoutMs{30000}; // default 30s
|
||||
};
|
||||
|
||||
class CommandExecutor {
|
||||
public:
|
||||
explicit CommandExecutor(const Command& cmd) : cmd_(cmd) {}
|
||||
void Execute(WorkSpace* ws, WorkSpace::CommandWhen when);
|
||||
|
||||
const Command& Get() const { return cmd_; }
|
||||
|
||||
private:
|
||||
Command cmd_;
|
||||
};
|
||||
117
src/workspace/CommandManager.cpp
Normal file
117
src/workspace/CommandManager.cpp
Normal file
@ -0,0 +1,117 @@
|
||||
#include "workspace/CommandManager.h"
|
||||
|
||||
#include <QFileInfo>
|
||||
|
||||
#include "xml/tinyxml2.h"
|
||||
#include "common/SpdLogger.h"
|
||||
|
||||
static QMap<QString, QString> parseEnvAttr(const QString& envAttr) {
|
||||
QMap<QString, QString> env;
|
||||
if (envAttr.isEmpty()) return env;
|
||||
const auto pairs = envAttr.split(';', Qt::SkipEmptyParts);
|
||||
for (const auto& p : pairs) {
|
||||
const auto kv = p.split('=', Qt::KeepEmptyParts);
|
||||
if (kv.size() >= 2) env.insert(kv[0].trimmed(), kv[1].trimmed());
|
||||
}
|
||||
return env;
|
||||
}
|
||||
|
||||
void CommandManager::Reload(WorkSpace* ws) {
|
||||
onCreate_.clear();
|
||||
onLoad_.clear();
|
||||
if (!ws) return;
|
||||
|
||||
const QString cmdPath = ws->GetCommondFilePath();
|
||||
if (cmdPath.isEmpty()) {
|
||||
LOG_INFO("no command xml configured");
|
||||
return;
|
||||
}
|
||||
QFileInfo fi(cmdPath);
|
||||
if (!fi.exists() || !fi.isFile()) {
|
||||
LOG_WARN("command xml not found: {}", cmdPath.toLocal8Bit().constData());
|
||||
return;
|
||||
}
|
||||
|
||||
tinyxml2::XMLDocument doc;
|
||||
auto rc = doc.LoadFile(cmdPath.toLocal8Bit().constData());
|
||||
if (rc != tinyxml2::XML_SUCCESS) {
|
||||
LOG_WARN("load command xml failed: {} rc:{}", cmdPath.toLocal8Bit().constData(), static_cast<int>(rc));
|
||||
return;
|
||||
}
|
||||
auto* root = doc.RootElement();
|
||||
if (!root) {
|
||||
LOG_WARN("command xml has no root: {}", cmdPath.toLocal8Bit().constData());
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto* node = root->FirstChildElement(); node; node = node->NextSiblingElement()) {
|
||||
const char* tag = node->Name();
|
||||
if (!tag) continue;
|
||||
QString tagQ = QString::fromUtf8(tag).toLower();
|
||||
if (tagQ != QLatin1String("commond") && tagQ != QLatin1String("command")) continue;
|
||||
|
||||
Command cmd;
|
||||
if (const char* nameAttr = node->Attribute("name")) cmd.name = QString::fromUtf8(nameAttr);
|
||||
if (const char* exeAttr = node->Attribute("exe")) cmd.program = QString::fromUtf8(exeAttr);
|
||||
if (cmd.program.isEmpty()) {
|
||||
if (const char* programAttr = node->Attribute("program")) cmd.program = QString::fromUtf8(programAttr);
|
||||
}
|
||||
if (const char* pathAttr = node->Attribute("path")) cmd.path = QString::fromUtf8(pathAttr);
|
||||
if (cmd.path.isEmpty()) {
|
||||
if (const char* pathTypo = node->Attribute("paht")) cmd.path = QString::fromUtf8(pathTypo);
|
||||
}
|
||||
if (const char* argsAttr = node->Attribute("args")) cmd.rawArgs = QString::fromUtf8(argsAttr);
|
||||
if (const char* cwdAttr = node->Attribute("workingDir")) cmd.workingDir = QString::fromUtf8(cwdAttr);
|
||||
if (cmd.workingDir.isEmpty()) {
|
||||
if (const char* cwdAttr2 = node->Attribute("cwd")) cmd.workingDir = QString::fromUtf8(cwdAttr2);
|
||||
}
|
||||
if (const char* enabledAttr = node->Attribute("enabled")) {
|
||||
QString en = QString::fromUtf8(enabledAttr).toLower();
|
||||
cmd.enabled = !(en == QLatin1String("false") || en == QLatin1String("0"));
|
||||
}
|
||||
if (const char* descAttr = node->Attribute("descript")) cmd.descript = QString::fromUtf8(descAttr);
|
||||
if (cmd.descript.isEmpty()) {
|
||||
if (const char* desc2 = node->Attribute("description")) cmd.descript = QString::fromUtf8(desc2);
|
||||
}
|
||||
if (const char* timeoutAttr = node->Attribute("timeoutSec")) {
|
||||
bool ok = false; int v = QString::fromUtf8(timeoutAttr).toInt(&ok);
|
||||
if (ok && v > 0) cmd.timeoutMs = v * 1000;
|
||||
}
|
||||
// env: either attribute env="KEY=VAL;K2=V2" or child elements <env key="" value=""/>
|
||||
if (const char* envAttr = node->Attribute("env")) {
|
||||
cmd.env = parseEnvAttr(QString::fromUtf8(envAttr));
|
||||
}
|
||||
for (auto* envNode = node->FirstChildElement("env"); envNode; envNode = envNode->NextSiblingElement("env")) {
|
||||
const char* k = envNode->Attribute("key");
|
||||
const char* v = envNode->Attribute("value");
|
||||
if (k && v) cmd.env.insert(QString::fromUtf8(k), QString::fromUtf8(v));
|
||||
}
|
||||
|
||||
// Pre-build args list from rawArgs (actual insertion of path happens in executor)
|
||||
if (!cmd.rawArgs.isEmpty()) {
|
||||
for (const auto& part : cmd.rawArgs.split(' ', Qt::SkipEmptyParts)) {
|
||||
cmd.args << part;
|
||||
}
|
||||
}
|
||||
|
||||
// when routing
|
||||
WorkSpace::CommandWhen target = WorkSpace::CommandWhen::OnCreate; // default
|
||||
if (const char* whenAttr = node->Attribute("when")) {
|
||||
QString wa = QString::fromUtf8(whenAttr).toLower();
|
||||
if (wa == QLatin1String("onload")) target = WorkSpace::CommandWhen::OnLoad;
|
||||
}
|
||||
|
||||
auto exec = std::make_unique<CommandExecutor>(cmd);
|
||||
if (target == WorkSpace::CommandWhen::OnCreate) onCreate_.push_back(std::move(exec));
|
||||
else onLoad_.push_back(std::move(exec));
|
||||
}
|
||||
}
|
||||
|
||||
void CommandManager::Execute(WorkSpace* ws, WorkSpace::CommandWhen when) {
|
||||
// Reload each time to reflect latest XML
|
||||
Reload(ws);
|
||||
auto& list = (when == WorkSpace::CommandWhen::OnCreate) ? onCreate_ : onLoad_;
|
||||
for (auto& exec : list) {
|
||||
exec->Execute(ws, when);
|
||||
}
|
||||
}
|
||||
17
src/workspace/CommandManager.h
Normal file
17
src/workspace/CommandManager.h
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "workspace/WorkSpace.h"
|
||||
#include "workspace/CommandExecutor.h"
|
||||
|
||||
class CommandManager {
|
||||
public:
|
||||
void Reload(WorkSpace* ws);
|
||||
void Execute(WorkSpace* ws, WorkSpace::CommandWhen when);
|
||||
|
||||
private:
|
||||
std::vector<std::unique_ptr<CommandExecutor>> onCreate_;
|
||||
std::vector<std::unique_ptr<CommandExecutor>> onLoad_;
|
||||
};
|
||||
34
src/workspace/FileEntry.h
Normal file
34
src/workspace/FileEntry.h
Normal file
@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include <QString>
|
||||
|
||||
enum class FileEntryType {
|
||||
Curve,
|
||||
Surface,
|
||||
Table,
|
||||
Light
|
||||
};
|
||||
|
||||
struct FileEntry {
|
||||
FileEntryType type;
|
||||
QString fileName; // relative file name under workspace dir; may be empty
|
||||
};
|
||||
|
||||
inline const char* FileEntryTypeToString(FileEntryType t) {
|
||||
switch (t) {
|
||||
case FileEntryType::Curve: return "curve";
|
||||
case FileEntryType::Surface: return "surface";
|
||||
case FileEntryType::Table: return "table";
|
||||
case FileEntryType::Light: return "light";
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
inline bool FileEntryTypeFromString(const char* s, FileEntryType& out) {
|
||||
if (!s) return false;
|
||||
if (0 == strcmp(s, "curve")) { out = FileEntryType::Curve; return true; }
|
||||
if (0 == strcmp(s, "surface")) { out = FileEntryType::Surface; return true; }
|
||||
if (0 == strcmp(s, "table")) { out = FileEntryType::Table; return true; }
|
||||
if (0 == strcmp(s, "light")) { out = FileEntryType::Light; return true; }
|
||||
return false;
|
||||
}
|
||||
@ -6,6 +6,7 @@
|
||||
|
||||
#include "workspace/WorkSpaceXMLParse.h"
|
||||
#include "workspace/WorkSpaceXMLWrite.h"
|
||||
#include "workspace/CommandManager.h"
|
||||
|
||||
#include "workspace/WorkSpaceItem.h"
|
||||
#include "workspace/Timestep.h"
|
||||
@ -15,6 +16,7 @@
|
||||
#include "common/SpdLogger.h"
|
||||
#include "entities/Entity.h"
|
||||
#include "utils/FileUtils.h"
|
||||
#include <QProcess>
|
||||
//#include "workspace/WorkSpaceItemGroup.h"
|
||||
//#include "workspace/WorkSpaceRiverGroup.h"
|
||||
//#include "workspace/WorkSpaceRiverNetGroup.h"
|
||||
@ -25,6 +27,7 @@ WorkSpace::WorkSpace(QObject* parent) noexcept
|
||||
: QObject(parent) {
|
||||
uuid_ = QUuid::createUuid().toString();
|
||||
homeViewpoint_ = osgEarth::Viewpoint("home", 120.000000, 25.000000, 100.000000, -2.500000, -90.000000, 8200000.000000);
|
||||
cmdMgr_ = std::make_unique<CommandManager>();
|
||||
}
|
||||
|
||||
WorkSpace::WorkSpace(const QString& path, QObject* parent)
|
||||
@ -32,6 +35,7 @@ WorkSpace::WorkSpace(const QString& path, QObject* parent)
|
||||
, path_(path){
|
||||
uuid_ = QUuid::createUuid().toString();
|
||||
homeViewpoint_ = osgEarth::Viewpoint("home", 120.000000, 25.000000, 100.000000, -2.500000, -90.000000, 8200000.000000);
|
||||
cmdMgr_ = std::make_unique<CommandManager>();
|
||||
}
|
||||
|
||||
const QString WorkSpace::GetDir() const {
|
||||
@ -39,6 +43,22 @@ const QString WorkSpace::GetDir() const {
|
||||
return info.absolutePath();
|
||||
}
|
||||
|
||||
void WorkSpace::SetCommondFilePath(const QString& path) {
|
||||
QFileInfo fileInfo(path);
|
||||
QString dirPath = QString("%1/%2").arg(GetDir(), fileInfo.fileName());
|
||||
bool sucess = FileUtils::CopyFileToPath(path, dirPath, true);
|
||||
LOG_INFO("copy commond file {}: {} to {}",
|
||||
path.toLocal8Bit().data(),
|
||||
dirPath.toLocal8Bit().data(),
|
||||
sucess);
|
||||
commondPath_ = fileInfo.fileName();
|
||||
}
|
||||
|
||||
const QString WorkSpace::GetCommondFilePath() const {
|
||||
QString path = QString("%1/%2").arg(GetDir(), commondPath_);
|
||||
return path;
|
||||
}
|
||||
|
||||
void WorkSpace::SetSimMatlab(const QString& path) {
|
||||
QFileInfo fileInfo(path);
|
||||
QString dirPath = QString("%1/%2").arg(GetDir(), fileInfo.fileName());
|
||||
@ -103,6 +123,87 @@ void WorkSpace::SetRDPath(const QString& path)
|
||||
rdFile_ = fileInfo.fileName();
|
||||
}
|
||||
|
||||
std::vector<FileEntry> WorkSpace::GetFileEntries(FileEntryType type) const {
|
||||
auto it = files_.find(type);
|
||||
if (it == files_.end()) {
|
||||
return {};
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
|
||||
WorkSpace::FileEntryResult WorkSpace::CreateFileEntry(FileEntryType type) {
|
||||
auto& vec = files_[type];
|
||||
if (vec.size() >= 9) {
|
||||
return FileEntryResult::LimitExceeded;
|
||||
}
|
||||
// push a placeholder; actual filename may be set elsewhere via SetWavePath/SetRDPath/etc
|
||||
vec.push_back(FileEntry{ type, QString() });
|
||||
++filesSeq_;
|
||||
// Notify listeners (e.g., PropertyBrowser) to refresh workspace properties
|
||||
emit FilesChanged(type);
|
||||
return FileEntryResult::Ok;
|
||||
}
|
||||
|
||||
bool WorkSpace::SetFileEntryCount(FileEntryType type, int count) {
|
||||
if (count < 0) count = 0;
|
||||
if (count > 9) count = 9;
|
||||
auto& vec = files_[type];
|
||||
if (static_cast<int>(vec.size()) == count) {
|
||||
return true;
|
||||
}
|
||||
if (static_cast<int>(vec.size()) < count) {
|
||||
int toAdd = count - static_cast<int>(vec.size());
|
||||
for (int i = 0; i < toAdd; ++i) {
|
||||
vec.push_back(FileEntry{ type, QString() });
|
||||
}
|
||||
} else {
|
||||
vec.resize(count);
|
||||
}
|
||||
++filesSeq_;
|
||||
emit FilesChanged(type);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WorkSpace::SetFileEntryPath(FileEntryType type, int index, const QString& path) {
|
||||
auto& vec = files_[type];
|
||||
if (index < 0 || index >= static_cast<int>(vec.size())) {
|
||||
return false;
|
||||
}
|
||||
QFileInfo fileInfo(path);
|
||||
if (!fileInfo.exists()) {
|
||||
return false;
|
||||
}
|
||||
QString dirPath = QString("%1/%2").arg(GetDir(), fileInfo.fileName());
|
||||
bool sucess = FileUtils::CopyFileToPath(path, dirPath, true);
|
||||
LOG_INFO("copy grouped file {}: {} to {}",
|
||||
path.toLocal8Bit().data(),
|
||||
dirPath.toLocal8Bit().data(),
|
||||
sucess);
|
||||
if (!sucess) {
|
||||
return false;
|
||||
}
|
||||
vec[index].fileName = fileInfo.fileName();
|
||||
++filesSeq_;
|
||||
emit FilesChanged(type);
|
||||
return true;
|
||||
}
|
||||
|
||||
QString WorkSpace::GetFileEntryAbsPath(FileEntryType type, int index) const {
|
||||
auto it = files_.find(type);
|
||||
if (it == files_.end()) {
|
||||
return QString();
|
||||
}
|
||||
const auto& vec = it->second;
|
||||
if (index < 0 || index >= static_cast<int>(vec.size())) {
|
||||
return QString();
|
||||
}
|
||||
const QString& name = vec[index].fileName;
|
||||
if (name.isEmpty()) {
|
||||
return QString();
|
||||
}
|
||||
return QString("%1/%2").arg(GetDir(), name);
|
||||
}
|
||||
|
||||
const QString WorkSpace::GetRDPath() const
|
||||
{
|
||||
QString path = QString("%1/%2").arg(GetDir(), rdFile_);
|
||||
@ -282,4 +383,13 @@ void WorkSpace::OnLoaded() {
|
||||
if (nullptr != timestep_) {
|
||||
emit TimestepChanged(timestep_);
|
||||
}
|
||||
// Execute commands configured for onLoad
|
||||
ExecuteCommands(CommandWhen::OnLoad);
|
||||
}
|
||||
|
||||
void WorkSpace::ExecuteCommands(CommandWhen when) {
|
||||
if (!cmdMgr_) {
|
||||
cmdMgr_ = std::make_unique<CommandManager>();
|
||||
}
|
||||
cmdMgr_->Execute(this, when);
|
||||
}
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <cstdint>
|
||||
#include <QObject>
|
||||
|
||||
#include <osgEarth/Viewpoint>
|
||||
@ -9,10 +11,12 @@
|
||||
#include "scene/OEScene.h"
|
||||
#include "config.h"
|
||||
#include "common/SpdLogger.h"
|
||||
#include "workspace/FileEntry.h"
|
||||
|
||||
//#include "../ui/chartPlot/DYTChart.h"
|
||||
|
||||
class WorkSpaceItem;
|
||||
class CommandManager;
|
||||
|
||||
class WorkSpace : public QObject {
|
||||
Q_OBJECT
|
||||
@ -46,6 +50,14 @@ public:
|
||||
inline const QString& GetDescribe() const {
|
||||
return describe_;
|
||||
}
|
||||
|
||||
void SetCommondFilePath(const QString& path);
|
||||
const QString GetCommondFilePath() const;
|
||||
|
||||
// Execute command xml according to trigger
|
||||
enum class CommandWhen { OnCreate, OnLoad };
|
||||
void ExecuteCommands(CommandWhen when);
|
||||
|
||||
void SetSimMatlab(const QString& path);
|
||||
const QString GetSimMatlab() const;
|
||||
|
||||
@ -65,6 +77,16 @@ public:
|
||||
void SetRDPath(const QString& path);
|
||||
const QString GetRDPath() const;
|
||||
|
||||
// Files list API (per-type, max 9 per type)
|
||||
enum class FileEntryResult { Ok, LimitExceeded, Duplicate, CopyFailed };
|
||||
FileEntryResult CreateFileEntry(FileEntryType type);
|
||||
std::vector<FileEntry> GetFileEntries(FileEntryType type) const;
|
||||
|
||||
// Manage grouped file entries
|
||||
bool SetFileEntryCount(FileEntryType type, int count);
|
||||
bool SetFileEntryPath(FileEntryType type, int index, const QString& path);
|
||||
QString GetFileEntryAbsPath(FileEntryType type, int index) const;
|
||||
|
||||
inline void SetHomeViewpoint(const osgEarth::Viewpoint& viewpoint) {
|
||||
homeViewpoint_ = viewpoint;
|
||||
homeViewpoint_.setHeading(0.0); // Ensure heading is set to 0.0
|
||||
@ -119,10 +141,12 @@ public:
|
||||
void OnLoaded();
|
||||
|
||||
Q_SIGNALS:
|
||||
void EntityAdded(class Entity* entity);
|
||||
void EntityRemoved(class Entity* entity);
|
||||
void TimestepChanged(class Timestep* timestep);
|
||||
void LampStatusChanged(class LampStatus* lampStatus);
|
||||
void EntityAdded(class Entity* entity);
|
||||
void EntityRemoved(class Entity* entity);
|
||||
void TimestepChanged(class Timestep* timestep);
|
||||
void LampStatusChanged(class LampStatus* lampStatus);
|
||||
// Emitted when grouped file entries change (count or path or creation)
|
||||
void FilesChanged(FileEntryType type);
|
||||
|
||||
protected:
|
||||
const QString& GetSimMatlabName() const {
|
||||
@ -134,6 +158,7 @@ private:
|
||||
QString uuid_;
|
||||
QString describe_;
|
||||
QString path_;
|
||||
QString commondPath_;
|
||||
QString simMatlabPath_;
|
||||
|
||||
QString waveFile_;
|
||||
@ -144,11 +169,19 @@ private:
|
||||
osgEarth::Viewpoint homeViewpoint_;
|
||||
|
||||
bool leaded_{ false };
|
||||
std::vector<class Entity*> entities_;
|
||||
OEScene* scene_{ nullptr };
|
||||
class Timestep* timestep_{ nullptr };
|
||||
class LampStatus* lampStatus_{ nullptr };
|
||||
std::vector<class Entity*> entities_;
|
||||
OEScene* scene_{ nullptr };
|
||||
class Timestep* timestep_{ nullptr };
|
||||
class LampStatus* lampStatus_{ nullptr };
|
||||
class Entity* trackedEntity_{ nullptr };
|
||||
// Stored as file entries under workspace dir, keyed by type
|
||||
std::map<FileEntryType, std::vector<FileEntry>> files_;
|
||||
// Monotonic sequence for file entries changes, used to trigger UI refresh
|
||||
std::uint64_t filesSeq_{ 0 };
|
||||
// Executor for command XML actions
|
||||
std::unique_ptr<CommandManager> cmdMgr_;
|
||||
public:
|
||||
std::uint64_t GetFilesSeq() const { return filesSeq_; }
|
||||
friend class WorkSpaceXMLWrite;
|
||||
};
|
||||
|
||||
|
||||
@ -84,6 +84,30 @@ bool WorkSpaceXMLParse::ParseLamp(const tinyxml2::XMLElement* element) {
|
||||
return workSpace_->SetLampPath(path);
|
||||
}
|
||||
|
||||
bool WorkSpaceXMLParse::ParseFiles(const tinyxml2::XMLElement* element) {
|
||||
if (nullptr == element) {
|
||||
LOG_WARN("element is nullptr");
|
||||
return false;
|
||||
}
|
||||
|
||||
const tinyxml2::XMLElement* typeElement = element->FirstChildElement("type");
|
||||
while (nullptr != typeElement) {
|
||||
const char* name = typeElement->Attribute("name");
|
||||
int count = 0;
|
||||
typeElement->QueryIntAttribute("count", &count);
|
||||
if (nullptr != name && count > 0) {
|
||||
FileEntryType enumType;
|
||||
if (FileEntryTypeFromString(name, enumType)) {
|
||||
for (int i = 0; i < count; ++i) {
|
||||
workSpace_->CreateFileEntry(enumType);
|
||||
}
|
||||
}
|
||||
}
|
||||
typeElement = typeElement->NextSiblingElement("type");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WorkSpaceXMLParse::ParseEntities(const tinyxml2::XMLElement* element) {
|
||||
if (nullptr == element) {
|
||||
LOG_WARN("element is nullptr");
|
||||
@ -238,6 +262,9 @@ bool WorkSpaceXMLParse::Load(const QString& dyt) {
|
||||
else if (0 == strcmp(name, "SimMatlab")) {
|
||||
ParseSimMatlab(xmlElement);
|
||||
}
|
||||
else if (0 == strcmp(name, "files")) {
|
||||
ParseFiles(xmlElement);
|
||||
}
|
||||
xmlElement = xmlElement->NextSiblingElement();
|
||||
}
|
||||
|
||||
|
||||
@ -35,6 +35,7 @@ private:
|
||||
bool ParseChart(const tinyxml2::XMLElement* element);
|
||||
bool ParseReport(const tinyxml2::XMLElement* element);
|
||||
bool ParseSimMatlab(const tinyxml2::XMLElement* element);
|
||||
bool ParseFiles(const tinyxml2::XMLElement* element);
|
||||
|
||||
private:
|
||||
QString name_;
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
#include "utils/StringUtils.h"
|
||||
|
||||
#include "workspace/WorkSpaceManager.h"
|
||||
#include "workspace/FileEntry.h"
|
||||
|
||||
WorkSpaceXMLWrite::WorkSpaceXMLWrite(WorkSpace* workspace, QObject* parent) noexcept
|
||||
: QObject(parent)
|
||||
@ -35,6 +36,7 @@ bool WorkSpaceXMLWrite::Save(const QString& path) {
|
||||
SaveChart(scene, &doc);
|
||||
SaveTimeStep(scene);
|
||||
SaveLamp(scene);
|
||||
SaveFiles(scene, &doc);
|
||||
|
||||
tinyxml2::XMLElement* entitiesXml = scene->InsertNewChildElement("entities");
|
||||
std::vector<Entity*>& entities = workSpace_->GetEntities();
|
||||
@ -120,3 +122,19 @@ bool WorkSpaceXMLWrite::SaveChart(tinyxml2::XMLElement* scene, tinyxml2::XMLDocu
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WorkSpaceXMLWrite::SaveFiles(tinyxml2::XMLElement* scene, tinyxml2::XMLDocument* doc) {
|
||||
// Persist multi-file entries per type as counts
|
||||
tinyxml2::XMLElement* files = doc->NewElement("files");
|
||||
scene->LinkEndChild(files);
|
||||
|
||||
for (const auto& kv : workSpace_->files_) {
|
||||
const FileEntryType type = kv.first;
|
||||
const auto& vec = kv.second;
|
||||
tinyxml2::XMLElement* typeElem = doc->NewElement("type");
|
||||
typeElem->SetAttribute("name", FileEntryTypeToString(type));
|
||||
typeElem->SetAttribute("count", static_cast<int>(vec.size()));
|
||||
files->LinkEndChild(typeElem);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -16,11 +16,12 @@ public:
|
||||
bool Save(const QString& path);
|
||||
|
||||
protected:
|
||||
bool SaveScene(tinyxml2::XMLElement* scene);
|
||||
bool SaveTimeStep(tinyxml2::XMLElement* scene);
|
||||
bool SaveLamp(tinyxml2::XMLElement* scene);
|
||||
bool SaveEntities(tinyxml2::XMLElement* scene, tinyxml2::XMLDocument* doc);
|
||||
bool SaveChart(tinyxml2::XMLElement* scene, tinyxml2::XMLDocument* doc);
|
||||
bool SaveScene(tinyxml2::XMLElement* scene);
|
||||
bool SaveTimeStep(tinyxml2::XMLElement* scene);
|
||||
bool SaveLamp(tinyxml2::XMLElement* scene);
|
||||
bool SaveEntities(tinyxml2::XMLElement* scene, tinyxml2::XMLDocument* doc);
|
||||
bool SaveChart(tinyxml2::XMLElement* scene, tinyxml2::XMLDocument* doc);
|
||||
bool SaveFiles(tinyxml2::XMLElement* scene, tinyxml2::XMLDocument* doc);
|
||||
private:
|
||||
WorkSpace* workSpace_;
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user