Merge branch 'new_osg' of http://brigecode.icu:16623/PM/DYTSrouce into new_osg

This commit is contained in:
pimin 2025-10-16 16:36:32 +08:00
commit dc83646fab
27 changed files with 1272 additions and 109 deletions

View File

@ -559,27 +559,27 @@
<context>
<name>MainFrame</name>
<message>
<location filename="../ui/MainFrame.cpp" line="43"/>
<location filename="../ui/MainFrame.cpp" line="45"/>
<source>Dyt</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/MainFrame.cpp" line="102"/>
<location filename="../ui/MainFrame.cpp" line="104"/>
<source>file manager</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/MainFrame.cpp" line="108"/>
<location filename="../ui/MainFrame.cpp" line="114"/>
<source>simu manager</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/MainFrame.cpp" line="111"/>
<location filename="../ui/MainFrame.cpp" line="117"/>
<source>play manager</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/MainFrame.cpp" line="114"/>
<location filename="../ui/MainFrame.cpp" line="120"/>
<source>system manager</source>
<translation type="unfinished"></translation>
</message>
@ -592,132 +592,132 @@
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/MainWindow.cpp" line="58"/>
<location filename="../ui/MainWindow.cpp" line="61"/>
<source>model elements</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/MainWindow.cpp" line="66"/>
<location filename="../ui/MainWindow.cpp" line="69"/>
<source>attribte</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/MainWindow.cpp" line="82"/>
<location filename="../ui/MainWindow.cpp" line="85"/>
<source>Main View</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/MainWindow.cpp" line="116"/>
<location filename="../ui/MainWindow.cpp" line="119"/>
<source>Wave Curve</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/MainWindow.cpp" line="125"/>
<location filename="../ui/MainWindow.cpp" line="128"/>
<source>Speed Curve</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/MainWindow.cpp" line="138"/>
<location filename="../ui/MainWindow.cpp" line="141"/>
<source>3D Curve</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/MainWindow.cpp" line="154"/>
<location filename="../ui/MainWindow.cpp" line="157"/>
<source>Target number</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/MainWindow.cpp" line="154"/>
<location filename="../ui/MainWindow.cpp" line="157"/>
<source>Signal-to-noise ratio</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/MainWindow.cpp" line="155"/>
<location filename="../ui/MainWindow.cpp" line="158"/>
<source>Azimuth line of sight</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/MainWindow.cpp" line="155"/>
<location filename="../ui/MainWindow.cpp" line="158"/>
<source>Pitch gaze angle</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/MainWindow.cpp" line="156"/>
<location filename="../ui/MainWindow.cpp" line="159"/>
<source>azimuth</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/MainWindow.cpp" line="156"/>
<location filename="../ui/MainWindow.cpp" line="159"/>
<source>Pitch angle</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/MainWindow.cpp" line="157"/>
<location filename="../ui/MainWindow.cpp" line="160"/>
<source>attribute</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/MainWindow.cpp" line="157"/>
<location filename="../ui/MainWindow.cpp" line="160"/>
<source>Doppler</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/MainWindow.cpp" line="158"/>
<location filename="../ui/MainWindow.cpp" line="161"/>
<source>course</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/MainWindow.cpp" line="158"/>
<location filename="../ui/MainWindow.cpp" line="161"/>
<source>Speed</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/MainWindow.cpp" line="159"/>
<location filename="../ui/MainWindow.cpp" line="162"/>
<source>longitude</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/MainWindow.cpp" line="159"/>
<location filename="../ui/MainWindow.cpp" line="162"/>
<source>latitude</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/MainWindow.cpp" line="160"/>
<location filename="../ui/MainWindow.cpp" line="163"/>
<source>distance</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/MainWindow.cpp" line="160"/>
<location filename="../ui/MainWindow.cpp" line="163"/>
<source>velocity</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/MainWindow.cpp" line="161"/>
<location filename="../ui/MainWindow.cpp" line="164"/>
<source>Radial dimensions</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/MainWindow.cpp" line="161"/>
<location filename="../ui/MainWindow.cpp" line="164"/>
<source>Target RCS</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/MainWindow.cpp" line="167"/>
<location filename="../ui/MainWindow.cpp" line="170"/>
<source>Report Table</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/MainWindow.cpp" line="180"/>
<location filename="../ui/MainWindow.cpp" line="183"/>
<source>Signal Indicator Lamp</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/MainWindow.cpp" line="191"/>
<location filename="../ui/MainWindow.cpp" line="194"/>
<source>ParamSetting</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/MainWindow.cpp" line="200"/>
<location filename="../ui/MainWindow.cpp" line="203"/>
<source>bat File</source>
<translation type="unfinished"></translation>
</message>
@ -972,26 +972,26 @@
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8045"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8238"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8051"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8245"/>
<source>Curve[%1]</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8046"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8239"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8052"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8246"/>
<source>Surface[%1]</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8047"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8240"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8053"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8247"/>
<source>Table[%1]</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8048"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8241"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8054"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8248"/>
<source>Light[%1]</source>
<translation type="unfinished"></translation>
</message>
@ -1067,48 +1067,48 @@
<context>
<name>QtConeWaveComponentManager</name>
<message>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="9230"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="9239"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="9252"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="9261"/>
<source>ConeWaveComponent</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="9327"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="9349"/>
<source>Height</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="9334"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="9356"/>
<source>Radius</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="9341"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="9363"/>
<source>waveCount</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="9351"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="9373"/>
<source>waveSpeed</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="9358"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="9380"/>
<source>baseColor</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="9365"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="9387"/>
<source>waveColor</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="9372"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="9394"/>
<source>ringBrightAlpha</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="9379"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="9401"/>
<source>ringDarkAlpha</source>
<translation type="unfinished"></translation>
</message>
@ -1214,28 +1214,28 @@
<context>
<name>QtDashedLineComponentManager</name>
<message>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="9571"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="9580"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="9593"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="9602"/>
<source>DashedLineComponent</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="9649"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="9671"/>
<source>Start</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="9656"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="9678"/>
<source>End</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="9663"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="9685"/>
<source>Radius</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="9670"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="9692"/>
<source>Color</source>
<translation type="unfinished"></translation>
</message>
@ -1251,17 +1251,17 @@
<context>
<name>QtEntityPropertyManager</name>
<message>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8675"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8697"/>
<source>Name</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8682"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8704"/>
<source>Visible</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8689"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8711"/>
<source>Transform</source>
<translation type="unfinished"></translation>
</message>
@ -1343,13 +1343,13 @@
<context>
<name>QtMeshComponetManager</name>
<message>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8806"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8815"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8828"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8837"/>
<source>MeshComponent</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8888"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8910"/>
<source>Mesh</source>
<translation type="unfinished"></translation>
</message>
@ -1398,13 +1398,13 @@
<context>
<name>QtPathComponentManager</name>
<message>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8965"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8974"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8987"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8996"/>
<source>PathComponent</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="9047"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="9069"/>
<source>Path</source>
<translation type="unfinished"></translation>
</message>
@ -1654,87 +1654,92 @@
<context>
<name>QtWorkspacePropertyManager</name>
<message>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8282"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8289"/>
<source>Name</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8289"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8296"/>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8296"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8303"/>
<source>Timestep</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8303"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8310"/>
<source>SimMatlab</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8310"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8317"/>
<source>MatlabParam</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8317"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8324"/>
<source>WavePath</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8324"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8331"/>
<source>ReportPath</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8331"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8338"/>
<source>RDPath</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8354"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8346"/>
<source>CommondPath</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8369"/>
<source>Count</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8370"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8385"/>
<source>Curve[%1]</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8371"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8386"/>
<source>Surface[%1]</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8372"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8387"/>
<source>Table[%1]</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8373"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8388"/>
<source>Light[%1]</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8384"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8399"/>
<source>Curves</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8387"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8402"/>
<source>Surfaces</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8390"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8405"/>
<source>Tables</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8393"/>
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8408"/>
<source>Lights</source>
<translation type="unfinished"></translation>
</message>
@ -1762,6 +1767,29 @@
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>SimuRunMenu</name>
<message>
<location filename="../ui/Menu/SimuRunMenu.cpp" line="55"/>
<source>no workspace</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/Menu/SimuRunMenu.cpp" line="65"/>
<source>no commands</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/Menu/SimuRunMenu.cpp" line="72"/>
<source>Commands</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/Menu/SimuRunMenu.cpp" line="87"/>
<source>unnamed</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>SimuRunMenuClass</name>
<message>

View File

@ -25,6 +25,8 @@
#include "ui/Menu/ChartPlotMenu.h" // lz 20140914
#include "common/SpdLogger.h"
#include "ui/Menu/SimuRunMenu.h"
#include "ui_MainFrame.h"
#include "viewer/OsgWidget.h"
@ -104,8 +106,12 @@ void MainFrame::InitUI() {
//AddMenuWidget("view_manager", tr("view manager"), new ViewManagerMenu(this));
//AddMenuWidget("plan_manager", tr("plan manager"), new PlanManagerMenu(this));
//AddMenuWidget("dynamic_display", tr("dynamic display"), new DynamicDisplayMenu(this));
ChartPlotMenu* chartMenu = new ChartPlotMenu(this);
AddMenuWidget("simu_manager", tr("simu manager"), chartMenu);
// ChartPlotMenu* chartMenu = new ChartPlotMenu(this);
// AddMenuWidget("simu_manager", tr("simu manager"), chartMenu);
// Command buttons menu based on parsed commands
SimuRunMenu* simuRunMenu = new SimuRunMenu(this);
AddMenuWidget("simu_manager", tr("simu manager"), simuRunMenu);
PlayManagerMenu* playMenu = new PlayManagerMenu(this);
AddMenuWidget("play_manager", tr("play manager"), playMenu);

View File

@ -27,6 +27,9 @@
#include "Matlab/MatlabObject.h"
// 曲线面板管理器
#include "Panel/DataPanelManager.h"
#include "ui_MainWindow.h"
#include "viewer/OsgWidget.h"
#include "DockTitleBar.h"
@ -211,6 +214,13 @@ void MainWindow::InitUI() {
// InitDockLayout();
// 初始化数据面板管理器
dataPanelManager_ = new DataPanelManager(this, this);
// 连接工作空间变化信号
connect(&WorkSpaceManager::Get(), &WorkSpaceManager::WorkSpaceChanged,
dataPanelManager_, &DataPanelManager::OnWorkspaceChanged);
// Restore previous UI layout if available
UiLayoutManager::Restore(this, 1);
@ -230,6 +240,13 @@ void MainWindow::InitUI() {
void MainWindow::UninitUI() {
// Save layout state before tearing down widgets
UiLayoutManager::Save(this, 1);
// 清理数据面板管理器
if (dataPanelManager_) {
delete dataPanelManager_;
dataPanelManager_ = nullptr;
}
if (qtOsgViewWidget_) {
qtOsgViewWidget_->Uninitialize();
delete qtOsgViewWidget_;

View File

@ -10,6 +10,8 @@ namespace Ui {
class MainWindow;
}
class DataPanelManager;
class MainWindow : public QMainWindow {
Q_OBJECT
@ -37,6 +39,14 @@ public:
return surfaceDlg_;
}
/**
* @brief
* @return
*/
DataPanelManager* GetDataPanelManager() const {
return dataPanelManager_;
}
void slotShowUISetting();
public slots:
@ -68,6 +78,9 @@ private:
class CodeEdtUI* matlabFileDlg_{ nullptr };
class AddParamSetting* addParamDlg_{ nullptr };
// 数据面板管理器
DataPanelManager* dataPanelManager_{ nullptr };
QMap<QString, QDockWidget*> m_mapDockWidget;
ChartXMLMgr m_mgrChart;

View File

@ -1,10 +1,107 @@
#include "SimuRunMenu.h"
#include "ui/Menu/SimuRunMenu.h"
#include <QToolButton>
#include <QHBoxLayout>
#include <QLabel>
#include "workspace/WorkSpaceManager.h"
#include "workspace/WorkSpace.h"
#include "workspace/CommandManager.h"
SimuRunMenu::SimuRunMenu(QWidget *parent)
: QWidget(parent)
{
: QWidget(parent) {
ui.setupUi(this);
// Create a vertical layout to host grouped command rows
auto* layout = new QVBoxLayout(this);
layout->setContentsMargins(9, 0, 0, 0);
layout->setSpacing(6);
setLayout(layout);
// Refresh when workspace changes
connect(&WorkSpaceManager::Get(), &WorkSpaceManager::WorkSpaceChanged,
this, &SimuRunMenu::OnWorkspaceChanged);
// Initial population
RefreshButtons();
}
SimuRunMenu::~SimuRunMenu()
{}
SimuRunMenu::~SimuRunMenu() {
}
void SimuRunMenu::OnWorkspaceChanged(WorkSpace* ws) {
Q_UNUSED(ws);
RefreshButtons();
}
void SimuRunMenu::RefreshButtons() {
// Clear existing buttons
if (auto* layout = qobject_cast<QVBoxLayout*>(this->layout())) {
while (layout->count() > 0) {
QLayoutItem* item = layout->takeAt(0);
if (item) {
if (auto* w = item->widget()) {
w->deleteLater();
}
delete item;
}
}
}
auto* ws = WorkSpaceManager::Get().GetCurrent();
if (!ws) {
// Show hint when no workspace
if (auto* layout = qobject_cast<QVBoxLayout*>(this->layout())) {
auto* hint = new QLabel(tr("no workspace"), this);
layout->addWidget(hint);
}
return;
}
CommandManager mgr;
const auto items = mgr.ListCommands(ws);
if (items.empty()) {
if (auto* layout = qobject_cast<QVBoxLayout*>(this->layout())) {
auto* hint = new QLabel(tr("no commands"), this);
layout->addWidget(hint);
}
return;
}
// Render all commands in a single group without trigger distinction
CreateGroup(tr("Commands"), items);
}
void SimuRunMenu::CreateGroup(const QString& title,
const std::vector<Command>& items) {
auto* root = qobject_cast<QVBoxLayout*>(this->layout());
if (!root) return;
auto* label = new QLabel(title, this);
root->addWidget(label);
auto* row = new QHBoxLayout();
row->setSpacing(6);
for (const auto& item : items) {
auto* btn = new QToolButton(this);
btn->setText(item.name.isEmpty() ? tr("unnamed") : item.name);
QString tip = item.descript;
if (!item.program.isEmpty()) {
tip += QStringLiteral("\nprog: ") + item.program;
}
if (!item.path.isEmpty()) {
tip += QStringLiteral("\npath: ") + item.path;
}
btn->setToolTip(tip);
row->addWidget(btn);
connect(btn, &QToolButton::clicked, this, [name = item.name]() {
auto* wsCur = WorkSpaceManager::Get().GetCurrent();
if (!wsCur) return;
CommandManager execMgr;
execMgr.ExecuteByName(wsCur, name);
});
}
row->addStretch(1);
root->addLayout(row);
}

View File

@ -2,15 +2,25 @@
#include <QWidget>
#include "ui_SimuRunMenu.h"
#include "workspace/CommandManager.h"
#include "workspace/CommandExecutor.h"
class SimuRunMenu : public QWidget
{
class SimuRunMenu : public QWidget {
Q_OBJECT
public:
SimuRunMenu(QWidget *parent = nullptr);
~SimuRunMenu();
private slots:
void OnWorkspaceChanged(class WorkSpace* ws);
private:
void RefreshButtons();
void CreateGroup(const QString& title,
const std::vector<Command>& items);
private:
Ui::SimuRunMenuClass ui;
};

View File

@ -0,0 +1,48 @@
#include "ui/Panel/CurvePanel.h"
#include "ui/DockWidget.h"
#include "common/SpdLogger.h"
#include <QVBoxLayout>
#include <QLabel>
#include <QFileInfo>
CurvePanel::CurvePanel(int index, const QString& filePath, QWidget* parent)
: DataPanel(index, FileEntryType::Curve, filePath, parent)
{
LOG_INFO("Created CurvePanel {} for file: {}", index, filePath.toStdString());
}
CurvePanel::~CurvePanel()
{
LOG_INFO("Destroyed CurvePanel {}", GetIndex());
}
void CurvePanel::RefreshPanel()
{
// Implement curve-specific refresh logic here
// For now, just call the base class implementation
DataPanel::RefreshPanel();
LOG_INFO("Refreshed CurvePanel {}", GetIndex());
}
void CurvePanel::InitUI()
{
// Create basic layout
QVBoxLayout* layout = new QVBoxLayout(this);
// Add placeholder label showing panel information
QLabel* infoLabel = new QLabel(QString("Curve Panel %1\nFile: %2\n\nCurve Drawing Area\nPlease inherit this class to implement specific drawing functionality")
.arg(GetIndex())
.arg(QFileInfo(GetFilePath()).fileName()));
infoLabel->setAlignment(Qt::AlignCenter);
infoLabel->setStyleSheet("QLabel { color: #666; font-size: 12px; padding: 20px; }");
layout->addWidget(infoLabel);
setLayout(layout);
}
QString CurvePanel::GetTypeDisplayName() const
{
return "Curve";
}

55
src/ui/Panel/CurvePanel.h Normal file
View File

@ -0,0 +1,55 @@
#pragma once
#include "DataPanel.h"
/**
* @file CurvePanel.h
* @brief Curve Panel Class
* Specialized panel for curve data visualization and manipulation
*/
/**
* @brief Curve panel class
* Specialized panel for curve data, inherits from DataPanel
*/
class CurvePanel : public DataPanel
{
Q_OBJECT
public:
/**
* @brief Constructor
* @param index Panel index
* @param filePath Associated file path
* @param parent Parent widget
*/
explicit CurvePanel(int index, const QString& filePath, QWidget* parent = nullptr);
/**
* @brief Destructor
*/
virtual ~CurvePanel();
/**
* @brief Get file type
* @return File type (always Curve for this class)
*/
FileEntryType GetFileType() const override { return FileEntryType::Curve; }
/**
* @brief Refresh panel content
*/
void RefreshPanel() override;
protected:
/**
* @brief Initialize UI for curve-specific layout
*/
void InitUI() override;
/**
* @brief Get type display name
* @return Display name for curve type
*/
QString GetTypeDisplayName() const override;
};

View File

@ -0,0 +1,75 @@
#include "ui/Panel/DataPanel.h"
#include "ui/DockWidget.h"
#include "common/SpdLogger.h"
#include <QVBoxLayout>
#include <QLabel>
#include <QFileInfo>
#include <QCloseEvent>
DataPanel::DataPanel(int index, FileEntryType fileType, const QString& filePath, QWidget* parent)
: QWidget(parent)
, index_(index)
, fileType_(fileType)
, filePath_(filePath)
, title_()
, dockWidget_(nullptr)
{
title_ = GenerateTitle();
InitUI();
LOG_INFO("Created DataPanel {} for {} file: {}", index_, FileEntryTypeToString(fileType_), filePath_.toStdString());
}
DataPanel::~DataPanel()
{
LOG_INFO("Destroyed DataPanel {} ({})", index_, FileEntryTypeToString(fileType_));
}
void DataPanel::closeEvent(QCloseEvent* event)
{
emit PanelClosed();
event->accept();
}
void DataPanel::InitUI()
{
// Create basic layout
QVBoxLayout* layout = new QVBoxLayout(this);
// Add placeholder label showing panel information
QString typeDisplayName = GetTypeDisplayName();
QLabel* infoLabel = new QLabel(QString("Panel %1 (%2)\nFile: %3\n\n%4 Data Area\nPlease inherit this class to implement specific functionality")
.arg(index_)
.arg(typeDisplayName)
.arg(QFileInfo(filePath_).fileName())
.arg(typeDisplayName));
infoLabel->setAlignment(Qt::AlignCenter);
infoLabel->setStyleSheet("QLabel { color: #666; font-size: 12px; padding: 20px; }");
layout->addWidget(infoLabel);
setLayout(layout);
}
QString DataPanel::GenerateTitle()
{
QFileInfo fileInfo(filePath_);
QString typeDisplayName = GetTypeDisplayName();
return QString("%1 Panel %2 - %3").arg(typeDisplayName).arg(index_).arg(fileInfo.baseName());
}
QString DataPanel::GetTypeDisplayName() const
{
switch (fileType_) {
case FileEntryType::Curve:
return "Curve";
case FileEntryType::Surface:
return "Surface";
case FileEntryType::Table:
return "Table";
case FileEntryType::Light:
return "Light";
default:
return "Unknown";
}
}

115
src/ui/Panel/DataPanel.h Normal file
View File

@ -0,0 +1,115 @@
#pragma once
#include <QWidget>
#include <QString>
#include "workspace/FileEntry.h"
class DockWidget;
/**
* @file DataPanel.h
* @brief Data Panel Base Class
* Provides panel framework structure for different data types, specific functionality implemented by derived classes
*/
/**
* @brief Data panel base class
* Provides panel framework structure for different data types, specific functionality implemented by derived classes
*/
class DataPanel : public QWidget
{
Q_OBJECT
public:
/**
* @brief Constructor
* @param index Panel index
* @param fileType File type
* @param filePath Associated file path
* @param parent Parent widget
*/
explicit DataPanel(int index, FileEntryType fileType, const QString& filePath, QWidget* parent = nullptr);
/**
* @brief Destructor
*/
virtual ~DataPanel();
/**
* @brief Get panel index
* @return Panel index
*/
int GetIndex() const { return index_; }
/**
* @brief Get file type (virtual function, implemented by derived classes)
* @return File type
*/
virtual FileEntryType GetFileType() const { return fileType_; }
/**
* @brief Get file path
* @return File path
*/
QString GetFilePath() const { return filePath_; }
/**
* @brief Get panel title
* @return Panel title
*/
QString GetTitle() const { return title_; }
/**
* @brief Set dock widget reference
* @param dockWidget Dock widget pointer
*/
void SetDockWidget(DockWidget* dockWidget) { dockWidget_ = dockWidget; }
/**
* @brief Get dock widget reference
* @return Dock widget pointer
*/
DockWidget* GetDockWidget() const { return dockWidget_; }
/**
* @brief Refresh panel content (virtual function, implemented by derived classes)
*/
virtual void RefreshPanel() {}
signals:
/**
* @brief Panel close signal
*/
void PanelClosed();
protected:
/**
* @brief Close event handler
* @param event Close event
*/
void closeEvent(QCloseEvent* event) override;
/**
* @brief Initialize UI (virtual function, derived classes implement specific layout)
*/
virtual void InitUI();
/**
* @brief Generate panel title
* @return Generated title
*/
virtual QString GenerateTitle();
/**
* @brief Get type display name (virtual function, implemented by derived classes)
* @return Display name for the file type
*/
virtual QString GetTypeDisplayName() const;
private:
int index_; // Panel index
FileEntryType fileType_; // File type
QString filePath_; // Associated file path
QString title_; // Panel title
DockWidget* dockWidget_; // Dock widget reference
};

View File

@ -0,0 +1,67 @@
#include "DataPanelFactory.h"
#include "DataPanel.h"
#include "CurvePanel.h"
#include "common/SpdLogger.h"
// Forward declarations for future panel types
// #include "SurfacePanel.h"
// #include "TablePanel.h"
// #include "LightPanel.h"
DataPanel* DataPanelFactory::CreatePanel(int index, FileEntryType fileType, const QString& filePath, QWidget* parent)
{
switch (fileType) {
case FileEntryType::Curve:
// For now, create CurvePanel which should inherit from DataPanel
// TODO: Update CurvePanel to inherit from DataPanel
return new CurvePanel(index, filePath, parent);
case FileEntryType::Surface:
// TODO: Implement SurfacePanel
LOG_WARN("SurfacePanel not implemented yet, creating base DataPanel");
return new DataPanel(index, fileType, filePath, parent);
case FileEntryType::Table:
// TODO: Implement TablePanel
LOG_WARN("TablePanel not implemented yet, creating base DataPanel");
return new DataPanel(index, fileType, filePath, parent);
case FileEntryType::Light:
// TODO: Implement LightPanel
LOG_WARN("LightPanel not implemented yet, creating base DataPanel");
return new DataPanel(index, fileType, filePath, parent);
default:
LOG_ERROR("Unsupported file type: {}", static_cast<int>(fileType));
return nullptr;
}
}
bool DataPanelFactory::IsTypeSupported(FileEntryType fileType)
{
switch (fileType) {
case FileEntryType::Curve:
case FileEntryType::Surface:
case FileEntryType::Table:
case FileEntryType::Light:
return true;
default:
return false;
}
}
QString DataPanelFactory::GetTypeDisplayName(FileEntryType fileType)
{
switch (fileType) {
case FileEntryType::Curve:
return "Curve";
case FileEntryType::Surface:
return "Surface";
case FileEntryType::Table:
return "Table";
case FileEntryType::Light:
return "Light";
default:
return "Unknown";
}
}

View File

@ -0,0 +1,49 @@
#pragma once
#include <memory>
#include "workspace/FileEntry.h"
class DataPanel;
class QWidget;
/**
* @file DataPanelFactory.h
* @brief Data Panel Factory
* Creates appropriate panel instances based on file type
*/
/**
* @brief Data panel factory class
* Creates appropriate panel instances based on file type using factory pattern
*/
class DataPanelFactory
{
public:
/**
* @brief Create panel based on file type
* @param index Panel index
* @param fileType File type
* @param filePath File path
* @param parent Parent widget
* @return Created panel pointer (caller takes ownership)
*/
static DataPanel* CreatePanel(int index, FileEntryType fileType, const QString& filePath, QWidget* parent = nullptr);
/**
* @brief Check if file type is supported
* @param fileType File type to check
* @return True if supported, false otherwise
*/
static bool IsTypeSupported(FileEntryType fileType);
/**
* @brief Get display name for file type
* @param fileType File type
* @return Display name
*/
static QString GetTypeDisplayName(FileEntryType fileType);
private:
// Private constructor to prevent instantiation
DataPanelFactory() = default;
};

View File

@ -0,0 +1,296 @@
#include "DataPanelManager.h"
#include "DataPanel.h"
#include "DataPanelFactory.h"
#include "ui/DockWidget.h"
#include "ui/DockTitleBar.h"
#include "ui/MainWindow.h"
#include "workspace/FileEntry.h"
#include "common/SpdLogger.h"
#include <QFileInfo>
#include <QDir>
const QString DataPanelManager::PANEL_OBJECT_NAME_PREFIX = "DataPanel_";
DataPanelManager::DataPanelManager(MainWindow* mainWindow, QObject* parent)
: QObject(parent)
, mainWindow_(mainWindow)
, currentWorkspace_(nullptr)
{
LOG_INFO("DataPanelManager initialized");
}
DataPanelManager::~DataPanelManager()
{
ClearAllPanels();
LOG_INFO("DataPanelManager destroyed");
}
void DataPanelManager::SetWorkspace(WorkSpace* workspace)
{
if (currentWorkspace_ == workspace) {
return;
}
// Disconnect old workspace signal connections
if (currentWorkspace_) {
disconnect(currentWorkspace_, nullptr, this, nullptr);
}
currentWorkspace_ = workspace;
// Connect new workspace signals
if (currentWorkspace_) {
connect(currentWorkspace_, &WorkSpace::FilesChanged, this, &DataPanelManager::OnFilesChanged);
}
// Update all panel types
if (currentWorkspace_) {
UpdatePanelsForType(FileEntryType::Curve);
UpdatePanelsForType(FileEntryType::Surface);
UpdatePanelsForType(FileEntryType::Table);
UpdatePanelsForType(FileEntryType::Light);
} else {
ClearAllPanels();
}
}
int DataPanelManager::GetActivePanelCount(FileEntryType fileType) const
{
if (static_cast<int>(fileType) == -1) {
// Return total count
return dataPanels_.size();
}
// Count panels of specific type
int count = 0;
for (auto it = dataPanels_.begin(); it != dataPanels_.end(); ++it) {
if (it.value()->GetFileType() == fileType) {
count++;
}
}
return count;
}
QList<DataPanel*> DataPanelManager::GetPanelsOfType(FileEntryType fileType) const
{
QList<DataPanel*> panels;
for (auto it = dataPanels_.begin(); it != dataPanels_.end(); ++it) {
if (it.value()->GetFileType() == fileType) {
panels.append(it.value());
}
}
return panels;
}
void DataPanelManager::OnWorkspaceChanged(WorkSpace* workspace)
{
SetWorkspace(workspace);
}
void DataPanelManager::OnFilesChanged(FileEntryType type)
{
// Only respond to supported file types
if (!DataPanelFactory::IsTypeSupported(type)) {
return;
}
UpdatePanelsForType(type);
}
void DataPanelManager::OnPanelClosed()
{
DataPanel* panel = qobject_cast<DataPanel*>(sender());
if (panel) {
RemovePanel(panel);
}
}
void DataPanelManager::UpdatePanelsForType(FileEntryType fileType)
{
if (!currentWorkspace_) {
ClearPanelsOfType(fileType);
return;
}
// Get files of specified type from current workspace
std::vector<FileEntry> files = currentWorkspace_->GetFileEntries(fileType);
// Limit to maximum panels per type
const int maxPanels = qMin(static_cast<int>(files.size()), GetMaxPanelCount());
// Find panels to remove (excess panels of this type)
QStringList keysToRemove;
for (auto it = dataPanels_.begin(); it != dataPanels_.end(); ++it) {
DataPanel* panel = it.value();
if (panel->GetFileType() == fileType && panel->GetIndex() >= maxPanels) {
keysToRemove.append(it.key());
}
}
// Remove excess panels
for (const QString& key : keysToRemove) {
RemovePanel(dataPanels_[key]);
}
// Create or update panels
for (int i = 0; i < maxPanels; ++i) {
const FileEntry& fileEntry = files[i];
QString filePath = currentWorkspace_->GetFileEntryAbsPath(fileEntry.type, i);
QString panelKey = QString("%1_%2").arg(FileEntryTypeToString(fileType)).arg(i);
if (dataPanels_.contains(panelKey)) {
// Check if file path has changed
DataPanel* existingPanel = dataPanels_[panelKey];
if (existingPanel->GetFilePath() != filePath) {
// File path changed, recreate panel
RemovePanel(existingPanel);
CreateDataPanel(fileType, filePath);
} else {
// File path unchanged, refresh data
existingPanel->RefreshPanel();
}
} else {
// Create new panel
CreateDataPanel(fileType, filePath);
}
}
}
DataPanel* DataPanelManager::CreateDataPanel(FileEntryType fileType, const QString& filePath)
{
if (GetActivePanelCount(fileType) >= GetMaxPanelCount()) {
LOG_WARN("Cannot create more {} panels, maximum count reached: {}",
FileEntryTypeToString(fileType), GetMaxPanelCount());
return nullptr;
}
// Find next available index for this file type
int index = FindNextAvailableIndex(fileType);
QString panelKey = QString("%1_%2").arg(FileEntryTypeToString(fileType)).arg(index);
// Create dock widget
DockWidget* dockWidget = new DockWidget(mainWindow_);
dockWidget->setObjectName(GeneratePanelObjectName(fileType, index));
// Set title bar
DockTitleBar* titleBar = new DockTitleBar(dockWidget);
dockWidget->SetDockWidgetTitleBar(titleBar);
// Connect signals
connect(dockWidget, &DockWidget::dockLocationChanged, this, [this](Qt::DockWidgetArea area) {
// Handle dock location changes if needed
});
// Add to main window
mainWindow_->addDockWidget(Qt::RightDockWidgetArea, dockWidget);
// Create panel using factory
DataPanel* panel = DataPanelFactory::CreatePanel(index, fileType, filePath, dockWidget);
if (!panel) {
LOG_ERROR("Failed to create panel for type: {}", FileEntryTypeToString(fileType));
dockWidget->deleteLater();
return nullptr;
}
dockWidget->setWidget(panel);
// Set panel's dock widget reference
panel->SetDockWidget(dockWidget);
// Connect panel signals
connect(panel, &DataPanel::PanelClosed, this, &DataPanelManager::OnPanelClosed);
// Save references
dataPanels_[panelKey] = panel;
dockWidgets_[panelKey] = dockWidget;
LOG_INFO("Created {} panel {} for file: {}",
FileEntryTypeToString(fileType), index, filePath.toStdString());
return panel;
}
void DataPanelManager::RemovePanel(DataPanel* panel)
{
if (!panel) {
return;
}
// Find panel key
QString panelKey;
for (auto it = dataPanels_.begin(); it != dataPanels_.end(); ++it) {
if (it.value() == panel) {
panelKey = it.key();
break;
}
}
if (panelKey.isEmpty()) {
return;
}
// Remove dock widget
if (dockWidgets_.contains(panelKey)) {
DockWidget* dockWidget = dockWidgets_[panelKey];
mainWindow_->removeDockWidget(dockWidget);
dockWidget->deleteLater();
}
// Remove from mappings
dataPanels_.remove(panelKey);
dockWidgets_.remove(panelKey);
// Delete panel
panel->deleteLater();
LOG_INFO("Removed {} panel {}",
FileEntryTypeToString(panel->GetFileType()), panel->GetIndex());
}
void DataPanelManager::ClearAllPanels()
{
// Get copy of all keys
QStringList keys = dataPanels_.keys();
// Remove panels one by one
for (const QString& key : keys) {
RemovePanel(dataPanels_[key]);
}
LOG_INFO("Cleared all data panels");
}
void DataPanelManager::ClearPanelsOfType(FileEntryType fileType)
{
QStringList keysToRemove;
for (auto it = dataPanels_.begin(); it != dataPanels_.end(); ++it) {
if (it.value()->GetFileType() == fileType) {
keysToRemove.append(it.key());
}
}
for (const QString& key : keysToRemove) {
RemovePanel(dataPanels_[key]);
}
LOG_INFO("Cleared all {} panels", FileEntryTypeToString(fileType));
}
QString DataPanelManager::GeneratePanelObjectName(FileEntryType fileType, int index) const
{
return QString("%1%2_%3").arg(PANEL_OBJECT_NAME_PREFIX)
.arg(FileEntryTypeToString(fileType))
.arg(index);
}
int DataPanelManager::FindNextAvailableIndex(FileEntryType fileType) const
{
int index = 0;
QString baseKey = QString("%1_").arg(FileEntryTypeToString(fileType));
while (dataPanels_.contains(baseKey + QString::number(index))) {
index++;
}
return index;
}

View File

@ -0,0 +1,125 @@
#pragma once
#include <QObject>
#include <QMap>
#include <memory>
#include "workspace/WorkSpace.h"
#include "workspace/FileEntry.h"
class DockWidget;
class DataPanel;
class MainWindow;
/**
* @file DataPanelManager.h
* @brief Data Panel Manager
* Manages data panels created based on workspace files, supports multiple file types
*/
class DataPanelManager : public QObject
{
Q_OBJECT
public:
explicit DataPanelManager(MainWindow* mainWindow, QObject* parent = nullptr);
~DataPanelManager();
/**
* @brief Set current workspace
* @param workspace Workspace pointer
*/
void SetWorkspace(WorkSpace* workspace);
/**
* @brief Get current active panel count for specific type
* @param fileType File type (if not specified, returns total count)
* @return Panel count
*/
int GetActivePanelCount(FileEntryType fileType = static_cast<FileEntryType>(-1)) const;
/**
* @brief Get maximum panel count per type
* @return Maximum panel count
*/
int GetMaxPanelCount() const { return 9; }
/**
* @brief Get panels of specific type
* @param fileType File type
* @return List of panels for the specified type
*/
QList<DataPanel*> GetPanelsOfType(FileEntryType fileType) const;
public slots:
/**
* @brief Handle workspace changes
* @param workspace New workspace
*/
void OnWorkspaceChanged(WorkSpace* workspace);
/**
* @brief Handle file changes
* @param type File type
*/
void OnFilesChanged(FileEntryType type);
/**
* @brief Handle panel close event
*/
void OnPanelClosed();
private:
/**
* @brief Update panels for specific file type
* @param fileType File type to update
*/
void UpdatePanelsForType(FileEntryType fileType);
/**
* @brief Create new data panel
* @param fileType File type
* @param filePath File path
* @return Created panel pointer
*/
DataPanel* CreateDataPanel(FileEntryType fileType, const QString& filePath);
/**
* @brief Remove panel
* @param panel Panel pointer
*/
void RemovePanel(DataPanel* panel);
/**
* @brief Clear all panels
*/
void ClearAllPanels();
/**
* @brief Clear panels of specific type
* @param fileType File type
*/
void ClearPanelsOfType(FileEntryType fileType);
/**
* @brief Generate panel object name
* @param fileType File type
* @param index Panel index
* @return Object name
*/
QString GeneratePanelObjectName(FileEntryType fileType, int index) const;
/**
* @brief Find next available index for file type
* @param fileType File type
* @return Next available index
*/
int FindNextAvailableIndex(FileEntryType fileType) const;
private:
MainWindow* mainWindow_; // Main window pointer
WorkSpace* currentWorkspace_; // Current workspace
QMap<QString, DataPanel*> dataPanels_; // Panel mapping (key -> panel)
QMap<QString, DockWidget*> dockWidgets_; // Dock widget mapping (key -> dock widget)
static const QString PANEL_OBJECT_NAME_PREFIX; // Panel object name prefix
};

View File

@ -7920,6 +7920,7 @@ public:
QMap<const QtProperty*, QtProperty*> m_properyToWavePath;
QMap<const QtProperty*, QtProperty*> m_properyToReportPath;
QMap<const QtProperty*, QtProperty*> m_properyToRDPath;
QMap<const QtProperty*, QtProperty*> m_properyToCommondPath;
QMap<const QtProperty*, QtProperty*> m_nameToPropery;
QMap<const QtProperty*, QtProperty*> m_descriptionToPropery;
@ -7929,6 +7930,7 @@ public:
QMap<const QtProperty*, QtProperty*> m_wavePathToPropery;
QMap<const QtProperty*, QtProperty*> m_reportPathToPropery;
QMap<const QtProperty*, QtProperty*> m_rdPathToPropery;
QMap<const QtProperty*, QtProperty*> m_commondPathToPropery;
// Grouped file entries: Curve
QMap<const QtProperty*, QtProperty*> m_properyToCurveGroup;
@ -8000,6 +8002,10 @@ void QtWorkspacePropertyManagerPrivate::slotStringChanged(QtProperty* property,
QWorkspaceAttribute c = m_values[prop];
c.SetRDPath(value);
q_ptr->setValue(prop, c);
} else if (QtProperty* prop = m_commondPathToPropery.value(property, 0)) {
QWorkspaceAttribute c = m_values[prop];
c.SetCommondFilePath(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);
@ -8213,6 +8219,7 @@ void QtWorkspacePropertyManager::setValue(QtProperty* property, const QWorkspace
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());
d_ptr->m_filesProperyManager->setValue(d_ptr->m_properyToCommondPath[property], value.GetCommondFilePath());
auto syncGroup = [&](FileEntryType type,
QMap<const QtProperty*, QtProperty*>& propToGroup,
@ -8334,6 +8341,14 @@ void QtWorkspacePropertyManager::initializeProperty(QtProperty* property) {
d_ptr->m_rdPathToPropery[prop] = property;
property->addSubProperty(prop);
// Command XML path
prop = d_ptr->m_filesProperyManager->addProperty();
prop->setPropertyName(tr("CommondPath"));
d_ptr->m_filesProperyManager->setValueOnly(prop, val.GetCommondFilePath());
d_ptr->m_properyToCommondPath[property] = prop;
d_ptr->m_commondPathToPropery[prop] = property;
property->addSubProperty(prop);
// Add grouped file sections
auto addGroup = [&](FileEntryType type, const QString& groupName,
QMap<const QtProperty*, QtProperty*>& propToGroup,
@ -8455,6 +8470,13 @@ void QtWorkspacePropertyManager::uninitializeProperty(QtProperty* property) {
}
d_ptr->m_properyToRDPath.remove(property);
prop = d_ptr->m_commondPathToPropery[property];
if (prop) {
d_ptr->m_commondPathToPropery.remove(prop);
delete prop;
}
d_ptr->m_properyToCommondPath.remove(property);
// Cleanup grouped file properties
auto cleanupGroup = [&](QMap<const QtProperty*, QtProperty*>& propToGroup,
QMap<const QtProperty*, QtProperty*>& groupToProp,

View File

@ -174,6 +174,24 @@ const QString QWorkspaceAttribute::GetRDPath() const
return workspace_->GetRDPath();
}
void QWorkspaceAttribute::SetCommondFilePath(const QString& path)
{
if (nullptr == workspace_) {
return;
}
workspace_->SetCommondFilePath(path);
}
const QString QWorkspaceAttribute::GetCommondFilePath() const
{
if (nullptr == workspace_) {
return "";
}
// 只返回文件名,不包含完整路径
return workspace_->GetCommondFilePath();
}
std::vector<FileEntry> QWorkspaceAttribute::GetFileEntries(FileEntryType type) const {
if (nullptr == workspace_) {
return {};

View File

@ -80,6 +80,10 @@ public:
void SetRDPath(const QString& path);
const QString GetRDPath() const;
// Command XML path
void SetCommondFilePath(const QString& path);
const QString GetCommondFilePath() const;
// Grouped files API
std::vector<FileEntry> GetFileEntries(FileEntryType type) const;
void SetFileEntryCount(FileEntryType type, int count);

View File

@ -21,7 +21,7 @@ void CommandManager::Reload(WorkSpace* ws) {
onLoad_.clear();
if (!ws) return;
const QString cmdPath = ws->GetCommondFilePath();
const QString cmdPath = QString("%1/%2").arg(ws->GetDir(), ws->GetCommondFilePath());
if (cmdPath.isEmpty()) {
LOG_INFO("no command xml configured");
return;
@ -115,3 +115,31 @@ void CommandManager::Execute(WorkSpace* ws, WorkSpace::CommandWhen when) {
exec->Execute(ws, when);
}
}
std::vector<Command> CommandManager::ListCommands(WorkSpace* ws) {
std::vector<Command> items;
Reload(ws);
for (auto& exec : onCreate_) {
items.push_back(exec->Get());
}
for (auto& exec : onLoad_) {
items.push_back(exec->Get());
}
return items;
}
bool CommandManager::ExecuteByName(WorkSpace* ws, const QString& name) {
Reload(ws);
auto matchAndRun = [&](std::vector<std::unique_ptr<CommandExecutor>>& list, WorkSpace::CommandWhen when) -> bool {
for (auto& exec : list) {
if (exec->Get().name == name) {
exec->Execute(ws, when);
return true;
}
}
return false;
};
if (matchAndRun(onCreate_, WorkSpace::CommandWhen::OnCreate)) return true;
if (matchAndRun(onLoad_, WorkSpace::CommandWhen::OnLoad)) return true;
return false;
}

View File

@ -11,6 +11,11 @@ public:
void Reload(WorkSpace* ws);
void Execute(WorkSpace* ws, WorkSpace::CommandWhen when);
// List parsed commands (no trigger distinction for UI consumption)
std::vector<Command> ListCommands(WorkSpace* ws);
// Execute a single command by its name (exact match)
bool ExecuteByName(WorkSpace* ws, const QString& name);
private:
std::vector<std::unique_ptr<CommandExecutor>> onCreate_;
std::vector<std::unique_ptr<CommandExecutor>> onLoad_;

View File

@ -54,11 +54,6 @@ void WorkSpace::SetCommondFilePath(const QString& path) {
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());

View File

@ -52,7 +52,9 @@ public:
}
void SetCommondFilePath(const QString& path);
const QString GetCommondFilePath() const;
const QString GetCommondFilePath() const {
return commondPath_;
}
// Execute command xml according to trigger
enum class CommandWhen { OnCreate, OnLoad };
@ -183,5 +185,6 @@ private:
public:
std::uint64_t GetFilesSeq() const { return filesSeq_; }
friend class WorkSpaceXMLWrite;
friend class WorkSpaceXMLParse;
};

View File

@ -190,7 +190,7 @@ void WorkSpaceManager::OnFrame() {
QString WorkSpaceManager::GetDefaultWorkSpaceName() {
#if _DEBUG
const QString iniFile = QString("%1workspace/config.ini").arg(QString(CONFIG_PATH)).arg(skin);
const QString iniFile = QString("%1workspace/config.ini").arg(QString(CONFIG_PATH));
#else
const QString appDirPath = QApplication::applicationDirPath();
const QString iniFile = QString("%1/config/workspace/config.ini").arg(appDirPath);

View File

@ -84,6 +84,23 @@ bool WorkSpaceXMLParse::ParseLamp(const tinyxml2::XMLElement* element) {
return workSpace_->SetLampPath(path);
}
bool WorkSpaceXMLParse::ParseCommond(const tinyxml2::XMLElement* element) {
if (nullptr == element) {
LOG_WARN("commond element is nullptr");
return false;
}
const char* path = element->Attribute("path");
if (nullptr == path) {
LOG_WARN("commond element not has path");
return false;
}
// Set the command file path using the filename stored in XML
workSpace_->commondPath_ = path;
return true;
}
bool WorkSpaceXMLParse::ParseFiles(const tinyxml2::XMLElement* element) {
if (nullptr == element) {
LOG_WARN("element is nullptr");
@ -252,6 +269,8 @@ bool WorkSpaceXMLParse::Load(const QString& dyt) {
ParseTimestep(xmlElement);
} else if (0 == strcmp(name, "lamp")) {
ParseLamp(xmlElement);
} else if (0 == strcmp(name, "commond")) {
ParseCommond(xmlElement);
}
else if (0 == strcmp(name, "charts")) {
ParseChart(xmlElement);

View File

@ -31,6 +31,7 @@ private:
bool ParseScene(const tinyxml2::XMLElement* element);
bool ParseTimestep(const tinyxml2::XMLElement* element);
bool ParseLamp(const tinyxml2::XMLElement* element);
bool ParseCommond(const tinyxml2::XMLElement* element);
bool ParseEntities(const tinyxml2::XMLElement* element);
bool ParseChart(const tinyxml2::XMLElement* element);
bool ParseReport(const tinyxml2::XMLElement* element);

View File

@ -12,6 +12,8 @@
#include "workspace/WorkSpaceManager.h"
#include "workspace/FileEntry.h"
#include <QFileInfo>
WorkSpaceXMLWrite::WorkSpaceXMLWrite(WorkSpace* workspace, QObject* parent) noexcept
: QObject(parent)
, workSpace_(workspace) {}
@ -36,6 +38,7 @@ bool WorkSpaceXMLWrite::Save(const QString& path) {
SaveChart(scene, &doc);
SaveTimeStep(scene);
SaveLamp(scene);
SaveCommond(scene);
SaveFiles(scene, &doc);
tinyxml2::XMLElement* entitiesXml = scene->InsertNewChildElement("entities");
@ -58,6 +61,8 @@ bool WorkSpaceXMLWrite::SaveScene(tinyxml2::XMLElement* scene) {
scene->SetAttribute("describe", workSpace_->GetDescribe().toStdString().c_str());
scene->SetAttribute("uuid", workSpace_->GetUUid().toStdString().c_str());
scene->SetAttribute("viewpoint", StringUtils::ViewpointToString(workSpace_->GetHomeViewpoint()).c_str());
scene->SetAttribute("commondPath", "");
return true;
}
@ -72,12 +77,22 @@ bool WorkSpaceXMLWrite::SaveTimeStep(tinyxml2::XMLElement* scene) {
}
bool WorkSpaceXMLWrite::SaveLamp(tinyxml2::XMLElement* scene) {
LampStatus* lampStatus = workSpace_->GetLampStatus();
if (nullptr == lampStatus) {
return false;
tinyxml2::XMLElement* lamp = scene->InsertNewChildElement("lamp");
const QString lampPath = workSpace_->GetLampStatus()->GetPath();
if (!lampPath.isEmpty()) {
lamp->SetAttribute("path", lampPath.toStdString().c_str());
}
return true;
}
bool WorkSpaceXMLWrite::SaveCommond(tinyxml2::XMLElement* scene) {
const QString commondPath = workSpace_->GetCommondFilePath();
if (!commondPath.isEmpty()) {
tinyxml2::XMLElement* commond = scene->InsertNewChildElement("commond");
// Extract just the filename from the full path for storage
QFileInfo fileInfo(commondPath);
commond->SetAttribute("path", fileInfo.fileName().toStdString().c_str());
}
tinyxml2::XMLElement* timestepXml = scene->InsertNewChildElement("lamp");
timestepXml->SetAttribute("path", lampStatus->GetPath().toStdString().c_str());
return true;
}

View File

@ -19,6 +19,7 @@ protected:
bool SaveScene(tinyxml2::XMLElement* scene);
bool SaveTimeStep(tinyxml2::XMLElement* scene);
bool SaveLamp(tinyxml2::XMLElement* scene);
bool SaveCommond(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);

51
workspace/command.xml Normal file
View File

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<commands>
<!-- 创建时执行的命令 -->
<command name="初始化环境"
program="cmd.exe"
path="echo Initializing workspace environment..."
description="初始化工作空间环境"
when="oncreate"
enabled="true" />
<command name="检查Python版本"
program="python"
args="--version"
description="检查Python版本信息"
when="oncreate"
enabled="true" />
<!-- 加载时执行的命令 -->
<command name="启动服务"
program="cmd.exe"
path="echo Starting services..."
description="启动相关服务"
when="onload"
enabled="true" />
<command name="检查系统状态"
program="powershell.exe"
args="Get-Process | Select-Object -First 5"
description="检查系统进程状态"
when="onload"
enabled="true" />
<!-- 通用命令默认为oncreate -->
<command name="打开记事本"
program="notepad.exe"
description="打开Windows记事本"
enabled="true" />
<command name="查看目录"
program="cmd.exe"
args="/c dir"
description="查看当前目录内容"
enabled="true" />
<!-- 禁用的命令示例 -->
<command name="禁用命令"
program="cmd.exe"
path="echo This command is disabled"
description="这是一个被禁用的命令示例"
enabled="false" />
</commands>