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