modified tablepanel
This commit is contained in:
parent
fafd290244
commit
863e0867ce
@ -11,8 +11,6 @@
|
||||
#include <QCheckBox>
|
||||
#include <QHBoxLayout>
|
||||
|
||||
#include "ui_FitCurve.h"
|
||||
|
||||
CurvePanel::CurvePanel(int index, const QString& filePath, QWidget* parent)
|
||||
: DataPanel(index, FileEntryType::Curve, filePath, parent)
|
||||
{
|
||||
|
||||
@ -5,9 +5,6 @@
|
||||
#include <memory>
|
||||
#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;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -1,31 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>FitCurve</class>
|
||||
<widget class="QDialog" name="FitCurve">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>977</width>
|
||||
<height>703</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>FitCurveDialog</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="horizontalLayoutWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>70</x>
|
||||
<y>40</y>
|
||||
<width>851</width>
|
||||
<height>621</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="chartLayout"/>
|
||||
</widget>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
224
src/ui/Panel/TablePanel.cpp
Normal file
224
src/ui/Panel/TablePanel.cpp
Normal file
@ -0,0 +1,224 @@
|
||||
#include "ui/Panel/TablePanel.h"
|
||||
#include "ui/DockWidget.h"
|
||||
#include "ui/DockTitleBar.h"
|
||||
#include "common/SpdLogger.h"
|
||||
#include <QHBoxLayout>
|
||||
#include <QFileInfo>
|
||||
#include <QMessageBox>
|
||||
#include <QHeaderView>
|
||||
|
||||
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<FileEntryTable> 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<int, QVariantList> 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<int, QVariantList> >::const_iterator ite = m_dataTable.lowerBound(t);
|
||||
if (ite == m_dataTable.end())
|
||||
{
|
||||
ite--;
|
||||
}
|
||||
|
||||
QMap<int, QVariantList> mapData = ite.value();
|
||||
for (QMap<int, QVariantList>::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();
|
||||
}
|
||||
}
|
||||
76
src/ui/Panel/TablePanel.h
Normal file
76
src/ui/Panel/TablePanel.h
Normal file
@ -0,0 +1,76 @@
|
||||
#pragma once
|
||||
|
||||
#include "DataPanel.h"
|
||||
#include "workspace/FileEntry.h"
|
||||
#include <memory>
|
||||
#include <QTableWidget>
|
||||
|
||||
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<FileEntryTable> 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<QString, QColor> > m_tableSetting;
|
||||
QMap< double, QMap<int, QVariantList> > m_dataTable;
|
||||
};
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
// 创建 <chart> 元素
|
||||
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);
|
||||
|
||||
// 为每个CurveProperty创建<curve>元素
|
||||
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;
|
||||
}
|
||||
|
||||
// 解析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
|
||||
|
||||
@ -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 {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user