257 lines
6.3 KiB
C++
257 lines
6.3 KiB
C++
#include "PropertyItemModel.hxx"
|
|
|
|
#include <Main/fg_props.hxx>
|
|
|
|
#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 (static_cast<size_t>(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<int, QByteArray> PropertyItemModel::roleNames() const
|
|
{
|
|
QHash<int, QByteArray> 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<PropertyItemModelRoleMapping> PropertyItemModel::mappings()
|
|
{
|
|
return QQmlListProperty<PropertyItemModelRoleMapping>(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<PropertyItemModelRoleMapping> *list,
|
|
PropertyItemModelRoleMapping *mapping)
|
|
{
|
|
PropertyItemModel *model = qobject_cast<PropertyItemModel *>(list->object);
|
|
if (model) {
|
|
model->_roleMappings.append(mapping);
|
|
model->mappingsChanged();
|
|
model->rebuild();
|
|
}
|
|
}
|
|
|
|
PropertyItemModelRoleMapping* PropertyItemModel::at_mapping(QQmlListProperty<PropertyItemModelRoleMapping> *list, int index)
|
|
{
|
|
PropertyItemModel *model = qobject_cast<PropertyItemModel *>(list->object);
|
|
if (model) {
|
|
return model->_roleMappings.at(index);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int PropertyItemModel::count_mapping(QQmlListProperty<PropertyItemModelRoleMapping> *list)
|
|
{
|
|
PropertyItemModel *model = qobject_cast<PropertyItemModel *>(list->object);
|
|
if (model) {
|
|
return model->_roleMappings.size();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void PropertyItemModel::clear_mapping(QQmlListProperty<PropertyItemModelRoleMapping> *list)
|
|
{
|
|
PropertyItemModel *model = qobject_cast<PropertyItemModel *>(list->object);
|
|
if (model) {
|
|
model->_roleMappings.clear();
|
|
model->mappingsChanged();
|
|
model->rebuild();
|
|
}
|
|
}
|
|
|
|
#include "PropertyItemModel.moc"
|