diff --git a/src/translations/Dyt_zh_CN.ts b/src/translations/Dyt_zh_CN.ts index 21ae8592..13a9e92e 100644 --- a/src/translations/Dyt_zh_CN.ts +++ b/src/translations/Dyt_zh_CN.ts @@ -61,61 +61,76 @@ - X Axis Title: + Chart Type: - - Enter X axis title... + + Wave - - Y Axis Title: + + Report - Enter Y axis title... + X Axis Title: + Enter X axis title... + + + + + Y Axis Title: + + + + + Enter Y axis title... + + + + Time Parameter: - + Axis Range Settings - + X Min: - + X Max: - + Y Min: - + Y Max: - + X Tick Count: - + Curve Name: @@ -125,243 +140,265 @@ - + Y Tick Count: - + Curve Management - + Curves: - + Add Curve - + Remove - + Selected Curve Properties - + Enter curve name... - + Curve Color: - + Select Color - + background-color: rgb(255, 0, 0); border: 1px solid black; - + Data Start: - + Data Stop: + X Value: + + + + + Y Value: + + + + Add File - + Cancel - + Curve %1 - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + Validation Error - + Please select a data file. - + Selected file does not exist. - + Selected file is not readable. Please check file permissions. - + File is too large (over 100MB). Please select a smaller file. - + At least one curve must be defined. - + Curve %1 name cannot be empty. - + Curve name '%1' is duplicated. Please use different names. - + Curve name '%1' is too long. Please limit to 50 characters. - + Curve '%1' start and stop values must be greater than 0. - + Curve '%1' start value cannot be greater than stop value. - + Curve '%1' data range is too small. At least 2 data points are required. - + Curve '%1' stop value is too large. Please ensure it does not exceed 1000000. - + + Curve '%1' X value is out of range. Please ensure it is between -1000000 and 1000000. + + + + + Curve '%1' Y value is out of range. Please ensure it is between -1000000 and 1000000. + + + + Chart name cannot be empty. - + Chart name is too long. Please limit to 100 characters. - + X axis title is too long. Please limit to 50 characters. - + Y axis title is too long. Please limit to 50 characters. - + X axis minimum value must be less than maximum value. - + Y axis minimum value must be less than maximum value. - + Time parameter cannot be negative. - + X axis tick count must be at least 2. - - - + + + Error - + Failed to create file entry - + Unable to get current workspace - + Curve file count has reached the limit (9 files) - + File already exists - + File copy failed - + Invalid file - + Failed to add file diff --git a/src/ui/Panel/CurvePanel.cpp b/src/ui/Panel/CurvePanel.cpp index 848d380a..0dbf6d2b 100644 --- a/src/ui/Panel/CurvePanel.cpp +++ b/src/ui/Panel/CurvePanel.cpp @@ -119,10 +119,18 @@ void CurvePanel::UpdateCurveDisplay() QCheckBox* curveCheckBox = new QCheckBox(curve.name); curveCheckBox->setChecked(true); - // Curve info + // Curve info - display different information based on chart type QString colorStr = QString("rgb(%1,%2,%3)").arg(curve.color.red()).arg(curve.color.green()).arg(curve.color.blue()); - QLabel* curveInfo = new QLabel(QString("Range: %1-%2, Color: %3") - .arg(curve.start).arg(curve.stop).arg(colorStr)); + QLabel* curveInfo; + + if (chartProperties.chartType == ChartType::Wave) { + curveInfo = new QLabel(QString("Range: %1-%2, Color: %3") + .arg(curve.data.wave.start).arg(curve.data.wave.stop).arg(colorStr)); + } else { + curveInfo = new QLabel(QString("Position: (%1,%2), Color: %3") + .arg(curve.data.report.x).arg(curve.data.report.y).arg(colorStr)); + } + curveInfo->setStyleSheet(QString("QLabel { color: %1; }").arg(colorStr)); curveLayout->addWidget(curveCheckBox); @@ -176,8 +184,8 @@ void CurvePanel::UpdateCurveDisplay() // curveCheckBox->setChecked(true); // QLabel* curveInfo = new QLabel(QString("Range: %1-%2, Color: %3, Pos: (%4,%5,%6)") - // .arg(curve.start).arg(curve.stop).arg(curve.color) - // .arg(curve.x).arg(curve.y).arg(curve.z)); + // .arg(curve.data.wave.start).arg(curve.data.wave.stop).arg(curve.color) + // .arg(curve.data.report.x).arg(curve.data.report.y).arg(curve.z)); // curveInfo->setStyleSheet(QString("QLabel { color: rgb(%1); }").arg(curve.color)); // curveLayout->addWidget(curveCheckBox); @@ -340,19 +348,15 @@ void CurvePanel::OnDataPanelUpdated(FileEntryCurve* fileEntry) { updateMinMaxX(propChart.xMin, propChart.xMax, propChart.xCount); updateMinMaxY(propChart.yMin, propChart.yMax, propChart.yCount); + QString strFile = fileEntry->GetPath() + "/" + fileEntry->GetFileName(); FileEntryCurve::CurveProperties propCurves = fileEntry->GetCurveProperties(); - if (propCurves.size() > 0) + if (propChart.chartType == ChartType::Wave) { - QString strFile = fileEntry->GetPath(); - - if (propCurves.at(0).start == 0 && propCurves.at(0).stop == 0) - { - updateParseReportFile(strFile, propChart.timeParam, propCurves); - } - else - { - updateParseWaveFile(strFile, propChart.timeParam, propCurves); - } + updateParseWaveFile(strFile, propChart.timeParam, propCurves); + } + else if (propChart.chartType == ChartType::Report) + { + updateParseReportFile(strFile, propChart.timeParam, propCurves); } } @@ -490,7 +494,7 @@ void CurvePanel::updateParseWaveFile(const QString& strFile, int nT, FileEntryCu if (bResetAxisX) { - int nMax = propCurve.stop - propCurve.start; + int nMax = propCurve.data.wave.stop - propCurve.data.wave.start; if (m_iXMax < nMax) { m_iXMax = nMax; @@ -498,7 +502,7 @@ void CurvePanel::updateParseWaveFile(const QString& strFile, int nT, FileEntryCu } QVariantList listData; - for (int nJ = propCurve.start; nJ < propCurve.stop; nJ++) + for (int nJ = propCurve.data.wave.start; nJ < propCurve.data.wave.stop; nJ++) { double value = listLine.at(nJ).toDouble(); listData.push_back(value); @@ -602,8 +606,8 @@ void CurvePanel::updateParseReportFile(const QString & strFile, int nT, FileEntr { FileEntryCurve::CurveProperty propCurve = listCurve.at(nI); - double x = listLine.at(propCurve.x).toDouble(); - double y = listLine.at(propCurve.y).toDouble(); + double x = listLine.at(propCurve.data.report.x).toDouble(); + double y = listLine.at(propCurve.data.report.y).toDouble(); QPointF ptData = QPointF(x, y); mapData.insert(nI, ptData); @@ -713,7 +717,11 @@ void CurvePanel::updateReportData(double t) } } } - - } } + +void CurvePanel::OnTimeChanged(double time) +{ + updateWaveData(time); + updateReportData(time); +} \ No newline at end of file diff --git a/src/ui/Panel/CurvePanel.h b/src/ui/Panel/CurvePanel.h index 3f1b28b6..595fa721 100644 --- a/src/ui/Panel/CurvePanel.h +++ b/src/ui/Panel/CurvePanel.h @@ -72,6 +72,8 @@ protected: void OnDataPanelUpdated(FileEntryCurve* fileEntry); + virtual void OnTimeChanged(double time); + private: /** * @brief Update curve display based on chart data diff --git a/src/ui/Panel/DataPanel.h b/src/ui/Panel/DataPanel.h index 9ce2a2bb..c7129e06 100644 --- a/src/ui/Panel/DataPanel.h +++ b/src/ui/Panel/DataPanel.h @@ -81,6 +81,13 @@ public: * @brief Refresh panel content (virtual function, implemented by derived classes) */ virtual void RefreshPanel() {} + + /** + * @brief Handle time change event (virtual function, implemented by derived classes) + * @param time Current time value from Timestep + */ + virtual void OnTimeChanged(double time) {} + /** * @brief Initialize UI (virtual function, derived classes implement specific layout) */ diff --git a/src/ui/Panel/DataPanelManager.cpp b/src/ui/Panel/DataPanelManager.cpp index 3c85b607..c7bf4f7d 100644 --- a/src/ui/Panel/DataPanelManager.cpp +++ b/src/ui/Panel/DataPanelManager.cpp @@ -5,10 +5,12 @@ #include "ui/DockTitleBar.h" #include "ui/MainWindow.h" #include "workspace/FileEntry.h" +#include "workspace/Timestep.h" #include "common/SpdLogger.h" #include #include +#include const QString DataPanelManager::PANEL_OBJECT_NAME_PREFIX = "DataPanel_"; @@ -42,6 +44,18 @@ void DataPanelManager::SetWorkspace(WorkSpace* workspace) // Connect new workspace signals if (currentWorkspace_) { connect(currentWorkspace_, &WorkSpace::FilesChanged, this, &DataPanelManager::OnFilesChanged); + + // Connect to Timestep signals if available + if (currentWorkspace_->GetTimestep()) { + connect(currentWorkspace_->GetTimestep(), &Timestep::TimeChanged, this, &DataPanelManager::OnTimeChanged); + } + + // Connect to TimestepChanged signal to handle future Timestep changes + connect(currentWorkspace_, &WorkSpace::TimestepChanged, this, [this](Timestep* timestep) { + if (timestep) { + connect(timestep, &Timestep::TimeChanged, this, &DataPanelManager::OnTimeChanged); + } + }); } // Update all panel types @@ -292,12 +306,31 @@ QString DataPanelManager::GeneratePanelObjectName(FileEntryType fileType, int in int DataPanelManager::FindNextAvailableIndex(FileEntryType fileType) const { - int index = 0; - QString baseKey = QString("%1_").arg(FileEntryTypeToString(fileType)); + QSet usedIndices; + QString typeStr = FileEntryTypeToString(fileType); - while (dataPanels_.contains(baseKey + QString::number(index))) { - index++; + for (auto it = dataPanels_.constBegin(); it != dataPanels_.constEnd(); ++it) { + if (it.value()->GetFileType() == fileType) { + usedIndices.insert(it.value()->GetIndex()); + } } - return index; + for (int i = 0; i < GetMaxPanelCount(); ++i) { + if (!usedIndices.contains(i)) { + return i; + } + } + + return -1; // No available index +} + +void DataPanelManager::OnTimeChanged(double time) +{ + // Notify all active panels about time change + for (auto it = dataPanels_.constBegin(); it != dataPanels_.constEnd(); ++it) { + DataPanel* panel = it.value(); + if (panel) { + panel->OnTimeChanged(time); + } + } } \ No newline at end of file diff --git a/src/ui/Panel/DataPanelManager.h b/src/ui/Panel/DataPanelManager.h index 084f4a33..f4d64cbd 100644 --- a/src/ui/Panel/DataPanelManager.h +++ b/src/ui/Panel/DataPanelManager.h @@ -68,6 +68,12 @@ public slots: */ void OnPanelClosed(); + /** + * @brief Handle time change event from Timestep + * @param time Current time value + */ + void OnTimeChanged(double time); + private: /** * @brief Update panels for specific file type diff --git a/src/ui/WorkSpace/AddCurveFileDlg.cpp b/src/ui/WorkSpace/AddCurveFileDlg.cpp index 85a899d4..9fb1cc78 100644 --- a/src/ui/WorkSpace/AddCurveFileDlg.cpp +++ b/src/ui/WorkSpace/AddCurveFileDlg.cpp @@ -19,7 +19,17 @@ AddCurveFileDlg::AddCurveFileDlg(QWidget* parent) SetupUI(ui); SetTitle(getDialogTitle()); + + // Initialize chart type combo box + ui->chartTypeComboBox->addItem("Wave", static_cast(ChartType::Wave)); + ui->chartTypeComboBox->addItem("Report", static_cast(ChartType::Report)); + ui->chartTypeComboBox->setCurrentIndex(0); // Default to Wave + + // Initialize chart properties with default values + chartProperties_.chartType = ChartType::Wave; + setupConnections(); + updateCurvePropertiesUI(); // Initialize UI based on default chart type } AddCurveFileDlg::~AddCurveFileDlg() { @@ -30,6 +40,9 @@ void AddCurveFileDlg::setupConnections() { // File selection connections connect(ui->selectFileBtn, &QToolButton::clicked, this, &AddCurveFileDlg::OnSelectFile); + // Chart type connection + connect(ui->chartTypeComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, &AddCurveFileDlg::onChartTypeChanged); + // Curve management connections connect(ui->addCurveBtn, &QPushButton::clicked, this, &AddCurveFileDlg::onAddCurveClicked); connect(ui->removeCurveBtn, &QPushButton::clicked, this, &AddCurveFileDlg::onRemoveCurveClicked); @@ -41,6 +54,8 @@ void AddCurveFileDlg::setupConnections() { connect(ui->curveNameEdit, &QLineEdit::textChanged, this, &AddCurveFileDlg::onCurveNameChanged); connect(ui->dataStartSpinBox, QOverload::of(&QSpinBox::valueChanged), this, &AddCurveFileDlg::onCurveDataChanged); connect(ui->dataStopSpinBox, QOverload::of(&QSpinBox::valueChanged), this, &AddCurveFileDlg::onCurveDataChanged); + connect(ui->xValueSpinBox, QOverload::of(&QDoubleSpinBox::valueChanged), this, &AddCurveFileDlg::onCurveDataChanged); + connect(ui->yValueSpinBox, QOverload::of(&QDoubleSpinBox::valueChanged), this, &AddCurveFileDlg::onCurveDataChanged); // Dialog buttons connect(ui->addBtn, &QPushButton::clicked, this, &AddCurveFileDlg::onSure); @@ -78,24 +93,44 @@ void AddCurveFileDlg::onAddCurveClicked() { saveCurveProperties(); } - // Create new curve with default properties + // Create new curve with default properties based on chart type FileEntryCurve::CurveProperty newCurve; newCurve.name = generateCurveName(); newCurve.color = generateCurveColor(); - newCurve.start = 1; - newCurve.stop = 241; + + // Set default values based on chart type + if (chartProperties_.chartType == ChartType::Wave) { + newCurve.data.wave.start = 1; + newCurve.data.wave.stop = 241; + } else { + newCurve.data.report.x = 0.0; + newCurve.data.report.y = 0.0; + } // Add to curves list and UI curves_.append(newCurve); - // Add to UI list widget - QListWidgetItem* item = new QListWidgetItem(QString("%1 [%2,%3] (%4,%5,%6)") - .arg(newCurve.name) - .arg(newCurve.start) - .arg(newCurve.stop) - .arg(newCurve.color.red()) - .arg(newCurve.color.green()) - .arg(newCurve.color.blue())); + // Add to UI list widget with appropriate display format + QString displayText; + if (chartProperties_.chartType == ChartType::Wave) { + displayText = QString("%1 [%2,%3] (%4,%5,%6)") + .arg(newCurve.name) + .arg(newCurve.data.wave.start) + .arg(newCurve.data.wave.stop) + .arg(newCurve.color.red()) + .arg(newCurve.color.green()) + .arg(newCurve.color.blue()); + } else { + displayText = QString("%1 (%.2f,%.2f) (%4,%5,%6)") + .arg(newCurve.name) + .arg(newCurve.data.report.x) + .arg(newCurve.data.report.y) + .arg(newCurve.color.red()) + .arg(newCurve.color.green()) + .arg(newCurve.color.blue()); + } + + QListWidgetItem* item = new QListWidgetItem(displayText); ui->curveListWidget->addItem(item); ++currentCurveIndex_; @@ -138,24 +173,25 @@ void AddCurveFileDlg::onCurveListWidgetItemClicked(QListWidgetItem* item) { return; } - // 获取点击项的索引 int clickedIndex = ui->curveListWidget->row(item); - // 如果点击的是当前选中项,可以进入编辑模式 if (clickedIndex == currentCurveIndex_) { ui->curveNameEdit->setText(curves_[currentCurveIndex_].name); - ui->dataStartSpinBox->setValue(curves_[currentCurveIndex_].start); - ui->dataStopSpinBox->setValue(curves_[currentCurveIndex_].stop); + + if (chartProperties_.chartType == ChartType::Wave) { + ui->dataStartSpinBox->setValue(curves_[currentCurveIndex_].data.wave.start); + ui->dataStopSpinBox->setValue(curves_[currentCurveIndex_].data.wave.stop); + } else { + ui->xValueSpinBox->setValue(curves_[currentCurveIndex_].data.report.x); + ui->yValueSpinBox->setValue(curves_[currentCurveIndex_].data.report.y); + } + updateColorPreview(curves_[currentCurveIndex_].color); - - // 启用曲线属性编辑 enableCurveProperties(true); - // 将焦点设置到曲线名称编辑框,方便用户直接编辑 ui->curveNameEdit->setFocus(); ui->curveNameEdit->selectAll(); } else { - // 如果点击的是不同的项,更新选择 onCurveSelectionChanged(); } } @@ -185,35 +221,65 @@ void AddCurveFileDlg::onCurveNameChanged() { QString newName = ui->curveNameEdit->text(); curves_[currentCurveIndex_].name = newName; - // Update list item text - QListWidgetItem* item = ui->curveListWidget->item(currentCurveIndex_); - if (item) { - item->setText(QString("%1 [%2,%3] (%4,%5,%6)") - .arg(newName) - .arg(curves_[currentCurveIndex_].start) - .arg(curves_[currentCurveIndex_].stop) - .arg(curves_[currentCurveIndex_].color.red()) - .arg(curves_[currentCurveIndex_].color.green()) - .arg(curves_[currentCurveIndex_].color.blue())); - } + // Update list item text with appropriate format + QListWidgetItem* item = ui->curveListWidget->item(currentCurveIndex_); + if (item) { + QString displayText; + if (chartProperties_.chartType == ChartType::Wave) { + displayText = QString("%1 [%2,%3] (%4,%5,%6)") + .arg(newName) + .arg(curves_[currentCurveIndex_].data.wave.start) + .arg(curves_[currentCurveIndex_].data.wave.stop) + .arg(curves_[currentCurveIndex_].color.red()) + .arg(curves_[currentCurveIndex_].color.green()) + .arg(curves_[currentCurveIndex_].color.blue()); + } else { + displayText = QString("%1 (%.2f,%.2f) (%4,%5,%6)") + .arg(newName) + .arg(curves_[currentCurveIndex_].data.report.x) + .arg(curves_[currentCurveIndex_].data.report.y) + .arg(curves_[currentCurveIndex_].color.red()) + .arg(curves_[currentCurveIndex_].color.green()) + .arg(curves_[currentCurveIndex_].color.blue()); + } + item->setText(displayText); + } } } void AddCurveFileDlg::onCurveDataChanged() { if (currentCurveIndex_ >= 0 && currentCurveIndex_ < curves_.size()) { - curves_[currentCurveIndex_].start = ui->dataStartSpinBox->value(); - curves_[currentCurveIndex_].stop = ui->dataStopSpinBox->value(); + // Update curve data based on chart type + if (chartProperties_.chartType == ChartType::Wave) { + curves_[currentCurveIndex_].data.wave.start = ui->dataStartSpinBox->value(); + curves_[currentCurveIndex_].data.wave.stop = ui->dataStopSpinBox->value(); + } else { + curves_[currentCurveIndex_].data.report.x = ui->xValueSpinBox->value(); + curves_[currentCurveIndex_].data.report.y = ui->yValueSpinBox->value(); + } - // Update list item text + // Update display text in list widget QListWidgetItem* item = ui->curveListWidget->item(currentCurveIndex_); if (item) { - item->setText(QString("%1 [%2,%3] (%4,%5,%6)") - .arg(curves_[currentCurveIndex_].name) - .arg(curves_[currentCurveIndex_].start) - .arg(curves_[currentCurveIndex_].stop) - .arg(curves_[currentCurveIndex_].color.red()) - .arg(curves_[currentCurveIndex_].color.green()) - .arg(curves_[currentCurveIndex_].color.blue())); + QString itemText; + if (chartProperties_.chartType == ChartType::Wave) { + itemText = QString("%1 [%2,%3] (%4,%5,%6)") + .arg(curves_[currentCurveIndex_].name) + .arg(curves_[currentCurveIndex_].data.wave.start) + .arg(curves_[currentCurveIndex_].data.wave.stop) + .arg(curves_[currentCurveIndex_].color.red()) + .arg(curves_[currentCurveIndex_].color.green()) + .arg(curves_[currentCurveIndex_].color.blue()); + } else { + itemText = QString("%1 (%2,%3) (%4,%5,%6)") + .arg(curves_[currentCurveIndex_].name) + .arg(curves_[currentCurveIndex_].data.report.x) + .arg(curves_[currentCurveIndex_].data.report.y) + .arg(curves_[currentCurveIndex_].color.red()) + .arg(curves_[currentCurveIndex_].color.green()) + .arg(curves_[currentCurveIndex_].color.blue()); + } + item->setText(itemText); } } } @@ -227,39 +293,69 @@ void AddCurveFileDlg::onColorButtonClicked() { updateColorPreview(color); // Update list item text - QListWidgetItem* item = ui->curveListWidget->item(currentCurveIndex_); - if (item) { - item->setText(QString("%1 [%2,%3] (%4,%5,%6)") - .arg(curves_[currentCurveIndex_].name) - .arg(curves_[currentCurveIndex_].start) - .arg(curves_[currentCurveIndex_].stop) - .arg(color.red()) - .arg(color.green()) - .arg(color.blue())); - } + QListWidgetItem* item = ui->curveListWidget->item(currentCurveIndex_); + if (item) { + QString itemText; + if (chartProperties_.chartType == ChartType::Wave) { + itemText = QString("%1 [%2,%3] (%4,%5,%6)") + .arg(curves_[currentCurveIndex_].name) + .arg(curves_[currentCurveIndex_].data.wave.start) + .arg(curves_[currentCurveIndex_].data.wave.stop) + .arg(color.red()) + .arg(color.green()) + .arg(color.blue()); + } else { + itemText = QString("%1 (%2,%3) (%4,%5,%6)") + .arg(curves_[currentCurveIndex_].name) + .arg(curves_[currentCurveIndex_].data.report.x) + .arg(curves_[currentCurveIndex_].data.report.y) + .arg(color.red()) + .arg(color.green()) + .arg(color.blue()); + } + item->setText(itemText); + } } } } void AddCurveFileDlg::addCurveToList(const FileEntryCurve::CurveProperty& curve) { - QString itemText = QString("%1 [%2,%3] (%4,%5,%6)") - .arg(curve.name) - .arg(curve.start) - .arg(curve.stop) - .arg(curve.color.red()) - .arg(curve.color.green()) - .arg(curve.color.blue()); - - ui->curveListWidget->addItem(itemText); -} + QString itemText; + if (chartProperties_.chartType == ChartType::Wave) { + itemText = QString("%1 [%2,%3] (%4,%5,%6)") + .arg(curve.name) + .arg(curve.data.wave.start) + .arg(curve.data.wave.stop) + .arg(curve.color.red()) + .arg(curve.color.green()) + .arg(curve.color.blue()); + } else { + itemText = QString("%1 (%2,%3) (%4,%5,%6)") + .arg(curve.name) + .arg(curve.data.report.x) + .arg(curve.data.report.y) + .arg(curve.color.red()) + .arg(curve.color.green()) + .arg(curve.color.blue()); + } + + ui->curveListWidget->addItem(itemText); + } void AddCurveFileDlg::updateCurveProperties() { if (currentCurveIndex_ >= 0 && currentCurveIndex_ < curves_.size()) { const FileEntryCurve::CurveProperty& curve = curves_[currentCurveIndex_]; ui->curveNameEdit->setText(curve.name); - ui->dataStartSpinBox->setValue(curve.start); - ui->dataStopSpinBox->setValue(curve.stop); + + // Update properties based on chart type + if (chartProperties_.chartType == ChartType::Wave) { + ui->dataStartSpinBox->setValue(curve.data.wave.start); + ui->dataStopSpinBox->setValue(curve.data.wave.stop); + } else { + ui->xValueSpinBox->setValue(curve.data.report.x); + ui->yValueSpinBox->setValue(curve.data.report.y); + } selectedColor_ = curve.color; updateColorPreview(curve.color); @@ -269,16 +365,32 @@ void AddCurveFileDlg::updateCurveProperties() { void AddCurveFileDlg::saveCurveProperties() { if (currentCurveIndex_ >= 0 && currentCurveIndex_ < curves_.size()) { curves_[currentCurveIndex_].name = ui->curveNameEdit->text(); - curves_[currentCurveIndex_].start = ui->dataStartSpinBox->value(); - curves_[currentCurveIndex_].stop = ui->dataStopSpinBox->value(); + + // Save properties based on chart type + if (chartProperties_.chartType == ChartType::Wave) { + curves_[currentCurveIndex_].data.wave.start = ui->dataStartSpinBox->value(); + curves_[currentCurveIndex_].data.wave.stop = ui->dataStopSpinBox->value(); + } else { + curves_[currentCurveIndex_].data.report.x = ui->xValueSpinBox->value(); + curves_[currentCurveIndex_].data.report.y = ui->yValueSpinBox->value(); + } + curves_[currentCurveIndex_].color = selectedColor_; } } void AddCurveFileDlg::clearCurveProperties() { ui->curveNameEdit->clear(); - ui->dataStartSpinBox->setValue(1); - ui->dataStopSpinBox->setValue(241); + + // Clear properties based on chart type + if (chartProperties_.chartType == ChartType::Wave) { + ui->dataStartSpinBox->setValue(1); + ui->dataStopSpinBox->setValue(241); + } else { + ui->xValueSpinBox->setValue(0.0); + ui->yValueSpinBox->setValue(0.0); + } + selectedColor_ = QColor(255, 0, 0); updateColorPreview(selectedColor_); } @@ -379,30 +491,45 @@ bool AddCurveFileDlg::validateSpecificParams() { return false; } - // Data range validation - if (curve.start < 1 || curve.stop < 1) { - QMessageBox::warning(this, tr("Validation Error"), - tr("Curve '%1' start and stop values must be greater than 0.").arg(curve.name)); - return false; - } - - if (curve.start > curve.stop) { - QMessageBox::warning(this, tr("Validation Error"), - tr("Curve '%1' start value cannot be greater than stop value.").arg(curve.name)); - return false; - } - - // Data range reasonableness validation - if (curve.stop - curve.start < 1) { - QMessageBox::warning(this, tr("Validation Error"), - tr("Curve '%1' data range is too small. At least 2 data points are required.").arg(curve.name)); - return false; - } - - if (curve.stop > 1000000) { - QMessageBox::warning(this, tr("Validation Error"), - tr("Curve '%1' stop value is too large. Please ensure it does not exceed 1000000.").arg(curve.name)); - return false; + // Data range validation based on chart type + if (chartProperties_.chartType == ChartType::Wave) { + if (curve.data.wave.start < 1 || curve.data.wave.stop < 1) { + QMessageBox::warning(this, tr("Validation Error"), + tr("Curve '%1' start and stop values must be greater than 0.").arg(curve.name)); + return false; + } + + if (curve.data.wave.start > curve.data.wave.stop) { + QMessageBox::warning(this, tr("Validation Error"), + tr("Curve '%1' start value cannot be greater than stop value.").arg(curve.name)); + return false; + } + + // Data range reasonableness validation + if (curve.data.wave.stop - curve.data.wave.start < 1) { + QMessageBox::warning(this, tr("Validation Error"), + tr("Curve '%1' data range is too small. At least 2 data points are required.").arg(curve.name)); + return false; + } + + if (curve.data.wave.stop > 1000000) { + QMessageBox::warning(this, tr("Validation Error"), + tr("Curve '%1' stop value is too large. Please ensure it does not exceed 1000000.").arg(curve.name)); + return false; + } + } else { + // Report type validation - ensure x and y values are reasonable + if (curve.data.report.x < -1000000 || curve.data.report.x > 1000000) { + QMessageBox::warning(this, tr("Validation Error"), + tr("Curve '%1' X value is out of range. Please ensure it is between -1000000 and 1000000.").arg(curve.name)); + return false; + } + + if (curve.data.report.y < -1000000 || curve.data.report.y > 1000000) { + QMessageBox::warning(this, tr("Validation Error"), + tr("Curve '%1' Y value is out of range. Please ensure it is between -1000000 and 1000000.").arg(curve.name)); + return false; + } } } @@ -484,6 +611,7 @@ void AddCurveFileDlg::onSure() { // Set chart properties FileEntryCurve::ChartProperties chartProps; + chartProps.chartType = chartProperties_.chartType; // Set chart type chartProps.xCount = ui->xCountSpinBox->value(); chartProps.yCount = ui->yCountSpinBox->value(); chartProps.xTitle = ui->xTitleEdit->text(); @@ -535,3 +663,39 @@ void AddCurveFileDlg::onSure() { accept(); } } + +void AddCurveFileDlg::onChartTypeChanged() { + // Save current curve properties if any curve is selected + if (currentCurveIndex_ >= 0) { + saveCurveProperties(); + } + + // Update chart type based on combo box selection + int selectedIndex = ui->chartTypeComboBox->currentIndex(); + ChartType newChartType = static_cast(ui->chartTypeComboBox->itemData(selectedIndex).toInt()); + chartProperties_.chartType = newChartType; + + // Update UI to show appropriate curve property controls + updateCurvePropertiesUI(); + + // Update current curve properties display if a curve is selected + if (currentCurveIndex_ >= 0) { + updateCurveProperties(); + } +} + +void AddCurveFileDlg::updateCurvePropertiesUI() { + bool isWaveType = (chartProperties_.chartType == ChartType::Wave); + + // Show/hide Wave type controls (Data Start/Stop) + ui->dataStartLabel->setVisible(isWaveType); + ui->dataStartSpinBox->setVisible(isWaveType); + ui->dataStopLabel->setVisible(isWaveType); + ui->dataStopSpinBox->setVisible(isWaveType); + + // Show/hide Report type controls (X/Y Value) + ui->xValueLabel->setVisible(!isWaveType); + ui->xValueSpinBox->setVisible(!isWaveType); + ui->yValueLabel->setVisible(!isWaveType); + ui->yValueSpinBox->setVisible(!isWaveType); +} diff --git a/src/ui/WorkSpace/AddCurveFileDlg.h b/src/ui/WorkSpace/AddCurveFileDlg.h index 2da9ed32..045cdc8e 100644 --- a/src/ui/WorkSpace/AddCurveFileDlg.h +++ b/src/ui/WorkSpace/AddCurveFileDlg.h @@ -2,21 +2,16 @@ #include "BaseAddFileDlg.h" #include "workspace/FileEntry.h" -#include -#include -#include +QT_BEGIN_NAMESPACE +class QComboBox; class QLineEdit; -class QCheckBox; class QSpinBox; class QDoubleSpinBox; -class QComboBox; -class QTextEdit; -class QToolButton; -class QLabel; -class QPushButton; class QListWidget; -class QListWidgetItem; +class QPushButton; +class QLabel; +QT_END_NAMESPACE namespace Ui { class AddCurveFileDlg; @@ -39,10 +34,11 @@ private slots: void onColorButtonClicked(); void onAddCurveClicked(); void onRemoveCurveClicked(); - void onCurveListWidgetItemClicked(QListWidgetItem* item); + void onCurveListWidgetItemClicked(class QListWidgetItem* item); void onCurveSelectionChanged(); void onCurveNameChanged(); void onCurveDataChanged(); + void onChartTypeChanged(); void onSure(); private: @@ -50,6 +46,7 @@ private: void updateColorPreview(const QColor& color); void addCurveToList(const FileEntryCurve::CurveProperty& curve); void updateCurveProperties(); + void updateCurvePropertiesUI(); void saveCurveProperties(); void clearCurveProperties(); void enableCurveProperties(bool enabled); diff --git a/src/ui/WorkSpace/AddCurveFileDlg.ui b/src/ui/WorkSpace/AddCurveFileDlg.ui index a65caf16..57d21058 100644 --- a/src/ui/WorkSpace/AddCurveFileDlg.ui +++ b/src/ui/WorkSpace/AddCurveFileDlg.ui @@ -99,52 +99,52 @@ + + + Chart Type: + + + + + + + X Axis Title: - + Enter X axis title... - + Y Axis Title: - + Enter Y axis title... - + - Time Parameter: + Time: - - - - 0.000000000000000 - - - 999999.000000000000000 - - - 0.000000000000000 - - + + @@ -463,6 +463,58 @@ + + + + false + + + X Value: + + + + + + + false + + + -999999.000000000000000 + + + 999999.000000000000000 + + + 0.000000000000000 + + + + + + + false + + + Y Value: + + + + + + + false + + + -999999.000000000000000 + + + 999999.000000000000000 + + + 0.000000000000000 + + + diff --git a/src/workspace/FileEntry.cpp b/src/workspace/FileEntry.cpp index 47706214..63d1cd09 100644 --- a/src/workspace/FileEntry.cpp +++ b/src/workspace/FileEntry.cpp @@ -259,6 +259,7 @@ bool FileEntryCurve::SaveFiles(tinyxml2::XMLElement* scene, tinyxml2::XMLDocumen // 设置chart属性 chartElement->SetAttribute("name", name_.toUtf8().constData()); chartElement->SetAttribute("path", fileName_.toUtf8().constData()); + chartElement->SetAttribute("Type", ChartTypeToString(chartProperties_.chartType)); // 新增:保存Chart类型 chartElement->SetAttribute("xCount", chartProperties_.xCount); chartElement->SetAttribute("yCount", chartProperties_.yCount); chartElement->SetAttribute("xTitle", chartProperties_.xTitle.toUtf8().constData()); @@ -276,8 +277,15 @@ bool FileEntryCurve::SaveFiles(tinyxml2::XMLElement* scene, tinyxml2::XMLDocumen curveElement->SetAttribute("name", curve.name.toUtf8().constData()); curveElement->SetAttribute("color", QColorToString(curve.color).toUtf8().constData()); - curveElement->SetAttribute("start", curve.start); - curveElement->SetAttribute("stop", curve.stop); + + // 根据Chart类型保存不同的属性 + if (chartProperties_.chartType == ChartType::Wave) { + curveElement->SetAttribute("start", curve.data.wave.start); + curveElement->SetAttribute("stop", curve.data.wave.stop); + } else if (chartProperties_.chartType == ChartType::Report) { + curveElement->SetAttribute("x", curve.data.report.x); + curveElement->SetAttribute("y", curve.data.report.y); + } } return true; @@ -308,6 +316,19 @@ bool FileEntryCurve::ParseFiles(const tinyxml2::XMLElement* chartElement) { path_ = fileInfo.absolutePath(); } + // 解析Chart类型(新增) + const char* typeAttr = chartElement->Attribute("Type"); + if (typeAttr) { + ChartType chartType; + if (ChartTypeFromString(typeAttr, chartType)) { + chartProperties_.chartType = chartType; + } else { + chartProperties_.chartType = ChartType::Wave; // 默认为Wave + } + } else { + chartProperties_.chartType = ChartType::Wave; // 向后兼容,默认为Wave + } + chartProperties_.xCount = chartElement->IntAttribute("xCount", 0); chartProperties_.yCount = chartElement->IntAttribute("yCount", 0); @@ -335,26 +356,14 @@ bool FileEntryCurve::ParseFiles(const tinyxml2::XMLElement* chartElement) { if (curveNameAttr) curve.name = QString::fromUtf8(curveNameAttr); if (colorAttr) curve.color = StringToQColor(QString::fromUtf8(colorAttr)); - const char* startAttr = curveElement->Attribute("start"); - if (startAttr) - { - curve.start = curveElement->IntAttribute("start", 0); - } - const char* stopAttr = curveElement->Attribute("stop"); - if (stopAttr) - { - curve.stop = curveElement->IntAttribute("stop", 0); - } - const char* xAttr = curveElement->Attribute("x"); - if (xAttr) - { - curve.x = curveElement->IntAttribute("x", 0); - } - const char* yAttr = curveElement->Attribute("y"); - if (yAttr) - { - curve.y = curveElement->IntAttribute("y", 0); - } + // 根据Chart类型解析不同的属性 + if (chartProperties_.chartType == ChartType::Wave) { + curve.data.wave.start = curveElement->IntAttribute("start", 0); + curve.data.wave.stop = curveElement->IntAttribute("stop", 0); + } else if (chartProperties_.chartType == ChartType::Report) { + curve.data.report.x = curveElement->DoubleAttribute("x", 0.0); + curve.data.report.y = curveElement->DoubleAttribute("y", 0.0); + } curveProperties_.append(curve); } diff --git a/src/workspace/FileEntry.h b/src/workspace/FileEntry.h index 5148f29f..908c0dd7 100644 --- a/src/workspace/FileEntry.h +++ b/src/workspace/FileEntry.h @@ -11,6 +11,26 @@ enum class FileEntryType { Light }; +enum class ChartType { + Wave, + Report +}; + +inline const char* ChartTypeToString(ChartType t) { + switch (t) { + case ChartType::Wave: return "Wave"; + case ChartType::Report: return "Report"; + } + return "Wave"; +} + +inline bool ChartTypeFromString(const char* s, ChartType& out) { + if (!s) return false; + if (0 == strcmp(s, "Wave")) { out = ChartType::Wave; return true; } + if (0 == strcmp(s, "Report")) { out = ChartType::Report; return true; } + return false; +} + inline const char* FileEntryTypeToString(FileEntryType t) { switch (t) { case FileEntryType::Curve: return "curve"; @@ -84,6 +104,7 @@ std::shared_ptr CreateEmptyFileEntryLight(); class FileEntryCurve : public FileEntry { public: struct ChartProperties { + ChartType chartType; // 新增:Chart类型 int xCount; int yCount; // 对应XML的yCount QString xTitle; @@ -98,28 +119,34 @@ public: struct CurveProperty { QString name; QColor color; - int start; - int stop; - int x; - int y; - CurveProperty() { - name = ""; - start = 0; - stop = 0; - x = 0; - y = 0; - } + // Wave类型使用start/stop,Report类型使用x/y + union { + struct { + int start; + int stop; + } wave; + struct { + double x; + double y; + } report; + } data; }; using CurveProperties = QList; public: - FileEntryCurve() { type_ = FileEntryType::Curve; } + FileEntryCurve() { + type_ = FileEntryType::Curve; + chartProperties_.chartType = ChartType::Wave; // 默认为Wave类型 + } void SetChartProperties(const ChartProperties& props) { chartProperties_ = props; } const ChartProperties& GetChartProperties() const { return chartProperties_; } + void SetChartType(ChartType type) { chartProperties_.chartType = type; } + ChartType GetChartType() const { return chartProperties_.chartType; } + void AddCurveProperty(const CurveProperty& prop) { curveProperties_.append(prop); } void RemoveCurveProperty(int index) { curveProperties_.removeAt(index); } const CurveProperties& GetCurveProperties() const { return curveProperties_; } diff --git a/src/workspace/WorkSpaceXMLParse.cpp b/src/workspace/WorkSpaceXMLParse.cpp index 737cb281..6e4f98fe 100644 --- a/src/workspace/WorkSpaceXMLParse.cpp +++ b/src/workspace/WorkSpaceXMLParse.cpp @@ -107,6 +107,19 @@ bool WorkSpaceXMLParse::ParseFiles(const tinyxml2::XMLElement* element) { return false; } + // 首先处理新的Chart元素结构 + const tinyxml2::XMLElement* chartElement = element->FirstChildElement("Chart"); + while (nullptr != chartElement) { + // 创建FileEntryCurve对象来解析Chart数据 + auto curveEntry = CreateEmptyFileEntryCurve(); + if (curveEntry && curveEntry->ParseFiles(chartElement)) { + // 添加解析后的FileEntry到workspace + workSpace_->SetFileEntry(curveEntry, false); + } + chartElement = chartElement->NextSiblingElement("Chart"); + } + + // 保持向后兼容:处理旧的type元素结构 const tinyxml2::XMLElement* typeElement = element->FirstChildElement("type"); while (nullptr != typeElement) { const char* name = typeElement->Attribute("name");