FlightGear next
PropertyItemModel.cxx
Go to the documentation of this file.
2
3#include <Main/fg_props.hxx>
4
6
7class PropertyItemModelRoleMapping : public QObject
8{
9 Q_OBJECT
10
11 Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged)
12 Q_PROPERTY(QString roleName READ roleName WRITE setRoleName NOTIFY roleNameChanged)
13public:
14
15 QString path() const
16 {
17 return QString::fromStdString(_propertyPath);
18 }
19
20 QString roleName() const
21 {
22 return QString::fromLatin1(_roleName);
23 }
24
25public slots:
26 void setPath(QString path)
27 {
28 if (_propertyPath == path.toStdString())
29 return;
30
31 _propertyPath = path.toStdString();
32 emit pathChanged(path);
33 }
34
35 void setRoleName(QString roleName)
36 {
37 if (_roleName == roleName.toLatin1())
38 return;
39
40 _roleName = roleName.toLatin1();
42 }
43
44signals:
45 void pathChanged(QString path);
46
48
49private:
50 friend class PropertyItemModel;
51 std::string _propertyPath;
52 QByteArray _roleName;
53};
54
59
60int PropertyItemModel::rowCount(const QModelIndex &parent) const
61{
62 return _nodes.size();
63}
64
65QVariant PropertyItemModel::data(const QModelIndex &index, int role) const
66{
67 if (!index.isValid())
68 return {};
69
70 if (static_cast<size_t>(index.row()) >= _nodes.size())
71 return {};
72
73 SGPropertyNode_ptr n = _nodes.at(index.row());
74 Q_ASSERT(n);
75 int mappingIndex = role - Qt::UserRole;
76 if ((mappingIndex < 0) || (mappingIndex >= _roleMappings.size()))
77 return {};
78
79 const std::string& nodePath = _roleMappings.at(mappingIndex)->_propertyPath;
80 SGPropertyNode_ptr valueNode = n->getNode(nodePath);
81
82 // convert property value to a variant
83
84 return {};
85}
86
87QHash<int, QByteArray> PropertyItemModel::roleNames() const
88{
89 QHash<int, QByteArray> result;
90 int count = 0;
91 for (auto m : _roleMappings) {
92 result[Qt::UserRole + count++] = m->_roleName;
93 }
94 return result;
95}
96
98{
99 return QString::fromStdString(_modelRoot->getPath());
100}
101
103{
104 return _childNameFilter;
105}
106
108{
109 auto n = new FGQmlPropertyNode;
110 n->setNode(_modelRoot);
111 return n;
112}
113
115{
116 if (_modelRoot->getPath() == rootPath.toStdString())
117 return;
118
119 innerSetRoot(fgGetNode(rootPath.toStdString()));
120}
121
123{
124 if (_childNameFilter == childNameFilter)
125 return;
126
127 _childNameFilter = childNameFilter;
128 emit childNameFilterChanged(_childNameFilter);
129
130 beginResetModel();
131 rebuild();
132 endResetModel();
133}
134
136{
137 if (root->node() == _modelRoot) {
138 return;
139 }
140
141 innerSetRoot(root->node());
142}
143
144void PropertyItemModel::valueChanged(SGPropertyNode *node)
145{
146 // if node's parent is one of our nodes, emit data changed
147}
148
149void PropertyItemModel::childAdded(SGPropertyNode *parent, SGPropertyNode *child)
150{
151 if (parent == _modelRoot) {
152 if (_childNameFilter.isEmpty() || (child->getNameString() == _childNameFilter.toStdString())) {
153 // insert
154 // need to find appropriate index based on position
155 }
156 }
157
158 // if parent is one of our nodes, emit data changed for it
159}
160
161void PropertyItemModel::childRemoved(SGPropertyNode *parent, SGPropertyNode *child)
162{
163 if (parent == _modelRoot) {
164 // remove row
165 }
166
167 // if parent is one of our nodes, emit data changed for it
168
169}
170
171QQmlListProperty<PropertyItemModelRoleMapping> PropertyItemModel::mappings()
172{
173 return QQmlListProperty<PropertyItemModelRoleMapping>(this, nullptr,
174 &PropertyItemModel::append_mapping,
175 &PropertyItemModel::count_mapping,
176 &PropertyItemModel::at_mapping,
177 &PropertyItemModel::clear_mapping
178 );
179}
180
181void PropertyItemModel::rebuild()
182{
183 if (!_modelRoot) {
184 _nodes.clear();
185 return;
186 }
187
188 if (_childNameFilter.isEmpty()) {
189 // all children
190 _nodes.clear();
191 const int nChildren = _modelRoot->nChildren();
192 _nodes.resize(nChildren);
193 for (int c=0; c < nChildren; ++c) {
194 _nodes[c] = _modelRoot->getChild(c);
195 }
196 } else {
197 _nodes = _modelRoot->getChildren(_childNameFilter.toStdString());
198 }
199}
200
201void PropertyItemModel::innerSetRoot(SGPropertyNode_ptr root)
202{
203 if (_modelRoot) {
204 _modelRoot->removeChangeListener(this);;
205 }
206 beginResetModel();
207
208 _modelRoot = root;
209 if (_modelRoot) {
210 _modelRoot->addChangeListener(this);
211 }
212
213 rebuild();
214 emit rootChanged();
215 endResetModel();
216}
217
218void PropertyItemModel::append_mapping(QQmlListProperty<PropertyItemModelRoleMapping> *list,
220{
221 PropertyItemModel *model = qobject_cast<PropertyItemModel *>(list->object);
222 if (model) {
223 model->_roleMappings.append(mapping);
224 model->mappingsChanged();
225 model->rebuild();
226 }
227}
228
229PropertyItemModelRoleMapping* PropertyItemModel::at_mapping(QQmlListProperty<PropertyItemModelRoleMapping>* list, QML_LIST_INDEX_TYPE index)
230{
231 PropertyItemModel *model = qobject_cast<PropertyItemModel *>(list->object);
232 if (model) {
233 return model->_roleMappings.at(index);
234 }
235 return 0;
236}
237
238QML_LIST_INDEX_TYPE PropertyItemModel::count_mapping(QQmlListProperty<PropertyItemModelRoleMapping>* list)
239{
240 PropertyItemModel *model = qobject_cast<PropertyItemModel *>(list->object);
241 if (model) {
242 return model->_roleMappings.size();
243 }
244 return 0;
245}
246
247void PropertyItemModel::clear_mapping(QQmlListProperty<PropertyItemModelRoleMapping> *list)
248{
249 PropertyItemModel *model = qobject_cast<PropertyItemModel *>(list->object);
250 if (model) {
251 model->_roleMappings.clear();
252 model->mappingsChanged();
253 model->rebuild();
254 }
255}
256
257
258#include "PropertyItemModel.moc"
#define QML_LIST_INDEX_TYPE
void setNode(SGPropertyNode_ptr node)
void pathChanged(QString path)
void roleNameChanged(QString roleName)
void setRoleName(QString roleName)
FGQmlPropertyNode * root
void childRemoved(SGPropertyNode *parent, SGPropertyNode *child) override
QHash< int, QByteArray > roleNames() const override
void setRootPath(QString rootPath)
void setChildNameFilter(QString childNameFilter)
void childNameFilterChanged(QString childNameFilter)
QVariant data(const QModelIndex &index, int role) const override
void childAdded(SGPropertyNode *parent, SGPropertyNode *child) override
int rowCount(const QModelIndex &parent) const override
void setRoot(FGQmlPropertyNode *root)
void valueChanged(SGPropertyNode *node) override
QQmlListProperty< PropertyItemModelRoleMapping > mappings
SGPropertyNode * fgGetNode(const char *path, bool create)
Get a property node.
Definition proptest.cpp:27