Capture click ou key in tree

Capture click ou key in tree

Postby wartiaga » Fri Aug 20, 2021 12:00 pm

Hi,

How I capture key or mouse click in tree object?

Thanks in advance.
wartiaga
 
Posts: 212
Joined: Wed May 25, 2016 1:04 am

Re: Capture click ou key in tree

Postby Antonio Linares » Fri Aug 20, 2021 12:27 pm

oTree:bChanged = { | oItem |... }

Please review FWH\samples\pim.prg
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42103
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Capture click ou key in tree

Postby wartiaga » Fri Aug 20, 2021 12:51 pm

Antonio Linares wrote:oTree:bChanged = { | oItem |... }

Please review FWH\samples\pim.prg


Thanks Antonio but I don't have this sample in samples examples. I understand that bChanged I can capture moves in tree object but how I cant test if enter or click are pressed?
wartiaga
 
Posts: 212
Joined: Wed May 25, 2016 1:04 am

Re: Capture click ou key in tree

Postby Antonio Linares » Fri Aug 20, 2021 1:24 pm

pim.prg
Code: Select all  Expand view  RUN
// FiveWin PIM (personal information manager)

#include "FiveWin.ch"
#include "Splitter.ch"
#include "xbrowse.ch"
#include "c:\harbour\contrib\xhb\hbxml.ch"
#include "RichEdi5.ch"

#define TV_FIRST           4352
#define TVM_EDITLABEL      ( TV_FIRST + 14 )

static oWnd, oBtnSave, oImageList, oMruRCs
           
//----------------------------------------------------------------------------//
                   
function Main()    
                   
   local oBar, oMenuNew
   local oBmpTiled

   SetKey( VK_F12, { || If( oWnd:oWndActive != nil, oWnd:oWndActive:aControls[ 2 ]:SetFocus(),) } )
   SetKey( VK_F11, { || If( oWnd:oWndActive != nil, oWnd:oWndActive:aControls[ 1 ]:SetFocus(),) } )
   
   DEFINE BITMAP oBmpTiled RESOURCE "background"

   DEFINE WINDOW oWnd FROM 3, 6 TO 20, 70 ;
      TITLE FWVERSION + " PIM" ;
      MENU BuildMenu() MDI
                   
   DEFINE BUTTONBAR oBar SIZE 70, 70 OF oWnd 2010
                   
   DEFINE BUTTON OF oBar PROMPT "New" ;
      TOOLTIP "New" NOBORDER RESOURCE "New" ;
      ACTION NewDataFile()
                   
   DEFINE BUTTON OF oBar PROMPT "Open" ;
      TOOLTIP "Open" NOBORDER RESOURCE "Open" ;
      ACTION OpenDataFile()
                   
   DEFINE BUTTON oBtnSave OF oBar PROMPT "Save" ;
      TOOLTIP "Save" NOBORDER RESOURCE "Save" ACTION Save()
     
   oBtnSave:Disable()  

   DEFINE BUTTON OF oBar GROUP PROMPT "Exit" ;
      TOOLTIP "Exit" NOBORDER RESOURCE "Exit" ACTION oWnd:End()

   oImageList = TImageList():New()

   oImageList:Add( TBitmap():Define( "folder",,  oWnd ),;
                   TBitmap():Define( "fldmask",, oWnd ) )
   oImageList:Add( TBitmap():Define( "dialog",,  oWnd ),;
                   TBitmap():Define( "dlgmask",, oWnd ) )
   oImageList:Add( TBitmap():Define( "icon",,    oWnd ),;
                   TBitmap():Define( "icomask",, oWnd ) )
   oImageList:Add( TBitmap():Define( "bitmap",,  oWnd ),;
                   TBitmap():Define( "bmpmask",, oWnd ) )
   oImageList:Add( TBitmap():Define( "includes",, oWnd ),;
                   TBitmap():Define( "incmask",, oWnd ) )

   DEFINE MSGBAR OF oWnd PROMPT "Personal Information Manager (c) FiveTech Software 2020" DATE KEYBOARD 2010

   ACTIVATE WINDOW oWnd MAXIMIZED ;
      ON PAINT DrawTiled( hDC, oWnd, oBmpTiled )
      // VALID MsgYesNo( "Want to end ?" )

   oBmpTiled:End()
   oImageList:End()
 
return nil

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

function BuildMenu()

   local oMenu

   MENU oMenu 2007
      MENUITEM "&File"
      MENU
         MENUITEM "&New"  RESOURCE "new2"
         MENUITEM "&Open" RESOURCE "Open2" ;
            ACTION OpenDataFile()

         MENUITEM "&Save as..."
         SEPARATOR
   
         MENUITEM "Recent files"
         MENU
            MRU oMruRCs ;
               FILENAME ".\re.ini" ;    // .INI to manipulate. '\.' for local
               SECTION  "Recent RC files" ; // The name of the INI section
               ACTION   OpenDataFile( cMruItem ) ;   // cMruItem is automatically provided
               MESSAGE  "Open this file" ;   // The message for all of them
               SIZE     10
         ENDMENU
         
         SEPARATOR
         
         MENUITEM "&Exit..." ACTION oWnd:End() RESOURCE "Exit2"
      ENDMENU
      MENUITEM "&Edit"
      oMenu:AddMDI()
      oMenu:AddHelp( "FiveWin Resources Editor", "FiveTech 1993-2018" )
   ENDMENU

return oMenu

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

function Save()

   local oTreeView := oWnd:oWndActive:aControls[ 1 ]
   local cText := "", cFileName := oWnd:oWndActive:GetText()
   
   oTreeView:Scan( { | oItem, nItem | BuildXML( oItem, @cText, nItem, oTreeView ) }, .F. )
   cText += CRLF + "</xml>"

   if File( cFileName )
      if MsgYesNo( "Do you want to overwrite " + cFileName + " ?",;
                   cFileName + " already exists" )
         hb_MemoWrit( cFileName, cText, .F. )
      endif  
   else
      hb_MemoWrit( cFileName, cText, .F. )
   endif
   oBtnSave:Disable()
   
return nil  

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

function BuildXML( oItem, cText, nItem, oTree )

   // local c

   if oItem:oParent != nil
      cText += CRLF
   endif
   
   if oItem:oParent == nil .and. nItem == 1
      if oItem:cPrompt != "xml"
         oItem:Cargo = oItem:cPrompt
         oItem:cPrompt = "xml"
         cText += "<" + oItem:Cargo + ">"
      endif
   endif      

   if " " $ oItem:cPrompt
      oItem:cPrompt = StrTran( oItem:cPrompt, " ", "_" )
   endif  

   cText += "<" + If( ! Empty( oItem:cPrompt ), oItem:cPrompt, "" ) + ">"

   if ! Empty( oItem:Cargo )
      cText += StrTran( oItem:Cargo, Chr( 0 ), "" )
   endif    

   if oItem:oParent != nil
      if Len( oItem:aItems ) == 0
         cText += CRLF + "</" + oItem:cPrompt + ">"
         // c = CRLF + "</" + oItem:cPrompt + ">"
         while oItem:oParent != nil .and. oItem == ATail( oItem:oParent:aItems )
            if oItem:oParent:cPrompt != "xml"
               cText += CRLF + "</" + oItem:oParent:cPrompt + ">"
               // c += CRLF + "</" + oItem:oParent:cPrompt + ">"
            endif
            oItem = oItem:oParent
         end  
         // MsgInfo( c )
      endif      
   endif  

return .F.  // so it iterates the entire tree

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

function NewDataFile( cFileName )

   local oWndData, oTree, oMemo, cItemText := "", oSplit

   DEFAULT cFileName := cNewFileName( "new", "xml" )

   DEFINE WINDOW oWndData TITLE cFileName MDICHILD

   oTree = TTreeView():New( 2, 0, oWndData,,,,,,,,,, .T. ) // lEditable
   oTree:bChanged = { | oItem | oItem := oTree:GetSelected(),;
                      if( oItem != nil, ;
                         if( !Empty( oItem:Cargo ), ;
                             oMemo:LoadRTF( oItem:Cargo, !oMemo:IsTextRtf( oItem:Cargo ) ), ;
                                 oMemo:SetText( "" ) ), oMemo:SetText( "" ) ) }
                     
   // oTree:bLDblClick = { || ShowItem( oTree:GetSelected() ) }                  
   oTree:bRClicked = { | nRow, nCol | EditTree( nRow, nCol, oWndData, oTree ) }
   oTree:bKeyChar = { | nKey | If( nKey == 43, TreeAddItem( oTree ),) }

   oTree:SetImageList( oImageList )
   oTree:nWidth += 48

   if ! File( cFileName )
      hb_MemoWrit( cFileName, '<xml>version="1.0"<new></new></xml>', .F. )
      OpenXml( cFileName, oTree )
      oTree:ExpandAll()
   endif  

   // @ 0, 25.7 GET oMemo VAR cItemText MEMO OF oWndData SIZE 300, 100 ;
   //    ON CHANGE ( oBtnSave:Enable(), oMemo:Cargo := .T.,;
   //                oTree:GetSelected():Cargo := cItemText )

   @ 0, 205 RICHEDIT5 oMemo VAR cItemText OF oWndData SIZE 300, 100 PIXEL BARBUTTON ;
      ON CHANGE ( cItemText := oMemo:SaveAsRTF(), oBtnSave:Enable(), oMemo:Cargo := .T.,;
                  If( oTree:GetSelected() != nil, oTree:GetSelected():Cargo := cItemText,) )                  
                 
   oMemo:Cargo = .F. // it has not changed              

   @ 0, 200 SPLITTER oSplit ;
      VERTICAL ;
      PREVIOUS CONTROLS oTree ;
      HINDS CONTROLS oMemo ;
      SIZE 4, 200 PIXEL ;
      OF oWndData
     
   oSplit:AdjClient()  

   ACTIVATE WINDOW oWndData ;
      ON RESIZE oSplit:AdjClient()
     
   oWndData:bGotFocus = { || If( oMemo:Cargo, oBtnSave:Enable(), oBtnSave:Disable() ) }  

return nil

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

function OpenDataFile( cFileName )

   local cTxtFile, oTree

   DEFAULT cFileName := cGetFile( "XML files (*.xml) |*.xml| JSON files (*.json)", "Select a data file" )

   if Empty( cFileName )
      return nil
   endif  

   oMruRCs:Save( cFileName )
   oBtnSave:Disable()

   NewDataFile( cFileName )
   oTree = oWnd:oWndActive:aControls[ 1 ]

   if ! Empty( cFileName )        
      do case
         case Upper( cFileExt( cFileName ) ) == "XML"
            if ! OpenXML( cFileName, oTree )
               oWnd:oWndActive:End()
            else
               oTree:ExpandAll()
               oTree:GoTop()
            endif  
           
         case Upper( cFileExt( cFileName ) ) == "JSON"
            OpenJSON( cFileName, oTree )
      endcase
   endif  
     
return nil

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

function OpenXML( cFileName, oTree )

   local aRoots := {}, hFile, oXmlDoc, oXmlIter, oTagLast, oTagActual, oCol

   hFile    = FOpen( cFileName )
   oXmlDoc  = TXmlDocument():New( hFile )
   oXmlIter = TXmlIterator():New( oXmlDoc:oRoot )

   if oXmlDoc:nError != 0
      MsgStop( "Filename: " + cFileName + CRLF + ;
               "Line " + AllTrim( Str( oXmlDoc:nLine ) ) + CRLF + ;
               "Description: " + XmlError( oXmlDoc:nError ) + CRLF + ;
               "Node: <" + If( ! Empty( oXmlDoc:oErrorNode:cName ), oXmlDoc:oErrorNode:cName, "" ) + ;
               ">", "XML error" )
      return .F.        
   endif

   // XBrowse( oXmlDoc )
   
   AAdd( aRoots, oTree )

   while ( oTagActual := oXmlIter:Next() ) != nil
      // XBROWSER oTagActual ;
      //    SETUP ( oCol := oBrw:AddCol(), oCol:bStrData := { || oTagActual:Depth() }, oCol:cHeader := "Depth" )
     
      // MsgInfo( oTagActual:cName )

      if oTagLast != nil
         if oTagLast:Depth() < oTagActual:Depth()
            AAdd( aRoots, nil )
            aRoots[ oTagActual:Depth() + 1 ] = aRoots[ oTagActual:Depth() ]:Add( oTagActual:cName )
            aRoots[ oTagActual:Depth() + 1 ]:Cargo = oTagActual:cData
         endif

         if oTagLast:Depth() > oTagActual:Depth()
            aRoots[ oTagActual:depth() + 1 ] = aRoots[ oTagActual:Depth() ]:Add( oTagActual:cName )
            aRoots[ oTagActual:depth() + 1 ]:Cargo = oTagActual:cData
         endif

         if oTagLast:Depth() == oTagActual:Depth()
            aRoots[ oTagActual:Depth() + 1 ] = aRoots[ Max( oTagLast:Depth(), 1 ) ]:Add( oTagActual:cName )
            aRoots[ oTagActual:Depth() + 1 ]:Cargo = oTagActual:cData                                        
         endif
      else
         AAdd( aRoots, oTree:Add( oTagActual:cName ) )
         ATail( aRoots ):Cargo = oTagActual:cData
      endif
      oTagLast = oTagActual
   end

   FClose( hFile )

return .T.      

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

function OpenJSON( cFileName )

return nil    

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

function ShowImage( cBmp )

   local oDlg, oBmp
   
   DEFINE DIALOG oDlg TITLE cBmp

   if Lower( Right( cBmp, 3 ) ) == "bmp"
      @ 0, 0 BITMAP oBmp FILENAME cBmp OF oDlg NOBORDER
   elseif Lower( Right( cBmp, 3 ) ) == "ico"
      @ 0, 0 ICON oBmp FILENAME cBmp OF oDlg
   endif    
   
   ACTIVATE DIALOG oDlg CENTERED ;
      ON INIT ( oDlg:SetSize( Max( 300, oBmp:nWidth + 20 ),;
                              Max( 300, oBmp:nHeight + 20 ) ),;
                oBmp:Center( oDlg ), oDlg:Center() )              
   
return nil  

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

function TreeAddItem( oTree )

   local oItem := oTree:GetSelected()

   if oItem != nil .and. oItem:oParent != nil
      oItem = oTree:GetSelected():oParent:Add( "new" )
      oTree:Select( oItem )
      oTree:Refresh()
      TreeEditItem( oTree )
      oBtnSave:Enable()
   endif
   
return nil  

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

function TreeEditItem( oTree )
 
   local oItem := oTree:GetSelected()

   if oItem != nil
      PostMessage( oTree:hWnd, TVM_EDITLABEL, 0, oItem:hItem )
   endif

return nil

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

function EditTree( nRow, nCol, oWndData, oTree )

   local oPopup, cPrompt, oItem
   
   MENU oPopup POPUP 2015
      MENUITEM "&Add"       RESOURCE "plus" ACTION TreeAddItem( oTree )
      MENUITEM "Add &child" ACTION If( oTree:GetSelected() != nil,;
                                  ( oTree:GetSelected():Add( "new" ), oTree:Refresh(), oBtnSave:Enable() ),)
      MENUITEM "&Edit"      RESOURCE "edit" ACTION TreeEditItem( oTree )  
      MENUITEM "&Delete"    ACTION If( oTree:GetSelected() != nil,;
                                  ( oTree:GetSelected():End(), oTree:Refresh(), oBtnSave:Enable() ),)
      SEPARATOR
      MENUITEM "&Open all"  ACTION oTree:ExpandAll()
      MENUITEM "&Close all" ACTION oTree:CollapseAll()  
      SEPARATOR
      MENUITEM "Move &Up"   ACTION oTree:GoPrev()                          
      MENUITEM "Move Dow&n" ACTION oTree:GoNext()  
      MENUITEM "Swap up"    ACTION oTree:SwapUp()
      MENUITEM "Swap Down"  ACTION oTree:SwapDown()                        
   ENDMENU  

   ACTIVATE POPUP oPopup WINDOW oWndData AT nRow, nCol

return nil

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

function XmlError( nError )

   local aErrors := { "HBXML_ERROR_IO", "HBXML_ERROR_NOMEM", "HBXML_ERROR_OUTCHAR",;
                      "HBXML_ERROR_INVNODE", "HBXML_ERROR_INVATT", "HBXML_ERROR_MALFATT",;
                      "HBXML_ERROR_INVCHAR", "HBXML_ERROR_NAMETOOLONG", "HBXML_ERROR_ATTRIBTOOLONG",;
                      "HBXML_ERROR_VALATTOOLONG", "HBXML_ERROR_UNCLOSED", "HBXML_ERROR_UNCLOSEDENTITY",;
                      "HBXML_ERROR_WRONGENTITY" }

return If( nError > 0 .and. nError < 14, aErrors[ nError ], "error range must be 1-13" )

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

static function GenDblClickBlock( oCtrl )

return { || MsgInfo( oCtrl:nId ) }

//----------------------------------------------------------------------------//
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42103
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Capture click ou key in tree

Postby Antonio Linares » Fri Aug 20, 2021 1:26 pm

oTree:bKeyChar = { | nKey | If( nKey == 13, MsgInfo( "enter" ),) }
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42103
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Capture click ou key in tree

Postby wartiaga » Fri Aug 20, 2021 1:27 pm

Antonio Linares wrote:pim.prg
Code: Select all  Expand view  RUN
// FiveWin PIM (personal information manager)

#include "FiveWin.ch"
#include "Splitter.ch"
#include "xbrowse.ch"
#include "c:\harbour\contrib\xhb\hbxml.ch"
#include "RichEdi5.ch"

#define TV_FIRST           4352
#define TVM_EDITLABEL      ( TV_FIRST + 14 )

static oWnd, oBtnSave, oImageList, oMruRCs
           
//----------------------------------------------------------------------------//
                   
function Main()    
                   
   local oBar, oMenuNew
   local oBmpTiled

   SetKey( VK_F12, { || If( oWnd:oWndActive != nil, oWnd:oWndActive:aControls[ 2 ]:SetFocus(),) } )
   SetKey( VK_F11, { || If( oWnd:oWndActive != nil, oWnd:oWndActive:aControls[ 1 ]:SetFocus(),) } )
   
   DEFINE BITMAP oBmpTiled RESOURCE "background"

   DEFINE WINDOW oWnd FROM 3, 6 TO 20, 70 ;
      TITLE FWVERSION + " PIM" ;
      MENU BuildMenu() MDI
                   
   DEFINE BUTTONBAR oBar SIZE 70, 70 OF oWnd 2010
                   
   DEFINE BUTTON OF oBar PROMPT "New" ;
      TOOLTIP "New" NOBORDER RESOURCE "New" ;
      ACTION NewDataFile()
                   
   DEFINE BUTTON OF oBar PROMPT "Open" ;
      TOOLTIP "Open" NOBORDER RESOURCE "Open" ;
      ACTION OpenDataFile()
                   
   DEFINE BUTTON oBtnSave OF oBar PROMPT "Save" ;
      TOOLTIP "Save" NOBORDER RESOURCE "Save" ACTION Save()
     
   oBtnSave:Disable()  

   DEFINE BUTTON OF oBar GROUP PROMPT "Exit" ;
      TOOLTIP "Exit" NOBORDER RESOURCE "Exit" ACTION oWnd:End()

   oImageList = TImageList():New()

   oImageList:Add( TBitmap():Define( "folder",,  oWnd ),;
                   TBitmap():Define( "fldmask",, oWnd ) )
   oImageList:Add( TBitmap():Define( "dialog",,  oWnd ),;
                   TBitmap():Define( "dlgmask",, oWnd ) )
   oImageList:Add( TBitmap():Define( "icon",,    oWnd ),;
                   TBitmap():Define( "icomask",, oWnd ) )
   oImageList:Add( TBitmap():Define( "bitmap",,  oWnd ),;
                   TBitmap():Define( "bmpmask",, oWnd ) )
   oImageList:Add( TBitmap():Define( "includes",, oWnd ),;
                   TBitmap():Define( "incmask",, oWnd ) )

   DEFINE MSGBAR OF oWnd PROMPT "Personal Information Manager (c) FiveTech Software 2020" DATE KEYBOARD 2010

   ACTIVATE WINDOW oWnd MAXIMIZED ;
      ON PAINT DrawTiled( hDC, oWnd, oBmpTiled )
      // VALID MsgYesNo( "Want to end ?" )

   oBmpTiled:End()
   oImageList:End()
 
return nil

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

function BuildMenu()

   local oMenu

   MENU oMenu 2007
      MENUITEM "&File"
      MENU
         MENUITEM "&New"  RESOURCE "new2"
         MENUITEM "&Open" RESOURCE "Open2" ;
            ACTION OpenDataFile()

         MENUITEM "&Save as..."
         SEPARATOR
   
         MENUITEM "Recent files"
         MENU
            MRU oMruRCs ;
               FILENAME ".\re.ini" ;    // .INI to manipulate. '\.' for local
               SECTION  "Recent RC files" ; // The name of the INI section
               ACTION   OpenDataFile( cMruItem ) ;   // cMruItem is automatically provided
               MESSAGE  "Open this file" ;   // The message for all of them
               SIZE     10
         ENDMENU
         
         SEPARATOR
         
         MENUITEM "&Exit..." ACTION oWnd:End() RESOURCE "Exit2"
      ENDMENU
      MENUITEM "&Edit"
      oMenu:AddMDI()
      oMenu:AddHelp( "FiveWin Resources Editor", "FiveTech 1993-2018" )
   ENDMENU

return oMenu

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

function Save()

   local oTreeView := oWnd:oWndActive:aControls[ 1 ]
   local cText := "", cFileName := oWnd:oWndActive:GetText()
   
   oTreeView:Scan( { | oItem, nItem | BuildXML( oItem, @cText, nItem, oTreeView ) }, .F. )
   cText += CRLF + "</xml>"

   if File( cFileName )
      if MsgYesNo( "Do you want to overwrite " + cFileName + " ?",;
                   cFileName + " already exists" )
         hb_MemoWrit( cFileName, cText, .F. )
      endif  
   else
      hb_MemoWrit( cFileName, cText, .F. )
   endif
   oBtnSave:Disable()
   
return nil  

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

function BuildXML( oItem, cText, nItem, oTree )

   // local c

   if oItem:oParent != nil
      cText += CRLF
   endif
   
   if oItem:oParent == nil .and. nItem == 1
      if oItem:cPrompt != "xml"
         oItem:Cargo = oItem:cPrompt
         oItem:cPrompt = "xml"
         cText += "<" + oItem:Cargo + ">"
      endif
   endif      

   if " " $ oItem:cPrompt
      oItem:cPrompt = StrTran( oItem:cPrompt, " ", "_" )
   endif  

   cText += "<" + If( ! Empty( oItem:cPrompt ), oItem:cPrompt, "" ) + ">"

   if ! Empty( oItem:Cargo )
      cText += StrTran( oItem:Cargo, Chr( 0 ), "" )
   endif    

   if oItem:oParent != nil
      if Len( oItem:aItems ) == 0
         cText += CRLF + "</" + oItem:cPrompt + ">"
         // c = CRLF + "</" + oItem:cPrompt + ">"
         while oItem:oParent != nil .and. oItem == ATail( oItem:oParent:aItems )
            if oItem:oParent:cPrompt != "xml"
               cText += CRLF + "</" + oItem:oParent:cPrompt + ">"
               // c += CRLF + "</" + oItem:oParent:cPrompt + ">"
            endif
            oItem = oItem:oParent
         end  
         // MsgInfo( c )
      endif      
   endif  

return .F.  // so it iterates the entire tree

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

function NewDataFile( cFileName )

   local oWndData, oTree, oMemo, cItemText := "", oSplit

   DEFAULT cFileName := cNewFileName( "new", "xml" )

   DEFINE WINDOW oWndData TITLE cFileName MDICHILD

   oTree = TTreeView():New( 2, 0, oWndData,,,,,,,,,, .T. ) // lEditable
   oTree:bChanged = { | oItem | oItem := oTree:GetSelected(),;
                      if( oItem != nil, ;
                         if( !Empty( oItem:Cargo ), ;
                             oMemo:LoadRTF( oItem:Cargo, !oMemo:IsTextRtf( oItem:Cargo ) ), ;
                                 oMemo:SetText( "" ) ), oMemo:SetText( "" ) ) }
                     
   // oTree:bLDblClick = { || ShowItem( oTree:GetSelected() ) }                  
   oTree:bRClicked = { | nRow, nCol | EditTree( nRow, nCol, oWndData, oTree ) }
   oTree:bKeyChar = { | nKey | If( nKey == 43, TreeAddItem( oTree ),) }

   oTree:SetImageList( oImageList )
   oTree:nWidth += 48

   if ! File( cFileName )
      hb_MemoWrit( cFileName, '<xml>version="1.0"<new></new></xml>', .F. )
      OpenXml( cFileName, oTree )
      oTree:ExpandAll()
   endif  

   // @ 0, 25.7 GET oMemo VAR cItemText MEMO OF oWndData SIZE 300, 100 ;
   //    ON CHANGE ( oBtnSave:Enable(), oMemo:Cargo := .T.,;
   //                oTree:GetSelected():Cargo := cItemText )

   @ 0, 205 RICHEDIT5 oMemo VAR cItemText OF oWndData SIZE 300, 100 PIXEL BARBUTTON ;
      ON CHANGE ( cItemText := oMemo:SaveAsRTF(), oBtnSave:Enable(), oMemo:Cargo := .T.,;
                  If( oTree:GetSelected() != nil, oTree:GetSelected():Cargo := cItemText,) )                  
                 
   oMemo:Cargo = .F. // it has not changed              

   @ 0, 200 SPLITTER oSplit ;
      VERTICAL ;
      PREVIOUS CONTROLS oTree ;
      HINDS CONTROLS oMemo ;
      SIZE 4, 200 PIXEL ;
      OF oWndData
     
   oSplit:AdjClient()  

   ACTIVATE WINDOW oWndData ;
      ON RESIZE oSplit:AdjClient()
     
   oWndData:bGotFocus = { || If( oMemo:Cargo, oBtnSave:Enable(), oBtnSave:Disable() ) }  

return nil

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

function OpenDataFile( cFileName )

   local cTxtFile, oTree

   DEFAULT cFileName := cGetFile( "XML files (*.xml) |*.xml| JSON files (*.json)", "Select a data file" )

   if Empty( cFileName )
      return nil
   endif  

   oMruRCs:Save( cFileName )
   oBtnSave:Disable()

   NewDataFile( cFileName )
   oTree = oWnd:oWndActive:aControls[ 1 ]

   if ! Empty( cFileName )        
      do case
         case Upper( cFileExt( cFileName ) ) == "XML"
            if ! OpenXML( cFileName, oTree )
               oWnd:oWndActive:End()
            else
               oTree:ExpandAll()
               oTree:GoTop()
            endif  
           
         case Upper( cFileExt( cFileName ) ) == "JSON"
            OpenJSON( cFileName, oTree )
      endcase
   endif  
     
return nil

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

function OpenXML( cFileName, oTree )

   local aRoots := {}, hFile, oXmlDoc, oXmlIter, oTagLast, oTagActual, oCol

   hFile    = FOpen( cFileName )
   oXmlDoc  = TXmlDocument():New( hFile )
   oXmlIter = TXmlIterator():New( oXmlDoc:oRoot )

   if oXmlDoc:nError != 0
      MsgStop( "Filename: " + cFileName + CRLF + ;
               "Line " + AllTrim( Str( oXmlDoc:nLine ) ) + CRLF + ;
               "Description: " + XmlError( oXmlDoc:nError ) + CRLF + ;
               "Node: <" + If( ! Empty( oXmlDoc:oErrorNode:cName ), oXmlDoc:oErrorNode:cName, "" ) + ;
               ">", "XML error" )
      return .F.        
   endif

   // XBrowse( oXmlDoc )
   
   AAdd( aRoots, oTree )

   while ( oTagActual := oXmlIter:Next() ) != nil
      // XBROWSER oTagActual ;
      //    SETUP ( oCol := oBrw:AddCol(), oCol:bStrData := { || oTagActual:Depth() }, oCol:cHeader := "Depth" )
     
      // MsgInfo( oTagActual:cName )

      if oTagLast != nil
         if oTagLast:Depth() < oTagActual:Depth()
            AAdd( aRoots, nil )
            aRoots[ oTagActual:Depth() + 1 ] = aRoots[ oTagActual:Depth() ]:Add( oTagActual:cName )
            aRoots[ oTagActual:Depth() + 1 ]:Cargo = oTagActual:cData
         endif

         if oTagLast:Depth() > oTagActual:Depth()
            aRoots[ oTagActual:depth() + 1 ] = aRoots[ oTagActual:Depth() ]:Add( oTagActual:cName )
            aRoots[ oTagActual:depth() + 1 ]:Cargo = oTagActual:cData
         endif

         if oTagLast:Depth() == oTagActual:Depth()
            aRoots[ oTagActual:Depth() + 1 ] = aRoots[ Max( oTagLast:Depth(), 1 ) ]:Add( oTagActual:cName )
            aRoots[ oTagActual:Depth() + 1 ]:Cargo = oTagActual:cData                                        
         endif
      else
         AAdd( aRoots, oTree:Add( oTagActual:cName ) )
         ATail( aRoots ):Cargo = oTagActual:cData
      endif
      oTagLast = oTagActual
   end

   FClose( hFile )

return .T.      

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

function OpenJSON( cFileName )

return nil    

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

function ShowImage( cBmp )

   local oDlg, oBmp
   
   DEFINE DIALOG oDlg TITLE cBmp

   if Lower( Right( cBmp, 3 ) ) == "bmp"
      @ 0, 0 BITMAP oBmp FILENAME cBmp OF oDlg NOBORDER
   elseif Lower( Right( cBmp, 3 ) ) == "ico"
      @ 0, 0 ICON oBmp FILENAME cBmp OF oDlg
   endif    
   
   ACTIVATE DIALOG oDlg CENTERED ;
      ON INIT ( oDlg:SetSize( Max( 300, oBmp:nWidth + 20 ),;
                              Max( 300, oBmp:nHeight + 20 ) ),;
                oBmp:Center( oDlg ), oDlg:Center() )              
   
return nil  

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

function TreeAddItem( oTree )

   local oItem := oTree:GetSelected()

   if oItem != nil .and. oItem:oParent != nil
      oItem = oTree:GetSelected():oParent:Add( "new" )
      oTree:Select( oItem )
      oTree:Refresh()
      TreeEditItem( oTree )
      oBtnSave:Enable()
   endif
   
return nil  

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

function TreeEditItem( oTree )
 
   local oItem := oTree:GetSelected()

   if oItem != nil
      PostMessage( oTree:hWnd, TVM_EDITLABEL, 0, oItem:hItem )
   endif

return nil

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

function EditTree( nRow, nCol, oWndData, oTree )

   local oPopup, cPrompt, oItem
   
   MENU oPopup POPUP 2015
      MENUITEM "&Add"       RESOURCE "plus" ACTION TreeAddItem( oTree )
      MENUITEM "Add &child" ACTION If( oTree:GetSelected() != nil,;
                                  ( oTree:GetSelected():Add( "new" ), oTree:Refresh(), oBtnSave:Enable() ),)
      MENUITEM "&Edit"      RESOURCE "edit" ACTION TreeEditItem( oTree )  
      MENUITEM "&Delete"    ACTION If( oTree:GetSelected() != nil,;
                                  ( oTree:GetSelected():End(), oTree:Refresh(), oBtnSave:Enable() ),)
      SEPARATOR
      MENUITEM "&Open all"  ACTION oTree:ExpandAll()
      MENUITEM "&Close all" ACTION oTree:CollapseAll()  
      SEPARATOR
      MENUITEM "Move &Up"   ACTION oTree:GoPrev()                          
      MENUITEM "Move Dow&n" ACTION oTree:GoNext()  
      MENUITEM "Swap up"    ACTION oTree:SwapUp()
      MENUITEM "Swap Down"  ACTION oTree:SwapDown()                        
   ENDMENU  

   ACTIVATE POPUP oPopup WINDOW oWndData AT nRow, nCol

return nil

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

function XmlError( nError )

   local aErrors := { "HBXML_ERROR_IO", "HBXML_ERROR_NOMEM", "HBXML_ERROR_OUTCHAR",;
                      "HBXML_ERROR_INVNODE", "HBXML_ERROR_INVATT", "HBXML_ERROR_MALFATT",;
                      "HBXML_ERROR_INVCHAR", "HBXML_ERROR_NAMETOOLONG", "HBXML_ERROR_ATTRIBTOOLONG",;
                      "HBXML_ERROR_VALATTOOLONG", "HBXML_ERROR_UNCLOSED", "HBXML_ERROR_UNCLOSEDENTITY",;
                      "HBXML_ERROR_WRONGENTITY" }

return If( nError > 0 .and. nError < 14, aErrors[ nError ], "error range must be 1-13" )

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

static function GenDblClickBlock( oCtrl )

return { || MsgInfo( oCtrl:nId ) }

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


Thank you!
wartiaga
 
Posts: 212
Joined: Wed May 25, 2016 1:04 am


Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: Marc Vanzegbroeck and 84 guests