TSBrowse TXBrowse ?

TSBrowse TXBrowse ?

Postby avista » Fri Jan 21, 2011 1:40 pm

Hi all,

I use TSBrowse in many situations ... but it is not part of FWH.
Alternative is to continye to use TSBrowse or is possible to convert in TXBrowse.
TXBrowse dont support SUPERHEADERs, PREEDIT ... ????
Possible to use code something like this ?

ADD TO oBrw DATA FIELDWBLOCK( "DDOK", SELECT() ) ;
HEADER "Od datum" SIZE 8*10 PICTURE "99.99.99" ;
EDITABLE MOVE DT_MOVE_RIGHT ;
WHEN F_GKNI1_WHEN(oBrw) ;
VALID { | uVar | OK_DAT( uVar ) } ;
PREEDIT { || F_GKNI1_REPLACE(oBrw,oSayKonNaz,oSayParNaz) } ;
POSTEDIT {| uVar | IIF( EMPTY(STA_N->DDO), (STA_N->DDO := uVar, oBrw:GoRight()), ) ,;
IIF( EMPTY(STA_N->VAL), (STA_N->VAL := uVar, oBrw:GoRight()), ) ;
}

Best Retards,

ps.

I still think TSBrowse is excelant class ...why is not part of FWH ?
User avatar
avista
 
Posts: 301
Joined: Fri Jun 01, 2007 9:07 am
Location: Macedonia

Re: TSBrowse TXBrowse ?

Postby James Bott » Fri Jan 21, 2011 4:50 pm

I am not sure from the syntax example exactly what it does. Maybe if you describe what things this example provides, someone can tell you if they can be done in xBrowse.

Regards,
James
User avatar
James Bott
 
Posts: 4840
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA

Re: TSBrowse TXBrowse ?

Postby James Bott » Fri Jan 21, 2011 5:20 pm

Maybe this will answer your question about superheaders.

viewtopic.php?f=3&t=17582&p=92426&hilit=xbrowse+header#p92426

James
User avatar
James Bott
 
Posts: 4840
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA

Re: TSBrowse TXBrowse ?

Postby nageswaragunupudi » Fri Jan 21, 2011 6:10 pm

XBrowse can do all.
Regards

G. N. Rao.
Hyderabad, India
User avatar
nageswaragunupudi
 
Posts: 10690
Joined: Sun Nov 19, 2006 5:22 am
Location: India

Re: TSBrowse TXBrowse ?

Postby avista » Sun Jan 23, 2011 6:44 pm

Hi,
Thanks for reply

I need most of all option PREEDIT action to be evaluated just bevore editing field.
For example somthing like this

ADD TO oBrw DATA FIELDWBLOCK( "PRICE", SELECT() ) ;
HEADER "Price" SIZE 80 PICTURE "99999.99" ;
EDITABLE MOVE DT_MOVE_RIGHT ;
VALID { | uVar | uVar > 0 } ;
PREEDIT { | uVar| nTotal : = nToatl - uVar } ; // Before editing
POSTEDIT {| uVar | nTotal : = nToatl + uVar } // After editing

Regards,
and thanks.
User avatar
avista
 
Posts: 301
Joined: Fri Jun 01, 2007 9:07 am
Location: Macedonia

Re: TSBrowse TXBrowse ?

Postby James Bott » Sun Jan 23, 2011 7:00 pm

Avista,

There is a oCol:bPostEdit but I don't see a b:OnPreEdit codeblock. However, as per your example, I think xbrowse can handle column totals by just using the TOTAL clause.

ADD COLUMN oCol TO oBrw ... TOTAL

Perhaps Rao can answer the preEdit question.

Regards,
James
User avatar
James Bott
 
Posts: 4840
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA

Re: TSBrowse TXBrowse ?

Postby nageswaragunupudi » Mon Jan 24, 2011 7:40 am

TSBrowse is one of the greatest free contributions to the FiveWin community by Maestro Manuel Mercado. Many programmers like me used and were benefited by his valuable contributions. We can not forget Heranan's WBrowse too.

I consider it to be not in a good taste to compare FWH's classes with non-FWH libraries. I confine my discusssions to FWH's own browses.

Purpose of these two lines
Code: Select all  Expand view  RUN

PREEDIT { | uVar| nTotal : = nToatl - uVar } ; // Before editing
POSTEDIT {| uVar | nTotal : = nToatl + uVar } // After editing
 

is to update the totals by reducing the old value before edit and adding the new value after edit and then redisplay the totals. We write similar code for every column. If instead of just totals, we need to display average, std, etc. the code we need to write to recompute and display the footers is more complex.

In the case of XBrowse all this code is not required and is rather redundant.

We just need to tell xbrowse that we need totals of the column. XBrowse undestands that if a cell is edited, the total in the footer also is to be recomputed and xbrowse itself does the recomputation and refreshes display of the total.

Let us start with a simple example, where we display numeric columns, with totals in the footers and update to totals in the footers when the user edits a cell.

Code: Select all  Expand view  RUN

#include "FiveWin.Ch"
#include "ord.ch"
#include "xbrowse.ch"

//----------------------------------------------------------------------------//

REQUEST DBFCDX

//----------------------------------------------------------------------------//

function Main()

   local oDlg, oBrw, oFont

   USE CUSTOMER NEW ALIAS CUST SHARED
   SET ORDER TO TAG FIRST
   GO TOP

   DEFINE FONT oFont NAME 'TAHOMA' SIZE 0,-12
   DEFINE DIALOG oDlg SIZE 600,400 PIXEL TITLE 'XBrowse Totals' ;
      FONT oFont
   @ 10,10 XBROWSE oBrw SIZE -10,-30 PIXEL OF oDlg ;
      COLUMNS "First", "Married", "HireDate", "Age", "Salary" ;
      DATASOURCE "CUST" ;
      AUTOSORT CELL LINES FOOTERS NOBORDER FASTEDIT


   WITH OBJECT oBrw

      // Specific to columns
      :Married:SetCheck()
      :HireDate:cEditPicture  := "dd mmm yyyy"
      :Age:nFooterType        := AGGR_STD
      :Salary:nFooterType     := AGGR_SUM

      // for the entire browse
      :nEditTypes             := EDIT_GET
      :nStretchCol            := STRETCHCOL_WIDEST

      // finally
      :MakeTotals()
      :CreateFromCode()
   END

   @ oDlg:nHeight / 2 - 25, 10 BUTTON "Excel" SIZE 40,12 PIXEL OF oDlg ACTION oBrw:ToExcel()
   @ oDlg:nHeight / 2 - 25, 55 BUTTON "Excel" SIZE 40,12 PIXEL OF oDlg ACTION oBrw:Report()

   ACTIVATE DIALOG oDlg CENTERED
   RELEASE FONT oFont
   CLOSE CUST

return (0)

//----------------------------------------------------------------------------//

init procedure PrgInit

    SET DATE ITALIAN
    SET CENTURY ON
    SET TIME FORMAT TO "HH:MM:SS"
    SET EPOCH TO YEAR(DATE())-50

    SET DELETED ON
    SET EXCLUSIVE OFF

    RDDSETDEFAULT( "DBFCDX" )

    XbrNumFormat( 'E', .t. )
    SetGetColorFocus()

return

//----------------------------------------------------------------------------//
 


Image

I have used the customer.dbf in the \fwh\samples folder. Compile, link and run the program in the samples folder.

Footers display Standard Deviation of "Age" column and Total of "Salary" column. When a cell is edited, the footers are also updated automatically. Imagine the kind of code needed for all this and see how much reduction of code is possible with xbrowse, in particular, with regards to recomputation of Standard Deviation.

Let us now go through the code line by line:
Code: Select all  Expand view  RUN
XbrNumFormat( 'E', .t. ) // European number format with thousand separators.
 

This is the code at the beginning of the application. XBrowse automatically supplies picture clauses depending on the data type. The above setting at the outset instructs the xbrowse to use european number formatting with thousand separators by default. If we need to change the foratting to international ( American ) we simiply change this line to XBrNumFormat( 'A', .t. ). We do not need to change the picture clauses through out our application.

Code: Select all  Expand view  RUN

@ 10,10 XBROWSE oBrw SIZE -10,-30 PIXEL OF oDlg <clauses>
 


XBrowse provides syntaxes similar to both TWBrowse and TCBrowse. In the above line, negative sizes indicate that a margin of 10 pixels on the right and 30 pixels at the bottom to be left. We can also specify the size in absolute pixels. Advantage of specifying right and bottom margins is that if we later change the size of the dialog, we do not have to change the size of XBrowse also. In addition, if the browse is created in a window, the browse also is resized when the window is resized, without our having to write "ON RESIZE oWnd" code.

Code: Select all  Expand view  RUN

      COLUMNS "First", "Married", "HireDate", "Age", "Salary" ;
 

XBrowse supports the legacy syntax of FIELDS ... But columns syntax is extremely powerful.

By using the above syntax, XBrowse decides a few things automatically.

XBrowse knows that it needs to display the fields with the names given above. It also knows the the programmer expects the headers to be shown in mixed case as specified. It knows that we naturally want text to be aligned left and dates and numbers to right and aligns accordingly by default. It also provides picture clauses suitable to the datatype. Dates are shown in Set Date format, and Salary is shown in european number format with thousand separators. XBrowse also computes the exact widths required to display the columns based on the field lengths. Please note that we can always override these defaults, but most of the times, these defaults serve the purpose without our having to write the code.

Code: Select all  Expand view  RUN

AUTOSORT
 


With this one clause, we tell XBrowse that we want that if the user clicks on header, the browse should be sorted on that column. XBrowse checks all the index tag expressions and decides the right Tag to set order to for each column. XBrowse also builds an appropriate Seek Codebolock for incremental seek on the sorted column. Incremental seeks can be on text, numbers or dates. With earlier browses, we have to write a lot of code to accomplish this.

Code: Select all  Expand view  RUN

   WITH OBJECT oBrw

      // Specific to columns
      :Married:SetCheck()
      <Other Clauses>
   END
 

oBrw:Married returns the column object with header "Married" (Case insensitive, ignoring any blanks in the header). There are several ways to access a column object.
oBrw:aCols[ <n> ] --> Column object of <n>th column. This is the most familiar way of referring to column objects, from our experience with other browses. While we can access a column object like this, this is highly undesirable. With XBrowse the user can move the columns at the run time resulting in reordering of the columns. At runtime. oBrw:aCols[ 2 ] may not refer the second column at the time of cration of the browse.

If we prefer to use numbers, it is better to use oBrw:oCol( <n> ). This returns the <n>th column at the time of creation. However, we need to keep in mind that the column creation order can change after using any of oBrw:DelCol( <x> ). oBrw:ReArrangeCols(...) or oBrw:RestoreState(...)/
Another and safer way is to refer a column is to refer it by its header.
oBrw:oCol( cHeader ) or oBrw:cHeader returns the column object with that header.

Now by calling SetCheck() method, the logical values are displayed with on and off bitmaps. We can supply our own bitmaps or XBrowse provides default bitmaps.

Code: Select all  Expand view  RUN

:HireDate:cEditPicture  := "dd mmm yyyy"
 

By default, xBrwose uses Set Date format for display of dates. We can override this by using a different format like the above. This new format is used while exporting to Excel or printing a report.

Code: Select all  Expand view  RUN

:Age:nFooterType        := AGGR_STD
:Salary:nFooterType     := AGGR_SUM
 


Here we instruct xbrowse that we want to show Standard Deviation in the footer of the column "Age" and totals for the column "Salary". We need to call the method oBrw:MakeTotals() once at the beginnning. Later, when a cell is edited inline XBrowse automatically recomputes the footers and repaints the footers. XBrowse does these computations incrementally for the changes alone without recalculating for the entire table again. This feature reduces lot of coding in our application program and we even do not have to know how to compute aggregates like STD.
Other aggregate functions available for footers are MIN,MAX,AVG,COUNT,STDEVP. The computations are identical to Excel's functions with the same names. When we use xBrowse's built in export to excel, xbrowse incorporate the appropriate excel formulae while exporting but not just the numbers. You may test this by exporting to excel and examining the formulae at the end.

Code: Select all  Expand view  RUN

:nEditTypes             := EDIT_GET
 


When we create the XBrowse with the above command syntax, XBrowe creates all the columns and their codeblocks suitable for inline editing appropriate locking for shared tables. But does not allow edit by default, unless the programmer specifies a column to be editable. This can be done by oCol:nEditType := EDIT_GET (or other modes of editing). Also if we use the syntax ADD COLUMN TO oBrw .. we can use the EDITABLE clause.
We can set the editable property by setting for each column with oCol:nEditType := nEditType or for the all columns of browse at once with oBrw:nEditTypes := <nEditType].

XBrowse takes care of locking records of the DBF while saving the edited values and we do not have to write the code to save the edited values.

By default post edit navigation of cursor in FastEdit mode is similar to Excel, which we can override.

As I said earlier, recomputation of aggregates is automatic.

Code: Select all  Expand view  RUN

:nStretchCol            := STRETCHCOL_WIDEST
 


We are used to stretch the last column with the earlier browses. But imagine how ackward it would be to streatch a numeric column like Age or Salary? It gives a better appearance by streatching a text column, preferably the widest one. XBrowse provides a great flexibility here.

There are a lot more advanced feaures built into xbrowse and it is not possible to introduce all of them in one sample like this.

XBrowse can do almost all things that can be done with earlier browses and a lot more. One difference is that XBrowse does most of these things automatically while we need to write long lines of code ourselves in earlier browses.

Now, let us again look back at preedit, postedit functionality. There may be cases where the automatic features of xbrowse are not adequate or suitable in some situations. In such a case, we can use oCol:bOnChange := { |oCol,uOldValue| OurFunc( oCol, uOldValue). This codeblock is evaluated by XBrowse when the inline edit "changes" the value of a cell. Not called when the values are same before and after edit. We can access the new value with oCol:Value and the old value is provided as the second parameter.


XBrowse is a new paradigm in browsing. Let us not compare. Just use it and enjoy great functionality with minimal coding effort.

As I keep advising, move away from the legacy way of creating XBrowse and columns as in oBrw := TXBrowse():New(), oBrw:AddCol(), oCol:bStrData, etc. This is the surest way of telling XBrowse that I dont want to use your capabilities.
Regards

G. N. Rao.
Hyderabad, India
User avatar
nageswaragunupudi
 
Posts: 10690
Joined: Sun Nov 19, 2006 5:22 am
Location: India

Re: TSBrowse TXBrowse ?

Postby James Bott » Mon Jan 24, 2011 6:25 pm

Rao,

Thanks for that very detailed description of xBrowse.

I do have a question. It seems that bOnChange is evaluated post editing just like bPostEdit, correct? And so there is no way to do a pre-edit?

Regards,
James
User avatar
James Bott
 
Posts: 4840
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA

Re: TSBrowse TXBrowse ?

Postby nageswaragunupudi » Tue Jan 25, 2011 6:44 am

XBrowse column object has two datas bOnPreEdit (introduced very recently) and bOnPostEdit which is existing since the first release of XBrowse. But better not to confuse them with the preedit and postedit as in Mr. Avista's example. The purpose of these codeblocks in xbrowse are basically different.

bOnPostEdit:

This data has been there since the first release of XBrowse. In the initial version of xbrowse, this is the only way to save data after inline edit. After inline edit, this codeblock is called with oCol, uNewValue and nLastKey as parameters. The programmer was expected to specify how the data was to be saved in the table. Writing code for this is tricky, error-prone and differs for different datasources like array, dbf, objects, recsets, etc. Programmer has to code for locks, error conditions and so on.

In later versions, XBrowse automatically generates this codeblock in the following circumstances. (1) Columns are created through XBROWSE command or ADD COLUMN command or lAutoCols / aCols are specified in SetRDD() like methods. If we create columns with oBrw:AddCol() method, we need to provide our own bPostEdit block. The default codeblocks created by XBrowse are well tested and appropriate for the datasource. Using xbrowse's inbuilt facility makes it easier for us use the same code for different datasources. Example, we may first create xbrowse for RDD and then switch to TDatabase object. XBrowse automatically generates appropriate SETGET blocks and bOnPostEdit blocks. I advise that it is much safer to let this work done by xbrowse.

bOnPreEdit: (introduced very recently)

When inline edit of a cell is invoked by pressing a key, Enter or F2 the column's Edit() method creates a Get ( or other ) object for edit. In some rare situations, the programmer may like to extend or modify the functioning of the Get object, example, by having his own bKeyChar block for the Get. To enable this, oCol:bOnPreEdit is evaluated with column object as paramter after creation of the get object and before activating it.

Most of the times we do not have to deal with these two codeblocks.
Regards

G. N. Rao.
Hyderabad, India
User avatar
nageswaragunupudi
 
Posts: 10690
Joined: Sun Nov 19, 2006 5:22 am
Location: India


Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: No registered users and 16 guests