From b1572d6e74ee1688d529e8bae28e6c7103ee4f5f Mon Sep 17 00:00:00 2001 From: Pritpal Bedi Date: Sat, 19 Dec 2009 10:38:34 +0000 Subject: [PATCH] 2009-12-19 02:30 UTC-0800 Pritpal Bedi (pritpal@vouchcac.com) * contrib/hbide/hbide.prg * contrib/hbxbp/xbpqtuiloader.prg ! Implemented signal/slot mechanism. A working usage is the "Find/Replace" dialog is now entirely based on XbpQtUiLoader() class. "Project Properties" dialogs skeleton is also in place and is working, just a little more required to make it completely functional. XbpQtUiLoader() class appears to be heading towards an excellent tool and will eliminate to have a native Form Designer. Simply design a complex widget in Qt's powerful Qt Creater and exploit is with this class in the application. I have a lot many ideas to cook, your suggestions are welcome. --- harbour/ChangeLog | 15 +++ harbour/contrib/hbide/hbide.prg | 143 +++++++++++++++++------- harbour/contrib/hbxbp/xbpqtuiloader.prg | 111 +++++++++++++----- 3 files changed, 195 insertions(+), 74 deletions(-) diff --git a/harbour/ChangeLog b/harbour/ChangeLog index c8c63b12d7..9639e38585 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -17,6 +17,21 @@ past entries belonging to author(s): Viktor Szakats. */ +2009-12-19 02:30 UTC-0800 Pritpal Bedi (pritpal@vouchcac.com) + * contrib/hbide/hbide.prg + * contrib/hbxbp/xbpqtuiloader.prg + ! Implemented signal/slot mechanism. + A working usage is the "Find/Replace" dialog is now + entirely based on XbpQtUiLoader() class. "Project Properties" + dialogs skeleton is also in place and is working, just a little more + required to make it completely functional. + + XbpQtUiLoader() class appears to be heading towards an + excellent tool and will eliminate to have a native Form Designer. + Simply design a complex widget in Qt's powerful Qt Creater + and exploit is with this class in the application. + I have a lot many ideas to cook, your suggestions are welcome. + 2009-12-19 11:22 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl) * harbour/src/rtl/gtwin/gtwin.c ! applied Xavi's patch fixing CTRL+C error handler setting in newly diff --git a/harbour/contrib/hbide/hbide.prg b/harbour/contrib/hbide/hbide.prg index 1329b97ec2..3e4b03402a 100644 --- a/harbour/contrib/hbide/hbide.prg +++ b/harbour/contrib/hbide/hbide.prg @@ -206,6 +206,7 @@ CLASS HbIde METHOD updateFuncList() METHOD gotoFunction() METHOD fetchProjectProperties() + METHOD fetchProjectPropertiesViaUI() METHOD loadProjectProperties() METHOD appendProjectInTree() METHOD manageItemSelected() @@ -226,7 +227,13 @@ CLASS HbIde DATA aProjects INIT {} METHOD createTags() + + DATA oProps + DATA oFindRepl + METHOD find() + METHOD replace() METHOD findReplace() + METHOD manageFocusInEditor() METHOD convertSelection() METHOD printPreview() @@ -236,12 +243,15 @@ CLASS HbIde METHOD updateHbp() METHOD saveProject() METHOD addSourcesToProject() + /* Project Build and Launch Methods */ DATA cProcessInfo DATA qProcess + METHOD buildProject() METHOD buildProjectViaQt() METHOD readProcessInfo() + ENDCLASS /*----------------------------------------------------------------------*/ @@ -350,7 +360,7 @@ METHOD HbIde:create( cProjIni ) CASE ::mp1 == xbeK_CTRL_F IF !empty( ::qCurEdit ) - ::findReplace( "finddialog" ) + ::findReplace() ENDIF ENDCASE @@ -359,6 +369,10 @@ METHOD HbIde:create( cProjIni ) ::oXbp:handleEvent( ::nEvent, ::mp1, ::mp2 ) ENDDO + IF !empty( ::oFindRepl ) + ::oFindRepl:destroy() + ENDIF + /* Very important - destroy resources */ HBXBP_DEBUG( "======================================================" ) HBXBP_DEBUG( "Before ::oDlg:destroy()", memory( 1001 ), hbqt_getMemUsed() ) @@ -1480,7 +1494,7 @@ METHOD HbIde:executeAction( cKey ) ENDIF CASE cKey == "Find" IF !empty( ::qCurEdit ) - ::findReplace( "finddialog" ) + ::findReplace() ENDIF CASE cKey == "ToUpper" ::convertSelection( cKey ) @@ -1517,7 +1531,7 @@ METHOD HbIde:executeAction( cKey ) ::lDockRVisible := !( ::lDockRVisible ) CASE cKey == "Compile" - TestXbpQtUiLoader() + CASE cKey == "CompilePPO" ENDCASE @@ -1543,40 +1557,6 @@ METHOD HbIde:loadUI( cUi ) RETURN qDialog -/*----------------------------------------------------------------------*/ - -METHOD HbIde:findReplace( cUi ) - LOCAL qUiLoader, qFile, cUiFull - - IF ::qFindDlg == NIL - cUiFull := s_resPath + cUi + ".ui" - qFile := QFile():new( cUiFull ) - IF qFile:open( 1 ) - qUiLoader := QUiLoader():new() - ::qFindDlg := QDialog():configure( qUiLoader:load( qFile, QT_PTROFXBP( ::oDlg ) ) ) - qFile:close() - // - ::qFindDlg:setWindowFlags( Qt_Sheet ) - // - ::oFind := XbpComboBox():new():hbCreateFromQtPtr( , , , , , , Qt_findChild( ::qFindDlg, "comboFindWhat" ) ) - ::oRepl := XbpComboBox():new():hbCreateFromQtPtr( , , , , , , Qt_findChild( ::qFindDlg, "comboReplaceWith" ) ) - - ::oPBFind := XbpPushButton():new():hbCreateFromQtPtr( , , , , , , Qt_findChild( ::qFindDlg, "buttonFind" ) ) - ::oPBFind:activate := {|| ::qCurEdit:find( QLineEdit():configure( ::oFind:oWidget:lineEdit() ):text() ) } - - ::oPBRepl := XbpPushButton():new():hbCreateFromQtPtr( , , , , , , Qt_findChild( ::qFindDlg, "buttonReplace" ) ) - ::oPBRepl:activate := {|t| t := QLineEdit():configure( ::oRepl:oWidget:lineEdit() ):text() } - - ::oPBClose := XbpPushButton():new():hbCreateFromQtPtr( , , , , , , Qt_findChild( ::qFindDlg, "buttonClose" ) ) - ::oPBClose:activate := {|| ::qFindDlg:hide() } - ENDIF - ENDIF - - ::oFind:setFocus() - ::qFindDlg:show() - - RETURN Self - /*----------------------------------------------------------------------*/ // Project Properties /*----------------------------------------------------------------------*/ @@ -1621,6 +1601,7 @@ METHOD HbIde:loadProjectProperties( cProject, lNew, lFetch ) IF lFetch ::cSaveTo := "" ::fetchProjectProperties() + //::fetchProjectPropertiesViaUI() IF !empty( ::cSaveTo ) .and. file( ::cSaveTo ) cProject := ::cSaveTo /* Reload from file */ @@ -1638,6 +1619,61 @@ METHOD HbIde:loadProjectProperties( cProject, lNew, lFetch ) /*----------------------------------------------------------------------*/ +METHOD HbIde:fetchProjectPropertiesViaUI() + LOCAL cPrjLoc := hb_dirBase() + "projects" + LOCAL aPrjProps := ::aPrjProps + + ::oProps := XbpQtUiLoader():new( ::oDlg ) + ::oProps:file := s_resPath + "projectproperties.ui" + ::oProps:create() + + ::oProps:qObj[ "comboPrjType" ]:addItem( "Executable" ) + ::oProps:qObj[ "comboPrjType" ]:addItem( "Library" ) + ::oProps:qObj[ "comboPrjType" ]:addItem( "Dll" ) + + ::oProps:signal( "buttonCn" , "clicked()", {|| ::oProps:oWidget:close() } ) + ::oProps:signal( "buttonSave" , "clicked()", {|| ::saveProject() } ) + ::oProps:signal( "buttonSaveExit", "clicked()", {|| ::saveProject(), ::oProps:oWidget:close() } ) + ::oProps:signal( "buttonSelect" , "clicked()", {|| ::addSourcesToProject() } ) + + ::oProps:signal( "tabWidget" , "currentChanged(int)", {|o,p| ::updateHbp( p, o ) } ) + + IF empty( aPrjProps ) + ::oProps:qObj[ "editPrjTitle" ]:setText( "untitled" ) + ::oProps:qObj[ "editPrjLoctn" ]:setText( cPrjLoc ) + ::oProps:qObj[ "editWrkFolder" ]:setText( hb_dirBase() ) + ::oProps:qObj[ "editDstFolder" ]:setText( cPrjLoc ) + ::oProps:qObj[ "editOutName" ]:setText( "untitled" ) + + ELSE + ::oProps:qObj[ "editPrjTitle" ]:setText( aPrjProps[ PRJ_PRP_PROPERTIES, 1, PRJ_PRP_TITLE ] ) + ::oProps:qObj[ "editPrjLoctn" ]:setText( aPrjProps[ PRJ_PRP_PROPERTIES, 1, PRJ_PRP_LOCATION ] ) + ::oProps:qObj[ "editWrkFolder" ]:setText( aPrjProps[ PRJ_PRP_PROPERTIES, 1, PRJ_PRP_WRKFOLDER ] ) + ::oProps:qObj[ "editDstFolder" ]:setText( aPrjProps[ PRJ_PRP_PROPERTIES, 1, PRJ_PRP_DSTFOLDER ] ) + ::oProps:qObj[ "editOutName" ]:setText( aPrjProps[ PRJ_PRP_PROPERTIES, 1, PRJ_PRP_OUTPUT ] ) + + ::oProps:qObj[ "editFlags" ]:setPlainText( ArrayToMemo( aPrjProps[ PRJ_PRP_FLAGS , 1 ] ) ) + ::oProps:qObj[ "editSources" ]:setPlainText( ArrayToMemo( aPrjProps[ PRJ_PRP_SOURCES , 1 ] ) ) + ::oProps:qObj[ "editMetaData" ]:setPlainText( ArrayToMemo( aPrjProps[ PRJ_PRP_METADATA, 1 ] ) ) + ::oProps:qObj[ "editCompilers" ]:setPlainText( memoread( hb_dirBase() + "hbide.env" ) ) + + #if 0 + ::oProps:qObj[ "editLaunchParams" ]:setText() + ::oProps:qObj[ "editLaunchExe" ]:setText() + ::oProps:qObj[ "editHbp" ]:setPlainText() + #endif + ENDIF + + ::oProps:exec() + ::oProps:destroy() + ::oProps := NIL + + ::manageFocusInEditor() + + RETURN Self + +/*----------------------------------------------------------------------*/ + METHOD HbIde:fetchProjectProperties() LOCAL qPrpDlg, qPrjType, oPrjTtl, oPBOk, oPBCn, oTabWidget, oPBSv, oPBSelect LOCAL oPrjLoc, oPrjWrk, oPrjDst, oPrjOut, oPrjInc, oPrjLau, oPrjLEx, oPrjSrc, oPrjMta, oPrjHbp, oPrjCmp @@ -1946,14 +1982,35 @@ METHOD HbIde:readProcessInfo( nMode, iBytes ) /*----------------------------------------------------------------------*/ -FUNCTION TestXbpQtUiLoader() - LOCAL oUiLoader +METHOD HbIde:replace() - oUiLoader := XbpQtUiLoader():new() - oUiLoader:file := s_resPath + "finddialog.ui" - oUiLoader:create() + RETURN QLineEdit():configure( ::oRepl:oWidget:lineEdit() ):text() - oUiLoader:setText( "comboFindWhat", "Harbour" ) +/*----------------------------------------------------------------------*/ + +METHOD HbIde:find() + + ::qCurEdit:find( QLineEdit():configure( ::oFindRepl:qObj[ "comboFindWhat" ]:lineEdit() ):text() ) + + RETURN Self + +/*----------------------------------------------------------------------*/ + +METHOD HbIde:findReplace() + + IF empty( ::oFindRepl ) + ::oFindRepl := XbpQtUiLoader():new( ::oDlg ) + ::oFindRepl:file := s_resPath + "finddialog.ui" + ::oFindRepl:create() + ::oFindRepl:setWindowFlags( Qt_Sheet ) + + ::oFindRepl:signal( "buttonFind" , "clicked()", {|| ::find() } ) + ::oFindRepl:signal( "buttonReplace" , "clicked()", {|| ::replace() } ) + ::oFindRepl:signal( "buttonClose" , "clicked()", {|| ::oFindRepl:hide() } ) + ENDIF + + ::oFindRepl:qObj[ "comboFindWhat" ]:setFocus() + ::oFindRepl:show() RETURN Nil diff --git a/harbour/contrib/hbxbp/xbpqtuiloader.prg b/harbour/contrib/hbxbp/xbpqtuiloader.prg index f2eaaff33a..68a05e80dd 100644 --- a/harbour/contrib/hbxbp/xbpqtuiloader.prg +++ b/harbour/contrib/hbxbp/xbpqtuiloader.prg @@ -78,17 +78,23 @@ CLASS XbpQtUiLoader INHERIT XbpWindow DATA file INIT "" DATA modal INIT .t. - DATA parts INIT hb_hash() - DATA baseWidget + DATA qObj INIT hb_hash() DATA widgets INIT {} + DATA aSignals INIT {} + DATA aEvents INIT {} + METHOD new() METHOD create() METHOD configure() VIRTUAL - METHOD destroy() VIRTUAL + METHOD destroy() + METHOD loadUI() METHOD loadContents() METHOD loadWidgets() + METHOD signal() + METHOD event() + ERROR HANDLER OnError() @@ -110,11 +116,54 @@ METHOD XbpQtUiLoader:create( oParent, oOwner, aPos, aSize, aPresParams, lVisible IF !empty( ::file ) .and. file( ::file ) ::loadContents( ::file ) + ::oWidget := ::loadUI( ::file ) IF !empty( ::oWidget ) ::loadWidgets() - ::oWidget:show() + ENDIF + ENDIF + + RETURN Self + +/*----------------------------------------------------------------------*/ + +METHOD XbpQtUiLoader:destroy() + LOCAL a_ + + FOR EACH a_ IN ::aSignals + Qt_DisConnect_Signal( a_[ 1 ], a_[ 2 ] ) + NEXT + + FOR EACH a_ IN ::aEvents + Qt_DisConnect_Event( a_[ 1 ], a_[ 2 ] ) + NEXT + + ::oWidget:hide() + ::oWidget:close() + ::oWidget:pPtr := 0 + + RETURN NIL + +/*----------------------------------------------------------------------*/ + +METHOD XbpQtUiLoader:event( cWidget, nEvent, bBlock ) + + IF hb_hHasKey( ::qObj, cWidget ) + IF Qt_Connect_Signal( ::qObj[ cWidget ], nEvent, bBlock ) + aadd( ::aEvents, { ::qObj[ cWidget ], nEvent } ) + ENDIF + ENDIF + + RETURN Self + +/*----------------------------------------------------------------------*/ + +METHOD XbpQtUiLoader:signal( cWidget, cSignal, bBlock ) + + IF hb_hHasKey( ::qObj, cWidget ) + IF Qt_Connect_Signal( ::qObj[ cWidget ], cSignal, bBlock ) + aadd( ::aSignals, { ::qObj[ cWidget ], cSignal } ) ENDIF ENDIF @@ -127,16 +176,18 @@ METHOD XbpQtUiLoader:loadWidgets() FOR EACH a_ IN ::widgets IF a_:__enumIndex() > 1 - cBlock := "{|| " + a_[ 1 ] + "() }" + IF type( a_[ 1 ] + "()" ) == "UI" + cBlock := "{|| " + a_[ 1 ] + "() }" - pPtr := Qt_findChild( ::oWidget, a_[ 2 ] ) - bBlock := &( cBlock ) + pPtr := Qt_findChild( ::oWidget, a_[ 2 ] ) + bBlock := &( cBlock ) - x := eval( bBlock ) - IF hb_isObject( x ) - x:pPtr := pPtr + x := eval( bBlock ) + IF hb_isObject( x ) + x:pPtr := pPtr + ::qObj[ a_[ 2 ] ] := x + ENDIF ENDIF - ::parts[ a_[ 2 ] ] := x ENDIF NEXT @@ -161,7 +212,7 @@ METHOD XbpQtUiLoader:loadContents( cUiFull ) n := at( ">", cBuffer ) cWidget := alltrim( strtran( substr( cBuffer, 1, n-1 ), '"', "" ) ) - HBXBP_DEBUG( "XbpQtUiLoader:loadContents", cClass, cWidget ) + HBXBP_DEBUG( pad( cClass,30 ), cWidget ) aadd( ::widgets, { cClass, cWidget } ) ENDDO @@ -171,12 +222,22 @@ METHOD XbpQtUiLoader:loadContents( cUiFull ) /*----------------------------------------------------------------------*/ METHOD XbpQtUiLoader:loadUI( cUiFull ) - LOCAL qWidget, qUiLoader, qFile + LOCAL qWidget, qUiLoader, qFile, pWidget qFile := QFile():new( cUiFull ) IF qFile:open( 1 ) qUiLoader := QUiLoader():new() - qWidget := QWidget():configure( qUiLoader:load( qFile, IF( empty( ::oParent ), NIL, QT_PTROFXBP( ::oParent ) ) ) ) + pWidget := qUiLoader:load( qFile, IF( empty( ::oParent ), NIL, QT_PTROFXBP( ::oParent ) ) ) + DO CASE + CASE ::widgets[ 1,1 ] == "QWidget" + qWidget := QWidget():configure( pWidget ) + CASE ::widgets[ 1,1 ] == "QDialog" + qWidget := QDialog():configure( pWidget ) + CASE ::widgets[ 1,1 ] == "QMainWindow" + qWidget := QMainWindow():configure( pWidget ) + OTHERWISE + qWidget := QWidget():configure( pWidget ) + ENDCASE qFile:close() ENDIF @@ -184,32 +245,20 @@ METHOD XbpQtUiLoader:loadUI( cUiFull ) /*----------------------------------------------------------------------*/ -#if 0 /* Syntax */ - oUI:setText( "editWidget", "Some Text" ) - ^^^ XbpQtUiLoader() - ^^^^^^^ HBQT Object Method - ^^^^^^^^^^^^ Object Name In the Widget - ^^^^^^^^^^^ Value to be posted -#endif - METHOD OnError( ... ) - LOCAL cMsg, xReturn, cWidget - LOCAL aP, aPP := {} + LOCAL cMsg + LOCAL xReturn cMsg := __GetMessage() IF SubStr( cMsg, 1, 1 ) == "_" cMsg := SubStr( cMsg, 2 ) ENDIF - aP := hb_aParams() - cWidget := aP[ 1 ] + HBXBP_DEBUG( "OnError", cMsg ) - aeval( aP, {|e| aadd( aPP, e ) }, 2 ) - - IF hb_hHasKey( ::parts, cWidget ) - xReturn := hb_ExecFromArray( ::parts[ cWidget ], cMsg, aPP ) - ENDIF + xReturn := ::oWidget:&cMsg( ... ) RETURN xReturn /*----------------------------------------------------------------------*/ +