libdrmconf  0.12.0
A library to program DMR radios.
configobject.hh
1 #ifndef CONFIGOBJECT_HH
2 #define CONFIGOBJECT_HH
3 
4 #include <QObject>
5 #include <QString>
6 #include <QHash>
7 #include <QVector>
8 #include <QMetaProperty>
9 
10 #include <yaml-cpp/yaml.h>
11 
12 #include "errorstack.hh"
13 
14 // Forward declaration
15 class Config;
16 class ConfigObject;
17 class ConfigExtension;
18 
20 template <class T>
21 bool propIsInstance(const QMetaProperty &prop) {
22  if (QMetaType::UnknownType == prop.userType())
23  return false;
24  QMetaType type(prop.userType());
25  if (! (QMetaType::PointerToQObject & type.flags()))
26  return false;
27  const QMetaObject *propType = type.metaObject();
28  for (; nullptr != propType; propType = propType->superClass()) {
29  if (0==strcmp(T::staticMetaObject.className(), propType->className()))
30  return true;
31  }
32  return false;
33 }
34 
35 
39 class ConfigItem : public QObject
40 {
41  Q_OBJECT
42 
43 public:
47  class Context
48  {
49  public:
51  Context();
53  virtual ~Context();
54 
56  const QString &version() const;
58  void setVersion(const QString &ver);
59 
61  virtual bool contains(ConfigObject *obj) const;
63  virtual bool contains(const QString &id) const;
64 
66  virtual QString getId(ConfigObject *obj) const;
68  virtual ConfigObject *getObj(const QString &id) const;
69 
71  virtual bool add(const QString &id, ConfigObject *);
72 
74  static bool hasTag(const QString &className, const QString &property, const QString &tag);
76  static bool hasTag(const QString &className, const QString &property, ConfigObject *obj);
78  static ConfigObject *getTag(const QString &className, const QString &property, const QString &tag);
80  static QString getTag(const QString &className, const QString &property, ConfigObject *obj);
82  static void setTag(const QString &className, const QString &property, const QString &tag, ConfigObject *obj);
83 
84  protected:
86  QString _version;
88  QHash<QString, ConfigObject *> _objects;
90  QHash<ConfigObject*, QString> _ids;
92  static QHash<QString, QHash<QString, ConfigObject *>> _tagObjects;
94  static QHash<QString, QHash<ConfigObject *, QString>> _tagNames;
95  };
96 
97 protected:
100  explicit ConfigItem(QObject *parent = nullptr);
101 
102 public:
106  virtual bool copy(const ConfigItem &other);
107 
109  virtual ConfigItem *clone() const = 0;
110 
117  virtual int compare(const ConfigItem &other) const;
118 
119 public:
122  virtual bool label(Context &context, const ErrorStack &err=ErrorStack());
125  virtual YAML::Node serialize(const Context &context, const ErrorStack &err=ErrorStack());
126 
130  virtual ConfigItem *allocateChild(QMetaProperty &prop, const YAML::Node &node,
131  const Context &ctx, const ErrorStack &err=ErrorStack());
133  virtual bool parse(const YAML::Node &node, Context &ctx, const ErrorStack &err=ErrorStack());
135  virtual bool link(const YAML::Node &node, const Context &ctx, const ErrorStack &err=ErrorStack());
136 
138  virtual void clear();
139 
141  virtual const Config *config() const;
143  virtual void findItemsOfTypes(const QStringList &typeNames, QSet<ConfigItem*> &items) const;
144 
146  template <class Object>
147  bool is() const {
148  return nullptr != qobject_cast<const Object*>(this);
149  }
150 
152  template <class Object>
153  const Object *as() const {
154  return qobject_cast<const Object*>(this);
155  }
156 
158  template <class Object>
159  Object *as() {
160  return qobject_cast<Object *>(this);
161  }
162 
164  bool hasDescription() const;
166  bool hasLongDescription() const;
168  bool hasDescription(const QMetaProperty &prop) const;
170  bool hasLongDescription(const QMetaProperty &prop) const;
172  QString description() const;
174  QString longDescription() const;
176  QString description(const QMetaProperty &prop) const;
178  QString longDescription(const QMetaProperty &prop) const;
179 
180 protected:
183  virtual bool populate(YAML::Node &node, const Context &context, const ErrorStack &err=ErrorStack());
184 
185 signals:
188  void modified(ConfigItem *obj);
190  void beginClear();
192  void endClear();
193 };
194 
195 
199 {
200  Q_OBJECT
201 
203  Q_PROPERTY(QString name READ name WRITE setName)
204 
205 
206  Q_CLASSINFO("IdPrefix", "obj")
207 
208 protected:
211  ConfigObject(QObject *parent = nullptr);
212 
216  ConfigObject(const QString &name, QObject *parent = nullptr);
217 
218 public:
220  virtual const QString &name() const;
222  virtual void setName(const QString &name);
223 
224 public:
226  QString idPrefix() const;
227  bool label(Context &context, const ErrorStack &err=ErrorStack());
228  bool parse(const YAML::Node &node, Context &ctx, const ErrorStack &err=ErrorStack());
229 
230 protected:
231  virtual bool populate(YAML::Node &node, const Context &context, const ErrorStack &err=ErrorStack());
232 
234  static QString findIdPrefix(const QMetaObject* meta);
235 
236 protected:
238  QString _name;
239 };
240 
241 
246 {
247  Q_OBJECT
248 
249 protected:
251  explicit ConfigExtension(QObject *parent=nullptr);
252 };
253 
254 
257 class AbstractConfigObjectList: public QObject
258 {
259  Q_OBJECT
260 
261 protected:
263  explicit AbstractConfigObjectList(const QMetaObject &elementTypes=ConfigObject::staticMetaObject, QObject *parent = nullptr);
265  AbstractConfigObjectList(const std::initializer_list<QMetaObject> &elementTypes, QObject *parent=nullptr);
266 
267 public:
269  virtual bool copy(const AbstractConfigObjectList &other);
270 
272  virtual bool label(ConfigItem::Context &context, const ErrorStack &err=ErrorStack()) = 0;
275  virtual YAML::Node serialize(const ConfigItem::Context &context, const ErrorStack &err=ErrorStack()) = 0;
276 
278  virtual int count() const;
280  virtual int indexOf(ConfigObject *obj) const;
282  virtual void clear();
283 
285  virtual const Config *config() const;
287  virtual void findItemsOfTypes(const QStringList &typeNames, QSet<ConfigItem*> &items) const;
289  virtual QList<ConfigObject *> findItemsByName(const QString name) const;
290 
292  virtual bool has(ConfigObject *obj) const;
294  virtual ConfigObject *get(int idx) const;
296  virtual int add(ConfigObject *obj, int row=-1, bool unique=true);
298  virtual int replace(ConfigObject *obj, int row, bool unique=true);
300  virtual bool take(ConfigObject *obj);
302  virtual bool del(ConfigObject *obj);
303 
305  virtual bool moveUp(int idx);
307  virtual bool moveUp(int first, int last);
309  virtual bool moveDown(int idx);
311  virtual bool moveDown(int first, int last);
315  virtual bool move(int source, int count, int destination);
316 
318  const QList<QMetaObject> &elementTypes() const;
320  QStringList classNames() const;
321 
322 signals:
324  void elementAdded(int idx);
326  void elementModified(int idx);
328  void elementRemoved(int idx);
329 
330 private slots:
332  void onElementModified(ConfigItem *obj);
334  void onElementDeleted(QObject *obj);
335 
336 protected:
338  QList<QMetaObject> _elementTypes;
340  QVector<ConfigObject *> _items;
341 };
342 
343 
349 {
350  Q_OBJECT
351 
352 protected:
354  explicit ConfigObjectList(const QMetaObject &elementTypes=ConfigItem::staticMetaObject, QObject *parent = nullptr);
356  ConfigObjectList(const std::initializer_list<QMetaObject> &elementTypes, QObject *parent=nullptr);
357 
358 public:
359  int add(ConfigObject *obj, int row=-1, bool unique=true);
360  bool take(ConfigObject *obj);
361  bool del(ConfigObject *obj);
362  void clear();
363  bool copy(const AbstractConfigObjectList &other);
364 
371  virtual int compare(const ConfigObjectList &other) const;
372 
374  virtual ConfigItem *allocateChild(const YAML::Node &node, ConfigItem::Context &ctx, const ErrorStack &err=ErrorStack()) = 0;
376  virtual bool parse(const YAML::Node &node, ConfigItem::Context &ctx, const ErrorStack &err=ErrorStack());
378  virtual bool link(const YAML::Node &node, const ConfigItem::Context &ctx, const ErrorStack &err=ErrorStack());
379 
380  bool label(ConfigItem::Context &context, const ErrorStack &err=ErrorStack());
381  YAML::Node serialize(const ConfigItem::Context &context, const ErrorStack &err=ErrorStack());
382 };
383 
384 
390 {
391  Q_OBJECT
392 
393 protected:
395  explicit ConfigObjectRefList(const QMetaObject &elementTypes=ConfigObject::staticMetaObject, QObject *parent = nullptr);
397  ConfigObjectRefList(const std::initializer_list<QMetaObject> &elementTypes, QObject *parent=nullptr);
398 
399 public:
400  bool label(ConfigItem::Context &context, const ErrorStack &err=ErrorStack());
401  YAML::Node serialize(const ConfigItem::Context &context, const ErrorStack &err=ErrorStack());
402 
409  virtual int compare(const ConfigObjectRefList &other) const;
410 };
411 
412 
413 #endif // CONFIGOBJECT_HH
Generic list class for config objects.
Definition: configobject.hh:258
virtual int indexOf(ConfigObject *obj) const
Returns the index of the given object within the list.
Definition: configobject.cc:1131
QStringList classNames() const
Returns a list of all class names.
Definition: configobject.cc:1333
virtual bool move(int source, int count, int destination)
Moves the given source range to the destination index.
Definition: configobject.cc:1310
QVector< ConfigObject * > _items
Holds the list items.
Definition: configobject.hh:340
void elementAdded(int idx)
Gets emitted if an element was added to the list.
virtual YAML::Node serialize(const ConfigItem::Context &context, const ErrorStack &err=ErrorStack())=0
Recursively serializes the configuration to YAML nodes.
QList< QMetaObject > _elementTypes
Holds the static QMetaObject of the element type.
Definition: configobject.hh:338
virtual void clear()
Clears the list.
Definition: configobject.cc:1136
virtual int add(ConfigObject *obj, int row=-1, bool unique=true)
Adds an element to the list.
Definition: configobject.cc:1182
virtual const Config * config() const
Returns the config object, this list belongs to.
Definition: configobject.cc:1144
void elementRemoved(int idx)
Gets emitted if one of the lists elements gets deleted.
virtual bool has(ConfigObject *obj) const
Returns true, if the list contains the given object.
Definition: configobject.cc:1172
virtual bool label(ConfigItem::Context &context, const ErrorStack &err=ErrorStack())=0
Recursively labels the config object.
virtual bool moveUp(int idx)
Moves an object at index idx one step up.
Definition: configobject.cc:1276
virtual QList< ConfigObject * > findItemsByName(const QString name) const
Searches the list for objects with the given name.
Definition: configobject.cc:1162
virtual bool take(ConfigObject *obj)
Removes an element from the list.
Definition: configobject.cc:1256
virtual int count() const
Returns the number of elements in the list.
Definition: configobject.cc:1126
virtual ConfigObject * get(int idx) const
Returns the list element at the given index or nullptr if out of bounds.
Definition: configobject.cc:1177
virtual bool copy(const AbstractConfigObjectList &other)
Copies all elements from other to this list.
Definition: configobject.cc:1117
virtual void findItemsOfTypes(const QStringList &typeNames, QSet< ConfigItem * > &items) const
Searches the config tree to find all instances of the given type names.
Definition: configobject.cc:1153
void elementModified(int idx)
Gets emitted if one of the lists elements gets modified.
virtual bool moveDown(int idx)
Moves an object at index idx one step down.
Definition: configobject.cc:1293
AbstractConfigObjectList(const QMetaObject &elementTypes=ConfigObject::staticMetaObject, QObject *parent=nullptr)
Hidden constructor.
Definition: configobject.cc:1104
virtual int replace(ConfigObject *obj, int row, bool unique=true)
Replaces an element in the list.
Definition: configobject.cc:1213
virtual bool del(ConfigObject *obj)
Removes an element from the list (and deletes it if owned).
Definition: configobject.cc:1271
const QList< QMetaObject > & elementTypes() const
Returns the element type for this list.
Definition: configobject.cc:1328
Base class of all device/vendor specific confiuration extensions.
Definition: configobject.hh:246
ConfigExtension(QObject *parent=nullptr)
Hidden constructor.
Definition: configobject.cc:1094
Parse context for config objects.
Definition: configobject.hh:48
QString _version
The version string.
Definition: configobject.hh:86
const QString & version() const
Returns the read version string.
Definition: configobject.cc:49
virtual bool add(const QString &id, ConfigObject *)
Associates the given object with the given ID.
Definition: configobject.cc:78
void setVersion(const QString &ver)
Sets the version string.
Definition: configobject.cc:53
QHash< QString, ConfigObject * > _objects
ID->OBJ look-up table.
Definition: configobject.hh:88
Context()
Empty constructor.
Definition: configobject.cc:38
virtual ~Context()
Destructor.
Definition: configobject.cc:44
virtual QString getId(ConfigObject *obj) const
Returns ID of the given object.
Definition: configobject.cc:68
static ConfigObject * getTag(const QString &className, const QString &property, const QString &tag)
Returns the object associated with the tag for the property of the class.
Definition: configobject.cc:99
static QHash< QString, QHash< ConfigObject *, QString > > _tagNames
Maps singleton objects to tags.
Definition: configobject.hh:94
virtual ConfigObject * getObj(const QString &id) const
Returns the object for the given ID.
Definition: configobject.cc:73
static void setTag(const QString &className, const QString &property, const QString &tag, ConfigObject *obj)
Associates the given object with the tag for the property of the given class.
Definition: configobject.cc:117
static QHash< QString, QHash< QString, ConfigObject * > > _tagObjects
Maps tags to singleton objects.
Definition: configobject.hh:92
QHash< ConfigObject *, QString > _ids
OBJ->ID look-up table.
Definition: configobject.hh:90
virtual bool contains(ConfigObject *obj) const
Returns true, if the context contains the given object.
Definition: configobject.cc:58
static bool hasTag(const QString &className, const QString &property, const QString &tag)
Returns true if the property of the class has the specified tag associated.
Definition: configobject.cc:87
Base class for all configuration objects (channels, zones, contacts, etc).
Definition: configobject.hh:40
virtual bool link(const YAML::Node &node, const Context &ctx, const ErrorStack &err=ErrorStack())
Links the given object to the rest of the codeplug using the given context.
Definition: configobject.cc:758
virtual int compare(const ConfigItem &other) const
Compares the items.
Definition: configobject.cc:238
bool hasLongDescription() const
Returns true if there is a class info "longDescription" for this instance.
Definition: configobject.cc:940
virtual bool copy(const ConfigItem &other)
Copies the given item into this one.
Definition: configobject.cc:139
virtual bool populate(YAML::Node &node, const Context &context, const ErrorStack &err=ErrorStack())
Recursively serializes the configuration to YAML nodes.
Definition: configobject.cc:395
QString longDescription() const
Returns the long description of this instance if set by a class info.
Definition: configobject.cc:972
bool hasDescription() const
Returns true if there is a class info "description" for this instance.
Definition: configobject.cc:934
virtual void findItemsOfTypes(const QStringList &typeNames, QSet< ConfigItem * > &items) const
Searches the config tree to find all instances of the given type names.
Definition: configobject.cc:911
Object * as()
Casts this object to the given type.
Definition: configobject.hh:159
virtual ConfigItem * clone() const =0
Clones this item.
virtual ConfigItem * allocateChild(QMetaProperty &prop, const YAML::Node &node, const Context &ctx, const ErrorStack &err=ErrorStack())
Allocates an instance for the given property on the given YAML node.
Definition: configobject.cc:487
bool is() const
Returns true if this object is of class Object.
Definition: configobject.hh:147
virtual bool label(Context &context, const ErrorStack &err=ErrorStack())
Recursively labels the config object.
Definition: configobject.cc:341
virtual const Config * config() const
Returns the config, the item belongs to or nullptr if not part of a config.
Definition: configobject.cc:900
virtual YAML::Node serialize(const Context &context, const ErrorStack &err=ErrorStack())
Recursively serializes the configuration to YAML nodes.
Definition: configobject.cc:365
virtual void clear()
Clears the config object.
Definition: configobject.cc:373
const Object * as() const
Casts this object to the given type.
Definition: configobject.hh:153
virtual bool parse(const YAML::Node &node, Context &ctx, const ErrorStack &err=ErrorStack())
Parses the given YAML node, updates the given object and updates the given context (IDs).
Definition: configobject.cc:515
QString description() const
Returns the description of this instance if set by a class info.
Definition: configobject.cc:964
void endClear()
Gets emitted after clearing the item.
ConfigItem(QObject *parent=nullptr)
Hidden constructor.
Definition: configobject.cc:132
void modified(ConfigItem *obj)
Gets emitted once the config object is modified.
void beginClear()
Gets emitted before clearing the item.
List class for config objects.
Definition: configobject.hh:349
bool take(ConfigObject *obj)
Removes an element from the list.
Definition: configobject.cc:1467
int add(ConfigObject *obj, int row=-1, bool unique=true)
Adds an element to the list.
Definition: configobject.cc:1460
void clear()
Clears the list.
Definition: configobject.cc:1481
ConfigObjectList(const QMetaObject &elementTypes=ConfigItem::staticMetaObject, QObject *parent=nullptr)
Hidden constructor.
Definition: configobject.cc:1363
virtual int compare(const ConfigObjectList &other) const
Compares the object lists.
Definition: configobject.cc:1498
virtual bool parse(const YAML::Node &node, ConfigItem::Context &ctx, const ErrorStack &err=ErrorStack())
Parses the list from the YAML node.
Definition: configobject.cc:1397
virtual ConfigItem * allocateChild(const YAML::Node &node, ConfigItem::Context &ctx, const ErrorStack &err=ErrorStack())=0
Allocates a member objects for the given YAML node.
bool copy(const AbstractConfigObjectList &other)
Copies all elements from other to this list.
Definition: configobject.cc:1489
virtual bool link(const YAML::Node &node, const ConfigItem::Context &ctx, const ErrorStack &err=ErrorStack())
Links the list from the given YAML node.
Definition: configobject.cc:1431
YAML::Node serialize(const ConfigItem::Context &context, const ErrorStack &err=ErrorStack())
Recursively serializes the configuration to YAML nodes.
Definition: configobject.cc:1385
bool del(ConfigObject *obj)
Removes an element from the list (and deletes it if owned).
Definition: configobject.cc:1474
bool label(ConfigItem::Context &context, const ErrorStack &err=ErrorStack())
Recursively labels the config object.
Definition: configobject.cc:1376
List class for config objects.
Definition: configobject.hh:390
bool label(ConfigItem::Context &context, const ErrorStack &err=ErrorStack())
Recursively labels the config object.
Definition: configobject.cc:1527
YAML::Node serialize(const ConfigItem::Context &context, const ErrorStack &err=ErrorStack())
Recursively serializes the configuration to YAML nodes.
Definition: configobject.cc:1534
ConfigObjectRefList(const QMetaObject &elementTypes=ConfigObject::staticMetaObject, QObject *parent=nullptr)
Hidden constructor.
Definition: configobject.cc:1514
virtual int compare(const ConfigObjectRefList &other) const
Compares the object ref lists.
Definition: configobject.cc:1547
Base class of all labeled and named objects.
Definition: configobject.hh:199
virtual bool populate(YAML::Node &node, const Context &context, const ErrorStack &err=ErrorStack())
Recursively serializes the configuration to YAML nodes.
Definition: configobject.cc:1072
bool parse(const YAML::Node &node, Context &ctx, const ErrorStack &err=ErrorStack())
Parses the given YAML node, updates the given object and updates the given context (IDs).
Definition: configobject.cc:1054
ConfigObject(QObject *parent=nullptr)
Specifies the prefix for every ID assigned to every object during serialization.
Definition: configobject.cc:1001
bool label(Context &context, const ErrorStack &err=ErrorStack())
Recursively labels the config object.
Definition: configobject.cc:1032
virtual void setName(const QString &name)
Sets the name of the object.
Definition: configobject.cc:1019
QString _name
Holds the name of the object.
Definition: configobject.hh:238
QString name
The name of the object.
Definition: configobject.hh:203
QString idPrefix() const
Returns the ID prefix for this object.
Definition: configobject.cc:1027
static QString findIdPrefix(const QMetaObject *meta)
Helper to find the IdPrefix class info in the class hierarchy.
Definition: configobject.cc:1079
The config class, representing the codeplug configuration.
Definition: config.hh:70
Implements a stack of error messages to provide a pretty formatted error traceback.
Definition: errorstack.hh:41