#include "PropertyItemModel.hxx" #include
#include "FGQmlPropertyNode.hxx" class PropertyItemModelRoleMapping : public QObject { Q_OBJECT Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged) Q_PROPERTY(QString roleName READ roleName WRITE setRoleName NOTIFY roleNameChanged) public: QString path() const { return QString::fromStdString(_propertyPath); } QString roleName() const { return QString::fromLatin1(_roleName); } public slots: void setPath(QString path) { if (_propertyPath == path.toStdString()) return; _propertyPath = path.toStdString(); emit pathChanged(path); } void setRoleName(QString roleName) { if (_roleName == roleName.toLatin1()) return; _roleName = roleName.toLatin1(); emit roleNameChanged(roleName); } signals: void pathChanged(QString path); void roleNameChanged(QString roleName); private: friend class PropertyItemModel; std::string _propertyPath; QByteArray _roleName; }; PropertyItemModel::PropertyItemModel() { } int PropertyItemModel::rowCount(const QModelIndex &parent) const { return _nodes.size(); } QVariant PropertyItemModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) return {}; if (index.row() >= _nodes.size()) return {}; SGPropertyNode_ptr n = _nodes.at(index.row()); Q_ASSERT(n); int mappingIndex = role - Qt::UserRole; if ((mappingIndex < 0) || (mappingIndex >= _roleMappings.size())) return {}; const std::string& nodePath = _roleMappings.at(mappingIndex)->_propertyPath; SGPropertyNode_ptr valueNode = n->getNode(nodePath); // convert property value to a variant return {}; } QHash PropertyItemModel::roleNames() const { QHash result; int count = 0; for (auto m : _roleMappings) { result[Qt::UserRole + count++] = m->_roleName; } return result; } QString PropertyItemModel::rootPath() const { return QString::fromStdString(_modelRoot->getPath()); } QString PropertyItemModel::childNameFilter() const { return _childNameFilter; } FGQmlPropertyNode *PropertyItemModel::root() const { auto n = new FGQmlPropertyNode; n->setNode(_modelRoot); return n; } void PropertyItemModel::setRootPath(QString rootPath) { if (_modelRoot->getPath() == rootPath.toStdString()) return; innerSetRoot(fgGetNode(rootPath.toStdString())); } void PropertyItemModel::setChildNameFilter(QString childNameFilter) { if (_childNameFilter == childNameFilter) return; _childNameFilter = childNameFilter; emit childNameFilterChanged(_childNameFilter); beginResetModel(); rebuild(); endResetModel(); } void PropertyItemModel::setRoot(FGQmlPropertyNode *root) { if (root->node() == _modelRoot) { return; } innerSetRoot(root->node()); } void PropertyItemModel::valueChanged(SGPropertyNode *node) { // if node's parent is one of our nodes, emit data changed } void PropertyItemModel::childAdded(SGPropertyNode *parent, SGPropertyNode *child) { if (parent == _modelRoot) { if (_childNameFilter.isEmpty() || (child->getNameString() == _childNameFilter.toStdString())) { // insert // need to find appropriate index based on position } } // if parent is one of our nodes, emit data changed for it } void PropertyItemModel::childRemoved(SGPropertyNode *parent, SGPropertyNode *child) { if (parent == _modelRoot) { // remove row } // if parent is one of our nodes, emit data changed for it } QQmlListProperty PropertyItemModel::mappings() { return QQmlListProperty(this, nullptr, &PropertyItemModel::append_mapping, &PropertyItemModel::count_mapping, &PropertyItemModel::at_mapping, &PropertyItemModel::clear_mapping ); } void PropertyItemModel::rebuild() { if (!_modelRoot) { _nodes.clear(); return; } if (_childNameFilter.isEmpty()) { // all children _nodes.clear(); const int nChildren = _modelRoot->nChildren(); _nodes.resize(nChildren); for (int c=0; c < nChildren; ++c) { _nodes[c] = _modelRoot->getChild(c); } } else { _nodes = _modelRoot->getChildren(_childNameFilter.toStdString()); } } void PropertyItemModel::innerSetRoot(SGPropertyNode_ptr root) { if (_modelRoot) { _modelRoot->removeChangeListener(this);; } beginResetModel(); _modelRoot = root; if (_modelRoot) { _modelRoot->addChangeListener(this); } rebuild(); emit rootChanged(); endResetModel(); } void PropertyItemModel::append_mapping(QQmlListProperty *list, PropertyItemModelRoleMapping *mapping) { PropertyItemModel *model = qobject_cast(list->object); if (model) { model->_roleMappings.append(mapping); model->mappingsChanged(); model->rebuild(); } } PropertyItemModelRoleMapping* PropertyItemModel::at_mapping(QQmlListProperty *list, int index) { PropertyItemModel *model = qobject_cast(list->object); if (model) { return model->_roleMappings.at(index); } return 0; } int PropertyItemModel::count_mapping(QQmlListProperty *list) { PropertyItemModel *model = qobject_cast(list->object); if (model) { return model->_roleMappings.size(); } return 0; } void PropertyItemModel::clear_mapping(QQmlListProperty *list) { PropertyItemModel *model = qobject_cast(list->object); if (model) { model->_roleMappings.clear(); model->mappingsChanged(); model->rebuild(); } } #include "PropertyItemModel.moc"