2017-07-21 18:21:34 +02:00
|
|
|
/******************************************************************************
|
|
|
|
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
|
|
|
* This file may be used under the terms of the QSkinny License, Version 1.0
|
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
#ifndef QSK_OBJECT_TREE_H
|
|
|
|
#define QSK_OBJECT_TREE_H 1
|
|
|
|
|
|
|
|
#include "QskGlobal.h"
|
|
|
|
#include "QskControl.h"
|
|
|
|
#include "QskWindow.h"
|
|
|
|
|
2018-07-19 14:10:48 +02:00
|
|
|
#include <qvariant.h>
|
2017-07-21 18:21:34 +02:00
|
|
|
|
|
|
|
namespace QskObjectTree
|
|
|
|
{
|
|
|
|
class Visitor
|
|
|
|
{
|
|
|
|
public:
|
2017-12-07 17:04:05 +01:00
|
|
|
virtual ~Visitor() = default;
|
|
|
|
|
2017-07-21 18:21:34 +02:00
|
|
|
virtual bool visitDown( QObject* object ) = 0;
|
|
|
|
virtual bool visitUp( const QObject* object ) = 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
QSK_EXPORT QObjectList childNodes( const QObject* );
|
|
|
|
QSK_EXPORT QObject* parentNode( const QObject* );
|
|
|
|
QSK_EXPORT bool isRoot( const QObject* );
|
|
|
|
|
|
|
|
void traverseDown( QObject* object, Visitor& visitor );
|
|
|
|
void traverseUp( QObject* object, Visitor& visitor );
|
|
|
|
|
|
|
|
template< class T >
|
|
|
|
class ResolveVisitor : public Visitor
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
ResolveVisitor( const char* propertyName ):
|
|
|
|
m_propertyName( propertyName )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
inline const T& resolveValue() const
|
|
|
|
{
|
|
|
|
return m_value;
|
|
|
|
}
|
|
|
|
|
|
|
|
void setResolveValue( const T& value )
|
|
|
|
{
|
|
|
|
m_value = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual bool visitDown( QObject* object ) override final
|
|
|
|
{
|
|
|
|
if ( QskControl* control = qobject_cast< QskControl* >( object ) )
|
|
|
|
return setImplicitValue( control, m_value );
|
|
|
|
|
|
|
|
if ( QskWindow* window = qobject_cast< QskWindow* >( object ) )
|
|
|
|
return setImplicitValue( window, m_value );
|
|
|
|
|
|
|
|
return !setProperty( object, m_propertyName.constData(), m_value );
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual bool visitUp( const QObject* object ) override final
|
|
|
|
{
|
|
|
|
if ( isRoot( object ) )
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if ( const QskControl* control = qobject_cast< const QskControl* >( object ) )
|
|
|
|
{
|
|
|
|
m_value = value( control );
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( const QskWindow* window = qobject_cast< const QskWindow* >( object ) )
|
|
|
|
{
|
|
|
|
m_value = value( window );
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return getProperty( object, m_propertyName, m_value );
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
inline bool getProperty(
|
|
|
|
const QObject* object, const char* name, T& value ) const
|
|
|
|
{
|
|
|
|
if ( !m_propertyName.isEmpty() )
|
|
|
|
{
|
|
|
|
const QVariant v = object->property( name );
|
|
|
|
if ( v.canConvert< T >() )
|
|
|
|
{
|
|
|
|
value = qvariant_cast< T >( v );
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool setProperty(
|
|
|
|
QObject* object, const char* name, const T& value ) const
|
|
|
|
{
|
|
|
|
T oldValue;
|
|
|
|
if ( !getProperty( object, name, oldValue ) || oldValue == value )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
object->setProperty( name, value );
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual bool setImplicitValue( QskControl*, const T& ) = 0;
|
|
|
|
virtual bool setImplicitValue( QskWindow*, const T& ) = 0;
|
|
|
|
|
|
|
|
virtual T value( const QskControl* ) const = 0;
|
|
|
|
virtual T value( const QskWindow* ) const = 0;
|
|
|
|
|
|
|
|
private:
|
|
|
|
const QByteArray m_propertyName;
|
|
|
|
T m_value;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|