[KLF Backend][KLF Tools][KLF Home]
KLatexFormula Project
src/klftools/klfpobj.h
Go to the documentation of this file.
00001 /***************************************************************************
00002  *   file klfpobj.h
00003  *   This file is part of the KLatexFormula Project.
00004  *   Copyright (C) 2011 by Philippe Faist
00005  *   philippe.faist at bluewin.ch
00006  *                                                                         *
00007  *   This program is free software; you can redistribute it and/or modify  *
00008  *   it under the terms of the GNU General Public License as published by  *
00009  *   the Free Software Foundation; either version 2 of the License, or     *
00010  *   (at your option) any later version.                                   *
00011  *                                                                         *
00012  *   This program is distributed in the hope that it will be useful,       *
00013  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00014  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00015  *   GNU General Public License for more details.                          *
00016  *                                                                         *
00017  *   You should have received a copy of the GNU General Public License     *
00018  *   along with this program; if not, write to the                         *
00019  *   Free Software Foundation, Inc.,                                       *
00020  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00021  ***************************************************************************/
00022 /* $Id$ */
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     // parse enum values
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 // exact matches
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   / ** \brief Parses a string representation of a property
00428    *
00429    * Subclasses should reimplement this function to parse the actual string into a value. Note
00430    * that this function should NOT set the property, it should just parse the string in a way
00431    * depending on what kind of information the property \c propId is supposed to store.
00432    *
00433    * The formatting is left to the implementation. It could be user input, for example.
00434    *
00435    * The default implementation calls \ref parsePropertyValue(const QString&, const QString&) .
00436    * It is thus enough for subclasses to reimplement the other method.
00437    * /
00438    virtual QVariant parsePropertyValue(int propId, const QString& strvalue);
00439 
00440    / ** \brief Parses a string representation of a property
00441    *
00442    * Subclasses should reimplement this function to parse the actual string into a value. Note
00443    * that this function should NOT set the property, it should just parse the string in a way
00444    * depending on what kind of information the property \c propName is supposed to store.
00445    *
00446    * The formatting is left to the implementation. It could be user input, for example.
00447    *
00448    * Since the base implementation has no idea what kind of information \c propId is supposed
00449    * to store, the default implementation returns a null \c QVariant().
00450    * /
00451    virtual QVariant parsePropertyValue(const QString& propName, const QString& strvalue);
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       // from our helper base class
00875       registerbuiltinprop(pPObj, pPropId, pname);
00876     } else {
00877       // make sure the correct name was registered
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: // is querying the existance of a registered type
00918       x = registered_types.contains(QByteArray(name));
00919       return x;
00920     case Register: // want to register the given type
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: // is querying the existance of a registered type
00960       x = registered_types.contains(QByteArray(name));
00961       return x;
00962     case Register: // want to register the given type
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

Generated by doxygen 1.7.6.1. The KLatexFormula website is hosted on sourceforge.net