Problem with TWBrowse Class (linux) using UPDATE.

Post Reply
User avatar
xProgrammer
Posts: 464
Joined: Tue May 16, 2006 7:47 am
Location: Australia

Problem with TWBrowse Class (linux) using UPDATE.

Post by xProgrammer »

Hi Antonio

I have run into a problem trying to use the UPDATE option on BROWSE object. I can get the updated array displayed correctly but you can't navigate correctly through them.

If as originally activated the browse has 9 entries in it and then you have 13 and <dialog>:Update() then if you start with the first item of the browse selected and keep pressing Down you will go:

1 2 3 4 5 6 7 8 13

Now if you keep pressing Up you will go

13 12 11 10 9 8 7 6 1

Clicking the mouse gives related issues.

calling <browse-object>:SetArray( <data-array> ) doesn't solve this problem.

I would appreciate any help you can give me on this.

Regards
Doug
(xProgrammer)
User avatar
xProgrammer
Posts: 464
Joined: Tue May 16, 2006 7:47 am
Location: Australia

Post by xProgrammer »

Hi Antonio

I'm not sure exactly why TBROWSE:SetArray() is giving the above problem. I have seemed to be able to get the correct behaviour by setting TBROWSE:cargo to the logical length and modifying the TBROWSE:SetArray() method as follows:

Code: Select all

   ::bLogicLen = { | o | ::nLen := o:cargo }
This solution is not ideal in that it depends upon the programmer updating the cargo value whenever the length of the array has altered. If there isn't a neater approach adding a new DATA to TBROWSE to hold this value would presumably be preferable.

Your thoughts would be appreciated

Regards
Doug
(xProgrammer)
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Doug,

Please check if this is the code that you have in Class TWBrowse method SetArray(), thanks

Code: Select all

METHOD SetArray( aArray ) CLASS TWBrowse

   ::nAt       = 1
   ::cAlias    = "ARRAY"
   // ::bLine     = { || { aArray[ ::nAt ] } }
   ::bLogicLen = { || ::nLen := Len( aArray ) }
   ::bGoTop    = { || ::nAt := 1 }
   ::bGoBottom = { || ::nAt := Eval( ::bLogicLen, Self ) }
   ::bSkip     = { | nSkip, nOld | nOld := ::nAt, ::nAt += nSkip,;
                  ::nAt := Min( Max( ::nAt, 1 ), Eval( ::bLogicLen, Self ) ),;
                  ::nAt - nOld }
return nil
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
xProgrammer
Posts: 464
Joined: Tue May 16, 2006 7:47 am
Location: Australia

Post by xProgrammer »

Hi Antonio

Yes it is - and I don't quite understand why it doesn't work - maybe something to do with when the code block is "compiled"? I thought that if I used ASize() to resize the array rather than Array( 0 ) it might fix the problem but it didn't seem to.

I have added DATA iLength to the BROWSE class and am setting that in my code and everything seems to work OK. I have:

Code: Select all

::bLogicLen = { | o | ::nLen := o:iLength }
The standard SetArray() works until you Update() the BROWSE and have an altered array length.

I don't think there's some other factor causing this problem but I guess I can't be certain unless I reproduce it on a simple example.

Regards
Doug
(xProgrammer)

I guess I could have:

Code: Select all

::bLogicLen = { | | ::nLen := ::iLength }
or would it work just setting ::nLen directly?
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Doug,

If you modify the array then you should do oBrowse:SetArray( aModifiedArray ) again
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
xProgrammer
Posts: 464
Joined: Tue May 16, 2006 7:47 am
Location: Australia

Post by xProgrammer »

Hi Antonio

I did call <browse>:SetArray( <array> ) again after modifying the array but the problem persisted.

Regards
Doug
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Doug,

Fixed! :-) This is the right code:

Code: Select all

METHOD SetArray( aArray ) CLASS TWBrowse

   ::nAt       = 1
   ::cAlias    = "ARRAY"
   // ::bLine     = { || { aArray[ ::nAt ] } }
   ::bLogicLen = { || ::nLen := Len( aArray ) }
   ::bGoTop    = { || ::nAt := 1 }
   ::bGoBottom = { || ::nAt := Eval( ::bLogicLen, Self ) }
   ::bSkip     = { | nSkip, nOld | nOld := ::nAt, ::nAt += nSkip,;
                  ::nAt := Min( Max( ::nAt, 1 ), Eval( ::bLogicLen, Self ) ),;
                  ::nAt - nOld }
   ::oVScroll:SetRange( 1, Eval( ::bLogicLen, Self ), ::nRowCount() )
                  
return nil 
A new DATA nAt has to be added to the Class. I have emailed you the modified files, the new LIBs and a working example :-)

This is the working example:
TestBrwA.prg

Code: Select all

// Using a browse to display a multidimensional array

#include "FiveLinux.ch"

function Main()

   local oWnd, oBrw, aTest := { { "one", "two" }, { "three", "four" } }

   DEFINE WINDOW oWnd TITLE "Testing Browses" SIZE 522, 317

   @ 2, 2 BROWSE oBrw OF oWnd ;
      HEADERS "First", "Second" ;
      FIELDS  aTest[ oBrw:nAt ][ 1 ], aTest[ oBrw:nAt ][ 2 ]

   oBrw:SetArray( aTest )

   @ 28, 2 BUTTON "_Ok" OF oWnd ACTION oWnd:End()
   
   @ 28, 30 BUTTON "Add" OF oWnd ACTION ( AAdd( aTest, { "five", "six" } ), oBrw:SetArray( aTest ), oBrw:GoTop() )

   ACTIVATE WINDOW oWnd

return nil
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
xProgrammer
Posts: 464
Joined: Tue May 16, 2006 7:47 am
Location: Australia

Thanks (and please check)

Post by xProgrammer »

Hi Antonio

Thanks for the fix - greatly appreciated.

When I applied the fix to my code I still had a slight problem - that could be due to my alterations to TWBrowse. The add button kept adding to the array, but only the first addition was displayed. (Try clicking on the Add button several times in a row). However this was easily fixed by adding oWnd:Refresh() after oBrw:GoTop().

This fix was important for the next major part of my medical software and I am most grateful.

Regards
Doug
(xProgrammer)
Post Reply