From 962d72bde9f69aa1781a47f846b42a8173be36da Mon Sep 17 00:00:00 2001 From: brige Date: Thu, 16 Oct 2025 11:29:25 +0800 Subject: [PATCH] add panel --- src/translations/Dyt_zh_CN.ts | 52 ++--- src/ui/MainWindow.cpp | 17 ++ src/ui/MainWindow.h | 13 ++ src/ui/Panel/CurvePanel.cpp | 48 +++++ src/ui/Panel/CurvePanel.h | 55 ++++++ src/ui/Panel/DataPanel.cpp | 75 ++++++++ src/ui/Panel/DataPanel.h | 115 +++++++++++ src/ui/Panel/DataPanelFactory.cpp | 67 +++++++ src/ui/Panel/DataPanelFactory.h | 49 +++++ src/ui/Panel/DataPanelManager.cpp | 296 +++++++++++++++++++++++++++++ src/ui/Panel/DataPanelManager.h | 125 ++++++++++++ src/workspace/WorkSpaceManager.cpp | 2 +- 12 files changed, 887 insertions(+), 27 deletions(-) create mode 100644 src/ui/Panel/CurvePanel.cpp create mode 100644 src/ui/Panel/CurvePanel.h create mode 100644 src/ui/Panel/DataPanel.cpp create mode 100644 src/ui/Panel/DataPanel.h create mode 100644 src/ui/Panel/DataPanelFactory.cpp create mode 100644 src/ui/Panel/DataPanelFactory.h create mode 100644 src/ui/Panel/DataPanelManager.cpp create mode 100644 src/ui/Panel/DataPanelManager.h diff --git a/src/translations/Dyt_zh_CN.ts b/src/translations/Dyt_zh_CN.ts index 1df46af7..7f03a00c 100644 --- a/src/translations/Dyt_zh_CN.ts +++ b/src/translations/Dyt_zh_CN.ts @@ -592,132 +592,132 @@ - + model elements - + attribte - + Main View - + Wave Curve - + Speed Curve - + 3D Curve - + Target number - + Signal-to-noise ratio - + Azimuth line of sight - + Pitch gaze angle - + azimuth - + Pitch angle - + attribute - + Doppler - + course - + Speed - + longitude - + latitude - + distance - + velocity - + Radial dimensions - + Target RCS - + Report Table - + Signal Indicator Lamp - + ParamSetting - + bat File diff --git a/src/ui/MainWindow.cpp b/src/ui/MainWindow.cpp index a9dcf674..06f4419d 100644 --- a/src/ui/MainWindow.cpp +++ b/src/ui/MainWindow.cpp @@ -27,6 +27,9 @@ #include "Matlab/MatlabObject.h" +// 曲线面板管理器 +#include "Panel/DataPanelManager.h" + #include "ui_MainWindow.h" #include "viewer/OsgWidget.h" #include "DockTitleBar.h" @@ -211,6 +214,13 @@ void MainWindow::InitUI() { // InitDockLayout(); + // 初始化数据面板管理器 + dataPanelManager_ = new DataPanelManager(this, this); + + // 连接工作空间变化信号 + connect(&WorkSpaceManager::Get(), &WorkSpaceManager::WorkSpaceChanged, + dataPanelManager_, &DataPanelManager::OnWorkspaceChanged); + // Restore previous UI layout if available UiLayoutManager::Restore(this, 1); @@ -228,6 +238,13 @@ void MainWindow::InitUI() { void MainWindow::UninitUI() { // Save layout state before tearing down widgets UiLayoutManager::Save(this, 1); + + // 清理数据面板管理器 + if (dataPanelManager_) { + delete dataPanelManager_; + dataPanelManager_ = nullptr; + } + if (qtOsgViewWidget_) { qtOsgViewWidget_->Uninitialize(); delete qtOsgViewWidget_; diff --git a/src/ui/MainWindow.h b/src/ui/MainWindow.h index 376d73b7..aca6633c 100644 --- a/src/ui/MainWindow.h +++ b/src/ui/MainWindow.h @@ -8,6 +8,8 @@ namespace Ui { class MainWindow; } +class DataPanelManager; + class MainWindow : public QMainWindow { Q_OBJECT @@ -35,6 +37,14 @@ public: return surfaceDlg_; } + /** + * @brief 获取数据面板管理器 + * @return 数据面板管理器指针 + */ + DataPanelManager* GetDataPanelManager() const { + return dataPanelManager_; + } + void slotShowUISetting(); public slots: @@ -62,6 +72,9 @@ private: class CodeEdtUI* matlabFileDlg_{ nullptr }; class AddParamSetting* addParamDlg_{ nullptr }; + // 数据面板管理器 + DataPanelManager* dataPanelManager_{ nullptr }; + QMap m_mapDockWidget; }; \ No newline at end of file diff --git a/src/ui/Panel/CurvePanel.cpp b/src/ui/Panel/CurvePanel.cpp new file mode 100644 index 00000000..865222c8 --- /dev/null +++ b/src/ui/Panel/CurvePanel.cpp @@ -0,0 +1,48 @@ +#include "ui/Panel/CurvePanel.h" +#include "ui/DockWidget.h" +#include "common/SpdLogger.h" + +#include +#include +#include + +CurvePanel::CurvePanel(int index, const QString& filePath, QWidget* parent) + : DataPanel(index, FileEntryType::Curve, filePath, parent) +{ + LOG_INFO("Created CurvePanel {} for file: {}", index, filePath.toStdString()); +} + +CurvePanel::~CurvePanel() +{ + LOG_INFO("Destroyed CurvePanel {}", GetIndex()); +} + +void CurvePanel::RefreshPanel() +{ + // Implement curve-specific refresh logic here + // For now, just call the base class implementation + DataPanel::RefreshPanel(); + + LOG_INFO("Refreshed CurvePanel {}", GetIndex()); +} + +void CurvePanel::InitUI() +{ + // Create basic layout + QVBoxLayout* layout = new QVBoxLayout(this); + + // Add placeholder label showing panel information + QLabel* infoLabel = new QLabel(QString("Curve Panel %1\nFile: %2\n\nCurve Drawing Area\nPlease inherit this class to implement specific drawing functionality") + .arg(GetIndex()) + .arg(QFileInfo(GetFilePath()).fileName())); + infoLabel->setAlignment(Qt::AlignCenter); + infoLabel->setStyleSheet("QLabel { color: #666; font-size: 12px; padding: 20px; }"); + + layout->addWidget(infoLabel); + setLayout(layout); +} + +QString CurvePanel::GetTypeDisplayName() const +{ + return "Curve"; +} \ No newline at end of file diff --git a/src/ui/Panel/CurvePanel.h b/src/ui/Panel/CurvePanel.h new file mode 100644 index 00000000..1fa7e231 --- /dev/null +++ b/src/ui/Panel/CurvePanel.h @@ -0,0 +1,55 @@ +#pragma once + +#include "DataPanel.h" + +/** + * @file CurvePanel.h + * @brief Curve Panel Class + * Specialized panel for curve data visualization and manipulation + */ + +/** + * @brief Curve panel class + * Specialized panel for curve data, inherits from DataPanel + */ +class CurvePanel : public DataPanel +{ + Q_OBJECT + +public: + /** + * @brief Constructor + * @param index Panel index + * @param filePath Associated file path + * @param parent Parent widget + */ + explicit CurvePanel(int index, const QString& filePath, QWidget* parent = nullptr); + + /** + * @brief Destructor + */ + virtual ~CurvePanel(); + + /** + * @brief Get file type + * @return File type (always Curve for this class) + */ + FileEntryType GetFileType() const override { return FileEntryType::Curve; } + + /** + * @brief Refresh panel content + */ + void RefreshPanel() override; + +protected: + /** + * @brief Initialize UI for curve-specific layout + */ + void InitUI() override; + + /** + * @brief Get type display name + * @return Display name for curve type + */ + QString GetTypeDisplayName() const override; +}; \ No newline at end of file diff --git a/src/ui/Panel/DataPanel.cpp b/src/ui/Panel/DataPanel.cpp new file mode 100644 index 00000000..fa90efeb --- /dev/null +++ b/src/ui/Panel/DataPanel.cpp @@ -0,0 +1,75 @@ +#include "ui/Panel/DataPanel.h" +#include "ui/DockWidget.h" +#include "common/SpdLogger.h" + +#include +#include +#include +#include + +DataPanel::DataPanel(int index, FileEntryType fileType, const QString& filePath, QWidget* parent) + : QWidget(parent) + , index_(index) + , fileType_(fileType) + , filePath_(filePath) + , title_() + , dockWidget_(nullptr) +{ + title_ = GenerateTitle(); + InitUI(); + + LOG_INFO("Created DataPanel {} for {} file: {}", index_, FileEntryTypeToString(fileType_), filePath_.toStdString()); +} + +DataPanel::~DataPanel() +{ + LOG_INFO("Destroyed DataPanel {} ({})", index_, FileEntryTypeToString(fileType_)); +} + +void DataPanel::closeEvent(QCloseEvent* event) +{ + emit PanelClosed(); + event->accept(); +} + +void DataPanel::InitUI() +{ + // Create basic layout + QVBoxLayout* layout = new QVBoxLayout(this); + + // Add placeholder label showing panel information + QString typeDisplayName = GetTypeDisplayName(); + QLabel* infoLabel = new QLabel(QString("Panel %1 (%2)\nFile: %3\n\n%4 Data Area\nPlease inherit this class to implement specific functionality") + .arg(index_) + .arg(typeDisplayName) + .arg(QFileInfo(filePath_).fileName()) + .arg(typeDisplayName)); + infoLabel->setAlignment(Qt::AlignCenter); + infoLabel->setStyleSheet("QLabel { color: #666; font-size: 12px; padding: 20px; }"); + + layout->addWidget(infoLabel); + setLayout(layout); +} + +QString DataPanel::GenerateTitle() +{ + QFileInfo fileInfo(filePath_); + QString typeDisplayName = GetTypeDisplayName(); + return QString("%1 Panel %2 - %3").arg(typeDisplayName).arg(index_).arg(fileInfo.baseName()); +} + +QString DataPanel::GetTypeDisplayName() const +{ + switch (fileType_) { + case FileEntryType::Curve: + return "Curve"; + case FileEntryType::Surface: + return "Surface"; + case FileEntryType::Table: + return "Table"; + case FileEntryType::Light: + return "Light"; + default: + return "Unknown"; + } +} \ No newline at end of file diff --git a/src/ui/Panel/DataPanel.h b/src/ui/Panel/DataPanel.h new file mode 100644 index 00000000..611a7879 --- /dev/null +++ b/src/ui/Panel/DataPanel.h @@ -0,0 +1,115 @@ +#pragma once + +#include +#include +#include "workspace/FileEntry.h" + +class DockWidget; + +/** + * @file DataPanel.h + * @brief Data Panel Base Class + * Provides panel framework structure for different data types, specific functionality implemented by derived classes + */ + +/** + * @brief Data panel base class + * Provides panel framework structure for different data types, specific functionality implemented by derived classes + */ +class DataPanel : public QWidget +{ + Q_OBJECT + +public: + /** + * @brief Constructor + * @param index Panel index + * @param fileType File type + * @param filePath Associated file path + * @param parent Parent widget + */ + explicit DataPanel(int index, FileEntryType fileType, const QString& filePath, QWidget* parent = nullptr); + + /** + * @brief Destructor + */ + virtual ~DataPanel(); + + /** + * @brief Get panel index + * @return Panel index + */ + int GetIndex() const { return index_; } + + /** + * @brief Get file type (virtual function, implemented by derived classes) + * @return File type + */ + virtual FileEntryType GetFileType() const { return fileType_; } + + /** + * @brief Get file path + * @return File path + */ + QString GetFilePath() const { return filePath_; } + + /** + * @brief Get panel title + * @return Panel title + */ + QString GetTitle() const { return title_; } + + /** + * @brief Set dock widget reference + * @param dockWidget Dock widget pointer + */ + void SetDockWidget(DockWidget* dockWidget) { dockWidget_ = dockWidget; } + + /** + * @brief Get dock widget reference + * @return Dock widget pointer + */ + DockWidget* GetDockWidget() const { return dockWidget_; } + + /** + * @brief Refresh panel content (virtual function, implemented by derived classes) + */ + virtual void RefreshPanel() {} + +signals: + /** + * @brief Panel close signal + */ + void PanelClosed(); + +protected: + /** + * @brief Close event handler + * @param event Close event + */ + void closeEvent(QCloseEvent* event) override; + + /** + * @brief Initialize UI (virtual function, derived classes implement specific layout) + */ + virtual void InitUI(); + + /** + * @brief Generate panel title + * @return Generated title + */ + virtual QString GenerateTitle(); + + /** + * @brief Get type display name (virtual function, implemented by derived classes) + * @return Display name for the file type + */ + virtual QString GetTypeDisplayName() const; + +private: + int index_; // Panel index + FileEntryType fileType_; // File type + QString filePath_; // Associated file path + QString title_; // Panel title + DockWidget* dockWidget_; // Dock widget reference +}; \ No newline at end of file diff --git a/src/ui/Panel/DataPanelFactory.cpp b/src/ui/Panel/DataPanelFactory.cpp new file mode 100644 index 00000000..2e59f7a7 --- /dev/null +++ b/src/ui/Panel/DataPanelFactory.cpp @@ -0,0 +1,67 @@ +#include "DataPanelFactory.h" +#include "DataPanel.h" +#include "CurvePanel.h" +#include "common/SpdLogger.h" + +// Forward declarations for future panel types +// #include "SurfacePanel.h" +// #include "TablePanel.h" +// #include "LightPanel.h" + +DataPanel* DataPanelFactory::CreatePanel(int index, FileEntryType fileType, const QString& filePath, QWidget* parent) +{ + switch (fileType) { + case FileEntryType::Curve: + // For now, create CurvePanel which should inherit from DataPanel + // TODO: Update CurvePanel to inherit from DataPanel + return new CurvePanel(index, filePath, parent); + + case FileEntryType::Surface: + // TODO: Implement SurfacePanel + LOG_WARN("SurfacePanel not implemented yet, creating base DataPanel"); + return new DataPanel(index, fileType, filePath, parent); + + case FileEntryType::Table: + // TODO: Implement TablePanel + LOG_WARN("TablePanel not implemented yet, creating base DataPanel"); + return new DataPanel(index, fileType, filePath, parent); + + case FileEntryType::Light: + // TODO: Implement LightPanel + LOG_WARN("LightPanel not implemented yet, creating base DataPanel"); + return new DataPanel(index, fileType, filePath, parent); + + default: + LOG_ERROR("Unsupported file type: {}", static_cast(fileType)); + return nullptr; + } +} + +bool DataPanelFactory::IsTypeSupported(FileEntryType fileType) +{ + switch (fileType) { + case FileEntryType::Curve: + case FileEntryType::Surface: + case FileEntryType::Table: + case FileEntryType::Light: + return true; + default: + return false; + } +} + +QString DataPanelFactory::GetTypeDisplayName(FileEntryType fileType) +{ + switch (fileType) { + case FileEntryType::Curve: + return "Curve"; + case FileEntryType::Surface: + return "Surface"; + case FileEntryType::Table: + return "Table"; + case FileEntryType::Light: + return "Light"; + default: + return "Unknown"; + } +} \ No newline at end of file diff --git a/src/ui/Panel/DataPanelFactory.h b/src/ui/Panel/DataPanelFactory.h new file mode 100644 index 00000000..a72b631c --- /dev/null +++ b/src/ui/Panel/DataPanelFactory.h @@ -0,0 +1,49 @@ +#pragma once + +#include +#include "workspace/FileEntry.h" + +class DataPanel; +class QWidget; + +/** + * @file DataPanelFactory.h + * @brief Data Panel Factory + * Creates appropriate panel instances based on file type + */ + +/** + * @brief Data panel factory class + * Creates appropriate panel instances based on file type using factory pattern + */ +class DataPanelFactory +{ +public: + /** + * @brief Create panel based on file type + * @param index Panel index + * @param fileType File type + * @param filePath File path + * @param parent Parent widget + * @return Created panel pointer (caller takes ownership) + */ + static DataPanel* CreatePanel(int index, FileEntryType fileType, const QString& filePath, QWidget* parent = nullptr); + + /** + * @brief Check if file type is supported + * @param fileType File type to check + * @return True if supported, false otherwise + */ + static bool IsTypeSupported(FileEntryType fileType); + + /** + * @brief Get display name for file type + * @param fileType File type + * @return Display name + */ + static QString GetTypeDisplayName(FileEntryType fileType); + +private: + // Private constructor to prevent instantiation + DataPanelFactory() = default; +}; \ No newline at end of file diff --git a/src/ui/Panel/DataPanelManager.cpp b/src/ui/Panel/DataPanelManager.cpp new file mode 100644 index 00000000..8764e78b --- /dev/null +++ b/src/ui/Panel/DataPanelManager.cpp @@ -0,0 +1,296 @@ +#include "DataPanelManager.h" +#include "DataPanel.h" +#include "DataPanelFactory.h" +#include "ui/DockWidget.h" +#include "ui/DockTitleBar.h" +#include "ui/MainWindow.h" +#include "workspace/FileEntry.h" +#include "common/SpdLogger.h" + +#include +#include + +const QString DataPanelManager::PANEL_OBJECT_NAME_PREFIX = "DataPanel_"; + +DataPanelManager::DataPanelManager(MainWindow* mainWindow, QObject* parent) + : QObject(parent) + , mainWindow_(mainWindow) + , currentWorkspace_(nullptr) +{ + LOG_INFO("DataPanelManager initialized"); +} + +DataPanelManager::~DataPanelManager() +{ + ClearAllPanels(); + LOG_INFO("DataPanelManager destroyed"); +} + +void DataPanelManager::SetWorkspace(WorkSpace* workspace) +{ + if (currentWorkspace_ == workspace) { + return; + } + + // Disconnect old workspace signal connections + if (currentWorkspace_) { + disconnect(currentWorkspace_, nullptr, this, nullptr); + } + + currentWorkspace_ = workspace; + + // Connect new workspace signals + if (currentWorkspace_) { + connect(currentWorkspace_, &WorkSpace::FilesChanged, this, &DataPanelManager::OnFilesChanged); + } + + // Update all panel types + if (currentWorkspace_) { + UpdatePanelsForType(FileEntryType::Curve); + UpdatePanelsForType(FileEntryType::Surface); + UpdatePanelsForType(FileEntryType::Table); + UpdatePanelsForType(FileEntryType::Light); + } else { + ClearAllPanels(); + } +} + +int DataPanelManager::GetActivePanelCount(FileEntryType fileType) const +{ + if (static_cast(fileType) == -1) { + // Return total count + return dataPanels_.size(); + } + + // Count panels of specific type + int count = 0; + for (auto it = dataPanels_.begin(); it != dataPanels_.end(); ++it) { + if (it.value()->GetFileType() == fileType) { + count++; + } + } + return count; +} + +QList DataPanelManager::GetPanelsOfType(FileEntryType fileType) const +{ + QList panels; + for (auto it = dataPanels_.begin(); it != dataPanels_.end(); ++it) { + if (it.value()->GetFileType() == fileType) { + panels.append(it.value()); + } + } + return panels; +} + +void DataPanelManager::OnWorkspaceChanged(WorkSpace* workspace) +{ + SetWorkspace(workspace); +} + +void DataPanelManager::OnFilesChanged(FileEntryType type) +{ + // Only respond to supported file types + if (!DataPanelFactory::IsTypeSupported(type)) { + return; + } + + UpdatePanelsForType(type); +} + +void DataPanelManager::OnPanelClosed() +{ + DataPanel* panel = qobject_cast(sender()); + if (panel) { + RemovePanel(panel); + } +} + +void DataPanelManager::UpdatePanelsForType(FileEntryType fileType) +{ + if (!currentWorkspace_) { + ClearPanelsOfType(fileType); + return; + } + + // Get files of specified type from current workspace + std::vector files = currentWorkspace_->GetFileEntries(fileType); + + // Limit to maximum panels per type + const int maxPanels = qMin(static_cast(files.size()), GetMaxPanelCount()); + + // Find panels to remove (excess panels of this type) + QStringList keysToRemove; + for (auto it = dataPanels_.begin(); it != dataPanels_.end(); ++it) { + DataPanel* panel = it.value(); + if (panel->GetFileType() == fileType && panel->GetIndex() >= maxPanels) { + keysToRemove.append(it.key()); + } + } + + // Remove excess panels + for (const QString& key : keysToRemove) { + RemovePanel(dataPanels_[key]); + } + + // Create or update panels + for (int i = 0; i < maxPanels; ++i) { + const FileEntry& fileEntry = files[i]; + QString filePath = currentWorkspace_->GetFileEntryAbsPath(fileEntry.type, i); + QString panelKey = QString("%1_%2").arg(FileEntryTypeToString(fileType)).arg(i); + + if (dataPanels_.contains(panelKey)) { + // Check if file path has changed + DataPanel* existingPanel = dataPanels_[panelKey]; + if (existingPanel->GetFilePath() != filePath) { + // File path changed, recreate panel + RemovePanel(existingPanel); + CreateDataPanel(fileType, filePath); + } else { + // File path unchanged, refresh data + existingPanel->RefreshPanel(); + } + } else { + // Create new panel + CreateDataPanel(fileType, filePath); + } + } +} + +DataPanel* DataPanelManager::CreateDataPanel(FileEntryType fileType, const QString& filePath) +{ + if (GetActivePanelCount(fileType) >= GetMaxPanelCount()) { + LOG_WARN("Cannot create more {} panels, maximum count reached: {}", + FileEntryTypeToString(fileType), GetMaxPanelCount()); + return nullptr; + } + + // Find next available index for this file type + int index = FindNextAvailableIndex(fileType); + QString panelKey = QString("%1_%2").arg(FileEntryTypeToString(fileType)).arg(index); + + // Create dock widget + DockWidget* dockWidget = new DockWidget(mainWindow_); + dockWidget->setObjectName(GeneratePanelObjectName(fileType, index)); + + // Set title bar + DockTitleBar* titleBar = new DockTitleBar(dockWidget); + dockWidget->SetDockWidgetTitleBar(titleBar); + + // Connect signals + connect(dockWidget, &DockWidget::dockLocationChanged, this, [this](Qt::DockWidgetArea area) { + // Handle dock location changes if needed + }); + + // Add to main window + mainWindow_->addDockWidget(Qt::RightDockWidgetArea, dockWidget); + + // Create panel using factory + DataPanel* panel = DataPanelFactory::CreatePanel(index, fileType, filePath, dockWidget); + if (!panel) { + LOG_ERROR("Failed to create panel for type: {}", FileEntryTypeToString(fileType)); + dockWidget->deleteLater(); + return nullptr; + } + + dockWidget->setWidget(panel); + + // Set panel's dock widget reference + panel->SetDockWidget(dockWidget); + + // Connect panel signals + connect(panel, &DataPanel::PanelClosed, this, &DataPanelManager::OnPanelClosed); + + // Save references + dataPanels_[panelKey] = panel; + dockWidgets_[panelKey] = dockWidget; + + LOG_INFO("Created {} panel {} for file: {}", + FileEntryTypeToString(fileType), index, filePath.toStdString()); + return panel; +} + +void DataPanelManager::RemovePanel(DataPanel* panel) +{ + if (!panel) { + return; + } + + // Find panel key + QString panelKey; + for (auto it = dataPanels_.begin(); it != dataPanels_.end(); ++it) { + if (it.value() == panel) { + panelKey = it.key(); + break; + } + } + + if (panelKey.isEmpty()) { + return; + } + + // Remove dock widget + if (dockWidgets_.contains(panelKey)) { + DockWidget* dockWidget = dockWidgets_[panelKey]; + mainWindow_->removeDockWidget(dockWidget); + dockWidget->deleteLater(); + } + + // Remove from mappings + dataPanels_.remove(panelKey); + dockWidgets_.remove(panelKey); + + // Delete panel + panel->deleteLater(); + + LOG_INFO("Removed {} panel {}", + FileEntryTypeToString(panel->GetFileType()), panel->GetIndex()); +} + +void DataPanelManager::ClearAllPanels() +{ + // Get copy of all keys + QStringList keys = dataPanels_.keys(); + + // Remove panels one by one + for (const QString& key : keys) { + RemovePanel(dataPanels_[key]); + } + + LOG_INFO("Cleared all data panels"); +} + +void DataPanelManager::ClearPanelsOfType(FileEntryType fileType) +{ + QStringList keysToRemove; + for (auto it = dataPanels_.begin(); it != dataPanels_.end(); ++it) { + if (it.value()->GetFileType() == fileType) { + keysToRemove.append(it.key()); + } + } + + for (const QString& key : keysToRemove) { + RemovePanel(dataPanels_[key]); + } + + LOG_INFO("Cleared all {} panels", FileEntryTypeToString(fileType)); +} + +QString DataPanelManager::GeneratePanelObjectName(FileEntryType fileType, int index) const +{ + return QString("%1%2_%3").arg(PANEL_OBJECT_NAME_PREFIX) + .arg(FileEntryTypeToString(fileType)) + .arg(index); +} + +int DataPanelManager::FindNextAvailableIndex(FileEntryType fileType) const +{ + int index = 0; + QString baseKey = QString("%1_").arg(FileEntryTypeToString(fileType)); + + while (dataPanels_.contains(baseKey + QString::number(index))) { + index++; + } + + return index; +} \ No newline at end of file diff --git a/src/ui/Panel/DataPanelManager.h b/src/ui/Panel/DataPanelManager.h new file mode 100644 index 00000000..084f4a33 --- /dev/null +++ b/src/ui/Panel/DataPanelManager.h @@ -0,0 +1,125 @@ +#pragma once + +#include +#include +#include +#include "workspace/WorkSpace.h" +#include "workspace/FileEntry.h" + +class DockWidget; +class DataPanel; +class MainWindow; + +/** + * @file DataPanelManager.h + * @brief Data Panel Manager + * Manages data panels created based on workspace files, supports multiple file types + */ + +class DataPanelManager : public QObject +{ + Q_OBJECT + +public: + explicit DataPanelManager(MainWindow* mainWindow, QObject* parent = nullptr); + ~DataPanelManager(); + + /** + * @brief Set current workspace + * @param workspace Workspace pointer + */ + void SetWorkspace(WorkSpace* workspace); + + /** + * @brief Get current active panel count for specific type + * @param fileType File type (if not specified, returns total count) + * @return Panel count + */ + int GetActivePanelCount(FileEntryType fileType = static_cast(-1)) const; + + /** + * @brief Get maximum panel count per type + * @return Maximum panel count + */ + int GetMaxPanelCount() const { return 9; } + + /** + * @brief Get panels of specific type + * @param fileType File type + * @return List of panels for the specified type + */ + QList GetPanelsOfType(FileEntryType fileType) const; + +public slots: + /** + * @brief Handle workspace changes + * @param workspace New workspace + */ + void OnWorkspaceChanged(WorkSpace* workspace); + + /** + * @brief Handle file changes + * @param type File type + */ + void OnFilesChanged(FileEntryType type); + + /** + * @brief Handle panel close event + */ + void OnPanelClosed(); + +private: + /** + * @brief Update panels for specific file type + * @param fileType File type to update + */ + void UpdatePanelsForType(FileEntryType fileType); + + /** + * @brief Create new data panel + * @param fileType File type + * @param filePath File path + * @return Created panel pointer + */ + DataPanel* CreateDataPanel(FileEntryType fileType, const QString& filePath); + + /** + * @brief Remove panel + * @param panel Panel pointer + */ + void RemovePanel(DataPanel* panel); + + /** + * @brief Clear all panels + */ + void ClearAllPanels(); + + /** + * @brief Clear panels of specific type + * @param fileType File type + */ + void ClearPanelsOfType(FileEntryType fileType); + + /** + * @brief Generate panel object name + * @param fileType File type + * @param index Panel index + * @return Object name + */ + QString GeneratePanelObjectName(FileEntryType fileType, int index) const; + + /** + * @brief Find next available index for file type + * @param fileType File type + * @return Next available index + */ + int FindNextAvailableIndex(FileEntryType fileType) const; + +private: + MainWindow* mainWindow_; // Main window pointer + WorkSpace* currentWorkspace_; // Current workspace + QMap dataPanels_; // Panel mapping (key -> panel) + QMap dockWidgets_; // Dock widget mapping (key -> dock widget) + + static const QString PANEL_OBJECT_NAME_PREFIX; // Panel object name prefix +}; \ No newline at end of file diff --git a/src/workspace/WorkSpaceManager.cpp b/src/workspace/WorkSpaceManager.cpp index 582e244f..7b85fea4 100644 --- a/src/workspace/WorkSpaceManager.cpp +++ b/src/workspace/WorkSpaceManager.cpp @@ -190,7 +190,7 @@ void WorkSpaceManager::OnFrame() { QString WorkSpaceManager::GetDefaultWorkSpaceName() { #if _DEBUG - const QString iniFile = QString("%1workspace/config.ini").arg(QString(CONFIG_PATH)).arg(skin); + const QString iniFile = QString("%1workspace/config.ini").arg(QString(CONFIG_PATH)); #else const QString appDirPath = QApplication::applicationDirPath(); const QString iniFile = QString("%1/config/workspace/config.ini").arg(appDirPath);