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 <tqstrlist.h>
00023 #include <tqmetaobject.h>
00024 #include <tqvariant.h>
00025 #include <tqcursor.h>
00026 #include <tqbitmap.h>
00027 #include <tqregion.h>
00028 #include <tqpointarray.h>
00029 #include <tqiconset.h>
00030 #include <tqfont.h>
00031 #include <tqimage.h>
00032 #include <tqbrush.h>
00033 #include <tqpalette.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 TQObject *m_object;
00049 };
00050
00051 KDCOPPropertyProxy::KDCOPPropertyProxy( TQObject *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 TQCString &fun )
00063 {
00064 return isPropertyRequest( fun, d->m_object );
00065 }
00066
00067 bool KDCOPPropertyProxy::processPropertyRequest( const TQCString &fun, const TQByteArray &data,
00068 TQCString &replyType, TQByteArray &replyData )
00069 {
00070 return processPropertyRequest( fun, data, replyType, replyData, d->m_object );
00071 }
00072
00073 TQValueList<TQCString> KDCOPPropertyProxy::functions()
00074 {
00075 return functions( d->m_object );
00076 }
00077
00078 bool KDCOPPropertyProxy::isPropertyRequest( const TQCString &fun, TQObject *object )
00079 {
00080 if ( fun == "property(TQCString)" ||
00081 fun == "setProperty(TQCString,TQVariant)" ||
00082 fun == "propertyNames(bool)" )
00083 return true;
00084
00085 bool set;
00086 TQCString propName, arg;
00087 return decodePropertyRequestInternal( fun, object, set, propName, arg );
00088 }
00089
00090 TQValueList<TQCString> KDCOPPropertyProxy::functions( TQObject *object )
00091 {
00092 TQValueList<TQCString> res;
00093 res << "TQVariant property(TQCString property)";
00094 res << "bool setProperty(TQCString name,TQVariant property)";
00095 res << "TQValueList<TQCString> propertyNames(bool super)";
00096
00097 TQMetaObject *metaObj = object->metaObject();
00098 TQStrList properties = metaObj->propertyNames( true );
00099 TQStrListIterator it( properties );
00100 for (; it.current(); ++it )
00101 {
00102 const TQMetaProperty *metaProp = metaObj->property( metaObj->findProperty( it.current(), true ), true );
00103
00104 assert( metaProp );
00105
00106 TQCString name = it.current();
00107 name.prepend( " " );
00108 name.prepend( metaProp->type() );
00109 name.append( "()" );
00110 res << name;
00111
00112 if ( metaProp->writable() )
00113 {
00114 TQCString 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 TQCString &fun, const TQByteArray &data,
00125 TQCString &replyType, TQByteArray &replyData,
00126 TQObject *object )
00127 {
00128 if ( fun == "property(TQCString)" )
00129 {
00130 TQCString propName;
00131 TQDataStream stream( data, IO_ReadOnly );
00132 stream >> propName;
00133
00134 replyType = "TQVariant";
00135 TQDataStream reply( replyData, IO_WriteOnly );
00136 reply << object->property( propName );
00137 return true;
00138 }
00139
00140 if ( fun == "setProperty(TQCString,TQVariant)" )
00141 {
00142 TQCString propName;
00143 TQVariant propValue;
00144 TQDataStream stream( data, IO_ReadOnly );
00145 stream >> propName >> propValue;
00146
00147 replyType = "bool";
00148 TQDataStream reply( replyData, IO_WriteOnly );
00149 reply << (TQ_INT8)object->setProperty( propName, propValue );
00150 return true;
00151 }
00152
00153 if ( fun == "propertyNames(bool)" )
00154 {
00155 TQ_INT8 b;
00156 TQDataStream stream( data, IO_ReadOnly );
00157 stream >> b;
00158
00159 TQValueList<TQCString> res;
00160 TQStrList props = object->metaObject()->propertyNames( static_cast<bool>( b ) );
00161 TQStrListIterator it( props );
00162 for (; it.current(); ++it )
00163 res.append( it.current() );
00164
00165 replyType = "TQValueList<TQCString>";
00166 TQDataStream reply( replyData, IO_WriteOnly );
00167 reply << res;
00168 return true;
00169 }
00170
00171 bool set;
00172 TQCString propName, arg;
00173
00174 bool res = decodePropertyRequestInternal( fun, object, set, propName, arg );
00175 if ( !res )
00176 return false;
00177
00178 if ( set )
00179 {
00180 TQVariant prop;
00181 TQDataStream stream( data, IO_ReadOnly );
00182
00183 TQVariant::Type type = TQVariant::nameToType( arg );
00184 if ( type == TQVariant::Invalid )
00185 return false;
00186
00187 #define DEMARSHAL( type, val ) \
00188 case TQVariant::type: \
00189 { \
00190 val v; \
00191 stream >> v; \
00192 prop = TQVariant( v ); \
00193 } \
00194 break;
00195
00196 typedef TQValueList<TQVariant> ListType;
00197 typedef TQMap<TQString,TQVariant> MapType;
00198
00199 switch ( type )
00200 {
00201 DEMARSHAL( Cursor, TQCursor )
00202 DEMARSHAL( Bitmap, TQBitmap )
00203 DEMARSHAL( PointArray, TQPointArray )
00204 DEMARSHAL( Region, TQRegion )
00205 DEMARSHAL( List, ListType )
00206 DEMARSHAL( Map, MapType )
00207 DEMARSHAL( String, TQString )
00208 DEMARSHAL( CString, TQCString )
00209 DEMARSHAL( StringList, TQStringList )
00210 DEMARSHAL( Font, TQFont )
00211 DEMARSHAL( Pixmap, TQPixmap )
00212 DEMARSHAL( Image, TQImage )
00213 DEMARSHAL( Brush, TQBrush )
00214 DEMARSHAL( Point, TQPoint )
00215 DEMARSHAL( Rect, TQRect )
00216 DEMARSHAL( Size, TQSize )
00217 DEMARSHAL( Color, TQColor )
00218 DEMARSHAL( Palette, TQPalette )
00219 DEMARSHAL( ColorGroup, TQColorGroup )
00220 case TQVariant::IconSet:
00221 {
00222 TQPixmap val;
00223 stream >> val;
00224 prop = TQVariant( TQIconSet( val ) );
00225 }
00226 break;
00227 DEMARSHAL( Int, int )
00228 DEMARSHAL( UInt, uint )
00229 case TQVariant::Bool:
00230 {
00231 TQ_INT8 v;
00232 stream >> v;
00233 prop = TQVariant( 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 TQVariant prop = object->property( propName );
00247
00248 if ( prop.type() == TQVariant::Invalid )
00249 return false;
00250
00251 replyType = prop.typeName();
00252 TQDataStream reply( replyData, IO_WriteOnly );
00253
00254 #define MARSHAL( type ) \
00255 case TQVariant::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 TQVariant::IconSet:
00281 reply << prop.toIconSet().pixmap();
00282 break;
00283 MARSHAL( Int )
00284 MARSHAL( UInt )
00285 case TQVariant::Bool:
00286 reply << (TQ_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 TQCString &fun, TQObject *object, bool &set,
00303 TQCString &propName, TQCString &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 }