2004-06-07 13:45 UTC+0300 Phil Krylov <phil@newstar.rinet.ru>
This commit is contained in:
@@ -8,6 +8,20 @@
|
||||
2002-12-01 23:12 UTC+0100 Foo Bar <foo.bar@foobar.org>
|
||||
*/
|
||||
|
||||
2004-06-07 13:45 UTC+0300 Phil Krylov <phil@newstar.rinet.ru>
|
||||
* source/debug/dbgwa.prg
|
||||
* source/debug/dbgtarr.prg
|
||||
* source/debug/tbrwtext.prg
|
||||
* source/debug/debugger.prg
|
||||
! Miscellaneous fixes borrowed from xHarbour:
|
||||
! Fixed support for monitoring work areas with non-contigous numbers.
|
||||
! Fixed monitoring empty subarrays.
|
||||
! Maintain separate "active" line and cursor line in the code window.
|
||||
Support external initialization of TBrwText():lLineNumbers.
|
||||
! Fixed problems with breakpoints and source files stored in multiple
|
||||
directories. The environment variable HB_DBG_PATH takes precedence
|
||||
over PATH to search for source files.
|
||||
|
||||
2004-06-03 11:00 UTC+0100 Ryszard Glab <rglab@imid.med.pl>
|
||||
|
||||
* source/compiler/harbour.c
|
||||
|
||||
@@ -158,6 +158,9 @@ method SetsKeyPressed( nKey, oBrwSets, nSets, oWnd ,cName,LenArr,aArray) Class T
|
||||
|
||||
Case nKey == K_ENTER
|
||||
if valtype(aArray[nSet])=="A"
|
||||
if Len( aArray[ nSet ] ) == 0
|
||||
Alert( "Array is empty" )
|
||||
else
|
||||
SetPos(ownd:nBottom,ownd:nLeft)
|
||||
::aWindows[::nCurwindow]:lFocused:=.f.
|
||||
::arrayname:= ::arrayname+"["+alltrim(cTemp)+"]"
|
||||
@@ -171,6 +174,7 @@ method SetsKeyPressed( nKey, oBrwSets, nSets, oWnd ,cName,LenArr,aArray) Class T
|
||||
else
|
||||
::ncurwindow--
|
||||
endif
|
||||
endif
|
||||
elseif valtype(aArray[nSet])=="B"
|
||||
Alert("Value cannot be edited")
|
||||
else
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/*
|
||||
* Harbour Project source code:
|
||||
* The Debugger Array Inspector
|
||||
* The Debugger Work Area Inspector
|
||||
*
|
||||
* Copyright 2001-2002 Ignacio Ortiz de Zuñiga <ignacio@fivetech.com>
|
||||
* www - http://www.harbour-project.org
|
||||
@@ -58,21 +58,27 @@ function __dbgShowWorkAreas( oDebugger )
|
||||
local oDlg, oCol
|
||||
local aAlias, aBrw, aStruc, aInfo
|
||||
local cColor
|
||||
local n1, n2, n3
|
||||
local n1, n2, n3, cur_id
|
||||
|
||||
aAlias := {}
|
||||
aBrw := Array(3)
|
||||
n1 := 1
|
||||
n2 := 1
|
||||
n3 := 1
|
||||
cur_id := 1
|
||||
|
||||
cColor := iif( __Dbg():lMonoDisplay, "N/W, W/N, W+/W, W+/N",;
|
||||
"N/W, N/BG, R/W, R/BG" )
|
||||
|
||||
do while !Empty( Alias( n1 ) )
|
||||
Aadd(aAlias, Alias( n1 ))
|
||||
n1++
|
||||
enddo
|
||||
/* We can't determine the last used area, so use 512 here */
|
||||
for n1 := 1 to 512
|
||||
if ( n1 )->( Used() )
|
||||
AAdd(aAlias, { n1, Alias(n1) })
|
||||
if n1 == Select()
|
||||
cur_id = Len(aAlias)
|
||||
endif
|
||||
endif
|
||||
next
|
||||
|
||||
if len( aAlias ) == 0
|
||||
Alert( "No workareas in use")
|
||||
@@ -94,7 +100,7 @@ function __dbgShowWorkAreas( oDebugger )
|
||||
|
||||
aBrw[1] := TBrowseNew( oDlg:nTop + 1, oDlg:nLeft + 1, oDlg:nBottom - 1, oDlg:nLeft + 11 )
|
||||
|
||||
aBrw[1]:Cargo := ( n1 := Select() )
|
||||
aBrw[1]:Cargo := ( n1 := cur_id )
|
||||
aBrw[1]:ColorSpec := oDlg:cColor
|
||||
aBrw[1]:GoTopBlock := { || n1 := 1 }
|
||||
aBrw[1]:GoBottomBlock := { || n1 := Len( aAlias ) }
|
||||
@@ -102,15 +108,15 @@ function __dbgShowWorkAreas( oDebugger )
|
||||
n1 := iif( nSkip > 0, Min( Len( aAlias ), n1 + nSkip ),;
|
||||
Max( 1, n1 + nSkip ) ), n1 - nPos }
|
||||
|
||||
aBrw[1]:AddColumn( oCol := TBColumnNew( "", { || PadR( aAlias[ n1 ], 11 ) } ) )
|
||||
aBrw[1]:AddColumn( oCol := TBColumnNew( "", { || PadR( aAlias[n1][2], 11 ) } ) )
|
||||
|
||||
oCol:ColorBlock := { || iif( aAlias[ n1 ] == Alias(), {3, 4}, {1, 2} ) }
|
||||
oCol:ColorBlock := { || iif( aAlias[n1][1] == Select(), {3, 4}, {1, 2} ) }
|
||||
|
||||
/*
|
||||
Info Browse
|
||||
*/
|
||||
|
||||
aInfo := ( aAlias[n1] )->(DbfInfo())
|
||||
aInfo := ( aAlias[n1][1] )->( DbfInfo() )
|
||||
|
||||
aBrw[2] := TBrowseNew( oDlg:nTop + 7, oDlg:nLeft + 13, oDlg:nBottom - 1, oDlg:nLeft + 50 )
|
||||
|
||||
@@ -124,13 +130,13 @@ function __dbgShowWorkAreas( oDebugger )
|
||||
|
||||
aBrw[2]:AddColumn( oCol := TBColumnNew( "", { || Padr(aInfo[ n2 ], 38) } ) )
|
||||
|
||||
oCol:ColorBlock := { || iif( aAlias[ n1 ] == Alias() .and. n2 == 1, {3, 4}, {1, 2} ) }
|
||||
oCol:ColorBlock := { || iif( aAlias[n1][1] == Select() .and. n2 == 1, {3, 4}, {1, 2} ) }
|
||||
|
||||
/*
|
||||
Struc browse
|
||||
*/
|
||||
|
||||
aStruc := ( aAlias[n1] )->(DbStruct())
|
||||
aStruc := ( aAlias[n1][1] )->( DbStruct() )
|
||||
|
||||
aBrw[3] := TBrowseNew( oDlg:nTop + 1, oDlg:nLeft + 52, oDlg:nBottom - 1, oDlg:nLeft + 70 )
|
||||
|
||||
@@ -241,7 +247,7 @@ static function DlgWorkAreaKey( nKey, oDlg, aBrw, aAlias, aStruc, aInfo )
|
||||
aBrw[2]:GoTop()
|
||||
aBrw[2]:Invalidate()
|
||||
aBrw[2]:ForceStable()
|
||||
aInfo := ( aAlias[aBrw[1]:Cargo] )->(DbfInfo( aInfo ))
|
||||
aInfo := ( aAlias[aBrw[1]:Cargo][1] )->( DbfInfo(aInfo) )
|
||||
aBrw[3]:Configure()
|
||||
aBrw[2]:Invalidate()
|
||||
aBrw[2]:RefreshAll()
|
||||
@@ -250,13 +256,13 @@ static function DlgWorkAreaKey( nKey, oDlg, aBrw, aAlias, aStruc, aInfo )
|
||||
aBrw[3]:GoTop()
|
||||
aBrw[3]:Invalidate()
|
||||
aBrw[3]:ForceStable()
|
||||
aStruc := ( aAlias[aBrw[1]:Cargo] )->(DbStruct())
|
||||
aStruc := ( aAlias[aBrw[1]:Cargo][1] )->( DbStruct() )
|
||||
aBrw[3]:Configure()
|
||||
aBrw[3]:Invalidate()
|
||||
aBrw[3]:RefreshAll()
|
||||
aBrw[3]:ForceStable()
|
||||
aBrw[3]:Dehilite()
|
||||
UpdateInfo( oDlg, aAlias[aBrw[1]:Cargo] )
|
||||
UpdateInfo( oDlg, aAlias[aBrw[1]:Cargo][2] )
|
||||
endif
|
||||
case nFocus == 2
|
||||
WorkAreasKeyPressed( nKey, aBrw[2], oDlg, len( aInfo ) )
|
||||
@@ -350,7 +356,13 @@ return aInfo
|
||||
|
||||
static function UpdateInfo( oDlg, cAlias )
|
||||
|
||||
local cOldAlias := Alias()
|
||||
local cOldAlias
|
||||
|
||||
if empty(cAlias)
|
||||
return NIL
|
||||
endif
|
||||
|
||||
cOldAlias := Alias()
|
||||
|
||||
SELECT (cAlias)
|
||||
|
||||
|
||||
@@ -206,13 +206,13 @@ procedure __dbgEntry( nMode, uParam1, uParam2, uParam3 ) // debugger entry poin
|
||||
s_oDebugger:Activate()
|
||||
endif
|
||||
|
||||
case nMode == HB_DBG_MODULENAME
|
||||
case nMode == HB_DBG_MODULENAME // called from hvm.c hb_vmModuleName()
|
||||
// add a call to the stack but don't try to show the code yet
|
||||
cProcName := ProcName( 1 )
|
||||
|
||||
if cProcName == "(_INITSTATICS)"
|
||||
//module wide static variable
|
||||
AADD( __dbgStatics, { uParam1, {} } )
|
||||
AADD( __dbgStatics, { strip_path( uParam1 ), {} } )
|
||||
return // We can not use s_oDebugger yet, so we return
|
||||
endif
|
||||
|
||||
@@ -282,7 +282,7 @@ procedure __dbgEntry( nMode, uParam1, uParam2, uParam3 ) // debugger entry poin
|
||||
|
||||
if s_oDebugger:lShowStatics
|
||||
if ( nAt := AScan( s_oDebugger:aVars,; // Is there another var with this name ?
|
||||
{ | aVar | aVar[ VAR_NAME ] == cVarName } ) ) != 0
|
||||
{ | aVar | aVar[ VAR_NAME ] == cVarName } ) ) != 0
|
||||
s_oDebugger:aVars[ nAt ] := ATAIL( s_oDebugger:aCallStack[ 1 ][ CSTACK_STATICS ] )
|
||||
else
|
||||
AAdd( s_oDebugger:aVars, ATAIL( s_oDebugger:aCallStack[ 1 ][ CSTACK_STATICS ] ) )
|
||||
@@ -325,6 +325,7 @@ CLASS TDebugger
|
||||
DATA oBrwPnt, oWndPnt
|
||||
DATA lppo INIT .F. //view preprocessed output
|
||||
DATA lRunAtStartup
|
||||
DATA lLineNumbers INIT .T.
|
||||
|
||||
METHOD New()
|
||||
METHOD Activate()
|
||||
@@ -470,7 +471,10 @@ METHOD New() CLASS TDebugger
|
||||
// default the search path for files to the current directory
|
||||
// that way if the source is in the same directory it will still be found even if the application
|
||||
// changes the current directory with the SET DEFAULT command
|
||||
::cPathForFiles := getenv( "PATH" )
|
||||
::cPathForFiles := getenv( "HB_DBG_PATH" )
|
||||
if empty( ::cPathForFiles )
|
||||
::cPathForFiles := getenv( "PATH" )
|
||||
endif
|
||||
::nTabWidth := 4
|
||||
::nSpeed := 0
|
||||
::lShowCallStack := .f.
|
||||
@@ -506,14 +510,6 @@ METHOD New() CLASS TDebugger
|
||||
|
||||
return Self
|
||||
|
||||
METHOD PathForFiles() CLASS TDebugger
|
||||
|
||||
::cPathForFiles := ::InputBox( "Search path for source files:", ::cPathForFiles )
|
||||
IF ! RIGHT(::cPathForFiles,1) $ HB_OSPATHDELIMITERS()
|
||||
::cPathForFiles:=::cPathForFiles + HB_OSPATHSEPARATOR()
|
||||
ENDIF
|
||||
|
||||
return Self
|
||||
|
||||
METHOD Activate() CLASS TDebugger
|
||||
|
||||
@@ -1273,6 +1269,20 @@ METHOD NextWindow() CLASS TDebugger
|
||||
|
||||
return nil
|
||||
|
||||
|
||||
METHOD PathForFiles( cPathForFiles ) CLASS TDebugger
|
||||
|
||||
IF cPathForFiles == NIL
|
||||
cPathForFiles := ::InputBox( "Search path for source files:", ::cPathForFiles )
|
||||
ENDIF
|
||||
IF ! RIGHT(cPathForFiles, 1) $ HB_OSPATHDELIMITERS()
|
||||
cPathForFiles += HB_OSPATHSEPARATOR()
|
||||
ENDIF
|
||||
::cPathForFiles := cPathForFiles
|
||||
|
||||
RETURN Self
|
||||
|
||||
|
||||
METHOD PrevWindow() CLASS TDebugger
|
||||
|
||||
local oWnd
|
||||
@@ -1685,19 +1695,20 @@ return { | a | a[ 1 ] == Self:oBrwText:nRow } // it was nLine
|
||||
METHOD StackProc( cModuleName, nProcLevel ) CLASS TDebugger
|
||||
// always treat filename as lower case - we need it consistent for comparisons
|
||||
LOCAL nPos:=RAT( ":", cModuleName )
|
||||
LOCAL aEntry := { ;
|
||||
IIF(::lCodeBlock,"(b)","")+SubStr( cModuleName, nPos + 1 ),; //function name
|
||||
{},; //local vars
|
||||
nil,; //line no, nil means that no line number is stored yet
|
||||
lower( strip_path( LEFT( cModuleName, nPos - 1 ) ) ),; // and the module name
|
||||
{}, ; // static vars
|
||||
nProcLevel }
|
||||
|
||||
ASize( ::aCallStack, Len( ::aCallStack ) + 1 )
|
||||
AIns( ::aCallStack, 1 )
|
||||
|
||||
// nil means that no line number is stored yet
|
||||
::aCallStack[1]:= { IIF(::lCodeBlock,"(b)","")+SubStr( cModuleName, nPos + 1 ),; //function name
|
||||
{},; //local vars
|
||||
nil,; //line no
|
||||
lower(LEFT( cModuleName, nPos - 1 )),; // and the module name
|
||||
{},; // static vars
|
||||
nProcLevel }
|
||||
::aCallStack[ 1 ] := aEntry
|
||||
return nil
|
||||
|
||||
|
||||
//METHOD ShowCodeLine( nLine, cPrgName ) CLASS TDebugger
|
||||
METHOD ShowCodeLine( nProc ) CLASS TDebugger
|
||||
LOCAL nPos, nLevel
|
||||
@@ -1730,36 +1741,56 @@ LOCAL nLine, cPrgName
|
||||
cPrgName += cPrgName +".ppo"
|
||||
ENDIF
|
||||
endif
|
||||
if( cPrgName != ::cPrgName .OR. ::oBrwText == NIL )
|
||||
if ! File( cPrgName ) .and. ! Empty( ::cPathForFiles )
|
||||
cPrgName := ::LocatePrgPath( cPrgName )
|
||||
|
||||
if ! empty( cPrgName )
|
||||
|
||||
if ( strip_path( cPrgName ) != strip_path( ::cPrgName ) .OR. ::oBrwText == NIL )
|
||||
|
||||
if ! File( cPrgName ) .and. !Empty( ::cPathForFiles )
|
||||
cPrgName := ::LocatePrgPath( cPrgName )
|
||||
endif
|
||||
|
||||
::cPrgName := cPrgName
|
||||
|
||||
if ::oBrwText == nil
|
||||
::oBrwText := TBrwText():New( ::oWndCode:nTop + 1, ::oWndCode:nLeft + 1,;
|
||||
::oWndCode:nBottom - 1, ::oWndCode:nRight - 1, cPrgName,;
|
||||
__DbgColors()[ 2 ] + "," + __DbgColors()[ 5 ] + "," + ;
|
||||
__DbgColors()[ 3 ] + "," + __DbgColors()[ 6 ], ;
|
||||
::lLineNumbers )
|
||||
|
||||
::oWndCode:Browser := ::oBrwText
|
||||
|
||||
else
|
||||
::oBrwText:LoadFile(cPrgName)
|
||||
endif
|
||||
|
||||
::oWndCode:bPainted := {|| IIF( ::oBrwText != nil, ::oBrwText:RefreshAll():ForceStable(), ::oWndCode:Clear() ) }
|
||||
::RedisplayBreakpoints() // check for breakpoints in this file and display them
|
||||
::oWndCode:SetCaption( ::cPrgName )
|
||||
::oWndCode:Refresh() // to force the window caption to update
|
||||
endif
|
||||
::cPrgName := cPrgName
|
||||
::oBrwText := nil
|
||||
::oBrwText := TBrwText():New( ::oWndCode:nTop + 1, ::oWndCode:nLeft + 1,;
|
||||
::oWndCode:nBottom - 1, ::oWndCode:nRight - 1, cPrgName,;
|
||||
__DbgColors()[ 2 ] + "," + __DbgColors()[ 5 ] + "," + ;
|
||||
__DbgColors()[ 3 ] + "," + __DbgColors()[ 6 ] )
|
||||
|
||||
::oWndCode:Browser := ::oBrwText
|
||||
::oWndCode:bPainted :={|| IIF(::oBrwText!=nil,::oBrwText:refreshAll():forceStable(),::oWndCode:Clear()) }
|
||||
::RedisplayBreakpoints() // check for breakpoints in this file and display them
|
||||
::oWndCode:SetCaption( ::cPrgName )
|
||||
::oWndCode:Refresh() // to force the window caption to update
|
||||
::oBrwText:SetActiveLine( nLine )
|
||||
::GotoLine( nLine )
|
||||
endif
|
||||
::GoToLine( nLine )
|
||||
endif
|
||||
|
||||
return nil
|
||||
|
||||
METHOD Open() CLASS TDebugger
|
||||
LOCAL cFileName := ::InputBox( "Please enter the filename", Space( 255 ) )
|
||||
LOCAL cPrgName
|
||||
|
||||
cFileName:= ALLTRIM( cFileName )
|
||||
if !EMPTY(cFileName) .AND. (cFileName != ::cPrgName .OR. valtype(::cPrgName)=='U')
|
||||
METHOD Open() CLASS TDebugger
|
||||
LOCAL cFileName := ::InputBox( "Please enter the filename", Space( 255 ) )
|
||||
LOCAL cPrgName
|
||||
|
||||
cFileName:= ALLTRIM( cFileName )
|
||||
|
||||
if !EMPTY(cFileName) .AND. (cFileName != ::cPrgName .OR. valtype(::cPrgName)=='U')
|
||||
if ! File( cFileName ) .and. ! Empty( ::cPathForFiles )
|
||||
cFileName := ::LocatePrgPath( cFileName )
|
||||
cFileName := ::LocatePrgPath( cFileName )
|
||||
if Empty( cFileName )
|
||||
Alert( "File not found!" )
|
||||
return NIL
|
||||
endif
|
||||
endif
|
||||
::cPrgName := cFileName
|
||||
::lppo := RAT(".PPO", UPPER(cFileName)) > 0
|
||||
@@ -1768,15 +1799,16 @@ LOCAL cPrgName
|
||||
::oBrwText := TBrwText():New( ::oWndCode:nTop + 1, ::oWndCode:nLeft + 1,;
|
||||
::oWndCode:nBottom - 1, ::oWndCode:nRight - 1, cFileName,;
|
||||
__DbgColors()[ 2 ] + "," + __DbgColors()[ 5 ] + "," + ;
|
||||
__DbgColors()[ 3 ] + "," + __DbgColors()[ 6 ] )
|
||||
__DbgColors()[ 3 ] + "," + __DbgColors()[ 6 ], ;
|
||||
::lLineNumbers )
|
||||
::oWndCode:Browser := ::oBrwText
|
||||
::RedisplayBreakpoints() // check for breakpoints in this file and display them
|
||||
::oWndCode:SetCaption( ::cPrgName )
|
||||
::oWndCode:Refresh() // to force the window caption to update
|
||||
::oWndCode:Refresh() // to force the window caption to update
|
||||
endif
|
||||
|
||||
return nil
|
||||
|
||||
|
||||
METHOD OpenPPO() CLASS TDebugger
|
||||
LOCAL nPos
|
||||
LOCAL lSuccess:=.F.
|
||||
@@ -1816,7 +1848,7 @@ METHOD RedisplayBreakPoints() CLASS TDebugger
|
||||
|
||||
local n
|
||||
for n := 1 to Len( ::aBreakpoints )
|
||||
if ::aBreakpoints[ n ] [ 2 ] == ::cPrgName
|
||||
if ::aBreakpoints[ n ] [ 2 ] == strip_path( ::cPrgName )
|
||||
::oBrwText:ToggleBreakPoint(::aBreakpoints[ n ] [ 1 ], .T.)
|
||||
Endif
|
||||
next
|
||||
@@ -2214,36 +2246,44 @@ METHOD Static() CLASS TDebugger
|
||||
|
||||
return nil
|
||||
|
||||
|
||||
// Toggle a breakpoint at the cursor position in the currently viewed file
|
||||
// which may be different from the file in which execution was broken
|
||||
METHOD ToggleBreakPoint() CLASS TDebugger
|
||||
// look for a breakpoint which matches both line number and program name
|
||||
local nAt
|
||||
LOCAL cLine
|
||||
|
||||
cLine := ::oBrwText:GetLine( ::oBrwText:nRow )
|
||||
IF( ::oBrwText:lLineNumbers )
|
||||
cLine := SUBSTR( cLine, AT(":",cLine)+1 )
|
||||
ENDIF
|
||||
IF( IsValidStopLine( cLine ) )
|
||||
nAt := AScan( ::aBreakPoints, { | aBreak | aBreak[ 1 ] == ;
|
||||
::oBrwText:nRow ;
|
||||
.AND. aBreak [ 2 ] == ::cPrgName} ) // it was nLine
|
||||
// look for a breakpoint which matches both line number and program name
|
||||
local nAt
|
||||
LOCAL cLine
|
||||
local cFileName
|
||||
|
||||
if nAt == 0
|
||||
AAdd( ::aBreakPoints, { ::oBrwText:nRow, ::cPrgName } ) // it was nLine
|
||||
::oBrwText:ToggleBreakPoint(::oBrwText:nRow, .T.)
|
||||
else
|
||||
ADel( ::aBreakPoints, nAt )
|
||||
ASize( ::aBreakPoints, Len( ::aBreakPoints ) - 1 )
|
||||
::oBrwText:ToggleBreakPoint(::oBrwText:nRow, .F.)
|
||||
endif
|
||||
IF !::lActive
|
||||
RETURN NIL
|
||||
ENDIF
|
||||
|
||||
::oBrwText:RefreshCurrent()
|
||||
ENDIF
|
||||
cLine := ::oBrwText:GetLine( ::oBrwText:nRow )
|
||||
IF ::oBrwText:lLineNumbers
|
||||
cLine := SUBSTR( cLine, AT(":",cLine)+1 )
|
||||
ENDIF
|
||||
IF IsValidStopLine( cLine )
|
||||
cFileName := strip_path( ::cPrgName )
|
||||
|
||||
nAt := AScan( ::aBreakPoints, { | aBreak | aBreak[ 1 ] == ::oBrwText:nRow ;
|
||||
.AND. aBreak[ 2 ] == cFileName } ) // it was nLine
|
||||
|
||||
if nAt == 0
|
||||
AAdd( ::aBreakPoints, { ::oBrwText:nRow, cFileName } ) // it was nLine
|
||||
::oBrwText:ToggleBreakPoint(::oBrwText:nRow, .T.)
|
||||
else
|
||||
ADel( ::aBreakPoints, nAt )
|
||||
ASize( ::aBreakPoints, Len( ::aBreakPoints ) - 1 )
|
||||
::oBrwText:ToggleBreakPoint(::oBrwText:nRow, .F.)
|
||||
endif
|
||||
|
||||
::oBrwText:RefreshCurrent()
|
||||
ENDIF
|
||||
|
||||
return nil
|
||||
|
||||
|
||||
METHOD ViewSets() CLASS TDebugger
|
||||
|
||||
local oWndSets := TDbWindow():New( 1, 8, MaxRow() - 2, MaxCol() - 8,;
|
||||
@@ -2519,7 +2559,7 @@ LOCAL cLine
|
||||
cLine := SUBSTR( cLine, AT(":",cLine)+1 )
|
||||
ENDIF
|
||||
IF( IsValidStopLine( cLine ) )
|
||||
::aToCursor := { ::oBrwText:nRow, ::cPrgName }
|
||||
::aToCursor := { ::oBrwText:nRow, strip_path( ::cPrgName ) }
|
||||
::RestoreAppStatus()
|
||||
::lToCursor := .t.
|
||||
::Exit()
|
||||
@@ -3162,8 +3202,11 @@ static function PathToArray( cList )
|
||||
local nPos
|
||||
local aList := {}
|
||||
local cSep
|
||||
local cDirSep
|
||||
|
||||
cSep := HB_OsPathListSeparator()
|
||||
cDirSep := HB_OsPathDelimiters()
|
||||
|
||||
if ( cList <> NIL )
|
||||
|
||||
do while ( nPos := at( cSep, cList ) ) <> 0
|
||||
@@ -3173,6 +3216,19 @@ static function PathToArray( cList )
|
||||
|
||||
aadd( aList, cList ) // Add final element
|
||||
|
||||
/* Strip ending delimiters */
|
||||
AEval(aList, {|x, i| if( Right( x, 1 ) $ cDirSep, aList[ i ] := Left( x, Len( x ) - 1 ), ) } )
|
||||
endif
|
||||
|
||||
return aList
|
||||
return aList
|
||||
|
||||
|
||||
/* Strip path from filename */
|
||||
STATIC FUNCTION strip_path( cFileName )
|
||||
LOCAL cName := "", cExt := ""
|
||||
DEFAULT cFileName TO ""
|
||||
|
||||
HB_FNAMESPLIT( cFileName, NIL, @cName, @cExt )
|
||||
RETURN cName + cExt
|
||||
|
||||
|
||||
|
||||
@@ -58,15 +58,15 @@
|
||||
|
||||
// Color definitions and positions inside ::cColorSpec
|
||||
#define CLR_CODE 0 // color of code
|
||||
#define CLR_CURSOR 1 // color of hilighted line
|
||||
#define CLR_CURSOR 1 // color of highlighted line (the line to be executed)
|
||||
#define CLR_BKPT 2 // color of breakpoint line
|
||||
#define CLR_HIBKPT 3 // color of hilighted breakpoint line
|
||||
#define CLR_HIBKPT 3 // color of highlighted breakpoint line
|
||||
|
||||
|
||||
CLASS TBrwText FROM HBEditor
|
||||
|
||||
DATA cFileName // the name of the browsed file
|
||||
DATA nActiveLine // Active line inside Code Window (last executed one)
|
||||
DATA nActiveLine // Active line inside Code Window (the line to be executed)
|
||||
|
||||
DATA aBreakPoints // Array with line numbers of active Break Points
|
||||
|
||||
@@ -89,7 +89,8 @@ CLASS TBrwText FROM HBEditor
|
||||
METHOD RefreshCurrent()
|
||||
METHOD ForceStable() INLINE NIL
|
||||
|
||||
METHOD GotoLine(n) // Moves active line cursor, that is it hilights last executed line of code
|
||||
METHOD GotoLine(n) // Moves active line cursor
|
||||
METHOD SetActiveLine( n ) // Sets the line to be executed
|
||||
|
||||
METHOD GetLine(nRow) // Redefine HBEditor method to add line number
|
||||
METHOD LineColor(nRow) // Redefine HBEditor method to handle line coloring
|
||||
@@ -98,19 +99,22 @@ CLASS TBrwText FROM HBEditor
|
||||
// if lSet is .F. BreakPoint at nRow has to be removed
|
||||
METHOD Search( cString, lCaseSensitive, nMode ) // 0 from Begining to end, 1 Forward, 2 Backwards
|
||||
|
||||
METHOD LoadFile(cFileName)
|
||||
|
||||
ENDCLASS
|
||||
|
||||
|
||||
METHOD New(nTop, nLeft, nBottom, nRight, cFileName, cColor) CLASS TBrwText
|
||||
METHOD New(nTop, nLeft, nBottom, nRight, cFileName, cColor, lLineNumbers) CLASS TBrwText
|
||||
|
||||
DEFAULT cColor TO SetColor()
|
||||
DEFAULT lLineNumbers TO .T.
|
||||
|
||||
::cFileName := cFileName
|
||||
::nActiveLine := 1
|
||||
|
||||
::aBreakPoints := {}
|
||||
|
||||
::lLineNumbers := .T.
|
||||
::lLineNumbers := lLineNumbers
|
||||
|
||||
Super:New("", nTop, nLeft, nBottom, nRight, .T.)
|
||||
Super:SetColor(cColor)
|
||||
@@ -120,6 +124,13 @@ METHOD New(nTop, nLeft, nBottom, nRight, cFileName, cColor) CLASS TBrwText
|
||||
return Self
|
||||
|
||||
|
||||
METHOD LoadFile(cFileName) CLASS TBrwText
|
||||
|
||||
Super:LoadFile(cFileName)
|
||||
|
||||
return Self
|
||||
|
||||
|
||||
METHOD GoTop() CLASS TBrwText
|
||||
::MoveCursor(K_CTRL_PGUP)
|
||||
return Self
|
||||
@@ -170,17 +181,15 @@ METHOD RefreshCurrent() CLASS TBrwText
|
||||
return Self
|
||||
|
||||
|
||||
METHOD SetActiveLine( n ) CLASS TBrwText
|
||||
::nActiveLine := n
|
||||
::RefreshWindow()
|
||||
return Self
|
||||
|
||||
|
||||
METHOD GotoLine(n) CLASS TBrwText
|
||||
|
||||
// We need to set active line before calling ::RefreshLine() since ::LineColor()
|
||||
// uses nActiveLine to decide which color to use to paint line
|
||||
::nActiveLine := n
|
||||
::RefreshLine()
|
||||
|
||||
Super:GotoLine(n)
|
||||
// I need to call ::RefreshLine() here because HBEditor does not repaint current line
|
||||
// if it needs not to and without this explicit call I don't see ActiveLine cursor movement
|
||||
::RefreshLine()
|
||||
|
||||
return Self
|
||||
|
||||
@@ -192,24 +201,19 @@ return iif(::lLineNumbers, AllTrim(Str(nRow)) + ": ", "") + Super:GetLine(nRow)
|
||||
|
||||
METHOD LineColor(nRow) CLASS TBrwText
|
||||
|
||||
local cColor, lHilited, lBreak
|
||||
local cColor, lHilited, lBreak, nIndex := CLR_CODE
|
||||
|
||||
lHilited := (nRow == ::nActiveLine)
|
||||
lBreak := AScan(::aBreakPoints, nRow) > 0
|
||||
|
||||
if lHilited .AND. lBreak
|
||||
cColor := hb_ColorIndex(::cColorSpec, CLR_HIBKPT)
|
||||
|
||||
elseif lHilited
|
||||
cColor := hb_ColorIndex(::cColorSpec, CLR_CURSOR)
|
||||
|
||||
elseif lBreak
|
||||
cColor := hb_ColorIndex(::cColorSpec, CLR_BKPT)
|
||||
|
||||
else
|
||||
cColor := hb_ColorIndex(::cColorSpec, CLR_CODE)
|
||||
|
||||
if lHilited
|
||||
nIndex += CLR_CURSOR
|
||||
endif
|
||||
if lBreak
|
||||
nIndex += CLR_BKPT
|
||||
endif
|
||||
|
||||
cColor := hb_ColorIndex(::cColorSpec, nIndex)
|
||||
|
||||
return cColor
|
||||
|
||||
|
||||
Reference in New Issue
Block a user