OpenLexocad  27.1
PropertyLink.h
Go to the documentation of this file.
1 #pragma once
2 #pragma warning(disable : 4251)
4 #include <Base/Writer.h>
5 #include <Core/DocObject.h>
6 #include <Base/Log.h>
7 #include <Core/Object_Hnd.h>
11 #include <Core/Variant.h>
12 
13 #include <unordered_set>
14 #include <list>
15 
16 namespace Core
17 {
18 template <typename T>
19 struct TypeName
20 {
21  static const char* Get() { return typeid(T).name(); }
22 };
23 
24 //----------------------------------------------------------------------------
25 // PropertyLink<T>
26 //----------------------------------------------------------------------------
27 
28 template <typename T>
30 {
31  TYPESYSTEM_PROPERTY_HEADER(PropertyLink, Core::PropertyLinkBase);
33 
34 public:
35  void setValue(T value) { inherited::setValue(value); }
36  T getValue() const { return static_cast<T>(inherited::getValue()); }
37 
39  {
40  inherited::restore(reader, version);
41  if (hObject.getStatus() == Object_Hnd::Valid && getValue() && !dynamic_cast<T>(getValue()))
42  {
43  setValue(nullptr);
44  cDebug("ERROR: Trying to fill PropertyLink with object of wrong type!");
45  }
46  }
47 
48  virtual bool removeLink(DocObject* o) override
49  {
50  setValue(nullptr);
51  return true;
52  }
53 };
54 
55 #ifndef SWIG
56 template <typename T>
57 Base::Type PropertyLink<T>::classTypeId = Base::Type().createType(Base::Type::badType(), TypeName<PropertyLink<T>>::Get());
58 #endif
59 
60 
61 //----------------------------------------------------------------------------
62 // PropertyLinkSet<T>
63 //----------------------------------------------------------------------------
64 
65 template <typename T>
67 {
68  TYPESYSTEM_PROPERTY_HEADER(PropertyLinkSet, Core::PropertyLinkSetBase);
70 
71 public:
72  void setValue(const std::unordered_set<T>& linkset) { inherited::setValue(*(const std::unordered_set<Core::DocObject*>*)(&linkset)); }
73  const std::unordered_set<T>& getValue() const { return *(const std::unordered_set<T>*)(&_linkSet); }
74 
75  bool addLink(T link) { return inherited::addLink(link); }
76  bool removeLink(T link) { return inherited::removeLink(link); }
77 
78  void addLinks(const std::unordered_set<T>& linkset) { inherited::addLinks(*(const std::unordered_set<Core::DocObject*>*)(&linkset)); }
79 };
80 
81 #ifndef SWIG
82 template <typename T>
83 Base::Type PropertyLinkSet<T>::classTypeId = Base::Type().createType(Base::Type::badType(), TypeName<PropertyLinkSet<T>>::Get());
84 #endif
85 
86 
87 //----------------------------------------------------------------------------
88 // PropertyLinkList
89 //----------------------------------------------------------------------------
90 
91 class LX_CORE_EXPORT PropertyLinkList : public PropertyLinkListBase
92 {
94 
95 public:
96  PropertyLinkList() = default;
97  virtual ~PropertyLinkList() = default;
98 
99  virtual void setValue(const std::list<Core::DocObject*>& list) override;
100  virtual bool setValueFromVariant(const Core::Variant& value) override;
101  virtual void copyValue(Core::Property* p) override;
102 
103  virtual void addLink(Core::DocObject* o) override;
104  virtual bool removeLink(Core::DocObject* o) override;
105  virtual void setEmpty() override;
106 
107  virtual Core::Variant getVariant() const override;
108 
109  inline virtual void restore(Base::AbstractXMLReader& reader, Base::PersistenceVersion& version) override;
110  virtual bool isEqual(const Property* p) const override;
111 };
112 
113 
114 //----------------------------------------------------------------------------
115 // PropertyTypedLinkList
116 //----------------------------------------------------------------------------
117 
118 template <typename T>
119 class PropertyTypedLinkList : public PropertyLinkListBase //@todo mondzi: check if everything works
120 {
121  TYPESYSTEM_PROPERTY_HEADER(PropertyTypedLinkList, Core::PropertyLinkListBase);
122 
123 public:
124  void setValue(const std::list<T>& aList);
125  bool setValueFromVariant(const Core::Variant& value) override;
126  void copyValue(Core::Property* p) override;
127  const std::list<T>& getValue() const { return *(const std::list<T>*)(&_linkList); };
128 
129  void addLink(T link);
130  bool removeLink(T link);
131  bool hasLink(T link) const;
132 
133  void setEmpty();
134  inline bool isEmpty() const { return _linkList.empty(); }
135 
136  size_t getSize() const { return _linkList.size(); }
137 
140  bool isEqual(const Property*) const override;
141 };
142 
143 #ifndef SWIG
144 template <typename T>
145 Base::Type PropertyTypedLinkList<T>::classTypeId = Base::Type().createType(Base::Type::badType(), TypeName<PropertyTypedLinkList<T>>::Get());
146 #endif
147 
148 // implementation
149 
150 template <typename T>
152 {
153  return std::find(_linkList.begin(), _linkList.end(), link) != _linkList.end();
154 }
155 
156 template <typename T>
158 {
159  if (const PropertyTypedLinkList<T>* other = dynamic_cast<const PropertyTypedLinkList<T>*>(p))
160  return _linkList == other->_linkList;
161 
162  return false;
163 }
164 
165 template <typename T>
167 {
168  if(!link)
169  return;
170 
171  aboutToSetValue();
172  if (link)
173  link->ref();
174  onAddLink( link );
175  _linkList.push_back(link);
176  hasSetValue();
177 }
178 
179 template <typename T>
181 {
182 
183  if (!link)
184  return false;
185  if(!hasLink(link))
186  return false;
187 
188  link->unref();
189  aboutToSetValue();
190  onRemoveLink(link );
191  _linkList.remove(link);
192  hasSetValue();
193  return true;
194 }
195 
196 template <typename T>
198 {
199  aboutToSetValue();
200  for (Core::DocObject* link : _linkList)
201  {
202  if (link)
203  link->unref();
204  }
205 
206  onRemoveLinks( _linkList );
207  _linkList = *(const std::list<Core::DocObject*>*)(&list);
208  onAddLinks( _linkList) ;
209 
210  for (Core::DocObject* link : _linkList)
211  {
212  if (link)
213  link->ref();
214  }
215  hasSetValue();
216 }
217 
218 template <typename T>
220 {
222  {
223  std::list<Core::DocObject*> linkList = value.toLinkList();
224  for (Core::DocObject* o : linkList)
225  {
226  if (o && !dynamic_cast<T>(o))
227  {
228  cDebug("ERROR: Cannot set Core::PropertyTypedLinkList value");
229  return false;
230  }
231  }
232  setValue(*(const std::list<T>*)(&linkList));
233  return true;
234  }
235 
236  cDebug("ERROR: Cannot set Core::PropertyTypedLinkList value");
237  return false;
238 }
239 
240 template <typename T>
242 {
243  assert(p->getTypeId() == getTypeId() && "Wrong property type!");
244  if (p->getTypeId() == getTypeId())
245  {
247  setValue(other->getValue());
248  }
249 }
250 
251 template <typename T>
253 {
254  aboutToSetValue();
255  for (Core::DocObject* link : _linkList)
256  {
257  if (link)
258  link->unref();
259  }
260 
261  onRemoveLinks(_linkList);
262  _linkList.clear();
263  hasSetValue();
264 }
265 
266 template <typename T>
268 {
269  UNUSED(version);
270  std::vector<Core::DocObject*> toSave;
271  for (Core::DocObject* obj : _linkList)
272  {
273  if (!obj)
274  {
275  // can nullptr be valid? -mh-
276  toSave.push_back(obj);
277  }
278  else if (obj && (!obj->isTemporary() || obj->mustbeSaved()))
279  {
280  toSave.push_back(obj);
281  }
282  }
283 
284  writer << "<Link size=\"" << toSave.size() << "\"/>";
285 
286  for (Core::DocObject* link : toSave)
287  {
288  writer << "<Link value=\"" << (link ? link->getId() : std::string()) << "\"/>";
289  }
290 }
291 
292 template <typename T>
294 {
295  UNUSED(version);
296  _linkList.clear();
297  reader.readElement("Link");
298  int size = (reader.getAttributeAsInteger(L"size"));
299 
300  for (int i = 0; i < size; i++)
301  {
302  reader.readElement("Link");
303 
304  Base::String value = reader.getAttribute(L"value");
305  std::string id = Base::StringTool::toQString(value).toUtf8().constData();
306  if (!id.empty())
307  {
308  Core::CoreDocument* cd = ((Core::DocObject*)getContainer())->getDocument();
309  T link = dynamic_cast<T>(cd->getObjectById(id));
310  if (link)
311  {
312  link->ref();
313  onAddLink( (Core::DocObject*) link );
314  _linkList.push_back(link);
315  }
316  else
317  {
318  cDebug("Error: Core::PropertyLinkList::restore ExecObject: %s not found!", id.c_str());
319  }
320  }
321  }
322 }
323 
324 DECLARE_PROPERTY_FACTORY(PropertyLinkBase_Factory, Core::PropertyLinkBase);
325 DECLARE_PROPERTY_FACTORY(PropertyLinkSetBase_Factory, Core::PropertyLinkSetBase);
326 DECLARE_PROPERTY_FACTORY(PropertyLinkList_Factory, Core::PropertyLinkList);
327 
328 } // namespace Core
static QString toQString(const Base::String &str)
Converts a Base::String to a QString.
Definition: PropertyLink.h:19
LX_BASE_EXPORT Base::LogClass cDebug()
void onAddLinks(PropertyLinkBaseBase *p, Core::DocObject *from, const std::list< Core::DocObject * > &linkList)
Definition: Persistence.h:14
virtual Base::String getAttribute(const char *AttrName) const =0
Definition: Object_Hnd.h:16
virtual long getAttributeAsInteger(const char *AttrName) const =0
virtual void readElement(const char *ElementName=0)=0
Core::PropertyText name
Definition: CoreDocument.h:167
virtual Type getTypeId(void) const
bool canConvert(Variant::Type t) const
A Utf-16 (windows) or ucs4 (unix) encoded string class.
Definition: String.h:23
LX_CORE_EXPORT Version & version
Definition: Type.h:52
Definition: CoreDocument.h:210
Definition: Variant.h:87
std::list< Core::DocObject * > toLinkList(bool *ok=nullptr) const
#define UNUSED(expr)
Definition: Enums.h:12
Status getStatus() const
Definition: AbstractXMLReader.h:7
static const char * Get()
Definition: PropertyLink.h:21
static const Type createType(const Type parent, const char *name, instantiationMethod method=0)
Definition: Base.h:12
void onRemoveLinks(PropertyLinkBaseBase *p, Core::DocObject *from, const std::list< Core::DocObject * > &linkList)
Definition: Writer.h:16
virtual uint64_t size()
Definition: Writer.h:69
void onAddLink(PropertyLinkBaseBase *p, Core::DocObject *from, Core::DocObject *o)
Definition: Variant.h:161
static const Type badType(void)
Definition: Type.h:99
Definition: Property.h:77
void onRemoveLink(PropertyLinkBaseBase *p, Core::DocObject *from, Core::DocObject *o)
TYPESYSTEM_HEADER()
DECLARE_PROPERTY_FACTORY(PropertyAxis1_Factory, Core::PropertyAxis1)
Definition: DocObject.h:51