kdecore Library API Documentation

kdcoppropertyproxy.cpp

00001 /* This file is part of the KDE project
00002    Copyright (C) 1999 Simon Hausmann <hausmann@kde.org>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License as published by the Free Software Foundation; either
00007    version 2 of the License, or (at your option) any later version.
00008 
00009    This library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this library; see the file COPYING.LIB.  If not, write to
00016    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00017    Boston, MA 02111-1307, USA.
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 }
KDE Logo
This file is part of the documentation for kdelibs Version 3.1.4.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Sun Feb 27 22:14:46 2005 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001