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