From 8c03d9884925b8ae92d1f49e778313ff7b9be210 Mon Sep 17 00:00:00 2001 From: brige Date: Mon, 3 Nov 2025 00:36:16 +0800 Subject: [PATCH] modify file attribute --- src/ui/Menu/ChartPlotMenu.ui | 135 ----- src/ui/PropertyBrowser.cpp | 63 ++- src/ui/PropertyBrowser.h | 1 + src/ui/PropertyBrowser/qtpropertymanager.cpp | 506 +++++++++++++++++- src/ui/PropertyBrowser/qtpropertymanager.h | 43 ++ .../PropertyBrowser/qtworkspaceattribute.cpp | 166 ++++++ src/ui/PropertyBrowser/qtworkspaceattribute.h | 48 ++ 7 files changed, 819 insertions(+), 143 deletions(-) delete mode 100644 src/ui/Menu/ChartPlotMenu.ui diff --git a/src/ui/Menu/ChartPlotMenu.ui b/src/ui/Menu/ChartPlotMenu.ui deleted file mode 100644 index c6dad019..00000000 --- a/src/ui/Menu/ChartPlotMenu.ui +++ /dev/null @@ -1,135 +0,0 @@ - - - ChartPlotMenuClass - - - - 0 - 0 - 859 - 63 - - - - ChartPlotMenu - - - - - - - - false - - - - 60 - 30 - - - - Wave文件 - - - - - - - false - - - - 60 - 30 - - - - Report文件 - - - - - - - false - - - - 60 - 30 - - - - RD文件 - - - - - - - false - - - - 60 - 30 - - - - Matlab文件 - - - - - - - true - - - - 60 - 30 - - - - Lamp文件 - - - - - - - false - - - - 60 - 30 - - - - Run Simu - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - diff --git a/src/ui/PropertyBrowser.cpp b/src/ui/PropertyBrowser.cpp index 5a39f84b..b0cf7b1a 100644 --- a/src/ui/PropertyBrowser.cpp +++ b/src/ui/PropertyBrowser.cpp @@ -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*/) { +void PropertyBrowser::OnWorkspaceFilesChanged(FileEntryType type, std::shared_ptr 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() { diff --git a/src/ui/PropertyBrowser.h b/src/ui/PropertyBrowser.h index 9d345df4..e1c22475 100644 --- a/src/ui/PropertyBrowser.h +++ b/src/ui/PropertyBrowser.h @@ -45,6 +45,7 @@ private: class QtModelBasePropertyManager* modelBaseManager_{ nullptr }; class QtWorkspacePropertyManager* workSpaceManager_{ nullptr }; class QtEntityPropertyManager* entityManager_{ nullptr }; + class QtCurveEntryPropertyManager* curveEntryManager_{ nullptr }; QMap propertyToId_; QMap idToProperty_; diff --git a/src/ui/PropertyBrowser/qtpropertymanager.cpp b/src/ui/PropertyBrowser/qtpropertymanager.cpp index 87856c59..b72ed5df 100644 --- a/src/ui/PropertyBrowser/qtpropertymanager.cpp +++ b/src/ui/PropertyBrowser/qtpropertymanager.cpp @@ -7976,6 +7976,15 @@ public: QMap> m_properyToPolarPaths; QMap m_polarPathToPropery; QMap m_polarPathIndex; + + // Image + QMap m_properyToImageGroup; + QMap m_imageGroupToPropery; + QMap m_properyToImageCount; + QMap m_imageCountToPropery; + QMap> m_properyToImagePaths; + QMap m_imagePathToPropery; + QMap 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 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 m_properyToName; + QMap m_nameToPropery; + QMap m_properyToChartType; + QMap m_chartTypeToPropery; + QMap m_properyToCurvesGroup; + QMap m_curvesGroupToPropery; + QMap m_properyToCurveCount; + QMap m_curveCountToPropery; + + // Per-curve sub-properties + struct CurveSubProps { + QVector names; + QVector colors; + QVector waveStarts; + QVector waveStops; + QVector reportXs; + QVector reportYs; + }; + QMap m_curveProps; + + // Reverse lookup for per-curve properties + QMap m_curveNameToRoot; + QMap m_curveNameIndex; + QMap m_curveColorToRoot; + QMap m_curveColorIndex; + QMap m_waveStartToRoot; + QMap m_waveStartIndex; + QMap m_waveStopToRoot; + QMap m_waveStopIndex; + QMap m_reportXToRoot; + QMap m_reportXIndex; + QMap m_reportYToRoot; + QMap 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& toRoot, QMap& 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& toRoot, QMap& 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& toRoot, QMap& 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 diff --git a/src/ui/PropertyBrowser/qtpropertymanager.h b/src/ui/PropertyBrowser/qtpropertymanager.h index c1fabc4e..0e6aeeb5 100644 --- a/src/ui/PropertyBrowser/qtpropertymanager.h +++ b/src/ui/PropertyBrowser/qtpropertymanager.h @@ -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 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; diff --git a/src/ui/PropertyBrowser/qtworkspaceattribute.cpp b/src/ui/PropertyBrowser/qtworkspaceattribute.cpp index 04a275c9..9a2967d9 100644 --- a/src/ui/PropertyBrowser/qtworkspaceattribute.cpp +++ b/src/ui/PropertyBrowser/qtworkspaceattribute.cpp @@ -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); +} diff --git a/src/ui/PropertyBrowser/qtworkspaceattribute.h b/src/ui/PropertyBrowser/qtworkspaceattribute.h index 8970da9c..c9b8d77d 100644 --- a/src/ui/PropertyBrowser/qtworkspaceattribute.h +++ b/src/ui/PropertyBrowser/qtworkspaceattribute.h @@ -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;