modify file attribute

This commit is contained in:
brige 2025-11-03 00:36:16 +08:00
parent a6d8351546
commit 8c03d98849
7 changed files with 819 additions and 143 deletions

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;
// Refresh workspace group
{
auto it = idToProperty_.find(tr("WorkSpace"));
if (it == idToProperty_.end()) return;
if (it != idToProperty_.end()) {
QtProperty* property = it.value();
QWorkspaceAttribute worksapceAttribute(currentWorkspace_);
// Refresh the full workspace property tree to reflect new counts/paths
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,6 +8033,11 @@ 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);
}
}
@ -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;