From 94b33cecb73f0bd80bfc03dc89e86f66ba31e397 Mon Sep 17 00:00:00 2001 From: Pritpal Bedi Date: Mon, 25 Jan 2010 07:13:15 +0000 Subject: [PATCH] 2010-01-24 22:28 UTC-0800 Pritpal Bedi (pritpal@vouchcac.com) * contrib/hbxbp/Makefile * contrib/hbxbp/hbpprocess.prg + Implemented first HbpProcess() class ( Harbour Extension ) which is based on Qt's process management classes. The usage concept is well defined in /contrib/hbide/ideprojmanager.prg. I will write the documentation at some later date. * contrib/hbide/resources/projectproperties.ui + More components. * contrib/hbide/projects/hbide.hbi + More info. * contrib/hbide/hbide.ch * contrib/hbide/hbide.prg * contrib/hbide/idedocks.prg * contrib/hbide/idemisc.prg * contrib/hbide/ideobject.prg * contrib/hbide/ideprojmanager.prg * contrib/hbide/idesaveload.prg ! Updated to hold Development Environments concept introduced. Read below. - contrib/hbide/hbide.env + contrib/hbide/resources/hbide.env + The environment skeletons (working) on my machine connecting hbIDE to hbMK2 engine. You can copy it and place it in projects folder with suitable path amendments and call it in hbIDE. This implementation facilitae to generate any project on any compiler from within single instance of hbIDE without leaving it. Here are the implementation details: FORMAT ====== [ BCC55 5.5.1 Command Line Tools ] {hb_comp} bcc {shell} cmd.exe {ext} bat # {content} set HB_COMPILER=bcc {content} set PATH=c:\harbour_dev;c:\harbour_dev\bcc\bin;C:\harbour_dev\harbour\bcc\bin; [ MINGW 4.4.2 Windows ] {hb_plat} win {hb_comp} mingw {content} set PATH=c:\mingw\bin;c:\qt\2009.03\qt\bin; {content} set PATH=c:\harbour_dev;c:\harbour_dev\harbour\mingw\bin;%path% {content} set HB_WITH_QT=c:\qt\2009.03\qt ... {hb_plat} == set HB_ARCHITECTURE= {hb_comp} == set HB_COMPILER= {shell} == shell command to execute {ext} == the extension of shell commands file {content} == active contents placed in the shell commands file Any lines with {contents} marker will form the body of commands file. You can place remarks preceded with # sign. Currently {contents} are implemented, rest will take a couple of days. PLACEHOLDER =========== in dialog but with separate button to save this and its path information alone. Just avoided one more dialog. ACTIVATION ========== Right-click on node in "Projects" tree and select . The selected environment will become the default for current session and will be saved for next invocation until it is changed. Next build will respect this setting. EFFECTIVENESS ============= Create a desktop icon pointing to hbIDE.exe and place the only parameter poing to "hbide.env" file. You can copy it anywhere in your project tree, amend it to suit your requirements, and just execute hbIDE on your desktop. NOTE: you _MUST NOT_ set any compiler specific variables before invoking hbIDE. Your working slate must be clean. WHAT_IS_NOT_DONE ================ The bash commands and their shell invocation. But I know a lot of you will implement that in no time. --- harbour/ChangeLog | 90 +++ harbour/contrib/hbide/hbide.ch | 9 +- harbour/contrib/hbide/hbide.env | 0 harbour/contrib/hbide/hbide.prg | 48 +- harbour/contrib/hbide/idedocks.prg | 13 +- harbour/contrib/hbide/idemisc.prg | 45 +- harbour/contrib/hbide/ideobject.prg | 5 + harbour/contrib/hbide/ideprojmanager.prg | 724 ++++++++++-------- harbour/contrib/hbide/idesaveload.prg | 8 +- harbour/contrib/hbide/projects/hbide.hbi | 1 + harbour/contrib/hbide/resources/hbide.env | 55 ++ .../hbide/resources/projectproperties.ui | 235 ++++-- harbour/contrib/hbxbp/Makefile | 1 + harbour/contrib/hbxbp/hbpprocess.prg | 298 +++++++ 14 files changed, 1125 insertions(+), 407 deletions(-) delete mode 100644 harbour/contrib/hbide/hbide.env create mode 100644 harbour/contrib/hbide/resources/hbide.env create mode 100644 harbour/contrib/hbxbp/hbpprocess.prg diff --git a/harbour/ChangeLog b/harbour/ChangeLog index cc67daf7ef..d3dd2cb471 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -17,6 +17,96 @@ past entries belonging to author(s): Viktor Szakats. */ +2010-01-24 22:28 UTC-0800 Pritpal Bedi (pritpal@vouchcac.com) + * contrib/hbxbp/Makefile + * contrib/hbxbp/hbpprocess.prg + + Implemented first HbpProcess() class ( Harbour Extension ) + which is based on Qt's process management classes. + The usage concept is well defined in + /contrib/hbide/ideprojmanager.prg. + I will write the documentation at some later date. + + * contrib/hbide/resources/projectproperties.ui + + More components. + + * contrib/hbide/projects/hbide.hbi + + More info. + + * contrib/hbide/hbide.ch + * contrib/hbide/hbide.prg + * contrib/hbide/idedocks.prg + * contrib/hbide/idemisc.prg + * contrib/hbide/ideobject.prg + * contrib/hbide/ideprojmanager.prg + * contrib/hbide/idesaveload.prg + ! Updated to hold Development Environments concept introduced. + Read below. + - contrib/hbide/hbide.env + + contrib/hbide/resources/hbide.env + + The environment skeletons (working) on my machine connecting + hbIDE to hbMK2 engine. You can copy it and place it + in projects folder with suitable path amendments and + call it in hbIDE. This implementation facilitae to + generate any project on any compiler from within + single instance of hbIDE without leaving it. + + Here are the implementation details: + + FORMAT + ====== + [ BCC55 5.5.1 Command Line Tools ] + {hb_comp} bcc + {shell} cmd.exe + {ext} bat + # + {content} set HB_COMPILER=bcc + {content} set PATH=c:\harbour_dev;c:\harbour_dev\bcc\bin;C:\harbour_dev\harbour\bcc\bin; + + [ MINGW 4.4.2 Windows ] + {hb_plat} win + {hb_comp} mingw + {content} set PATH=c:\mingw\bin;c:\qt\2009.03\qt\bin; + {content} set PATH=c:\harbour_dev;c:\harbour_dev\harbour\mingw\bin;%path% + {content} set HB_WITH_QT=c:\qt\2009.03\qt + ... + + {hb_plat} == set HB_ARCHITECTURE= + {hb_comp} == set HB_COMPILER= + {shell} == shell command to execute + {ext} == the extension of shell commands file + {content} == active contents placed in the shell commands file + Any lines with {contents} marker will form the + body of commands file. You can place remarks + preceded with # sign. + + Currently {contents} are implemented, rest will take a couple of days. + + PLACEHOLDER + =========== + in dialog but with separate + button to save this and its path information alone. Just avoided one + more dialog. + + ACTIVATION + ========== + Right-click on node in "Projects" tree and select . + The selected environment will become the default for current session and will + be saved for next invocation until it is changed. Next build will respect + this setting. + + EFFECTIVENESS + ============= + Create a desktop icon pointing to hbIDE.exe and place the only parameter + poing to "hbide.env" file. You can copy it anywhere in your project tree, + amend it to suit your requirements, and just execute hbIDE on your desktop. + NOTE: you _MUST NOT_ set any compiler specific variables before invoking + hbIDE. Your working slate must be clean. + + WHAT_IS_NOT_DONE + ================ + The bash commands and their shell invocation. But I know a lot of you + will implement that in no time. + 2010-01-25 05:09 UTC+0100 Viktor Szakats (harbour.01 syenar.hu) * contrib/hbwin/win_tprn.prg * contrib/hbwin/win_bmp.c diff --git a/harbour/contrib/hbide/hbide.ch b/harbour/contrib/hbide/hbide.ch index 63f487509e..6fee196d78 100644 --- a/harbour/contrib/hbide/hbide.ch +++ b/harbour/contrib/hbide/hbide.ch @@ -82,8 +82,11 @@ #define ThemesDialogGeometry 11 #define CurrentTheme 12 #define CurrentCodec 13 +#define PathMk2 14 +#define PathEnv 15 +#define CurrentEnvironment 16 -#define INI_HBIDE_VRBLS 13 +#define INI_HBIDE_VRBLS 16 /* .hbi structure constants */ #define PRJ_PRP_PROPERTIES 1 @@ -101,8 +104,9 @@ #define PRJ_PRP_OUTPUT 6 #define PRJ_PRP_LPARAMS 7 #define PRJ_PRP_LPROGRAM 8 +#define PRJ_PRP_BACKUP 9 // -#define PRJ_PRP_PRP_VRBLS 8 +#define PRJ_PRP_PRP_VRBLS 9 /* Project Properties array elements */ #define E_qPrjType 1 @@ -127,6 +131,7 @@ #define SB_PNL_SELECTEDCHARS 6 #define SB_PNL_MODIFIED 7 #define SB_PNL_M_2 8 +#define SB_PNL_ENVIRON 8 #define SB_PNL_STREAM 9 #define SB_PNL_EDIT 10 #define SB_PNL_SEARCH 11 diff --git a/harbour/contrib/hbide/hbide.env b/harbour/contrib/hbide/hbide.env deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/harbour/contrib/hbide/hbide.prg b/harbour/contrib/hbide/hbide.prg index 47ea60abc3..5aa81a6f1d 100644 --- a/harbour/contrib/hbide/hbide.prg +++ b/harbour/contrib/hbide/hbide.prg @@ -115,6 +115,7 @@ CLASS HbIde DATA oEM /* Editor Tabs Manager */ DATA oSM /* Souces Manager */ DATA oFR /* Find Replace Manager */ + DATA oEV /* Available Environments */ DATA oThemes DATA aMeta INIT {} /* Holds current definition only */ @@ -177,16 +178,22 @@ CLASS HbIde DATA lDockBVisible INIT .f. DATA lTabCloseRequested INIT .f. + DATA cWrkProject INIT "" + DATA cWrkTheme INIT "" + DATA cWrkCodec INIT "" + DATA cWrkPathMk2 INIT hb_getenv( "HBIDE_DIR_HBMK2" ) + DATA cWrkPathEnv INIT hb_DirBase() + "resources" + DATA cWrkEnvironment INIT "" + + DATA oEnvironment + DATA cSaveTo INIT "" DATA oOpenedSources DATA resPath INIT hb_DirBase() + "resources" + hb_OsPathSeparator() DATA pathSep INIT hb_OsPathSeparator() DATA cLastFileOpenPath INIT hb_DirBase() + "projects" - DATA cWrkProject INIT "" - DATA cWrkTheme INIT "" DATA cProcessInfo DATA cIniThemes - DATA cWrkCodec INIT "" DATA cSeparator INIT "/*" + replicate( "-", 70 ) + "*/" DATA nTabSpaces INIT 3 /* Via User Setup */ @@ -262,8 +269,9 @@ METHOD HbIde:create( cProjIni ) /* Load IDE Settings */ hbide_loadINI( Self, cProjIni ) /* Set variables from last session */ - ::cWrkTheme := ::aINI[ INI_HBIDE, CurrentTheme ] - ::cWrkCodec := ::aINI[ INI_HBIDE, CurrentCodec ] + ::cWrkTheme := ::aINI[ INI_HBIDE, CurrentTheme ] + ::cWrkCodec := ::aINI[ INI_HBIDE, CurrentCodec ] + ::cWrkEnvironment := ::aINI[ INI_HBIDE, CurrentEnvironment ] /* Set Codec at the Begining */ HbXbp_SetCodec( ::cWrkCodec ) @@ -294,6 +302,9 @@ METHOD HbIde:create( cProjIni ) /* Load IDE|User defined Themes */ hbide_loadThemes( Self ) + /* Load Environments */ + ::oEV := IdeEnvironments():new( Self, hbide_pathToOSPath( ::aINI[ INI_HBIDE, PathEnv ] + ::pathSep + "hbide.env" ) ):create() + /* Prepare Editor's Tabs */ ::oEM:prepareTabWidget() @@ -334,6 +345,9 @@ METHOD HbIde:create( cProjIni ) /* Again to be displayed in Statusbar */ HbXbp_SetCodec( ::cWrkCodec ) + /* Display cWrkEnvironment in StatusBar */ + ::oDK:dispEnvironment( ::cWrkEnvironment ) + /* Request Main Window to Appear on the Screen */ ::oDlg:Show() @@ -908,8 +922,8 @@ METHOD HbIde:manageItemSelected( oXbpTreeItem ) /*----------------------------------------------------------------------*/ METHOD HbIde:manageProjectContext( mp1, mp2, oXbpTreeItem ) - LOCAL n, cHbi, aPrj - LOCAL aPops := {} + LOCAL n, cHbi, aPrj, s + LOCAL aPops := {}, aSub :={} HB_SYMBOL_UNUSED( mp2 ) @@ -930,6 +944,16 @@ METHOD HbIde:manageProjectContext( mp1, mp2, oXbpTreeItem ) aadd( aPops, { "New Project" , {|| ::oPM:loadProperties( , .t., .t., .t. ) } } ) aadd( aPops, { "" } ) aadd( aPops, { "Load Project" , {|| ::oPM:loadProperties( , .f., .f., .t. ) } } ) + aadd( aPops, { "" } ) + // + IF !empty( ::oEV:getNames ) + aadd( aPops, { "" } ) + FOR EACH s IN ::oEV:getNames() + aadd( aSub, { s , {|x| ::cWrkEnvironment := x, ::oDK:dispEnvironment( x ) } } ) + NEXT + aadd( aPops, { aSub, "Environment..." } ) + ENDIF + // hbide_ExecPopup( aPops, mp1, ::oProjTree:oWidget ) CASE ::aProjData[ n, TRE_TYPE ] == "Project Name" @@ -951,7 +975,15 @@ METHOD HbIde:manageProjectContext( mp1, mp2, oXbpTreeItem ) aadd( aPops, { "Launch" , {|| ::oPM:launchProject( oXbpTreeItem:caption ) } } ) aadd( aPops, { "" } ) aadd( aPops, { "Close This Project" , {|| ::oPM:closeProject( oXbpTreeItem:caption ) } } ) - // + /* + IF !empty( ::oEV:getNames ) + aadd( aPops, { "" } ) + FOR EACH s IN ::oEV:getNames() + aadd( aSub, { s , {|x| ::cWrkEnvironment := x, ::oDK:dispEnvironment( x ) } } ) + NEXT + aadd( aPops, { aSub, "Select an environment" } ) + ENDIF + */ hbide_ExecPopup( aPops, mp1, ::oProjTree:oWidget ) CASE ::aProjData[ n, TRE_TYPE ] == "Source File" diff --git a/harbour/contrib/hbide/idedocks.prg b/harbour/contrib/hbide/idedocks.prg index 196c777e98..050d43cf32 100644 --- a/harbour/contrib/hbide/idedocks.prg +++ b/harbour/contrib/hbide/idedocks.prg @@ -72,7 +72,7 @@ /*----------------------------------------------------------------------*/ -CLASS IdeDockS INHERIT IdeObject +CLASS IdeDocks INHERIT IdeObject DATA nPass INIT 0 @@ -94,6 +94,7 @@ CLASS IdeDockS INHERIT IdeObject METHOD toggleBottomDocks() METHOD setStatusText( nPart, xValue ) METHOD getMarkWidget( nIndex ) + METHOD dispEnvironment( cEnviron ) ENDCLASS @@ -413,7 +414,7 @@ METHOD IdeDocks:buildStatusBar() ::oSBar:addItem( "", , , , "Ins" ):oWidget:setMinimumWidth( 30 ) ::oSBar:addItem( "", , , , "M_1" ):oWidget:setMinimumWidth( 30 ) ::oSBar:addItem( "", , , , "Modified" ):oWidget:setMinimumWidth( 50 ) - ::oSBar:addItem( "", , , , "M_2" ):oWidget:setMinimumWidth( 30 ) + ::oSBar:addItem( "", , , , "Environ" ):oWidget:setMinimumWidth( 30 ) ::oSBar:addItem( "", , , , "Stream" ):oWidget:setMinimumWidth( 20 ) ::oSBar:addItem( "", , , , "Edit" ):oWidget:setMinimumWidth( 20 ) ::oSBar:addItem( "", , , , "Search" ):oWidget:setMinimumWidth( 20 ) @@ -489,6 +490,12 @@ METHOD IdeDocks:toggleBottomDocks() /*----------------------------------------------------------------------*/ +METHOD IdeDocks:dispEnvironment( cEnviron ) + ::setStatusText( SB_PNL_ENVIRON, cEnviron ) + RETURN Self + +/*----------------------------------------------------------------------*/ + METHOD IdeDocks:setStatusText( nPart, xValue ) LOCAL oPanel := ::oSBar:getItem( nPart ) @@ -510,6 +517,8 @@ METHOD IdeDocks:setStatusText( nPart, xValue ) oPanel:caption := iif( xValue, "Modified", "" ) EXIT CASE SB_PNL_M_2 + CASE SB_PNL_ENVIRON + oPanel:caption := "Env: " + xValue EXIT CASE SB_PNL_STREAM EXIT diff --git a/harbour/contrib/hbide/idemisc.prg b/harbour/contrib/hbide/idemisc.prg index 77aceaf290..74c29e7b31 100644 --- a/harbour/contrib/hbide/idemisc.prg +++ b/harbour/contrib/hbide/idemisc.prg @@ -98,7 +98,7 @@ PROCEDURE hbide_justACall() /*----------------------------------------------------------------------*/ FUNCTION hbide_execPopup( aPops, aPos, qParent ) - LOCAL i, qPop, qPoint, qAct, cAct, xRet, pAct, a_ + LOCAL i, qPop, qPoint, qAct, cAct, xRet, pAct, a_, qSub, b_ qPop := QMenu():new( iif( hb_isObject( qParent ), qParent, NIL ) ) @@ -108,6 +108,13 @@ FUNCTION hbide_execPopup( aPops, aPos, qParent ) ELSE IF hb_isObject( aPops[ i, 1 ] ) qPop:addAction_4( aPops[ i, 1 ] ) + ELSEIF hb_isArray( aPops[ i, 1 ] ) /* Sub-menu */ + qSub := QMenu():new( qPop ) + FOR EACH a_ IN aPops[ i, 1 ] + qSub:addAction( a_[ 1 ] ) + NEXT + qSub:setTitle( aPops[ i,2 ] ) + qPop:addMenu( qSub ) ELSE qPop:addAction( aPops[ i, 1 ] ) ENDIF @@ -125,9 +132,16 @@ FUNCTION hbide_execPopup( aPops, aPos, qParent ) xRet := eval( aPops[ a_:__enumIndex(), 2 ] ) EXIT ENDIF + ELSEIF hb_isArray( a_[ 1 ] ) + FOR EACH b_ IN a_[ 1 ] + IF b_[ 1 ] == cAct + xRet := eval( b_[ 2 ], cAct ) + EXIT + ENDIF + NEXT ELSE IF a_[ 1 ] == cAct - xRet := eval( aPops[ a_:__enumIndex(), 2 ] ) + xRet := eval( aPops[ a_:__enumIndex(), 2 ], cAct ) EXIT ENDIF ENDIF @@ -335,7 +349,7 @@ FUNCTION hbide_fetchHbiStructFromFile( cProject ) STATIC FUNCTION hbide_pullHbiStruct( a_ ) LOCAL n, s, nPart, cKey, cVal, ss LOCAL aPrp := { "Type", "Title", "Location", "WorkingFolder", "DestinationFolder", ; - "Output", "LaunchParams", "LaunchProgram" } + "Output", "LaunchParams", "LaunchProgram", "BackupFolder" } LOCAL a1_0 := afill( array( PRJ_PRP_PRP_VRBLS ), "" ) LOCAL a1_1 := {} @@ -565,6 +579,12 @@ FUNCTION hbide_pathNormalized( cPath, lLower ) /*----------------------------------------------------------------------*/ +FUNCTION hbide_pathFile( cPath, cFile ) + cPath := iif( right( cPath, 1 ) $ "\/", substr( cPath, 1, len( cPath ) - 1 ), cPath ) + RETURN hbide_pathToOSPath( cPath + "\" + cFile ) + +/*----------------------------------------------------------------------*/ + FUNCTION hbide_pathToOSPath( cPath ) cPath := strtran( cPath, "/" , hb_osPathSeparator() ) @@ -763,8 +783,22 @@ FUNCTION hbide_parseKeyValPair( s, cKey, cVal ) /*----------------------------------------------------------------------*/ +FUNCTION hbide_parseFilter( s, cKey, cVal ) + LOCAL n, n1, lYes := .f. + + IF ( n := at( "{", s ) ) > 0 + IF ( n1 := at( "}", s ) ) > 0 + cKey := alltrim( substr( s, n+1, n1-n-1 ) ) + cVal := alltrim( substr( s, n1+1 ) ) + lYes := .t. + ENDIF + ENDIF + RETURN lYes + +/*----------------------------------------------------------------------*/ + FUNCTION hbide_dbg( ... ) - HB_TRACE( HB_TR_ALWAYS, procname(1),... ) + HB_TRACE( HB_TR_ALWAYS, ... ) RETURN nil /*----------------------------------------------------------------------*/ @@ -805,8 +839,7 @@ FUNCTION hbide_checkDefaultExtension( cFileName, cDefaultExt ) /*----------------------------------------------------------------------*/ FUNCTION hbide_pathProc( cPathR, cPathA ) - LOCAL cDirA - LOCAL cDirR, cDriveR, cNameR, cExtR + LOCAL cDirA, cDirR, cDriveR, cNameR, cExtR IF Empty( cPathA ) RETURN cPathR diff --git a/harbour/contrib/hbide/ideobject.prg b/harbour/contrib/hbide/ideobject.prg index 94e5e71472..1afdc8a1fe 100644 --- a/harbour/contrib/hbide/ideobject.prg +++ b/harbour/contrib/hbide/ideobject.prg @@ -89,6 +89,7 @@ CLASS IdeObject ACCESS oDK INLINE ::oIde:oDK ACCESS oAC INLINE ::oIde:oAC ACCESS oSM INLINE ::oIde:oSM + ACCESS oEV INLINE ::oIde:oEV ACCESS aMeta INLINE ::oIde:aMeta @@ -108,6 +109,10 @@ CLASS IdeObject ACCESS cWrkProject INLINE ::oIde:cWrkProject ACCESS cWrkTheme INLINE ::oIde:cWrkTheme ACCESS cWrkCodec INLINE ::oIde:cWrkCodec + ACCESS cWrkPathMk2 INLINE ::oIde:cWrkPathMk2 + ACCESS cWrkPathEnv INLINE ::oIde:cWrkPathEnv + ACCESS cWrkEnvironment INLINE ::oIde:cWrkEnvironment + // ACCESS resPath INLINE ::oIde:resPath ACCESS pathSep INLINE ::oIde:pathSep ACCESS cLastFileOpenPath INLINE ::oIde:cLastFileOpenPath diff --git a/harbour/contrib/hbide/ideprojmanager.prg b/harbour/contrib/hbide/ideprojmanager.prg index 9cbff2dbf9..9e1260ebdc 100644 --- a/harbour/contrib/hbide/ideprojmanager.prg +++ b/harbour/contrib/hbide/ideprojmanager.prg @@ -69,19 +69,129 @@ #include "common.ch" #include "hbclass.ch" +/*----------------------------------------------------------------------*/ +// +// Class IdeEnvironments +// /*----------------------------------------------------------------------*/ -#define CHN_BGN 1 -#define CHN_OUT 2 -#define CHN_ERR 3 -#define CHN_FIN 4 -#define CHN_STT 5 -#define CHN_ERE 6 -#define CHN_CLO 7 -#define CHN_BYT 8 -#define CHN_RCF 9 -#define CHN_REA 10 +CLASS IdeEnvironments + DATA oIde + DATA cEnvFile + DATA aNames INIT {} + DATA aEnvrns INIT {} + DATA aShellContents INIT {} + DATA aCommons INIT {} + + METHOD new( oIde, cEnvFile ) + METHOD create( oIde, cEnvFile ) + METHOD parse( aContents ) + METHOD prepareBatch( cEnviron ) + METHOD getNames() INLINE ::aNames + + ENDCLASS + +/*----------------------------------------------------------------------*/ + +METHOD IdeEnvironments:new( oIde, cEnvFile ) + + ::oIde := oIde + ::cEnvFile := cEnvFile + + RETURN Self + +/*----------------------------------------------------------------------*/ + +METHOD IdeEnvironments:create( oIde, cEnvFile ) + LOCAL a_ + + DEFAULT oIde TO ::oIde + DEFAULT cEnvFile TO ::cEnvFile + + ::oIde := oIde + ::cEnvFile := cEnvFile + + IF empty( ::cEnvFile ) .OR. !hb_fileExists( ::cEnvFile ) + RETURN Self + ENDIF + + a_:= hbide_readSource( ::cEnvFile ) + + ::parse( a_ ) + + RETURN Self + +/*----------------------------------------------------------------------*/ + +METHOD IdeEnvironments:parse( aContents ) + LOCAL s, cPart, cEnv, a_, cKey, cVal + + a_:= {} + cEnv := "" + FOR EACH s IN aContents + s := alltrim( s ) + IF empty( s ) .OR. left( s, 1 ) == "#" /* Remark */ + LOOP + ENDIF + IF left( s, 1 ) == "[" + s := alltrim( strtran( s, "[", "" ) ) + s := alltrim( strtran( s, "]", "" ) ) + IF lower( s ) == "common" + cPart := "common" + ELSE + cPart := "environment" + IF ( s != cEnv ) .AND. !empty( cEnv ) + aadd( ::aNames, cEnv ) + aadd( ::aEnvrns, { cEnv, a_ } ) + ENDIF + cEnv := s + a_:= {} + ENDIF + ELSE + IF cPart == "common" + IF hbide_parseKeyValPair( s, @cKey, @cVal ) + aadd( ::aCommons, { lower( cKey ), cVal } ) /* Format Later */ + ENDIF + ELSEIF cPart == "environment" + IF hbide_parseFilter( s, @cKey, @cVal ) + aadd( a_, { lower( cKey ), cVal } ) + ENDIF + ENDIF + ENDIF + NEXT + IF !empty( cEnv ) .AND. !empty( a_ ) + aadd( ::aNames, cEnv ) + aadd( ::aEnvrns, { cKey, a_ } ) + ENDIF + + RETURN Self + +/*----------------------------------------------------------------------*/ + +METHOD IdeEnvironments:prepareBatch( cEnviron ) + LOCAL n, cFile := space( 255 ), s, k, nHandle, a_ + + IF ( n := ascan( ::aEnvrns, {|e_| e_[ 1 ] == cEnviron } ) ) > 0 + IF ( nHandle := HB_FTempCreateEx( @cFile, NIL, "ide_", ".bat" ) ) > 0 + k := "" + FOR EACH a_ IN ::aEnvrns[ n, 2 ] + s := a_[ 1 ] + IF s == "content" + k += a_[ 2 ] + CRLF + ENDIF + NEXT + fWrite( nHandle, k ) + fClose( nHandle ) + ENDIF + ENDIF + + RETURN cFile + +/*----------------------------------------------------------------------*/ +// +// Class IdeProject +// /*----------------------------------------------------------------------*/ CLASS IdeProject @@ -97,6 +207,7 @@ CLASS IdeProject DATA wrkDirectory INIT hb_dirBase() + "projects" DATA destination INIT hb_dirBase() + "projects" DATA outputName INIT hb_dirBase() + "projects" + DATA backup INIT "" DATA launchParams INIT "" DATA launchProgram INIT "" DATA hbpFlags INIT {} @@ -104,9 +215,10 @@ CLASS IdeProject DATA metaData INIT {} DATA dotHbp INIT "" DATA compilers INIT "" - DATA hbmk2dir INIT hb_getenv( "HBIDE_DIR_HBMK2" ) + DATA cPathMk2 INIT hb_getenv( "HBIDE_DIR_HBMK2" ) + DATA cPathEnv INIT hb_DirBase() + "resources" - METHOD new( aProps ) + METHOD new( oIde, aProps ) METHOD applyMeta( s ) METHOD expandMeta( s ) @@ -114,7 +226,7 @@ CLASS IdeProject /*----------------------------------------------------------------------*/ -METHOD IdeProject:new( aProps ) +METHOD IdeProject:new( oIde, aProps ) LOCAL b_, a_ IF hb_isArray( aProps ) .AND. !empty( aProps ) @@ -148,6 +260,12 @@ METHOD IdeProject:new( aProps ) IF empty( ::wrkDirectory ) ::wrkDirectory := ::location ENDIF + IF !empty( oIde:aINI[ INI_HBIDE, PathMk2 ] ) + ::cPathMk2 := oIde:aINI[ INI_HBIDE, PathMk2 ] + ENDIF + IF !empty( oIde:aINI[ INI_HBIDE, PathEnv ] ) + ::cPathEnv := oIde:aINI[ INI_HBIDE, PathEnv ] + ENDIF FOR EACH a_ IN ::metaData a_[ 2 ] := hbide_pathNormalized( a_[ 2 ], .f. ) @@ -193,7 +311,6 @@ CLASS IdeProjManager INHERIT IdeObject DATA cSaveTo DATA aPrjProps INIT {} - DATA qProcess DATA nStarted INIT 0 DATA lLaunch INIT .f. @@ -201,6 +318,8 @@ CLASS IdeProjManager INHERIT IdeObject DATA cPPO INIT "" DATA lPPO INIT .f. DATA oProject + DATA cBatch + DATA oProcess METHOD new( oIde ) METHOD create( oIde ) @@ -224,10 +343,10 @@ CLASS IdeProjManager INHERIT IdeObject METHOD closeProject( cProject ) METHOD promptForPath( cObjPathName, cTitle, cObjFileName, cObjPath2, cObjPath3 ) METHOD buildProject( cProject, lLaunch, lRebuild, lPPO, lViaQt ) - METHOD buildProcess() - METHOD readProcessInfo( nMode, i, ii ) METHOD launchProject( cProject ) - + METHOD showOutput( cOutput, mp2, oProcess ) + METHOD finished( nExitCode, nExitStatus, oProcess ) + METHOD saveEnvironments() ENDCLASS /*----------------------------------------------------------------------*/ @@ -327,7 +446,7 @@ METHOD IdeProjManager:loadProperties( cProjFileName, lNew, lFetch, lUpdateTree ) IF lFetch /* Access/Assign via this object */ - ::oProject := IdeProject():new( ::aPrjProps ) + ::oProject := IdeProject():new( ::oIde, ::aPrjProps ) // ::fetchProperties() IF !empty( ::cSaveTo ) .and. hb_FileExists( ::cSaveTo ) @@ -380,13 +499,18 @@ METHOD IdeProjManager:fetchProperties() ENDCASE cLukupPng := ::resPath + "folder.png" + // ::oUI:q_buttonChoosePrjLoc:setIcon( cLukupPng ) - ::oUI:q_buttonChooseWd:setIcon( cLukupPng ) - ::oUI:q_buttonChooseDest:setIcon( cLukupPng ) + ::oUI:q_buttonChooseWd :setIcon( cLukupPng ) + ::oUI:q_buttonChooseDest :setIcon( cLukupPng ) + ::oUI:q_buttonBackup :setIcon( cLukupPng ) + ::oUI:q_buttonPathMk2 :setIcon( cLukupPng ) + ::oUI:q_buttonPathEnv :setIcon( cLukupPng ) + ::oUI:q_buttonSaveEnv :setIcon( ::resPath + "save.png" ) - ::oUI:q_buttonSelect:setIcon( ::resPath + "open.png" ) - ::oUI:q_buttonSort:setIcon( ::resPath + "toupper.png" ) // TODO: toupper.png => atoz.png - ::oUI:q_buttonSortZA:setIcon( ::resPath + "tolower.png" ) // tolower.png => ztoa.png + ::oUI:q_buttonSelect :setIcon( ::resPath + "open.png" ) + ::oUI:q_buttonSort :setIcon( ::resPath + "toupper.png" ) // TODO: toupper.png => atoz.png + ::oUI:q_buttonSortZA :setIcon( ::resPath + "tolower.png" ) // tolower.png => ztoa.png ::oUI:q_buttonSortOrg:setIcon( ::resPath + "invertcase.png" ) // tolower.png => ztoa.png ::oUI:signal( "buttonCn" , "clicked()", {|| ::oUI:oWidget:close() } ) @@ -396,14 +520,22 @@ METHOD IdeProjManager:fetchProperties() ::oUI:signal( "buttonSort" , "clicked()", {|| ::sortSources( "az" ) } ) ::oUI:signal( "buttonSortZA" , "clicked()", {|| ::sortSources( "za" ) } ) ::oUI:signal( "buttonSortOrg" , "clicked()", {|| ::sortSources( "org" ) } ) + ::oUI:signal( "buttonSaveEnv" , "clicked()", {|| ::saveEnvironments() } ) // ::oUI:signal( "tabWidget" , "currentChanged(int)", {|o,p| ::updateHbp( p, o ) } ) - ::oUI:signal( "editMetaData" , "textChanged()", {|o| ::updateMetaData( o ) } ) + ::oUI:signal( "editMetaData" , "textChanged()" , {|o| ::updateMetaData( o ) } ) - ::oUI:signal( "buttonChoosePrjLoc", "clicked()", {|| ::PromptForPath( 'editPrjLoctn', 'Choose the Project Location...' ) } )//, ; - // 'editOutName', "editWrkFolder", "editDstFolder" ) } ) - ::oUI:signal( "buttonChooseWd" , "clicked()", {|| ::PromptForPath( 'editWrkFolder', 'Choose a Working Folder...' ) } ) - ::oUI:signal( "buttonChooseDest" , "clicked()", {|| ::PromptForPath( 'editDstFolder', 'Choose a Destination Folder...' ) } ) + ::oUI:signal( "buttonChoosePrjLoc", "clicked()", {|| ::PromptForPath( 'editPrjLoctn' , 'Choose Project Location...' ) } ) + ::oUI:signal( "buttonChooseWd" , "clicked()", {|| ::PromptForPath( 'editWrkFolder', 'Choose Working Folder...' ) } ) + ::oUI:signal( "buttonChooseDest" , "clicked()", {|| ::PromptForPath( 'editDstFolder', 'Choose Destination Folder...' ) } ) + ::oUI:signal( "buttonBackup" , "clicked()", {|| ::PromptForPath( 'editBackup' , 'Choose Backup Folder...' ) } ) + ::oUI:signal( "buttonPathMk2" , "clicked()", {|| ::PromptForPath( 'editPathMk2' , 'Choose hbMK2.exe Folder...' ) } ) + ::oUI:signal( "buttonPathEnv" , "clicked()", {|| ::PromptForPath( 'editPathEnv' , 'Choose hbIDE.env Folder...' ), ; + ::oUI:q_editCompilers:setPlainText( hb_memoread( hbide_pathToOSPath( ::oUI:q_editPathEnv:text() + ::pathSep + "hbide.env" ) ) ) } ) + + ::oUI:q_editPathMk2 :setText( ::aINI[ INI_HBIDE, PathMk2 ] ) + ::oUI:q_editPathEnv :setText( ::aINI[ INI_HBIDE, PathEnv ] ) + ::oUI:q_editCompilers:setPlainText( hb_memoread( hbide_pathToOSPath( ::aINI[ INI_HBIDE, PathEnv ] + ::pathSep + "hbide.env" ) ) ) IF empty( ::aPrjProps ) /* @@ -414,16 +546,16 @@ METHOD IdeProjManager:fetchProperties() ::oUI:q_editPrjLoctn:setText( hbide_pathNormalized( cPrjLoc, .F. ) ) ELSE - ::oUI:q_editPrjTitle:setText( ::oProject:applyMeta( ::oProject:title ) ) - ::oUI:q_editPrjLoctn:setText( ::oProject:applyMeta( ::oProject:location ) ) + ::oUI:q_editPrjTitle :setText( ::oProject:applyMeta( ::oProject:title ) ) + ::oUI:q_editPrjLoctn :setText( ::oProject:applyMeta( ::oProject:location ) ) ::oUI:q_editWrkFolder:setText( ::oProject:applyMeta( ::oProject:wrkDirectory ) ) - ::oUI:q_editDstFolder:setText( ::oProject:applyMeta( ::oProject:destination ) ) - ::oUI:q_editOutName:setText( ::oProject:outputName ) + ::oUI:q_editDstFolder:setText( ::oProject:applyMeta( ::oProject:destination ) ) + ::oUI:q_editBackup :setText( ::oProject:applyMeta( ::oProject:backup ) ) + ::oUI:q_editOutName :setText( ::oProject:outputName ) - ::oUI:q_editFlags:setPlainText( hbide_arrayToMemo( ::aPrjProps[ PRJ_PRP_FLAGS , 1 ] ) ) - ::oUI:q_editSources:setPlainText( hbide_arrayToMemo( ::aPrjProps[ PRJ_PRP_SOURCES , 1 ] ) ) - ::oUI:q_editMetaData:setPlainText( hbide_arrayToMemo( ::aPrjProps[ PRJ_PRP_METADATA, 1 ] ) ) - ::oUI:q_editCompilers:setPlainText( memoread( hb_dirBase() + "hbide.env" ) ) + ::oUI:q_editFlags :setPlainText( hbide_arrayToMemo( ::aPrjProps[ PRJ_PRP_FLAGS , 1 ] ) ) + ::oUI:q_editSources :setPlainText( hbide_arrayToMemo( ::aPrjProps[ PRJ_PRP_SOURCES , 1 ] ) ) + ::oUI:q_editMetaData :setPlainText( hbide_arrayToMemo( ::aPrjProps[ PRJ_PRP_METADATA, 1 ] ) ) #if 0 ::oUI:q_editLaunchParams:setText() @@ -453,6 +585,169 @@ METHOD IdeProjManager:fetchProperties() /*----------------------------------------------------------------------*/ +METHOD IdeProjManager:save( lCanClose ) + LOCAL a_, lOk, cPath, txt_ + + * Validate certain parameters before continuing ... (vailtom) + + /* Title cannot be the output name, but reverse is possible + -------------------------------------------------------- + We must also consider that user may be building the project in parts + OR may be basic definition must be in place + */ + IF Empty( ::oUI:q_editPrjTitle:text() ) + ::oUI:q_editPrjTitle:setText( ::oUI:q_editOutName:text() ) + ENDIF + + IF Empty( ::oUI:q_editOutName:text() ) + MsgBox( 'Invalid Output FileName' ) + ::oUI:q_editOutName:setFocus() + RETURN .F. + ENDIF + + /* This must be valid, we cannot skip */ + IF !hbide_isValidPath( ::oProject:expandMeta( ::oUI:q_editPrjLoctn:text() ), 'Project Location' ) + ::oUI:q_editPrjLoctn:setFocus() + RETURN .F. + ENDIF + + /* This we can skip now: later at project building we can check: TO:RECONSIDER */ + IF !empty( cPath := ::oUI:q_editWrkFolder:text() ) + IF !hbide_isValidPath( ::oProject:expandMeta( cPath ), 'Working Folder' ) + // ::oUI:q_editWrkFolder:setText( ::oUI:q_editPrjLoctn:text() ) + RETURN .F. + ENDIF + ENDIF + + /* This we can skip now: later at project building we can check: TO:RECONSIDER */ + IF !empty( cPath := ::oUI:q_editDstFolder:text() ) + IF !hbide_isValidPath( ::oProject:expandMeta( cPath ), 'Destination Folder' ) + // ::oUI:q_editDstFolder:setText( ::oUI:q_editPrjLoctn:text() ) + RETURN .F. + ENDIF + ENDIF + + txt_:= {} + // + aadd( txt_, "[ PROPERTIES ]" ) + aadd( txt_, "Type = " + { "Executable", "Lib", "Dll" }[ ::oUI:q_comboPrjType:currentIndex()+1 ] ) + aadd( txt_, "Title = " + ::oUI:q_editPrjTitle :text() ) + aadd( txt_, "Location = " + ::oUI:q_editPrjLoctn :text() ) + aadd( txt_, "WorkingFolder = " + ::oUI:q_editWrkFolder :text() ) + aadd( txt_, "DestinationFolder = " + ::oUI:q_editDstFolder :text() ) + aadd( txt_, "Output = " + ::oUI:q_editOutName :text() ) + aadd( txt_, "LaunchParams = " + ::oUI:q_editLaunchParams:text() ) + aadd( txt_, "LaunchProgram = " + ::oUI:q_editLaunchExe :text() ) + aadd( txt_, "BackupFolder = " + ::oUI:q_editBackup :text() ) + aadd( txt_, " " ) + // + aadd( txt_, "[ FLAGS ]" ) + a_:= hbide_memoToArray( ::oUI:q_editFlags:toPlainText() ) ; aeval( a_, {|e| aadd( txt_, e ) } ) ; aadd( txt_, " " ) + aadd( txt_, "[ SOURCES ]" ) + a_:= hbide_memoToArray( ::oUI:q_editSources:toPlainText() ) ; aeval( a_, {|e| aadd( txt_, e ) } ) ; aadd( txt_, " " ) + aadd( txt_, "[ METADATA ]" ) + a_:= hbide_memoToArray( ::oUI:q_editMetaData:toPlainText() ); aeval( a_, {|e| aadd( txt_, e ) } ) ; aadd( txt_, " " ) + + #if 0 + /* Setup Meta Keys */ + a4_1 := hbide_setupMetaKeys( a_ ) + + ::cSaveTo := hbide_parseWithMetaData( ::oUI:q_editPrjLoctn:text(), a4_1 ) + ; + ::pathSep + ; + hbide_parseWithMetaData( ::oUI:q_editOutName:text(), a4_1 ) + ; + ".hbi" + ::cSaveTo := hbide_pathToOSPath( ::cSaveTo ) + #endif + + ::cSaveTo := ::oProject:expandMeta( ::oUI:q_editPrjLoctn:text() ) + ; + ::pathSep + ; + ::oProject:expandMeta( ::oUI:q_editOutName:text() ) + ; + ".hbi" + ::cSaveTo := hbide_pathToOSPath( ::cSaveTo ) + + IF ( lOk := hbide_createTarget( ::cSaveTo, txt_ ) ) +* MsgBox( 'The project file is saved successfully: ' + ::cSaveTo, 'Saving project ...' ) + ELSE + MsgBox( 'Error saving project file: ' + ::cSaveTo, 'Error saving project ...' ) + ENDIF + + IF lCanClose .AND. lOk + ::oUI:oWidget:close() + ENDIF + + RETURN lOk + +/*----------------------------------------------------------------------*/ + +METHOD IdeProjManager:saveEnvironments() + LOCAL cText + + ::oProject:cPathMk2 := ::oUI:q_editPathMk2:text() + ::oProject:cPathEnv := ::oUI:q_editPathEnv:text() + + ::oIde:aINI[ INI_HBIDE, PathMk2 ] := ::oProject:cPathMk2 + ::oIde:aINI[ INI_HBIDE, PathEnv ] := ::oProject:cPathEnv + // + ::oIde:cWrkPathMk2 := ::oProject:cPathMk2 + ::oIde:cWrkPathEnv := ::oProject:cPathEnv + + IF !empty( cText := ::oUI:q_editCompilers:toPlainText() ) + hb_MemoWrit( hbide_pathFile( ::oProject:cPathEnv, "hbide.env" ), cText ) + ENDIF + + RETURN Self + +/*----------------------------------------------------------------------*/ + +METHOD IdeProjManager:updateHbp( iIndex ) + LOCAL a_, a4_1, txt_, s + LOCAL cExt + + IF iIndex != 3 + RETURN nil + ENDIF + + a_:= hb_atokens( strtran( ::oUI:q_editMetaData:toPlainText(), chr( 13 ) ), _EOL ) + a4_1 := hbide_setupMetaKeys( a_ ) + + txt_:= {} + /* This block will be absent when submitting to hbmk engine */ + aadd( txt_, "# " + hbide_parseWithMetaData( ::oUI:q_editWrkFolder:text(), a4_1 ) + ::pathSep + ; + hbide_parseWithMetaData( ::oUI:q_editOutName:text(), a4_1 ) + ".hbp" ) + aadd( txt_, " " ) + + /* Flags */ + a_:= hb_atokens( ::oUI:q_editFlags:toPlainText(), _EOL ) + FOR EACH s IN a_ + s := alltrim( s ) + IF !( "#" == left( s,1 ) ) .and. !empty( s ) + s := hbide_parseWithMetaData( s, a4_1 ) + aadd( txt_, s ) + ENDIF + NEXT + aadd( txt_, " " ) + + /* Sources */ + a_:= hb_atokens( ::oUI:q_editSources:toPlainText(), _EOL ) + FOR EACH s IN a_ + s := alltrim( s ) + IF !( "#" == left( s,1 ) ) .and. !empty( s ) + s := hbide_parseWithMetaData( s, a4_1 ) + hb_FNameSplit( s, , , @cExt ) + IF lower( cExt ) $ ".c,.cpp,.prg,.rc,.res" + aadd( txt_, s ) + ENDIF + ENDIF + NEXT + aadd( txt_, " " ) + + /* Final assault */ + ::oUI:q_editHbp:setPlainText( hbide_arrayToMemo( txt_ ) ) + + RETURN txt_ + +/*----------------------------------------------------------------------*/ + METHOD IdeProjManager:sortSources( cMode ) LOCAL a_, cTyp, s, d_, n LOCAL aSrc := { ".ch", ".prg", ".c", ".cpp", ".h", ".obj", ".o", ".lib", ".a", ".rc", ".res" } @@ -531,149 +826,6 @@ METHOD IdeProjManager:updateMetaData() /*----------------------------------------------------------------------*/ -METHOD IdeProjManager:save( lCanClose ) - LOCAL a_, lOk, cPath, txt_ - - * Validate certain parameters before continuing ... (vailtom) - - /* Title cannot be the output name, but reverse is possible - -------------------------------------------------------- - We must also consider that user may be building the project in parts - OR may be basic definition must be in place - */ - IF Empty( ::oUI:q_editPrjTitle:text() ) - ::oUI:q_editPrjTitle:setText( ::oUI:q_editOutName:text() ) - ENDIF - - IF Empty( ::oUI:q_editOutName:text() ) - MsgBox( 'Invalid Output FileName' ) - ::oUI:q_editOutName:setFocus() - RETURN .F. - ENDIF - - /* This must be valid, we cannot skip */ - IF !hbide_isValidPath( ::oProject:expandMeta( ::oUI:q_editPrjLoctn:text() ), 'Project Location' ) - ::oUI:q_editPrjLoctn:setFocus() - RETURN .F. - ENDIF - - /* This we can skip now: later at project building we can check: TO:RECONSIDER */ - IF !empty( cPath := ::oUI:q_editWrkFolder:text() ) - IF !hbide_isValidPath( ::oProject:expandMeta( cPath ), 'Working Folder' ) - // ::oUI:q_editWrkFolder:setText( ::oUI:q_editPrjLoctn:text() ) - RETURN .F. - ENDIF - ENDIF - - /* This we can skip now: later at project building we can check: TO:RECONSIDER */ - IF !empty( cPath := ::oUI:q_editDstFolder:text() ) - IF !hbide_isValidPath( ::oProject:expandMeta( cPath ), 'Destination Folder' ) - // ::oUI:q_editDstFolder:setText( ::oUI:q_editPrjLoctn:text() ) - RETURN .F. - ENDIF - ENDIF - - txt_:= {} - // - aadd( txt_, "[ PROPERTIES ]" ) - aadd( txt_, "Type = " + { "Executable", "Lib", "Dll" }[ ::oUI:q_comboPrjType:currentIndex()+1 ] ) - aadd( txt_, "Title = " + ::oUI:q_editPrjTitle:text() ) - aadd( txt_, "Location = " + ::oUI:q_editPrjLoctn:text() ) - aadd( txt_, "WorkingFolder = " + ::oUI:q_editWrkFolder:text() ) - aadd( txt_, "DestinationFolder = " + ::oUI:q_editDstFolder:text() ) - aadd( txt_, "Output = " + ::oUI:q_editOutName:text() ) - aadd( txt_, "LaunchParams = " + ::oUI:q_editLaunchParams:text() ) - aadd( txt_, "LaunchProgram = " + ::oUI:q_editLaunchExe:text() ) - aadd( txt_, " " ) - // - aadd( txt_, "[ FLAGS ]" ) - a_:= hbide_memoToArray( ::oUI:q_editFlags:toPlainText() ) ; aeval( a_, {|e| aadd( txt_, e ) } ) ; aadd( txt_, " " ) - aadd( txt_, "[ SOURCES ]" ) - a_:= hbide_memoToArray( ::oUI:q_editSources:toPlainText() ) ; aeval( a_, {|e| aadd( txt_, e ) } ) ; aadd( txt_, " " ) - aadd( txt_, "[ METADATA ]" ) - a_:= hbide_memoToArray( ::oUI:q_editMetaData:toPlainText() ); aeval( a_, {|e| aadd( txt_, e ) } ) ; aadd( txt_, " " ) - - #if 0 - /* Setup Meta Keys */ - a4_1 := hbide_setupMetaKeys( a_ ) - - ::cSaveTo := hbide_parseWithMetaData( ::oUI:q_editPrjLoctn:text(), a4_1 ) + ; - ::pathSep + ; - hbide_parseWithMetaData( ::oUI:q_editOutName:text(), a4_1 ) + ; - ".hbi" - ::cSaveTo := hbide_pathToOSPath( ::cSaveTo ) - #endif - - ::cSaveTo := ::oProject:expandMeta( ::oUI:q_editPrjLoctn:text() ) + ; - ::pathSep + ; - ::oProject:expandMeta( ::oUI:q_editOutName:text() ) + ; - ".hbi" - ::cSaveTo := hbide_pathToOSPath( ::cSaveTo ) - - IF ( lOk := hbide_createTarget( ::cSaveTo, txt_ ) ) - *MsgBox( 'The project file was saved successfully: ' + ::cSaveTo, 'Saving project ...' ) - hb_MemoWrit( hb_dirBase() + "hbide.env", ::oUI:q_editCompilers:toPlainText() ) - ELSE - MsgBox( 'Error saving project file: ' + ::cSaveTo, 'Error saving project ...' ) - ENDIF - - IF lCanClose .AND. lOk - ::oUI:oWidget:close() - ENDIF - - RETURN lOk - -/*----------------------------------------------------------------------*/ - -METHOD IdeProjManager:updateHbp( iIndex ) - LOCAL a_, a4_1, txt_, s - LOCAL cExt - - IF iIndex != 3 - RETURN nil - ENDIF - - a_:= hb_atokens( strtran( ::oUI:q_editMetaData:toPlainText(), chr( 13 ) ), _EOL ) - a4_1 := hbide_setupMetaKeys( a_ ) - - txt_:= {} - /* This block will be absent when submitting to hbmk engine */ - aadd( txt_, "# " + hbide_parseWithMetaData( ::oUI:q_editWrkFolder:text(), a4_1 ) + ::pathSep + ; - hbide_parseWithMetaData( ::oUI:q_editOutName:text(), a4_1 ) + ".hbp" ) - aadd( txt_, " " ) - - /* Flags */ - a_:= hb_atokens( ::oUI:q_editFlags:toPlainText(), _EOL ) - FOR EACH s IN a_ - s := alltrim( s ) - IF !( "#" == left( s,1 ) ) .and. !empty( s ) - s := hbide_parseWithMetaData( s, a4_1 ) - aadd( txt_, s ) - ENDIF - NEXT - aadd( txt_, " " ) - - /* Sources */ - a_:= hb_atokens( ::oUI:q_editSources:toPlainText(), _EOL ) - FOR EACH s IN a_ - s := alltrim( s ) - IF !( "#" == left( s,1 ) ) .and. !empty( s ) - s := hbide_parseWithMetaData( s, a4_1 ) - hb_FNameSplit( s, , , @cExt ) - IF lower( cExt ) $ ".c,.cpp,.prg,.rc,.res" - aadd( txt_, s ) - ENDIF - ENDIF - NEXT - aadd( txt_, " " ) - - /* Final assault */ - ::oUI:q_editHbp:setPlainText( hbide_arrayToMemo( txt_ ) ) - - RETURN txt_ - -/*----------------------------------------------------------------------*/ - METHOD IdeProjManager:addSources() LOCAL aFiles, a_, b_, a4_1, s @@ -827,7 +979,7 @@ METHOD IdeProjManager:getProjectByFile( cProjectFile ) aProj := ::aProjects[ n ] ENDIF - RETURN IdeProject():new( aProj ) + RETURN IdeProject():new( ::oIde, aProj ) /*----------------------------------------------------------------------*/ @@ -838,7 +990,7 @@ METHOD IdeProjManager:getProjectByTitle( cProjectTitle ) aProj := ::aProjects[ n, 3 ] ENDIF - RETURN IdeProject():new( aProj ) + RETURN IdeProject():new( ::oIde, aProj ) /*----------------------------------------------------------------------*/ @@ -912,8 +1064,9 @@ METHOD IdeProjManager:promptForPath( cObjPathName, cTitle, cObjFileName, cObjPat /*----------------------------------------------------------------------*/ METHOD IdeProjManager:buildProject( cProject, lLaunch, lRebuild, lPPO, lViaQt ) - LOCAL cOutput, cErrors, cHbpPath, qStringList, oEdit, cHbpFN, cTmp, nResult, cTargetFN - LOCAL aHbp := {} + LOCAL cHbpPath, oEdit, cHbpFN, cTmp, cTargetFN, cExeHbMk2, aHbp, cCmd + + aHbp := {} DEFAULT lLaunch TO .F. DEFAULT lRebuild TO .F. @@ -970,15 +1123,16 @@ METHOD IdeProjManager:buildProject( cProject, lLaunch, lRebuild, lPPO, lViaQt ) aadd( aHbp, "-o" + cTargetFN ) aadd( aHbp, "-workdir=" + ::oProject:wrkDirectory + "/${hb_plat}/${hb_comp}" ) ENDIF - aadd( aHbp, "-q" ) - aadd( aHbp, "-trace" ) - aadd( aHbp, "-info" ) + aadd( aHbp, "-q" ) + aadd( aHbp, "-trace" ) + aadd( aHbp, "-info" ) IF lRebuild - aadd( aHbp, "-rebuild" ) + aadd( aHbp, "-rebuild" ) ENDIF aadd( aHbp, " " ) IF !( ::lPPO ) + /* Add all sources to .hbp */ aadd( aHbp, "# Source Files" ) aadd( aHbp, " " ) aeval( hbide_filesToSources( ::oProject:sources ), {|e| aadd( aHbp, e ) } ) @@ -991,7 +1145,7 @@ METHOD IdeProjManager:buildProject( cProject, lLaunch, lRebuild, lPPO, lViaQt ) aadd( aHbp, "-p" ) aadd( aHbp, " " ) aadd( aHbp, "# Source File - PPO" ) - aadd( aHbp, " " ) + aadd( aHbp, " " ) // TODO: We have to test if the current file is part of a project, and we // pull your settings, even though this is not the active project - vailtom @@ -1018,8 +1172,6 @@ METHOD IdeProjManager:buildProject( cProject, lLaunch, lRebuild, lPPO, lViaQt ) ::oOutputResult:oWidget:append( 'Error saving: ' + cHbpPath ) ELSE - ::nStarted := seconds() - cTmp := hbide_outputLine() + CRLF + ; "Project [ " + cProject + " ] " + ; "Launch [ " + iif( lLaunch , 'Yes', 'No' ) + " ] " + ; @@ -1028,140 +1180,72 @@ METHOD IdeProjManager:buildProject( cProject, lLaunch, lRebuild, lPPO, lViaQt ) hbide_outputLine() + CRLF ::oOutputResult:oWidget:append( cTmp ) - IF lViaQt - ::buildProcess() + ::oIde:oEV := IdeEnvironments():new():create( ::oIde, hbide_pathFile( ::aINI[ INI_HBIDE, PathEnv ], "hbide.env" ) ) + ::cBatch := ::oEV:prepareBatch( ::cWrkEnvironment ) + #if 0 /* This does not works - reason being it picks up hbmk2 from fixed location */ + cExeHbMk2 := hbide_pathFile( ::oProject:cPathMk2, "hbmk2" ) + #else /* This works properly */ + cExeHbMk2 := "hbmk2" /* Needs that path is already set before calling hbmk2 */ + #endif - #if 0 /* Mechanism to supply environment variables to called process */ - /* I do not know nixes but assume that Qt must be issueing proper */ - /* shell command for the target OS to set them. */ - /* If I am not wrong, HBMK2 can have these variables alread set */ - /* and hence developer can choose any compiler of his choice. */ - /* */ - /* Actually, this was the intension in hbIDE.env I commited in IDE root */ - qStringList := QStringList():new() - qStringList:append( "HB_WITH_QT=c:\qt\4.5.3\lib" ) - ::qProcess:setEnvironment( qStringList ) + ::oProcess := HbpProcess():new() + // + ::oProcess:output := {|cOut, mp2, oHbp| ::showOutput( cOut,mp2,oHbp ) } + ::oProcess:finished := {|nEC , nES, oHbp| ::finished( nEC ,nES,oHbp ) } + ::oProcess:workingPath := ::oProject:wrkDirectory - qStringList := QStringList():new() - qStringList:append( [/c c:\batches\SetMinGW-harbour-E.bat && hbMK2.exe ] + cHbpPath ) - ::qProcess:start( "cmd.exe", qStringList ) - #else - - qStringList := QStringList():new() - IF ::lPPO - qStringList:append( "-hbraw" ) + #if 1 + cCmd := "cmd.exe" + IF empty( ::cBatch ) + ::oProcess:addArg( "/c " + cExeHbMk2 + " " + cHbpPath + iif( ::lPPO, " -hbraw", "" ) ) + ELSE + ::oProcess:addArg( "/c " + ::cBatch + " && " + cExeHbMk2 + " " + cHbpPath + iif( ::lPPO, " -hbraw", "" ) ) ENDIF - qStringList:append( cHbpPath ) - // - ::qProcess:setWorkingDirectory( ::oProject:wrkDirectory ) - // - ::qProcess:start( ::oProject:hbmk2dir + "hbmk2", qStringList ) - #endif - ELSE - cOutput := "" ; cErrors := "" - nResult := hb_processRun( ::oProject:hbmk2dir + "hbmk2 " + iif( ::lPPO, "-hbraw ", "" ) + cHbpPath, , @cOutput, @cErrors ) - - cTmp := cOutput + CRLF - cTmp += IIF( empty( cErrors ), "", cErrors ) + CRLF - cTmp += hbide_outputLine() + CRLF - cTmp += "Exit Code [ " + hb_ntos( nResult ) + " ] " + ; - "Finished at [ " + time() + " ] " + ; - "Done in [ " + hb_ntos( seconds() - ::nStarted ) + " Secs ]" + CRLF - cTmp += hbide_outputLine() + CRLF - - hbide_convertBuildStatusMsgToHtml( cTmp, ::oOutputResult:oWidget ) - - IF ( nResult == 0 ) .AND. ( lLaunch ) - ::LaunchProject( cProject ) - ENDIF - - IF ::lPPO .AND. hb_FileExists( ::cPPO ) - ::editSource( ::cPPO ) - ENDIF - ENDIF + #else + cCmd := "cmd.exe /c " + ::cBatch + " && " + cExeHbMk2 + " " + cHbpPath + iif( ::lPPO, " -hbraw", "" ) + #endif + ::oProcess:start( cCmd ) ENDIF RETURN Self /*----------------------------------------------------------------------*/ -METHOD IdeProjManager:buildProcess() +METHOD IdeProjManager:showOutput( cOutput, mp2, oProcess ) - ::qProcess := QProcess():new() - ::qProcess:setReadChannel( 1 ) + hbide_justACall( mp2, oProcess ) - Qt_Slots_Connect( ::pSlots, ::qProcess, "readyRead()" , {|o,i| ::readProcessInfo( CHN_REA, i, o ) } ) - Qt_Slots_Connect( ::pSlots, ::qProcess, "readChannelFinished()" , {|o,i| ::readProcessInfo( CHN_RCF, i, o ) } ) - Qt_Slots_Connect( ::pSlots, ::qProcess, "aboutToClose()" , {|o,i| ::readProcessInfo( CHN_CLO, i, o ) } ) - Qt_Slots_Connect( ::pSlots, ::qProcess, "bytesWritten(int)" , {|o,i| ::readProcessInfo( CHN_BYT, i, o ) } ) - Qt_Slots_Connect( ::pSlots, ::qProcess, "stateChanged(int)" , {|o,i| ::readProcessInfo( CHN_STT, i, o ) } ) - Qt_Slots_Connect( ::pSlots, ::qProcess, "error(int)" , {|o,i| ::readProcessInfo( CHN_ERE, i, o ) } ) - Qt_Slots_Connect( ::pSlots, ::qProcess, "started()" , {|o,i| ::readProcessInfo( CHN_BGN, o, i ) } ) - Qt_Slots_Connect( ::pSlots, ::qProcess, "readyReadStandardOutput()", {|o,i| ::readProcessInfo( CHN_OUT, i, o ) } ) - Qt_Slots_Connect( ::pSlots, ::qProcess, "readyReadStandardError()" , {|o,i| ::readProcessInfo( CHN_ERR, i, o ) } ) - Qt_Slots_Connect( ::pSlots, ::qProcess, "finished(int,int)" , {|o,i,ii| ::readProcessInfo( CHN_FIN, i, ii, o ) } ) + hbide_convertBuildStatusMsgToHtml( cOutput, ::oOutputResult:oWidget ) RETURN Self /*----------------------------------------------------------------------*/ -METHOD IdeProjManager:readProcessInfo( nMode, i, ii ) - LOCAL cLine, cTmp, nSize +METHOD IdeProjManager:finished( nExitCode, nExitStatus, oProcess ) + LOCAL cTmp - nSize := 16384 + hbide_justACall( oProcess ) - DO CASE - CASE nMode == CHN_REA // ReadReady() + cTmp := hbide_outputLine() + CRLF + cTmp += "Exit Code [ " + hb_ntos( nExitCode ) + " ] Exit Status [ " + hb_ntos( nExitStatus ) + " ] " +; + "Finished at [ " + time() + " ] Done in [ " + hb_ntos( seconds() - oProcess:started ) +" Secs ]" + CRLF + cTmp += hbide_outputLine() + CRLF - CASE nMode == CHN_OUT - ::qProcess:setReadChannel( 0 ) - cLine := space( nSize ) - ::qProcess:read( @cLine, nSize ) - IF !empty( cLine ) - hbide_convertBuildStatusMsgToHtml( trim( cLine ), ::oOutputResult:oWidget ) - ENDIF + ::oOutputResult:oWidget:append( cTmp ) - CASE nMode == CHN_ERR - ::qProcess:setReadChannel( 1 ) - cLine := space( nSize ) - ::qProcess:read( @cLine, nSize ) - IF !empty( cLine ) - hbide_convertBuildStatusMsgToHtml( trim( cLine ), ::oOutputResult:oWidget ) - ENDIF + ferase( ::cBatch ) - CASE nMode == CHN_FIN - cTmp := hbide_outputLine() + CRLF - cTmp += "Exit Code [ " + hb_ntos( i ) + " ] Exit Status [ " + hb_ntos( ii ) + " ] " +; - "Finished at [ " + time() + " ] Done in [ " + hb_ntos( seconds() - ::nStarted ) +" Secs ]" + CRLF - cTmp += hbide_outputLine() + CRLF - - ::oOutputResult:oWidget:append( cTmp ) - - Qt_Slots_disConnect( ::pSlots, ::qProcess, "readyRead()" ) - Qt_Slots_disConnect( ::pSlots, ::qProcess, "readChannelFinished()" ) - Qt_Slots_disConnect( ::pSlots, ::qProcess, "aboutToClose()" ) - Qt_Slots_disConnect( ::pSlots, ::qProcess, "bytesWritten(int)" ) - Qt_Slots_disConnect( ::pSlots, ::qProcess, "stateChanged(int)" ) - Qt_Slots_disConnect( ::pSlots, ::qProcess, "error(int)" ) - Qt_Slots_disConnect( ::pSlots, ::qProcess, "started()" ) - Qt_Slots_disConnect( ::pSlots, ::qProcess, "readyReadStandardOutput()" ) - Qt_Slots_disConnect( ::pSlots, ::qProcess, "readyReadStandardError()" ) - Qt_Slots_disConnect( ::pSlots, ::qProcess, "finished(int,int)" ) - - ::qProcess:kill() - ::qProcess:pPtr := 0 - ::qProcess := NIL - - IF ::lLaunch + IF ::lLaunch + IF nExitCode == 0 ::launchProject( ::cProjectInProcess ) ENDIF - IF ::lPPO .AND. hb_FileExists( ::cPPO ) - ::editSource( ::cPPO ) - ENDIF - ENDCASE + ENDIF + IF ::lPPO .AND. hb_FileExists( ::cPPO ) + ::editSource( ::cPPO ) + ENDIF - RETURN nil + RETURN Self /*----------------------------------------------------------------------*/ /* @@ -1193,19 +1277,43 @@ METHOD IdeProjManager:launchProject( cProject ) cTmp := "Launch application error: file not found " + cTargetFN + "!" ELSEIF oProject:type == "Executable" - cTmp := "Launch application " + cTargetFN + "... " - qProcess := QProcess():new() + // + //qProcess:setWorkingDirectory( hbide_pathToOSPath( oProject:wrkDirectory ) ) - qProcess:setWorkingDirectory( hbide_pathToOSPath( oProject:wrkDirectory ) ) -hbide_dbg( oProject:wrkDirectory, qProcess:workingDirectory() ) - qProcess:startDetached_2( cTargetFN ) - //qProcess:waitForStarted() - qProcess:pPtr := 0 - qProcess := NIL + #if 1 + cTmp := "Launching application with environment [ " + cTargetFN + " ]" + + #if 0 + qStrList := QStringList():new() + ::cBatch := ::oEV:prepareBatch( ::cWrkEnvironment ) /* at this point we only know default environment */ + IF empty( ::cBatch ) + qStrList:append( "/c " + cTargetFN ) + ELSE + qStrList:append( "/c " + ::cBatch + " && " + cTargetFN ) + ENDIF + qProcess:startDetached_1( "cmd.exe", qStrList ) + #endif + + qProcess:startDetached_2( cTargetFN ) + qProcess:waitForStarted() + qProcess:pPtr := 0 + qProcess := NIL + + //qProcess:start( "cmd.exe", qStrList ) + + #else + cTmp := "Launching application [ " + cTargetFN + " ]" + + qProcess:startDetached_2( cTargetFN ) + qProcess:waitForStarted() + qProcess:pPtr := 0 + qProcess := NIL + + #endif ELSE - cTmp := "Launch application " + cTargetFN + "... (not applicable)" + cTmp := "Launching application [ " + cTargetFN + " ] ( not applicable )." ENDIF diff --git a/harbour/contrib/hbide/idesaveload.prg b/harbour/contrib/hbide/idesaveload.prg index dfbcca85ab..cb2dd8ceda 100644 --- a/harbour/contrib/hbide/idesaveload.prg +++ b/harbour/contrib/hbide/idesaveload.prg @@ -91,6 +91,9 @@ FUNCTION hbide_saveINI( oIde ) aadd( txt_, "ThemesDialogGeometry = " + oIde:aIni[ INI_HBIDE, ThemesDialogGeometry ] ) aadd( txt_, "CurrentTheme = " + oIde:cWrkTheme ) aadd( txt_, "CurrentCodec = " + oIde:cWrkCodec ) + aadd( txt_, "PathMk2 = " + oIde:aIni[ INI_HBIDE, PathMk2 ] ) + aadd( txt_, "PathEnv = " + oIde:aIni[ INI_HBIDE, PathEnv ] ) + aadd( txt_, "CurrentEnvironment = " + oIde:cWrkEnvironment ) aadd( txt_, " " ) aadd( txt_, "[PROJECTS]" ) @@ -161,8 +164,9 @@ FUNCTION hbide_loadINI( oIde, cHbideIni ) LOCAL aIdeEle := { "mainwindowgeometry" , "projecttreevisible" , "projecttreegeometry", ; "functionlistvisible", "functionlistgeometry", "recenttabindex" , ; "currentproject" , "gotodialoggeometry" , "propsdialoggeometry", ; - "finddialoggeometry" , "themesdialoggeometry", "currenttheme", ; - "currentcodec" } + "finddialoggeometry" , "themesdialoggeometry", "currenttheme" , ; + "currentcodec" , "pathmk2" , "pathenv" , ; + "currentenvironment" } /* Initiate the place holders */ oIde:aIni := Array( INI_SECTIONS_COUNT ) diff --git a/harbour/contrib/hbide/projects/hbide.hbi b/harbour/contrib/hbide/projects/hbide.hbi index fca67fe086..2e3fdf81ca 100644 --- a/harbour/contrib/hbide/projects/hbide.hbi +++ b/harbour/contrib/hbide/projects/hbide.hbi @@ -7,6 +7,7 @@ DestinationFolder = projects Output = hbide LaunchParams = LaunchProgram = +BackupFolder = [ FLAGS ] ../../hbxbp/hbxbp.hbc diff --git a/harbour/contrib/hbide/resources/hbide.env b/harbour/contrib/hbide/resources/hbide.env new file mode 100644 index 0000000000..ee199b882b --- /dev/null +++ b/harbour/contrib/hbide/resources/hbide.env @@ -0,0 +1,55 @@ + [ COMMON ] +PLATFORM = win +COMPILER = bcc +SHELL = cmd.exe +EXT = bat + + [ BCC55 5.5.1 Command Line Tools ] +{hb_comp} bcc +{shell} cmd.exe +{ext} bat +{content} set HB_COMPILER=bcc +{content} set PATH=c:\harbour;c:\harbour\bcc\bin;C:\harbour\harbour\bcc\bin; + + [ MINGW 4.4.2 Windows ] +{hb_plat} win +{hb_comp} mingw +{content} set PATH=c:\mingw\bin;c:\qt\2009.03\qt\bin; +{content} set PATH=c:\harbour;c:\harbour\harbour\mingw\bin;%path% +{content} set HB_WITH_QT=c:\qt\2009.03\qt + + [ MSVC 8.0 ] +{hb_comp} msvc +{shell} cmd.exe +{ext} bat +{content} call "%ProgramFiles%\Microsoft Visual Studio 9.0\VC\vcvarsall.bat" x86 +{content} set PATH=c:\harbour;%ProgramFiles%\Microsoft Visual Studio 9.0\VC\bin;%path% +{content} set PATH=c:\harbour;;C:\harbour\harbour\msvc\bin;%path% +{content} set HB_COMPILER=msvc +{content} set HB_WITH_QT=c:\qt\2009.03\qt + + [ Pelles C ] +{hb_comp} pocc +{shell} cmd.exe +{ext} bat +{content} set PATH=c:\harbour\pellesc\bin; +{content} set INCLUDE=c:\harbour\pellesc\include;c:\harbour\pellesc\include\win;%INCLUDE% +{content} set LIB=c:\harbour\pellesc\lib;c:\harbour\pellesc\lib\win;%LIB% +{content} set PATH=c:\harbour;c:\harbour\harbour\pellesc\bin;%path% + + [ Watcom ] +{hb_comp} owatcom +{content} set PATH=C:\WATCOM\BINNT; +{content} set PATH=C:\WATCOM\BINW;%PATH% +{content} set INCLUDE=C:\WATCOM\H;%INCLUDE% +{content} set INCLUDE=C:\WATCOM\H\NT;%INCLUDE% +{content} set WATCOM=C:\WATCOM +{content} set EDPATH=C:\WATCOM\EDDAT +{content} set PATH=c:\harbour;c:\harbour\harbour\watcom\bin;%PATH% + + [ MINGW 4.0.0 Linux - A Skeleton ] +{hb_comp} mingw +{shell}.sh +{content} shell command 1 +{content} shell command 2 + diff --git a/harbour/contrib/hbide/resources/projectproperties.ui b/harbour/contrib/hbide/resources/projectproperties.ui index dd58065a6e..487b9279fc 100644 --- a/harbour/contrib/hbide/resources/projectproperties.ui +++ b/harbour/contrib/hbide/resources/projectproperties.ui @@ -105,23 +105,7 @@ p, li { white-space: pre-wrap; } - - - - - - - - 21 - 20 - - - - true - - - - + Working Folder: @@ -131,7 +115,7 @@ p, li { white-space: pre-wrap; } - + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> @@ -142,20 +126,7 @@ p, li { white-space: pre-wrap; } - - - - - - - - 21 - 20 - - - - - + Destination Folder: @@ -165,7 +136,7 @@ p, li { white-space: pre-wrap; } - + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> @@ -177,41 +148,7 @@ p, li { white-space: pre-wrap; } - - - - - - - - 21 - 20 - - - - - - - - Output Name: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Output name is used as final name for .hbi .hbp .exe .lib .a and will be added to the paths retrieved via &lt;Project Location&gt;, &lt;Working Folder&gt;, &lt;Destination Folder&gt;, etc. So this is a very important component.</p></body></html> - - - - + Compile/Link Flags: @@ -221,7 +158,7 @@ p, li { white-space: pre-wrap; } - + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> @@ -238,7 +175,7 @@ p, li { white-space: pre-wrap; } - + Launch Parameters: @@ -248,10 +185,10 @@ p, li { white-space: pre-wrap; } - + - + Launch Program: @@ -261,9 +198,71 @@ p, li { white-space: pre-wrap; } - + + + + + Backup Location: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Output name is used as final name for .hbi .hbp .exe .lib .a and will be added to the paths retrieved via &lt;Project Location&gt;, &lt;Working Folder&gt;, &lt;Destination Folder&gt;, etc. So this is a very important component.</p></body></html> + + + + + + + Output Name: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + ... + + + + + + + ... + + + + + + + ... + + + + + + + ... + + + @@ -425,10 +424,10 @@ p, li { white-space: pre-wrap; } - Compilers + Environments - + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> @@ -449,6 +448,88 @@ p, li { white-space: pre-wrap; } + + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + Path to hbMK2.exe + + + + + + + + + + + 0 + 0 + + + + + + + + + + + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + Path to hbIDE.env + + + + + + + + + + + + + + + + + + + The environment definitions will not be saved along the project details. You need to click me in order to save it permanently. + + + ... + + + @@ -493,12 +574,8 @@ p, li { white-space: pre-wrap; } comboPrjType editPrjTitle editPrjLoctn - buttonChoosePrjLoc editWrkFolder - buttonChooseWd editDstFolder - buttonChooseDest - editOutName editFlags editLaunchParams editLaunchExe diff --git a/harbour/contrib/hbxbp/Makefile b/harbour/contrib/hbxbp/Makefile index 27c3059ea1..bb1a9da181 100644 --- a/harbour/contrib/hbxbp/Makefile +++ b/harbour/contrib/hbxbp/Makefile @@ -9,6 +9,7 @@ include $(TOP)$(ROOT)config/global.mk LIBNAME := hbxbp PRG_SOURCES := \ + hbpprocess.prg \ xbp3state.prg \ xbpappevent.prg \ xbpbitmap.prg \ diff --git a/harbour/contrib/hbxbp/hbpprocess.prg b/harbour/contrib/hbxbp/hbpprocess.prg new file mode 100644 index 0000000000..558a7f62dd --- /dev/null +++ b/harbour/contrib/hbxbp/hbpprocess.prg @@ -0,0 +1,298 @@ +/* + * $Id$ + */ + +/* + * Harbour Project source code: + * + * Copyright 2010 Pritpal Bedi + * www - http://www.harbour-project.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/). + * + * As a special exception, the Harbour Project gives permission for + * additional uses of the text contained in its release of Harbour. + * + * The exception is that, if you link the Harbour libraries with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the Harbour library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by the Harbour + * Project under the name Harbour. If you copy code from other + * Harbour Project or Free Software Foundation releases into a copy of + * Harbour, as the General Public License permits, the exception does + * not apply to the code that you add in this way. To avoid misleading + * anyone as to the status of such modified files, you must delete + * this exception notice from them. + * + * If you write modifications of your own for Harbour, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + * + */ +/*----------------------------------------------------------------------*/ +/*----------------------------------------------------------------------*/ +/*----------------------------------------------------------------------*/ +/* + * EkOnkar + * ( The LORD is ONE ) + * + * Xbase++ Compatible Library + * Harbour Extension + * + * Pritpal Bedi + * 24Jan2010 + */ +/*----------------------------------------------------------------------*/ +/*----------------------------------------------------------------------*/ +/*----------------------------------------------------------------------*/ + +#include "hbqt.ch" +#include "common.ch" +#include "hbclass.ch" + +/*----------------------------------------------------------------------*/ + +#define CHN_BGN 1 +#define CHN_OUT 2 +#define CHN_ERR 3 +#define CHN_FIN 4 +#define CHN_STT 5 +#define CHN_ERE 6 +#define CHN_CLO 7 +#define CHN_BYT 8 +#define CHN_RCF 9 +#define CHN_REA 10 + +/*----------------------------------------------------------------------*/ +// +// Class HbpProcess +// +/*----------------------------------------------------------------------*/ + +CLASS HbpProcess + + DATA cShellCmd + DATA lDetatched INIT .f. + + METHOD new( cShellCmd ) + METHOD create( cShellCmd ) + METHOD destroy() VIRTUAL + METHOD addArg( cArg ) + METHOD start( cShellCmd ) + + METHOD finished( bBlock ) SETGET // Slot + METHOD output( bBlock ) SETGET // Slot + METHOD workingPath( cPath ) SETGET // Slot + + ACCESS started INLINE ::nStarted + ACCESS ended INLINE ::nEnded + ACCESS exitCode INLINE ::nExitCode + ACCESS exitStatus INLINE ::nExitStatus + + PROTECTED: + + DATA nStarted INIT 0 + DATA nEnded INIT 0 + DATA nExitCode INIT -1 + DATA nExitStatus INIT -1 + DATA cWrkDirectory INIT "" + DATA qProcess + DATA qStrList + DATA bFinish + DATA bOutput + + METHOD read( nMode, i, ii ) + METHOD outputMe( cLine ) + METHOD finish() + + ACCESS pSlots INLINE hbxbp_getSlotsPtr() + + ENDCLASS + +/*----------------------------------------------------------------------*/ + +METHOD HbpProcess:new( cShellCmd ) + + ::cShellCmd := cShellCmd + + RETURN Self + +/*----------------------------------------------------------------------*/ + +METHOD HbpProcess:create( cShellCmd ) + + DEFAULT cShellCmd TO ::cShellCmd + + ::cShellCmd := cShellCmd + + RETURN Self + +/*----------------------------------------------------------------------*/ + +METHOD HbpProcess:workingPath( cPath ) + + IF !empty( cPath ) + ::cWrkDirectory := cPath + ENDIF + RETURN ::cWrkDirectory + +/*----------------------------------------------------------------------*/ + +METHOD HbpProcess:finished( bBlock ) + + IF hb_isBlock( bBlock ) + ::bFinish := bBlock + ENDIF + + RETURN ::bFinish + +/*----------------------------------------------------------------------*/ + +METHOD HbpProcess:output( bBlock ) + + IF hb_isBlock( bBlock ) + ::bOutput := bBlock + ENDIF + + RETURN ::bFinish + +/*----------------------------------------------------------------------*/ + +METHOD HbpProcess:addArg( cArg ) + + IF empty( ::qStrList ) + ::qStrList := QStringList():new() + ENDIF + ::qStrList:append( cArg ) + + RETURN Self + +/*----------------------------------------------------------------------*/ + +METHOD HbpProcess:start( cShellCmd ) + + DEFAULT cShellCmd TO ::cShellCmd + + ::cShellCmd := cShellCmd + + ::qProcess := QProcess():new() + + ::qProcess:setReadChannel( 1 ) + + #if 0 + Qt_Slots_Connect( ::pSlots, ::qProcess, "readyRead()" , {|o,i| ::read( CHN_REA, i, o ) } ) + Qt_Slots_Connect( ::pSlots, ::qProcess, "readChannelFinished()" , {|o,i| ::read( CHN_RCF, i, o ) } ) + Qt_Slots_Connect( ::pSlots, ::qProcess, "aboutToClose()" , {|o,i| ::read( CHN_CLO, i, o ) } ) + Qt_Slots_Connect( ::pSlots, ::qProcess, "bytesWritten(int)" , {|o,i| ::read( CHN_BYT, i, o ) } ) + Qt_Slots_Connect( ::pSlots, ::qProcess, "stateChanged(int)" , {|o,i| ::read( CHN_STT, i, o ) } ) + Qt_Slots_Connect( ::pSlots, ::qProcess, "error(int)" , {|o,i| ::read( CHN_ERE, i, o ) } ) + Qt_Slots_Connect( ::pSlots, ::qProcess, "started()" , {|o,i| ::read( CHN_BGN, i, o ) } ) + #endif + + Qt_Slots_Connect( ::pSlots, ::qProcess, "readyReadStandardOutput()", {|o,i| ::read( CHN_OUT, i, o ) } ) + Qt_Slots_Connect( ::pSlots, ::qProcess, "readyReadStandardError()" , {|o,i| ::read( CHN_ERR, i, o ) } ) + Qt_Slots_Connect( ::pSlots, ::qProcess, "finished(int,int)" , {|o,i,ii| ::read( CHN_FIN, i, ii, o ) } ) + + IF !empty( ::cWrkDirectory ) + ::qProcess:setWorkingDirectory( ::cWrkDirectory ) + ENDIF + ::nStarted := seconds() + + IF !empty( ::qStrList ) + ::qProcess:start( ::cShellCmd, ::qStrList ) + ELSE + ::qProcess:start_1( ::cShellCmd ) + ENDIF + + RETURN Self + +/*----------------------------------------------------------------------*/ + +METHOD HbpProcess:read( nMode, i, ii ) + LOCAL cLine, nSize + + nSize := 16384 + + DO CASE + CASE nMode == CHN_REA + + CASE nMode == CHN_OUT + ::qProcess:setReadChannel( 0 ) + cLine := space( nSize ) + ::qProcess:read( @cLine, nSize ) + ::outputMe( cLine ) + + CASE nMode == CHN_ERR + ::qProcess:setReadChannel( 1 ) + cLine := space( nSize ) + ::qProcess:read( @cLine, nSize ) + ::outputMe( cLine ) + + CASE nMode == CHN_FIN + ::nExitCode := i + ::nExitStatus := ii + ::nEnded := Seconds() + ::finish() + + ENDCASE + + RETURN nil + +/*----------------------------------------------------------------------*/ + +METHOD HbpProcess:outputMe( cLine ) + + IF hb_isBlock( ::bOutput ) .AND. !empty( cLine ) + eval( ::bOutput, trim( cLine ), NIL, Self ) + ENDIF + + RETURN Self + +/*----------------------------------------------------------------------*/ + +METHOD HbpProcess:finish() + + #if 0 + Qt_Slots_disConnect( ::pSlots, ::qProcess, "readyRead()" ) + Qt_Slots_disConnect( ::pSlots, ::qProcess, "readChannelFinished()" ) + Qt_Slots_disConnect( ::pSlots, ::qProcess, "aboutToClose()" ) + Qt_Slots_disConnect( ::pSlots, ::qProcess, "bytesWritten(int)" ) + Qt_Slots_disConnect( ::pSlots, ::qProcess, "stateChanged(int)" ) + Qt_Slots_disConnect( ::pSlots, ::qProcess, "error(int)" ) + Qt_Slots_disConnect( ::pSlots, ::qProcess, "started()" ) + #endif + Qt_Slots_disConnect( ::pSlots, ::qProcess, "readyReadStandardOutput()" ) + Qt_Slots_disConnect( ::pSlots, ::qProcess, "readyReadStandardError()" ) + Qt_Slots_disConnect( ::pSlots, ::qProcess, "finished(int,int)" ) + + IF hb_isBlock( ::bFinish ) + eval( ::bFinish, ::nExitCode, ::nExitStatus, Self ) + ENDIF + + ::qProcess:kill() + // + ::qProcess:pPtr := 0 + ::qProcess := NIL + + RETURN Self + +/*----------------------------------------------------------------------*/