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