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
Harbour@harbour-project.org
http://lists.harbour-project.org/mailman/listinfo/harbour

Reply via email to