DYTSrouce/src/ui/Panel/DataPanelManager.cpp

343 lines
9.8 KiB
C++
Raw Normal View History

2025-10-16 03:29:25 +00:00
#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"
2025-10-27 07:19:55 +00:00
#include "workspace/Timestep.h"
2025-10-16 03:29:25 +00:00
#include "common/SpdLogger.h"
#include <QFileInfo>
#include <QDir>
2025-10-27 07:19:55 +00:00
#include <QSet>
2025-10-16 03:29:25 +00:00
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);
2025-10-27 07:19:55 +00:00
// Connect to Timestep signals if available
if (currentWorkspace_->GetTimestep()) {
connect(currentWorkspace_->GetTimestep(), &Timestep::TimeChanged, this, &DataPanelManager::OnTimeChanged);
}
// Connect to TimestepChanged signal to handle future Timestep changes
connect(currentWorkspace_, &WorkSpace::TimestepChanged, this, [this](Timestep* timestep) {
if (timestep) {
connect(timestep, &Timestep::TimeChanged, this, &DataPanelManager::OnTimeChanged);
}
});
2025-10-16 03:29:25 +00:00
}
// Update all panel types
if (currentWorkspace_) {
UpdatePanelsForType(FileEntryType::Curve);
UpdatePanelsForType(FileEntryType::Surface);
UpdatePanelsForType(FileEntryType::Table);
UpdatePanelsForType(FileEntryType::Light);
2025-10-31 15:10:35 +00:00
UpdatePanelsForType(FileEntryType::Polar);
2025-10-16 03:29:25 +00:00
} else {
ClearAllPanels();
}
}
int DataPanelManager::GetActivePanelCount(FileEntryType fileType) const
{
if (static_cast<int>(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<DataPanel*> DataPanelManager::GetPanelsOfType(FileEntryType fileType) const
{
QList<DataPanel*> 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);
}
2025-10-27 14:58:41 +00:00
void DataPanelManager::OnFilesChanged(FileEntryType type, std::shared_ptr<FileEntry> fileEntry)
2025-10-16 03:29:25 +00:00
{
// Only respond to supported file types
if (!DataPanelFactory::IsTypeSupported(type)) {
return;
}
UpdatePanelsForType(type);
}
void DataPanelManager::OnPanelClosed()
{
DataPanel* panel = qobject_cast<DataPanel*>(sender());
if (panel) {
RemovePanel(panel);
}
}
void DataPanelManager::UpdatePanelsForType(FileEntryType fileType)
{
if (!currentWorkspace_) {
ClearPanelsOfType(fileType);
return;
}
// Get files of specified type from current workspace
2025-10-26 07:55:41 +00:00
std::vector<std::shared_ptr<FileEntry>> files = currentWorkspace_->GetFileEntries(fileType);
2025-10-16 03:29:25 +00:00
// Limit to maximum panels per type
const int maxPanels = qMin(static_cast<int>(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) {
2025-10-26 07:55:41 +00:00
std::shared_ptr<FileEntry> fileEntry = files[i];
QString filePath = currentWorkspace_->GetFileEntryAbsPath(fileEntry->GetType(), i);
2025-10-16 03:29:25 +00:00
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
2025-10-20 18:17:40 +00:00
DataPanel* panel = DataPanelFactory::CreatePanel(fileType, index, filePath, dockWidget);
2025-10-16 03:29:25 +00:00
if (!panel) {
LOG_ERROR("Failed to create panel for type: {}", FileEntryTypeToString(fileType));
dockWidget->deleteLater();
return nullptr;
}
2025-10-27 07:26:32 +00:00
dockWidget->setWidget(panel);
// Set panel's dock widget reference
panel->SetDockWidget(dockWidget);
2025-10-26 12:14:06 +00:00
auto fileEntries = currentWorkspace_->GetFileEntries(fileType);
if (index < fileEntries.size()) {
panel->SetFileEntry(fileEntries[index]);
2025-10-27 00:35:04 +00:00
panel->InitUI();
2025-10-27 02:39:03 +00:00
panel->RefreshPanel();
2025-10-26 12:14:06 +00:00
}
2025-10-22 01:32:34 +00:00
2025-10-16 03:29:25 +00:00
// 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
{
2025-10-27 07:19:55 +00:00
QSet<int> usedIndices;
QString typeStr = FileEntryTypeToString(fileType);
2025-10-16 03:29:25 +00:00
2025-11-01 04:43:16 +00:00
for (auto it = dataPanels_.constBegin(); it != dataPanels_.constEnd(); ++it)
{
FileEntryType type = it.value()->GetFileType();
if (type == fileType)
{
int nIndex = it.value()->GetIndex();
usedIndices.insert(nIndex);
2025-10-27 07:19:55 +00:00
}
}
2025-11-01 04:43:16 +00:00
for (int i = 0; i < GetMaxPanelCount(); ++i)
{
if (!usedIndices.contains(i))
{
2025-10-27 07:19:55 +00:00
return i;
}
2025-10-16 03:29:25 +00:00
}
2025-10-27 07:19:55 +00:00
return -1; // No available index
}
void DataPanelManager::OnTimeChanged(double time)
{
// Notify all active panels about time change
for (auto it = dataPanels_.constBegin(); it != dataPanels_.constEnd(); ++it) {
DataPanel* panel = it.value();
if (panel) {
panel->OnTimeChanged(time);
}
}
2025-10-16 03:29:25 +00:00
}