298 lines
8.3 KiB
C++
298 lines
8.3 KiB
C++
#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 <QFileInfo>
|
|
#include <QDir>
|
|
|
|
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<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);
|
|
}
|
|
|
|
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<DataPanel*>(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<FileEntry> files = currentWorkspace_->GetFileEntries(fileType);
|
|
|
|
// 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) {
|
|
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(fileType, index, filePath, dockWidget);
|
|
if (!panel) {
|
|
LOG_ERROR("Failed to create panel for type: {}", FileEntryTypeToString(fileType));
|
|
dockWidget->deleteLater();
|
|
return nullptr;
|
|
}
|
|
|
|
panel->InitUI();
|
|
|
|
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;
|
|
} |