From 863e0867ce2ecda6c0cf3b49195ff10d3982a451 Mon Sep 17 00:00:00 2001 From: pimin <362371171@qq.com> Date: Mon, 27 Oct 2025 17:48:27 +0800 Subject: [PATCH] modified tablepanel --- src/ui/Panel/CurvePanel.cpp | 2 - src/ui/Panel/CurvePanel.h | 7 - src/ui/Panel/DataPanelFactory.cpp | 4 +- src/ui/Panel/FitCurve.ui | 31 ---- src/ui/Panel/TablePanel.cpp | 224 +++++++++++++++++++++++++++ src/ui/Panel/TablePanel.h | 76 +++++++++ src/ui/WorkSpace/AddTableFileDlg.cpp | 6 +- src/workspace/FileEntry.cpp | 112 +++++++++++--- src/workspace/FileEntry.h | 18 +-- 9 files changed, 401 insertions(+), 79 deletions(-) delete mode 100644 src/ui/Panel/FitCurve.ui create mode 100644 src/ui/Panel/TablePanel.cpp create mode 100644 src/ui/Panel/TablePanel.h diff --git a/src/ui/Panel/CurvePanel.cpp b/src/ui/Panel/CurvePanel.cpp index 0dbf6d2b..659b5505 100644 --- a/src/ui/Panel/CurvePanel.cpp +++ b/src/ui/Panel/CurvePanel.cpp @@ -11,8 +11,6 @@ #include #include -#include "ui_FitCurve.h" - CurvePanel::CurvePanel(int index, const QString& filePath, QWidget* parent) : DataPanel(index, FileEntryType::Curve, filePath, parent) { diff --git a/src/ui/Panel/CurvePanel.h b/src/ui/Panel/CurvePanel.h index 595fa721..4427d3b4 100644 --- a/src/ui/Panel/CurvePanel.h +++ b/src/ui/Panel/CurvePanel.h @@ -5,9 +5,6 @@ #include #include "ui/chartPlot/FitCurveChartView.h" -namespace Ui { - class FitCurve; -} /** * @file CurvePanel.h * @brief Curve Panel Class @@ -92,13 +89,9 @@ private: void updateReportData(double t); private: - Ui::FitCurve* ui; FitCurveChartView* curveChartView; QChart* curveChart; - bool isPressed = false; - QPoint pressedPoint; - QValueAxis* m_pAxisX = NULL; QValueAxis* m_pAxisY = NULL; float m_iXMax; diff --git a/src/ui/Panel/DataPanelFactory.cpp b/src/ui/Panel/DataPanelFactory.cpp index 7dad248d..ee278bfe 100644 --- a/src/ui/Panel/DataPanelFactory.cpp +++ b/src/ui/Panel/DataPanelFactory.cpp @@ -5,7 +5,7 @@ // Forward declarations for future panel types // #include "SurfacePanel.h" -// #include "TablePanel.h" + #include "TablePanel.h" // #include "LightPanel.h" DataPanel* DataPanelFactory::CreatePanel(FileEntryType fileType, int index, const QString& filePath, QWidget* parent) @@ -24,7 +24,7 @@ DataPanel* DataPanelFactory::CreatePanel(FileEntryType fileType, int index, cons case FileEntryType::Table: // TODO: Implement TablePanel LOG_WARN("TablePanel not implemented yet, creating base DataPanel"); - return new DataPanel(index, fileType, filePath, parent); + return new TablePanel(index, filePath, parent); case FileEntryType::Light: // TODO: Implement LightPanel diff --git a/src/ui/Panel/FitCurve.ui b/src/ui/Panel/FitCurve.ui deleted file mode 100644 index 70c5f48a..00000000 --- a/src/ui/Panel/FitCurve.ui +++ /dev/null @@ -1,31 +0,0 @@ - - - FitCurve - - - - 0 - 0 - 977 - 703 - - - - FitCurveDialog - - - - - 70 - 40 - 851 - 621 - - - - - - - - - diff --git a/src/ui/Panel/TablePanel.cpp b/src/ui/Panel/TablePanel.cpp new file mode 100644 index 00000000..bb7a9a2e --- /dev/null +++ b/src/ui/Panel/TablePanel.cpp @@ -0,0 +1,224 @@ +#include "ui/Panel/TablePanel.h" +#include "ui/DockWidget.h" +#include "ui/DockTitleBar.h" +#include "common/SpdLogger.h" +#include +#include +#include +#include + +TablePanel::TablePanel(int index, const QString& filePath, QWidget* parent) + : DataPanel(index, FileEntryType::Curve, filePath, parent) +{ + LOG_INFO("Created TablePanel {} for file: {}", index, filePath.toStdString()); +} + +TablePanel::TablePanel(int index, std::shared_ptr fileEntry, QWidget* parent) + : DataPanel(index, fileEntry, parent) +{ + if (fileEntry) { + LOG_INFO("Created TablePanel {} for chart: {}", index, fileEntry->GetName().toStdString()); + // Override the title with chart name + title_ = QString("Table Panel %1 - %2").arg(index).arg(fileEntry->GetName()); + } + else { + LOG_WARN("Created TablePanel {} with null chart data", index); + } +} + +TablePanel::~TablePanel() +{ + LOG_INFO("Destroyed TablePanel {}", GetIndex()); +} + +void TablePanel::RefreshPanel() +{ + // Implement curve-specific refresh logic here + DataPanel::RefreshPanel(); + + if (auto fileEntry = fileEntry_->AsTable()) { + OnDataPanelUpdated(fileEntry); + } + + LOG_INFO("Refreshed TablePanel {}", GetIndex()); +} + +void TablePanel::InitUI() +{ + m_pTableWidget = new QTableWidget; + + QHeaderView* horizontalHeader = m_pTableWidget->horizontalHeader(); + QColor headerColor = QColor(100, 100, 100); + horizontalHeader->setStyleSheet(QString("QHeaderView::section {background-color: %1;}").arg(headerColor.name())); + horizontalHeader->setStretchLastSection(true); + + m_pTableWidget->verticalHeader()->setHidden(true); + + m_pTableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); + m_pTableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); + m_pTableWidget->setContextMenuPolicy(Qt::CustomContextMenu); + //m_pTableWidget->setSortingEnabled(true); + + //connect(m_pTableWidget, SIGNAL(itemDoubleClicked(QTableWidgetItem *)), + // this, SLOT(slotDoubleClickedItem(QTableWidgetItem *))); + + //connect(m_pTableWidget, SIGNAL(itemClicked(QTableWidgetItem *)), + // this, SLOT(slotClickedItem(QTableWidgetItem *))); + + //connect(m_pTableWidget->horizontalHeader(),SIGNAL(sectionClicked(int)), this, SLOT(slotSortTabCol(int))); + + QHBoxLayout* mainLayout = new QHBoxLayout(this); + mainLayout->setContentsMargins(0, 0, 0, 0); + mainLayout->addWidget(m_pTableWidget); + setLayout(mainLayout); +} + +QString TablePanel::GetTypeDisplayName() const +{ + return "Table"; +} + +void TablePanel::OnDataPanelUpdated(FileEntryTable* fileEntry) +{ + QString strName = fileEntry->GetName(); + updateTitle(strName); + + FileEntryTable::ChartProperties propChart = fileEntry->GetChartProperties(); + + QStringList tableHeader = propChart.headerString.split(',', Qt::SkipEmptyParts); + SetHeader(tableHeader); + + QString strFile = fileEntry->GetPath() + "/" + fileEntry->GetFileName(); + FileEntryTable::TableProperties listCurve = fileEntry->GetTableProperties(); + updateParseFile(strFile, propChart.timeParam, listCurve); +} + +void TablePanel::OnTimeChanged(double time) +{ + updateTable(time); +} + +void TablePanel::updateTitle(const QString & title) +{ + if (nullptr != dockWidget_) + { + dockWidget_->setWindowTitle(title); + } +} + +void TablePanel::SetHeader(const QStringList& headerLabels) +{ + m_pTableWidget->clear(); + + m_pTableWidget->setColumnCount(headerLabels.size()); + m_pTableWidget->setHorizontalHeaderLabels(headerLabels); +} + +void TablePanel::updateParseFile(const QString & strFile, int nT, FileEntryTable::TableProperties listCurve) +{ + if (strFile.isEmpty()) + { + QMessageBox::information(nullptr, QString::fromLocal8Bit("提示"), QString::fromLocal8Bit("请检查数据文件路径!")); + return; + } + + QFile file(strFile); + if (file.open(QIODevice::ReadOnly)) + { + for (int nI = 0; nI < listCurve.size(); nI++) + { + FileEntryTable::TableProperty curve = listCurve.at(nI); + m_tableSetting.insert(nI, qMakePair(curve.name, curve.color)); + } + + while (!file.atEnd()) + { + QString strLine = file.readLine().simplified(); + if (!strLine.isEmpty()) + { + QStringList listLine = strLine.split(" "); + double t = listLine.at(nT).toDouble(); + + QMap mapData; + if (listCurve.size() == 0) + { + int nCount = m_pTableWidget->columnCount(); + int nRow = (listLine.size() - 1) / nCount; + for (int nI = 0; nI < nRow; nI++) + { + int nBegin = nT + 1 + nI * nCount; + QVariantList varList; + for (int nJ = 0; nJ < nCount; nJ++) + { + int nIndex = nBegin + nJ; + double data = listLine.at(nIndex).toDouble(); + varList.push_back(data); + } + mapData.insert(nI, varList); + } + } + else + { + for (int nI = 0; nI < listCurve.size(); nI++) + { + FileEntryTable::TableProperty curve = listCurve.at(nI); + + QVariantList varList; + for (int nJ = 0; nJ < curve.datas.size(); nJ++) + { + int nIndex = curve.datas.at(nJ); + double data = listLine.at(nIndex).toDouble(); + varList.push_back(data); + } + mapData.insert(nI, varList); + } + } + + m_dataTable.insert(t, mapData); + } + } + file.close(); + } +} + +void TablePanel::updateTable(double t) +{ + if (m_dataTable.size() > 0) + { + clearTable(); + + QMap< double, QMap >::const_iterator ite = m_dataTable.lowerBound(t); + if (ite == m_dataTable.end()) + { + ite--; + } + + QMap mapData = ite.value(); + for (QMap::Iterator it = mapData.begin(); it != mapData.end(); it++) + { + int nRow = it.key(); + QVariantList dataList = it.value(); + + m_pTableWidget->insertRow(nRow); + + for (int nI = 0; nI < dataList.size(); nI++) + { + QString strVal; + strVal.sprintf("%.6f", dataList.at(nI).toFloat()); + QTableWidgetItem *item = new QTableWidgetItem(strVal); + item->setTextAlignment(Qt::AlignCenter); + m_pTableWidget->setItem(nRow, nI, item); + } + } + } +} + +void TablePanel::clearTable() +{ + int nCount = m_pTableWidget->rowCount(); + for (int nI = 0; nI < nCount; ) + { + m_pTableWidget->removeRow(0); + nCount = m_pTableWidget->rowCount(); + } +} \ No newline at end of file diff --git a/src/ui/Panel/TablePanel.h b/src/ui/Panel/TablePanel.h new file mode 100644 index 00000000..5b884ff2 --- /dev/null +++ b/src/ui/Panel/TablePanel.h @@ -0,0 +1,76 @@ +#pragma once + +#include "DataPanel.h" +#include "workspace/FileEntry.h" +#include +#include + +class TablePanel : public DataPanel +{ + Q_OBJECT + +public: + /** + * @brief Constructor + * @param index Panel index + * @param filePath Associated file path + * @param parent Parent widget + */ + explicit TablePanel(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 TablePanel(int index, std::shared_ptr fileEntry, QWidget* parent = nullptr); + + /** + * @brief Destructor + */ + virtual ~TablePanel(); + + /** + * @brief Get file type + * @return File type (always Curve for this class) + */ + FileEntryType GetFileType() const override { return FileEntryType::Table; } + + /** + * @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(FileEntryTable* fileEntry); + + virtual void OnTimeChanged(double time); + +private: + void updateTitle(const QString& title); + void SetHeader(const QStringList& headerLabels); + + void updateParseFile(const QString& strFile, int nT, FileEntryTable::TableProperties listCurve); + + void updateTable(double t); + void clearTable(); + +private: + QTableWidget *m_pTableWidget; + + QMap< int, QPair > m_tableSetting; + QMap< double, QMap > m_dataTable; +}; + diff --git a/src/ui/WorkSpace/AddTableFileDlg.cpp b/src/ui/WorkSpace/AddTableFileDlg.cpp index 25dbb4fa..734718be 100644 --- a/src/ui/WorkSpace/AddTableFileDlg.cpp +++ b/src/ui/WorkSpace/AddTableFileDlg.cpp @@ -134,17 +134,15 @@ void AddTableFileDlg::accept() for (QString& header : headers) { header = header.trimmed(); } - fileEntry->SetTableHeaders(headers); + //fileEntry->SetTableHeaders(headers); } // Set chart properties FileEntryTable::ChartProperties chartProps; + chartProps.headerString = headersText; chartProps.timeParam = ui->timeParamSpinBox->value(); fileEntry->SetChartProperties(chartProps); - // Set description (using table name as description for now) - fileEntry->SetDescription(ui->tableNameEdit->text()); - // Add to workspace WorkSpace* workspace = WorkSpaceManager::Get().GetCurrent(); if (!workspace) { diff --git a/src/workspace/FileEntry.cpp b/src/workspace/FileEntry.cpp index 63d1cd09..cf367097 100644 --- a/src/workspace/FileEntry.cpp +++ b/src/workspace/FileEntry.cpp @@ -217,32 +217,104 @@ const FileEntryTable::TableProperties& FileEntryTable::GetTableProperties() cons return tableProperties_; } -void FileEntryTable::SetTableHeaders(const QStringList& headers) { - tableHeaders_ = headers; -} - -void FileEntryTable::SetTableHeaders(const QString& headerString) { - tableHeaders_ = headerString.split(',', Qt::SkipEmptyParts); - // Trim whitespace from each header - for (QString& header : tableHeaders_) { - header = header.trimmed(); - } -} - -const QStringList& FileEntryTable::GetTableHeaders() const { - return tableHeaders_; -} - FileEntryTable* FileEntryTable::AsTable() { return this; } -void FileEntryTable::SetDescription(const QString& description) { - description_ = description; +bool FileEntryTable::SaveFiles(tinyxml2::XMLElement * scene, tinyxml2::XMLDocument * doc) +{ + if (!scene || !doc) { + LOG_ERROR("Invalid XML parameters"); + return false; + } + + // 鍒涘缓 鍏冪礌 + tinyxml2::XMLElement* chartElement = doc->NewElement("chart"); + scene->InsertEndChild(chartElement); + + // 璁剧疆chart灞炴 + chartElement->SetAttribute("name", name_.toUtf8().constData()); + chartElement->SetAttribute("path", fileName_.toUtf8().constData()); + chartElement->SetAttribute("head", chartProperties_.headerString.toUtf8().constData()); + chartElement->SetAttribute("t", chartProperties_.timeParam); + + // 涓烘瘡涓狢urveProperty鍒涘缓鍏冪礌 + for (const auto& curve : tableProperties_) { + tinyxml2::XMLElement* curveElement = doc->NewElement("curve"); + chartElement->InsertEndChild(curveElement); + + curveElement->SetAttribute("name", curve.name.toUtf8().constData()); + curveElement->SetAttribute("color", QColorToString(curve.color).toUtf8().constData()); + + QString strData = ""; + for (int i = 0; i < curve.datas.size(); i++) + { + int nIndex = curve.datas.at(i); + if (strData.isEmpty()) + { + strData = QString::number(nIndex); + } + else + { + strData += "," + QString::number(nIndex); + } + } + curveElement->SetAttribute("data", strData.toUtf8().constData()); + } + + return true; } -const QString& FileEntryTable::GetDescription() const { - return description_; +bool FileEntryTable::ParseFiles(const tinyxml2::XMLElement * element) +{ + if (!element) { + LOG_ERROR("Invalid XML element"); + return false; + } + + // 瑙f瀽chart灞炴 + const char* nameAttr = element->Attribute("name"); + const char* pathAttr = element->Attribute("path"); + if (nameAttr) name_ = QString::fromUtf8(nameAttr); + if (pathAttr) { + QString fullPath = QString::fromUtf8(pathAttr); + QFileInfo fileInfo(fullPath); + fileName_ = fileInfo.fileName(); + path_ = fileInfo.absolutePath(); + } + + const char* headAttr = element->Attribute("head"); + if (headAttr) { + chartProperties_.headerString = QString::fromUtf8(headAttr); + } + + chartProperties_.timeParam = element->DoubleAttribute("t", 0.0); + + for (const tinyxml2::XMLElement* curveElement = element->FirstChildElement("curve"); + curveElement != nullptr; + curveElement = curveElement->NextSiblingElement("curve")) { + + TableProperty table; + + const char* curveNameAttr = curveElement->Attribute("name"); + const char* colorAttr = curveElement->Attribute("color"); + if (curveNameAttr) table.name = QString::fromUtf8(curveNameAttr); + if (colorAttr) table.color = StringToQColor(QString::fromUtf8(colorAttr)); + + const char* dataAttr = curveElement->Attribute("data"); + if (dataAttr) + { + QStringList strList = QString::fromUtf8(dataAttr).split(",", Qt::SkipEmptyParts); + for (int i = 0; i < strList.size(); i++) + { + table.datas.push_back(strList.at(i).toInt()); + } + } + + tableProperties_.append(table); + } + + return true; } // FileEntryCurve SaveFiles implementation diff --git a/src/workspace/FileEntry.h b/src/workspace/FileEntry.h index 908c0dd7..3fb0a5e3 100644 --- a/src/workspace/FileEntry.h +++ b/src/workspace/FileEntry.h @@ -221,8 +221,7 @@ private: class FileEntryTable : public FileEntry { public: struct ChartProperties { - QString name; - QString path; + QString headerString; double timeParam; }; @@ -247,23 +246,16 @@ public: void SetTableProperty(int index, const TableProperty& table); const TableProperties& GetTableProperties() const; - // Table headers management - void SetTableHeaders(const QStringList& headers); - void SetTableHeaders(const QString& headerString); // Parse from comma-separated string - const QStringList& GetTableHeaders() const; - // Type conversion FileEntryTable* AsTable() override; - - // Description management - void SetDescription(const QString& description); - const QString& GetDescription() const; + + // XML澶勭悊鏂规硶 + bool SaveFiles(tinyxml2::XMLElement* scene, tinyxml2::XMLDocument* doc) override; + bool ParseFiles(const tinyxml2::XMLElement* element) override; private: ChartProperties chartProperties_; - QStringList tableHeaders_; TableProperties tableProperties_; - QString description_; }; class FileEntryLight : public FileEntry {