Revert " modify license, permission and remove ^M char"
[framework/osp/uifw.git] / src / ui / inc / FUi_PropertyBase.h
1 //
2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Flora License, Version 1.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://floralicense.org/license/
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an AS IS BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 /**
18  * @file                FUi_PropertyBase.h
19  * @brief               This is the header file for the _PropertyBase class.
20  *
21  * This header file contains declarations of the _PropertyBase class. @n
22  */
23 #ifndef _FUI_INTERNAL_PROPERTYBASE_H_
24 #define _FUI_INTERNAL_PROPERTYBASE_H_
25
26 #include <FOspConfig.h>
27 #include <FBaseTypes.h>
28 #include <FBaseObject.h>
29 #include <FBaseColHashMap.h>
30 #include <FUiVariant.h>
31 #include <FBaseSysLog.h>
32 #include "FUi_IPropertyChangeEventListener.h"
33 #include "FUi_PropertyUtils.h"
34
35 enum _PropertyType
36 {
37         READ_ONLY = 0,
38         WRITE_ONLY,
39         READ_WRITE
40 };
41
42 namespace Tizen { namespace Ui
43 {
44
45 #define DECLARE_CLASS_BEGIN(classType, superClassType) \
46 public: \
47         typedef classType _THISCLASS; \
48         typedef superClassType _SUPERCLASS;     \
49         class __register_property_class__ \
50                 : public Tizen::Ui::_RegisterPropertyBase \
51         { \
52 public: \
53                 __register_property_class__() \
54                 {
55
56 #define DECLARE_PROPERTY(Name, GetName, SetName) \
57         { \
58                 _RegisterPropertyBase::RegisterProperty<_THISCLASS>(Name, &_THISCLASS::GetName, &_THISCLASS::SetName); \
59         }
60
61 #define DECLARE_READONLY_PROPERTY(Name, GetName) \
62         { \
63                 _RegisterPropertyBase::RegisterProperty<_THISCLASS>(Name, &_THISCLASS::GetName, null); \
64         }
65
66 #define DECLARE_WRITEONLY_PROPERTY(Name, SetName) \
67         { \
68                 _RegisterPropertyBase::RegisterProperty<_THISCLASS>(Name, null, &_THISCLASS::SetName); \
69         }
70
71 #define DECLARE_CLASS_END() \
72         } \
73         virtual ~__register_property_class__(void) { } \
74         }; \
75 public: \
76         static __register_property_class__ _registerPropertyClass; \
77         virtual result SetProperty(const Tizen::Base::String & name, const Tizen::Ui::Variant &value) \
78         { \
79                 ClearLastResult(); \
80                 result r = E_SUCCESS; \
81                 if (IsPropertyChangeEventListenerAdded()) \
82                 { \
83                         bool returnValue = _registerPropertyClass.IsPropertyAvailable<_THISCLASS>(this, name); \
84                         if (returnValue) \
85                         { \
86                                 Tizen::Ui::Variant oldValue(GetProperty(name)); \
87                                 _PropertyBase::FirePropertyEvent(*this, name, oldValue, value, false); \
88                                 r = _registerPropertyClass.SetProperty<_THISCLASS>(this, name, value); \
89                                 SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r)); \
90                                 _PropertyBase::FirePropertyEvent(*this, name, oldValue, value, true); \
91                         } \
92                         else \
93                         { \
94                                 r = _SUPERCLASS::SetProperty(name, value); \
95                                 return r; \
96                         } \
97                 } \
98                 else \
99                 { \
100                         r = _registerPropertyClass.SetProperty<_THISCLASS>(this, name, value); \
101                         if (r == E_KEY_NOT_FOUND) \
102                         { \
103                                 r = _SUPERCLASS::SetProperty(name, value); \
104                                 return r; \
105                         } \
106                 } \
107                 if (r != E_KEY_NOT_FOUND) \
108                 { \
109                         SysTryReturn(NID_UI, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r)); \
110                 } \
111                 return r; \
112         } \
113         virtual Tizen::Ui::Variant GetProperty(const Tizen::Base::String & name) const { \
114                 ClearLastResult(); \
115                 Tizen::Ui::Variant returnValue = _registerPropertyClass.GetProperty<_THISCLASS>(this, name);    \
116                 if (GetLastResult() == E_KEY_NOT_FOUND) \
117                 { \
118                         returnValue = _SUPERCLASS::GetProperty(name); \
119                         return returnValue;     \
120                 } \
121                 else \
122                 { \
123                         result r = GetLastResult();\
124                         SysTryReturn(NID_UI, r == E_SUCCESS, returnValue, r, "[%s] Propagating.", GetErrorMessage(r)); \
125                 } \
126                 return returnValue;     \
127         }
128
129 #define IMPLEMENT_PROPERTY(classType) \
130         classType::__register_property_class__ classType::_registerPropertyClass;
131
132 template<typename OwnType>
133 class _Property
134         : public Tizen::Base::Object
135 {
136 public:
137         typedef result (OwnType::*SetterType)(const Variant& value);
138         typedef Variant (OwnType::*GetterType)(void) const;
139
140         _Property(void)
141                 : __setter(null)
142                 , __getter(null)
143         {
144         }
145         virtual ~_Property(void)
146         {
147         }
148
149         void Register(GetterType getter, SetterType setter) { __setter = setter; __getter = getter; }
150         Variant GetProperty(const Object* pObject) const
151         {
152                 return Variant((((OwnType*) pObject)->*__getter)());
153         }
154         result SetProperty(const Object* pObject, const Variant& value)
155         {
156                 OwnType* pOwnType = (OwnType*) pObject;
157                 return (pOwnType->*__setter)(value);
158         }
159         bool IsReadOnly(void) const { return __setter == null; }
160         bool IsWriteOnly(void) const { return __getter == null; }
161
162 private:
163         SetterType __setter;
164         GetterType __getter;
165 }; // _Property
166
167 class _RegisterPropertyBase
168         : public Tizen::Base::Object
169 {
170 public:
171         _RegisterPropertyBase()
172         {
173                 __pHashMap = null;
174         }
175         virtual ~_RegisterPropertyBase(void)
176         {
177                 if (__pHashMap)
178                 {
179                         __pHashMap->RemoveAll(true);
180                         delete __pHashMap;
181                 }
182         }
183
184         template<class OwnType>
185         result SetProperty(const Object* pObject, const Tizen::Base::String& name, const Variant& value)
186         {
187                 ClearLastResult();
188
189                 Tizen::Base::Collection::HashMap* pMap = GetHashMap();
190                 _Property<OwnType>* pProperty = null;
191                 if (pMap != null)
192                 {
193                         pProperty = static_cast<_Property<OwnType>*>(pMap->GetValue(name));
194                         if (pProperty != null)
195                         {
196                                 SysTryReturn(NID_UI, !pProperty->IsReadOnly(), E_INVALID_OPERATION, E_INVALID_OPERATION, "[%s] Propagating.", GetErrorMessage(GetLastResult()));
197                                 return pProperty->SetProperty(pObject, value);
198                         }
199                 }
200                 return E_KEY_NOT_FOUND;
201         }
202
203         template<class OwnType>
204         Variant GetProperty(const Object* pObject, const Tizen::Base::String& name) const
205         {
206                 ClearLastResult();
207
208                 Tizen::Base::Collection::HashMap* pMap = GetHashMap();
209                 _Property<OwnType>* pProperty = null;
210                 if (pMap != null)
211                 {
212                         pProperty = static_cast<_Property<OwnType>*>(pMap->GetValue(name));
213                         if (pProperty != null)
214                         {
215                                 SysTryReturn(NID_UI, !pProperty->IsWriteOnly(), Variant(), E_INVALID_OPERATION, "[%s] Propagating.", GetErrorMessage(GetLastResult()));
216                                 return pProperty->GetProperty(pObject);
217                         }
218                         else
219                         {
220                                 SetLastResult(E_KEY_NOT_FOUND);
221                         }
222                 }
223
224                 return Variant::NULL_VARIANT;
225         }
226
227         template<class OwnType>
228         bool IsPropertyAvailable(const Object* pObject, const Tizen::Base::String& name) const
229         {
230                 Tizen::Base::Collection::HashMap* pMap = GetHashMap();
231                 _Property<OwnType>* pProperty = null;
232                 if (pMap != null)
233                 {
234                         pProperty = static_cast<_Property<OwnType>*>(pMap->GetValue(name));
235                         if (pProperty != null)
236                         {
237                                 return true;
238                         }
239                 }
240
241                 return false;
242         }
243
244         template<class OwnType>
245         void RegisterProperty(const Tizen::Base::String& propertyName, typename _Property<OwnType>::GetterType getter, typename _Property<OwnType>::SetterType setter)
246         {
247                 ClearLastResult();
248                 result r = E_SUCCESS;
249
250                 Tizen::Base::Collection::HashMap* pMap = GetHashMap();
251                 if (pMap != null)
252                 {
253                         // create the property name key in the HashMap
254                         bool hasKey = true;
255                         r = pMap->ContainsKey(propertyName, hasKey);
256                         if (!IsFailed(r) && hasKey == false)
257                         {
258                                 _Property<OwnType>* pProperty = new (std::nothrow) _Property<OwnType>;
259                                 if (pProperty == null)
260                                 {
261                                         SysLog(NID_UI, "[E_OUT_OF_MEMORY] Unable to create _Property.");
262                                         SetLastResult(E_OUT_OF_MEMORY);
263                                         return;
264                                 }
265                                 pProperty->Register(getter, setter);
266                                 pMap->Add(*(new (std::nothrow) Tizen::Base::String(propertyName)), *pProperty);
267                         }
268                 }
269         }
270
271         result InitHashMap(void)
272         {
273                 result r = E_SUCCESS;
274
275                 if (__pHashMap == null)
276                 {
277                         __pHashMap = new (std::nothrow) Tizen::Base::Collection::HashMap;
278                         if (__pHashMap == null)
279                         {
280                                 return E_OUT_OF_MEMORY;
281                         }
282
283                         r = __pHashMap->Construct(16, 0.75f, *_PropertyUtils::GetInstance()->GetStringHashProvider(), *_PropertyUtils::GetInstance()->GetStringComparer());
284                 }
285
286                 return r;
287         }
288
289         Tizen::Base::Collection::HashMap* GetHashMap(void) const
290         {
291                 result r = E_SUCCESS;
292
293                 _RegisterPropertyBase& thisObject = const_cast<_RegisterPropertyBase&>(*this);
294                 if (__pHashMap == null)
295                 {
296                         r = thisObject.InitHashMap();
297                         if (r != E_SUCCESS)
298                         {
299                                 SysLog(NID_UI, "[E_OUT_OF_MEMORY] Unable to create HashMap.");
300                                 SetLastResult(E_OUT_OF_MEMORY);
301                                 return null;
302                         }
303                 }
304                 return __pHashMap;
305         }
306
307 private:
308         _RegisterPropertyBase(const _RegisterPropertyBase&);
309         _RegisterPropertyBase& operator =(const _RegisterPropertyBase&);
310         Tizen::Base::Collection::HashMap* __pHashMap;
311 }; // _RegisterPropertyBase
312
313 class _OSP_EXPORT_ _PropertyBase
314         : public Tizen::Base::Object
315 {
316 public:
317         _PropertyBase(void);
318         virtual ~_PropertyBase(void);
319
320         virtual result SetProperty(const Tizen::Base::String& name, const Variant& value);
321         virtual Variant GetProperty(const Tizen::Base::String& name) const;
322
323         result AddPropertyChangeEventListener(const Tizen::Ui::_IPropertyChangeEventListener& listener);
324         result RemovePropertyChangeEventListener(const Tizen::Ui::_IPropertyChangeEventListener& listener);
325         result SetPropertyChangeEventListener(const Tizen::Ui::_IPropertyChangeEventListener* pListener);
326         bool FirePropertyEvent(const Tizen::Ui::_PropertyBase& source, const Tizen::Base::String& name, const Variant& oldValue, const Variant& newValue, bool isChangedEvent = false);
327         bool IsPropertyChangeEventListenerAdded(void) const;
328
329 private:
330         _PropertyBase(const _PropertyBase&);
331         _PropertyBase& operator =(const _PropertyBase&);
332         Tizen::Ui::_IPropertyChangeEventListener* __pPropertyChangeEventListener;
333 }; // _PropertyBase
334
335 } } // Tizen::Ui
336
337 #endif //_FUI_INTERNAL_PROPERTYBASE_H_
338