home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 16
/
CD_ASCQ_16_0994.iso
/
news
/
4611
/
fw16d.ins
/
SOURCE
/
CLASSES
/
WBROWSE.PRG
< prev
next >
Wrap
Text File
|
1994-06-10
|
27KB
|
1,027 lines
#include "FiveWin.ch"
#include "InKey.ch"
#include "Set.ch"
#include "Constant.ch"
#define GW_HWNDFIRST 0
#define GW_HWNDLAST 1
#define GW_HWNDNEXT 2
#define HWND_BROADCAST 65535 // 0xFFFF
#define CS_DBLCLKS 8
#define COLOR_ACTIVECAPTION 2
#define COLOR_CAPTIONTEXT 9
#define WM_SETFONT 48 // 0x30
extern DBSKIP
static lRegistered := .f.
//----------------------------------------------------------------------------//
CLASS TWBrowse FROM TControl
DATA cAlias, cField, uValue1, uValue2
DATA bLine, bSkip, bGoTop, bGoBottom, bLogicLen, bChange, bAdd
DATA nRowPos, nColPos, nLen, nAt
DATA lHitTop, lHitBottom
DATA oVScroll, oHScroll
DATA aHeaders, aColSizes
DATA nClrBackHead, nClrForeHead
DATA nClrBackFocus, nClrForeFocus
METHOD New( nRow, nCol, nWidth, nHeigth, bLine, aHeaders, ;
aColSizes, oWnd, cField, uVal1, uVal2, bChange,;
bLDblClick, bRClick, oFont, oCursor, nClrFore,;
nForeBack, cMsg, lUpdate ) CONSTRUCTOR
METHOD ReDefine( nId, bLine, oDlg, aHeaders, aColSizes, cField, uVal1,;
uVal2, bChange, bLDblClick, bRClick, oFont,;
oCursor, nClrFore, nClrBack, cMsg, lUpdate ) CONSTRUCTOR
METHOD SetArray( aArray )
METHOD lCloseArea() INLINE ;
If( ! Empty( ::cAlias ), ( ::cAlias )->( DbCloseArea() ),),;
If( ! Empty( ::cAlias ), ::cAlias := "",), .t.
METHOD Default()
METHOD EditCol( nCol, uVar, cPicture, bValid, nClrFore, nClrBack )
METHOD GetDlgCode() INLINE nOR( DLGC_WANTARROWS, DLGC_WANTCHARS )
METHOD GoUp()
METHOD GoDown()
METHOD GoLeft()
METHOD GoRight()
METHOD GoTop()
METHOD GoBottom()
METHOD HandleEvent( nMsg, nWParam, nLParam )
METHOD HScroll( nWParam, nLParam )
METHOD Init( hDlg ) INLINE Super:Init( hDlg ), ::Default()
METHOD PageUp( nLines )
METHOD PageDown( nLines )
METHOD KeyDown( nKey )
METHOD KeyChar( nKey, nFlags )
METHOD LButtonDown( nRow, nCol, nKeyFlags )
METHOD MouseMove( nRow, nCol, nKeyFlags )
METHOD Paint()
METHOD VScroll( nWParam, nLParam )
METHOD Skip( n )
METHOD DrawLine( nRow ) INLINE ;
wBrwLine( ::hWnd, ::hDC, If( nRow == nil, ::nRowPos, nRow ), ;
Eval( ::bLine ), ::GetColSizes(), ::nColPos,;
::nClrText, ::nClrPane,;
If( ::oFont != nil, ::oFont:hFont, 0 ),;
ValType( ::aColSizes ) == "B" )
METHOD DrawSelect() INLINE ;
wBrwLine( ::hWnd, ::hDC, ::nRowPos, Eval( ::bLine ),;
::GetColSizes(), ::nColPos, ::nClrForeFocus,;
If( ::lFocused, ::nClrBackFocus, CLR_GRAY ),;
If( ::oFont != nil, ::oFont:hFont, 0 ),;
ValType( ::aColSizes ) == "B" )
METHOD RecAdd() INLINE If( ::bAdd != nil, Eval( ::bAdd ),)
METHOD SetFilter( cField, uVal1, uVal2 )
METHOD GotFocus() INLINE Super:GotFocus(),;
If( ::nLen > 0 .and. ! Empty( ::cAlias ), ::DrawSelect(),)
MESSAGE RecCount METHOD _RecCount( uSeekValue )
METHOD UpStable() // Thanks to Javier Alcazar
// Corrects the same page skipping bug!
METHOD nRowCount() INLINE ;
nWRows( ::hWnd, 0, If( ::oFont != nil, ::oFont:hFont, 0 ) ) - 1
METHOD GetColSizes() INLINE ;
If( ValType( ::aColSizes ) == "A", ::aColSizes, Eval( ::aColSizes ) )
METHOD LostFocus() INLINE Super:LostFocus(),;
If( ::nLen > 0 .and. ! Empty( ::cAlias ), ::DrawSelect(),)
ENDCLASS
//----------------------------------------------------------------------------//
METHOD New( nRow, nCol, nWidth, nHeigth, bLine, aHeaders, aColSizes, oWnd,;
cField, uVal1, uVal2, bChange, bLDblClick, bRClick,;
oFont, oCursor, nClrFore, nClrBack, cMsg, lUpdate ) CLASS TWBrowse
DEFAULT nRow := 0, nCol := 0, nHeigth := 100, nWidth := 100,;
oWnd := GetWndDefault(), nClrFore := CLR_BLACK,;
nClrBack := CLR_LIGHTGRAY,;
lUpdate := .f.
::cCaption = ""
::nTop = nRow * BRSE_CHARPIX_H // 14
::nLeft = nCol * BRSE_CHARPIX_W //8
::nBottom = ::nTop + nHeigth - 1
::nRight = ::nLeft + nWidth - 1
::oWnd = oWnd
::lHitTop = .f.
::lHitBottom = .f.
::lFocused = .f.
::nRowPos = 1
::nColPos = 1
::nStyle = nOr( WS_CHILD, WS_VSCROLL, WS_HSCROLL,;
WS_BORDER, WS_VISIBLE, WS_TABSTOP )
::nId = ::GetNewId()
::cAlias = Alias()
::bLine = bLine
::SetFilter( cField, uVal1, uVal2 )
::bAdd = { || ( ::cAlias )->( DbAppend() ), ::UpStable() }
::aHeaders = aHeaders
::aColSizes = aColSizes
::nLen = 0
::lDrag = .f.
::lCaptured = .f.
::bChange = bChange
::bLDblClick = bLDblClick
::bRClicked = bRClick
::oCursor = oCursor
::oFont = oFont
::nClrBackHead = GetSysColor( COLOR_ACTIVECAPTION )
::nClrForeHead = GetSysColor( COLOR_CAPTIONTEXT )
::nClrBackFocus = CLR_CYAN
::nClrForeFocus = CLR_WHITE
::cMsg = cMsg
::lUpdate = lUpdate
::SetColor( nClrFore, nClrBack )
if ! lRegistered
::Register( nOr( CS_VREDRAW, CS_HREDRAW, CS_GLOBALCLASS, CS_DBLCLKS ) )
lRegistered = .t.
endif
if oWnd:lVisible
::Create()
::Default()
::lVisible = .t.
else
oWnd:DefControl( Self )
::lVisible = .f.
endif
if uVal1 != nil
Eval( ::bGoTop )
endif
return nil
//----------------------------------------------------------------------------//
METHOD ReDefine( nId, bLine, oDlg, aHeaders, aColSizes, cField, uVal1, uVal2,;
bChange, bLDblClick, bRClick, oFont, oCursor,;
nClrFore, nClrBack, cMsg, lUpdate ) CLASS TWBrowse
DEFAULT oDlg := GetWndDefault(), nClrFore := CLR_BLACK,;
nClrBack := CLR_LIGHTGRAY, lUpdate := .f.
::lHitTop = .f.
::lHitBottom = .f.
::lFocused = .f.
::nId = nId
::nRowPos = 1
::nColPos = 1
::cAlias = Alias()
::oWnd = oDlg
::aHeaders = aHeaders
::aColSizes = aColSizes
::nClrPane = CLR_LIGHTGRAY
::nClrText = CLR_WHITE
::nLen = 0
::lDrag = .f.
::lCaptured = .f.
::lVisible = .f.
::bLine = bLine
::bChange = bChange
::bLDblClick = bLDblClick
::bRClicked = bRClick
::oCursor = oCursor
::oFont = oFont
::nClrBackHead = GetSysColor( COLOR_ACTIVECAPTION )
::nClrForeHead = GetSysColor( COLOR_CAPTIONTEXT )
::nClrBackFocus = CLR_CYAN
::nClrForeFocus = CLR_WHITE
::cMsg = cMsg
::lUpdate = lUpdate
::SetColor( nClrFore, nClrBack )
::SetFilter( cField, uVal1, uVal2 )
::bAdd = { || ( ::cAlias )->( DbAppend() ), ::UpStable() }
if ! lRegistered
::Register( nOr( CS_VREDRAW, CS_HREDRAW, CS_GLOBALCLASS, CS_DBLCLKS ) )
lRegistered = .t.
endif
oDlg:DefControl( Self )
if uVal1 != nil
Eval( ::bGoTop )
endif
return nil
//----------------------------------------------------------------------------//
METHOD SetArray( aArray ) CLASS TWBrowse
::nAt = 1
::cAlias = "ARRAY"
::bLogicLen = { || Len( aArray ) }
::bGoTop = { || ::nAt := 1 }
::bGoBottom = { || ::nAt := Eval( ::bLogicLen ) }
::bSkip = { | nSkip, nOld | nOld := ::nAt, ::nAt += nSkip,;
::nAt := Min( Max( ::nAt, 1 ), Eval( ::bLogicLen ) ),;
::nAt - nOld }
return nil
//----------------------------------------------------------------------------//
METHOD Paint() CLASS TWBrowse
wBrwLine( ::hWnd, ::hDC, 0, ::aHeaders, ::GetColSizes(),;
::nColPos, ::nClrForeHead, ::nClrBackHead,;
If( ::oFont != nil, ::oFont:hFont, 0 ) )
if ::nLen > 0
::Skip( 1 - ::nRowPos )
// WBrwPane() returns the Nº of visible rows
// WBrwPane recieves at aColSizes the Array or a Block
// to get dinamically the Sizes !!!
::Skip( ::nRowPos - WBrwPane( ::hWnd, ::hDC, Self, ::bLine,;
::aColSizes, ::nColPos, ::nClrText, ::nClrPane,;
If( ::oFont != nil, ::oFont:hFont, 0 ) ) )
::DrawSelect()
endif
::lHitTop = .f.
::lHitBottom = .f.
return 0
//----------------------------------------------------------------------------//
METHOD EditCol( nCol, uVar, cPicture, bValid, nClrFore, nClrBack ) CLASS TWBrowse
local oDlg
local aDim := aBrwPosRect( ::hWnd, ::nRowPos, ::aColSizes, ::nColPos, nCol,;
If( ::oFont != nil, ::oFont:hFont, 0 ) )
DEFINE DIALOG oDlg FROM aDim[ 1 ], aDim[ 2 ] TO aDim[ 3 ], aDim[ 4 ] ;
STYLE nOR( WS_VISIBLE, WS_POPUP, WS_BORDER ) PIXEL
ACTIVATE DIALOG oDlg
return nil
//----------------------------------------------------------------------------//
METHOD GoUp() CLASS TWBrowse
local nSkipped
local nLines := ::nRowCount()
if ::nLen < 1
return nil
endif
if ! ::lHitTop
::DrawLine()
if ::Skip( -1 ) == -1
::lHitBottom = .f.
if ::nRowPos > 1
::nRowPos--
else
WBrwScroll( ::hWnd, -1, If( ::oFont != nil, ::oFont:hFont, 0 ) )
endif
else
::lHitTop = .t.
endif
::DrawSelect()
::oVScroll:GoUp()
if ::bChange != nil
Eval( ::bChange )
endif
endif
return nil
//----------------------------------------------------------------------------//
METHOD GoDown() CLASS TWBrowse
local nSkipped
local nLines := ::nRowCount()
if ::nLen < 1
return nil
endif
if ! ::lHitBottom
::DrawLine()
if ::Skip( 1 ) == 1
::lHitTop = .f.
if ::nRowPos < nLines
::nRowPos++
else
WBrwScroll( ::hWnd, 1, If( ::oFont != nil, ::oFont:hFont, 0 ) )
endif
else
::lHitBottom = .t.
endif
::DrawSelect()
::oVScroll:GoDown()
if ::bChange != nil
Eval( ::bChange )
endif
endif
return nil
//---------------------------------------------------------------------------//
METHOD GoLeft() CLASS TWBrowse
if ::nColPos > 1
::nColPos--
::Refresh( .f. )
::oHScroll:GoUp()
endif
return nil
//---------------------------------------------------------------------------//
METHOD GoRight() CLASS TWBrowse
if ::nColPos < Len( ::GetColSizes() )
::nColPos++
::Refresh( .f. )
::oHScroll:GoDown()
endif
return nil
//----------------------------------------------------------------------------//
METHOD GoTop() CLASS TWBrowse
if ::nLen < 1
return nil
endif
if ! ::lHitTop
Eval( ::bGoTop )
::lHitTop = .t.
::lHitBottom = .f.
::nRowPos = 1
::Refresh( .f. )
::oVScroll:GoTop()
if ::bChange != nil
Eval( ::bChange )
endif
endif
return nil
//----------------------------------------------------------------------------//
METHOD GoBottom() CLASS TWBrowse
local nSkipped
local nLines := ::nRowCount()
local n
if ::nLen < 1
return nil
endif
if ! ::lHitBottom
::lHitBottom = .t.
::lHitTop = .f.
Eval( ::bGoBottom )
nSkipped = ::Skip( -( nLines - 1 ) )
::nRowPos = 1 - nSkipped
::GetDC()
for n = 1 to -nSkipped
::DrawLine( n )
::Skip( 1 )
next
::DrawSelect()
::ReleaseDC()
::oVScroll:GoBottom()
if ::bChange != nil
Eval( ::bChange )
endif
endif
return nil
//----------------------------------------------------------------------------//
METHOD LButtonDown( nRow, nCol, nKeyFlags ) CLASS TWBrowse
local nClickRow, nSkipped
if ::nLen < 1
return nil
endif
::SetFocus()
nClickRow = nWRow( ::hWnd, ::hDC, nRow,;
If( ::oFont != nil, ::oFont:hFont, 0 ) )
if nClickRow > 0 .and. nClickRow != ::nRowPos .and. ;
nClickRow < ::nRowCount() + 1
::DrawLine()
nSkipped = ::Skip( nClickRow - ::nRowPos )
::nRowPos += nSkipped
::oVScroll:SetPos( ::oVScroll:GetPos() + nSkipped )
::DrawSelect()
::lHitTop = .f.
::lHitBottom = .f.
if ::bChange != nil
Eval( ::bChange )
endif
endif
return 0
//----------------------------------------------------------------------------//
METHOD HandleEvent( nMsg, nWParam, nLParam ) CLASS TWBrowse
do case
case nMsg == WM_KEYDOWN
return ::KeyDown( nWParam )
case nMsg == WM_LBUTTONDOWN
return ::LButtonDown( nHiWord( nLParam ), nLoWord( nLParam ), nWParam )
case nMsg == WM_PAINT
::BeginPaint()
if ::oVScroll != nil // They generate WM_PAINT msgs when range 0
::oVScroll:SetRange( 1, ::nLen := Eval( ::bLogicLen ) )
endif // so here we avoid 'flicking'
if ::oHScroll != nil
::oHScroll:SetRange( 1, Len( ::GetColSizes() ) )
endif
::Paint()
::EndPaint()
return 0
case nMsg == WM_VSCROLL
return ::VScroll( nWParam, nLParam )
case nMsg == WM_HSCROLL
return ::HScroll( nWParam, nLParam )
case nMsg == FW_CLOSEAREA
if ! Empty( ::cAlias )
( ::cAlias )->( DbCloseArea() )
::cAlias = ""
return 0
endif
endcase
return Super:HandleEvent( nMsg, nWParam, nLParam )
//----------------------------------------------------------------------------//
METHOD Default() CLASS TWBrowse
local n, aFields
local cAlias := Alias()
local nElements
DEFAULT ::aHeaders := {}, ::aColSizes := {}
if ::bLine == nil
::bLine = { || _aFields( cAlias ) }
endif
nElements = Len( Eval( ::bLine ) )
if Len( ::aHeaders ) < nElements // == nil
::aHeaders = Array( nElements )
for n = 1 to nElements
::aHeaders[ n ] = ( cAlias )->( Field( n ) )
next
endif
if Len( ::GetColSizes() ) < nElements
aFields = Eval( ::bLine )
::aColSizes = Array( nElements )
for n = 1 to nElements
::aColSizes[ n ] := GetTextWidth( 0, Replicate( "B", ;
Max( Len( ::aHeaders[ n ] ), ;
Len( aFields[ n ] ) ) + 1 ) )
next
endif
DEFINE SCROLLBAR ::oVScroll VERTICAL OF Self ;
RANGE 1, Eval( ::bLogicLen )
DEFINE SCROLLBAR ::oHScroll HORIZONTAL OF Self ;
RANGE 1, Len( ::GetColSizes() )
if ::oFont == nil
::oFont = ::oWnd:oFont
endif
return nil
//----------------------------------------------------------------------------//
function _aFields( cAlias )
local aFld := Array( ( cAlias )->( FCount() ) )
local n, uVal
for n = 1 to Len( aFld )
uVal = ( cAlias )->( FieldGet( n ) )
if ValType( uVal ) == "N"
uVal = Str( uVal )
aFld[ n ] = xPadL( uVal,;
GetTextWidth( 0, Replicate( "B", Len( uVal ) ) ) )
else
aFld[ n ] = cValToChar( uVal )
endif
next
return aFld
//---------------------------------------------------------------------------//
METHOD KeyDown( nKey ) CLASS TWBrowse
do case
case nKey == VK_UP
::GoUp()
case nKey == VK_DOWN
::GoDown()
case nKey == VK_LEFT
::GoLeft()
case nKey == VK_RIGHT
::GoRight()
case nKey == VK_HOME
::GoTop()
case nKey == VK_END
::GoBottom()
case nKey == VK_PRIOR
::PageUp()
case nKey == VK_NEXT
::PageDown()
otherwise
Super:KeyDown( nKey )
endcase
return 0
//----------------------------------------------------------------------------//
METHOD KeyChar( nKey, nFlags ) CLASS TWBrowse
do case
case nKey == K_PGUP
::PageUp()
case nKey == K_PGDN
::PageDown()
otherwise
return nil
endcase
return 0
//----------------------------------------------------------------------------//
METHOD PageUp( nLines ) CLASS TListBox
local nSkipped
DEFAULT nLines := ::nRowCount()
nSkipped = ::Skip( -nLines )
if ::nLen < 1
return nil
endif
if ! ::lHitTop
if nSkipped == 0
::lHitTop = .t.
else
::lHitBottom = .f.
if -nSkipped < nLines
::nRowPos = 1
::oVScroll:SetPos( 1 )
else
nSkipped = ::Skip( -nLines )
::Skip( -nSkipped )
::oVScroll:SetPos( ::oVScroll:GetPos() + nSkipped )
endif
::Refresh( .f. )
if ::bChange != nil
Eval( ::bChange )
endif
endif
// ::oVScroll:PageUp()
else
::oVScroll:GoTop()
endif
return nil
//----------------------------------------------------------------------------//
METHOD PageDown( nLines ) CLASS TListBox
local nSkipped, n
DEFAULT nLines := ::nRowCount()
if ::nLen < 1
return nil
endif
if ! ::lHitBottom
::DrawLine()
nSkipped = ::Skip( ( nLines * 2 ) - ::nRowPos )
if nSkipped != 0
::lHitTop = .f.
endif
do case
case nSkipped == 0 .or. nSkipped < nLines
if nLines - ::nRowPos < nSkipped
::GetDC()
::Skip( -( nLines ) )
for n = 1 to ( nLines - 1 )
::Skip( 1 )
::DrawLine( n )
next
::ReleaseDC()
::Skip( 1 )
endif
::nRowPos = Min( ::nRowPos + nSkipped, nLines )
::lHitBottom = .t.
::oVScroll:GoBottom()
otherwise
::GetDC()
for n = nLines to 1 step -1
::DrawLine( n )
::Skip( -1 )
next
::ReleaseDC()
::Skip( ::nRowPos )
endcase
::DrawSelect()
if ::bChange != nil
Eval( ::bChange )
endif
if ! ::lHitBottom
::oVScroll:SetPos( ::oVScroll:GetPos() + nSkipped - ( nLines - ::nRowPos ) )
else
::oVScroll:GoBottom()
endif
endif
return nil
//----------------------------------------------------------------------------//
METHOD VScroll( nWParam, nLParam ) CLASS TWBrowse
local nLines := ::nRowCount()
local nLen
do case
case nWParam == SB_LINEUP
::GoUp()
case nWParam == SB_LINEDOWN
::GoDown()
case nWParam == SB_PAGEUP
::PageUp()
case nWParam == SB_PAGEDOWN
::PageDown()
case nWParam == SB_TOP
::GoTop()
case nWParam == SB_BOTTOM
::GoBottom()
case nWParam == SB_THUMBPOSITION
if ::nLen < 1
return 0
endif
::Skip( nLParam - ::oVScroll:GetPos() )
::oVScroll:SetPos( nLParam )
nLen = Eval( ::bLogicLen )
if nLParam - ::oVScroll:nMin < nLines
::nRowPos = 1
endif
if ::oVScroll:nMax - nLParam < Min( nLines, nLen )
::nRowPos = Min( nLines, nLen ) - ( ::oVScroll:nMax - nLParam )
endif
::Refresh( .f. )
if ::bChange != nil
Eval( ::bChange )
endif
otherwise
return nil
endcase
return 0
//----------------------------------------------------------------------------//
METHOD HScroll( nWParam, nLParam ) CLASS TWBrowse
do case
case nWParam == SB_LINEUP
::GoLeft()
case nWParam == SB_LINEDOWN
::GoRight()
case nWParam == SB_PAGEUP
::GoLeft()
case nWParam == SB_PAGEDOWN
::GoRight()
case nWParam == SB_TOP
::nColPos = 1
::oHScroll:SetPos( 1 )
::Refresh( .f. )
case nWParam == SB_BOTTOM
::nColPos = Len( ::GetColSizes() )
::oHScroll:SetPos( ::nColPos )
::Refresh( .f. )
case nWParam == SB_THUMBPOSITION
::nColPos = nLParam
::oHScroll:SetPos( nLParam )
::Refresh( .f. )
otherwise
return nil
endcase
return 0
//----------------------------------------------------------------------------//
METHOD Skip( n ) CLASS TWBrowse
if ::bSkip != nil
return Eval( ::bSkip, n )
endif
return _DBSkipper( n )
//----------------------------------------------------------------------------//
static function BrwGoBottom( uExpr )
local lSoftSeek := Set( _SET_SOFTSEEK, .t. )
if ValType( uExpr ) == "C"
DbSeek( SubStr( uExpr, 1, Len( uExpr ) - 1 ) + ;
Chr( Asc( SubStr( uExpr, Len( uExpr ) ) ) + 1 ) )
else
DbSeek( uExpr + 1 )
endif
DbSkip( -1 )
Set( _SET_SOFTSEEK, lSoftSeek )
return nil
//----------------------------------------------------------------------------//
// To simulate Filters using INDEXES -they go extremely fast!-
static function BuildSkip( cAlias, cField, uValue1, uValue2 )
local bSkipBlock
local cType := ValType( uValue1 )
do case
case cType == "C"
bSkipBlock = { | n | ( cAlias )->( BrwGoTo( n, ;
&( "{||" + cField + ">= '" + uValue1 + "' .and." + ;
cField + "<= '" + uValue2 + "' }" ) ) ) }
case cType == "D"
bSkipBlock = { | n | ( cAlias )->( BrwGoTo( n, ;
&( "{||" + cField + ">= CToD( '" + DToC( uValue1 ) + "') .and." + ;
cField + "<= CToD( '" + DToC( uValue2 ) + "') }" ) ) ) }
case cType == "N"
bSkipBlock = { | n | ( cAlias )->( BrwGoTo( n, ;
&( "{||" + cField + ">= " + cValToChar( uValue1 ) + " .and." + ;
cField + "<= " + cValToChar( uValue2 ) + " }" ) ) ) }
case cType == "L"
bSkipBlock = { | n | ( cAlias )->( BrwGoTo( n, ;
&( "{||" + cField + ">= " + cValToChar( uValue1 ) + " .and." + ;
cField + "<= " + cValToChar( uValue2 ) + " }" ) ) ) }
endcase
return bSkipBlock
//----------------------------------------------------------------------------//
static function BrwGoTo( n, bWhile )
local nSkipped := 0, nDirection := If( n > 0, 1, -1 )
while nSkipped != n .and. Eval( bWhile ) .and. ! EoF() .and. ! BoF()
DbSkip( nDirection )
nSkipped += nDirection
enddo
do case
case EoF()
DbSkip( -1 )
nSkipped += -nDirection
case BoF()
DbGoTo( RecNo() )
nSkipped++
case ! Eval( bWhile )
DbSkip( -nDirection )
nSkipped += -nDirection
endcase
return nSkipped
//----------------------------------------------------------------------------//
METHOD _RecCount( uSeekValue ) CLASS TWBrowse
local nRecNo := RecNo()
local nRecs := 1
if DbSeek( uSeekValue )
while ::Skip( 1 ) == 1
nRecs++
end
endif
GOTO nRecNo
return nRecs
//----------------------------------------------------------------------------//
METHOD UpStable() CLASS TWBrowse
local nRow := ::nRowPos
local nRows := ::nRowCount()
local nRecNo := ( ::cAlias )->( RecNo() )
local n := 1
local lSkip := .t.
::nRowPos = 1
::lHitTop = .f.
::lHitBottom = .f.
::GoTop()
while ! ( ::cAlias )->( EoF() )
if n > nRows
( ::cAlias )->( DbGoTo( nRecNo ) )
::nRowPos = nRow
lSkip = .f.
exit
endif
if nRecNo == ( ::cAlias )->( RecNo() )
::nRowPos = n
exit
else
( ::cAlias )->( DbSkip() )
endif
n++
end
if lSkip
( ::cAlias )->( DbSkip( -::nRowPos ) )
endif
return nil
//----------------------------------------------------------------------------//
METHOD SetFilter( cField, uVal1, uVal2 ) CLASS TWBrowse
DEFAULT uVal2 := uVal1
::cField = cField
::uValue1 = uVal1
::uValue2 = uVal2
// Posibility of using FILTERs based on INDEXES!!!
::bGoTop = If( uVal1 != nil, { || ( ::cAlias )->( DbSeek( uVal1 ) ) },;
{ || ( ::cAlias )->( DbGoTop() ) } )
::bGoBottom = If( uVal2 != nil, { || ( ::cAlias )->( BrwGoBottom( uVal2 ) ) },;
{ || ( ::cAlias )->( DbGoBottom() ) } )
::bSkip = If( uVal1 != nil, BuildSkip( ::cAlias, cField, uVal1, uVal2 ),;
{ | n | ( ::cAlias )->( _DbSkipper( n ) ) } )
::bLogicLen = If( uVal1 != nil,;
{ || ( ::cAlias )->( Self:RecCount( uVal1 ) ) },;
{ || ( ::cAlias )->( RecCount() ) } )
return nil
//----------------------------------------------------------------------------//
METHOD MouseMove( nRow, nCol, nKeyFlags ) CLASS TWBrowse
local nColPos := 0
if ::lDrag
return Super:MouseMove( nRow, nCol, nKeyFlags )
else
if AScan( ::GetColSizes(),;
{ | nColumn | nColPos += nColumn,;
nCol >= nColPos - 1 .and. ;
nCol <= nColPos + 1 } ) != 0
CursorWE()
else
Super:MouseMove( nRow, nCol, nKeyFlags )
endif
endif
return 0
//----------------------------------------------------------------------------//