Hi Przemek and All,

Perfect.

Just another idea to put this in practice (and now I'm trying 
to find optimum without thinking about who will or should 
implement this):

Currently we have .qth files as source for the generator.
I'd find it much better to use the QT headers _directly_, 
thus fully automatizing the generator and making it quite 
easy to add/remove classes and update them when newer QT 
versions are released. At the same time making sure that 
we are _really_ covering the actual classes with no room 
for mistakes or differences.

Quick glance to current .qth files shows that it would 
be enough to only cover in local config files the few points 
which need some special handling, the rest could be 
swapped for a more intelligent parser, following #include 
references and parsing QT .cpp headers.

Any opinion on that? (particularly from Pritpal)

[ Anyhow even current .qth files seems enough to implement 
the stuff suggested by Przemek, plus probably the more strict 
parameter type checking, too. ]

Brgds,
Viktor

On 2010 Apr 12, at 19:56, Przemysław Czerpak wrote:

> On Mon, 12 Apr 2010, Szak�ts Viktor wrote:
> 
> Hi,
> 
>>> Hi Viktor, I was about to send this message to the list when I had a
>>> shocking vision....
>>> In postgres.c it is NORMAL to discriminate between objects... there is
>>> no use in passing type X instead of type Y and it must be avoided and
>>> RTE is good.....
>>> But in Qt we have a HIERARCHY !
>>> It is perfectly normal to pass a QPushButton to a function that
>>> expects a QObject !!!!!!!!!! since QObject is a super-class !
>>> Since we don't store the object hierarchy Pritpal just checks that
>>> ClassName() starts with a Q or HB .... and keeps the finger crossed...
>> That's even worse than handling everything as the base class.
> [...]
>> First I think we need to make sure we can identify the 
>> class of every GC allocated objects. If we can do this, 
>> we may make the next step and properly filter accepted 
>> parameters. For this we also need to maintain the layout 
>> of the QT class hierarchy. This raises other issues, like 
>> how to keep this in sync with QT version. This information 
>> BTW is already maintained in HBQT on the .prg level.
>> So you could make sth like:
> [...]
> 
> Half year ago I committed to this list code which realize it:
> http://lists.harbour-project.org/pipermail/harbour/2009-October/026490.html
> 
> It was example with few typos (see the above thread).
> Below is cleaned version which also uses explicit casting.
> It fully resolve the problem of casting to ancestors classes
> when pointer to QT object is extracted from HVM item with
> full validation. Please also note that it does not need any
> global replication of QT hierarchy. Just simply each class
> can independently decide which casting to ancestor is allowed
> by registering itself in the ancestors wrappers using
> qt_childregister_<class>() function.
> It also does not need metaObject or similar tricks.
> All what you need is using such code for all QT classes wrappers.
> 
> best regards,
> Przemek
> 
> 
> 
> 
> 
> /* global declaration */
> typedef void * ( * QT_PARAM_FUNC ) ( int, HB_BOOL );
> typedef struct _QT_PARAM_INFO
> {
>   QT_PARAM_FUNC            pFunc;
>   struct _QT_PARAM_INFO  * pNext;
>   HB_BOOL                  fInited;
> } QT_PARAM_INFO;
> 
> /* this function is part of QDialog wrapper */
> extern void qt_childregister_QDialog( QT_PARAM_INFO * paramInfo );
> 
> /* public functions in other class wrappers */
> extern QWidget * hbqt_par_QWidget( int iParam, HB_BOOL fError );
> extern QPrinter * hbqt_par_QPrinter( int iParam, HB_BOOL fError );
> 
> /* public function in this class wrapper */
> extern QPageSetupDialog * hbqt_par_QPageSetupDialog( int iParam,
>                                                     HB_BOOL fError );
> extern void qt_childregister_QPageSetupDialog( QT_PARAM_INFO * paramInfo );
> 
> /*** QPageSetupDialog.cpp ***/
> 
> static HB_GARBAGE_FUNC( release_QPageSetupDialog )
> {
>   QPointer< QPageSetupDialog > * pObj =
>                              ( QPointer< QPageSetupDialog > * ) Cargo;
>   QPageSetupDialog * obj = * pObj;
> 
>   if( obj )
>   {
>      *pObj = NULL;
>      delete obj;
>   }
> }
> 
> static const HB_GC_FUNCS s_gcQPageSetupDialog =
> {
>   release_QPageSetupDialog,
>   hb_gcDummyMark
> };
> 
> static QT_PARAM_INFO s_paramInfo_QDialog;
> static QT_PARAM_INFO * s_paramList = NULL;
> 
> /* public function use by descendant classes to register their
> * param functions
> */
> void qt_childregister_QPageSetupDialog( QT_PARAM_INFO * paramInfo )
> {
>   if( !paramInfo->fInited )
>   {
>      /* TODO: add MT protection in fianl version,
>               ignore it in devel code */
>      paramInfo->fInited = HB_TRUE;
>      paramInfo->pNext = s_paramList;
>      s_paramList = paramInfo;
>   }
> }
> 
> /* public function which extracts pointer to QPageSetupDialog object
> * from given HVM parameter. This parameter may contain also any
> * descendant class which register its param function using
> * qt_childregister_QPageSetupDialog().
> */
> QPageSetupDialog * hbqt_par_QPageSetupDialog( int iParam, HB_BOOL fError )
> {
>   QPointer< QPageSetupDialog > * pObj;
>   QPageSetupDialog * obj = NULL;
> 
>   pObj = ( QPointer< QPageSetupDialog > * )
>                              hb_parptrGC( &s_gcQPageSetupDialog, iParam );
>   if( pObj == NULL )
>   {
>      /* Not a QPageSetupDialog pointer item, check all registered
>       * descendant classes
>       */
>      QT_PARAM_INFO * paramInfo = s_paramList;
>      while( paramInfo )
>      {
>         obj = ( QPageSetupDialog * ) paramInfo->pFunc( iParam, HB_FALSE );
>         if( obj )
>            return obj;
>         paramInfo = paramInfo->pNext;
>      }
>   }
> 
>   if( pObj == NULL )
>   {
>      if( fError )
>      {
>         /* RT ERROR - wrong parameter */
>      }
>   }
>   else
>   {
>      obj = * pObj;
>      if( obj == NULL && fError )
>      {
>         /* RT ERROR - object deleted by other code */
>      }
>   }
> 
>   return obj;
> }
> 
> static QDialog * hbqt_par_QPageSetupDialogAsQDialog( int iParam,
>                                                     HB_BOOL fError )
> {
>   QPageSetupDialog * obj = hbqt_par_QPageSetupDialog( iParam, fError );
>   return ( QDialog * ) obj;
> }
> 
> static QPointer< QPageSetupDialog > * qt_alloc_QPageSetupDialog( 
> QPageSetupDialog * obj )
> {
>   QPointer< QPageSetupDialog > * pObj;
> 
>   if( !s_paramInfo_QDialog.fInited )
>   {
>      /* First call - register in parent class our param function */
>      s_paramInfo_QDialog.pFunc = ( QT_PARAM_FUNC )
>                                  hbqt_par_QPageSetupDialogAsQDialog;
>      qt_childregister_QDialog( &s_paramInfo_QDialog );
> 
>      /* if class inherits directly from more then one classes
>       * (multiinheritance) then for each parent class register
>       * coresponding s_paramInfo_<X> parameter
>       */
>   }
> 
>   pObj = ( QPointer< QPageSetupDialog > * )
>            memset( hb_gcAllocate( sizeof( QPointer< QPageSetupDialog > ),
>                                   &s_gcQPageSetupDialog ),
>                    0, sizeof( QPointer< QPageSetupDialog > ) );
>   * pObj = obj;
> 
>   return pObj;
> }
> 
> /* PRG class functions */
> 
> HB_FUNC( QT_QPAGESETUPDIALOG )
> {
>   QPageSetupDialog * obj = NULL;
> 
>   if( hb_pcount() >= 2 )
>   {
>      QPrinter * qp = hbqt_par_QPrinter( 1, HB_TRUE );
>      if( qp )
>      {
>         QWidget * qw = hbqt_par_QWidget( 2, HB_TRUE );
>         if( qw )
>            obj = new QPageSetupDialog( qp, qw );
>      }
>   }
>   else
>      obj = new QPageSetupDialog( hbqt_par_QWidget( 1, HB_TRUE ) );
> 
>   if( obj )
>      hb_retptrGC( qt_alloc_QPageSetupDialog( obj ) );
> }
> 
> HB_FUNC( QT_QPAGESETUPDIALOG_EXEC )
> {
>   QPageSetupDialog * obj = hbqt_par_QPageSetupDialog( 1, HB_TRUE );
> 
>   if( obj )
>      hb_retni( obj->exec() );
> }
> 
> [...]
> _______________________________________________
> Harbour mailing list (attachment size limit: 40KB)
> Harbour@harbour-project.org
> http://lists.harbour-project.org/mailman/listinfo/harbour

_______________________________________________
Harbour mailing list (attachment size limit: 40KB)
Harbour@harbour-project.org
http://lists.harbour-project.org/mailman/listinfo/harbour

Reply via email to