Compare commits

...

2 Commits

Author SHA1 Message Date
8c03d98849 modify file attribute 2025-11-03 00:36:16 +08:00
a6d8351546 modify mainfram and remove chart plotmenu 2025-11-02 19:28:37 +08:00
11 changed files with 881 additions and 229 deletions

View File

@ -22,7 +22,6 @@
#include "chartPlot/FitCurveDialog.h"
#include "chartPlot/SurfaceDialog.h"
#include "ui/Menu/ChartPlotMenu.h" // lz 20140914
#include "common/SpdLogger.h"
#include "ui/Menu/SimuRunMenu.h"

View File

@ -85,9 +85,22 @@ void MainWindow::InitUI() {
//addDockWidget(pSettingUI->GetArea("PropertyBrowser"), attribte);
propertyBrowser_ = new PropertyBrowser(0);
propertyBrowser_->AttachDock(attribte);
// Ensure property panel has a reasonable minimum width; no maximum limit
attribte->setMinimumWidth(240);
mapDockWidget_.insert("PropertyBrowser", attribte);
addDockWidget(Qt::RightDockWidgetArea, attribte);
// Set an initial width for the property dock (no max constraint),
// this serves as default when there is no saved layout yet.
{
const int totalWidth = qMax(800, this->width());
const int initialPropWidth = qBound(240, totalWidth / 4, 480); // ~25% of window, within [240, 480]
QList<QDockWidget*> docksProp;
QList<int> sizesProp;
docksProp << attribte; sizesProp << initialPropWidth;
resizeDocks(docksProp, sizesProp, Qt::Horizontal);
}
connect(modelBrowser_, &ModelBrowser::WorkSpaceChange, propertyBrowser_, &PropertyBrowser::OnWorkSpaceChange);
connect(modelBrowser_, &ModelBrowser::EntityChange, propertyBrowser_, &PropertyBrowser::OnEntityChange);
@ -98,6 +111,10 @@ void MainWindow::InitUI() {
viewDock->SetDockWidgetTitleBar(new DockTitleBar(viewDock));
viewDock->setObjectName("Dock.MainView");
viewDock->setWidget(qtOsgViewWidget_);
// Ensure main view has a reasonable minimum size to avoid being squeezed
// Use smaller minimum size to support smaller displays
qtOsgViewWidget_->setMinimumSize(640, 480);
viewDock->setMinimumSize(640, 480);
addDockWidget(Qt::LeftDockWidgetArea, viewDock);
mapDockWidget_.insert("MainView", viewDock);
@ -116,6 +133,51 @@ void MainWindow::InitUI() {
UiLayoutManager::Restore(this, 1);
LOG_INFO("MainWindow::InitUI - UiLayoutManager::Restore completed");
// After restore, if the main view is too small, expand it
{
QDockWidget* mainViewDock = mapDockWidget_.value("MainView", nullptr);
QDockWidget* modelDock = mapDockWidget_.value("ModelBrowser", nullptr);
QDockWidget* propertyDock = mapDockWidget_.value("PropertyBrowser", nullptr);
if (mainViewDock) {
// Use percentage-based allocation instead of fixed pixel values
const int totalWidth = this->width();
const int modelBrowserWidth = qMin(280, totalWidth / 6); // ~15% or max 280px
const int propertyBrowserWidth = qMin(320, totalWidth / 4); // ~25% or max 320px
const int mainViewMinWidth = totalWidth - modelBrowserWidth - propertyBrowserWidth - 50; // Reserve some margin
// Only resize if main view is too small (less than 50% of available space)
if (mainViewDock->width() < mainViewMinWidth * 0.5) {
QList<QDockWidget*> docks;
QList<int> sizes;
if (modelDock) { docks << modelDock; sizes << modelBrowserWidth; }
docks << mainViewDock; sizes << mainViewMinWidth;
resizeDocks(docks, sizes, Qt::Horizontal);
}
}
// Defer setting an initial width for the property dock once, without constraining max width
if (propertyDock) {
QDockWidget* capturedDock = propertyDock;
QMetaObject::invokeMethod(this, [this, capturedDock]() {
QDockWidget* pd = capturedDock;
if (!pd) return;
const int totalW = this->width();
const int desired = qBound(240, totalW / 4, 480); // ~25% of window
LOG_INFO("PropertyDock pre-adjust width=%d, desired=%d, windowW=%d", pd->width(), desired, totalW);
const int oldMin = pd->minimumWidth();
const int oldMax = pd->maximumWidth();
pd->setMinimumWidth(desired);
pd->setMaximumWidth(desired);
QList<QDockWidget*> docksProp; QList<int> sizesProp;
docksProp << pd; sizesProp << desired;
resizeDocks(docksProp, sizesProp, Qt::Horizontal);
pd->setMinimumWidth(oldMin > 0 ? oldMin : 240);
pd->setMaximumWidth(QWIDGETSIZE_MAX);
LOG_INFO("PropertyDock post-adjust width=%d (min=%d,max=%d)", pd->width(), pd->minimumWidth(), pd->maximumWidth());
}, Qt::QueuedConnection);
}
}
//ui->viewWidget->layout()->addWidget(qtOsgViewWidget_);
qtOsgViewWidget_->LoadDefaultScene();

View File

@ -1,60 +0,0 @@
#include "ChartPlotMenu.h"
#include "../Matlab/MatlabObject.h"
#include "../../common/RecourceHelper.h"
#include "workspace/WorkSpace.h"
#include "workspace/WorkSpaceManager.h"
#include "workspace/LampStatus.h"
#include "utils/FileUtils.h"
#include <qmessagebox.h>
#include <qfiledialog.h>
#include <QDir>
ChartPlotMenu::ChartPlotMenu(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
InitMenu();
}
ChartPlotMenu::~ChartPlotMenu()
{
}
void ChartPlotMenu::InitMenu()
{
// Deprecated: SimMatlab run action removed
// Deprecated: SimMatlab selection removed
// Deprecated: Wave file selection removed
// Deprecated: RD file selection removed
// Deprecated: Report file selection removed
// Restore Lamp file selection with safe encoding
connect(ui.toolButton_6, &QToolButton::clicked, this, [this]() {
auto* ws = WorkSpaceManager::Get().GetCurrent();
const QString defaultDir = ws ? ws->GetDir() : QDir::currentPath();
const QString title = QString::fromLocal8Bit("选择Lamp文件");
const QString filters = QString::fromLocal8Bit("文本文件 (*.txt);;所有文件 (*.*)");
const QString file = QFileDialog::getOpenFileName(this, title, defaultDir, filters);
if (file.isEmpty()) {
return;
}
if (!ws) {
QMessageBox::warning(this, QString::fromLocal8Bit("提示"), QString::fromLocal8Bit("当前无工作区"));
return;
}
const bool ok = ws->SetLampPath(file);
if (ok) {
QMessageBox::information(this, QString::fromLocal8Bit("Lamp"), QString::fromLocal8Bit("已加载 Lamp 文件"));
} else {
QMessageBox::warning(this, QString::fromLocal8Bit("Lamp"), QString::fromLocal8Bit("加载 Lamp 文件失败"));
}
});
}

View File

@ -1,25 +0,0 @@
#pragma once
#include <QWidget>
#include "ui_ChartPlotMenu.h"
class DYTChart;
class ChartPlotMenu : public QWidget
{
Q_OBJECT
public:
ChartPlotMenu(QWidget *parent = nullptr);
~ChartPlotMenu();
protected:
void InitMenu();
bool IsRuning();
signals:
private:
Ui::ChartPlotMenuClass ui;
};

View File

@ -1,135 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ChartPlotMenuClass</class>
<widget class="QWidget" name="ChartPlotMenuClass">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>859</width>
<height>63</height>
</rect>
</property>
<property name="windowTitle">
<string>ChartPlotMenu</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QToolButton" name="toolButton_5">
<property name="visible">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>60</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>Wave文件</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="toolButton_4">
<property name="visible">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>60</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>Report文件</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="toolButton_3">
<property name="visible">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>60</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>RD文件</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="toolButton_2">
<property name="visible">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>60</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>Matlab文件</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="toolButton_6">
<property name="visible">
<bool>true</bool>
</property>
<property name="minimumSize">
<size>
<width>60</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>Lamp文件</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="toolButton">
<property name="visible">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>60</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>Run Simu</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>

View File

@ -64,6 +64,21 @@ void PropertyBrowser::OnWorkSpaceChange(const QVariant& value) {
currentWorkspace_ = workspace;
QObject::connect(currentWorkspace_, &WorkSpace::FilesChanged,
this, &PropertyBrowser::OnWorkspaceFilesChanged);
// Mount first curve entry if available
auto curves = currentWorkspace_->GetFileEntries(FileEntryType::Curve);
if (!curves.empty()) {
auto entry = curves.front();
if (entry) {
auto curve = entry->AsCurve();
if (curve) {
QtProperty* cprop = curveEntryManager_->addProperty(tr("CurveEntry"));
QCurveEntryAttribute attr(curve);
curveEntryManager_->setValue(cprop, attr);
addProperty(cprop, tr("CurveEntry"));
}
}
}
}
void PropertyBrowser::OnEntityChange(const QVariant& value) {
@ -139,6 +154,7 @@ void PropertyBrowser::InitPropertyManager() {
modelBaseManager_ = new QtModelBasePropertyManager(this);
workSpaceManager_ = new QtWorkspacePropertyManager(this);
entityManager_ = new QtEntityPropertyManager(this);
curveEntryManager_ = new QtCurveEntryPropertyManager(this);
QtDoubleSpinBoxFactory* doubleSpinBoxFactory = new QtDoubleSpinBoxFactory(this);
QtCheckBoxFactory* checkBoxFactory = new QtCheckBoxFactory(this);
@ -146,6 +162,7 @@ void PropertyBrowser::InitPropertyManager() {
QtLineEditFactory* lineEditFactory = new QtLineEditFactory(this);
QtEnumEditorFactory* comboBoxFactory = new QtEnumEditorFactory(this);
QtFilePathFactory* filePathFactory = new QtFilePathFactory(this);
QtColorEditorFactory* colorFactory = new QtColorEditorFactory(this);
//QtTransfromEditorFactory* transformFactory = new QtTransfromEditorFactory(this);
browser_->setFactoryForManager(intManager_, spinBoxFactory);
@ -173,16 +190,48 @@ void PropertyBrowser::InitPropertyManager() {
browser_->setFactoryForManager(
entityManager_->subTransfromProperyManager()->subVec3SPropertyManager()->subDoublePropertyManager(),
doubleSpinBoxFactory);
// Curve entry sub editors
browser_->setFactoryForManager(curveEntryManager_->subStringProperyManager(), lineEditFactory);
browser_->setFactoryForManager(curveEntryManager_->subEnumProperyManager(), comboBoxFactory);
browser_->setFactoryForManager(curveEntryManager_->subIntProperyManager(), spinBoxFactory);
browser_->setFactoryForManager(curveEntryManager_->subDoubleProperyManager(), doubleSpinBoxFactory);
browser_->setFactoryForManager(curveEntryManager_->subColorProperyManager(), colorFactory);
}
void PropertyBrowser::OnWorkspaceFilesChanged(FileEntryType /*type*/, std::shared_ptr<FileEntry> /*fileEntry*/) {
void PropertyBrowser::OnWorkspaceFilesChanged(FileEntryType type, std::shared_ptr<FileEntry> fileEntry) {
if (!currentWorkspace_) return;
auto it = idToProperty_.find(tr("WorkSpace"));
if (it == idToProperty_.end()) return;
QtProperty* property = it.value();
QWorkspaceAttribute worksapceAttribute(currentWorkspace_);
// Refresh the full workspace property tree to reflect new counts/paths
workSpaceManager_->setValue(property, worksapceAttribute);
// Refresh workspace group
{
auto it = idToProperty_.find(tr("WorkSpace"));
if (it != idToProperty_.end()) {
QtProperty* property = it.value();
QWorkspaceAttribute worksapceAttribute(currentWorkspace_);
workSpaceManager_->setValue(property, worksapceAttribute);
}
}
// Refresh curve entry when curve files mutate
if (type == FileEntryType::Curve) {
auto curves = currentWorkspace_->GetFileEntries(FileEntryType::Curve);
QCurveEntryAttribute attr(nullptr);
if (!curves.empty()) {
auto entry = curves.front();
if (entry) {
auto curve = entry->AsCurve();
if (curve) attr = QCurveEntryAttribute(curve);
}
}
auto it = idToProperty_.find(tr("CurveEntry"));
if (it != idToProperty_.end()) {
curveEntryManager_->setValue(it.value(), attr);
} else if (attr.GetEntry()) {
QtProperty* prop = curveEntryManager_->addProperty(tr("CurveEntry"));
curveEntryManager_->setValue(prop, attr);
addProperty(prop, tr("CurveEntry"));
}
}
}
void PropertyBrowser::InitComponentPropertyManager() {

View File

@ -45,6 +45,7 @@ private:
class QtModelBasePropertyManager* modelBaseManager_{ nullptr };
class QtWorkspacePropertyManager* workSpaceManager_{ nullptr };
class QtEntityPropertyManager* entityManager_{ nullptr };
class QtCurveEntryPropertyManager* curveEntryManager_{ nullptr };
QMap<QtProperty*, QString> propertyToId_;
QMap<QString, QtProperty*> idToProperty_;

View File

@ -7976,6 +7976,15 @@ public:
QMap<const QtProperty*, QVector<QtProperty*>> m_properyToPolarPaths;
QMap<const QtProperty*, QtProperty*> m_polarPathToPropery;
QMap<const QtProperty*, int> m_polarPathIndex;
// Image
QMap<const QtProperty*, QtProperty*> m_properyToImageGroup;
QMap<const QtProperty*, QtProperty*> m_imageGroupToPropery;
QMap<const QtProperty*, QtProperty*> m_properyToImageCount;
QMap<const QtProperty*, QtProperty*> m_imageCountToPropery;
QMap<const QtProperty*, QVector<QtProperty*>> m_properyToImagePaths;
QMap<const QtProperty*, QtProperty*> m_imagePathToPropery;
QMap<const QtProperty*, int> m_imagePathIndex;
};
void QtWorkspacePropertyManagerPrivate::slotStringChanged(QtProperty* property, QString value) {
@ -8024,7 +8033,12 @@ void QtWorkspacePropertyManagerPrivate::slotStringChanged(QtProperty* property,
int idx = m_polarPathIndex.value(property, 0);
c.SetFileEntryPath(FileEntryType::Polar, idx, value);
q_ptr->setValue(prop, c);
}
} else if (QtProperty* prop = m_imagePathToPropery.value(property, 0)) {
QWorkspaceAttribute c = m_values[prop];
int idx = m_imagePathIndex.value(property, 0);
c.SetFileEntryPath(FileEntryType::Image, idx, value);
q_ptr->setValue(prop, c);
}
}
void QtWorkspacePropertyManagerPrivate::slotIntChanged(QtProperty* property, int value) {
@ -8080,6 +8094,7 @@ void QtWorkspacePropertyManagerPrivate::slotIntChanged(QtProperty* property, int
handleType(FileEntryType::Table, m_tableCountToPropery, m_properyToTablePaths, m_tablePathToPropery, m_tablePathIndex, m_properyToTableGroup);
handleType(FileEntryType::Light, m_lightCountToPropery, m_properyToLightPaths, m_lightPathToPropery, m_lightPathIndex, m_properyToLightGroup);
handleType(FileEntryType::Polar, m_polarCountToPropery, m_properyToPolarPaths, m_polarPathToPropery, m_polarPathIndex, m_properyToPolarGroup);
handleType(FileEntryType::Image, m_imageCountToPropery, m_properyToImagePaths, m_imagePathToPropery, m_imagePathIndex, m_properyToImageGroup);
}
void QtWorkspacePropertyManagerPrivate::slotPropertyDestroyed(QtProperty* property) {
@ -8241,6 +8256,7 @@ void QtWorkspacePropertyManager::setValue(QtProperty* property, const QWorkspace
case FileEntryType::Surface: title = QObject::tr("Surface[%1]").arg(i + 1); break;
case FileEntryType::Table: title = QObject::tr("Table[%1]").arg(i + 1); break;
case FileEntryType::Light: title = QObject::tr("Light[%1]").arg(i + 1); break;
case FileEntryType::Image: title = QObject::tr("Image[%1]").arg(i + 1); break;
}
p->setPropertyName(title);
group->addSubProperty(p);
@ -8269,6 +8285,7 @@ void QtWorkspacePropertyManager::setValue(QtProperty* property, const QWorkspace
syncGroup(FileEntryType::Table, d_ptr->m_properyToTableGroup, d_ptr->m_properyToTableCount, d_ptr->m_properyToTablePaths, d_ptr->m_tablePathToPropery, d_ptr->m_tablePathIndex);
syncGroup(FileEntryType::Light, d_ptr->m_properyToLightGroup, d_ptr->m_properyToLightCount, d_ptr->m_properyToLightPaths, d_ptr->m_lightPathToPropery, d_ptr->m_lightPathIndex);
syncGroup(FileEntryType::Polar, d_ptr->m_properyToPolarGroup, d_ptr->m_properyToPolarCount, d_ptr->m_properyToPolarPaths, d_ptr->m_polarPathToPropery, d_ptr->m_polarPathIndex);
syncGroup(FileEntryType::Image, d_ptr->m_properyToImageGroup, d_ptr->m_properyToImageCount, d_ptr->m_properyToImagePaths, d_ptr->m_imagePathToPropery, d_ptr->m_imagePathIndex);
emit propertyChanged(property);
emit valueChanged(property, value);
@ -8349,6 +8366,7 @@ void QtWorkspacePropertyManager::initializeProperty(QtProperty* property) {
case FileEntryType::Surface: title = tr("Surface[%1]").arg(i + 1); break;
case FileEntryType::Table: title = tr("Table[%1]").arg(i + 1); break;
case FileEntryType::Light: title = tr("Light[%1]").arg(i + 1); break;
case FileEntryType::Image: title = tr("Image[%1]").arg(i + 1); break;
}
p->setPropertyName(title);
d_ptr->m_filesProperyManager->setValueOnly(p, val.GetFileEntryAbsPath(type, i));
@ -8374,6 +8392,9 @@ void QtWorkspacePropertyManager::initializeProperty(QtProperty* property) {
addGroup(FileEntryType::Polar, tr("Polars"), d_ptr->m_properyToPolarGroup, d_ptr->m_polarGroupToPropery,
d_ptr->m_properyToPolarCount, d_ptr->m_polarCountToPropery,
d_ptr->m_properyToPolarPaths, d_ptr->m_polarPathToPropery, d_ptr->m_polarPathIndex);
addGroup(FileEntryType::Image, tr("Images"), d_ptr->m_properyToImageGroup, d_ptr->m_imageGroupToPropery,
d_ptr->m_properyToImageCount, d_ptr->m_imageCountToPropery,
d_ptr->m_properyToImagePaths, d_ptr->m_imagePathToPropery, d_ptr->m_imagePathIndex);
}
/*!
@ -8488,6 +8509,489 @@ void QtWorkspacePropertyManager::uninitializeProperty(QtProperty* property) {
cleanupGroup(d_ptr->m_properyToPolarGroup, d_ptr->m_polarGroupToPropery,
d_ptr->m_properyToPolarCount, d_ptr->m_polarCountToPropery,
d_ptr->m_properyToPolarPaths, d_ptr->m_polarPathToPropery, d_ptr->m_polarPathIndex);
cleanupGroup(d_ptr->m_properyToImageGroup, d_ptr->m_imageGroupToPropery,
d_ptr->m_properyToImageCount, d_ptr->m_imageCountToPropery,
d_ptr->m_properyToImagePaths, d_ptr->m_imagePathToPropery, d_ptr->m_imagePathIndex);
}
#pragma endregion
// QtCurveEntryPropertyManager
#pragma region QtCurveEntryPropertyManager
class QtCurveEntryPropertyManagerPrivate {
QtCurveEntryPropertyManager* q_ptr;
Q_DECLARE_PUBLIC(QtCurveEntryPropertyManager)
public:
void slotStringChanged(QtProperty* property, QString value);
void slotEnumChanged(QtProperty* property, int value);
void slotIntChanged(QtProperty* property, int value);
void slotDoubleChanged(QtProperty* property, double value);
void slotColorChanged(QtProperty* property, const QColor& value);
void slotPropertyDestroyed(QtProperty* property);
typedef QMap<const QtProperty*, QCurveEntryAttribute> PropertyValueMap;
PropertyValueMap m_values;
QtStringPropertyManager* m_stringProperyManager{ nullptr };
QtEnumPropertyManager* m_enumProperyManager{ nullptr };
QtIntPropertyManager* m_intProperyManager{ nullptr };
QtDoublePropertyManager* m_doubleProperyManager{ nullptr };
QtColorPropertyManager* m_colorProperyManager{ nullptr };
QtGroupPropertyManager* m_groupProperyManager{ nullptr };
// Top-level mappings
QMap<const QtProperty*, QtProperty*> m_properyToName;
QMap<const QtProperty*, QtProperty*> m_nameToPropery;
QMap<const QtProperty*, QtProperty*> m_properyToChartType;
QMap<const QtProperty*, QtProperty*> m_chartTypeToPropery;
QMap<const QtProperty*, QtProperty*> m_properyToCurvesGroup;
QMap<const QtProperty*, QtProperty*> m_curvesGroupToPropery;
QMap<const QtProperty*, QtProperty*> m_properyToCurveCount;
QMap<const QtProperty*, QtProperty*> m_curveCountToPropery;
// Per-curve sub-properties
struct CurveSubProps {
QVector<QtProperty*> names;
QVector<QtProperty*> colors;
QVector<QtProperty*> waveStarts;
QVector<QtProperty*> waveStops;
QVector<QtProperty*> reportXs;
QVector<QtProperty*> reportYs;
};
QMap<const QtProperty*, CurveSubProps> m_curveProps;
// Reverse lookup for per-curve properties
QMap<const QtProperty*, QtProperty*> m_curveNameToRoot;
QMap<const QtProperty*, int> m_curveNameIndex;
QMap<const QtProperty*, QtProperty*> m_curveColorToRoot;
QMap<const QtProperty*, int> m_curveColorIndex;
QMap<const QtProperty*, QtProperty*> m_waveStartToRoot;
QMap<const QtProperty*, int> m_waveStartIndex;
QMap<const QtProperty*, QtProperty*> m_waveStopToRoot;
QMap<const QtProperty*, int> m_waveStopIndex;
QMap<const QtProperty*, QtProperty*> m_reportXToRoot;
QMap<const QtProperty*, int> m_reportXIndex;
QMap<const QtProperty*, QtProperty*> m_reportYToRoot;
QMap<const QtProperty*, int> m_reportYIndex;
};
void QtCurveEntryPropertyManagerPrivate::slotStringChanged(QtProperty* property, QString value) {
if (QtProperty* root = m_nameToPropery.value(property, nullptr)) {
QCurveEntryAttribute c = m_values[root];
c.SetName(value);
q_ptr->setValue(root, c);
} else if (QtProperty* root2 = m_curveNameToRoot.value(property, nullptr)) {
QCurveEntryAttribute c = m_values[root2];
int idx = m_curveNameIndex.value(property, 0);
c.SetCurveName(idx, value);
q_ptr->setValue(root2, c);
}
}
void QtCurveEntryPropertyManagerPrivate::slotEnumChanged(QtProperty* property, int value) {
if (QtProperty* root = m_chartTypeToPropery.value(property, nullptr)) {
QCurveEntryAttribute c = m_values[root];
ChartType t = ChartType::Wave;
if (value == 1) t = ChartType::Report;
c.SetChartType(t);
q_ptr->setValue(root, c);
}
}
void QtCurveEntryPropertyManagerPrivate::slotIntChanged(QtProperty* property, int value) {
if (QtProperty* root = m_curveCountToPropery.value(property, nullptr)) {
// Adjust per-curve subproperties to match new count
CurveSubProps& subs = m_curveProps[root];
int current = subs.names.size();
QtProperty* group = m_properyToCurvesGroup.value(root, nullptr);
if (value > current) {
for (int i = current; i < value; ++i) {
// Create a subgroup label
// Name
QtProperty* nameProp = m_stringProperyManager->addProperty();
nameProp->setPropertyName(QObject::tr("Curve[%1] Name").arg(i + 1));
group->addSubProperty(nameProp);
subs.names.append(nameProp);
m_curveNameToRoot[nameProp] = root;
m_curveNameIndex[nameProp] = i;
// Color
QtProperty* colorProp = m_colorProperyManager->addProperty();
colorProp->setPropertyName(QObject::tr("Curve[%1] Color").arg(i + 1));
group->addSubProperty(colorProp);
subs.colors.append(colorProp);
m_curveColorToRoot[colorProp] = root;
m_curveColorIndex[colorProp] = i;
// WaveStart
QtProperty* wsProp = m_intProperyManager->addProperty();
wsProp->setPropertyName(QObject::tr("Curve[%1] WaveStart").arg(i + 1));
group->addSubProperty(wsProp);
subs.waveStarts.append(wsProp);
m_waveStartToRoot[wsProp] = root;
m_waveStartIndex[wsProp] = i;
// WaveStop
QtProperty* weProp = m_intProperyManager->addProperty();
weProp->setPropertyName(QObject::tr("Curve[%1] WaveStop").arg(i + 1));
group->addSubProperty(weProp);
subs.waveStops.append(weProp);
m_waveStopToRoot[weProp] = root;
m_waveStopIndex[weProp] = i;
// ReportX
QtProperty* rxProp = m_doubleProperyManager->addProperty();
rxProp->setPropertyName(QObject::tr("Curve[%1] ReportX").arg(i + 1));
group->addSubProperty(rxProp);
subs.reportXs.append(rxProp);
m_reportXToRoot[rxProp] = root;
m_reportXIndex[rxProp] = i;
// ReportY
QtProperty* ryProp = m_doubleProperyManager->addProperty();
ryProp->setPropertyName(QObject::tr("Curve[%1] ReportY").arg(i + 1));
group->addSubProperty(ryProp);
subs.reportYs.append(ryProp);
m_reportYToRoot[ryProp] = root;
m_reportYIndex[ryProp] = i;
}
} else if (value < current) {
for (int i = current - 1; i >= value; --i) {
auto eraseProp = [&](QtProperty* p, QMap<const QtProperty*, QtProperty*>& toRoot, QMap<const QtProperty*, int>& toIndex) {
toIndex.remove(p);
toRoot.remove(p);
delete p;
};
eraseProp(subs.names.at(i), m_curveNameToRoot, m_curveNameIndex);
eraseProp(subs.colors.at(i), m_curveColorToRoot, m_curveColorIndex);
eraseProp(subs.waveStarts.at(i), m_waveStartToRoot, m_waveStartIndex);
eraseProp(subs.waveStops.at(i), m_waveStopToRoot, m_waveStopIndex);
eraseProp(subs.reportXs.at(i), m_reportXToRoot, m_reportXIndex);
eraseProp(subs.reportYs.at(i), m_reportYToRoot, m_reportYIndex);
subs.names.remove(i);
subs.colors.remove(i);
subs.waveStarts.remove(i);
subs.waveStops.remove(i);
subs.reportXs.remove(i);
subs.reportYs.remove(i);
}
}
// Update underlying model
QCurveEntryAttribute c = m_values[root];
c.SetCurveCount(value);
q_ptr->setValue(root, c);
} else if (QtProperty* root2 = m_waveStartToRoot.value(property, nullptr)) {
QCurveEntryAttribute c = m_values[root2];
int idx = m_waveStartIndex.value(property, 0);
c.SetWaveStart(idx, value);
q_ptr->setValue(root2, c);
} else if (QtProperty* root3 = m_waveStopToRoot.value(property, nullptr)) {
QCurveEntryAttribute c = m_values[root3];
int idx = m_waveStopIndex.value(property, 0);
c.SetWaveStop(idx, value);
q_ptr->setValue(root3, c);
}
}
void QtCurveEntryPropertyManagerPrivate::slotDoubleChanged(QtProperty* property, double value) {
if (QtProperty* root = m_reportXToRoot.value(property, nullptr)) {
QCurveEntryAttribute c = m_values[root];
int idx = m_reportXIndex.value(property, 0);
c.SetReportX(idx, value);
q_ptr->setValue(root, c);
} else if (QtProperty* root2 = m_reportYToRoot.value(property, nullptr)) {
QCurveEntryAttribute c = m_values[root2];
int idx = m_reportYIndex.value(property, 0);
c.SetReportY(idx, value);
q_ptr->setValue(root2, c);
}
}
void QtCurveEntryPropertyManagerPrivate::slotColorChanged(QtProperty* property, const QColor& value) {
if (QtProperty* root = m_curveColorToRoot.value(property, nullptr)) {
QCurveEntryAttribute c = m_values[root];
int idx = m_curveColorIndex.value(property, 0);
c.SetCurveColor(idx, value);
q_ptr->setValue(root, c);
}
}
void QtCurveEntryPropertyManagerPrivate::slotPropertyDestroyed(QtProperty* property) {
if (QtProperty* subProp = m_nameToPropery.value(property, nullptr)) {
m_nameToPropery[subProp] = 0;
m_nameToPropery.remove(property);
} else if (QtProperty* subProp = m_chartTypeToPropery.value(property, nullptr)) {
m_chartTypeToPropery[subProp] = 0;
m_chartTypeToPropery.remove(property);
}
}
QtCurveEntryPropertyManager::QtCurveEntryPropertyManager(QObject* parent)
: QtAbstractPropertyManager(parent), d_ptr(new QtCurveEntryPropertyManagerPrivate) {
d_ptr->q_ptr = this;
d_ptr->m_stringProperyManager = new QtStringPropertyManager(this);
connect(d_ptr->m_stringProperyManager, SIGNAL(valueChanged(QtProperty*, QString)),
this, SLOT(slotStringChanged(QtProperty*, QString)));
d_ptr->m_enumProperyManager = new QtEnumPropertyManager(this);
connect(d_ptr->m_enumProperyManager, SIGNAL(valueChanged(QtProperty*, int)),
this, SLOT(slotEnumChanged(QtProperty*, int)));
d_ptr->m_intProperyManager = new QtIntPropertyManager(this);
connect(d_ptr->m_intProperyManager, SIGNAL(valueChanged(QtProperty*, int)),
this, SLOT(slotIntChanged(QtProperty*, int)));
d_ptr->m_doubleProperyManager = new QtDoublePropertyManager(this);
connect(d_ptr->m_doubleProperyManager, SIGNAL(valueChanged(QtProperty*, double)),
this, SLOT(slotDoubleChanged(QtProperty*, double)));
d_ptr->m_colorProperyManager = new QtColorPropertyManager(this);
connect(d_ptr->m_colorProperyManager, SIGNAL(valueChanged(QtProperty*, const QColor&)),
this, SLOT(slotColorChanged(QtProperty*, const QColor&)));
d_ptr->m_groupProperyManager = new QtGroupPropertyManager(this);
}
QtCurveEntryPropertyManager::~QtCurveEntryPropertyManager() {
clear();
}
QCurveEntryAttribute QtCurveEntryPropertyManager::value(const QtProperty* property) const {
return d_ptr->m_values.value(property, QCurveEntryAttribute());
}
QtStringPropertyManager* QtCurveEntryPropertyManager::subStringProperyManager() const { return d_ptr->m_stringProperyManager; }
QtEnumPropertyManager* QtCurveEntryPropertyManager::subEnumProperyManager() const { return d_ptr->m_enumProperyManager; }
QtIntPropertyManager* QtCurveEntryPropertyManager::subIntProperyManager() const { return d_ptr->m_intProperyManager; }
QtDoublePropertyManager* QtCurveEntryPropertyManager::subDoubleProperyManager() const { return d_ptr->m_doubleProperyManager; }
QtColorPropertyManager* QtCurveEntryPropertyManager::subColorProperyManager() const { return d_ptr->m_colorProperyManager; }
QtGroupPropertyManager* QtCurveEntryPropertyManager::subGroupProperyManager() const { return d_ptr->m_groupProperyManager; }
QString QtCurveEntryPropertyManager::valueText(const QtProperty* property) const {
const QtCurveEntryPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
if (it == d_ptr->m_values.constEnd()) return QString();
return QString("curve entry");
}
QIcon QtCurveEntryPropertyManager::valueIcon(const QtProperty* /*property*/) const {
return QIcon();
}
void QtCurveEntryPropertyManager::setValue(QtProperty* property, const QCurveEntryAttribute& val) {
const QtCurveEntryPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
if (it == d_ptr->m_values.end()) return;
if (it.value() == val) return;
it.value() = val;
// Update top-level subproperties
d_ptr->m_stringProperyManager->setValue(d_ptr->m_properyToName[property], val.GetName());
// ChartType enum: 0 Wave, 1 Report
int enumVal = (val.GetChartType() == ChartType::Report) ? 1 : 0;
d_ptr->m_enumProperyManager->setValue(d_ptr->m_properyToChartType[property], enumVal);
// Sync curves group
QtProperty* group = d_ptr->m_properyToCurvesGroup.value(property, nullptr);
if (group) {
int count = val.GetCurveCount();
QtProperty* countProp = d_ptr->m_properyToCurveCount.value(property, nullptr);
if (countProp) d_ptr->m_intProperyManager->setValueOnly(countProp, count);
// Resize child arrays
QtCurveEntryPropertyManagerPrivate::CurveSubProps& subs = d_ptr->m_curveProps[property];
int current = subs.names.size();
if (count > current) {
for (int i = current; i < count; ++i) {
// Name
QtProperty* nameProp = d_ptr->m_stringProperyManager->addProperty();
nameProp->setPropertyName(tr("Curve[%1] Name").arg(i + 1));
group->addSubProperty(nameProp);
subs.names.append(nameProp);
d_ptr->m_curveNameToRoot[nameProp] = property;
d_ptr->m_curveNameIndex[nameProp] = i;
// Color
QtProperty* colorProp = d_ptr->m_colorProperyManager->addProperty();
colorProp->setPropertyName(tr("Curve[%1] Color").arg(i + 1));
group->addSubProperty(colorProp);
subs.colors.append(colorProp);
d_ptr->m_curveColorToRoot[colorProp] = property;
d_ptr->m_curveColorIndex[colorProp] = i;
// WaveStart
QtProperty* wsProp = d_ptr->m_intProperyManager->addProperty();
wsProp->setPropertyName(tr("Curve[%1] WaveStart").arg(i + 1));
group->addSubProperty(wsProp);
subs.waveStarts.append(wsProp);
d_ptr->m_waveStartToRoot[wsProp] = property;
d_ptr->m_waveStartIndex[wsProp] = i;
// WaveStop
QtProperty* weProp = d_ptr->m_intProperyManager->addProperty();
weProp->setPropertyName(tr("Curve[%1] WaveStop").arg(i + 1));
group->addSubProperty(weProp);
subs.waveStops.append(weProp);
d_ptr->m_waveStopToRoot[weProp] = property;
d_ptr->m_waveStopIndex[weProp] = i;
// ReportX
QtProperty* rxProp = d_ptr->m_doubleProperyManager->addProperty();
rxProp->setPropertyName(tr("Curve[%1] ReportX").arg(i + 1));
group->addSubProperty(rxProp);
subs.reportXs.append(rxProp);
d_ptr->m_reportXToRoot[rxProp] = property;
d_ptr->m_reportXIndex[rxProp] = i;
// ReportY
QtProperty* ryProp = d_ptr->m_doubleProperyManager->addProperty();
ryProp->setPropertyName(tr("Curve[%1] ReportY").arg(i + 1));
group->addSubProperty(ryProp);
subs.reportYs.append(ryProp);
d_ptr->m_reportYToRoot[ryProp] = property;
d_ptr->m_reportYIndex[ryProp] = i;
}
} else if (count < current) {
for (int i = current - 1; i >= count; --i) {
auto eraseProp = [&](QtProperty* p, QMap<const QtProperty*, QtProperty*>& toRoot, QMap<const QtProperty*, int>& toIndex) {
toIndex.remove(p);
toRoot.remove(p);
delete p;
};
eraseProp(subs.names.at(i), d_ptr->m_curveNameToRoot, d_ptr->m_curveNameIndex);
eraseProp(subs.colors.at(i), d_ptr->m_curveColorToRoot, d_ptr->m_curveColorIndex);
eraseProp(subs.waveStarts.at(i), d_ptr->m_waveStartToRoot, d_ptr->m_waveStartIndex);
eraseProp(subs.waveStops.at(i), d_ptr->m_waveStopToRoot, d_ptr->m_waveStopIndex);
eraseProp(subs.reportXs.at(i), d_ptr->m_reportXToRoot, d_ptr->m_reportXIndex);
eraseProp(subs.reportYs.at(i), d_ptr->m_reportYToRoot, d_ptr->m_reportYIndex);
subs.names.remove(i);
subs.colors.remove(i);
subs.waveStarts.remove(i);
subs.waveStops.remove(i);
subs.reportXs.remove(i);
subs.reportYs.remove(i);
}
}
// Set values from attribute
for (int i = 0; i < count; ++i) {
d_ptr->m_stringProperyManager->setValueOnly(subs.names.at(i), val.GetCurveName(i));
d_ptr->m_colorProperyManager->setValue(subs.colors.at(i), val.GetCurveColor(i));
d_ptr->m_intProperyManager->setValueOnly(subs.waveStarts.at(i), val.GetWaveStart(i));
d_ptr->m_intProperyManager->setValueOnly(subs.waveStops.at(i), val.GetWaveStop(i));
d_ptr->m_doubleProperyManager->setValueOnly(subs.reportXs.at(i), val.GetReportX(i));
d_ptr->m_doubleProperyManager->setValueOnly(subs.reportYs.at(i), val.GetReportY(i));
}
}
emit propertyChanged(property);
emit valueChanged(property, val);
}
void QtCurveEntryPropertyManager::initializeProperty(QtProperty* property) {
QCurveEntryAttribute val;
d_ptr->m_values[property] = val;
// Name
QtProperty* prop = d_ptr->m_stringProperyManager->addProperty();
prop->setPropertyName(tr("Name"));
d_ptr->m_stringProperyManager->setValueOnly(prop, val.GetName());
d_ptr->m_properyToName[property] = prop;
d_ptr->m_nameToPropery[prop] = property;
property->addSubProperty(prop);
// ChartType enum
prop = d_ptr->m_enumProperyManager->addProperty();
prop->setPropertyName(tr("ChartType"));
d_ptr->m_enumProperyManager->setEnumNames(prop, QStringList() << tr("Wave") << tr("Report"));
d_ptr->m_enumProperyManager->setValue(prop, 0);
d_ptr->m_properyToChartType[property] = prop;
d_ptr->m_chartTypeToPropery[prop] = property;
property->addSubProperty(prop);
// Curves group
QtProperty* group = d_ptr->m_groupProperyManager->addProperty();
group->setPropertyName(tr("Curves"));
property->addSubProperty(group);
d_ptr->m_properyToCurvesGroup[property] = group;
d_ptr->m_curvesGroupToPropery[group] = property;
// Count
QtProperty* countProp = d_ptr->m_intProperyManager->addProperty();
countProp->setPropertyName(tr("Count"));
d_ptr->m_intProperyManager->setRange(countProp, 0, 1024);
d_ptr->m_intProperyManager->setValueOnly(countProp, val.GetCurveCount());
d_ptr->m_properyToCurveCount[property] = countProp;
d_ptr->m_curveCountToPropery[countProp] = property;
group->addSubProperty(countProp);
// Initialize existing curves if any
QtCurveEntryPropertyManagerPrivate::CurveSubProps& subs = d_ptr->m_curveProps[property];
int count = val.GetCurveCount();
for (int i = 0; i < count; ++i) {
QtProperty* nameProp = d_ptr->m_stringProperyManager->addProperty();
nameProp->setPropertyName(tr("Curve[%1] Name").arg(i + 1));
d_ptr->m_stringProperyManager->setValueOnly(nameProp, val.GetCurveName(i));
group->addSubProperty(nameProp);
subs.names.append(nameProp);
d_ptr->m_curveNameToRoot[nameProp] = property;
d_ptr->m_curveNameIndex[nameProp] = i;
QtProperty* colorProp = d_ptr->m_colorProperyManager->addProperty();
colorProp->setPropertyName(tr("Curve[%1] Color").arg(i + 1));
d_ptr->m_colorProperyManager->setValue(colorProp, val.GetCurveColor(i));
group->addSubProperty(colorProp);
subs.colors.append(colorProp);
d_ptr->m_curveColorToRoot[colorProp] = property;
d_ptr->m_curveColorIndex[colorProp] = i;
QtProperty* wsProp = d_ptr->m_intProperyManager->addProperty();
wsProp->setPropertyName(tr("Curve[%1] WaveStart").arg(i + 1));
d_ptr->m_intProperyManager->setValueOnly(wsProp, val.GetWaveStart(i));
group->addSubProperty(wsProp);
subs.waveStarts.append(wsProp);
d_ptr->m_waveStartToRoot[wsProp] = property;
d_ptr->m_waveStartIndex[wsProp] = i;
QtProperty* weProp = d_ptr->m_intProperyManager->addProperty();
weProp->setPropertyName(tr("Curve[%1] WaveStop").arg(i + 1));
d_ptr->m_intProperyManager->setValueOnly(weProp, val.GetWaveStop(i));
group->addSubProperty(weProp);
subs.waveStops.append(weProp);
d_ptr->m_waveStopToRoot[weProp] = property;
d_ptr->m_waveStopIndex[weProp] = i;
QtProperty* rxProp = d_ptr->m_doubleProperyManager->addProperty();
rxProp->setPropertyName(tr("Curve[%1] ReportX").arg(i + 1));
d_ptr->m_doubleProperyManager->setValueOnly(rxProp, val.GetReportX(i));
group->addSubProperty(rxProp);
subs.reportXs.append(rxProp);
d_ptr->m_reportXToRoot[rxProp] = property;
d_ptr->m_reportXIndex[rxProp] = i;
QtProperty* ryProp = d_ptr->m_doubleProperyManager->addProperty();
ryProp->setPropertyName(tr("Curve[%1] ReportY").arg(i + 1));
d_ptr->m_doubleProperyManager->setValueOnly(ryProp, val.GetReportY(i));
group->addSubProperty(ryProp);
subs.reportYs.append(ryProp);
d_ptr->m_reportYToRoot[ryProp] = property;
d_ptr->m_reportYIndex[ryProp] = i;
}
}
void QtCurveEntryPropertyManager::uninitializeProperty(QtProperty* property) {
// Cleanup top-level
QtProperty* prop = d_ptr->m_nameToPropery[property];
if (prop) { d_ptr->m_nameToPropery.remove(prop); delete prop; }
d_ptr->m_properyToName.remove(property);
prop = d_ptr->m_chartTypeToPropery[property];
if (prop) { d_ptr->m_chartTypeToPropery.remove(prop); delete prop; }
d_ptr->m_properyToChartType.remove(property);
// Curves
QtProperty* group = d_ptr->m_properyToCurvesGroup.value(property, nullptr);
QtCurveEntryPropertyManagerPrivate::CurveSubProps& subs = d_ptr->m_curveProps[property];
auto eraseProp = [&](QtProperty* p, QMap<const QtProperty*, QtProperty*>& toRoot, QMap<const QtProperty*, int>& toIndex) {
toIndex.remove(p);
toRoot.remove(p);
delete p;
};
for (QtProperty* p : subs.names) eraseProp(p, d_ptr->m_curveNameToRoot, d_ptr->m_curveNameIndex);
for (QtProperty* p : subs.colors) eraseProp(p, d_ptr->m_curveColorToRoot, d_ptr->m_curveColorIndex);
for (QtProperty* p : subs.waveStarts) eraseProp(p, d_ptr->m_waveStartToRoot, d_ptr->m_waveStartIndex);
for (QtProperty* p : subs.waveStops) eraseProp(p, d_ptr->m_waveStopToRoot, d_ptr->m_waveStopIndex);
for (QtProperty* p : subs.reportXs) eraseProp(p, d_ptr->m_reportXToRoot, d_ptr->m_reportXIndex);
for (QtProperty* p : subs.reportYs) eraseProp(p, d_ptr->m_reportYToRoot, d_ptr->m_reportYIndex);
subs.names.clear(); subs.colors.clear(); subs.waveStarts.clear(); subs.waveStops.clear(); subs.reportXs.clear(); subs.reportYs.clear();
d_ptr->m_curveProps.remove(property);
QtProperty* countProp = d_ptr->m_properyToCurveCount.value(property, nullptr);
if (countProp) { d_ptr->m_curveCountToPropery.remove(countProp); d_ptr->m_properyToCurveCount.remove(property); delete countProp; }
if (group) { d_ptr->m_curvesGroupToPropery.remove(group); d_ptr->m_properyToCurvesGroup.remove(property); delete group; }
}
#pragma endregion

View File

@ -1050,6 +1050,49 @@ private:
#pragma endregion
#pragma region QtCurveEntryPropertyManager
class QtCurveEntryPropertyManagerPrivate;
class QtCurveEntryPropertyManager : public QtAbstractPropertyManager {
Q_OBJECT
public:
QtCurveEntryPropertyManager(QObject* parent = 0);
~QtCurveEntryPropertyManager();
QCurveEntryAttribute value(const QtProperty* property) const;
QtStringPropertyManager* subStringProperyManager() const;
QtEnumPropertyManager* subEnumProperyManager() const;
QtIntPropertyManager* subIntProperyManager() const;
QtDoublePropertyManager* subDoubleProperyManager() const;
QtColorPropertyManager* subColorProperyManager() const;
QtGroupPropertyManager* subGroupProperyManager() const;
public Q_SLOTS:
void setValue(QtProperty* property, const QCurveEntryAttribute& val);
Q_SIGNALS:
void valueChanged(QtProperty* property, const QCurveEntryAttribute& val);
protected:
QString valueText(const QtProperty* property) const override;
QIcon valueIcon(const QtProperty* property) const override;
void initializeProperty(QtProperty* property) override;
void uninitializeProperty(QtProperty* property) override;
private:
QScopedPointer<QtCurveEntryPropertyManagerPrivate> d_ptr;
Q_DECLARE_PRIVATE(QtCurveEntryPropertyManager)
Q_DISABLE_COPY_MOVE(QtCurveEntryPropertyManager)
Q_PRIVATE_SLOT(d_func(), void slotStringChanged(QtProperty*, QString))
Q_PRIVATE_SLOT(d_func(), void slotEnumChanged(QtProperty*, int))
Q_PRIVATE_SLOT(d_func(), void slotIntChanged(QtProperty*, int))
Q_PRIVATE_SLOT(d_func(), void slotDoubleChanged(QtProperty*, double))
Q_PRIVATE_SLOT(d_func(), void slotColorChanged(QtProperty*, const QColor&))
Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty*))
};
#pragma endregion
#pragma region QtEntityPropertyManager
class QtEntityPropertyManagerPrivate;

View File

@ -641,3 +641,169 @@ QDashedLineComponentAttribute& QDashedLineComponentAttribute::operator=(const QD
object_ = other.object_;
return *this;
}
// ---- QCurveEntryAttribute ----
QCurveEntryAttribute::QCurveEntryAttribute(FileEntryCurve* entry)
: entry_(entry) {
}
bool QCurveEntryAttribute::operator==(const QCurveEntryAttribute& other) {
return entry_ == other.entry_;
}
QCurveEntryAttribute& QCurveEntryAttribute::operator=(const QCurveEntryAttribute& other) {
entry_ = other.entry_;
return *this;
}
void QCurveEntryAttribute::SetName(const QString& name) {
if (!entry_) return;
entry_->SetName(name);
}
QString QCurveEntryAttribute::GetName() const {
if (!entry_) return QString();
return entry_->GetName();
}
void QCurveEntryAttribute::SetChartType(ChartType type) {
if (!entry_) return;
entry_->SetChartType(type);
}
ChartType QCurveEntryAttribute::GetChartType() const {
if (!entry_) return ChartType::Wave;
return entry_->GetChartType();
}
int QCurveEntryAttribute::GetCurveCount() const {
if (!entry_) return 0;
return entry_->GetCurveProperties().size();
}
void QCurveEntryAttribute::SetCurveCount(int count) {
if (!entry_) return;
if (count < 0) count = 0;
auto props = entry_->GetCurveProperties();
int current = props.size();
if (count == current) return;
if (count > current) {
// Append default curve properties
for (int i = current; i < count; ++i) {
FileEntryCurve::CurveProperty cp;
cp.name = QString("Curve %1").arg(i + 1);
cp.color = QColor(0, 255, 0);
cp.data.wave.start = 0;
cp.data.wave.stop = 0;
entry_->AddCurveProperty(cp);
}
} else {
// Remove surplus from the end
for (int i = current - 1; i >= count; --i) {
entry_->RemoveCurveProperty(i);
}
}
}
QString QCurveEntryAttribute::GetCurveName(int index) const {
if (!entry_) return QString();
const auto& cps = entry_->GetCurveProperties();
if (index < 0 || index >= cps.size()) return QString();
return cps.at(index).name;
}
void QCurveEntryAttribute::SetCurveName(int index, const QString& name) {
if (!entry_) return;
auto cps = entry_->GetCurveProperties();
if (index < 0 || index >= cps.size()) return;
auto cp = cps.at(index);
cp.name = name;
// overwrite by remove/add pattern
entry_->RemoveCurveProperty(index);
entry_->AddCurveProperty(cp);
}
QColor QCurveEntryAttribute::GetCurveColor(int index) const {
if (!entry_) return QColor();
const auto& cps = entry_->GetCurveProperties();
if (index < 0 || index >= cps.size()) return QColor();
return cps.at(index).color;
}
void QCurveEntryAttribute::SetCurveColor(int index, const QColor& color) {
if (!entry_) return;
auto cps = entry_->GetCurveProperties();
if (index < 0 || index >= cps.size()) return;
auto cp = cps.at(index);
cp.color = color;
entry_->RemoveCurveProperty(index);
entry_->AddCurveProperty(cp);
}
int QCurveEntryAttribute::GetWaveStart(int index) const {
if (!entry_) return 0;
const auto& cps = entry_->GetCurveProperties();
if (index < 0 || index >= cps.size()) return 0;
return cps.at(index).data.wave.start;
}
void QCurveEntryAttribute::SetWaveStart(int index, int start) {
if (!entry_) return;
auto cps = entry_->GetCurveProperties();
if (index < 0 || index >= cps.size()) return;
auto cp = cps.at(index);
cp.data.wave.start = start;
entry_->RemoveCurveProperty(index);
entry_->AddCurveProperty(cp);
}
int QCurveEntryAttribute::GetWaveStop(int index) const {
if (!entry_) return 0;
const auto& cps = entry_->GetCurveProperties();
if (index < 0 || index >= cps.size()) return 0;
return cps.at(index).data.wave.stop;
}
void QCurveEntryAttribute::SetWaveStop(int index, int stop) {
if (!entry_) return;
auto cps = entry_->GetCurveProperties();
if (index < 0 || index >= cps.size()) return;
auto cp = cps.at(index);
cp.data.wave.stop = stop;
entry_->RemoveCurveProperty(index);
entry_->AddCurveProperty(cp);
}
double QCurveEntryAttribute::GetReportX(int index) const {
if (!entry_) return 0.0;
const auto& cps = entry_->GetCurveProperties();
if (index < 0 || index >= cps.size()) return 0.0;
return cps.at(index).data.report.x;
}
void QCurveEntryAttribute::SetReportX(int index, double x) {
if (!entry_) return;
auto cps = entry_->GetCurveProperties();
if (index < 0 || index >= cps.size()) return;
auto cp = cps.at(index);
cp.data.report.x = x;
entry_->RemoveCurveProperty(index);
entry_->AddCurveProperty(cp);
}
double QCurveEntryAttribute::GetReportY(int index) const {
if (!entry_) return 0.0;
const auto& cps = entry_->GetCurveProperties();
if (index < 0 || index >= cps.size()) return 0.0;
return cps.at(index).data.report.y;
}
void QCurveEntryAttribute::SetReportY(int index, double y) {
if (!entry_) return;
auto cps = entry_->GetCurveProperties();
if (index < 0 || index >= cps.size()) return;
auto cp = cps.at(index);
cp.data.report.y = y;
entry_->RemoveCurveProperty(index);
entry_->AddCurveProperty(cp);
}

View File

@ -145,6 +145,54 @@ private:
class MeshComponent* object_{ nullptr };
};
// Curve entry attribute: wraps a single FileEntryCurve for item-level editing
class QCurveEntryAttribute {
public:
QCurveEntryAttribute() = default;
QCurveEntryAttribute(class FileEntryCurve* entry);
QCurveEntryAttribute& operator=(const QCurveEntryAttribute& other);
~QCurveEntryAttribute() = default;
bool operator== (const QCurveEntryAttribute& other);
// Display name of the chart entry
void SetName(const QString& name);
QString GetName() const;
// Chart type
void SetChartType(ChartType type);
ChartType GetChartType() const;
// Curve properties count
int GetCurveCount() const;
void SetCurveCount(int count);
// Per-curve basic fields
QString GetCurveName(int index) const;
void SetCurveName(int index, const QString& name);
QColor GetCurveColor(int index) const;
void SetCurveColor(int index, const QColor& color);
// Wave-specific fields
int GetWaveStart(int index) const;
void SetWaveStart(int index, int start);
int GetWaveStop(int index) const;
void SetWaveStop(int index, int stop);
// Report-specific fields
double GetReportX(int index) const;
void SetReportX(int index, double x);
double GetReportY(int index) const;
void SetReportY(int index, double y);
// Underlying entry access
class FileEntryCurve* GetEntry() const { return entry_; }
private:
class FileEntryCurve* entry_{ nullptr };
};
class QPathComponentAttribute {
public:
QPathComponentAttribute() = default;