From 6040a3f698b214870ffbd3b4802fd6ed12755893 Mon Sep 17 00:00:00 2001 From: pimin <362371171@qq.com> Date: Sun, 2 Nov 2025 17:51:46 +0800 Subject: [PATCH] add iamge panel --- src/ui/Menu/FileManagerMenu.cpp | 11 + src/ui/Panel/ImagePanel.cpp | 8 +- src/ui/WorkSpace/AddCurveFileDlg.ui | 8 +- src/ui/WorkSpace/AddFileDialogFactory.cpp | 3 + src/ui/WorkSpace/AddImageDlg.ui | 848 ++++++++++++++++++++++ src/ui/WorkSpace/AddImageFileDlg.cpp | 593 +++++++++++++++ src/ui/WorkSpace/AddImageFileDlg.h | 61 ++ src/ui/chartPlot/DYTChart.cpp | 140 ++-- src/viewer/OsgWidget.cpp | 2 +- 9 files changed, 1597 insertions(+), 77 deletions(-) create mode 100644 src/ui/WorkSpace/AddImageDlg.ui create mode 100644 src/ui/WorkSpace/AddImageFileDlg.cpp create mode 100644 src/ui/WorkSpace/AddImageFileDlg.h diff --git a/src/ui/Menu/FileManagerMenu.cpp b/src/ui/Menu/FileManagerMenu.cpp index 3bb3fadd..ad9b8f4f 100644 --- a/src/ui/Menu/FileManagerMenu.cpp +++ b/src/ui/Menu/FileManagerMenu.cpp @@ -296,5 +296,16 @@ void FileManagerMenu::AddPolarFile() void FileManagerMenu::AddImageFile() { + auto current = WorkSpaceManager::Get().GetCurrent(); + if (nullptr == current) { + QMessageBox::information(&MainFrame::Get(), QObject::tr("prompt"), QObject::tr("please create workspace first")); + return; + } + // Show light file addition dialog + auto dialog = AddFileDialogFactory::createDialog(FileEntryType::Image, &MainFrame::Get()); + if (dialog && dialog->exec() == QDialog::Accepted) { + + SaveWorkSpace(); + } } \ No newline at end of file diff --git a/src/ui/Panel/ImagePanel.cpp b/src/ui/Panel/ImagePanel.cpp index 86c5ee41..38a17688 100644 --- a/src/ui/Panel/ImagePanel.cpp +++ b/src/ui/Panel/ImagePanel.cpp @@ -44,11 +44,9 @@ void ImagePanel::RefreshPanel() void ImagePanel::InitUI() { - - QHBoxLayout* mainLayout = new QHBoxLayout(this); - mainLayout->setContentsMargins(0, 0, 0, 0); - //mainLayout->addWidget(m_pTableWidget); - setLayout(mainLayout); + QGridLayout* pMainLyt = new QGridLayout(this); + pMainLyt->setContentsMargins(5, 0, 5, 0); + setLayout(pMainLyt); } QString ImagePanel::GetTypeDisplayName() const diff --git a/src/ui/WorkSpace/AddCurveFileDlg.ui b/src/ui/WorkSpace/AddCurveFileDlg.ui index d38df86f..0f93434a 100644 --- a/src/ui/WorkSpace/AddCurveFileDlg.ui +++ b/src/ui/WorkSpace/AddCurveFileDlg.ui @@ -612,7 +612,13 @@ 50 - 0 + 25 + + + + + 50 + 25 diff --git a/src/ui/WorkSpace/AddFileDialogFactory.cpp b/src/ui/WorkSpace/AddFileDialogFactory.cpp index ffb9fc9d..c69678d4 100644 --- a/src/ui/WorkSpace/AddFileDialogFactory.cpp +++ b/src/ui/WorkSpace/AddFileDialogFactory.cpp @@ -6,6 +6,7 @@ #include "AddTableFileDlg.h" #include "AddLightFileDlg.h" #include "AddPolarFileDlg.h" +#include "AddImageFileDlg.h" BaseAddFileDlg* AddFileDialogFactory::createDialog(FileEntryType type, QWidget* parent) { switch (type) { @@ -19,6 +20,8 @@ BaseAddFileDlg* AddFileDialogFactory::createDialog(FileEntryType type, QWidget* return new AddLightFileDlg(parent); case FileEntryType::Polar: return new AddPolarFileDlg(parent); + case FileEntryType::Image: + return new AddImageFileDlg(parent); default: return nullptr; } diff --git a/src/ui/WorkSpace/AddImageDlg.ui b/src/ui/WorkSpace/AddImageDlg.ui new file mode 100644 index 00000000..4a21a0c5 --- /dev/null +++ b/src/ui/WorkSpace/AddImageDlg.ui @@ -0,0 +1,848 @@ + + + AddImageDlg + + + + 0 + 0 + 580 + 756 + + + + Add Image + + + + + + File Selection + + + + + + + 0 + 25 + + + + File Path: + + + + + + + + 0 + 25 + + + + true + + + Select curve data file... + + + + + + + + 0 + 25 + + + + ... + + + + + + + + 0 + 25 + + + + File Name: + + + + + + + + 0 + 25 + + + + - + + + + + + + + 0 + 25 + + + + File Size: + + + + + + + + 0 + 25 + + + + - + + + + + + + + + + Angular Axis + + + + + + + 0 + 25 + + + + Title: + + + + + + + + 0 + 25 + + + + Enter axis title... + + + + + + + + 0 + 25 + + + + Min: + + + + + + + + 0 + 25 + + + + -999999.000000000000000 + + + 999999.000000000000000 + + + 0.000000000000000 + + + + + + + + 0 + 25 + + + + Max: + + + + + + + + 0 + 25 + + + + -999999.000000000000000 + + + 999999.000000000000000 + + + 360.000000000000000 + + + + + + + + 0 + 25 + + + + Count: + + + + + + + + 0 + 25 + + + + 2 + + + 50 + + + 13 + + + + + + + + 0 + 25 + + + + Unit: + + + + + + + + 0 + 25 + + + + Enter axis Unit... + + + + + + + + + + Radial Axis + + + + + + + 0 + 25 + + + + Title: + + + + + + + + 0 + 25 + + + + Enter axis title... + + + + + + + + 0 + 25 + + + + Min: + + + + + + + + 0 + 25 + + + + -999999.000000000000000 + + + 999999.000000000000000 + + + 0.000000000000000 + + + + + + + + 0 + 25 + + + + Max: + + + + + + + + 0 + 25 + + + + -999999.000000000000000 + + + 999999.000000000000000 + + + 0.000000000000000 + + + + + + + + 0 + 25 + + + + Count: + + + + + + + + 0 + 25 + + + + 2 + + + 50 + + + 6 + + + + + + + + 0 + 25 + + + + Unit: + + + + + + + + 0 + 25 + + + + Enter axis Unit... + + + + + + + + + + Curve Management + + + + + + + + Curves: + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 80 + 16777215 + + + + Add + + + + + + + + 0 + 0 + + + + + 60 + 16777215 + + + + Remove + + + + + + + + + + 16777215 + 120 + + + + false + + + + + + + false + + + Selected Curve Properties + + + + + + + 0 + 25 + + + + Name: + + + + + + + + 0 + 25 + + + + Enter curve name... + + + + + + + + 0 + 25 + + + + Color: + + + + + + + + + + 0 + 0 + + + + + 100 + 16777215 + + + + Select Color + + + + + + + + 50 + 25 + + + + background-color: rgb(255, 0, 0); border: 1px solid black; + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + 0 + 25 + + + + Angular: + + + + + + + + 0 + 25 + + + + 0 + + + 999999 + + + 0 + + + + + + + + 0 + 25 + + + + Radial: + + + + + + + + 0 + 25 + + + + 0 + + + 999999 + + + 0 + + + + + + + false + + + X Value: + + + + + + + false + + + -999999.000000000000000 + + + 999999.000000000000000 + + + 0.000000000000000 + + + + + + + false + + + Y Value: + + + + + + + false + + + -999999.000000000000000 + + + 999999.000000000000000 + + + 0.000000000000000 + + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 100 + 0 + + + + Add File + + + true + + + + + + + + 100 + 0 + + + + Cancel + + + + + + + + + Chart Properties + + + + + + + 0 + 25 + + + + + + + + + 0 + 25 + + + + Time: + + + + + + + + 0 + 25 + + + + Chart Name: + + + + + + + + 0 + 25 + + + + Chart 1 + + + Enter chart name... + + + + + + + + + + + diff --git a/src/ui/WorkSpace/AddImageFileDlg.cpp b/src/ui/WorkSpace/AddImageFileDlg.cpp new file mode 100644 index 00000000..49fa4914 --- /dev/null +++ b/src/ui/WorkSpace/AddImageFileDlg.cpp @@ -0,0 +1,593 @@ +#include "AddImageFileDlg.h" + +#include +#include +#include +#include +#include + +#include "workspace/WorkSpace.h" +#include "workspace/WorkSpaceManager.h" + +#include "ui_AddImageDlg.h" + +AddImageFileDlg::AddImageFileDlg(QWidget* parent) + : BaseAddFileDlg(FileEntryType::Polar, parent) + , ui(new Ui::AddImageDlg) + , currentCurveIndex_(-1) + , selectedColor_(255, 0, 0) +{ + + SetupUI(ui); + SetTitle(getDialogTitle()); + + setupConnections(); +} + +AddImageFileDlg::~AddImageFileDlg() +{ + delete ui; +} + + +QString AddImageFileDlg::getFileFilter() const +{ + return tr("Data Files (*.txt *.csv *.dat);;All Files (*.*)"); +} + +QString AddImageFileDlg::getDialogTitle() const +{ + return tr("Add Image"); +} + +bool AddImageFileDlg::validateSpecificParams() +{ + // File path validation + const QString& selectFilePath = getSelectedFilePath(); + if (selectFilePath.isEmpty()) + { + QMessageBox::warning(this, tr("Validation Error"), tr("Please select a data file.")); + return false; + } + + // File existence validation + QFileInfo fileInfo(selectFilePath); + if (!fileInfo.exists()) + { + QMessageBox::warning(this, tr("Validation Error"), tr("Selected file does not exist.")); + return false; + } + + // File readability validation + if (!fileInfo.isReadable()) + { + QMessageBox::warning(this, tr("Validation Error"), tr("Selected file is not readable. Please check file permissions.")); + return false; + } + + // File size validation (avoid memory issues with large files) + if (fileInfo.size() > 100 * 1024 * 1024) + { // 100MB limit + QMessageBox::warning(this, tr("Validation Error"), tr("File is too large (over 100MB). Please select a smaller file.")); + return false; + } + + // Curve count validation + if (curves_.isEmpty()) + { + QMessageBox::warning(this, tr("Validation Error"), tr("At least one curve must be defined.")); + return false; + } + + // Save current curve properties + if (currentCurveIndex_ >= 0) + { + saveCurveProperties(); + } + + // Curve name uniqueness validation + QStringList curveNames; + for (int i = 0; i < curves_.size(); ++i) + { + const FileEntryPolar::LineProperty& curve = curves_[i]; + + if (curve.name.isEmpty()) + { + QMessageBox::warning(this, tr("Validation Error"), + tr("Curve %1 name cannot be empty.").arg(i + 1)); + return false; + } + + if (curveNames.contains(curve.name)) + { + QMessageBox::warning(this, tr("Validation Error"), + tr("Curve name '%1' is duplicated. Please use different names.").arg(curve.name)); + return false; + } + curveNames.append(curve.name); + + // Curve name length validation + if (curve.name.length() > 50) + { + QMessageBox::warning(this, tr("Validation Error"), + tr("Curve name '%1' is too long. Please limit to 50 characters.").arg(curve.name)); + return false; + } + + // Report type validation - ensure x and y values are reasonable + if (curve.Angular < -1000000 || curve.Angular > 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.Radial < -1000000 || curve.Radial > 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; + } + } + + // Chart properties validation + if (ui->chartNameEdit->text().isEmpty()) + { + QMessageBox::warning(this, tr("Validation Error"), tr("Chart name cannot be empty.")); + return false; + } + + if (ui->chartNameEdit->text().length() > 100) + { + QMessageBox::warning(this, tr("Validation Error"), tr("Chart name is too long. Please limit to 100 characters.")); + return false; + } + + // Axis range validation + double AngularMin = ui->SpinBox_Min_Angular->value(); + double AngularMax = ui->SpinBox_Max_Angular->value(); + double RadialMin = ui->SpinBox_Min_Radial->value(); + double RadialMax = ui->SpinBox_Max_Radial->value(); + + if (AngularMin > AngularMax) + { + QMessageBox::warning(this, tr("Validation Error"), tr("Angular axis minimum value must be less than maximum value.")); + return false; + } + + if (RadialMin > RadialMax) + { + QMessageBox::warning(this, tr("Validation Error"), tr("Radial axis minimum value must be less than maximum value.")); + return false; + } + + + // Time parameter validation + double timeParam = ui->SpinBox_time->value(); + if (timeParam < 0) + { + QMessageBox::warning(this, tr("Validation Error"), tr("Time parameter cannot be negative.")); + return false; + } + + return true; +} + +void AddImageFileDlg::updateFileInfo(const QString& filePath) +{ + QFileInfo fileInfo(filePath); + if (fileInfo.exists()) { + ui->fileNameValue->setText(fileInfo.fileName()); + qint64 size = fileInfo.size(); + QString sizeText; + if (size < 1024) { + sizeText = QString("%1 B").arg(size); + } + else if (size < 1024 * 1024) { + sizeText = QString("%1 KB").arg(size / 1024.0, 0, 'f', 1); + } + else { + sizeText = QString("%1 MB").arg(size / (1024.0 * 1024.0), 0, 'f', 1); + } + ui->fileSizeValue->setText(sizeText); + } + else { + ui->fileNameValue->setText("-"); + ui->fileSizeValue->setText("-"); + } + + ui->filePathEdit->setText(filePath); +} + +void AddImageFileDlg::setupConnections() +{ + // File selection connections + connect(ui->selectFileBtn, &QToolButton::clicked, this, &AddImageFileDlg::OnSelectFile); + + // Curve management connections + connect(ui->addCurveBtn, &QPushButton::clicked, this, &AddImageFileDlg::onAddCurveClicked); + connect(ui->removeCurveBtn, &QPushButton::clicked, this, &AddImageFileDlg::onRemoveCurveClicked); + connect(ui->curveListWidget, &QListWidget::currentRowChanged, this, &AddImageFileDlg::onCurveSelectionChanged); + connect(ui->curveListWidget, &QListWidget::itemClicked, this, &AddImageFileDlg::onCurveListWidgetItemClicked); + + // Curve properties connections + connect(ui->colorButton, &QPushButton::clicked, this, &AddImageFileDlg::onColorButtonClicked); + connect(ui->curveNameEdit, &QLineEdit::textChanged, this, &AddImageFileDlg::onCurveNameChanged); + connect(ui->SpinBox_Angular, QOverload::of(&QSpinBox::valueChanged), this, &AddImageFileDlg::onCurveDataChanged); + connect(ui->SpinBox_Radial, QOverload::of(&QSpinBox::valueChanged), this, &AddImageFileDlg::onCurveDataChanged); + + // Dialog buttons + connect(ui->addBtn, &QPushButton::clicked, this, &AddImageFileDlg::onSure); + connect(ui->cancelBtn, &QPushButton::clicked, this, &QDialog::reject); +} + +void AddImageFileDlg::onColorButtonClicked() +{ + if (currentCurveIndex_ >= 0 && currentCurveIndex_ < curves_.size()) + { + QColor color = QColorDialog::getColor(curves_[currentCurveIndex_].color, this, "Select Curve Color"); + if (color.isValid()) + { + curves_[currentCurveIndex_].color = color; + selectedColor_ = color; + updateColorPreview(color); + + // Update list item text + QListWidgetItem* item = ui->curveListWidget->item(currentCurveIndex_); + if (item) + { + QString itemText = QString("%1 (%2,%3) (%4,%5,%6)") + .arg(curves_[currentCurveIndex_].name) + .arg(curves_[currentCurveIndex_].Angular) + .arg(curves_[currentCurveIndex_].Radial) + .arg(color.red()) + .arg(color.green()) + .arg(color.blue()); + + item->setText(itemText); + } + } + } +} + +void AddImageFileDlg::updateColorPreview(const QColor& color) +{ + QString styleSheet = QString("background-color: rgb(%1, %2, %3); border: 1px solid black;") + .arg(color.red()) + .arg(color.green()) + .arg(color.blue()); + ui->colorPreview->setStyleSheet(styleSheet); +} + +void AddImageFileDlg::onAddCurveClicked() +{ + // Save current curve properties if any curve is selected + if (currentCurveIndex_ >= 0) + { + saveCurveProperties(); + } + + // Create new curve with default properties based on chart type + FileEntryPolar::LineProperty newCurve; + newCurve.name = generateCurveName(); + newCurve.color = generateCurveColor(); + newCurve.Angular = 0.0; + newCurve.Radial = 0.0; + + // Add to curves list and UI + curves_.append(newCurve); + + // Add to UI list widget with appropriate display format + QString displayText = QString("%1 (%2,%3) (%4,%5,%6)") + .arg(newCurve.name) + .arg(newCurve.Angular) + .arg(newCurve.Radial) + .arg(newCurve.color.red()) + .arg(newCurve.color.green()) + .arg(newCurve.color.blue()); + + QListWidgetItem* item = new QListWidgetItem(displayText); + ui->curveListWidget->addItem(item); + ++currentCurveIndex_; + + ui->curveNameEdit->setText(newCurve.name); + + // Select the new curve + ui->curveListWidget->setCurrentRow(curves_.size() - 1); +} + +void AddImageFileDlg::onRemoveCurveClicked() +{ + int currentRow = ui->curveListWidget->currentRow(); + if (currentRow < 0 || currentRow >= curves_.size()) + { + return; + } + + // Don't allow removing the last curve + if (curves_.size() <= 0) + { + QMessageBox::information(this, "Information", "At least one curve must remain."); + return; + } + + // Remove from curves list and UI + curves_.removeAt(currentRow); + delete ui->curveListWidget->takeItem(currentRow); + + // Update current index + if (currentRow >= curves_.size()) + { + currentRow = curves_.size() - 1; + } + + if (currentRow >= 0) + { + ui->curveListWidget->setCurrentRow(currentRow); + } + else + { + currentCurveIndex_ = -1; + clearCurveProperties(); + enableCurveProperties(false); + } +} + +void AddImageFileDlg::onCurveListWidgetItemClicked(QListWidgetItem* item) +{ + if (!item) + { + return; + } + + int clickedIndex = ui->curveListWidget->row(item); + + if (clickedIndex == currentCurveIndex_) + { + ui->curveNameEdit->setText(curves_[currentCurveIndex_].name); + + ui->SpinBox_Angular->blockSignals(true); + ui->SpinBox_Angular->setValue(curves_[currentCurveIndex_].Angular); + ui->SpinBox_Angular->blockSignals(false); + + ui->SpinBox_Radial->blockSignals(true); + ui->SpinBox_Radial->setValue(curves_[currentCurveIndex_].Radial); + ui->SpinBox_Radial->blockSignals(false); + + updateColorPreview(curves_[currentCurveIndex_].color); + enableCurveProperties(true); + + ui->curveNameEdit->setFocus(); + ui->curveNameEdit->selectAll(); + } + else + { + onCurveSelectionChanged(); + } +} + +void AddImageFileDlg::onCurveSelectionChanged() +{ + int currentRow = ui->curveListWidget->currentRow(); + + // Save previous curve properties + if (currentCurveIndex_ >= 0 && currentCurveIndex_ < curves_.size()) + { + saveCurveProperties(); + } + + currentCurveIndex_ = currentRow; + + if (currentRow >= 0 && currentRow < curves_.size()) + { + // Load selected curve properties + updateCurveProperties(); + enableCurveProperties(true); + } + else + { + clearCurveProperties(); + enableCurveProperties(false); + } +} + +void AddImageFileDlg::onCurveNameChanged() +{ + if (currentCurveIndex_ >= 0 && currentCurveIndex_ < curves_.size()) + { + QString newName = ui->curveNameEdit->text(); + curves_[currentCurveIndex_].name = newName; + + // Update list item text with appropriate format + QListWidgetItem* item = ui->curveListWidget->item(currentCurveIndex_); + if (item) + { + QString displayText = QString("%1 (%2,%3) (%4,%5,%6)") + .arg(newName) + .arg(curves_[currentCurveIndex_].Angular) + .arg(curves_[currentCurveIndex_].Radial) + .arg(curves_[currentCurveIndex_].color.red()) + .arg(curves_[currentCurveIndex_].color.green()) + .arg(curves_[currentCurveIndex_].color.blue()); + + item->setText(displayText); + } + } +} + +void AddImageFileDlg::saveCurveProperties() +{ + if (currentCurveIndex_ >= 0 && currentCurveIndex_ < curves_.size()) + { + curves_[currentCurveIndex_].name = ui->curveNameEdit->text(); + + // Save properties based on chart type + curves_[currentCurveIndex_].Angular = ui->SpinBox_Angular->value(); + curves_[currentCurveIndex_].Radial = ui->SpinBox_Radial->value(); + + curves_[currentCurveIndex_].color = selectedColor_; + } +} + +void AddImageFileDlg::clearCurveProperties() +{ + ui->curveNameEdit->clear(); + + // Clear properties based on chart type + ui->SpinBox_Angular->setValue(0.0); + ui->SpinBox_Radial->setValue(0.0); + + selectedColor_ = QColor(255, 0, 0); + updateColorPreview(selectedColor_); +} + +void AddImageFileDlg::enableCurveProperties(bool enabled) +{ + ui->curvePropertiesGroupBox->setEnabled(enabled); +} + +QString AddImageFileDlg::generateCurveName() +{ + return tr("Curve %1").arg(curves_.size() + 1); +} + +QColor AddImageFileDlg::generateCurveColor() const +{ + // Generate different colors for each curve + static const QColor colors[] = { + QColor(255, 0, 0), // Red + QColor(0, 255, 0), // Green + QColor(0, 0, 255), // Blue + QColor(255, 255, 0), // Yellow + QColor(255, 0, 255), // Magenta + QColor(0, 255, 255), // Cyan + QColor(255, 128, 0), // Orange + QColor(128, 0, 255), // Purple + }; + + int colorIndex = curves_.size() % (sizeof(colors) / sizeof(colors[0])); + return colors[colorIndex]; +} + +void AddImageFileDlg::updateCurveProperties() +{ + if (currentCurveIndex_ >= 0 && currentCurveIndex_ < curves_.size()) + { + const FileEntryPolar::LineProperty& curve = curves_[currentCurveIndex_]; + + ui->curveNameEdit->setText(curve.name); + + ui->SpinBox_Angular->blockSignals(true); + ui->SpinBox_Angular->setValue(curve.Angular); + ui->SpinBox_Angular->blockSignals(false); + + ui->SpinBox_Radial->blockSignals(true); + ui->SpinBox_Radial->setValue(curve.Radial); + ui->SpinBox_Radial->blockSignals(false); + + selectedColor_ = curve.color; + updateColorPreview(curve.color); + } +} + +void AddImageFileDlg::onSure() +{ + if (validateSpecificParams()) + { + // Create FileEntryCurve object using factory function + auto fileEntryPolar = CreateFileEntryPolar(getSelectedFilePath()); + if (!fileEntryPolar) + { + QMessageBox::warning(this, tr("Error"), tr("Failed to create file entry")); + return; + } + + // Set curve properties + fileEntryPolar->SetName(ui->chartNameEdit->text()); + + // Set chart properties + FileEntryPolar::ChartProperties chartProps; + chartProps.AngularCount = ui->SpinBox_Count_Angular->value(); + chartProps.RadialCount = ui->SpinBox_Count_Radial->value(); + chartProps.AngularTitle = ui->TitleEdit_Angular->text(); + chartProps.RadialTitle = ui->TitleEdit_Radial->text(); + chartProps.AngularUnit = ui->TitleEdit_Unit_Angular->text(); + chartProps.RadialUnit = ui->TitleEdit_Unit_Radial->text(); + chartProps.AngularMin = ui->SpinBox_Min_Angular->value(); + chartProps.AngularMax = ui->SpinBox_Max_Angular->value(); + chartProps.RadialMin = ui->SpinBox_Min_Radial->value(); + chartProps.RadialMax = ui->SpinBox_Max_Radial->value(); + chartProps.timeParam = ui->SpinBox_time->value(); + fileEntryPolar->SetChartProperties(chartProps); + + // Add curve properties + for (const auto& curve : curves_) + { + fileEntryPolar->AddLineProperty(curve); + } + + // Get current workspace + WorkSpace* workspace = WorkSpaceManager::Get().GetCurrent(); + if (!workspace) + { + QMessageBox::warning(this, tr("Error"), tr("Unable to get current workspace")); + return; + } + + // Add FileEntryCurve to workspace using new SetFileEntry method + auto result = workspace->SetFileEntry(fileEntryPolar); + if (result != WorkSpace::FileEntryResult::Ok) + { + QString errorMsg; + switch (result) { + case WorkSpace::FileEntryResult::LimitExceeded: + errorMsg = tr("Polar file count has reached the limit (9 files)"); + break; + case WorkSpace::FileEntryResult::Duplicate: + errorMsg = tr("File already exists"); + break; + case WorkSpace::FileEntryResult::CopyFailed: + errorMsg = tr("File copy failed"); + break; + case WorkSpace::FileEntryResult::InvalidFile: + errorMsg = tr("Invalid file"); + break; + default: + errorMsg = tr("Failed to add file"); + break; + } + QMessageBox::warning(this, tr("Error"), errorMsg); + return; + } + + accept(); + } + else + { + QMessageBox::critical(this, tr("Error"), tr("Failed to create Polar file entry.")); + } +} + +void AddImageFileDlg::onCurveDataChanged() +{ + if (currentCurveIndex_ >= 0 && currentCurveIndex_ < curves_.size()) + { + curves_[currentCurveIndex_].Angular = ui->SpinBox_Angular->value(); + curves_[currentCurveIndex_].Radial = ui->SpinBox_Radial->value(); + + // Update display text in list widget + QListWidgetItem* item = ui->curveListWidget->item(currentCurveIndex_); + if (item) + { + QString itemText = QString("%1 (%2,%3) (%4,%5,%6)") + .arg(curves_[currentCurveIndex_].name) + .arg(curves_[currentCurveIndex_].Angular) + .arg(curves_[currentCurveIndex_].Radial) + .arg(curves_[currentCurveIndex_].color.red()) + .arg(curves_[currentCurveIndex_].color.green()) + .arg(curves_[currentCurveIndex_].color.blue()); + + item->setText(itemText); + } + } +} \ No newline at end of file diff --git a/src/ui/WorkSpace/AddImageFileDlg.h b/src/ui/WorkSpace/AddImageFileDlg.h new file mode 100644 index 00000000..adbb4a96 --- /dev/null +++ b/src/ui/WorkSpace/AddImageFileDlg.h @@ -0,0 +1,61 @@ +#pragma once + +#include "BaseAddFileDlg.h" +#include "workspace/FileEntry.h" + +QT_BEGIN_NAMESPACE +class QComboBox; +class QLineEdit; +class QSpinBox; +class QDoubleSpinBox; +class QListWidget; +class QPushButton; +class QLabel; +QT_END_NAMESPACE + +namespace Ui { + class AddImageDlg; +} + +class AddImageFileDlg : public BaseAddFileDlg +{ + Q_OBJECT + +public: + explicit AddImageFileDlg(QWidget* parent = nullptr); + ~AddImageFileDlg() override; + +protected: + QString getFileFilter() const override; + QString getDialogTitle() const override; + bool validateSpecificParams() override; + void updateFileInfo(const QString& filePath) override; + +private slots: + void onColorButtonClicked(); + void onAddCurveClicked(); + void onRemoveCurveClicked(); + void onCurveListWidgetItemClicked(class QListWidgetItem* item); + void onCurveSelectionChanged(); + void onCurveNameChanged(); + void onCurveDataChanged(); + void onSure(); + +private: + void setupConnections(); + void updateColorPreview(const QColor& color); + void updateCurveProperties(); + void saveCurveProperties(); + void clearCurveProperties(); + void enableCurveProperties(bool enabled); + QString generateCurveName(); + QColor generateCurveColor() const; + +private: + Ui::AddImageDlg* ui; + int currentCurveIndex_; + QColor selectedColor_; + + FileEntryPolar::ChartProperties chartProperties_; + FileEntryPolar::LineProperties curves_; +}; \ No newline at end of file diff --git a/src/ui/chartPlot/DYTChart.cpp b/src/ui/chartPlot/DYTChart.cpp index 12832027..43e8fc15 100644 --- a/src/ui/chartPlot/DYTChart.cpp +++ b/src/ui/chartPlot/DYTChart.cpp @@ -104,7 +104,7 @@ void DYTChart::InitChartData(QVariant var) InitXTable(strFilePathX); InitYTable(strFilePathY); - // ��ά���� + // 三维曲线 if (m_iCurveType == 3) { QString strFilePathZ = varCurParamMap.value("zFile").toString(); @@ -130,7 +130,7 @@ void DYTChart::InitChart(int iType) ui.comboBox->hide(); - if (1 == iType) // ��ά���� + if (1 == iType) // 二维曲线 { /*m_p2DCurve = new FitCurveDialog(1); m_p2DCurve->show(); @@ -150,7 +150,7 @@ void DYTChart::InitChart(int iType) ui.label_7->hide(); ui.toolButton_10->hide(); } - else if (2 == iType) // ��ά���ߣ�y������� + else if (2 == iType) // 二维曲线(y轴对数) { //m_p2DLgCurve = new FitCurveDialog(2); ////ui.stackedWidget->insertWidget(0, m_p2DLgCurve); @@ -171,7 +171,7 @@ void DYTChart::InitChart(int iType) ui.label_7->hide(); ui.toolButton_10->hide(); } - else // ��ά���� + else // 三维曲线 { ui.label_13->hide(); ui.comboBox_3->hide(); @@ -267,11 +267,11 @@ void DYTChart::ParseAntennaPatternFile(const QString& strFile, std::vector>& { if (strFile.isEmpty()) { - //QMessageBox::information(nullptr, QString::fromLocal8Bit("��ʾ"), QString::fromLocal8Bit("��������RD�ļ�·����")); + QMessageBox::information(nullptr, QString::fromLocal8Bit("提示"), QString::fromLocal8Bit("请检查数据RD文件路径!")); return; } @@ -332,7 +332,7 @@ void DYTChart::ParseRD(const QString& strFile, std::vector>& if (file.open(QIODevice::ReadOnly)) { int iRow = 0; - int iStartReadRow = iRowCount * m_iCurTime; // ��ʼ �� + int iStartReadRow = iRowCount * m_iCurTime; // 起始 行 while (!file.atEnd()) { if (iRow >= iStartReadRow && (iRow - iStartReadRow) <= iRowCount) @@ -366,7 +366,7 @@ void DYTChart::ParseWave(const QString& strFile, std::vector> { if (strFile.isEmpty()) { - //QMessageBox::information(nullptr, QString::fromLocal8Bit("��ʾ"), QString::fromLocal8Bit("��������Wave�ļ�·����")); + QMessageBox::information(nullptr, QString::fromLocal8Bit("提示"), QString::fromLocal8Bit("请检查数据Wave文件路径!")); return; } @@ -374,7 +374,7 @@ void DYTChart::ParseWave(const QString& strFile, std::vector> if (file.open(QIODevice::ReadOnly)) { int iRow = 0; - int iStartReadRow = iRowCount * m_iCurTime; // ��ʼ �� + int iStartReadRow = iRowCount * m_iCurTime; // 起始 行 while (!file.atEnd()) { if (iRow >= iStartReadRow && (iRow - iStartReadRow) <= iRowCount) @@ -769,33 +769,33 @@ void DYTChart::UpdateRDCurve(int iTime, int iSelRowCount) varCurDataList.push_back(varX); } - // ������ɫ + // 曲线颜色 QColor curColor; curColor.setNamedColor(ui.label_4->text()); - // �������� + // 曲线名称 QString strName = ui.lineEdit_2->text(); - // y������ 0һ��1���� + // y轴类型 0一般1对数 int iYType = 0; if (2 == m_iCurveType) { iYType = 1; } - // x������ + // x轴数据 QString strFilePathX = ui.lineEdit->text(); - // y������ + // y轴数据 QString strFilePathY = ui.lineEdit_3->text(); - // Z������ + // Z轴数据 QString strFilePathZ = ui.lineEdit_9->text(); - // �������� + // 曲线类型 //int iCurveType = ui.comboBox_2->currentIndex(); - // x���� + // x标题 QString strXTitle = ui.lineEdit_10->text(); - // y���� + // y标题 QString strYTitle = ui.lineEdit_11->text(); - // z���� + // z标题 QString strZTitle = ui.lineEdit_12->text(); int iXCol = 0, iYCol = 0, iZCol = 0; @@ -866,10 +866,10 @@ void DYTChart::Clear() void DYTChart::slotSelXFile() { - QString strFilePath = QFileDialog::getOpenFileName(nullptr, QString::fromLocal8Bit("ѡ�������ļ�"), "home", "*.txt"); + QString strFilePath = QFileDialog::getOpenFileName(nullptr, QString::fromLocal8Bit("选择数据文件"), "home", "*.txt"); if (strFilePath.isEmpty()) { - QMessageBox::information(nullptr, QString::fromLocal8Bit("��ʾ"), QString::fromLocal8Bit("��ѡ����Ч���ļ�·����")); + QMessageBox::information(nullptr, QString::fromLocal8Bit("提示"), QString::fromLocal8Bit("请选择有效的文件路径!")); return; } @@ -880,10 +880,10 @@ void DYTChart::slotSelXFile() void DYTChart::slotSelYFile() { - QString strFilePath = QFileDialog::getOpenFileName(nullptr, QString::fromLocal8Bit("ѡ�������ļ�"), "home", "*.txt"); + QString strFilePath = QFileDialog::getOpenFileName(nullptr, QString::fromLocal8Bit("选择数据文件"), "home", "*.txt"); if (strFilePath.isEmpty()) { - QMessageBox::information(nullptr, QString::fromLocal8Bit("��ʾ"), QString::fromLocal8Bit("��ѡ����Ч���ļ�·����")); + QMessageBox::information(nullptr, QString::fromLocal8Bit("提示"), QString::fromLocal8Bit("请选择有效的文件路径!")); return; } @@ -894,10 +894,10 @@ void DYTChart::slotSelYFile() void DYTChart::slotSelZFile() { - QString strFilePath = QFileDialog::getOpenFileName(nullptr, QString::fromLocal8Bit("ѡ�������ļ�"), "home", "*.txt"); + QString strFilePath = QFileDialog::getOpenFileName(nullptr, QString::fromLocal8Bit("选择数据文件"), "home", "*.txt"); if (strFilePath.isEmpty()) { - QMessageBox::information(nullptr, QString::fromLocal8Bit("��ʾ"), QString::fromLocal8Bit("��ѡ����Ч���ļ�·����")); + QMessageBox::information(nullptr, QString::fromLocal8Bit("提示"), QString::fromLocal8Bit("请选择有效的文件路径!")); return; } @@ -997,19 +997,19 @@ void DYTChart::slotAdd() } - // x������ + // x轴数据 QString strFilePathX = ui.lineEdit->text(); - // y������ + // y轴数据 QString strFilePathY = ui.lineEdit_3->text(); - // Z������ + // Z轴数据 QString strFilePathZ = ui.lineEdit_9->text(); - // �������� + // 曲线类型 //int iCurveType = ui.comboBox_2->currentIndex(); - // x���� + // x标题 QString strXTitle = ui.lineEdit_10->text(); - // y���� + // y标题 QString strYTitle = ui.lineEdit_11->text(); - // z���� + // z标题 QString strZTitle = ui.lineEdit_12->text(); std::vector vecX; @@ -1017,7 +1017,7 @@ void DYTChart::slotAdd() std::vector> vecZ; int iXCol = 0, iYCol = 0, iZCol = 0; - // ��ȡx������ + // 读取x轴数据 { iXCol = ui.comboBox_2->currentIndex(); int iRowCount = ui.tableWidget->rowCount(); @@ -1037,12 +1037,12 @@ void DYTChart::slotAdd() } else { - //QMessageBox::information(nullptr, QString::fromLocal8Bit("��ʾ"), QString::fromLocal8Bit("X�������ļ�����ʧ�ܣ������ļ��Ƿ�������")); + //QMessageBox::information(nullptr, QString::fromLocal8Bit("提示"), QString::fromLocal8Bit("X轴数据文件加载失败,请检测文件是否正常!")); return; } } - // ��ȡy������ + // 读取y轴数据 { iYCol = ui.comboBox_4->currentIndex(); int iRowCount = ui.tableWidget_2->rowCount(); @@ -1059,12 +1059,12 @@ void DYTChart::slotAdd() } else { - //QMessageBox::information(nullptr, QString::fromLocal8Bit("��ʾ"), QString::fromLocal8Bit("Y�������ļ�����ʧ�ܣ������ļ��Ƿ�������")); + //QMessageBox::information(nullptr, QString::fromLocal8Bit("提示"), QString::fromLocal8Bit("Y轴数据文件加载失败,请检测文件是否正常!")); return; } } - // ��ά���� + // 三维曲线 if (m_iCurveType == 3) { //iZCol = ui.comboBox_5->currentIndex(); @@ -1089,23 +1089,23 @@ void DYTChart::slotAdd() } else { - //QMessageBox::information(nullptr, QString::fromLocal8Bit("��ʾ"), QString::fromLocal8Bit("Z�������ļ�����ʧ�ܣ������ļ��Ƿ�������")); + //QMessageBox::information(nullptr, QString::fromLocal8Bit("提示"), QString::fromLocal8Bit("Z轴数据文件加载失败,请检测文件是否正常!")); return; } } - // �����������ݵij��ȣ�����С���ȶ��� + // 对齐两组数据的长度,按最小长度对齐 size_t min_size = std::min({ vecX.size(), vecY.size() }); if (vecZ.size() > 0) { min_size = std::min({ min_size, vecZ.size() }); } - // �ϲ����� + // 合并数据 QVariantList varCurDataList; for (size_t i = 0; i < min_size; i++) { - if (m_iCurveType == 3) // ��ά�������� + if (m_iCurveType == 3) // 三维曲线数据 { std::vector vecZRow = vecZ[i]; @@ -1128,21 +1128,21 @@ void DYTChart::slotAdd() } } - // ������ɫ + // 曲线颜色 QColor curColor; curColor.setNamedColor(ui.label_4->text()); - // �������� + // 曲线名称 QString strName = ui.lineEdit_2->text(); - // y������ 0һ��1���� + // y轴类型 0一般1对数 int iYType = 0; if (2 == m_iCurveType) { iYType = 1; } - // ����ID + // 曲线ID m_iCurveID++; m_iCurSelID = m_iCurveID; @@ -1200,19 +1200,19 @@ void DYTChart::slotUpdate() return; } - // x������ + // x轴数据 QString strFilePathX = ui.lineEdit->text(); - // y������ + // y轴数据 QString strFilePathY = ui.lineEdit_3->text(); - // Z������ + // Z轴数据 QString strFilePathZ = ui.lineEdit_9->text(); - // �������� + // 曲线类型 //int iCurveType = ui.comboBox_2->currentIndex(); - // x���� + // x标题 QString strXTitle = ui.lineEdit_10->text(); - // y���� + // y标题 QString strYTitle = ui.lineEdit_11->text(); - // z���� + // z标题 QString strZTitle = ui.lineEdit_12->text(); std::vector vecX; @@ -1220,7 +1220,7 @@ void DYTChart::slotUpdate() std::vector> vecZ; int iXCol = 0, iYCol = 0, iZCol = 0; - // ��ȡx������ + // 读取x轴数据 { iXCol = ui.comboBox_2->currentIndex(); int iRowCount = ui.tableWidget->rowCount(); @@ -1240,12 +1240,12 @@ void DYTChart::slotUpdate() } else { - //QMessageBox::information(nullptr, QString::fromLocal8Bit("��ʾ"), QString::fromLocal8Bit("X�������ļ�����ʧ�ܣ������ļ��Ƿ�������")); + QMessageBox::information(nullptr, QString::fromLocal8Bit("提示"), QString::fromLocal8Bit("X轴数据文件加载失败,请检测文件是否正常!")); return; } } - // ��ȡy������ + // 读取y轴数据 { iYCol = ui.comboBox_4->currentIndex(); int iRowCount = ui.tableWidget_2->rowCount(); @@ -1262,12 +1262,12 @@ void DYTChart::slotUpdate() } else { - QMessageBox::information(nullptr, QString::fromLocal8Bit("��ʾ"), QString::fromLocal8Bit("Y�������ļ�����ʧ�ܣ������ļ��Ƿ�������")); + QMessageBox::information(nullptr, QString::fromLocal8Bit("提示"), QString::fromLocal8Bit("Y轴数据文件加载失败,请检测文件是否正常!")); return; } } - // ��ά���� + // 三维曲线 if (m_iCurveType == 3) { //iZCol = ui.comboBox_5->currentIndex(); @@ -1292,23 +1292,23 @@ void DYTChart::slotUpdate() } else { - QMessageBox::information(nullptr, QString::fromLocal8Bit("��ʾ"), QString::fromLocal8Bit("Z�������ļ�����ʧ�ܣ������ļ��Ƿ�������")); + QMessageBox::information(nullptr, QString::fromLocal8Bit("提示"), QString::fromLocal8Bit("Z轴数据文件加载失败,请检测文件是否正常!")); return; } } - // �����������ݵij��ȣ�����С���ȶ��� + // 对齐两组数据的长度,按最小长度对齐 size_t min_size = std::min({ vecX.size(), vecY.size() }); if (vecZ.size() > 0) { min_size = std::min({ min_size, vecZ.size() }); } - // �ϲ����� + // 合并数据 QVariantList varCurDataList; for (size_t i = 0; i < min_size; i++) { - if (m_iCurveType == 3) // ��ά�������� + if (m_iCurveType == 3) // 三维曲线数据 { std::vector vecZRow = vecZ[i]; @@ -1331,14 +1331,14 @@ void DYTChart::slotUpdate() } } - // ������ɫ + // 曲线颜色 QColor curColor; curColor.setNamedColor(ui.label_4->text()); - // �������� + // 曲线名称 QString strName = ui.lineEdit_2->text(); - // y������ 0һ��1���� + // y轴类型 0一般1对数 int iYType = 0; if (2 == m_iCurveType) { @@ -1458,7 +1458,7 @@ void DYTChart::slotUpdateTime(double iTime) std::vector vecY; std::vector> vecZ; - // ��ȡx������ + // 读取x轴数据 { int iRowCount = ui.tableWidget->rowCount(); if (iRowCount > 0) @@ -1477,7 +1477,7 @@ void DYTChart::slotUpdateTime(double iTime) } } - // ��ȡy������ + // 读取y轴数据 { int iRowCount = ui.tableWidget_2->rowCount(); if (iRowCount > 0) @@ -1493,14 +1493,14 @@ void DYTChart::slotUpdateTime(double iTime) } } - // �����������ݵij��ȣ�����С���ȶ��� + // 对齐两组数据的长度,按最小长度对齐 size_t min_size = std::min({ vecX.size(), vecY.size() }); if (vecZ.size() > 0) { min_size = std::min({ min_size, vecZ.size() }); } - // �ϲ����� + // 合并数据 QVariantList varCurDataList; for (size_t i = 0; i < min_size; i++) { diff --git a/src/viewer/OsgWidget.cpp b/src/viewer/OsgWidget.cpp index 938059c8..201efaa9 100644 --- a/src/viewer/OsgWidget.cpp +++ b/src/viewer/OsgWidget.cpp @@ -161,7 +161,7 @@ osgQt::GraphicsWindowQt* OsgWidget::createGraphicsWindow(int x, int y, int w, in traits->alpha = ds->getMinimumNumAlphaBits(); traits->stencil = ds->getMinimumNumStencilBits(); traits->sampleBuffers = ds->getMultiSamples(); - traits->samples = ds->getNumMultiSamples(); + traits->samples = 16/*ds->getNumMultiSamples()*/; return new osgQt::GraphicsWindowQt(traits.get()); }