2012-06-06 18:54 UTC-0800 Pritpal Bedi (bedipritpal@hotmail.com)

* contrib/hbqt/qtcore/hbqt_bind.cpp
    * Struggled: to set pointer arithmatic to be used properly.
      Also at times Qt returns different type instead of one 
      defined in documentation, but referred in description part only.
      For example, a popup menu returns null instead of QAction if 
      no item is selected or user pressed escape. This is not 
      possible to manage such instances in present engine. For 
      this reason only :isValidPointer() method was introduced.
      In REVAMPED hbQT this is different. So to test it, the only 
      way to ascertain is if the Harbour class name is of same type.

  * contrib/hbqt/tests/qtrevamp.prg
    + Added: popup menu option to demonstrate what happens 
      at the background, if tracelog is activated.    

    ; NOTE: I am not from C or C++ background at all, so some things 
      may not be as elegant as those should be when viewed from 
      source point of view. Also trace entries are left in the 
      code, though under DEBUG mode, which will be cleaned once 
      code settles down.
This commit is contained in:
Pritpal Bedi
2012-06-07 02:04:20 +00:00
parent c4ca9bc3af
commit 8f4cd3929a
3 changed files with 106 additions and 20 deletions

View File

@@ -16,6 +16,28 @@
The license applies to all entries newer than 2009-04-28.
*/
2012-06-06 18:54 UTC-0800 Pritpal Bedi (bedipritpal@hotmail.com)
* contrib/hbqt/qtcore/hbqt_bind.cpp
* Struggled: to set pointer arithmatic to be used properly.
Also at times Qt returns different type instead of one
defined in documentation, but referred in description part only.
For example, a popup menu returns null instead of QAction if
no item is selected or user pressed escape. This is not
possible to manage such instances in present engine. For
this reason only :isValidPointer() method was introduced.
In REVAMPED hbQT this is different. So to test it, the only
way to ascertain is if the Harbour class name is of same type.
* contrib/hbqt/tests/qtrevamp.prg
+ Added: popup menu option to demonstrate what happens
at the background, if tracelog is activated.
; NOTE: I am not from C or C++ background at all, so some things
may not be as elegant as those should be when viewed from
source point of view. Also trace entries are left in the
code, though under DEBUG mode, which will be cleaned once
code settles down.
2012-06-07 00:43 UTC+0200 Viktor Szakats (harbour syenar.net)
* contrib/xhb/bkgtsks.c
% cleanup missed in prev

View File

@@ -129,6 +129,9 @@ PHB_ITEM hbqt_bindGetHbObject( PHB_ITEM pItem, void * qtObject, PHB_SYMB pClassF
PHBQT_BIND bind;
PHB_ITEM pObject = NULL;
if( qtObject == NULL )
return pObject;
HBQT_BIND_LOCK
bind = s_hbqt_binds;
while( bind )
@@ -176,9 +179,11 @@ PHB_ITEM hbqt_bindGetHbObject( PHB_ITEM pItem, void * qtObject, PHB_SYMB pClassF
{
if( s_destroyer == NULL )
s_destroyer = new HBQDestroyer();
QObject::connect( ( QObject * ) qtObject, SIGNAL(destroyed(QObject*)), s_destroyer, SLOT(destroyer()) );
HB_TRACE( HB_TR_DEBUG, ( "hbqt_bindGetHbObject( %p )...%s", qtObject, ( ( QObject * ) qtObject )->metaObject()->className() ) );
if( qtObject != NULL )
{
QObject::connect( ( QObject * ) qtObject, SIGNAL(destroyed(QObject*)), s_destroyer, SLOT(destroyer()) );
HB_TRACE( HB_TR_DEBUG, ( "hbqt_bindGetHbObject( %p )...%s", qtObject, ( ( QObject * ) qtObject )->metaObject()->className() ) );
}
}
else
{
@@ -239,47 +244,70 @@ void hbqt_bindDestroyHbObject( PHB_ITEM pObject )
if( bind->hbObject == hbObject )
{
found = HB_TRUE;
bool fObject = bind->iFlags & HBQT_BIT_QOBJECT;
QObject * obj = NULL;
const char * classname = NULL;
if( fObject )
{
obj = ( QObject * ) bind->qtObject;
classname = obj->metaObject()->className();
}
if( bind->iFlags & HBQT_BIT_OWNER )
{
if( bind->iFlags & HBQT_BIT_QOBJECT )
if( fObject )
{
HB_TRACE( HB_TR_DEBUG, ( "..............HARBOUR_ABOUT_TO_DESTROY( %p )...%s", bind->qtObject, ( ( QObject * ) bind->qtObject )->metaObject()->className() ) );
QObject * obj = ( QObject * ) bind->qtObject;
HB_TRACE( HB_TR_DEBUG, ( "..............HARBOUR_ABOUT_TO_DESTROY_%s( %p )", classname, obj ) );
if( obj )
{
if( ! ( obj->metaObject()->className() == ( const char * ) "QAction" ) )
if( classname != ( const char * ) "QAction" )
{
if( obj->parent() == NULL )
{
HB_TRACE( HB_TR_DEBUG, ( "HARBOUR_DESTROYED( %p )...%s", obj, obj->metaObject()->className() ) );
bind->fDeleting = true;
bind->pDelFunc( obj, bind->iFlags );
* bind_ptr = bind->next;
hb_xfree( bind );
HB_TRACE( HB_TR_DEBUG, ( "HARBOUR_DESTROYED_%s( %p )", classname, obj ) );
}
}
}
else
{
* bind_ptr = bind->next;
hb_xfree( bind );
HB_TRACE( HB_TR_DEBUG, ( "HARBOUR_DESTROYED_QTObjIsNull_%s( %p )", classname, obj ) );
}
}
else
{
HB_TRACE( HB_TR_DEBUG, ( "HARBOUR_DESTROYED( %p )", bind->qtObject ) );
bind->pDelFunc( bind->qtObject, bind->iFlags );
void * oobj = bind->qtObject;
* bind_ptr = bind->next;
bind->pDelFunc( bind->qtObject, bind->iFlags );
hb_xfree( bind );
HB_TRACE( HB_TR_DEBUG, ( "HARBOUR_DESTROYED( %p )", oobj ) );
Q_UNUSED( oobj );
}
}
else
{
HB_TRACE( HB_TR_DEBUG, ( "HARBOUR_DESTROYED_NO_OWNER( %p )", bind->qtObject ) );
if( fObject )
{
HB_TRACE( HB_TR_DEBUG, ( "HARBOUR_DESTROYED_NOT_OWNED_BY_HHARBOUR( %p )...%s", bind->qtObject, obj->metaObject()->className() ) );
}
else
{
HB_TRACE( HB_TR_DEBUG, ( "HARBOUR_DESTROYED_NOT_OWNED_BY_HHARBOUR( %p )", bind->qtObject ) );
}
* bind_ptr = bind->next;
hb_xfree( bind );
}
break;
break;
}
bind_ptr = &bind->next;
}
HBQT_BIND_UNLOCK
if( ! found )
{
HB_TRACE( HB_TR_DEBUG, ( "..............HARBOUR_DESTROYING_NOT_FOUND_ARRAYID( %p )", hbObject ) );
@@ -299,17 +327,17 @@ void hbqt_bindDestroyQtObject( void * qtObject )
{
if( bind->qtObject == qtObject )
{
* bind_ptr = bind->next;
if( ! bind->fDeleting )
{
if( bind->iFlags & HBQT_BIT_QOBJECT )
{
HB_TRACE( HB_TR_DEBUG, ( "QT_DESTROYED( %p ).............%s", bind->qtObject, ( ( QObject * ) bind->qtObject )->metaObject()->className() ) );
HB_TRACE( HB_TR_DEBUG, ( "QT_DESTROYED_%s( %p )", ( ( QObject * ) bind->qtObject )->metaObject()->className(), bind->qtObject ) );
}
else
{
HB_TRACE( HB_TR_DEBUG, ( "QT_DESTROYED( %p )", bind->qtObject ) );
}
* bind_ptr = bind->next;
hb_xfree( bind );
}
break;

View File

@@ -3,6 +3,9 @@
*/
#include "hbtrace.ch"
FUNCTION Main()
LOCAL oWnd
@@ -38,15 +41,15 @@ STATIC FUNCTION BuildMenuBar( oWnd )
//
oMenu1 := QMenu( oMenuBar )
//
oMenu1:setTitle( "&Dialogs" )
oMenu1:setTitle( "&Options" )
oItemIns := QAction( oMenu1 )
oItemIns:setText( "&MessageBox()" )
oItemIns:connect( "triggered()", {|| DlgMBox( "Yes" ) } )
oItemMod := QAction( oMenu1 )
oItemMod:setText( "&FileDialog()" )
oItemMod:connect( "triggered()", {|| DlgFiles( "*.prg" ) } )
oItemMod:setText( "&ContextMenu()" )
oItemMod:connect( "triggered()", {|| ContextMenu( oWnd ) } )
oMenu1:addAction( oItemIns )
oMenu1:addAction( oItemMod )
@@ -62,8 +65,8 @@ FUNCTION AddLabel( oWnd )
LOCAL oL
oL := QLabel( oWnd )
oL:move( 180,95 )
oL:setText( "Harbour Qt" )
oL:move( 155,95 )
oL:setText( "Harbour Qt Revamped" )
// oL is local, still it is visible to the appln throughout.
// Also memory is released automatically once its parent
@@ -100,3 +103,36 @@ FUNCTION DlgFiles( cMask )
RETURN cMask
FUNCTION ContextMenu( oWnd )
LOCAL qMenu, qAct
qMenu := QMenu()
qMenu:addAction( "Copy" )
qMenu:addAction( "Select All" )
qMenu:addAction( "Clear" )
qMenu:addAction( "Print" )
qMenu:addAction( "Save as..." )
qMenu:addSeparator()
qMenu:addAction( "Find" )
qAct := qMenu:exec( oWnd:mapToGlobal( QPoint( 10,10 ) ) )
// The test below is neccessary because Qt returns NULL in case
// user clicks anything except a menu item. Theoretically, Qt
// should have returned a QAction.
//
IF __objGetClsName( qAct ) == "QAction"
IF hb_isString( qAct:text() )
//...
ENDIF
ENDIF
// qMenu is a local variable and is carries no parent,
// which should be like this for any context menu,
// The memory is released, along its actions, when
// RETURN is hit.
RETURN NIL