diff --git a/harbour/ChangeLog b/harbour/ChangeLog index d2b94a1c30..7be65b816e 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -17,6 +17,20 @@ past entries belonging to author(s): Viktor Szakats. */ +2009-12-08 18:27 UTC-0800 Pritpal Bedi (pritpal@vouchcac.com) + * contrib/hbide/hbide.prg + * contrib/hbide/idemisc.prg + * contrib/hbide/projects/hbide.hbi + * contrib/hbqt/hbqt_slots.cpp + * contrib/hbqt/hbqt_slots.h + * contrib/hbxbp/xbpmle.prg + + Implemented project building. + Right click on project tree node and select + or context menu options. + + I am looking for Qt like process management in Harbour. + I mean, I need callback when process is running. + 2009-12-08 16:56 UTC+0100 Viktor Szakats (harbour.01 syenar.hu) * src/common/hbver.c ! Fixed determining the patch level of MSVC compiler on diff --git a/harbour/contrib/hbide/hbide.prg b/harbour/contrib/hbide/hbide.prg index c734b57ef1..cfd2a9492d 100644 --- a/harbour/contrib/hbide/hbide.prg +++ b/harbour/contrib/hbide/hbide.prg @@ -234,8 +234,12 @@ CLASS HbIde METHOD updateHbp() METHOD saveProject() METHOD addSourcesToProject() - - + /* Project Build and Launch Methods */ + DATA cProcessInfo + DATA qProcess + METHOD buildProject() + METHOD buildProjectViaQt() + METHOD readProcessInfo() ENDCLASS /*----------------------------------------------------------------------*/ @@ -588,7 +592,7 @@ METHOD HbIde:editSource( cSourceFile, nPos, nHPos, nVPos ) LOCAL oTab, qEdit, qHiliter, qLayout, qDocument, qHScr, qVScr LOCAL lFirst := .t. - IF !( IsValidSource( cSourceFile ) ) + IF !( IsValidText( cSourceFile ) ) RETURN Self ENDIF @@ -1054,7 +1058,8 @@ METHOD HbIde:manageProjectContext( mp1, mp2, oXbpTreeItem ) // aadd( aPops, { "Properties" , {|| ::loadProjectProperties( cHbi, .f., .t. ) } } ) aadd( aPops, { "" } ) - aadd( aPops, { "Save and Build" , {|| NIL } } ) + aadd( aPops, { "Save and Build" , {|| ::buildProject( oXbpTreeItem:caption ) } } ) + aadd( aPops, { "Save and Build (Qt)" , {|| ::buildProjectViaQt( oXbpTreeItem:caption ) } } ) aadd( aPops, { "Save, Build and Launch" , {|| NIL } } ) aadd( aPops, { "" } ) aadd( aPops, { "Save and Re-Build" , {|| NIL } } ) @@ -1373,6 +1378,9 @@ METHOD HbIde:buildOutputResults() ::oDockB2:oWidget:setFocusPolicy( Qt_NoFocus ) ::oOutputResult := XbpMLE():new( ::oDockB2 ):create( , , { 0,0 }, { 100, 400 }, , .t. ) + ::oOutputResult:wordWrap := .f. + //::oOutputResult:dataLink := {|x| IIf( x==NIL, cText, cText := x ) } + ::oDockB2:oWidget:setWidget( QT_PTROFXBP( ::oOutputResult ) ) ::oDlg:oWidget:addDockWidget_1( Qt_BottomDockWidgetArea, QT_PTROFXBP( ::oDockB2 ), Qt_Vertical ) @@ -1613,6 +1621,8 @@ METHOD HbIde:loadProjectProperties( cProject, lNew, lFetch ) IF n == 0 aadd( ::aProjects, { lower( cProject ), cProject, aclone( ::aPrjProps ) } ) + ELSE + ::aProjects[ n,3 ] := aclone( ::aPrjProps ) ENDIF RETURN Self @@ -1693,6 +1703,8 @@ METHOD HbIde:fetchProjectProperties() ::aPrpObjs := {} ENDIF + ::manageFocusInEditor() + RETURN Self /*----------------------------------------------------------------------*/ @@ -1745,7 +1757,7 @@ METHOD HbIde:updateHbp( iIndex ) /* Final assault */ ::aPrpObjs[ E_oPrjHbp ]:setPlainText( ArrayToMemo( txt_ ) ) - RETURN nil + RETURN txt_ /*----------------------------------------------------------------------*/ @@ -1816,5 +1828,100 @@ METHOD HbIde:addSourcesToProject() RETURN Self /*----------------------------------------------------------------------*/ -// +// Project Builds /*----------------------------------------------------------------------*/ +/* hb_processRun( , [ ], [ @ ], [ @ ], [ ] ) -> */ + +METHOD HbIde:buildProject( cProject ) + LOCAL cCmd, cOutput, cErrors, n, aPrj, cHbpPath, aHbp + + IF empty( cProject ) + RETURN Self + ENDIF + + n := ascan( ::aProjects, {|e_, x| x := e_[ 3 ], x[ 1,2,PRJ_PRP_TITLE ] == cProject } ) + aPrj := ::aProjects[ n,3 ] + cHbpPath := aPrj[ PRJ_PRP_PROPERTIES, 2, PRJ_PRP_LOCATION ] + hb_OsPathSeparator() + aPrj[ PRJ_PRP_PROPERTIES, 2, PRJ_PRP_OUTPUT ] + ".hbp" + + aHbp := {} + aeval( aPrj[ PRJ_PRP_FLAGS, 2 ], {|e| aadd( aHbp, e ) } ) + aeval( FilesToSources( aPrj[ PRJ_PRP_SOURCES, 2 ] ), {|e| aadd( aHbp, e ) } ) + + CreateTarget( cHbpPath, aHbp ) + + cCmd := "hbmk2.exe " + cHbpPath + + ::lDockBVisible := .t. + ::oDockB2:show() + + hb_processRun( cCmd, , @cOutput, @cErrors ) + + ::oOutputResult:setData( cOutput + CRLF + CRLF + cErrors ) + + RETURN Self + +/*----------------------------------------------------------------------*/ + +METHOD HbIde:buildProjectViaQt( cProject ) + LOCAL n, aPrj, cHbpPath, aHbp, qStringList + + n := ascan( ::aProjects, {|e_, x| x := e_[ 3 ], x[ 1,2,PRJ_PRP_TITLE ] == cProject } ) + aPrj := ::aProjects[ n,3 ] + cHbpPath := aPrj[ PRJ_PRP_PROPERTIES, 2, PRJ_PRP_LOCATION ] + hb_OsPathSeparator() + aPrj[ PRJ_PRP_PROPERTIES, 2, PRJ_PRP_OUTPUT ] + ".hbp" + + aHbp := {} + aeval( aPrj[ PRJ_PRP_FLAGS, 2 ], {|e| aadd( aHbp, e ) } ) + aeval( FilesToSources( aPrj[ PRJ_PRP_SOURCES, 2 ] ), {|e| aadd( aHbp, e ) } ) + + CreateTarget( cHbpPath, aHbp ) + + ::lDockBVisible := .t. + ::oDockB2:show() + + ::cProcessInfo := "" + + qStringList := QStringList():new() + qStringList:append( cHbpPath ) + + ::qProcess := QProcess():new() + ::qProcess:setReadChannelMode( 0 ) + ::qProcess:setReadChannel( 0 ) + + Qt_Connect_Signal( QT_PTROF( ::qProcess ), "readyReadStandardOutput()", {|o,i| ::readProcessInfo( 3, i, o ) } ) + Qt_Connect_Signal( QT_PTROF( ::qProcess ), "finished(int,int)", {|o,i| ::readProcessInfo( 2, i, o ) } ) + + ::qProcess:start( "hbmk2.exe", QT_PTROF( qStringList ) ) + + RETURN Self + +/*----------------------------------------------------------------------*/ + +METHOD HbIde:readProcessInfo( nMode, iBytes ) + LOCAL cLine + + DO CASE + CASE nMode == 1 + ::cProcessInfo += ::qProcess:read( iBytes ) + ::oOutputResult:setData( ::cProcessInfo ) + + CASE nMode == 3 + cLine := space( 1024 ) + ::qProcess:readLine( @cLine, 1024 ) + IF !empty( cLine ) + ::cProcessInfo += CRLF + trim( cLine ) + ::oOutputResult:oWidget:appendPlainText( cLine ) + ENDIF + + CASE nMode == 2 + ::qProcess:kill() + Qt_DisConnect_Signal( QT_PTROF( ::qProcess ), "finished(int,int)" ) + Qt_DisConnect_Signal( QT_PTROF( ::qProcess ), "bytesWritten(int)" ) + + ::qProcess:pPtr := 0 + + ENDCASE + + RETURN nil + +/*----------------------------------------------------------------------*/ + diff --git a/harbour/contrib/hbide/idemisc.prg b/harbour/contrib/hbide/idemisc.prg index 910e12ba57..56b12f4c1f 100644 --- a/harbour/contrib/hbide/idemisc.prg +++ b/harbour/contrib/hbide/idemisc.prg @@ -373,7 +373,7 @@ FUNCTION MemoToArray( s ) /*----------------------------------------------------------------------*/ -FUNCTION IsValidSource( cSourceFile ) +FUNCTION IsValidText( cSourceFile ) LOCAL cExt hb_fNameSplit( cSourceFile, , , @cExt ) @@ -383,6 +383,16 @@ FUNCTION IsValidSource( cSourceFile ) /*----------------------------------------------------------------------*/ +FUNCTION IsValidSource( cSourceFile ) + LOCAL cExt + + hb_fNameSplit( cSourceFile, , , @cExt ) + cExt := lower( cExt ) + + RETURN ( cExt $ ".c,.cpp,.prg,.res,.rc" ) + +/*----------------------------------------------------------------------*/ + FUNCTION PathNormalized( cPath, lLower ) LOCAL S @@ -394,3 +404,16 @@ FUNCTION PathNormalized( cPath, lLower ) /*----------------------------------------------------------------------*/ +FUNCTION FilesToSources( aFiles ) + LOCAL aSrc := {} + LOCAL s + + FOR EACH s IN aFiles + IF IsValidSource( s ) + aadd( aSrc, s ) + ENDIF + NEXT + + RETURN aSrc + +/*----------------------------------------------------------------------*/ diff --git a/harbour/contrib/hbide/projects/hbide.hbi b/harbour/contrib/hbide/projects/hbide.hbi index 88ba01db9e..cfe53078fc 100644 --- a/harbour/contrib/hbide/projects/hbide.hbi +++ b/harbour/contrib/hbide/projects/hbide.hbi @@ -2,17 +2,23 @@ Type = Executable Title = Harbour-Qt IDE Location = projects -WorkingFolder = +WorkingFolder = projects DestinationFolder = projects Output = hbide LaunchParams = LaunchProgram = [ FLAGS ] +../../hbxbp/hbxbp.hbc -w3 +-inc +-gui -es2 -lhbwin +-lpsapi -Lc:\qt\2009.01\qt\lib +-oprojects\hbides.exe +-workdir=projects/${hb_comp}/hbide [ SOURCES ] # "Not Equal To == #" is a comment line as is accepted in .hbp diff --git a/harbour/contrib/hbqt/hbqt_slots.cpp b/harbour/contrib/hbqt/hbqt_slots.cpp index 38d184b344..43b466d73e 100644 --- a/harbour/contrib/hbqt/hbqt_slots.cpp +++ b/harbour/contrib/hbqt/hbqt_slots.cpp @@ -511,6 +511,20 @@ void Slots::cellPressed( int row, int column ) void Slots::currentCellChanged( int currentRow, int currentColumn, int previousRow, int previousColumn ) { hbqt_SlotsExecIntIntIntInt( qobject_cast( sender() ), "currentCellChanged(int,int,int,int)", currentRow, currentColumn, previousRow, previousColumn ); } void Slots::tabCloseRequested( int index ) { hbqt_SlotsExecInt( qobject_cast( sender() ), "tabCloseRequested(int)", index ); } void Slots::paintRequested( QPrinter * printer ) { hbqt_SlotsExecPointer( qobject_cast( sender() ), "paintRequested(QPrinter)", printer ); } +/* QIODevice */ +void Slots::aboutToClose() { hbqt_SlotsExec( qobject_cast( sender() ), "aboutToClose()" ); } +void Slots::bytesWritten( qint64 bytes ) { hbqt_SlotsExecInt( qobject_cast( sender() ), "bytesWritten(int)", bytes ); } +void Slots::readChannelFinished() { hbqt_SlotsExec( qobject_cast( sender() ), "readChannelFinished()" ); } +void Slots::readyRead() { hbqt_SlotsExec( qobject_cast( sender() ), "readyRead()" ); } +/* QProcess */ +void Slots::error( QProcess::ProcessError error ) { hbqt_SlotsExecInt( qobject_cast( sender() ), "error(error)", error ); } +void Slots::finished( int exitCode, QProcess::ExitStatus exitStatus ) { hbqt_SlotsExecIntInt( qobject_cast( sender() ), "finished(int,int)", exitCode, exitStatus ); } +void Slots::readyReadStandardError() { hbqt_SlotsExec( qobject_cast( sender() ), "readyReadStandardError()" ); } +void Slots::readyReadStandardOutput() { hbqt_SlotsExec( qobject_cast( sender() ), "readyReadStandardOutput()" ); } +void Slots::started() { hbqt_SlotsExec( qobject_cast( sender() ), "started()" ); } +void Slots::stateChanged( QProcess::ProcessState newState ) { hbqt_SlotsExecInt( qobject_cast( sender() ), "stateChanged(int)", newState ); } +/* */ + /*----------------------------------------------------------------------*/ /* @@ -627,6 +641,17 @@ HB_FUNC( QT_CONNECT_SIGNAL ) else if( signal == ( QString ) "currentCellChanged(int,int,int,int)" ) ret = object->connect( object, SIGNAL( currentCellChanged( int, int, int, int ) ) , t_slots, SLOT( currentCellChanged( int, int, int, int ) ) , Qt::AutoConnection ); else if( signal == ( QString ) "tabCloseRequested(int)" ) ret = object->connect( object, SIGNAL( tabCloseRequested( int ) ) , t_slots, SLOT( tabCloseRequested( int ) ) , Qt::AutoConnection ); else if( signal == ( QString ) "paintRequested(QPrinter)" ) ret = object->connect( object, SIGNAL( paintRequested( QPrinter * ) ) , t_slots, SLOT( paintRequested( QPrinter * ) ) , Qt::AutoConnection ); + /* QIODevice & QProcess */ + else if( signal == ( QString ) "aboutToClose()" ) ret = object->connect( object, SIGNAL( aboutToClose() ) , t_slots, SLOT( aboutToClose() ) , Qt::AutoConnection ); + else if( signal == ( QString ) "bytesWritten(int)" ) ret = object->connect( object, SIGNAL( bytesWritten( qint64 ) ) , t_slots, SLOT( bytesWritten( qint64 ) ) , Qt::AutoConnection ); + else if( signal == ( QString ) "readChannelFinished()" ) ret = object->connect( object, SIGNAL( readChannelFinished() ) , t_slots, SLOT( readChannelFinished() ) , Qt::AutoConnection ); + else if( signal == ( QString ) "readyRead()" ) ret = object->connect( object, SIGNAL( readyRead() ) , t_slots, SLOT( readyRead() ) , Qt::AutoConnection ); + else if( signal == ( QString ) "error(int)" ) ret = object->connect( object, SIGNAL( error( int ) ) , t_slots, SLOT( error( int ) ) , Qt::AutoConnection ); + else if( signal == ( QString ) "finished(int,int)" ) ret = object->connect( object, SIGNAL( finished( int, QProcess::ExitStatus ) ) , t_slots, SLOT( finished( int, QProcess::ExitStatus ) ) , Qt::AutoConnection ); + else if( signal == ( QString ) "readyReadStandardError()" ) ret = object->connect( object, SIGNAL( readyReadStandardError() ) , t_slots, SLOT( readyReadStandardError() ) , Qt::AutoConnection ); + else if( signal == ( QString ) "readyReadStandardOutput()" ) ret = object->connect( object, SIGNAL( readyReadStandardOutput() ) , t_slots, SLOT( readyReadStandardOutput() ) , Qt::AutoConnection ); + else if( signal == ( QString ) "started()" ) ret = object->connect( object, SIGNAL( started() ) , t_slots, SLOT( started() ) , Qt::AutoConnection ); + else if( signal == ( QString ) "stateChanged(int)" ) ret = object->connect( object, SIGNAL( stateChanged( int ) ) , t_slots, SLOT( stateChanged( int ) ) , Qt::AutoConnection ); else ret = false; if( ret == true ) @@ -734,6 +759,17 @@ static bool disconnect_signal( QObject * object, const char * signal ) else if( signal == ( QString ) "currentCellChanged(int,int,int,int)" ) return object->disconnect( SIGNAL( currentCellChanged( int, int, int, int ) ) ); else if( signal == ( QString ) "tabCloseRequested(int)" ) return object->disconnect( SIGNAL( tabCloseRequested( int ) ) ); else if( signal == ( QString ) "paintRequested(QPrinter)" ) return object->disconnect( SIGNAL( paintRequested( QPrinter * ) ) ); + /* QIODevice & QProcess */ + else if( signal == ( QString ) "aboutToClose()" ) return object->disconnect( SIGNAL( aboutToClose() ) ); + else if( signal == ( QString ) "bytesWritten(int)" ) return object->disconnect( SIGNAL( bytesWritten( qint64 ) ) ); + else if( signal == ( QString ) "readChannelFinished()" ) return object->disconnect( SIGNAL( readChannelFinished() ) ); + else if( signal == ( QString ) "readyRead()" ) return object->disconnect( SIGNAL( readyRead() ) ); + else if( signal == ( QString ) "error(int)" ) return object->disconnect( SIGNAL( error( int ) ) ); + else if( signal == ( QString ) "finished(int,int)" ) return object->disconnect( SIGNAL( finished( int, QProcess::ExitStatus ) ) ); + else if( signal == ( QString ) "readyReadStandardError()" ) return object->disconnect( SIGNAL( readyReadStandardError() ) ); + else if( signal == ( QString ) "readyReadStandardOutput()" ) return object->disconnect( SIGNAL( readyReadStandardOutput() ) ); + else if( signal == ( QString ) "started()" ) return object->disconnect( SIGNAL( started() ) ); + else if( signal == ( QString ) "stateChanged(int)" ) return object->disconnect( SIGNAL( stateChanged( int ) ) ); return false; } diff --git a/harbour/contrib/hbqt/hbqt_slots.h b/harbour/contrib/hbqt/hbqt_slots.h index 578f4a8420..d35620d41d 100644 --- a/harbour/contrib/hbqt/hbqt_slots.h +++ b/harbour/contrib/hbqt/hbqt_slots.h @@ -75,6 +75,7 @@ #include #include #include +#include #include "hbapi.h" #include "hbapiitm.h" @@ -324,6 +325,19 @@ public slots: void currentCellChanged( int currentRow, int currentColumn, int previousRow, int previousColumn ); void tabCloseRequested( int index ); void paintRequested( QPrinter * printer ); + /* QIODevice */ + void aboutToClose(); + void bytesWritten( qint64 bytes ); + void readChannelFinished(); + void readyRead(); + /* QProcess */ + void error( QProcess::ProcessError error ); + void finished( int exitCode, QProcess::ExitStatus exitStatus ); + void readyReadStandardError(); + void readyReadStandardOutput(); + void started(); + void stateChanged( QProcess::ProcessState newState ); + /* */ }; class Events: public QObject diff --git a/harbour/contrib/hbxbp/xbpmle.prg b/harbour/contrib/hbxbp/xbpmle.prg index 8f2c39eb7d..ada0507fda 100644 --- a/harbour/contrib/hbxbp/xbpmle.prg +++ b/harbour/contrib/hbxbp/xbpmle.prg @@ -141,7 +141,7 @@ METHOD XbpMLE:create( oParent, oOwner, aPos, aSize, aPresParams, lVisible ) ::xbpWindow:create( oParent, oOwner, aPos, aSize, aPresParams, lVisible ) - ::oWidget := QTextEdit():new( ::pParent ) + ::oWidget := QPlainTextEdit():new( ::pParent ) IF !( ::editable ) ::oWidget:setReadOnly( .t. )