On Fri, 25 Apr 2008, Szakáts Viktor wrote:
Hi Viktor,
sorry for the delay.
> Could you pls reattach the modified br.prg? It looks
> this one was the original file.
Ups, my fault. I'm attaching modified version.
> Do you think there is any reasonable way to avoid
> to infamous "roll up" problem in any ways?
> This might have something to do with your point 2.
> See below the conversation about the "roll up"
> problem. It basically means that in "certain" situations
> the user will experience the browse to start going
> up one by one until it reaches the beginning of the
> table.
It will happen when some filtered records will disappear
due to concurent access. TBrowse does not know anything
about data source. It means it's possible to desynchronize
the data in the cache with real data. Each tbrowse implementation
will have such problem until it will not be extended with
additional data attribute which will have unique record ID
(RecNo() is good enough) to detect it. Additionaly it should
have an mechanism for scope checking and automatic refreshing
when it will detect out of scope positioning. In summary it's
not sth what can be easy added though it should be possible
to add some smaller modifications to TBrowse and it will be
possible for user to implement such functionality in child
class. I'll think about it.
best regards,
Przemek
STATIC s_nCount := 0
STATIC s_cCurrBlock := ""
STATIC s_cResult1
STATIC s_cResult2
#translate TEST_CALL( <x> ) => TEST_C_CALL( o, #<x>, {|| <x> } )
FUNCTION Main()
LOCAL o
LOCAL nOldRecNo
LOCAL tmp
// AltD()
dbCreate( "_test", {{ "ID", "C", 10, 0 }} )
USE _test NEW EXCLUSIVE ALIAS w_TEST
dbAppend() ; w_TEST->ID := "01"
dbAppend() ; w_TEST->ID := "02"
dbAppend() ; w_TEST->ID := "03"
dbAppend() ; w_TEST->ID := "04"
o := TBrowseNew( 0, 0, 6, 8 )
o:GoTopBlock := { || nOldRecNo := RecNo(), dbGoTop(), my_QOut( o, {
"TOP", RecNo(), nOldRecNo } ) }
o:GoBottomBlock := { || nOldRecNo := RecNo(), dbGoBottom(), my_QOut( o, {
"BOT", RecNo(), nOldRecNo } ) }
o:SkipBlock := { | nRecs | nOldRecNo := RecNo(), tmp := Skipped( nRecs
), my_QOut( o, { "SKP", RecNo(), nOldRecNo, nRecs, tmp } ), tmp }
o:AddColumn( TBColumnNew( "#", {|| my_QOut( NIL, { "BLK", RecNo() } ),
StrZero( RecNo(), 3 ) } ) )
#define Inkey(x)
CLS
TEST_CALL( o:leftVisible )
TEST_CALL( o:goTop() )
TEST_CALL( ForceStable( o ) )
TEST_CALL( o:goTop() )
TEST_CALL( o:pageUp() )
TEST_CALL( ForceStable( o ) )
TEST_CALL( o:goTop() )
TEST_CALL( o:pageDown() )
TEST_CALL( ForceStable( o ) )
TEST_CALL( o:goBottom() )
TEST_CALL( ForceStable( o ) )
TEST_CALL( o:goBottom() )
TEST_CALL( o:pageUp() )
TEST_CALL( ForceStable( o ) )
TEST_CALL( o:goBottom() )
TEST_CALL( o:pageDown() )
TEST_CALL( ForceStable( o ) )
TEST_CALL( o:leftVisible )
TEST_CALL( o:stabilize )
TEST_CALL( o:stabilize )
TEST_CALL( o:stabilize )
TEST_CALL( o:stabilize )
TEST_CALL( o:stabilize )
TEST_CALL( o:stabilize )
TEST_CALL( o:stabilize )
TEST_CALL( o:stabilize )
TEST_CALL( o:rowPos )
TEST_CALL( o:rowPos )
TEST_CALL( dbGoTop() )
TEST_CALL( ForceStable( o ) )
TEST_CALL( o:goTop() )
TEST_CALL( o:goBottom() )
TEST_CALL( ForceStable( o ) )
TEST_CALL( o:up() )
TEST_CALL( o:up() )
TEST_CALL( o:down() )
// dbGoTop()
TEST_CALL( ForceStable( o ) )
TEST_CALL( o:PageUp() )
TEST_CALL( ForceStable( o ) )
o:goTop()
o:forceStable()
TEST_CALL( o:down() )
TEST_CALL( o:down() )
TEST_CALL( o:PageDown() )
TEST_CALL( o:PageDown() )
TEST_CALL( o:PageUp() )
TEST_CALL( ForceStable( o ) )
Inkey(0)
TEST_CALL( o:goTop() )
TEST_CALL( o:PageDown() )
TEST_CALL( ForceStable( o ) )
Inkey(0)
TEST_CALL( o:goTop() )
TEST_CALL( o:down() )
TEST_CALL( ForceStable( o ) )
Inkey(0)
TEST_CALL( o:goTop() )
TEST_CALL( o:down() )
TEST_CALL( o:down() )
TEST_CALL( o:down() )
TEST_CALL( o:down() )
TEST_CALL( o:down() )
TEST_CALL( o:down() )
TEST_CALL( ForceStable( o ) )
Inkey(0)
TEST_CALL( o:goBottom() )
TEST_CALL( ForceStable( o ) )
Inkey(0)
TEST_CALL( o:goBottom() )
TEST_CALL( o:stabilize )
TEST_CALL( o:stabilize )
TEST_CALL( o:stabilize )
TEST_CALL( o:stabilize )
TEST_CALL( o:stabilize )
TEST_CALL( o:stabilize )
TEST_CALL( o:stabilize )
Inkey(0)
TEST_CALL( o:goBottom() )
TEST_CALL( o:pageDown() )
TEST_CALL( o:stabilize )
TEST_CALL( o:stabilize )
TEST_CALL( o:stabilize )
TEST_CALL( o:stabilize )
TEST_CALL( o:stabilize )
TEST_CALL( o:stabilize )
TEST_CALL( o:stabilize )
Inkey(0)
TEST_CALL( o:goTop() )
TEST_CALL( o:stabilize )
TEST_CALL( o:stabilize )
TEST_CALL( o:stabilize )
TEST_CALL( o:stabilize )
TEST_CALL( o:stabilize )
TEST_CALL( o:stabilize )
TEST_CALL( o:stabilize )
Inkey(0)
TEST_CALL( o:goTop() )
TEST_CALL( o:stabilize )
TEST_CALL( o:stabilize )
TEST_CALL( o:stabilize )
TEST_CALL( o:stabilize )
TEST_CALL( o:stabilize )
TEST_CALL( o:stabilize )
TEST_CALL( o:down() )
TEST_CALL( o:stabilize )
Inkey(0)
TEST_CALL( o:goTop() )
TEST_CALL( o:stabilize )
TEST_CALL( o:stabilize )
TEST_CALL( o:stabilize )
TEST_CALL( o:stabilize )
TEST_CALL( o:stabilize )
TEST_CALL( o:stabilize )
TEST_CALL( o:down() )
TEST_CALL( o:down() )
TEST_CALL( o:down() )
TEST_CALL( o:down() )
TEST_CALL( o:down() )
TEST_CALL( o:down() )
TEST_CALL( o:stabilize )
TEST_CALL( o:stabilize )
TEST_CALL( o:stabilize )
TEST_CALL( o:stabilize )
Inkey(0)
/*
o:Stabilize()
o:Up()
o:Down()
o:PageUp()
o:PageDown()
o:GoTop()
o:GoBottom()
*/
RETURN NIL
STATIC FUNCTION Skipped( nRecs )
LOCAL nSkipped := 0
IF LastRec() != 0
IF nRecs == 0
dbSkip( 0 )
ELSEIF nRecs > 0 .AND. RecNo() != LastRec() + 1
DO WHILE nSkipped < nRecs
dbSkip()
IF Eof()
dbSkip( -1 )
EXIT
ENDIF
nSkipped++
ENDDO
ELSEIF nRecs < 0
DO WHILE nSkipped > nRecs
dbSkip( -1 )
IF Bof()
EXIT
ENDIF
nSkipped--
ENDDO
ENDIF
ENDIF
RETURN nSkipped
FUNCTION XToStrE( xValue )
LOCAL cType := ValType( xValue )
DO CASE
CASE cType == "C"
xValue := StrTran( xValue, Chr(0), '"+Chr(0)+"' )
xValue := StrTran( xValue, Chr(9), '"+Chr(9)+"' )
xValue := StrTran( xValue, Chr(10), '"+Chr(10)+"' )
xValue := StrTran( xValue, Chr(13), '"+Chr(13)+"' )
xValue := StrTran( xValue, Chr(26), '"+Chr(26)+"' )
RETURN xValue
CASE cType == "N" ; RETURN LTrim( Str( xValue ) )
CASE cType == "D" ; RETURN DToS( xValue )
CASE cType == "L" ; RETURN iif( xValue, ".T.", ".F." )
CASE cType == "O" ; RETURN xValue:className() + " Object"
CASE cType == "U" ; RETURN "NIL"
CASE cType == "B" ; RETURN '{||...} -> ' + XToStrE( Eval( xValue ) )
CASE cType == "A" ; RETURN '{ ' + ArrayToEList( xValue ) + ' }'
CASE cType == "M" ; RETURN 'M:' + xValue
ENDCASE
RETURN ""
FUNCTION ArrayToEList( a )
LOCAL tmp
LOCAL cString := ""
FOR tmp := 1 TO Len( a )
cString += XToStrE( a[ tmp ] )
IF tmp < Len( a )
cString += ", "
ENDIF
NEXT
RETURN cString
FUNCTION ForceStable( o )
DO WHILE !TEST_CALL( o:stabilize )
ENDDO
RETURN NIL
FUNCTION TEST_C_CALL( o, cBlock, bBlock )
LOCAL xRetVal
LOCAL cOldBlock := s_cCurrBlock
s_cCurrBlock := cBlock
LOGSTUFF( o, .T., "BEGIN" )
xRetVal := Eval( bBlock )
LOGSTUFF( o, .T., "END" )
s_cCurrBlock := cOldBlock
RETURN xRetVal
FUNCTION LOGSTUFF( o, l, cText )
STATIC s_nRow := 0
LOCAL nLevel := 16
IF s_nRow == MaxRow()
Scroll( 0, 16, MaxRow(), MaxCol(), 1, 0 )
DispOutAt( MaxRow(), 0, Space( MaxCol() + 1 ) )
ELSE
s_nRow++
ENDIF
#define DispOut( x ) OutStd( x )
WHILE procline(--nLevel)==0
ENDDO
//nLevel:=2
SetPos( s_nRow, 16 + iif( l, 0, 3 ) )
++s_nCount
DispOut( padr(procname(nLevel),10)+":"+strzero(procline(nLevel),3) )
//DispOut( s_nCount )
DispOut( " " )
DispOut( PadR( iif( l, s_cCurrBlock, "" ), 11 ) ) ; DispOut( " " )
DispOut( iif( o != NIL, o:rowPos, PadL( "", 10 ) ) ) ; DispOut( " " )
DispOut( cText ) ; DispOut( " " )
DispOut( /* Chr( 13 ) + */ Chr( 10 ) )
RETURN NIL
FUNCTION my_QOut( o, a )
LOGSTUFF( o, .F., ArrayToEList( a ) )
RETURN NIL
_______________________________________________
Harbour mailing list
[email protected]
http://lists.harbour-project.org/mailman/listinfo/harbour