You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
417 lines
13 KiB
417 lines
13 KiB
//-*-C++-*-
|
|
/*
|
|
**************************************************************************
|
|
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.tqfind( name );
|
|
}
|
|
|
|
private:
|
|
TQString m_className;
|
|
PMMetaObject* m_pSuperClass;
|
|
PMPropertyList m_properties;
|
|
PMPropertyDict m_propertiesDict;
|
|
PMObjectFactoryMethod m_factory;
|
|
};
|
|
|
|
#endif
|