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.
tdelibs/kdecore/kdcoppropertyproxy.cpp

336 lines
8.2 KiB

/* This file is part of the KDE project
Copyright (C) 1999 Simon Hausmann <hausmann@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "kdcoppropertyproxy.h"
#include <qstrlist.h>
#include <qmetaobject.h>
#include <qvariant.h>
#include <qcursor.h>
#include <qbitmap.h>
#include <qregion.h>
#include <qpointarray.h>
#include <qiconset.h>
#include <qfont.h>
#include <qimage.h>
#include <qbrush.h>
#include <qpalette.h>
#include <ctype.h>
#include <assert.h>
class KDCOPPropertyProxyPrivate
{
public:
KDCOPPropertyProxyPrivate()
{
}
~KDCOPPropertyProxyPrivate()
{
}
QObject *m_object;
};
KDCOPPropertyProxy::KDCOPPropertyProxy( QObject *object )
{
d = new KDCOPPropertyProxyPrivate;
d->m_object = object;
}
KDCOPPropertyProxy::~KDCOPPropertyProxy()
{
delete d;
}
bool KDCOPPropertyProxy::isPropertyRequest( const QCString &fun )
{
return isPropertyRequest( fun, d->m_object );
}
bool KDCOPPropertyProxy::processPropertyRequest( const QCString &fun, const QByteArray &data,
QCString &replyType, QByteArray &replyData )
{
return processPropertyRequest( fun, data, replyType, replyData, d->m_object );
}
QValueList<QCString> KDCOPPropertyProxy::functions()
{
return functions( d->m_object );
}
bool KDCOPPropertyProxy::isPropertyRequest( const QCString &fun, QObject *object )
{
if ( fun == "property(QCString)" ||
fun == "setProperty(QCString,QVariant)" ||
fun == "propertyNames(bool)" )
return true;
bool set;
QCString propName, arg;
return decodePropertyRequestInternal( fun, object, set, propName, arg );
}
QValueList<QCString> KDCOPPropertyProxy::functions( QObject *object )
{
QValueList<QCString> res;
res << "QVariant property(QCString property)";
res << "bool setProperty(QCString name,QVariant property)";
res << "QValueList<QCString> propertyNames(bool super)";
QMetaObject *metaObj = object->metaObject();
QStrList properties = metaObj->propertyNames( true );
QStrListIterator it( properties );
for (; it.current(); ++it )
{
const QMetaProperty *metaProp = metaObj->property( metaObj->findProperty( it.current(), true ), true );
assert( metaProp );
QCString name = it.current();
name.prepend( " " );
name.prepend( metaProp->type() );
name.append( "()" );
res << name;
if ( metaProp->writable() )
{
QCString setName = it.current();
setName[ 0 ] = toupper( setName[ 0 ] );
setName = "void set" + setName + "(" + metaProp->type() + " " + it.current() + ")";
res << setName;
}
}
return res;
}
bool KDCOPPropertyProxy::processPropertyRequest( const QCString &fun, const QByteArray &data,
QCString &replyType, QByteArray &replyData,
QObject *object )
{
if ( fun == "property(QCString)" )
{
QCString propName;
QDataStream stream( data, IO_ReadOnly );
stream >> propName;
replyType = "QVariant";
QDataStream reply( replyData, IO_WriteOnly );
reply << object->property( propName );
return true;
}
if ( fun == "setProperty(QCString,QVariant)" )
{
QCString propName;
QVariant propValue;
QDataStream stream( data, IO_ReadOnly );
stream >> propName >> propValue;
replyType = "bool";
QDataStream reply( replyData, IO_WriteOnly );
reply << (Q_INT8)object->setProperty( propName, propValue );
return true;
}
if ( fun == "propertyNames(bool)" )
{
Q_INT8 b;
QDataStream stream( data, IO_ReadOnly );
stream >> b;
QValueList<QCString> res;
QStrList props = object->metaObject()->propertyNames( static_cast<bool>( b ) );
QStrListIterator it( props );
for (; it.current(); ++it )
res.append( it.current() );
replyType = "QValueList<QCString>";
QDataStream reply( replyData, IO_WriteOnly );
reply << res;
return true;
}
bool set;
QCString propName, arg;
bool res = decodePropertyRequestInternal( fun, object, set, propName, arg );
if ( !res )
return false;
if ( set )
{
QVariant prop;
QDataStream stream( data, IO_ReadOnly );
QVariant::Type type = QVariant::nameToType( arg );
if ( type == QVariant::Invalid )
return false;
#define DEMARSHAL( type, val ) \
case QVariant::type: \
{ \
val v; \
stream >> v; \
prop = QVariant( v ); \
} \
break;
typedef QValueList<QVariant> ListType;
typedef QMap<QString,QVariant> MapType;
switch ( type )
{
DEMARSHAL( Cursor, QCursor )
DEMARSHAL( Bitmap, QBitmap )
DEMARSHAL( PointArray, QPointArray )
DEMARSHAL( Region, QRegion )
DEMARSHAL( List, ListType )
DEMARSHAL( Map, MapType )
DEMARSHAL( String, QString )
DEMARSHAL( CString, QCString )
DEMARSHAL( StringList, QStringList )
DEMARSHAL( Font, QFont )
DEMARSHAL( Pixmap, QPixmap )
DEMARSHAL( Image, QImage )
DEMARSHAL( Brush, QBrush )
DEMARSHAL( Point, QPoint )
DEMARSHAL( Rect, QRect )
DEMARSHAL( Size, QSize )
DEMARSHAL( Color, QColor )
DEMARSHAL( Palette, QPalette )
DEMARSHAL( ColorGroup, QColorGroup )
case QVariant::IconSet:
{
QPixmap val;
stream >> val;
prop = QVariant( QIconSet( val ) );
}
break;
DEMARSHAL( Int, int )
DEMARSHAL( UInt, uint )
case QVariant::Bool:
{
Q_INT8 v;
stream >> v;
prop = QVariant( static_cast<bool>( v ), 1 );
}
break;
DEMARSHAL( Double, double )
default:
return false;
}
replyType = "void";
return object->setProperty( propName, prop );
}
else
{
QVariant prop = object->property( propName );
if ( prop.type() == QVariant::Invalid )
return false;
replyType = prop.typeName();
QDataStream reply( replyData, IO_WriteOnly );
#define MARSHAL( type ) \
case QVariant::type: \
reply << prop.to##type(); \
break;
switch ( prop.type() )
{
MARSHAL( Cursor )
MARSHAL( Bitmap )
MARSHAL( PointArray )
MARSHAL( Region )
MARSHAL( List )
MARSHAL( Map )
MARSHAL( String )
MARSHAL( CString )
MARSHAL( StringList )
MARSHAL( Font )
MARSHAL( Pixmap )
MARSHAL( Image )
MARSHAL( Brush )
MARSHAL( Point )
MARSHAL( Rect )
MARSHAL( Size )
MARSHAL( Color )
MARSHAL( Palette )
MARSHAL( ColorGroup )
case QVariant::IconSet:
reply << prop.toIconSet().pixmap();
break;
MARSHAL( Int )
MARSHAL( UInt )
case QVariant::Bool:
reply << (Q_INT8)prop.toBool();
break;
MARSHAL( Double )
default:
return false;
}
#undef MARSHAL
#undef DEMARSHAL
return true;
}
return false;
}
bool KDCOPPropertyProxy::decodePropertyRequestInternal( const QCString &fun, QObject *object, bool &set,
QCString &propName, QCString &arg )
{
if ( fun.length() < 3 )
return false;
set = false;
propName = fun;
if ( propName.left( 3 ) == "set" )
{
propName.detach();
set = true;
propName = propName.mid( 3 );
int p1 = propName.find( '(' );
uint len = propName.length();
if ( propName[ len - 1 ] != ')' )
return false;
arg = propName.mid( p1+1, len - p1 - 2 );
propName.truncate( p1 );
propName[ 0 ] = tolower( propName[ 0 ] );
}
else
propName.truncate( propName.length() - 2 );
if ( !object->metaObject()->propertyNames( true ).contains( propName ) )
return false;
return true;
}