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 <Close Project> and <Remove Project> options
      which can be invoked from context menu of project node.
This commit is contained in:
Pritpal Bedi
2010-01-27 17:09:12 +00:00
parent 7fb6524767
commit 5790842dc4
5 changed files with 505 additions and 306 deletions

View File

@@ -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 <Close Project> and <Remove Project> 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

View File

@@ -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

View File

@@ -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.
/*----------------------------------------------------------------------*/

View File

@@ -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()

View File

@@ -73,7 +73,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="2" column="1" colspan="2">
<item row="2" column="1">
<widget class="QLineEdit" name="editPrjTitle">
<property name="toolTip">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
@@ -263,10 +263,34 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QToolButton" name="buttonXmate">
<property name="toolTip">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item>
<widget class="QToolButton" name="buttonHbp">
<property name="toolTip">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p align=&quot;center&quot; style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Loading a .hbp project file is essentially a &lt;/p&gt;
&lt;p align=&quot;center&quot; style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;task of redefining its flow and contents order.&lt;/p&gt;
&lt;p align=&quot;center&quot; style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;hbIDE rewrites the existing .hbp file if the &lt;/p&gt;
&lt;p align=&quot;center&quot; style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&quot;Project Location&quot; points to same folder &lt;/p&gt;
&lt;p align=&quot;center&quot; style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;where your such loaded .hbp resides.&lt;/p&gt;
&lt;p align=&quot;center&quot; style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;So&lt;/p&gt;
&lt;p align=&quot;center&quot; style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;take care to change the &quot;Project Location&quot;&lt;/span&gt;&lt;/p&gt;
&lt;p align=&quot;center&quot; style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;to different folder than home folder of .hbp.&lt;/p&gt;
&lt;p align=&quot;center&quot; style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;This is done at the time of &quot;Build&quot; process.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="buttonXmate">
<property name="toolTip">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;&quot;&gt;
@@ -275,11 +299,26 @@ p, li { white-space: pre-wrap; }
&lt;p align=&quot;center&quot; style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;hbIDE attempts to recognize various components&lt;/p&gt;
&lt;p align=&quot;center&quot; style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;but it is possible that it may not load everything.&lt;/p&gt;
&lt;p align=&quot;center&quot; style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;So you may need manual editing.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>...</string>
</property>
</widget>
</property>
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>