00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef KLFPOBJ_H
00026 #define KLFPOBJ_H
00027
00028 #include <QDebug>
00029 #include <QVariant>
00030 #include <QByteArray>
00031 #include <QDataStream>
00032 #include <QTextStream>
00033 #include <QVector>
00034 #include <QList>
00035 #include <QMap>
00036 #include <QStringList>
00037
00038 #include <klfdefs.h>
00039
00040
00041
00042
00058 class KLF_EXPORT KLFAbstractPropertizedObject
00059 {
00060 public:
00061 KLFAbstractPropertizedObject();
00062 virtual ~KLFAbstractPropertizedObject();
00063
00071 virtual QString objectKind() const = 0;
00072
00077 virtual QVariant property(const QString& propName) const = 0;
00078
00084 virtual QStringList propertyNameList() const = 0;
00085
00097 virtual bool setProperty(const QString& pname, const QVariant& value) = 0;
00098
00099
00108 virtual QMap<QString,QVariant> allProperties() const;
00109
00124 virtual bool setAllProperties(const QMap<QString,QVariant>& data);
00125
00129 virtual bool hasFixedTypes() const { return false; }
00130
00135 virtual QByteArray typeNameFor(const QString& property) const { Q_UNUSED(property); return QByteArray(); }
00136
00144 virtual QByteArray typeSpecificationFor(const QString& property) const { Q_UNUSED(property); return QByteArray(); }
00145 };
00146
00147
00148 class KLF_EXPORT KLFSpecifyableType
00149 {
00150 public:
00151 KLFSpecifyableType();
00152 virtual ~KLFSpecifyableType();
00153
00154 virtual QByteArray specification() const = 0;
00155 virtual bool setSpecification(const QByteArray& data) = 0;
00156 };
00157
00158
00159 class KLF_EXPORT KLFEnumType : public KLFSpecifyableType
00160 {
00161 int val;
00162 QStringList enumVals;
00163 public:
00164 KLFEnumType(int initvalue = 0) : val(initvalue), enumVals()
00165 {
00166 }
00167 KLFEnumType(const KLFEnumType& copy) : KLFSpecifyableType(), val(copy.val), enumVals(copy.enumVals)
00168 {
00169 }
00170 virtual ~KLFEnumType() { }
00171
00172 inline int value() const
00173 {
00174 return val;
00175 }
00176 inline void setValue(int v)
00177 {
00178 val = v;
00179 }
00180
00181 inline QString enumValue() const
00182 {
00183 if (val < 0 || val >= enumVals.size()) {
00184 klfWarning("Invalid value: "<<val<<" for enum values "<<enumVals) ;
00185 return QString();
00186 }
00187 return enumVals[val];
00188 }
00189
00190
00191 inline QStringList enumValues() const
00192 {
00193 return enumVals;
00194 }
00195 inline void setEnumValues(const QStringList& list)
00196 {
00197 enumVals = list;
00198 }
00199
00200 QByteArray specification() const
00201 {
00202 return enumVals.join(":").toUtf8();
00203 }
00204
00205 bool setSpecification(const QByteArray& data)
00206 {
00207
00208 setEnumValues(QString::fromUtf8(data).split(QRegExp(":")));
00209 return true;
00210 }
00211
00212 };
00213
00214
00215 Q_DECLARE_METATYPE(KLFEnumType) ;
00216
00217 KLF_EXPORT QDataStream& operator<<(QDataStream& stream, const KLFEnumType& e);
00218 KLF_EXPORT QDataStream& operator>>(QDataStream& stream, KLFEnumType& e);
00219
00220 inline bool operator==(const KLFEnumType& a, const KLFEnumType& b)
00221 { return a.value() == b.value(); }
00222
00223
00224
00225
00226 class KLFPObjPropRefHelper;
00227
00228
00277 class KLF_EXPORT KLFPropertizedObject : public KLFAbstractPropertizedObject
00278 {
00279 public:
00283 explicit KLFPropertizedObject(const QString& propertyNameSpace);
00284 virtual ~KLFPropertizedObject();
00285
00294 virtual QVariant property(const QString& propName) const;
00304 virtual QVariant property(int propId) const;
00315 virtual QVariant property(const QString& propName, const QVariant& defaultValue) const;
00323 virtual bool hasPropertyValue(const QString& propName) const;
00331 virtual bool hasPropertyValue(int propId) const;
00332
00341 QList<int> propertyIdList() const;
00342
00349 QStringList propertyNameList() const;
00350
00355 QMap<QString,QVariant> allProperties() const;
00356
00369 virtual bool setProperty(const QString& propname, const QVariant& value);
00370
00376 virtual bool setProperty(int propId, const QVariant& value);
00377
00387 virtual bool setAllProperties(const QMap<QString, QVariant>& propValues);
00388
00389
00399 QDataStream& streamInto(QDataStream& stream) const;
00400
00407 QDataStream& streamFrom(QDataStream& stream);
00408
00409
00416 QByteArray allPropertiesToByteArray() const;
00417
00424 void setAllPropertiesFromByteArray(const QByteArray& data);
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00457 enum ToStringFlag {
00458 ToStringUseHtml = 0x0001,
00459 ToStringUseHtmlDiv = 0x0002,
00460 ToStringQuoteValues = 0x0004,
00461 ToStringAllProperties = 0x0008
00462 };
00467 virtual QString toString(uint toStringFlags = 0) const;
00468
00470
00472 int propertyMaxId() const;
00474
00477 bool propertyIdRegistered(int propId) const;
00479
00482 bool propertyNameRegistered(const QString& propertyName) const;
00484
00487 int propertyIdForName(const QString& propertyName) const;
00489
00492 QString propertyNameForId(int propId) const;
00494
00497 QList<int> registeredPropertyIdList() const;
00499
00502 QStringList registeredPropertyNameList() const;
00504
00507 QMap<QString, int> registeredProperties() const;
00508
00509 virtual QString objectKind() const { return pPropNameSpace; }
00510
00511 protected:
00512
00522 virtual void propertyValueChanged(int propId, const QVariant& oldValue,
00523 const QVariant& newValue);
00524
00525
00530 virtual bool doSetProperty(const QString& propname, const QVariant& value);
00531
00536 virtual bool doSetProperty(int propId, const QVariant& value);
00537
00543 virtual int doLoadProperty(const QString& propname, const QVariant& value);
00544
00548 void registerBuiltInProperty(int propId, const QString& propName) const;
00549
00554 int registerProperty(const QString& propertyName) const;
00555
00605 static void registerBuiltInProperty(const QString& propNameSpace, int propId,
00606 const QString& name);
00607
00621 static int registerProperty(const QString& propNameSpace, const QString& propertyName);
00622
00630 static int propertyMaxId(const QString& propNameSpace);
00631
00639 static bool propertyIdRegistered(const QString& propNameSpace, int propId);
00640
00648 static bool propertyNameRegistered(const QString& propNameSpace, const QString& propertyName);
00649
00662 static int propertyIdForName(const QString& propNameSpace, const QString& propertyName);
00663
00671 static QString propertyNameForId(const QString& propNameSpace, int propId);
00672
00679 static QList<int> registeredPropertyIdList(const QString& propNameSpace);
00680
00687 static QStringList registeredPropertyNameList(const QString& propNameSpace);
00688
00695 static QMap<QString, int> registeredProperties(const QString& propNameSpace);
00696
00697 QString propertyNameSpace() const { return pPropNameSpace; }
00698
00699 QVector<QVariant> propertyVector() const { return pProperties; }
00700
00701
00702 friend class KLFPObjPropRefHelper;
00703
00704 private:
00706 KLFPropertizedObject() { }
00707
00708 QString pPropNameSpace;
00709
00710 QVector<QVariant> pProperties;
00711
00715 static int internalRegisterProperty(const QString& propNameSpace, const QString& name,
00716 int propId = -1);
00717 static QMap<QString, QMap<QString, int> > pRegisteredProperties;
00718 static QMap<QString, int> pRegisteredPropertiesMaxId;
00719
00720 friend bool operator==(const KLFPropertizedObject& a, const KLFPropertizedObject& b);
00721 };
00722
00726 bool operator==(const KLFPropertizedObject& a, const KLFPropertizedObject& b);
00727
00731 KLF_EXPORT QDataStream& operator<<(QDataStream& stream, const KLFPropertizedObject& obj);
00735 KLF_EXPORT QDataStream& operator>>(QDataStream& stream, KLFPropertizedObject& obj);
00736
00737 KLF_EXPORT QTextStream& operator<<(QTextStream& stream, const KLFPropertizedObject& obj);
00738
00739 KLF_EXPORT QDebug& operator<<(QDebug& stream, const KLFPropertizedObject& obj);
00740
00741
00746 class KLFPObjPropRefHelper
00747 {
00748 protected:
00749 void registerbuiltinprop(KLFPropertizedObject *obj, int propid, const QString& pname)
00750 {
00751 obj->registerBuiltInProperty(propid, pname);
00752 }
00753 QString propertyNameSpace(KLFPropertizedObject *obj) const { return obj->propertyNameSpace(); }
00754 };
00755
00756 template<class T>
00757 class KLF_EXPORT KLFPObjPropRef : private KLFPObjPropRefHelper
00758 {
00759 KLFPropertizedObject *pPObj;
00760 int pPropId;
00761 public:
00762 typedef T Type;
00763
00764 KLFPObjPropRef(KLFPropertizedObject *pobj, int propId)
00765 : pPObj(pobj), pPropId(propId)
00766 {
00767 }
00768 KLFPObjPropRef(const KLFPObjPropRef& other)
00769 : pPObj(other.pPObj), pPropId(other.pPropId)
00770 {
00771 }
00778 KLFPObjPropRef(KLFPropertizedObject *pobj, int builtInPropId, const QString& pname)
00779 : pPObj(pobj), pPropId(builtInPropId)
00780 {
00781 init(pname);
00782 }
00789 KLFPObjPropRef(KLFPropertizedObject *pobj, int builtInPropId, const QString& pname, const T& value)
00790 : pPObj(pobj), pPropId(builtInPropId)
00791 {
00792 init(pname);
00793 set(value);
00794 }
00795
00796 operator QVariant() const
00797 {
00798 return variantValue();
00799 }
00800 operator T() const
00801 {
00802 return value<T>();
00803 }
00804 const T operator ()() const
00805 {
00806 return value<T>();
00807 }
00808 const KLFPObjPropRef& operator=(const QVariant& v)
00809 {
00810 pPObj->setProperty(pPropId, v);
00811 return *this;
00812 }
00813 const KLFPObjPropRef& operator=(const T& value)
00814 {
00815 pPObj->setProperty(pPropId, QVariant::fromValue<T>(value));
00816 return *this;
00817 }
00819 const KLFPObjPropRef& operator=(const KLFPObjPropRef& value)
00820 {
00821 return this->operator=(value.value());
00822 }
00823
00824 QVariant variantValue() const
00825 {
00826 return pPObj->property(pPropId);
00827 }
00828
00829 const T value() const
00830 {
00831 return value<T>();
00832 }
00833
00834 template<class VariantType>
00835 const T value() const
00836 {
00837 QVariant v = pPObj->property(pPropId);
00838 return T(v.value<VariantType>());
00839 }
00840
00841 template<class VariantType>
00842 void set(const T& value)
00843 {
00844 pPObj->setProperty(pPropId, QVariant::fromValue<VariantType>(value));
00845 }
00846 void set(const T& value)
00847 {
00848 set<T>(value);
00849 }
00850
00851 template<class VariantType>
00852 bool equals(const KLFPObjPropRef& other) const
00853 {
00854 return (value<VariantType>() == other.value<VariantType>());
00855 }
00856 bool equals(const KLFPObjPropRef& other) const
00857 {
00858 return equals<T>(other);
00859 }
00860
00861 bool operator==(const T& val) const
00862 {
00863 return (value() == val);
00864 }
00865 bool operator==(const KLFPObjPropRef& other) const
00866 {
00867 return (value() == other.value());
00868 }
00869
00870 private:
00871 void init(const QString& pname)
00872 {
00873 if (!pPObj->propertyIdRegistered(pPropId)) {
00874
00875 registerbuiltinprop(pPObj, pPropId, pname);
00876 } else {
00877
00878 KLF_ASSERT_CONDITION(pPObj->propertyNameForId(pPropId) == pname,
00879 qPrintable(propertyNameSpace(pPObj))<<": Built-In property ID "<<pPropId
00880 <<" does not have name "<<pname<<" !",
00881 ; ) ;
00882 }
00883 }
00884
00885 };
00886
00887 template<typename T>
00888 inline QDebug & operator<<(QDebug & str, const KLFPObjPropRef<T> & p)
00889 {
00890 return str << p();
00891 }
00892
00893
00894
00895
00896
00898 class KLFPObjRegisteredType {
00899 public:
00900 KLFPObjRegisteredType(const char *name)
00901 {
00902 doregister(Register, name);
00903 }
00904
00905 static bool isRegistered(const char *name)
00906 {
00907 return doregister(Query, name);
00908 }
00909
00910 private:
00911 enum Action { Query, Register };
00912 static int doregister(Action action, const char * name)
00913 {
00914 static QList<QByteArray> registered_types;
00915 bool x;
00916 switch (action) {
00917 case Query:
00918 x = registered_types.contains(QByteArray(name));
00919 return x;
00920 case Register:
00921 registered_types.append(QByteArray(name));
00922 return 0;
00923 default:
00924 fprintf(stderr, "ERRORORROOERROR: %s: what is your action?? `%d' for name `%s'\n",
00925 KLF_FUNC_NAME, (int)action, name);
00926 }
00927 return -1;
00928 }
00929 };
00930
00936 #define KLF_DECLARE_POBJ_TYPE(TYPE) \
00937 static KLFPObjRegisteredType __klf_pobj_regtype_##TYPE = KLFPObjRegisteredType(#TYPE) ;
00938
00940 class KLFSpecifyableRegisteredType {
00941 public:
00942 KLFSpecifyableRegisteredType(const char *name)
00943 {
00944 doregister(Register, name);
00945 }
00946
00947 static bool isRegistered(const char *name)
00948 {
00949 return doregister(Query, name);
00950 }
00951
00952 private:
00953 enum Action { Query, Register };
00954 static int doregister(Action action, const char * name)
00955 {
00956 static QList<QByteArray> registered_types;
00957 bool x;
00958 switch (action) {
00959 case Query:
00960 x = registered_types.contains(QByteArray(name));
00961 return x;
00962 case Register:
00963 registered_types.append(QByteArray(name));
00964 return 0;
00965 default:
00966 fprintf(stderr, "ERRORORROORORR: %s: what is your action?? `%d' for name `%s'\n",
00967 KLF_FUNC_NAME, (int)action, name);
00968 }
00969 return -1;
00970 }
00971 };
00972
00974 #define KLF_DECLARE_SPECIFYABLE_TYPE(TYPE) \
00975 static KLFSpecifyableRegisteredType __klf_specifyable_regtype_##TYPE = KLFSpecifyableRegisteredType(#TYPE) ;
00976
00977
00978
00979 #endif