diff --git a/src/Dyt.qrc b/src/Dyt.qrc index 3007ee41..95741fca 100644 --- a/src/Dyt.qrc +++ b/src/Dyt.qrc @@ -38,6 +38,7 @@ res/models/radar_jamming_station.png res/models/satellite.png res/models/warships.png + res/default/menu_image_file.png diff --git a/src/res/default/menu_image_file.png b/src/res/default/menu_image_file.png new file mode 100644 index 00000000..979815d8 Binary files /dev/null and b/src/res/default/menu_image_file.png differ diff --git a/src/translations/Dyt_zh_CN.ts b/src/translations/Dyt_zh_CN.ts index a151b381..2d3d28e7 100644 --- a/src/translations/Dyt_zh_CN.ts +++ b/src/translations/Dyt_zh_CN.ts @@ -4,397 +4,391 @@ AddCurveFileDlg - - + + Add Curve Data File - + File Selection - + File Path: - + Select curve data file... - + ... - + File Name: - - + + - - + File Size: - + Chart Properties - + Chart Name: - + Chart 1 - + Enter chart name... - + Chart Type: - + X Axis Title: - + Enter X axis title... - + Y Axis Title: - + Enter Y axis title... - + Time: - + Axis Range Settings - + X Tick Count: - + X Min: - + Y Max: - + Y Min: - + X Max: - + Y Tick Count: - + Curve Management - + Curves: - + Add Curve - + Remove - + Selected Curve Properties - + Curve Name: - + 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. - - - - + Data Files (*.txt *.csv *.dat);;All Files (*.*) - - - + + + 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 @@ -403,7 +397,7 @@ AddLightFileDlg - + Add Light Data File @@ -435,7 +429,7 @@ - + - @@ -451,153 +445,163 @@ - Chart Names: + Chart Name: - - Color Properties + + Chart 1 + Time: + + + + + Color Properties + + + + Open Color: - - + + Select Color - + background-color: rgb(0, 255, 0); border: 1px solid black; - + Close Color: - + background-color: rgb(255, 0, 0); border: 1px solid black; - + Light Management - + Lights: - + Add Light Row - + Remove - + Selected Light Properties - + Light Names: - + Enter light names (comma separated)... - + Light Datas: - + Enter data values (comma separated integers)... - + Edit Data - + Row Index: - + Add File - + Cancel - + Light Data Files (*.txt *.csv *.dat);;All Files (*.*) - + Warning - + Please enter a Chart name. - - + + Error - + 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 @@ -889,160 +893,6 @@ - - AddPolarFileDlg - - - Data Files (*.txt *.csv *.dat);;All Files (*.*) - - - - - Add Polar - - - - - - - - - - - - - - - - - - - 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' 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. - - - - - Angular axis minimum value must be less than maximum value. - - - - - Radial axis minimum value must be less than maximum value. - - - - - Time parameter cannot be negative. - - - - - Curve %1 - - - - - - - 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 - - - AddSurfaceFileDlg @@ -1267,7 +1117,7 @@ - + Warning @@ -1287,49 +1137,49 @@ - + Please enter a Surface name. - - - + + + Error - + Failed to create surface file entry. - + Unable to get current workspace - + Surface file count has reached the limit (9 files) - + File already exists - + File copy failed - + Invalid file - + Failed to add file @@ -1940,6 +1790,11 @@ new polar file + + + new image file + + FitCurveChartView @@ -2302,38 +2157,38 @@ - + Open Workspace - - + + Dyt Files (*.dyt) - - - - - - + + + + + + prompt - - - - - - + + + + + + please create workspace first - + Save Workspace diff --git a/src/ui/Panel/ImagePanel.cpp b/src/ui/Panel/ImagePanel.cpp new file mode 100644 index 00000000..86c5ee41 --- /dev/null +++ b/src/ui/Panel/ImagePanel.cpp @@ -0,0 +1,77 @@ +#include "ui/Panel/ImagePanel.h" +#include "ui/DockWidget.h" +#include "ui/DockTitleBar.h" +#include "common/SpdLogger.h" +#include +#include +#include + +ImagePanel::ImagePanel(int index, const QString& filePath, QWidget* parent) + : DataPanel(index, FileEntryType::Table, filePath, parent) +{ + LOG_INFO("Created ImagePanel {} for file: {}", index, filePath.toStdString()); +} + +ImagePanel::ImagePanel(int index, std::shared_ptr fileEntry, QWidget* parent) + : DataPanel(index, fileEntry, parent) +{ + if (fileEntry) { + LOG_INFO("Created ImagePanel {} for chart: {}", index, fileEntry->GetName().toStdString()); + // Override the title with chart name + title_ = QString("Image Panel %1 - %2").arg(index).arg(fileEntry->GetName()); + } + else { + LOG_WARN("Created ImagePanel {} with null chart data", index); + } +} + +ImagePanel::~ImagePanel() +{ + LOG_INFO("Destroyed ImagePanel {}", GetIndex()); +} + +void ImagePanel::RefreshPanel() +{ + // Implement curve-specific refresh logic here + DataPanel::RefreshPanel(); + + if (auto fileEntry = fileEntry_->AsImage()) { + OnDataPanelUpdated(fileEntry); + } + + LOG_INFO("Refreshed ImagePanel {}", GetIndex()); +} + +void ImagePanel::InitUI() +{ + + QHBoxLayout* mainLayout = new QHBoxLayout(this); + mainLayout->setContentsMargins(0, 0, 0, 0); + //mainLayout->addWidget(m_pTableWidget); + setLayout(mainLayout); +} + +QString ImagePanel::GetTypeDisplayName() const +{ + return "Image"; +} + +void ImagePanel::OnDataPanelUpdated(FileEntryImage* fileEntry) +{ + QString strName = fileEntry->GetName(); + updateTitle(strName); + +} + +void ImagePanel::OnTimeChanged(double time) +{ + +} + +void ImagePanel::updateTitle(const QString & title) +{ + if (nullptr != dockWidget_) + { + dockWidget_->setWindowTitle(title); + } +} \ No newline at end of file diff --git a/src/ui/Panel/ImagePanel.h b/src/ui/Panel/ImagePanel.h new file mode 100644 index 00000000..bdd862b9 --- /dev/null +++ b/src/ui/Panel/ImagePanel.h @@ -0,0 +1,63 @@ +#pragma once + +#include "DataPanel.h" +#include "workspace/FileEntry.h" +#include + +class ImagePanel : public DataPanel +{ + Q_OBJECT + +public: + /** + * @brief Constructor + * @param index Panel index + * @param filePath Associated file path + * @param parent Parent widget + */ + explicit ImagePanel(int index, const QString& filePath, QWidget* parent = nullptr); + + /** + * @brief Constructor with chart data + * @param index Panel index + * @param chartData Chart data containing curve information + * @param parent Parent widget + */ + explicit ImagePanel(int index, std::shared_ptr fileEntry, QWidget* parent = nullptr); + + /** + * @brief Destructor + */ + virtual ~ImagePanel(); + + /** + * @brief Get file type + * @return File type (always Curve for this class) + */ + FileEntryType GetFileType() const override { return FileEntryType::Image; } + + /** + * @brief Refresh panel content + */ + void RefreshPanel() override; + +protected: + /** + * @brief Initialize UI for curve-specific layout + */ + virtual void InitUI(); + + /** + * @brief Get type display name + * @return Display name for curve type + */ + QString GetTypeDisplayName() const override; + + void OnDataPanelUpdated(FileEntryImage* fileEntry); + + virtual void OnTimeChanged(double time); + +private: + void updateTitle(const QString& title); +}; + diff --git a/src/workspace/FileEntry.cpp b/src/workspace/FileEntry.cpp index 4b702d1b..db727c98 100644 --- a/src/workspace/FileEntry.cpp +++ b/src/workspace/FileEntry.cpp @@ -46,6 +46,8 @@ std::shared_ptr CreateFileEntry(FileEntryType type, const QString& fi return CreateFileEntryLight(filePath); case FileEntryType::Polar: return CreateFileEntryPolar(filePath); + case FileEntryType::Image: + return CreateFileEntryImage(filePath); default: LOG_ERROR("Unknown FileEntryType: {}", static_cast(type)); return nullptr; @@ -122,6 +124,20 @@ std::shared_ptr CreateFileEntryPolar(const QString& filePath) { return fileEntry; } +std::shared_ptr CreateFileEntryImage(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; +} + // Factory functions for creating empty FileEntry objects (for XML parsing) std::shared_ptr CreateEmptyFileEntry(FileEntryType type) { switch (type) { @@ -135,6 +151,8 @@ std::shared_ptr CreateEmptyFileEntry(FileEntryType type) { return CreateEmptyFileEntryLight(); case FileEntryType::Polar: return CreateEmptyFileEntryPolar(); + case FileEntryType::Image: + return CreateEmptyFileEntryImage(); default: LOG_ERROR("Unknown FileEntryType: {}", static_cast(type)); return nullptr; @@ -171,6 +189,12 @@ std::shared_ptr CreateEmptyFileEntryPolar() { return fileEntry; } +std::shared_ptr CreateEmptyFileEntryImage() { + auto fileEntry = std::make_shared(); + // Don't set path or name - these will be set during XML parsing + return fileEntry; +} + // FileEntrySurface method implementations void FileEntrySurface::SetChartProperties(const ChartProperties& properties) { chartProperties_ = properties; @@ -807,4 +831,37 @@ bool FileEntryPolar::ParseFiles(const tinyxml2::XMLElement* chartElement) { } return true; +} + + +void FileEntryImage::SetChartProperties(const ChartProperties& properties) { + chartProperties_ = properties; +} + +const FileEntryImage::ChartProperties& FileEntryImage::GetChartProperties() const { + return chartProperties_; +} + +void FileEntryImage::AddImageProperty(const ImageProperty& image) { + imageProperties_.append(image); +} + +void FileEntryImage::RemoveImageProperty(int index) { + if (index >= 0 && index < imageProperties_.size()) { + imageProperties_.removeAt(index); + } +} + +void FileEntryImage::SetImageProperty(int index, const ImageProperty& surface) { + if (index >= 0 && index < imageProperties_.size()) { + imageProperties_[index] = surface; + } +} + +const FileEntryImage::ImageProperties& FileEntryImage::GetImageProperties() const { + return imageProperties_; +} + +FileEntryImage* FileEntryImage::AsImage() { + return this; } \ No newline at end of file diff --git a/src/workspace/FileEntry.h b/src/workspace/FileEntry.h index 4b59b42e..e1f36cbd 100644 --- a/src/workspace/FileEntry.h +++ b/src/workspace/FileEntry.h @@ -9,7 +9,8 @@ enum class FileEntryType { Surface, Table, Light, - Polar + Polar, + Image }; enum class ChartType { @@ -39,6 +40,7 @@ inline const char* FileEntryTypeToString(FileEntryType t) { case FileEntryType::Table: return "table"; case FileEntryType::Light: return "light"; case FileEntryType::Polar: return "polar"; + case FileEntryType::Image: return "image"; } return "unknown"; } @@ -50,6 +52,7 @@ 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; } if (0 == strcmp(s, "polar")) { out = FileEntryType::Polar; return true; } + if (0 == strcmp(s, "image")) { out = FileEntryType::Image; return true; } return false; } @@ -58,6 +61,7 @@ class FileEntryLight; class FileEntrySurface; class FileEntryTable; class FileEntryPolar; +class FileEntryImage; class FileEntry { public: @@ -80,6 +84,7 @@ public: virtual FileEntrySurface* AsSurface() { return nullptr; } virtual FileEntryTable* AsTable() { return nullptr; } virtual FileEntryPolar* AsPolar() { return nullptr; } + virtual FileEntryImage* AsImage() { return nullptr; } virtual bool ParseFiles(const tinyxml2::XMLElement* element) { return false; } virtual bool SaveFiles(tinyxml2::XMLElement* scene, tinyxml2::XMLDocument* doc) { return false; } @@ -101,6 +106,7 @@ std::shared_ptr CreateFileEntrySurface(const QString& filePath); std::shared_ptr CreateFileEntryTable(const QString& filePath); std::shared_ptr CreateFileEntryLight(const QString& filePath); std::shared_ptr CreateFileEntryPolar(const QString& filePath); +std::shared_ptr CreateFileEntryImage(const QString& filePath); // Factory functions for creating empty FileEntry objects (for XML parsing) std::shared_ptr CreateEmptyFileEntry(FileEntryType type); @@ -109,6 +115,7 @@ std::shared_ptr CreateEmptyFileEntrySurface(); std::shared_ptr CreateEmptyFileEntryTable(); std::shared_ptr CreateEmptyFileEntryLight(); std::shared_ptr CreateEmptyFileEntryPolar(); +std::shared_ptr CreateEmptyFileEntryImage(); class FileEntryCurve : public FileEntry { @@ -350,4 +357,54 @@ public: private: ChartProperties chartProperties_; LineProperties lineProperties_; +}; + +class FileEntryImage : public FileEntry { +public: + struct ChartProperties { + int AngularCount; + int RadialCount; + QString AngularTitle; + QString RadialTitle; + double AngularMin; + double AngularMax; + double RadialMin; + double RadialMax; + QString AngularUnit; + QString RadialUnit; + double timeParam; // 对应XML的t + }; + + struct ImageProperty { + QString name; + QColor color; + int Angular; + int Radial; + }; + + using ImageProperties = QList; + +public: + FileEntryImage() { type_ = FileEntryType::Image; } + + // Chart properties management + void SetChartProperties(const ChartProperties& properties); + const ChartProperties& GetChartProperties() const; + + // Line properties management + void AddImageProperty(const ImageProperty& image); + void RemoveImageProperty(int index); + void SetImageProperty(int index, const ImageProperty& image); + const ImageProperties& GetImageProperties() const; + + // Type conversion + FileEntryImage* AsImage() override; + + //// XML处理方法 + //bool SaveFiles(tinyxml2::XMLElement* scene, tinyxml2::XMLDocument* doc) override; + //bool ParseFiles(const tinyxml2::XMLElement* element) override; + +private: + ChartProperties chartProperties_; + ImageProperties imageProperties_; }; \ No newline at end of file