tdegraphics/kpovmodeler/pmmetaobject.h

416 lines
13 KiB

/*
**************************************************************************
description
--------------------
copyright : (C) 2002 by Andreas Zehender
email : zehender@kde.org
**************************************************************************
**************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
**************************************************************************/
#ifndef PMMETAOBJECT_H
#define PMMETAOBJECT_H
#include <tqstring.h>
#include <tqstringlist.h>
#include <tqptrlist.h>
#include <tqdict.h>
#include "pmvariant.h"
class PMPart;
/**
* Base class for all properties
*/
class PMPropertyBase
{
public:
/**
* Default constructor
*/
PMPropertyBase( const TQString& name, PMVariant::PMVariantDataType t,
bool readOnly = false, bool writeOnly = false );
/**
* Copy constructor
*/
PMPropertyBase( const PMPropertyBase& p );
/**
* Destructor
*/
virtual ~PMPropertyBase( );
/**
* Returns the properties name
*/
TQString name( ) const { return m_name; }
/**
* Returns the data type
*/
PMVariant::PMVariantDataType type( ) const { return m_type; }
/**
* Sets the property.
*
* Returns true if successful.
*
* Makes a type check and calls @ref setProtected on success.
*/
bool setProperty( PMObject* obj, const PMVariant& );
/**
* Returns the property value
*/
PMVariant getProperty( const PMObject* obj );
/**
* Returns the number of dimensions for array properties
* or 0 otherwise
*/
virtual int dimensions( ) const { return 0; }
/**
* Has to be reimplemented for array properties.
*
* The first parameter is the dimension, the second the index.
*/
virtual void setIndex( int /*dimension*/, int /*index*/ ) { };
/**
* Has to be reimplemented for array properties.
*
* Returns the current size for the object and dimension.
*/
virtual int size( PMObject*, int /*dimension*/ ) const { return 0; }
/**
* Returns true if the property is an enum
*/
virtual bool isEnum( ) const { return false; }
/**
* Returns the list of enum values
*/
virtual TQStringList enumValues( ) const { return TQStringList( ); }
/**
* Returns true if the property is read-only. False by default
*/
bool isReadOnly( ) const { return m_readOnly; }
/**
* Returns true if the property is write-only. False by default
*/
bool isWriteOnly( ) const { return m_writeOnly; }
protected:
/**
* Reimplement this function to call the correct object method.
*
* The variant is already converted to the correct type.
*/
virtual bool setProtected( PMObject* obj, const PMVariant& ) = 0;
/**
* Reimplement this function to call the correct object method.
*/
virtual PMVariant getProtected( const PMObject* obj ) = 0;
private:
PMVariant::PMVariantDataType m_type;
TQString m_name;
TQStringList* m_pEnumList;
bool m_readOnly;
bool m_writeOnly;
};
typedef TQPtrList<PMPropertyBase> PMPropertyList;
typedef TQDict<PMPropertyBase> PMPropertyDict;
typedef TQDictIterator<PMPropertyBase> PMPropertyIterator;
/**
* Macro that defines a property class for a PMObject class
*
* Example: PMDefinePropertyClass( PMBox, PMProperty ); defines
* a class PMProperty that can store pointer to member functions
* for PMBox objects.
*
* Use only in .cpp files.
*/
#define PMDefinePropertyClass( ObjectClass, PropertyClass ) \
class PropertyClass : public PMPropertyBase \
{ \
public: \
typedef void ( ObjectClass::*SetIntPtr ) ( int ); \
typedef void ( ObjectClass::*SetUnsignedPtr ) ( unsigned ); \
typedef void ( ObjectClass::*SetDoublePtr ) ( double ); \
typedef void ( ObjectClass::*SetBoolPtr ) ( bool ); \
typedef void ( ObjectClass::*SetThreeStatePtr )( PMThreeState ); \
typedef void ( ObjectClass::*SetStringPtr ) ( const TQString& ); \
typedef void ( ObjectClass::*SetVectorPtr ) ( const PMVector& ); \
typedef void ( ObjectClass::*SetColorPtr ) ( const PMColor& ); \
typedef void ( ObjectClass::*SetObjectPtr ) ( PMObject* ); \
\
typedef int ( ObjectClass::*GetIntPtr ) ( void ) const; \
typedef unsigned ( ObjectClass::*GetUnsignedPtr ) ( void ) const; \
typedef double ( ObjectClass::*GetDoublePtr ) ( void ) const; \
typedef bool ( ObjectClass::*GetBoolPtr ) ( void ) const; \
typedef PMThreeState ( ObjectClass::*GetThreeStatePtr ) ( void ) const; \
typedef TQString ( ObjectClass::*GetStringPtr ) ( void ) const; \
typedef PMVector ( ObjectClass::*GetVectorPtr ) ( void ) const; \
typedef PMColor ( ObjectClass::*GetColorPtr ) ( void ) const; \
typedef PMObject* ( ObjectClass::*GetObjectPtr ) ( void ) const; \
\
PropertyClass( const TQString& name, SetIntPtr setFktn, GetIntPtr getFktn ) \
: PMPropertyBase( name, PMVariant::Integer, \
setFktn == 0, getFktn == 0 ) \
{ \
m_setFunction.setInt = setFktn; \
m_getFunction.getInt = getFktn; \
} \
PropertyClass( const TQString& name, SetUnsignedPtr setFktn, GetUnsignedPtr getFktn ) \
: PMPropertyBase( name, PMVariant::Unsigned, \
setFktn == 0, getFktn == 0 ) \
{ \
m_setFunction.setUnsigned = setFktn; \
m_getFunction.getUnsigned = getFktn; \
} \
PropertyClass( const TQString& name, SetDoublePtr setFktn, GetDoublePtr getFktn ) \
: PMPropertyBase( name, PMVariant::Double, \
setFktn == 0, getFktn == 0 ) \
{ \
m_setFunction.setDouble = setFktn; \
m_getFunction.getDouble = getFktn; \
} \
PropertyClass( const TQString& name, SetBoolPtr setFktn, GetBoolPtr getFktn ) \
: PMPropertyBase( name, PMVariant::Bool, \
setFktn == 0, getFktn == 0 ) \
{ \
m_setFunction.setBool = setFktn; \
m_getFunction.getBool = getFktn; \
} \
PropertyClass( const TQString& name, SetThreeStatePtr setFktn, GetThreeStatePtr getFktn ) \
: PMPropertyBase( name, PMVariant::ThreeState, \
setFktn == 0, getFktn == 0 ) \
{ \
m_setFunction.setThreeState = setFktn; \
m_getFunction.getThreeState = getFktn; \
} \
PropertyClass( const TQString& name, SetStringPtr setFktn, GetStringPtr getFktn ) \
: PMPropertyBase( name, PMVariant::String, \
setFktn == 0, getFktn == 0 ) \
{ \
m_setFunction.setString = setFktn; \
m_getFunction.getString = getFktn; \
} \
PropertyClass( const TQString& name, SetVectorPtr setFktn, GetVectorPtr getFktn ) \
: PMPropertyBase( name, PMVariant::Vector, \
setFktn == 0, getFktn == 0 ) \
{ \
m_setFunction.setVector = setFktn; \
m_getFunction.getVector = getFktn; \
} \
PropertyClass( const TQString& name, SetColorPtr setFktn, GetColorPtr getFktn ) \
: PMPropertyBase( name, PMVariant::Color, \
setFktn == 0, getFktn == 0 ) \
{ \
m_setFunction.setColor = setFktn; \
m_getFunction.getColor = getFktn; \
} \
PropertyClass( const TQString& name, SetObjectPtr setFktn, GetObjectPtr getFktn ) \
: PMPropertyBase( name, PMVariant::ObjectPointer, \
setFktn == 0, getFktn == 0 ) \
{ \
m_setFunction.setObject = setFktn; \
m_getFunction.getObject = getFktn; \
} \
\
protected: \
bool setProtected( PMObject* obj, const PMVariant& v ) \
{ \
ObjectClass* o = ( ObjectClass* ) obj; \
switch( type( ) ) \
{ \
case PMVariant::Integer: \
( o->*( m_setFunction.setInt ) )( v.intData( ) ); \
break; \
case PMVariant::Unsigned: \
( o->*( m_setFunction.setUnsigned ) )( v.unsignedData( ) ); \
break; \
case PMVariant::Double: \
( o->*( m_setFunction.setDouble ) )( v.doubleData( ) ); \
break; \
case PMVariant::Bool: \
( o->*( m_setFunction.setBool ) )( v.boolData( ) ); \
break; \
case PMVariant::ThreeState: \
( o->*( m_setFunction.setThreeState ) )( v.threeStateData( ) ); \
break; \
case PMVariant::String: \
( o->*( m_setFunction.setString ) )( v.stringData( ) ); \
break; \
case PMVariant::Vector: \
( o->*( m_setFunction.setVector ) )( v.vectorData( ) ); \
break; \
case PMVariant::Color: \
( o->*( m_setFunction.setColor ) )( v.colorData( ) ); \
break; \
case PMVariant::ObjectPointer: \
( o->*( m_setFunction.setObject ) )( v.objectData( ) ); \
break; \
case PMVariant::None: \
break; \
} \
return true; \
} \
\
PMVariant getProtected( const PMObject* obj ) \
{ \
const ObjectClass* o = ( const ObjectClass* ) obj; \
PMVariant result; \
\
switch( type( ) ) \
{ \
case PMVariant::Integer: \
result.setInt( ( o->*( m_getFunction.getInt ) )( ) ); \
break; \
case PMVariant::Unsigned: \
result.setUnsigned( ( o->*( m_getFunction.getUnsigned ) )( ) ); \
break; \
case PMVariant::Double: \
result.setDouble( ( o->*( m_getFunction.getDouble ) )( ) ); \
break; \
case PMVariant::Bool: \
result.setBool( ( o->*( m_getFunction.getBool ) )( ) ); \
break; \
case PMVariant::ThreeState: \
result.setThreeState( ( o->*( m_getFunction.getThreeState ) )( ) ); \
break; \
case PMVariant::String: \
result.setString( ( o->*( m_getFunction.getString ) )( ) ); \
break; \
case PMVariant::Vector: \
result.setVector( ( o->*( m_getFunction.getVector ) )( ) ); \
break; \
case PMVariant::Color: \
result.setColor( ( o->*( m_getFunction.getColor ) )( ) ); \
break; \
case PMVariant::ObjectPointer: \
result.setObject( ( o->*( m_getFunction.getObject ) )( ) ); \
break; \
case PMVariant::None: \
break; \
} \
return result; \
} \
\
private: \
union \
{ \
SetIntPtr setInt; \
SetUnsignedPtr setUnsigned; \
SetDoublePtr setDouble; \
SetBoolPtr setBool; \
SetThreeStatePtr setThreeState; \
SetStringPtr setString; \
SetVectorPtr setVector; \
SetColorPtr setColor; \
SetObjectPtr setObject; \
} m_setFunction; \
\
union \
{ \
GetIntPtr getInt; \
GetUnsignedPtr getUnsigned; \
GetDoublePtr getDouble; \
GetBoolPtr getBool; \
GetThreeStatePtr getThreeState; \
GetStringPtr getString; \
GetVectorPtr getVector; \
GetColorPtr getColor; \
GetObjectPtr getObject; \
} m_getFunction; \
}
// no semicolon, put a semicolon after the macro!
typedef PMObject* ( *PMObjectFactoryMethod ) ( PMPart* );
/**
* Meta information object for the @ref PMObject class.
*
* Stores information (class name, inheritance hierarchy,
* object properties) for each class.
*/
class PMMetaObject
{
public:
/**
* Creates a PMMetaObject. The class name has to be the class name
* without the PM prefix.
*
* factoryMethod is a function pointer to a factory method
* with signature PMObject* theMethod( PMPart* ) that returns
* a new object of that type. factoryMethod may be 0 for
* abstract classes.
*/
PMMetaObject( const TQString& className, PMMetaObject* superClass = 0,
PMObjectFactoryMethod factoryMethod = 0 );
/**
* Destructor
*/
~PMMetaObject( );
/**
* Returns the class name
*/
TQString className( ) const { return m_className; }
/**
* Returns the meta object of the super class
*/
PMMetaObject* superClass( ) const { return m_pSuperClass; }
/**
* Returns a new object instance
*/
PMObject* newObject( PMPart* part ) const;
/**
* Returns true if the class is an abstract class
* (if no factory method was set in the constructor)
*/
bool isAbstract( ) const { return m_factory == 0; }
/**
* Adds a property.
*
* The meta object becomes the owner of the property object
*/
void addProperty( PMPropertyBase* p );
/**
* Returns an iterator to the properties
*/
PMPropertyIterator properties( ) const
{
return PMPropertyIterator( m_propertiesDict );
}
/**
* Returns a property by name or 0 if a property with the name
* doesn't exist.
*/
PMPropertyBase* property( const TQString& name ) const
{
return m_propertiesDict.find( name );
}
private:
TQString m_className;
PMMetaObject* m_pSuperClass;
PMPropertyList m_properties;
PMPropertyDict m_propertiesDict;
PMObjectFactoryMethod m_factory;
};
#endif