An easy way to make a tree-browse

User avatar
nageswaragunupudi
Posts: 8017
Joined: Sun Nov 19, 2006 5:22 am
Location: India
Contact:

An easy way to make a tree-browse

Post by nageswaragunupudi »

Code: Select all

#include "fivewin.ch"

REQUEST DBFCDX

function Main()

   field STATE,HIREDATE,CITY
   local oDlg, oFont, oBrw

   USE CUSTOMER NEW SHARED VIA "DBFCDX"
   INDEX ON STATE + STR(INT(YEAR(HIREDATE)/10)*10,4) + CITY TAG STATEYR TO TMP MEMORY
   GO TOP

   DEFINE FONT oFont NAME "TAHOMA" SIZE 0,-14
   DEFINE DIALOG oDlg SIZE 700,600 PIXEL TRUEPIXEL FONT oFont

   @ 20,20 XBROWSE oBrw SIZE -20,-20 PIXEL OF oDlg ;
      DATASOURCE "CUSTOMER" ;
      COLUMNS "STATE", "STRZERO(INT(YEAR(HIREDATE)/10)*10,4) AS DECADE", ;
              "CITY", "FIRST", "AGE", "HIREDATE", "SALARY" ;
      CELL LINES NOBORDER

   WITH OBJECT oBrw
      :AddBitmap( { FWDArrow(), FWRArrow(), "c:\fwh\bitmaps\treevh.bmp" } )
      :SetTree( 3 )
      :oTree:OpenAll()
      :lDisplayZeros := .f.
      //
      :CreateFromCode()
   END

   ACTIVATE DIALOG oDlg CENTERED
   RELEASE FONT oFont

return nil
 
Image
Regards

G. N. Rao.
Hyderabad, India
User avatar
ukoenig
Posts: 3981
Joined: Wed Dec 19, 2007 6:40 pm
Location: Germany
Contact:

Re: An easy way to make a tree-browse

Post by ukoenig »

Mr. Rao,

I added 3 quick preview-buttons to Your sample.
is it possible to change a treelevel on button-action ?.
I mean close, show level 1 or 2
( I used oBrw:oTree:OpenAll() for level 2 )

Image

regards
Uwe :?:
Last edited by ukoenig on Mon Jul 15, 2019 9:33 am, edited 8 times in total.
Since 1995 ( the first release of FW 1.9 )
i work with FW.
If you have any questions about special functions, maybe i can help.
User avatar
nageswaragunupudi
Posts: 8017
Joined: Sun Nov 19, 2006 5:22 am
Location: India
Contact:

Re: An easy way to make a tree-browse

Post by nageswaragunupudi »

please see these methods
METHOD OpenAll()
METHOD Expand( nLevel )
METHOD Collapse( nLevel )
in linklist.prg
Regards

G. N. Rao.
Hyderabad, India
User avatar
ukoenig
Posts: 3981
Joined: Wed Dec 19, 2007 6:40 pm
Location: Germany
Contact:

Re: An easy way to make a tree-browse

Post by ukoenig »

Thank You very much.
The infos I've been looking for to switch between the different levels.

@ 50,20 XBROWSE oBrw SIZE -20,-20 PIXEL OF oDlg ;
DATASOURCE "CUSTOMER" ;
COLUMNS "STATE", "STRZERO(INT(YEAR(HIREDATE)/10)*10,4) AS DECADE", ;
"CITY", "FIRST", "AGE", "HIREDATE", "SALARY" ;
CELL LINES NOBORDER
...
...

@ 10, 20 BTNBMP PROMPT "NO TREE" SIZE 100,30 PIXEL OF oDlg FLAT ;
ACTION ( oBrw:oTree:Collapse( 1 ), oBrw:Refresh() )

@ 10, 140 BTNBMP PROMPT "LEVEL 1" SIZE 100,30 PIXEL OF oDlg FLAT ;
ACTION ( oBrw:oTree:Expand( 2 ), oBrw:Refresh() )

@ 10, 260 BTNBMP PROMPT "LEVEL 2" SIZE 100,30 PIXEL OF oDlg FLAT ;
ACTION ( oBrw:oTree:OpenAll(), oBrw:Refresh() )


best regards
Uwe :D
Since 1995 ( the first release of FW 1.9 )
i work with FW.
If you have any questions about special functions, maybe i can help.
User avatar
ukoenig
Posts: 3981
Joined: Wed Dec 19, 2007 6:40 pm
Location: Germany
Contact:

Re: An easy way to make a tree-browse

Post by ukoenig »

Could it be possible to auto-close the old tree on rowchange and open
the tree on new rowselection straight with a defined level ?

normal ( some mouseclicks needed ) :
1. click : level 1
2. click : level 2
3. click : close
4. click : new row
c
Image

regards
Uwe :?:
Since 1995 ( the first release of FW 1.9 )
i work with FW.
If you have any questions about special functions, maybe i can help.
User avatar
vilian
Posts: 795
Joined: Wed Nov 09, 2005 2:17 am
Location: Brazil
Contact:

Re: An easy way to make a tree-browse

Post by vilian »

Mr Rao,

Could you show us a little/easy sample about how to a xbrowse/tree from an array ?
Sds,
Vilian F. Arraes
vilian@vfatec.com.br
Belém-Pa-Brazil
ShumingWang
Posts: 454
Joined: Sun Oct 30, 2005 6:37 am
Location: Guangzhou(Canton),China

Re: An easy way to make a tree-browse

Post by ShumingWang »

obrow2:setTree(otree)

ocol:=obrow2:aCols[ 1 ]
ocol:cheader:="科目代码"
ocol:AddBitmap( { "tree1", "tree2", "treevh" } )
// ocol:cFooter := "GRAND TOTAL"
ocol:nEditType := {||if(::ledit,1,0)}
ocol:bEditValue := {||odb2:cquery:="select * from ac where acid='"+obrow2:oTreeItem:cPrompt+"'",odb2:refresh(),obrow2:oTreeItem:cPrompt}
// on chang ,to refresh other columns datas

oCol:bOnPostEdit := {|o, v, n|if( n != VK_ESCAPE ,obrow2:oTreeItem:cPrompt := padr(v,nacidlen," ") ,)}
ocol:bpopup:={||acc0501(,,obrow2)}
// right click call popu menu
// insert sub grade tree item, insert new tree item, delete tree item

ocol:bLDClickData:={||acc0502(obrow2:otreeitem),obrow2:otreeitem:Toggle(),obrow2:refresh()}
//ldbl click tree
// dynamic expand sub trees


oCol := obrow2:AddCol()
oCol:bStrData := {||odb2:descrip}
oCol:cHeader := "科目名称"
oCol:bEditValue:= {||odb2:descrip}
oCol:nEditType:={||if(::ledit.and.!odb2:EOF(),1,0)}
oCol:bOnPostEdit := {|o, v, n| if( n != VK_ESCAPE .and. v != odb2:descrip,(odb2:descrip:=v,odb2:save()) , ) }

oCol := obrow2:AddCol()
oCol:bStrData := {||odb2:currency}
oCol:cHeader := "货币"
oCol:bEditValue:= {||odb2:currency}
ocol:nedittype:= {||if(::ledit.and.!odb2:EOF(),EDIT_GET_BUTTON,0)}
oCol:bEditBlock := {||currencybrw(odb2:currency)}
oCol:bOnPostEdit := {|o, v, n| if( n != VK_ESCAPE .and. v != odb2:currency,(v:=currencybrw(v,.t.),odb2:currency:=v,odb2:SAVE()) , ) }
oCol:nWidth := 60

....

// insert sub grade tree item, insert new tree item, delete tree item
FUNCTION acc0501(nrow,ncol,obrow2)
local itemid1,omenu2,acid1

MENU oMenu2 popup
MENUITEM "增加本阶" ACTION (acid1:=padr(obrow2:otreeitem:cprompt,nacidlen," "),msgget("新编码","",@acid1),;
oserver:query("insert into ac (acid,currency) select '"+acid1+"',currency from currency limit 1 on duplicate key update descrip=descrip"),;
if(MYSQL_AFFECTED_ROWS(oserver:nSocket)>0,(obrow2:otreeitem:add(acid1),obrow2:refresh()),))
MENUITEM "增加下阶 " ACTION (acid1:=padr(obrow2:otreeitem:cprompt,nacidlen," "),msgget("新编码","",@acid1),;
oserver:query("insert into ac (acid,facid,currency) select '"+acid1+"','"+obrow2:otreeitem:cprompt+"',currency from currency limit 1 on duplicate key update descrip=descrip"),;
if(MYSQL_AFFECTED_ROWS(oserver:nSocket)>0,(obrow2:otreeitem:addchild(acid1),obrow2:refresh()),))
MENUITEM "删除本阶" ACTION (if(msgyesno("删除当前代码","请确认"),(obrow2:odbf:DELETE(),if(!oserver:lerror,(obrow2:otreeitem:DELETE(),obrow2:refresh()),msgstop("该科目在凭证中已经使用,需要先在凭证里修改或者删除","停止"))),))
ENDMENU
return oMenu2

// dynamic expand sub trees
FUNCTION acc0502(otreeitem)
local odb1,otreeitem2
if otreeitem:otree==nil

odb1:=oserver:query("select acid from ac where facid='"+otreeitem:cprompt+"'")

while !odb1:EOF()
otreeitem2:=otreeitem:addchild(odb1:acid)

acc0502(otreeitem2)
otreeitem2:Toggle()
odb1:SKIP()
end
odb1:end()

end

return
User avatar
nageswaragunupudi
Posts: 8017
Joined: Sun Nov 19, 2006 5:22 am
Location: India
Contact:

Re: An easy way to make a tree-browse

Post by nageswaragunupudi »

vilian wrote:Mr Rao,

Could you show us a little/easy sample about how to a xbrowse/tree from an array ?

Code: Select all

#include "fivewin.ch"

function Main()

   local aData, oTree
   local oDlg, oFont, oBrw

   aData    := ;
   {  { "P00100", 00, 120 } ;
   ,  { "P00100", 01,  60 } ;
   ,  { "P00100", 02,  60 } ;
   ,  { "P00200", 00, 120 } ;
   ,  { "P00200", 01,  60 } ;
   ,  { "P00200", 02,  60 } ;
   ,  { "P00300", 00, 120 } ;
   ,  { "P00300", 01,  60 } ;
   ,  { "P00300", 02,  60 } ;
   }

   oTree    := BuildTree( aData )

   DEFINE FONT oFont NAME "TAHOMA" SIZE 0,-15
   DEFINE DIALOG oDlg SIZE 450,400 PIXEL TRUEPIXEL FONT oFont

   @ 20,20 XBROWSE oBrw SIZE -20,-20 PIXEL OF oDlg ;
      DATASOURCE oTree ;
      COLUMNS 2, 3 ;
      HEADERS "ITEM", "PART", "VALUE" ;
      PICTURES nil, "@L 99", "9,999.99" ;
      CELL LINES NOBORDER

   WITH OBJECT oBrw
      :lDisplayZeros := .f.
      :aCols[ 1 ]:AddBitmap( { FWDArrow(), FWRArrow(), GetTreeBmps()[ 2 ] } )
/*
      :aCols[ 3 ]:bEditValue  := { || ;
         If( oBrw:oTreeItem:nLevel == 1 .and. oBrw:oTreeItem:lOpened, 0, ;
             oBrw:oTreeItem:Cargo [ 3 ] ) }
*/
      :bClrStd := { || { CLR_BLACK, If( oBrw:oTreeItem:nLevel == 1, CLR_YELLOW, CLR_WHITE ) } }
      //
      :CreateFromCode()
   END

   ACTIVATE DIALOG oDlg CENTERED
   RELEASE FONT oFont

return nil

function BuildTree( aData )

   local oTree, oItem
   local cGrp, aRow

   TREE oTree
   for each aRow in aData
      if aRow[ 1 ] == cGrp
         if oItem:nLevel == 1
            TREE
         endif
         TREEITEM oItem PROMPT aRow[ 1 ] + "-" + STRZERO( aRow[ 2 ], 2 ) ;
                        CARGO aRow
      else
         if oItem != nil .and. oItem:nLevel > 1
            ENDTREE
         endif
         cGrp  := aRow[ 1 ]
         TREEITEM oItem PROMPT cGrp CARGO aRow
      endif
   next
   ENDTREE

   oTree:OpenAll()

return oTree
 
Regards

G. N. Rao.
Hyderabad, India
User avatar
vilian
Posts: 795
Joined: Wed Nov 09, 2005 2:17 am
Location: Brazil
Contact:

Re: An easy way to make a tree-browse

Post by vilian »

Thank you,

It's exactly I need :)
Sds,
Vilian F. Arraes
vilian@vfatec.com.br
Belém-Pa-Brazil
User avatar
MarioG
Posts: 1356
Joined: Fri Oct 14, 2005 1:28 pm
Location: Resistencia - Chaco - AR

Re: An easy way to make a tree-browse

Post by MarioG »

nageswaragunupudi wrote:
vilian wrote:Mr Rao,

Could you show us a little/easy sample about how to a xbrowse/tree from an array ?

Code: Select all

#include "fivewin.ch"

function Main()

   local aData, oTree
   local oDlg, oFont, oBrw

   aData    := ;
   {  { "P00100", 00, 120 } ;
   ,  { "P00100", 01,  60 } ;
   ,  { "P00100", 02,  60 } ;
   ,  { "P00200", 00, 120 } ;
   ,  { "P00200", 01,  60 } ;
   ,  { "P00200", 02,  60 } ;
   ,  { "P00300", 00, 120 } ;
   ,  { "P00300", 01,  60 } ;
   ,  { "P00300", 02,  60 } ;
   }

   oTree    := BuildTree( aData )

   DEFINE FONT oFont NAME "TAHOMA" SIZE 0,-15
   DEFINE DIALOG oDlg SIZE 450,400 PIXEL TRUEPIXEL FONT oFont

   @ 20,20 XBROWSE oBrw SIZE -20,-20 PIXEL OF oDlg ;
      DATASOURCE oTree ;
      COLUMNS 2, 3 ;
      HEADERS "ITEM", "PART", "VALUE" ;
      PICTURES nil, "@L 99", "9,999.99" ;
      CELL LINES NOBORDER

   WITH OBJECT oBrw
      :lDisplayZeros := .f.
      :aCols[ 1 ]:AddBitmap( { FWDArrow(), FWRArrow(), GetTreeBmps()[ 2 ] } )
/*
      :aCols[ 3 ]:bEditValue  := { || ;
         If( oBrw:oTreeItem:nLevel == 1 .and. oBrw:oTreeItem:lOpened, 0, ;
             oBrw:oTreeItem:Cargo [ 3 ] ) }
*/
      :bClrStd := { || { CLR_BLACK, If( oBrw:oTreeItem:nLevel == 1, CLR_YELLOW, CLR_WHITE ) } }
      //
      :CreateFromCode()
   END

   ACTIVATE DIALOG oDlg CENTERED
   RELEASE FONT oFont

return nil

function BuildTree( aData )

   local oTree, oItem
   local cGrp, aRow

   TREE oTree
   for each aRow in aData
      if aRow[ 1 ] == cGrp
         if oItem:nLevel == 1
            TREE
         endif
         TREEITEM oItem PROMPT aRow[ 1 ] + "-" + STRZERO( aRow[ 2 ], 2 ) ;
                        CARGO aRow
      else
         if oItem != nil .and. oItem:nLevel > 1
            ENDTREE
         endif
         cGrp  := aRow[ 1 ]
         TREEITEM oItem PROMPT cGrp CARGO aRow
      endif
   next
   ENDTREE

   oTree:OpenAll()

return oTree
 
Hi
I have a tree of two levels (MariaDb's objetc)
I need to evaluate if the 2nd Level is open.
If open, Then I take an action.
Only when double click on 2nd Level
How I do it?
Thanks
Resistencia - "Ciudad de las Esculturas"
Chaco - Argentina
User avatar
nageswaragunupudi
Posts: 8017
Joined: Sun Nov 19, 2006 5:22 am
Location: India
Contact:

Re: An easy way to make a tree-browse

Post by nageswaragunupudi »

You can trigger an action on double click with the codeblock

Code: Select all

oCol:bLDClickData := { |r,c,f,col| someaction( r,c,f,col ) }
 
Inside the function, check for

Code: Select all

if oCol:oBrw:oTreeItem:nLevel == 2
   // action
endif
return nil
 
Regards

G. N. Rao.
Hyderabad, India
User avatar
MarioG
Posts: 1356
Joined: Fri Oct 14, 2005 1:28 pm
Location: Resistencia - Chaco - AR

Re: An easy way to make a tree-browse

Post by MarioG »

Good Morning (for me)
Many Thanks Mr. Rao!

I looked at in TxBrowse, TXBrwColumn and TLinkList class and not find :oBrw:oTreeItem. Where is it?
Resistencia - "Ciudad de las Esculturas"
Chaco - Argentina
User avatar
nageswaragunupudi
Posts: 8017
Joined: Sun Nov 19, 2006 5:22 am
Location: India
Contact:

Re: An easy way to make a tree-browse

Post by nageswaragunupudi »

XBrowse has DATA oTreeItem
Regards

G. N. Rao.
Hyderabad, India
User avatar
MarioG
Posts: 1356
Joined: Fri Oct 14, 2005 1:28 pm
Location: Resistencia - Chaco - AR

Re: An easy way to make a tree-browse

Post by MarioG »

Resistencia - "Ciudad de las Esculturas"
Chaco - Argentina
User avatar
MarioG
Posts: 1356
Joined: Fri Oct 14, 2005 1:28 pm
Location: Resistencia - Chaco - AR

Re: An easy way to make a tree-browse

Post by MarioG »

Hello Mr Rao
I'm using a Tree and it's good
I'm using the same oTree:MakeTree() that your sample
but when i send oTree:CollapseAll()
it collapse the app

Error occurred at: 20/11/2019, 19:37:33
Error description: Error BASE/1004 Message not found: TLINKLIST:COLLAPSEALL
Args:
[ 1] = O TLINKLIST

Stack Calls
===========
Called from: => __ERRRT_SBASE( 0 )
Called from: ../../../tobject.prg => TLINKLIST:ERROR( 0 )
Called from: ../../../tobject.prg => (b)HBOBJECT( 0 )
Called from: ../../../tobject.prg => TLINKLIST:MSGNOTFOUND( 0 )
Called from: ../../../tobject.prg => TLINKLIST:COLLAPSEALL( 0 )
Called from: D:\Fuen32\FeHot\Source\FeH_TGes.prg => (b)TGESTION_RESERVAS( 115 )

what is wrong?
Resistencia - "Ciudad de las Esculturas"
Chaco - Argentina
Post Reply