00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "kdcoppropertyproxy.h"
00021
00022 #include <qstrlist.h>
00023 #include <qmetaobject.h>
00024 #include <qvariant.h>
00025 #include <qcursor.h>
00026 #include <qbitmap.h>
00027 #include <qregion.h>
00028 #include <qpointarray.h>
00029 #include <qiconset.h>
00030 #include <qfont.h>
00031 #include <qimage.h>
00032 #include <qbrush.h>
00033 #include <qpalette.h>
00034
00035 #include <ctype.h>
00036 #include <assert.h>
00037
00038 class KDCOPPropertyProxyPrivate
00039 {
00040 public:
00041 KDCOPPropertyProxyPrivate()
00042 {
00043 }
00044 ~KDCOPPropertyProxyPrivate()
00045 {
00046 }
00047
00048 QObject *m_object;
00049 };
00050
00051 KDCOPPropertyProxy::KDCOPPropertyProxy( QObject *object )
00052 {
00053 d = new KDCOPPropertyProxyPrivate;
00054 d->m_object = object;
00055 }
00056
00057 KDCOPPropertyProxy::~KDCOPPropertyProxy()
00058 {
00059 delete d;
00060 }
00061
00062 bool KDCOPPropertyProxy::isPropertyRequest( const QCString &fun )
00063 {
00064 return isPropertyRequest( fun, d->m_object );
00065 }
00066
00067 bool KDCOPPropertyProxy::processPropertyRequest( const QCString &fun, const QByteArray &data,
00068 QCString &replyType, QByteArray &replyData )
00069 {
00070 return processPropertyRequest( fun, data, replyType, replyData, d->m_object );
00071 }
00072
00073 QValueList<QCString> KDCOPPropertyProxy::functions()
00074 {
00075 return functions( d->m_object );
00076 }
00077
00078 bool KDCOPPropertyProxy::isPropertyRequest( const QCString &fun, QObject *object )
00079 {
00080 if ( fun == "property(QCString)" ||
00081 fun == "setProperty(QCString,QVariant)" ||
00082 fun == "propertyNames(bool)" )
00083 return true;
00084
00085 bool set;
00086 QCString propName, arg;
00087 return decodePropertyRequestInternal( fun, object, set, propName, arg );
00088 }
00089
00090 QValueList<QCString> KDCOPPropertyProxy::functions( QObject *object )
00091 {
00092 QValueList<QCString> res;
00093 res << "QVariant property(QCString property)";
00094 res << "bool setProperty(QCString name,QVariant property)";
00095 res << "QValueList<QCString> propertyNames(bool super)";
00096
00097 QMetaObject *metaObj = object->metaObject();
00098 QStrList properties = metaObj->propertyNames( true );
00099 QStrListIterator it( properties );
00100 for (; it.current(); ++it )
00101 {
00102 const QMetaProperty *metaProp = metaObj->property( metaObj->findProperty( it.current(), true ), true );
00103
00104 assert( metaProp );
00105
00106 QCString name = it.current();
00107 name.prepend( " " );
00108 name.prepend( metaProp->type() );
00109 name.append( "()" );
00110 res << name;
00111
00112 if ( metaProp->writable() )
00113 {
00114 QCString setName = it.current();
00115 setName[ 0 ] = toupper( setName[ 0 ] );
00116 setName = "void set" + setName + "(" + metaProp->type() + " " + it.current() + ")";
00117 res << setName;
00118 }
00119 }
00120
00121 return res;
00122 }
00123
00124 bool KDCOPPropertyProxy::processPropertyRequest( const QCString &fun, const QByteArray &data,
00125 QCString &replyType, QByteArray &replyData,
00126 QObject *object )
00127 {
00128 if ( fun == "property(QCString)" )
00129 {
00130 QCString propName;
00131 QDataStream stream( data, IO_ReadOnly );
00132 stream >> propName;
00133
00134 replyType = "QVariant";
00135 QDataStream reply( replyData, IO_WriteOnly );
00136 reply << object->property( propName );
00137 return true;
00138 }
00139
00140 if ( fun == "setProperty(QCString,QVariant)" )
00141 {
00142 QCString propName;
00143 QVariant propValue;
00144 QDataStream stream( data, IO_ReadOnly );
00145 stream >> propName >> propValue;
00146
00147 replyType = "bool";
00148 QDataStream reply( replyData, IO_WriteOnly );
00149 reply << (Q_INT8)object->setProperty( propName, propValue );
00150 return true;
00151 }
00152
00153 if ( fun == "propertyNames(bool)" )
00154 {
00155 Q_INT8 b;
00156 QDataStream stream( data, IO_ReadOnly );
00157 stream >> b;
00158
00159 QValueList<QCString> res;
00160 QStrList props = object->metaObject()->propertyNames( static_cast<bool>( b ) );
00161 QStrListIterator it( props );
00162 for (; it.current(); ++it )
00163 res.append( it.current() );
00164
00165 replyType = "QValueList<QCString>";
00166 QDataStream reply( replyData, IO_WriteOnly );
00167 reply << res;
00168 return true;
00169 }
00170
00171 bool set;
00172 QCString propName, arg;
00173
00174 bool res = decodePropertyRequestInternal( fun, object, set, propName, arg );
00175 if ( !res )
00176 return false;
00177
00178 if ( set )
00179 {
00180 QVariant prop;
00181 QDataStream stream( data, IO_ReadOnly );
00182
00183 QVariant::Type type = QVariant::nameToType( arg );
00184 if ( type == QVariant::Invalid )
00185 return false;
00186
00187 #define DEMARSHAL( type, val ) \
00188 case QVariant::type: \
00189 { \
00190 val v; \
00191 stream >> v; \
00192 prop = QVariant( v ); \
00193 } \
00194 break;
00195
00196 typedef QValueList<QVariant> ListType;
00197 typedef QMap<QString,QVariant> MapType;
00198
00199 switch ( type )
00200 {
00201 DEMARSHAL( Cursor, QCursor )
00202 DEMARSHAL( Bitmap, QBitmap )
00203 DEMARSHAL( PointArray, QPointArray )
00204 DEMARSHAL( Region, QRegion )
00205 DEMARSHAL( List, ListType )
00206 DEMARSHAL( Map, MapType )
00207 DEMARSHAL( String, QString )
00208 DEMARSHAL( CString, QCString )
00209 DEMARSHAL( StringList, QStringList )
00210 DEMARSHAL( Font, QFont )
00211 DEMARSHAL( Pixmap, QPixmap )
00212 DEMARSHAL( Image, QImage )
00213 DEMARSHAL( Brush, QBrush )
00214 DEMARSHAL( Point, QPoint )
00215 DEMARSHAL( Rect, QRect )
00216 DEMARSHAL( Size, QSize )
00217 DEMARSHAL( Color, QColor )
00218 DEMARSHAL( Palette, QPalette )
00219 DEMARSHAL( ColorGroup, QColorGroup )
00220 case QVariant::IconSet:
00221 {
00222 QPixmap val;
00223 stream >> val;
00224 prop = QVariant( QIconSet( val ) );
00225 }
00226 break;
00227 DEMARSHAL( Int, int )
00228 DEMARSHAL( UInt, uint )
00229 case QVariant::Bool:
00230 {
00231 Q_INT8 v;
00232 stream >> v;
00233 prop = QVariant( static_cast<bool>( v ), 1 );
00234 }
00235 break;
00236 DEMARSHAL( Double, double )
00237 default:
00238 return false;
00239 }
00240
00241 replyType = "void";
00242 return object->setProperty( propName, prop );
00243 }
00244 else
00245 {
00246 QVariant prop = object->property( propName );
00247
00248 if ( prop.type() == QVariant::Invalid )
00249 return false;
00250
00251 replyType = prop.typeName();
00252 QDataStream reply( replyData, IO_WriteOnly );
00253
00254 #define MARSHAL( type ) \
00255 case QVariant::type: \
00256 reply << prop.to##type(); \
00257 break;
00258
00259 switch ( prop.type() )
00260 {
00261 MARSHAL( Cursor )
00262 MARSHAL( Bitmap )
00263 MARSHAL( PointArray )
00264 MARSHAL( Region )
00265 MARSHAL( List )
00266 MARSHAL( Map )
00267 MARSHAL( String )
00268 MARSHAL( CString )
00269 MARSHAL( StringList )
00270 MARSHAL( Font )
00271 MARSHAL( Pixmap )
00272 MARSHAL( Image )
00273 MARSHAL( Brush )
00274 MARSHAL( Point )
00275 MARSHAL( Rect )
00276 MARSHAL( Size )
00277 MARSHAL( Color )
00278 MARSHAL( Palette )
00279 MARSHAL( ColorGroup )
00280 case QVariant::IconSet:
00281 reply << prop.toIconSet().pixmap();
00282 break;
00283 MARSHAL( Int )
00284 MARSHAL( UInt )
00285 case QVariant::Bool:
00286 reply << (Q_INT8)prop.toBool();
00287 break;
00288 MARSHAL( Double )
00289 default:
00290 return false;
00291 }
00292
00293 #undef MARSHAL
00294 #undef DEMARSHAL
00295
00296 return true;
00297 }
00298
00299 return false;
00300 }
00301
00302 bool KDCOPPropertyProxy::decodePropertyRequestInternal( const QCString &fun, QObject *object, bool &set,
00303 QCString &propName, QCString &arg )
00304 {
00305 if ( fun.length() < 3 )
00306 return false;
00307
00308 set = false;
00309
00310 propName = fun;
00311
00312 if ( propName.left( 3 ) == "set" )
00313 {
00314 propName.detach();
00315 set = true;
00316 propName = propName.mid( 3 );
00317 int p1 = propName.find( '(' );
00318
00319 uint len = propName.length();
00320
00321 if ( propName[ len - 1 ] != ')' )
00322 return false;
00323
00324 arg = propName.mid( p1+1, len - p1 - 2 );
00325 propName.truncate( p1 );
00326 propName[ 0 ] = tolower( propName[ 0 ] );
00327 }
00328 else
00329 propName.truncate( propName.length() - 2 );
00330
00331 if ( !object->metaObject()->propertyNames( true ).contains( propName ) )
00332 return false;
00333
00334 return true;
00335 }