Alaska Software Inc. - XbpBrowse() - wrong behaviour
Username: Password:
AuthorTopic: XbpBrowse() - wrong behaviour
Thomas BraunXbpBrowse() - wrong behaviour
on Mon, 30 Mar 2015 16:49:43 +0200
Hi,

I'm using dbeditor, written by Jeremy Suiter, James Loughner and some
smaller contributions by myself.

Currently I'm struggling with some weird bug regarding XbpBrowse()

While I was trying to do a mass replace on a date type column, I received
this error message:

"Can't replace field, variable types do not match"

I narrowed this down to the following line, which is used to get the data
type of the current browser cell:

cType:=ValType(oFocusBrowse:getData()[1])

oFocusBrowse is a XbpBrowse() object, getData() is supposed to return the
value of the currently highlited cell.

But in this case, it always returns this string -> "1", regardless what the
actual content of the current cell is.

Only on the second try, after confirming the error message with "OK",
getData() returns the correct value.

If I close and re-open the datatable, the same thing happens, first time
wrong value, second time OK.

I'm quite sure this did not happen pre-2.0

Thomas
Andreas Gehrs-Pahl
Re: XbpBrowse() - wrong behaviour
on Mon, 30 Mar 2015 17:46:51 -0400
Thomas,

>oFocusBrowse is a XbpBrowse() object, getData() is supposed to return the
>value of the currently highlited cell.

oXbpBrowse:GetData() actually returns an Array. That Array will contain 
either no values, the value of the highlighted Cell, or all the values of 
the highlighted Row, depending on the oXbpBrowse:CursorMode iVar content.

Since Xbase++ 2.00.483, the returned value actually depends also on the 
oXbpBrowse:NavigationMode. In (the new) XBPBRW_NAVIGATION_SYSTEM mode, the 
returned value is simply the contents of the oXbpBrowse:aCachedRow iVar. 
Only in XBPBRW_NAVIGATION_1XCOMPATIBLE mode is the actual, current, data 
returned (and the oXbpBrowse:DataLink evaluated, if it exists), using the 
oXbpBrowse:EditBuffer() method.

Your code: 

>cType:=ValType(oFocusBrowse:getData()[1])

is designed to get the first Array Element of the returned value. I have 
some old copy of DbEditor and it always includes the Record ID in the first 
column of the browse, so what you get -- the "1" -- is the display value of 
the first cell of the first column, which is Record Number "1".

The default value for the oXbpBrowse:CursorMode iVar was XBPBRW_CURSOR_CELL 
prior to Xbase++ 2.00.483 but has now been changed to XBPBRW_CURSOR_ROW. As 
you (apparently) never set oXbpBrowse:CursorMode in your DbEditor code, the 
return value of oXbpBrowse:GetData() is the contents of the entire Row, and 
oXbpBrowse:GetData()[1] will always give you the Record ID.

Adding: oBrowse:CursorMode := XBPBRW_CURSOR_CELL somewhere in your code 
between oBrowse:New(...) and oBrowse:Create(...) might fix the issue. If 
you make the change after oBrowse:Create(...) in your code, you need to add 
an oBrowse:Configure().

But even in Cell mode, the correct Cell (or column) must be selected, to get 
any value other than the "1" from the first (Record ID) column.

Hope that helps,

Andreas

Andreas Gehrs-Pahl
Absolute Software, LLC

phone: (989) 723-9927
email: Andreas.GP@Charter.net
web:   http://www.Aerospace-History.net
Thomas BraunRe: XbpBrowse() - wrong behaviour
on Tue, 31 Mar 2015 10:13:35 +0200
Hi Andreas,

> Thomas,
> 
>>oFocusBrowse is a XbpBrowse() object, getData() is supposed to return the
>>value of the currently highlited cell.
> 
> oXbpBrowse:GetData() actually returns an Array.

I know - I just shortened the description due to lazyness 

> Since Xbase++ 2.00.483, the returned value actually depends also on the 
> oXbpBrowse:NavigationMode.

Did not know this. Thanks!

It seems like this introduced some kind of bug.

> Your code: 
> 
>>cType:=ValType(oFocusBrowse:getData()[1])
> 
> is designed to get the first Array Element of the returned value. I have 
> some old copy of DbEditor and it always includes the Record ID in the first 
> column of the browse, so what you get -- the "1" -- is the display value of 
> the first cell of the first column, which is Record Number "1".

I only get the wrong data the first time I try it - on every following try
it works - and does return the correct value... as long as I don't close
the browse window and open it again.

Probably there is some additional refresh after the first time that fixes
the problem?

> The default value for the oXbpBrowse:CursorMode iVar was XBPBRW_CURSOR_CELL 
> prior to Xbase++ 2.00.483 but has now been changed to XBPBRW_CURSOR_ROW. As 
> you (apparently) never set oXbpBrowse:CursorMode in your DbEditor code

Yes, I already do - to cell mode: 

oBrowse:cursorMode := XBPBRW_CURSOR_CELL

> return value of oXbpBrowse:GetData() is the contents of the entire Row, and 
> oXbpBrowse:GetData()[1] will always give you the Record ID.

No. The array only has one element - I checked this with the debugger.

Most of the time it looks like this: {"1"}... sometimes it looks like this
{"    1"}, on one test it even returned the value of of a cell that was two
columns to the left of the actually highlighted one but I could not
reproduce this one.

> 
> Adding: oBrowse:CursorMode := XBPBRW_CURSOR_CELL somewhere in your code 
> between oBrowse:New(...) and oBrowse:Create(...) might fix the issue.

No. Apparently something seems to be broken when XBPBRW_NAVIGATION_SYSTEM
is used. If Alaska juts would publish the source of the xbpBrowse - then I
could check myself.

I now changed to XBPBRW_NAVIGATION_1XCOMPATIBLE mode, and the correct
behaviour came back.

In case somebody wants to try, or needs read-only access to the source, it
can be found in my Subversion repository: 

https://85.214.247.76/repo/dbeditor/trunk
username: guest
password: guest

Just comment line 45 in browse.prg to see the problem.

Thomas
Andreas Gehrs-Pahl
Re: XbpBrowse() - wrong behaviour
on Tue, 31 Mar 2015 10:37:33 -0400
Thomas,

>No. Apparently something seems to be broken when XBPBRW_NAVIGATION_SYSTEM
>is used. If Alaska juts would publish the source of the xbpBrowse - then I
>could check myself.

The source code for the browsers is available -- at least as part of the 
Professional Subscription -- and can be found here:

..\Source\Runtime\DUI\...

The source code for some of the underlying classes, like XbpCellGroup() and 
XbpMultiCellGroup() aren't included, but XbpBrowse(), XbpColumn(), as well 
as XbpQuickBrowse() are there.

Hope that helps,

Andreas

Andreas Gehrs-Pahl
Absolute Software, LLC

phone: (989) 723-9927
email: Andreas.GP@Charter.net
web:   http://www.Aerospace-History.net
Andreas Gehrs-Pahl
Re: XbpBrowse() - wrong behaviour
on Tue, 31 Mar 2015 15:43:51 -0400
Thomas,

After I read your (more comprehensive) error description I took a look at 
the XbpBrowse() code, and I found a logical error in its implementation. If 
the (default) ::NavigationMode of XBPBRW_NAVIGATION_SYSTEM is used, then the 
browse will cache the current Row (or Cell) when the Browse is stabilized, 
and that cached value is used in the ::EditBuffer() -- and therefore also 
the ::GetData() -- method. This is required as the cursor might not be on 
the actual "current" (highlighted) record in that Navigation Mode.

The problem with the current implementation is that if the ::CursorMode is 
XBPBRW_CURSOR_CELL (rather than the default of XBPBRW_CURSOR_ROW) only the 
"current" cell is saved in the new ::aCachedRow iVar. Therefore, until you 
navigate to a different Row, the ::aCachedRow iVar will always contain the 
value of the Cell that was active when you selected the Row -- initially the 
first Column of the first Row) -- no matter which Cell (or Column) of the 
first Row is actually highlighted by moving the cursor within the same Row.

To fix this, ::aCachedRow should always cache the contents of the entire Row 
rather than just a single Cell -- no matter which ::CursorMode is selected 
actually -- and the ::EditBuffer() method should return the appropriate 
value, based on the ::CursorMode. That way, no matter in which Column/Cell 
the cursor is at any time, the correct data contents would be returned.

This should be a simple fix for Alaska, and you could even implement this 
yourself, if you want to use ::NavigationMode of XBPBRW_NAVIGATION_SYSTEM 
with a ::CursorMode of XBPBRW_CURSOR_CELL, before Alaska fixes this.

Hope that helps,

Andreas

Andreas Gehrs-Pahl
Absolute Software, LLC

phone: (989) 723-9927
email: Andreas.GP@Charter.net
web:   http://www.Aerospace-History.net