Seamly2D
Code documentation
vpropertymodel.cpp
Go to the documentation of this file.
1 /************************************************************************
2  **
3  ** @file vpropertymodel.cpp
4  ** @author hedgeware <internal(at)hedgeware.net>
5  ** @date
6  **
7  ** @brief
8  ** @copyright
9  ** All rights reserved. This program and the accompanying materials
10  ** are made available under the terms of the GNU Lesser General Public License
11  ** (LGPL) version 2.1 which accompanies this distribution, and is available at
12  ** http://www.gnu.org/licenses/lgpl-2.1.html
13  **
14  ** This library is distributed in the hope that it will be useful,
15  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
16  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  ** Lesser General Public License for more details.
18  **
19  *************************************************************************/
20 
21 #include "vpropertymodel.h"
22 
23 #include <QList>
24 
25 #include "vproperty.h"
26 #include "vpropertyset.h"
27 
28 #include "vpropertymodel_p.h"
29 
31  : QAbstractItemModel(parent), d_ptr(d)
32 {
33 }
34 
35 
37  QAbstractItemModel(parent), d_ptr(new VPropertyModelPrivate())
38 {
39 }
40 
42 {
43  delete d_ptr->Properties;
44  delete d_ptr;
45 }
46 
47 //! Adds the property to the model and attaches it to the parentid
48 bool VPE::VPropertyModel::addProperty(VProperty* property, const QString& id, const QString &parentid, bool emitsignals)
49 {
50  if (!property)
51  {
52  return false;
53  }
54 
55  if (!d_ptr->Properties) // If not existant, create property set
56  {
57  d_ptr->Properties = new VPropertySet();
58  }
59 
60  if (emitsignals)
61  {
62  VProperty* tmpParent = getProperty(parentid);
63  int tmpRow = tmpParent != nullptr ? tmpParent->getRowCount() : d_ptr->Properties->getRootPropertyCount();
64  beginInsertRows((tmpParent != nullptr ? getIndexFromProperty(tmpParent) : QModelIndex()), tmpRow, tmpRow);
65  }
66 
67  d_ptr->Properties->addProperty(property, id, parentid);
68 
69  if (emitsignals)
70  {
71  endInsertRows();
72  }
73 
74  return true;
75 
76 }
77 
78 //! Creates a property and adds it to the model
79 VPE::VProperty* VPE::VPropertyModel::createProperty(const QString& id, const QString& name, const QString& parentid,
80  const QVariant& data)
81 {
82  VProperty* tmpProp = new VProperty(name);
83  tmpProp->setValue(data);
84  if (addProperty(tmpProp, id, parentid))
85  {
86  return tmpProp;
87  }
88  else
89  return nullptr;
90 }
91 
92 //! Gets a property by it's ID
94 {
95  return d_ptr->Properties != nullptr ? d_ptr->Properties->getProperty(id) : nullptr;
96 }
97 
98 //! Returns the model index at row/column
99 QModelIndex VPE::VPropertyModel::index(int row, int column, const QModelIndex& parent) const
100 {
101  if (d_ptr->Properties == nullptr || (parent.isValid() && parent.column() > 1))
102  {
103  return QModelIndex();
104  }
105 
106  if (parent.isValid())
107  {
108  // Get the parent index
109  VProperty* parentItem = getProperty(parent);
110  if (parentItem)
111  {
112  VProperty* childItem = parentItem->getChild(row);
113  if (childItem)
114  {
115  return createIndex(row, column, childItem);
116  }
117  }
118  }
119  else if (row >= 0 && row < d_ptr->Properties->count())
120  {
121  return createIndex(row, column, d_ptr->Properties->getRootProperty(row));
122  }
123 
124  return QModelIndex();
125 }
126 
127 //! Returns the parent of one model index
128 QModelIndex VPE::VPropertyModel::parent ( const QModelIndex & index ) const
129 {
130  if (!index.isValid())
131  {
132  return QModelIndex();
133  }
134 
135  VProperty* childItem = getProperty(index);
136  if (childItem)
137  {
138  VProperty* parentItem = childItem->getParent();
139  if (parentItem)
140  {
141  VProperty* grandParentItem = parentItem->getParent();
142  int parents_row = grandParentItem != nullptr ? grandParentItem->getChildRow(parentItem)
143  : d_ptr->Properties->getRootProperties().indexOf(parentItem);
144 
145  if (parents_row >= 0)
146  {
147  return createIndex(parents_row, 0, parentItem);
148  }
149  }
150  }
151 
152  return QModelIndex();
153 }
154 
155 //! Returns the item flags for the given index
156 Qt::ItemFlags VPE::VPropertyModel::flags (const QModelIndex& index) const
157 {
158  VProperty* tmpProperty = getProperty(index);
159  if (!tmpProperty)
160  {
161  return Qt::NoItemFlags;
162  }
163  else
164  return tmpProperty->flags(index.column());
165 }
166 
167 //! Sets the role data for the item at index to value
168 bool VPE::VPropertyModel::setData (const QModelIndex& index, const QVariant& value, int role)
169 {
170  VProperty* tmpProperty = getProperty(index);
171  if (index.column() == 1 && tmpProperty)
172  {
173  bool tmpHasChanged = tmpProperty->setData(value, role);
174  if (tmpProperty->getUpdateParent() && tmpHasChanged)
175  { // If neccessary, update the parent as well
176  QModelIndex tmpParentIndex = parent(index);
177  emit dataChanged(tmpParentIndex, tmpParentIndex);
178  }
179 
180  if (tmpHasChanged)
181  {
182  emit onDataChangedByEditor(tmpProperty);
183  }
184  }
185 
186 
187  return true;
188 }
189 
190 
191 //! Returns the data of an model index
192 QVariant VPE::VPropertyModel::data ( const QModelIndex & index, int role ) const
193 {
194  VProperty* tmpProperty = getProperty(index);
195  if (!tmpProperty)
196  {
197  return QVariant();
198  }
199  else
200  return tmpProperty->data(index.column(), role);
201 }
202 
203 
204 QVariant VPE::VPropertyModel::headerData (int section, Qt::Orientation orientation, int role) const
205 {
206  if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
207  {
208  // Header data
209  if (section == 0)
210  {
211  return d_ptr->HeadlineProperty;
212  }
213  else if (section == 1)
214  {
215  return d_ptr->HeadlineValue;
216  }
217  }
218  else if (role == Qt::DisplayRole)
219  {
220  return QVariant(section);
221  }
222 
223  return QVariant();
224 }
225 
226 
227 //! Returns the number of rows
228 int VPE::VPropertyModel::rowCount ( const QModelIndex & parent ) const
229 {
230  if (parent.isValid())
231  {
232  VProperty* tmpParent = getProperty(parent);
233  if (tmpParent)
234  {
235  return tmpParent->getRowCount();
236  }
237  }
238 
239  // Return the root property count
240  if (d_ptr->Properties)
241  {
242  return d_ptr->Properties->getRootPropertyCount();
243  }
244 
245  return 0;
246 }
247 
248 
249 //! Returns the number of columns
250 int VPE::VPropertyModel::columnCount ( const QModelIndex & parent) const
251 {
252  Q_UNUSED(parent)
253  return 2;
254 }
255 
256 
257 //! Gets a property by its ModelIndex
258 VPE::VProperty* VPE::VPropertyModel::getProperty(const QModelIndex &index) const
259 {
260  if (index.isValid())
261  {
262  VProperty* prop = static_cast<VProperty*>(index.internalPointer());
263 
264  if (prop)
265  {
266  return prop;
267  }
268  }
269  return nullptr;
270 }
271 
273 {
274  return d_ptr->Properties != nullptr ? d_ptr->Properties->getPropertyID(prop) : QString();
275 }
276 
277 QModelIndex VPE::VPropertyModel::getIndexFromProperty(VProperty* property, int column) const
278 {
279  if (!property || column > columnCount() || column < 0)
280  {
281  return QModelIndex();
282  }
283 
284  VProperty* parentItem = property->getParent();
285  int row = 0;
286 
287  if (parentItem)
288  {
289  row = parentItem->getChildRow(property);
290  }
291 
292  return createIndex(row, column, property);
293 }
294 
295 
297 {
298  QModelIndex tmpIndex = getIndexFromProperty(property, 1);
299  if (tmpIndex.isValid())
300  {
301  emit dataChanged(tmpIndex, tmpIndex);
302  emit onDataChangedByEditor(property);
303  }
304 }
305 
307 {
308  return d_ptr->Properties;
309 }
310 
311 void VPE::VPropertyModel::clear(bool emit_signals)
312 {
313  setPropertySet(nullptr, emit_signals);
314 }
315 
317 {
318  VPropertySet* tmpOldPropertySet = d_ptr->Properties;
319 
320  if (emit_signals)
321  {
322  emit beginResetModel();
323  }
324  d_ptr->Properties = new_property_set;
325  if (emit_signals)
326  {
327  emit endResetModel();
328  }
329 
330  return tmpOldPropertySet;
331 }
332 
333 void VPE::VPropertyModel::setPropertySet(VPropertySet *property_set, bool emit_signals)
334 {
335  VPropertySet* tmpOldPropertySet = takePropertySet(property_set, emit_signals);
336  delete tmpOldPropertySet;
337 }
338 
340 {
341  QModelIndex tmpIndex = getIndexFromProperty(getProperty(id));
342  if (d_ptr->Properties && tmpIndex.isValid())
343  {
344  beginRemoveRows(tmpIndex.parent(), tmpIndex.row(), tmpIndex.row());
345  VProperty* tmpProp = d_ptr->Properties->takeProperty(id);
346  endRemoveRows();
347  return tmpProp;
348  }
349 
350  return nullptr;
351 }
352 
353 void VPE::VPropertyModel::removeProperty(const QString &id)
354 {
355  QModelIndex tmpIndex = getIndexFromProperty(getProperty(id));
356  if (d_ptr->Properties && tmpIndex.isValid())
357  {
358  beginRemoveRows(tmpIndex.parent(), tmpIndex.row(), tmpIndex.row());
359  d_ptr->Properties->removeProperty(id);
360  endRemoveRows();
361  }
362 }
virtual QModelIndex getIndexFromProperty(VProperty *property, int column=0) const
Gets a property by its ModelIndex.
virtual int columnCount(const QModelIndex &parent=QModelIndex()) const Q_DECL_OVERRIDE
Returns the number of columns.
virtual Qt::ItemFlags flags(const QModelIndex &index) const Q_DECL_OVERRIDE
Returns the item flags for the given index.
virtual QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const Q_DECL_OVERRIDE
Returns the data of an model index.
void onDataChangedByModel(VProperty *property)
This function causes the views to update the property.
virtual ~VPropertyModel() Q_DECL_OVERRIDE
VPropertyModel(QObject *parent=nullptr)
virtual VProperty * createProperty(const QString &id, const QString &name, const QString &parentid=QString(), const QVariant &data=QVariant())
Creates a property and adds it to the model.
virtual QString getPropertyID(const VProperty *prop) const
Returns the ID of the property within the model The concept of property IDs is, that the object that ...
virtual void removeProperty(const QString &id)
Removes a property from the model and deletes it.
virtual QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const Q_DECL_OVERRIDE
Returns the data for the given role and section in the header with the specified orientation.
virtual VPropertySet * takePropertySet(VPropertySet *new_property_set=nullptr, bool emit_signals=true)
Removes the current property set and returns it. If new_property_set is set, the old one will be repl...
virtual void setPropertySet(VPropertySet *property_set, bool emit_signals=true)
Sets a new property set. The model will take ownership of the property set. The old property set will...
virtual int rowCount(const QModelIndex &parent=QModelIndex()) const Q_DECL_OVERRIDE
Returns the number of rows.
virtual bool addProperty(VProperty *property, const QString &id, const QString &parentid=QString(), bool emitsignals=true)
Adds the property to the model and attaches it to the parentid.
virtual QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const Q_DECL_OVERRIDE
Returns the model index at row/column.
virtual VProperty * takeProperty(const QString &id)
Removes a property from the model and returns it.
virtual VProperty * getProperty(const QString &id)
Gets a property by it's ID.
virtual void clear(bool emit_signals=true)
Clears the model, deletes the property set managed by this model.
virtual QModelIndex parent(const QModelIndex &index) const Q_DECL_OVERRIDE
Returns the parent of one model index.
virtual bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole) Q_DECL_OVERRIDE
Sets the role data for the item at index to value.
virtual const VPropertySet * getPropertySet() const
Returns a const pointer to the property set managed by this model. If you want to manipulate the prop...
VPropertySet is a simple class for managing a set of properties. If you don't need all the Model-func...
Definition: vpropertyset.h:48
virtual Qt::ItemFlags flags(int column=DPC_Name) const
Returns item flags.
Definition: vproperty.cpp:156
virtual bool setData(const QVariant &data, int role=Qt::EditRole)
This is used by the model to set the data.
Definition: vproperty.cpp:86
virtual QVariant data(int column=DPC_Name, int role=Qt::DisplayRole) const
Get the data how it should be displayed.
Definition: vproperty.cpp:68
virtual bool getUpdateParent() const
Returns whether the views have to update the parent of this property if it changes.
Definition: vproperty.cpp:314
virtual int getRowCount() const
Gets the number of children.
Definition: vproperty.cpp:245
virtual void setValue(const QVariant &value)
Sets the value of the property.
Definition: vproperty.cpp:171
virtual VProperty * getParent() const
Gets the parent of this property.
Definition: vproperty.cpp:251
virtual int getChildRow(VProperty *child) const
Returns the row the child has.
Definition: vproperty.cpp:308
virtual VProperty * getChild(int row) const
Returns the child at a certain row.
Definition: vproperty.cpp:234
@ Properties