From 5790842dc4ceae7b1a99b995e52256abd52585b9 Mon Sep 17 00:00:00 2001 From: Pritpal Bedi Date: Wed, 27 Jan 2010 17:09:12 +0000 Subject: [PATCH] 2010-01-27 08:58 UTC-0800 Pritpal Bedi (pritpal@vouchcac.com) * contrib/hbide/hbide.prg * contrib/hbide/idemisc.prg * contrib/hbide/ideprojmanager.prg * contrib/hbide/resources/projectproperties.ui + Implemented loading project from .hbp. Look for the button on top of "Properties" dialog. Please note that .hbp file is loaded with its whole contentents and then is sectionized as per .hbi protocol. So, the disadvantage is you loose the free-format implementation of .hbp. It has to be discovered how can we cover this aspect. Be careful when building the project as existing .hbp will be overwritten if you choose the "Project Location" of the project pointing to same folder where .hbp resides. Other than loosing "-skip" protocol of .hbp, I am sure we are loosing nothing else, please test. + Implemention and options which can be invoked from context menu of project node. --- harbour/ChangeLog | 21 ++ harbour/contrib/hbide/hbide.prg | 220 +++++++-------- harbour/contrib/hbide/idemisc.prg | 256 ++++++++++-------- harbour/contrib/hbide/ideprojmanager.prg | 255 ++++++++++++----- .../hbide/resources/projectproperties.ui | 59 +++- 5 files changed, 505 insertions(+), 306 deletions(-) diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 692cb3c510..ed1dc38cec 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -17,6 +17,27 @@ past entries belonging to author(s): Viktor Szakats. */ +2010-01-27 08:58 UTC-0800 Pritpal Bedi (pritpal@vouchcac.com) + * contrib/hbide/hbide.prg + * contrib/hbide/idemisc.prg + * contrib/hbide/ideprojmanager.prg + * contrib/hbide/resources/projectproperties.ui + + Implemented loading project from .hbp. + Look for the button on top of "Properties" dialog. + Please note that .hbp file is loaded with its whole + contentents and then is sectionized as per .hbi + protocol. So, the disadvantage is you loose the + free-format implementation of .hbp. It has to be + discovered how can we cover this aspect. Be careful + when building the project as existing .hbp will be + overwritten if you choose the "Project Location" + of the project pointing to same folder where .hbp + resides. Other than loosing "-skip" protocol of .hbp, + I am sure we are loosing nothing else, please test. + + + Implemention and options + which can be invoked from context menu of project node. + 2010-01-26 18:21 UTC-0800 Pritpal Bedi (pritpal@vouchcac.com) * contrib/hbide/idemisc.prg * contrib/hbide/ideprojmanager.prg diff --git a/harbour/contrib/hbide/hbide.prg b/harbour/contrib/hbide/hbide.prg index bf6f4e3628..3b01de8eab 100644 --- a/harbour/contrib/hbide/hbide.prg +++ b/harbour/contrib/hbide/hbide.prg @@ -216,7 +216,8 @@ CLASS HbIde METHOD setPosByIni( qWidget, nPart ) METHOD setSizeByIni( qWidget, nPart ) METHOD manageFocusInEditor() - METHOD updateProjectTree( aPrj, lRemove ) + METHOD removeProjectTree( aPrj ) + METHOD updateProjectTree( aPrj ) METHOD manageItemSelected( oXbpTreeItem ) METHOD manageProjectContext( mp1, mp2, oXbpTreeItem ) METHOD updateFuncList() @@ -331,7 +332,9 @@ METHOD HbIde:create( cProjIni ) ::cWrkProject := ::aINI[ INI_HBIDE, CurrentProject ] ::oPM:populate() ::oSM:loadSources() + #if 0 /* Must not be greyed as we have more options there */ ::updateProjectMenu() + #endif ::updateTitleBar() /* Set some last settings */ ::oPM:setCurrentProject( ::cWrkProject, .f. ) @@ -747,142 +750,110 @@ METHOD HbIde:manageFocusInEditor() /*----------------------------------------------------------------------*/ -METHOD HbIde:updateProjectTree( aPrj, lRemove ) - LOCAL cType, oParent, oP, aSrc, j, cProject, nPath - LOCAL aPath, aInUse, cPath, cFile, cExt, oPP, cPathA, nPos +METHOD HbIde:removeProjectTree( aPrj ) + LOCAL oProject, nIndex, oParent, oP, n - DEFAULT lRemove TO .F. - - IF Empty( aPrj ) + oProject := IdeProject():new( Self, aPrj ) + IF empty( oProject:title ) RETURN Self ENDIF - - cProject := aPrj[ PRJ_PRP_PROPERTIES, 2, E_oPrjTtl ] - - IF Empty( cProject ) - RETURN Self + nIndex := aScan( ::aProjData, {|e_| e_[ TRE_TYPE ] == "Project Name" .AND. e_[ TRE_ORIGINAL ] == oProject:title } ) + IF nIndex > 0 + oParent := ::aProjData[ nIndex, TRE_OITEM ] + DO WHILE .t. + n := ascan( ::aProjData, {|e_| e_[ TRE_OPARENT ] == oParent } ) + IF n == 0 + EXIT + ENDIF + oParent:delItem( ::aProjData[ n, TRE_OITEM ] ) + hb_adel( ::aProjData, n, .t. ) + ENDDO ENDIF - nPos := aScan( ::aProjData, {|e_| e_[ TRE_TYPE ] == "Project Name" .and. e_[ TRE_ORIGINAL ] == cProject } ) - cType := aPrj[ PRJ_PRP_PROPERTIES, 2, E_qPrjType ] + oP := oParent - DO CASE - CASE cType == "Executable" + SWITCH oProject:type + CASE "Executable" oParent := ::aProjData[ 1, 1 ] - CASE cType == "Lib" + EXIT + CASE "Lib" oParent := ::aProjData[ 2, 1 ] - CASE cType == "Dll" + EXIT + CASE "Dll" oParent := ::aProjData[ 3, 1 ] - ENDCASE + EXIT + ENDSWITCH - IF !( lRemove ) + nIndex := aScan( ::aProjData, {|e_| e_[ TRE_OITEM ] == oP } ) + oParent:delItem( oP ) + hb_adel( ::aProjData, nIndex, .t. ) - * It is a new node? - IF nPos == 0 - oParent:expand( .t. ) + RETURN Self - oP := oParent:addItem( cProject ) - aadd( ::aProjData, { oP, "Project Name", oParent, cProject, aPrj } ) - oParent := oP +/*----------------------------------------------------------------------*/ - * Need to be an update? - ELSE - nPos := aScan( oParent:aChilds, {|o| o:caption == cProject } ) +METHOD HbIde:updateProjectTree( aPrj ) + LOCAL oProject, n, oSource, oItem, nProjExists, oP, oParent, cPath - IF nPos <> 00 - oParent := oParent:aChilds[ nPos ] - ENDIF - ENDIF - - aSrc := aClone( aPrj[ PRJ_PRP_SOURCES, 2 ] ) - aSrc := ASort( aSrc ) - aPath := {} - aInUse:= {} - - * Load previous aPath used to fill ::aProjData - * 03/01/2010 - 16:08:25 - vailtom - FOR j := 1 TO LEN( ::aProjData ) - IF !hb_isChar( ::aProjData[ j, 5 ] ) .OR. ; // It is not a char? - ::aProjData[ j, TRE_TYPE ] != 'Path' .OR. ; // Is not an path? - ::aProjData[ j, TRE_DATA ] != cProject // Is not from same project? - LOOP - ENDIF - AAdd( aPath, { ::aProjData[ j, TRE_ORIGINAL ], ::aProjData[ j, 1 ]} ) - NEXT - - * Add new nodes with file names to tree... - FOR j := 1 TO len( aSrc ) - hb_fNameSplit( aSrc[ j ], @cPath, @cFile, @cExt ) - - cPathA := hbide_pathNormalized( cPath, .T. ) - nPath := aScan( aPath, {|e_| e_[ 1 ] == cPathA } ) - - AAdd( aInUse, cPathA ) - - * Find an node with Caption == cPathA - IF ( nPath == 0 ) - oPP := oParent:addItem( hbide_pathNormalized( cPath, .f. ) ) - aadd( ::aProjData, { oPP, "Path", oParent, cPathA, cProject } ) - aadd( aPath, { cPathA, oPP } ) - nPath := len( aPath ) - ENDIF - - oPP := aPath[ nPath,2 ] - cFile := cFile + cExt - nPos := aScan( ::aProjData, {|e_| e_[ TRE_TYPE ] == "Source File" .AND. ; - e_[ TRE_ORIGINAL ] == aSrc[ j ] } ) - IF nPos == 00 - aadd( ::aProjData, { oPP:addItem( cFile ), "Source File", oPP, aSrc[ j ], cProject } ) - ENDIF - NEXT - - * Remove deleted nodes from tree - FOR j := 1 TO LEN( ::aProjData ) - - * Is not from same project? - IF !hb_isChar( ::aProjData[ j, TRE_DATA ] ) .OR. ; - ::aProjData[ j, TRE_DATA ] != cProject - LOOP - ENDIF - - * It is a path? - IF ::aProjData[ j, 2 ] == 'Path' - cPathA := ::aProjData[ j, TRE_ORIGINAL ] - nPath := aScan( aInUse, {|e_| e_ == cPathA } ) - - IF nPath == 00 - ::aProjData[ j, TRE_OPARENT ]:delItem( ::aProjData[ j, 1 ] ) - hb_aDel( ::aProjData, j, .T. ) - ENDIF - - LOOP - ENDIF - - * It is a filename? - IF ::aProjData[ j, 2 ] == 'Source File' - cFile := ::aProjData[ j, TRE_ORIGINAL ] - nPos := aScan( aSrc, {|e_| e_ == cFile } ) - - IF nPos == 00 - ::aProjData[ j, TRE_OPARENT ]:delItem( ::aProjData[ j, TRE_OITEM ] ) - hb_aDel( ::aProjData, j, .T. ) - ENDIF - - LOOP - ENDIF - NEXT - - ELSE - - IF nPos != 0 - nPos := aScan( oParent:aChilds, {|e_| e_:Caption == cProject } ) - - IF nPos > 0 - oParent:delItem( oParent:aChilds[ nPos ] ) - ENDIF - ENDIF + oProject := IdeProject():new( Self, aPrj ) + IF empty( oProject:title ) + RETURN Self ENDIF + SWITCH oProject:type + CASE "Executable" + oParent := ::aProjData[ 1, 1 ] + EXIT + CASE "Lib" + oParent := ::aProjData[ 2, 1 ] + EXIT + CASE "Dll" + oParent := ::aProjData[ 3, 1 ] + EXIT + ENDSWITCH + + nProjExists := aScan( ::aProjData, {|e_| e_[ TRE_TYPE ] == "Project Name" .AND. e_[ TRE_ORIGINAL ] == oProject:title } ) + + IF nProjExists > 0 + nProjExists := aScan( oParent:aChilds, {|o| o:caption == oProject:title } ) + IF nProjExists > 0 + oP := oParent:aChilds[ nProjExists ] + ELSE + RETURN Self /* Some Error - It must never happen */ + ENDIF + /* Delete Existing Nodes */ + DO WHILE .t. + n := ascan( ::aProjData, {|e_| e_[ TRE_OPARENT ] == oP } ) + IF n == 0 + EXIT + ENDIF + oP:delItem( ::aProjData[ n, TRE_OITEM ] ) + hb_adel( ::aProjData, n, .t. ) + ENDDO + ENDIF + IF empty( oP ) + oParent:expand( .t. ) + oP := oParent:addItem( oProject:title ) + aadd( ::aProjData, { oP, "Project Name", oParent, oProject:title, aPrj, oProject } ) + ENDIF + oParent := oP + /* Reassign all children nodes */ + FOR EACH cPath IN oProject:hPaths + oItem := oParent:addItem( cPath:__enumKey() ) + aadd( ::aProjData, { oItem, "Path", oParent, cPath:__enumKey(), oProject:title, oProject } ) + NEXT + /* Souces */ + FOR EACH oSource IN oProject:hSources + n := ascan( ::aProjData, {|e_| e_[ TRE_TYPE ] == "Path" .AND. ; + e_[ TRE_ORIGINAL ] == oSource:path .AND. ; + e_[ TRE_DATA ] == oProject:title } ) + IF n > 0 + oP := ::aProjData[ n, TRE_OITEM ] + oItem := oP:addItem( oSource:file + oSource:ext ) + aadd( ::aProjData, { oItem, "Source File", oP, oSource:original, oProject:title } ) + ENDIF + NEXT + RETURN Self /*----------------------------------------------------------------------*/ @@ -953,7 +924,7 @@ METHOD HbIde:manageProjectContext( mp1, mp2, oXbpTreeItem ) IF !empty( ::oEV:getNames() ) aadd( aPops, { "" } ) FOR EACH s IN ::oEV:getNames() - aadd( aSub, { s , {|x| ::cWrkEnvironment := x, ::oDK:dispEnvironment( x ) } } ) + aadd( aSub, { s , {|x| ::cWrkEnvironment := x, ::oDK:dispEnvironment( x ) } } ) NEXT aadd( aPops, { aSub, "Environment..." } ) ENDIF @@ -978,11 +949,12 @@ METHOD HbIde:manageProjectContext( mp1, mp2, oXbpTreeItem ) aadd( aPops, { "" } ) aadd( aPops, { "Launch" , {|| ::oPM:launchProject( oXbpTreeItem:caption ) } } ) aadd( aPops, { "" } ) - aadd( aPops, { "Close This Project" , {|| ::oPM:closeProject( oXbpTreeItem:caption ) } } ) + aadd( aPops, { "Close this Project" , {|| ::oPM:closeProject( oXbpTreeItem:caption ) } } ) + aadd( aPops, { "Remove this Project" , {|| ::oPM:removeProject( oXbpTreeItem:caption ) } } ) IF !empty( ::oEV:getNames() ) aadd( aPops, { "" } ) FOR EACH s IN ::oEV:getNames() - aadd( aSub, { s , {|x| ::cWrkEnvironment := x, ::oDK:dispEnvironment( x ) } } ) + aadd( aSub, { s , {|x| ::cWrkEnvironment := x, ::oDK:dispEnvironment( x ) } } ) NEXT aadd( aPops, { aSub, "Select an environment" } ) ENDIF diff --git a/harbour/contrib/hbide/idemisc.prg b/harbour/contrib/hbide/idemisc.prg index 9c95b39e75..f748070538 100644 --- a/harbour/contrib/hbide/idemisc.prg +++ b/harbour/contrib/hbide/idemisc.prg @@ -1182,120 +1182,162 @@ FUNCTION hbide_getOS() RETURN cOS /*----------------------------------------------------------------------*/ -#if 0 -PROCEDURE hbide_convert_xhp_to_hbp( cSrcName ) - LOCAL cSrc := MemoRead( cSrcName ) - LOCAL cDst - LOCAL aDst := {} +/* + * Harbour Project source code: + * + * Copyright 2010 Viktor Szakats (harbour.01 syenar.hu) + * www - http://www.harbour-project.org + * + */ +#define HBIDE_HBP_PTYPE_FILES "files" +#define HBIDE_HBP_PTYPE_OPTIONS "options" +#define HBIDE_HBP_PTYPE_HBIDEPARAMS "hbideparams" + +FUNCTION hbide_fetchHbpData( cHBPFileName ) + LOCAL aParamList + + aParamList := hbide_HBPGetParamList( cHBPFileName ) + + hbide_dbg( "hbmk2 files" ) ; AEval( hbide_HBPParamListFilter( aParamList, HBIDE_HBP_PTYPE_FILES ), {| tmp | hbide_dbg( tmp ) } ) + hbide_dbg( "hbmk2 options" ) ; AEval( hbide_HBPParamListFilter( aParamList, HBIDE_HBP_PTYPE_OPTIONS ), {| tmp | hbide_dbg( tmp ) } ) + hbide_dbg( "hbide comments" ) ; AEval( hbide_HBPParamListFilter( aParamList, HBIDE_HBP_PTYPE_HBIDEPARAMS ), {| tmp | hbide_dbg( tmp ) } ) + + RETURN { hbide_HBPParamListFilter( aParamList, HBIDE_HBP_PTYPE_OPTIONS ), ; + hbide_HBPParamListFilter( aParamList, HBIDE_HBP_PTYPE_FILES ) } + +/*----------------------------------------------------------------------*/ + +FUNCTION hbide_HBPParamListFilter( aParams, nType ) + LOCAL aArray := {} LOCAL tmp - LOCAL cLine - LOCAL cSetting - LOCAL cValue - LOCAL aValue - LOCAL cFile - LOCAL hLIBPATH := {=>} - LOCAL cMAIN := NIL - LOCAL lFileSection := .F. + LOCAL cParamNQ - LOCAL cHome, cOutname, cType, cDefine, cInclude, aFiles := {} - LOCAL cRun, cParams, cDestntn, cMap - - - cSrc := StrTran( cSrc, Chr( 13 ) + Chr( 10 ), Chr( 10 ) ) - cSrc := StrTran( cSrc, Chr( 9 ), Chr( 32 ) ) - - FOR EACH cLine IN hb_ATokens( cSrc, Chr( 10 ) ) - IF cLine == "[Files]" - lFileSection := .T. - ELSEIF lFileSection - tmp := At( "=", cLine ) - IF tmp > 0 - cFile := AllTrim( Left( cLine, tmp - 1 ) ) - SWITCH Lower( FN_ExtGet( cFile ) ) - CASE ".c" - CASE ".prg" - IF !( "%HB_INSTALL%\" $ cFile ) - AAdd( aDst, StrTran( cFile, "%HOME%\" ) ) - ENDIF - EXIT - CASE ".lib" - CASE ".a" - IF !( "%C_LIB_INSTALL%\" $ cFile ) .AND. ; - !( "%HB_LIB_INSTALL%\" $ cFile ) - cFile := StrTran( cFile, "%HOME%\" ) - IF !( FN_DirGet( cFile ) $ hLIBPATH ) - hLIBPATH[ FN_DirGet( cFile ) ] := NIL - ENDIF - AAdd( aDst, "-l" + FN_NameGet( cFile ) ) - ENDIF - EXIT - CASE ".obj" - CASE ".o" - IF !( "%C_LIB_INSTALL%\" $ cFile ) .AND. ; - !( "%HB_LIB_INSTALL%\" $ cFile ) - AAdd( aDst, StrTran( cFile, "%HOME%\" ) ) - ENDIF - EXIT - ENDSWITCH + FOR EACH tmp IN aParams + DO CASE + CASE Lower( Left( tmp[ 1 ], 7 ) ) == "#hbide." + IF nType == HBIDE_HBP_PTYPE_HBIDEPARAMS + AAdd( aArray, tmp[ 1 ] ) ENDIF - ELSE - tmp := At( "=", cLine ) - IF tmp > 0 - cSetting := AllTrim( Left( cLine, tmp - 1 ) ) - cValue := AllTrim( SubStr( cLine, tmp + Len( "=" ) ) ) - aValue := hb_ATokens( cValue ) - IF ! Empty( cValue ) - SWITCH cSetting - CASE "Create Map/List File" - IF cValue == "Yes" - AAdd( aDst, "-map" ) - ENDIF - EXIT - CASE "Final Path" - IF ! Empty( cValue ) - AAdd( aDst, "-o" + DirAddPathSep( StrTran( cValue, "%HOME%\" ) ) ) - ENDIF - EXIT - CASE "Include" - FOR EACH tmp IN aValue - IF Left( tmp, 2 ) == "-I" - tmp := SubStr( tmp, 3 ) - ENDIF - AAdd( aDst, "-incpath=" + StrTran( StrTran( tmp, Chr( 34 ) ), "%HOME%\" ) ) - NEXT - EXIT - CASE "Define" - FOR EACH tmp IN aValue - IF Left( tmp, 2 ) == "-D" - tmp := SubStr( tmp, 3 ) - ENDIF - AAdd( aDst, "-D" + tmp ) - NEXT - EXIT - CASE "Params" - FOR EACH tmp IN aValue - AAdd( aDst, "-runflag=" + tmp ) - NEXT - EXIT - ENDSWITCH + CASE Left( tmp[ 1 ], 1 ) == "#" + /* misc comment line, always skip */ + CASE Empty( tmp[ 1 ] ) + /* empty line, always skip */ + OTHERWISE + cParamNQ := hbide_HBPStrStripQuote( tmp[ 1 ] ) + IF Left( cParamNQ, 1 ) == "-" + /* in conformance with hbmk2, skip remaining hbmk2 parameters if -skip is found */ + IF Lower( cParamNQ ) == "-skip" .AND. ( nType == HBIDE_HBP_PTYPE_FILES .OR. nType == HBIDE_HBP_PTYPE_OPTIONS ) + EXIT + ENDIF + IF nType == HBIDE_HBP_PTYPE_OPTIONS + AAdd( aArray, cParamNQ ) + ENDIF + ELSE + IF nType == HBIDE_HBP_PTYPE_FILES + AAdd( aArray, cParamNQ ) ENDIF ENDIF + ENDCASE + NEXT + + RETURN aArray + +/*----------------------------------------------------------------------*/ + +/* Load entire .hbp files, with empty lines and comments for + further processing. [vszakats] */ +FUNCTION hbide_HBPGetParamList( cFileName ) + LOCAL aParams := {} + + hbide_HBPLoad( aParams, cFileName ) + + RETURN aParams + +/*----------------------------------------------------------------------*/ + +/* Recursive .hbp/.hbm files are not currently supported. + It can be added, but it makes updating the options much more + complicated. [vszakats] */ + +#define HBIDE_HBP_EOL Chr( 10 ) + +STATIC PROCEDURE hbide_HBPLoad( aParams, cFileName ) + LOCAL cFile + LOCAL cLine + LOCAL cParam + LOCAl cParamNQ + + IF hb_FileExists( cFileName ) + + cFile := MemoRead( cFileName ) /* NOTE: Intentionally using MemoRead() which handles EOF char. */ + + IF ! hb_osNewLine() == HBIDE_HBP_EOL + cFile := StrTran( cFile, hb_osNewLine(), HBIDE_HBP_EOL ) + ENDIF + IF ! hb_osNewLine() == Chr( 13 ) + Chr( 10 ) + cFile := StrTran( cFile, Chr( 13 ) + Chr( 10 ), HBIDE_HBP_EOL ) ENDIF - NEXT - FOR EACH tmp IN hLIBPATH - AAdd( aDst, "-L" + tmp:__enumKey() ) - NEXT - - cDst := "" - FOR EACH tmp IN aDst - cDst += tmp + hb_osNewLine() - NEXT - - hbmk_OutStd( hb_StrFormat( I_( "Saving as .hbp file: %1$s" ), cDstName ) ) - - hb_MemoWrit( cDstName, cDst ) + FOR EACH cLine IN hb_ATokens( cFile, HBIDE_HBP_EOL ) + IF Empty( cLine ) .OR. ; + Left( cLine, 1 ) == "#" + AAdd( aParams, { cLine, cFileName, cLine:__enumIndex() } ) + ELSE + FOR EACH cParam IN hb_ATokens( cLine,, .T. ) + cParamNQ := hbide_HBPStrStripQuote( cParam ) + IF ! Empty( cParamNQ ) + DO CASE + CASE !( Left( cParamNQ, 1 ) == "-" ) .AND. Len( cParamNQ ) >= 1 .AND. Left( cParamNQ, 1 ) == "@" .AND. ; + !( Lower( hbide_HBPExtGet( cParamNQ ) ) == ".clp" ) + /* skip recurse */ + CASE !( Left( cParamNQ, 1 ) == "-" ) .AND. ; + ( Lower( hbide_HBPExtGet( cParamNQ ) ) == ".hbm" .OR. ; + Lower( hbide_HBPExtGet( cParamNQ ) ) == ".hbp" ) + /* skip recurse */ + OTHERWISE + AAdd( aParams, { cParam, cFileName, cLine:__enumIndex() } ) + ENDCASE + ENDIF + NEXT + ENDIF + NEXT + ENDIF RETURN -#endif + +/*----------------------------------------------------------------------*/ + +STATIC FUNCTION hbide_HBPStrStripQuote( cString ) + RETURN iif( Left( cString, 1 ) == '"' .AND. Right( cString, 1 ) == '"',; + SubStr( cString, 2, Len( cString ) - 2 ),; + cString ) + +/*----------------------------------------------------------------------*/ + +STATIC FUNCTION hbide_HBPExtGet( cFileName ) + LOCAL cExt + + hb_FNameSplit( cFileName,,, @cExt ) + + RETURN cExt + +/*----------------------------------------------------------------------*/ +// +/*----------------------------------------------------------------------*/ + +FUNCTION hbide_parseHbpFilter( s, cFilt, cPath ) + LOCAL n, n1 + + cFilt := "" + cPath := s + IF ( n := at( "{", s ) ) > 0 + IF ( n1 := at( "}", s ) ) > 0 + cFilt := substr( s, n + 1, n1 - n + 1 ) + cPath := alltrim( substr( s, n1 + 1 ) ) + RETURN .t. + ENDIF + ENDIF + + RETURN .f. + /*----------------------------------------------------------------------*/ diff --git a/harbour/contrib/hbide/ideprojmanager.prg b/harbour/contrib/hbide/ideprojmanager.prg index 10f23b04a2..5eda008c7f 100644 --- a/harbour/contrib/hbide/ideprojmanager.prg +++ b/harbour/contrib/hbide/ideprojmanager.prg @@ -77,15 +77,15 @@ CLASS IdeEnvironments - DATA oIde + 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 new( oIDE, cEnvFile ) + METHOD create( oIDE, cEnvFile ) METHOD parse( aContents ) METHOD prepareBatch( cEnviron ) METHOD getNames() INLINE ::aNames @@ -94,22 +94,22 @@ CLASS IdeEnvironments /*----------------------------------------------------------------------*/ -METHOD IdeEnvironments:new( oIde, cEnvFile ) +METHOD IdeEnvironments:new( oIDE, cEnvFile ) - ::oIde := oIde + ::oIDE := oIDE ::cEnvFile := cEnvFile RETURN Self /*----------------------------------------------------------------------*/ -METHOD IdeEnvironments:create( oIde, cEnvFile ) +METHOD IdeEnvironments:create( oIDE, cEnvFile ) LOCAL a_ - DEFAULT oIde TO ::oIde + DEFAULT oIDE TO ::oIDE DEFAULT cEnvFile TO ::cEnvFile - ::oIde := oIde + ::oIDE := oIDE ::cEnvFile := cEnvFile IF empty( ::cEnvFile ) .OR. !hb_fileExists( ::cEnvFile ) @@ -202,6 +202,42 @@ METHOD IdeEnvironments:prepareBatch( cEnviron ) RETURN cFile +/*----------------------------------------------------------------------*/ +// +// Class IdeSource +// +/*----------------------------------------------------------------------*/ + +CLASS IdeSource + + DATA original + DATA normalized + DATA filter + DATA path + DATA file + DATA ext + + METHOD new( cSource ) + + ENDCLASS + +/*----------------------------------------------------------------------*/ + +METHOD IdeSource:new( cSource ) + LOCAL cFilt, cPathFile, cPath, cFile, cExt + + hbide_parseHbpFilter( cSource, @cFilt, @cPathFile ) + hb_fNameSplit( cPathFile, @cPath, @cFile, @cExt ) + + ::original := cSource + ::normalized := hbide_pathNormalized( cSource, .t. ) + ::filter := cFilt + ::path := hbide_pathNormalized( cPath, .t. ) + ::file := cFile + ::ext := lower( cExt ) + + RETURN Self + /*----------------------------------------------------------------------*/ // // Class IdeProject @@ -231,8 +267,10 @@ CLASS IdeProject DATA compilers INIT "" DATA cPathMk2 INIT hb_getenv( "HBIDE_DIR_HBMK2" ) DATA cPathEnv INIT hb_DirBase() + "resources" + DATA hSources INIT {=>} + DATA hPaths INIT {=>} - METHOD new( oIde, aProps ) + METHOD new( oIDE, aProps ) METHOD applyMeta( s ) METHOD expandMeta( s ) @@ -240,17 +278,13 @@ CLASS IdeProject /*----------------------------------------------------------------------*/ -METHOD IdeProject:new( oIde, aProps ) - LOCAL b_, a_ +METHOD IdeProject:new( oIDE, aProps ) + LOCAL b_, a_, oSource, cSource IF hb_isArray( aProps ) .AND. !empty( aProps ) ::aProjProps := aProps b_:= aProps - - //::normalizedName := b_[ 1 ] - //::fileName := b_[ 2 ] - a_:= b_[ PRJ_PRP_PROPERTIES, 2 ] ::type := a_[ E_qPrjType ] @@ -274,16 +308,22 @@ METHOD IdeProject:new( oIde, aProps ) IF empty( ::wrkDirectory ) ::wrkDirectory := ::location ENDIF - IF !empty( oIde:aINI[ INI_HBIDE, PathMk2 ] ) - ::cPathMk2 := oIde:aINI[ INI_HBIDE, PathMk2 ] + 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 ] + 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. ) NEXT + + FOR EACH cSource IN ::sources + oSource := IdeSource():new( cSource ) + ::hSources[ oSource:normalized ] := oSource + ::hPaths[ oSource:path ] := NIL + NEXT ENDIF RETURN Self @@ -334,9 +374,10 @@ CLASS IdeProjManager INHERIT IdeObject DATA oProject DATA cBatch DATA oProcess + DATA lSaveOK INIT .f. - METHOD new( oIde ) - METHOD create( oIde ) + METHOD new( oIDE ) + METHOD create( oIDE ) METHOD destroy() METHOD populate() @@ -353,8 +394,10 @@ CLASS IdeProjManager INHERIT IdeObject METHOD selectCurrentProject() METHOD getProjectProperties( cProjectTitle ) METHOD getProjectByFile( cProjectFile ) + METHOD getProjectFileNameFromTitle( cProjectTitle ) METHOD getProjectByTitle( cProjectTitle ) - METHOD closeProject( cProject ) + METHOD removeProject( cProjectTitle ) + METHOD closeProject( cProjectTitle ) METHOD promptForPath( cObjPathName, cTitle, cObjFileName, cObjPath2, cObjPath3 ) METHOD buildProject( cProject, lLaunch, lRebuild, lPPO, lViaQt ) METHOD launchProject( cProject ) @@ -363,23 +406,25 @@ CLASS IdeProjManager INHERIT IdeObject METHOD saveEnvironments() METHOD manageEnvironments() METHOD loadXhpProject() + METHOD loadHbpProject() + ENDCLASS /*----------------------------------------------------------------------*/ -METHOD IdeProjManager:new( oIde ) +METHOD IdeProjManager:new( oIDE ) - ::oIde := oIde + ::oIDE := oIDE RETURN Self /*----------------------------------------------------------------------*/ -METHOD IdeProjManager:create( oIde ) +METHOD IdeProjManager:create( oIDE ) - DEFAULT oIde TO ::oIde + DEFAULT oIDE TO ::oIDE - ::oIde := oIde + ::oIDE := oIDE RETURN Self @@ -457,12 +502,12 @@ METHOD IdeProjManager:loadProperties( cProjFileName, lNew, lFetch, lUpdateTree ) IF empty( ::aPrjProps ) ::aPrjProps := hbide_fetchHbiStructFromFile( hbide_pathToOSPath( cProjFileName ) ) ENDIF - ::oIde:aMeta := ::aPrjProps[ PRJ_PRP_METADATA, 2 ] + ::oIDE:aMeta := ::aPrjProps[ PRJ_PRP_METADATA, 2 ] ENDIF IF lFetch /* Access/Assign via this object */ - ::oProject := IdeProject():new( ::oIde, ::aPrjProps ) + ::oProject := IdeProject():new( ::oIDE, ::aPrjProps ) // ::fetchProperties() IF !empty( ::cSaveTo ) .and. hb_FileExists( ::cSaveTo ) @@ -471,16 +516,20 @@ METHOD IdeProjManager:loadProperties( cProjFileName, lNew, lFetch, lUpdateTree ) ENDIF ENDIF + IF lFetch .AND. empty( ::cSaveTo ) + RETURN Self + ENDIF + IF n == 0 - aadd( ::oIde:aProjects, { hbide_pathNormalized( cProjFileName ), cProjFileName, aclone( ::aPrjProps ) } ) + aadd( ::oIDE:aProjects, { hbide_pathNormalized( cProjFileName ), cProjFileName, aclone( ::aPrjProps ) } ) IF lUpdateTree - ::oIde:updateProjectTree( ::aPrjProps ) + ::oIDE:updateProjectTree( ::aPrjProps ) ENDIF - hbide_mnuAddFileToMRU( ::oIde, cProjFileName, INI_RECENTPROJECTS ) + hbide_mnuAddFileToMRU( ::oIDE, cProjFileName, INI_RECENTPROJECTS ) ELSE ::aProjects[ n, 3 ] := aclone( ::aPrjProps ) IF lUpdateTree - ::oIde:updateProjectTree( ::aPrjProps ) + ::oIDE:updateProjectTree( ::aPrjProps ) ENDIF IF lUpdateTree .AND. ::aPrjProps[ PRJ_PRP_PROPERTIES, 2, E_qPrjType ] <> t MsgBox( "::removeProjectFromTree( ::aPrjProps )" ) @@ -523,15 +572,17 @@ METHOD IdeProjManager:fetchProperties() ::oUI:q_buttonChooseDest :setIcon( cLukupPng ) ::oUI:q_buttonBackup :setIcon( cLukupPng ) ::oUI:q_buttonXmate :setIcon( ::resPath + "xmate.png" ) + ::oUI:q_buttonHbp :setIcon( ::resPath + "open.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() } ) - ::oUI:signal( "buttonSave" , "clicked()", {|| ::save( .F. ) } ) - ::oUI:signal( "buttonSaveExit" , "clicked()", {|| ::save( .T. ) } ) + ::oUI:signal( "buttonCn" , "clicked()", {|| ::lSaveOK := .f., ::oUI:oWidget:close() } ) + ::oUI:signal( "buttonSave" , "clicked()", {|| ::lSaveOK := .t., ::save( .F. ) } ) + ::oUI:signal( "buttonSaveExit" , "clicked()", {|| ::lSaveOK := .t., ::save( .T. ) } ) + // ::oUI:signal( "buttonSelect" , "clicked()", {|| ::addSources() } ) ::oUI:signal( "buttonSort" , "clicked()", {|| ::sortSources( "az" ) } ) ::oUI:signal( "buttonSortZA" , "clicked()", {|| ::sortSources( "za" ) } ) @@ -545,6 +596,7 @@ METHOD IdeProjManager:fetchProperties() ::oUI:signal( "buttonChooseDest" , "clicked()", {|| ::PromptForPath( 'editDstFolder', 'Choose Destination Folder...' ) } ) ::oUI:signal( "buttonBackup" , "clicked()", {|| ::PromptForPath( 'editBackup' , 'Choose Backup Folder...' ) } ) ::oUI:signal( "buttonXmate" , "clicked()", {|| ::loadXhpProject() } ) + ::oUI:signal( "buttonHbp" , "clicked()", {|| ::loadHbpProject() } ) IF empty( ::aPrjProps ) /* @@ -688,6 +740,54 @@ METHOD IdeProjManager:save( lCanClose ) /*----------------------------------------------------------------------*/ +METHOD IdeProjManager:loadHbpProject() + LOCAL cHbp, aData, aOptns, aFiles, cHome, cOutName, cType, n + + cHbp := hbide_fetchAFile( ::oDlg, "Selecet Harbour Project File", { { "Harbour Project Files", "*.hbp" } } ) + IF empty( cHbp ) + RETURN Self + ENDIF + hb_fNameSplit( cHbp, @cHome, @cOutName ) + cHome := hbide_pathStripLastSlash( cHome ) + + aData := hbide_fetchHbpData( cHbp ) + aOptns := aData[ 1 ] + aFiles := aData[ 2 ] + + IF ( n := ascan( aOptns, {|e| lower( e ) $ "-hbexec,-hblib,-hbdyn" } ) ) > 0 + cType := lower( aOptns[ n ] ) + ELSE + cType := "" + ENDIF + /* Basic Parsing is complete , parse paths from keywords */ + SWITCH cType + CASE "-hblib" + ::oUI:q_comboPrjType:setCurrentIndex( 1 ) + EXIT + CASE "-hbdyn" + ::oUI:q_comboPrjType:setCurrentIndex( 2 ) + EXIT + OTHERWISE + ::oUI:q_comboPrjType:setCurrentIndex( 0 ) + EXIT + ENDSWITCH + + ::oUI:q_editPrjTitle :setText( cOutName ) + ::oUI:q_editPrjLoctn :setText( cHome ) +* ::oUI:q_editWrkFolder:setText( "" ) + ::oUI:q_editDstFolder:setText( "" ) /* To parse -o : but first fix path verification to honor filters */ +* ::oUI:q_editBackup :setText( "" ) + ::oUI:q_editOutName :setText( cOutName ) +* ::oUI:q_editLaunchParams:setText( cParams ) +* ::oUI:q_editLaunchExe:setText( cRun ) + + ::oUI:q_editFlags :setPlainText( hbide_arrayToMemo( aOptns ) ) + ::oUI:q_editSources:setPlainText( hbide_arrayToMemo( aFiles ) ) + + RETURN Self + +/*----------------------------------------------------------------------*/ + METHOD IdeProjManager:loadXhpProject() LOCAL cXhp, a_, s, n, cPart, cKey, cVal LOCAL cHome, cOutname, cType, cDefine, cInclude @@ -909,11 +1009,11 @@ METHOD IdeProjManager:saveEnvironments() cPathMk2 := ::oUI:q_editPathMk2:text() cPathEnv := ::oUI:q_editPathEnv:text() - ::oIde:aINI[ INI_HBIDE, PathMk2 ] := cPathMk2 - ::oIde:aINI[ INI_HBIDE, PathEnv ] := cPathEnv + ::oIDE:aINI[ INI_HBIDE, PathMk2 ] := cPathMk2 + ::oIDE:aINI[ INI_HBIDE, PathEnv ] := cPathEnv // - ::oIde:cWrkPathMk2 := cPathMk2 - ::oIde:cWrkPathEnv := cPathEnv + ::oIDE:cWrkPathMk2 := cPathMk2 + ::oIDE:cWrkPathEnv := cPathEnv IF !empty( cText := ::oUI:q_editCompilers:toPlainText() ) hb_MemoWrit( hbide_pathFile( cPathEnv, "hbide.env" ), cText ) @@ -1083,11 +1183,11 @@ METHOD IdeProjManager:setCurrentProject( cProjectName ) LOCAL lValid := .T. IF Empty( cProjectName ) - ::oIde:cWrkProject := '' + ::oIDE:cWrkProject := '' ELSEIF ( n := ascan( ::aProjects, {|e_| e_[ 3, PRJ_PRP_PROPERTIES, 2, E_oPrjTtl ] == cProjectName } ) ) > 0 aPrjProps := ::aProjects[ n, 3 ] - ::oIde:cWrkProject := aPrjProps[ PRJ_PRP_PROPERTIES, 2, E_oPrjTtl ] + ::oIDE:cWrkProject := aPrjProps[ PRJ_PRP_PROPERTIES, 2, E_oPrjTtl ] ELSE * MsgBox( 'Invalid project selected: "' + cProjectName + '"' ) @@ -1100,22 +1200,24 @@ METHOD IdeProjManager:setCurrentProject( cProjectName ) ::oSBar:getItem( SB_PNL_PROJECT ):caption := ::cWrkProject ENDIF - ::oIde:updateTitleBar() - ::oIde:updateProjectMenu() + ::oIDE:updateTitleBar() + #if 0 /* It must not be as there are more actions attached */ + ::oIDE:updateProjectMenu() + #endif /* Reset Old Color */ IF !empty( cOldProject ) - IF !empty( oItem := hbide_findProjTreeItem( ::oIde, cOldProject, "Project Name" ) ) + IF !empty( oItem := hbide_findProjTreeItem( ::oIDE, cOldProject, "Project Name" ) ) oItem:oWidget:setForeground( 0, QBrush():new( "QColor", QColor():new( 0,0,0 ) ) ) //oItem:oWidget:setBackground( 0, QBrush():new( "QColor", QColor():new( 255,255,255 ) ) ) ENDIF ENDIF /* Set New Color */ IF !empty( ::cWrkProject ) - IF !empty( oItem := hbide_findProjTreeItem( ::oIde, ::cWrkProject, "Project Name" ) ) + IF !empty( oItem := hbide_findProjTreeItem( ::oIDE, ::cWrkProject, "Project Name" ) ) oItem:oWidget:setForeground( 0, ::qBrushWrkProject ) //oItem:oWidget:setBackground( 0, ::qBrushWrkProject ) - hbide_expandChildren( ::oIde, oItem ) + hbide_expandChildren( ::oIDE, oItem ) ::oProjTree:oWidget:setCurrentItem( oItem:oWidget ) ENDIF ENDIF @@ -1158,7 +1260,7 @@ METHOD IdeProjManager:selectCurrentProject() ENDIF oDlg := HbpQtUI():new( ::oDlg ) - oDlg:file := ::oIde:resPath + "selectproject.ui" + oDlg:file := ::oIDE:resPath + "selectproject.ui" oDlg:create() * Fill ComboBox with current project names @@ -1203,7 +1305,18 @@ METHOD IdeProjManager:getProjectByFile( cProjectFile ) aProj := ::aProjects[ n ] ENDIF - RETURN IdeProject():new( ::oIde, aProj ) + RETURN IdeProject():new( ::oIDE, aProj ) + +/*----------------------------------------------------------------------*/ + +METHOD IdeProjManager:getProjectFileNameFromTitle( cProjectTitle ) + LOCAL n, cProjFileName := "" + + IF ( n := ascan( ::aProjects, {|e_, x| x := e_[ 3 ], x[ 1, 2, PRJ_PRP_TITLE ] == cProjectTitle } ) ) > 0 + cProjFileName := ::aProjects[ n, 2 ] + ENDIF + + RETURN cProjFileName /*----------------------------------------------------------------------*/ @@ -1214,29 +1327,42 @@ METHOD IdeProjManager:getProjectByTitle( cProjectTitle ) aProj := ::aProjects[ n, 3 ] ENDIF - RETURN IdeProject():new( ::oIde, aProj ) + RETURN IdeProject():new( ::oIDE, aProj ) /*----------------------------------------------------------------------*/ -METHOD IdeProjManager:closeProject( cProject ) - LOCAL nPos +METHOD IdeProjManager:removeProject( cProjectTitle ) + LOCAL cProjFileName, nPos + + IF !empty( cProjFileName := ::getProjectFileNameFromTitle( cProjectTitle ) ) + ::closeProject( cProjectTitle ) + + nPos := ascan( ::aProjects, {|e_| e_[ 2 ] == cProjFileName } ) + IF nPos > 0 + hb_adel( ::aProjects, nPos, .T. ) + hbide_saveINI( ::oIDE ) + ENDIF + ENDIF + + RETURN Self + +/*----------------------------------------------------------------------*/ + +METHOD IdeProjManager:closeProject( cProjectTitle ) + LOCAL oProject, aProp IF Empty( ::aProjects ) - MsgBox( "No Projects Available" ) RETURN Self ENDIF - DEFAULT cProject TO ::getCurrentProject() - - nPos := ascan( ::aProjects, {|e_| e_[ 3, PRJ_PRP_PROPERTIES, 2, E_oPrjTtl ] == cProject } ) - IF ( nPos < 0 ) - MsgBox( 'Invalid project: "' + cProject + '"' ) + aProp := ::getProjectProperties( cProjectTitle ) + oProject := IdeProject():new( ::oIDE, aProp ) + IF empty( oProject:title ) RETURN Self ENDIF - ::aPrjProps := {} - ::updateProjectTree( ::aProjects[ nPos, 3 ], .T. ) - hb_adel( ::aProjects, nPos, .T. ) + ::oIDE:removeProjectTree( aProp ) + ::setCurrentProject( '' ) RETURN Self @@ -1384,7 +1510,7 @@ METHOD IdeProjManager:buildProject( cProject, lLaunch, lRebuild, lPPO, lViaQt ) ENDIF ENDIF - ::oIde:lDockBVisible := .t. + ::oIDE:lDockBVisible := .t. ::oDockB2:show() ::oOutputResult:oWidget:clear() @@ -1400,7 +1526,7 @@ METHOD IdeProjManager:buildProject( cProject, lLaunch, lRebuild, lPPO, lViaQt ) hbide_outputLine() + CRLF ::oOutputResult:oWidget:append( cTmp ) - ::oIde:oEV := IdeEnvironments():new():create( ::oIde, hbide_pathFile( ::aINI[ INI_HBIDE, PathEnv ], "hbide.env" ) ) + ::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" ) @@ -1469,8 +1595,7 @@ METHOD IdeProjManager:finished( nExitCode, nExitStatus, oProcess ) * 03/01/2010 - 09:24:50 */ METHOD IdeProjManager:launchProject( cProject ) - LOCAL cTargetFN, cTmp, oProject - LOCAL qProcess + LOCAL cTargetFN, cTmp, oProject, qProcess IF empty( cProject ) cProject := ::oPM:getCurrentProject() diff --git a/harbour/contrib/hbide/resources/projectproperties.ui b/harbour/contrib/hbide/resources/projectproperties.ui index 3aa9b42d55..eeb33fb2b5 100644 --- a/harbour/contrib/hbide/resources/projectproperties.ui +++ b/harbour/contrib/hbide/resources/projectproperties.ui @@ -73,7 +73,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"> @@ -263,10 +263,34 @@ p, li { white-space: pre-wrap; } - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> + + + + + + <!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;">Loading a .hbp project file is essentially a </p> +<p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">task of redefining its flow and contents order.</p> +<p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">hbIDE rewrites the existing .hbp file if the </p> +<p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">"Project Location" points to same folder </p> +<p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">where your such loaded .hbp resides.</p> +<p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">So</p> +<p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">take care to change the "Project Location"</span></p> +<p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">to different folder than home folder of .hbp.</p> +<p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">This is done at the time of "Build" process.</p></body></html> + + + ... + + + + + + + <!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;"> @@ -275,11 +299,26 @@ p, li { white-space: pre-wrap; } <p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">hbIDE attempts to recognize various components</p> <p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">but it is possible that it may not load everything.</p> <p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">So you may need manual editing.</p></body></html> - - - ... - - + + + ... + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + +