From 05d2968d41efe6e431b5b929f6da4c93ca4d1e44 Mon Sep 17 00:00:00 2001 From: brige Date: Sun, 26 Oct 2025 15:55:41 +0800 Subject: [PATCH] modify file entity --- src/translations/Dyt_zh_CN.ts | 220 ++++++++++------ src/ui/Menu/FileManagerMenu.cpp | 116 +++++---- src/ui/Panel/DataPanelManager.cpp | 6 +- .../PropertyBrowser/qtworkspaceattribute.cpp | 15 +- src/ui/PropertyBrowser/qtworkspaceattribute.h | 2 +- src/ui/WorkSpace/AddCurveFileDlg.cpp | 245 +++++++++--------- src/ui/WorkSpace/AddCurveFileDlg.h | 59 +---- src/ui/WorkSpace/AddLightFileDlg.cpp | 4 - src/ui/WorkSpace/AddLightFileDlg.h | 2 +- src/ui/WorkSpace/AddSurfaceFileDlg.cpp | 5 - src/ui/WorkSpace/AddSurfaceFileDlg.h | 1 - src/ui/WorkSpace/AddTableFileDlg.cpp | 5 - src/ui/WorkSpace/AddTableFileDlg.h | 1 - src/ui/WorkSpace/BaseAddFileDlg.cpp | 85 +----- src/ui/WorkSpace/BaseAddFileDlg.h | 23 +- src/workspace/FileEntry.cpp | 79 ++++++ src/workspace/FileEntry.h | 82 +++++- src/workspace/WorkSpace.cpp | 125 ++++++--- src/workspace/WorkSpace.h | 13 +- src/workspace/WorkSpaceXMLParse.cpp | 4 +- 20 files changed, 608 insertions(+), 484 deletions(-) create mode 100644 src/workspace/FileEntry.cpp diff --git a/src/translations/Dyt_zh_CN.ts b/src/translations/Dyt_zh_CN.ts index bbabbc89..e3bf245a 100644 --- a/src/translations/Dyt_zh_CN.ts +++ b/src/translations/Dyt_zh_CN.ts @@ -245,152 +245,194 @@ - + 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. - + 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. - + X column and Y column cannot be the same. - + Data column indices must be greater than 0. - + Time parameter cannot be negative. - + X axis tick count must be at least 2. - + Description is too long. Please limit to 500 characters. + + + + + 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 + + AddLightFileDlg @@ -1740,30 +1782,34 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + prompt - - - + + + please create workspace first @@ -1773,42 +1819,50 @@ - - + + - + Error - - + + - - Failed to set file path + + Failed to create file entry - - - - + + + + + invalid file + + + + + + + up to 9 files allowed for this type - - - - + + + + file already added for this type - - - - + + + + copy file failed diff --git a/src/ui/Menu/FileManagerMenu.cpp b/src/ui/Menu/FileManagerMenu.cpp index b10caebb..f5c94408 100644 --- a/src/ui/Menu/FileManagerMenu.cpp +++ b/src/ui/Menu/FileManagerMenu.cpp @@ -96,20 +96,19 @@ void FileManagerMenu::AddWaveFile() { if (dialog && dialog->exec() == QDialog::Accepted) { QString selectedPath = dialog->getSelectedFilePath(); - // Create file entry - switch (current->CreateFileEntry(FileEntryType::Curve)) { - case WorkSpace::FileEntryResult::Ok: { - // Get the index of the newly created file entry - auto entries = current->GetFileEntries(FileEntryType::Curve); - int newIndex = static_cast(entries.size()) - 1; - - // Set file path - if (!current->SetFileEntryPath(FileEntryType::Curve, newIndex, selectedPath)) { - QMessageBox::warning(&MainFrame::Get(), QObject::tr("Error"), - QObject::tr("Failed to set file path")); - } - break; + // Create file entry using factory function + auto fileEntry = CreateFileEntryCurve(selectedPath); + if (!fileEntry) { + QMessageBox::warning(&MainFrame::Get(), QObject::tr("Error"), + QObject::tr("Failed to create file entry")); + return; } + + // Add to workspace + switch (current->SetFileEntry(fileEntry)) { + case WorkSpace::FileEntryResult::Ok: + // Success - no action needed + break; case WorkSpace::FileEntryResult::LimitExceeded: QMessageBox::information(&MainFrame::Get(), QObject::tr("prompt"), QObject::tr("up to 9 files allowed for this type")); @@ -122,6 +121,10 @@ void FileManagerMenu::AddWaveFile() { QMessageBox::information(&MainFrame::Get(), QObject::tr("prompt"), QObject::tr("copy file failed")); break; + case WorkSpace::FileEntryResult::InvalidFile: + QMessageBox::information(&MainFrame::Get(), QObject::tr("prompt"), + QObject::tr("invalid file")); + break; } } } @@ -138,20 +141,19 @@ void FileManagerMenu::AddSurfaceFile() { if (dialog && dialog->exec() == QDialog::Accepted) { QString selectedPath = dialog->getSelectedFilePath(); - // Create file entry - switch (current->CreateFileEntry(FileEntryType::Surface)) { - case WorkSpace::FileEntryResult::Ok: { - // Get the index of the newly created file entry - auto entries = current->GetFileEntries(FileEntryType::Surface); - int newIndex = static_cast(entries.size()) - 1; - - // Set file path - if (!current->SetFileEntryPath(FileEntryType::Surface, newIndex, selectedPath)) { - QMessageBox::warning(&MainFrame::Get(), QObject::tr("Error"), - QObject::tr("Failed to set file path")); - } - break; + // Create file entry using factory function + auto fileEntry = CreateFileEntrySurface(selectedPath); + if (!fileEntry) { + QMessageBox::warning(&MainFrame::Get(), QObject::tr("Error"), + QObject::tr("Failed to create file entry")); + return; } + + // Add to workspace + switch (current->SetFileEntry(fileEntry)) { + case WorkSpace::FileEntryResult::Ok: + // Success - no action needed + break; case WorkSpace::FileEntryResult::LimitExceeded: QMessageBox::information(&MainFrame::Get(), QObject::tr("prompt"), QObject::tr("up to 9 files allowed for this type")); @@ -164,6 +166,10 @@ void FileManagerMenu::AddSurfaceFile() { QMessageBox::information(&MainFrame::Get(), QObject::tr("prompt"), QObject::tr("copy file failed")); break; + case WorkSpace::FileEntryResult::InvalidFile: + QMessageBox::information(&MainFrame::Get(), QObject::tr("prompt"), + QObject::tr("invalid file")); + break; } } } @@ -180,20 +186,19 @@ void FileManagerMenu::AddTableFile() { if (dialog && dialog->exec() == QDialog::Accepted) { QString selectedPath = dialog->getSelectedFilePath(); - // Create file entry - switch (current->CreateFileEntry(FileEntryType::Table)) { - case WorkSpace::FileEntryResult::Ok: { - // Get the index of the newly created file entry - auto entries = current->GetFileEntries(FileEntryType::Table); - int newIndex = static_cast(entries.size()) - 1; - - // Set file path - if (!current->SetFileEntryPath(FileEntryType::Table, newIndex, selectedPath)) { - QMessageBox::warning(&MainFrame::Get(), QObject::tr("Error"), - QObject::tr("Failed to set file path")); - } - break; + // Create file entry using factory function + auto fileEntry = CreateFileEntryTable(selectedPath); + if (!fileEntry) { + QMessageBox::warning(&MainFrame::Get(), QObject::tr("Error"), + QObject::tr("Failed to create file entry")); + return; } + + // Add to workspace + switch (current->SetFileEntry(fileEntry)) { + case WorkSpace::FileEntryResult::Ok: + // Success - no action needed + break; case WorkSpace::FileEntryResult::LimitExceeded: QMessageBox::information(&MainFrame::Get(), QObject::tr("prompt"), QObject::tr("up to 9 files allowed for this type")); @@ -206,6 +211,10 @@ void FileManagerMenu::AddTableFile() { QMessageBox::information(&MainFrame::Get(), QObject::tr("prompt"), QObject::tr("copy file failed")); break; + case WorkSpace::FileEntryResult::InvalidFile: + QMessageBox::information(&MainFrame::Get(), QObject::tr("prompt"), + QObject::tr("invalid file")); + break; } } } @@ -222,20 +231,19 @@ void FileManagerMenu::AddLightFile() { if (dialog && dialog->exec() == QDialog::Accepted) { QString selectedPath = dialog->getSelectedFilePath(); - // Create file entry - switch (current->CreateFileEntry(FileEntryType::Light)) { - case WorkSpace::FileEntryResult::Ok: { - // Get the index of the newly created file entry - auto entries = current->GetFileEntries(FileEntryType::Light); - int newIndex = static_cast(entries.size()) - 1; - - // Set file path - if (!current->SetFileEntryPath(FileEntryType::Light, newIndex, selectedPath)) { - QMessageBox::warning(&MainFrame::Get(), QObject::tr("Error"), - QObject::tr("Failed to set file path")); - } - break; + // Create file entry using factory function + auto fileEntry = CreateFileEntryLight(selectedPath); + if (!fileEntry) { + QMessageBox::warning(&MainFrame::Get(), QObject::tr("Error"), + QObject::tr("Failed to create file entry")); + return; } + + // Add to workspace + switch (current->SetFileEntry(fileEntry)) { + case WorkSpace::FileEntryResult::Ok: + // Success - no action needed + break; case WorkSpace::FileEntryResult::LimitExceeded: QMessageBox::information(&MainFrame::Get(), QObject::tr("prompt"), QObject::tr("up to 9 files allowed for this type")); @@ -248,6 +256,10 @@ void FileManagerMenu::AddLightFile() { QMessageBox::information(&MainFrame::Get(), QObject::tr("prompt"), QObject::tr("copy file failed")); break; + case WorkSpace::FileEntryResult::InvalidFile: + QMessageBox::information(&MainFrame::Get(), QObject::tr("prompt"), + QObject::tr("invalid file")); + break; } } } diff --git a/src/ui/Panel/DataPanelManager.cpp b/src/ui/Panel/DataPanelManager.cpp index 46eb1b64..d35f4d74 100644 --- a/src/ui/Panel/DataPanelManager.cpp +++ b/src/ui/Panel/DataPanelManager.cpp @@ -114,7 +114,7 @@ void DataPanelManager::UpdatePanelsForType(FileEntryType fileType) } // Get files of specified type from current workspace - std::vector files = currentWorkspace_->GetFileEntries(fileType); + std::vector> files = currentWorkspace_->GetFileEntries(fileType); // Limit to maximum panels per type const int maxPanels = qMin(static_cast(files.size()), GetMaxPanelCount()); @@ -135,8 +135,8 @@ void DataPanelManager::UpdatePanelsForType(FileEntryType fileType) // Create or update panels for (int i = 0; i < maxPanels; ++i) { - const FileEntry& fileEntry = files[i]; - QString filePath = currentWorkspace_->GetFileEntryAbsPath(fileEntry.type, i); + std::shared_ptr fileEntry = files[i]; + QString filePath = currentWorkspace_->GetFileEntryAbsPath(fileEntry->GetType(), i); QString panelKey = QString("%1_%2").arg(FileEntryTypeToString(fileType)).arg(i); if (dataPanels_.contains(panelKey)) { diff --git a/src/ui/PropertyBrowser/qtworkspaceattribute.cpp b/src/ui/PropertyBrowser/qtworkspaceattribute.cpp index b402d5f9..6ef94bee 100644 --- a/src/ui/PropertyBrowser/qtworkspaceattribute.cpp +++ b/src/ui/PropertyBrowser/qtworkspaceattribute.cpp @@ -192,7 +192,7 @@ const QString QWorkspaceAttribute::GetCommondFilePath() const return workspace_->GetCommondFilePath(); } -std::vector QWorkspaceAttribute::GetFileEntries(FileEntryType type) const { +std::vector> QWorkspaceAttribute::GetFileEntries(FileEntryType type) const { if (nullptr == workspace_) { return {}; } @@ -210,7 +210,18 @@ void QWorkspaceAttribute::SetFileEntryPath(FileEntryType type, int index, const if (nullptr == workspace_) { return; } - workspace_->SetFileEntryPath(type, index, path); + + // Get the file entries for this type + auto entries = workspace_->GetFileEntries(type); + if (index < 0 || index >= static_cast(entries.size())) { + return; + } + + // Update the path of the specific entry + entries[index]->SetPath(path); + + // Trigger files changed signal + workspace_->SetFileEntryCount(type, static_cast(entries.size())); } QString QWorkspaceAttribute::GetFileEntryAbsPath(FileEntryType type, int index) const { diff --git a/src/ui/PropertyBrowser/qtworkspaceattribute.h b/src/ui/PropertyBrowser/qtworkspaceattribute.h index f1add88a..7efdc1a6 100644 --- a/src/ui/PropertyBrowser/qtworkspaceattribute.h +++ b/src/ui/PropertyBrowser/qtworkspaceattribute.h @@ -85,7 +85,7 @@ public: const QString GetCommondFilePath() const; // Grouped files API - std::vector GetFileEntries(FileEntryType type) const; + std::vector> GetFileEntries(FileEntryType type) const; void SetFileEntryCount(FileEntryType type, int count); void SetFileEntryPath(FileEntryType type, int index, const QString& path); QString GetFileEntryAbsPath(FileEntryType type, int index) const; diff --git a/src/ui/WorkSpace/AddCurveFileDlg.cpp b/src/ui/WorkSpace/AddCurveFileDlg.cpp index a10e49f3..3c75f77c 100644 --- a/src/ui/WorkSpace/AddCurveFileDlg.cpp +++ b/src/ui/WorkSpace/AddCurveFileDlg.cpp @@ -6,6 +6,9 @@ #include #include +#include "workspace/WorkSpace.h" +#include "workspace/WorkSpaceManager.h" + #include "ui_AddCurveFileDlg.h" AddCurveFileDlg::AddCurveFileDlg(QWidget* parent) @@ -16,7 +19,6 @@ AddCurveFileDlg::AddCurveFileDlg(QWidget* parent) SetupUI(ui); SetTitle(getDialogTitle()); - setupSpecificUI(); setupConnections(); } @@ -24,44 +26,15 @@ AddCurveFileDlg::~AddCurveFileDlg() { delete ui; } -void AddCurveFileDlg::setupSpecificUI() { - // Initialize curve properties group as disabled - enableCurveProperties(false); - - // Initialize color preview - updateColorPreview(selectedColor_); - - // Add a default curve - CurveProperties defaultCurve; - defaultCurve.name = generateCurveName(); - defaultCurve.color = generateCurveColor(); - defaultCurve.start = 1; - defaultCurve.stop = 241; - - curves_.append(defaultCurve); - addCurveToList(defaultCurve); - - // Select the first curve - if (ui->curveListWidget->count() > 0) { - ui->curveListWidget->setCurrentRow(0); - onCurveSelectionChanged(); - } -} - void AddCurveFileDlg::setupConnections() { // File selection connections - connect(ui->selectFileBtn, &QToolButton::clicked, this, &AddCurveFileDlg::onSelectFileClicked); - connect(ui->filePathEdit, &QLineEdit::textChanged, this, &AddCurveFileDlg::onFilePathChanged); - - // Data format connections - connect(ui->separatorComboBox, QOverload::of(&QComboBox::currentIndexChanged), - this, &AddCurveFileDlg::onDelimiterChanged); - connect(ui->hasHeaderCheckBox, &QCheckBox::toggled, this, &AddCurveFileDlg::onHeaderToggled); + connect(ui->selectFileBtn, &QToolButton::clicked, this, &AddCurveFileDlg::OnSelectFile); // Curve management connections connect(ui->addCurveBtn, &QPushButton::clicked, this, &AddCurveFileDlg::onAddCurveClicked); connect(ui->removeCurveBtn, &QPushButton::clicked, this, &AddCurveFileDlg::onRemoveCurveClicked); connect(ui->curveListWidget, &QListWidget::currentRowChanged, this, &AddCurveFileDlg::onCurveSelectionChanged); + connect(ui->curveListWidget, &QListWidget::itemClicked, this, &AddCurveFileDlg::onCurveListWidgetItemClicked); // Curve properties connections connect(ui->colorButton, &QPushButton::clicked, this, &AddCurveFileDlg::onColorButtonClicked); @@ -74,36 +47,29 @@ void AddCurveFileDlg::setupConnections() { connect(ui->cancelBtn, &QPushButton::clicked, this, &QDialog::reject); } -void AddCurveFileDlg::onSelectFileClicked() { - QString fileName = QFileDialog::getOpenFileName( - this, - getDialogTitle(), - QString(), - getFileFilter() - ); - - if (!fileName.isEmpty()) { - ui->filePathEdit->setText(fileName); - updateFileInfo(fileName); - } -} void AddCurveFileDlg::updateFileInfo(const QString& filePath) { QFileInfo fileInfo(filePath); if (fileInfo.exists()) { ui->fileNameValue->setText(fileInfo.fileName()); - ui->fileSizeValue->setText(QString::number(fileInfo.size()) + " bytes"); + 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("-"); } -} -void AddCurveFileDlg::onFilePathChanged() { - QString filePath = ui->filePathEdit->text(); - if (!filePath.isEmpty()) { - updateFileInfo(filePath); - } + ui->filePathEdit->setText(filePath); } void AddCurveFileDlg::onAddCurveClicked() { @@ -113,7 +79,7 @@ void AddCurveFileDlg::onAddCurveClicked() { } // Create new curve with default properties - CurveProperties newCurve; + FileEntryCurve::CurveProperty newCurve; newCurve.name = generateCurveName(); newCurve.color = generateCurveColor(); newCurve.start = 1; @@ -121,7 +87,17 @@ void AddCurveFileDlg::onAddCurveClicked() { // Add to curves list and UI curves_.append(newCurve); - addCurveToList(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())); + ui->curveListWidget->addItem(item); + ++currentCurveIndex_; // Select the new curve ui->curveListWidget->setCurrentRow(curves_.size() - 1); @@ -134,7 +110,7 @@ void AddCurveFileDlg::onRemoveCurveClicked() { } // Don't allow removing the last curve - if (curves_.size() <= 1) { + if (curves_.size() <= 0) { QMessageBox::information(this, "Information", "At least one curve must remain."); return; } @@ -157,6 +133,33 @@ void AddCurveFileDlg::onRemoveCurveClicked() { } } +void AddCurveFileDlg::onCurveListWidgetItemClicked(QListWidgetItem* item) { + if (!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); + updateColorPreview(curves_[currentCurveIndex_].color); + + // 启用曲线属性编辑 + enableCurveProperties(true); + + // 将焦点设置到曲线名称编辑框,方便用户直接编辑 + ui->curveNameEdit->setFocus(); + ui->curveNameEdit->selectAll(); + } else { + // 如果点击的是不同的项,更新选择 + onCurveSelectionChanged(); + } +} + void AddCurveFileDlg::onCurveSelectionChanged() { int currentRow = ui->curveListWidget->currentRow(); @@ -238,7 +241,7 @@ void AddCurveFileDlg::onColorButtonClicked() { } } -void AddCurveFileDlg::addCurveToList(const CurveProperties& curve) { +void AddCurveFileDlg::addCurveToList(const FileEntryCurve::CurveProperty& curve) { QString itemText = QString("%1 [%2,%3] (%4,%5,%6)") .arg(curve.name) .arg(curve.start) @@ -252,7 +255,7 @@ void AddCurveFileDlg::addCurveToList(const CurveProperties& curve) { void AddCurveFileDlg::updateCurveProperties() { if (currentCurveIndex_ >= 0 && currentCurveIndex_ < curves_.size()) { - const CurveProperties& curve = curves_[currentCurveIndex_]; + const FileEntryCurve::CurveProperty& curve = curves_[currentCurveIndex_]; ui->curveNameEdit->setText(curve.name); ui->dataStartSpinBox->setValue(curve.start); @@ -315,13 +318,14 @@ void AddCurveFileDlg::updateColorPreview(const QColor& color) { bool AddCurveFileDlg::validateSpecificParams() { // File path validation - if (ui->filePathEdit->text().isEmpty()) { + 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(ui->filePathEdit->text()); + QFileInfo fileInfo(selectFilePath); if (!fileInfo.exists()) { QMessageBox::warning(this, tr("Validation Error"), tr("Selected file does not exist.")); return false; @@ -353,7 +357,7 @@ bool AddCurveFileDlg::validateSpecificParams() { // Curve name uniqueness validation QStringList curveNames; for (int i = 0; i < curves_.size(); ++i) { - const CurveProperties& curve = curves_[i]; + const FileEntryCurve::CurveProperty& curve = curves_[i]; if (curve.name.isEmpty()) { QMessageBox::warning(this, tr("Validation Error"), @@ -485,68 +489,67 @@ QString AddCurveFileDlg::getDialogTitle() const { return "Add Curve Data File"; } -AddCurveFileDlg::CurveParams AddCurveFileDlg::getCurveParams() const { - CurveParams params; - params.chart = getChartProperties(); - params.curves = getCurveProperties(); - params.format = getDataFormatParams(); - return params; -} - -AddCurveFileDlg::ChartProperties AddCurveFileDlg::getChartProperties() const { - ChartProperties chart; - chart.name = ui->chartNameEdit->text(); - chart.path = ui->filePathEdit->text(); - chart.xTitle = ui->xTitleEdit->text(); - chart.yTitle = ui->yTitleEdit->text(); - chart.xMin = ui->xMinSpinBox->value(); - chart.xMax = ui->xMaxSpinBox->value(); - chart.xCount = ui->xCountSpinBox->value(); - chart.yMin = ui->yMinSpinBox->value(); - chart.yMax = ui->yMaxSpinBox->value(); - chart.timeParam = ui->timeParamSpinBox->value(); - return chart; -} - -QList AddCurveFileDlg::getCurveProperties() const { - return curves_; -} - -AddCurveFileDlg::DataFormatParams AddCurveFileDlg::getDataFormatParams() const { - DataFormatParams format; - - // Get delimiter based on combo box selection - QString delimiterText = ui->separatorComboBox->currentText(); - if (delimiterText.contains("Comma")) { - format.delimiter = ","; - } else if (delimiterText.contains("Tab")) { - format.delimiter = "\t"; - } else if (delimiterText.contains("Space")) { - format.delimiter = " "; - } else if (delimiterText.contains("Semicolon")) { - format.delimiter = ";"; - } else { - format.delimiter = ","; // Default - } - - format.hasHeader = ui->hasHeaderCheckBox->isChecked(); - format.xColumn = ui->xColumnSpinBox->value(); - format.yColumn = ui->yColumnSpinBox->value(); - format.description = ui->descriptionEdit->toPlainText(); - - return format; -} - -void AddCurveFileDlg::onDelimiterChanged() { - // This slot can be used for future delimiter-related logic -} - -void AddCurveFileDlg::onHeaderToggled(bool hasHeader) { - // This slot can be used for future header-related logic -} - void AddCurveFileDlg::onSure() { if (validateSpecificParams()) { + // Create FileEntryCurve object using factory function + auto fileEntryCurve = CreateFileEntryCurve(getSelectedFilePath()); + if (!fileEntryCurve) { + QMessageBox::warning(this, tr("Error"), tr("Failed to create file entry")); + return; + } + + // Set curve properties + fileEntryCurve->SetName(ui->chartNameEdit->text()); + + // Set chart properties + FileEntryCurve::ChartProperties chartProps; + chartProps.xCount = ui->xCountSpinBox->value(); + chartProps.xTitle = ui->xTitleEdit->text(); + chartProps.yTitle = ui->yTitleEdit->text(); + chartProps.xMin = ui->xMinSpinBox->value(); + chartProps.xMax = ui->xMaxSpinBox->value(); + chartProps.yMin = ui->yMinSpinBox->value(); + chartProps.yMax = ui->yMaxSpinBox->value(); + chartProps.timeParam = ui->timeParamSpinBox->value(); + fileEntryCurve->SetChartProperties(chartProps); + + // Add curve properties + for (const auto& curve : curves_) { + fileEntryCurve->AddCurveProperty(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(fileEntryCurve); + if (result != WorkSpace::FileEntryResult::Ok) { + QString errorMsg; + switch (result) { + case WorkSpace::FileEntryResult::LimitExceeded: + errorMsg = tr("Curve 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(); } -} \ No newline at end of file +} diff --git a/src/ui/WorkSpace/AddCurveFileDlg.h b/src/ui/WorkSpace/AddCurveFileDlg.h index e9c20631..2da9ed32 100644 --- a/src/ui/WorkSpace/AddCurveFileDlg.h +++ b/src/ui/WorkSpace/AddCurveFileDlg.h @@ -1,8 +1,10 @@ #pragma once #include "BaseAddFileDlg.h" +#include "workspace/FileEntry.h" #include #include +#include class QLineEdit; class QCheckBox; @@ -24,66 +26,20 @@ class AddCurveFileDlg : public BaseAddFileDlg { Q_OBJECT public: - // Chart properties structure - struct ChartProperties { - QString name; - QString path; - QString xTitle; - QString yTitle; - double xMin; - double xMax; - int xCount; - double yMin; - double yMax; - double timeParam; - }; - - // Curve properties structure - struct CurveProperties { - QString name; - QColor color; - int start; - int stop; - }; - - // Data format parameters structure - struct DataFormatParams { - QString delimiter; - bool hasHeader; - int xColumn; - int yColumn; - QString description; - }; - - // Combined parameters structure - struct CurveParams { - ChartProperties chart; - QList curves; // Changed to support multiple curves - DataFormatParams format; - }; - explicit AddCurveFileDlg(QWidget* parent = nullptr); ~AddCurveFileDlg() override; - CurveParams getCurveParams() const; - ChartProperties getChartProperties() const; - QList getCurveProperties() const; // Changed to return list - DataFormatParams getDataFormatParams() const; - protected: QString getFileFilter() const override; QString getDialogTitle() const override; - void setupSpecificUI() override; bool validateSpecificParams() override; + void updateFileInfo(const QString& filePath) override; private slots: - void onDelimiterChanged(); - void onHeaderToggled(bool hasHeader); - void onSelectFileClicked(); - void onFilePathChanged(); void onColorButtonClicked(); void onAddCurveClicked(); void onRemoveCurveClicked(); + void onCurveListWidgetItemClicked(QListWidgetItem* item); void onCurveSelectionChanged(); void onCurveNameChanged(); void onCurveDataChanged(); @@ -91,9 +47,8 @@ private slots: private: void setupConnections(); - void updateFileInfo(const QString& filePath); void updateColorPreview(const QColor& color); - void addCurveToList(const CurveProperties& curve); + void addCurveToList(const FileEntryCurve::CurveProperty& curve); void updateCurveProperties(); void saveCurveProperties(); void clearCurveProperties(); @@ -102,7 +57,9 @@ private: QColor generateCurveColor() const; Ui::AddCurveFileDlg* ui; - QList curves_; int currentCurveIndex_; QColor selectedColor_; + + FileEntryCurve::ChartProperties chartProperties_; + FileEntryCurve::CurveProperties curves_; }; \ No newline at end of file diff --git a/src/ui/WorkSpace/AddLightFileDlg.cpp b/src/ui/WorkSpace/AddLightFileDlg.cpp index f67844ee..dd5b8b0a 100644 --- a/src/ui/WorkSpace/AddLightFileDlg.cpp +++ b/src/ui/WorkSpace/AddLightFileDlg.cpp @@ -11,16 +11,12 @@ AddLightFileDlg::AddLightFileDlg(QWidget* parent) ui->setupUi(this); SetTitle(getDialogTitle()); - setupSpecificUI(); } AddLightFileDlg::~AddLightFileDlg() { delete ui; } -void AddLightFileDlg::setupSpecificUI() { -} - bool AddLightFileDlg::validateSpecificParams() { LightParams params = getLightParams(); diff --git a/src/ui/WorkSpace/AddLightFileDlg.h b/src/ui/WorkSpace/AddLightFileDlg.h index 04588887..f5a6ba30 100644 --- a/src/ui/WorkSpace/AddLightFileDlg.h +++ b/src/ui/WorkSpace/AddLightFileDlg.h @@ -27,8 +27,8 @@ public: protected: QString getFileFilter() const override; QString getDialogTitle() const override; - void setupSpecificUI() override; bool validateSpecificParams() override; + void updateFileInfo(const QString& filePath) override {} private slots: void onDelimiterChanged(); diff --git a/src/ui/WorkSpace/AddSurfaceFileDlg.cpp b/src/ui/WorkSpace/AddSurfaceFileDlg.cpp index 65faa002..c924087f 100644 --- a/src/ui/WorkSpace/AddSurfaceFileDlg.cpp +++ b/src/ui/WorkSpace/AddSurfaceFileDlg.cpp @@ -14,7 +14,6 @@ AddSurfaceFileDlg::AddSurfaceFileDlg(QWidget* parent) ui_->setupUi(this); SetTitle(getDialogTitle()); - setupSpecificUI(); setupConnections(); } @@ -22,10 +21,6 @@ AddSurfaceFileDlg::~AddSurfaceFileDlg() { delete ui_; } -void AddSurfaceFileDlg::setupSpecificUI() { - // UI is already set up in constructor -} - void AddSurfaceFileDlg::setupConnections() { connect(ui_->selectFileBtn, &QToolButton::clicked, this, &AddSurfaceFileDlg::onSelectFileClicked); connect(ui_->filePathEdit, &QLineEdit::textChanged, this, &AddSurfaceFileDlg::onFilePathChanged); diff --git a/src/ui/WorkSpace/AddSurfaceFileDlg.h b/src/ui/WorkSpace/AddSurfaceFileDlg.h index 367ba2e2..07738b19 100644 --- a/src/ui/WorkSpace/AddSurfaceFileDlg.h +++ b/src/ui/WorkSpace/AddSurfaceFileDlg.h @@ -41,7 +41,6 @@ public: protected: QString getFileFilter() const override; QString getDialogTitle() const override; - void setupSpecificUI() override; bool validateSpecificParams() override; private slots: diff --git a/src/ui/WorkSpace/AddTableFileDlg.cpp b/src/ui/WorkSpace/AddTableFileDlg.cpp index ef6f9181..8f666f4d 100644 --- a/src/ui/WorkSpace/AddTableFileDlg.cpp +++ b/src/ui/WorkSpace/AddTableFileDlg.cpp @@ -16,7 +16,6 @@ AddTableFileDlg::AddTableFileDlg(QWidget* parent) ui->setupUi(this); SetTitle(getDialogTitle()); - setupSpecificUI(); setupConnections(); } @@ -24,10 +23,6 @@ AddTableFileDlg::~AddTableFileDlg() { delete ui; } -void AddTableFileDlg::setupSpecificUI() { - // UI is already set up in constructor -} - void AddTableFileDlg::setupConnections() { // Connect file selection connect(ui->selectFileBtn, &QToolButton::clicked, this, &AddTableFileDlg::onSelectFileClicked); diff --git a/src/ui/WorkSpace/AddTableFileDlg.h b/src/ui/WorkSpace/AddTableFileDlg.h index f91de097..8ed648b3 100644 --- a/src/ui/WorkSpace/AddTableFileDlg.h +++ b/src/ui/WorkSpace/AddTableFileDlg.h @@ -28,7 +28,6 @@ public: protected: QString getFileFilter() const override; QString getDialogTitle() const override; - void setupSpecificUI() override; bool validateSpecificParams() override; private slots: diff --git a/src/ui/WorkSpace/BaseAddFileDlg.cpp b/src/ui/WorkSpace/BaseAddFileDlg.cpp index 8efc49c7..1036464d 100644 --- a/src/ui/WorkSpace/BaseAddFileDlg.cpp +++ b/src/ui/WorkSpace/BaseAddFileDlg.cpp @@ -18,15 +18,8 @@ BaseAddFileDlg::BaseAddFileDlg(FileEntryType fileType, QWidget* parent) : Dialog(parent) - , fileType_(fileType) - , leFilePath_(nullptr) - , tbSelectFile_(nullptr) - , lblFileName_(nullptr) - , lblFileSize_(nullptr) - , teDescription_(nullptr) { + , fileType_(fileType) { - //setupBaseUI(); - initBaseConnect(); } BaseAddFileDlg::~BaseAddFileDlg() { @@ -40,67 +33,12 @@ QString BaseAddFileDlg::getSelectedFilePath() const { return selectedFilePath_; } -QString BaseAddFileDlg::getDescription() const { - return teDescription_->toPlainText().trimmed(); -} - -void BaseAddFileDlg::setupBaseUI() { - setFixedSize(500, 400); - - QVBoxLayout* mainLayout = new QVBoxLayout(this); - mainLayout->setContentsMargins(20, 20, 20, 20); - mainLayout->setSpacing(15); - - QGroupBox* fileGroup = new QGroupBox(QStringLiteral("File Selection"), this); - QGridLayout* fileLayout = new QGridLayout(fileGroup); - - QLabel* pathLabel = new QLabel(QStringLiteral("File Path:"), this); - leFilePath_ = new QLineEdit(this); - leFilePath_->setReadOnly(true); - tbSelectFile_ = new QToolButton(this); - tbSelectFile_->setText(QStringLiteral("...")); - tbSelectFile_->setFixedSize(30, 25); - - fileLayout->addWidget(pathLabel, 0, 0); - fileLayout->addWidget(leFilePath_, 0, 1); - fileLayout->addWidget(tbSelectFile_, 0, 2); - - mainLayout->addWidget(fileGroup); - - QGroupBox* infoGroup = new QGroupBox(QStringLiteral("File Information"), this); - QGridLayout* infoLayout = new QGridLayout(infoGroup); - - QLabel* nameLabel = new QLabel(QStringLiteral("File Name:"), this); - lblFileName_ = new QLabel(QStringLiteral("No file selected"), this); - QLabel* sizeLabel = new QLabel(QStringLiteral("File Size:"), this); - lblFileSize_ = new QLabel(QStringLiteral("0 bytes"), this); - - infoLayout->addWidget(nameLabel, 0, 0); - infoLayout->addWidget(lblFileName_, 0, 1); - infoLayout->addWidget(sizeLabel, 1, 0); - infoLayout->addWidget(lblFileSize_, 1, 1); - - mainLayout->addWidget(infoGroup); - - QGroupBox* descGroup = new QGroupBox(QStringLiteral("Description"), this); - QVBoxLayout* descLayout = new QVBoxLayout(descGroup); - teDescription_ = new QTextEdit(this); - teDescription_->setMaximumHeight(80); - descLayout->addWidget(teDescription_); - mainLayout->addWidget(descGroup); - -} - -void BaseAddFileDlg::initBaseConnect() { - connect(tbSelectFile_, &QToolButton::clicked, this, &BaseAddFileDlg::OnSelectFile); -} - void BaseAddFileDlg::OnSelectFile() { const QString workspacePath = Application::GetWorkSpacePath(); QString filePath = QFileDialog::getOpenFileName( this, - QStringLiteral("Select File"), - workspacePath, + getDialogTitle(), + QString(), getFileFilter() ); @@ -109,7 +47,6 @@ void BaseAddFileDlg::OnSelectFile() { } selectedFilePath_ = filePath; - leFilePath_->setText(filePath); updateFileInfo(filePath); LOG_INFO("Selected file: {}", filePath.toStdString()); @@ -123,22 +60,6 @@ void BaseAddFileDlg::OnSure() { accept(); } -void BaseAddFileDlg::updateFileInfo(const QString& filePath) { - QFileInfo fileInfo(filePath); - lblFileName_->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); - } - lblFileSize_->setText(sizeText); -} - bool BaseAddFileDlg::validateBaseInput() { if (selectedFilePath_.isEmpty()) { QMessageBox::warning(this, QStringLiteral("Warning"), diff --git a/src/ui/WorkSpace/BaseAddFileDlg.h b/src/ui/WorkSpace/BaseAddFileDlg.h index 4de55b03..b584e3e3 100644 --- a/src/ui/WorkSpace/BaseAddFileDlg.h +++ b/src/ui/WorkSpace/BaseAddFileDlg.h @@ -7,11 +7,6 @@ #include -class QLineEdit; -class QLabel; -class QTextEdit; -class QToolButton; - class BaseAddFileDlg : public Dialog { Q_OBJECT @@ -21,7 +16,7 @@ public: FileEntryType getSelectedFileType() const; QString getSelectedFilePath() const; - QString getDescription() const; + QString getDescription() const { return description_; } virtual bool validateSpecificParams() = 0; virtual QString getFileFilter() const = 0; @@ -32,21 +27,15 @@ protected slots: void OnSure(); protected: - QLineEdit* leFilePath_; - QToolButton* tbSelectFile_; - QLabel* lblFileName_; - QLabel* lblFileSize_; - QTextEdit* teDescription_; - - void setupBaseUI(); - void initBaseConnect(); - void updateFileInfo(const QString& filePath); bool validateBaseInput(); void SetTitle(const QString& title); - virtual void setupSpecificUI() = 0; + virtual void updateFileInfo(const QString& filePath) = 0; + +protected: + QString selectedFilePath_; + QString description_; private: FileEntryType fileType_; - QString selectedFilePath_; }; \ No newline at end of file diff --git a/src/workspace/FileEntry.cpp b/src/workspace/FileEntry.cpp new file mode 100644 index 00000000..e8334725 --- /dev/null +++ b/src/workspace/FileEntry.cpp @@ -0,0 +1,79 @@ +#include "workspace/FileEntry.h" + +#include + +#include "common/SpdLogger.h" + +void FileEntry::SetPath(const QString& path) { + QFileInfo fileInfo(path); + if (!fileInfo.exists()) { + LOG_WARN("file not exist: {}", path.toLocal8Bit().constData()); + return; + } + path_ = fileInfo.path(); + fileName_ = fileInfo.fileName(); +} + +// Factory function implementations +std::shared_ptr CreateFileEntry(FileEntryType type, const QString& filePath) { + switch (type) { + case FileEntryType::Curve: + return CreateFileEntryCurve(filePath); + case FileEntryType::Surface: + return CreateFileEntrySurface(filePath); + case FileEntryType::Table: + return CreateFileEntryTable(filePath); + case FileEntryType::Light: + return CreateFileEntryLight(filePath); + default: + LOG_ERROR("Unknown FileEntryType: {}", static_cast(type)); + return nullptr; + } +} + +std::shared_ptr CreateFileEntryCurve(const QString& filePath) { + QFileInfo fileInfo(filePath); + if (!fileInfo.exists()) { + LOG_ERROR("File does not exist: {}", filePath.toUtf8().constData()); + return nullptr; + } + + auto fileEntry = std::make_shared(); + fileEntry->SetPath(filePath); + fileEntry->SetName(fileInfo.baseName()); // Use base name as default display name + + return fileEntry; +} + +std::shared_ptr CreateFileEntrySurface(const QString& filePath) { + auto fileEntry = std::make_shared(); + fileEntry->SetType(FileEntryType::Surface); + + if (!filePath.isEmpty()) { + fileEntry->SetPath(filePath); + } + + return fileEntry; +} + +std::shared_ptr CreateFileEntryTable(const QString& filePath) { + auto fileEntry = std::make_shared(); + fileEntry->SetType(FileEntryType::Table); + + if (!filePath.isEmpty()) { + fileEntry->SetPath(filePath); + } + + return fileEntry; +} + +std::shared_ptr CreateFileEntryLight(const QString& filePath) { + auto fileEntry = std::make_shared(); + fileEntry->SetType(FileEntryType::Light); + + if (!filePath.isEmpty()) { + fileEntry->SetPath(filePath); + } + + return fileEntry; +} \ No newline at end of file diff --git a/src/workspace/FileEntry.h b/src/workspace/FileEntry.h index 51495ff6..5a63f5d5 100644 --- a/src/workspace/FileEntry.h +++ b/src/workspace/FileEntry.h @@ -1,6 +1,7 @@ #pragma once #include +#include enum class FileEntryType { Curve, @@ -9,11 +10,6 @@ enum class FileEntryType { Light }; -struct FileEntry { - FileEntryType type; - QString fileName; // relative file name under workspace dir; may be empty -}; - inline const char* FileEntryTypeToString(FileEntryType t) { switch (t) { case FileEntryType::Curve: return "curve"; @@ -31,4 +27,78 @@ inline bool FileEntryTypeFromString(const char* s, FileEntryType& out) { if (0 == strcmp(s, "table")) { out = FileEntryType::Table; return true; } if (0 == strcmp(s, "light")) { out = FileEntryType::Light; return true; } return false; -} \ No newline at end of file +} + +class FileEntryCurve; + +class FileEntry { +public: + virtual ~FileEntry() = default; + + FileEntryType GetType() const { return type_; } + void SetType(FileEntryType type) { type_ = type; } + + void SetPath(const QString& path); + QString GetPath() const { return path_; } + + void SetFileNanme(const QString& fileNmae) { fileName_ = fileNmae; } + const QString& GetFileName() const { return fileName_; } + + void SetName(const QString& name) { name_ = name; } + QString GetName() const { return name_; } + + virtual FileEntryCurve* AsCurve() { return nullptr; } + +protected: + FileEntryType type_; + QString path_; + QString fileName_; + QString name_; +}; + +// Factory functions for creating FileEntry objects +std::shared_ptr CreateFileEntry(FileEntryType type, const QString& filePath); +std::shared_ptr CreateFileEntryCurve(const QString& filePath); +std::shared_ptr CreateFileEntrySurface(const QString& filePath); +std::shared_ptr CreateFileEntryTable(const QString& filePath); +std::shared_ptr CreateFileEntryLight(const QString& filePath); + + +class FileEntryCurve : public FileEntry { +public: + struct ChartProperties { + int xCount; + QString xTitle; + QString yTitle; + double xMin; + double xMax; + double yMin; + double yMax; + double timeParam; + }; + + struct CurveProperty { + QString name; + QColor color; + int start; + int stop; + }; + + using CurveProperties = QList; + +public: + FileEntryCurve() { type_ = FileEntryType::Curve; } + + void SetChartProperties(const ChartProperties& props) { chartProperties_ = props; } + const ChartProperties& GetChartProperties() const { return chartProperties_; } + + void AddCurveProperty(const CurveProperty& prop) { curveProperties_.append(prop); } + void RemoveCurveProperty(int index) { curveProperties_.removeAt(index); } + const CurveProperties& GetCurveProperties() const { return curveProperties_; } + + FileEntryCurve* AsCurve() override { return this; } + +private: + ChartProperties chartProperties_; + CurveProperties curveProperties_; +}; diff --git a/src/workspace/WorkSpace.cpp b/src/workspace/WorkSpace.cpp index 7605814f..07c910e7 100644 --- a/src/workspace/WorkSpace.cpp +++ b/src/workspace/WorkSpace.cpp @@ -7,6 +7,7 @@ #include "workspace/WorkSpaceXMLParse.h" #include "workspace/WorkSpaceXMLWrite.h" #include "workspace/CommandManager.h" +#include "workspace/FileEntry.h" #include "workspace/WorkSpaceItem.h" #include "workspace/Timestep.h" @@ -118,7 +119,64 @@ void WorkSpace::SetRDPath(const QString& path) rdFile_ = fileInfo.fileName(); } -std::vector WorkSpace::GetFileEntries(FileEntryType type) const { +WorkSpace::FileEntryResult WorkSpace::SetFileEntry(std::shared_ptr fileEntry) { + if (!fileEntry) { + LOG_ERROR("FileEntry is null"); + return FileEntryResult::InvalidFile; + } + + FileEntryType type = fileEntry->GetType(); + auto& vec = files_[type]; + + // Check limit (max 9 per type) + if (vec.size() >= 9) { + LOG_WARN("File entry limit exceeded for type: {}", FileEntryTypeToString(type)); + return FileEntryResult::LimitExceeded; + } + + // Check for duplicates by file path + QString filePath = QString("%1/%2").arg(fileEntry->GetPath(), fileEntry->GetFileName()); + for (const auto& existingEntry : vec) { + if (existingEntry->GetPath() == filePath) { + LOG_WARN("Duplicate file entry: {}", filePath.toUtf8().constData()); + return FileEntryResult::Duplicate; + } + } + + // Copy file to workspace directory + QFileInfo fileInfo(filePath); + if (!fileInfo.exists()) { + LOG_ERROR("File does not exist: {}", filePath.toUtf8().constData()); + return FileEntryResult::InvalidFile; + } + + QString targetPath = QString("%1/%2").arg(GetDir(), fileInfo.fileName()); + bool copySuccess = FileUtils::CopyFileToPath(filePath, targetPath, true); + LOG_INFO("Copy file {} to {}: {}", + filePath.toLocal8Bit().data(), + targetPath.toLocal8Bit().data(), + copySuccess); + + if (!copySuccess) { + LOG_ERROR("Failed to copy file to workspace"); + return FileEntryResult::CopyFailed; + } + + // Update file entry with workspace-relative path + fileEntry->SetFileNanme(fileInfo.fileName()); + + // Add to files collection + vec.push_back(fileEntry); + ++filesSeq_; + + emit FilesChanged(type); + LOG_INFO("Successfully added file entry: {} (type: {})", + fileInfo.fileName().toUtf8().constData(), + FileEntryTypeToString(type)); + + return FileEntryResult::Ok; +} +std::vector> WorkSpace::GetFileEntries(FileEntryType type) const { auto it = files_.find(type); if (it == files_.end()) { return {}; @@ -126,19 +184,6 @@ std::vector WorkSpace::GetFileEntries(FileEntryType type) const { return it->second; } -WorkSpace::FileEntryResult WorkSpace::CreateFileEntry(FileEntryType type) { - auto& vec = files_[type]; - if (vec.size() >= 9) { - return FileEntryResult::LimitExceeded; - } - // push a placeholder; actual filename may be set elsewhere via SetWavePath/SetRDPath/etc - vec.push_back(FileEntry{ type, QString() }); - ++filesSeq_; - // Notify listeners (e.g., PropertyBrowser) to refresh workspace properties - emit FilesChanged(type); - return FileEntryResult::Ok; -} - bool WorkSpace::SetFileEntryCount(FileEntryType type, int count) { if (count < 0) count = 0; if (count > 9) count = 9; @@ -149,7 +194,31 @@ bool WorkSpace::SetFileEntryCount(FileEntryType type, int count) { if (static_cast(vec.size()) < count) { int toAdd = count - static_cast(vec.size()); for (int i = 0; i < toAdd; ++i) { - vec.push_back(FileEntry{ type, QString() }); + // Create the appropriate FileEntry subclass based on type + std::shared_ptr fileEntry; + switch (type) { + case FileEntryType::Curve: + fileEntry = std::make_shared(); + break; + case FileEntryType::Surface: + // TODO: Create FileEntrySurface when implemented + fileEntry = std::make_shared(); + fileEntry->SetType(FileEntryType::Surface); + break; + case FileEntryType::Table: + // TODO: Create FileEntryTable when implemented + fileEntry = std::make_shared(); + fileEntry->SetType(FileEntryType::Table); + break; + case FileEntryType::Light: + // TODO: Create FileEntryLight when implemented + fileEntry = std::make_shared(); + fileEntry->SetType(FileEntryType::Light); + break; + default: + return false; // Invalid type + } + vec.push_back(fileEntry); } } else { vec.resize(count); @@ -159,30 +228,6 @@ bool WorkSpace::SetFileEntryCount(FileEntryType type, int count) { return true; } -bool WorkSpace::SetFileEntryPath(FileEntryType type, int index, const QString& path) { - auto& vec = files_[type]; - if (index < 0 || index >= static_cast(vec.size())) { - return false; - } - QFileInfo fileInfo(path); - if (!fileInfo.exists()) { - return false; - } - QString dirPath = QString("%1/%2").arg(GetDir(), fileInfo.fileName()); - bool sucess = FileUtils::CopyFileToPath(path, dirPath, true); - LOG_INFO("copy grouped file {}: {} to {}", - path.toLocal8Bit().data(), - dirPath.toLocal8Bit().data(), - sucess); - if (!sucess) { - return false; - } - vec[index].fileName = fileInfo.fileName(); - ++filesSeq_; - emit FilesChanged(type); - return true; -} - QString WorkSpace::GetFileEntryAbsPath(FileEntryType type, int index) const { auto it = files_.find(type); if (it == files_.end()) { @@ -192,7 +237,7 @@ QString WorkSpace::GetFileEntryAbsPath(FileEntryType type, int index) const { if (index < 0 || index >= static_cast(vec.size())) { return QString(); } - const QString& name = vec[index].fileName; + const QString& name = vec[index]->GetFileName(); if (name.isEmpty()) { return QString(); } diff --git a/src/workspace/WorkSpace.h b/src/workspace/WorkSpace.h index 30a3db3d..3a0396ae 100644 --- a/src/workspace/WorkSpace.h +++ b/src/workspace/WorkSpace.h @@ -81,13 +81,15 @@ public: const QString GetRDPath() const; // Files list API (per-type, max 9 per type) - enum class FileEntryResult { Ok, LimitExceeded, Duplicate, CopyFailed }; - FileEntryResult CreateFileEntry(FileEntryType type); - std::vector GetFileEntries(FileEntryType type) const; + enum class FileEntryResult { Ok, LimitExceeded, Duplicate, CopyFailed, TypeMismatch, InvalidFile }; + + // New unified file entry management + FileEntryResult SetFileEntry(std::shared_ptr fileEntry); + + std::vector> GetFileEntries(FileEntryType type) const; // Manage grouped file entries bool SetFileEntryCount(FileEntryType type, int count); - bool SetFileEntryPath(FileEntryType type, int index, const QString& path); QString GetFileEntryAbsPath(FileEntryType type, int index) const; // Chart data management @@ -154,7 +156,6 @@ Q_SIGNALS: void EntityRemoved(class Entity* entity); void TimestepChanged(class Timestep* timestep); void LampStatusChanged(class LampStatus* lampStatus); - // Emitted when grouped file entries change (count or path or creation) void FilesChanged(FileEntryType type); protected: @@ -184,7 +185,7 @@ private: class LampStatus* lampStatus_{ nullptr }; class Entity* trackedEntity_{ nullptr }; // Stored as file entries under workspace dir, keyed by type - std::map> files_; + std::map>> files_; // Chart data storage QList fileTypeData_; // Monotonic sequence for file entries changes, used to trigger UI refresh diff --git a/src/workspace/WorkSpaceXMLParse.cpp b/src/workspace/WorkSpaceXMLParse.cpp index b6614015..141139e4 100644 --- a/src/workspace/WorkSpaceXMLParse.cpp +++ b/src/workspace/WorkSpaceXMLParse.cpp @@ -379,9 +379,7 @@ bool WorkSpaceXMLParse::ParseFiles(const tinyxml2::XMLElement* element) { // Also create file entries for backward compatibility FileEntryType enumType; if (FileEntryTypeFromString(name, enumType)) { - for (int i = 0; i < count; ++i) { - workSpace_->CreateFileEntry(enumType); - } + workSpace_->SetFileEntryCount(enumType, count); } } typeElement = typeElement->NextSiblingElement("type");